From 64792b23f40ddf7d4da55450a986d94ab727ea2d Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Wed, 9 Apr 2025 19:24:42 +0330 Subject: [PATCH 01/36] Added a super power for Sword(bounos track) complete the methods and implents Weapons --- .../project/object/armors/KnightArmor.java | 15 ++++++++-- .../org/project/object/weapons/Sword.java | 30 ++++++++++++------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/object/armors/KnightArmor.java b/Java-Ring/src/main/java/org/project/object/armors/KnightArmor.java index 0dedcc2..e2c876c 100644 --- a/Java-Ring/src/main/java/org/project/object/armors/KnightArmor.java +++ b/Java-Ring/src/main/java/org/project/object/armors/KnightArmor.java @@ -1,6 +1,15 @@ package org.project.object.armors; -// TODO: UPDATE IMPLEMENTATION -public class KnightArmor { - // TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR +public class KnightArmor extends Armor { + + public KnightArmor() { + super(15, 100); + } + + @Override + public void repair() { + super.repair(); + System.out.println("Knight armor is fully repaired!"); + } + } \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Sword.java b/Java-Ring/src/main/java/org/project/object/weapons/Sword.java index a0e3cc3..8d3f8e2 100644 --- a/Java-Ring/src/main/java/org/project/object/weapons/Sword.java +++ b/Java-Ring/src/main/java/org/project/object/weapons/Sword.java @@ -1,26 +1,34 @@ package org.project.object.weapons; +import java.util.ArrayList; + import org.project.entity.Entity; -import java.util.ArrayList; -// TODO: UPDATE IMPLEMENTATION -public class Sword { - /* - THIS IS AN EXAMPLE OF A WEAPON DESIGN. - */ +public class Sword extends Weapon { int abilityCharge; public Sword() { - // TODO: DESIGN SWORD'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR + super(20, 10); + this.abilityCharge = 0; } - // TODO: (BONUS) UPDATE THE UNIQUE ABILITY - public void uniqueAbility(ArrayList targets) { + + public void fireWhirlAttack(ArrayList targets) { abilityCharge += 2; - for (Entity target : targets) { - target.takeDamage(getDamage()); + if(abilityCharge >= 3){ + for(Entity target : targets) { + target.takeDamage(getDamage() * 2); + } + abilityCharge = 0; + System.out.println("Firewhirl attack!"); + } + else { + System.out.println("Ability is not charged yet!"); } } + public void chargingAbility(){ + abilityCharge++; + } } From c6c19a67df695f71396b4cea2ab41ebd9da3788d Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 14:48:15 +0330 Subject: [PATCH 02/36] Main java changed --- Java-Ring/src/main/java/org/project/Main.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Java-Ring/src/main/java/org/project/Main.java b/Java-Ring/src/main/java/org/project/Main.java index c2e0550..724a284 100644 --- a/Java-Ring/src/main/java/org/project/Main.java +++ b/Java-Ring/src/main/java/org/project/Main.java @@ -1,10 +1,11 @@ package org.project; -import org.project.location.Location; import java.util.ArrayList; import java.util.List; +import org.project.location.Location; + public class Main { public static void main(String[] args) { // TODO: ADD SOME LOCATIONS TO YOUR GAME From 47cd0c65bc60ef131bcd974536b1df80f14ca370 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 14:51:17 +0330 Subject: [PATCH 03/36] some eror fixed --- .../src/main/java/org/project/entity/players/Player.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Player.java b/Java-Ring/src/main/java/org/project/entity/players/Player.java index 674905a..e52538c 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Player.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Player.java @@ -4,8 +4,8 @@ import org.project.object.armors.Armor; import org.project.object.weapons.Weapon; -// TODO: UPDATE IMPLEMENTATION -public abstract class Player { +// TODO: UPDATE IMPLEMENTATION(Updated) +public abstract class Player implements Entity { protected String name; Weapon weapon; Armor armor; @@ -23,6 +23,7 @@ public Player(String name, int hp, int mp, Weapon weapon, Armor armor) { this.armor = armor; } + @Override public void attack(Entity target) { target.takeDamage(weapon.getDamage()); @@ -86,4 +87,4 @@ public Armor getArmor() { return armor; } -} +} \ No newline at end of file From 974202a9672c51fcba30112715124c9c769ce274 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 14:53:05 +0330 Subject: [PATCH 04/36] Bouns super power add for sword called fireWhirlAttack --- .../main/java/org/project/object/weapons/Sword.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Sword.java b/Java-Ring/src/main/java/org/project/object/weapons/Sword.java index 8d3f8e2..833dfe7 100644 --- a/Java-Ring/src/main/java/org/project/object/weapons/Sword.java +++ b/Java-Ring/src/main/java/org/project/object/weapons/Sword.java @@ -15,20 +15,17 @@ public Sword() { } + public void chargingAbility(){ abilityCharge += 2; } + public void fireWhirlAttack(ArrayList targets) { - abilityCharge += 2; + if(abilityCharge >= 3){ for(Entity target : targets) { target.takeDamage(getDamage() * 2); } - abilityCharge = 0; + abilityCharge -= 2; System.out.println("Firewhirl attack!"); } - else { - System.out.println("Ability is not charged yet!"); - } - } - public void chargingAbility(){ - abilityCharge++; + else {System.out.println("Ability is not charged yet!");} } } From 6fe6f1830500130525be49f55cf031eba6745f7f Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 14:56:57 +0330 Subject: [PATCH 05/36] Use Special ability method updated added set level and getlevel --- .../org/project/entity/players/Knight.java | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Knight.java b/Java-Ring/src/main/java/org/project/entity/players/Knight.java index 14d8fa2..54a2b5d 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Knight.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Knight.java @@ -1,6 +1,42 @@ 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.object.armors.KnightArmor; +import org.project.object.weapons.Sword; + + +public class Knight extends Player { + private int kickCooldown; + + private int level; + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public Knight(String name) { + super(name, 150, 50, new Sword(), new KnightArmor()); + this.kickCooldown = 0; + } + + + public void useSpecialAbility(Entity target) { + if(kickCooldown <= 0 ) { + int damage = 30 + (getLevel() * 5); + System.out.println(getName() + "Launches a fierce Knight kick!"); + target.takeDamage(damage); + kickCooldown = 3; + } + else{ + System.out.println("Kick ability is on recharge (" + kickCooldown + " turns remaining)"); + } + + } + public void reduceCooldown(){ + if(kickCooldown > 0) {kickCooldown--;} + } +} \ No newline at end of file From 1dde45f3e9935629787cf0a5c0f9ff81f1336301 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 15:10:44 +0330 Subject: [PATCH 06/36] take damage method updated(Bouns) and defend system updated --- .../org/project/entity/players/Player.java | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Player.java b/Java-Ring/src/main/java/org/project/entity/players/Player.java index e52538c..9f51e7b 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Player.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Player.java @@ -6,6 +6,7 @@ // TODO: UPDATE IMPLEMENTATION(Updated) public abstract class Player implements Entity { + protected String name; Weapon weapon; Armor armor; @@ -13,7 +14,10 @@ public abstract class Player implements Entity { private int maxHP; private int mp; private int maxMP; - + private int experience = 0; + private int level = 1; + private boolean isDefending = false; + public Player(String name, int hp, int mp, Weapon weapon, Armor armor) { this.name = name; this.hp = hp; @@ -23,21 +27,42 @@ public Player(String name, int hp, int mp, Weapon weapon, Armor armor) { this.armor = armor; } - + public void gainExperience(int amount) { + experience += amount; + System.out.println("Gained " + amount + " XP!"); + + if (experience >= level * 100) { + levelUp(); + } + } + + private void levelUp() { + level++; + maxHP += 10; + hp = maxHP; + System.out.println("Level up! Now level " + level); + } + @Override public void attack(Entity target) { target.takeDamage(weapon.getDamage()); } + @Override public void defend() { - // TODO: (BONUS) IMPLEMENT A DEFENSE METHOD FOR SHIELDS + isDefending = true; + System.out.println(getName() + " raises their guard!"); } - - // TODO: (BONUS) UPDATE THE FORMULA OF TAKING DAMAGE @Override public void takeDamage(int damage) { - hp -= damage - armor.getDefense(); + int finalDamage = isDefending ? + Math.max(1, damage/2 - armor.getDefense()) : + Math.max(1, damage - armor.getDefense()); + + hp -= finalDamage; + isDefending = false; + System.out.println(getName() + " takes " + finalDamage + " damage!"); } @Override @@ -56,7 +81,6 @@ public void fillMana(int mana) { } } - public String getName() { return name; } @@ -87,4 +111,4 @@ public Armor getArmor() { return armor; } -} \ No newline at end of file +} From e56dc02178a3f600d498b651e368a7c8570e91a9 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 15:11:36 +0330 Subject: [PATCH 07/36] Nothing new --- Java-Ring/src/main/java/org/project/entity/players/Knight.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Knight.java b/Java-Ring/src/main/java/org/project/entity/players/Knight.java index 54a2b5d..086db20 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Knight.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Knight.java @@ -32,7 +32,8 @@ public void useSpecialAbility(Entity target) { kickCooldown = 3; } else{ - System.out.println("Kick ability is on recharge (" + kickCooldown + " turns remaining)"); + System.out.println("Kick ability is on recharge (" + + kickCooldown + " turns remaining)"); } } From 43e5e8e940d8a50e2ed405ecdf745cb151f184fa Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 15:57:53 +0330 Subject: [PATCH 08/36] Object Interface updated --- .../main/java/org/project/object/Object.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/object/Object.java b/Java-Ring/src/main/java/org/project/object/Object.java index 922cbd5..83c9460 100644 --- a/Java-Ring/src/main/java/org/project/object/Object.java +++ b/Java-Ring/src/main/java/org/project/object/Object.java @@ -3,9 +3,18 @@ import org.project.entity.Entity; public interface Object { + // Core method all objects must implement void use(Entity target); - - /* - TODO: ADD OTHER REQUIRED AND BONUS METHODS - */ -} + + // Identification methods + String getName(); + String getDescription(); + + // Inventory management helpers + boolean isConsumable(); + int getValue(); // Gold value + + // Equipment status methods (default implementations) + default boolean isBroken() { return false; } + default void repair() {} +} \ No newline at end of file From 8c0046b6e64c3cb88cfafb73d972b8f41b00b730 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 16:00:16 +0330 Subject: [PATCH 09/36] Abstract class consumables updated --- .../object/consumables/Consumable.java | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/object/consumables/Consumable.java b/Java-Ring/src/main/java/org/project/object/consumables/Consumable.java index fd8962c..6ea6c9f 100644 --- a/Java-Ring/src/main/java/org/project/object/consumables/Consumable.java +++ b/Java-Ring/src/main/java/org/project/object/consumables/Consumable.java @@ -1,8 +1,50 @@ package org.project.object.consumables; -// TODO: UPDATE IMPLEMENTATION -public abstract class Consumable { - /* - TODO: ADD OTHER REQUIRED AND BONUS METHODS - */ +import org.project.entity.Entity; +import org.project.object.Object; + +public abstract class Consumable implements Object { + + protected String name; + protected String description; + protected int value; + protected int remainingUses; + + public Consumable(String name, String desc, int value, int uses) { + this.name = name; + this.description = desc; + this.value = value; + this.remainingUses = uses; + } + + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public boolean isConsumable() { + return true; + } + + @Override + public int getValue() { + return value; + } + + public int getRemainingUses() { + return remainingUses; + } + + protected void consumeUse() { + if (remainingUses > 0) { + remainingUses--; + } + } } From b0ad48b9d420fe1fcaadd2fa13adef645e908857 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Thu, 10 Apr 2025 16:00:53 +0330 Subject: [PATCH 10/36] Abstract class consumables updated --- .../src/main/java/org/project/object/consumables/Consumable.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Java-Ring/src/main/java/org/project/object/consumables/Consumable.java b/Java-Ring/src/main/java/org/project/object/consumables/Consumable.java index 6ea6c9f..bf9863e 100644 --- a/Java-Ring/src/main/java/org/project/object/consumables/Consumable.java +++ b/Java-Ring/src/main/java/org/project/object/consumables/Consumable.java @@ -1,6 +1,5 @@ package org.project.object.consumables; -import org.project.entity.Entity; import org.project.object.Object; public abstract class Consumable implements Object { From 65f49f66fbd662ce9495e5ee453fae5d02104f45 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sat, 12 Apr 2025 20:06:20 +0330 Subject: [PATCH 11/36] Added a getter method --- .../main/java/org/project/entity/Entity.java | 28 +++++++++++++------ .../java/org/project/location/Location.java | 5 ++-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/Entity.java b/Java-Ring/src/main/java/org/project/entity/Entity.java index 2a060f9..2736bcc 100644 --- a/Java-Ring/src/main/java/org/project/entity/Entity.java +++ b/Java-Ring/src/main/java/org/project/entity/Entity.java @@ -1,21 +1,31 @@ package org.project.entity; public interface Entity { + // Combat Core void attack(Entity target); + void takeDamage(int damage); + void heal(int health); - void defend(); - void heal(int health); - void fillMana(int mana); + // Status methods + boolean isAlive(); + String getname(); + int getHealth(); + int getMaxHealth(); - void takeDamage(int damage); - int getMaxHP(); + // Magic/Ability system + void useSpecialAbility(Entity target); + void defend(); + + String getName(); + + // Resource management + void gainExperience(int amount); + default boolean isDefending() { return false; } - int getMaxMP(); - /* - TODO: ADD OTHER REQUIRED AND BONUS METHODS - */ + + String getDescription(); } diff --git a/Java-Ring/src/main/java/org/project/location/Location.java b/Java-Ring/src/main/java/org/project/location/Location.java index dfa9cb8..b03fadf 100644 --- a/Java-Ring/src/main/java/org/project/location/Location.java +++ b/Java-Ring/src/main/java/org/project/location/Location.java @@ -1,13 +1,14 @@ package org.project.location; -import org.project.entity.enemies.Enemy; - import java.util.ArrayList; +import org.project.entity.enemies.Enemy; + public class Location { private String name; private ArrayList enemies; + private ArrayList locations; public Location(ArrayList locations, ArrayList enemies) { this.locations = locations; From a024fdab436ff5f63f922e7060bd664651eb66bc Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sat, 12 Apr 2025 20:08:04 +0330 Subject: [PATCH 12/36] Updated --- .../org/project/entity/enemies/Enemy.java | 73 ++++++++++++++----- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Enemy.java b/Java-Ring/src/main/java/org/project/entity/enemies/Enemy.java index 1fcc491..07abd41 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Enemy.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Enemy.java @@ -1,35 +1,74 @@ package org.project.entity.enemies; +import org.project.entity.Entity; import org.project.object.weapons.Weapon; -// TODO: UPDATE IMPLEMENTATION -public abstract class Enemy { - Weapon weapon; - private int hp; - private int mp; +public abstract class Enemy implements Entity { - public Enemy(int hp, int mp, Weapon weapon) { - this.hp = hp; - this.mp = mp; + protected final String name; + protected int health; + protected int maxHealth; + protected Weapon weapon; + protected int expReward; + public Enemy(String name, int health, Weapon weapon, int expReward) { + this.name = name; + this.maxHealth = health; + this.health = health; this.weapon = weapon; + this.expReward = expReward; } - // TODO: (BONUS) UPDATE THE FORMULA OF TAKING DAMAGE @Override - public void takeDamage(int damage) { - hp -= damage; + public void attack(Entity target) { + System.out.println(name + " attacks!"); + weapon.use(target); } - public int getHp() { - return hp; + @Override + public void takeDamage(int amount) { + health -= amount; + System.out.printf("%s took %d damage (%d/%d HP)%n", + name, amount, health, maxHealth); + } + + @Override + public void heal(int amount) { + health = Math.min(health + amount, maxHealth); + System.out.println(name + " recovered " + amount + " HP!"); + } + + @Override + public abstract String getDescription(); + + // Getters + @Override + public String getName() { + return name; + } + + @Override + public int getHealth() { + return health; } - public int getMp() { - return mp; + @Override + public int getMaxHealth() { + return maxHealth; } - public Weapon getWeapon() { - return weapon; + public int getExpReward() { + return expReward; + } + + @Override + public boolean isAlive() { + return health > 0; } + + @Override + public void defend() { + System.out.println(name + " braces for impact!"); + } + } From 3d0bb6d2a70d786170738a12587a845b9f2741b6 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sat, 12 Apr 2025 22:38:58 +0330 Subject: [PATCH 13/36] for checking problems --- .vscode/settings.json | 3 + Java-Ring/.idea/.name | 1 + .../src/main/java/org/project/GameEngine.java | 177 ++++++++++++++++++ Java-Ring/src/main/java/org/project/Main.java | 16 -- .../org/project/entity/enemies/Dragon.java | 85 +++++++++ .../org/project/entity/enemies/Goblin.java | 62 ++++++ .../org/project/entity/enemies/Skeleton.java | 33 +++- .../org/project/entity/players/Knight.java | 50 ++--- .../org/project/entity/players/Player.java | 162 ++++++++++------ .../java/org/project/location/Location.java | 78 ++++++-- .../java/org/project/object/armors/Armor.java | 67 ++++--- .../project/object/armors/KnightArmor.java | 51 ++++- .../org/project/object/consumables/Flask.java | 59 +++++- .../java/org/project/object/weapons/Claw.java | 24 +++ .../project/object/weapons/OtherWeapons.java | 109 +++++++++++ .../org/project/object/weapons/Sword.java | 35 ++-- .../org/project/object/weapons/Weapon.java | 83 ++++++-- 17 files changed, 913 insertions(+), 182 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 Java-Ring/.idea/.name create mode 100644 Java-Ring/src/main/java/org/project/GameEngine.java delete mode 100644 Java-Ring/src/main/java/org/project/Main.java create mode 100644 Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java create mode 100644 Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java create mode 100644 Java-Ring/src/main/java/org/project/object/weapons/Claw.java create mode 100644 Java-Ring/src/main/java/org/project/object/weapons/OtherWeapons.java diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3ebdbc0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "CodeGPT.apiKey": "CodeGPT Plus Beta" +} \ No newline at end of file diff --git a/Java-Ring/.idea/.name b/Java-Ring/.idea/.name new file mode 100644 index 0000000..6c13084 --- /dev/null +++ b/Java-Ring/.idea/.name @@ -0,0 +1 @@ +Enemy.java \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/GameEngine.java b/Java-Ring/src/main/java/org/project/GameEngine.java new file mode 100644 index 0000000..26e257f --- /dev/null +++ b/Java-Ring/src/main/java/org/project/GameEngine.java @@ -0,0 +1,177 @@ +package org.project; + +import org.project.entity.players.*; +import org.project.location.Location; +import java.util.Scanner; +// import org.project.entity.object.consumables.Consumable; // Ensure this matches the actual package of Consumable + +public class GameEngine { + private Player player; + private Location currentLocation; + private Scanner scanner = new Scanner(System.in); + private boolean gameRunning = true; + + public void startGame() { + initializePlayer(); + initializeLocations(); + + while (gameRunning && player.isAlive()) { + displayMainMenu(); + handleMainMenuInput(); + } + + endGame(); + } + + private void initializePlayer() { + System.out.println("=== CHARACTER CREATION ==="); + System.out.print("Enter your name: "); + String name = scanner.nextLine(); + + System.out.println("Choose your class:"); + System.out.println("1. Knight\n2. Wizard\n3. Assassin"); + int classChoice = scanner.nextInt(); + + player = switch (classChoice) { + case 1 -> new Knight(name); + // case 2 -> new Wizard(name); + // case 3 -> new Assassin(name); + default -> new Knight(name); + }; + + System.out.printf("%s the %s enters the Java Ring!%n", + player.getName(), player.getClass().getSimpleName()); + } + + private void initializeLocations() { + currentLocation = new Location("Forgotten Forest", + "A dense woodland shrouded in mist"); + } + + private void displayMainMenu() { + System.out.println("\n=== MAIN MENU ==="); + System.out.println("Location: " + currentLocation.getName()); + System.out.println("1. Explore"); + System.out.println("2. Character Info"); + System.out.println("3. Inventory"); + System.out.println("4. Quit"); + System.out.print("Choose an action: "); + } + + private void handleMainMenuInput() { + int choice = scanner.nextInt(); + + switch (choice) { + case 1 -> explore(); + case 2 -> displayCharacterInfo(); + case 3 -> manageInventory(); + case 4 -> gameRunning = false; + default -> System.out.println("Invalid choice!"); + } + } + + private void explore() { + System.out.println("\nYou venture deeper into " + currentLocation.getName()); + + if (Math.random() < 0.7) { // 70% encounter chance + startCombat(currentLocation.generateEnemy()); + } else { + System.out.println("The path is quiet for now..."); + currentLocation.increaseDanger(); + } + } + + private void startCombat(Enemy enemy) { + System.out.printf("%nA wild %s appears!%n", enemy.getName()); + + while (player.isAlive() && enemy.isAlive()) { + playerTurn(enemy); + if (enemy.isAlive()) { + enemyTurn(enemy); + } + } + + if (player.isAlive()) { + System.out.printf("You defeated the %s!%n", enemy.getName()); + player.gainExperience(enemy.getExpReward()); + currentLocation.increaseDanger(); + } + } + + private void playerTurn(Enemy enemy) { + System.out.println("\n=== YOUR TURN ==="); + System.out.printf("HP: %d/%d | Enemy HP: %d%n", + player.getHealth(), player.getMaxHealth(), enemy.getHealth()); + + System.out.println("1. Attack"); + System.out.println("2. Defend"); + System.out.println("3. Special Ability"); + System.out.println("4. Use Item"); + System.out.print("Choose action: "); + + int choice = scanner.nextInt(); + + switch (choice) { + case 1 -> player.attack(enemy); + case 2 -> player.defend(); + case 3 -> player.useSpecialAbility(enemy); + case 4 -> useItemInCombat(); + default -> System.out.println("Invalid choice!"); + } + } + + private void enemyTurn(Enemy enemy) { + System.out.printf("%n=== %s's TURN ===%n", enemy.getName()); + enemy.attack(player); + } + + private void useItemInCombat() { + if (player.getInventory().isEmpty()) { + System.out.println("Your inventory is empty!"); + return; + } + + System.out.println("\nAvailable items:"); + for (int i = 0; i < player.getInventory().size(); i++) { + Consumable item = player.getInventory().get(i); + System.out.printf("%d. %s (%d uses)%n", + i + 1, item.getName(), item.getRemainingUses()); + } + + System.out.print("Select item (0 to cancel): "); + int choice = scanner.nextInt() - 1; + + if (choice >= 0 && choice < player.getInventory().size()) { + player.useItem(choice); + } + } + + private void displayCharacterInfo() { + System.out.println("\n=== CHARACTER SHEET ==="); + System.out.printf("Name: %s%n", player.getName()); + System.out.printf("Class: %s%n", player.getClass().getSimpleName()); + System.out.printf("Level: %d%n", player.getLevel()); + System.out.printf("HP: %d/%d%n", player.getHealth(), player.getMaxHealth()); + System.out.printf("XP: %d/%d%n", + player.getExperience(), player.getLevel() * 100); + System.out.printf("Weapon: %s%n", player.getWeapon().getDescription()); + System.out.printf("Armor: %s%n", player.getArmor().getDescription()); + } + + private void manageInventory() { + // Similar to combat item menu but with repair options + // Implementation omitted for brevity + } + + private void endGame() { + if (player.isAlive()) { + System.out.println("You leave the Java Ring... for now."); + } else { + System.out.println("GAME OVER"); + } + } + + public static void main(String[] args) { + new GameEngine().startGame(); + } +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/Main.java b/Java-Ring/src/main/java/org/project/Main.java deleted file mode 100644 index 724a284..0000000 --- a/Java-Ring/src/main/java/org/project/Main.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.project; - - -import java.util.ArrayList; -import java.util.List; - -import org.project.location.Location; - -public class Main { - public static void main(String[] args) { - // TODO: ADD SOME LOCATIONS TO YOUR GAME - List locations = new ArrayList<>(); - - // TODO: IMPLEMENT GAMEPLAY - } -} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java b/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java new file mode 100644 index 0000000..ff267e3 --- /dev/null +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java @@ -0,0 +1,85 @@ +package org.project.entity.enemies; + +import org.project.entity.Entity; +import org.project.entity.enemies.Enemy; +import org.project.object.weapons.Claw; + +public class Dragon extends Enemy { + + private boolean usedFireBreath; + private static final int FIRE_BREATH_COOLDOWN = 3; + private int fireBreathCooldown = 0; + private static final double BURN_CHANCE = 0.3; + + public Dragon(int health, int expReward) { + super("Ancient Dragon", health, new Claw(), expReward); + this.usedFireBreath = false; + } + + + @Override + public void attack(Entity target) { + if (!usedFireBreath && health < maxHealth / 2) { + fireBreath(target); + usedFireBreath = true; + } else if (fireBreathCooldown <= 0 && Math.random() < 0.25) { + fireBreath(target); + fireBreathCooldown = FIRE_BREATH_COOLDOWN; + } else { + super.attack(target); + if (fireBreathCooldown > 0) { + fireBreathCooldown--; + } + } + } + + + + private void fireBreath(Entity target) { + System.out.println("Dragon rears back and unleashes a torrent of flames!"); + int baseDamage = (int) (weapon.getDamage() * 2.5); + int actualDamage = target.isDefending() ? baseDamage / 2 : baseDamage; + + target.takeDamage(actualDamage); + System.out.printf("%s takes %d fire damage!%n", target.getName(), actualDamage); + + if (Math.random() < BURN_CHANCE) { + int burnDamage = (int) (baseDamage * 0.3); + applyBurn(target, burnDamage); + } + this.takeDamage((int) (maxHealth * 0.05)); + } + + private void applyBurn(Entity target, int burnDamage) { + System.out.printf(" %s catches fire and will take %d damage over time!%n", + target.getName(), burnDamage * 3); + System.out.println(target.getName() + " is burning!"); + new Thread(() -> { + try { + // Burn over 3 turns + for (int i = 0; i < 3 && target.isAlive(); i++) { + Thread.sleep(2000); // Simulate turn delay + target.takeDamage(burnDamage); + System.out.println(target.getName() + " takes " + burnDamage + " burn damage!"); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }).start(); + } + + @Override + public void takeDamage(int amount) { + // Dragons take reduced damage from non-magical attacks + int reducedDamage = (int) (amount * 0.75); + super.takeDamage(reducedDamage); + System.out.println("Dragon's scales reduce damage to " + reducedDamage + "!"); + } + @Override + public String getDescription() { + return String.format( + "Ancient dragon with fiery breath (Reduces damage by 25% | Health: %d/%d)", + health, maxHealth + ); + } +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java b/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java new file mode 100644 index 0000000..c27d525 --- /dev/null +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java @@ -0,0 +1,62 @@ +package org.project.entity.enemies; + +import org.project.entity.Entity; +import org.project.entity.enemies.Enemy; + +public class Goblin extends Enemy { + private static final double DODGE_CHANCE = 0.25; + private static final int STEAL_AMOUNT = 5; + private boolean hasStolen = false; + + public Goblin(int health, int expReward) { + super("Goblin", health, new Dagger(), expReward); + } + + @Override + public void gainExperience(int amount) { + // Enemies don't gain experience + } + + @Override + public void takeDamage(int amount) { + if (Math.random() < DODGE_CHANCE) { + System.out.println("Goblin nimbly dodges the attack!"); + return; + } + super.takeDamage(amount); + } + @Override + public String getName() { + return "Goblin"; + } + @Override + public void useSpecialAbility(Entity target) { + if (!hasStolen) { + // Goblin's dirty trick: steals HP on first special use + int damage = STEAL_AMOUNT + (int) (Math.random() * 5); + target.takeDamage(damage); + this.heal(damage); + System.out.printf("Goblin stabs %s and steals %d HP!%n", + target.getName(), damage); + hasStolen = true; + } else { + // Regular attack if already used special + System.out.println("Goblin attempts another dirty trick but fails!"); + super.attack(target); + } + } + + @Override + public void attack(Entity target) { + // 10% chance to use special ability randomly + if (Math.random() < 0.1) { + useSpecialAbility(target); + } else { + super.attack(target); + } + } + @Override + public String getDescription() { + return "A sneaky goblin that fights dirty (Dodge chance: 25%)"; + } +} diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java b/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java index 8c3e638..955b7b1 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java @@ -1,6 +1,31 @@ package org.project.entity.enemies; -// TODO: UPDATE IMPLEMENTATION -public class Skeleton { - // TODO: DESIGN ENEMY'S WEAPON AND ARMOR AND IMPLEMENT THE CONSTRUCTOR -} + + +public class Skeleton extends Enemy implements Entity { + private boolean hasResurrected; + + public Skeleton(int health, int expReward) { + super("Skeleton", health, new RustySword(), expReward); + this.hasResurrected = false; + } + + @Override + public void takeDamage(int amount) { + super.takeDamage(amount); + if (!isAlive() && !hasResurrected) { + resurrect(); + } + } + + private void resurrect() { + health = maxHealth / 2; + hasResurrected = true; + System.out.println("The skeleton reassembles itself!"); + } + + // @Override + // Void string getDescription() { + // return "A reanimated skeleton with a rusty sword. (Resurrects once)"; + // } +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/entity/players/Knight.java b/Java-Ring/src/main/java/org/project/entity/players/Knight.java index 086db20..a3f781f 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Knight.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Knight.java @@ -1,43 +1,43 @@ package org.project.entity.players; - import org.project.entity.Entity; import org.project.object.armors.KnightArmor; import org.project.object.weapons.Sword; - public class Knight extends Player { - private int kickCooldown; - private int level; + @Override + public String getname() { + return this.name; + } + private int kickCooldown; + private static final int KICK_DAMAGE = 35; - public int getLevel() { - return level; - } - - public void setLevel(int level) { - this.level = level; - } - public Knight(String name) { - super(name, 150, 50, new Sword(), new KnightArmor()); + super(name, 200, 30, new Sword(), new KnightArmor()); this.kickCooldown = 0; } - - + + @Override public void useSpecialAbility(Entity target) { - if(kickCooldown <= 0 ) { - int damage = 30 + (getLevel() * 5); - System.out.println(getName() + "Launches a fierce Knight kick!"); - target.takeDamage(damage); + if (kickCooldown <= 0) { + int totalDamage = KICK_DAMAGE + (level * 2); + System.out.printf("%s performs a mighty kick (%d damage)!%n", + name, totalDamage); + target.takeDamage(totalDamage); kickCooldown = 3; + } else { + System.out.printf("Kick on cooldown (%d turns remaining)%n", + kickCooldown); } - else{ - System.out.println("Kick ability is on recharge (" - + kickCooldown + " turns remaining)"); - } + } + public void reduceCooldowns() { + if (kickCooldown > 0) kickCooldown--; } - public void reduceCooldown(){ - if(kickCooldown > 0) {kickCooldown--;} + + @Override + public void attack(Entity target) { + super.attack(target); + reduceCooldowns(); } } \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/entity/players/Player.java b/Java-Ring/src/main/java/org/project/entity/players/Player.java index 9f51e7b..a1aa7cc 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Player.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Player.java @@ -1,106 +1,125 @@ package org.project.entity.players; +import java.util.ArrayList; +import java.util.List; + import org.project.entity.Entity; import org.project.object.armors.Armor; +import org.project.object.consumables.Consumable; +import org.project.object.consumables.Flask; import org.project.object.weapons.Weapon; -// TODO: UPDATE IMPLEMENTATION(Updated) public abstract class Player implements Entity { - protected String name; - Weapon weapon; - Armor armor; - private int hp; - private int maxHP; - private int mp; - private int maxMP; - private int experience = 0; - private int level = 1; - private boolean isDefending = false; - - public Player(String name, int hp, int mp, Weapon weapon, Armor armor) { + protected final String name; + protected int health; + protected int maxHealth; + protected int mana; + protected int maxMana; + protected Weapon weapon; + protected Armor armor; + protected int level; + protected int experience; + protected List inventory; + protected boolean defending; + + public Player(String name, int maxHealth, int maxMana, Weapon weapon, Armor armor) { this.name = name; - this.hp = hp; - this.mp = mp; - + this.maxHealth = maxHealth; + this.health = maxHealth; + this.maxMana = maxMana; + this.mana = maxMana; this.weapon = weapon; this.armor = armor; + this.level = 1; + this.experience = 0; + this.inventory = new ArrayList<>(); + this.inventory.add(new Flask()); // Starting item } - public void gainExperience(int amount) { - experience += amount; - System.out.println("Gained " + amount + " XP!"); - - if (experience >= level * 100) { - levelUp(); - } + @Override + public void attack(Entity target) { + weapon.use(target); } - private void levelUp() { - level++; - maxHP += 10; - hp = maxHP; - System.out.println("Level up! Now level " + level); + @Override + public void defend() { + defending = true; + System.out.println(name + " takes defensive stance!"); } @Override - public void attack(Entity target) { - target.takeDamage(weapon.getDamage()); - } + public void takeDamage(int amount) { + int reducedDamage = armor.protect(amount); + health -= reducedDamage; + defending = false; + System.out.printf("%s took %d damage (reduced from %d)%n", + name, reducedDamage, amount); - @Override - public void defend() { - isDefending = true; - System.out.println(getName() + " raises their guard!"); + if (health <= 0) { + System.out.println(name + " has been defeated!"); + } } + @Override - public void takeDamage(int damage) { - int finalDamage = isDefending ? - Math.max(1, damage/2 - armor.getDefense()) : - Math.max(1, damage - armor.getDefense()); - - hp -= finalDamage; - isDefending = false; - System.out.println(getName() + " takes " + finalDamage + " damage!"); + public void heal(int amount) { + health = Math.min(health + amount, maxHealth); + System.out.println(name + " recovered " + amount + " HP!"); } @Override - public void heal(int health) { - hp += health; - if (hp > maxHP) { - hp = maxHP; + public void gainExperience(int amount) { + experience += amount; + System.out.println(name + " gained " + amount + " XP!"); + + if (experience >= level * 100) { + levelUp(); } } - @Override - public void fillMana(int mana) { - mp += mana; - if (mp > maxMP) { - mp = maxMP; + private void levelUp() { + level++; + maxHealth += 10; + maxMana += 5; + health = maxHealth; + mana = maxMana; + System.out.printf("%s leveled up to %d!%n", name, level); + } + + // Inventory management + public void useItem(int index) { + if (index >= 0 && index < inventory.size()) { + Consumable item = inventory.get(index); + item.use(this); + if (item.getRemainingUses() <= 0) { + inventory.remove(index); + } } } + // Getters + @Override public String getName() { return name; } - public int getHp() { - return hp; + @Override + public int getHealth() { + return health; } @Override - public int getMaxHP() { - return maxHP; + public int getMaxHealth() { + return maxHealth; } - public int getMp() { - return mp; + public int getMana() { + return mana; } - @Override - public int getMaxMP() { - return maxMP; + public int getMaxMana() { + return maxMana; } public Weapon getWeapon() { @@ -111,4 +130,25 @@ public Armor getArmor() { return armor; } + public int getLevel() { + return level; + } + + public int getExperience() { + return experience; + } + + public List getInventory() { + return inventory; + } + + @Override + public boolean isAlive() { + return health > 0; + } + + @Override + public boolean isDefending() { + return defending; + } } diff --git a/Java-Ring/src/main/java/org/project/location/Location.java b/Java-Ring/src/main/java/org/project/location/Location.java index b03fadf..a53b86b 100644 --- a/Java-Ring/src/main/java/org/project/location/Location.java +++ b/Java-Ring/src/main/java/org/project/location/Location.java @@ -1,33 +1,85 @@ package org.project.location; -import java.util.ArrayList; +import java.util.Random; +import org.project.entity.enemies.Dragon; import org.project.entity.enemies.Enemy; +import org.project.entity.enemies.Goblin; +import org.project.entity.enemies.Skeleton; public class Location { + + public enum Biome { + FOREST, CAVE, MOUNTAIN , RUINS + } + private String name; + private String description; + private int dangerLevel; + private Random random = new Random(); + private Biome biome; + + public Location(String name, String description) { + this.name = name; + this.description = description; + this.dangerLevel = 1; + this.biome = biome; + } - private ArrayList enemies; - private ArrayList locations; + public Enemy generateEnemy() { + int scaledHealth = 50 + (dangerLevel * 20); + int scaledExp = 30 + (dangerLevel * 10); + + // Biome-based enemy weights + double[] weights = getBiomeWeights(); + double roll = random.nextDouble() * 100; + + if (roll < weights[0]) { + return new Goblin(scaledHealth, scaledExp); + } else if (roll < weights[0] + weights[1]) { + return new Skeleton(scaledHealth, scaledExp); + } else { + return new Dragon(scaledHealth, scaledExp); + } + } - public Location(ArrayList locations, ArrayList enemies) { - this.locations = locations; - this.enemies = enemies; + private double[] getBiomeWeights() { + return switch (biome) { + case FOREST -> new double[]{70, 25, 5}; // 70% Goblin, 25% Skeleton, 5% Dragon + case CAVE -> new double[]{30, 65, 5}; // More skeletons in caves + case MOUNTAIN -> new double[]{10, 30, 60}; // Dragons dominate mountains + case RUINS -> new double[]{40, 55, 5}; // Balanced with more undead + default -> new double[]{60, 35, 5}; + }; } - /* - TODO: (BONUS) RESET EACH LOCATION AFTER PLAYER LEAVES - */ + public void increaseDanger() { + dangerLevel++; + System.out.println(name + " grows more dangerous..."); + } + + // Getters public String getName() { return name; } - public ArrayList getLocations() { - return locations; + public String getDescription() { + return description; + } + + public int getDangerLevel() { + return dangerLevel; } - public ArrayList getEnemies() { - return enemies; + // New method to get danger description + public String getDangerDescription() { + if (dangerLevel <= 2) { + return "Safe"; + } + if (dangerLevel <= 5) { + return "Risky"; + } + return "Deadly"; } } diff --git a/Java-Ring/src/main/java/org/project/object/armors/Armor.java b/Java-Ring/src/main/java/org/project/object/armors/Armor.java index 346c25e..1a12ca7 100644 --- a/Java-Ring/src/main/java/org/project/object/armors/Armor.java +++ b/Java-Ring/src/main/java/org/project/object/armors/Armor.java @@ -1,42 +1,67 @@ package org.project.object.armors; +import org.project.object.Object; + // TODO: UPDATE IMPLEMENTATION -public abstract class Armor { - private int defense; - private int maxDefense; - private int durability; - private int maxDurability; +public abstract class Armor implements Object { - private boolean isBroke; + protected String name; + private int defense; + protected int durability; + final int maxDurability; - public Armor(int defense, int durability) { + public Armor(String name, int defense, int durability) { + this.name = name; this.defense = defense; - this.durability = durability; + this.durability = this.maxDurability = durability; } - public void checkBreak() { - if (durability <= 0) { - isBroke = true; - defense = 0; + public int protect(int incomingDamage) { + int damageReduction = Math.min(defense, incomingDamage / 2); + int damageTaken = Math.max(1, incomingDamage - damageReduction); + + durability -= incomingDamage / 10; + if (durability < 0) { + durability = 0; } + + return damageTaken; } - // TODO: (BONUS) UPDATE THE REPAIR METHOD + + @Override public void repair() { - isBroke = false; - defense = maxDefense; durability = maxDurability; + System.out.println(name + " has been repaired!"); } - public int getDefense() { - return defense; + @Override + public boolean isBroken() { + return durability <= 0; } - public int getDurability() { - return durability; + // Standard getters + @Override + public String getName() { + return name; } - public boolean isBroke() { - return isBroke; + @Override + public String getDescription() { + return String.format("%s (%d DEF)", name, defense); + } + + @Override + public boolean isConsumable() { + return false; + } + + @Override + public int getValue() { + return defense * 12; + } + + public int getDurability() { + return durability; } } diff --git a/Java-Ring/src/main/java/org/project/object/armors/KnightArmor.java b/Java-Ring/src/main/java/org/project/object/armors/KnightArmor.java index e2c876c..c624c26 100644 --- a/Java-Ring/src/main/java/org/project/object/armors/KnightArmor.java +++ b/Java-Ring/src/main/java/org/project/object/armors/KnightArmor.java @@ -1,15 +1,58 @@ package org.project.object.armors; -public class KnightArmor extends Armor { +import org.project.entity.Entity; +import org.project.object.Object; - public KnightArmor() { - super(15, 100); +public class KnightArmor extends Armor implements Object { + private static final int BASE_DEFENSE = 25; + private static final int BASE_DURABILITY = 150; + private static final String ARMOR_NAME = "Knight's Plate Armor"; + + public KnightArmor() { + super(ARMOR_NAME, BASE_DEFENSE, BASE_DURABILITY); + } + + @Override + public void use(Entity target) { + // Armor can't be "used" like consumables, but we implement the required method + System.out.println(ARMOR_NAME + " cannot be used directly"); + } + + @Override + public int protect(int incomingDamage) { + // Knight armor has 15% chance to completely block physical attacks + if (Math.random() < 0.15 && getDurability() > 0) { + System.out.println(ARMOR_NAME + " deflects the attack completely!"); + reduceDurability(); // Blocking still stresses the armor + return 0; + } + return super.protect(incomingDamage); + } + + private void reduceDurability() { + if (durability > 0) { + durability -= 2; + } } @Override public void repair() { super.repair(); - System.out.println("Knight armor is fully repaired!"); + System.out.println(ARMOR_NAME + " shines like new after repair!"); + } + + @Override + public String getDescription() { + return String.format("%s (Def: %d, Dur: %d/%d) - Heavy plate armor with chance to block attacks", + name, getBaseDefense(), getDurability(), maxDurability); } + public int getBaseDefense() { + return BASE_DEFENSE; + } + + @Override + public boolean isConsumable() { + return false; + } } \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/object/consumables/Flask.java b/Java-Ring/src/main/java/org/project/object/consumables/Flask.java index d7e515d..bb0bb49 100644 --- a/Java-Ring/src/main/java/org/project/object/consumables/Flask.java +++ b/Java-Ring/src/main/java/org/project/object/consumables/Flask.java @@ -2,15 +2,58 @@ import org.project.entity.Entity; -// TODO: UPDATE IMPLEMENTATION -public class Flask { - /* - THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN. - */ +public class Flask extends Consumable { + private static final int HEAL_POWER = 30; + private static final String NAME = "Healing Flask"; + private static final String DESCRIPTION = "Restores 30 HP"; + private static final int VALUE = 50; + private static final int MAX_USES = 3; + + public Flask() { + super(NAME, DESCRIPTION, VALUE, MAX_USES); + } - // TODO: (BONUS) UPDATE USE METHOD @Override public void use(Entity target) { - target.heal(target.getMaxHP() / 10); + if (getRemainingUses() > 0) { + target.heal(HEAL_POWER); + consumeUse(); + System.out.printf("%s healed for %d HP! (%d uses remain)%n", + target.getName(), HEAL_POWER, getRemainingUses()); + + // Bonus: Flask gets more effective at low health + if (target.getHealth() < target.getMaxHealth() * 0.3) { + int bonusHeal = HEAL_POWER / 2; + target.heal(bonusHeal); + System.out.printf("Emergency boost! Additional %d HP restored!%n", bonusHeal); + } + } else { + System.out.println("Flask is empty!"); + } + } + + @Override + public boolean isConsumable() { + return true; + } + + // Bonus: Refill method + public void refill() { + if (getRemainingUses() < MAX_USES) { + System.out.println("Flask has been refilled!"); + resetUses(); + } else { + System.out.println("Flask is already full!"); + } + } + + // Method to reset the uses of the flask + private void resetUses() { + setRemainingUses(MAX_USES); + } + + // Setter for remaining uses + private void setRemainingUses(int uses) { + this.remainingUses = uses; } -} +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Claw.java b/Java-Ring/src/main/java/org/project/object/weapons/Claw.java new file mode 100644 index 0000000..2c1fa6d --- /dev/null +++ b/Java-Ring/src/main/java/org/project/object/weapons/Claw.java @@ -0,0 +1,24 @@ +package org.project.object.weapons; + +import java.util.List; + +import org.project.entity.Entity; + +public class Claw extends Weapon { + public Claw() { + super("Dragon Claws", 25, 0, Integer.MAX_VALUE); + } + + @Override + public int getDamage() { + return 25 + (int)(Math.random() * 5); // 25-30 damage + } + + @Override + public void specialAbility(List targets) { + System.out.println("Dragon performs a rending slash!"); + for (Entity target : targets) { + target.takeDamage(getDamage() * 3 / 4); // 75% damage to all + } + } +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/object/weapons/OtherWeapons.java b/Java-Ring/src/main/java/org/project/object/weapons/OtherWeapons.java new file mode 100644 index 0000000..f2aa423 --- /dev/null +++ b/Java-Ring/src/main/java/org/project/object/weapons/OtherWeapons.java @@ -0,0 +1,109 @@ +package org.project.object.weapons; + +import java.util.List; + +import org.project.entity.Entity; + +public class OtherWeapons { + // Made classes public and non-static since they're in their own file + // Each weapon is now a standalone class extending Weapon + + public static class FireSword extends Weapon { + private static final int BURN_DURATION = 3; + private static final int BURN_DAMAGE = 5; + + public FireSword() { + super("Flametongue Sword", 30, 10, 100); + } + + @Override + public int getDamage() { + return baseDamage + (int)(Math.random() * 5); // 30-34 damage + } + + @Override + public void specialAbility(List targets) { + System.out.println("Sword erupts in flames!"); + for (Entity target : targets) { + int damage = getDamage() + 15; + target.takeDamage(damage); + System.out.printf("%s takes %d fire damage!%n", target.getName(), damage); + applyBurn(target); + } + } + + private void applyBurn(Entity target) { + System.out.printf("%s catches fire for %d turns!%n", + target.getName(), BURN_DURATION); + // Implementation for burn over time + new Thread(() -> { + try { + for (int i = 0; i < BURN_DURATION && target.isAlive(); i++) { + Thread.sleep(2000); // Simulate turn delay + target.takeDamage(BURN_DAMAGE); + System.out.printf("%s takes %d burn damage!%n", + target.getName(), BURN_DAMAGE); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }).start(); + } + } + + public static class FrostAxe extends Weapon { + private static final double FREEZE_CHANCE = 0.2; + private static final int FREEZE_DURATION = 2; + + public FrostAxe() { + super("Frostbite Axe", 35, 15, 80); + } + + @Override + public void specialAbility(List targets) { + System.out.println("Axe releases a chilling wave!"); + for (Entity target : targets) { + target.takeDamage(20); + if (Math.random() < FREEZE_CHANCE) { + System.out.println(target.getName() + " is frozen solid!"); + // Freeze would prevent target from acting for FREEZE_DURATION turns + } + } + } + } + + public static class PoisonDagger extends Weapon { + private static final int POISON_DURATION = 3; + private static final int POISON_DAMAGE = 3; + + public PoisonDagger() { + super("Venomstrike Dagger", 20, 5, 120); + } + + @Override + public void specialAbility(List targets) { + System.out.println("Dagger drips with venom!"); + for (Entity target : targets) { + applyPoison(target); + } + } + + private void applyPoison(Entity target) { + System.out.printf("%s is poisoned for %d turns!%n", + target.getName(), POISON_DURATION); + // Poison damage over time + new Thread(() -> { + try { + for (int i = 0; i < POISON_DURATION && target.isAlive(); i++) { + Thread.sleep(2000); // Simulate turn delay + target.takeDamage(POISON_DAMAGE); + System.out.printf("%s takes %d poison damage!%n", + target.getName(), POISON_DAMAGE); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }).start(); + } + } +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Sword.java b/Java-Ring/src/main/java/org/project/object/weapons/Sword.java index 833dfe7..6abd535 100644 --- a/Java-Ring/src/main/java/org/project/object/weapons/Sword.java +++ b/Java-Ring/src/main/java/org/project/object/weapons/Sword.java @@ -1,6 +1,6 @@ package org.project.object.weapons; -import java.util.ArrayList; +import java.util.List; import org.project.entity.Entity; @@ -10,22 +10,33 @@ public class Sword extends Weapon { int abilityCharge; public Sword() { - super(20, 10); + super("Stell Sword" , 25 , 15, 100); this.abilityCharge = 0; } - public void chargingAbility(){ abilityCharge += 2; } - - public void fireWhirlAttack(ArrayList targets) { - - if(abilityCharge >= 3){ - for(Entity target : targets) { - target.takeDamage(getDamage() * 2); + + @Override + public void specialAbility(List targets) { + if (abilityCharge >= 3) { + System.out.println("Executing Whirlwind Slash!"); + for (Entity target : targets) { + target.takeDamage(baseDamage * 2); } - abilityCharge -= 2; - System.out.println("Firewhirl attack!"); + abilityCharge = 0; + } else { + System.out.printf("Need %d more attacks to charge!\n", 3 - abilityCharge); } - else {System.out.println("Ability is not charged yet!");} } + @Override + public void use(Entity target) { + super.use(target); + gainCharge(); + } + private void gainCharge() { + if (abilityCharge < 3) { + abilityCharge++; + } + } + } diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Weapon.java b/Java-Ring/src/main/java/org/project/object/weapons/Weapon.java index 35e1ecc..c009e41 100644 --- a/Java-Ring/src/main/java/org/project/object/weapons/Weapon.java +++ b/Java-Ring/src/main/java/org/project/object/weapons/Weapon.java @@ -1,35 +1,82 @@ package org.project.object.weapons; +import java.util.List; + import org.project.entity.Entity; +import org.project.object.Object; -// TODO: UPDATE IMPLEMENTATION -public abstract class Weapon { - private int damage; - private int manaCost; +public abstract class Weapon implements Object { - /* - TODO: ADD OTHER REQUIRED AND BONUS ATTRIBUTES - */ + protected String name; + protected int baseDamage; + protected int manaCost; + protected int durability; + protected int maxDurability; - public Weapon(int damage, int manaCost) { - this.damage = damage; + public Weapon(String name, int damage, int manaCost, int durability) { + this.name = name; + this.baseDamage = damage; this.manaCost = manaCost; + this.durability = this.maxDurability = durability; } - + public int getDamage() { + return baseDamage; + } + // Core combat method @Override public void use(Entity target) { - target.takeDamage(damage); + if (durability > 0) { + int damage = calculateDamage(); + target.takeDamage(damage); + durability--; + System.out.printf("%s dealt %d damage! (Durability: %d/%d)\n", + name, damage, durability, maxDurability); + } else { + System.out.println(name + " is broken!"); + } } - public int getDamage() { - return damage; + protected int calculateDamage() { + return baseDamage; + } + + // Special ability for weapons + public abstract void specialAbility(List targets); + + // Repair system + @Override + public void repair() { + durability = maxDurability; + System.out.println(name + " has been repaired!"); } - public int getManaCost() { - return manaCost; + @Override + public boolean isBroken() { + return durability <= 0; } - /* - TODO: ADD OTHER REQUIRED AND BONUS METHODS - */ + // Standard getters + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return String.format("%s (%d DMG)", name, baseDamage); + } + + @Override + public boolean isConsumable() { + return false; + } + + @Override + public int getValue() { + return baseDamage * 8; + } + + public int getDurability() { + return durability; + } } From 4144adfe2146a92222a8640e3dd7bdd2d9a02f3b Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 18:01:54 +0330 Subject: [PATCH 14/36] Entity is completed --- Java-Ring/src/main/java/org/project/entity/Entity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Java-Ring/src/main/java/org/project/entity/Entity.java b/Java-Ring/src/main/java/org/project/entity/Entity.java index 2736bcc..e17256d 100644 --- a/Java-Ring/src/main/java/org/project/entity/Entity.java +++ b/Java-Ring/src/main/java/org/project/entity/Entity.java @@ -10,7 +10,7 @@ public interface Entity { // Status methods boolean isAlive(); - String getname(); + int getHealth(); int getMaxHealth(); From 72ac6ce7514b6e2d2ab7b0fca59cce4895e01d88 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 18:02:47 +0330 Subject: [PATCH 15/36] New enemy added with superpower --- .../org/project/entity/enemies/Dragon.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java b/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java index ff267e3..d8dd4ee 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java @@ -1,7 +1,6 @@ package org.project.entity.enemies; import org.project.entity.Entity; -import org.project.entity.enemies.Enemy; import org.project.object.weapons.Claw; public class Dragon extends Enemy { @@ -11,8 +10,8 @@ public class Dragon extends Enemy { private int fireBreathCooldown = 0; private static final double BURN_CHANCE = 0.3; - public Dragon(int health, int expReward) { - super("Ancient Dragon", health, new Claw(), expReward); + public Dragon(int health, int expReward, Claw claw) { + super("Dragon", health, new Claw(), expReward); this.usedFireBreath = false; } @@ -20,10 +19,10 @@ public Dragon(int health, int expReward) { @Override public void attack(Entity target) { if (!usedFireBreath && health < maxHealth / 2) { - fireBreath(target); + useSpecialAbility(target); usedFireBreath = true; } else if (fireBreathCooldown <= 0 && Math.random() < 0.25) { - fireBreath(target); + useSpecialAbility(target); fireBreathCooldown = FIRE_BREATH_COOLDOWN; } else { super.attack(target); @@ -33,9 +32,9 @@ public void attack(Entity target) { } } - - private void fireBreath(Entity target) { +@Override + public void useSpecialAbility(Entity target) { // fire breath System.out.println("Dragon rears back and unleashes a torrent of flames!"); int baseDamage = (int) (weapon.getDamage() * 2.5); int actualDamage = target.isDefending() ? baseDamage / 2 : baseDamage; @@ -43,13 +42,13 @@ private void fireBreath(Entity target) { target.takeDamage(actualDamage); System.out.printf("%s takes %d fire damage!%n", target.getName(), actualDamage); - if (Math.random() < BURN_CHANCE) { + if (Math.random() < BURN_CHANCE) + { int burnDamage = (int) (baseDamage * 0.3); applyBurn(target, burnDamage); } this.takeDamage((int) (maxHealth * 0.05)); } - private void applyBurn(Entity target, int burnDamage) { System.out.printf(" %s catches fire and will take %d damage over time!%n", target.getName(), burnDamage * 3); @@ -75,10 +74,23 @@ public void takeDamage(int amount) { super.takeDamage(reducedDamage); System.out.println("Dragon's scales reduce damage to " + reducedDamage + "!"); } + + @Override + public String getName() { + return "Dragon"; + } + + + + @Override + public void gainExperience(int amount) { + + } + @Override public String getDescription() { return String.format( - "Ancient dragon with fiery breath (Reduces damage by 25% | Health: %d/%d)", + "Dragon with fiery breath (Reduces damage by 25% | Health: %d/%d)", health, maxHealth ); } From d89b3491dda09c717935d996ff65b9add76107d4 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 18:03:39 +0330 Subject: [PATCH 16/36] Goblin is now completed and now can dage the attack --- .../main/java/org/project/entity/enemies/Goblin.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java b/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java index c27d525..8fd6ab1 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java @@ -1,17 +1,17 @@ package org.project.entity.enemies; import org.project.entity.Entity; -import org.project.entity.enemies.Enemy; +import org.project.object.weapons.Dagger; public class Goblin extends Enemy { private static final double DODGE_CHANCE = 0.25; private static final int STEAL_AMOUNT = 5; private boolean hasStolen = false; - public Goblin(int health, int expReward) { + public Goblin(int health, int expReward, Dagger dagger) { super("Goblin", health, new Dagger(), expReward); } - + @Override public void gainExperience(int amount) { // Enemies don't gain experience @@ -25,10 +25,14 @@ public void takeDamage(int amount) { } super.takeDamage(amount); } + @Override public String getName() { return "Goblin"; } + + + @Override public void useSpecialAbility(Entity target) { if (!hasStolen) { From 8476a793e8e2cac43f7580298908df0e66c1a3ee Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 18:04:54 +0330 Subject: [PATCH 17/36] Skeleton has two lives and a RustySword to attack --- .../org/project/entity/enemies/Skeleton.java | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java b/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java index 955b7b1..3f92bd5 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java @@ -1,15 +1,16 @@ package org.project.entity.enemies; +import org.project.entity.Entity; +import org.project.object.weapons.RustySword; - -public class Skeleton extends Enemy implements Entity { +public class Skeleton extends Enemy { private boolean hasResurrected; - - public Skeleton(int health, int expReward) { + + public Skeleton(int health, int expReward, RustySword rustySword) { super("Skeleton", health, new RustySword(), expReward); this.hasResurrected = false; } - + @Override public void takeDamage(int amount) { super.takeDamage(amount); @@ -17,15 +18,32 @@ public void takeDamage(int amount) { resurrect(); } } - + + @Override + public String getDescription() { + return "A reanimated skeleton with a rusty sword. (Resurrects once)"; + } + + @Override + public String getName() { + return "Skeleton"; + } + + @Override + public void useSpecialAbility(Entity target) { + System.out.println("Sneaky Skeleton doesn't have a super power" + + " but this bastard got two lives ;) "); + } + + @Override + public void gainExperience(int amount) { +// Enemies don't gain experience + } + private void resurrect() { health = maxHealth / 2; hasResurrected = true; System.out.println("The skeleton reassembles itself!"); } - // @Override - // Void string getDescription() { - // return "A reanimated skeleton with a rusty sword. (Resurrects once)"; - // } } \ No newline at end of file From ce631a2f744fe341aeca31e70f302e5645b116f3 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 18:08:42 +0330 Subject: [PATCH 18/36] Knight now has super power and can recover his hp --- .../main/java/org/project/entity/players/Knight.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Knight.java b/Java-Ring/src/main/java/org/project/entity/players/Knight.java index a3f781f..9f4db4c 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Knight.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Knight.java @@ -6,9 +6,19 @@ public class Knight extends Player { @Override - public String getname() { + public String getName() { return this.name; } + public boolean hasKickReady() { + return kickCooldown <= 0; + } + @Override + public String getDescription() { + return String.format("%s - Lvl %d Knight (%d/%d HP) | %s", + name, level, health, maxHealth, + hasKickReady() ? "Kick Ready" : "Kick CD: " + kickCooldown); + } + private int kickCooldown; private static final int KICK_DAMAGE = 35; From 3b9d139fb21fdc6d15aa25063ad07157c49d4692 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 18:09:21 +0330 Subject: [PATCH 19/36] Updated --- Java-Ring/src/main/java/org/project/entity/players/Player.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Player.java b/Java-Ring/src/main/java/org/project/entity/players/Player.java index a1aa7cc..a6c42d4 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Player.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Player.java @@ -37,6 +37,7 @@ public Player(String name, int maxHealth, int maxMana, Weapon weapon, Armor armo this.inventory.add(new Flask()); // Starting item } + @Override public void attack(Entity target) { weapon.use(target); From 12c4c259558bb96655a6b16ce56c6173083046dd Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 18:10:17 +0330 Subject: [PATCH 20/36] Location is now updated --- .../java/org/project/location/Location.java | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/location/Location.java b/Java-Ring/src/main/java/org/project/location/Location.java index a53b86b..025367e 100644 --- a/Java-Ring/src/main/java/org/project/location/Location.java +++ b/Java-Ring/src/main/java/org/project/location/Location.java @@ -6,6 +6,9 @@ import org.project.entity.enemies.Enemy; import org.project.entity.enemies.Goblin; import org.project.entity.enemies.Skeleton; +import org.project.object.weapons.Claw; +import org.project.object.weapons.Dagger; +import org.project.object.weapons.RustySword; public class Location { @@ -26,22 +29,37 @@ public Location(String name, String description) { this.biome = biome; } - public Enemy generateEnemy() { +// public Enemy generateEnemy() { +// int scaledHealth = 50 + (dangerLevel * 20); +// int scaledExp = 30 + (dangerLevel * 10); +// int enemyType = random.nextInt(3); // 0=Goblin, 1=Skeleton, 2=Dragon +// +// return switch (enemyType) { +// case 0 -> new Goblin(scaledHealth, scaledExp, new Dagger()); +// case 1 -> new Skeleton(scaledHealth, scaledExp, new RustySword()); +// case 2 -> new Dragon(scaledHealth, scaledExp, new Claw()); +// default -> throw new IllegalStateException("Invalid enemy type"); +// }; +// } +public Enemy generateEnemy() { + try { int scaledHealth = 50 + (dangerLevel * 20); int scaledExp = 30 + (dangerLevel * 10); - - // Biome-based enemy weights - double[] weights = getBiomeWeights(); - double roll = random.nextDouble() * 100; - - if (roll < weights[0]) { - return new Goblin(scaledHealth, scaledExp); - } else if (roll < weights[0] + weights[1]) { - return new Skeleton(scaledHealth, scaledExp); - } else { - return new Dragon(scaledHealth, scaledExp); - } + int enemyType = random.nextInt(3); // 0-2 + + System.out.println("Generating enemy type: " + enemyType); // Debug + + return switch (enemyType) { + case 0 -> new Goblin(scaledHealth, scaledExp, new Dagger()); + case 1 -> new Skeleton(scaledHealth, scaledExp, new RustySword()); + case 2 -> new Dragon(scaledHealth, scaledExp, new Claw()); + default -> throw new IllegalStateException("Invalid enemy type"); + }; + } catch (Exception e) { + System.err.println("Failed to generate enemy: " + e.getMessage()); + return null; // Or create a default enemy } +} private double[] getBiomeWeights() { return switch (biome) { From e319d14aa5b8eb5b04977f075f222c0e1670281c Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 18:14:11 +0330 Subject: [PATCH 21/36] Remove unused OtherWeaopns.java --- .../project/object/weapons/OtherWeapons.java | 109 ------------------ 1 file changed, 109 deletions(-) delete mode 100644 Java-Ring/src/main/java/org/project/object/weapons/OtherWeapons.java diff --git a/Java-Ring/src/main/java/org/project/object/weapons/OtherWeapons.java b/Java-Ring/src/main/java/org/project/object/weapons/OtherWeapons.java deleted file mode 100644 index f2aa423..0000000 --- a/Java-Ring/src/main/java/org/project/object/weapons/OtherWeapons.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.project.object.weapons; - -import java.util.List; - -import org.project.entity.Entity; - -public class OtherWeapons { - // Made classes public and non-static since they're in their own file - // Each weapon is now a standalone class extending Weapon - - public static class FireSword extends Weapon { - private static final int BURN_DURATION = 3; - private static final int BURN_DAMAGE = 5; - - public FireSword() { - super("Flametongue Sword", 30, 10, 100); - } - - @Override - public int getDamage() { - return baseDamage + (int)(Math.random() * 5); // 30-34 damage - } - - @Override - public void specialAbility(List targets) { - System.out.println("Sword erupts in flames!"); - for (Entity target : targets) { - int damage = getDamage() + 15; - target.takeDamage(damage); - System.out.printf("%s takes %d fire damage!%n", target.getName(), damage); - applyBurn(target); - } - } - - private void applyBurn(Entity target) { - System.out.printf("%s catches fire for %d turns!%n", - target.getName(), BURN_DURATION); - // Implementation for burn over time - new Thread(() -> { - try { - for (int i = 0; i < BURN_DURATION && target.isAlive(); i++) { - Thread.sleep(2000); // Simulate turn delay - target.takeDamage(BURN_DAMAGE); - System.out.printf("%s takes %d burn damage!%n", - target.getName(), BURN_DAMAGE); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - }).start(); - } - } - - public static class FrostAxe extends Weapon { - private static final double FREEZE_CHANCE = 0.2; - private static final int FREEZE_DURATION = 2; - - public FrostAxe() { - super("Frostbite Axe", 35, 15, 80); - } - - @Override - public void specialAbility(List targets) { - System.out.println("Axe releases a chilling wave!"); - for (Entity target : targets) { - target.takeDamage(20); - if (Math.random() < FREEZE_CHANCE) { - System.out.println(target.getName() + " is frozen solid!"); - // Freeze would prevent target from acting for FREEZE_DURATION turns - } - } - } - } - - public static class PoisonDagger extends Weapon { - private static final int POISON_DURATION = 3; - private static final int POISON_DAMAGE = 3; - - public PoisonDagger() { - super("Venomstrike Dagger", 20, 5, 120); - } - - @Override - public void specialAbility(List targets) { - System.out.println("Dagger drips with venom!"); - for (Entity target : targets) { - applyPoison(target); - } - } - - private void applyPoison(Entity target) { - System.out.printf("%s is poisoned for %d turns!%n", - target.getName(), POISON_DURATION); - // Poison damage over time - new Thread(() -> { - try { - for (int i = 0; i < POISON_DURATION && target.isAlive(); i++) { - Thread.sleep(2000); // Simulate turn delay - target.takeDamage(POISON_DAMAGE); - System.out.printf("%s takes %d poison damage!%n", - target.getName(), POISON_DAMAGE); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - }).start(); - } - } -} \ No newline at end of file From 422c67f9692841e00e2ba4fc453134945b03077b Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:18:39 +0330 Subject: [PATCH 22/36] The main game is fully completed --- .vscode/settings.json | 3 - .../src/main/java/org/project/GameEngine.java | 136 ++++++++++++------ .../org/project/entity/players/Wizard.java | 2 + .../object/consumables/ManaPotion.java | 2 + .../org/project/object/weapons/Staff.java | 2 + 5 files changed, 96 insertions(+), 49 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 Java-Ring/src/main/java/org/project/entity/players/Wizard.java create mode 100644 Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java create mode 100644 Java-Ring/src/main/java/org/project/object/weapons/Staff.java diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 3ebdbc0..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "CodeGPT.apiKey": "CodeGPT Plus Beta" -} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/GameEngine.java b/Java-Ring/src/main/java/org/project/GameEngine.java index 26e257f..4d8b66f 100644 --- a/Java-Ring/src/main/java/org/project/GameEngine.java +++ b/Java-Ring/src/main/java/org/project/GameEngine.java @@ -1,7 +1,10 @@ package org.project; +import org.project.entity.enemies.Enemy; import org.project.entity.players.*; import org.project.location.Location; +import org.project.object.consumables.Consumable; + import java.util.Scanner; // import org.project.entity.object.consumables.Consumable; // Ensure this matches the actual package of Consumable @@ -14,12 +17,12 @@ public class GameEngine { public void startGame() { initializePlayer(); initializeLocations(); - + while (gameRunning && player.isAlive()) { displayMainMenu(); handleMainMenuInput(); } - + endGame(); } @@ -27,25 +30,25 @@ private void initializePlayer() { System.out.println("=== CHARACTER CREATION ==="); System.out.print("Enter your name: "); String name = scanner.nextLine(); - + System.out.println("Choose your class:"); System.out.println("1. Knight\n2. Wizard\n3. Assassin"); - int classChoice = scanner.nextInt(); - + + int classChoice = Integer.parseInt(scanner.nextLine()); player = switch (classChoice) { case 1 -> new Knight(name); - // case 2 -> new Wizard(name); + case 2 -> new Wizard(name); // case 3 -> new Assassin(name); default -> new Knight(name); }; - - System.out.printf("%s the %s enters the Java Ring!%n", - player.getName(), player.getClass().getSimpleName()); + + System.out.printf("%s the %s enters the Java Ring!%n", + player.getName(), player.getClass().getSimpleName()); } private void initializeLocations() { - currentLocation = new Location("Forgotten Forest", - "A dense woodland shrouded in mist"); + currentLocation = new Location("Forgotten Forest", + "A dense woodland shrouded in mist"); } private void displayMainMenu() { @@ -53,73 +56,114 @@ private void displayMainMenu() { System.out.println("Location: " + currentLocation.getName()); System.out.println("1. Explore"); System.out.println("2. Character Info"); - System.out.println("3. Inventory"); - System.out.println("4. Quit"); + System.out.println("3. Quit"); System.out.print("Choose an action: "); } private void handleMainMenuInput() { int choice = scanner.nextInt(); - + switch (choice) { case 1 -> explore(); case 2 -> displayCharacterInfo(); - case 3 -> manageInventory(); - case 4 -> gameRunning = false; + case 3 -> gameRunning = false; default -> System.out.println("Invalid choice!"); } } private void explore() { System.out.println("\nYou venture deeper into " + currentLocation.getName()); - - if (Math.random() < 0.7) { // 70% encounter chance - startCombat(currentLocation.generateEnemy()); + + if (Math.random() < 0.7) { + Enemy enemy = currentLocation.generateEnemy(); + if (enemy != null) { + System.out.println("Encountered: " + enemy.getDescription()); + startCombat(enemy); + } else { + System.out.println("The enemy mysteriously vanished..."); + } } else { - System.out.println("The path is quiet for now..."); - currentLocation.increaseDanger(); + System.out.println("The path is clear for now..."); } + currentLocation.increaseDanger(); } private void startCombat(Enemy enemy) { System.out.printf("%nA wild %s appears!%n", enemy.getName()); - + while (player.isAlive() && enemy.isAlive()) { + // Add turn counter for debugging + int turnCounter = 0; + System.out.println("\n--- Turn " + turnCounter + " ---"); playerTurn(enemy); - if (enemy.isAlive()) { - enemyTurn(enemy); - } + + if (!enemy.isAlive()) break; + + turnCounter++; + enemyTurn(enemy); } - + if (player.isAlive()) { System.out.printf("You defeated the %s!%n", enemy.getName()); player.gainExperience(enemy.getExpReward()); - currentLocation.increaseDanger(); + } else { + System.out.println("You have been defeated..."); } } private void playerTurn(Enemy enemy) { System.out.println("\n=== YOUR TURN ==="); System.out.printf("HP: %d/%d | Enemy HP: %d%n", - player.getHealth(), player.getMaxHealth(), enemy.getHealth()); - + player.getHealth(), player.getMaxHealth(), enemy.getHealth()); + System.out.println("1. Attack"); System.out.println("2. Defend"); System.out.println("3. Special Ability"); System.out.println("4. Use Item"); System.out.print("Choose action: "); - - int choice = scanner.nextInt(); - + + int choice = getValidInput(1, 4); // Using robust input method + switch (choice) { - case 1 -> player.attack(enemy); - case 2 -> player.defend(); - case 3 -> player.useSpecialAbility(enemy); + case 1 -> + { + player.attack(enemy); // Pass enemy to attack + System.out.printf("%s attacks %s!%n", + player.getName(), enemy.getName()); + } + case 2 -> + { + player.defend(); + System.out.println(player.getName() + " defends!"); + } + case 3 -> + { + if (player instanceof Knight) { ((Knight)player).useSpecialAbility(enemy); } // Pass enemy to special + else { player.useSpecialAbility(enemy); } // Generic case + + System.out.printf("%s uses special ability on %s!%n", + player.getName(), enemy.getName()); + } case 4 -> useItemInCombat(); - default -> System.out.println("Invalid choice!"); + default -> + { + System.out.println("Invalid choice! Lost your turn..."); + } } } + // Robust input handling method + private int getValidInput(int min, int max) { + while (true) { + try { + int choice = Integer.parseInt(scanner.nextLine()); + if (choice >= min && choice <= max) return choice; + System.out.printf("Enter %d-%d: ", min, max); + } catch (NumberFormatException e) { + System.out.print("(Numbers only) "); + } + } + } private void enemyTurn(Enemy enemy) { System.out.printf("%n=== %s's TURN ===%n", enemy.getName()); enemy.attack(player); @@ -130,17 +174,17 @@ private void useItemInCombat() { System.out.println("Your inventory is empty!"); return; } - + System.out.println("\nAvailable items:"); for (int i = 0; i < player.getInventory().size(); i++) { Consumable item = player.getInventory().get(i); System.out.printf("%d. %s (%d uses)%n", - i + 1, item.getName(), item.getRemainingUses()); + i + 1, ((Consumable) item).getName(), item.getRemainingUses()); } - + System.out.print("Select item (0 to cancel): "); int choice = scanner.nextInt() - 1; - + if (choice >= 0 && choice < player.getInventory().size()) { player.useItem(choice); } @@ -152,16 +196,16 @@ private void displayCharacterInfo() { System.out.printf("Class: %s%n", player.getClass().getSimpleName()); System.out.printf("Level: %d%n", player.getLevel()); System.out.printf("HP: %d/%d%n", player.getHealth(), player.getMaxHealth()); - System.out.printf("XP: %d/%d%n", - player.getExperience(), player.getLevel() * 100); + System.out.printf("XP: %d/%d%n", + player.getExperience(), player.getLevel() * 100); System.out.printf("Weapon: %s%n", player.getWeapon().getDescription()); System.out.printf("Armor: %s%n", player.getArmor().getDescription()); } - private void manageInventory() { - // Similar to combat item menu but with repair options - // Implementation omitted for brevity - } + + + + private void endGame() { if (player.isAlive()) { diff --git a/Java-Ring/src/main/java/org/project/entity/players/Wizard.java b/Java-Ring/src/main/java/org/project/entity/players/Wizard.java new file mode 100644 index 0000000..43242f3 --- /dev/null +++ b/Java-Ring/src/main/java/org/project/entity/players/Wizard.java @@ -0,0 +1,2 @@ +package org.project.entity.players;public class Wizard { +} diff --git a/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java b/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java new file mode 100644 index 0000000..e1b414a --- /dev/null +++ b/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java @@ -0,0 +1,2 @@ +package org.project.object.consumables;public class ManaPotion { +} diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Staff.java b/Java-Ring/src/main/java/org/project/object/weapons/Staff.java new file mode 100644 index 0000000..1fe9b4b --- /dev/null +++ b/Java-Ring/src/main/java/org/project/object/weapons/Staff.java @@ -0,0 +1,2 @@ +package org.project.object.weapons;public class Staff { +} From 15f50a07bb30da3d97b8a32b7b5448b5b853d8e8 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:21:03 +0330 Subject: [PATCH 23/36] It's ability for Goblin --- .../org/project/object/weapons/Dagger.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Java-Ring/src/main/java/org/project/object/weapons/Dagger.java diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Dagger.java b/Java-Ring/src/main/java/org/project/object/weapons/Dagger.java new file mode 100644 index 0000000..2ec6fa2 --- /dev/null +++ b/Java-Ring/src/main/java/org/project/object/weapons/Dagger.java @@ -0,0 +1,42 @@ +package org.project.object.weapons; + +import org.project.entity.Entity; +import java.util.List; + +public class Dagger extends Weapon { + private static final int BASE_DAMAGE = 15; + private static final int CRIT_CHANCE = 25; // 25% crit chance + private static final int CRIT_MULTIPLIER = 2; + + public Dagger() { + super("Rusty Dagger", BASE_DAMAGE, 5, 50); // name, damage, manaCost, durability + } + + @Override + public int getDamage() { + // 25% chance to crit for double damage + return (Math.random() * 100 < CRIT_CHANCE) ? + BASE_DAMAGE * CRIT_MULTIPLIER : + BASE_DAMAGE; + } + + @Override + public void specialAbility(List targets) { + if (targets.isEmpty()) return; + + Entity primaryTarget = targets.get(0); + int damage = getDamage() + 5; // Backstab bonus + + System.out.printf("Goblin backstabs %s for %d damage!%n", + primaryTarget.getName(), damage); + primaryTarget.takeDamage(damage); + } + + @Override + public String getDescription() { + return String.format( + "%s (Damage: %d, Crit: %d%%, Durability: %d/%d)", + name, BASE_DAMAGE, CRIT_CHANCE, durability, maxDurability + ); + } +} \ No newline at end of file From c6307f8805f0587acf3ecf8e70f000cb26d403bf Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:21:53 +0330 Subject: [PATCH 24/36] It's a special ability for Skeleton --- .../project/object/weapons/RustySword.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Java-Ring/src/main/java/org/project/object/weapons/RustySword.java diff --git a/Java-Ring/src/main/java/org/project/object/weapons/RustySword.java b/Java-Ring/src/main/java/org/project/object/weapons/RustySword.java new file mode 100644 index 0000000..74f4b60 --- /dev/null +++ b/Java-Ring/src/main/java/org/project/object/weapons/RustySword.java @@ -0,0 +1,49 @@ +package org.project.object.weapons; + +import org.project.entity.Entity; +import java.util.List; + +public class RustySword extends Weapon { + private static final int BASE_DAMAGE = 18; + private static final double RUST_CHANCE = 0.3; // 30% chance to apply rust effect + private static final int RUST_DAMAGE_PENALTY = 2; // Reduces target's damage + + public RustySword() { + super("Rusty Sword", BASE_DAMAGE, 8, 40); // name, damage, manaCost, durability + } + + @Override + public int getDamage() { + // 5% chance to break on hit + if (Math.random() < 0.05) { + durability -= 5; + } + return BASE_DAMAGE; + } + + @Override + public void specialAbility(List targets) { + if (targets.isEmpty()) return; + + Entity target = targets.get(0); + if (Math.random() < RUST_CHANCE) { + System.out.printf("%s's rust infects %s, reducing their damage output!%n", + name, target.getName()); + // Implementation would reduce target's damage by RUST_DAMAGE_PENALTY + } + } + + @Override + public String getDescription() { + return String.format( + "%s (Damage: %d, Rust: %.0f%%, Durability: %d/%d)", + name, BASE_DAMAGE, RUST_CHANCE * 100, durability, maxDurability + ); + } + + // Unique rust effect application + public void applyRust(Entity target) { + // Implementation would track damage reduction on target + System.out.println("Rust spreads, weakening " + target.getName()); + } +} \ No newline at end of file From 786f1eb75cc7d230675b61ea5c6bb55bd5c82aaa Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:26:45 +0330 Subject: [PATCH 25/36] Add Staff weapon for Wizard --- .../org/project/object/weapons/Staff.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Staff.java b/Java-Ring/src/main/java/org/project/object/weapons/Staff.java index 1fe9b4b..9dbe987 100644 --- a/Java-Ring/src/main/java/org/project/object/weapons/Staff.java +++ b/Java-Ring/src/main/java/org/project/object/weapons/Staff.java @@ -1,2 +1,21 @@ -package org.project.object.weapons;public class Staff { -} +package org.project.object.weapons; + +import org.project.entity.Entity; + +import java.util.List; + +public class Staff extends Weapon { + public Staff() { + super("Wizard's Staff", 12, 0, 60); // Low physical damage, no mana cost + } + + @Override + public void specialAbility(List targets) { + + } + + @Override + public String getDescription() { + return name + " (Damage: " + baseDamage + ", +5 mana regen when equipped)"; + } +} \ No newline at end of file From 8d99890936bafb1c866267cf07f4ac84137477e8 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:28:08 +0330 Subject: [PATCH 26/36] Add ManaPotion consumable --- .../object/consumables/ManaPotion.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java b/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java index e1b414a..5af722a 100644 --- a/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java +++ b/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java @@ -1,2 +1,22 @@ -package org.project.object.consumables;public class ManaPotion { -} +package org.project.object.consumables; + +import org.project.entity.Entity; +import org.project.object.consumables.Consumable; + +public class ManaPotion extends Consumable { + private static final int MANA_RESTORE = 40; + + public ManaPotion() { + super("Mana Potion", "Restores 40 MP", 75, 2); + } + + @Override + public void use(Entity target) { + if (getRemainingUses() > 0) { + target.healMana(MANA_RESTORE); + consumeUse(); + System.out.printf("%s restored %d MP! (%d uses remain)%n", + target.getName(), MANA_RESTORE, getRemainingUses()); + } + } +} \ No newline at end of file From cf8d4f8089c2b34fbe35027cf3ad75e084811e73 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:30:23 +0330 Subject: [PATCH 27/36] Add ManaPotion consumable --- .../java/org/project/location/Location.java | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/location/Location.java b/Java-Ring/src/main/java/org/project/location/Location.java index 025367e..fed80b6 100644 --- a/Java-Ring/src/main/java/org/project/location/Location.java +++ b/Java-Ring/src/main/java/org/project/location/Location.java @@ -29,7 +29,7 @@ public Location(String name, String description) { this.biome = biome; } -// public Enemy generateEnemy() { + // public Enemy generateEnemy() { // int scaledHealth = 50 + (dangerLevel * 20); // int scaledExp = 30 + (dangerLevel * 10); // int enemyType = random.nextInt(3); // 0=Goblin, 1=Skeleton, 2=Dragon @@ -41,25 +41,25 @@ public Location(String name, String description) { // default -> throw new IllegalStateException("Invalid enemy type"); // }; // } -public Enemy generateEnemy() { - try { - int scaledHealth = 50 + (dangerLevel * 20); - int scaledExp = 30 + (dangerLevel * 10); - int enemyType = random.nextInt(3); // 0-2 - - System.out.println("Generating enemy type: " + enemyType); // Debug - - return switch (enemyType) { - case 0 -> new Goblin(scaledHealth, scaledExp, new Dagger()); - case 1 -> new Skeleton(scaledHealth, scaledExp, new RustySword()); - case 2 -> new Dragon(scaledHealth, scaledExp, new Claw()); - default -> throw new IllegalStateException("Invalid enemy type"); - }; - } catch (Exception e) { - System.err.println("Failed to generate enemy: " + e.getMessage()); - return null; // Or create a default enemy + public Enemy generateEnemy() { + try { + int scaledHealth = 50 + (dangerLevel * 20); + int scaledExp = 30 + (dangerLevel * 10); + int enemyType = random.nextInt(3); // 0-2 + + System.out.println("Generating enemy type: " + enemyType); // Debug + + return switch (enemyType) { + case 0 -> new Goblin(scaledHealth, scaledExp, new Dagger()); + case 1 -> new Skeleton(scaledHealth, scaledExp, new RustySword()); + case 2 -> new Dragon(scaledHealth, scaledExp, new Claw()); + default -> throw new IllegalStateException("Invalid enemy type"); + }; + } catch (Exception e) { + System.err.println("Failed to generate enemy: " + e.getMessage()); + return null; // Or create a default enemy + } } -} private double[] getBiomeWeights() { return switch (biome) { From e78d11fc502383b457a5d09d14592d66f713ddbd Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:35:08 +0330 Subject: [PATCH 28/36] Wizard is character that player can choose to play --- .../org/project/entity/players/Wizard.java | 153 +++++++++++++++++- 1 file changed, 151 insertions(+), 2 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Wizard.java b/Java-Ring/src/main/java/org/project/entity/players/Wizard.java index 43242f3..5d2bb70 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Wizard.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Wizard.java @@ -1,2 +1,151 @@ -package org.project.entity.players;public class Wizard { -} +package org.project.entity.players; + +import org.project.entity.Entity; +import org.project.object.armors.Armor; +import org.project.object.consumables.ManaPotion; +import org.project.object.weapons.Staff; + +public class Wizard extends Player { + private int manaRegenRate; + private static final int BASE_MANA_REGEN = 5; + private static final int FIREBALL_COST = 20; + private static final int FIREBALL_DAMAGE = 40; + + public Wizard(String name) { + super(name, 120, 100, new Staff(), new RobeArmor()); + this.manaRegenRate = BASE_MANA_REGEN; + this.inventory.add(new ManaPotion()); // Starting mana potion + } + + @Override + public void use(Entity target) { + if (target == null) { + System.out.println(name + " waves their staff but nothing happens!"); + return; + } + + // Check if using a mana potion when mana is low + if (mana < maxMana * 0.3 && hasManaPotion()) { + useManaPotion(); + return; + } + + // Default spell casting behavior + if (mana >= FIREBALL_COST) { + castFireball(target); + } else if (mana >= 10) { + castMagicMissile(target); + } else { + System.out.println(name + " is too exhausted to cast spells!"); + basicStaffAttack(target); + } + } + + @Override + public void useSpecialAbility(Entity target) { + if (mana >= FIREBALL_COST) { + castFireball(target); + } else { + System.out.printf("%s doesn't have enough mana! (Need %d, has %d)%n", + name, FIREBALL_COST, mana); + } + } + + @Override + public void attack(Entity target) { + if (Math.random() < 0.3 && mana >= 10) { // 30% chance to use magic missile + castMagicMissile(target); + } else { + basicStaffAttack(target); + } + regenerateMana(); + } + + private void castFireball(Entity target) { + System.out.printf("%s hurls a massive Fireball at %s! (%d damage)%n", + name, target.getName(), FIREBALL_DAMAGE); + target.takeDamage(FIREBALL_DAMAGE); + mana -= FIREBALL_COST; + + // 20% chance to apply burn effect + if (Math.random() < 0.2) { + applyBurnEffect(target, FIREBALL_DAMAGE / 4); + } + } + + private void castMagicMissile(Entity target) { + int damage = 15 + (int)(Math.random() * 10); + System.out.printf("%s shoots Magic Missiles at %s! (%d damage)%n", + name, target.getName(), damage); + target.takeDamage(damage); + mana -= 10; + } + + private void basicStaffAttack(Entity target) { + System.out.printf("%s bonks %s with their staff!%n", name, target.getName()); + super.attack(target); // Uses the default weapon attack + } + + private void regenerateMana() { + mana = Math.min(maxMana, mana + manaRegenRate); + } + + private boolean hasManaPotion() { + return inventory.stream() + .anyMatch(item -> item instanceof ManaPotion && item.getRemainingUses() > 0); + } + + private void useManaPotion() { + inventory.stream() + .filter(item -> item instanceof ManaPotion) + .findFirst() + .ifPresent(potion -> { + System.out.println(name + " quickly drinks a mana potion!"); + potion.use(this); + }); + } + + private void applyBurnEffect(Entity target, int burnDamage) { + System.out.printf("%s catches fire! (%d burn damage over 3 turns)%n", + target.getName(), burnDamage * 3); + + // Simple turn-based burn effect + new Thread(() -> { + try { + for (int i = 0; i < 3 && target.isAlive(); i++) { + Thread.sleep(1500); // Simulate turn delay + target.takeDamage(burnDamage); + System.out.println(target.getName() + " takes " + burnDamage + " burn damage!"); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }).start(); + } + + @Override + public String getDescription() { + return String.format("%s - Lvl %d Wizard (%d/%d HP, %d/%d MP)", + name, level, health, maxHealth, mana, maxMana); + } + + // Wizard-specific armor + private static class RobeArmor extends Armor { + public RobeArmor() { + super("Wizard's Robe", 10, 80); + } + + @Override + public int protect(int incomingDamage) { + // Robes reduce magic damage more than physical + int reducedDamage = (int)(incomingDamage * 0.8); // 20% reduction + durability -= 1; // Robes degrade slower + return reducedDamage; + } + + @Override + public void use(Entity target) { + + } + } +} \ No newline at end of file From ba521319fbf8977ac25810a7ef1a1347d9d72654 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:36:22 +0330 Subject: [PATCH 29/36] modified for using manapotion --- .../java/org/project/entity/players/Player.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Player.java b/Java-Ring/src/main/java/org/project/entity/players/Player.java index a6c42d4..d1a68e3 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Player.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Player.java @@ -14,13 +14,13 @@ public abstract class Player implements Entity { protected final String name; protected int health; protected int maxHealth; - protected int mana; - protected int maxMana; + protected static int mana; + protected static int maxMana; protected Weapon weapon; protected Armor armor; protected int level; protected int experience; - protected List inventory; + protected static List inventory; protected boolean defending; public Player(String name, int maxHealth, int maxMana, Weapon weapon, Armor armor) { @@ -35,9 +35,13 @@ public Player(String name, int maxHealth, int maxMana, Weapon weapon, Armor armo this.experience = 0; this.inventory = new ArrayList<>(); this.inventory.add(new Flask()); // Starting item + this.maxMana = maxMana; + this.mana = maxMana; } + public abstract void use(Entity target); + @Override public void attack(Entity target) { weapon.use(target); @@ -152,4 +156,10 @@ public boolean isAlive() { public boolean isDefending() { return defending; } + + @Override + public void healMana(int amount) { + mana = Math.min(maxMana, mana + amount); + System.out.println(name + " recovered " + amount + " MP!"); + } } From 294f639584c65ecb5906ee7ce0bab1b61173192f Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:36:42 +0330 Subject: [PATCH 30/36] modified for using manapotion --- .../src/main/java/org/project/entity/players/Knight.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Java-Ring/src/main/java/org/project/entity/players/Knight.java b/Java-Ring/src/main/java/org/project/entity/players/Knight.java index 9f4db4c..7c85423 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Knight.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Knight.java @@ -45,6 +45,11 @@ public void reduceCooldowns() { if (kickCooldown > 0) kickCooldown--; } + @Override + public void use(Entity target) { + + } + @Override public void attack(Entity target) { super.attack(target); From ff15435946dda3ce2bc6968ed914f7a874778081 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:38:09 +0330 Subject: [PATCH 31/36] it is completed --- .../java/org/project/entity/enemies/Dragon.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java b/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java index d8dd4ee..cd7ede4 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java @@ -87,6 +87,21 @@ public void gainExperience(int amount) { } + @Override + public void healMana(int amount) { + + } + + @Override + public int getMana() { + return super.getMana(); + } + + @Override + public int getMaxMana() { + return super.getMaxMana(); + } + @Override public String getDescription() { return String.format( From 8cd9c3099ff806f84aec720c6c4072e4060e46c4 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:38:51 +0330 Subject: [PATCH 32/36] completed --- .../java/org/project/entity/enemies/Goblin.java | 15 +++++++++++++++ .../java/org/project/entity/enemies/Skeleton.java | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java b/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java index 8fd6ab1..ae907b9 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Goblin.java @@ -17,6 +17,21 @@ public void gainExperience(int amount) { // Enemies don't gain experience } + @Override + public boolean isDefending() { + return super.isDefending(); + } + + @Override + public void healMana(int amount) { + + } + + @Override + public int getMana() { + return super.getMana(); + } + @Override public void takeDamage(int amount) { if (Math.random() < DODGE_CHANCE) { diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java b/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java index 3f92bd5..58da3d0 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Skeleton.java @@ -40,6 +40,21 @@ public void gainExperience(int amount) { // Enemies don't gain experience } + @Override + public boolean isDefending() { + return super.isDefending(); + } + + @Override + public void healMana(int amount) { + + } + + @Override + public int getMana() { + return super.getMana(); + } + private void resurrect() { health = maxHealth / 2; hasResurrected = true; From 344c1e0a27d96b1121f48ec4613e9c5ed3472b30 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Sun, 13 Apr 2025 22:39:49 +0330 Subject: [PATCH 33/36] Modified for Manapotion --- Java-Ring/src/main/java/org/project/entity/Entity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Java-Ring/src/main/java/org/project/entity/Entity.java b/Java-Ring/src/main/java/org/project/entity/Entity.java index e17256d..3ce5f25 100644 --- a/Java-Ring/src/main/java/org/project/entity/Entity.java +++ b/Java-Ring/src/main/java/org/project/entity/Entity.java @@ -24,7 +24,9 @@ public interface Entity { // Resource management void gainExperience(int amount); default boolean isDefending() { return false; } - + void healMana(int amount); + default int getMana() { return 0; } + default int getMaxMana() { return 0; } String getDescription(); From 07764cf2ae390e6195c1ea0e4aaa941acd9f481f Mon Sep 17 00:00:00 2001 From: Ahmadreza Jafari Date: Tue, 15 Apr 2025 21:20:09 +0330 Subject: [PATCH 34/36] Update README.md --- README.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/README.md b/README.md index aef5f82..fece5b3 100644 --- a/README.md +++ b/README.md @@ -131,20 +131,12 @@ Want to **earn extra points**? Try implementing one of these: โœ… **Multiple Weapons System** โš”๏ธ *(Extra Score!)* - Players and monsters can **switch between different weapons** during combat instead of being limited to one. -โœ… **Multiple Players Mode** ๐Ÿ‘ฅ *(Extra Score!)* -- Implement a **party-based battle system** where **multiple players** can fight against **monsters together**. - โœ… **Dragonโ€™s Multi-Target Attack** ๐Ÿ‰ *(Extra Score!)* - If there are **multiple players in the battle**, the **dragonโ€™s unique ability** should **damage all players simultaneously** instead of just one. -โœ… **(Bonus) Inventory System** -- Allow players to **pick up and use items** like different classes of shields and more potions. - -โœ… **(Bonus) Experience & Leveling System** +โœ… Experience & Leveling System** - Players gain XP from battles and level up, increasing their **attack power**. -โœ… **(Bonus) PvP Mode** -- Implement a **Player vs. Player** combat system. By implementing any of these extra features, you can earn additional points to boost your final score! ๐Ÿš€ From 6e7ad724be2ac3c675d054d7fc265691caa86021 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Tue, 15 Apr 2025 21:26:02 +0330 Subject: [PATCH 35/36] Comments are added --- .../src/main/java/org/project/GameEngine.java | 172 +++++++++++------- 1 file changed, 111 insertions(+), 61 deletions(-) diff --git a/Java-Ring/src/main/java/org/project/GameEngine.java b/Java-Ring/src/main/java/org/project/GameEngine.java index 4d8b66f..1662405 100644 --- a/Java-Ring/src/main/java/org/project/GameEngine.java +++ b/Java-Ring/src/main/java/org/project/GameEngine.java @@ -4,155 +4,191 @@ import org.project.entity.players.*; import org.project.location.Location; import org.project.object.consumables.Consumable; - import java.util.Scanner; -// import org.project.entity.object.consumables.Consumable; // Ensure this matches the actual package of Consumable +/** + * Main game engine class that controls the game flow and manages player interactions. + * Handles initialization, game loop, combat, and menu systems. + */ public class GameEngine { - private Player player; - private Location currentLocation; - private Scanner scanner = new Scanner(System.in); - private boolean gameRunning = true; - + // Game state variables + private Player player; // Current player character + private Location currentLocation; // Active game location + private Scanner scanner = new Scanner(System.in); // Input handler + private boolean gameRunning = true; // Main game loop flag + + /** + * Starts the main game loop and manages the game lifecycle + */ public void startGame() { - initializePlayer(); - initializeLocations(); + initializePlayer(); // Set up player character + initializeLocations(); // Initialize game world + // Main game loop - runs while game is active and player is alive while (gameRunning && player.isAlive()) { - displayMainMenu(); - handleMainMenuInput(); + displayMainMenu(); // Show player options + handleMainMenuInput(); // Process player choice } - endGame(); + endGame(); // Handle game conclusion } + /** + * Initializes player character with name and class selection + */ private void initializePlayer() { System.out.println("=== CHARACTER CREATION ==="); System.out.print("Enter your name: "); String name = scanner.nextLine(); + // Class selection menu System.out.println("Choose your class:"); System.out.println("1. Knight\n2. Wizard\n3. Assassin"); int classChoice = Integer.parseInt(scanner.nextLine()); + + // Create player based on class choice player = switch (classChoice) { - case 1 -> new Knight(name); - case 2 -> new Wizard(name); - // case 3 -> new Assassin(name); - default -> new Knight(name); + case 1 -> new Knight(name); // Tank class + case 2 -> new Wizard(name); // Mage class + default -> new Knight(name); // Default to Knight }; System.out.printf("%s the %s enters the Java Ring!%n", player.getName(), player.getClass().getSimpleName()); } + /** + * Initializes game locations and starting area + */ private void initializeLocations() { + // Create starting location with description currentLocation = new Location("Forgotten Forest", "A dense woodland shrouded in mist"); } + /** + * Displays the main game menu options + */ private void displayMainMenu() { System.out.println("\n=== MAIN MENU ==="); System.out.println("Location: " + currentLocation.getName()); - System.out.println("1. Explore"); - System.out.println("2. Character Info"); - System.out.println("3. Quit"); + System.out.println("1. Explore"); // Risk encounter + System.out.println("2. Character Info"); // View stats + System.out.println("3. Quit"); // Exit game System.out.print("Choose an action: "); } + /** + * Handles player input from main menu + */ private void handleMainMenuInput() { - int choice = scanner.nextInt(); + int choice = getValidInput(1, 3); // Get validated input switch (choice) { - case 1 -> explore(); - case 2 -> displayCharacterInfo(); - case 3 -> gameRunning = false; + case 1 -> explore(); // Enter exploration + case 2 -> displayCharacterInfo(); // Show character sheet + case 3 -> gameRunning = false; // Quit game default -> System.out.println("Invalid choice!"); } } + /** + * Handles exploration logic and random encounters + */ private void explore() { System.out.println("\nYou venture deeper into " + currentLocation.getName()); + // 70% chance of enemy encounter if (Math.random() < 0.7) { Enemy enemy = currentLocation.generateEnemy(); if (enemy != null) { System.out.println("Encountered: " + enemy.getDescription()); - startCombat(enemy); + startCombat(enemy); // Begin combat if enemy exists } else { System.out.println("The enemy mysteriously vanished..."); } } else { System.out.println("The path is clear for now..."); } - currentLocation.increaseDanger(); + currentLocation.increaseDanger(); // Scale difficulty } + /** + * Manages combat between player and enemy + * @param enemy The enemy to fight + */ private void startCombat(Enemy enemy) { System.out.printf("%nA wild %s appears!%n", enemy.getName()); + // Combat continues until one combatant is defeated while (player.isAlive() && enemy.isAlive()) { - // Add turn counter for debugging - int turnCounter = 0; - System.out.println("\n--- Turn " + turnCounter + " ---"); - playerTurn(enemy); + playerTurn(enemy); // Player action phase - if (!enemy.isAlive()) break; + if (!enemy.isAlive()) break; // Check if enemy defeated - turnCounter++; - enemyTurn(enemy); + enemyTurn(enemy); // Enemy action phase } + // Combat resolution if (player.isAlive()) { System.out.printf("You defeated the %s!%n", enemy.getName()); - player.gainExperience(enemy.getExpReward()); + player.gainExperience(enemy.getExpReward()); // Award XP } else { System.out.println("You have been defeated..."); } } + /** + * Handles player's turn during combat + * @param enemy The current combat target + */ private void playerTurn(Enemy enemy) { System.out.println("\n=== YOUR TURN ==="); + // Display combat status System.out.printf("HP: %d/%d | Enemy HP: %d%n", player.getHealth(), player.getMaxHealth(), enemy.getHealth()); + // Combat action menu System.out.println("1. Attack"); System.out.println("2. Defend"); System.out.println("3. Special Ability"); System.out.println("4. Use Item"); System.out.print("Choose action: "); - int choice = getValidInput(1, 4); // Using robust input method + int choice = getValidInput(1, 4); // Validate input + // Process player choice switch (choice) { - case 1 -> - { - player.attack(enemy); // Pass enemy to attack + case 1 -> { // Standard attack + player.attack(enemy); System.out.printf("%s attacks %s!%n", player.getName(), enemy.getName()); } - case 2 -> - { + case 2 -> { // Defensive stance player.defend(); System.out.println(player.getName() + " defends!"); } - case 3 -> - { - if (player instanceof Knight) { ((Knight)player).useSpecialAbility(enemy); } // Pass enemy to special - else { player.useSpecialAbility(enemy); } // Generic case - + case 3 -> { // Class-specific ability + if (player instanceof Knight) { + ((Knight)player).useSpecialAbility(enemy); + } else { + player.useSpecialAbility(enemy); + } System.out.printf("%s uses special ability on %s!%n", player.getName(), enemy.getName()); } - case 4 -> useItemInCombat(); - default -> - { - System.out.println("Invalid choice! Lost your turn..."); - } + case 4 -> useItemInCombat(); // Inventory usage + default -> System.out.println("Invalid choice! Lost your turn..."); } } - // Robust input handling method + /** + * Validates player input within a specified range + * @param min Minimum valid value + * @param max Maximum valid value + * @return Validated user input + */ private int getValidInput(int min, int max) { while (true) { try { @@ -164,32 +200,44 @@ private int getValidInput(int min, int max) { } } } + + /** + * Handles enemy's turn during combat + * @param enemy The attacking enemy + */ private void enemyTurn(Enemy enemy) { System.out.printf("%n=== %s's TURN ===%n", enemy.getName()); - enemy.attack(player); + enemy.attack(player); // Enemy performs attack } + /** + * Manages item usage during combat + */ private void useItemInCombat() { if (player.getInventory().isEmpty()) { System.out.println("Your inventory is empty!"); return; } + // Display inventory System.out.println("\nAvailable items:"); for (int i = 0; i < player.getInventory().size(); i++) { Consumable item = player.getInventory().get(i); System.out.printf("%d. %s (%d uses)%n", - i + 1, ((Consumable) item).getName(), item.getRemainingUses()); + i + 1, item.getName(), item.getRemainingUses()); } System.out.print("Select item (0 to cancel): "); - int choice = scanner.nextInt() - 1; + int choice = getValidInput(0, player.getInventory().size()) - 1; - if (choice >= 0 && choice < player.getInventory().size()) { - player.useItem(choice); + if (choice >= 0) { + player.useItem(choice); // Use selected item } } + /** + * Displays character statistics and equipment + */ private void displayCharacterInfo() { System.out.println("\n=== CHARACTER SHEET ==="); System.out.printf("Name: %s%n", player.getName()); @@ -202,11 +250,9 @@ private void displayCharacterInfo() { System.out.printf("Armor: %s%n", player.getArmor().getDescription()); } - - - - - + /** + * Handles game conclusion with appropriate message + */ private void endGame() { if (player.isAlive()) { System.out.println("You leave the Java Ring... for now."); @@ -215,7 +261,11 @@ private void endGame() { } } + /** + * Entry point for the game + * @param args Command line arguments (unused) + */ public static void main(String[] args) { - new GameEngine().startGame(); + new GameEngine().startGame(); // Launch game } } \ No newline at end of file From 8b047c31e35f353e0dc0b69a779754a510ef06b7 Mon Sep 17 00:00:00 2001 From: MRL0R3 Date: Tue, 15 Apr 2025 22:20:38 +0330 Subject: [PATCH 36/36] --- .idea/gradle.xml | 5 +- Java-Ring/.idea/.name | 2 +- Java-Ring/.idea/gradle.xml | 4 +- Java-Ring/.idea/misc.xml | 2 +- .../org/project/entity/enemies/Dragon.java | 96 ++++++++---- .../org/project/entity/enemies/Enemy.java | 81 ++++++++-- .../org/project/entity/players/Knight.java | 97 ++++++++---- .../org/project/entity/players/Player.java | 138 +++++++++++++----- .../java/org/project/location/Location.java | 117 +++++++++------ .../java/org/project/object/armors/Armor.java | 2 +- .../object/consumables/ManaPotion.java | 1 - .../org/project/object/weapons/Weapon.java | 80 ++++++++-- 12 files changed, 458 insertions(+), 167 deletions(-) diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 7c34d9c..dc9f2b1 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,11 +1,14 @@ + \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java b/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java index cd7ede4..4906f07 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Dragon.java @@ -3,61 +3,99 @@ import org.project.entity.Entity; import org.project.object.weapons.Claw; +/** + * Dragon enemy class - A powerful fire-breathing creature with damage reduction. + * Special abilities include fire breath attacks and burn damage over time. + */ public class Dragon extends Enemy { - - private boolean usedFireBreath; - private static final int FIRE_BREATH_COOLDOWN = 3; - private int fireBreathCooldown = 0; - private static final double BURN_CHANCE = 0.3; - + // Combat state tracking + private boolean usedFireBreath; // Flag for emergency fire breath + private static final int FIRE_BREATH_COOLDOWN = 3; // Turns between fire breaths + private int fireBreathCooldown = 0; // Current cooldown counter + private static final double BURN_CHANCE = 0.3; // 30% chance to apply burn + + /** + * Constructs a new Dragon enemy + * @param health Initial health points + * @param expReward Experience granted when defeated + * @param claw Natural weapon (Claw) for basic attacks + */ public Dragon(int health, int expReward, Claw claw) { super("Dragon", health, new Claw(), expReward); this.usedFireBreath = false; } - + /** + * Dragon's attack logic with fire breath conditions + * @param target The entity being attacked + */ @Override public void attack(Entity target) { + // Emergency fire breath when below 50% health (once per combat) if (!usedFireBreath && health < maxHealth / 2) { useSpecialAbility(target); usedFireBreath = true; - } else if (fireBreathCooldown <= 0 && Math.random() < 0.25) { + } + // Random fire breath (25% chance when off cooldown) + else if (fireBreathCooldown <= 0 && Math.random() < 0.25) { useSpecialAbility(target); fireBreathCooldown = FIRE_BREATH_COOLDOWN; - } else { + } + // Standard claw attack + else { super.attack(target); + // Reduce cooldown if active if (fireBreathCooldown > 0) { fireBreathCooldown--; } } } - -@Override - public void useSpecialAbility(Entity target) { // fire breath + /** + * Dragon's special ability - Fire Breath + * Deals heavy damage with chance to apply burn effect + * @param target The entity being targeted + */ + @Override + public void useSpecialAbility(Entity target) { System.out.println("Dragon rears back and unleashes a torrent of flames!"); + + // Calculate base damage (2.5x weapon damage) int baseDamage = (int) (weapon.getDamage() * 2.5); + + // Halve damage if target is defending int actualDamage = target.isDefending() ? baseDamage / 2 : baseDamage; + // Apply damage target.takeDamage(actualDamage); System.out.printf("%s takes %d fire damage!%n", target.getName(), actualDamage); - if (Math.random() < BURN_CHANCE) - { + // 30% chance to apply burn effect + if (Math.random() < BURN_CHANCE) { int burnDamage = (int) (baseDamage * 0.3); applyBurn(target, burnDamage); } + + // Dragon takes 5% max health as self-damage (exhaustion) this.takeDamage((int) (maxHealth * 0.05)); } + + /** + * Applies burn damage over time (3 turns) + * @param target The burning entity + * @param burnDamage Damage per turn + */ private void applyBurn(Entity target, int burnDamage) { System.out.printf(" %s catches fire and will take %d damage over time!%n", target.getName(), burnDamage * 3); System.out.println(target.getName() + " is burning!"); + + // Burn effect in separate thread (non-blocking) new Thread(() -> { try { - // Burn over 3 turns + // Damage over 3 turns for (int i = 0; i < 3 && target.isAlive(); i++) { - Thread.sleep(2000); // Simulate turn delay + Thread.sleep(2000); // 2 second delay between ticks target.takeDamage(burnDamage); System.out.println(target.getName() + " takes " + burnDamage + " burn damage!"); } @@ -67,46 +105,54 @@ private void applyBurn(Entity target, int burnDamage) { }).start(); } + /** + * Dragon takes reduced damage due to thick scales + * @param amount Incoming damage amount + */ @Override public void takeDamage(int amount) { - // Dragons take reduced damage from non-magical attacks + // 25% damage reduction int reducedDamage = (int) (amount * 0.75); super.takeDamage(reducedDamage); System.out.println("Dragon's scales reduce damage to " + reducedDamage + "!"); } + // --- Inherited Method Implementations --- + @Override public String getName() { return "Dragon"; } - - @Override public void gainExperience(int amount) { - + // Dragons don't gain experience } @Override public void healMana(int amount) { - + // Dragons don't use mana } @Override public int getMana() { - return super.getMana(); + return 0; // Dragons have no mana pool } @Override public int getMaxMana() { - return super.getMaxMana(); + return 0; // Dragons have no mana pool } + /** + * Provides formatted description with current status + * @return String describing dragon and its health + */ @Override public String getDescription() { return String.format( - "Dragon with fiery breath (Reduces damage by 25% | Health: %d/%d)", - health, maxHealth + "Dragon with fiery breath (Reduces damage by 25% | Health: %d/%d)", + health, maxHealth ); } } \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/entity/enemies/Enemy.java b/Java-Ring/src/main/java/org/project/entity/enemies/Enemy.java index 07abd41..1c92d96 100644 --- a/Java-Ring/src/main/java/org/project/entity/enemies/Enemy.java +++ b/Java-Ring/src/main/java/org/project/entity/enemies/Enemy.java @@ -3,28 +3,51 @@ import org.project.entity.Entity; import org.project.object.weapons.Weapon; +/** + * Abstract base class for all enemy entities in the game. + * Provides common functionality and attributes shared by all enemies. + */ public abstract class Enemy implements Entity { - protected final String name; - protected int health; - protected int maxHealth; - protected Weapon weapon; - protected int expReward; + // Core enemy attributes + protected final String name; // Enemy's display name + protected int health; // Current health points + protected int maxHealth; // Maximum health capacity + protected Weapon weapon; // Equipped weapon + protected int expReward; // Experience granted when defeated + /** + * Constructs a new Enemy instance. + * + * @param name The name of the enemy + * @param health Initial/maximum health points + * @param weapon The weapon this enemy uses + * @param expReward Experience points awarded when defeated + */ public Enemy(String name, int health, Weapon weapon, int expReward) { this.name = name; this.maxHealth = health; - this.health = health; + this.health = health; // Start at full health this.weapon = weapon; this.expReward = expReward; } + /** + * Performs an attack on the target entity using the enemy's weapon. + * + * @param target The entity to attack + */ @Override public void attack(Entity target) { System.out.println(name + " attacks!"); - weapon.use(target); + weapon.use(target); // Delegate attack to equipped weapon } + /** + * Reduces the enemy's health by the specified amount. + * + * @param amount The amount of damage to take + */ @Override public void takeDamage(int amount) { health -= amount; @@ -32,43 +55,75 @@ public void takeDamage(int amount) { name, amount, health, maxHealth); } + /** + * Restores health points to the enemy. + * + * @param amount The amount of health to restore + */ @Override public void heal(int amount) { - health = Math.min(health + amount, maxHealth); + health = Math.min(health + amount, maxHealth); // Prevent overhealing System.out.println(name + " recovered " + amount + " HP!"); } - + + /** + * Abstract method for enemy descriptions. + * Must be implemented by concrete enemy classes. + * + * @return A formatted description of the enemy + */ @Override public abstract String getDescription(); - - // Getters + + // ========== GETTER METHODS ========== // + + /** + * @return The enemy's name + */ @Override public String getName() { return name; } + /** + * @return Current health points + */ @Override public int getHealth() { return health; } + /** + * @return Maximum health capacity + */ @Override public int getMaxHealth() { return maxHealth; } + /** + * @return Experience points awarded when defeated + */ public int getExpReward() { return expReward; } + /** + * Checks if the enemy is still alive. + * + * @return true if health > 0, false otherwise + */ @Override public boolean isAlive() { return health > 0; } + /** + * Default defend action for enemies. + * Can be overridden by specific enemy types. + */ @Override public void defend() { System.out.println(name + " braces for impact!"); } - -} +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/entity/players/Knight.java b/Java-Ring/src/main/java/org/project/entity/players/Knight.java index 7c85423..e420de0 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Knight.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Knight.java @@ -1,58 +1,101 @@ package org.project.entity.players; + import org.project.entity.Entity; import org.project.object.armors.KnightArmor; import org.project.object.weapons.Sword; +/** + * The Knight player class - A heavily armored warrior specializing in melee combat + * and defensive abilities. Features a powerful kick special ability with cooldown. + */ public class Knight extends Player { - @Override - public String getName() { - return this.name; + // Combat cooldown tracking + private int kickCooldown; // Turns remaining until kick can be used again + private static final int KICK_DAMAGE = 35; // Base damage for the kick ability + + /** + * Constructs a new Knight character with default equipment + * @param name The knight's display name + */ + public Knight(String name) { + super(name, 200, 30, new Sword(), new KnightArmor()); // High health, medium mana + this.kickCooldown = 0; // Ability starts ready } + + /** + * Checks if the knight's kick ability is available + * @return true if kick can be used, false if on cooldown + */ public boolean hasKickReady() { return kickCooldown <= 0; } - @Override - public String getDescription() { - return String.format("%s - Lvl %d Knight (%d/%d HP) | %s", - name, level, health, maxHealth, - hasKickReady() ? "Kick Ready" : "Kick CD: " + kickCooldown); - } - - private int kickCooldown; - private static final int KICK_DAMAGE = 35; - - public Knight(String name) { - super(name, 200, 30, new Sword(), new KnightArmor()); - this.kickCooldown = 0; - } + /** + * Knight's special ability - Mighty Kick + * Deals heavy damage with scaling based on level + * @param target The entity to attack + */ @Override public void useSpecialAbility(Entity target) { - if (kickCooldown <= 0) { + if (hasKickReady()) { + // Calculate damage: base + (2 * level) int totalDamage = KICK_DAMAGE + (level * 2); - System.out.printf("%s performs a mighty kick (%d damage)!%n", - name, totalDamage); + System.out.printf("%s performs a mighty kick (%d damage)!%n", + name, totalDamage); target.takeDamage(totalDamage); - kickCooldown = 3; + kickCooldown = 3; // 3-turn cooldown } else { - System.out.printf("Kick on cooldown (%d turns remaining)%n", - kickCooldown); + System.out.printf("Kick on cooldown (%d turns remaining)%n", + kickCooldown); } } + /** + * Reduces all active cooldowns by 1 turn + * Called automatically after each attack + */ public void reduceCooldowns() { if (kickCooldown > 0) kickCooldown--; } + /** + * Performs a standard attack and reduces cooldowns + * @param target The entity to attack + */ @Override - public void use(Entity target) { + public void attack(Entity target) { + super.attack(target); // Perform basic weapon attack + reduceCooldowns(); // Progress ability cooldowns + } + + /** + * Generates a character status description + * @return Formatted string with health and ability status + */ + @Override + public String getDescription() { + return String.format("%s - Lvl %d Knight (%d/%d HP) | %s", + name, level, health, maxHealth, + hasKickReady() ? "Kick Ready" : "Kick CD: " + kickCooldown); + } + // ====== Inherited Method Implementations ====== // + + /** + * @return The knight's name + */ + @Override + public String getName() { + return this.name; } + /** + * Placeholder for item usage functionality + * @param target The target entity (unused) + */ @Override - public void attack(Entity target) { - super.attack(target); - reduceCooldowns(); + public void use(Entity target) { + // TODO: Implement knight-specific item interactions } } \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/entity/players/Player.java b/Java-Ring/src/main/java/org/project/entity/players/Player.java index d1a68e3..dac912a 100644 --- a/Java-Ring/src/main/java/org/project/entity/players/Player.java +++ b/Java-Ring/src/main/java/org/project/entity/players/Player.java @@ -2,62 +2,94 @@ import java.util.ArrayList; import java.util.List; - import org.project.entity.Entity; import org.project.object.armors.Armor; import org.project.object.consumables.Consumable; import org.project.object.consumables.Flask; import org.project.object.weapons.Weapon; +/** + * Abstract base class representing a player character in the game. + * Contains core player systems including combat, inventory, and progression. + */ public abstract class Player implements Entity { - protected final String name; - protected int health; - protected int maxHealth; - protected static int mana; - protected static int maxMana; - protected Weapon weapon; - protected Armor armor; - protected int level; - protected int experience; - protected static List inventory; - protected boolean defending; - + // Character Attributes + protected final String name; // Player's name + protected int health; // Current health points + protected int maxHealth; // Maximum health capacity + protected static int mana; // Current mana points + protected static int maxMana; // Maximum mana capacity + protected Weapon weapon; // Equipped weapon + protected Armor armor; // Equipped armor + protected int level; // Current character level + protected int experience; // Accumulated experience + protected static List inventory; // Item inventory + protected boolean defending; // Defense state flag + + /** + * Constructs a new Player character with starting equipment. + * + * @param name Character name + * @param maxHealth Starting maximum health + * @param maxMana Starting maximum mana + * @param weapon Starting weapon + * @param armor Starting armor + */ public Player(String name, int maxHealth, int maxMana, Weapon weapon, Armor armor) { this.name = name; this.maxHealth = maxHealth; - this.health = maxHealth; + this.health = maxHealth; // Start at full health this.maxMana = maxMana; - this.mana = maxMana; + this.mana = maxMana; // Start at full mana this.weapon = weapon; this.armor = armor; - this.level = 1; - this.experience = 0; + this.level = 1; // Start at level 1 + this.experience = 0; // Start with 0 XP this.inventory = new ArrayList<>(); - this.inventory.add(new Flask()); // Starting item - this.maxMana = maxMana; - this.mana = maxMana; + this.inventory.add(new Flask()); // Give starting health potion + this.defending = false; // Not defending initially } + // ========== COMBAT METHODS ========== // + /** + * Abstract method for class-specific special abilities. + * Must be implemented by concrete player classes. + * + * @param target The entity to use the ability on + */ public abstract void use(Entity target); + /** + * Performs a basic attack using the equipped weapon. + * + * @param target The entity to attack + */ @Override public void attack(Entity target) { - weapon.use(target); + weapon.use(target); // Delegate attack to weapon } + /** + * Enters a defensive stance, reducing incoming damage. + */ @Override public void defend() { defending = true; System.out.println(name + " takes defensive stance!"); } + /** + * Takes damage after armor mitigation. + * + * @param amount Raw damage amount before reduction + */ @Override public void takeDamage(int amount) { - int reducedDamage = armor.protect(amount); + int reducedDamage = armor.protect(amount); // Apply armor reduction health -= reducedDamage; - defending = false; + defending = false; // Defense ends after being hit System.out.printf("%s took %d damage (reduced from %d)%n", name, reducedDamage, amount); @@ -67,43 +99,81 @@ public void takeDamage(int amount) { } } + // ========== HEALTH/MANA MANAGEMENT ========== // + + /** + * Restores health points. + * + * @param amount Amount to heal (won't exceed maxHealth) + */ @Override public void heal(int amount) { health = Math.min(health + amount, maxHealth); System.out.println(name + " recovered " + amount + " HP!"); } + /** + * Restores mana points. + * + * @param amount Amount to restore (won't exceed maxMana) + */ + @Override + public void healMana(int amount) { + mana = Math.min(maxMana, mana + amount); + System.out.println(name + " recovered " + amount + " MP!"); + } + + // ========== PROGRESSION SYSTEM ========== // + + /** + * Awards experience points and handles level-ups. + * + * @param amount Experience points to add + */ @Override public void gainExperience(int amount) { experience += amount; System.out.println(name + " gained " + amount + " XP!"); + // Level up if enough experience (100 XP per level) if (experience >= level * 100) { levelUp(); } } + /** + * Increases character level and improves stats. + */ private void levelUp() { level++; - maxHealth += 10; - maxMana += 5; - health = maxHealth; - mana = maxMana; + maxHealth += 10; // HP increase per level + maxMana += 5; // MP increase per level + health = maxHealth; // Fully heal on level up + mana = maxMana; // Fully restore mana System.out.printf("%s leveled up to %d!%n", name, level); } - // Inventory management + // ========== INVENTORY SYSTEM ========== // + + /** + * Uses an item from inventory. + * + * @param index Inventory slot number (0-based) + */ public void useItem(int index) { if (index >= 0 && index < inventory.size()) { Consumable item = inventory.get(index); - item.use(this); + item.use(this); // Apply item effect + + // Remove if depleted if (item.getRemainingUses() <= 0) { inventory.remove(index); } } } - // Getters + // ========== GETTER METHODS ========== // + @Override public String getName() { return name; @@ -156,10 +226,4 @@ public boolean isAlive() { public boolean isDefending() { return defending; } - - @Override - public void healMana(int amount) { - mana = Math.min(maxMana, mana + amount); - System.out.println(name + " recovered " + amount + " MP!"); - } -} +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/location/Location.java b/Java-Ring/src/main/java/org/project/location/Location.java index fed80b6..45f4586 100644 --- a/Java-Ring/src/main/java/org/project/location/Location.java +++ b/Java-Ring/src/main/java/org/project/location/Location.java @@ -1,53 +1,60 @@ package org.project.location; import java.util.Random; +import org.project.entity.enemies.*; +import org.project.object.weapons.*; -import org.project.entity.enemies.Dragon; -import org.project.entity.enemies.Enemy; -import org.project.entity.enemies.Goblin; -import org.project.entity.enemies.Skeleton; -import org.project.object.weapons.Claw; -import org.project.object.weapons.Dagger; -import org.project.object.weapons.RustySword; - +/** + * Represents a game location with biome-specific properties and enemy spawning logic. + * Handles danger level progression and location-based enemy generation. + */ public class Location { + /** + * Biome types that affect enemy spawn rates and location properties + */ public enum Biome { - FOREST, CAVE, MOUNTAIN , RUINS + FOREST, // Dense woodland areas + CAVE, // Underground caverns + MOUNTAIN, // High altitude terrain + RUINS // Ancient structures } - private String name; - private String description; - private int dangerLevel; - private Random random = new Random(); - private Biome biome; - - public Location(String name, String description) { + // Location properties + private String name; // Location display name + private String description; // Flavor text description + private int dangerLevel; // Difficulty scaling factor (1+) + private Random random = new Random(); // Random number generator + private Biome biome; // Biome type + + /** + * Constructs a new game location + * @param name The location's name + * @param description Descriptive text about the location + * @param biome The biome type (FOREST, CAVE, etc.) + */ + public Location(String name, String description, Biome biome) { this.name = name; this.description = description; - this.dangerLevel = 1; + this.dangerLevel = 1; // Start at minimum danger this.biome = biome; } - // public Enemy generateEnemy() { -// int scaledHealth = 50 + (dangerLevel * 20); -// int scaledExp = 30 + (dangerLevel * 10); -// int enemyType = random.nextInt(3); // 0=Goblin, 1=Skeleton, 2=Dragon -// -// return switch (enemyType) { -// case 0 -> new Goblin(scaledHealth, scaledExp, new Dagger()); -// case 1 -> new Skeleton(scaledHealth, scaledExp, new RustySword()); -// case 2 -> new Dragon(scaledHealth, scaledExp, new Claw()); -// default -> throw new IllegalStateException("Invalid enemy type"); -// }; -// } + /** + * Generates an enemy scaled to current danger level + * @return A new Enemy instance (Goblin/Skeleton/Dragon) + * @throws IllegalStateException if invalid enemy type generated + */ public Enemy generateEnemy() { try { + // Scale stats based on danger level int scaledHealth = 50 + (dangerLevel * 20); int scaledExp = 30 + (dangerLevel * 10); - int enemyType = random.nextInt(3); // 0-2 - System.out.println("Generating enemy type: " + enemyType); // Debug + // Randomly select enemy type (0-2) + int enemyType = random.nextInt(3); + + System.out.println("Generating enemy type: " + enemyType); // Debug output return switch (enemyType) { case 0 -> new Goblin(scaledHealth, scaledExp, new Dagger()); @@ -57,47 +64,63 @@ public Enemy generateEnemy() { }; } catch (Exception e) { System.err.println("Failed to generate enemy: " + e.getMessage()); - return null; // Or create a default enemy + return null; // Fallback for error cases } } + /** + * Gets biome-specific enemy spawn weights + * @return Array of weights [Goblin%, Skeleton%, Dragon%] + */ private double[] getBiomeWeights() { return switch (biome) { - case FOREST -> new double[]{70, 25, 5}; // 70% Goblin, 25% Skeleton, 5% Dragon - case CAVE -> new double[]{30, 65, 5}; // More skeletons in caves - case MOUNTAIN -> new double[]{10, 30, 60}; // Dragons dominate mountains - case RUINS -> new double[]{40, 55, 5}; // Balanced with more undead - default -> new double[]{60, 35, 5}; + case FOREST -> new double[]{70, 25, 5}; // Mostly Goblins + case CAVE -> new double[]{30, 65, 5}; // Skeleton-heavy + case MOUNTAIN -> new double[]{10, 30, 60}; // Dragon territory + case RUINS -> new double[]{40, 55, 5}; // Undead-focused + default -> new double[]{60, 35, 5}; // Default mix }; } - + /** + * Increases location danger level + * Makes future enemies stronger and increases rewards + */ public void increaseDanger() { dangerLevel++; System.out.println(name + " grows more dangerous..."); } - // Getters + // ========== GETTER METHODS ========== // + + /** + * @return Location name + */ public String getName() { return name; } + /** + * @return Location description text + */ public String getDescription() { return description; } + /** + * @return Current danger level (1+) + */ public int getDangerLevel() { return dangerLevel; } - // New method to get danger description + /** + * Gets descriptive danger rating + * @return "Safe", "Risky", or "Deadly" based on danger level + */ public String getDangerDescription() { - if (dangerLevel <= 2) { - return "Safe"; - } - if (dangerLevel <= 5) { - return "Risky"; - } + if (dangerLevel <= 2) return "Safe"; + if (dangerLevel <= 5) return "Risky"; return "Deadly"; } -} +} \ No newline at end of file diff --git a/Java-Ring/src/main/java/org/project/object/armors/Armor.java b/Java-Ring/src/main/java/org/project/object/armors/Armor.java index 1a12ca7..623186d 100644 --- a/Java-Ring/src/main/java/org/project/object/armors/Armor.java +++ b/Java-Ring/src/main/java/org/project/object/armors/Armor.java @@ -2,7 +2,7 @@ import org.project.object.Object; -// TODO: UPDATE IMPLEMENTATION + public abstract class Armor implements Object { protected String name; diff --git a/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java b/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java index 5af722a..d1955fc 100644 --- a/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java +++ b/Java-Ring/src/main/java/org/project/object/consumables/ManaPotion.java @@ -1,7 +1,6 @@ package org.project.object.consumables; import org.project.entity.Entity; -import org.project.object.consumables.Consumable; public class ManaPotion extends Consumable { private static final int MANA_RESTORE = 40; diff --git a/Java-Ring/src/main/java/org/project/object/weapons/Weapon.java b/Java-Ring/src/main/java/org/project/object/weapons/Weapon.java index c009e41..46e729c 100644 --- a/Java-Ring/src/main/java/org/project/object/weapons/Weapon.java +++ b/Java-Ring/src/main/java/org/project/object/weapons/Weapon.java @@ -1,28 +1,49 @@ package org.project.object.weapons; import java.util.List; - import org.project.entity.Entity; import org.project.object.Object; +/** + * Abstract base class for all weapons in the game. + * Implements core combat functionality, durability systems, and special abilities. + */ public abstract class Weapon implements Object { - protected String name; - protected int baseDamage; - protected int manaCost; - protected int durability; - protected int maxDurability; + // Weapon Attributes + protected String name; // Display name of the weapon + protected int baseDamage; // Base damage value + protected int manaCost; // Mana required for special abilities + protected int durability; // Current durability + protected int maxDurability; // Maximum durability capacity + /** + * Constructs a new weapon instance. + * @param name The weapon's display name + * @param damage Base damage value + * @param manaCost Mana cost for special abilities + * @param durability Starting/Maximum durability + */ public Weapon(String name, int damage, int manaCost, int durability) { this.name = name; this.baseDamage = damage; this.manaCost = manaCost; this.durability = this.maxDurability = durability; } + + /** + * Gets the base damage value before modifiers. + * @return The weapon's base damage + */ public int getDamage() { return baseDamage; } - // Core combat method + + /** + * Core combat method - attacks a target entity. + * Decreases durability with each use. + * @param target The entity to attack + */ @Override public void use(Entity target) { if (durability > 0) { @@ -36,47 +57,82 @@ public void use(Entity target) { } } + /** + * Calculates final damage (can be overridden for custom damage formulas). + * @return The calculated damage amount + */ protected int calculateDamage() { - return baseDamage; + return baseDamage; // Default implementation uses base damage } - // Special ability for weapons + /** + * Abstract method for weapon special abilities. + * Must be implemented by concrete weapon classes. + * @param targets List of entities affected by the ability + */ public abstract void specialAbility(List targets); - // Repair system + // ========== DURABILITY SYSTEM ========== // + + /** + * Fully repairs the weapon. + */ @Override public void repair() { durability = maxDurability; System.out.println(name + " has been repaired!"); } + /** + * Checks if the weapon is broken. + * @return true if durability <= 0, false otherwise + */ @Override public boolean isBroken() { return durability <= 0; } - // Standard getters + // ========== GETTER METHODS ========== // + + /** + * @return The weapon's name + */ @Override public String getName() { return name; } + /** + * Provides a formatted weapon description. + * @return String containing name and damage value + */ @Override public String getDescription() { return String.format("%s (%d DMG)", name, baseDamage); } + /** + * Weapons are not consumable items. + * @return Always false + */ @Override public boolean isConsumable() { return false; } + /** + * Calculates the weapon's in-game value. + * @return Base damage * 8 (gold value) + */ @Override public int getValue() { return baseDamage * 8; } + /** + * @return Current durability + */ public int getDurability() { return durability; } -} +} \ No newline at end of file