pfrpg_readers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []