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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +23 -0
  3. data/Rakefile +1 -1
  4. data/lib/pfrpg_core/attack.rb +66 -0
  5. data/lib/pfrpg_core/attributes.rb +113 -0
  6. data/lib/pfrpg_core/avatar_url.rb +15 -0
  7. data/lib/pfrpg_core/bonus.rb +1 -1
  8. data/lib/pfrpg_core/character.rb +83 -0
  9. data/lib/pfrpg_core/class_feature.rb +31 -0
  10. data/lib/pfrpg_core/combat.rb +60 -0
  11. data/lib/pfrpg_core/demographics.rb +30 -0
  12. data/lib/pfrpg_core/derived/combat_bonuses.rb +78 -0
  13. data/lib/pfrpg_core/derived/defense.rb +29 -0
  14. data/lib/pfrpg_core/derived/magic.rb +145 -0
  15. data/lib/pfrpg_core/derived/misc.rb +114 -0
  16. data/lib/pfrpg_core/derived/offense.rb +49 -0
  17. data/lib/pfrpg_core/derived.rb +10 -0
  18. data/lib/pfrpg_core/effect_processor.rb +1 -1
  19. data/lib/pfrpg_core/effect_totaler.rb +29 -0
  20. data/lib/pfrpg_core/equipment_totaler.rb +14 -0
  21. data/lib/pfrpg_core/feat.rb +27 -0
  22. data/lib/pfrpg_core/feat_totaler.rb +61 -0
  23. data/lib/pfrpg_core/feature_duplicator.rb +26 -0
  24. data/lib/pfrpg_core/feature_totaler.rb +86 -0
  25. data/lib/pfrpg_core/filterable.rb +1 -1
  26. data/lib/pfrpg_core/filters/filter.rb +14 -0
  27. data/lib/pfrpg_core/filters/proficiency_mod.rb +34 -0
  28. data/lib/pfrpg_core/filters/prowess_mod.rb +20 -0
  29. data/lib/pfrpg_core/filters/ranged_attack_mod.rb +28 -0
  30. data/lib/pfrpg_core/filters/skill_focus_mod.rb +25 -0
  31. data/lib/pfrpg_core/filters/strength_mod.rb +21 -0
  32. data/lib/pfrpg_core/filters/weapon_finesse_mod.rb +24 -0
  33. data/lib/pfrpg_core/filters/weapon_focus_mod.rb +23 -0
  34. data/lib/pfrpg_core/filters/weapon_mastery_mod.rb +23 -0
  35. data/lib/pfrpg_core/filters/weapon_specialization_mod.rb +22 -0
  36. data/lib/pfrpg_core/filters/weapon_training_mod.rb +22 -0
  37. data/lib/pfrpg_core/inventory.rb +62 -0
  38. data/lib/pfrpg_core/item.rb +42 -0
  39. data/lib/pfrpg_core/level.rb +14 -0
  40. data/lib/pfrpg_core/level_parser.rb +9 -1
  41. data/lib/pfrpg_core/macros/macro.rb +62 -0
  42. data/lib/pfrpg_core/macros/manyshot_macro.rb +12 -0
  43. data/lib/pfrpg_core/macros/power_attack_macro.rb +12 -0
  44. data/lib/pfrpg_core/macros/rapid_shot_macro.rb +12 -0
  45. data/lib/pfrpg_core/macros/sneak_attack_macro.rb +33 -0
  46. data/lib/pfrpg_core/macros/vital_strike_macro.rb +12 -0
  47. data/lib/pfrpg_core/null_object.rb +31 -29
  48. data/lib/pfrpg_core/saving_throws.rb +43 -0
  49. data/lib/pfrpg_core/skills.rb +141 -0
  50. data/lib/pfrpg_core/specializer.rb +48 -0
  51. data/lib/pfrpg_core/spell.rb +37 -0
  52. data/lib/pfrpg_core/spell_books.rb +36 -0
  53. data/lib/pfrpg_core/spells_per_level.rb +53 -0
  54. data/lib/pfrpg_core/version.rb +1 -1
  55. data/lib/pfrpg_core/weapon_training_calculator.rb +36 -0
  56. data/lib/pfrpg_core.rb +13 -2
  57. data/test/alignment_test.rb +30 -0
  58. data/test/attributes_test.rb +50 -0
  59. data/test/bonus_test.rb +29 -0
  60. data/test/feat_totaler_test.rb +24 -7
  61. data/test/helper.rb +1 -1
  62. data/test/levels_test.rb +19 -0
  63. data/test/misc_test.rb +78 -0
  64. data/test/saves_test.rb +54 -0
  65. data/test/skills_test.rb +93 -0
  66. data/test/test_helper.rb +78 -0
  67. metadata +66 -35
  68. data/lib/pfrpg_core/affectable.rb +0 -7
  69. data/lib/pfrpg_core/effect.rb +0 -39
  70. data/lib/pfrpg_core/prerequisite.rb +0 -58
  71. data/lib/pfrpg_core/quick_classed.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24480e464296020ce60bfca1fd95227cadb8a359
