4 Commits
Author SHA1 Message Date
Ramtin 88a19279d3 add enemy and enemy roles 2026-07-08 17:32:54 +03:30
Ramtin ddc2b8df73 simplify Player and Enemy classes 2026-07-08 17:20:19 +03:30
Ramtin ef6c2d3dd0 add player and player roles 2026-07-08 17:19:38 +03:30
Ramtin 7a4421e722 add weapon util interface 2026-07-08 16:27:58 +03:30
17 changed files with 587 additions and 103 deletions
@@ -0,0 +1,5 @@
package org.project.Interface;
public interface IDamageUtil {
public int GetDamage();
}
@@ -1,7 +1,9 @@
package org.project.Interface;
import org.project.constants.gameConstant.AttackPowerUp;
public interface IDamager {
public void Damage(IDamageable target);
public IDamager[] GetUtils();
public void Damage(IDamageable target, int amount, AttackPowerUp[] powerUps);
public IDamageUtil[] GetDamageUtils();
public int GetDamage();
}
@@ -0,0 +1,19 @@
package org.project.Interface;
import org.project.constants.gameConstant.FightMoves;
import org.project.entity.Entity;
import java.util.ArrayList;
public interface IFighter {
public void LightAttack(IDamageable target);
public void HeavyAttack(IDamageable target);
public void defend();
public void HealMove();
public void SpecialAbility(Entity entity);
public ArrayList<FightMoves> GetAvailableMoves();
public String GetSpecialAbilityDescription(Entity entity);
public String GetSpecialAbilityResultDescription(Entity entity);
}
@@ -2,5 +2,7 @@ package org.project.constants.gameConstant;
public enum AttackPowerUp {
ANTI_SHIELD,
ANTI_CUSTOM
ANTI_CUSTOM,
NO_DEFENSE,
INEVITABLE,
}
@@ -0,0 +1,5 @@
package org.project.constants.gameConstant;
public enum DefencePowerUp {
INVISIBLE,
}
@@ -0,0 +1,9 @@
package org.project.constants.gameConstant;
public enum FightMoves {
LIGHT_ATTACK,
HEAVY_ATTACK,
HEAL,
DEFEND,
SPECIAL
}
@@ -1,13 +1,7 @@
package org.project.entity;
import org.project.Interface.IDamageable;
import org.project.Interface.IDefendable;
import org.project.Interface.IDefender;
import org.project.Interface.IHealable;
import org.project.constants.gameConstant.AttackPowerUp;
import org.project.constants.gameConstant.EntityState;
import org.project.constants.gameConstant.ItemClass;
import org.project.constants.gameConstant.ItemClassExt;
import org.project.Interface.*;
import org.project.constants.gameConstant.*;
import org.project.item.Accessory.Costume;
import org.project.item.Accessory.Shield;
import org.project.item.Accessory.Weapon;
@@ -15,22 +9,97 @@ import org.project.item.Item;
import org.project.item.SellableItem;
import java.util.ArrayList;
import java.util.Arrays;
public abstract class Entity implements IDamageable, IHealable, IDefendable {
public abstract class Entity implements IDamageable, IHealable, IDefendable, IFighter, IDamager {
public String Name;
public int MaxHealth;
public int Health;
private int Stamina;
protected int MaxStamina;
private long Money;
private int BaseDamage;
protected int BaseDamage;
private EntityState State;
public Weapon Weapon;
public Shield Shield;
public Costume Costume;
public ArrayList<Item> Inventory;
protected int DefenseBonus;
public boolean IsDefending;
public ArrayList<DefencePowerUp> defencePowerUps;
protected int HealAmount;
protected int HeavyAttackStamina;
protected int SpecialAbilityStamina;
public Entity(String name, int maxHealth, int health, int stamina, int maxStamina, long money, int baseDamage, EntityState state, Weapon weapon,
Shield shield, Costume costume, ArrayList<Item> inventory, int defenseBonus, boolean isDefending, int healAmount) {
Name = name;
MaxHealth = maxHealth;
Health = health;
Stamina = stamina;
MaxStamina = maxStamina;
Money = money;
BaseDamage = baseDamage;
State = state;
Weapon = weapon;
Shield = shield;
Costume = costume;
Inventory = inventory;
DefenseBonus = defenseBonus;
IsDefending = isDefending;
HealAmount = healAmount;
HeavyAttackStamina = 50;
SpecialAbilityStamina = 100;
}
protected Entity() {}
public int GetStamina() { return Stamina; }
public void ResetStamina() { Stamina = MaxStamina; }
public void ModifyStamina(int amount, boolean dir) {
if (dir) {
Stamina += amount;
if (Stamina > MaxStamina) {
Stamina = MaxStamina;
}
}
Stamina -= amount;
if (Stamina < 0) {
Stamina = 0;
}
}
public EntityState GetState() { return State; }
public int GetBaseDamage() { return BaseDamage; }
@Override
public int GetDamage() {
int damage = BaseDamage;
IDamageUtil[] utils = GetDamageUtils();
for (IDamageUtil util : utils) {
if (util != null) {
damage += util.GetDamage();
}
}
return damage;
}
@Override
public IDamageUtil[] GetDamageUtils() {
return new IDamageUtil[] {Weapon};
}
@Override
public void Damage(IDamageable target, int amount, AttackPowerUp[] powerUps) {
target.TakeDamage(amount, powerUps);
}
public long GetMoney() { return Money; }
@@ -48,6 +117,10 @@ public abstract class Entity implements IDamageable, IHealable, IDefendable {
return result;
}
public void SetState(EntityState state) {
State = state;
}
public void ModifyMoney(long amount, boolean dir) {
if (dir) {
Money += amount;
@@ -73,15 +146,28 @@ public abstract class Entity implements IDamageable, IHealable, IDefendable {
@Override
public void TakeDamage(int amount, AttackPowerUp[] powerUps) {
if (!defencePowerUps.contains(DefencePowerUp.INVISIBLE)) return;
IDefender[] defenders = GetDefenders();
if (Arrays.binarySearch(powerUps, AttackPowerUp.INEVITABLE) < 0) {
for (IDefender defender : defenders) {
if (defender != null) {
amount = defender.Apply(amount, powerUps);
}
}
if (IsDefending) {
if (Arrays.binarySearch(powerUps, AttackPowerUp.INEVITABLE) < 0) {
amount -= DefenseBonus;
}
IsDefending = false;
}
}
if (amount > 0) {
Health -= amount;
}
if (IsDestroyed()) {
HandleZeroHealth();
@@ -120,4 +206,46 @@ public abstract class Entity implements IDamageable, IHealable, IDefendable {
public void RemoveFromInventory(Item item) {
Inventory.remove(item);
}
@Override
public abstract void LightAttack(IDamageable target);
@Override
public abstract void HeavyAttack(IDamageable target);
@Override
public void defend() {
IsDefending = true;
}
@Override
public void HealMove() {
Heal(HealAmount);
}
@Override
public abstract void SpecialAbility(Entity entity);
@Override
public abstract String GetSpecialAbilityDescription(Entity entity);
@Override
public abstract String GetSpecialAbilityResultDescription(Entity entity);
@Override
public ArrayList<FightMoves> GetAvailableMoves() {
if (GetState() == EntityState.FROZEN) return new ArrayList<>(){};
ArrayList<FightMoves> result = new ArrayList<>();
result.add(FightMoves.DEFEND);
result.add(FightMoves.LIGHT_ATTACK);
if (Health < MaxHealth) {
result.add(FightMoves.HEAL);
}
if (Stamina > MaxStamina / 2) {
result.add(FightMoves.SPECIAL);
}
if (Stamina > MaxStamina / 4) {
result.add(FightMoves.HEAVY_ATTACK);
}
return result;
}
}
@@ -0,0 +1,52 @@
package org.project.entity.enemies;
import org.project.constants.gameConstant.AttackPowerUp;
import org.project.constants.gameConstant.EntityState;
import org.project.entity.Entity;
import org.project.entity.players.Player;
import org.project.item.Accessory.Costume;
import org.project.item.Accessory.Shield;
import org.project.item.Accessory.Weapon;
import org.project.item.Item;
import org.project.item.KeyItem;
import java.util.ArrayList;
public class Dragon extends Enemy {
public Dragon (String name, int maxHealth, int health, long money, int baseDamage, EntityState state, Weapon weapon,
Shield shield, Costume costume, ArrayList<Item> inventory, int defenseBonus, boolean isDefending,
int healAmount, int stamina, int maxStamina) {
super(name, maxHealth, health, money, baseDamage, state, weapon, shield, costume, inventory, defenseBonus, isDefending, healAmount, stamina, maxStamina);
this.Key = new KeyItem("Dragon Key", this);
}
public Dragon() {
this("Dragon", 5000, 5000, 0, 100, EntityState.ALIVE, null, null, null, new ArrayList<>(){}, 50, false, 50, 500, 500);
}
@Override
public void DropLoot(Player player) {
Key.Owner = player;
player.AddToInventory(Key);
}
@Override
public void SpecialAbility(Entity entity) {
int curHealth = entity.Health;
ModifyStamina(SpecialAbilityStamina, false);
Damage(entity, GetDamage(), new AttackPowerUp[]{AttackPowerUp.INEVITABLE});
Heal(curHealth - entity.Health);
}
@Override
public String GetSpecialAbilityDescription(Entity entity) {
return "Vampire will suck the blood out of " + entity.Name + " and heal themselves while hurting the enemy";
}
@Override
public String GetSpecialAbilityResultDescription(Entity entity) {
return "Vampire attacked " + entity.Name + " and sucked his blood out of his veins. He seems more powerful";
}
}
@@ -1,34 +1,103 @@
package org.project.entity.enemies;
import org.project.item.weapons.Weapon;
import org.project.Interface.IDamageable;
import org.project.constants.gameConstant.AttackPowerUp;
import org.project.constants.gameConstant.EntityState;
import org.project.constants.gameConstant.FightMoves;
import org.project.constants.gameConstant.ItemClass;
import org.project.entity.Entity;
import org.project.entity.players.Player;
import org.project.item.Accessory.Costume;
import org.project.item.Accessory.Shield;
import org.project.item.Accessory.Weapon;
import org.project.item.Item;
import org.project.item.KeyItem;
// TODO: UPDATE IMPLEMENTATION
public abstract class Enemy {
Weapon weapon;
private int hp;
private int mp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.util.Random;
public Enemy(int hp, int mp, Weapon weapon) {
this.hp = hp;
this.mp = mp;
public abstract class Enemy extends Entity {
protected KeyItem Key;
this.weapon = weapon;
public Enemy (String name, int maxHealth, int health, long money, int baseDamage, EntityState state, Weapon weapon,
Shield shield, Costume costume, ArrayList<Item> inventory, int defenseBonus, boolean isDefending,
int healAmount, int stamina, int maxStamina) {
super(name, maxHealth, health, stamina, maxStamina, money, baseDamage, state, weapon, shield, costume, inventory, defenseBonus, isDefending, healAmount);
Key = new KeyItem(null, this);
}
protected Enemy() {
super();
}
public void DropLoot(Player player) {
Random random = new Random();
for (Item item : Inventory) {
int change = random.nextInt(2);
if (change == 0) {
player.AddToInventory(item);
}
}
ArrayList<Item> keys = player.GetInventoryByClass(ItemClass.KEY);
if (keys.stream().noneMatch(obj -> Objects.equals(obj.getName(), Key.getName()))) {
int chance = random.nextInt(5);
if (chance == 0) {
Key.Owner = player;
player.AddToInventory(Key);
}
}
player.ModifyMoney(GetMoney(), true);
}
public void PlayRound(Player player) {
ArrayList<FightMoves> moves = GetAvailableMoves();
Random random = new Random();
int change = random.nextInt(4);
if (change == 0 && moves.contains(FightMoves.HEAL)) HealMove();
else if (change == 1 && moves.contains(FightMoves.DEFEND)) defend();
else if (moves.contains(FightMoves.SPECIAL)) SpecialAbility(player);
else if (moves.contains(FightMoves.HEAVY_ATTACK)) HeavyAttack(player);
else LightAttack(player);
}
@Override
public void takeDamage(int damage) {
hp -= damage;
public void LightAttack(IDamageable target) {
int damage = GetDamage();
Damage(target, (int)(damage * 0.4), new AttackPowerUp[]{});
ModifyStamina(MaxStamina/8, true);
}
public int getHp() {
return hp;
@Override
public void HeavyAttack(IDamageable target) {
int damage = GetDamage();
ModifyStamina(HeavyAttackStamina, false);
Damage(target, (int)(damage * 0.9), new AttackPowerUp[]{});
}
public int getMp() {
return mp;
@Override
public void HealMove() {
super.HealMove();
ModifyStamina(MaxStamina/4, true);
}
public Weapon getWeapon() {
return weapon;
}
@Override
public abstract void SpecialAbility(Entity entity);
@Override
public abstract String GetSpecialAbilityDescription(Entity entity);
@Override
public abstract String GetSpecialAbilityResultDescription(Entity entity);
}
@@ -0,0 +1,5 @@
package org.project.entity.enemies;
public class Goblin extends Enemy {
}
@@ -1,6 +1,5 @@
package org.project.entity.enemies;
// TODO: UPDATE IMPLEMENTATION
public class Skeleton {
// TODO: DESIGN ENEMY AND IMPLEMENT THE CONSTRUCTOR
public class Skeleton extends Enemy {
}
@@ -0,0 +1,45 @@
package org.project.entity.enemies;
import org.project.constants.gameConstant.AttackPowerUp;
import org.project.constants.gameConstant.EntityState;
import org.project.entity.Entity;
import org.project.item.Accessory.Costume;
import org.project.item.Accessory.Shield;
import org.project.item.Accessory.Weapon;
import org.project.item.Item;
import org.project.item.KeyItem;
import java.util.ArrayList;
public class Vampire extends Enemy {
public Vampire (String name, int maxHealth, int health, long money, int baseDamage, EntityState state, Weapon weapon,
Shield shield, Costume costume, ArrayList<Item> inventory, int defenseBonus, boolean isDefending,
int healAmount, int stamina, int maxStamina) {
super(name, maxHealth, health, money, baseDamage, state, weapon, shield, costume, inventory, defenseBonus, isDefending, healAmount, stamina, maxStamina);
this.Key = new KeyItem("Vampire Key", this);
}
public Vampire() {
this("Vampire", 150, 150, 100, 20, EntityState.ALIVE, null, null, null, new ArrayList<>(), 8, false, 30, 100, 100);
}
@Override
public void SpecialAbility(Entity entity) {
int curHealth = entity.Health;
ModifyStamina(SpecialAbilityStamina, false);
Damage(entity, GetDamage(), new AttackPowerUp[]{AttackPowerUp.INEVITABLE});
Heal(curHealth - entity.Health);
}
@Override
public String GetSpecialAbilityDescription(Entity entity) {
return "Vampire will suck the blood out of " + entity.Name + " and heal themselves while hurting the enemy";
}
@Override
public String GetSpecialAbilityResultDescription(Entity entity) {
return "Vampire attacked " + entity.Name + " and sucked his blood out of his veins. He seems more powerful";
}
}
@@ -0,0 +1,51 @@
package org.project.entity.players;
import org.project.constants.gameConstant.AttackPowerUp;
import org.project.constants.gameConstant.EntityState;
import org.project.entity.Entity;
import org.project.item.Accessory.Costume;
import org.project.item.Accessory.Shield;
import org.project.item.Accessory.Weapon;
import org.project.item.Item;
import java.util.ArrayList;
public class Assassin extends Player {
public Assassin(String name, int maxHealth, int health, long money, int baseDamage, EntityState state, Weapon weapon,
Shield shield, Costume costume, ArrayList<Item> inventory, int defenseBonus, boolean isDefending,
int healAmount, int stamina, int maxStamina, int level, int levelProgress) {
super(name, maxHealth, health, money, baseDamage, state, weapon, shield, costume, inventory, defenseBonus, isDefending, healAmount, stamina, maxStamina, level, levelProgress);
}
public Assassin(String name, int level) {
this(name);
LevelUpTo(level);
}
public Assassin(String name) {
this(name, 125, 125, 100, 15, EntityState.ALIVE, null, null, null, new ArrayList<>(), 5, false, 35, 100, 100, 1, 0);
}
@Override
public void SpecialAbility(Entity entity) {
ModifyStamina(SpecialAbilityStamina, false);
entity.SetState(EntityState.FROZEN);
Damage(entity, GetDamage() * 3, new AttackPowerUp[]{AttackPowerUp.NO_DEFENSE});
Heal(MaxHealth/4);
}
@Override
public String GetSpecialAbilityDescription(Entity entity) {
return "Turn invisible and cause a critical damage to " + entity.Name + ". Your enemy cannot defend your attack \n";
}
@Override
public String GetSpecialAbilityResultDescription(Entity entity) {
if (entity.IsDefending) {
return entity.Name + " Holds their guard up, but you strike them from another direction";
}
return "\"Show Yourself coward\" Says " + entity.Name + " As they helplessly try to hit you. But their eyes cannot find you no matter how hard they try";
}
}
@@ -1,6 +1,50 @@
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.constants.gameConstant.AttackPowerUp;
import org.project.constants.gameConstant.EntityState;
import org.project.entity.Entity;
import org.project.item.Accessory.Costume;
import org.project.item.Accessory.Shield;
import org.project.item.Accessory.Weapon;
import org.project.item.Item;
import java.util.ArrayList;
public class Knight extends Player {
public Knight(String name, int maxHealth, int health, long money, int baseDamage, EntityState state, Weapon weapon,
Shield shield, Costume costume, ArrayList<Item> inventory, int defenseBonus, boolean isDefending,
int healAmount, int stamina, int maxStamina, int level, int levelProgress) {
super(name, maxHealth, health, money, baseDamage, state, weapon, shield, costume, inventory, defenseBonus, isDefending, healAmount, stamina, maxStamina, level, levelProgress);
}
public Knight(String name, int level) {
this(name);
LevelUpTo(level);
}
public Knight(String name) {
this(name, 150, 150, 100, 20, EntityState.ALIVE, null, null, null, new ArrayList<>(), 8, false, 30, 100, 100, 1, 0);
}
@Override
public void SpecialAbility(Entity entity) {
ModifyStamina(SpecialAbilityStamina, false);
Damage(entity, GetDamage(), new AttackPowerUp[]{});
entity.SetState(EntityState.FROZEN);
}
@Override
public String GetSpecialAbilityDescription(Entity entity) {
return "Slam " + entity.Name + "with your unstoppable strength and stun them for the next turn";
}
@Override
public String GetSpecialAbilityResultDescription(Entity entity) {
if (entity.IsDefending) {
return "You slammed " + entity.Name + ", they try to defend, but they were thrown to the ground";
}
return "You slammed " + entity.Name + ", your enemy seems deezy";
}
}
@@ -1,89 +1,90 @@
package org.project.entity.players;
import org.project.Interface.IDamageable;
import org.project.constants.gameConstant.AttackPowerUp;
import org.project.constants.gameConstant.EntityState;
import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
import org.project.item.Accessory.Costume;
import org.project.item.Accessory.Shield;
import org.project.item.Accessory.Weapon;
import org.project.item.Item;
// TODO: UPDATE IMPLEMENTATION
public abstract class Player {
protected String name;
Weapon weapon;
Armor armor;
private int hp;
private int maxHP;
private int mp;
private int maxMP;
import java.util.ArrayList;
public Player(String name, int hp, int mp, Weapon weapon, Armor armor) {
this.name = name;
this.hp = hp;
this.mp = mp;
public abstract class Player extends Entity {
public int Level;
private int LevelProgress;
this.weapon = weapon;
this.armor = armor;
public Player (String name, int maxHealth, int health, long money, int baseDamage, EntityState state, Weapon weapon,
Shield shield, Costume costume, ArrayList<Item> inventory, int defenseBonus, boolean isDefending,
int healAmount, int stamina, int maxStamina, int level, int levelProgress) {
super(name, maxHealth, health, stamina, maxStamina, money, baseDamage, state, weapon, shield, costume, inventory, defenseBonus, isDefending, healAmount);
Level = level;
LevelProgress = levelProgress;
}
protected Player() {
super();
}
public void LevelUpTo(int level) {
while (Level < level) {
LevelUp();
}
}
public void AddLevelProgress(int amount) {
LevelProgress += amount;
if (LevelProgress >= 100) {
LevelUp();
}
}
public void LevelUp() {
Level++;
double upgradeRatio = (1.1 + ((double) Level * 0.02));
int gift = Level * 10;
LevelProgress -= 100;
MaxStamina = (int) (MaxStamina * upgradeRatio);
MaxHealth = (int) (MaxHealth * upgradeRatio);
BaseDamage = (int) (BaseDamage * upgradeRatio);
DefenseBonus = (int) (DefenseBonus * upgradeRatio);
HealAmount = (int) (HealAmount * upgradeRatio);
ModifyMoney(gift, true);
}
@Override
public void attack(Entity target) {
target.takeDamage(weapon.getDamage());
public void LightAttack(IDamageable target) {
int damage = GetDamage();
Damage(target, (int)(damage * 0.5), new AttackPowerUp[]{});
ModifyStamina(MaxStamina/8, true);
}
@Override
public void defend() {
// TODO
}
public void HeavyAttack(IDamageable target) {
int damage = GetDamage();
ModifyStamina(HeavyAttackStamina, false);
@Override
public void takeDamage(int damage) {
hp -= damage - armor.GetDefense();
Damage(target, damage, new AttackPowerUp[]{});
}
@Override
public void heal(int health) {
hp += health;
if (hp > maxHP) {
hp = maxHP;
}
public void HealMove() {
super.HealMove();
ModifyStamina(MaxStamina/4, true);
}
@Override
public void fillMana(int mana) {
mp += mana;
if (mp > maxMP) {
mp = maxMP;
}
}
public String getName() {
return name;
}
public int getHp() {
return hp;
}
public abstract void SpecialAbility(Entity entity);
@Override
public int getMaxHP() {
return maxHP;
}
public int getMp() {
return mp;
}
public abstract String GetSpecialAbilityDescription(Entity entity);
@Override
public int getMaxMP() {
return maxMP;
}
public Weapon getWeapon() {
return weapon;
}
public Armor getArmor() {
return armor;
}
public abstract String GetSpecialAbilityResultDescription(Entity entity);
}
@@ -0,0 +1,46 @@
package org.project.entity.players;
import org.project.constants.gameConstant.AttackPowerUp;
import org.project.constants.gameConstant.EntityState;
import org.project.entity.Entity;
import org.project.item.Accessory.Costume;
import org.project.item.Accessory.Shield;
import org.project.item.Accessory.Weapon;
import org.project.item.Item;
import java.util.ArrayList;
public class Wizard extends Player {
public Wizard(String name, int maxHealth, int health, long money, int baseDamage, EntityState state, Weapon weapon,
Shield shield, Costume costume, ArrayList<Item> inventory, int defenseBonus, boolean isDefending,
int healAmount, int stamina, int maxStamina, int level, int levelProgress) {
super(name, maxHealth, health, money, baseDamage, state, weapon, shield, costume, inventory, defenseBonus, isDefending, healAmount, stamina, maxStamina, level, levelProgress);
}
public Wizard(String name, int level) {
this(name);
LevelUpTo(level);
}
public Wizard(String name) {
this(name, 100, 100, 100, 15, EntityState.ALIVE, null, null, null, new ArrayList<>(), 5, false, 40, 100, 100, 1, 0);
}
@Override
public void SpecialAbility(Entity entity) {
ModifyStamina(SpecialAbilityStamina, false);
Damage(entity, GetDamage() * 3, new AttackPowerUp[]{AttackPowerUp.INEVITABLE});
Heal(MaxHealth/4);
}
@Override
public String GetSpecialAbilityDescription(Entity entity) {
return "Cast a spell to damage " + entity.Name + "and heal yourself. Your spell will pass enemy's defences";
}
@Override
public String GetSpecialAbilityResultDescription(Entity entity) {
return "You cased the spell, enemy cannot do anything but to look at you with fear";
}
}
@@ -1,8 +1,9 @@
package org.project.item.Accessory;
import org.project.Interface.IDamageUtil;
import org.project.entity.Entity;
public class Weapon extends Accessory {
public class Weapon extends Accessory implements IDamageUtil {
private final int Damage;
public Weapon (String name, Entity owner, int price, int health, int maxHealth, int damage) {
@@ -10,6 +11,7 @@ public class Weapon extends Accessory {
this.Damage = damage;
}
@Override
public int GetDamage() {
return Damage;
}