diff options
Diffstat (limited to 'src/creature.cc')
-rw-r--r-- | src/creature.cc | 108 |
1 files changed, 68 insertions, 40 deletions
diff --git a/src/creature.cc b/src/creature.cc index 53a4994..ac616ac 100644 --- a/src/creature.cc +++ b/src/creature.cc @@ -14,9 +14,20 @@ typedef nlohmann::json json; using namespace std; namespace creature { + template<typename T> map<T, int> makeMap(map<string, int> src) { + //cout << "Got here!\n"; + map<T, int> ret; + for(auto& [abilityStr, val] : src) { + ret.insert({T(abilityStr), val}); + } + //cout << "And here!\n"; + return ret; + } + Creature::Creature(const json& data) - : inventory(json2ptrvec<entry::Item>(data["inventory"])), stats(data["stats"]), skills(data["skills"]), creatureName(data["name"]), size(data["size"]), type(data["type"]), alignment(data["alignment"]), hdCount(data["hit_die_count"]), hdSides(data["hit_die_sides"]), speed(data["speed"]), saves(data["saves"]), langs(data["langs"]), cr(data["cr"]), proficiency(data["prof"]), dmgImmunities(json2vec<dmgType>(data["d_immunities"])), dmgResistances(json2vec<dmgType>(data["d_resistances"])), dmgVulnerabilities(json2vec<dmgType>(data["d_vulnerabilities"])), condImmunities(json2vec<dmgType>(data["c_immunities"])), features(json2ptrvec<entry::Feature>(data["features"])) + : inventory(json2ptrvec<entry::Item>(data["inventory"])), stats(makeMap<rules::Ability>(data["stats"])), skills(makeMap<rules::Skill>(data["skills"])), creatureName(data["name"]), size(data["size"]), type(data["type"]), alignment(data["alignment"]), hdCount(data["hit_die_count"]), hdSides(data["hit_die_sides"]), speed(data["speed"]), saves(json2vec<rules::Ability>(data["saves"])), langs(data["langs"]), cr(data["cr"]), proficiency(data["prof"]), natArmorName(data["natural_armor"]["name"]), natArmorBonus(data["natural_armor"]["bonus"]), dmgImmunities(json2vec<dmgType>(data["d_immunities"])), dmgResistances(json2vec<dmgType>(data["d_resistances"])), dmgVulnerabilities(json2vec<dmgType>(data["d_vulnerabilities"])), condImmunities(json2vec<dmgType>(data["c_immunities"])), features(json2ptrvec<entry::Feature>(data["features"])) { + //cout << "...And here!\n"; // Initialize names and hp if(((map<string, json>) data).contains("givenName")) { givenName = data["givenName"]; @@ -24,7 +35,7 @@ namespace creature { hp = data["hp"]; } else { givenName = "Jerry"; //TODO: Autogenerate - hpMax = this->getBonus("con") * hdCount; + hpMax = this->getBonus(rules::Ability::Con()) * hdCount; for(int i = 0; i < hdCount; i++) { hpMax += roll(hdSides); } @@ -95,15 +106,15 @@ namespace creature { } } - int Creature::getSkillBonus(const string& skill) const { - int bonus = this->getBonus(rules::skill2ability[skill]); + int Creature::getSkillBonus(const rules::Skill& skill) const { + int bonus = this->getBonus(skill.getAbility()); if(skills.contains(skill)) { bonus += skills.at(skill) * getProficiency(); } return bonus; } - int Creature::getAbilitySaveBonus(const string& ability) const { + int Creature::getAbilitySaveBonus(const rules::Ability& ability) const { int bonus = this->getBonus(ability); if(find(saves.begin(), saves.end(), ability) != saves.end()) { bonus += getProficiency(); @@ -124,35 +135,40 @@ namespace creature { } } - map<string, int> Creature::getSkills() const { - map<string, int> s; + map<rules::Skill, int> Creature::getSkills() const { + map<rules::Skill, int> s; for(auto skill : skills) { - s[skill.first] = getSkillBonus(skill.first); + s.insert({skill.first, getSkillBonus(skill.first)}); } return s; } - map<string, int> Creature::getSaves() const { - map<string, int> s; + map<rules::Ability, int> Creature::getSaves() const { + map<rules::Ability, int> s; for(auto save : saves) { - s[save] = this->getBonus(save) + getProficiency(); + s.insert({save, this->getBonus(save) + getProficiency()}); } return s; } - void Creature::setScore(const string& ability, int score) { - stats[ability] = score; + void Creature::setScore(const rules::Ability& ability, int score) { + stats.insert({ability, score}); } - void Creature::setProfLevel(const string& skill, int level) { - skills[skill] = level; + void Creature::setProfLevel(const rules::Skill& skill, int level) { + skills.insert({skill, level}); } const int getAC(const Creature& c) { - int baseBonus = 10 + c.getBonus("dex"); + auto natArmor = c.getNaturalArmor(); + if(! natArmor.first.empty()) { + return natArmor.second; + } + int dex = c.getBonus(rules::Ability::Dex()); + int baseBonus = 10 + dex; int miscBonus = 0; for(auto a : getItems<entry::Armor>(c)) { - if(c.getScore("str") < a->getStrRequirement()) { + if(c.getScore(rules::Ability::Str()) < a->getStrRequirement()) { continue; } auto armorType = a->getArmorType(); @@ -161,9 +177,9 @@ namespace creature { } else { baseBonus = a->getACBonus(); if(armorType == "light") { - baseBonus += c.getBonus("dex"); + baseBonus += dex; } else if(armorType == "medium") { - baseBonus += (c.getBonus("dex") > 2)? 2 : c.getBonus("dex"); + baseBonus += (dex > 2)? 2 : dex; } } } @@ -181,19 +197,24 @@ namespace creature { string genText(const Creature& c) { stringstream text; text << c.getGivenName() << " (" << c.getCreatureName() << "): " << c.getHP() << "/" << c.getHPMax() << " hp, " << getAC(c) << " ac"; - string armor = utils::join(mapItems(creature::getItems<entry::Armor>(c)), ", "); - if(! armor.empty()) { - text << " (" << armor << ")"; + if(! c.getNaturalArmor().first.empty()) { + text << " (" << c.getNaturalArmor().first << ")"; + } else { + string armor = utils::join(mapItems(creature::getItems<entry::Armor>(c)), ", "); + if(! armor.empty()) { + text << " (" << armor << ")"; + } } text << ", speed " << c.getSpeed() << "\n"; text << "A cr " << c.getCR() << " " << c.getAlignment() << " " << c.getSize() << " " << c.getType() << ".\n"; text << "Stats:\n"; - //text << setiosflags(ios::fixed) << setw(6); - for(auto ability : rules::abilities) { - text << " " << setw(6) << std::left << ability; + using namespace rules; + vector<rules::Ability> abilities {Ability::Str(), Ability::Dex(), Ability::Con(), Ability::Int(), Ability::Wis(), Ability::Cha()}; + for(auto ability : abilities) { + text << " " << setw(6) << std::left << ability.getAbbrev(); } text << "\n"; - for(auto ability : rules::abilities) { + for(auto ability : abilities) { text << setw(7) << std::left << (to_string(c.getScore(ability)) + "(" + to_string(c.getBonus(ability)) + ")"); } text << "\n"; @@ -201,26 +222,33 @@ namespace creature { if(! c.getSenses().empty()) { text << utils::join(c.getSenses(), ", ") << ". "; } - text << "Passive Perception " << 10 + c.getBonus("wis") << "\n"; + text << "Passive Perception " << 10 + c.getSkillBonus(rules::Skill::Perception()) << "\n"; if(! c.getLanguages().empty()) { text << "Languages: " << c.getLanguages() << "\n"; } - - text << "\nSkills:\n"; - for(auto skill : c.getSkills()) { - text << skill.first << " (+" << skill.second << ")\n"; + if(! c.getSkills().empty()) { + text << "\nSkills:\n"; + for(auto skill : c.getSkills()) { + text << skill.first.getName() << " (+" << skill.second << ")\n"; + } } - text << "\nSaves:\n"; - for(auto save : c.getSaves()) { - text << save.first << " (+" << save.second << ")\n"; + if(! c.getSaves().empty()) { + text << "\nSaves:\n"; + for(auto save : c.getSaves()) { + text << save.first.getAbbrev() << " (+" << save.second << ")\n"; + } } - text << "\nFeatures:\n"; - for(auto f: c.getFeatures()) { - text << f->getText(c) << "\n"; + if(! c.getFeatures().empty()) { + text << "\nFeatures:\n"; + for(auto f: c.getFeatures()) { + text << f->getText(c) << "\n"; + } } - text << "\nInventory:\n"; - for(auto i : c.getInventory()) { - text << i->getText(c) << "\n"; + if(! c.getInventory().empty()) { + text << "\nInventory:\n"; + for(auto i : c.getInventory()) { + text << i->getText(c) << "\n"; + } } return text.str(); |