From 2a9f262e6db5906db445d465e500d7ba8c90fab3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 5 May 2021 09:44:50 -0400 Subject: Implemented additional commands --- src/creature.cc | 75 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 19 deletions(-) (limited to 'src/creature.cc') diff --git a/src/creature.cc b/src/creature.cc index e1f2b61..21943fe 100644 --- a/src/creature.cc +++ b/src/creature.cc @@ -6,6 +6,7 @@ #include "weapon.h" #include "armor.h" #include "attack.h" +#include "spellcasting.h" #include #include #include @@ -24,7 +25,7 @@ namespace creature { } Creature::Creature(const json& data, const json& base) - : Entry(base), inventory(json2ptrvec(data["inventory"])), stats(makeMap(data["stats"])), skills(makeMap(data["skills"])), size(data["size"]), alignment(data["alignment"]), hdCount(data["hit_die_count"]), hdSides(data["hit_die_sides"]), speed(data["speed"]), saves(json2vec(data["saves"])), langs(data["langs"]), cr(data["cr"]), proficiency(data["prof"]), natArmorName(data["natural_armor"]["name"]), natArmorBonus(data["natural_armor"]["bonus"]), dmgImmunities(json2vec(data["d_immunities"])), dmgResistances(json2vec(data["d_resistances"])), dmgVulnerabilities(json2vec(data["d_vulnerabilities"])), condImmunities(json2vec(data["c_immunities"])), features(json2ptrvec(data["features"])) + : Entry(base), inventory(json2ptrvec(data["inventory"])), stats(makeMap(data["stats"])), skills(makeMap(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(json2vec(data["saves"])), langs(data["langs"]), cr(data["cr"]), natArmorName(data["natural_armor"]["name"]), natArmorBonus(data["natural_armor"]["bonus"]), dmgImmunities(json2vec(data["d_immunities"])), dmgResistances(json2vec(data["d_resistances"])), dmgVulnerabilities(json2vec(data["d_vulnerabilities"])), condImmunities(json2vec(data["c_immunities"])), features(json2ptrvec(data["features"])) { // Initialize names and hp if(((map) data).contains("givenName")) { @@ -41,14 +42,6 @@ namespace creature { } } - template vector getJsonVectP(vector src) { - vector ret; - for(T i : src) { - ret.push_back(i->toJson()); - } - return ret; - } - nlohmann::json Creature::toJson() const { nlohmann::json data = Entry::toJson(); data["size"] = size; @@ -71,19 +64,19 @@ namespace creature { data["givenName"] = givenName; data["hpMax"] = hpMax; data["hp"] = hp; - data["inventory"] = getJsonVectP(inventory); - data["features"] = getJsonVectP(features); + data["inventory"] = ptrvec2json(inventory); + data["features"] = ptrvec2json(features); return data; } // True if type without matching qualifiers is in subdata - bool conditionApplies(const string& type, const vector& qualifiers, const vector subdata) { + bool conditionApplies(const string& type, const vector& qualifiers, const vector subdata) { bool applies = false; for(dmgType con : subdata) { if(con.type == type) { applies = true; - for(string qualifier : qualifiers) { - if(find(con.qualifiers.begin(), con.qualifiers.end(), qualifier) == con.qualifiers.end()) { + for(auto qualifier : qualifiers) { + if(find(con.qualifiers.begin(), con.qualifiers.end(), qualifier) != con.qualifiers.end()) { applies = false; } } @@ -92,7 +85,7 @@ namespace creature { return applies; } - void Creature::applyDamage(int amount, const string& type, const vector& qualifiers) { + void Creature::applyDamage(int amount, const string& type, const vector& qualifiers) { if(! conditionApplies(type, qualifiers, dmgImmunities)) { if(conditionApplies(type, qualifiers, dmgResistances)) { hp -= amount / 2; @@ -131,9 +124,45 @@ namespace creature { inventory.push_back(item); } - void Creature::removeInventoryItem(const string& name) { + shared_ptr Creature::getSpellcasting() const { + for(auto f : getFeatures()) { + if(f->getType() == "spells") { + return dynamic_pointer_cast(f); + } + } + return shared_ptr(); + } + + void Creature::addSpell(shared_ptr spell) { + auto sc = getSpellcasting(); + if(! sc) { + throw runtime_error("Creature " + getName() + " has no spellcasting"); + } + std::size_t level = spell->getLevel(); + while(sc->getSlotLevels().size() <= level) { + sc->addSlotLevel(); + } + sc->getSlotLevels()[level]->spells.push_back(spell); + } + + void Creature::removeSpell(shared_ptr spell) { + auto sc = getSpellcasting(); + if(sc) { + if(sc->getSlotLevels().size() > (size_t) spell->getLevel()) { + auto sl = sc->getSlotLevels()[spell->getLevel()]; + for(auto it = sl->spells.begin(); it != sl->spells.end(); it++) { + if(*it == spell) { + sl->spells.erase(it); + break; + } + } + } + } + } + + void Creature::removeInventoryItem(shared_ptr item) { for(auto it = inventory.begin(); it != inventory.end(); it++) { - if((*it)->getName() == name) { + if(*it == item) { inventory.erase(it); break; } @@ -158,7 +187,7 @@ namespace creature { void Creature::setScore(const rules::Ability& ability, int score) { int initBonus = getBonus(ability); - stats.insert({ability, score}); + stats[ability] = score; if(ability == rules::Ability::Con()) { int delta = getBonus(ability) - initBonus; hpMax += delta * hdCount; @@ -167,7 +196,14 @@ namespace creature { } void Creature::setProfLevel(const rules::Skill& skill, int level) { - skills.insert({skill, level}); + skills[skill] = level; + if(level == 0) { + skills.erase(skill); + } + } + + void Creature::longRest() { + hp = hpMax; } const int getAC(const Creature& c) { @@ -267,6 +303,7 @@ namespace creature { if(! c.getLanguages().empty()) { text << "Languages: " << c.getLanguages() << endl; } + text << "Proficiency: " << c.getProficiency() << endl; if(! c.getSkills().empty()) { text << endl << "Skills:" << endl; for(auto skill : c.getSkills()) { -- cgit v1.2.3