package net.alcuria.umbracraft.party;
import net.alcuria.umbracraft.Game;
import net.alcuria.umbracraft.util.O;
import net.sourceforge.jeval.EvaluationException;
import com.badlogic.gdx.utils.ObjectMap;
/** A collection of current character stats. Most of the stats are obtained via
* getters that parse the stats from the definition
* @author Andrew Keturi */
public class MemberStats {
public static enum BaseStat {
AGILITY, STRENGTH, VITALITY, WISDOM;
public String getFunc(String hero) {
O.notNull(hero);
switch (this) {
case STRENGTH:
return Game.db().hero(hero).strFunc;
case AGILITY:
return Game.db().hero(hero).agiFunc;
case VITALITY:
return Game.db().hero(hero).vitFunc;
case WISDOM:
return Game.db().hero(hero).wisFunc;
default:
return "0";
}
}
}
private ObjectMap<BaseStat, Integer> baseStats;
private int expNeeded;
private String hero;
public int hp, level, ep, maxEp, exp;
private int maxHp;
/** For deserialization */
public MemberStats() {
}
public MemberStats(String hero) {
this.hero = hero;
level = Game.db().hero(hero).startingLevel;
ep = 10;
exp = 0;
baseStats = new ObjectMap<MemberStats.BaseStat, Integer>();
expNeeded = parse(Game.db().config().expNeededFunc);
maxHp = parse(Game.db().config().maxHpFunc);
hp = maxHp;
}
/** Increments the member's level, updating exp and needed exp */
public void awardExp(long amount) {
exp += amount;
while (exp >= expNeeded) {
level++;
exp -= expNeeded;
if (exp < 0) {
exp = 0;
}
expNeeded = parse(Game.db().config().expNeededFunc);
Game.log(Game.db().hero(hero).name + " reached level " + level + " | " + exp + "/" + expNeeded);
}
}
/** @return exp needed. The expression is parsed on-call to calculate, so it's
* probably a good idea to cache the result if it needs to be called
* often. */
public int getExpNeeded() {
expNeeded = parse(Game.db().config().expNeededFunc);
return expNeeded;
}
/** @return the character's max hp. The expression is parsed on-call to
* calculate, so it's probably a good idea to cache the result if it
* needs to be called often. */
public int getMaxHp() {
maxHp = parse(Game.db().config().maxHpFunc);
return maxHp;
}
/** @return The {@link PartyMember}'s strength. The expression is parsed
* on-call to calculate, so it's probably a good idea to cache the
* result if it needs to be called often. */
public int getStat(BaseStat stat) {
O.notNull(baseStats);
int statVal = parse(stat.getFunc(hero));
baseStats.put(stat, statVal);
return statVal;
}
private int parse(String expression) {
try {
expression = replaceVariables(expression);
return (int) Game.eval().getNumberResult(expression);
} catch (EvaluationException | NullPointerException e) {
Game.error("Could not parse expression: " + expression);
return 0;
}
}
private String replaceVariables(String expression) {
if (!baseStats.containsKey(BaseStat.AGILITY)) {
baseStats.clear();
baseStats.put(BaseStat.STRENGTH, 0);
baseStats.put(BaseStat.AGILITY, 0);
baseStats.put(BaseStat.WISDOM, 0);
baseStats.put(BaseStat.VITALITY, 0);
for (BaseStat key : baseStats.keys()) {
baseStats.put(key, parse(key.getFunc(hero)));
}
}
int agility = baseStats.get(BaseStat.AGILITY);
int vitality = baseStats.get(BaseStat.VITALITY);
int wisdom = baseStats.get(BaseStat.WISDOM);
int strength = baseStats.get(BaseStat.WISDOM);
return expression.replace("lvl", String.valueOf(level)).replace("agi", String.valueOf(agility)).replace("vit", String.valueOf(vitality)).replace("wis", String.valueOf(wisdom)).replace("str", String.valueOf(strength));
}
}