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
|
inline bool Cleric::turnsAwayUndead (const std::vector<Monster*>& monsters) const {
enum {NoTurn = 13, Turned = 2, Dispelled = 1};
static /*const*/ std::map<std::type_index, std::array<int, 11>> turnUndeadValues = { // const will not compile (why?)
{std::type_index (typeid (Skeleton)), { 7, Turned, Turned, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled} },
{std::type_index (typeid (Zombie)), { 9, 7, Turned, Turned, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled} },
{std::type_index (typeid (Ghoul)), { 11, 9, 7, Turned, Turned, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled, Dispelled} }
// etc...
};
static /*const*/ std::map<std::type_index, std::string> undeadMonsterName { // const will not compile (why?)
{std::type_index (typeid (Skeleton)), "skeleton"},
{std::type_index (typeid (Zombie)), "zombie"},
{std::type_index (typeid (Ghoul)), "ghoul"}
// etc...
};
std::map<std::type_index, std::deque<UndeadMonster*>> activeUndeadMonstersPresentMap;
for (Monster* x: monsters)
if (x->isUndead() && !x->incapacitated())
activeUndeadMonstersPresentMap[std::type_index (typeid (*x))].emplace_back (dynamic_cast<UndeadMonster*>(x));
using td = std::pair<std::type_index, std::deque<UndeadMonster*>>;
std::vector<td> activeUndeadMonstersPresent; // Need to sort all the elements of activeUndeadMonstersPresentMap according to hitDice of the undead monsters in the deques.
std::copy (activeUndeadMonstersPresentMap.begin(), activeUndeadMonstersPresentMap.end(), std::back_inserter (activeUndeadMonstersPresent));
std::sort (activeUndeadMonstersPresent.begin(), activeUndeadMonstersPresent.end(),
[](const td& x, const td& y)->bool {return x.second.front()->HitDice() < y.second.front()->HitDice();});
const int roll = (std::rand() % 6 + 1) + (std::rand() % 6 + 1), index = (Level() <= 10) ? Level() - 1 : 10;
if (roll < turnUndeadValues[activeUndeadMonstersPresent.front().first][index]) // why the /*const*/ will cause this line to fail?
{
pressContinue (Name() + " has failed to turn away any of the undead monsters.");
return false;
}
int numHitDiceAffected = (std::rand() % 6 + 1) + (std::rand() % 6 + 1);
for (td& pair: activeUndeadMonstersPresent)
{
if (roll < turnUndeadValues[pair.first][index])
continue;
const int hitDice = static_cast<int> (pair.second.front()->HitDice().level);
const std::size_t num = pair.second.size();
int totalNumHitDice = num * hitDice;
if (numHitDiceAffected >= totalNumHitDice)
{
const std::string nameOfUndeadMonster = undeadMonsterName[pair.first]; // why the /*const*/ will cause this line to fail?
std::cout << "All " << num << " active " << nameOfUndeadMonster << "s have been turned away." << std::endl;
for (UndeadMonster* x: pair.second)
x->isTurnedAway();
}
// etc...
}
}
|