adventure 0.17.7.pre.pre

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,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adventure
4
+ # Defines and creates general buildings, such as houses and stores.
5
+ class Building
6
+ attr_reader :id, :name, :location, :desc, :type, :owner, :quests, :wares
7
+
8
+ # Creates a new building, be it a house, a tavern, or a store.
9
+ #
10
+ # @param name [String] The name of the house, tavern or store.
11
+ # @param location [String] Where the building is located in the village.
12
+ # @param desc [String] A description of the appearence of the building.
13
+ # @param type [String] What kind of building this is (_e.g._ house).
14
+ # @param owner [Actor] An {Actor} instance to own the building.
15
+ # @param quests [Array] Either nil for no quest or an array of {Quest}s.
16
+ # @param wares [Array] Either nil for no wares or an array, each element of
17
+ # it being a two-element Array, the first the name of the ware, the second
18
+ # the price of the ware (the price must be a String with the currency).
19
+ def initialize(name, location, desc, type, owner, quests = nil, wares = nil)
20
+ @id = ('building-' + name).slugify
21
+ @name = name
22
+ @location = location
23
+ @desc = desc
24
+ @type = type
25
+
26
+ process_case
27
+ check_owner(owner)
28
+ check_quests(quests)
29
+ check_wares(wares)
30
+ end
31
+
32
+ # Returns the full description of the building, with owner information.
33
+ #
34
+ # @return [String] A full description of the building.
35
+ def description
36
+ "This is #{@type.indefinitize} on #{@location}.\n\n#{@name} is owned by "\
37
+ "#{@owner.name}, #{@owner.description}\n\n#{@desc.chomp('.')}."
38
+ end
39
+
40
+ private
41
+
42
+ def process_case
43
+ @name = @name.capitalize
44
+ @location = @location.downcase
45
+ @desc = @desc.downcase
46
+ @type = @type.downcase
47
+ end
48
+
49
+ def check_owner(owner)
50
+ raise ArgumentError, 'Owner must be an Actor' unless owner.is_a? Actor
51
+
52
+ @owner = owner
53
+ end
54
+
55
+ def check_quests(quests)
56
+ unless quests.nil?
57
+ msg = 'Quests must be an Array or nil'
58
+ raise ArgumentError, msg unless quests.is_a?(Array)
59
+
60
+ raise ArgumentError, 'Quests must be a non-empty Array' if quests.empty?
61
+
62
+ msg = 'Each element of the quests array must be a Quest instance'
63
+ quests.each do |quest|
64
+ raise ArgumentError, msg unless quest.is_a? Quest
65
+ end
66
+ end
67
+
68
+ @quests = quests
69
+ end
70
+
71
+ def check_wares(wares)
72
+ unless wares.nil?
73
+ raise ArgumentError, 'Wares must be an Array' unless wares.is_a? Array
74
+ end
75
+
76
+ @wares = wares
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adventure
4
+ # Defines and creates a dungeon, which is actually a category for Rooms.
5
+ class Dungeon
6
+ attr_reader :name, :first
7
+
8
+ # Creates a new instance of a Dungeon, which is a category for {Room}s and
9
+ # sets an entry point.
10
+ #
11
+ # @param name [String] The name of the dungeon.
12
+ def initialize(name)
13
+ @name = name.capitalize
14
+ end
15
+
16
+ # Sets the entry point {Room} to the dungeon.
17
+ #
18
+ # @param room [Room] The entry {Room}.
19
+ def first=(room)
20
+ raise TypeError, 'Must be a Room' unless room.is_a? Room
21
+
22
+ @first = room
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adventure
4
+ # Defines a singleton encounter (one that happens and finishes in a single
5
+ # page).
6
+ class Encounter
7
+ attr_reader :name, :before, :enemies, :after, :exp, :gold, :items
8
+
9
+ # Creates a new Encounter.
10
+ #
11
+ # @param name [String] The name of the Encounter.
12
+ # @param enemies [Array] An Array of arrays, each of which must be comprised
13
+ # of three elements: Creature name, quantity and commentaries. _E.g._:
14
+ # [
15
+ # ...
16
+ # ['Goblin', 3, 'See MM pg.166'],
17
+ # ...
18
+ # ]
19
+ # @param reward [Array] An Array that must contain three elements: the XP
20
+ # points, the gold coins and any items earned upon winning. Leave an empty
21
+ # array or 0 if none.
22
+ # @param before [String] If anything can be done before the encounter (_e.g.
23
+ # _ trying to stealth to gain a surprise round), describe it here.
24
+ # @param after [String] If anything can be done after the encounter (_e.g._
25
+ # the goblins had a painting and you may try to identify it with a History
26
+ # check), describe it here.
27
+ def initialize(name, enemies, reward, before = '', after = '')
28
+ @name = name.capitalize
29
+ @before = before
30
+ @after = after
31
+
32
+ check_enemies(enemies)
33
+ check_reward(reward)
34
+ end
35
+
36
+ private
37
+
38
+ def check_enemies(enemies)
39
+ msg = 'Enemies must be an Array of arrays'
40
+ raise ArgumentError, msg unless enemies.is_a? Array
41
+
42
+ msg = 'Each enemy must be an array of itself'
43
+ enemies.each do |enemy|
44
+ raise ArgumentError, msg unless enemy.is_a? Array
45
+ end
46
+
47
+ @enemies = enemies
48
+ end
49
+
50
+ def check_reward(reward)
51
+ msg = 'Reward must be an Array'
52
+ raise ArgumentError, msg unless reward.is_a? Array
53
+
54
+ msg = 'Reward must be an Array with three elements'
55
+ raise ArgumentError, msg unless reward.length == 3
56
+
57
+ @exp, @gold, @items = reward
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adventure
4
+ # Defines and creates NPCs.
5
+ class Quest
6
+ attr_reader :name, :description, :goal, :reward
7
+ attr_accessor :dungeon
8
+
9
+ # Creates a new instance of Quest.
10
+ #
11
+ # @param name [String] The name of the Quest.
12
+ # @param description [String] The description and history of the Quest.
13
+ # @param goal [String] The goal of the Quest.
14
+ # @param reward [String] The reward or rewards of completing the Quest.
15
+ # @param dungeon [Dungeon] The dungeon where the Quest takes place.
16
+ def initialize(name, description, goal, reward, dungeon)
17
+ @name = name.capitalize
18
+ @description = description
19
+ @goal = goal
20
+ @reward = reward
21
+
22
+ check_dungeon(dungeon)
23
+ end
24
+
25
+ # Returns the first {Room} of the {Dungeon} where the Quest takes place.
26
+ #
27
+ # @return [Room] The entry point of the {Dungeon} for this Quest.
28
+ def begin
29
+ @dungeon.first
30
+ end
31
+
32
+ private
33
+
34
+ def check_dungeon(dungeon)
35
+ msg = 'Dungeon must be a Dungeon'
36
+ raise ArgumentError, msg unless dungeon.is_a? Dungeon
37
+
38
+ msg = 'Dungeon must have a first Room'
39
+ raise ArgumentError, msg unless dungeon.first.is_a? Room
40
+
41
+ @dungeon = dungeon
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adventure
4
+ # Defines and creates rooms for dungeons and encounters.
5
+ class Room
6
+ attr_reader :id, :name, :lit, :description, :encounter
7
+ attr_reader :north, :south, :east, :west, :up, :down
8
+
9
+ # Creates a new room.
10
+ #
11
+ # @param name [String] The name of the Room.
12
+ # @param description [String] The description of the Room.
13
+ # @param encounter [Encounter or nil] A {Encounter} instance or nil if no
14
+ # encounter happens on this Room.
15
+ # @param dungeon [Dungeon] The {Dungeon} to which this room belongs.
16
+ # @param lit [Boolean] If the room has a light source and is lit by it.
17
+ def initialize(name, description, encounter, dungeon, lit = true)
18
+ @id = ('room-' + name).slugify
19
+ @name = name.capitalize
20
+ @description = description
21
+ @lit = lit
22
+
23
+ check_encounter(encounter)
24
+ check_dungeon(dungeon)
25
+ end
26
+
27
+ def north=(room)
28
+ check_room(room)
29
+ @north = room
30
+ end
31
+
32
+ def south=(room)
33
+ check_room(room)
34
+ @south = room
35
+ end
36
+
37
+ def east=(room)
38
+ check_room(room)
39
+ @east = room
40
+ end
41
+
42
+ def west=(room)
43
+ check_room(room)
44
+ @west = room
45
+ end
46
+
47
+ def up=(room)
48
+ check_room(room)
49
+ @up = room
50
+ end
51
+
52
+ def down=(room)
53
+ check_room(room)
54
+ @down = room
55
+ end
56
+
57
+ private
58
+
59
+ def check_encounter(encount)
60
+ msg = 'Encounter must be an Encounter instance'
61
+ raise ArgumentError, msg unless encount.is_a?(Encounter) || encount.nil?
62
+
63
+ @encounter = encounter
64
+ end
65
+
66
+ def check_dungeon(dungeon)
67
+ msg = 'Dungeon must be a Dungeon instance'
68
+ raise ArgumentError, msg unless dungeon.is_a? Dungeon
69
+
70
+ @dungeon = dungeon
71
+ end
72
+
73
+ def check_room(room)
74
+ msg = 'Room must be a Room instance or nil'
75
+ raise ArgumentError, msg unless room.is_a?(Room) || room.nil?
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Adventure
4
+ # Defines and creates a settlement.
5
+ class Settlement
6
+ attr_reader :id, :name, :population, :type, :wealth, :gp_limit
7
+ attr_reader :demographics, :environment, :stores, :houses
8
+
9
+ # Creates a new settlement, with all its contents.
10
+ #
11
+ # @param name [String] The name of the Settlement.
12
+ # @param population [Integer] The number of people on the Settlement,
13
+ # minimum of 20 (less than that and its a large home, not a settlement).
14
+ # @param demographics [Array] An array in which each element must be an
15
+ # array with two elements, the first a String of the race, the second an
16
+ # Integer of the rough percentage this race represents. _E.g._:
17
+ # [
18
+ # ['humans', 90],
19
+ # ['halflings', 6],
20
+ # ['misc', 4]
21
+ # ]
22
+ # @param environment [String] The environment surrounding the Settlement.
23
+ # @param buildings [Hash] The list of {Building}s of the Settlement, which
24
+ # must be a Hash with two elements, each with a specific key: _stores_ and
25
+ # _houses_. Each of this keys must contain an Array of Buildings, or an
26
+ # empty Array if there are no building of that category on the Settlement.
27
+ def initialize(name, population, demographics, environment, buildings)
28
+ check_params(population, demographics)
29
+ check_name(name)
30
+
31
+ @population = population.to_i
32
+ @type, @gp_limit = type_limit
33
+ @wealth = wealth_calc
34
+ @demographics = demographics
35
+ @environment = environment
36
+
37
+ check_buildings(buildings)
38
+ end
39
+
40
+ # Returns a description of the Settlement.
41
+ #
42
+ # @return [String] A description of the Settlement.
43
+ def short_description
44
+ "#{@name} is a #{@type.downcase} of #{@population} souls, most of which"\
45
+ " are #{predominant_race}. The #{@type.downcase} is in a "\
46
+ "#{@environment.downcase}, with #{@stores.length} stores and "\
47
+ "#{@houses.length} houses of note."
48
+ end
49
+
50
+ private
51
+
52
+ def type_limit
53
+ if @population < 2001
54
+ small_settlements
55
+ else
56
+ large_settlements
57
+ end
58
+ end
59
+
60
+ def small_settlements
61
+ case @population
62
+ when 20..80
63
+ ['Thorp', 40]
64
+ when 81..400
65
+ ['Hamlet', 100]
66
+ when 401..900
67
+ ['Village', 200]
68
+ when 901..2000
69
+ ['Small town', 800]
70
+ end
71
+ end
72
+
73
+ def large_settlements
74
+ case @population
75
+ when 2001..5000
76
+ ['Large town', 3000]
77
+ when 5001..12_000
78
+ ['Small city', 15_000]
79
+ when 12_001..25_000
80
+ ['Large city', 40_000]
81
+ else
82
+ ['Metropolis', 100_000]
83
+ end
84
+ end
85
+
86
+ def wealth_calc
87
+ ((@gp_limit / 2) * (@population / 10)).to_i
88
+ end
89
+
90
+ def predominant_race
91
+ percent = 0
92
+ main_race = ''
93
+ @demographics.each do |pop|
94
+ if pop[1] > percent
95
+ main_race = pop[0]
96
+ percent = pop[1]
97
+ end
98
+ end
99
+
100
+ main_race
101
+ end
102
+
103
+ def check_params(pop, demo)
104
+ raise ArgumentError, 'Two few people (min 20)' unless pop >= 20
105
+ raise ArgumentError, 'Demographics must be a Hash' unless demo.is_a? Array
106
+ end
107
+
108
+ def check_name(name)
109
+ @id = ('settlement-' + name).slugify
110
+ @name = name
111
+ end
112
+
113
+ def check_buildings(buildings)
114
+ msg = 'Building must be a Hash with two keys, and arrays under them'
115
+ raise ArgumentError, msg unless buildings.is_a? Hash
116
+
117
+ check_building_category('stores', buildings)
118
+ check_building_category('houses', buildings)
119
+
120
+ @stores = buildings['stores']
121
+ @houses = buildings['houses']
122
+ end
123
+
124
+ def check_building_category(cat, buildings)
125
+ msg = "Building must contain a list of houses under the '#{cat}' key."
126
+ raise ArgumentError, msg unless buildings.key?(cat)
127
+
128
+ msg = "Building must contain arrays under the '#{cat}' key."
129
+ raise ArgumentError, msg unless buildings[cat].is_a? Array
130
+
131
+ msg = 'Each element of the arrays must be an instance of Building'
132
+ buildings[cat].each do |lot|
133
+ raise ArgumentError, msg unless lot.is_a? Building
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the main module of this Gem. It defines each component of an
4
+ # Adventure. The export of such adventure is located elsewhere.
5
+ module Adventure
6
+ # Sets the current version of the gem
7
+ @version = '0.17.7-pre'
8
+
9
+ # Returns the Gem's current version.
10
+ #
11
+ # @return [String] The Gem's current version.
12
+ def self.version
13
+ @version
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adventure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.17.7.pre.pre
5
+ platform: ruby
6
+ authors:
7
+ - Igor Padoim
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-09-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.8.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.8.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: indefinite_article
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.2.4
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.2.4
69
+ - !ruby/object:Gem::Dependency
70
+ name: jekyll_slugify
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.4.2
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.4.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: random_name_generator
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.0.3
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.0.3
97
+ description:
98
+ email:
99
+ - igorpadoim@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitattributes"
105
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
106
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
107
+ - ".github/ISSUE_TEMPLATE/user_question.md"
108
+ - ".github/PULL_REQUEST_TEMPLATE.md"
109
+ - ".github/config.yml"
110
+ - ".gitignore"
111
+ - ".rspec"
112
+ - ".rubocop.yml"
113
+ - ".travis.yml"
114
+ - CHANGELOG.md
115
+ - CODE-OF-CONDUCT.md
116
+ - CONTRIBUTING.md
117
+ - Gemfile
118
+ - Gemfile.lock
119
+ - LICENSE.md
120
+ - OGL.md
121
+ - README.md
122
+ - Rakefile
123
+ - adventure.gemspec
124
+ - bin/console
125
+ - bin/setup
126
+ - lib/adventure.rb
127
+ - lib/adventure/actor.rb
128
+ - lib/adventure/building.rb
129
+ - lib/adventure/dungeon.rb
130
+ - lib/adventure/encounter.rb
131
+ - lib/adventure/quest.rb
132
+ - lib/adventure/room.rb
133
+ - lib/adventure/settlement.rb
134
+ - lib/adventure/version.rb
135
+ homepage: https://github.com/Nereare/Adventure
136
+ licenses:
137
+ - MIT
138
+ metadata:
139
+ homepage_uri: https://github.com/Nereare/Adventure
140
+ source_code_uri: https://github.com/Nereare/Adventure
141
+ changelog_uri: https://github.com/Nereare/Adventure/blob/master/CHANGELOG.md
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">"
154
+ - !ruby/object:Gem::Version
155
+ version: 1.3.1
156
+ requirements: []
157
+ rubygems_version: 3.0.6
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: A random adventure generator for D&D 5e.
161
+ test_files: []