#pragma once #include "json.hpp" #include "rules.h" #include "utils.h" #include "entry.h" #include namespace entry { class Feature; class Item; } typedef nlohmann::json json; namespace creature { class Creature; class dmgType : public Jsonable { public: dmgType(const json& data) : type(data["type"]), qualifiers(data["qualifiers"]) {} std::string type; std::vector qualifiers; operator string() const { if(qualifiers.empty()) { return type; } return utils::join(qualifiers, ", ") + " " + type; } json toJson(void) const { return json({ {"type", type}, {"qualifiers", qualifiers} }); } }; // 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); virtual ~Creature() {}; // Getters int getSkillBonus(const rules::Skill& skill) const; int getAbilitySaveBonus(const rules::Ability& ability) const; std::map getSkills(void) const; std::map getSaves(void) const; //Override getText virtual std::string getText() const override {return genText(*this);} // 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 getNaturalArmor(void) const {return {natArmorName, natArmorBonus};} std::string getLanguages(void) const {return langs;} int getHP(void) const {return hp;} int getHPMax(void) const {return hpMax;} std::vector getSenses(void) const {return senses;} 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;} std::vector> getFeatures(void) const {return features;} std::vector> getInventory(void) const {return inventory;} std::vector getDmgImmunities(void) const {return dmgImmunities;} std::vector getDmgResistances(void) const {return dmgResistances;} std::vector getDmgVulnerabilities(void) const {return dmgVulnerabilities;} std::vector getCondImmunities(void) const {return condImmunities;} // Setters (mutators) void setGivenName(std::string name) {givenName = name;} void applyDamage(int amount, const std::string& type, const std::vector& qualifiers); void setScore(const rules::Ability& ability, int score); void setProfLevel(const rules::Skill& skill, int level); void addInventoryItem(std::shared_ptr item); void removeInventoryItem(const std::string& itemName); virtual json toJson(void) const; private: // Mutable variables std::string givenName; int hpMax; int hp; std::vector> inventory; std::map stats; std::map skills; //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 saves; const std::vector senses; const std::string langs; const double cr; const int proficiency; const std::string natArmorName; const int natArmorBonus; const std::vector dmgImmunities; const std::vector dmgResistances; const std::vector dmgVulnerabilities; const std::vector condImmunities; const std::vector> features; }; // Convenience function to get any instances of T (subclass of Item) in the inventory template std::vector> getItems(const Creature& c) { std::vector> Ts; for(auto item : c.getInventory()) { std::shared_ptr t = dynamic_pointer_cast(item); if(t) { Ts.push_back(t); } } return Ts; } }