aboutsummaryrefslogtreecommitdiff
path: root/src/creature.cc
diff options
context:
space:
mode:
authorYour Name <you@example.com>2021-04-20 12:40:37 -0400
committerYour Name <you@example.com>2021-04-20 12:40:37 -0400
commitcd57ad6e208728bafcbc8c7d7b85d88603706978 (patch)
tree7cb0fc9511a0e8124e497d53edbe38d646dd8299 /src/creature.cc
parent2cae1aa33f80ce0844fb54a84ce103146a7fe7ad (diff)
downloaddmtool-cd57ad6e208728bafcbc8c7d7b85d88603706978.tar.gz
dmtool-cd57ad6e208728bafcbc8c7d7b85d88603706978.tar.bz2
dmtool-cd57ad6e208728bafcbc8c7d7b85d88603706978.zip
Updated natural armor and skills
Diffstat (limited to 'src/creature.cc')
-rw-r--r--src/creature.cc108
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();