develop #3
Generated
+5
@@ -16,5 +16,10 @@
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://mirror-maven.runflare.com/maven2" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,150 @@
|
||||
# JAVA KNIGHT - Turn-Based RPG
|
||||
A turn-based role-playing game with Roguelike elements that runs in the terminal.
|
||||
|
||||
---
|
||||
## Story
|
||||
The land of Javanese lived in peace until a magical Dragon attacked and transformed the people into monsters: Goblins, Skeletons, and Vampires. The Dragon hid three keys to its castle among these creatures. You must collect all three keys and defeat the Dragon to break the curse.
|
||||
|
||||
---
|
||||
## How to play
|
||||
### Run the Game
|
||||
|
||||
```bash
|
||||
javac org/project/Main.java
|
||||
java org.project.Main
|
||||
```
|
||||
|
||||
### Classes(Starting States)
|
||||
---
|
||||
|
||||
|Player | HP | Damage | Weapon | Armor |
|
||||
|Knight | 80 | 40 | Sword(15 dmg) | KnightArmor(8 def) |
|
||||
|Wizard | 70 | 60 | Wood(12 dmg) | ClothArmor(3 def) |
|
||||
|Assassin | 60 | 50 | Dagger(14 dmg) | LeatherArmor(5 def)|
|
||||
|
||||
---
|
||||
### Leveling System
|
||||
|
||||
Gain XP from defeating enemies
|
||||
100 XP needed to level up
|
||||
|
||||
level up : +10 Max HP, +5 Max MP , full heal
|
||||
---
|
||||
## Enemy Special Abilities
|
||||
### Enemy Ability Effect
|
||||
|
||||
|Enemy | HP |Damage| Special Ability |
|
||||
|Goblin | 40 | 15 | 30% critical hit chance |
|
||||
|Skeleton| 50 | 15 | Revives once whit 50% HP|
|
||||
|Vampire | 55 | 15 | Lifesteal 50% of damage|
|
||||
|Dragon | 150| 35 | Fire breath(35 damage) |
|
||||
|
||||
---
|
||||
### Key System
|
||||
|
||||
Each monster type has 20% chance to drop its key
|
||||
Collect all 3 keys to fight the Dragon
|
||||
---
|
||||
### Controls
|
||||
1.Light Attack | 2.Heavy Attack | 3.Defend
|
||||
4.Heal |5.Special |6.Use Fl
|
||||
---
|
||||
|
||||
org/project/
|
||||
├── Main.java
|
||||
├── entity/
|
||||
│ ├── Entity.java (interface)
|
||||
│ ├── ICombatActions.java (interface)
|
||||
│ ├── players/
|
||||
│ │ ├── Player.java (abstract)
|
||||
│ │ ├── Knight.java
|
||||
│ │ ├── Wizard.java
|
||||
│ │ └── Assassin.java
|
||||
│ └── enemies/
|
||||
│ ├── Enemy.java (abstract)
|
||||
│ ├── Goblin.java
|
||||
│ ├── Skeleton.java
|
||||
│ ├── Vampire.java
|
||||
│ └── Dragon.java
|
||||
├── item/
|
||||
│ ├── Item.java (interface)
|
||||
│ ├── weapons/
|
||||
│ │ ├── Weapon.java (abstract)
|
||||
│ │ ├── Sword.java
|
||||
│ │ ├── Staff.java
|
||||
│ │ ├── Dagger.java
|
||||
│ │ └── Claw.java
|
||||
│ ├── armors/
|
||||
│ │ ├── Armor.java (abstract)
|
||||
│ │ ├── KnightArmor.java
|
||||
│ │ ├── ClothArmor.java
|
||||
│ │ └── LeatherArmor.java
|
||||
│ └── consumables/
|
||||
│ ├── Consumable.java (abstract)
|
||||
│ └── Flask.java
|
||||
└── location/
|
||||
└── Location.java
|
||||
---
|
||||
### Controls
|
||||
|
||||
Key Action
|
||||
1 Light Attack
|
||||
2 Heavy Attack
|
||||
3 Defend
|
||||
4 Heal
|
||||
5 Special Ability
|
||||
6 Use Flask
|
||||
|
||||
---
|
||||
## Console Colors (ANSI Codes)
|
||||
### Color Code Usage
|
||||
|
||||
|Red | \u001B[31m | Damage, enemies |
|
||||
|Green | \u001B[32m | Healing, victory |
|
||||
|Yellow| \u001B[33m | Keys, level up, warnings |
|
||||
|Blue | \u001B[34m | Mana, defending |
|
||||
|Purple| \u001B[35m | Special abilities |
|
||||
|Cyan | \u001B[36m | Player info, locations |
|
||||
|Reset | \u001B[0m | Reset to default |
|
||||
|
||||
---
|
||||
### Random Generation
|
||||
|
||||
|Element |Range |
|
||||
|Enemy count per location|2-3 |
|
||||
|Enemy type |Goblin/Skeleton /Vampire|
|
||||
|Key drop chance |20% |
|
||||
|Critical hit (Goblin) |30% |
|
||||
---
|
||||
### Step Action
|
||||
|
||||
1 |Choose your class(Knight / Wizard/ Assassin) |
|
||||
2 |Travel between locations |
|
||||
3 |Fight enemies to gain XP |
|
||||
4 |Collect keys from Goblin,Skeleton, and Vampire|
|
||||
5 | Unlock the Castle after collecting all 3 keys|
|
||||
6 |Fight and defeat the Dragon |
|
||||
7 |Save Javanest and win! |
|
||||
---
|
||||
### Defense Calculation
|
||||
|
||||
|Scenario |Formula |
|
||||
|Normal hit |Final Damage = Damage-Armor Defense |
|
||||
|While defending|Final Damage =(Damage/2)- Armor Defense|
|
||||
|Broken armor |Final Damage = Damage(defense = 0) |
|
||||
---
|
||||
### Armor Stats
|
||||
|
||||
|Armor |Defense|Durability|Class |
|
||||
|KnightArmor |8 |20 |Knight |
|
||||
|LeatherArmor|5 |15 |Assassin|
|
||||
|ClothArmor |3 |10 |Wizard |
|
||||
---
|
||||
### XP Rewards from Enemies
|
||||
|
||||
|Enemy |XP Reward|
|
||||
|Goblin |50 |
|
||||
|Skeleton|60 |
|
||||
|Vampire |70 |
|
||||
|Dragon |200 |
|
||||
---
|
||||
@@ -1,15 +1,261 @@
|
||||
package org.project;
|
||||
|
||||
import org.project.entity.enemies.Dragon;
|
||||
import org.project.entity.enemies.Enemy;
|
||||
import org.project.entity.players.Assassin;
|
||||
import org.project.entity.players.Knight;
|
||||
import org.project.entity.players.Player;
|
||||
import org.project.entity.players.Wizard;
|
||||
import org.project.item.consumables.Flask;
|
||||
import org.project.item.weapons.Dagger;
|
||||
import org.project.location.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
// TODO: ADD LOCATIONS TO YOUR GAME
|
||||
List<Location> locations = new ArrayList<>();
|
||||
private static Scanner scanner = new Scanner(System.in);
|
||||
private static Random random = new Random();
|
||||
private static Player player;
|
||||
private static List<Location> locations = new ArrayList<>();
|
||||
private static boolean hasGoblinKey = false;
|
||||
private static boolean hasSkeletonKey = false;
|
||||
private static boolean hasVampireKey = false;
|
||||
private static ArrayList<Flask> inventory = new ArrayList<>();
|
||||
|
||||
// TODO: IMPLEMENT GAMEPLAY
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("\u001B[33m Welcome to JAVA KNIGHT \u001B[0m");
|
||||
chooseClass();
|
||||
//hasGoblinKey = true;
|
||||
//hasVampireKey = true;
|
||||
//hasSkeletonKey = true;
|
||||
|
||||
setupLocations();
|
||||
|
||||
boolean gameRunning = true;
|
||||
|
||||
while (gameRunning && player.isAlive()) {
|
||||
Location currentLocation = locations.get(0);
|
||||
System.out.println("\n\u001B[36m you are in: " + currentLocation.getName() + "\u001B[0m");
|
||||
System.out.println(player.getName() + "level: " + player.getLevel() + "HP: " + player.getHp() + "/" + player.getMaxHP() + "MP" + player.getMp() + "/" + player.getMaxMP());
|
||||
System.out.println("\n\u001B[33m What do you want to do?\u001B[0m");
|
||||
System.out.println("1. Fight an enemy");
|
||||
System.out.println("2. Move to another location");
|
||||
|
||||
if (hasSkeletonKey && hasGoblinKey && hasVampireKey) {
|
||||
System.out.println("3.Go to castle to fight dragon !");
|
||||
} else {
|
||||
System.out.println("\u001B[90m🔒 Need All 3 keys: " + (hasGoblinKey ? "✓ Goblin" : "not Goblin") + " | " + (hasSkeletonKey ? "✓ Skeleton" : "not Skeleton") + " | " + (hasVampireKey ? "✓ Vampire" : "not Vampire") + "\u001B[0m");
|
||||
}
|
||||
|
||||
System.out.println("\n Choose: ");
|
||||
|
||||
int choice = getIntInput();
|
||||
|
||||
if (choice == 1) {
|
||||
fight(currentLocation);
|
||||
} else if (choice == 2) {
|
||||
moveLocation();
|
||||
} else if (choice == 3 && hasVampireKey && hasSkeletonKey && hasGoblinKey) {
|
||||
fightDragon();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!player.isAlive()) {
|
||||
System.out.println("\u001B[31m GAME OVER" + player.getName() + "has been defeated \u001B[0m");
|
||||
}
|
||||
}
|
||||
|
||||
public static int getIntInput(){
|
||||
while (!scanner.hasNextInt()){
|
||||
System.out.println("Enter an number: ");
|
||||
scanner.next();
|
||||
}
|
||||
return scanner.nextInt();
|
||||
}
|
||||
|
||||
private static void chooseClass() {
|
||||
System.out.println("\n1.Knight | 2.Wizard | 3.Assassin");
|
||||
System.out.println("Choose class :");
|
||||
int choice = getIntInput();
|
||||
System.out.println("Enter name :");
|
||||
String name = scanner.next();
|
||||
|
||||
switch (choice) {
|
||||
case 1:
|
||||
player = new Knight(name);
|
||||
break;
|
||||
case 2:
|
||||
player = new Wizard(name);
|
||||
break;
|
||||
case 3:
|
||||
player = new Assassin(name);
|
||||
break;
|
||||
default:
|
||||
player = new Knight(name);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
inventory.add(new Flask());
|
||||
}
|
||||
System.out.println("You have 3 flask");
|
||||
}
|
||||
|
||||
private static void setupLocations(){
|
||||
locations = new ArrayList<>();
|
||||
locations.add(new Location("Dark forest"));
|
||||
locations.add(new Location("Mine"));
|
||||
locations.add(new Location("Desert"));
|
||||
}
|
||||
|
||||
private static void moveLocation(){
|
||||
System.out.println("\n Locations :");
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
System.out.println((i+1) + ". " + locations.get(i).getName());
|
||||
}
|
||||
System.out.println("Choice :");
|
||||
int choice = getIntInput()-1;
|
||||
Location selected = locations.get(choice);
|
||||
locations.remove(choice);
|
||||
locations.add(0,selected);
|
||||
}
|
||||
|
||||
private static void fight(Location location){
|
||||
Enemy enemy = location.getRandomEnemy();
|
||||
System.out.println(player.getName() + " VS " + enemy.getName());
|
||||
|
||||
boolean enemyTurn = false;
|
||||
|
||||
while (player.isAlive() && enemy.isAlive()){
|
||||
if(!enemyTurn){
|
||||
System.out.println( player.getHp() + "/" + player.getMaxHP() + "HP|" + player.getMp() + "/" + player.getMaxMP());
|
||||
System.out.println("Enemy :" + enemy.getHp() + "/" + enemy.getMaxHP() + "HP");
|
||||
System.out.println("\n1.Light(0) 2.Heavy(8) 3.Defend(6) 4.Heal(12) 5.Special 6.Flask(" + inventory.size() + ")");
|
||||
System.out.println("Choice: ");
|
||||
|
||||
int action = getIntInput();
|
||||
|
||||
switch (action){
|
||||
case 1:
|
||||
player.lightAttack(enemy);
|
||||
break;
|
||||
case 2:
|
||||
player.heavyAttack(enemy);
|
||||
break;
|
||||
case 3:
|
||||
player.defend();
|
||||
break;
|
||||
case 4:
|
||||
player.heal();
|
||||
break;
|
||||
case 5:
|
||||
player.specialAbility(enemy);
|
||||
break;
|
||||
case 6:
|
||||
if(!inventory.isEmpty()) inventory.remove(0).use(player);
|
||||
else System.out.println("No flask");
|
||||
break;
|
||||
default:
|
||||
player.lightAttack(enemy);
|
||||
}
|
||||
if(!enemy.isAlive()) break;
|
||||
|
||||
enemyTurn = true;
|
||||
}else{
|
||||
System.out.println("\n " + enemy.getName() + " attacks!");
|
||||
enemy.specialAbility(player);
|
||||
|
||||
if(!player.isAlive()) break;
|
||||
enemyTurn = false;
|
||||
}
|
||||
}
|
||||
if(!enemy.isAlive()){
|
||||
System.out.println("\u001B[32 " + " Victory!" + enemy.getXpReward() + "XP\u001B[0m");
|
||||
player.gainXp(enemy.getXpReward());
|
||||
checkKeyDrop(enemy);
|
||||
location.removeEnemy(enemy);
|
||||
player.heal(30);
|
||||
player.fillMana(20);
|
||||
}else if(!player.isAlive()){
|
||||
System.out.println("\u001B[32" + " You were killed! \u001B[0m");
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkKeyDrop(Enemy enemy){
|
||||
String keyType = enemy.geTKeyType();
|
||||
if(keyType == null) return;
|
||||
|
||||
double chance = random.nextDouble();
|
||||
|
||||
if(keyType.equals("Goblin key") && !hasGoblinKey && chance < 0.2 ){
|
||||
hasGoblinKey = true;
|
||||
System.out.println("\u001B[33m Got Goblin key! (1/3) \u001B[0m");
|
||||
}else if(keyType.equals("Skeleton key") && !hasSkeletonKey && chance < 0.2 ){
|
||||
hasSkeletonKey = true;
|
||||
System.out.println("\u001B[33m Got Skeleton key! (2/3) \u001B[0m");
|
||||
}else if(keyType.equals("Vampire key") && !hasVampireKey && chance < 0.2 ){
|
||||
hasVampireKey = true;
|
||||
System.out.println("\u001B[33m Got Vampire key! (3/3) \u001B[0m");
|
||||
}
|
||||
|
||||
if(hasGoblinKey && hasSkeletonKey && hasVampireKey){
|
||||
System.out.println("\u001B[33m All 3 keys collected! Castle is open! \u001B[0m");
|
||||
}
|
||||
}
|
||||
|
||||
private static void fightDragon(){
|
||||
Dragon dragon = new Dragon();
|
||||
System.out.println("\u001B[31m FINAL BOSS! \u001B[0m");
|
||||
|
||||
boolean enemyTurn = false;
|
||||
|
||||
while(player.isAlive() && dragon.isAlive()){
|
||||
if(!enemyTurn){
|
||||
System.out.println("\n " + player.getHp() + "/" + player.getMaxHP() +"| " + player.getMp() + "/" + player.getMaxMP());
|
||||
System.out.println("Dragon: " + dragon.getHp() + "/" + dragon.getMaxHP());
|
||||
System.out.println("\n1.Light 2.Heavy 3.Defend 4.Heal 5.Special 6.Flask (" + inventory.size() + ")");
|
||||
System.out.println("Choose: ");
|
||||
|
||||
int action = getIntInput();
|
||||
|
||||
switch (action) {
|
||||
case 1:
|
||||
player.lightAttack(dragon);
|
||||
break;
|
||||
case 2:
|
||||
player.heavyAttack(dragon);
|
||||
break;
|
||||
case 3:
|
||||
player.defend();
|
||||
break;
|
||||
case 4:
|
||||
player.heal();
|
||||
break;
|
||||
case 5:
|
||||
player.specialAbility(dragon);
|
||||
break;
|
||||
case 6:
|
||||
if (!inventory.isEmpty()) inventory.remove(0).use(player);
|
||||
break;
|
||||
default:
|
||||
player.lightAttack(dragon);
|
||||
}
|
||||
|
||||
if(!dragon.isAlive()){
|
||||
break;
|
||||
}else{
|
||||
dragon.specialAbility(player);
|
||||
enemyTurn = false;
|
||||
}
|
||||
}
|
||||
if(!dragon.isAlive()){
|
||||
System.out.println("\u001B[33m You killed dragon ! \u001B[0m");
|
||||
}else{
|
||||
System.out.println("\u001B[31m Dragon killed you ! \u001B[0m");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,15 @@
|
||||
package org.project.entity;
|
||||
|
||||
import org.project.item.Item;
|
||||
import org.project.item.weapons.Weapon;
|
||||
import java.util.List;
|
||||
|
||||
public interface Entity {
|
||||
void attack(Entity target);
|
||||
|
||||
void defend();
|
||||
|
||||
void heal(int health);
|
||||
|
||||
void fillMana(int mana);
|
||||
|
||||
void takeDamage(int damage);
|
||||
|
||||
int getMaxHP();
|
||||
|
||||
int getMaxMP();
|
||||
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS METHODS
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.project.entity.enemies;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
|
||||
public interface CombatActions {
|
||||
void lightAttack(Entity target);
|
||||
void heavyAttack(Entity target);
|
||||
void defend();
|
||||
void heal();
|
||||
void specialAbility(Entity target);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.project.entity.enemies;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.weapons.Claw;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
public class Dragon extends Enemy{
|
||||
public Dragon(String name, int hp, int mp, Weapon weapon, int xpReward) {
|
||||
super("Dragon", 150,50, new Claw(20,0), 200);
|
||||
}
|
||||
|
||||
public Dragon() {
|
||||
super("Dragon", 150,50, new Claw(20,0), 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(Entity target){
|
||||
int damage = weapon.getDamage()+15;
|
||||
target.takeDamage(damage);
|
||||
System.out.println("\u001B[31m Dragon attacked for " + damage + " damage!\u001B[0m");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void specialAbility(Entity target) {
|
||||
System.out.println("\u001B[31m Dragon BREATHES FIRE! 35 damage! \u001B[0m");
|
||||
target.takeDamage(35);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String geTKeyType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,89 @@
|
||||
package org.project.entity.enemies;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Enemy {
|
||||
Weapon weapon;
|
||||
private int hp;
|
||||
private int mp;
|
||||
public abstract class Enemy implements Entity {
|
||||
protected Weapon weapon;
|
||||
protected String name;
|
||||
protected int hp;
|
||||
protected int mp;
|
||||
protected int maxHP;
|
||||
protected int maxMP;
|
||||
protected int xpReward;
|
||||
|
||||
public Enemy(int hp, int mp, Weapon weapon) {
|
||||
|
||||
public Enemy(String name ,int hp, int mp, Weapon weapon , int xpReward) {
|
||||
this.hp = hp;
|
||||
this.mp = mp;
|
||||
|
||||
this.maxHP = hp;
|
||||
this.maxMP = mp;
|
||||
this.name = name;
|
||||
this.xpReward = xpReward;
|
||||
this.weapon = weapon;
|
||||
}
|
||||
|
||||
public abstract void specialAbility(Entity target);
|
||||
public abstract String geTKeyType();
|
||||
|
||||
@Override
|
||||
public void attack(Entity target) {
|
||||
int damage = weapon.getDamage();
|
||||
target.takeDamage(damage);
|
||||
System.out.println("\u001B[31m" + this.name + " attacks for " + damage + " damage!\u001B[0m");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defend() {
|
||||
System.out.println("\u001B[34m" + this.name + " is defending.\u001B[0m");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void heal(int health) {
|
||||
hp += health;
|
||||
if (hp > maxHP) hp = maxHP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillMana(int mana) {
|
||||
mp += mana;
|
||||
if (mp > maxMP) mp = maxMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takeDamage(int damage) {
|
||||
hp -= damage;
|
||||
if (hp < 0) hp = 0;
|
||||
System.out.println("\u001B[31m" + name + " takes " + damage + " damage!\u001B[0m");
|
||||
}
|
||||
|
||||
public boolean isAlive(){
|
||||
return hp > 0;
|
||||
}
|
||||
|
||||
public int getHp() {
|
||||
return hp;
|
||||
}
|
||||
|
||||
public int getMp() {
|
||||
return mp;
|
||||
@Override
|
||||
public int getMaxHP() {
|
||||
return maxHP;
|
||||
}
|
||||
|
||||
public Weapon getWeapon() {
|
||||
@Override
|
||||
public int getMaxMP() {
|
||||
return maxMP;
|
||||
}
|
||||
|
||||
public int getXpReward(){
|
||||
return xpReward;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
public Weapon getWeapon(){
|
||||
return weapon;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.project.entity.enemies;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.weapons.Sword;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
public class Goblin extends Enemy{
|
||||
|
||||
public Goblin(String name, int hp, int mp, Weapon weapon, int xpReward) {
|
||||
super("Goblin", 40, 15, new Sword(), 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(Entity target){
|
||||
int damage = weapon.getDamage();
|
||||
if (Math.random() < 0.3) {
|
||||
damage *= 2;
|
||||
System.out.println("\u001B[31m Goblin landed a CRITICAL hit!\u001B[0m");
|
||||
}
|
||||
target.takeDamage(damage);
|
||||
System.out.println("\u001B[31m Goblin attacked for " + damage + " damage!\u001B[0m");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void specialAbility(Entity target) {
|
||||
System.out.println("\u001B[31m Goblin use RAPID STRIKE \u001B[0m");
|
||||
attack(target);
|
||||
attack(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String geTKeyType() {
|
||||
return "GoblinKey";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,39 @@
|
||||
package org.project.entity.enemies;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class Skeleton {
|
||||
// TODO: DESIGN ENEMY AND IMPLEMENT THE CONSTRUCTOR
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.weapons.Sword;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
public class Skeleton extends Enemy{
|
||||
private boolean hasRevived;
|
||||
|
||||
public Skeleton(String name, int hp, int mp, Weapon weapon, int xpReward) {
|
||||
super("Skeleton", 50, 20, new Sword(), 60);
|
||||
this.hasRevived = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takeDamage(int damage){
|
||||
hp -= damage;
|
||||
if (hp < 0) hp = 0;
|
||||
System.out.println("\u001B[31m" + name + " Skeleton takes " + damage + " damage!\u001B[0m");
|
||||
if (!hasRevived){
|
||||
hp = maxHP/2;
|
||||
hasRevived = true;
|
||||
System.out.println("\u001B[35m Skeleton is revived whit " + hp + " HP!\u001B[0m");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void specialAbility(Entity target){
|
||||
System.out.println("\u001B[31m uses ability!\u001B[0m");
|
||||
attack(target);
|
||||
heal(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String geTKeyType() {
|
||||
return "SkeletonKey";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.project.entity.enemies;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.weapons.Sword;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
public class Vampire extends Enemy{
|
||||
public Vampire(String name, int hp, int mp, Weapon weapon, int xpReward) {
|
||||
super("Vampire", 55,25, new Sword(), 70);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(Entity target){
|
||||
int damage = weapon.getDamage();
|
||||
target.takeDamage(damage);
|
||||
int healAmount = damage/2;
|
||||
heal(healAmount);
|
||||
System.out.println("\u001B[31m Vampire attacked for " + damage + " damage & drained " +healAmount + " HP!\u001B[0m");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void specialAbility(Entity target) {
|
||||
System.out.println("\u001B[35m Vampire use BLOOD CURSE! \u001B[0m");
|
||||
attack(target);
|
||||
attack(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String geTKeyType() {
|
||||
return "VampireKey";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.project.entity.players;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.armors.Armor;
|
||||
import org.project.item.armors.LeatherArmor;
|
||||
import org.project.item.weapons.Dagger;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
public class Assassin extends Player{
|
||||
private boolean invisible;
|
||||
|
||||
public Assassin(String name, int hp, int mp, Weapon weapon, Armor armor) {
|
||||
super(name, 60, 50, new Dagger(14,0),new LeatherArmor(5,15));
|
||||
this.invisible = false;
|
||||
}
|
||||
|
||||
public Assassin(String name) {
|
||||
super(name, 60, 50, new Dagger(14,0),new LeatherArmor(5,15));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lightAttack(Entity target){
|
||||
int damage = 5 + (level*2);
|
||||
target.takeDamage(damage);
|
||||
System.out.println("\u001B[31m" + name + " use Light attack! (0 mana) " + damage + " damage!\u001B[0m");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void specialAbility(Entity target) {
|
||||
if(mp >=18){
|
||||
mp -= 18;
|
||||
invisible = true;
|
||||
System.out.println("\u001B[35m" + name + " turned Invisible! next attack will be critical (-18 mana)\u001B[0m");
|
||||
}else{
|
||||
System.out.println("\u001b[33m Not enough mana ! \u001B[0m");
|
||||
lightAttack(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,32 @@
|
||||
package org.project.entity.players;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class Knight {
|
||||
// TODO: DESIGN KNIGHT'S WEAPON AND ARMOR AND IMPLEMENT THE CONSTRUCTOR
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.armors.Armor;
|
||||
import org.project.item.armors.KnightArmor;
|
||||
import org.project.item.weapons.Sword;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
public class Knight extends Player {
|
||||
|
||||
public Knight(String name, int hp, int mp, Weapon weapon, Armor armor) {
|
||||
super(name, 80, 40, new Sword(), new KnightArmor(8,20));
|
||||
}
|
||||
|
||||
public Knight(String name) {
|
||||
super(name, 80, 40, new Sword(), new KnightArmor(8,20));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void specialAbility(Entity target) {
|
||||
if(mp >= 15){
|
||||
mp -= 15;
|
||||
int damage = weapon.getDamage() + 15;
|
||||
target.takeDamage(damage);
|
||||
System.out.println("\u001B[35m " + name + "enemy stunned (-15 mana)" + damage + "damage! \u001B[0m");
|
||||
}else{
|
||||
System.out.println("\u001B[33m Not enough mana ! \u001B[0m");
|
||||
lightAttack(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,60 +1,129 @@
|
||||
package org.project.entity.players;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.entity.enemies.CombatActions;
|
||||
import org.project.item.armors.Armor;
|
||||
import org.project.item.weapons.Weapon;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Player {
|
||||
public abstract class Player implements Entity, CombatActions {
|
||||
protected String name;
|
||||
Weapon weapon;
|
||||
Armor armor;
|
||||
private int hp;
|
||||
private int maxHP;
|
||||
private int mp;
|
||||
private int maxMP;
|
||||
protected Weapon weapon;
|
||||
protected Armor armor;
|
||||
protected int hp;
|
||||
protected int mp;
|
||||
protected int maxHP;
|
||||
protected int maxMP;
|
||||
protected int xp;
|
||||
protected int level;
|
||||
protected boolean isDefending;
|
||||
|
||||
public Player(String name, int hp, int mp, Weapon weapon, Armor armor) {
|
||||
this.name = name;
|
||||
this.hp = hp;
|
||||
this.mp = mp;
|
||||
|
||||
this.maxHP = hp;
|
||||
this.maxMP = mp;
|
||||
this.weapon = weapon;
|
||||
this.armor = armor;
|
||||
this.level = 1;
|
||||
this.xp = 0;
|
||||
this.isDefending = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(Entity target) {
|
||||
target.takeDamage(weapon.getDamage());
|
||||
public void lightAttack(Entity target) {
|
||||
int damage= 5 + (level*2);
|
||||
target.takeDamage(damage);
|
||||
System.out.println("\u001B[31m" + name + " use Light attack! (0 mana) " + damage + " damage!\u001B[0m");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void heavyAttack(Entity target){
|
||||
if(mp >= 8){
|
||||
mp -= 8;
|
||||
int damage = weapon.getDamage() + 10;
|
||||
target.takeDamage(damage);
|
||||
System.out.println("\u001B[31m" + name + " use heavy attack! (-8 mana) " + damage + " damage!\u001B[0m");
|
||||
}else{
|
||||
System.out.println("\u001B[33m Not enough mana! use light attack instead.\u001B[0m" );
|
||||
lightAttack(target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void defend() {
|
||||
// TODO
|
||||
isDefending = true;
|
||||
System.out.println("\u001B[34m" + this.name + " is defending.next attack reduced by half!\u001B[0m");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attack(Entity target){
|
||||
lightAttack(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void takeDamage(int damage) {
|
||||
hp -= damage - armor.getDefense();
|
||||
if(isDefending){
|
||||
damage = damage/2;
|
||||
isDefending = false;
|
||||
System.out.println("\u001B[34m" + name + " Defense reduced damage!\u001B[0m");
|
||||
}
|
||||
|
||||
int armorDefense =(armor != null && !armor.isBroke()) ? armor.getDefense(): 0;
|
||||
int finalDamage = damage - armorDefense;
|
||||
if(finalDamage < 0) finalDamage=0;
|
||||
|
||||
hp -= finalDamage;
|
||||
if (hp < 0) hp = 0;
|
||||
System.out.println("\u001B[31m" + name + " took " + finalDamage + " damage!\u001B[0m");
|
||||
|
||||
//if(armor != null){
|
||||
//armorDefense.reductDurability();
|
||||
//}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void heal(int health) {
|
||||
hp += health;
|
||||
if (hp > maxHP) {
|
||||
hp = maxHP;
|
||||
public void heal() {
|
||||
if(mp>=12){
|
||||
mp -= 12;
|
||||
int healAmount = 20;
|
||||
hp += healAmount;
|
||||
if (hp > maxHP) hp = maxHP;
|
||||
System.out.println("\u001B[32m" + name + " head" + healAmount + "HP (-12 mana)\u001B[0m");
|
||||
}else{
|
||||
System.out.println("\u001B[33m Not enough mana to heal!\u001B[0m");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void heal(int health){
|
||||
hp += health;
|
||||
if(hp > maxHP) hp = maxHP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillMana(int mana) {
|
||||
mp += mana;
|
||||
if (mp > maxMP) {
|
||||
if (mp > maxMP) mp = maxMP;
|
||||
}
|
||||
|
||||
public void gainXp(int amount){
|
||||
xp += amount;
|
||||
System.out.println("\u001B[33m" + name + "gained" + amount + "XP \u001B[0m");
|
||||
if(xp >= 100){
|
||||
level ++;
|
||||
xp = 0;
|
||||
maxHP += 10;
|
||||
maxMP += 5;
|
||||
hp = maxHP;
|
||||
mp = maxMP;
|
||||
System.out.println("\u001B[33m Level up" + level + "\u001B[0m");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAlive(){
|
||||
return hp>0;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
@@ -82,8 +151,8 @@ public abstract class Player {
|
||||
return weapon;
|
||||
}
|
||||
|
||||
public Armor getArmor() {
|
||||
return armor;
|
||||
public int getLevel(){
|
||||
return level;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.project.entity.players;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.armors.Armor;
|
||||
import org.project.item.armors.ClothArmor;
|
||||
import org.project.item.weapons.Weapon;
|
||||
import org.project.item.weapons.Wood;
|
||||
|
||||
public class Wizard extends Player{
|
||||
|
||||
public Wizard(String name, int hp, int mp, Weapon weapon, Armor armor) {
|
||||
super(name, 70, 60, new Wood(12 ,0), new ClothArmor(3,10));
|
||||
}
|
||||
|
||||
public Wizard(String name) {
|
||||
super(name, 70, 60, new Wood(12 ,0), new ClothArmor(3,10));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void specialAbility(Entity target) {
|
||||
if(mp >= 20){
|
||||
mp -= 20;
|
||||
int damage = weapon.getDamage() + 12;
|
||||
target.takeDamage(damage);
|
||||
heal(10);
|
||||
System.out.println("\u001b[35m" + name + "Cast FIRESTORM!" + damage + "damage and heal 10 HP! (-20 mana) \u001B[0m");
|
||||
}else{
|
||||
System.out.println("\u001b[33m Not enough mana ! \u001B[0m");
|
||||
lightAttack(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,6 @@ package org.project.item;
|
||||
import org.project.entity.Entity;
|
||||
|
||||
public interface Item {
|
||||
void use(Entity target);
|
||||
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS METHODS
|
||||
*/
|
||||
void use(Entity target);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
package org.project.item.armors;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Armor {
|
||||
private int defense;
|
||||
private int maxDefense;
|
||||
private int durability;
|
||||
private int maxDurability;
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.Item;
|
||||
|
||||
private boolean isBroke;
|
||||
public abstract class Armor {
|
||||
protected int defense;
|
||||
protected int maxDefense;
|
||||
protected int durability;
|
||||
protected int maxDurability;
|
||||
protected boolean isBroke;
|
||||
|
||||
public Armor(int defense, int durability) {
|
||||
this.defense = defense;
|
||||
this.durability = durability;
|
||||
this.isBroke = false;
|
||||
}
|
||||
|
||||
public void checkBreak() {
|
||||
if (durability <= 0) {
|
||||
isBroke = true;
|
||||
defense = 0;
|
||||
System.out.println("\u001B[31m Armor broke! \u001B[0m");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: (BONUS) UPDATE THE REPAIR METHOD
|
||||
public void repair() {
|
||||
isBroke = false;
|
||||
defense = maxDefense;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.project.item.armors;
|
||||
|
||||
public class ClothArmor extends Armor{
|
||||
public ClothArmor(int defense, int durability) {
|
||||
super(3, 10);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
package org.project.item.armors;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class KnightArmor {
|
||||
// TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
|
||||
|
||||
import org.project.entity.Entity;
|
||||
|
||||
public class KnightArmor extends Armor {
|
||||
public KnightArmor(int defense, int durability) {
|
||||
super(8, 20);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.project.item.armors;
|
||||
|
||||
public class LeatherArmor extends Armor{
|
||||
public LeatherArmor(int defense, int durability) {
|
||||
super(5, 15);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,20 @@
|
||||
package org.project.item.consumables;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Consumable {
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS METHODS
|
||||
*/
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.Item;
|
||||
|
||||
public abstract class Consumable implements Item {
|
||||
protected int healAmount;
|
||||
protected int manaAmount;
|
||||
|
||||
public Consumable(){
|
||||
this.healAmount = healAmount;
|
||||
this.manaAmount = manaAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use(Entity target){
|
||||
target.heal(healAmount);
|
||||
target.fillMana(manaAmount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package org.project.item.consumables;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.Item;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public class Flask {
|
||||
/*
|
||||
THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN.
|
||||
*/
|
||||
public class Flask implements Item {
|
||||
|
||||
// TODO: UPDATE USE METHOD
|
||||
@Override
|
||||
public void use(Entity target) {
|
||||
target.heal(target.getMaxHP() / 10);
|
||||
int healAmount = target.getMaxHP() /10;
|
||||
target.heal(healAmount);
|
||||
target.fillMana(10);
|
||||
System.out.println("\u001B[32m Flask used! Healed " + healAmount + "HP and restored 10 mana! \u001B[0m");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.project.item.weapons;
|
||||
|
||||
public class Claw extends Weapon{
|
||||
public Claw(int damage, int manaCost) {
|
||||
super(20, 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.project.item.weapons;
|
||||
|
||||
public class Dagger extends Weapon{
|
||||
public Dagger(int damage, int manaCost) {
|
||||
super(14, 0);
|
||||
}
|
||||
}
|
||||
@@ -4,19 +4,15 @@ 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(15 , 0);
|
||||
}
|
||||
|
||||
// TODO: (BONUS) UPDATE THE UNIQUE ABILITY
|
||||
public void uniqueAbility(ArrayList<Entity> targets) {
|
||||
abilityCharge += 2;
|
||||
for (Entity target : targets) {
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
package org.project.item.weapons;
|
||||
|
||||
import org.project.entity.Entity;
|
||||
import org.project.item.Item;
|
||||
|
||||
// TODO: UPDATE IMPLEMENTATION
|
||||
public abstract class Weapon {
|
||||
public abstract class Weapon implements Item {
|
||||
private int damage;
|
||||
private int manaCost;
|
||||
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS ATTRIBUTES
|
||||
*/
|
||||
|
||||
public Weapon(int damage, int manaCost) {
|
||||
this.damage = damage;
|
||||
this.manaCost = manaCost;
|
||||
@@ -29,7 +25,4 @@ public abstract class Weapon {
|
||||
return manaCost;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: ADD OTHER REQUIRED AND BONUS METHODS
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.project.item.weapons;
|
||||
|
||||
public class Wood extends Weapon {
|
||||
public Wood(int damage, int manaCost) {
|
||||
super(12, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,82 @@
|
||||
package org.project.location;
|
||||
|
||||
import org.project.entity.enemies.Enemy;
|
||||
import org.project.entity.enemies.Goblin;
|
||||
import org.project.entity.enemies.Skeleton;
|
||||
import org.project.entity.enemies.Vampire;
|
||||
import org.project.item.weapons.Sword;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
public class Location {
|
||||
private String name;
|
||||
|
||||
private String name;
|
||||
private ArrayList<Enemy> enemies;
|
||||
private static Random random = new Random();
|
||||
private ArrayList<Location> locations;
|
||||
|
||||
public Location(ArrayList<Location> locations, ArrayList<Enemy> enemies) {
|
||||
this.locations = locations;
|
||||
this.enemies = enemies;
|
||||
}
|
||||
|
||||
public Location(String name) {
|
||||
this.name = name;
|
||||
this.locations = new ArrayList<Location>();
|
||||
this.enemies = new ArrayList<Enemy>();
|
||||
generateEnemies();
|
||||
}
|
||||
|
||||
public void generateEnemies(){
|
||||
int enemyCount = random.nextInt(2) + 2;
|
||||
for (int i = 0; i < enemyCount; i++) {
|
||||
int type = random.nextInt(3);
|
||||
switch (type){
|
||||
case 0 :
|
||||
enemies.add(new Goblin("Goblin", 40, 15, new Sword(), 50));
|
||||
break;
|
||||
case 1 :
|
||||
enemies.add(new Skeleton("Skeleton", 50, 20, new Sword(), 60));
|
||||
break;
|
||||
case 2 :
|
||||
enemies.add(new Vampire("Vampire", 55,25, new Sword(), 70));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Enemy getRandomEnemy(){
|
||||
if(enemies.isEmpty() ){
|
||||
return null;
|
||||
}
|
||||
return enemies.get(random.nextInt(enemies.size()));
|
||||
}
|
||||
|
||||
public void removeEnemy(Enemy enemy){
|
||||
enemies.remove(enemy);
|
||||
}
|
||||
|
||||
public boolean hasEnemies(){
|
||||
return !enemies.isEmpty();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(){
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void addLocation(Location location){
|
||||
this.locations.add(location);
|
||||
}
|
||||
|
||||
public void addEnemy(Enemy enemy){
|
||||
this.enemies.add(enemy);
|
||||
}
|
||||
|
||||
public ArrayList<Location> getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user