aboutsummaryrefslogtreecommitdiff
path: root/src/creature.cc
diff options
context:
space:
mode:
authorYour Name <you@example.com>2023-11-22 15:28:00 -0500
committerYour Name <you@example.com>2023-11-22 15:28:00 -0500
commitae68e84557a7e56fd7210c1009aa1313dcc78adf (patch)
tree60616c822927847dd078f014c514a65f764607f3 /src/creature.cc
parent0d32e0d3342ef2455014c8e1164977c816763317 (diff)
downloaddmtool-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.cc86
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()) {