aboutsummaryrefslogtreecommitdiff
path: root/src/weapon.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/weapon.cc')
-rw-r--r--src/weapon.cc82
1 files changed, 67 insertions, 15 deletions
diff --git a/src/weapon.cc b/src/weapon.cc
index b3dad1d..dd60b6c 100644
--- a/src/weapon.cc
+++ b/src/weapon.cc
@@ -1,6 +1,7 @@
#include "weapon.h"
#include "creature.h"
#include "rules.h"
+#include "dice.h"
#include <string>
#include <sstream>
#include <algorithm>
@@ -8,13 +9,6 @@
using namespace std;
namespace entry {
- int Weapon::getDamageDieSides(bool versatile) const {
- if(versatile && getProperties().count("versatile")) {
- return damageDieSides + 2;
- }
- return damageDieSides;
- }
-
string getTextHelper(const Weapon& w, string toHitBonus, string damageBonus) {
stringstream text;
text << "+" << toHitBonus << " to hit, ";
@@ -27,9 +21,25 @@ namespace entry {
if(w.getRange().second > 0) {
text << "range " << w.getRange().first << "/" << w.getRange().second << " ft.";
}
- text << " Hit: " << w.getDamageDieCount() << "d" << w.getDamageDieSides() << " + " << damageBonus << " " << w.getDamageType() << " damage";
- if(w.getProperties().count("versatile")) {
- text << " (or " << w.getDamageDieCount() << "d" << w.getDamageDieSides(true) << " + " << damageBonus << " " << w.getDamageType() << " damage if two-handed)";
+ text << " Hit: ";
+ auto dmgs = w.getDamage();
+ for(size_t i = 0; i < dmgs.size(); i++) {
+ const Damage& d = dmgs[i];
+ text << d.count << "d" << d.sides;
+ if(i == 0) {
+ if(w.getProperties().count("versatile")) {
+ text << " (or " << d.count << "d" << d.sides + 2 << " if two-handed)";
+ }
+ text << " + " << damageBonus;
+ }
+ text << " " << d.type << " damage";
+ if(i < dmgs.size()-1) {
+ if(d.isOr) {
+ text << " or ";
+ } else {
+ text << " plus ";
+ }
+ }
}
text << ".";
auto props = w.getProperties();
@@ -39,10 +49,56 @@ namespace entry {
if(! props.empty()) {
text << " Additional properties: " << utils::join(props, ", ") << ".";
}
+ if(! w.Entry::getText().empty()) {
+ text << " " << w.Entry::getText();
+ }
text << " " << genText(static_cast<const Substantial&>(w));
return text.str();
}
+ vector<Damage> rollDmg(const Weapon& w, bool versatile) {
+ vector<Damage> dmgs = w.getDamage();
+ bool first = true;
+ for(Damage& d : dmgs) {
+ d.rolled = 0;
+ int sides = d.sides;
+ if(first && versatile && w.getProperties().count("versatile")) {
+ sides += 2;
+ }
+ first = false;
+ for(int i = 0; i < d.count; i++) {
+ d.rolled += dice::roll(sides);
+ }
+ }
+ return dmgs;
+ }
+
+ string formatDmg(const Weapon& w, const creature::Creature& c) {
+ stringstream text;
+ vector<Damage> dmgsNoVersatile = rollDmg(w, false);
+ vector<Damage> dmgsVersatile = rollDmg(w, true);
+ int abilityBonus = c.getBonus(creature::getBestAbility(getAbilityOptions(w), c));
+ for(size_t i = 0; i < dmgsNoVersatile.size(); i++) {
+ if(i == 0) {
+ text << dmgsNoVersatile[i].rolled + abilityBonus;
+ if(w.getProperties().count("versatile")) {
+ text << " (or " << dmgsVersatile[i].rolled + abilityBonus << " if two-handed)";
+ }
+ } else {
+ text << dmgsNoVersatile[i].rolled;
+ }
+ text << " " << dmgsNoVersatile[i].type << " damage";
+ if(i < dmgsNoVersatile.size()-1) {
+ if(dmgsNoVersatile[i].isOr) {
+ text << " or ";
+ } else {
+ text << " plus ";
+ }
+ }
+ }
+ return text.str();
+ }
+
vector<rules::Ability> getAbilityOptions(const Weapon& w) {
// Do finesse
if(w.getProperties().count("finesse")) {
@@ -76,11 +132,7 @@ namespace entry {
stringstream text;
text << genText(static_cast<const Item&>(w), c);
// Determine best ability bonus
- auto abilities = getAbilityOptions(w);
- int abilityBonus = c.getBonus(abilities[0]);
- if(abilities.size() == 2) {
- abilityBonus = max(abilityBonus, c.getBonus(abilities[1]));
- }
+ int abilityBonus = c.getBonus(creature::getBestAbility(getAbilityOptions(w), c));
text << ": " << getTextHelper(w, to_string(abilityBonus + c.getProficiency()), to_string(abilityBonus));
return text.str();
}