#pragma once #include "json.hpp" #include "rules.h" #include "utils.h" #include "entry.h" #include namespace entry { class Feature; class Item; class Weapon; class Attack; class Spell; class Spellcasting; } typedef nlohmann::json json; namespace creature { class Creature; class dmgType : public Jsonable { public: dmgType(const json& data) : type(data["type"]), qualifiers(utils::json2vec(data["qualifiers"])) {} std::string type; std::vector 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} }); } }; // 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::shared_ptr getSpellcasting(void) const; 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 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 addInventoryItem(std::shared_ptr item); void addSpell(std::shared_ptr spell); void removeSpell(std::shared_ptr spell); void removeInventoryItem(std::shared_ptr item); void longRest(void); virtual json toJson(void) const; private: // Mutable variables std::string givenName; int hpMax; int hp; std::vector> inventory; std::map stats; std::map 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 saves; const std::vector senses; const std::string langs; const double cr; 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; }; // Helper function to get all attacks (weapons and pseudo-weapons included) std::vector> getAttacks(const Creature& c); // Helper function to get the best ability for this creature (chooses arbitrarily in case of ties) rules::Ability getBestAbility(const std::vector& abilities, const Creature& c); }