namelessjon-exalted 0.1.0

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