empi 0.21 → 0.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/empi.rb +8 -5
- data/lib/lib/game_states/build_state.rb +68 -0
- data/lib/{game_state.rb → lib/game_states/game_state.rb} +0 -0
- data/lib/lib/game_states/play_state.rb +149 -0
- data/lib/{escape_state.rb → lib/game_states/quit_state.rb} +4 -5
- data/lib/lib/game_states/set_state.rb +75 -0
- data/lib/lib/game_states/welcome_state.rb +85 -0
- data/lib/lib/game_states/win_state.rb +61 -0
- data/lib/{army.rb → lib/units/army.rb} +2 -2
- data/lib/{ship.rb → lib/units/ship.rb} +2 -2
- data/lib/{town.rb → lib/units/town.rb} +31 -23
- data/lib/{unit.rb → lib/units/unit.rb} +73 -47
- data/lib/{unitFunction.rb → lib/units/unit_function.rb} +13 -4
- data/lib/lib/user_interface/cursor.rb +252 -0
- data/lib/lib/user_interface/infopane.rb +49 -0
- data/lib/lib/user_interface/map.rb +189 -0
- data/lib/lib/user_interface/tile.rb +56 -0
- metadata +23 -19
- data/lib/build_state.rb +0 -54
- data/lib/cursor.rb +0 -167
- data/lib/infopane.rb +0 -38
- data/lib/map.rb +0 -153
- data/lib/play_state.rb +0 -98
- data/lib/tile.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abe9081612cf59f547e94e98d5ee4373fab6ded9298bfb20366bc3d67725c0cc
|
4
|
+
data.tar.gz: 7f7683c7a94d512965feed1617fc3cb700851e5444862a28069b8c2ddb76cecc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: feac436c82e490b978bac742c546816879fa7c32ef3e14410023078d83b1e8d5366d3ffa7ef051442cf84d5cef728f8c7ee2f2577ddce84c7f3ef16c2661def1
|
7
|
+
data.tar.gz: 73ade95b93a6b84b509ecb88ea545aaa80babbd007586bc4d5db52dee03a79eec15c9fd18f7a4422db265398921e1ab33701bd2c2230f9a7592fdc64cae64277
|
data/lib/empi.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'gosu'
|
3
3
|
|
4
|
-
require_relative './game_state'
|
5
|
-
require_relative './
|
4
|
+
require_relative './lib/game_states/game_state'
|
5
|
+
require_relative './lib/game_states/welcome_state'
|
6
6
|
|
7
7
|
TILESIZE = 50
|
8
8
|
MAPX = 10
|
@@ -19,11 +19,15 @@ class GameWindow < Gosu::Window
|
|
19
19
|
height = (MAPY + 2) * TILESIZE, \
|
20
20
|
fullscreen = false)
|
21
21
|
super
|
22
|
-
|
22
|
+
|
23
|
+
# Set version name
|
24
|
+
version = '0.25'
|
25
|
+
self.caption = "Empi: Ruby Edition #{version}"
|
26
|
+
WelcomeState.instance.version = version
|
23
27
|
|
24
28
|
# Activate first state
|
25
29
|
$window = self
|
26
|
-
GameState.switch!(
|
30
|
+
GameState.switch!(WelcomeState.instance)
|
27
31
|
end
|
28
32
|
|
29
33
|
# Catch the released button
|
@@ -46,7 +50,6 @@ class GameWindow < Gosu::Window
|
|
46
50
|
|
47
51
|
# Draw according to current state
|
48
52
|
def draw
|
49
|
-
|
50
53
|
@button = BUTTON_PROCESSED # draw just once after each button release
|
51
54
|
unless $window.state.nil?
|
52
55
|
@state.draw
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './play_state'
|
5
|
+
|
6
|
+
require_relative './../units/army'
|
7
|
+
require_relative './../units/ship'
|
8
|
+
|
9
|
+
# Game state of selection of the build project
|
10
|
+
class BuildState < GameState
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
attr_accessor :unit
|
14
|
+
|
15
|
+
# What to do just after state gets activated
|
16
|
+
#def after_start
|
17
|
+
#end
|
18
|
+
|
19
|
+
# What to do just before state gets deactivated
|
20
|
+
#def before_end
|
21
|
+
#end
|
22
|
+
|
23
|
+
# Process given button
|
24
|
+
def update(button)
|
25
|
+
newly_selected = nil
|
26
|
+
|
27
|
+
case(button)
|
28
|
+
# Cancelled change of project = return
|
29
|
+
when Gosu::KbEscape then
|
30
|
+
puts PROMPT + @unit.to_s + ": cancelling, nothing changed"
|
31
|
+
GameState.switch!(PlayState.instance)
|
32
|
+
# Paused production = reset function and return
|
33
|
+
when Gosu::Kb0, Gosu::KbN then
|
34
|
+
puts PROMPT + @unit.to_s + ": production paused, resetting function"
|
35
|
+
@unit.set_function!(FUNCNONE, @unit.faction)
|
36
|
+
GameState.switch!(PlayState.instance)
|
37
|
+
# Selected new project = set it and return
|
38
|
+
when Gosu::Kb1, Gosu::KbA then
|
39
|
+
newly_selected = Army
|
40
|
+
when Gosu::Kb2, Gosu::KbS then
|
41
|
+
newly_selected = Ship
|
42
|
+
end
|
43
|
+
|
44
|
+
# Did we get any proper answer?
|
45
|
+
if newly_selected
|
46
|
+
@unit.set_project!(newly_selected)
|
47
|
+
GameState.switch!(PlayState.instance)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def draw
|
52
|
+
# Combine parts according to if there already is some project set
|
53
|
+
unit_text = "Built so far in " + @unit.to_s + ":"
|
54
|
+
project_text = "
|
55
|
+
#{@unit.parts_built} " +
|
56
|
+
"part#{ 's' unless @unit.parts_built == 1 } of " +
|
57
|
+
@unit.project.name + " (" + @unit.build_info + ")"
|
58
|
+
options_text = "Select the project:\n
|
59
|
+
1, A – Army (#{ @unit.price_list[Army] } turns)
|
60
|
+
2, S – Ship (#{ @unit.price_list[Ship] } turns)\n
|
61
|
+
0, N – pause production
|
62
|
+
Esc – cancel change of project"
|
63
|
+
|
64
|
+
build_project = Gosu::Image.from_text(
|
65
|
+
unit_text + "\n" + project_text + "\n\n" + options_text, 20)
|
66
|
+
build_project.draw((2*TILESIZE) + XTEXT, (2*TILESIZE) + YTEXT, ZTEXT)
|
67
|
+
end
|
68
|
+
end
|
File without changes
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './welcome_state'
|
5
|
+
require_relative './win_state'
|
6
|
+
|
7
|
+
require_relative './../user_interface/cursor'
|
8
|
+
require_relative './../user_interface/infopane'
|
9
|
+
require_relative './../user_interface/map'
|
10
|
+
|
11
|
+
XTEXT = 5
|
12
|
+
YTEXT = 5
|
13
|
+
ZTILE = 0
|
14
|
+
ZUNIT = 1
|
15
|
+
ZTEXT = 2
|
16
|
+
ZCURSOR = 3
|
17
|
+
|
18
|
+
FACTIONS = 2
|
19
|
+
COLOUR = [0xff_ffffff, 0xff_ff3300, 0xff_ffcc00]
|
20
|
+
|
21
|
+
FUNCNONE = 'none'
|
22
|
+
FUNCSENTRY = 'sentry'
|
23
|
+
FUNCBUILD = 'build'
|
24
|
+
|
25
|
+
# Game state of main gameplay
|
26
|
+
class PlayState < GameState
|
27
|
+
include Singleton
|
28
|
+
|
29
|
+
attr_reader :map
|
30
|
+
attr_writer :desired_new_map
|
31
|
+
|
32
|
+
# Load new scenario or resume game
|
33
|
+
def after_start
|
34
|
+
if @desired_new_map
|
35
|
+
WinState.instance.unset_victory!
|
36
|
+
load_new_map!
|
37
|
+
help # show help after each loading of a new map
|
38
|
+
@desired_new_map = nil
|
39
|
+
|
40
|
+
next_faction_turn! # so FAC1 will be the first active faction, with announcement
|
41
|
+
else
|
42
|
+
# Make sure everything is set up
|
43
|
+
unless @infopane and @map and @cursor
|
44
|
+
abort("PlayState.after_start(): Map parts are not properly loaded
|
45
|
+
(#{@infopane}, #{@map}, #{@cursor})")
|
46
|
+
end
|
47
|
+
|
48
|
+
@cursor.info_stopped = false
|
49
|
+
|
50
|
+
# Remind player the current status
|
51
|
+
if @cursor.freeroam
|
52
|
+
@infopane.text = 'freeroam is enabled'
|
53
|
+
puts 'freeroam is enabled'
|
54
|
+
else
|
55
|
+
@cursor.info
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# What to do just before state gets deactivated
|
61
|
+
def before_end
|
62
|
+
@cursor.info_stopped = true
|
63
|
+
end
|
64
|
+
|
65
|
+
# Process given button or send it to cursor
|
66
|
+
def update(button)
|
67
|
+
case(button)
|
68
|
+
when Gosu::KbEscape then
|
69
|
+
unless WinState.instance.faction
|
70
|
+
GameState.switch!(WelcomeState.instance)
|
71
|
+
else
|
72
|
+
GameState.switch!(WinState.instance)
|
73
|
+
end
|
74
|
+
when Gosu::KbPeriod then
|
75
|
+
next_faction_turn!
|
76
|
+
when Gosu::KbH then
|
77
|
+
help
|
78
|
+
else
|
79
|
+
@cursor.update(button)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Draw all parts of main window
|
84
|
+
def draw
|
85
|
+
@map.draw_tiles
|
86
|
+
@cursor.draw
|
87
|
+
@infopane.draw
|
88
|
+
end
|
89
|
+
|
90
|
+
# Load the desired map
|
91
|
+
def load_new_map!
|
92
|
+
puts("=============\n" \
|
93
|
+
"=============\n" \
|
94
|
+
"Loading save: #{@desired_new_map}")
|
95
|
+
@infopane = Infopane.new
|
96
|
+
@map = Map.new(@desired_new_map, @infopane)
|
97
|
+
@cursor = Cursor.new(0, 0, @map, @infopane)
|
98
|
+
end
|
99
|
+
|
100
|
+
# End turn of the active faction
|
101
|
+
def next_faction_turn!
|
102
|
+
@infopane.next_faction!
|
103
|
+
|
104
|
+
# Have all factions played this turn so we are now back at the first one?
|
105
|
+
if @infopane.faction == 1
|
106
|
+
puts "=============\n" \
|
107
|
+
"End of turn\n" \
|
108
|
+
"=============\n"
|
109
|
+
@infopane.next_turn!
|
110
|
+
end
|
111
|
+
|
112
|
+
# Announce game state at the start of turn of the next faction
|
113
|
+
# TODO add change-of-active-faction screen
|
114
|
+
puts "-----------\n" + @infopane.turnscore
|
115
|
+
|
116
|
+
# Activate functions and reset moves for units of the next faction
|
117
|
+
functionable_faction_units = @map.all_units.select { |uu|
|
118
|
+
uu.faction == @infopane.faction and
|
119
|
+
uu.function != FUNCNONE
|
120
|
+
}
|
121
|
+
functionable_faction_units.each { |uu| uu.function! }
|
122
|
+
|
123
|
+
all_faction_units = @map.all_units.select { |uu|
|
124
|
+
uu.faction == @infopane.faction
|
125
|
+
}
|
126
|
+
all_faction_units.each { |uu| uu.reset_moves!}
|
127
|
+
|
128
|
+
# Win check: current faction has lost all units
|
129
|
+
if !WinState.instance.faction and all_faction_units.empty?
|
130
|
+
WinState.instance.set_victory!(
|
131
|
+
3 - @infopane.faction, # TODO more factions?
|
132
|
+
'Annihilation', @infopane.turn, @infopane.score
|
133
|
+
)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Lock the cursor to the first waiting unit
|
137
|
+
@cursor.reset!
|
138
|
+
end
|
139
|
+
|
140
|
+
# Printout the controls
|
141
|
+
def help
|
142
|
+
puts "-----------\n" \
|
143
|
+
"H: help, Esc: menu, Enter: info, " \
|
144
|
+
".: end your turn, J: switch freeroam\n" \
|
145
|
+
"QWEADZXC or arrow keys: movement, K: previous unit, L: next unit\n" \
|
146
|
+
"functions: S sentry, B build, N none\n" \
|
147
|
+
"-----------\n"
|
148
|
+
end
|
149
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
|
3
3
|
require_relative './game_state'
|
4
|
-
require_relative './
|
4
|
+
require_relative './welcome_state'
|
5
5
|
|
6
6
|
# Game state of closing the game window
|
7
|
-
class
|
7
|
+
class QuitState < GameState
|
8
8
|
include Singleton
|
9
9
|
|
10
10
|
# What to do just after state gets activated
|
@@ -13,16 +13,15 @@ class EscapeState < GameState
|
|
13
13
|
|
14
14
|
# What to do just before state gets deactivated
|
15
15
|
#def before_end
|
16
|
-
# TODO hide question?
|
17
16
|
#end
|
18
17
|
|
19
|
-
# Process given button
|
18
|
+
# Process given button
|
20
19
|
def update(button)
|
21
20
|
case(button)
|
22
21
|
when Gosu::KbY then
|
23
22
|
$window.close
|
24
23
|
when Gosu::KbN, Gosu::KbEscape then
|
25
|
-
GameState.switch!(
|
24
|
+
GameState.switch!(WelcomeState.instance)
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './welcome_state'
|
5
|
+
|
6
|
+
# Game state of settings screen
|
7
|
+
class SetState < GameState
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
# TODO move out?
|
11
|
+
attr_reader :settings
|
12
|
+
|
13
|
+
# What to do just after state gets activated
|
14
|
+
#def after_start
|
15
|
+
#end
|
16
|
+
|
17
|
+
# What to do just before state gets deactivated
|
18
|
+
#def before_end
|
19
|
+
#end
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
super
|
23
|
+
@settings = { # TODO move out?
|
24
|
+
'axis_top' => true,
|
25
|
+
'axis_bottom' => false,
|
26
|
+
'axis_left' => true,
|
27
|
+
'axis_right' => false
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
# Process given button
|
32
|
+
def update(button)
|
33
|
+
case(button)
|
34
|
+
when Gosu::Kb1, Gosu::Kb2, Gosu::Kb3, Gosu::Kb4 then
|
35
|
+
change_setting!(button)
|
36
|
+
when Gosu::KbEscape then
|
37
|
+
GameState.switch!(WelcomeState.instance)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def draw
|
42
|
+
header_text = '
|
43
|
+
/-- /// /-/ -/-
|
44
|
+
/-- ||| /-/ |
|
45
|
+
/-- ||| | -/-'
|
46
|
+
options_text = "
|
47
|
+
1 – show top axis: #{@settings['axis_top']}
|
48
|
+
2 – show bottom axis: #{@settings['axis_bottom']}
|
49
|
+
3 – show left axis: #{@settings['axis_left']}
|
50
|
+
4 – show right axis: #{@settings['axis_right']}\n
|
51
|
+
Esc – return to menu"
|
52
|
+
warning_text = '
|
53
|
+
Warning: settings are not saved
|
54
|
+
when Empi is closed'
|
55
|
+
|
56
|
+
menu = Gosu::Image.from_text(
|
57
|
+
header_text + "\n\n\n\n\n" + options_text + "\n\n\n" + warning_text, 20)
|
58
|
+
|
59
|
+
menu.draw((3*TILESIZE) + XTEXT, (2*TILESIZE) + YTEXT, ZTEXT)
|
60
|
+
end
|
61
|
+
|
62
|
+
def change_setting!(button)
|
63
|
+
changed_setting = {
|
64
|
+
Gosu::Kb1 => 'axis_top',
|
65
|
+
Gosu::Kb2 => 'axis_bottom',
|
66
|
+
Gosu::Kb3 => 'axis_left',
|
67
|
+
Gosu::Kb4 => 'axis_right'
|
68
|
+
}[button]
|
69
|
+
|
70
|
+
old_value = @settings[changed_setting]
|
71
|
+
@settings[changed_setting] = !@settings[changed_setting] # TODO other than boolean types?
|
72
|
+
puts "setting #{changed_setting} changed from #{old_value} " \
|
73
|
+
"to #{@settings[changed_setting]}"
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './play_state'
|
5
|
+
require_relative './quit_state'
|
6
|
+
require_relative './set_state'
|
7
|
+
require_relative './win_state'
|
8
|
+
|
9
|
+
# Game state of main menu
|
10
|
+
class WelcomeState < GameState
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
attr_accessor :version
|
14
|
+
|
15
|
+
# What to do just after state gets activated
|
16
|
+
#def after_start
|
17
|
+
#end
|
18
|
+
|
19
|
+
# What to do just before state gets deactivated
|
20
|
+
#def before_end
|
21
|
+
#end
|
22
|
+
|
23
|
+
# Process given button
|
24
|
+
def update(button)
|
25
|
+
case(button)
|
26
|
+
when Gosu::KbEscape then
|
27
|
+
# If there is active map go either to it or to its win screen
|
28
|
+
if PlayState.instance.map
|
29
|
+
unless WinState.instance.faction
|
30
|
+
GameState.switch!(PlayState.instance)
|
31
|
+
else
|
32
|
+
GameState.switch!(WinState.instance)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
when Gosu::Kb1, Gosu::Kb2, Gosu::Kb3 then
|
36
|
+
PlayState.instance.desired_new_map = {
|
37
|
+
Gosu::Kb1 => 'm01',
|
38
|
+
Gosu::Kb2 => 'm02',
|
39
|
+
Gosu::Kb3 => 'm03'
|
40
|
+
}[button]
|
41
|
+
GameState.switch!(PlayState.instance)
|
42
|
+
when Gosu::Kb9, Gosu::KbS then
|
43
|
+
GameState.switch!(SetState.instance)
|
44
|
+
when Gosu::Kb0, Gosu::KbQ then
|
45
|
+
GameState.switch!(QuitState.instance)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def draw
|
50
|
+
header_text = '
|
51
|
+
/-- /// /-/ -/-
|
52
|
+
/-- ||| /-/ |
|
53
|
+
/-- ||| | -/-'
|
54
|
+
|
55
|
+
# Is there active map? Is it won?
|
56
|
+
if PlayState.instance.map
|
57
|
+
unless WinState.instance.faction
|
58
|
+
resume_text = "
|
59
|
+
Esc – resume"
|
60
|
+
else
|
61
|
+
resume_text = "
|
62
|
+
Esc – return to victory screen"
|
63
|
+
end
|
64
|
+
else
|
65
|
+
resume_text = "\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
options_text = "
|
69
|
+
1 – start new: Map 01
|
70
|
+
2 – start new: Map 02
|
71
|
+
3 – start new: Map 03\n
|
72
|
+
9, S – settings
|
73
|
+
0, Q – quit"
|
74
|
+
|
75
|
+
version_text = "
|
76
|
+
version #{self.version}"
|
77
|
+
|
78
|
+
menu = Gosu::Image.from_text(
|
79
|
+
header_text + "\n\n\n" +
|
80
|
+
resume_text + "\n" +
|
81
|
+
options_text + "\n\n\n\n\n\n\n\n" +
|
82
|
+
version_text, 20)
|
83
|
+
menu.draw((3*TILESIZE) + XTEXT, (2*TILESIZE) + YTEXT, ZTEXT)
|
84
|
+
end
|
85
|
+
end
|