aboutsummaryrefslogtreecommitdiff
path: root/src/creature.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/creature.cc')
-rw-r--r--src/creature.cc75
1 files changed, 56 insertions, 19 deletions
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 <algorithm>
#include <iostream>
#include <sstream>
@@ -24,7 +25,7 @@ namespace creature {
}
Creature::Creature(const json& data, const json& base)
- : Entry(base), inventory(json2ptrvec<entry::Item>(data["inventory"])), stats(makeMap<rules::Ability>(data["stats"])), skills(makeMap<rules::Skill>(data["skills"])), size(data["size"]), 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"]))
+ : Entry(base), inventory(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(json2vec<rules::Ability>(data["saves"])), langs(data["langs"]), cr(data["cr"]), 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"]))
{
// Initialize names and hp
if(((map<string, json>) data).contains("givenName")) {
@@ -41,14 +42,6 @@ namespace creature {
}
}
- template<typename T> vector<json> getJsonVectP(vector<T> src) {
- vector<json> 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<string>& qualifiers, const vector<dmgType> subdata) {
+ bool conditionApplies(const string& type, const vector<rules::Qualifier>& qualifiers, const vector<dmgType> 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<string>& qualifiers) {
+ void Creature::applyDamage(int amount, const string& type, const vector<rules::Qualifier>& 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<entry::Spellcasting> Creature::getSpellcasting() const {
+ for(auto f : getFeatures()) {
+ if(f->getType() == "spells") {
+ return dynamic_pointer_cast<entry::Spellcasting>(f);
+ }
+ }
+ return shared_ptr<entry::Spellcasting>();
+ }
+
+ void Creature::addSpell(shared_ptr<entry::Spell> 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<entry::Spell> 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<entry::Item> 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()) {