aboutsummaryrefslogtreecommitdiff
path: root/src/rules.h
blob: 18cdef0755dc5c08a14ef282028ba17247329917 (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
#pragma once
#include "jsonable.h"
#include <vector>
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#include <stdexcept>

namespace rules {

    class Ability : public Jsonable {
        public:
            std::string getFull() const {return abilities.at(getAbbrev());}
            std::string getAbbrev() const {return abbrev;}
            operator std::string() const {return getAbbrev();}
            virtual nlohmann::json toJson(void) const {
                return getAbbrev();
            }
            bool operator<(const Ability& rhs) const {return getAbbrev() < rhs.getAbbrev();}
            bool operator==(const Ability& rhs) const {return getAbbrev() == rhs.getAbbrev();}

            Ability() {}
            explicit Ability(const nlohmann::json& data) : abbrev(data) {}

            virtual ~Ability() {}

            static Ability Str() {return Ability("str");}
            static Ability Dex() {return Ability("dex");}
            static Ability Con() {return Ability("con");}
            static Ability Int() {return Ability("int");}
            static Ability Wis() {return Ability("wis");}
            static Ability Cha() {return Ability("cha");}

            static Ability string2ability(std::string s) {
                transform(s.begin(), s.end(), s.begin(), ::tolower);
                for(auto [abbrev, full] : abilities) {
                    transform(full.begin(), full.end(), full.begin(), ::tolower);
                    if(s == abbrev || s == full) {
                        return Ability(abbrev);
                    }
                }
                throw std::invalid_argument("Cannot find an ability for input: \"" + s + "\"");
            }

        private:
            const std::string abbrev;

            static const std::map<std::string, std::string> abilities;
    };

    class Skill : public Jsonable {
        public:
            std::string getName() const {return name;}
            Ability getAbility() const {return Ability(skill2ability.at(getName()));}
            operator std::string() const {return getName();}
            virtual nlohmann::json toJson(void) const {
                return getName();
            }
            bool operator<(const Skill& rhs) const {return getName() < rhs.getName();}
            bool operator==(const Skill& rhs) const {return getName() == rhs.getName();}

            virtual ~Skill() {}

            static Skill Athletics() {return Skill("Athletics");}
            static Skill Acrobatics() {return Skill("Acrobatics");}
            static Skill SleightOfHand() {return Skill("Sleight of Hand");}
            static Skill Stealth() {return Skill("Stealth");}
            static Skill Arcana() {return Skill("Arcana");}
            static Skill History() {return Skill("History");}
            static Skill Investigation() {return Skill("Investigation");}
            static Skill Nature() {return Skill("Nature");}
            static Skill Religion() {return Skill("Religion");}
            static Skill AnimalHandling() {return Skill("Animal Handling");}
            static Skill Insight() {return Skill("Insight");}
            static Skill Medicine() {return Skill("Medicine");}
            static Skill Perception() {return Skill("Perception");}
            static Skill Survival() {return Skill("Survival");}
            static Skill Deception() {return Skill("Deception");}
            static Skill Intimidation() {return Skill("Intimidation");}
            static Skill Performance() {return Skill("Performance");}
            static Skill Persuasion() {return Skill("Persuasion");}

            explicit Skill(const nlohmann::json& data) : name(data) {}

            static Skill string2skill(std::string s) {
                transform(s.begin(), s.end(), s.begin(), ::tolower);
                for(auto& [name, _] : skill2ability) {
                    std::string n = name;
                    transform(n.begin(), n.end(), n.begin(), ::tolower);
                    if(s == n) {
                        return Skill(name);
                    }
                }
                throw std::invalid_argument("Cannot find a skill for input: \"" + s + "\"");
            }

        private:
            const std::string name;

            static const std::map<std::string, std::string> skill2ability;
    };
    
    std::ostream& operator<<(std::ostream& os, const Ability& a);
    std::ostream& operator<<(std::ostream& os, const Skill& s);
}