diff options
author | Your Name <you@example.com> | 2021-04-20 12:40:37 -0400 |
---|---|---|
committer | Your Name <you@example.com> | 2021-04-20 12:40:37 -0400 |
commit | cd57ad6e208728bafcbc8c7d7b85d88603706978 (patch) | |
tree | 7cb0fc9511a0e8124e497d53edbe38d646dd8299 /src | |
parent | 2cae1aa33f80ce0844fb54a84ce103146a7fe7ad (diff) | |
download | dmtool-cd57ad6e208728bafcbc8c7d7b85d88603706978.tar.gz dmtool-cd57ad6e208728bafcbc8c7d7b85d88603706978.tar.bz2 dmtool-cd57ad6e208728bafcbc8c7d7b85d88603706978.zip |
Updated natural armor and skills
Diffstat (limited to 'src')
-rw-r--r-- | src/armor.cc | 6 | ||||
-rw-r--r-- | src/creature.cc | 108 | ||||
-rw-r--r-- | src/creature.h | 26 | ||||
-rw-r--r-- | src/dmtool.cc | 27 | ||||
-rw-r--r-- | src/feature.h | 5 | ||||
-rw-r--r-- | src/item.h | 4 | ||||
-rw-r--r-- | src/jsonable.h | 1 | ||||
-rw-r--r-- | src/rules.h | 137 | ||||
-rw-r--r-- | src/spellcasting.cc | 2 | ||||
-rw-r--r-- | src/spellcasting.h | 7 | ||||
-rw-r--r-- | src/weapon.cc | 5 |
11 files changed, 214 insertions, 114 deletions
diff --git a/src/armor.cc b/src/armor.cc index e7ed323..54284c7 100644 --- a/src/armor.cc +++ b/src/armor.cc @@ -1,6 +1,7 @@ #include "armor.h" #include "creature.h" #include "entry.h" +#include "rules.h" #include <string> #include <sstream> @@ -16,10 +17,11 @@ namespace entry{ text << genText(static_cast<const Item&>(a), c); text << ": AC: " << a.getACBonus(); if(a.getArmorType() == "light") { - text << " + dex (i.e., " << (a.getACBonus() + c.getBonus("dex")) << ")"; + text << " + dex (i.e., " << (a.getACBonus() + c.getBonus(rules::Ability::Dex())) << ")"; } else if(a.getArmorType() == "medium") { int actualBonus = a.getACBonus(); - actualBonus += (c.getBonus("dex") > 2)? 2 : c.getBonus("dex"); + int dex = c.getBonus(rules::Ability::Dex()); + actualBonus += (dex > 2)? 2 : dex; text << " + dex max 2 (i.e., " << actualBonus << ")"; } if(a.getStrRequirement() > 0) { 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(); diff --git a/src/creature.h b/src/creature.h index 7327de9..1c8db21 100644 --- a/src/creature.h +++ b/src/creature.h @@ -1,6 +1,7 @@ #pragma once #include "json.hpp" #include "jsonable.h" +#include "rules.h" namespace entry { class Feature; @@ -34,10 +35,10 @@ namespace creature { virtual ~Creature() {}; // Getters - int getSkillBonus(const std::string& skill) const; - int getAbilitySaveBonus(const std::string& ability) const; - std::map<std::string, int> getSkills(void) const; - std::map<std::string, int> getSaves(void) const; + int getSkillBonus(const rules::Skill& skill) const; + int getAbilitySaveBonus(const rules::Ability& ability) const; + std::map<rules::Skill, int> getSkills(void) const; + std::map<rules::Ability, int> getSaves(void) const; // Inline getters std::string getCreatureName(void) const {return creatureName;} @@ -46,13 +47,14 @@ namespace creature { std::string getSize(void) const {return size;} std::string getAlignment(void) const {return alignment;} double getCR(void) const {return cr;} + std::pair<std::string, int> getNaturalArmor(void) const {return {natArmorName, natArmorBonus};} std::string getLanguages(void) const {return langs;} int getHP(void) const {return hp;} int getHPMax(void) const {return hpMax;} std::vector<std::string> getSenses(void) const {return senses;} std::string getSpeed(void) const {return speed;} - int getScore(const std::string& ability) const {return stats.at(ability);} - int getBonus(const std::string& ability) const {return (int) (getScore(ability) - 10) / 2;} + int getScore(const rules::Ability& ability) const {return stats.at(ability);} + int getBonus(const rules::Ability& ability) const {return (int) (getScore(ability) - 10) / 2;} int getProficiency(void) const {return proficiency;} std::vector<std::shared_ptr<entry::Feature>> getFeatures(void) const {return features;} std::vector<std::shared_ptr<entry::Item>> getInventory(void) const {return inventory;} @@ -61,8 +63,8 @@ namespace creature { // Setters (mutators) void setGivenName(std::string name) {givenName = name;} void applyDamage(int amount, const std::string& type, const std::vector<std::string>& qualifiers); - void setScore(const std::string& ability, int score); - void setProfLevel(const std::string& skill, int level); + void setScore(const rules::Ability& ability, int score); + void setProfLevel(const rules::Skill& skill, int level); void addInventoryItem(std::shared_ptr<entry::Item> item); void removeInventoryItem(const std::string& itemName); @@ -74,8 +76,8 @@ namespace creature { int hpMax; int hp; std::vector<std::shared_ptr<entry::Item>> inventory; - std::map<std::string, int> stats; - std::map<std::string, int> skills; + std::map<rules::Ability, int> stats; + std::map<rules::Skill, int> skills; //Immutable variables const std::string creatureName; @@ -85,11 +87,13 @@ namespace creature { const int hdCount; const int hdSides; const std::string speed; - const std::vector<std::string> saves; + const std::vector<rules::Ability> saves; const std::vector<std::string> senses; const std::string langs; const double cr; const int proficiency; + const std::string natArmorName; + const int natArmorBonus; const std::vector<dmgType> dmgImmunities; const std::vector<dmgType> dmgResistances; const std::vector<dmgType> dmgVulnerabilities; diff --git a/src/dmtool.cc b/src/dmtool.cc index 7f2c72c..f9d32ab 100644 --- a/src/dmtool.cc +++ b/src/dmtool.cc @@ -17,24 +17,34 @@ void usage(string exename) { cout << indDesc << "List creatures and objects.\n"; cout << indOpt << "cp old-path new-path\n"; cout << indDesc << "Copy old-path to new-path.\n"; + cout << indOpt << "mv old-path new-path\n"; + cout << indDesc << "Move old-path to new-path.\n"; cout << indOpt << "rm path\n"; cout << indDesc << "Remove existing creature, object, or directory.\n"; cout << indOpt << "roll path name\n"; cout << indDesc << "Roll a skill check, save, or attack.\n"; cout << indOpt << "damage path amount [type]\n"; cout << indDesc << "Damage creature by amount. Type defaults to \"force\".\n"; + cout << indOpt << "heal path amount\n"; + cout << indDesc << "Heal creature by amount.\n"; + cout << indOpt << "reset path\n"; + cout << indDesc << "Reset creature to full health (as if completing a long rest).\n"; cout << indOpt << "set path field value\n"; cout << indDesc << "Set a field to a new value, where field is any of:\n"; cout << indDesc << " ability (str, dex, con, int, wis, cha); value is new ability score\n"; cout << indDesc << " skill (athletics, \"sleight of hand\", etc.); value is (none|proficient|expert)\n"; - cout << indDesc << " name; value is new given name\n"; - cout << indOpt << "add path object\n"; - cout << indDesc << "Add object to creature's inventory. If it is armor or a weapon, it will automatically be equipped (if applicable)\n"; - + cout << indDesc << " name; value is new given name.\n"; + cout << indOpt << "add path entry\n"; + cout << indDesc << "Add entry to creature, where entry is an item or spell.\n"; cout << indOpt << "help\n"; cout << indDesc << "Show this help.\n"; } +void print(string path) { + creature::Creature c(utils::loadJson(path)); + cout << genText(c); +} + void list(vector<string> args) { string baseDir = settings::getString("savedir"); vector<string> listPaths; @@ -48,8 +58,7 @@ void list(vector<string> args) { for(auto listPath : listPaths) { if(fs::is_regular_file(fs::status(listPath))) { // Try loading and printing stuff about it - creature::Creature c(utils::loadJson(listPath)); - cout << genText(c); + print(listPath); } else if(fs::is_directory(fs::status(listPath))) { for(fs::directory_entry path : filesystem::directory_iterator(listPath)) { @@ -64,9 +73,12 @@ void list(vector<string> args) { } void cp(vector<string> args) {} +void mv(vector<string> args) {} void rm(vector<string> args) {} void roll(vector<string> args) {} void damage(vector<string> args) {} +void heal(vector<string> args) {} +void reset(vector<string> args) {} void set(vector<string> args) {} void add(vector<string> args) {} @@ -82,9 +94,12 @@ int main(int argc, char *argv[]) { args.erase(args.begin()); if(cmd == "ls") list(args); else if(cmd == "cp") cp(args); + else if(cmd == "mv") mv(args); else if(cmd == "rm") rm(args); else if(cmd == "roll") roll(args); else if(cmd == "damage") damage(args); + else if(cmd == "heal") heal(args); + else if(cmd == "reset") reset(args); else if(cmd == "set") set(args); else if(cmd == "add") add(args); else if(cmd == "help") usage(exename); diff --git a/src/feature.h b/src/feature.h index f3073d8..69112ea 100644 --- a/src/feature.h +++ b/src/feature.h @@ -7,10 +7,9 @@ namespace entry { class Feature : public Entry { public: static std::shared_ptr<Feature> create(const nlohmann::json& data); + virtual ~Feature() {} protected: - Feature(const nlohmann::json& data) : Entry(data) {}; + Feature(const nlohmann::json& data) : Entry(data) {} }; - - //std::string genText(const Feature& f, const creature::Creature& c); } @@ -7,15 +7,17 @@ namespace entry { class Item : public Entry { public: static std::shared_ptr<Item> create(const nlohmann::json& data); + virtual ~Item() {} protected: - Item(const nlohmann::json& data) : Entry(data) {}; + Item(const nlohmann::json& data) : Entry(data) {} }; class Substantial { public: virtual int getCost(void) const = 0; virtual double getWeight(void) const = 0; + virtual ~Substantial() {} }; std::string genText(const Substantial& s); diff --git a/src/jsonable.h b/src/jsonable.h index 4be2bec..d6866b8 100644 --- a/src/jsonable.h +++ b/src/jsonable.h @@ -8,6 +8,7 @@ class Jsonable { public: virtual nlohmann::json toJson(void) const = 0; operator nlohmann::json() const {return toJson();} + virtual ~Jsonable() {} }; template<typename T> std::vector<T> json2vec(const nlohmann::json& data) { diff --git a/src/rules.h b/src/rules.h index c1cc6e1..8b54e8d 100644 --- a/src/rules.h +++ b/src/rules.h @@ -1,57 +1,104 @@ #pragma once +#include "jsonable.h" #include <vector> #include <map> +#include <string> +#include <iostream> using namespace std; namespace rules { - static vector<string> abilities {"str", "dex", "con", "int", "wis", "cha"}; - - static map<string, string> skill2ability { - {"Athletics", "str"}, - {"Acrobatics", "dex"}, - {"Sleight of Hand", "dex"}, - {"Stealth", "dex"}, - {"Arcana", "int"}, - {"History", "int"}, - {"Investigation", "int"}, - {"Nature", "int"}, - {"Religion", "int"}, - {"Animal Handling", "wis"}, - {"Insight", "wis"}, - {"Medicine", "wis"}, - {"Perception", "wis"}, - {"Survival", "wis"}, - {"Deception", "cha"}, - {"Intimidation", "cha"}, - {"Performance", "cha"}, - {"Persuasion", "cha"} - }; + class Ability : public Jsonable { + public: + string getFull() const {return abilities.at(getAbbrev());} + string getAbbrev() const {return abbrev;} + virtual nlohmann::json toJson(void) const { + return getAbbrev(); + } + bool operator<(const Ability& rhs) const {return getAbbrev() < rhs.getAbbrev();} + bool operator==(const Ability& rhs) const {return getAbbrev() == rhs.getAbbrev();} + + Ability() {} + explicit Ability(const nlohmann::json& data) : abbrev(data) {} + + virtual ~Ability() {} - static map<string, map<string, int>> armor { - {"light", { - {"padded", 11}, - {"leather", 11}, - {"studded leather", 12} - }}, - {"medium", { - {"hide", 12}, - {"chain shirt", 13}, - {"scale mail", 14}, - {"breastplate", 14}, - {"half plate", 15} - }}, - {"heavy", { - {"ring mail", 14}, - {"chain mail", 16}, - {"splint", 17}, - {"plate", 18} - }}, - {"misc", { - {"shield", 2}, - {"ring of protection", 1} - }} + static Ability Str() {return Ability("str");} + static Ability Dex() {return Ability("dex");} + static Ability Con() {return Ability("con");} + static Ability Int() {return Ability("int");} + static Ability Wis() {return Ability("wis");} + static Ability Cha() {return Ability("cha");} + + private: + const string abbrev; + + const map<string, string> abilities { + {"str", "Strength"}, + {"dex", "Dexterity"}, + {"con", "Constitution"}, + {"int", "Intelligence"}, + {"wis", "Wisdom"}, + {"cha", "Charisma"} + }; }; + class Skill : public Jsonable { + public: + string getName() const {return name;} + Ability getAbility() const {return Ability(skill2ability.at(getName()));} + virtual nlohmann::json toJson(void) const { + return getName(); + } + bool operator<(const Skill& rhs) const {return getName() < rhs.getName();} + bool operator==(const Skill& rhs) const {return getName() == rhs.getName();} + + virtual ~Skill() {} + + static Skill Athletics() {return Skill("Athletics");} + static Skill Acrobatics() {return Skill("Acrobatics");} + static Skill SleightOfHand() {return Skill("Sleight of Hand");} + static Skill Stealth() {return Skill("Stealth");} + static Skill Arcana() {return Skill("Arcana");} + static Skill History() {return Skill("History");} + static Skill Investigation() {return Skill("Investigation");} + static Skill Nature() {return Skill("Nature");} + static Skill Religion() {return Skill("Religion");} + static Skill AnimalHandling() {return Skill("Animal Handling");} + static Skill Insight() {return Skill("Insight");} + static Skill Medicine() {return Skill("Medicine");} + static Skill Perception() {return Skill("Perception");} + static Skill Survival() {return Skill("Survival");} + static Skill Deception() {return Skill("Deception");} + static Skill Intimidation() {return Skill("Intimidation");} + static Skill Performance() {return Skill("Performance");} + static Skill Persuasion() {return Skill("Persuasion");} + + explicit Skill(const nlohmann::json& data) : name(data) {} + + private: + const string name; + + const map<string, string> skill2ability { + {"Athletics", "str"}, + {"Acrobatics", "dex"}, + {"Sleight of Hand", "dex"}, + {"Stealth", "dex"}, + {"Arcana", "int"}, + {"History", "int"}, + {"Investigation", "int"}, + {"Nature", "int"}, + {"Religion", "int"}, + {"Animal Handling", "wis"}, + {"Insight", "wis"}, + {"Medicine", "wis"}, + {"Perception", "wis"}, + {"Survival", "wis"}, + {"Deception", "cha"}, + {"Intimidation", "cha"}, + {"Performance", "cha"}, + {"Persuasion", "cha"} + }; + }; } diff --git a/src/spellcasting.cc b/src/spellcasting.cc index 62af6de..e36fd5b 100644 --- a/src/spellcasting.cc +++ b/src/spellcasting.cc @@ -33,7 +33,7 @@ namespace entry { string genText(const Spellcasting& s, const creature::Creature& c) { stringstream text; text << genText(static_cast<const Feature&>(s), c); - text << ": Spellcasting ability: " << s.getAbility(); + text << ": Spellcasting ability: " << s.getAbility().getFull(); text << " (spell save DC " << 8 + c.getBonus(s.getAbility()) + c.getProficiency(); text << ", +" << c.getBonus(s.getAbility()) + c.getProficiency() << " to hit with spell attacks)."; if(s.isInnate()) { diff --git a/src/spellcasting.h b/src/spellcasting.h index 0ea235c..654a386 100644 --- a/src/spellcasting.h +++ b/src/spellcasting.h @@ -3,6 +3,7 @@ #include "json.hpp" #include "spell.h" #include "jsonable.h" +#include "rules.h" typedef nlohmann::json json; @@ -23,11 +24,11 @@ namespace entry { class Spellcasting : public Feature { public: - Spellcasting(const json& data, const json& base) : Feature(base), innate(data["innate"]), ability(data["spellcasting_ability"]), spellsBySlot(json2vec<SlotLevel>(data["levels"])) {} + Spellcasting(const json& data, const json& base) : Feature(base), innate(data["innate"]), ability(rules::Ability(data["spellcasting_ability"])), spellsBySlot(json2vec<SlotLevel>(data["levels"])) {} virtual ~Spellcasting() {} bool isInnate(void) const {return innate;} - std::string getAbility(void) const {return ability;} + rules::Ability getAbility(void) const {return ability;} std::vector<SlotLevel> getSpellsBySlot(void) const {return spellsBySlot;} virtual std::string getText(const creature::Creature& c) const; @@ -41,7 +42,7 @@ namespace entry { private: const bool innate; - const std::string ability; + const rules::Ability ability; const std::vector<SlotLevel> spellsBySlot; }; diff --git a/src/weapon.cc b/src/weapon.cc index 3a42e80..af75736 100644 --- a/src/weapon.cc +++ b/src/weapon.cc @@ -1,5 +1,6 @@ #include "weapon.h" #include "creature.h" +#include "rules.h" #include <string> #include <sstream> #include <algorithm> @@ -22,9 +23,9 @@ namespace entry { stringstream text; text << genText(static_cast<const Item&>(w), c); // Determine best ability bonus - int abilityBonus = c.getBonus("str"); + int abilityBonus = c.getBonus(rules::Ability::Str()); if(w.getProperties().count("finesse")) { - abilityBonus = max(abilityBonus, c.getBonus("dex")); + abilityBonus = max(abilityBonus, c.getBonus(rules::Ability::Dex())); } text << ": +" << abilityBonus + c.getProficiency() << " to hit, "; if(w.getReach() > 0) { |