pfrpg_readers 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4885ad49ec886cd2e8d960b8f97010033e3d4441
4
+ data.tar.gz: 1d3d76f37dfac171e966bb099cb96479b77a64e0
5
+ SHA512:
6
+ metadata.gz: e8b81723f671480ffc70a1d5ff87ea4e8619bbfb4d76d25b6138bf8edbb17202600b3cab8abff3caa715d7958aa44f97b53831583008f138c540ca5332f1ca32
7
+ data.tar.gz: b62737180c42527a8ddd7cdba4068ae2e37bd36af3e25c2be5e218284cfc33009d3b3ff556f6f5a9ed72e6b1226a1e6b19eeca67d27fb587d169e3cb9a8cde3e
@@ -0,0 +1,8 @@
1
+ require 'pfrpg_readers/defensible'
2
+
3
+ Dir[File.expand_path(File.join(File.dirname(File.absolute_path(__FILE__)), 'pfrpg_readers/')) + "/**/*.rb"].each do |file|
4
+ require file
5
+ end
6
+
7
+ module PfrpgReaders
8
+ end
@@ -0,0 +1,64 @@
1
+ module PfrpgReaders
2
+ class Attack
3
+ include PfrpgCore::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
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
+ @other_bonus = 0 # things like weapon spec, training, etc
26
+ apply_filters
27
+ end
28
+
29
+ def attack_bonus
30
+ attacks = []
31
+ static_bonus = NullObject.maybe(weapon_bonus) +
32
+ NullObject.maybe(other_bonus) +
33
+ NullObject.maybe(strength_bonus)
34
+ base = NullObject.maybe(bab)
35
+ attacks << (static_bonus + base)
36
+ while(base >= 6)
37
+ base -= 5
38
+ attacks << (static_bonus + base)
39
+ end
40
+ return attacks
41
+ end
42
+
43
+ def as_json(options={})
44
+ {
45
+ :weapon_name => @weapon_name,
46
+ :range => @range,
47
+ :weight_class => @weight_class,
48
+ :damage => get_damage.to_s,
49
+ :weapon_type => @weapon_type,
50
+ :critical_range => @critical_range,
51
+ :critical_dmg => @critical_dmg,
52
+ :weapon_bonus => @weapon_bonus,
53
+ :strength_bonus => @strength_bonus,
54
+ :other_bonus => @other_bonus,
55
+ :attack_bonus => attack_bonus,
56
+ :filters => filter_str
57
+ }
58
+ end
59
+
60
+ def get_damage
61
+ size == 'MEDIUM' ? damage.dmg_m : damage.dmg_s
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,47 @@
1
+ require_relative 'filters/filter.rb'
2
+
3
+ module PfrpgReaders
4
+ module Attackable
5
+ def combat_maneuver_bonus
6
+ base = str_bonus + bab - size_modifier
7
+ misc = character.get_bonus('cmb').to_i
8
+ base += misc
9
+ return base
10
+ end
11
+
12
+ def attack_filters
13
+ standard_filters = [
14
+ Filters::StrengthMod.new(character),
15
+ Filters::WeaponFinesseMod.new(character),
16
+ Filters::RangedAttackMod.new(character),
17
+ Filters::WeaponFocusMod.new(character),
18
+ Filters::WeaponSpecializationMod.new(character),
19
+ Filters::ProficiencyMod.new(character)
20
+ ]
21
+ standard_filters << character.get_attack_filters
22
+ standard_filters.flatten
23
+ end
24
+
25
+ def attacks
26
+ atk = []
27
+ character.equipped_weapons.each do |w|
28
+ atk << Attack.new({ :weapon_name => w.get_best_name,
29
+ :range => w.range,
30
+ :weight_class => w.weight_class,
31
+ :damage => w.damage,
32
+ :weapon_type => w.weapon_type,
33
+ :critical_range => w.critical_range,
34
+ :critical_dmg => w.critical_dmg,
35
+ :bonus => w.bonus,
36
+ :strength_bonus => str_bonus,
37
+ :bab => bab,
38
+ :size => character.race.size,
39
+ :filters => attack_filters,
40
+ :filter_str => [],
41
+ :weapon => w
42
+ })
43
+ end
44
+ return atk
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,76 @@
1
+ class PfrpgReaders::AttributesReader
2
+ attr_reader :character
3
+
4
+ def initialize(character)
5
+ @character = character
6
+ end
7
+
8
+ def as_json(options={})
9
+ {
10
+ :values => {
11
+ :strength => strength,
12
+ :dexterity => dexterity,
13
+ :charisma => charisma,
14
+ :wisdom => wisdom,
15
+ :constitution => constitution,
16
+ :intelligence => intelligence
17
+ },
18
+ :modifier => {
19
+ :strength => strength_modifier,
20
+ :dexterity => dexterity_modifier,
21
+ :charisma => charisma_modifier,
22
+ :wisdom => wisdom_modifier,
23
+ :constitution => constitution_modifier,
24
+ :intelligence => intelligence_modifier
25
+ }
26
+ }
27
+ end
28
+
29
+ def strength
30
+ @character.modified_str
31
+ end
32
+
33
+ def strength_modifier
34
+ @character.str_mod
35
+ end
36
+
37
+ def dexterity
38
+ @character.modified_dex
39
+ end
40
+
41
+ def dexterity_modifier
42
+ @character.dex_mod
43
+ end
44
+
45
+ def charisma
46
+ @character.modified_cha
47
+ end
48
+
49
+ def charisma_modifier
50
+ @character.cha_mod
51
+ end
52
+
53
+ def intelligence
54
+ @character.modified_int
55
+ end
56
+
57
+ def intelligence_modifier
58
+ @character.int_mod
59
+ end
60
+
61
+ def wisdom
62
+ @character.modified_wis
63
+ end
64
+
65
+ def wisdom_modifier
66
+ @character.wis_mod
67
+ end
68
+
69
+ def constitution
70
+ @character.modified_con
71
+ end
72
+
73
+ def constitution_modifier
74
+ @character.con_mod
75
+ end
76
+ end
@@ -0,0 +1,15 @@
1
+ class PfrpgReaders::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
@@ -0,0 +1,60 @@
1
+ module PfrpgReaders
2
+ class CombatReader
3
+ include PfrpgReaders::Defensible
4
+ include PfrpgReaders::Attackable
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.str_mod)
14
+ @dex_bonus = NullObject.maybe(character.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.get_armor_ac)
20
+ @shield_ac = NullObject.maybe(character.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,27 @@
1
+ module PfrpgReaders
2
+ module Defensible
3
+ def armor_class
4
+ base_ac + dodge_modifier + deflection_modifier + armor_ac + shield_ac + natural_armor + size_modifier + dex_bonus + armor_modifier
5
+ end
6
+
7
+ def flat_footed_ac
8
+ base_ac + deflection_modifier + armor_ac + shield_ac + natural_armor + size_modifier
9
+ end
10
+
11
+ def combat_maneuver_defense
12
+ base_ac + str_bonus + dex_bonus + dodge_modifier + deflection_modifier + bab - size_modifier
13
+ end
14
+
15
+ def touch_ac
16
+ base_ac + dex_bonus + dodge_modifier + deflection_modifier + size_modifier
17
+ end
18
+
19
+ def spell_resistance
20
+ spell_resistance
21
+ end
22
+
23
+ def damage_reduction
24
+ damage_reduction
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ class PfrpgReaders::DemographicsReader
2
+ attr_reader :player_name, :character_name, :deity, :gender
3
+
4
+ def initialize(character)
5
+ if @character.respond_to? 'player_name'
6
+ @player_name = character.player_name
7
+ end
8
+ @character_name = character.name
9
+ @deity = character.deity
10
+ @gender = character.gender
11
+ end
12
+
13
+ def as_json(options={})
14
+ {
15
+ :player_name => @player_name,
16
+ :character_name => @character_name,
17
+ :deity => @deity,
18
+ :gender => @gender
19
+ }
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ module FeatureDuplicator
2
+
3
+ def dupe_words
4
+ ['Sneak Attack', 'Channel Energy', 'Damage Reduction', 'Trap Sense']
5
+ end
6
+
7
+ # filter things with multiple bonuses, like sneak attack and channel energy
8
+ def filter_duplicates(features)
9
+ dupe_words.each do |w|
10
+ features = features - smallest(features, w)
11
+ end
12
+ features
13
+ end
14
+
15
+ def smallest(features, phrase)
16
+ smallest = features.select { |x| x.name[phrase] != nil }
17
+ return [] if (smallest.empty? || smallest.size == 1)
18
+ smallest.sort_by! { |x| parse_number(x.name) }
19
+ smallest[0..smallest.size-2]
20
+ end
21
+
22
+ # of the form, 'Sneak Attack (10d6)'
23
+ def parse_number(description)
24
+ (description.split('d6')[0].split(' ').last.split('(')[1]).to_i
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ require_relative './weapon_training_mod.rb'
2
+ require_relative './weapon_specialization_mod.rb'
3
+ require_relative './weapon_finesse_mod.rb'
4
+ require_relative './strength_mod.rb'
5
+ require_relative './proficiency_mod.rb'
6
+ require_relative './weapon_focus_mod.rb'
7
+
8
+ module PfrpgReaders
9
+ module Filters
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ module PfrpgReaders
2
+ module Filters
3
+ class ProficiencyMod
4
+ attr_reader :character
5
+ def initialize(character)
6
+ @character = character
7
+ end
8
+
9
+ def filter(attack)
10
+ proficiency = Specializer.new(character)
11
+ unless proficiency.is_proficient_in_weapon? attack.weapon
12
+ modify_for_weapon(attack)
13
+ end
14
+ armor = character.armor_and_shield
15
+ armor.each do |a|
16
+ unless proficiency.is_proficient_in_armor? a
17
+ modify_for_armor(attack, a)
18
+ end
19
+ end
20
+ end
21
+
22
+ def modify_for_weapon(attack)
23
+ attack.filter_str << 'Not proficient with weapon, -4 atk'
24
+ attack.other_bonus -= 4
25
+ end
26
+
27
+ def modify_for_armor(attack, armor)
28
+ attack.filter_str << "Not proficient with armor: #{armor.name}"
29
+ # armor check penalties are negative
30
+ attack.other_bonus += NullObject.maybe(armor.armor_check_penalty)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ module PfrpgReaders
2
+ module Filters
3
+ class RangedAttackMod
4
+ attr_reader :character
5
+ def initialize(character)
6
+ @character = character
7
+ end
8
+
9
+ def filter(attack)
10
+ unless character.feats.find { |x| x.name == 'Weapon Finesse' }
11
+ modify_attack_for_ranged_attack(attack, character.dex_mod, character.str_mod)
12
+ end
13
+ end
14
+
15
+ def modify_attack_for_ranged_attack(attack, dex, str)
16
+ begin
17
+ ranged = attack.range.to_i
18
+ if !(ranged == nil || ranged == '' || ranged == 0)
19
+ attack.filter_str << "Range Bonus: -#{dex}, +#{str}"
20
+ attack.other_bonus += dex
21
+ attack.other_bonus -= str
22
+ end
23
+ rescue Exception => e
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ module PfrpgReaders
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.char_feats.select { |x| x.pathfinder_feat.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 PfrpgReaders
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.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 PfrpgReaders
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.dex_mod, character.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 PfrpgReaders
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.char_feats.find { |x| x.pathfinder_feat.name == 'Weapon Focus' }
11
+ if f != nil && (attack.weapon.name.downcase == f.feat_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,24 @@
1
+ class PfrpgReaders::WeaponMasteryMod
2
+ attr_reader :character, :feature
3
+ def initialize(character, feature)
4
+ @character = character
5
+ @feature = feature
6
+ end
7
+
8
+ def filter(attack)
9
+ if attack.weapon.name == @feature.weapon_type
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
24
+
@@ -0,0 +1,22 @@
1
+ module PfrpgReaders
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.char_feats.find { |x| x.pathfinder_feat.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 PfrpgReaders
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 = Cheesewhiz.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,39 @@
1
+ class PfrpgReaders::InventoryReader
2
+
3
+ attr_reader :inventory, :equipment
4
+ def initialize(character)
5
+ @character = character
6
+ @inventory = get_inventory
7
+ @equipment = get_equipment
8
+ end
9
+
10
+ def get_inventory
11
+ @character.inventory
12
+ end
13
+
14
+ def get_equipment
15
+ @character.equipment
16
+ end
17
+
18
+ def pretty(items)
19
+ items.map { |i| PrettyItem.new(i) }
20
+ end
21
+
22
+ def as_json(options={})
23
+ {
24
+ :equipment => get_equipment,
25
+ :inventory => get_inventory
26
+ }
27
+ end
28
+ end
29
+
30
+ class PfrpgReaders::PrettyItem
31
+ attr_reader :name, :description, :slot, :type, :equipped
32
+
33
+ def initialize(item)
34
+ @name = item.name
35
+ @description = item.description
36
+ @slot = item.slot
37
+ @type = item.type
38
+ end
39
+ end
@@ -0,0 +1,156 @@
1
+ module PfrpgReaders
2
+ class MiscReader
3
+ include FeatureDuplicator
4
+ attr_reader :initiative, :speed, :hit_points, :feats, :class_features, :levels,
5
+ :total_level, :alignment, :languages, :size
6
+ def initialize(character)
7
+ @character = character
8
+ @initiative = gen_initiative
9
+ @speed = gen_speed
10
+ @feats = gen_feats
11
+ @class_features = gen_class_features
12
+ @levels = gen_levels
13
+ @total_level = gen_total_level
14
+ @hit_points = gen_hit_points
15
+ @alignment = character.alignment
16
+ @size = character.racial_size
17
+ end
18
+
19
+ def as_json(options={})
20
+ {
21
+ :initiative => @initiative,
22
+ :alignment => @alignment,
23
+ :speed => @speed,
24
+ :hit_points => @hit_points,
25
+ :feats => @feats,
26
+ :class_features => @class_features,
27
+ :levels => @levels,
28
+ :total_level => @total_level,
29
+ :size => @size,
30
+ :level_string => level_string,
31
+ :temporary => @character.temp_values
32
+ }
33
+ end
34
+
35
+ def level_string
36
+ str = "#{alignment} :"
37
+ @levels.each do |l|
38
+ str += "#{l.name}/#{l.level}"
39
+ str += "*" if l.favored
40
+ end
41
+ str
42
+ end
43
+
44
+ def gen_hit_points
45
+ hp = @character.hit_points
46
+ # TODO : potentially move off this method when multiple hp affect stats exist
47
+ if (@feats.find { |x| x.name == 'Toughness' })
48
+ hp += 3
49
+ if (total_level > 3)
50
+ hp += total_level - 3
51
+ end
52
+ end
53
+ return hp
54
+ end
55
+
56
+ def gen_total_level
57
+ if @character.respond_to? 'get_last_level'
58
+ return 0 if @character.levels.empty?
59
+ return @character.get_last_level.number
60
+ end
61
+ @character.latest_levels.inject(0) {|sum, x| sum = sum + x.class_number }
62
+ end
63
+
64
+ def gen_speed
65
+ base_speed = NullObject.maybe(@character.race).speed || 0
66
+ base_speed += parse_speed_bonuses(@character.get_bonus("speed"))
67
+ base_speed -= @character.armor_speed_penalty
68
+ speeds = {}
69
+ ['land','fly','climb','swim'].each do |type|
70
+ speeds["#{type}_speed"] = calc_speed(type, base_speed)
71
+ end
72
+ speeds['speed'] = speeds['land_speed']
73
+ return speeds
74
+ end
75
+
76
+ def calc_speed(speed_type, base)
77
+ base + @character.get_bonus("#{speed_type}_speed")
78
+ end
79
+
80
+ def gen_initiative
81
+ initiative = 0
82
+ initiative += @character.dex_mod
83
+ initiative += @character.get_bonus("initiative").to_i
84
+ return initiative
85
+ end
86
+
87
+ def gen_feats
88
+ @character.total_feats.map { |x| PrettyFeat.new(x) }
89
+ end
90
+
91
+ def gen_class_features
92
+ features = @character.class_features.map { |x| PrettyClassFeature.new(x) }
93
+ filter_duplicates(features)
94
+ end
95
+
96
+ def gen_levels
97
+ @character.latest_levels.map { |x| PrettyLevel.new(x, @character) }
98
+ end
99
+
100
+ def parse_speed_bonuses(speed_bonuses)
101
+ speed_bonus = 0
102
+ speed_bonuses.each do |s|
103
+ speed_bonus += s.to_i if MathHelper.is_number(s)
104
+ end
105
+ speed_bonus
106
+ end
107
+
108
+
109
+ end
110
+
111
+ class MiscReader::PrettyFeat
112
+ attr_reader :name, :description, :special
113
+ def initialize(char_feat)
114
+ if char_feat.respond_to? 'pathfinder_feat'
115
+ feat = NullObject.maybe(char_feat.pathfinder_feat)
116
+ else
117
+ feat = NullObject.maybe(char_feat.feat)
118
+ end
119
+ @name = feat.name || "Feat"
120
+ if (@name == 'Custom Feat')
121
+ @description = char_feat.feat_special
122
+ else
123
+ @description = feat.benefit
124
+ @special = char_feat.feat_special
125
+ end
126
+ end
127
+ end
128
+
129
+ class MiscReader::PrettyLevel
130
+ attr_reader :name, :level, :favored
131
+ def initialize(level, character)
132
+ @name = level.class_name
133
+ @level = level.class_number
134
+ if character.respond_to? 'preferred_class'
135
+ @favored = (level.class_name == character.preferred_class)
136
+ end
137
+ end
138
+ end
139
+
140
+ class MiscReader::PrettyClassFeature
141
+ attr_reader :name, :description, :type
142
+ def initialize(feature)
143
+ if feature.respond_to? 'feature'
144
+ f = feature.feature
145
+ else
146
+ f = feature
147
+ end
148
+ # TODO this belogns on the feature object
149
+ @type = feature.feature_type
150
+ @category = f.category
151
+ @name = f.display_name
152
+ @description = f.description
153
+ @special = feature.special
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,41 @@
1
+ module PfrpgReaders
2
+ class PFRPGCharacter
3
+ attr_reader :character, :attributes, :feats, :skills, :spells, :combat, :misc,
4
+ :inventory, :avatar
5
+
6
+ def initialize(character)
7
+ @character = character
8
+ @attributes = AttributesReader.new(character)
9
+ @demographics = DemographicsReader.new(character)
10
+ @combat = CombatReader.new(character)
11
+ @saves = SavesReader.new(character)
12
+ @misc = MiscReader.new(character)
13
+ @skills = SkillsReader.new(character)
14
+ @inventory = InventoryReader.new(character)
15
+ @spells = SpellsReader.new(character)
16
+ @avatar = character.avatar if character.respond_to? 'avatar'
17
+ end
18
+
19
+ def as_json(options={})
20
+ p = {
21
+ :id => @character.id,
22
+ :uuid => @character.uuid,
23
+ :character => @character,
24
+ :demographics => @demographics,
25
+ :attributes => @attributes,
26
+ :combat => @combat,
27
+ :saves => @saves,
28
+ :misc => @misc,
29
+ :skills => @skills,
30
+ :spells => @spells,
31
+ :inventory => @inventory
32
+ }
33
+ p[:avatar] = AvatarURL.new(@avatar) if @avatar
34
+ p
35
+ end
36
+
37
+ def find_by_id(id)
38
+ Character.find(id)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,40 @@
1
+ module PfrpgReaders
2
+ module PfrpgReaders
3
+ class PfrpgNpc
4
+ attr_reader :npc, :attributes, :feats, :skills, :spells, :combat, :misc,
5
+ :inventory, :avatar
6
+
7
+ def initialize(npc)
8
+ @npc = npc
9
+ @attributes = AttributesReader.new(npc)
10
+ @demographics = DemographicsReader.new(npc)
11
+ @combat = CombatReader.new(npc)
12
+ @saves = SavesReader.new(npc)
13
+ @misc = MiscReader.new(npc)
14
+ @skills = SkillsReader.new(npc)
15
+ @inventory = InventoryReader.new(npc)
16
+ @spells = SpellsReader.new(npc)
17
+ @validation = ValidationReader.new(npc)
18
+ @avatar = npc.avatar
19
+ end
20
+
21
+ def as_json(options={})
22
+ {
23
+ :id => @npc.id,
24
+ :uuid => @npc.uuid,
25
+ :npc => @npc,
26
+ :demographics => @demographics,
27
+ :attributes => @attributes,
28
+ :combat => @combat,
29
+ :saves => @saves,
30
+ :misc => @misc,
31
+ :skills => @skills,
32
+ :spells => @spells,
33
+ :inventory => @inventory,
34
+ :validation => @validation,
35
+ :avatar => AvatarURL.new(@avatar)
36
+ }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,42 @@
1
+ class PfrpgReaders::SavesReader
2
+ attr_reader :character, :con_modifier, :dex_modifier, :wis_modifier,
3
+ :saves, :bonuses
4
+ def initialize(character)
5
+ @character = character
6
+ @con_modifier = character.con_mod
7
+ @wis_modifier = character.wis_mod
8
+ @dex_modifier = character.dex_mod
9
+ @saves = character.get_saves
10
+ @bonuses = character.get_save_bonuses
11
+ end
12
+
13
+ def as_json(options={})
14
+ {
15
+ :con_modifier => @con_modifier,
16
+ :wis_modifier => @wis_modifier,
17
+ :dex_modifier => @dex_modifier,
18
+ :base_ref => @saves[:ref],
19
+ :base_fort => @saves[:fort],
20
+ :base_will => @saves[:will],
21
+ :bonus_ref => @bonuses[:ref],
22
+ :bonus_will => @bonuses[:will],
23
+ :bonus_fort => @bonuses[:fort],
24
+ :fortitude => fortitude,
25
+ :reflex => reflex,
26
+ :will => will
27
+ }
28
+ end
29
+
30
+ def fortitude
31
+ con_modifier + saves[:fort] + bonuses[:fort]
32
+ end
33
+
34
+ def reflex
35
+ dex_modifier + saves[:ref] + bonuses[:ref]
36
+ end
37
+
38
+ def will
39
+ wis_modifier + saves[:will] + bonuses[:will]
40
+ end
41
+ end
42
+
@@ -0,0 +1,115 @@
1
+ module PfrpgReaders
2
+ class SkillsReader
3
+ attr_reader :skills
4
+ def initialize(character)
5
+ @character = character
6
+ @skills = gen_skills
7
+ end
8
+
9
+ def skill_filters
10
+ [
11
+ Filters::SkillFocusMod.new(@character)
12
+ ]
13
+ end
14
+
15
+ def gen_skills
16
+ @character.get_all_skills.map { |x| PrettySkill.new(x, @character, skill_filters) }
17
+ end
18
+
19
+ def as_json(options={})
20
+ skillz = {}
21
+ skills.each do |s|
22
+ skillz[s.name] = s
23
+ end
24
+ skillz
25
+ end
26
+ end
27
+
28
+ class PrettySkill
29
+ include PfrpgCore::Filterable
30
+ attr_reader :name, :class_skill, :stat_bonus, :ac_penalty,
31
+ :misc_bonus, :total_bonus, :trained_rank, :attribute,
32
+ :filters, :filter_str
33
+
34
+ def initialize(skill, character, skill_filters)
35
+ @class_skill = is_class_skill?(skill, character)
36
+ @ac_penalty = calculate_ac_penalty(skill, character)
37
+ @name = skill[:skill].description
38
+ @trained_rank = skill[:char_skill]['trained_rank']
39
+ @stat_bonus = calculate_attribute_bonus(skill, character)
40
+ @misc_bonus = calculate_misc_bonus(skill, character)
41
+ @attribute = skill[:skill].attribute
42
+ @total_bonus = total_bonuses
43
+ @filters = skill_filters
44
+ @filter_str = []
45
+ apply_filters
46
+ end
47
+
48
+ def misc_bonus=(misc)
49
+ @misc_bonus=misc
50
+ end
51
+
52
+ def as_json(options={})
53
+ {
54
+ :class_skill => @class_skill,
55
+ :ac_penalty => @ac_penalty,
56
+ :name => @name,
57
+ :trained_rank => @trained_rank,
58
+ :stat_bonus => @stat_bonus,
59
+ :misc_bonus => @misc_bonus,
60
+ :total_bonus => @total_bonus,
61
+ :attribute => @attribute
62
+ }
63
+ end
64
+
65
+ def is_class_skill?(skill, character)
66
+ found = character.latest_levels.any? do |l|
67
+ l.heroclass.skills.find { |x| x.to_s == skill[:skill].to_s }
68
+ end
69
+ found ||= class_skill_bonuses(character).find do |x|
70
+ if x
71
+ x.downcase == skill[:skill].description.downcase
72
+ else
73
+ false
74
+ end
75
+ end
76
+ return (found != nil && found)
77
+ end
78
+
79
+ def class_skill_bonuses(character)
80
+ bonuses = character.get_bonus("class_skill")
81
+ bonuses ||= []
82
+ return bonuses
83
+ end
84
+
85
+ def calculate_ac_penalty(skill, character)
86
+ ac_penalty = 0
87
+ if skill[:skill].ac_penalty?
88
+ ac_penalty = character.get_ac_penalty
89
+ end
90
+ ac_penalty
91
+ end
92
+
93
+ def calculate_attribute_bonus(skill, character)
94
+ attribute = skill[:skill].attribute
95
+ bonus = character.send("#{attribute}_mod")
96
+ bonus ||= 0
97
+ end
98
+
99
+ def total_bonuses
100
+ total = @misc_bonus + @stat_bonus - @ac_penalty + @trained_rank
101
+ total += 3 if (@class_skill && @trained_rank > 0)
102
+ total
103
+ end
104
+
105
+ def calculate_misc_bonus(skill, character)
106
+ if skill[:skill].respond_to? "bonus_str"
107
+ misc = character.get_bonus(skill[:skill].bonus_str).to_i
108
+ else
109
+ misc = character.get_bonus(skill[:skill].description).to_i
110
+ end
111
+ misc ||= 0
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,51 @@
1
+ class PfrpgReaders::SpellsReader
2
+ def initialize(character)
3
+ @character = character
4
+ @spells = {}
5
+ end
6
+
7
+ def get_sorcerer_spells
8
+ @character.known_sorcerer_spells
9
+ end
10
+
11
+ def get_cleric
12
+ []
13
+ end
14
+
15
+ def get_sorcerer
16
+ []
17
+ end
18
+
19
+ def get_wizard
20
+ []
21
+ end
22
+
23
+ def get_druid
24
+ []
25
+ end
26
+
27
+ def get_ranger
28
+ []
29
+ end
30
+
31
+ def get_bard
32
+ []
33
+ end
34
+
35
+ def get_paladin
36
+ []
37
+ end
38
+
39
+ def as_json(options={})
40
+ l = @character.latest_levels
41
+ {
42
+ :sorcerer_spells => get_sorcerer_spells,
43
+ :Cleric => @character.spells_per_level('Cleric', l),
44
+ :Wizard => @character.spells_per_level('Wizard', l),
45
+ :Druid => @character.spells_per_level('Druid', l),
46
+ :Paladin => @character.spells_per_level('Paladin', l),
47
+ :Ranger => @character.spells_per_level('Ranger', l),
48
+ :Bard => @character.spells_per_level('Bard', l)
49
+ }
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ module PfrpgReaders
2
+ class ValidationReader
3
+ attr_reader :feats, :skills, :features
4
+ def initialize(entity)
5
+ @entity = entity
6
+ @feats = feat_total
7
+ @skills = skill_total
8
+ @features = feature_total
9
+ end
10
+
11
+ def feat_total
12
+ return PfrpgTables::FeatTotaler.new(entity).total
13
+ end
14
+
15
+ def skill_total
16
+ 0
17
+ end
18
+
19
+ def feature_total
20
+ 0
21
+ end
22
+
23
+ def as_json(options = {})
24
+ {
25
+ :feats => @feats,
26
+ :skills => @skills,
27
+ :features => @features
28
+ }
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module PfrpgReaders
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pfrpg_readers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jordan OMara
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: readers
14
+ email:
15
+ - jordan@herosheets.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/pfrpg_readers.rb
21
+ - lib/pfrpg_readers/attack.rb
22
+ - lib/pfrpg_readers/attackable.rb
23
+ - lib/pfrpg_readers/attributes_reader.rb
24
+ - lib/pfrpg_readers/avatar_url.rb
25
+ - lib/pfrpg_readers/combat_reader.rb
26
+ - lib/pfrpg_readers/defensible.rb
27
+ - lib/pfrpg_readers/demographics_reader.rb
28
+ - lib/pfrpg_readers/feature_duplicator.rb
29
+ - lib/pfrpg_readers/filters/filter.rb
30
+ - lib/pfrpg_readers/filters/proficiency_mod.rb
31
+ - lib/pfrpg_readers/filters/ranged_attack_mod.rb
32
+ - lib/pfrpg_readers/filters/skill_focus_mod.rb
33
+ - lib/pfrpg_readers/filters/strength_mod.rb
34
+ - lib/pfrpg_readers/filters/weapon_finesse_mod.rb
35
+ - lib/pfrpg_readers/filters/weapon_focus_mod.rb
36
+ - lib/pfrpg_readers/filters/weapon_mastery_mod.rb
37
+ - lib/pfrpg_readers/filters/weapon_specialization_mod.rb
38
+ - lib/pfrpg_readers/filters/weapon_training_mod.rb
39
+ - lib/pfrpg_readers/inventory_reader.rb
40
+ - lib/pfrpg_readers/misc_reader.rb
41
+ - lib/pfrpg_readers/pfrpg_character.rb
42
+ - lib/pfrpg_readers/pfrpg_npc.rb
43
+ - lib/pfrpg_readers/saves_reader.rb
44
+ - lib/pfrpg_readers/skills_reader.rb
45
+ - lib/pfrpg_readers/spells_reader.rb
46
+ - lib/pfrpg_readers/validation_reader.rb
47
+ - lib/pfrpg_readers/version.rb
48
+ homepage: http://herosheets.com
49
+ licenses: []
50
+ metadata: {}
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project:
67
+ rubygems_version: 2.2.2
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: PFRPG readers
71
+ test_files: []