aboutsummaryrefslogtreecommitdiff
path: root/src/cmd_manipulate.cc
diff options
context:
space:
mode:
authorYour Name <you@example.com>2021-05-06 14:13:28 -0400
committerYour Name <you@example.com>2021-05-06 14:13:28 -0400
commit9f3802690f9dd9452e96d1d7a879291978d66e35 (patch)
tree6d6c17b39abdb9490119241bc4fc061744b46d7d /src/cmd_manipulate.cc
parent2a9f262e6db5906db445d465e500d7ba8c90fab3 (diff)
downloaddmtool-9f3802690f9dd9452e96d1d7a879291978d66e35.tar.gz
dmtool-9f3802690f9dd9452e96d1d7a879291978d66e35.tar.bz2
dmtool-9f3802690f9dd9452e96d1d7a879291978d66e35.zip
Refactoring
Diffstat (limited to 'src/cmd_manipulate.cc')
-rw-r--r--src/cmd_manipulate.cc186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/cmd_manipulate.cc b/src/cmd_manipulate.cc
new file mode 100644
index 0000000..fe59ebf
--- /dev/null
+++ b/src/cmd_manipulate.cc
@@ -0,0 +1,186 @@
+#include "cmd.h"
+#include "utils.h"
+#include "creature.h"
+#include "item.h"
+#include "spellcasting.h"
+#include <sstream>
+#include <memory>
+
+namespace fs = std::filesystem;
+
+namespace cmd {
+ std::string healOrDamage(bool heal, std::vector<std::string> args, std::vector<std::string> flags) {
+ std::stringstream text;
+ std::vector<rules::Qualifier> qualifiers;
+ if(! heal) {
+ for(auto flag : flags) {
+ if(flag == "m" || flag == "magical") {
+ qualifiers.push_back(rules::Qualifier::Magical());
+ } else if(flag == "s" || flag == "silvered") {
+ qualifiers.push_back(rules::Qualifier::Silvered());
+ } else if(flag == "a" || flag == "adamantine") {
+ qualifiers.push_back(rules::Qualifier::Adamantine());
+ }
+ }
+ }
+ fs::path p = getTruePath(args[0]);
+ auto c = utils::instantiate<creature::Creature>(p);
+ int amnt = utils::parseInt(args[1]);
+ int initHP = c->getHP();
+ std::string dmgType = "force";
+ if(heal) {
+ c->applyHealing(amnt);
+ } else {
+ if(args.size() == 3) {
+ dmgType = args[2];
+ }
+ c->applyDamage(amnt, dmgType, qualifiers);
+ }
+ text << (heal? "Healing " : "Damaging ") << c->getGivenName() << " the " << c->getCreatureName() << " by " << amnt;
+ if(! heal) {
+ std::string qualsString;
+ std::vector<std::string> positiveQuals;
+ for(auto qual : qualifiers) {
+ positiveQuals.push_back(qual.getPositive());
+ }
+ if(! positiveQuals.empty()) {
+ qualsString = " " + utils::join(positiveQuals, ", ");
+ }
+ text << qualsString << " " << dmgType << " damage";
+ }
+ text << ". HP: " << initHP << " -> " << c->getHP() << "." << std::endl;
+ utils::saveJson(*c, p);
+ return text.str();
+ }
+
+ std::string heal(std::vector<std::string> args) {
+ return healOrDamage(true, args, {});
+ }
+
+ std::string damage(std::vector<std::string> args, std::vector<std::string> flags) {
+ return healOrDamage(false, args, flags);
+ }
+
+ std::string reset(std::vector<std::string> args) {
+ for(std::string s : args) {
+ fs::path p = getTruePath(s);
+ auto c = utils::instantiate<creature::Creature>(p);
+ c->longRest();
+ utils::saveJson(*c, p);
+ }
+ return "";
+ }
+
+ std::string set(std::vector<std::string> args) {
+ if(args.size() < 3) {
+ throw std::runtime_error("Subcommand 'set' requires at least 3 arguments");
+ }
+ fs::path p = getTruePath(args[0]);
+ args.erase(args.begin()); // remove path from args
+ auto c = utils::instantiate<creature::Creature>(p);
+ if(args[0] == "name") {
+ args.erase(args.begin()); // remove "name" from args
+ c->setGivenName(utils::join(args, " "));
+ } else if(args[0] == "proficiency") {
+ c->setProficiency(utils::parseInt(args[1]));
+ } else {
+ // Either an ability or a skill. If skill, then it could be multiple words long.
+ std::string toSet = args.back();
+ args.erase(--args.end());
+ std::string abilityOrSkill = utils::join(args, " ");
+ rules::Skill skill = rules::tryGetAbilityOrSkill<rules::Skill>(abilityOrSkill);
+ rules::Ability ability = rules::tryGetAbilityOrSkill<rules::Ability>(abilityOrSkill);
+ if(skill) {
+ // ensure lower case
+ utils::lower(toSet);
+ int level = -1;
+ if(toSet == "none") level = 0;
+ else if(toSet == "proficient") level = 1;
+ else if(toSet == "expert") level = 2;
+ if(level == -1) {
+ throw std::runtime_error("Skill levels can be set to none, proficient, or expert, but " + toSet + " was given.");
+ }
+ c->setProfLevel(skill, level);
+ } else if(ability) {
+ c->setScore(ability, utils::parseInt(toSet));
+ } else {
+ throw std::runtime_error("Subcommand 'set' expected an ability, skill, proficiency, or name field to set, but was given " + abilityOrSkill);
+ }
+ }
+ utils::saveJson(*c, p);
+ return "";
+ }
+
+ std::string add(std::vector<std::string> args) {
+ std::stringstream text;
+ fs::path p = getTruePath(args[0]);
+ args.erase(args.begin()); // remove path from args
+ auto c = utils::instantiate<creature::Creature>(p);
+ std::string addName = utils::join(args, " ");
+ std::shared_ptr<entry::Entry> ent;
+ fs::path path = getTruePath(addName);
+ if(fs::directory_entry(path).exists()) {
+ ent = utils::instantiate<entry::Entry>(path);
+ } else {
+ ent = entry::Entry::create(utils::findByName(addName));
+ }
+ // Determine if it is an item or a spell
+ auto i = std::dynamic_pointer_cast<entry::Item>(ent);
+ if(i) {
+ c->addInventoryItem(i);
+ } else {
+ auto s = std::dynamic_pointer_cast<entry::Spell>(ent);
+ if(s) {
+ c->addSpell(s);
+ } else {
+ throw std::runtime_error("Could not add the " + ent->getType() + " " + ent->getName() + " to " + c->getGivenName() + " the " + c->getName() + ": Requires a weapon, armor, or spell, but received object of type " + ent->getType());
+ }
+ }
+ utils::saveJson(*c, p);
+ text << "Added the " << ent->getType() << " " << ent->getName() << " to " << c->getGivenName() << " the " << c->getName() << std::endl;
+ return text.str();
+ }
+
+ std::string del(std::vector<std::string> args) {
+ std::stringstream text;
+ fs::path p = getTruePath(args[0]);
+ args.erase(args.begin()); // remove path from args
+ auto c = utils::instantiate<creature::Creature>(p);
+ //Atempt to load the item if it's a path
+ std::string itemName = utils::join(args, " ");
+ try {
+ auto i = utils::instantiate<entry::Entry>(getTruePath(itemName));
+ if(i) {
+ itemName = i->getName();
+ }
+ } catch(std::exception& e) {} // eat.
+ utils::lower(itemName);
+ // Loop through all of c's stuff, searching for itemName
+ std::shared_ptr<entry::Entry> removed;
+ for(auto item : c->getInventory()) {
+ std::string name = item->getName();
+ if(utils::lower(name) == itemName) {
+ c->removeInventoryItem(item);
+ removed = item;
+ break;
+ }
+ }
+ if(! removed) {
+ for(auto spell : c->getSpellcasting()->getSpells()) {
+ std::string name = spell->getName();
+ if(utils::lower(name) == itemName) {
+ c->removeSpell(spell);
+ removed = spell;
+ break;
+ }
+ }
+ }
+ utils::saveJson(*c, p);
+ if(removed) {
+ text << "Successfully removed the " << removed->Entry::getType() << " " << removed->getName() << std::endl;
+ } else {
+ text << "Could not find any inventory item nor spell by that name" << std::endl;
+ }
+ return text.str();
+ }
+}