/** * Recalc derived stats from base stats + effect bonuses */ void StatBlock::applyEffects() { // preserve hp/mp states prev_maxhp = get(STAT_HP_MAX); prev_maxmp = get(STAT_MP_MAX); pres_hp = hp; pres_mp = mp; // calculate primary stats // refresh the character menu if there has been a change if (get_physical() != physical_character + effects.bonus_physical || get_mental() != mental_character + effects.bonus_mental || get_offense() != offense_character + effects.bonus_offense || get_defense() != defense_character + effects.bonus_defense) refresh_stats = true; offense_additional = effects.bonus_offense; defense_additional = effects.bonus_defense; physical_additional = effects.bonus_physical; mental_additional = effects.bonus_mental; calcBase(); for (int i=0; i<STAT_COUNT; i++) { current[i] = base[i] + effects.bonus[i]; } for (unsigned i=0; i<effects.bonus_resist.size(); i++) { vulnerable[i] = vulnerable_base[i] - effects.bonus_resist[i]; } current[STAT_HP_MAX] += (current[STAT_HP_MAX] * current[STAT_HP_PERCENT]) / 100; current[STAT_MP_MAX] += (current[STAT_MP_MAX] * current[STAT_MP_PERCENT]) / 100; if (hp > get(STAT_HP_MAX)) hp = get(STAT_HP_MAX); if (mp > get(STAT_MP_MAX)) mp = get(STAT_MP_MAX); speed = speed_default; }
/** * Recalc derived stats from base stats * Creatures might skip these formulas. */ void StatBlock::recalc() { level = 0; for (int i=0; i<MAX_CHARACTER_LEVEL; i++) { if (xp >= xp_table[i]) level=i+1; } // TODO: move these formula numbers to an engine config file int hp_base = 10; int hp_per_level = 2; int hp_per_physical = 8; int hp_regen_base = 10; int hp_regen_per_level = 1; int hp_regen_per_physical = 4; int mp_base = 10; int mp_per_level = 2; int mp_per_mental = 8; int mp_regen_base = 10; int mp_regen_per_level = 1; int mp_regen_per_mental = 4; int accuracy_base = 75; int accuracy_per_level = 1; int accuracy_per_offense = 5; int avoidance_base = 25; int avoidance_per_level = 1; int avoidance_per_defense = 5; int crit_base = 5; int crit_per_level = 1; int lev0 = level -1; int phys0 = get_physical() -1; int ment0 = get_mental() -1; int off0 = get_offense() -1; int def0 = get_defense() -1; hp = maxhp = hp_base + (hp_per_level * lev0) + (hp_per_physical * phys0); mp = maxmp = mp_base + (mp_per_level * lev0) + (mp_per_mental * ment0); hp_per_minute = hp_regen_base + (hp_regen_per_level * lev0) + (hp_regen_per_physical * phys0); mp_per_minute = mp_regen_base + (mp_regen_per_level * lev0) + (mp_regen_per_mental * ment0); accuracy = accuracy_base + (accuracy_per_level * lev0) + (accuracy_per_offense * off0); avoidance = avoidance_base + (avoidance_per_level * lev0) + (avoidance_per_defense * def0); crit = crit_base + (crit_per_level * lev0); physoff = get_physical() + get_offense(); physdef = get_physical() + get_defense(); mentoff = get_mental() + get_offense(); mentdef = get_mental() + get_defense(); physment = get_physical() + get_mental(); offdef = get_offense() + get_defense(); int stat_sum = get_physical() + get_mental() + get_offense() + get_defense(); // determine class // if all four stats are max, Grand Master if (stat_sum >= 20) character_class = "Grand Master"; // if three stats are max, Master else if (stat_sum >= 16) character_class = "Master"; // if one attribute is much higher than the others, use the attribute class name else if (get_physical() > get_mental()+1 && get_physical() > get_offense()+1 && get_physical() > get_defense()+1) character_class = "Warrior"; else if (get_mental() > get_physical()+1 && get_mental() > get_offense()+1 && get_mental() > get_defense()+1) character_class = "Wizard"; else if (get_offense() > get_physical()+1 && get_offense() > get_mental()+1 && get_offense() > get_defense()+1) character_class = "Ranger"; else if (get_defense() > get_physical()+1 && get_defense() > get_mental()+1 && get_defense() > get_offense()+1) character_class = "Paladin"; // if there is no dominant attribute, use the dicipline class name else if (physoff > physdef && physoff > mentoff && physoff > mentdef && physoff > physment && physoff > offdef) character_class = "Rogue"; else if (physdef > physoff && physdef > mentoff && physdef > mentdef && physdef > physment && physdef > offdef) character_class = "Knight"; else if (mentoff > physoff && mentoff > physdef && mentoff > mentdef && mentoff > physment && mentoff > offdef) character_class = "Shaman"; else if (mentdef > physoff && mentdef > physdef && mentdef > mentoff && mentdef > physment && mentdef > offdef) character_class = "Cleric"; else if (physment > physoff && physment > physdef && physment > mentoff && physment > mentdef && physment > offdef) character_class = "Battle Mage"; else if (offdef > physoff && offdef > physdef && offdef > mentoff && offdef > mentdef && offdef > physment) character_class = "Heavy Archer"; // otherwise, use the generic name else character_class = "Adventurer"; }