aboutsummaryrefslogtreecommitdiff
path: root/src/cmd_manipulate.cc
diff options
context:
space:
mode:
authorYour Name <you@example.com>2022-01-03 16:25:45 -0500
committerYour Name <you@example.com>2022-01-03 16:25:45 -0500
commit3f78a7e1647ba94129236bd2bf4fc855c109628a (patch)
tree0a1538d44715738c8cbbae00bf1995777227b963 /src/cmd_manipulate.cc
parentd222c5a39943ed9f83f11d63a42bdff4978179af (diff)
downloaddmtool-3f78a7e1647ba94129236bd2bf4fc855c109628a.tar.gz
dmtool-3f78a7e1647ba94129236bd2bf4fc855c109628a.tar.bz2
dmtool-3f78a7e1647ba94129236bd2bf4fc855c109628a.zip
Added command to force a saving throw
Diffstat (limited to 'src/cmd_manipulate.cc')
-rw-r--r--src/cmd_manipulate.cc88
1 files changed, 61 insertions, 27 deletions
diff --git a/src/cmd_manipulate.cc b/src/cmd_manipulate.cc
index 294b600..aa6407d 100644
--- a/src/cmd_manipulate.cc
+++ b/src/cmd_manipulate.cc
@@ -17,16 +17,10 @@
namespace fs = std::filesystem;
namespace cmd {
- std::string healOrDamageProgrammatic(fs::path p, bool heal, int amnt, std::string dmgType, std::vector<rules::Qualifier> qualifiers) {
+ // Call after applying to format printing
+ std::string formatHealingDamage(const std::shared_ptr<creature::Creature>& c, int initHP, bool heal, int amnt, const std::string& dmgType, const std::vector<rules::Qualifier>& qualifiers) {
std::stringstream text;
- auto c = utils::instantiate<creature::Creature>(p);
- int initHP = c->getHP();
- if(heal) {
- c->applyHealing(amnt);
- } else {
- c->applyDamage(amnt, dmgType, qualifiers);
- }
- text << (heal? "Healing " : "Damaging ") << c->getGivenName() << " the " << c->getCreatureName() << " by " << amnt;
+ text << (heal? "Healing " : "Damaging ") << c->getGivenName() << " the " << c->getCreatureName() << " by " << amnt;
if(! heal) {
std::string qualsString;
std::vector<std::string> positiveQuals;
@@ -39,23 +33,23 @@ namespace cmd {
text << qualsString << " " << dmgType << " damage";
}
text << ". HP: " << initHP << " -> " << c->getHP() << "." << std::endl;
- utils::saveJson(*c, p);
return text.str();
}
- std::string healOrDamage(bool heal, std::vector<std::string> args, std::vector<std::string> flags) {
- 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());
- }
- }
- }
+ std::string healOrDamageProgrammatic(fs::path p, bool heal, int amnt, std::string dmgType, const std::vector<rules::Qualifier>& qualifiers) {
+ auto c = utils::instantiate<creature::Creature>(p);
+ int initHP = c->getHP();
+ if(heal) {
+ c->applyHealing(amnt);
+ } else {
+ c->applyDamage(amnt, dmgType, qualifiers);
+ }
+ utils::saveJson(*c, p);
+ return formatHealingDamage(c, initHP, heal, amnt, dmgType, qualifiers);
+ }
+
+ std::string healOrDamage(bool heal, std::vector<std::string> args, std::map<std::string, std::string> flags) {
+ auto qualifiers = parseQualifiers(flags);
fs::path p = getTruePath(args[0]);
int amnt = utils::parseInt(args[1]);
std::string dmgType = "force";
@@ -65,10 +59,10 @@ namespace cmd {
return healOrDamageProgrammatic(p, heal, amnt, dmgType, qualifiers);
}
- std::string attack(std::vector<std::string> args, std::vector<std::string> flags) {
+ std::string attack(std::vector<std::string> args, std::map<std::string, std::string> flags) {
std::stringstream text;
- bool is2h = std::find(flags.begin(), flags.end(), "2") != flags.end();
- bool is1h = std::find(flags.begin(), flags.end(), "1") != flags.end();
+ bool is2h = flags.find("2") != flags.end();
+ bool is1h = flags.find("1") != flags.end();
if(is2h and is1h) {
text << "ERROR: Cannot be both 1 handed and 2 handed!" << std::endl;
return text.str();
@@ -120,9 +114,49 @@ namespace cmd {
return healOrDamage(true, args, {});
}
- std::string damage(std::vector<std::string> args, std::vector<std::string> flags) {
+ std::string damage(std::vector<std::string> args, std::map<std::string, std::string> flags) {
return healOrDamage(false, args, flags);
}
+
+ std::string save(std::vector<std::string> args, std::map<std::string, std::string> flags) {
+ if(args.size() < 3) {
+ throw std::runtime_error("Subcommand 'save' requires at least 3 arguments");
+ }
+ std::stringstream text;
+ rules::Ability ability = rules::tryGetAbilityOrSkill<rules::Ability>(args[0]);
+ if(! ability) {
+ throw std::runtime_error("Requires a valid ability name but received \"" + args[0] + "\".");
+ }
+ args.erase(args.begin());
+ int DC = utils::parseInt(args[0]);
+ args.erase(args.begin());
+ // Now iterate over the paths
+ for(std::string s : args) {
+ fs::path p = getTruePath(s);
+ auto c = utils::instantiate<creature::Creature>(p);
+ int initHP = c->getHP();
+ int rolled = dice::roll(20);
+ int bonus = c->getAbilitySaveBonus(ability);
+ int damage = 0;
+ std::string type = "force";
+ bool halves = flags.find("halves") != flags.end();
+ if(flags.find("damage") != flags.end()) {
+ damage = utils::parseInt(flags.at("damage"));
+ if(flags.find("type") != flags.end()) type = flags.at("type");
+ auto qualifiers = parseQualifiers(flags);
+ rolled = c->saveOrDamage(ability, DC, damage, type, qualifiers, halves);
+ rolled -= bonus; // It's combined in creature
+ }
+ bool passed = rolled + bonus >= DC;
+ text << c->getName() << " " << (passed? "PASS" : "FAIL") << ": ";
+ text << formatRoll(ability.getFull(), "save", rolled, bonus);
+ if(flags.find("damage") != flags.end() and (halves or ! passed)) {
+ text << formatHealingDamage(c, initHP, false, damage, type, parseQualifiers(flags));
+ }
+ utils::saveJson(*c, p);
+ }
+ return text.str();
+ }
std::string reset(std::vector<std::string> args) {
for(std::string s : args) {