pfrpg_utility 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 49f2a54caed217925fbbdc1da8aa2e034a75d15c
4
+ data.tar.gz: 21a2f8ba64a06101272dff66e045f03983bf3480
5
+ SHA512:
6
+ metadata.gz: b8317083daa87df08f73aa4f3bf7f6c93c851a2f7dbca405f3e1ea45cebb405447bf581046a0a2260b5f743e9eed8b3cb1174268c7a2c45fc1f099a9fb834275
7
+ data.tar.gz: e0599d118521f48938a352425ee8731214d4ad4858da681d6eda90f88328456b153b7f962dadd864167d7434f303098fffa683f14ce5fadf3096d5bd5aa6cfae
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 ADDED
@@ -0,0 +1,7 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs.push "lib"
5
+ t.test_files = FileList['test/*_test.rb']
6
+ t.verbose = true
7
+ end
@@ -0,0 +1,8 @@
1
+ module PfrpgUtility
2
+ end
3
+
4
+ require 'pfrpg_utility/dice'
5
+ require 'pfrpg_utility/affectable'
6
+ require 'pfrpg_utility/alignment'
7
+ require 'pfrpg_utility/effect'
8
+ require 'pfrpg_utility/prerequisite'
@@ -0,0 +1,7 @@
1
+ module PfrpgCore
2
+ module Affectable
3
+ def get_effects
4
+ Effect.load(effects)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,94 @@
1
+ module PfrpgCore
2
+ class Alignment
3
+
4
+ attr_reader :alignment
5
+ def initialize(alignment)
6
+ @alignment = PfrpgCore::Alignment.parse(alignment)
7
+ end
8
+
9
+ def self.filter_by_character(character)
10
+ alignments = []
11
+ first_class = character.get_last_level.heroclass
12
+ classed = get_alignments_for_class(first_class)
13
+ any.each do |alignment|
14
+ alignments << alignment if classed.include?(alignment)
15
+ end
16
+ return alignments
17
+ end
18
+
19
+ def self.get_alignments_for_class(heroclass)
20
+ heroclass.alignment
21
+ end
22
+
23
+ def self.parse(alignment_str)
24
+ return "None" unless alignment_str
25
+ if alignment_str.length == 2
26
+ h = {
27
+ 'CN' => "Chaotic Neutral",
28
+ 'CE' => "Chaotic Evil",
29
+ 'CG' => "Chaotic Good",
30
+ 'NE' => "Neutral Evil",
31
+ "TN" => "True Neutral",
32
+ "NG" => "Neutral Good",
33
+ "LE" => "Lawful Evil",
34
+ "LG" => "Lawful Good",
35
+ "LN" => "Lawful Neutral"
36
+ }
37
+ return h[alignment_str] || "None"
38
+ else
39
+ return alignment_str
40
+ end
41
+ end
42
+
43
+ def self.any
44
+ ["Chaotic Evil", "Chaotic Neutral", "Chaotic Good",
45
+ "Neutral Evil", "True Neutral", "Neutral Good",
46
+ "Lawful Evil", "Lawful Neutral", "Lawful Good" ]
47
+ end
48
+
49
+ def self.never_lawful
50
+ ["Chaotic Evil", "Chaotic Neutral", "Chaotic Good",
51
+ "Neutral Evil", "True Neutral", "Neutral Good" ]
52
+ end
53
+
54
+ def self.any_evil
55
+ ["Chaotic Evil", "Neutral Evil", "Lawful Evil"]
56
+ end
57
+
58
+ def self.any_neutral
59
+ ["Neutral Good", "Neutral Evil", "True Neutral"]
60
+ end
61
+
62
+ def self.any_lawful
63
+ ["Lawful Good", "Lawful Evil", "Lawful Neutral"]
64
+ end
65
+
66
+ def self.from_str(alignment_str)
67
+ any.find { |x| x.downcase == alignment_str.downcase }
68
+ end
69
+
70
+ def self.from_deity_str(str)
71
+ case str
72
+ when "CE"
73
+ from_str('Chaotic Evil')
74
+ when "CN"
75
+ from_str('Chaotic Neutral')
76
+ when "CG"
77
+ from_str('Chaotic Good')
78
+ when "NE"
79
+ from_str('Neutral Evil')
80
+ when "NE"
81
+ from_str('True Neutral')
82
+ when "NG"
83
+ from_str('Neutral Good')
84
+ when "LE"
85
+ from_str('Lawful Evil')
86
+ when "LN"
87
+ from_str('Lawful Neutral')
88
+ when "LG"
89
+ from_str('Lawful Good')
90
+ end
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,134 @@
1
+ # Copyright (c) 2006, Jamis Buck (jamis@37signals.com)
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are met:
6
+ #
7
+ # * Redistributions of source code must retain the above copyright notice,
8
+ # this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright notice,
10
+ # this list of conditions and the following disclaimer in the documentation
11
+ # and/or other materials provided with the distribution.
12
+ # * Neither the name of Jamis Buck nor the names of its contributors may be
13
+ # used to endorse or promote products derived from this software without
14
+ # specific prior written permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ # POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ # Dice class. It represents one or more homogeneous dice, with an optional
29
+ # integer increment and an optional integer multiplier. It is best used in
30
+ # conjunction with the Integer methods added at the bottom of this file.
31
+ #
32
+ # 4.d6 # => Dice.new(4, 6)
33
+ # 4.d6 + 2 # => Dice.new(4, 6) + 2
34
+ # # => Dice.new(4, 6, 2)
35
+ # 4.d6 * 10 # => Dice.new(4, 6) * 10
36
+ # # => Dice.new(4, 6, 0, 10)
37
+ class PfrpgCore::Dice
38
+ attr_reader :sides, :count, :increment, :multiplier
39
+
40
+ def initialize(count, sides, increment=0, multiplier=1)
41
+ @sides, @count = sides, count
42
+ @increment, @multiplier = increment, multiplier
43
+ end
44
+
45
+ # Return a new Dice object, with the given multiplier. If the dice already
46
+ # have a multipler, it accumulates.
47
+ def *(n)
48
+ PfrpgCore::Dice.new(count, sides, increment, multiplier * n)
49
+ end
50
+
51
+ # Return a new Dice object, with the given increment. If the dice already
52
+ # have an increment, it accumulates.
53
+ def +(n)
54
+ PfrpgCore::Dice.new(count, sides, increment+n, multiplier)
55
+ end
56
+
57
+ # Same as adding a negative increment.
58
+ def -(n)
59
+ self.+(-n)
60
+ end
61
+
62
+ # Roll the dice. If +collect+ is false (the default), returns an integer.
63
+ # Otherwise, it returns an array with one element for each rolled die.
64
+ #
65
+ # Note that the multipler (if any) is applied to each die, while the
66
+ # increment is applied at the end. If an array is returned, the
67
+ # increment (times the multiplier) will be the last element of the array.
68
+ def roll(collect=false)
69
+ result = collect ? [] : 0
70
+
71
+ count.times do
72
+ roll = (rand(sides) + 1) * multiplier
73
+ result = result.send(collect ? :push : :+, roll)
74
+ end
75
+
76
+ if increment != 0
77
+ result = result.send(collect ? :push : :+, increment * multiplier)
78
+ end
79
+
80
+ result
81
+ end
82
+
83
+ # Return the best +n+ of the dice rolled. If +collect+ is false (the default)
84
+ # an integer is returned, otherwise an array of the best rolls is returned.
85
+ def best(n, collect=false)
86
+ list = to_a.sort.last(n)
87
+ collect ? list : list.inject(0) { |s,v| s + v }
88
+ end
89
+
90
+ # Returns the highest possible integer that may be returned by rolling
91
+ # this dice instance.
92
+ def max
93
+ (count * sides + increment) * multiplier
94
+ end
95
+
96
+ # Returns the lowest possible integer that may be returned by rolling
97
+ # this dice instance.
98
+ def min
99
+ (count + increment) * multiplier
100
+ end
101
+
102
+ # Calculates and returns the average value (as a float) returned by rolling
103
+ # this dice instance.
104
+ def average
105
+ (max + min) / 2.0
106
+ end
107
+
108
+ # Same as calling #roll with a non-false parameter.
109
+ def to_a
110
+ roll(true)
111
+ end
112
+
113
+ # Returns a familiar representation of the dice instance.
114
+ def to_s
115
+ s = "#{count}d#{sides}"
116
+ s << "%+d" % increment if increment != 0
117
+ s << "*%d" % multiplier if multiplier != 1
118
+ s
119
+ end
120
+
121
+ alias to_i roll
122
+ alias inspect to_s
123
+ end
124
+
125
+ class Integer
126
+ # only define methods for common dice. I *could* use method_missing, but
127
+ # this approach helps catch typos, since I almost certainly wouldn't
128
+ # intend to do 2.d9 (it being a rare die, and not used by any RPG games
129
+ # I'm aware of). Also, the optimist in me likes to think this is more
130
+ # efficient than method_missing, though I haven't done any benchmarks. :)
131
+ [4,6,8,10,12,20].each do |sides|
132
+ define_method("d#{sides}") { PfrpgCore::Dice.new(self, sides) }
133
+ end
134
+ end
@@ -0,0 +1,39 @@
1
+ class PfrpgCore::Effect
2
+ attr_accessor :type, :key, :value, :affect
3
+ def initialize(type, key, value, affect=nil)
4
+ # standard effect proc; add a value
5
+ basic = Proc.new do |character, attribute, value|
6
+ character.bonuses.plus(attribute, value)
7
+ end
8
+ affect ||= basic
9
+ @type = type
10
+ @key = key
11
+ @value = value
12
+ @affect = affect
13
+ end
14
+
15
+ def self.load(effects_string)
16
+ return effects_string if effects_string.instance_of? Array
17
+ return [ effects_string ] if effects_string.instance_of? PfrpgCore::Effect
18
+ return [] if effects_string.nil? || effects_string.empty?
19
+ unless effects_string.instance_of? String
20
+ ap "Error effect: "
21
+ ap effects_string
22
+ end
23
+ raise Exception unless effects_string.instance_of? String
24
+ effects_string.split(";").map { |effect| parse_effect(effect) }
25
+ end
26
+
27
+ def self.parse_effect(string)
28
+ p = string.split(":")
29
+ type = p[0]
30
+ key = p[1]
31
+ value = p[2]
32
+ PfrpgCore::Effect.new(type, key, value)
33
+ end
34
+
35
+ def apply(character)
36
+ @affect.call(character, @key, @value)
37
+ end
38
+
39
+ end
@@ -0,0 +1,58 @@
1
+ module PfrpgCore
2
+ class Prerequisite
3
+
4
+ def initialize(attribute, value, matcher=nil)
5
+ default_matcher = Proc.new do |character, attribute, value|
6
+ true
7
+ end
8
+ @attribute = attribute
9
+ @value = value
10
+ @matcher = matcher || default_matcher
11
+ end
12
+
13
+ def self.load(prereq_string)
14
+ begin
15
+ prereqs = []
16
+ p = prereq_string.split(";")
17
+ p.each { |x| prereqs << parse_prereq(x) }
18
+ prereqs
19
+ rescue Exception
20
+ []
21
+ end
22
+ end
23
+
24
+ def self.parse_prereq(string)
25
+ p = string.split(":")
26
+ type = p[0]
27
+ attribute = p[1]
28
+ value = p[2]
29
+ case type
30
+ when "class"
31
+ Prerequisite::ClassPrereq.new(attribute, value)
32
+ when "attribute"
33
+ Prerequisite::AttributePrereq.new(attribute, value)
34
+ when "alignment"
35
+ Prerequisite::AlignmentPrereq.new(attribute, value)
36
+ when "feat"
37
+ Prerequisite::FeatPrereq.new(attribute, value)
38
+ when "skill"
39
+ Prerequisite::SkillPrereq.new(attribute, value)
40
+ when "class_feature"
41
+ Prerequisite::HeroclassFeaturePrereq.new(attribute, value)
42
+ when "combat"
43
+ Prerequisite::BabPrereq.new(attribute, value)
44
+ when "language"
45
+ Prerequisite::LanguagePrereq.new(attribute, value)
46
+ when "misc"
47
+ Prerequisite::MiscPrereq.new(attribute, value)
48
+ else
49
+ Prerequisite.new(attribute, value)
50
+ end
51
+ end
52
+
53
+ def match(character)
54
+ @matcher.call(character, @attribute, @value)
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,6 @@
1
+ class PfrpgUtility::Prerequisite::AlignmentPrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ alignments = PfrpgUtility::Alignment.send(@value)
4
+ alignments.include?(character.alignment.alignment)
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ class PfrpgUtility::Prerequisite::AttributePrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ atr = @attribute.downcase
4
+ str = "modified_#{atr[0..2]}"
5
+ character.attributes.send(str) >= (@value.to_i)
6
+ end
7
+ end
8
+
@@ -0,0 +1,5 @@
1
+ class PfrpgUtility::Prerequisite::BabPrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ character.get_highest_attack_bonus >= @value.to_i
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ class PfrpgUtility::Prerequisite::ClassPrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ begin
4
+ hc = PfrpgClasses::Heroclass.by_name(@attribute)
5
+ base = character.get_class_level(hc)
6
+ base += character.get_class_level('Eldritch Knight') if @attribute == 'Fighter'
7
+ return base >= value
8
+ rescue Exception
9
+ return false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ class PfrpgUtility::Prerequisite::FeatPrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ found = character.feats.find { |x| x.name == @attribute }
4
+ return (found != nil)
5
+ rescue Exception => e
6
+ # ap character.total_feats
7
+ raise e
8
+ end
9
+ end
10
+
@@ -0,0 +1,6 @@
1
+ class PfrpgUtility::Prerequisite::HeroclassFeaturePrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ found = character.class_features.find { |x| x.name.upcase[@attribute.upcase] }
4
+ return (found != nil)
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class PfrpgUtility::Prerequisite::LanguagePrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ character.demographics.languages.include?(@value)
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ class PfrpgUtility::Prerequisite::MiscPrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ begin
4
+ case @attribute
5
+ when "caster level"
6
+ return character.get_caster_level >= @value.to_i
7
+ when "total_level"
8
+ return character.get_total_level >= @value.to_i
9
+ when "caster"
10
+ return character.can_arcane?
11
+ when "divine"
12
+ return character.can_divine?
13
+ when "size"
14
+ return character.race.size.upcase == @value.upcase
15
+ end
16
+ rescue Exception => e
17
+ #ap "Exception: "
18
+ #ap e
19
+ #ap "Self:"
20
+ #ap self
21
+ return false
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ class PfrpgUtility::Prerequisite::SkillPrereq < PfrpgUtility::Prerequisite
2
+ def match(character)
3
+ skill_name = @attribute.downcase
4
+ if ['knowledge', 'perform', 'profession', 'craft'].include?(skill_name)
5
+ vals = []
6
+ classname = "PfrpgSkills::Skill::#{skill_name.capitalize}"
7
+ clazz = Kernel.const_get(classname)
8
+ k = clazz.new("NONE")
9
+ k.supported_types.each do |s|
10
+ vals << character.skills.current_trained_ranks(clazz.new(s).description)
11
+ end
12
+ ranks = vals.max
13
+ else
14
+ ranks = character.skills.current_trained_ranks(skill_name)
15
+ end
16
+ ranks >= @value.to_i
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module PfrpgUtility
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pfrpg_utility
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jordan OMara
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: utility
14
+ email:
15
+ - jordan@herosheets.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/pfrpg_utility/affectable.rb
21
+ - lib/pfrpg_utility/alignment.rb
22
+ - lib/pfrpg_utility/dice.rb
23
+ - lib/pfrpg_utility/effect.rb
24
+ - lib/pfrpg_utility/prerequisite/alignment_prereq.rb
25
+ - lib/pfrpg_utility/prerequisite/attribute_prereq.rb
26
+ - lib/pfrpg_utility/prerequisite/bab_prereq.rb
27
+ - lib/pfrpg_utility/prerequisite/class_prereq.rb
28
+ - lib/pfrpg_utility/prerequisite/feat_prereq.rb
29
+ - lib/pfrpg_utility/prerequisite/heroclass_feature_prereq.rb
30
+ - lib/pfrpg_utility/prerequisite/language_prereq.rb
31
+ - lib/pfrpg_utility/prerequisite/misc_prereq.rb
32
+ - lib/pfrpg_utility/prerequisite/skill_prereq.rb
33
+ - lib/pfrpg_utility/prerequisite.rb
34
+ - lib/pfrpg_utility/version.rb
35
+ - lib/pfrpg_utility.rb
36
+ - LICENSE
37
+ - Rakefile
38
+ homepage: http://herosheets.com
39
+ licenses: []
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 2.0.14
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: PFRPG Utilities
61
+ test_files: []