4
- data.tar.gz: 83c3d9251284b87f32e90b80f60fb8f7268d5c85
3
+ metadata.gz: a81b275bf8b1f380b13725652a251c708cd48916
4
+ data.tar.gz: 6e3b733562b317dd49e56212fa62a9e5e73c8ba8
5
5
  SHA512:
6
- metadata.gz: 1e9e1834b2016406b8bbe9d48635a33fccfec7f43783bc05c6dd6d3b539772fd5f49654e495fe4ca845713cc0ba8012cd633634ef88b96092122c06b4cdff962
7
- data.tar.gz: 187698110638a04a7b3ecfa318102cc2e00e3d8a771a581c9d90d18b144c4f1bb4bb16ac9da5465316c36b20ee40a467698cda211a74b4ac46417f917d44ded7
6
+ metadata.gz: 6d64a6bd2e769cad43e6f45994b9630678a40bcc5a22c26259566add1f313392acd68a6fe07d572a42ecef60ef7cd87a15c4676e978b8180f793d46001438e63
7
+ data.tar.gz: edc3cd41f5c5d5edd0037d5602f4bc20597f3216992974519f83fd0181e44f3c6cebf9a24854f538981f2c11f9b8ba374d3f1da91e6d9f17ef03d949668aef25
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License (MIT)
2
+ [OSI Approved License]
3
+ The MIT License (MIT)
4
+
5
+ Copyright (c) 2014 HeroSheets, LLC
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
data/Rakefile CHANGED
@@ -2,6 +2,6 @@ require 'rake/testtask'
2
2
 
3
3
  Rake::TestTask.new do |t|
4
4
  t.libs.push "lib"
5
- t.test_files = FileList['test/*_test.rb']
5
+ t.test_files = FileList['test/*.rb']
6
6
  t.verbose = true
7
7
  end
