pfrpg_core 0.0.2 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|