aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYour Name <you@example.com>2021-05-09 13:56:46 -0400
committerYour Name <you@example.com>2021-05-09 13:56:46 -0400
commitd13358b71ec15085f2638fd9c3fc634df62dfc94 (patch)
tree467c643a068bf2d83da3632823a6434244ae004e /src
parente3aaa68a2ea1a403256150121c57a0287014162f (diff)
downloaddmtool-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.cc10
-rw-r--r--src/armor.h15
-rw-r--r--src/creature.cc120
-rw-r--r--src/creature.h90
-rw-r--r--src/creature_data.h28
-rw-r--r--src/entry.cc4
-rw-r--r--src/entry.h6
-rw-r--r--src/jsonable.h17
-rw-r--r--src/rules.h49
-rw-r--r--src/spellcasting.cc4
-rw-r--r--src/spellcasting.h6
-rw-r--r--src/utils.h18
-rw-r--r--src/weapon.cc4
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();
}
}