rubywarrior-i18n 0.0.2
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.
- data/CHANGELOG.rdoc +38 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +20 -0
- data/README.md +199 -0
- data/Rakefile +17 -0
- data/bin/rubywarrior +5 -0
- data/features/command_options.feature +46 -0
- data/features/levels.feature +71 -0
- data/features/profiles.feature +56 -0
- data/features/step_definitions/common_steps.rb +19 -0
- data/features/step_definitions/interaction_steps.rb +65 -0
- data/features/support/env.rb +12 -0
- data/features/support/mockio.rb +57 -0
- data/features/towers.feature +14 -0
- data/i18n/en.yml +232 -0
- data/i18n/es.yml +233 -0
- data/lib/ruby_warrior.rb +53 -0
- data/lib/ruby_warrior/abilities/attack.rb +25 -0
- data/lib/ruby_warrior/abilities/base.rb +44 -0
- data/lib/ruby_warrior/abilities/bind.rb +20 -0
- data/lib/ruby_warrior/abilities/detonate.rb +34 -0
- data/lib/ruby_warrior/abilities/direction_of.rb +13 -0
- data/lib/ruby_warrior/abilities/direction_of_stairs.rb +13 -0
- data/lib/ruby_warrior/abilities/distance_of.rb +13 -0
- data/lib/ruby_warrior/abilities/explode.rb +28 -0
- data/lib/ruby_warrior/abilities/feel.rb +14 -0
- data/lib/ruby_warrior/abilities/form.rb +25 -0
- data/lib/ruby_warrior/abilities/health.rb +13 -0
- data/lib/ruby_warrior/abilities/listen.rb +15 -0
- data/lib/ruby_warrior/abilities/look.rb +16 -0
- data/lib/ruby_warrior/abilities/pivot.rb +17 -0
- data/lib/ruby_warrior/abilities/rescue.rb +24 -0
- data/lib/ruby_warrior/abilities/rest.rb +20 -0
- data/lib/ruby_warrior/abilities/shoot.rb +24 -0
- data/lib/ruby_warrior/abilities/walk.rb +21 -0
- data/lib/ruby_warrior/config.rb +22 -0
- data/lib/ruby_warrior/core_additions.rb +29 -0
- data/lib/ruby_warrior/floor.rb +71 -0
- data/lib/ruby_warrior/game.rb +209 -0
- data/lib/ruby_warrior/level.rb +123 -0
- data/lib/ruby_warrior/level_loader.rb +56 -0
- data/lib/ruby_warrior/player_generator.rb +41 -0
- data/lib/ruby_warrior/position.rb +82 -0
- data/lib/ruby_warrior/profile.rb +120 -0
- data/lib/ruby_warrior/runner.rb +34 -0
- data/lib/ruby_warrior/space.rb +71 -0
- data/lib/ruby_warrior/tower.rb +14 -0
- data/lib/ruby_warrior/turn.rb +38 -0
- data/lib/ruby_warrior/ui.rb +54 -0
- data/lib/ruby_warrior/units/archer.rb +34 -0
- data/lib/ruby_warrior/units/base.rb +100 -0
- data/lib/ruby_warrior/units/captive.rb +17 -0
- data/lib/ruby_warrior/units/golem.rb +20 -0
- data/lib/ruby_warrior/units/sludge.rb +30 -0
- data/lib/ruby_warrior/units/thick_sludge.rb +13 -0
- data/lib/ruby_warrior/units/warrior.rb +73 -0
- data/lib/ruby_warrior/units/wizard.rb +34 -0
- data/lib/ruby_warrior/version.rb +3 -0
- data/spec/fixtures/short-tower/level_001.rb +15 -0
- data/spec/fixtures/short-tower/level_002.rb +15 -0
- data/spec/fixtures/walking_player.rb +5 -0
- data/spec/ruby_warrior/abilities/attack_spec.rb +51 -0
- data/spec/ruby_warrior/abilities/base_spec.rb +38 -0
- data/spec/ruby_warrior/abilities/bind_spec.rb +19 -0
- data/spec/ruby_warrior/abilities/direction_of_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/direction_of_stairs_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/distance_of_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/explode_spec.rb +32 -0
- data/spec/ruby_warrior/abilities/feel_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/form_spec.rb +48 -0
- data/spec/ruby_warrior/abilities/health_spec.rb +13 -0
- data/spec/ruby_warrior/abilities/listen_spec.rb +17 -0
- data/spec/ruby_warrior/abilities/look_spec.rb +15 -0
- data/spec/ruby_warrior/abilities/pivot_spec.rb +18 -0
- data/spec/ruby_warrior/abilities/rescue_spec.rb +40 -0
- data/spec/ruby_warrior/abilities/rest_spec.rb +29 -0
- data/spec/ruby_warrior/abilities/shoot_spec.rb +22 -0
- data/spec/ruby_warrior/abilities/throw_spec.rb +46 -0
- data/spec/ruby_warrior/abilities/walk_spec.rb +25 -0
- data/spec/ruby_warrior/core_additions_spec.rb +7 -0
- data/spec/ruby_warrior/floor_spec.rb +81 -0
- data/spec/ruby_warrior/game_spec.rb +119 -0
- data/spec/ruby_warrior/level_loader_spec.rb +54 -0
- data/spec/ruby_warrior/level_spec.rb +203 -0
- data/spec/ruby_warrior/player_generator_spec.rb +12 -0
- data/spec/ruby_warrior/position_spec.rb +108 -0
- data/spec/ruby_warrior/profile_spec.rb +171 -0
- data/spec/ruby_warrior/space_spec.rb +190 -0
- data/spec/ruby_warrior/tower_spec.rb +15 -0
- data/spec/ruby_warrior/turn_spec.rb +42 -0
- data/spec/ruby_warrior/ui_spec.rb +93 -0
- data/spec/ruby_warrior/units/archer_spec.rb +23 -0
- data/spec/ruby_warrior/units/base_spec.rb +133 -0
- data/spec/ruby_warrior/units/captive_spec.rb +23 -0
- data/spec/ruby_warrior/units/golem_spec.rb +28 -0
- data/spec/ruby_warrior/units/sludge_spec.rb +27 -0
- data/spec/ruby_warrior/units/thick_sludge_spec.rb +19 -0
- data/spec/ruby_warrior/units/warrior_spec.rb +65 -0
- data/spec/ruby_warrior/units/wizard_spec.rb +23 -0
- data/spec/spec_helper.rb +10 -0
- data/templates/README.erb +33 -0
- data/templates/player.rb +5 -0
- data/towers/beginner/level_001.rb +18 -0
- data/towers/beginner/level_002.rb +19 -0
- data/towers/beginner/level_003.rb +23 -0
- data/towers/beginner/level_004.rb +20 -0
- data/towers/beginner/level_005.rb +24 -0
- data/towers/beginner/level_006.rb +21 -0
- data/towers/beginner/level_007.rb +20 -0
- data/towers/beginner/level_008.rb +23 -0
- data/towers/beginner/level_009.rb +22 -0
- data/towers/intermediate/level_001.rb +20 -0
- data/towers/intermediate/level_002.rb +22 -0
- data/towers/intermediate/level_003.rb +25 -0
- data/towers/intermediate/level_004.rb +26 -0
- data/towers/intermediate/level_005.rb +21 -0
- data/towers/intermediate/level_006.rb +25 -0
- data/towers/intermediate/level_007.rb +27 -0
- data/towers/intermediate/level_008.rb +25 -0
- data/towers/intermediate/level_009.rb +33 -0
- metadata +226 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Explode < Base
|
4
|
+
attr_accessor :time
|
5
|
+
|
6
|
+
def description
|
7
|
+
"#{R18n.t.explode.description}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform
|
11
|
+
if @unit.position
|
12
|
+
@unit.say "#{R18n.t.explode.collapsing_the_ceiling}"
|
13
|
+
@unit.position.floor.units.map do |unit|
|
14
|
+
unit.take_damage(100)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def pass_turn
|
20
|
+
if @time && @unit.position
|
21
|
+
@unit.say "#{R18n.t.explode.is_ticking}"
|
22
|
+
@time -= 1
|
23
|
+
perform if @time.zero?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Form < Base
|
4
|
+
def description
|
5
|
+
"#{R18n.t.form.description}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform(direction = :forward, &block)
|
9
|
+
verify_direction(direction)
|
10
|
+
if space(direction).empty?
|
11
|
+
x, y = @unit.position.translate_offset(*offset(direction))
|
12
|
+
health = (@unit.health/2.0).floor
|
13
|
+
golem = @unit.base_golem
|
14
|
+
golem.max_health = health
|
15
|
+
golem.turn = block
|
16
|
+
@unit.health -= health
|
17
|
+
@unit.position.floor.add(golem, x, y, @unit.position.direction)
|
18
|
+
@unit.say "#{R18n.t.form.golem_gives_health(R18n.t.direction[direction], health)}"
|
19
|
+
else
|
20
|
+
@unit.say "#{R18n.t.form.fails}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Listen < Base
|
4
|
+
def description
|
5
|
+
"#{R18n.t.listen.description}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform
|
9
|
+
@unit.position.floor.units.map do |unit|
|
10
|
+
unit.position.space unless unit == @unit
|
11
|
+
end.compact
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Look < Base
|
4
|
+
def description
|
5
|
+
"#{R18n.t.look.description}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform(direction = :forward)
|
9
|
+
verify_direction(direction)
|
10
|
+
[1, 2, 3].map do |amount|
|
11
|
+
space(direction, amount)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Pivot < Base
|
4
|
+
ROTATION_DIRECTIONS = [:forward, :right, :backward, :left]
|
5
|
+
|
6
|
+
def description
|
7
|
+
"#{R18n.t.rotate.description}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform(direction = :backward)
|
11
|
+
verify_direction(direction)
|
12
|
+
@unit.position.rotate(ROTATION_DIRECTIONS.index(direction))
|
13
|
+
@unit.say "#{R18n.t.rotate.pivots} #{R18n.t.direction[direction]}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Rescue < Base
|
4
|
+
def description
|
5
|
+
"#{R18n.t.rescue.description}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform(direction = :forward)
|
9
|
+
verify_direction(direction)
|
10
|
+
if space(direction).captive?
|
11
|
+
recipient = unit(direction)
|
12
|
+
@unit.say R18n.t.rescue.unbinds_and_rescues(R18n.t.direction[direction], "#{recipient}")
|
13
|
+
recipient.unbind
|
14
|
+
if recipient.kind_of? Units::Captive
|
15
|
+
recipient.position = nil
|
16
|
+
@unit.earn_points(20)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
@unit.say "#{R18n.t.rescue.unbinds_and_rescues_nothing(direction)}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Rest < Base
|
4
|
+
def description
|
5
|
+
"#{R18n.t.rest.description}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform
|
9
|
+
if @unit.health < @unit.max_health
|
10
|
+
amount = (@unit.max_health*0.1).round
|
11
|
+
amount = @unit.max_health-@unit.health if (@unit.health + amount) > @unit.max_health
|
12
|
+
@unit.health += amount
|
13
|
+
@unit.say "#{R18n.t.rest.receives_health(amount, @unit.health)}"
|
14
|
+
else
|
15
|
+
@unit.say "#{R18n.t.rest.fit_fiddle}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Shoot < Base
|
4
|
+
def description
|
5
|
+
"#{R18n.t.shoot.description}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform(direction = :forward)
|
9
|
+
verify_direction(direction)
|
10
|
+
receiver = multi_unit(direction, 1..3).compact.first
|
11
|
+
if receiver
|
12
|
+
@unit.say "#{R18n.t.shoot.and_hits(R18n.t.direction[direction], receiver)}"
|
13
|
+
damage(receiver, @unit.shoot_power)
|
14
|
+
else
|
15
|
+
@unit.say "#{R18n.t.shoot.and_hits_nothing}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def multi_unit(direction, range)
|
20
|
+
range.map { |n| unit(direction, n) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
module Abilities
|
3
|
+
class Walk < Base
|
4
|
+
def description
|
5
|
+
"#{R18n.t.direction.move_forward_default}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform(direction = :forward)
|
9
|
+
verify_direction(direction)
|
10
|
+
if @unit.position
|
11
|
+
@unit.say "#{R18n.t.walk.s} #{R18n.t.direction[direction]}"
|
12
|
+
if space(direction).empty?
|
13
|
+
@unit.position.move(*offset(direction))
|
14
|
+
else
|
15
|
+
@unit.say "#{R18n.t.direction.bumps_into} #{space(direction)}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
class Config
|
3
|
+
class << self
|
4
|
+
attr_accessor :delay, :in_stream, :out_stream, :practice_level
|
5
|
+
attr_writer :path_prefix, :skip_input
|
6
|
+
|
7
|
+
def path_prefix
|
8
|
+
@path_prefix || "."
|
9
|
+
end
|
10
|
+
|
11
|
+
def skip_input?
|
12
|
+
@skip_input
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset
|
16
|
+
[:@path_prefix, :@skip_input, :@delay, :@in_stream, :@out_stream, :@practice_level].each do |i|
|
17
|
+
remove_instance_variable(i) if instance_variable_defined?(i)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class String
|
2
|
+
def camelize
|
3
|
+
gsub(/(?:^|_)(.)/) { $1.upcase }
|
4
|
+
end
|
5
|
+
|
6
|
+
def constantize
|
7
|
+
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ self
|
8
|
+
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
|
9
|
+
end
|
10
|
+
|
11
|
+
Object.module_eval("::#{$1}", __FILE__, __LINE__)
|
12
|
+
end
|
13
|
+
|
14
|
+
def underscore
|
15
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
|
16
|
+
end
|
17
|
+
|
18
|
+
def humanize
|
19
|
+
gsub(/_/, " ").capitalize
|
20
|
+
end
|
21
|
+
|
22
|
+
def titleize
|
23
|
+
underscore.humanize.gsub(/\b('?[a-z])/) { $1.capitalize }
|
24
|
+
end
|
25
|
+
|
26
|
+
def hard_wrap(width = 80)
|
27
|
+
gsub(/(.{1,#{width}})(\s+|$)/, "\\1\n").strip
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
class Floor
|
3
|
+
attr_accessor :width, :height, :grid
|
4
|
+
attr_reader :stairs_location
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@width = 0
|
8
|
+
@height = 0
|
9
|
+
@units = []
|
10
|
+
@stairs_location = [-1, -1]
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(unit, x, y, direction = nil)
|
14
|
+
@units << unit
|
15
|
+
unit.position = Position.new(self, x, y, direction)
|
16
|
+
end
|
17
|
+
|
18
|
+
def place_stairs(x, y)
|
19
|
+
@stairs_location = [x, y]
|
20
|
+
end
|
21
|
+
|
22
|
+
def stairs_space
|
23
|
+
space(*@stairs_location)
|
24
|
+
end
|
25
|
+
|
26
|
+
def units
|
27
|
+
@units.reject { |u| u.position.nil? }
|
28
|
+
end
|
29
|
+
|
30
|
+
def other_units
|
31
|
+
units.reject { |u| u.kind_of? Units::Warrior }
|
32
|
+
end
|
33
|
+
|
34
|
+
def get(x, y)
|
35
|
+
units.detect do |unit|
|
36
|
+
unit.position.at?(x, y)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def space(x, y)
|
41
|
+
Space.new(self, x, y)
|
42
|
+
end
|
43
|
+
|
44
|
+
def out_of_bounds?(x, y)
|
45
|
+
x < 0 || y < 0 || x > @width-1 || y > @height-1
|
46
|
+
end
|
47
|
+
|
48
|
+
def character
|
49
|
+
rows = []
|
50
|
+
rows << " " + ("-" * @width)
|
51
|
+
@height.times do |y|
|
52
|
+
row = "|"
|
53
|
+
@width.times do |x|
|
54
|
+
row << space(x, y).character
|
55
|
+
end
|
56
|
+
row << "|"
|
57
|
+
rows << row
|
58
|
+
end
|
59
|
+
rows << " " + ("-" * @width)
|
60
|
+
rows.join("\n") + "\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
def unique_units
|
64
|
+
unique_units = []
|
65
|
+
units.each do |unit|
|
66
|
+
unique_units << unit unless unique_units.map { |u| u.class }.include?(unit.class)
|
67
|
+
end
|
68
|
+
unique_units
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
module RubyWarrior
|
2
|
+
|
3
|
+
class Game
|
4
|
+
|
5
|
+
def start
|
6
|
+
UI.puts R18n.t.welcome
|
7
|
+
|
8
|
+
if File.exist?(Config.path_prefix + '/.profile')
|
9
|
+
@profile = Profile.load(Config.path_prefix + '/.profile')
|
10
|
+
else
|
11
|
+
if File.exist?(Config.path_prefix + "/ruby-warrior")
|
12
|
+
FileUtils.mv(Config.path_prefix + '/ruby-warrior', Config.path_prefix + '/rubywarrior')
|
13
|
+
end
|
14
|
+
make_game_directory unless File.exist?(Config.path_prefix + '/rubywarrior')
|
15
|
+
end
|
16
|
+
|
17
|
+
if profile.epic?
|
18
|
+
if profile.level_after_epic?
|
19
|
+
go_back_to_normal_mode
|
20
|
+
else
|
21
|
+
play_epic_mode
|
22
|
+
end
|
23
|
+
else
|
24
|
+
play_normal_mode
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def make_game_directory
|
29
|
+
if UI.ask(R18n.t.directory.not_found)
|
30
|
+
Dir.mkdir(Config.path_prefix + '/rubywarrior')
|
31
|
+
else
|
32
|
+
UI.puts R18n.t.directory.cannot_continue
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def play_epic_mode
|
38
|
+
Config.delay /= 2 if Config.delay # speed up UI since we're going to be doing a lot here
|
39
|
+
profile.current_epic_score = 0
|
40
|
+
profile.current_epic_grades = {}
|
41
|
+
if Config.practice_level
|
42
|
+
@current_level = @next_level = nil
|
43
|
+
profile.level_number = Config.practice_level
|
44
|
+
play_current_level
|
45
|
+
else
|
46
|
+
playing = true
|
47
|
+
while playing
|
48
|
+
@current_level = @next_level = nil
|
49
|
+
profile.level_number += 1
|
50
|
+
playing = play_current_level
|
51
|
+
end
|
52
|
+
profile.save # saves the score for epic mode
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def play_normal_mode
|
57
|
+
if Config.practice_level
|
58
|
+
UI.puts R18n.t.practice_level.unable_not_in_epic_mode
|
59
|
+
else
|
60
|
+
if current_level.number.zero?
|
61
|
+
prepare_next_level
|
62
|
+
UI.puts R18n.t.first_level_generated(profile.directory_name)
|
63
|
+
else
|
64
|
+
play_current_level
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def play_current_level
|
70
|
+
continue = true
|
71
|
+
current_level.load_player
|
72
|
+
UI.puts R18n.t.level.starting(current_level.number)
|
73
|
+
current_level.play
|
74
|
+
if current_level.passed?
|
75
|
+
if next_level.exists?
|
76
|
+
UI.puts R18n.t.stairs.found
|
77
|
+
else
|
78
|
+
UI.puts R18n.t.end_of_game
|
79
|
+
continue = false
|
80
|
+
end
|
81
|
+
current_level.tally_points
|
82
|
+
if profile.epic?
|
83
|
+
UI.puts final_report if final_report && !continue
|
84
|
+
else
|
85
|
+
request_next_level
|
86
|
+
end
|
87
|
+
else
|
88
|
+
continue = false
|
89
|
+
UI.puts R18n.t.level.failed(current_level.number)
|
90
|
+
if !Config.skip_input? && current_level.clue && UI.ask(R18n.t.level.clues)
|
91
|
+
UI.puts current_level.clue.hard_wrap
|
92
|
+
end
|
93
|
+
end
|
94
|
+
continue
|
95
|
+
end
|
96
|
+
|
97
|
+
def request_next_level
|
98
|
+
if !Config.skip_input? && (next_level.exists? ? UI.ask(R18n.t.level.continue_next) : UI.ask(R18n.t.level.continue_epic_mode))
|
99
|
+
if next_level.exists?
|
100
|
+
prepare_next_level
|
101
|
+
UI.puts R18n.t.readme.see_updated(profile.directory_name)
|
102
|
+
else
|
103
|
+
prepare_epic_mode
|
104
|
+
UI.puts R18n.t.to_play_epic_mode
|
105
|
+
end
|
106
|
+
else
|
107
|
+
UI.puts R18n.t.level.staying_on_current
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def prepare_next_level
|
112
|
+
next_level.generate_player_files
|
113
|
+
profile.level_number += 1
|
114
|
+
profile.save # this saves score and new abilities too
|
115
|
+
end
|
116
|
+
|
117
|
+
def prepare_epic_mode
|
118
|
+
profile.enable_epic_mode
|
119
|
+
profile.level_number = 0
|
120
|
+
profile.save # this saves score too
|
121
|
+
end
|
122
|
+
|
123
|
+
def go_back_to_normal_mode
|
124
|
+
profile.enable_normal_mode
|
125
|
+
prepare_next_level
|
126
|
+
UI.puts R18n.t.mode.back_to_normal
|
127
|
+
UI.puts R18n.t.readme.see_updated(profile.directory_name)
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
# profiles
|
132
|
+
|
133
|
+
def profiles
|
134
|
+
profile_paths.map { |profile| Profile.load(profile) }
|
135
|
+
end
|
136
|
+
|
137
|
+
def profile_paths
|
138
|
+
Dir[Config.path_prefix + '/rubywarrior/**/.profile']
|
139
|
+
end
|
140
|
+
|
141
|
+
def profile
|
142
|
+
@profile ||= choose_profile
|
143
|
+
end
|
144
|
+
|
145
|
+
def new_profile
|
146
|
+
profile = Profile.new
|
147
|
+
profile.tower_path = UI.choose(R18n.t.game.tower, towers).path
|
148
|
+
profile.warrior_name = UI.request(R18n.t.warrior.enter_name)
|
149
|
+
profile
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
# towers
|
154
|
+
|
155
|
+
def towers
|
156
|
+
tower_paths.map { |path| Tower.new(path) }
|
157
|
+
end
|
158
|
+
|
159
|
+
def tower_paths
|
160
|
+
Dir[File.expand_path('../../../towers/*', __FILE__)]
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
# levels
|
165
|
+
|
166
|
+
def current_level
|
167
|
+
@current_level ||= profile.current_level
|
168
|
+
end
|
169
|
+
|
170
|
+
def next_level
|
171
|
+
@next_level ||= profile.next_level
|
172
|
+
end
|
173
|
+
|
174
|
+
def final_report
|
175
|
+
if profile.calculate_average_grade && !Config.practice_level
|
176
|
+
report = ""
|
177
|
+
report << R18n.t.game.average_grade_for_tower(Level.grade_letter(profile.calculate_average_grade))
|
178
|
+
profile.current_epic_grades.keys.sort.each do |level|
|
179
|
+
report << " #{R18n.t.level.number(level)} #{Level.grade_letter(profile.current_epic_grades[level])}\n"
|
180
|
+
end
|
181
|
+
report << R18n.t.level.to_practice
|
182
|
+
report
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
def choose_profile # REFACTORME
|
189
|
+
profile = UI.choose(R18n.t.profile.profile, profiles + [[:new, R18n.t.profile.new]])
|
190
|
+
if profile == :new
|
191
|
+
profile = new_profile
|
192
|
+
if profiles.any? { |p| p.player_path == profile.player_path }
|
193
|
+
if UI.ask(R18n.t.profile.replace_existing_for_tower)
|
194
|
+
UI.puts R18n.t.profile.replace_existing
|
195
|
+
profile
|
196
|
+
else
|
197
|
+
UI.puts R18n.t.profile.not_replacing
|
198
|
+
exit
|
199
|
+
end
|
200
|
+
else
|
201
|
+
profile
|
202
|
+
end
|
203
|
+
else
|
204
|
+
profile
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|