mission_game 1.1.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.
- checksums.yaml +7 -0
- data/bin/mission_game +4 -0
- data/lib/enemy.rb +69 -0
- data/lib/main.rb +142 -0
- data/lib/neworleans.rb +149 -0
- data/lib/player.rb +121 -0
- data/lib/story.rb +85 -0
- data/lib/ui.rb +259 -0
- data/mission_game.rb +43 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d57529ce9115a3acd92942159df8ccca05d7bd534d6054f28c35fb66f2df873f
|
4
|
+
data.tar.gz: a768a71daa75d1869d1a0d1f47c8dcc4c85e99cc6857a2a1c5b4b229451b3b54
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7097ef7f3fcba5a253e77d6a4e9f589b3422f570dced7f537c91f206df32278cc1120bc806094d9299a68bc227ccadf9990aaa8afb9913103bd879ed1d27ff31
|
7
|
+
data.tar.gz: 42cd40c3cae6b11292d368d8a13bea2d897d148dc0b65420783e69a547fc99f2cc3791bd4717841790060d713ad9f941b605bbd0de97d18ac671afc7988489d9
|
data/bin/mission_game
ADDED
data/lib/enemy.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Written by Webster Avosa
|
4
|
+
#
|
5
|
+
|
6
|
+
module MISSIONGAME
|
7
|
+
|
8
|
+
ENEMY_CATALOG = [
|
9
|
+
[:name => "Lucien Castle", :lives => 3, :bonus => 0, :str => 3, :points => 1],
|
10
|
+
[:name => "Klaus Mikaelson", :lives => 8, :bonus => 8, :str => 4, :points => 10],
|
11
|
+
[:name => "Damon Salvatore", :lives => 5, :bonus => 0, :str => 4, :points => 7],
|
12
|
+
[:name => "Mikael", :lives => 3, :bonus => 2, :str => 4, :points => 6],
|
13
|
+
[:name => "Taylor Lockwood", :lives => 4, :bonus => 0, :str => 4, :points => 2],
|
14
|
+
[:name => "Marcel Gerard", :lives => 7, :bonus => 3, :str => 5, :points => 5],
|
15
|
+
[:name => "Dahlia", :lives => 2, :bonus => 6, :str => 1, :points => 2],
|
16
|
+
[:name => "The Hollow", :lives => 5, :bonus => 0, :str => 4, :points => 3],
|
17
|
+
[:name => "Celeste Dubois", :lives => 3, :bonus => 10, :str => 2, :points => 5]
|
18
|
+
]
|
19
|
+
|
20
|
+
PLAYER_DEAD = "PLAYER_DEAD"
|
21
|
+
|
22
|
+
class Enemy
|
23
|
+
|
24
|
+
attr_accessor :name
|
25
|
+
attr_accessor :lives
|
26
|
+
attr_accessor :bonus
|
27
|
+
attr_accessor :str
|
28
|
+
attr_accessor :int
|
29
|
+
attr_accessor :points
|
30
|
+
|
31
|
+
def initialize(args = nil)
|
32
|
+
# Pick a random enemy
|
33
|
+
selected_enemy = ENEMY_CATALOG.sample[0]
|
34
|
+
@name = selected_enemy[:name]
|
35
|
+
@lives = selected_enemy[:lives] + rand(0..3)
|
36
|
+
@bonus = selected_enemy[:bonus] + rand(0..3)
|
37
|
+
@str = selected_enemy[:str]
|
38
|
+
@points = selected_enemy[:points]
|
39
|
+
@int = rand(2..6)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Enemy attacks player
|
43
|
+
def attack(args)
|
44
|
+
enemy = self
|
45
|
+
player = args[:player]
|
46
|
+
|
47
|
+
# Does the enemy even hit the player?
|
48
|
+
str_diff = (enemy.str - player.str) * 2
|
49
|
+
hit_chance = rand(1...100) + str_diff
|
50
|
+
|
51
|
+
if (hit_chance > 30)
|
52
|
+
# Determine value of the attack
|
53
|
+
attack_value = rand(1...player.str)
|
54
|
+
print enemy.name.light_red + " hits you for " + attack_value.to_s.light_yellow + " damage(s)!\n"
|
55
|
+
if attack_value > player.lives
|
56
|
+
return PLAYER_DEAD
|
57
|
+
else
|
58
|
+
return attack_value
|
59
|
+
end
|
60
|
+
else
|
61
|
+
print enemy.name.light_red + " sees you as an easy prey!\n"
|
62
|
+
end
|
63
|
+
return true
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/lib/main.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Written by Webster AVosa
|
4
|
+
|
5
|
+
MISSIONGAME_VERSION = "1.00"
|
6
|
+
|
7
|
+
# Create a new UI and New Orleans
|
8
|
+
ui = MISSIONGAME::UI.new
|
9
|
+
neworleans = MISSIONGAME::NewOrleans.new
|
10
|
+
|
11
|
+
# Clear the screen and print welcome message
|
12
|
+
ui.clear
|
13
|
+
ui.welcome
|
14
|
+
|
15
|
+
# Ask name
|
16
|
+
name = ui.ask("What is your name?", /\w/)
|
17
|
+
|
18
|
+
# Create a new player
|
19
|
+
player = MISSIONGAME::Player.new({:name => name, :neworleans => neworleans})
|
20
|
+
|
21
|
+
# Show intro story
|
22
|
+
ui.new_line
|
23
|
+
story = MISSIONGAME::Story.new
|
24
|
+
ui.draw_frame({:text => story.intro})
|
25
|
+
|
26
|
+
|
27
|
+
# MAIN INPUT LOOP
|
28
|
+
running = 1
|
29
|
+
while running
|
30
|
+
ui.new_line
|
31
|
+
# Get command from user
|
32
|
+
cmd = ui.get_cmd
|
33
|
+
case cmd
|
34
|
+
when "~"
|
35
|
+
binding.pry
|
36
|
+
when "map", "m"
|
37
|
+
map = neworleans.get_map({:player => player})
|
38
|
+
ui.draw_frame({:text => map})
|
39
|
+
when "version", "ver"
|
40
|
+
ui.display_version
|
41
|
+
when "clear", "cls"
|
42
|
+
ui.clear
|
43
|
+
when "name", "whoami"
|
44
|
+
ui.display_name({:player => player})
|
45
|
+
when "location", "loc", "where", "whereami"
|
46
|
+
ui.show_location({:player => player})
|
47
|
+
when "look", "what", "around"
|
48
|
+
neworleans.check_area({:player => player, :ui => ui, :story => story})
|
49
|
+
when "forward", "f"
|
50
|
+
unless player.in_combat
|
51
|
+
if !player.move({:direction => :up, :neworleans => neworleans, :ui => ui, :story => story})
|
52
|
+
player.in_combat = 1
|
53
|
+
end
|
54
|
+
else
|
55
|
+
ui.cannot_travel_combat
|
56
|
+
end
|
57
|
+
when "backward", "b"
|
58
|
+
unless player.in_combat
|
59
|
+
if !player.move({:direction => :down, :neworleans => neworleans, :ui => ui, :story => story})
|
60
|
+
player.in_combat = 1
|
61
|
+
end
|
62
|
+
else
|
63
|
+
ui.cannot_travel_combat
|
64
|
+
end
|
65
|
+
when "left", "l"
|
66
|
+
unless player.in_combat
|
67
|
+
if !player.move({:direction => :left, :neworleans => neworleans, :ui => ui, :story => story})
|
68
|
+
player.in_combat = 1
|
69
|
+
end
|
70
|
+
else
|
71
|
+
ui.cannot_travel_combat
|
72
|
+
end
|
73
|
+
when "right", "r"
|
74
|
+
unless player.in_combat
|
75
|
+
if !player.move({:direction => :right, :neworleans => neworleans, :ui => ui, :story => story})
|
76
|
+
player.in_combat = 1
|
77
|
+
end
|
78
|
+
else
|
79
|
+
ui.cannot_travel_combat
|
80
|
+
end
|
81
|
+
when "attack", "a"
|
82
|
+
if player.in_combat
|
83
|
+
retval = player.attack({:enemy => player.current_enemy, :ui => ui})
|
84
|
+
if retval == MISSIONGAME::ENEMY_KILLED
|
85
|
+
player.points += player.current_enemy.points
|
86
|
+
# Remove enemy from map
|
87
|
+
neworleans.the_map[player.y-1][player.x-1] = MISSIONGAME::MAP_KEY_GRASS
|
88
|
+
# Take player out of combat
|
89
|
+
player.current_enemy = nil
|
90
|
+
player.in_combat = false
|
91
|
+
end
|
92
|
+
if retval.is_a? Numeric
|
93
|
+
player.current_enemy.lives -= retval
|
94
|
+
retval = player.current_enemy.attack({:player => player})
|
95
|
+
if retval.is_a? Numeric
|
96
|
+
player.lives -= retval
|
97
|
+
end
|
98
|
+
if retval == MISSIONGAME::PLAYER_DEAD
|
99
|
+
player.dead = 1
|
100
|
+
end
|
101
|
+
end
|
102
|
+
else
|
103
|
+
ui.not_in_combat
|
104
|
+
end
|
105
|
+
when "player", "me", "info", "status", "i"
|
106
|
+
ui.player_info({:player => player})
|
107
|
+
when "enemy"
|
108
|
+
if player.in_combat
|
109
|
+
ui.enemy_info({:player => player})
|
110
|
+
else
|
111
|
+
ui.not_in_combat
|
112
|
+
end
|
113
|
+
when "points", "score"
|
114
|
+
ui.points({:player => player})
|
115
|
+
when "suicide"
|
116
|
+
player.dead = 1
|
117
|
+
when "help", "h", "?"
|
118
|
+
ui.help
|
119
|
+
when "quit", "q", "exit"
|
120
|
+
ui.quit
|
121
|
+
running = nil
|
122
|
+
else
|
123
|
+
ui.not_found
|
124
|
+
end
|
125
|
+
# Is player in combat but has no enemy? Assign one.
|
126
|
+
if player.in_combat && !player.current_enemy
|
127
|
+
enemy = MISSIONGAME::Enemy.new
|
128
|
+
player.current_enemy = enemy
|
129
|
+
ui.enemy_greet({:enemy => enemy})
|
130
|
+
end
|
131
|
+
# Player is dead!
|
132
|
+
if player.dead == 1
|
133
|
+
ui.player_dead({:story => story})
|
134
|
+
exit
|
135
|
+
end
|
136
|
+
# If player has reached the Witch
|
137
|
+
if player.x == MISSIONGAME::MAP_WIDTH && player.y == 1
|
138
|
+
ui.draw_frame({:text => story.ending})
|
139
|
+
ui.new_line
|
140
|
+
running = false
|
141
|
+
end
|
142
|
+
end
|
data/lib/neworleans.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Written by Webster Avosa
|
4
|
+
|
5
|
+
module MISSIONGAME
|
6
|
+
|
7
|
+
MAP_WIDTH = 64
|
8
|
+
MAP_HEIGHT = 14
|
9
|
+
|
10
|
+
MAP_KEY_TREE = "\u2663"
|
11
|
+
MAP_KEY_WATER = "\u2248"
|
12
|
+
MAP_KEY_GRASS = "\u2588"
|
13
|
+
MAP_KEY_MOUNTAIN = "\u25B2"
|
14
|
+
MAP_KEY_ENEMY = "\u263A"
|
15
|
+
MAP_KEY_WITCH = "\u263B"
|
16
|
+
MAP_KEY_PLAYER = "\u1330"
|
17
|
+
|
18
|
+
# Weighted
|
19
|
+
MAP_POSSIBLE_KEYS = [
|
20
|
+
MAP_KEY_TREE,
|
21
|
+
MAP_KEY_TREE,
|
22
|
+
MAP_KEY_TREE,
|
23
|
+
MAP_KEY_TREE,
|
24
|
+
MAP_KEY_WATER,
|
25
|
+
MAP_KEY_GRASS,
|
26
|
+
MAP_KEY_MOUNTAIN,
|
27
|
+
MAP_KEY_ENEMY,
|
28
|
+
MAP_KEY_ENEMY
|
29
|
+
]
|
30
|
+
|
31
|
+
# Make grass more common
|
32
|
+
32.times.each do
|
33
|
+
MAP_POSSIBLE_KEYS << MAP_KEY_GRASS
|
34
|
+
end
|
35
|
+
|
36
|
+
MAP_WITCH_X = MAP_WIDTH
|
37
|
+
MAP_WITCH_Y = 1
|
38
|
+
|
39
|
+
class NewOrleans
|
40
|
+
|
41
|
+
attr_reader :the_map
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
# Set initial New Orleans map
|
45
|
+
generate_map
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_width
|
49
|
+
MAP_WIDTH
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_height
|
53
|
+
MAP_HEIGHT
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return map data in a display format
|
57
|
+
def get_map(args)
|
58
|
+
player = args[:player]
|
59
|
+
buffer = Array.new
|
60
|
+
x = 1
|
61
|
+
y = 1
|
62
|
+
@the_map.each do |row|
|
63
|
+
tmp_row = Array.new
|
64
|
+
x = 1
|
65
|
+
row.each do |col|
|
66
|
+
placed = 0
|
67
|
+
# Place WITCH
|
68
|
+
if x == MAP_WITCH_X and y == MAP_WITCH_Y
|
69
|
+
tmp_row << MAP_KEY_WITCH.colorize(:color => :white, :background => :red)
|
70
|
+
placed = 1
|
71
|
+
end
|
72
|
+
# If player is here, display them
|
73
|
+
if x == player.x and y == player.y
|
74
|
+
tmp_row << MAP_KEY_PLAYER.colorize(:color => :red, :background => :white)
|
75
|
+
placed = 1
|
76
|
+
end
|
77
|
+
# If we haven't already placed the Player, run through the rest of the options
|
78
|
+
if placed == 0
|
79
|
+
case col
|
80
|
+
when MAP_KEY_TREE
|
81
|
+
tmp_row << col.colorize(:color => :light_green, :background => :green)
|
82
|
+
when MAP_KEY_GRASS
|
83
|
+
tmp_row << col.colorize(:color => :green, :background => :green)
|
84
|
+
when MAP_KEY_WATER
|
85
|
+
tmp_row << col.colorize(:color => :white, :background => :blue)
|
86
|
+
when MAP_KEY_MOUNTAIN
|
87
|
+
tmp_row << col.colorize(:color => :yellow, :background => :green)
|
88
|
+
when MAP_KEY_ENEMY
|
89
|
+
tmp_row << col.colorize(:color => :red, :background => :green)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
x += 1
|
93
|
+
end
|
94
|
+
buffer << tmp_row
|
95
|
+
y += 1
|
96
|
+
end
|
97
|
+
|
98
|
+
return buffer
|
99
|
+
end
|
100
|
+
|
101
|
+
# Check the current area on the map and describe it
|
102
|
+
def check_area(args)
|
103
|
+
player = args[:player]
|
104
|
+
ui = args[:ui]
|
105
|
+
story = args[:story]
|
106
|
+
x = player.x
|
107
|
+
y = player.y
|
108
|
+
current_area = @the_map[y-1][x-1]
|
109
|
+
case current_area
|
110
|
+
when MAP_KEY_TREE
|
111
|
+
ui.draw_frame({:text => story.area_tree})
|
112
|
+
when MAP_KEY_WATER
|
113
|
+
ui.draw_frame({:text => story.area_water})
|
114
|
+
when MAP_KEY_MOUNTAIN
|
115
|
+
ui.draw_frame({:text => story.area_mountain})
|
116
|
+
when MAP_KEY_ENEMY
|
117
|
+
ui.draw_frame({:text => story.area_enemy})
|
118
|
+
return false
|
119
|
+
end
|
120
|
+
return true
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def new_line
|
126
|
+
print "\n"
|
127
|
+
end
|
128
|
+
|
129
|
+
# Create a random new orleans map
|
130
|
+
def generate_map
|
131
|
+
tmp_map = Array.new
|
132
|
+
|
133
|
+
# Step through MAX_HEIGHT times
|
134
|
+
MAP_HEIGHT.times do
|
135
|
+
tmp_row = Array.new
|
136
|
+
MAP_WIDTH.times do
|
137
|
+
tmp_row << MAP_POSSIBLE_KEYS.sample
|
138
|
+
end
|
139
|
+
|
140
|
+
# Add our assembled row to the map
|
141
|
+
tmp_map << tmp_row
|
142
|
+
tmp_row = nil
|
143
|
+
end
|
144
|
+
@the_map = tmp_map
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
data/lib/player.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Written by Webster Avosa
|
4
|
+
|
5
|
+
module MISSIONGAME
|
6
|
+
|
7
|
+
ENEMY_KILLED = "KILLED"
|
8
|
+
|
9
|
+
HIT_CHANCE_MODIFIER = 5
|
10
|
+
ATTACK_VALUE_MODIFIER = 1
|
11
|
+
|
12
|
+
class Player
|
13
|
+
|
14
|
+
attr_accessor :name
|
15
|
+
attr_accessor :lives
|
16
|
+
attr_accessor :bonus
|
17
|
+
attr_accessor :x
|
18
|
+
attr_accessor :y
|
19
|
+
attr_accessor :level
|
20
|
+
attr_accessor :str
|
21
|
+
attr_accessor :int
|
22
|
+
attr_accessor :in_combat
|
23
|
+
attr_accessor :current_enemy
|
24
|
+
attr_accessor :points
|
25
|
+
attr_accessor :dead
|
26
|
+
|
27
|
+
def initialize (args)
|
28
|
+
name = args[:name]
|
29
|
+
neworleans = args[:neworleans]
|
30
|
+
@name = name
|
31
|
+
@level = 1
|
32
|
+
@lives = 100
|
33
|
+
@bonus = 100
|
34
|
+
@str = 5
|
35
|
+
@int = 5
|
36
|
+
@x = 1
|
37
|
+
@y = neworleans.get_height
|
38
|
+
@in_combat = false
|
39
|
+
@current_enemy = nil
|
40
|
+
@points = 0
|
41
|
+
@dead = 0
|
42
|
+
return "Welcome %{name}! Let's play!"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Player attacks enemy
|
46
|
+
def attack(args)
|
47
|
+
player = self
|
48
|
+
enemy = args[:enemy]
|
49
|
+
ui = args[:ui]
|
50
|
+
|
51
|
+
# Does the player even hit the enemy?
|
52
|
+
# We could use a hit chance stat here, but since we don't have one,
|
53
|
+
# we'll just base it off the player/enemy stength discrepency.
|
54
|
+
ui.enemy_info({:player => player})
|
55
|
+
ui.player_info({:player => player})
|
56
|
+
str_diff = (player.str - enemy.str) * 2
|
57
|
+
hit_chance = rand(1...100) + str_diff + HIT_CHANCE_MODIFIER
|
58
|
+
|
59
|
+
if (hit_chance > 50)
|
60
|
+
# Determine value of the attack
|
61
|
+
attack_value = rand(1...player.str) + ATTACK_VALUE_MODIFIER
|
62
|
+
if attack_value > enemy.lives
|
63
|
+
print "You fought for your life and " + "hit".light_yellow + " " + enemy.name.light_red + " for " + attack_value.to_s.light_white + " damages, killing him!\n"
|
64
|
+
print "You gain " + enemy.points.to_s.light_white + " points.\n"
|
65
|
+
return ENEMY_KILLED
|
66
|
+
else
|
67
|
+
print "You fought for your life and " + "hit".light_yellow + " " + enemy.name.light_red + " for " + attack_value.to_s.light_white + " damages, killing him!\n"
|
68
|
+
return attack_value
|
69
|
+
end
|
70
|
+
else
|
71
|
+
print "You fought for your life and " + "missed".light_red + " " + enemy.name + "!\n"
|
72
|
+
return 0
|
73
|
+
end
|
74
|
+
return true
|
75
|
+
end
|
76
|
+
|
77
|
+
def move(args)
|
78
|
+
direction = args[:direction]
|
79
|
+
neworleans = args[:neworleans]
|
80
|
+
ui = args[:ui]
|
81
|
+
story = args[:story]
|
82
|
+
case direction
|
83
|
+
when :up
|
84
|
+
if @y > 1
|
85
|
+
@y -= 1
|
86
|
+
else
|
87
|
+
ui.out_of_bounds
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
when :down
|
91
|
+
if @y < neworleans.get_height
|
92
|
+
@y += 1
|
93
|
+
else
|
94
|
+
ui.out_of_bounds
|
95
|
+
return false
|
96
|
+
end
|
97
|
+
when :left
|
98
|
+
if @x > 1
|
99
|
+
@x -= 1
|
100
|
+
else
|
101
|
+
ui.out_of_bounds
|
102
|
+
return false
|
103
|
+
end
|
104
|
+
when :right
|
105
|
+
if @x < neworleans.get_width
|
106
|
+
@x += 1
|
107
|
+
else
|
108
|
+
ui.out_of_bounds
|
109
|
+
return false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
unless neworleans.check_area({:player => self, :ui => ui, :story => story})
|
113
|
+
return false
|
114
|
+
else
|
115
|
+
return true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
data/lib/story.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Written by Webster Avosa
|
4
|
+
#
|
5
|
+
|
6
|
+
module MISSIONGAME
|
7
|
+
|
8
|
+
STORY_INTRO = [
|
9
|
+
"This is a game based on the movie series," + "The Originals".light_green + ", that has it's setting in New Orleans, Louisiana, United States.",
|
10
|
+
"Your mission is to meet "+ "Davina Clare".light_white + " a very powerful witch of New Orleans, and free her.",
|
11
|
+
"She is currently hostaged by the vampirers under the reign of Klaus Mikaelson.",
|
12
|
+
"She will provide you answers of all the questions you've always wanted to know.",
|
13
|
+
"",
|
14
|
+
"To get stated you will find a " + "map".light_white + " in the Mystic Falls of Virginia.",
|
15
|
+
"Understanding the map will be key to reaching the destination"
|
16
|
+
]
|
17
|
+
|
18
|
+
STORY_AREA_TREE = [
|
19
|
+
"Take a selfie of you before encountering a bloody scene lol."
|
20
|
+
]
|
21
|
+
|
22
|
+
STORY_AREA_WATER = [
|
23
|
+
"You just got close to Mississippi River."
|
24
|
+
]
|
25
|
+
|
26
|
+
STORY_AREA_MOUNTAIN = [
|
27
|
+
"A cool place to get yourself a beer before continuing with your mission."
|
28
|
+
]
|
29
|
+
|
30
|
+
STORY_AREA_VILLAINE = [
|
31
|
+
"You encountered a hungry vampire!"
|
32
|
+
]
|
33
|
+
|
34
|
+
STORY_PLAYER_DEAD = [
|
35
|
+
"You have been fed on.",
|
36
|
+
"",
|
37
|
+
"You failed to reach the witch. Please try again.",
|
38
|
+
]
|
39
|
+
|
40
|
+
STORY_END = [
|
41
|
+
"You've reached Davina Clare, the powerful witch!".light_white,
|
42
|
+
"",
|
43
|
+
"She stares at you and utters",
|
44
|
+
"",
|
45
|
+
"I can't imagine the time has finally come".light_yellow,
|
46
|
+
"This is going to be the end of dominance by vampires becuase this is your kingdom".light_yellow,
|
47
|
+
"you are special and powerful.".light_yellow,
|
48
|
+
"",
|
49
|
+
"THANK YOU FOR PLAYING!".light_red,
|
50
|
+
"",
|
51
|
+
]
|
52
|
+
|
53
|
+
class Story
|
54
|
+
|
55
|
+
def intro
|
56
|
+
return STORY_INTRO
|
57
|
+
end
|
58
|
+
|
59
|
+
def ending
|
60
|
+
return STORY_END
|
61
|
+
end
|
62
|
+
|
63
|
+
def area_tree
|
64
|
+
return STORY_AREA_TREE
|
65
|
+
end
|
66
|
+
|
67
|
+
def area_water
|
68
|
+
return STORY_AREA_WATER
|
69
|
+
end
|
70
|
+
|
71
|
+
def area_mountain
|
72
|
+
return STORY_AREA_MOUNTAIN
|
73
|
+
end
|
74
|
+
|
75
|
+
def area_villaine
|
76
|
+
return STORY_AREA_VILLAINE
|
77
|
+
end
|
78
|
+
|
79
|
+
def player_dead
|
80
|
+
return STORY_PLAYER_DEAD
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/lib/ui.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Written by Webster Avosa
|
4
|
+
#
|
5
|
+
|
6
|
+
module MISSIONGAME
|
7
|
+
|
8
|
+
UI_FRAME_HORIZONTAL = "\u2501"
|
9
|
+
UI_FRAME_VERTICAL = "\u2503"
|
10
|
+
UI_FRAME_UPPER_LEFT = "\u250F"
|
11
|
+
UI_FRAME_LOWER_LEFT = "\u2517"
|
12
|
+
UI_FRAME_UPPER_RIGHT = "\u2513"
|
13
|
+
UI_FRAME_LOWER_RIGHT = "\u251B"
|
14
|
+
|
15
|
+
UI_COPYRIGHT = "\u00A9"
|
16
|
+
UI_EMAIL = "\u2709"
|
17
|
+
UI_ARROW = "\u2712"
|
18
|
+
|
19
|
+
class UI
|
20
|
+
|
21
|
+
# Clear the screen
|
22
|
+
def clear
|
23
|
+
print "\e[H\e[2J"
|
24
|
+
end
|
25
|
+
|
26
|
+
def display_map(args)
|
27
|
+
map = args[:map]
|
28
|
+
new_line
|
29
|
+
draw_frame({:text => map})
|
30
|
+
new_line
|
31
|
+
end
|
32
|
+
|
33
|
+
def help
|
34
|
+
new_line
|
35
|
+
print "Valid Commands".light_green
|
36
|
+
new_line(2)
|
37
|
+
print UI_ARROW.light_yellow + " " + "right, r, ".light_white + + + " - Move right/east"
|
38
|
+
new_line
|
39
|
+
print UI_ARROW.light_yellow + " " + "backward, b, ".light_white + + + " - Move backward/south"
|
40
|
+
new_line
|
41
|
+
print UI_ARROW.light_yellow + " " + "left, l, ".light_white + + + " - Move left/west"
|
42
|
+
new_line
|
43
|
+
print UI_ARROW.light_yellow + " " + "forward, f, ".light_white + + + " - Move forward, f"
|
44
|
+
new_line
|
45
|
+
print UI_ARROW.light_yellow + " " + "map".light_white + " - Display map"
|
46
|
+
new_line
|
47
|
+
print UI_ARROW.light_yellow + " " + "where".light_white + " - Describe current surroundings"
|
48
|
+
new_line
|
49
|
+
print UI_ARROW.light_yellow + " " + "a, attack".light_white + " - Attack (only in combat)"
|
50
|
+
new_line
|
51
|
+
print UI_ARROW.light_yellow + " " + "enemy".light_white + " - Display information about your enemy"
|
52
|
+
new_line
|
53
|
+
print UI_ARROW.light_yellow + " " + "points, score, status, info".light_white + " - Display points (score)"
|
54
|
+
new_line
|
55
|
+
print UI_ARROW.light_yellow + " " + "clear, cls".light_white + " - Clears the screen"
|
56
|
+
new_line
|
57
|
+
print UI_ARROW.light_yellow + " " + "q, quit, exit".light_white + " - Quits the MISSIONGAME"
|
58
|
+
new_line
|
59
|
+
end
|
60
|
+
|
61
|
+
def points(args)
|
62
|
+
player = args[:player]
|
63
|
+
print "You currently have " + player.points.to_s.light_white + " points."
|
64
|
+
new_line
|
65
|
+
end
|
66
|
+
|
67
|
+
def enemy_info(args)
|
68
|
+
player = args[:player]
|
69
|
+
enemy = player.current_enemy
|
70
|
+
print enemy.name.light_red + " has " + enemy.str.to_s.light_white + " strength and " + enemy.lives.to_s.light_white + " lives."
|
71
|
+
new_line
|
72
|
+
end
|
73
|
+
|
74
|
+
def player_info(args)
|
75
|
+
player = args[:player]
|
76
|
+
print "You have " + player.lives.to_s.light_white + " lives and have " + player.points.to_s.light_white + " points."
|
77
|
+
new_line
|
78
|
+
end
|
79
|
+
|
80
|
+
# Ask user a question. A regular expression filter can be applied.
|
81
|
+
def ask(question, filter = nil)
|
82
|
+
if filter
|
83
|
+
match = false
|
84
|
+
answer = nil
|
85
|
+
while match == false
|
86
|
+
print UI_ARROW.red + question.light_white + " "
|
87
|
+
answer = gets.chomp
|
88
|
+
if answer.match(filter)
|
89
|
+
return answer
|
90
|
+
else
|
91
|
+
print "Sorry, please try again.".red
|
92
|
+
new_line
|
93
|
+
new_line
|
94
|
+
end
|
95
|
+
end
|
96
|
+
else
|
97
|
+
print "\u2712 ".red + question.light_white + " "
|
98
|
+
input = gets.chomp
|
99
|
+
return input
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Display welcome
|
104
|
+
def welcome
|
105
|
+
text = Array.new
|
106
|
+
text << "This is a text adventure game inspired by the movie series ".white + "The Originals".light_green
|
107
|
+
text << "Written by Webster Avosa as a ".white + UI_EMAIL.light_white + "Livestorm Back-End Hiring Test".light_green
|
108
|
+
text << "Copyright " + UI_COPYRIGHT + " Webster Avosa, All Rights Reserved.".white
|
109
|
+
text << "Licensed under MIT.".white
|
110
|
+
text << "Contact me ".white + UI_EMAIL.light_white + " websterb17@gmail.com".white
|
111
|
+
draw_frame({:text => text})
|
112
|
+
new_line
|
113
|
+
end
|
114
|
+
|
115
|
+
# Prints a new line. Optinally can print multiple lines.
|
116
|
+
def new_line(times = 1)
|
117
|
+
times.times do
|
118
|
+
print "\n"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Draw text surrounded in a nice frame
|
123
|
+
def draw_frame(args)
|
124
|
+
# Figure out width automatically
|
125
|
+
text = args[:text]
|
126
|
+
width = get_max_size_from_array(text)
|
127
|
+
draw_top_frame(width)
|
128
|
+
text.each do |t|
|
129
|
+
t_size = get_real_size(t)
|
130
|
+
draw_vert_frame_begin
|
131
|
+
if t.kind_of?(Array)
|
132
|
+
t.each do |s|
|
133
|
+
print s
|
134
|
+
end
|
135
|
+
else
|
136
|
+
print t
|
137
|
+
end
|
138
|
+
(width - (t_size + 4)).times do
|
139
|
+
print " "
|
140
|
+
end
|
141
|
+
draw_vert_frame_end
|
142
|
+
new_line
|
143
|
+
end
|
144
|
+
draw_bottom_frame(width)
|
145
|
+
end
|
146
|
+
|
147
|
+
def display_version
|
148
|
+
puts " Version " + MISSIONMISSIONGAME_VERSION.light_white
|
149
|
+
new_line
|
150
|
+
end
|
151
|
+
|
152
|
+
def not_found
|
153
|
+
print "Command not understood. Use the " + "help or h".red + " to see available commands.".light_white
|
154
|
+
new_line
|
155
|
+
end
|
156
|
+
|
157
|
+
def show_location(args)
|
158
|
+
player = args[:player]
|
159
|
+
print "You are currently on row " + player.y.to_s.light_white + ", column " + player.x.to_s.light_white
|
160
|
+
new_line
|
161
|
+
print "Use the " + "map".light_white + " command to see the map."
|
162
|
+
new_line
|
163
|
+
end
|
164
|
+
|
165
|
+
def cannot_travel_combat
|
166
|
+
puts "You're in a war with the vampires! Fight for your life to proceed or else your're being feasted on!"
|
167
|
+
end
|
168
|
+
|
169
|
+
def not_in_combat
|
170
|
+
puts "No vampire has attacked you just yet."
|
171
|
+
end
|
172
|
+
|
173
|
+
def quit
|
174
|
+
new_line
|
175
|
+
print "You abandoned your journey to getting answers to all of your many unaswered questions.".red
|
176
|
+
new_line(2)
|
177
|
+
end
|
178
|
+
|
179
|
+
def get_cmd
|
180
|
+
print "Type ".white + "help".light_white + " for possible commands.\n"
|
181
|
+
print "\u2712 ".red + "Your command? ".light_white
|
182
|
+
return gets.chomp.downcase
|
183
|
+
end
|
184
|
+
|
185
|
+
def out_of_bounds
|
186
|
+
print "x".red + " Requested move out of bounds."
|
187
|
+
new_line
|
188
|
+
end
|
189
|
+
|
190
|
+
def display_name(args)
|
191
|
+
player = args[:player]
|
192
|
+
print "You are " + player.name.light_white + ". Have you forgotten your own name?"
|
193
|
+
new_line
|
194
|
+
end
|
195
|
+
|
196
|
+
def player_dead(args)
|
197
|
+
story = args[:story]
|
198
|
+
new_line
|
199
|
+
text = story.player_dead
|
200
|
+
draw_frame(:text => text)
|
201
|
+
new_line
|
202
|
+
end
|
203
|
+
|
204
|
+
def enemy_greet(args)
|
205
|
+
enemy = args[:enemy]
|
206
|
+
print enemy.name.light_white + " attacks!"
|
207
|
+
new_line
|
208
|
+
end
|
209
|
+
|
210
|
+
private
|
211
|
+
|
212
|
+
def draw_vert_frame_begin
|
213
|
+
print UI_FRAME_VERTICAL.yellow + " "
|
214
|
+
end
|
215
|
+
|
216
|
+
def draw_vert_frame_end
|
217
|
+
print " " + UI_FRAME_VERTICAL.yellow
|
218
|
+
end
|
219
|
+
|
220
|
+
def draw_top_frame(width)
|
221
|
+
print UI_FRAME_UPPER_LEFT.yellow
|
222
|
+
(width - 2).times do
|
223
|
+
print UI_FRAME_HORIZONTAL.yellow
|
224
|
+
end
|
225
|
+
print UI_FRAME_UPPER_RIGHT.yellow
|
226
|
+
new_line
|
227
|
+
end
|
228
|
+
|
229
|
+
def draw_bottom_frame(width)
|
230
|
+
print UI_FRAME_LOWER_LEFT.yellow
|
231
|
+
(width - 2).times do
|
232
|
+
print UI_FRAME_HORIZONTAL.yellow
|
233
|
+
end
|
234
|
+
print UI_FRAME_LOWER_RIGHT.yellow
|
235
|
+
new_line
|
236
|
+
end
|
237
|
+
|
238
|
+
# Returns actual length of text accounting for UTF-8 and ANSI
|
239
|
+
def get_real_size(text)
|
240
|
+
if text.kind_of?(Array)
|
241
|
+
text.size
|
242
|
+
else
|
243
|
+
text.uncolorize.size
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# Returns size of longest string in array
|
248
|
+
def get_max_size_from_array(array)
|
249
|
+
max = 0
|
250
|
+
array.each do |s|
|
251
|
+
s_size = get_real_size(s)
|
252
|
+
max = s_size if s_size >= max
|
253
|
+
end
|
254
|
+
max + 4
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
data/mission_game.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Written by Webster Avosa
|
4
|
+
|
5
|
+
GAME_VERSION = "1.00"
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'colorize'
|
9
|
+
require 'pry'
|
10
|
+
rescue LoadError
|
11
|
+
puts
|
12
|
+
puts "This game requires the 'colorize' and 'pry' gem to run."
|
13
|
+
puts
|
14
|
+
puts "Installation Instructions"
|
15
|
+
puts "-------------------------"
|
16
|
+
puts
|
17
|
+
puts "Debian/Ubuntu Linux:"
|
18
|
+
puts " sudo apt install ruby-colorize && sudo apt install pry"
|
19
|
+
puts
|
20
|
+
puts "Other Linux Distros:"
|
21
|
+
puts " gem install colorize && gem install pry"
|
22
|
+
puts
|
23
|
+
puts "Windows:"
|
24
|
+
puts " gem install colorize && gem install pry"
|
25
|
+
puts
|
26
|
+
puts "macOS:"
|
27
|
+
puts " gem install colorize && gem install pry"
|
28
|
+
puts
|
29
|
+
puts
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
# Require libraries
|
36
|
+
load "lib/ui.rb"
|
37
|
+
load "lib/neworleans.rb"
|
38
|
+
load "lib/player.rb"
|
39
|
+
load "lib/story.rb"
|
40
|
+
load "lib/enemy.rb"
|
41
|
+
|
42
|
+
# Start
|
43
|
+
load "lib/main.rb"
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mission_game
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Webster Avosa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-10-12 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
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description:
|
42
|
+
email: websterb17@gmail.com
|
43
|
+
executables:
|
44
|
+
- mission_game
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- bin/mission_game
|
49
|
+
- lib/enemy.rb
|
50
|
+
- lib/main.rb
|
51
|
+
- lib/neworleans.rb
|
52
|
+
- lib/player.rb
|
53
|
+
- lib/story.rb
|
54
|
+
- lib/ui.rb
|
55
|
+
- mission_game.rb
|
56
|
+
homepage: https://github.com/avosa/mission_game
|
57
|
+
licenses:
|
58
|
+
- MIT
|
59
|
+
metadata: {}
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubygems_version: 3.2.22
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: This is an open-source text-based adventure game written in Ruby.
|
79
|
+
test_files: []
|