#include "spellcasting.h" #include "creature.h" #include "utils.h" #include #include #include using namespace std; namespace entry { shared_ptr SlotLevel::create(const json& data) { return shared_ptr(new SlotLevel(data)); } vector> Spellcasting::getSpells() const { vector> ret; for(auto sl : getSlotLevels()) { for(auto spell : sl->spells) { ret.push_back(spell); } } return ret; } string Spellcasting::getText(const creature::Creature& c) const { return genText(*this, c); } string genText(const Spellcasting& s, const creature::Creature& c) { stringstream text; text << s.getName() << " (" << s.getType() << "): "; text << "The " << c.getCreatureName() << "'s spellcasting ability is " << s.getAbility().getFull(); text << " (spell save DC " << 8 + c.getBonus(s.getAbility()) + c.getProficiency(); text << ", +" << c.getBonus(s.getAbility()) + c.getProficiency() << " to hit with spell attacks)."; if(s.isInnate()) { text << " Spellcasting is innate."; } int levelNumber = -1; for(auto level : s.getSlotLevels()) { levelNumber++; // Skip if it's empty if(level->numSlots == 0 && level->spells.empty()) { continue; } text << endl; if(levelNumber == 0) { if(s.isInnate()) { text << " At will: "; } else { text << " Cantrips: "; } } else { if(s.isInnate()) { text << " " << level->numSlots << "/day each: "; } else { text << " " << utils::toOrdinal(levelNumber) << " level (" << level->numSlots << " slots): "; } } vector names; for(auto spell : level->spells) { names.push_back(spell->getName()); } text << utils::join(names, ", "); } return text.str(); } }