equipments #22

Merged
viud3133 merged 40 commits from equipments into main 2025-10-30 12:09:43 +01:00
46 changed files with 1491 additions and 137 deletions
Showing only changes of commit 1c1d49b774 - Show all commits

11
hortlog -s –n Normal file
View File

@@ -0,0 +1,11 @@
error: unknown option `-git'
usage: git shortlog [<options>] [<revision-range>] [[--] <path>...]
or: git log --pretty=short | git shortlog [<options>]
-c, --[no-]committer group by committer rather than author
-n, --[no-]numbered sort output according to the number of commits per author
-s, --[no-]summary suppress commit descriptions, only provides commit count
-e, --[no-]email show the email address of each author
-w[<w>[,<i1>[,<i2>]]] linewrap output
--[no-]group <field> group by field

View File

@@ -1,11 +1,11 @@
package Action; package Action;
import Job.HasJob; import Job.JobHolder;
import Job.Wizard; import Job.Wizard;
public class CastAction implements Action { public class CastAction implements Action {
private Wizard requireWizard(Actor actor) { private Wizard requireWizard(Actor actor) {
if (actor instanceof HasJob hasJob && hasJob.getJob() instanceof Wizard wizard) { if (actor instanceof JobHolder hasJob && hasJob.getJob() instanceof Wizard wizard) {
return wizard; return wizard;
} }
throw new IllegalStateException(actor + " cannot perform this action without being a Wizard!"); throw new IllegalStateException(actor + " cannot perform this action without being a Wizard!");

View File

@@ -1,18 +1,22 @@
package Action; package Action;
import Job.HasJob; import Job.JobHolder;
import Job.Miner; import Job.Miner;
import Terrain.Biome;
public class DigAction implements Action { public class DigAction implements Action {
Biome biome;
public DigAction(Biome biome) {
this.biome = biome;
}
@Override @Override
public void execute(Actor actor) { public void execute(Actor actor) {
Miner miner = requireMiner(actor); Miner miner = requireMiner(actor);
miner.dig(actor); miner.dig(biome);
} }
private Miner requireMiner(Actor actor) { private Miner requireMiner(Actor actor) {
if (actor instanceof HasJob hasJob if (actor.getJob() instanceof Miner miner) {
&& hasJob.getJob() instanceof Miner miner) {
return miner; return miner;
} }
throw new IllegalStateException(actor + " cannot perform this action without being a Miner!"); throw new IllegalStateException(actor + " cannot perform this action without being a Miner!");

View File

@@ -1,6 +1,6 @@
package Action; package Action;
import Job.HasJob; import Job.JobHolder;
import Job.Wizard; import Job.Wizard;
public class LearnSpellAction implements Action { public class LearnSpellAction implements Action {
@@ -11,7 +11,7 @@ public class LearnSpellAction implements Action {
} }
private Wizard requireWizard(Actor actor) { private Wizard requireWizard(Actor actor) {
if (actor instanceof HasJob hasJob && hasJob.getJob() instanceof Wizard wizard) { if (actor instanceof JobHolder hasJob && hasJob.getJob() instanceof Wizard wizard) {
return wizard; return wizard;
} }
throw new IllegalStateException(actor + " cannot perform this action without being a Wizard!"); throw new IllegalStateException(actor + " cannot perform this action without being a Wizard!");

View File

@@ -1,7 +0,0 @@
package Character;
import java.util.List;
public interface HasInventory {
List<String> getInventory();
}

View File

@@ -0,0 +1,9 @@
package Combat;
import java.util.List;
public interface HasConditions {
void addCondition(String condition);
void removeCondition(String condition);
List<String> getConditions();
}

View File

@@ -3,9 +3,11 @@ package Combat;
import Entity.Entity; import Entity.Entity;
public class OffensiveDamageSpell extends Spell { public class OffensiveDamageSpell extends Spell {
private final int potency;
public OffensiveDamageSpell(String spellName, int cost, int potency) { public OffensiveDamageSpell(String spellName, int cost, int range, int potency) {
super(spellName, cost, potency); super(spellName, cost, range);
this.potency = potency;
} }
@Override @Override
@@ -15,4 +17,6 @@ public class OffensiveDamageSpell extends Spell {
health.setHealth(health.getHealth() - this.getPotency()); health.setHealth(health.getHealth() - this.getPotency());
} }
} }
public int getPotency() {return potency;}
} }

View File

@@ -0,0 +1,22 @@
package Combat;
import Entity.Entity;
public class OffensiveStatusSpell extends Spell {
private final String status;
public OffensiveStatusSpell(String spellName, int cost, int range, String status) {
super(spellName, cost, range);
this.status = status;
}
public void cast(Entity source, Entity target) {
if(source instanceof HasMana mana && target instanceof HasConditions conditions) {
mana.setMana(mana.getMana() - this.getCost());
conditions.addCondition(this.getStatus());
}
}
public String getStatus() {return status;}
}

View File

@@ -4,13 +4,13 @@ import Entity.Entity;
public abstract class Spell { public abstract class Spell {
private final String spellName; private final String spellName;
private int cost; private final int cost;
private int potency; private final int range;
public Spell(String spellName, int cost, int potency) { public Spell(String spellName, int cost, int range) {
this.spellName = spellName; this.spellName = spellName;
this.cost = cost; this.cost = cost;
this.potency = potency; this.range = range;
} }
public String getSpellName() { public String getSpellName() {
@@ -21,9 +21,7 @@ public abstract class Spell {
return cost; return cost;
} }
public int getPotency() { public int getRange() {return range;}
return potency;
}
public abstract void cast(Entity source, Entity target); public abstract void cast(Entity source, Entity target);
@@ -35,7 +33,7 @@ public abstract class Spell {
Spell spell = (Spell) o; Spell spell = (Spell) o;
if (cost != spell.cost) return false; if (cost != spell.cost) return false;
if (potency != spell.potency) return false; if (range != spell.range) return false;
return spellName.equals(spell.spellName); return spellName.equals(spell.spellName);
} }
@@ -43,12 +41,12 @@ public abstract class Spell {
public int hashCode() { public int hashCode() {
int result = spellName.hashCode(); int result = spellName.hashCode();
result = 31 * result + cost; result = 31 * result + cost;
result = 31 * result + potency; result = 31 * result + range;
return result; return result;
} }
@Override @Override
public String toString() { public String toString() {
return spellName + " (Cost: " + cost + ", Potency: " + potency + ")"; return spellName + " (Cost: " + cost + ", Range: " + range + ")";
} }
} }

View File

@@ -1,13 +1,39 @@
package Entity; package Entity;
public abstract class Entity implements HasPosition { import java.util.ArrayList;
import java.util.List;
public abstract class Entity implements Positionable {
protected String name; protected String name;
protected Position position; protected Position position;
private static final List<Entity> entities = new ArrayList<Entity>();
public Entity(String name) { public Entity(String name) {
this.name = name; this.name = name;
entities.add(this);
} }
public static List<Entity> getEntities() {
return entities;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Entity entity = (Entity) obj;
return name.equals(entity.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override public String toString() {
return name;
}
} }

View File

@@ -2,35 +2,61 @@ package Entity;
import Action.Action; import Action.Action;
import Action.Actor; import Action.Actor;
import Combat.HasConditions;
import Combat.HasHealth; import Combat.HasHealth;
import Combat.HasMana; import Combat.HasMana;
import Combat.Spell; import Combat.Spell;
import Inventory.Inventory; import Inventory.Inventory;
import Item.Equipment;
import Job.Job; import Job.Job;
import Job.HasJob; import Job.JobHolder;
import Inventory.HasInventory; import Inventory.InventoryHolder;
import Inventory.HasSpellBook; import Inventory.HasSpellBook;
import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
public class Player extends Entity implements Movable, Actor, HasInventory, HasSpellBook, HasJob, HasHealth, HasMana { public class Player extends Entity implements Movable, Actor, InventoryHolder, HasSpellBook, JobHolder, HasHealth, HasMana, HasConditions {
protected int health; protected int health;
protected int mana; protected int mana;
protected int strength;
protected int magicStrength;
protected int defence;
protected int magicDefence;
protected Job job; protected Job job;
protected Position position = new Position(0,0); protected Position position = new Position(0,0);
protected Inventory inventory= new Inventory(); protected Inventory inventory= new Inventory();
protected List<Spell> spells = new LinkedList<>(); protected List<Spell> spells = new LinkedList<>();
protected List<String> conditions = new LinkedList<>();
protected List<Equipment> equipments = new ArrayList<>();
public Player(String name, Job job) { public Player(String name, Job job) {
super(name); super(name);
this.job = job; this.job = job;
this.position = new Position(0,0); this.position = new Position(0,0);
for(int i= 0; i<4; i++){
equipments.add(null);
}
} }
public Player(String name) { public Player(String name) {
super(name); super(name);
} }
public Player(String name, Inventory inventory) {
super(name);
this.inventory = inventory;
this.position = new Position(0,0);
}
public Player(String name, Job job, Inventory inventory) {
super(name);
this.job = job;
this.inventory = inventory;
this.position = new Position(0,0);
}
@Override @Override
public void moveTo(Position position) { public void moveTo(Position position) {
if(canMoveTo(position)){ if(canMoveTo(position)){
@@ -40,7 +66,9 @@ public class Player extends Entity implements Movable, Actor, HasInventory, HasS
@Override @Override
public boolean canMoveTo(Position position) { public boolean canMoveTo(Position position) {
return true; boolean withinX = (position.x() - 2) < this.position.x() && this.position.x() < (position.x() + 2);
boolean withinY = (position.y() - 2) < this.position.y() && this.position.y() < (position.y() + 2);
return withinX && withinY;
} }
public Job getJob() { public Job getJob() {
return job; return job;
@@ -51,12 +79,35 @@ public class Player extends Entity implements Movable, Actor, HasInventory, HasS
this.job = job; this.job = job;
} }
public void equip(Equipment equipment) {
if(!equipment.getEquipable().equals(job)){
throw new IllegalStateException("A player with this job can not equip this equipment");
}
int i = equipment.getSlot();
if(!(equipments.get(i)==null)){
throw new IllegalStateException("Equipment slot already filled");
}
equipments.set(i, equipment);
}
public Inventory getInventory() { public Inventory getInventory() {
return inventory; return inventory;
} }
public List<Spell> getSpellBook() {return spells;} public List<Spell> getSpellBook() {return spells;}
public List<Equipment> getEquipments() {return equipments;}
@Override
public List<String> getConditions() {return conditions;}
@Override
public void addCondition(String condition) {this.conditions.add(condition);}
@Override
public void removeCondition(String condition) {this.conditions.remove(condition);}
@Override @Override
public void performAction(Action action) { public void performAction(Action action) {
action.execute(this); action.execute(this);
@@ -78,13 +129,104 @@ public class Player extends Entity implements Movable, Actor, HasInventory, HasS
} }
@Override @Override
public int getHealth() {return health;} public int getHealth() {
if(equipments.isEmpty()){
return health;
}
int totalHealth = health;
for (Equipment e : equipments) {
if (e!=null) {
totalHealth+= e.getEquipmentType().getModifiers().getMaxHpMod();
}
}
return totalHealth;
}
@Override @Override
public void setMana(int mana) {this.mana = mana;} public void setMana(int mana) {this.mana = mana;}
@Override @Override
public int getMana() {return mana;} public int getMana() {
if(equipments.isEmpty()){
return mana;
}
int totalMana = mana;
for (Equipment e : equipments) {
if (e!=null) {
totalMana+= e.getEquipmentType().getModifiers().getMaxMpMod();
}
}
return totalMana;
}
public int getStrength() {
if(equipments.isEmpty()){
return strength;
}
int totalStrength = strength;
for (Equipment e : equipments) {
if (e!=null) {
totalStrength+= e.getEquipmentType().getModifiers().getStrMod();
}
}
return totalStrength;
}
public int getMagicStrength() {
if(equipments.isEmpty()){
return magicStrength;
}
int totalMagicStrength = magicStrength;
for (Equipment e : equipments) {
if(e!=null) {
totalMagicStrength+= e.getEquipmentType().getModifiers().getMagicStrMod();
}
}
return totalMagicStrength;
}
public int getDefence() {
if(equipments.isEmpty()){
return defence;
}
int totalDefence = defence;
for (Equipment e : equipments) {
if (e!=null) {
totalDefence+= e.getEquipmentType().getModifiers().getDefMod();
}
}
return totalDefence;
}
public int getMagicDefence() {
if(equipments.isEmpty()){
return magicDefence;
}
int totalMagicDefence = magicDefence;
for (Equipment e : equipments) {
if(e!=null) {
totalMagicDefence+= e.getEquipmentType().getModifiers().getMagicDefMod();
}
}
return totalMagicDefence;
}
@Override @Override
public boolean isAlive() { public boolean isAlive() {

View File

@@ -1,6 +1,6 @@
package Entity; package Entity;
public interface HasPosition { public interface Positionable {
Position getPosition(); Position getPosition();
void setPosition(Position position); void setPosition(Position position);
} }

View File

@@ -1,7 +0,0 @@
package Inventory;
import java.util.List;
public interface HasInventory {
Inventory getInventory();
}

View File

@@ -1,24 +1,55 @@
package Inventory; package Inventory;
import Item.ItemStack;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
public class Inventory { public class Inventory {
List<String> items; private final List<ItemStack> items;
private final int maxWeight;
public Inventory() { public Inventory() {
items = new ArrayList<>(); items = new ArrayList<>();
maxWeight = 100;
} }
List<String> getItems() { public Inventory(int weightLimit) {
return items; items = new ArrayList<>();
this.maxWeight = weightLimit;
} }
public void addItem(String item) { public List<ItemStack> getItems() {
items.add(item); return Collections.unmodifiableList(items);
} }
public boolean containsItem(String item) { public void addItem(ItemStack stack) {
return items.contains(item); if (stack.getWeight() + getCurrentWeight() > maxWeight) {
trySubstack(stack);
} else {
items.add(stack);
}
}
private void trySubstack(ItemStack stack) {
int stackSize = getMaxStackSize(stack);
if (stackSize == 0) return;
items.add(new ItemStack(stack.getItem(), stackSize));
}
private int getMaxStackSize(ItemStack stack) {
int weight = stack.getItem().getWeight();
int maxSize = (maxWeight - getCurrentWeight()) / weight;
return Math.min(maxSize, stack.getQuantity());
}
public int getCurrentWeight() {
int currentWeight = 0;
for (ItemStack stack : items) {
currentWeight += stack.getWeight();
}
return currentWeight;
} }
} }

View File

@@ -0,0 +1,5 @@
package Inventory;
public interface InventoryHolder {
Inventory getInventory();
}

View File

@@ -0,0 +1,45 @@
package Item;
public class AttributeModifier {
private int maxHpMod;
private int maxMpMod;
private int strMod;
private int magicStrMod;
private int defMod;
private int magicDefMod;
public AttributeModifier(int maxHpMod, int maxMpMod, int strMod, int magicStrMod, int defMod, int magicDefMod) {
this.maxHpMod = maxHpMod;
this.maxMpMod = maxMpMod;
this.strMod = strMod;
this.magicStrMod = magicStrMod;
this.defMod = defMod;
this.magicDefMod = magicDefMod;
}
public int getMaxHpMod() {
return maxHpMod;
}
public int getMaxMpMod() {
return maxMpMod;
}
public int getStrMod() {
return strMod;
}
public int getMagicStrMod() {
return magicStrMod;
}
public int getDefMod() {
return defMod;
}
public int getMagicDefMod() {
return magicDefMod;
}
@Override
public String toString() {
return "" + maxHpMod + maxMpMod + strMod + magicStrMod + defMod + magicDefMod;
}
}

View File

@@ -0,0 +1,17 @@
package Item;
public record BasicItem(String id, String name, int weight) implements Item {
@Override
public String getId() {
return id;
}
@Override
public String getName() {
return name;
}
@Override
public int getWeight() {
return weight;
}
}

View File

@@ -0,0 +1,25 @@
package Item;
public class BodyArmour extends EquipmentType{
private String name;
private AttributeModifier modifiers;
public BodyArmour(String name, AttributeModifier modifiers) {
this.name = name;
this.modifiers = new AttributeModifier(modifiers.getMaxHpMod(), modifiers.getMaxMpMod(), modifiers.getStrMod(), modifiers.getMagicStrMod(), modifiers.getDefMod()*2, modifiers.getMagicDefMod()*2);
}
public String getName() {
return name;
}
public AttributeModifier getModifiers() {
return modifiers;
}
@Override
public String toString() {
return name + modifiers;
}
}

View File

@@ -0,0 +1,55 @@
package Item;
import Job.Job;
public class Equipment implements Item {
private String id;
private String name;
private EquipmentType equipmentType;
private Job equipable;
private int slot;
public Equipment(String id, String name, EquipmentType equipmentType, Job equipable, int slot) {
this.id = id;
this.name = name;
this.equipable = equipable;
this.equipmentType = equipmentType;
this.slot = slot;
}
@Override
public String getId() {
return id;
}
@Override
public String getName() {
return name;
}
@Override
public int getWeight() {
return 0;
}
public EquipmentType getEquipmentType() {
return equipmentType;
}
public Job getEquipable() {
return equipable;
}
public int getSlot() {
return slot;
}
public boolean equals(Equipment e) {
return name.equals(e.getName()) && equipmentType.toString().equals(e.getEquipmentType().toString());
}
}

View File

@@ -0,0 +1,11 @@
package Item;
public abstract class EquipmentType {
public String name;
public AttributeModifier attributeModifier;
public abstract String getName();
public abstract String toString();
public abstract AttributeModifier getModifiers();
}

View File

@@ -0,0 +1,7 @@
package Item;
public interface Item {
String getId();
String getName();
int getWeight();
}

View File

@@ -0,0 +1,20 @@
package Item;
public record ItemStack(Item item, int quantity) {
public ItemStack {
if (quantity <= 0) {
throw new IllegalArgumentException("Quantity must be greater than zero.");
}
}
public Item getItem() {
return item;
}
public int getQuantity() {
return quantity;
}
public int getWeight() {
return item.getWeight() * quantity;
}
}

View File

@@ -0,0 +1,25 @@
package Item;
public class MageHat extends EquipmentType{
private String name;
private AttributeModifier modifiers;
public MageHat(String name, AttributeModifier modifiers) {
this.name = name;
this.modifiers = new AttributeModifier(modifiers.getMaxHpMod(), modifiers.getMaxMpMod(), modifiers.getStrMod(), modifiers.getMagicStrMod()*2, modifiers.getDefMod(), modifiers.getMagicDefMod()*2);
}
public String getName() {
return name;
}
public AttributeModifier getModifiers() {
return modifiers;
}
@Override
public String toString() {
return name + modifiers;
}
}

View File

@@ -3,8 +3,6 @@ package Job;
import Shared.ExperienceTable; import Shared.ExperienceTable;
import Shared.Levelable; import Shared.Levelable;
import java.util.Objects;
public abstract class Job implements Levelable { public abstract class Job implements Levelable {
protected int level; protected int level;
protected int experience; protected int experience;
@@ -43,21 +41,4 @@ public abstract class Job implements Levelable {
level++; level++;
} }
@Override
public String toString() {
return String.format("Job: %s. Level: %d", name, level);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
return o != null && getClass() == o.getClass();
}
@Override
public int hashCode() {
return Objects.hash(name);
}
} }

View File

@@ -1,6 +1,6 @@
package Job; package Job;
public interface HasJob { public interface JobHolder {
Job getJob(); Job getJob();
void learnJob(Job job); void learnJob(Job job);
} }

View File

@@ -0,0 +1,8 @@
package Job;
public class Knight extends Job{
public Knight() {
super("Knight");
}
}

View File

@@ -1,17 +1,24 @@
package Job; package Job;
import Action.Actor; import Inventory.InventoryHolder;
import Inventory.HasInventory; import Item.ItemStack;
import Terrain.Biome;
public class Miner extends Job { public class Miner extends Job {
public Miner() { InventoryHolder actor;
public Miner(InventoryHolder actor) {
super("Miner"); super("Miner");
this.actor = actor;
} }
public void dig(Actor actor) { public InventoryHolder getActor() {
if (actor instanceof HasInventory a) { return actor;
a.getInventory().addItem("Stone"); }
}
public void dig(Biome biome) {
var item = biome.getLootTable().roll();
actor.getInventory().addItem(new ItemStack(item, 1));
} }
} }

View File

@@ -6,7 +6,10 @@ import Combat.OffensiveDamageSpell;
import Entity.Entity; import Entity.Entity;
import Inventory.HasSpellBook; import Inventory.HasSpellBook;
import Combat.Spell; import Combat.Spell;
import Entity.Position;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner; import java.util.Scanner;
public class Wizard extends Job { public class Wizard extends Job {
@@ -22,7 +25,7 @@ public class Wizard extends Job {
public void learnSpell(Actor actor) { public void learnSpell(Actor actor) {
if(actor instanceof HasSpellBook a ) { if(actor instanceof HasSpellBook a ) {
OffensiveDamageSpell defaultSpell = new OffensiveDamageSpell("fireball", 20, 20); OffensiveDamageSpell defaultSpell = new OffensiveDamageSpell("fireball", 20, 1,20);
a.getSpellBook().add(defaultSpell); a.getSpellBook().add(defaultSpell);
} }
} }
@@ -48,9 +51,10 @@ public class Wizard extends Job {
} }
Spell spell = spellbook.getSpellBook().get(spellIndex - 1); Spell spell = spellbook.getSpellBook().get(spellIndex - 1);
Entity target = selectSpellTarget(spell, entity);
if (mana.getMana() >= spell.getCost()){ if (mana.getMana() >= spell.getCost()){
spell.cast(entity, entity); spell.cast(entity, target);
} }
else{ else{
System.out.println("Not enough mana!"); System.out.println("Not enough mana!");
@@ -58,6 +62,36 @@ public class Wizard extends Job {
} }
} }
public Entity selectSpellTarget(Spell spell, Entity caster) {
int range = spell.getRange();
Position position = caster.getPosition();
int x = position.x();
int y = position.y();
List<Entity> acceptableTargets = new LinkedList<>();
for(Entity entity : Entity.getEntities()) {
if(x + range >= entity.getPosition().x() && x - range <= entity.getPosition().x()) {
if(y + range >= entity.getPosition().y() && y - range <= entity.getPosition().y()) {
acceptableTargets.add(entity);
}
}
}
System.out.println("Who do you want to target with the spell?");
for(int i = 0; i < acceptableTargets.size(); i++){
System.out.println((i + 1) + ". " + acceptableTargets.get(i).toString());
}
int EntityIndex = scanner.nextInt();
scanner.nextLine();
if(EntityIndex < 1 || EntityIndex > acceptableTargets.size()) {
System.out.println("Invalid choice!");
return null;
}
return acceptableTargets.get(EntityIndex - 1);
}
@Override @Override
public int getExperience() { public int getExperience() {
return experience; return experience;

View File

@@ -0,0 +1,11 @@
package Shared;
import java.util.Random;
public class DefaultRandomProvider implements RandomProvider {
private final Random random = new Random();
@Override
public int nextInt(int bound) {
return random.nextInt(bound);
}
}

View File

@@ -0,0 +1,4 @@
package Shared;
public record LootEntry<T>(T item, int weight) {
}

View File

@@ -0,0 +1,53 @@
package Shared;
import java.util.ArrayList;
import java.util.List;
public class LootTable<T> {
private RandomProvider random;
private final List<LootEntry<T>> entries = new ArrayList<>();
public LootTable() {
this.random = new DefaultRandomProvider();
}
public LootTable(List<LootEntry<T>> entries) {
this.random = new DefaultRandomProvider();
this.entries.addAll(entries);
}
public void setRandomProvider(RandomProvider random) {
this.random = random;
}
public LootTable(RandomProvider random) {
this.random = random;
}
public void addEntry(T entry, int weight) {
entries.add(new LootEntry<>(entry,weight));
}
public T roll() {
int totalWeight = entries.stream().mapToInt(LootEntry::weight).sum();
int roll = random.nextInt(totalWeight);
int current = 0;
for(LootEntry<T> entry : entries) {
current += entry.weight();
if (roll < current) {
return entry.item();
}
}
// Unreachable code. entries always have an entry or the class cant be instantiated.
// Cant put system into this state.
// only have a return here due to compiler requiring it.
return null;
}
public List<LootEntry<T>> getEntries() {
return entries;
}
}

View File

@@ -0,0 +1,5 @@
package Shared;
public interface RandomProvider {
int nextInt(int bound);
}

View File

@@ -0,0 +1,51 @@
package Terrain;
import Item.BasicItem;
import Item.Item;
import Shared.LootEntry;
import Shared.LootTable;
import java.util.ArrayList;
import java.util.List;
public enum Biome {
GRASSLAND("Grassland", new LootTable<>(new ArrayList<>(List.of(
new LootEntry<>(new BasicItem("mud", "Mud", 10), 10),
new LootEntry<>(new BasicItem("earth_root", "Earth Root", 5), 50),
new LootEntry<>(new BasicItem("crystal_core", "Crystal core", 20), 180)
)) {
})),
MOUNTAIN("Mountain", new LootTable<>(new ArrayList<>(List.of(
new LootEntry<>(new BasicItem("rock", "Rock", 50), 10),
new LootEntry<>(new BasicItem("iron", "Iron", 80), 50),
new LootEntry<>(new BasicItem("diamond", "Diamond", 8), 180)
)) {
})),
COAST("Coast", new LootTable<>(new ArrayList<>(List.of(
new LootEntry<>(new BasicItem("sand", "Sand", 1), 10),
new LootEntry<>(new BasicItem("shell", "Shell", 4), 50),
new LootEntry<>(new BasicItem("sandfish", "Sandfish", 11), 180)
)) {
})),
FOREST("Forest", new LootTable<>(new ArrayList<>(List.of(
new LootEntry<>(new BasicItem("moss", "Moss", 7 ), 10),
new LootEntry<>(new BasicItem("fairy_rock", "Fairy rock", 89), 50),
new LootEntry<>(new BasicItem("unicorn_horn", "Unicorn horn", 18), 230)
)) {
}));
private final String name;
private final LootTable<? extends Item> lootTable;
Biome(String name, LootTable<? extends Item> lootTable) {
this.name = name;
this.lootTable = lootTable;
}
public String getName() {
return name;
}
public LootTable<? extends Item> getLootTable() {
return lootTable;
}
}

View File

@@ -0,0 +1,14 @@
import Terrain.Biome;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class BiomeTest {
@Test
void instantiates_with_name() {
var biome = Biome.COAST;
assertEquals("Coast", biome.getName());
}
}

View File

@@ -0,0 +1,38 @@
import Action.DigAction;
import Entity.Player;
import Job.Miner;
import Terrain.Biome;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;
public class DigActionTest {
@Test
void can_be_executed_as_miner() {
var mockMiner = mock(Miner.class);
var player = mock(Player.class);
when(player.getJob()).thenReturn(mockMiner);
var biome = mock(Biome.class);
var action = new DigAction(biome);
action.execute(player);
verify(mockMiner, times(1)).dig(biome);
}
@Test
void digging_when_not_miner_throws_error() {
var player = mock(Player.class);
when(player.getJob()).thenReturn(null);
var biome = mock(Biome.class);
var action = new DigAction(biome);
assertThrows(IllegalStateException.class, () -> action.execute(player));
}
@Test
void digging_when_not_have_job_throws_error() {
var player = mock(Player.class);
var biome = mock(Biome.class);
var action = new DigAction(biome);
assertThrows(IllegalStateException.class, () -> action.execute(player));
}
}

188
src/test/java/EPTest.java Normal file
View File

@@ -0,0 +1,188 @@
import Combat.OffensiveDamageSpell;
import Entity.Entity;
import Entity.Player;
import Job.Wizard;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayInputStream;
import java.util.Scanner;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import static org.junit.jupiter.api.Assertions.*;
public class EPTest {
private Wizard wizard;
@BeforeEach
public void setup() {
wizard = new Wizard();
}
@BeforeEach
public void cleanup() {
Entity.getEntities().clear();
}
@Test
public void testCastSpell_successfulCast() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n1\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Gandalf", wizard);
player.setMana(50);
player.setHealth(100);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 1,15);
player.getSpellBook().add(fireball);
int initialMana = player.getMana();
wizard.castSpell(player);
assertThat(player.getMana(), is(initialMana - fireball.getCost()));
}
@Test
public void testCastSpell_notEnoughMana() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n1\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Merlin", wizard);
player.setMana(10);
player.setHealth(100);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 1,15);
player.getSpellBook().add(fireball);
int initialMana = player.getMana();
wizard.castSpell(player);
assertThat(player.getMana(), is(initialMana));
}
@Test
public void testCastSpell_indexOverBoundary() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("2\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Brick", wizard);
player.setMana(50);
player.setHealth(100);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 1, 15);
player.getSpellBook().add(fireball);
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
wizard.castSpell(player);
String output = outContent.toString();
assertTrue(output.contains("Invalid choice!"));
} finally {
System.setOut(originalOut);
}
}
@Test
public void testCastSpell_indexUnderBoundary() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("0\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Brick", wizard);
player.setMana(50);
player.setHealth(100);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 1, 15);
player.getSpellBook().add(fireball);
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
wizard.castSpell(player);
String output = outContent.toString();
assertTrue(output.contains("Invalid choice!"));
} finally {
System.setOut(originalOut);
}
}
@Test
public void select_spell_target_index_over_boundry() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n2\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Alfon", wizard);
player.setMana(50);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 1, 15);
player.getSpellBook().add(fireball);
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
wizard.castSpell(player);
String output = outContent.toString();
assertTrue(output.contains("Invalid choice!"));
} finally {
System.setOut(originalOut);
}
}
@Test
public void select_spell_target_index_under_boundry() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n0\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Alfon", wizard);
player.setMana(50);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 1, 15);
player.getSpellBook().add(fireball);
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
wizard.castSpell(player);
String output = outContent.toString();
assertTrue(output.contains("Invalid choice!"));
} finally {
System.setOut(originalOut);
}
}
@Test
public void cant_cast_spell_with_empty_spellbook() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("2\n".getBytes()));
wizard = new Wizard(testScanner);
Player player = new Player("Brick", wizard);
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outContent));
try {
wizard.castSpell(player);
String output = outContent.toString();
assertTrue(output.contains("You haven't learned any spells"));
} finally {
System.setOut(originalOut);
}
}
}

View File

@@ -0,0 +1,193 @@
import Entity.Player;
import Item.MageHat;
import Job.Wizard;
import Job.Knight;
import org.junit.jupiter.api.Test;
import Item.Equipment;
import Item.BodyArmour;
import Item.AttributeModifier;
import static org.junit.jupiter.api.Assertions.*;
public class EquipmentTest {
private Knight knight = new Knight();
private Wizard wizard = new Wizard();
private Player defaultWizard(){
return new Player("name", wizard);
}
private Equipment defaultBodyArmour() {
AttributeModifier a = new AttributeModifier(4,8,7,1,2,8);
BodyArmour b = new BodyArmour("Body Armour", a);
return new Equipment("5", "Thornmail", b, knight, 2);
}
private Equipment defaultMageHat() {
AttributeModifier a = new AttributeModifier(4,8,2,10,2,8);
MageHat b = new MageHat("Mage Hat", a);
return new Equipment("6", "Deathmage Cap", b, wizard, 1);
}
@Test
void setIdOnCreation(){
var e = defaultBodyArmour();
assertEquals(defaultBodyArmour().getId(), e.getId(), "Equipment id should have been set");
}
@Test
void setNameOnCreation() {
var e = defaultBodyArmour();
assertEquals("Thornmail", e.getName(), "Equipment name should have been set");
}
@Test
void setEquipmentWeightOnCreation() {
var e = defaultBodyArmour();
assertEquals(defaultBodyArmour().getWeight(), e.getWeight(), "Equipment weight should have been set");
}
@Test
void setBodyArmourTypeOnCreation() {
var e = defaultBodyArmour();
assertEquals("Body Armour", e.getEquipmentType().getName(), "Equipment type should have been set");
}
@Test
void setMageHatTypeOnCreation() {
var e = defaultMageHat();
assertEquals("Mage Hat", e.getEquipmentType().getName(), "Equipment type should have been set");
}
@Test
void setSlotOnCreation() {
var e = defaultBodyArmour();
assertEquals(2, e.getSlot(), "Equipment slot should have been set");
}
@Test
void setMaxHpModOnCreation() {
var e = defaultBodyArmour();
assertEquals(4, e.getEquipmentType().getModifiers().getMaxHpMod(), "Equipment max hp modifier should have been set");
}
@Test
void setMaxMpModOnCreation() {
var e = defaultBodyArmour();
assertEquals(8, e.getEquipmentType().getModifiers().getMaxMpMod(), "Equipment max mp modifier should have been set");
}
@Test
void setStrModOnCreation() {
var e = defaultBodyArmour();
assertEquals(7, e.getEquipmentType().getModifiers().getStrMod(), "Equipment strength modifier should have been set");
}
@Test
void setMagicStrModOnCreation() {
var e = defaultBodyArmour();
assertEquals(1, e.getEquipmentType().getModifiers().getMagicStrMod(), "Equipment magic strength modifier should have been set");
}
@Test
void setDefModOnCreation() {
var e = defaultBodyArmour();
assertEquals(4, e.getEquipmentType().getModifiers().getDefMod(), "Equipment defence modifier should have been set");
}
@Test
void setMagicDefModOnCreation() {
var e = defaultBodyArmour();
assertEquals(16, e.getEquipmentType().getModifiers().getMagicDefMod(), "Equipment magic defence modifier should have been set");
}
@Test
void canEquipWithRightJob() {
var p = defaultWizard();
p.equip(defaultMageHat());
assertTrue(p.getEquipments().get(defaultMageHat().getSlot()).equals(defaultMageHat()), "Wizard can equip wizard hat");
}
@Test
void canNotEquipWithWrongJob() {
var p = defaultWizard();
IllegalStateException exception = assertThrows(
IllegalStateException.class,
() -> p.equip(defaultBodyArmour())
);
assertTrue(exception.getMessage().contains("A player with this job can not equip this equipment"));
}
@Test
void canNotEquipAlreadyEquippedSlot() {
AttributeModifier a = new AttributeModifier(2,2,2,2,2,8);
MageHat b = new MageHat("Mage Hat", a);
Equipment e = new Equipment("7", "Mage hat2", b, wizard, 1);
var p = defaultWizard();
p.equip(defaultMageHat());
IllegalStateException exception = assertThrows(
IllegalStateException.class,
() -> p.equip(e)
);
assertTrue(exception.getMessage().contains("Equipment slot already filled"));
}
@Test
void bodyArmourToString() {
AttributeModifier a = new AttributeModifier(1,1,1,1,1,1);
BodyArmour b = new BodyArmour("Body Armour", a);
assertEquals("Body Armour111122", b.toString(), "Equipment name should have been set");
}
@Test
void mageHatToString() {
AttributeModifier a = new AttributeModifier(1,1,1,1,1,1);
MageHat b = new MageHat("Mage Hat", a);
assertEquals("Mage Hat111212", b.toString(), "Equipment name should have been set");
}
@Test
void equipmentModifiesPlayerHealth() {
var p = defaultWizard();
p.setHealth(100);
p.equip(defaultMageHat());
assertEquals(104, p.getHealth(), "Equipment modifies health");
}
@Test
void equipmentModifiesPlayerMana() {
var p = defaultWizard();
p.setMana(30);
p.equip(defaultMageHat());
assertEquals(38, p.getMana(), "Equipment modifies mana");
}
@Test
void equipmentModifiesPlayerStrength() {
var p = defaultWizard();
p.equip(defaultMageHat());
assertEquals(2, p.getStrength(), "Equipment modifies strength");
}
@Test
void equipmentModifiesPlayerMagicStrength() {
var p = defaultWizard();
p.equip(defaultMageHat());
assertEquals(20, p.getMagicStrength(), "Equipment modifies magic strength");
}
@Test
void equipmentModifiesPlayerDefence() {
var p = defaultWizard();
p.equip(defaultMageHat());
assertEquals(2, p.getDefence(), "Equipment modifies defence");
}
@Test
void equipmentModifiesPlayerMagicDefence() {
var p = defaultWizard();
p.equip(defaultMageHat());assertEquals(16, p.getMagicDefence() , "Equipment modifies magic defence");
}
}

View File

@@ -1,4 +1,9 @@
import Combat.OffensiveDamageSpell; import Combat.OffensiveDamageSpell;
import Combat.OffensiveStatusSpell;
import Entity.Position;
import Entity.Entity;
import Entity.Player; import Entity.Player;
import Job.Wizard; import Job.Wizard;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@@ -10,7 +15,6 @@ import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
public class InterestingTests { public class InterestingTests {
private Wizard wizard; private Wizard wizard;
@@ -20,46 +24,42 @@ public class InterestingTests {
wizard = new Wizard(); wizard = new Wizard();
} }
@Test @BeforeEach
public void testCastSpell_successfulCast() { public void cleanup() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n".getBytes())); Entity.getEntities().clear();
wizard = new Wizard(testScanner);
Player player = new Player("Gandalf", wizard);
player.setMana(50);
player.setHealth(100);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 15);
player.getSpellBook().add(fireball);
int initialMana = player.getMana();
int initialHealth = player.getHealth();
wizard.castSpell(player);
assertThat(player.getMana(), is(initialMana - fireball.getCost()));
assertThat(player.getHealth(), is(initialHealth - fireball.getPotency()));
} }
@Test @Test
public void testCastSpell_notEnoughMana() { public void condition_spell_adds_condition() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n".getBytes())); Scanner testScanner = new Scanner(new ByteArrayInputStream("1\n1\n".getBytes()));
wizard = new Wizard(testScanner); wizard = new Wizard(testScanner);
Player player = new Player("Merlin", wizard); Player player = new Player("Alfon", wizard);
player.setMana(10); player.setMana(50);
player.setHealth(100);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 15); OffensiveStatusSpell poisonSpray = new OffensiveStatusSpell("poisonSpray", 20, 1, "Poison");
player.getSpellBook().add(fireball); player.getSpellBook().add(poisonSpray);
int initialMana = player.getMana();
int initialHealth = player.getHealth();
wizard.castSpell(player); wizard.castSpell(player);
assertThat(player.getConditions().contains("Poison"), is(true));
}
assertThat(player.getMana(), is(initialMana)); @Test
assertThat(player.getHealth(),is(initialHealth)); public void select_spell_target_returns_correct_target() {
Scanner testScanner = new Scanner(new ByteArrayInputStream("2\n".getBytes()));
wizard = new Wizard(testScanner);
Position position = new Position(1,1);
Player player = new Player("Alfon", wizard);
Player player2 = new Player("Bob", wizard);
player.setMana(50);
player2.moveTo(position);
OffensiveDamageSpell fireball = new OffensiveDamageSpell("Fireball", 20, 1, 20);
player.getSpellBook().add(fireball);
Entity target = wizard.selectSpellTarget(fireball, player);
assertThat(target, is(player2));
} }
} }

View File

@@ -0,0 +1,78 @@
import Inventory.Inventory;
import Item.BasicItem;
import Item.ItemStack;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
public class InventoryTest {
@Test
void can_add_item_to_inventory() {
var inventory = new Inventory();
var item = new BasicItem("iron_sword", "Iron Sword", 5);
inventory.addItem(new ItemStack(item, 1));
assertThat(inventory.getItems(), hasItem(
hasProperty("item",
hasProperty("id", equalTo("iron_sword"))
)
));
}
@Test
void can_add_quantity_to_inventory() {
var inventory = new Inventory();
var item = new BasicItem("iron_sword", "Iron Sword", 5);
var stack = new ItemStack(item, 5);
inventory.addItem(stack);
assertThat(inventory.getItems(), hasItem(
allOf(
hasProperty("item",
hasProperty("id", equalTo("iron_sword"))),
hasProperty("quantity", equalTo(5))
)
));
}
@Test
void item_can_not_be_added_if_above_weight_limit() {
var inventory = new Inventory(5);
var item = new BasicItem("iron_sword", "Iron Sword", 10);
var stack = new ItemStack(item, 1);
inventory.addItem(stack);
assertThat(inventory.getItems().size(), is(0));
}
@Test
void add_substack_if_item_fits() {
var inventory = new Inventory(5);
var item = new BasicItem("sand_grain", "Sand Grain", 1);
var stack = new ItemStack(item, 8);
inventory.addItem(stack);
assertThat(inventory.getItems(), hasItem(allOf(
hasProperty("item", (
hasProperty("id", equalTo("sand_grain"))
)),
hasProperty("quantity", equalTo(5)))
));
}
@Test
void current_weight_is_zero_if_no_item_is_added() {
var inventory = new Inventory(5);
assertThat(inventory.getCurrentWeight(), is(0));
}
@Test
void current_weight_calculates_correctly() {
var inventory = new Inventory(10);
var item = new BasicItem("iron_sword", "Iron Sword", 5);
var item2 = new BasicItem("berry", "Berry", 1);
inventory.addItem(new ItemStack(item, 1));
inventory.addItem(new ItemStack(item2, 2));
assertThat(inventory.getCurrentWeight(), is(7));
}
}

View File

@@ -0,0 +1,29 @@
import Item.BasicItem;
import Item.ItemStack;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class ItemStackTest {
@Test
void instantiated_with_no_quantity_throws_exception() {
assertThrows(IllegalArgumentException.class, () -> new ItemStack(
new BasicItem("id", "name", 5), 0
));
}
@Test
void instantiated_with_negative_quantity_throws_exception() {
assertThrows(IllegalArgumentException.class, () -> new ItemStack(
new BasicItem("id", "name", 5), -4
));
}
@Test
void can_be_created_with_positive_quantity() {
var i = new ItemStack(new BasicItem("id", "name", 5), 5);
assertThat(i, instanceOf(ItemStack.class));
}
}

View File

@@ -0,0 +1,27 @@
import Item.BasicItem;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ItemTest {
private BasicItem item() {
return new BasicItem("item_id", "item", 5);
}
@Test
void instantiates_with_id() {
var i = item();
assertEquals("item_id", i.getId());
}
@Test
void instantiate_with_name() {
var item = item();
assertEquals("item", item.getName());
}
@Test
void instantiates_with_weight() {
var i = item();
assertEquals(5, i.getWeight());
}
}

View File

@@ -0,0 +1,45 @@
import Shared.LootTable;
import Shared.RandomProvider;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class LootTableTest {
LootTable<String> defaultLootTable() {
LootTable<String> lootTable = new LootTable<>();
lootTable.addEntry("Stone", 90);
lootTable.addEntry("Iron", 10);
return lootTable;
}
@Test
void instantiates_as_empty() {
LootTable<String> lootTable = new LootTable<>();
assertThat(lootTable.getEntries().size(), is(0));
}
@Test
void returns_an_item_was_added() {
LootTable<String> loot = defaultLootTable();
String result = loot.roll();
assertThat(result, anyOf(equalTo("Stone"), equalTo("Iron")));
}
@Test
void respects_weight_when_rolling() {
var mockRandomProvider = mock(RandomProvider.class);
when(mockRandomProvider.nextInt(anyInt())).thenReturn(94);
LootTable<String> loot = new LootTable<>(mockRandomProvider);
loot.addEntry("Stone", 90);
loot.addEntry("Iron", 10);
String result = loot.roll();
assertThat(result, equalTo("Iron"));
}
}

View File

@@ -4,6 +4,10 @@ import Combat.OffensiveDamageSpell;
import Entity.Player; import Entity.Player;
import Job.Wizard; import Job.Wizard;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
public class MagicSystemTest { public class MagicSystemTest {
@@ -34,7 +38,7 @@ public class MagicSystemTest {
} }
@Test void damage_spell_damages_target(){ @Test void damage_spell_damages_target(){
var defaultSpell = new OffensiveDamageSpell("fireball", 20, 20); var defaultSpell = new OffensiveDamageSpell("fireball", 20, 1, 20);
var p = defaultPlayer(); var p = defaultPlayer();
p.setMana(30); p.setMana(30);
p.setHealth(30); p.setHealth(30);
@@ -43,7 +47,7 @@ public class MagicSystemTest {
} }
@Test void damage_spell_drains_mana_from_caster(){ @Test void damage_spell_drains_mana_from_caster(){
var defaultSpell = new OffensiveDamageSpell("fireball", 20, 20); var defaultSpell = new OffensiveDamageSpell("fireball", 20, 1, 20);
var p = defaultPlayer(); var p = defaultPlayer();
p.setMana(30); p.setMana(30);
p.setHealth(30); p.setHealth(30);
@@ -52,10 +56,22 @@ public class MagicSystemTest {
} }
@Test void cant_cast_spell_with_empty_spellbook(){ @Test void cant_cast_spell_with_empty_spellbook(){
var p = defaultPlayer(); ByteArrayOutputStream outContent = new ByteArrayOutputStream();
var job = new Wizard(); PrintStream OriginalOut = System.out;
p.learnJob(job); System.setOut(new PrintStream(outContent));
p.performAction(new CastAction());
try {
var p = defaultPlayer();
var job = new Wizard();
p.learnJob(job);
p.performAction(new CastAction());
String output = outContent.toString();
assertTrue(output.contains("You haven't learned any spells"));
} finally {
System.setOut(OriginalOut);
}
} }
}
}

View File

@@ -1,46 +1,87 @@
import Action.DigAction;
import Entity.Player;
import Inventory.Inventory;
import Job.Miner; import Job.Miner;
import Shared.RandomProvider;
import Terrain.Biome;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.*;
public class MinerTest { public class MinerTest {
private Player defaultPlayer() {return new Player("John"); }
@Test @Test
void can_level_up() { void can_level_up() {
var job = new Miner(); var job = new Miner(defaultPlayer());
assertEquals(1, job.getLevel()); assertEquals(1, job.getLevel());
job.levelUp(); job.levelUp();
assertEquals(2, job.getLevel()); assertEquals(2, job.getLevel());
} }
@Test
void can_be_created_with_player() {
var miner = new Miner(defaultPlayer());
assertThat(miner.getActor(), equalTo(defaultPlayer()));
}
@Test @Test
void can_gain_xp() { void can_gain_xp() {
var job = new Miner(); var job = new Miner(defaultPlayer());
job.gainExperience(25); job.gainExperience(25);
assertEquals(25, job.getExperience()); assertEquals(25, job.getExperience());
} }
@Test @Test
void level_up_when_experience_cap_is_reached() { void level_up_when_experience_cap_is_reached() {
var job = new Miner(); Miner job = new Miner(defaultPlayer());
job.gainExperience(job.remainingXpUntilLevelUp()); job.gainExperience(job.remainingXpUntilLevelUp());
assertEquals(2, job.getLevel()); assertEquals(2, job.getLevel());
} }
@Test @Test
void additional_xp_carries_over_on_level_up() { void additional_xp_carries_over_on_level_up() {
var job = new Miner(); var job = new Miner(defaultPlayer());
job.gainExperience(job.remainingXpUntilLevelUp() + 10); job.gainExperience(job.remainingXpUntilLevelUp() + 10);
assertEquals(10, job.getExperience()); assertEquals(10, job.getExperience());
} }
@Test
void dig_in_coast_use_coast_loot() {
RandomProvider random = mock(RandomProvider.class);
when(random.nextInt(anyInt())).thenReturn(9);
var job = new Miner(defaultPlayer());
Biome.COAST.getLootTable().setRandomProvider(random);
job.dig(Biome.COAST);
assertThat(job.getActor().getInventory().getItems(), hasItem(
hasProperty("item", hasProperty("id", equalTo("sand")))));
}
@Test @Test
void dig_on_ice_require_ice_pick() { void dig_in_mountain_use_mountain_loot() {
RandomProvider random = mock(RandomProvider.class);
when(random.nextInt(anyInt())).thenReturn(15);
var job = new Miner(defaultPlayer());
Biome.MOUNTAIN.getLootTable().setRandomProvider(random);
job.dig(Biome.MOUNTAIN);
assertThat(job.getActor().getInventory().getItems(), hasItem(
hasProperty("item",
hasProperty("id", equalTo("iron")))
)
);
} }
@Test
void dig_use_workers_inventory() {
var mockInventory = mock(Inventory.class);
var miner = new Miner(new Player("John", mockInventory));
miner.dig(Biome.MOUNTAIN);
verify(mockInventory).addItem(any());
}
} }

View File

@@ -2,18 +2,31 @@ import Action.DigAction;
import Action.LearnSpellAction; import Action.LearnSpellAction;
import Combat.OffensiveDamageSpell; import Combat.OffensiveDamageSpell;
import Entity.Position; import Entity.Position;
import Inventory.Inventory;
import Job.Miner; import Job.Miner;
import Entity.Player; import Entity.Player;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import Job.Wizard; import Job.Wizard;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
class PlayerTest { class PlayerTest {
private Player defaultPlayer() { private Player defaultPlayer() {
return new Player("abc"); return new Player("abc");
} }
@Test
void player_can_be_created_with_job_and_inventory() {
var job = mock(Miner.class);
var inventory = mock(Inventory.class);
var player = new Player("abc", job, inventory);
assertThat(player, instanceOf(Player.class));
}
@Test @Test
public void is_dead_if_health_is_zero() { public void is_dead_if_health_is_zero() {
var p = defaultPlayer(); var p = defaultPlayer();
@@ -21,18 +34,42 @@ class PlayerTest {
assertFalse(p.isAlive()); assertFalse(p.isAlive());
} }
@Test void get_health_returns_health() { @Test
public void is_alive_if_has_health() {
var p = defaultPlayer();
p.setHealth(10);
assertTrue(p.isAlive());
}
@Test
void get_health_returns_health() {
var p = defaultPlayer(); var p = defaultPlayer();
p.setHealth(10); p.setHealth(10);
assertEquals(10, p.getHealth()); assertEquals(10, p.getHealth());
} }
@Test void get_mana_returns_mana() { @Test
void get_mana_returns_mana() {
var p = defaultPlayer(); var p = defaultPlayer();
p.setMana(10); p.setMana(10);
assertEquals(10, p.getMana()); assertEquals(10, p.getMana());
} }
@Test
void get_conditions_returns_conditions() {
var p = defaultPlayer();
p.addCondition("Poison");
assertTrue(p.getConditions().contains("Poison"));
}
@Test
void remove_condition_removes_condition() {
var p = defaultPlayer();
p.addCondition("Poison");
p.removeCondition("Poison");
assertFalse(p.getConditions().contains("Poison"));
}
@Test @Test
public void can_change_position() { public void can_change_position() {
var p = defaultPlayer(); var p = defaultPlayer();
@@ -40,29 +77,72 @@ class PlayerTest {
assertEquals(new Position(1,1), p.getPosition()); assertEquals(new Position(1,1), p.getPosition());
} }
@Test
public void can_not_walk_two_spaces_y() {
var p = defaultPlayer();
p.moveTo(new Position(1,2));
assertEquals(new Position(0,0), p.getPosition());
}
@Test
public void can_not_walk_two_spaces_x() {
var p = defaultPlayer();
p.moveTo(new Position(2,1));
assertEquals(new Position(0,0), p.getPosition());
}
@Test
void can_not_walk_two_spaces_y_negative() {
var p = defaultPlayer();
p.setPosition(new Position(3,3));
p.moveTo(new Position(1,3));
assertEquals(new Position(3,3), p.getPosition());
}
@Test
void can_not_walk_two_spaces_x_negative() {
var p = defaultPlayer();
p.setPosition(new Position(3,3));
p.moveTo(new Position(3,1));
assertEquals(new Position(3,3), p.getPosition());
}
@Test @Test
public void can_change_job() { public void can_change_job() {
var p = defaultPlayer(); var p = defaultPlayer();
assertNull(p.getJob()); assertNull(p.getJob());
var job = new Miner(); var job = new Miner(p);
p.learnJob(job); p.learnJob(job);
assertEquals(new Miner(), p.getJob()); assertThat(p.getJob(), instanceOf(Miner.class));
} }
@Test @Test
void miner_can_dig() { void miner_can_dig() {
var p = new Player("John"); var p = new Player("John");
p.learnJob(new Miner()); p.learnJob(new Miner(p));
p.performAction(new DigAction()); var mockAction = mock(DigAction.class);
assertTrue(p.getInventory().containsItem("Stone")); p.performAction(mockAction);
verify(mockAction, times(1)).execute(p);
}
@Test
void miner_can_dig_multiple_times() {
var p = new Player("John");
p.learnJob(new Miner(p));
var mockAction = mock(DigAction.class);
for(int i = 0; i < 10; i++) {
p.performAction(mockAction);
}
verify(mockAction, times(10)).execute(p);
} }
@Test @Test
void wizard_can_learn_spell() { void wizard_can_learn_spell() {
var p = new Player("Bob"); var p = new Player("Bob");
var job = new Wizard(); var job = new Wizard();
var defaultSpell = new OffensiveDamageSpell("fireball", 20, 20); var defaultSpell = new OffensiveDamageSpell("fireball", 20, 1, 20);
p.learnJob(job); p.learnJob(job);
p.performAction(new LearnSpellAction()); p.performAction(new LearnSpellAction());
System.out.println(p.getSpellBook()); System.out.println(p.getSpellBook());

View File

@@ -1,4 +1,5 @@
import Combat.OffensiveDamageSpell; import Combat.OffensiveDamageSpell;
import Combat.OffensiveStatusSpell;
import Combat.Spell; import Combat.Spell;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -7,8 +8,9 @@ import static org.junit.jupiter.api.Assertions.*;
public class SpellTest { public class SpellTest {
private Spell defaultSpell() { private Spell defaultSpell() {
return new OffensiveDamageSpell("fireball", 20, 40); return new OffensiveDamageSpell("fireball", 20, 1, 40);
} }
private Spell statusSpell() {return new OffensiveStatusSpell("poisonSpray", 20, 1, "Poison");}
@Test @Test
void setSpellNameOnCreation(){ void setSpellNameOnCreation(){
@@ -25,6 +27,12 @@ public class SpellTest {
@Test @Test
void setPotencyOnCreation() { void setPotencyOnCreation() {
var spell = defaultSpell(); var spell = defaultSpell();
assertEquals(40, spell.getPotency(), "spell potency should have been set"); assertEquals(40, ((OffensiveDamageSpell) spell).getPotency(), "spell potency should have been set");
}
@Test
void setConditionOnCreation() {
var spell = statusSpell();
assertEquals("Poison", ((OffensiveStatusSpell) spell).getStatus(), "spell status should have been set");
} }
} }