@@ -0,0 +1,66 @@
1
+ module PfrpgCore
2
+ class Attack
3
+ include Filterable
4
+
5
+ attr_accessor :weapon_name, :range, :damage, :weapon_type,
6
+ :base_bonus, :weapon_bonus, :weight_class, :critical_range,
7
+ :critical_dmg, :size, :weapon, :other_bonus, :filter_str,
8
+ :strength_bonus, :bab, :macros
9
+
10
+ def initialize(args)
11
+ @weapon_name = args[:weapon_name]
12
+ @range = args[:range]
13
+ @weight_class = args[:weight_class]
14
+ @damage = args[:damage]
15
+ @weapon_type = args[:weapon_type]
16
+ @critical_range = args[:critical_range]
17
+ @critical_dmg = args[:critical_dmg]
18
+ @weapon_bonus = args[:bonus] # bonus from weapon
19
+ @strength_bonus = args[:strength_bonus]
20
+ @bab = args[:bab]
21
+ @size = args[:size]
22
+ @filters = args[:filters]
23
+ @filter_str = []
24
+ @weapon = args[:weapon]
25
+ @macros = args[:macros]
26
+ @other_bonus = 0 # things like weapon spec, training, etc
27
+ apply_filters
28
+ end
29
+
30
+ def attack_bonus
31
+ attacks = []
32
+ static_bonus = NullObject.maybe(weapon_bonus) +
33
+ NullObject.maybe(other_bonus) +
34
+ NullObject.maybe(strength_bonus)
35
+ base = NullObject.maybe(bab)
36
+ attacks << (static_bonus + base)
37
+ while(base >= 6)
38
+ base -= 5
39
+ attacks << (static_bonus + base)
40
+ end
41
+ return attacks
42
+ end
43
+
44
+ def as_json(options={})
45
+ {
46
+ :weapon_name => @weapon_name,
47
+ :range => @range,
48
+ :weight_class => @weight_class,
49
+ :damage => get_damage.to_s,
50
+ :weapon_type => @weapon_type,
51
+ :critical_range => @critical_range,
52
+ :critical_dmg => @critical_dmg,
53
+ :weapon_bonus => @weapon_bonus,
54
+ :strength_bonus => @strength_bonus,
55
+ :other_bonus => @other_bonus,
56
+ :attack_bonus => attack_bonus,
57
+ :filters => filter_str,
58
+ :macros => @macros.map { |m| m.as_json }
59
+ }
60
+ end
61
+
62
+ def get_damage
63
+ size == 'MEDIUM' ? damage.dmg_m : damage.dmg_s
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,113 @@
1
+ module PfrpgCore
2
+ class Attributes
3
+
4
+ attr_accessor :raw_int, :raw_dex, :raw_str,
5
+ :raw_con, :raw_wis, :raw_cha, :max_dex
6
+
7
+ def initialize(attributes,bonuses=Bonuses.new)
8
+ @raw_int = attributes[:raw_int]
9
+ @raw_con = attributes[:raw_con]
10
+ @raw_str = attributes[:raw_str]
11
+ @raw_wis = attributes[:raw_wis]
12
+ @raw_cha = attributes[:raw_cha]
13
+ @raw_dex = attributes[:raw_dex]
14
+ @max_dex = attributes[:max_dex] || 1000
15
+ @bonuses = bonuses
16
+ end
17
+
18
+ def set_bonuses(bonuses)
19
+ @bonuses = bonuses
20
+ end
21
+
22
+ def modified_int
23
+ get_modified('int')
24
+ end
25
+
26
+ def int_mod
27
+ get_modifier(modified_int)
28
+ end
29
+
30
+ def modified_dex
31
+ get_modified('dex')
32
+ end
33
+
34
+ def dex_mod
35
+ # TODO : feats let you overcome this
36
+ dex = get_modifier(modified_dex)
37
+ max = @max_dex
38
+ dex = max if (dex > max)
39
+ dex
40
+ end
41
+
42
+ def modified_str
43
+ get_modified('str')
44
+ end
45
+
46
+ def str_mod
47
+ get_modifier(modified_str)
48
+ end
49
+
50
+ def modified_con
51
+ get_modified('con')
52
+ end
53
+
54
+ def con_mod
55
+ get_modifier(modified_con)
56
+ end
57
+
58
+ def modified_cha
59
+ get_modified('cha')
60
+ end
61
+
62
+ def cha_mod
63
+ get_modifier(modified_cha)
64
+ end
65
+
66
+ def modified_wis
67
+ get_modified('wis')
68
+ end
69
+
70
+ def wis_mod
71
+ get_modifier(modified_wis)
72
+ end
73
+
74
+ def get_modified(attribute)
75
+ base = self.send("raw_#{attribute}") || 0
76
+ base += NullObject.maybe(@bonuses.get(attribute)).to_i
77
+ base
78
+ end
79
+
80
+ def get_modifier(val)
81
+ return ((val - 10) / 2.0).floor
82
+ end
83
+
84
+
85
+ def as_json(options={})
86
+ {
87
+ :values => {
88
+ :strength => modified_str,
89
+ :dexterity => modified_dex,
90
+ :charisma => modified_cha,
91
+ :wisdom => modified_wis,
92
+ :constitution => modified_con,
93
+ :intelligence => modified_int
94
+ },
95
+ :modifier => {
96
+ :strength => str_mod,
97
+ :dexterity => dex_mod,
98
+ :charisma => cha_mod,
99
+ :wisdom => wis_mod,
100
+ :constitution => con_mod,
101
+ :intelligence => int_mod
102
+ }
103
+ }
104
+ end
105
+
106
+ alias_method :constitution, :modified_con
107
+ alias_method :strength, :modified_str
108
+ alias_method :wisdom, :modified_wis
109
+ alias_method :intelligence, :modified_int
110
+ alias_method :dexterity, :modified_dex
111
+ alias_method :charisma, :modified_cha
112
+ end
113
+ end
@@ -0,0 +1,15 @@
1
+ class PfrpgCore::AvatarURL
2
+ attr_reader :avatar
3
+ def initialize(avatar)
4
+ @avatar = avatar
5
+ end
6
+
7
+ def as_json(options={})
8
+ {
9
+ default_url: avatar.url,
10
+ thumb_url: avatar.url(:thumb),
11
+ medium_url: avatar.url(:medium),
12
+ square_url: avatar.url(:square)
13
+ }
14
+ end
15
+ end
@@ -5,4 +5,4 @@ module PfrpgCore
5
5
  NullObject.maybe(@bonuses.get(bonus))
