// TODO: Equipped weapons usage
package vee;
import vee.animation.Animatable;
import java.awt.Graphics;
import java.util.ArrayList;
import vee.types.DamageType;
import java.util.EnumMap;
import vee.animation.Moveable;
import vee.items.Equipment;
import vee.items.Item;
import vee.items.armors.Armor;
import vee.types.GenderType;
public abstract class Character implements Attackable, Weaponise, Animatable, Moveable {
protected String firstName;
protected String lastName;
protected Double currentHealth;
protected Double maxHealth;
protected String title;
protected EnumMap<DamageType, Double> vulnerabilities;
protected Inventory inventory;
protected EquippedItems equipment;
protected GenderType gender;
protected int column;
protected int row;
protected int level = 1;
protected Double defenseRating = 0.0;
private int rowMovementSpeed = 0;
private int columnMovementSpeed = 0;
protected char mapCharacter;
protected Character() {
this.setDefaults();
}
protected abstract void setDefaults();
public Double getCurrentHealth() {
return this.currentHealth;
}
public void setCurrentHealth(Double health) {
if(health < 0.0) {
this.currentHealth = 0.0;
}
else if(health > this.getMaxHealth()) {
this.currentHealth = this.getMaxHealth();
}
else {
this.currentHealth = health;
}
}
public Double getMaxHealth() {
return this.maxHealth;
}
public void setMaxHealth(Double health) {
this.maxHealth = health;
}
public void increaseCurrentHealth(Double health) {
Double currentHP = this.getCurrentHealth();
this.setCurrentHealth(currentHP + health);
}
public void decreaseCurrentHealth(Double health) {
Double currentHP = this.getCurrentHealth();
this.setCurrentHealth(currentHP - health);
}
public String getFirstName() {
return firstName;
}
private void setFirstName(String name) {
this.firstName = name;
}
public String getLastName() {
return lastName;
}
private void setLastName(String name) {
this.lastName = name;
}
public String getName() {
return this.firstName + " " + this.lastName;
}
public void setName(String firstName, String lastName) {
this.setFirstName(firstName);
this.setLastName(lastName);
}
public String getTitledName() {
return this.title + " " + this.firstName + " " + this.lastName;
}
public void setTitledName(String title, String firstName, String lastName) {
this.setTitle(title);
this.setName(firstName, lastName);
}
private void setTitle(String title) {
this.title = title;
}
public String getTitle(){
return this.title;
}
public GenderType getGender() {
return this.gender;
}
public void setGender(GenderType gender) {
this.gender = gender;
}
protected void setDefense(Double defense) {
if(defense < 0.0) {
this.defenseRating = 0.0;
}
else {
this.defenseRating = defense;
}
}
protected Double getDefense() {
return this.defenseRating;
}
protected void increaseDefense(Double defense) {
this.setDefense(this.getDefense() + defense);
}
protected void decreaseDefense(Double defense) {
this.setDefense(this.getDefense() - defense);
}
protected Double getVulnerability(DamageType damageType) {
return this.vulnerabilities.get(damageType);
}
@Override
public Double beAttacked(AttackAction attack) {
Double incomingDamage = attack.getDamage();
Double damageCoefficient = this.getVulnerability(attack.getDamageType());
Double defense = this.calculateDefense();
//TODO: I really don't like this ceil crap. Surely there's something better to do?
Double actualDamageTaken = Math.ceil(incomingDamage * damageCoefficient);
System.out.println("incomingDamage: "+incomingDamage+", defense: "+defense);
if(defense <= actualDamageTaken) {
actualDamageTaken -= defense;
}
else {
actualDamageTaken = 0.0;
}
System.out.println("actualDamageTaken: "+actualDamageTaken);
this.decreaseCurrentHealth(actualDamageTaken);
return actualDamageTaken;
}
public boolean addToInventory(Item item) {
//TODO: Such error checking everywhere. We have so many ignored possible errors.
return this.inventory.addItem(item);
}
public boolean equip(Equipment equipment) {
Equipment removedEquipment = this.equipment.equip(equipment);
// Add defense bonus of new armor
if(equipment.isArmor()) {
this.increaseDefense(((Armor)equipment).getDefense());
}
if(removedEquipment == null) {
return true;
}
// Decrease defense bonus of removed armor
if(removedEquipment.isArmor()) {
this.decreaseDefense(((Armor)removedEquipment).getDefense());
}
//TODO: Fix this. We can lose an item if it fails to add to inventory.
return this.addToInventory(removedEquipment);
}
public boolean unequip(Equipment equipment) {
Equipment removedEquipment = this.equipment.unequip(equipment);
if(removedEquipment == null) {
return true;
}
// Remove defense bonus
if(removedEquipment.isArmor()) {
this.decreaseDefense(((Armor)removedEquipment).getDefense());
}
//TODO: Fix this. We can lose an item if it fails to add to inventory.
return this.addToInventory(removedEquipment);
}
public boolean isEquipped(Equipment equipment) {
return this.equipment.isEquipped(equipment);
}
public boolean inInventory(Item item) {
return this.inventory.containsItem(item);
}
public Double calculateDefense() {
return this.getDefense();
}
public int getLevel() {
return this.level;
}
public void setLevel(int level) {
this.level = level;
}
public void levelUp() {
this.setLevel(this.getLevel() + 1);
}
public int getColumn() {
return this.column;
}
public void setColumn(int column) {
this.column = column;
}
public int getRow() {
return this.row;
}
public void setRow(int row) {
this.row = row;
}
@Override
public void step() {
throw new UnsupportedOperationException("Not supported yet.");
// this.setColumn(this.getColumn() + this.getColumnVelocity());
// mRow = mRow + mRowVelocity;
//
// if (mColumn <= 0 ||
// mColumn >= (GAME_COLUMNS - Saurian.getInstance().getIconWidth())) {
// mColumnVelocity = -mColumnVelocity;
// }
//
// if (mRow <= 0 ||
// mRow >= (GAME_ROWS - Saurian.getInstance().getIconHeight())) {
// mRowVelocity = -mRowVelocity;
// }
}
@Override
public void paint(Graphics pGraphics) {
// pGraphics.setColor(Color.WHITE);
// pGraphics.fillRect(0, 0, getWidth(), getHeight());
// Saurian.getInstance().paintIcon(null, pGraphics, (int)mColumn, (int)mRow);
}
//Pretty sure these aren't necessary
@Override
public int getWidth() {
// return GAME_COLUMNS;
return 10;
}
@Override
public int getHeight() {
// return GAME_ROWS;
return 10;
}
@Override
public void moveUp() {
int currentRow = this.getRow();
int speed = this.getRowMovementSpeed();
this.setRow(currentRow + speed);
}
@Override
public void moveDown() {
int currentRow = this.getRow();
int speed = this.getRowMovementSpeed();
this.setRow(currentRow - speed);
}
@Override
public void moveLeft() {
int currentColumn = this.getColumn();
int speed = this.getColumnMovementSpeed();
this.setRow(currentColumn - speed);
}
@Override
public void moveRight() {
int currentColumn = this.getColumn();
int speed = this.getColumnMovementSpeed();
this.setRow(currentColumn + speed);
}
public int getRowMovementSpeed() {
return rowMovementSpeed;
}
public void setRowMovementSpeed(int rowMovementSpeed) {
this.rowMovementSpeed = rowMovementSpeed;
}
public int getColumnMovementSpeed() {
return columnMovementSpeed;
}
public void setColumnMovementSpeed(int columnMovementSpeed) {
this.columnMovementSpeed = columnMovementSpeed;
}
public char getMapCharacter() {
return mapCharacter;
}
public void setMapCharacter(char mapCharacter) {
this.mapCharacter = mapCharacter;
}
}