diff options
author | Your Name <you@example.com> | 2023-11-22 15:28:00 -0500 |
---|---|---|
committer | Your Name <you@example.com> | 2023-11-22 15:28:00 -0500 |
commit | ae68e84557a7e56fd7210c1009aa1313dcc78adf (patch) | |
tree | 60616c822927847dd078f014c514a65f764607f3 /src/creature.cc | |
parent | 0d32e0d3342ef2455014c8e1164977c816763317 (diff) | |
download | dmtool-ae68e84557a7e56fd7210c1009aa1313dcc78adf.tar.gz dmtool-ae68e84557a7e56fd7210c1009aa1313dcc78adf.tar.bz2 dmtool-ae68e84557a7e56fd7210c1009aa1313dcc78adf.zip |
Increased capacity for creating items from command line
Diffstat (limited to 'src/creature.cc')
-rw-r--r-- | src/creature.cc | 86 |
1 files changed, 83 insertions, 3 deletions
diff --git a/src/creature.cc b/src/creature.cc index 4343b6d..955da4d 100644 --- a/src/creature.cc +++ b/src/creature.cc @@ -152,6 +152,19 @@ namespace creature { return bonus; } + void Creature::setProficientSave(const rules::Ability& ability) { + if(find(data->saves.begin(), data->saves.end(), ability) == data->saves.end()) { + data->saves.push_back(ability); + } + } + + void Creature::removeProficientSave(const rules::Ability& ability) { + for(auto it = data->saves.begin(); it != data->saves.end();) { + if(*it == ability) it = data->saves.erase(it); + else ++it; + } + } + void Creature::addInventoryItem(std::shared_ptr<entry::Item> item) { data->inventory.push_back(item); } @@ -209,6 +222,19 @@ namespace creature { } } + void Creature::addFeature(std::shared_ptr<entry::Feature> feature) { + data->features.push_back(feature); + } + + void Creature::removeFeature(std::shared_ptr<entry::Feature> feature) { + for(auto it = data->features.begin(); it != data->features.end(); it++) { + if(*it == feature) { + data->features.erase(it); + break; + } + } + } + std::map<rules::Skill, int> Creature::getSkills() const { std::map<rules::Skill, int> s; for(auto skill : data->skills) { @@ -309,6 +335,46 @@ namespace creature { return out; } + bool addEntry(std::shared_ptr<entry::Entry> entry, Creature& c) { + auto i = std::dynamic_pointer_cast<entry::Item>(entry); + if(i) { + c.addInventoryItem(i); + return true; + } + auto s = std::dynamic_pointer_cast<entry::Spell>(entry); + if(s) { + c.addSpell(s); + return true; + } + auto f = std::dynamic_pointer_cast<entry::Feature>(entry); + if(f) { + c.addFeature(f); + return true; + } + return false; + } + + template<typename F, typename E> std::shared_ptr<entry::Entry> tryRemove(std::string entryName, F remover, std::vector<E> entries) { + for(auto e : entries) { + std::string name = e->getName(); + if(utils::lower(name) == entryName) { + remover(e); + return e; + } + } + return std::shared_ptr<entry::Entry>(); + } + + std::shared_ptr<entry::Entry> removeEntry(std::string entryName, Creature& c) { + entryName = utils::lower(entryName); + if(auto e = tryRemove(entryName, [c](auto e) mutable {c.removeInventoryItem(e);}, c.getInventory())) return e; + if(auto e = tryRemove(entryName, [c](auto e) mutable {c.removeFeature(e);}, c.getFeatures())) return e; + if(c.getSpellcasting()) { + if(auto e = tryRemove(entryName, [c](auto e) mutable {c.removeSpell(e);}, c.getSpellcasting()->getSpells())) return e; + } + return std::shared_ptr<entry::Entry>(); + } + std::vector<std::string> dmgTypes2text(std::vector<dmgType> dmg) { std::vector<std::string> ret; for(dmgType t : dmg) { @@ -361,7 +427,9 @@ namespace creature { if(! getSkills().empty()) { text << std::endl << "Skills:" << std::endl; for(auto skill : getSkills()) { - text << " * " << skill.first.getName() << " (+" << skill.second << ")" << std::endl; + text << " * " << skill.first.getName(); + if(data->skills.at(skill.first) == 2) text << " Expert"; + text << " (+" << skill.second << ")" << std::endl; } } if(! getSaves().empty()) { @@ -389,9 +457,21 @@ namespace creature { } } if(! getInventory().empty()) { - text << std::endl << "Inventory:" << std::endl; + std::map<std::string, int> inventoryText; + double totalWeight = 0; + int totalCost = 0; for(auto i : getInventory()) { - text << " * " << i->getText(*this) << std::endl; + totalWeight += i->getWeight(); + totalCost += i->getCost(); + auto t = i->getText(*this); + if(inventoryText.contains(t)) inventoryText[t]++; + else inventoryText.insert({t, 1}); + } + text << std::endl << "Inventory (" << totalWeight << " lbs, value " << utils::getCostString(totalCost) << "):" << std::endl; + for(auto const& [t, count] : inventoryText) { + text << " * "; + if(count > 1) text << count << "x "; + text << t << std::endl; } } if(! Entry::getText().empty()) { |