aboutsummaryrefslogtreecommitdiff
path: root/src/creature.h
blob: b2a01e6f6261416a23cea71f78f39af771738c6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#pragma once
#include "rules.h"
#include "utils.h"
#include "entry.h"
#include "feature.h"
#include "item.h"
#include <cmath>
#include <nlohmann/json.hpp>

namespace entry {
    class Weapon;
    class Attack;
    class Spell;
    class Spellcasting;
}

namespace creature {
    class Creature;

    struct dmgType {
        std::string type;
        std::vector<rules::Qualifier> qualifiers;
        std::string getText() const {
            if(qualifiers.empty()) {
                return type;
            }
            return utils::join(qualifiers, ", ") + " " + type;
        }
    };
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(dmgType, type, qualifiers);

    struct NatArmor {
        std::string name;
        int bonus;
    };
    NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(NatArmor, name, bonus);

    // Convenience function to calculate AC
    const int getAC(const Creature& c);

    class Creature : public entry::Entry {
        public:
            virtual ~Creature() {}

            virtual void init() override;

            // Getters
            int getSkillBonus(const rules::Skill& skill) const;
            int getAbilitySaveBonus(const rules::Ability& ability) const;
            std::map<rules::Skill, int> getSkills(void) const;
            std::map<rules::Ability, int> getSaves(void) const;

            //Override getText
            virtual std::string getText() const override;

            // Inline getters
            std::string getCreatureName(void) const {return getName();}
            std::string getGivenName(void) const {return givenName;}
            std::string getSize(void) const {return size;}
            std::string getAlignment(void) const {return alignment;}
            double getCR(void) const {return cr;}
            NatArmor getNaturalArmor(void) const {return natural_armor;}
            std::string getLanguages(void) const {return langs;}
            int getHP(void) const {return hp;}
            int getHPMax(void) const {return hpMax;}
            std::vector<std::string> 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 prof;}
            std::vector<std::shared_ptr<entry::Feature>> getFeatures(void) const {return features;}
            std::shared_ptr<entry::Spellcasting> getSpellcasting(void) const;
            std::vector<std::shared_ptr<entry::Item>> getInventory(void) const {return inventory;}
            std::vector<dmgType> getDmgImmunities(void) const {return d_immunities;}
            std::vector<dmgType> getDmgResistances(void) const {return d_resistances;}
            std::vector<dmgType> getDmgVulnerabilities(void) const {return d_vulnerabilities;}
            std::vector<dmgType> getCondImmunities(void) const {return c_immunities;}


            // Setters (mutators)
            void setGivenName(std::string name) {givenName = name;}
            void applyDamage(int amount, const std::string& type, const std::vector<rules::Qualifier>& qualifiers);
            void applyHealing(int amount);
            void setScore(const rules::Ability& ability, int score);
            void setProfLevel(const rules::Skill& skill, int level);
            void setProficiency(int p) {prof = p;}
            void addInventoryItem(std::shared_ptr<entry::Item> item);
            void addSpellcasting(void);
            void addSpell(std::shared_ptr<entry::Spell> spell);
            void removeSpell(std::shared_ptr<entry::Spell> spell);
            void removeInventoryItem(std::shared_ptr<entry::Item> item);
            void longRest(void);

            NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Entry, Creature, givenName, hpMax, hp, inventory, stats, skills, prof, size, alignment, hit_die_count, hit_die_sides, speed, saves, senses, langs, cr, observant, natural_armor, d_immunities, d_resistances, d_vulnerabilities, c_immunities, features);

        private:
            std::string givenName;
            int hpMax;
            int hp;
            std::vector<std::shared_ptr<entry::Item>> inventory;
            std::map<rules::Ability, int> stats;
            std::map<rules::Skill, int> skills;
            int prof;
            std::string size;
            std::string alignment;
            int hit_die_count;
            int hit_die_sides;
            std::string speed;
            std::vector<rules::Ability> saves;
            std::vector<std::string> senses;
            std::string langs;
            double cr;
            bool observant;
            NatArmor natural_armor;
            std::vector<dmgType> d_immunities;
            std::vector<dmgType> d_resistances;
            std::vector<dmgType> d_vulnerabilities;
            std::vector<dmgType> c_immunities;
            std::vector<std::shared_ptr<entry::Feature>> features;

    };

    // Helper function to get all attacks (weapons and pseudo-weapons included)
    std::vector<std::shared_ptr<entry::Weapon>> 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<rules::Ability>& abilities, const Creature& c);
}