diff options
author | Your Name <you@example.com> | 2021-05-09 13:56:46 -0400 |
---|---|---|
committer | Your Name <you@example.com> | 2021-05-09 13:56:46 -0400 |
commit | d13358b71ec15085f2638fd9c3fc634df62dfc94 (patch) | |
tree | 467c643a068bf2d83da3632823a6434244ae004e /src | |
parent | e3aaa68a2ea1a403256150121c57a0287014162f (diff) | |
download | dmtool-d13358b71ec15085f2638fd9c3fc634df62dfc94.tar.gz dmtool-d13358b71ec15085f2638fd9c3fc634df62dfc94.tar.bz2 dmtool-d13358b71ec15085f2638fd9c3fc634df62dfc94.zip |
Reduced dependency on json-related hacks
Diffstat (limited to 'src')
-rw-r--r-- | src/armor.cc | 10 | ||||
-rw-r--r-- | src/armor.h | 15 | ||||
-rw-r--r-- | src/creature.cc | 120 | ||||
-rw-r--r-- | src/creature.h | 90 | ||||
-rw-r--r-- | src/creature_data.h | 28 | ||||
-rw-r--r-- | src/entry.cc | 4 | ||||
-rw-r--r-- | src/entry.h | 6 | ||||
-rw-r--r-- | src/jsonable.h | 17 | ||||
-rw-r--r-- | src/rules.h | 49 | ||||
-rw-r--r-- | src/spellcasting.cc | 4 | ||||
-rw-r--r-- | src/spellcasting.h | 6 | ||||
-rw-r--r-- | src/utils.h | 18 | ||||
-rw-r--r-- | src/weapon.cc | 4 |
13 files changed, 183 insertions, 188 deletions
diff --git a/src/armor.cc b/src/armor.cc index 85c5bc2..ecf8c1e 100644 --- a/src/armor.cc +++ b/src/armor.cc @@ -31,13 +31,13 @@ namespace entry{ } - string genText(const Armor& a, const creature::Creature& c) { + string Armor::getText(const creature::Creature& c) const { stringstream text; - text << genText(static_cast<const Item&>(a), c); + text << getName() << " (" << getType() << "): "; int dex = c.getBonus(rules::Ability::Dex()); - string dexBonusLight = " (i.e., " + to_string(a.getACBonus() + dex) + ")"; - string dexBonusMedium = " (i.e., " + to_string(a.getACBonus() + ((dex > 2)? 2 : dex)) + ")"; - text << ": " << getTextHelper(a, dexBonusLight, dexBonusMedium); + string dexBonusLight = " (i.e., " + to_string(getACBonus() + dex) + ")"; + string dexBonusMedium = " (i.e., " + to_string(getACBonus() + ((dex > 2)? 2 : dex)) + ")"; + text << getTextHelper(*this, dexBonusLight, dexBonusMedium); return text.str(); } } diff --git a/src/armor.h b/src/armor.h index 0d148b7..c059093 100644 --- a/src/armor.h +++ b/src/armor.h @@ -5,8 +5,6 @@ namespace entry { class Armor; - std::string genText(const Armor& a, const creature::Creature& c); - class Armor : public Item , public Substantial { public: Armor(const nlohmann::json& data, const nlohmann::json& base) : Item(base), acBonus(data["ac"]), armorType(data["armor_type"]), strRequirement(data["strength"]), stealthDis(data["disadvantage"]), cost(data["cost"]), weight(data["weight"]) {} @@ -19,18 +17,7 @@ namespace entry { double getWeight(void) const {return weight;} virtual std::string getText() const override; - virtual std::string getText(const creature::Creature& c) const override {return genText(*this, c);} - - /*virtual nlohmann::json toJson(void) const { - auto data = Item::toJson(); - data["ac"] = acBonus; - data["type"] = armorType; - data["strength"] = strRequirement; - data["disadvantage"] = stealthDis; - data["cost"] = cost; - data["weight"] = weight; - return data; - }*/ + virtual std::string getText(const creature::Creature& c) const override; private: const int acBonus; diff --git a/src/creature.cc b/src/creature.cc index dcd2324..d4cf8c4 100644 --- a/src/creature.cc +++ b/src/creature.cc @@ -16,16 +16,8 @@ typedef nlohmann::json json; using namespace std; namespace creature { - template<typename T> map<T, int> makeMap(map<string, int> src) { - map<T, int> ret; - for(auto& [abilityStr, val] : src) { - ret.insert({T(abilityStr), val}); - } - return ret; - } - Creature::Creature(const json& data, const json& base) - : Entry(base), inventory(utils::json2ptrvec<entry::Item>(data["inventory"])), stats(makeMap<rules::Ability>(data["stats"])), skills(makeMap<rules::Skill>(data["skills"])), proficiency(data["prof"]), size(data["size"]), alignment(data["alignment"]), hdCount(data["hit_die_count"]), hdSides(data["hit_die_sides"]), speed(data["speed"]), saves(utils::json2vec<rules::Ability>(data["saves"])), langs(data["langs"]), cr(data["cr"]), natArmorName(data["natural_armor"]["name"]), natArmorBonus(data["natural_armor"]["bonus"]), dmgImmunities(utils::json2vec<dmgType>(data["d_immunities"])), dmgResistances(utils::json2vec<dmgType>(data["d_resistances"])), dmgVulnerabilities(utils::json2vec<dmgType>(data["d_vulnerabilities"])), condImmunities(utils::json2vec<dmgType>(data["c_immunities"])), features(utils::json2ptrvec<entry::Feature>(data["features"])) + : Entry(base), inventory(data["inventory"]), stats(data["stats"]), skills(data["skills"]), prof(data["prof"]), size(data["size"]), alignment(data["alignment"]), hit_die_count(data["hit_die_count"]), hit_die_sides(data["hit_die_sides"]), speed(data["speed"]), saves(data["saves"]), langs(data["langs"]), cr(data["cr"]), observant(data["observant"]), natural_armor(data["natural_armor"]), d_immunities(data["d_immunities"]), d_resistances(data["d_resistances"]), d_vulnerabilities(data["d_vulnerabilities"]), c_immunities(data["c_immunities"]), features(data["features"]) { // Initialize names and hp if(((map<string, json>) data).contains("givenName")) { @@ -34,9 +26,9 @@ namespace creature { hp = data["hp"]; } else { givenName = "Jerry"; //TODO: Autogenerate - hpMax = this->getBonus(rules::Ability::Con()) * hdCount; - for(int i = 0; i < hdCount; i++) { - hpMax += dice::roll(hdSides); + hpMax = this->getBonus(rules::Ability::Con()) * hit_die_count; + for(int i = 0; i < hit_die_count; i++) { + hpMax += dice::roll(hit_die_sides); } hp = hpMax; } @@ -46,26 +38,26 @@ namespace creature { nlohmann::json data = Entry::toJson(); data["size"] = size; data["alignment"] = alignment; - data["hit_die_count"] = hdCount; - data["hit_die_sides"] = hdSides; + data["hit_die_count"] = hit_die_count; + data["hit_die_sides"] = hit_die_sides; data["speed"] = speed; data["stats"] = stats; data["skills"] = skills; data["saves"] = saves; data["langs"] = langs; data["cr"] = cr; - data["prof"] = proficiency; - data["natural_armor"]["name"] = natArmorName; - data["natural_armor"]["bonus"] = natArmorBonus; - data["d_immunities"] = dmgImmunities; - data["d_resistances"] = dmgResistances; - data["d_vulnerabilities"] = dmgVulnerabilities; - data["c_immunities"] = condImmunities; + data["observant"] = observant; + data["prof"] = prof; + data["natural_armor"] = natural_armor; + data["d_immunities"] = d_immunities; + data["d_resistances"] = d_resistances; + data["d_vulnerabilities"] = d_vulnerabilities; + data["c_immunities"] = c_immunities; data["givenName"] = givenName; data["hpMax"] = hpMax; data["hp"] = hp; - data["inventory"] = utils::ptrvec2json(inventory); - data["features"] = utils::ptrvec2json(features); + data["inventory"] = inventory; + data["features"] = features; return data; } @@ -86,10 +78,10 @@ namespace creature { } void Creature::applyDamage(int amount, const string& type, const vector<rules::Qualifier>& qualifiers) { - if(! conditionApplies(type, qualifiers, dmgImmunities)) { - if(conditionApplies(type, qualifiers, dmgResistances)) { + if(! conditionApplies(type, qualifiers, getDmgImmunities())) { + if(conditionApplies(type, qualifiers, getDmgResistances())) { hp -= amount / 2; - } else if(conditionApplies(type, qualifiers, dmgVulnerabilities)) { + } else if(conditionApplies(type, qualifiers, getDmgVulnerabilities())) { hp -= amount * 2; } else { hp -= amount; @@ -190,8 +182,8 @@ namespace creature { stats[ability] = score; if(ability == rules::Ability::Con()) { int delta = getBonus(ability) - initBonus; - hpMax += delta * hdCount; - hp += delta * hdCount; + hpMax += delta * hit_die_count; + hp += delta * hit_die_count; } } @@ -208,8 +200,8 @@ namespace creature { const int getAC(const Creature& c) { auto natArmor = c.getNaturalArmor(); - if(! natArmor.first.empty()) { - return natArmor.second; + if(! natArmor.name.empty()) { + return natArmor.bonus; } int dex = c.getBonus(rules::Ability::Dex()); int baseBonus = 10 + dex; @@ -271,19 +263,19 @@ namespace creature { return title + ": " + utils::join(dmgTypes2text(dmg), "; "); } - string genText(const Creature& c) { + string Creature::getText() const { stringstream text; - text << c.getGivenName() << " (" << c.getCreatureName() << "): " << c.getHP() << "/" << c.getHPMax() << " hp, " << getAC(c) << " ac"; - if(! c.getNaturalArmor().first.empty()) { - text << " (" << c.getNaturalArmor().first << ")"; + text << getGivenName() << " (" << getCreatureName() << "): " << getHP() << "/" << getHPMax() << " hp, " << getAC(*this) << " ac"; + if(! getNaturalArmor().name.empty()) { + text << " (" << getNaturalArmor().name << ")"; } else { - string armor = utils::join(mapItems(utils::castPtrs<entry::Item, entry::Armor>(c.getInventory())), ", "); + string armor = utils::join(mapItems(utils::castPtrs<entry::Item, entry::Armor>(getInventory())), ", "); if(! armor.empty()) { text << " (" << armor << ")"; } } - text << ", speed " << c.getSpeed() << endl; - text << "A cr " << c.getCR() << " " << c.getAlignment() << " " << c.getSize() << " " << c.getType() << "." << endl; + text << ", speed " << getSpeed() << endl; + text << "A cr " << getCR() << " " << getAlignment() << " " << getSize() << " " << getType() << "." << endl; text << "Stats:" << endl; using namespace rules; vector<rules::Ability> abilities {Ability::Str(), Ability::Dex(), Ability::Con(), Ability::Int(), Ability::Wis(), Ability::Cha()}; @@ -292,56 +284,56 @@ namespace creature { } text << endl; for(auto ability : abilities) { - text << setw(7) << std::left << (to_string(c.getScore(ability)) + "(" + to_string(c.getBonus(ability)) + ")"); + text << setw(7) << std::left << (to_string(getScore(ability)) + "(" + to_string(getBonus(ability)) + ")"); } text << endl; text << "Senses: "; - if(! c.getSenses().empty()) { - text << utils::join(c.getSenses(), ", ") << ". "; + if(! getSenses().empty()) { + text << utils::join(getSenses(), ", ") << ". "; } - text << "Passive Perception " << 10 + c.getSkillBonus(rules::Skill::Perception()) << endl; - if(! c.getLanguages().empty()) { - text << "Languages: " << c.getLanguages() << endl; + text << "Passive Perception " << 10 + getSkillBonus(rules::Skill::Perception()) << endl; + if(! getLanguages().empty()) { + text << "Languages: " << getLanguages() << endl; } - text << "Proficiency: " << c.getProficiency() << endl; - if(! c.getSkills().empty()) { + text << "Proficiency: " << getProficiency() << endl; + if(! getSkills().empty()) { text << endl << "Skills:" << endl; - for(auto skill : c.getSkills()) { + for(auto skill : getSkills()) { text << " * " << skill.first.getName() << " (+" << skill.second << ")" << endl; } } - if(! c.getSaves().empty()) { + if(! getSaves().empty()) { text << endl << "Saves:" << endl; - for(auto save : c.getSaves()) { + for(auto save : getSaves()) { text << " * " << save.first.getAbbrev() << " (+" << save.second << ")" << endl; } } - if(! c.getDmgImmunities().empty()) { - text << formatDmgTypeVector("\nDamage Immunities", c.getDmgImmunities()) << endl; + if(! getDmgImmunities().empty()) { + text << formatDmgTypeVector("\nDamage Immunities", getDmgImmunities()) << endl; } - if(! c.getDmgResistances().empty()) { - text << formatDmgTypeVector("\nDamage Resistances", c.getDmgResistances()) << endl; + if(! getDmgResistances().empty()) { + text << formatDmgTypeVector("\nDamage Resistances", getDmgResistances()) << endl; } - if(! c.getDmgVulnerabilities().empty()) { - text << formatDmgTypeVector("\nDamage Vulnerabilities", c.getDmgVulnerabilities()) << endl; + if(! getDmgVulnerabilities().empty()) { + text << formatDmgTypeVector("\nDamage Vulnerabilities", getDmgVulnerabilities()) << endl; } - if(! c.getCondImmunities().empty()) { - text << formatDmgTypeVector("\nCondition Immunities", c.getCondImmunities()) << endl; + if(! getCondImmunities().empty()) { + text << formatDmgTypeVector("\nCondition Immunities", getCondImmunities()) << endl; } - if(! c.getFeatures().empty()) { + if(! getFeatures().empty()) { text << endl << "Features:" << endl; - for(auto f: c.getFeatures()) { - text << " * " << f->getText(c) << endl; + for(auto f: getFeatures()) { + text << " * " << f->getText(*this) << endl; } } - if(! c.getInventory().empty()) { + if(! getInventory().empty()) { text << endl << "Inventory:" << endl; - for(auto i : c.getInventory()) { - text << " * " << i->getText(c) << endl; + for(auto i : getInventory()) { + text << " * " << i->getText(*this) << endl; } } - if(! c.Entry::getText().empty()) { - text << endl << c.Entry::getText() << endl; + if(! Entry::getText().empty()) { + text << endl << Entry::getText() << endl; } return text.str(); diff --git a/src/creature.h b/src/creature.h index 0970f04..6e0d226 100644 --- a/src/creature.h +++ b/src/creature.h @@ -19,32 +19,27 @@ typedef nlohmann::json json; namespace creature { class Creature; - class dmgType : public Jsonable { - public: - dmgType(const json& data) : type(data["type"]), qualifiers(utils::json2vec<rules::Qualifier>(data["qualifiers"])) {} - std::string type; - std::vector<rules::Qualifier> qualifiers; - std::string getText() const { - if(qualifiers.empty()) { - return type; - } - return utils::join(qualifiers, ", ") + " " + type; - } - json toJson(void) const { - return json({ - {"type", type}, - {"qualifiers", qualifiers} - }); + struct dmgType { + std::string type; + std::vector<rules::Qualifier> qualifiers; + std::string getText() const { + if(qualifiers.empty()) { + return type; } + return utils::join(qualifiers, ", ") + " " + type; + } + }; + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(dmgType, type, qualifiers); + struct NatArmor { + std::string name; + int bonus; }; + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(NatArmor, name, bonus); // Convenience function to calculate AC const int getAC(const Creature& c); - // Convenience function to spit out everything about it - std::string genText(const Creature& c); - class Creature : public entry::Entry { public: Creature(const json& data, const json& base); @@ -57,16 +52,15 @@ namespace creature { std::map<rules::Ability, int> getSaves(void) const; //Override getText - virtual std::string getText() const override {return genText(*this);} + virtual std::string getText() const override; // Inline getters std::string getCreatureName(void) const {return getName();} std::string getGivenName(void) const {return givenName;} - //std::string getType(void) const {return getType();} 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};} + NatArmor getNaturalArmor(void) const {return natural_armor;} std::string getLanguages(void) const {return langs;} int getHP(void) const {return hp;} int getHPMax(void) const {return hpMax;} @@ -74,14 +68,14 @@ namespace creature { std::string getSpeed(void) const {return speed;} int getScore(const rules::Ability& ability) const {return stats.at(ability);} int getBonus(const rules::Ability& ability) const {return std::floor((getScore(ability) - 10) / 2.0);} - int getProficiency(void) const {return proficiency;} + int getProficiency(void) const {return prof;} std::vector<std::shared_ptr<entry::Feature>> getFeatures(void) const {return features;} std::shared_ptr<entry::Spellcasting> getSpellcasting(void) const; std::vector<std::shared_ptr<entry::Item>> getInventory(void) const {return inventory;} - std::vector<dmgType> getDmgImmunities(void) const {return dmgImmunities;} - std::vector<dmgType> getDmgResistances(void) const {return dmgResistances;} - std::vector<dmgType> getDmgVulnerabilities(void) const {return dmgVulnerabilities;} - std::vector<dmgType> getCondImmunities(void) const {return condImmunities;} + std::vector<dmgType> getDmgImmunities(void) const {return d_immunities;} + std::vector<dmgType> getDmgResistances(void) const {return d_resistances;} + std::vector<dmgType> getDmgVulnerabilities(void) const {return d_vulnerabilities;} + std::vector<dmgType> getCondImmunities(void) const {return c_immunities;} // Setters (mutators) @@ -90,7 +84,7 @@ namespace creature { void applyHealing(int amount); void setScore(const rules::Ability& ability, int score); void setProfLevel(const rules::Skill& skill, int level); - void setProficiency(int prof) {proficiency = prof;} + void setProficiency(int p) {prof = p;} void addInventoryItem(std::shared_ptr<entry::Item> item); void addSpell(std::shared_ptr<entry::Spell> spell); void removeSpell(std::shared_ptr<entry::Spell> spell); @@ -100,34 +94,30 @@ namespace creature { virtual json toJson(void) const; private: - // Mutable variables + std::string givenName; int hpMax; int hp; std::vector<std::shared_ptr<entry::Item>> inventory; std::map<rules::Ability, int> stats; std::map<rules::Skill, int> skills; - int proficiency; - - //Immutable variables - //const std::string creatureName; - const std::string size; - //const std::string type; - const std::string alignment; - const int hdCount; - const int hdSides; - const std::string speed; - const std::vector<rules::Ability> saves; - const std::vector<std::string> senses; - const std::string langs; - const double cr; - const std::string natArmorName; - const int natArmorBonus; - const std::vector<dmgType> dmgImmunities; - const std::vector<dmgType> dmgResistances; - const std::vector<dmgType> dmgVulnerabilities; - const std::vector<dmgType> condImmunities; - const std::vector<std::shared_ptr<entry::Feature>> features; + int prof; + std::string size; + std::string alignment; + int hit_die_count; + int hit_die_sides; + std::string speed; + std::vector<rules::Ability> saves; + std::vector<std::string> senses; + std::string langs; + double cr; + bool observant; + NatArmor natural_armor; + std::vector<dmgType> d_immunities; + std::vector<dmgType> d_resistances; + std::vector<dmgType> d_vulnerabilities; + std::vector<dmgType> c_immunities; + std::vector<std::shared_ptr<entry::Feature>> features; }; diff --git a/src/creature_data.h b/src/creature_data.h new file mode 100644 index 0000000..151a84c --- /dev/null +++ b/src/creature_data.h @@ -0,0 +1,28 @@ +namespace creatue { + struct Creature_Data { + std::string givenName; + int hpMax; + int hp; + std::vector<std::shared_ptr<entry::Item>> inventory; + std::map<rules::Ability, int> stats; + std::map<rules::Skill, int> skills; + int proficiency; + std::string size; + std::string alignment; + int hdCount; + int hdSides; + std::string speed; + std::vector<rules::Ability> saves; + std::vector<std::string> senses; + std::string langs; + double cr; + bool observant; + std::string natArmorName; + int natArmorBonus; + std::vector<dmgType> dmgImmunities; + std::vector<dmgType> dmgResistances; + std::vector<dmgType> dmgVulnerabilities; + std::vector<dmgType> condImmunities; + std::vector<std::shared_ptr<entry::Feature>> features; + }; +} diff --git a/src/entry.cc b/src/entry.cc index ef2ec96..31ffb92 100644 --- a/src/entry.cc +++ b/src/entry.cc @@ -22,7 +22,7 @@ namespace entry { } - std::string genText(const Entry& e, const creature::Creature& c) { + /*std::string genText(const Entry& e, const creature::Creature& c) { return e.getName() + " (" + e.getType() + ")"; - } + }*/ } diff --git a/src/entry.h b/src/entry.h index c745097..efc402b 100644 --- a/src/entry.h +++ b/src/entry.h @@ -10,9 +10,6 @@ namespace creature { namespace entry { class Entry; - // Set up default text generation - std::string genText(const Entry& e, const creature::Creature& c); - class Entry : public Jsonable { public: static std::shared_ptr<Entry> create(const nlohmann::json& data); @@ -23,8 +20,7 @@ namespace entry { virtual std::string getText(void) const {return text;} void setText(std::string t) {text = t;} virtual std::string getText(const creature::Creature& c) const { - //return genText(*this, c); - return genText(*this, c) + ": " + getText(); + return getName() + " (" + getType() + "): " + getText(); } virtual nlohmann::json toJson(void) const { diff --git a/src/jsonable.h b/src/jsonable.h index 7411efa..01c720b 100644 --- a/src/jsonable.h +++ b/src/jsonable.h @@ -1,5 +1,7 @@ #pragma once #include "json.hpp" +#include <memory> +#include <vector> class Jsonable { public: @@ -7,3 +9,18 @@ class Jsonable { operator nlohmann::json() const {return toJson();} virtual ~Jsonable() {} }; + +namespace nlohmann { + template <typename T> struct adl_serializer<std::shared_ptr<T>> { + static void to_json(json& j, const std::shared_ptr<T>& opt) { + if(opt) { + j = *opt; + } else { + j = nullptr; + } + } + static void from_json(const json& j, std::shared_ptr<T>& opt) { + opt = std::shared_ptr<T>(T::create(j)); + } + }; +} diff --git a/src/rules.h b/src/rules.h index c1b130d..83d471f 100644 --- a/src/rules.h +++ b/src/rules.h @@ -10,23 +10,34 @@ namespace rules { - class Ability : public Jsonable { + class RuleItem { + public: + friend void to_json(nlohmann::json& j, const RuleItem& ri) { + j = ri.payload; + } + friend void from_json(const nlohmann::json& j, RuleItem& ri) { + ri.payload = j; + } + std::string getPayload(void) const {return payload;} + protected: + std::string payload; + }; + + class Ability : public RuleItem { public: std::string getFull() const {return abilities.at(getAbbrev());} - std::string getAbbrev() const {return abbrev;} + std::string getAbbrev() const {return getPayload();} operator std::string() const {return getAbbrev();} - 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();} operator bool() const {return ! getAbbrev().empty();} Ability() {} - explicit Ability(const nlohmann::json& data) : abbrev(data) { + Ability(const std::string& abbrev) { if(! abilities.contains(abbrev)) { throw std::invalid_argument("No such ability: " + abbrev); } + payload = abbrev; } virtual ~Ability() {} @@ -50,19 +61,14 @@ namespace rules { } private: - const std::string abbrev; - static const std::map<std::string, std::string> abilities; }; - class Skill : public Jsonable { + class Skill : public RuleItem { public: - std::string getName() const {return name;} + std::string getName() const {return getPayload();} Ability getAbility() const {return Ability(skill2ability.at(getName()));} operator std::string() const {return 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();} operator bool() const {return ! getName().empty();} @@ -89,10 +95,11 @@ namespace rules { static Skill Persuasion() {return Skill("Persuasion");} Skill() {}; - explicit Skill(const nlohmann::json& data) : name(data) { + Skill(const std::string& name) { if(! skill2ability.contains(name)) { throw std::invalid_argument("No such skill: " + name); } + payload = name; } static Skill fromString(std::string s) { @@ -108,25 +115,21 @@ namespace rules { } private: - const std::string name; - static const std::map<std::string, std::string> skill2ability; }; - class Qualifier : public Jsonable { + class Qualifier : public RuleItem { public: Qualifier() {} - Qualifier(const nlohmann::json& data) : negative(data) { + Qualifier(const std::string& negative) { if(! negative2positive.contains(negative)) { throw std::invalid_argument("No such qualifier: " + negative); } + payload = negative; } - std::string getNegative() const {return negative;} + std::string getNegative() const {return getPayload();} std::string getPositive() const {return negative2positive.at(getNegative());} operator std::string() const {return getNegative();} - virtual nlohmann::json toJson(void) const { - return getNegative(); - } virtual ~Qualifier() {} bool operator==(const Qualifier& rhs) const {return getNegative() == rhs.getNegative();} @@ -135,8 +138,6 @@ namespace rules { static Qualifier Adamantine() {return Qualifier("non-adamantine");} private: - const std::string negative; - static const std::map<std::string, std::string> negative2positive; }; diff --git a/src/spellcasting.cc b/src/spellcasting.cc index 2606b53..db8e71a 100644 --- a/src/spellcasting.cc +++ b/src/spellcasting.cc @@ -28,8 +28,8 @@ namespace entry { string genText(const Spellcasting& s, const creature::Creature& c) { stringstream text; - text << genText(static_cast<const Feature&>(s), c); - text << ": The " << c.getCreatureName() << "'s spellcasting ability is " << s.getAbility().getFull(); + text << s.getName() << " (" << s.getType() << "): "; + text << "The " << c.getCreatureName() << "'s spellcasting ability is " << 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 6672dba..bb99756 100644 --- a/src/spellcasting.h +++ b/src/spellcasting.h @@ -11,7 +11,7 @@ typedef nlohmann::json json; namespace entry { struct SlotLevel : public Jsonable { - SlotLevel(const json& data) : numSlots(data["slots"]), spells(utils::jsonList2ptrvec<Spell>("spells", data["spells"])) {} + SlotLevel(const json& data) : numSlots(data["slots"]), spells(utils::instantiateNames<Spell>("spells", data["spells"])) {} SlotLevel() : numSlots(0) {} virtual ~SlotLevel() {} int numSlots; @@ -32,7 +32,7 @@ namespace entry { class Spellcasting : public Feature { public: - Spellcasting(const json& data, const json& base) : Feature(base), innate(data["innate"]), ability(rules::Ability(data["spellcasting_ability"])), spellsBySlot(utils::json2ptrvec<SlotLevel>(data["levels"])) {} + Spellcasting(const json& data, const json& base) : Feature(base), innate(data["innate"]), ability(rules::Ability(data["spellcasting_ability"])), spellsBySlot(data["levels"]) {} // Can also be instantiated programatically Spellcasting(const std::string& entry, const std::string& name, const std::string& type, const std::string& text, const rules::Ability& ability, bool isInnate) : Feature(entry, name, type, text), innate(isInnate), ability(ability) {} virtual ~Spellcasting() {} @@ -48,7 +48,7 @@ namespace entry { auto data = Feature::toJson(); data["innate"] = innate; data["spellcasting_ability"] = ability; - data["levels"] = utils::ptrvec2json(spellsBySlot); + data["levels"] = spellsBySlot; return data; } diff --git a/src/utils.h b/src/utils.h index dea052b..71041a7 100644 --- a/src/utils.h +++ b/src/utils.h @@ -106,7 +106,7 @@ namespace utils { return std::vector<T>(begin(data), end(data)); } - template<typename T> std::vector<std::shared_ptr<T>> jsonList2ptrvec(const std::string& type, const std::vector<std::string>& names) { + template<typename T> std::vector<std::shared_ptr<T>> instantiateNames(const std::string& type, const std::vector<std::string>& names) { std::vector<std::shared_ptr<T>> ret; for(auto name : names) { auto j = utils::loadJson(type, name); @@ -114,20 +114,4 @@ namespace utils { } return ret; } - - template<typename T> std::vector<std::shared_ptr<T>> json2ptrvec(const nlohmann::json& data) { - std::vector<std::shared_ptr<T>> ret; - for(nlohmann::json d : data) { - ret.push_back(T::create(d)); - } - return ret; - } - - template<typename T> std::vector<nlohmann::json> ptrvec2json(std::vector<T> src) { - std::vector<nlohmann::json> ret; - for(T i : src) { - ret.push_back(i->toJson()); - } - return ret; - } } diff --git a/src/weapon.cc b/src/weapon.cc index db81047..fe50eaf 100644 --- a/src/weapon.cc +++ b/src/weapon.cc @@ -130,10 +130,10 @@ namespace entry { string genText(const Weapon& w, const creature::Creature& c) { stringstream text; - text << genText(static_cast<const Item&>(w), c); + text << w.getName() << " (" << w.getType() << "): "; // Determine best ability bonus int abilityBonus = c.getBonus(creature::getBestAbility(getAbilityOptions(w), c)); - text << ": " << getTextHelper(w, to_string(abilityBonus + c.getProficiency()), to_string(abilityBonus)); + text << getTextHelper(w, to_string(abilityBonus + c.getProficiency()), to_string(abilityBonus)); return text.str(); } } |