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
|
#include <iostream>
#include <memory>
#include <utility>
#include <list>
struct MonsterHitDice {
double level;
int adjustment;
int specialAbilitiesBonus;
};
struct Monster {
virtual ~Monster() = default ;
virtual MonsterHitDice HitDice() const = 0;
virtual int ArmorClass() const = 0;
virtual int NumberOfAttacks() const = 0;
// etc.
};
template <typename DERIVED, typename MONSTERHD, const MONSTERHD& HITDICE, int AC, int NATTACKS>
struct MonsterType: Monster {
static MonsterHitDice hitDice;
static int armorClass, numberOfAttacks;
virtual MonsterHitDice HitDice() const override {return hitDice;}
virtual int ArmorClass() const override {return armorClass;}
virtual int NumberOfAttacks() const override {return numberOfAttacks ;}
// etc.
};
template <typename DERIVED, typename MONSTERHD, const MONSTERHD& HITDICE, int AC, int NATTACKS>
MonsterHitDice MonsterType<DERIVED, MONSTERHD, HITDICE, AC, NATTACKS>::hitDice = HITDICE;
template <typename DERIVED, typename MONSTERHD, const MONSTERHD& HITDICE, int AC, int NATTACKS>
int MonsterType<DERIVED, MONSTERHD, HITDICE, AC, NATTACKS>::armorClass = AC;
template <typename DERIVED, typename MONSTERHD, const MONSTERHD& HITDICE, int AC, int NATTACKS>
int MonsterType<DERIVED, MONSTERHD, HITDICE, AC, NATTACKS>::numberOfAttacks = NATTACKS;
//// etc.
MonsterHitDice goblin_hd = {1,-1}, dragon_hd = {20,1}, troll_hd = {8,0,2}; // How to do it without resorting to this?
struct Goblin: public MonsterType<Goblin, MonsterHitDice, goblin_hd, 6, 1> {};
struct Dragon: MonsterType<Dragon, MonsterHitDice, dragon_hd, -2, 3> {};
struct Troll: MonsterType<Troll, MonsterHitDice, troll_hd, 2, 3> {};
int main() {
std::list<Monster*> monsters = {new Goblin(), new Dragon(), new Troll()};
for (const auto& x: monsters)
std::cout << x->HitDice().level << ", " << x->HitDice().adjustment <<
", " << x->ArmorClass() << ", " << x->NumberOfAttacks() << std::endl; std::cout << Goblin::hitDice.level << ", " << Goblin::hitDice.adjustment
<< ", " << Goblin::armorClass << ", " << Goblin::numberOfAttacks << std::endl;
}
|