namelessjon-exalted 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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Jonathan Stott
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,10 @@
1
+ exalted
2
+ =======
3
+
4
+ A collection of classes to make managing Exalted characters a little easier,
5
+ especially dealing with all the stats.
6
+
7
+ COPYRIGHT
8
+ =========
9
+
10
+ Copyright (c) 2008 Jonathan Stott. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ begin
4
+ gem('mislav-hanna')
5
+ require 'hanna/rdoctask'
6
+ rescue
7
+ require 'rake/rdoctask'
8
+ end
9
+ require 'rcov/rcovtask'
10
+
11
+ begin
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |s|
14
+ s.name = "exalted"
15
+ s.summary = "Classes to help with Exalted"
16
+ s.email = "jonathan.stott@gmail.com"
17
+ s.homepage = "http://github.com/namelessjon/exalted"
18
+ s.description = "Classes to help with characters for Exalted, the RPG by WW."
19
+ s.authors = ["Jonathan Stott"]
20
+ s.add_dependency('extlib', '~> 0.9.9')
21
+ s.files = FileList["[A-Z]*", "{lib,test}/**/*"]
22
+ end
23
+ rescue LoadError
24
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
25
+ end
26
+
27
+ Rake::TestTask.new do |t|
28
+ t.libs << 'lib'
29
+ t.pattern = 'spec/**/*_spec.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+ Rake::RDocTask.new do |rdoc|
34
+ rdoc.rdoc_dir = 'rdoc'
35
+ rdoc.title = 'exalted'
36
+ rdoc.options << '--line-numbers' << '--inline-source'
37
+ rdoc.rdoc_files.include('README*')
38
+ rdoc.rdoc_files.include('lib/**/*.rb')
39
+ end
40
+
41
+ Rcov::RcovTask.new do |t|
42
+ t.libs << 'spec'
43
+ t.test_files = FileList['spec/**/*_spec.rb']
44
+ t.verbose = true
45
+ end
46
+
47
+ task :default => :rcov
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ patch: 0
3
+ major: 0
4
+ minor: 1
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/ruby
2
+ # character.rb
3
+ # Jonathan D. Stott <jonathan.stott@gmail.com>
4
+
5
+ module Exalted
6
+
7
+ ATTRIBUTES = [
8
+ ['physical', %w{strength dexterity stamina}],
9
+ ['social', %w{charisma manipulation appearance}],
10
+ ['mental', %w{perception intelligence wits}]
11
+ ]
12
+
13
+ ABILITIES = {
14
+ 'DB1e' => [
15
+ ['air', %w{linguistics lore occult thrown stealth} ],
16
+ ['earth', %w{awareness craft endurance martial_arts resistance}],
17
+ ['fire', %w{athletics dodge melee presence socialize}],
18
+ ['water', %w{brawl bureaucracy investigation larceny sail}],
19
+ ['wood', %w{archery medicine performance ride survival}]
20
+ ],
21
+ 'DB2e' => [
22
+ ['air', %w{linguistics lore occult thrown stealth} ],
23
+ ['earth', %w{awareness craft integrity resistance war}],
24
+ ['fire', %w{athletics dodge melee presence socialize}],
25
+ ['water', %w{martial_arts bureaucracy investigation larceny sail}],
26
+ ['wood', %w{archery medicine performance ride survival}]
27
+ ],
28
+ 'S1e' => [
29
+ ['dawn', %w{archery brawl martial_arts melee thrown}],
30
+ ['zenith', %w{endurance performance presence resistance survival }],
31
+ ['twilight', %w{craft investigation lore medicine occult}],
32
+ ['night', %w{athletics awareness dodge larceny stealth}],
33
+ ['eclipse', %w{bureaucracy linguistics ride sail socialize}]
34
+ ]
35
+
36
+ }
37
+
38
+ class Character
39
+ attr_reader :name, :caste, :type, :languages, :attributes, :abilities
40
+
41
+ # Creates a new Character
42
+ #
43
+ # This method expects a hash, with the following keys
44
+ #
45
+ # name:: The character's name
46
+ # caste:: The character's caste (optional, see also aspect)
47
+ # aspect:: The character's aspect (optional, see also caste)
48
+ # type:: The Exalted type. Currently DB1e or DB2e or S1e
49
+ # languages:: The languages spoken by the character (Array)
50
+ # abilities:: A hash of 'ability => rating' pairs
51
+ # attributes:: A hash of 'attribute => rating' pairs
52
+ # favoured:: An array of the character's favoured abilities
53
+ def initialize(opts = {})
54
+ @opts = opts.to_mash
55
+
56
+
57
+ set_basics
58
+
59
+ set_attributes
60
+
61
+ set_abilities
62
+ end
63
+
64
+ protected
65
+
66
+ def set_basics
67
+ @name = @opts[:name]
68
+ @caste = @opts[:caste] || @opts[:aspect]
69
+ @type = @opts[:type]
70
+ @languages = @opts[:languages] || []
71
+ end
72
+
73
+ # sets up the attributes for the character
74
+ def set_attributes
75
+ # save the raw stuff for ease of reference
76
+ @raw_attributes = @opts[:attributes]
77
+
78
+ # create a new attributes set
79
+ @attributes = StatBlock.new(:attributes, ATTRIBUTES)
80
+
81
+ # setup the attributes set.
82
+ @raw_attributes.each do |name, rating|
83
+ @attributes[name].rating = rating
84
+ end
85
+ end
86
+
87
+
88
+ # sets up the abilities used
89
+ def set_abilities
90
+ # save the raw stuff for ease of reference
91
+ @raw_abilities = @opts[:abilities]
92
+ @favoureds = @opts[:favoured] || []
93
+ @specialities = @opts[:specialities] || {}
94
+
95
+ # create a new attributes set
96
+ if ABILITIES[self.type]
97
+ @abilities = StatBlock.new(:abilities, ABILITIES[self.type])
98
+ else
99
+ raise ArgumentError, "I don't know about '#{self.type}' Exalted."
100
+ end
101
+
102
+ # setup the attributes set.
103
+ @raw_abilities.each do |name, rating|
104
+ @abilities[name].rating = rating
105
+ end
106
+
107
+ # setup the caste abilities
108
+ if @abilities[self.caste]
109
+ @abilities[self.caste].caste = true
110
+ end
111
+
112
+ # set favoureds!
113
+ @favoureds.each do |a|
114
+ @abilities[a].favoured = true
115
+ end
116
+
117
+ # Add specialities
118
+ @specialities.each do |ability, specs|
119
+ # want a flat array of specs.
120
+ specs = [specs].flatten
121
+ @abilities[ability].specialities = specs
122
+ end
123
+
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,80 @@
1
+ # A Stat object holds all the information about an Exalted stat. This includes
2
+ # the name, rating, whether it is favoured, or caste and any specialities it
3
+ # might have.
4
+ class Exalted::Stat
5
+ # the stat's name
6
+ attr_accessor :name
7
+
8
+ # the stat's rating
9
+ attr_accessor :rating
10
+
11
+ # specialities the stat has
12
+ attr_accessor :specialities
13
+
14
+ # set the favoured status
15
+ attr_writer :favoured
16
+
17
+ # set the caste status
18
+ attr_writer :caste
19
+
20
+
21
+ # Creates a new stat.
22
+ #
23
+ # Options include
24
+ # favoured:: sets the favoured status of the stat
25
+ # caste:: sets the caste status of the set
26
+ # specialities:: Adds specialities to the set
27
+ # specs:: see specialities
28
+ def initialize(name, rating = 0, opts={})
29
+ if Hash === rating
30
+ opts = rating
31
+ rating = 0
32
+ end
33
+
34
+ @name = name.downcase.to_sym
35
+ @rating = rating
36
+ @favoured = opts.delete(:favoured) || false
37
+ @caste = opts.delete(:caste) || false
38
+ specialities = opts.delete(:specialities) || opts.delete(:specs) || []
39
+ @specialities = specialities.sort
40
+ end
41
+
42
+ # Is the stat favoured?
43
+ def favoured?
44
+ (@favoured) ? true : false
45
+ end
46
+
47
+ # Is the stat a caste ability?
48
+ def caste?
49
+ (@caste) ? true : false
50
+ end
51
+
52
+ # :nodoc:
53
+ def eql?(o)
54
+ return false unless o.is_a?(Exalted::Stat)
55
+ return false unless self.rating == o.rating
56
+ return false unless self.favoured? == o.favoured?
57
+ return false unless self.caste? == o.caste?
58
+ return false unless self.specialities == o.specialities
59
+ return true if self.name.eql?(o.name)
60
+ false
61
+ end
62
+
63
+ def ==(o)
64
+ case o
65
+ when String
66
+ return true if self.name.to_s == o.downcase
67
+ when Symbol
68
+ return true if self.name == o
69
+ when Exalted::Stat
70
+ return self.eql?(o)
71
+ else
72
+ return false
73
+ end
74
+ end
75
+
76
+ # :nodoc:
77
+ def inspect
78
+ "#<Stat:#{@name}:#{rating}:#{@caste || @favoured}:#{@specialities.map {|s| "'#{s}'"}.join(",")}>"
79
+ end
80
+ end
@@ -0,0 +1,60 @@
1
+ module Exalted
2
+ # A StatBlock holds several related StatSets, representing a character's
3
+ # Attributes or Abilities and similar groups of stats.
4
+ class StatBlock
5
+ include Enumerable
6
+
7
+ # the name of the statblock
8
+ attr_reader :name
9
+
10
+ # stat_sets in the block
11
+ attr_reader :stat_sets
12
+
13
+ # Create a new StatBlock
14
+ #
15
+ # The StatBlock is initialized with a name, e.g 'Attributes'
16
+ # and an array of tuples consisting of the arguments to a StatSet.new call
17
+ # @stats = [
18
+ # ['air', %w{linguistics lore occult thrown stealth}],
19
+ # ...,
20
+ # ['wood', %w{archery medicine performance ride survival}]
21
+ # ]
22
+ # @stat_block = StatBlock.new('abilities', @stats)
23
+ #
24
+ def initialize(name, stats)
25
+ @name = name
26
+ @stat_sets = []
27
+ stats.each do |name, abilities|
28
+ @stat_sets << StatSet.new(name, abilities)
29
+ end
30
+ end
31
+
32
+
33
+ def [](name)
34
+ # first, check for stat sets
35
+ stat_set = self.detect {|s| s == name }
36
+ if stat_set
37
+ return stat_set
38
+ else
39
+ @stat_sets.each do |stat_set|
40
+ if (stat_set.include?(name))
41
+ return stat_set[name]
42
+ end
43
+ end
44
+ nil
45
+ end
46
+ end
47
+
48
+ # yields each StatSet in turn to the block.
49
+ def each
50
+ @stat_sets.each { |ss| yield ss }
51
+ end
52
+
53
+ # yields each StatSet with stats with a non-zero rating inside to the block, in turn.
54
+ def each_rated
55
+ self.each do |ss|
56
+ yield ss if ss.detect { |s| s.rating > 0 }
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,119 @@
1
+ module Exalted
2
+ # A StatSet holds a group of related Stats, such as those comprising an
3
+ # caste or aspect ability grouping. The Set has a name, and a record of the
4
+ # Stats within it.
5
+ #
6
+ # # create a new stat set
7
+ # @stat_set = StatSet.new('fire', %w{athletics dodge melee presence socialize})
8
+ #
9
+ # # access the dodge stat
10
+ # @stat_set['dodge']
11
+ # # => #<Stat:dodge:0:false:>
12
+ #
13
+ class StatSet
14
+ include Enumerable
15
+
16
+ # name of the stat set, typically the caste or aspect.
17
+ attr_reader :name
18
+
19
+ # names of the stats in the set
20
+ attr_reader :stat_names
21
+
22
+ # the stats themselves
23
+ attr_reader :stats
24
+
25
+ # is this a set of caste abilities?
26
+ attr_reader :caste
27
+
28
+ def initialize(name, stats)
29
+ @name = name.to_sym
30
+ @stat_names = stats
31
+ @caste = false
32
+
33
+ create_stats
34
+ end
35
+
36
+ def inspect
37
+ "#<StatSet:#{name}:#{caste}:[#{stats.map {|s| s.inspect }.join(', ')}]>"
38
+ end
39
+
40
+ # hash style access to a Stat, based on the Stat's name.
41
+ def [](stat_name)
42
+ self.detect { |stat| stat == stat_name }
43
+ end
44
+
45
+ # yields each stat which has a non-zero rating in turn
46
+ def each
47
+ @stats.each do |stat|
48
+ yield stat
49
+ end
50
+ end
51
+
52
+ # yields only stats with a non-zero rating
53
+ def each_rated
54
+ self.each do |stat|
55
+ yield stat if stat.rating > 0
56
+ end
57
+ end
58
+
59
+ # assign caste status to all stats in the set at once.
60
+ def caste=(caste)
61
+ if @caste != caste
62
+ @stats.each do |stat|
63
+ stat.caste = caste
64
+ end
65
+ @caste = caste
66
+ end
67
+ end
68
+
69
+ # boolean accessor for if this is a caste stat set or no.
70
+ def caste?
71
+ (self.caste) ? true : false
72
+ end
73
+
74
+ # returns the number of stats in the set.
75
+ #
76
+ # If called as #size(false), only returns the number of stats with a non-zero
77
+ # rating
78
+ def size(all=true)
79
+ if all
80
+ @stats.size
81
+ else
82
+ @stats.find_all {|s| s.rating > 0 }.size
83
+ end
84
+ end
85
+
86
+ def ==(o)
87
+ case o
88
+ when String
89
+ return self.name.to_s == o
90
+ when Symbol
91
+ return self.name == o
92
+ when StatSet
93
+ return (self == o.name) && (self.stat_names == o.stat_names)
94
+ else
95
+ return false
96
+ end
97
+ end
98
+
99
+ def eql?(o)
100
+ return false unless o.is_a?(StatSet)
101
+ return false unless self.name.eql?(o.name)
102
+ return false unless self.stat_names.eql?(o.stat_names)
103
+ # detect for stats sharing the same name being not equal.
104
+ stats_not_eql = self.stat_names.detect { |n| !(self[n].eql?(o[n])) }
105
+ # if we have a stat that is not equal, we can return false
106
+ # otherwise, it appears we must return true!
107
+ return (stats_not_eql) ? false : true
108
+ end
109
+
110
+ protected
111
+
112
+ def create_stats
113
+ @stats = []
114
+ @stat_names.each do |name|
115
+ @stats << Stat.new(name)
116
+ end
117
+ end
118
+ end
119
+ end
data/lib/exalted.rb ADDED
@@ -0,0 +1,10 @@
1
+ gem('extlib', '~> 0.9.9')
2
+ require 'extlib'
3
+
4
+ module Exalted
5
+ end
6
+
7
+ require 'exalted/stat'
8
+ require 'exalted/stat_set'
9
+ require 'exalted/stat_block'
10
+ require 'exalted/character'
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: namelessjon-exalted
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Stott
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-27 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: extlib
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.9.9
23
+ version:
24
+ description: Classes to help with characters for Exalted, the RPG by WW
25
+ email: jonathan.stott@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - LICENSE
34
+ - README
35
+ - VERSION.yml
36
+ - Rakefile
37
+ - lib/exalted
38
+ - lib/exalted/stat_set.rb
39
+ - lib/exalted/stat_block.rb
40
+ - lib/exalted/stat.rb
41
+ - lib/exalted/character.rb
42
+ - lib/exalted.rb
43
+ has_rdoc: false
44
+ homepage: http://github.com/namelessjon/exalted
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.2.0
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: Classes to help with Exalted
69
+ test_files: []
70
+