lots 1.0.1

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4ea6a48ec0e11748ce6abb80dcfafaa15e52d4bc
4
+ data.tar.gz: d442fadaa33099b3d26c8f85135cfdf3df65a0de
5
+ SHA512:
6
+ metadata.gz: 91ab6cf3f8fede65c5444a24f74c0e8dfd9ee2ce11b82aefb4e4c49a9ddb7f21af7f9df5bca4f554896b2351f3b0545e3b2b78b638047a90f9747d854b6cd7ca
7
+ data.tar.gz: 9c2d12d07804768ba03653c3addaf62e9768afacc40430c17ec8ca70597c5469832aeb6e47791ae6cd72ef14e07ad13fe2ac92bceabeff5e67851b9b93480da7
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Dir.chdir(File.expand_path(File.dirname(__FILE__).to_s + "/.."))
4
+ load "lots.rb"
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Legend of the Sourcerer
4
+ # Written by Robert W. Oliver II <robert@cidergrove.com>
5
+ # Copyright (C) 2018 Sourcerer, All Rights Reserved.
6
+ # Licensed under GPLv3.
7
+
8
+ module LOTS
9
+
10
+ ENEMY_KILLED = "KILLED"
11
+
12
+ HIT_CHANCE_MODIFIER = 5
13
+ ATTACK_VALUE_MODIFIER = 1
14
+
15
+ class Character
16
+
17
+ attr_accessor :name
18
+ attr_accessor :health
19
+ attr_accessor :mana
20
+ attr_accessor :x
21
+ attr_accessor :y
22
+ attr_accessor :level
23
+ attr_accessor :str
24
+ attr_accessor :int
25
+ attr_accessor :in_combat
26
+ attr_accessor :current_enemy
27
+ attr_accessor :lines
28
+ attr_accessor :dead
29
+
30
+ def initialize (args)
31
+ name = args[:name]
32
+ world = args[:world]
33
+ @name = name
34
+ @level = 1
35
+ @health = 100
36
+ @mana = 100
37
+ @str = 5
38
+ @int = 5
39
+ @x = 1
40
+ @y = world.get_height
41
+ @in_combat = false
42
+ @current_enemy = nil
43
+ @lines = 0
44
+ @dead = 0
45
+ return "Welcome %{name}! Let's play Legend of the Sourcerer!"
46
+ end
47
+
48
+ # Player attacks enemy
49
+ def attack(args)
50
+ player = self
51
+ enemy = args[:enemy]
52
+ ui = args[:ui]
53
+
54
+ # Does the player even hit the enemy?
55
+ # We could use a hit chance stat here, but since we don't have one,
56
+ # we'll just base it off the player/enemy stength discrepency.
57
+ ui.enemy_info({:player => player})
58
+ ui.player_info({:player => player})
59
+ str_diff = (player.str - enemy.str) * 2
60
+ hit_chance = rand(1...100) + str_diff + HIT_CHANCE_MODIFIER
61
+
62
+ if (hit_chance > 50)
63
+ # Determine value of the attack
64
+ attack_value = rand(1...player.str) + ATTACK_VALUE_MODIFIER
65
+ if attack_value > enemy.health
66
+ print "You swing and " + "hit".light_yellow + " the " + enemy.name.light_red + " for " + attack_value.to_s.light_white + " damage, killing it!\n"
67
+ print "You gain " + enemy.lines.to_s.light_white + " lines of code.\n"
68
+ return ENEMY_KILLED
69
+ else
70
+ print "You swing and " + "hit".light_yellow + " the " + enemy.name.light_red + " for " + attack_value.to_s.light_white + " damage!\n"
71
+ return attack_value
72
+ end
73
+ else
74
+ print "You swing and " + "miss".light_red + " the " + enemy.name + "!\n"
75
+ return 0
76
+ end
77
+ return true
78
+ end
79
+
80
+ def move(args)
81
+ direction = args[:direction]
82
+ world = args[:world]
83
+ ui = args[:ui]
84
+ story = args[:story]
85
+ case direction
86
+ when :up
87
+ if @y > 1
88
+ @y -= 1
89
+ else
90
+ ui.out_of_bounds
91
+ return false
92
+ end
93
+ when :down
94
+ if @y < world.get_height
95
+ @y += 1
96
+ else
97
+ ui.out_of_bounds
98
+ return false
99
+ end
100
+ when :left
101
+ if @x > 1
102
+ @x -= 1
103
+ else
104
+ ui.out_of_bounds
105
+ return false
106
+ end
107
+ when :right
108
+ if @x < world.get_width
109
+ @x += 1
110
+ else
111
+ ui.out_of_bounds
112
+ return false
113
+ end
114
+ end
115
+ unless world.check_area({:player => self, :ui => ui, :story => story})
116
+ return false
117
+ else
118
+ return true
119
+ end
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Legend of the Sourcerer
4
+ # Written by Robert W. Oliver II <robert@cidergrove.com>
5
+ # Copyright (C) 2018 Sourcerer, All Rights Reserved.
6
+ # Licensed under GPLv3.
7
+ #
8
+ # Enemy Class
9
+ #
10
+
11
+ module LOTS
12
+
13
+ ENEMY_CATALOG = [
14
+ [:name => "Imp", :health => 3, :mana => 0, :str => 3, :lines => 1],
15
+ [:name => "Rabid Wolf", :health => 4, :mana => 0, :str => 4, :lines => 2],
16
+ [:name => "Rock Giant", :health => 7, :mana => 3, :str => 5, :lines => 5],
17
+ [:name => "Toxic Toad", :health => 2, :mana => 6, :str => 1, :lines => 2],
18
+ [:name => "Rabid Bear", :health => 5, :mana => 0, :str => 4, :lines => 3],
19
+ [:name => "Angry Fae", :health => 3, :mana => 10, :str => 2, :lines => 5]
20
+ ]
21
+
22
+ PLAYER_DEAD = "PLAYER_DEAD"
23
+
24
+ class Enemy
25
+
26
+ attr_accessor :name
27
+ attr_accessor :health
28
+ attr_accessor :mana
29
+ attr_accessor :str
30
+ attr_accessor :int
31
+ attr_accessor :lines
32
+
33
+ def initialize(args = nil)
34
+ # Pick a random enemy
35
+ selected_enemy = ENEMY_CATALOG.sample[0]
36
+ @name = selected_enemy[:name]
37
+ @health = selected_enemy[:health] + rand(0..3)
38
+ @mana = selected_enemy[:mana] + rand(0..3)
39
+ @str = selected_enemy[:str]
40
+ @lines = selected_enemy[:lines]
41
+ @int = rand(2..6)
42
+ end
43
+
44
+ # Enemy attacks player
45
+ def attack(args)
46
+ enemy = self
47
+ player = args[:player]
48
+
49
+ # Does the enemy even hit the player?
50
+ str_diff = (enemy.str - player.str) * 2
51
+ hit_chance = rand(1...100) + str_diff
52
+
53
+ if (hit_chance > 30)
54
+ # Determine value of the attack
55
+ attack_value = rand(1...player.str)
56
+ print enemy.name.light_red + " hits you for " + attack_value.to_s.light_yellow + " damage!\n"
57
+ if attack_value > player.health
58
+ return PLAYER_DEAD
59
+ else
60
+ return attack_value
61
+ end
62
+ else
63
+ print enemy.name.light_red + " misses you!\n"
64
+ end
65
+ return true
66
+ end
67
+
68
+
69
+ end
70
+
71
+ end
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Legend of the Sourcerer
4
+ # Written by Robert W. Oliver II <robert@cidergrove.com>
5
+ # Copyright (C) 2018 Sourcerer, All Rights Reserved.
6
+ # Licensed under GPLv3.
7
+
8
+ LOTS_VERSION = "1.00"
9
+
10
+ # Create a new UI and world
11
+ ui = LOTS::UI.new
12
+ world = LOTS::World.new
13
+
14
+ # Clear the screen and print welcome message
15
+ ui.clear
16
+ ui.welcome
17
+
18
+ # Ask name
19
+ name = ui.ask("What is your name?", /\w/)
20
+
21
+ # Create a new player
22
+ player = LOTS::Character.new({:name => name, :world => world})
23
+
24
+ # Show intro story
25
+ ui.new_line
26
+ story = LOTS::Story.new
27
+ ui.draw_frame({:text => story.intro})
28
+
29
+ # Show the map for the first time
30
+ map = world.get_map({:player => player})
31
+ ui.draw_frame({:text => map})
32
+
33
+ # MAIN INPUT LOOP
34
+ running = 1
35
+ while running
36
+ ui.new_line
37
+ # Get command from user
38
+ cmd = ui.get_cmd
39
+ case cmd
40
+ when "map", "m"
41
+ map = world.get_map({:player => player})
42
+ ui.draw_frame({:text => map})
43
+ when "version", "ver"
44
+ ui.display_version
45
+ when "clear", "cls"
46
+ ui.clear
47
+ when "name", "whoami"
48
+ ui.display_name({:player => player})
49
+ when "location", "loc", "where", "whereami"
50
+ ui.show_location({:player => player})
51
+ when "look", "what", "around"
52
+ world.check_area({:player => player, :ui => ui, :story => story})
53
+ when "up", "north", "u", "n"
54
+ unless player.in_combat
55
+ if !player.move({:direction => :up, :world => world, :ui => ui, :story => story})
56
+ player.in_combat = 1
57
+ end
58
+ else
59
+ ui.cannot_travel_combat
60
+ end
61
+ when "down", "south", "d", "s"
62
+ unless player.in_combat
63
+ if !player.move({:direction => :down, :world => world, :ui => ui, :story => story})
64
+ player.in_combat = 1
65
+ end
66
+ else
67
+ ui.cannot_travel_combat
68
+ end
69
+ when "left", "west", "l", "w"
70
+ unless player.in_combat
71
+ if !player.move({:direction => :left, :world => world, :ui => ui, :story => story})
72
+ player.in_combat = 1
73
+ end
74
+ else
75
+ ui.cannot_travel_combat
76
+ end
77
+ when "right", "east", "r", "e"
78
+ unless player.in_combat
79
+ if !player.move({:direction => :right, :world => world, :ui => ui, :story => story})
80
+ player.in_combat = 1
81
+ end
82
+ else
83
+ ui.cannot_travel_combat
84
+ end
85
+ when "attack", "a"
86
+ if player.in_combat
87
+ retval = player.attack({:enemy => player.current_enemy, :ui => ui})
88
+ if retval == LOTS::ENEMY_KILLED
89
+ player.lines += player.current_enemy.lines
90
+ # Remove enemy from map
91
+ world.the_map[player.y-1][player.x-1] = LOTS::MAP_KEY_GRASS
92
+ # Take player out of combat
93
+ player.current_enemy = nil
94
+ player.in_combat = false
95
+ end
96
+ if retval.is_a? Numeric
97
+ player.current_enemy.health -= retval
98
+ retval = player.current_enemy.attack({:player => player})
99
+ if retval.is_a? Numeric
100
+ player.health -= retval
101
+ end
102
+ if retval == LOTS::PLAYER_DEAD
103
+ player.dead = 1
104
+ end
105
+ end
106
+ else
107
+ ui.not_in_combat
108
+ end
109
+ when "player", "me", "info", "status", "i"
110
+ ui.player_info({:player => player})
111
+ when "enemy"
112
+ if player.in_combat
113
+ ui.enemy_info({:player => player})
114
+ else
115
+ ui.not_in_combat
116
+ end
117
+ when "lines", "score"
118
+ ui.lines({:player => player})
119
+ when "suicide"
120
+ player.dead = 1
121
+ when "help", "h", "?"
122
+ ui.help
123
+ when "quit", "exit"
124
+ ui.quit
125
+ running = nil
126
+ else
127
+ ui.not_found
128
+ end
129
+ # Is player in combat but has no enemy? Assign one.
130
+ if player.in_combat && !player.current_enemy
131
+ enemy = LOTS::Enemy.new
132
+ player.current_enemy = enemy
133
+ ui.enemy_greet({:enemy => enemy})
134
+ end
135
+ # Player is dead!
136
+ if player.dead == 1
137
+ ui.player_dead({:story => story})
138
+ exit
139
+ end
140
+ # If player has reached Sourcerer
141
+ if player.x == LOTS::MAP_WIDTH && player.y == 1
142
+ ui.draw_frame({:text => story.ending})
143
+ ui.new_line
144
+ running = false
145
+ end
146
+ end
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Legend of the Sourcerer
4
+ # Written by Robert W. Oliver II <robert@cidergrove.com>
5
+ # Copyright (C) 2018 Sourcerer, All Rights Reserved.
6
+ # Licensed under GPLv3.
7
+ #
8
+ # Story Class
9
+ #
10
+
11
+ module LOTS
12
+
13
+ STORY_INTRO = [
14
+ "Your journey to discover your true potential has been arduous, but a glimmer of hope shines in the darkness.",
15
+ "A vivid dream stirrs you from your sleep. You are instructed to visit the " + "Sourcerer".light_white + ", the Oracle of the Path.",
16
+ "You feel certain he will provide the insight you need. Inspired, you carry on.",
17
+ "",
18
+ "At the end of the day's travel, you set up camp and find an old " + "map".light_white + " at the base of a tree.",
19
+ "You gaze at the ancient parchment, studying the path ahead."
20
+ ]
21
+
22
+ STORY_AREA_TREE = [
23
+ "You see a magnificent tree standing tall above you."
24
+ ]
25
+
26
+ STORY_AREA_WATER = [
27
+ "You stand on the banks of a crystal-clear lake."
28
+ ]
29
+
30
+ STORY_AREA_MOUNTAIN = [
31
+ "A majestic snow-topped mountain range graces the horizon."
32
+ ]
33
+
34
+ STORY_AREA_ENEMY = [
35
+ "You encounter an enemy!"
36
+ ]
37
+
38
+ STORY_PLAYER_DEAD = [
39
+ "You have died.",
40
+ "",
41
+ "You failed to reach the Sourcerer. Please try again.",
42
+ ]
43
+
44
+ STORY_END = [
45
+ "You've reached the Sourcerer!".light_white,
46
+ "",
47
+ "He stares deeply into your eyes. His knowledable, seeking gaze inspires you to recall",
48
+ "the long journey you have endured. You recall your battles with vicious enemies and are",
49
+ "proud of the many lines of code you have earned.",
50
+ "",
51
+ "The Sourcerer speaks:",
52
+ "",
53
+ "To be a better programmer, you must learn from your journey. By taking careful note".light_yellow,
54
+ "of your successes and analyizing your performance, you can find the information you".light_yellow,
55
+ "seek to better yourself.".light_yellow,
56
+ "",
57
+ "THANK YOU FOR PLAYING!".light_red,
58
+ "",
59
+ ]
60
+
61
+ class Story
62
+
63
+ def intro
64
+ return STORY_INTRO
65
+ end
66
+
67
+ def ending
68
+ return STORY_END
69
+ end
70
+
71
+ def area_tree
72
+ return STORY_AREA_TREE
73
+ end
74
+
75
+ def area_water
76
+ return STORY_AREA_WATER
77
+ end
78
+
79
+ def area_mountain
80
+ return STORY_AREA_MOUNTAIN
81
+ end
82
+
83
+ def area_enemy
84
+ return STORY_AREA_ENEMY
85
+ end
86
+
87
+ def player_dead
88
+ return STORY_PLAYER_DEAD
89
+ end
90
+
91
+ end
92
+
93
+ end
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Legend of the Sourcerer
4
+ # Written by Robert W. Oliver II <robert@cidergrove.com>
5
+ # Copyright (C) 2018 Sourcerer, All Rights Reserved.
6
+ # Licensed under GPLv3.
7
+ #
8
+ # UI Class
9
+ #
10
+
11
+ module LOTS
12
+
13
+ UI_FRAME_HORIZONTAL = "\u2501"
14
+ UI_FRAME_VERTICAL = "\u2503"
15
+ UI_FRAME_UPPER_LEFT = "\u250F"
16
+ UI_FRAME_LOWER_LEFT = "\u2517"
17
+ UI_FRAME_UPPER_RIGHT = "\u2513"
18
+ UI_FRAME_LOWER_RIGHT = "\u251B"
19
+
20
+ UI_COPYRIGHT = "\u00A9"
21
+ UI_EMAIL = "\u2709"
22
+ UI_ARROW = "\u2712"
23
+
24
+ class UI
25
+
26
+ # Clear the screen
27
+ def clear
28
+ print "\e[H\e[2J"
29
+ end
30
+
31
+ def display_map(args)
32
+ map = args[:map]
33
+ new_line
34
+ draw_frame({:text => map})
35
+ new_line
36
+ end
37
+
38
+ def help
39
+ new_line
40
+ print "Valid Commands".light_green
41
+ new_line(2)
42
+ print UI_ARROW.light_yellow + " " + "east, e, right, ".light_white + "or " + "r".light_white + " - Move east (right)"
43
+ new_line
44
+ print UI_ARROW.light_yellow + " " + "south, s, down, ".light_white + "or " + "d".light_white + " - Move south (down)"
45
+ new_line
46
+ print UI_ARROW.light_yellow + " " + "west, w, left, ".light_white + "or " + "l".light_white + " - Move west (left)"
47
+ new_line
48
+ print UI_ARROW.light_yellow + " " + "north, n, up, ".light_white + "or " + "u".light_white + " - Move north (up)"
49
+ new_line
50
+ print UI_ARROW.light_yellow + " " + "map".light_white + " - Display map"
51
+ new_line
52
+ print UI_ARROW.light_yellow + " " + "where".light_white + " - Describe current surroundings"
53
+ new_line
54
+ print UI_ARROW.light_yellow + " " + "attack".light_white + " - Attack (only in combat)"
55
+ new_line
56
+ print UI_ARROW.light_yellow + " " + "enemy".light_white + " - Display information about your enemy"
57
+ new_line
58
+ print UI_ARROW.light_yellow + " " + "lines, score, status, info".light_white + " - Display lines of code (score)"
59
+ new_line
60
+ print UI_ARROW.light_yellow + " " + "clear, cls".light_white + " - Clears the screen"
61
+ new_line
62
+ print UI_ARROW.light_yellow + " " + "quit, exit".light_white + " - Quits the game"
63
+ new_line
64
+ end
65
+
66
+ def lines(args)
67
+ player = args[:player]
68
+ print "You currently have " + player.lines.to_s.light_white + " lines of code."
69
+ new_line
70
+ end
71
+
72
+ def enemy_info(args)
73
+ player = args[:player]
74
+ enemy = player.current_enemy
75
+ print enemy.name.light_red + " has " + enemy.str.to_s.light_white + " strength and " + enemy.health.to_s.light_white + " health."
76
+ new_line
77
+ end
78
+
79
+ def player_info(args)
80
+ player = args[:player]
81
+ print "You have " + player.health.to_s.light_white + " health and have " + player.lines.to_s.light_white + " lines of code."
82
+ new_line
83
+ end
84
+
85
+ # Ask user a question. A regular expression filter can be applied.
86
+ def ask(question, filter = nil)
87
+ if filter
88
+ match = false
89
+ answer = nil
90
+ while match == false
91
+ print UI_ARROW.red + question.light_white + " "
92
+ answer = gets.chomp
93
+ if answer.match(filter)
94
+ return answer
95
+ else
96
+ print "Sorry, please try again.".red
97
+ new_line
98
+ new_line
99
+ end
100
+ end
101
+ else
102
+ print "\u2712 ".red + question.light_white + " "
103
+ return gets.chomp
104
+ end
105
+ end
106
+
107
+ # Display welcome
108
+ def welcome
109
+ text = Array.new
110
+ text << "Legend of the Sourcerer".light_green
111
+ text << "Written by Robert W. Oliver II ".white + UI_EMAIL.light_white + " robert@cidergrove.com".white
112
+ text << "Copyright " + UI_COPYRIGHT + " Sourcerer, All Rights Reserved.".white
113
+ text << "Licensed under GPLv3.".white
114
+ draw_frame({:text => text})
115
+ new_line
116
+ end
117
+
118
+ # Prints a new line. Optinally can print multiple lines.
119
+ def new_line(times = 1)
120
+ times.times do
121
+ print "\n"
122
+ end
123
+ end
124
+
125
+ # Draw text surrounded in a nice frame
126
+ def draw_frame(args)
127
+ # Figure out width automatically
128
+ text = args[:text]
129
+ width = get_max_size_from_array(text)
130
+ draw_top_frame(width)
131
+ text.each do |t|
132
+ t_size = get_real_size(t)
133
+ draw_vert_frame_begin
134
+ if t.kind_of?(Array)
135
+ t.each do |s|
136
+ print s
137
+ end
138
+ else
139
+ print t
140
+ end
141
+ (width - (t_size + 4)).times do
142
+ print " "
143
+ end
144
+ draw_vert_frame_end
145
+ new_line
146
+ end
147
+ draw_bottom_frame(width)
148
+ end
149
+
150
+ def display_version
151
+ puts "This is " + "Legend of the Sourcerer".light_red + " Version " + LOTS_VERSION.light_white
152
+ new_line
153
+ end
154
+
155
+ def not_found
156
+ print "Command not understood. Please try again.".red
157
+ new_line
158
+ end
159
+
160
+ def show_location(args)
161
+ player = args[:player]
162
+ print "You are currently on row " + player.y.to_s.light_white + ", column " + player.x.to_s.light_white
163
+ new_line
164
+ print "Use the " + "map".light_white + " command to see the map."
165
+ new_line
166
+ end
167
+
168
+ def cannot_travel_combat
169
+ puts "You are in combat and cannot travel!"
170
+ end
171
+
172
+ def not_in_combat
173
+ puts "You are not in combat."
174
+ end
175
+
176
+ def quit
177
+ new_line
178
+ print "You abandoned your journey.".red
179
+ new_line(2)
180
+ end
181
+
182
+ def get_cmd
183
+ print "Type ".white + "help".light_white + " for possible commands.\n"
184
+ print "\u2712 ".red + "Your command? ".light_white
185
+ return gets.chomp.downcase
186
+ end
187
+
188
+ def out_of_bounds
189
+ print "x".red + " Requested move out of bounds."
190
+ new_line
191
+ end
192
+
193
+ def display_name(args)
194
+ player = args[:player]
195
+ print "You are " + player.name.light_white + ". Have you forgotten your own name?"
196
+ new_line
197
+ end
198
+
199
+ def player_dead(args)
200
+ story = args[:story]
201
+ new_line
202
+ text = story.player_dead
203
+ draw_frame(:text => text)
204
+ new_line
205
+ end
206
+
207
+ def enemy_greet(args)
208
+ enemy = args[:enemy]
209
+ print enemy.name.light_white + " attacks!"
210
+ new_line
211
+ end
212
+
213
+ private
214
+
215
+ def draw_vert_frame_begin
216
+ print UI_FRAME_VERTICAL.yellow + " "
217
+ end
218
+
219
+ def draw_vert_frame_end
220
+ print " " + UI_FRAME_VERTICAL.yellow
221
+ end
222
+
223
+ def draw_top_frame(width)
224
+ print UI_FRAME_UPPER_LEFT.yellow
225
+ (width - 2).times do
226
+ print UI_FRAME_HORIZONTAL.yellow
227
+ end
228
+ print UI_FRAME_UPPER_RIGHT.yellow
229
+ new_line
230
+ end
231
+
232
+ def draw_bottom_frame(width)
233
+ print UI_FRAME_LOWER_LEFT.yellow
234
+ (width - 2).times do
235
+ print UI_FRAME_HORIZONTAL.yellow
236
+ end
237
+ print UI_FRAME_LOWER_RIGHT.yellow
238
+ new_line
239
+ end
240
+
241
+ # Returns actual length of text accounting for UTF-8 and ANSI
242
+ def get_real_size(text)
243
+ if text.kind_of?(Array)
244
+ text.size
245
+ else
246
+ text.uncolorize.size
247
+ end
248
+ end
249
+
250
+ # Returns size of longest string in array
251
+ def get_max_size_from_array(array)
252
+ max = 0
253
+ array.each do |s|
254
+ s_size = get_real_size(s)
255
+ max = s_size if s_size >= max
256
+ end
257
+ max + 4
258
+ end
259
+
260
+ end
261
+
262
+ end
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Legend of the Sourcerer
4
+ # Written by Robert W. Oliver II <robert@cidergrove.com>
5
+ # Copyright (C) 2018 Sourcerer, All Rights Reserved.
6
+ # Licensed under GPLv3.
7
+
8
+ module LOTS
9
+
10
+ MAP_WIDTH = 64
11
+ MAP_HEIGHT = 14
12
+
13
+ MAP_KEY_TREE = "\u2663"
14
+ MAP_KEY_WATER = "\u2248"
15
+ MAP_KEY_GRASS = "\u2588"
16
+ MAP_KEY_MOUNTAIN = "\u25B2"
17
+ MAP_KEY_ENEMY = "\u263A"
18
+ MAP_KEY_SOURCERER = "\u263B"
19
+ MAP_KEY_PLAYER = "\u1330"
20
+
21
+ # Weighted
22
+ MAP_POSSIBLE_KEYS = [
23
+ MAP_KEY_TREE,
24
+ MAP_KEY_TREE,
25
+ MAP_KEY_TREE,
26
+ MAP_KEY_TREE,
27
+ MAP_KEY_WATER,
28
+ MAP_KEY_GRASS,
29
+ MAP_KEY_MOUNTAIN,
30
+ MAP_KEY_ENEMY,
31
+ MAP_KEY_ENEMY
32
+ ]
33
+
34
+ # Make grass more common
35
+ 32.times.each do
36
+ MAP_POSSIBLE_KEYS << MAP_KEY_GRASS
37
+ end
38
+
39
+ MAP_SOURCERER_X = MAP_WIDTH
40
+ MAP_SOURCERER_Y = 1
41
+
42
+ class World
43
+
44
+ attr_reader :the_map
45
+
46
+ def initialize
47
+ # Set initial world map
48
+ generate_map
49
+ end
50
+
51
+ def get_width
52
+ MAP_WIDTH
53
+ end
54
+
55
+ def get_height
56
+ MAP_HEIGHT
57
+ end
58
+
59
+ # Return map data in a display format
60
+ def get_map(args)
61
+ player = args[:player]
62
+ buffer = Array.new
63
+ x = 1
64
+ y = 1
65
+ @the_map.each do |row|
66
+ tmp_row = Array.new
67
+ x = 1
68
+ row.each do |col|
69
+ placed = 0
70
+ # Place sourcerer
71
+ if x == MAP_SOURCERER_X and y == MAP_SOURCERER_Y
72
+ tmp_row << MAP_KEY_SOURCERER.colorize(:color => :white, :background => :red)
73
+ placed = 1
74
+ end
75
+ # If player is here, display them
76
+ if x == player.x and y == player.y
77
+ tmp_row << MAP_KEY_PLAYER.colorize(:color => :red, :background => :white)
78
+ placed = 1
79
+ end
80
+ # If we haven't already placed the character, run through the rest of the options
81
+ if placed == 0
82
+ case col
83
+ when MAP_KEY_TREE
84
+ tmp_row << col.colorize(:color => :light_green, :background => :green)
85
+ when MAP_KEY_GRASS
86
+ tmp_row << col.colorize(:color => :green, :background => :green)
87
+ when MAP_KEY_WATER
88
+ tmp_row << col.colorize(:color => :white, :background => :blue)
89
+ when MAP_KEY_MOUNTAIN
90
+ tmp_row << col.colorize(:color => :yellow, :background => :green)
91
+ when MAP_KEY_ENEMY
92
+ tmp_row << col.colorize(:color => :red, :background => :green)
93
+ end
94
+ end
95
+ x += 1
96
+ end
97
+ buffer << tmp_row
98
+ y += 1
99
+ end
100
+
101
+ return buffer
102
+ end
103
+
104
+ # Check the current area on the map and describe it
105
+ def check_area(args)
106
+ player = args[:player]
107
+ ui = args[:ui]
108
+ story = args[:story]
109
+ x = player.x
110
+ y = player.y
111
+ current_area = @the_map[y-1][x-1]
112
+ case current_area
113
+ when MAP_KEY_TREE
114
+ ui.draw_frame({:text => story.area_tree})
115
+ when MAP_KEY_WATER
116
+ ui.draw_frame({:text => story.area_water})
117
+ when MAP_KEY_MOUNTAIN
118
+ ui.draw_frame({:text => story.area_mountain})
119
+ when MAP_KEY_ENEMY
120
+ ui.draw_frame({:text => story.area_enemy})
121
+ return false
122
+ end
123
+ return true
124
+ end
125
+
126
+ private
127
+
128
+ def new_line
129
+ print "\n"
130
+ end
131
+
132
+ # Create a random world map
133
+ def generate_map
134
+ tmp_map = Array.new
135
+
136
+ # Step through MAX_HEIGHT times
137
+ MAP_HEIGHT.times do
138
+ tmp_row = Array.new
139
+ MAP_WIDTH.times do
140
+ tmp_row << MAP_POSSIBLE_KEYS.sample
141
+ end
142
+
143
+ # Add our assembled row to the map
144
+ tmp_map << tmp_row
145
+ tmp_row = nil
146
+ end
147
+ @the_map = tmp_map
148
+
149
+ end
150
+
151
+ end
152
+ end
data/lots.rb ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Legend of the Sourcerer
4
+ # Written by Robert W. Oliver II <robert@cidergrove.com>
5
+ # Copyright (C) 2018 Sourcerer, All Rights Reserved.
6
+ # Licensed under GPLv3.
7
+
8
+ LOTS_VERSION = "1.00"
9
+
10
+ begin
11
+ require 'colorize'
12
+ rescue LoadError
13
+ puts
14
+ puts "Legend of the Sourcerer requires the 'colorize' gem to run."
15
+ puts
16
+ puts "Installation Instructions"
17
+ puts "-------------------------"
18
+ puts
19
+ puts "Debian/Ubuntu Linux:"
20
+ puts " sudo apt install ruby-colorize"
21
+ puts
22
+ puts "Other Linux Distros:"
23
+ puts " gem install colorize"
24
+ puts
25
+ puts "Windows:"
26
+ puts " gem install colorize"
27
+ puts
28
+ puts "macOS:"
29
+ puts " gem install colorize"
30
+ puts
31
+ puts
32
+ exit
33
+ end
34
+
35
+ # Require libraries
36
+ load "lib/ui.rb"
37
+ load "lib/world.rb"
38
+ load "lib/character.rb"
39
+ load "lib/story.rb"
40
+ load "lib/enemy.rb"
41
+
42
+ # Start
43
+ load "lib/main.rb"
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lots
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Robert W. Oliver II
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email: robert@cidergrove.com
29
+ executables:
30
+ - lots
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - bin/lots
35
+ - lib/character.rb
36
+ - lib/enemy.rb
37
+ - lib/main.rb
38
+ - lib/story.rb
39
+ - lib/ui.rb
40
+ - lib/world.rb
41
+ - lots.rb
42
+ homepage: https://github.com/rwoliver2/lots
43
+ licenses:
44
+ - GPL-3.0
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
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
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.5.2.1
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Legend of the Sourcerer is an open-source text-based adventure game written
66
+ in Ruby.
67
+ test_files: []