adventure 0.17.7.pre.pre

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