6
6
  end
7
7
  end
8
- end
8
+ end
@@ -0,0 +1,83 @@
1
+ module PfrpgCore
2
+ class Character
3
+ include PfrpgCore::Bonus
4
+ include Derived::CombatBonuses
5
+ include Derived::Magic
6
+ include Derived::Misc
7
+
8
+ attr_accessor :levels, :class_features, :feats, :inventory, :base_skills,
9
+ :spells, :attributes, :saves, :alignment, :race, :saves,
10
+ :demographics, :character_id, :character_uuid, :avatar,
11
+ :racial_bonuses, :latest_levels, :bonuses, :effects, :skills,
12
+ :combat, :spellbooks
13
+
14
+ def initialize(params)
15
+ @character_uuid = params[:uuid]
16
+ @character_id = params[:id]
17
+ # TODO: Refactor client to remove @character
18
+ # computed by calling objects
19
+ @character = params[:character]
20
+ @avatar = params[:avatar]
21
+ @demographics = params[:demographics]
22
+ @race = params[:race][:race]
23
+ @racial_bonuses = params[:race][:bonuses]
24
+ prime_bonuses_with_racial_stats
25
+ @attributes = PfrpgCore::Attributes.new(params[:attributes], @bonuses)
26
+ @levels = params[:levels][:latest].map { |x| PfrpgCore::Level.new(x) }
27
+ @latest_levels = params[:levels][:latest]
28
+ @alignment = params[:alignment]
29
+ @feats = params[:feats]
30
+ @class_features = FeatureDuplicator.filter_duplicates(params[:features])
31
+ @inventory = params[:inventory]
32
+ @base_skills = params[:base_skills]
33
+ @spellbooks = params[:spellbooks]
34
+ # uncomputable until bonuses are calculated
35
+ apply_bonuses
36
+ @attributes.set_bonuses(@bonuses)
37
+ @attributes.max_dex = self.get_max_dex_bonus
38
+ @saves = SavingThrows.new(params[:saves], @bonuses, @attributes)
39
+ @combat = PfrpgCore::Combat.new(self)
40
+ @skills = PfrpgCore::Skills.new(self)
41
+ @spells = PfrpgCore::SpellBooks.new(self)
42
+ end
43
+
44
+ def prime_bonuses_with_racial_stats
45
+ @bonuses = PfrpgCore::Bonuses.new
46
+ apply_effects(@racial_bonuses.map { |x| x.get_effects }.flatten)
47
+ end
48
+
49
+ def apply_bonuses
50
+ apply_effects(PfrpgCore::EffectTotaler.new(self).effects)
51
+ end
52
+
53
+ def apply_effects(effects)
54
+ e = PfrpgCore::EffectProcessor.new(self, effects)
55
+ e.process_effects.each do |effect|
56
+ effect.apply(self)
57
+ end
58
+ end
59
+
60
+ def name
61
+ @demographics.character_name
62
+ end
63
+
64
+ def as_json(options={})
65
+ p = {
66
+ :id => @character_id,
67
+ :uuid => @character_uuid,
68
+ :character => @character,
69
+ :demographics => @demographics,
70
+ :attributes => @attributes,
71
+ :combat => @combat,
72
+ :saves => @saves,
73
+ :misc => misc_json,
74
+ :skills => @skills,
75
+ :spells => @spells,
76
+ :inventory => @inventory
77
+ }
78
+ p[:avatar] = AvatarURL.new(@avatar) if @avatar
79
+ p
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,31 @@
1
+ module PfrpgCore
2
+ class ClassFeature
3
+ include PfrpgUtility::Affectable
4
+
5
+ attr_reader :name, :description, :effects, :category,
6
+ :special, :type, :attack_filter, :armor_filter,
7
+ :ability_name
8
+
9
+ def initialize(params)
10
+ @name = params[:name]
11
+ @description = params[:description]
12
+ @effects = params[:effects]
13
+ @type = params[:type]
14
+ @category = params[:category]
15
+ @special = params[:special]
16
+ @attack_filter= params[:attack_filter]
17
+ @armor_filter = params[:armor_filter]
18
+ @ability_name = params[:ability_name]
19
+ end
20
+
21
+ def as_json(options={})
22
+ {
23
+ name: @name,
24
+ description: @description,
25
+ type: @type,
26
+ category: @category,
27
+ name: @name
28
+ }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,60 @@
1
+ module PfrpgCore
2
+ class Combat
3
+ include Derived::Defense
4
+ include Derived::Offense
5
+
6
+ attr_reader :character, :str_bonus, :dex_bonus, :bab,
7
+ :weapon_finesse, :size_modifier, :deflection_modifier, :dodge_modifier,
8
+ :armor_ac, :shield_ac, :natural_armor, :max_dex_bonus, :armor_check_penalty,
9
+ :damage_reduction, :spell_resistance, :armor_modifier
10
+
11
+ def initialize(character)
12
+ @character = character
13
+ @str_bonus = NullObject.maybe(character.attributes.str_mod)
14
+ @dex_bonus = NullObject.maybe(character.attributes.dex_mod)
15
+ @bab = NullObject.maybe(character.get_highest_attack_bonus)
16
+ @weapon_finesse = false
17
+ @dodge_modifier = NullObject.maybe(character.get_dodge_modifier)
18
+ @deflection_modifier = NullObject.maybe(character.get_deflection_modifier)
19
+ @armor_ac = NullObject.maybe(character.inventory.get_armor_ac)
20
+ @shield_ac = NullObject.maybe(character.inventory.get_shield_ac)
21
+ @natural_armor = NullObject.maybe(character.get_natural_armor)
22
+ @size_modifier = NullObject.maybe(character.get_size_modifier)
23
+ @armor_check_penalty = NullObject.maybe(character.get_ac_penalty)
24
+ @max_dex_bonus = NullObject.maybe(character.get_max_dex_bonus)
25
+ @spell_resistance = NullObject.maybe(character.get_spell_resistance)
26
+ @damage_reduction = NullObject.maybe(character.get_damage_reduction)
27
+ @armor_modifier = NullObject.maybe(character.get_armor_modifier)
28
+ end
29
+
30
+ def as_json(options={})
31
+ {
32
+ :str_bonus => @str_bonus,
33
+ :dex_bonus => @dex_bonus,
34
+ :bab => @bab,
35
+ :weapon_finesse => @weapon_finesse,
36
+ :dodge_modifier => @dodge_modifier,
37
+ :armor_modifier => @armor_modifier,
38
+ :deflection_modifier => @deflection_modifier,
39
+ :armor_ac => @armor_ac,
40
+ :shield_ac => @shield_ac,
41
+ :natural_armor => @natural_armor,
42
+ :size_modifier => @size_modifier,
43
+ :armor_class => armor_class,
44
+ :flat_footed_ac => flat_footed_ac,
45
+ :cmd => combat_maneuver_defense,
46
+ :touch_ac => touch_ac,
47
+ :spell_resistance => spell_resistance,
48
+ :damage_reduction => damage_reduction,
49
+ :attacks => attacks,
50
+ :cmb => combat_maneuver_bonus
51
+ }
52
+ end
53
+
54
+ private
55
+ def base_ac
56
+ 10
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,30 @@
1
+ module PfrpgCore
2
+ class Demographics
3
+ attr_reader :player_name, :character_name, :deity, :gender, :height, :weight,
4
+ :description, :languages
5
+
6
+ def initialize(params)
7
+ @player_name = params[:player_name]
8
+ @character_name = params[:name]
9
+ @deity = params[:deity]
10
+ @gender = params[:gender]
11
+ @weight = params[:weight]
12
+ @height = params[:height]
13
+ @description = params[:description]
14
+ @languages = params[:languages]
15
+ end
16
+
17
+ def as_json(options={})
18
+ {
19
+ :player_name => @player_name,
20
+ :character_name => @character_name,
21
+ :deity => @deity,
22
+ :gender => @gender,
23
+ :height => @height,
24
+ :weight => @weight,
25
+ :description => @description,
26
+ :languages => @languages
27
+ }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,78 @@
1
+ module PfrpgCore
2
+ module Derived
3
+ module CombatBonuses
4
+ def get_dodge_modifier
5
+ get_bonus("dodge").to_i
6
+ end
7
+
8
+ def get_deflection_modifier
9
+ get_bonus("deflection").to_i
10
+ end
11
+
12
+ def get_armor_modifier
13
+ get_bonus("armor").to_i
14
+ end
15
+
16
+ def get_size_modifier
17
+ NullObject.maybe(@race).size_modifier
18
+ end
19
+
20
+ def get_natural_armor
21
+ get_bonus("natural_armor").to_i
22
+ end
23
+
24
+ def get_damage_reduction
25
+ get_bonus('damage_reduction')
26
+ end
27
+
28
+ def get_spell_resistance
29
+ get_bonus('spell_resistance')
30
+ end
31
+
32
+ def get_max_dex_bonus
33
+ max_dex_bonus = 100
34
+ any_max = false
35
+ @inventory.equipment.each do |e|
36
+ if (e.max_dex_bonus != nil) && (e.max_dex_bonus < max_dex_bonus)
37
+ any_max = true
38
+ max_dex_bonus = e.max_dex_bonus
39
+ end
40
+ end
41
+ max_dex_bonus += get_bonus("max_dex_bonus").to_i
42
+ max_dex_bonus
43
+ end
44
+
45
+ # the accurate BAB for a character is the sum of the highest
46
+ # granted bonuses from each class
47
+ # this method is NOT concerned with generating multi-attack bonuses
48
+ def get_highest_attack_bonus
49
+ bab = 0
50
+ latest_levels.each do |l|
51
+ bab += l.base_attack_bonus[0]
52
+ end
53
+ bab
54
+ return bab
55
+ end
56
+
57
+ def armor_speed_penalty
58
+ begin
59
+ return 0 if race.name == 'Dwarf'
60
+ return (race.speed == 30) ? (30 - @inventory.equipped_armor.speed_thirty) :
61
+ (20 - @inventory.equipped_armor.speed_twenty)
62
+ rescue Exception
63
+ return 0
64
+ end
65
+ end
66
+
67
+ def get_ac_penalty
68
+ @inventory.ac_penalty(self.bonuses)
69
+ end
70
+
71
+ def get_attack_filters
72
+ base = class_features.select { |x| x.attack_filter != nil }
73
+ filter_classes = base.collect { |x| [x,x.attack_filter] }
74
+ filter_classes.map { |x| x[1].new(self,x[0])}
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,29 @@
1
+ module PfrpgCore
2
+ module Derived
3
+ module Defense
4
+ def armor_class
5
+ base_ac + dodge_modifier + deflection_modifier + armor_ac + shield_ac + natural_armor + size_modifier + dex_bonus + armor_modifier
6
+ end
7
+
8
+ def flat_footed_ac
9
+ base_ac + deflection_modifier + armor_ac + shield_ac + natural_armor + size_modifier
10
+ end
11
+
12
+ def combat_maneuver_defense
13
+ base_ac + str_bonus + dex_bonus + dodge_modifier + deflection_modifier + bab - size_modifier
14
+ end
15
+
16
+ def touch_ac
17
+ base_ac + dex_bonus + dodge_modifier + deflection_modifier + size_modifier
18
+ end
19
+
20
+ def spell_resistance
21
+ spell_resistance
22
+ end
23
+
24
+ def damage_reduction
25
+ damage_reduction
26
+ end
27
+ end
28
+ end
29
+ end