pfrpg_core 0.0.2 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +23 -0
- data/Rakefile +1 -1
- data/lib/pfrpg_core/attack.rb +66 -0
- data/lib/pfrpg_core/attributes.rb +113 -0
- data/lib/pfrpg_core/avatar_url.rb +15 -0
- data/lib/pfrpg_core/bonus.rb +1 -1
- data/lib/pfrpg_core/character.rb +83 -0
- data/lib/pfrpg_core/class_feature.rb +31 -0
- data/lib/pfrpg_core/combat.rb +60 -0
- data/lib/pfrpg_core/demographics.rb +30 -0
- data/lib/pfrpg_core/derived/combat_bonuses.rb +78 -0
- data/lib/pfrpg_core/derived/defense.rb +29 -0
- data/lib/pfrpg_core/derived/magic.rb +145 -0
- data/lib/pfrpg_core/derived/misc.rb +114 -0
- data/lib/pfrpg_core/derived/offense.rb +49 -0
- data/lib/pfrpg_core/derived.rb +10 -0
- data/lib/pfrpg_core/effect_processor.rb +1 -1
- data/lib/pfrpg_core/effect_totaler.rb +29 -0
- data/lib/pfrpg_core/equipment_totaler.rb +14 -0
- data/lib/pfrpg_core/feat.rb +27 -0
- data/lib/pfrpg_core/feat_totaler.rb +61 -0
- data/lib/pfrpg_core/feature_duplicator.rb +26 -0
- data/lib/pfrpg_core/feature_totaler.rb +86 -0
- data/lib/pfrpg_core/filterable.rb +1 -1
- data/lib/pfrpg_core/filters/filter.rb +14 -0
- data/lib/pfrpg_core/filters/proficiency_mod.rb +34 -0
- data/lib/pfrpg_core/filters/prowess_mod.rb +20 -0
- data/lib/pfrpg_core/filters/ranged_attack_mod.rb +28 -0
- data/lib/pfrpg_core/filters/skill_focus_mod.rb +25 -0
- data/lib/pfrpg_core/filters/strength_mod.rb +21 -0
- data/lib/pfrpg_core/filters/weapon_finesse_mod.rb +24 -0
- data/lib/pfrpg_core/filters/weapon_focus_mod.rb +23 -0
- data/lib/pfrpg_core/filters/weapon_mastery_mod.rb +23 -0
- data/lib/pfrpg_core/filters/weapon_specialization_mod.rb +22 -0
- data/lib/pfrpg_core/filters/weapon_training_mod.rb +22 -0
- data/lib/pfrpg_core/inventory.rb +62 -0
- data/lib/pfrpg_core/item.rb +42 -0
- data/lib/pfrpg_core/level.rb +14 -0
- data/lib/pfrpg_core/level_parser.rb +9 -1
- data/lib/pfrpg_core/macros/macro.rb +62 -0
- data/lib/pfrpg_core/macros/manyshot_macro.rb +12 -0
- data/lib/pfrpg_core/macros/power_attack_macro.rb +12 -0
- data/lib/pfrpg_core/macros/rapid_shot_macro.rb +12 -0
- data/lib/pfrpg_core/macros/sneak_attack_macro.rb +33 -0
- data/lib/pfrpg_core/macros/vital_strike_macro.rb +12 -0
- data/lib/pfrpg_core/null_object.rb +31 -29
- data/lib/pfrpg_core/saving_throws.rb +43 -0
- data/lib/pfrpg_core/skills.rb +141 -0
- data/lib/pfrpg_core/specializer.rb +48 -0
- data/lib/pfrpg_core/spell.rb +37 -0
- data/lib/pfrpg_core/spell_books.rb +36 -0
- data/lib/pfrpg_core/spells_per_level.rb +53 -0
- data/lib/pfrpg_core/version.rb +1 -1
- data/lib/pfrpg_core/weapon_training_calculator.rb +36 -0
- data/lib/pfrpg_core.rb +13 -2
- data/test/alignment_test.rb +30 -0
- data/test/attributes_test.rb +50 -0
- data/test/bonus_test.rb +29 -0
- data/test/feat_totaler_test.rb +24 -7
- data/test/helper.rb +1 -1
- data/test/levels_test.rb +19 -0
- data/test/misc_test.rb +78 -0
- data/test/saves_test.rb +54 -0
- data/test/skills_test.rb +93 -0
- data/test/test_helper.rb +78 -0
- metadata +66 -35
- data/lib/pfrpg_core/affectable.rb +0 -7
- data/lib/pfrpg_core/effect.rb +0 -39
- data/lib/pfrpg_core/prerequisite.rb +0 -58
- data/lib/pfrpg_core/quick_classed.rb +0 -37
@@ -0,0 +1,25 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
module Filters
|
3
|
+
class SkillFocusMod
|
4
|
+
attr_reader :character
|
5
|
+
def initialize(character)
|
6
|
+
@character = character
|
7
|
+
end
|
8
|
+
|
9
|
+
def filter(skill)
|
10
|
+
prof_feats = character.feats.select { |x| x.name == 'Skill Focus' }
|
11
|
+
skills = []
|
12
|
+
prof_feats.each do |f|
|
13
|
+
skills << f.feat_special
|
14
|
+
end
|
15
|
+
if skills.include? skill.name
|
16
|
+
modify_skill_for_skill_focus(skill)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def modify_skill_for_skill_focus(skill)
|
21
|
+
skill.misc_bonus += 3
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
module Filters
|
3
|
+
class StrengthMod
|
4
|
+
attr_reader :character
|
5
|
+
def initialize(character)
|
6
|
+
@character = character
|
7
|
+
end
|
8
|
+
|
9
|
+
def filter(attack)
|
10
|
+
if attack.weapon.applies_strength_dmg?
|
11
|
+
base_mod = character.attributes.str_mod
|
12
|
+
if(attack.weapon.weight_class == 'Two-handed')
|
13
|
+
base_mod = (base_mod * 1.5)
|
14
|
+
end
|
15
|
+
attack.filter_str << "Strength damage : #{base_mod}"
|
16
|
+
attack.damage.add_static(base_mod) if attack.weapon.applies_strength_dmg?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
module Filters
|
3
|
+
class WeaponFinesseMod
|
4
|
+
attr_reader :character
|
5
|
+
def initialize(character)
|
6
|
+
@character = character
|
7
|
+
end
|
8
|
+
|
9
|
+
def filter(attack)
|
10
|
+
if character.feats.find { |x| x.name == 'Weapon Finesse' }
|
11
|
+
modify_attack_for_weapon_finesse(attack, character.attributes.dex_mod, character.attributes.str_mod)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def modify_attack_for_weapon_finesse(attack, dex, str)
|
16
|
+
if attack.weight_class == 'light' || attack.weight_class == 'natural'
|
17
|
+
attack.filter_str << "Weapon Finesse: -#{dex}, +#{str}"
|
18
|
+
attack.other_bonus += dex
|
19
|
+
attack.other_bonus -= str
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
module Filters
|
3
|
+
class WeaponFocusMod
|
4
|
+
attr_reader :character
|
5
|
+
def initialize(character)
|
6
|
+
@character = character
|
7
|
+
end
|
8
|
+
|
9
|
+
def filter(attack)
|
10
|
+
f = character.feats.find { |x| x.name == 'Weapon Focus' }
|
11
|
+
if f != nil && (attack.weapon.name.downcase == f.special.downcase)
|
12
|
+
modify(attack)
|
13
|
+
end
|
14
|
+
return attack
|
15
|
+
end
|
16
|
+
|
17
|
+
def modify(attack)
|
18
|
+
attack.filter_str << "Weapon Focus: attack bonus +1"
|
19
|
+
attack.other_bonus += 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class PfrpgCore::Filters::WeaponMasteryMod
|
2
|
+
attr_reader :character, :special
|
3
|
+
def initialize(character, feature)
|
4
|
+
@character = character
|
5
|
+
@special = feature.special
|
6
|
+
end
|
7
|
+
|
8
|
+
def filter(attack)
|
9
|
+
if attack.weapon.name == @special
|
10
|
+
modify(attack)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def modify(attack)
|
15
|
+
attack.critical_damage = increase_crit(attack.critical_damage)
|
16
|
+
end
|
17
|
+
|
18
|
+
def increase_crit(crit_str)
|
19
|
+
crit_num = crit_str.split("x")[0].to_i
|
20
|
+
crit_num += 1
|
21
|
+
"#{crit_num}x"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
module Filters
|
3
|
+
class WeaponSpecializationMod
|
4
|
+
attr_reader :character
|
5
|
+
def initialize(character)
|
6
|
+
@character = character
|
7
|
+
end
|
8
|
+
|
9
|
+
def filter(attack)
|
10
|
+
f = character.feats.find { |x| x.name == 'Weapon Specialization' }
|
11
|
+
if f != nil && attack.weapon.name == f.feat_special
|
12
|
+
modify(a)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def modify(attack)
|
17
|
+
attack.filter_str << "Weapon Specialization: +2 damage"
|
18
|
+
attack.damage.add_static(2)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
module Filters
|
3
|
+
class WeaponTrainingMod
|
4
|
+
attr_reader :character, :feature
|
5
|
+
def initialize(character, feature)
|
6
|
+
@character = character
|
7
|
+
@feature = feature
|
8
|
+
end
|
9
|
+
|
10
|
+
def filter(attack)
|
11
|
+
trainer = PfrpgCore::WeaponTrainingCalculator.new(character)
|
12
|
+
trained = trainer.trained_value(attack.weapon, feature)
|
13
|
+
modify(attack, trained)
|
14
|
+
end
|
15
|
+
|
16
|
+
def modify(attack, val)
|
17
|
+
attack.other_bonus += val
|
18
|
+
attack.damage.add_static(val)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
class Inventory
|
3
|
+
attr_reader :equipment, :inventory
|
4
|
+
def initialize(equipment, inventory)
|
5
|
+
@equipment = equipment
|
6
|
+
@inventory = inventory
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_armor_ac
|
10
|
+
equipped_armor.nil? ? 0 : equipped_armor.ac_bonus
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_shield_ac
|
14
|
+
shield = equipment.find { |x| x.slot == 'shield' }
|
15
|
+
shield.nil? ? 0 : shield.ac_bonus
|
16
|
+
end
|
17
|
+
|
18
|
+
def equipped_defensive
|
19
|
+
equipment.select { |x| x.ac_bonus != nil }
|
20
|
+
end
|
21
|
+
|
22
|
+
def equipped_armor
|
23
|
+
equipment.find { |x| x.slot == 'armor' }
|
24
|
+
end
|
25
|
+
|
26
|
+
def armor_and_shield
|
27
|
+
e = [ equipped_armor ]
|
28
|
+
e << equipment.find { |x| x.slot == 'shield' }
|
29
|
+
e.delete_if { |x| x == nil }
|
30
|
+
e
|
31
|
+
end
|
32
|
+
|
33
|
+
# monk is obnoxious
|
34
|
+
def equipped_weapons(levels = [])
|
35
|
+
weapons = equipment.select { |x| x.type == 'Weapon' || x.type == 'MagicWeapon' }
|
36
|
+
monk = levels.find { |x| x.classname == 'Monk' }
|
37
|
+
weapons << unarmed_strike(monk.rank) if (monk != nil && weapons.empty?)
|
38
|
+
return weapons
|
39
|
+
end
|
40
|
+
|
41
|
+
def unarmed_strike(monk_level)
|
42
|
+
PfrpgClasses::Heroclass.by_name('Monk').get_unarmed_weapon(monk_level)
|
43
|
+
end
|
44
|
+
|
45
|
+
def ac_penalty(bonuses = Bonuses.new)
|
46
|
+
ac_penalty = 0
|
47
|
+
equipment.each do |e|
|
48
|
+
ac_penalty += NullObject.maybe(e.armor_check_penalty).to_i
|
49
|
+
end
|
50
|
+
ac_penalty += bonuses.get("ac_penalty").to_i
|
51
|
+
ac_penalty = 0 if ac_penalty > 0
|
52
|
+
ac_penalty
|
53
|
+
end
|
54
|
+
|
55
|
+
def as_json(options={})
|
56
|
+
{
|
57
|
+
equipment: get_equipment,
|
58
|
+
inventory: get_inventory
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
class Item
|
3
|
+
include PfrpgUtility::Affectable
|
4
|
+
attr_reader :name, :description, :slot, :type, :equipped, :effects,
|
5
|
+
:cost, :dmg_s, :dmg_m, :critical_range, :critical_dmg,
|
6
|
+
:range, :weight, :dmg_type, :special, :source, :weapon_type,
|
7
|
+
:weight_class, :ac_bonus, :max_dex_bonus, :armor_check_penalty,
|
8
|
+
:arcane_spell_failure_chance, :speed_twenty, :speed_thirty
|
9
|
+
|
10
|
+
def initialize(item, equipped)
|
11
|
+
@name = item[:name]
|
12
|
+
@description = item[:description]
|
13
|
+
@slot = item[:slot]
|
14
|
+
@type = item[:type]
|
15
|
+
@effects = item[:effects]
|
16
|
+
@cost = item[:cost]
|
17
|
+
@dmg_m = item[:dmg_m]
|
18
|
+
@dmg_s = item[:dmg_s]
|
19
|
+
@critical_range = item[:critical_range]
|
20
|
+
@critical_dmg = item[:critical_dmg]
|
21
|
+
@range = item[:range]
|
22
|
+
@weight = item[:weight]
|
23
|
+
@dmg_type = item[:dmg_type]
|
24
|
+
@special = item[:special]
|
25
|
+
@source = item[:source]
|
26
|
+
@weapon_type = item[:weapon_type]
|
27
|
+
@weight_class = item[:weight_class]
|
28
|
+
@ac_bonus = item[:ac_bonus]
|
29
|
+
@max_dex_bonus = item[:max_dex_bonus]
|
30
|
+
@armor_check_penalty = item[:armor_check_penalty]
|
31
|
+
@arcane_spell_failure_chance = item[:arcane_spell_failure_chance]
|
32
|
+
@speed_twenty = item[:speed_twenty]
|
33
|
+
@speed_thirty = item[:speed_thirty]
|
34
|
+
@equipped = equipped
|
35
|
+
end
|
36
|
+
|
37
|
+
def applies_strength_dmg?
|
38
|
+
['light', 'one-handed', 'two-handed'].include?(weight_class.downcase) ||
|
39
|
+
name == 'Sling'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'pfrpg_classes'
|
2
|
+
|
3
|
+
module PfrpgCore
|
4
|
+
class Level
|
5
|
+
attr_reader :rank, :classname, :favored, :heroclass
|
6
|
+
def initialize(level)
|
7
|
+
@rank = level.class_number
|
8
|
+
@classname = level.class_name
|
9
|
+
@heroclass = PfrpgClasses::Heroclass.by_name(@classname)
|
10
|
+
@favored = level.favored
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -3,13 +3,21 @@ module PfrpgCore
|
|
3
3
|
attr_reader :level_string, :levels
|
4
4
|
def initialize(level_string)
|
5
5
|
@level_string = level_string
|
6
|
-
|
6
|
+
begin
|
7
|
+
@levels = parse
|
8
|
+
rescue Exception
|
9
|
+
@levels = {}
|
10
|
+
end
|
7
11
|
end
|
8
12
|
|
9
13
|
def total
|
10
14
|
return @levels.values.inject(0) { |sum, l| sum + l }
|
11
15
|
end
|
12
16
|
|
17
|
+
def levelmap
|
18
|
+
@levels.map { |x| PfrpgCore::Level.new(x) }
|
19
|
+
end
|
20
|
+
|
13
21
|
def parse
|
14
22
|
levels = {}
|
15
23
|
splits = @level_string.split(';')
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
class Macro
|
3
|
+
attr_reader :character
|
4
|
+
|
5
|
+
def initialize(character)
|
6
|
+
@character = character
|
7
|
+
end
|
8
|
+
|
9
|
+
def available?
|
10
|
+
false
|
11
|
+
end
|
12
|
+
|
13
|
+
def applies_to?(_weapon)
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def slug
|
18
|
+
name = self.class.name.split("PfrpgCore::")[1]
|
19
|
+
name.split('Macro').first
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
slug.titleize
|
24
|
+
end
|
25
|
+
|
26
|
+
def info
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def as_json
|
31
|
+
{
|
32
|
+
slug: slug,
|
33
|
+
name: name,
|
34
|
+
info: info
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.find_available(character)
|
39
|
+
macro_subclasses.map { |m| m.new(character) }.keep_if { |m| m.available? }
|
40
|
+
end
|
41
|
+
|
42
|
+
# TODO: This should not be needed - Rails provides #subclasses but there is
|
43
|
+
# crazy classloading stuff happening (or not happening actually) that
|
44
|
+
# is causing this to be empty...
|
45
|
+
def self.macro_subclasses
|
46
|
+
# Macro.subclasses
|
47
|
+
[
|
48
|
+
PowerAttackMacro,
|
49
|
+
SneakAttackMacro,
|
50
|
+
RapidShotMacro,
|
51
|
+
ManyshotMacro,
|
52
|
+
VitalStrikeMacro
|
53
|
+
]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
require 'pfrpg_core/macros/manyshot_macro'
|
59
|
+
require 'pfrpg_core/macros/power_attack_macro'
|
60
|
+
require 'pfrpg_core/macros/rapid_shot_macro'
|
61
|
+
require 'pfrpg_core/macros/sneak_attack_macro'
|
62
|
+
require 'pfrpg_core/macros/vital_strike_macro'
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
class PowerAttackMacro < Macro
|
3
|
+
|
4
|
+
def available?
|
5
|
+
character.feats.any? { |feat| feat.name == 'Power Attack' }
|
6
|
+
end
|
7
|
+
|
8
|
+
def applies_to?(weapon)
|
9
|
+
weapon.weight_class != 'ranged' && weapon.weight_class != 'ammunition'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
class SneakAttackMacro < Macro
|
3
|
+
|
4
|
+
def initialize(character)
|
5
|
+
super
|
6
|
+
|
7
|
+
sneak_attack_features = character.class_features.select do |feature|
|
8
|
+
feature.name.downcase.start_with? 'sneak a'
|
9
|
+
end
|
10
|
+
|
11
|
+
@sneak_attack_level = sneak_attack_features.map do |feature|
|
12
|
+
/Sneak Attack \((\d+)d6\)/.match(feature.name)[1].to_i
|
13
|
+
end.max || 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def name
|
17
|
+
"Sneak Attack (level #{@sneak_attack_level})"
|
18
|
+
end
|
19
|
+
|
20
|
+
def available?
|
21
|
+
@sneak_attack_level.nonzero?
|
22
|
+
end
|
23
|
+
|
24
|
+
def applies_to?(weapon)
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
def info
|
29
|
+
{ sneakAttackLevel: @sneak_attack_level }
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -1,37 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module PfrpgCore
|
2
|
+
class NullObject < Numeric
|
3
|
+
def to_a; []; end
|
4
|
+
def to_s; ""; end
|
5
|
+
def to_str; ""; end
|
6
|
+
def to_f; 0.0; end
|
7
|
+
def to_i; 0; end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def empty?
|
10
|
+
true
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
def as_json(options={})
|
14
|
+
""
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
def method_missing(*args, &block)
|
18
|
+
self
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
def self.maybe(value)
|
22
|
+
case value
|
23
|
+
when nil then NullObject.new
|
24
|
+
else value
|
25
|
+
end
|
24
26
|
end
|
25
|
-
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
def +(other)
|
29
|
+
case other
|
30
|
+
when String
|
31
|
+
to_s + other
|
32
|
+
when Fixnum
|
33
|
+
to_i + other
|
34
|
+
when Float
|
35
|
+
to_f + other
|
36
|
+
end
|
35
37
|
end
|
36
38
|
end
|
37
|
-
end
|
39
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module PfrpgCore
|
2
|
+
class SavingThrows
|
3
|
+
|
4
|
+
def initialize(saves, bonuses, attributes)
|
5
|
+
@attributes = attributes
|
6
|
+
@will = saves[:will]
|
7
|
+
@will_bonus = NullObject.maybe(bonuses.get('will')).to_i
|
8
|
+
@fortitude = saves[:fort]
|
9
|
+
@fort_bonus = NullObject.maybe(bonuses.get('fort')).to_i
|
10
|
+
@reflex = saves[:ref]
|
11
|
+
@ref_bonus = NullObject.maybe(bonuses.get('ref')).to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def fortitude
|
15
|
+
@attributes.con_mod + @fortitude + @fort_bonus
|
16
|
+
end
|
17
|
+
|
18
|
+
def reflex
|
19
|
+
@attributes.dex_mod + @reflex + @ref_bonus
|
20
|
+
end
|
21
|
+
|
22
|
+
def will
|
23
|
+
@attributes.wis_mod + @will + @will_bonus
|
24
|
+
end
|
25
|
+
|
26
|
+
def as_json(options={})
|
27
|
+
{
|
28
|
+
:con_modifier => @attributes.con_mod,
|
29
|
+
:wis_modifier => @attributes.wis_mod,
|
30
|
+
:dex_modifier => @attributes.dex_mod,
|
31
|
+
:base_ref => @reflex,
|
32
|
+
:base_fort => @fortitude,
|
33
|
+
:base_will => @will,
|
34
|
+
:bonus_ref => @ref_bonus,
|
35
|
+
:bonus_will => @will_bonus,
|
36
|
+
:bonus_fort => @fort_bonus,
|
37
|
+
:fortitude => fortitude,
|
38
|
+
:reflex => reflex,
|
39
|
+
:will => will
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|