empi 0.18 → 0.23
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 +4 -4
- data/lib/empi.rb +22 -75
- data/lib/lib/game_states/build_state.rb +82 -0
- data/lib/lib/game_states/game_state.rb +27 -0
- data/lib/lib/game_states/play_state.rb +135 -0
- data/lib/lib/game_states/quit_state.rb +33 -0
- data/lib/lib/game_states/welcome_state.rb +64 -0
- data/lib/{army.rb → lib/units/army.rb} +6 -3
- data/lib/{ship.rb → lib/units/ship.rb} +6 -3
- data/lib/lib/units/town.rb +106 -0
- data/lib/lib/units/unit.rb +301 -0
- data/lib/lib/units/unitFunction.rb +63 -0
- data/lib/lib/user_interface/cursor.rb +184 -0
- data/lib/lib/user_interface/infopane.rb +49 -0
- data/lib/{map.rb → lib/user_interface/map.rb} +32 -26
- data/lib/{tile.rb → lib/user_interface/tile.rb} +2 -2
- data/lib/docu/Empi v18.png b/data/lib/media/Empi → v18.png +0 -0
- data/lib/save/m02-err.esf +26 -0
- metadata +26 -18
- data/lib/cursor.rb +0 -183
- data/lib/docu/Empi v14.png +0 -0
- data/lib/docu/Empi v18 - printouts.png +0 -0
- data/lib/docu/info.txt +0 -282
- data/lib/infopane.rb +0 -36
- data/lib/town.rb +0 -28
- data/lib/unit.rb +0 -238
- data/lib/unitFunction.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7a7e44ce8aebd925aac9b87c2344c2ddfb75dc7e12b2d2d61d584c6c4ca2477
|
4
|
+
data.tar.gz: edc23d080b7c85249fd869b4571c6c42eff315a2a5ddee93720b5f7c9aa09004
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22293eedf9f530feafdc018936a37399c2c4ac975c65e00f4b32ffa4c27a79e912d1e2c5e3d0189d464b348b8f0aebc9b5c2955f7b616daadd813afc9f6e5a11
|
7
|
+
data.tar.gz: 4701285d5bb8aa354afd9d766e4b2012489822aaa0e3c59cc3c6b9ae6f9cb3a7c61ab521d142e425bfb582c6fa2c6ef86dc10a5fdb1a785a03ecf2de4a97c4f9
|
data/lib/empi.rb
CHANGED
@@ -1,113 +1,60 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'gosu'
|
3
3
|
|
4
|
-
require_relative './
|
5
|
-
require_relative './
|
6
|
-
require_relative './infopane'
|
7
|
-
require_relative './map'
|
8
|
-
require_relative './tile'
|
9
|
-
require_relative './ship'
|
10
|
-
require_relative './town'
|
4
|
+
require_relative './lib/game_states/game_state'
|
5
|
+
require_relative './lib/game_states/welcome_state'
|
11
6
|
|
12
7
|
TILESIZE = 50
|
13
8
|
MAPX = 10
|
14
9
|
MAPY = 10
|
15
10
|
|
16
|
-
XTEXT = 5
|
17
|
-
YTEXT = 5
|
18
|
-
|
19
|
-
ZTILE = 0
|
20
|
-
ZUNIT = 1
|
21
|
-
ZTEXT = 2
|
22
|
-
ZCURSOR = 3
|
23
|
-
|
24
|
-
FACTIONS = 2
|
25
|
-
COLOUR = [0xff_ffffff, 0xff_ff3300, 0xff_ffcc00]
|
26
|
-
|
27
|
-
FUNCNONE = 'none'
|
28
|
-
FUNCSENTRY = 'sentry'
|
29
|
-
FUNCBUILD = 'build'
|
30
|
-
|
31
11
|
PROMPT = '> '
|
12
|
+
BUTTON_PROCESSED = -1
|
32
13
|
|
33
14
|
# Main class
|
34
15
|
class GameWindow < Gosu::Window
|
16
|
+
attr_accessor :state
|
17
|
+
|
35
18
|
def initialize(width = (MAPX + 1) * TILESIZE, \
|
36
19
|
height = (MAPY + 2) * TILESIZE, \
|
37
20
|
fullscreen = false)
|
38
21
|
super
|
39
|
-
self.caption = 'Empi: Ruby Edition 0.
|
22
|
+
self.caption = 'Empi: Ruby Edition 0.23'
|
40
23
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
help # show help after loading of map
|
45
|
-
new_turn
|
24
|
+
# Activate first state
|
25
|
+
$window = self
|
26
|
+
GameState.switch!(WelcomeState.instance)
|
46
27
|
end
|
47
28
|
|
29
|
+
# Catch the released button
|
48
30
|
def button_up(key)
|
49
31
|
@button = key
|
50
32
|
end
|
51
33
|
|
52
|
-
# Process given button to
|
34
|
+
# Process given button according to current state
|
53
35
|
def update
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
when Gosu::KbEscape then
|
58
|
-
close
|
59
|
-
when Gosu::KbPeriod then
|
60
|
-
new_turn
|
61
|
-
when Gosu::KbH then
|
62
|
-
help
|
63
|
-
when Gosu::KbJ then
|
64
|
-
@cursor.switch_freeroam!
|
65
|
-
else
|
66
|
-
@cursor.update(@button)
|
36
|
+
# No (new) keys
|
37
|
+
unless @button == BUTTON_PROCESSED || @button.nil?
|
38
|
+
@state.update(@button)
|
67
39
|
end
|
68
40
|
end
|
69
41
|
|
70
42
|
# Draw only after some button was released and in the start
|
71
43
|
def needs_redraw?
|
72
|
-
@button !=
|
44
|
+
@button != BUTTON_PROCESSED
|
73
45
|
end
|
74
46
|
|
47
|
+
# Draw according to current state
|
75
48
|
def draw
|
76
|
-
@button = -1 # draw just once after each button press
|
77
|
-
|
78
|
-
@map.draw_tiles
|
79
|
-
@cursor.draw
|
80
|
-
@infopane.draw
|
81
|
-
|
82
|
-
# DEBUG @map.all_units.each { |uu| puts uu.info}
|
83
|
-
end
|
84
|
-
|
85
|
-
# End current turn and start the next one
|
86
|
-
def new_turn
|
87
|
-
puts "=============\n" \
|
88
|
-
"End of turn\n" \
|
89
|
-
"=============\n"
|
90
|
-
|
91
|
-
functionable_units = @map.all_units.select { |uu| uu.function != FUNCNONE}
|
92
|
-
functionable_units.each { |uu| uu.function! }
|
93
|
-
|
94
|
-
@map.all_units.each { |uu| uu.reset_moves!}
|
95
|
-
@infopane.next_turn
|
96
49
|
|
97
|
-
@
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
def help
|
102
|
-
puts "-----------\n" \
|
103
|
-
"h: help, Esc: end game, Enter: info, j: switch freeroam\n" \
|
104
|
-
"QWEADZXC or arrow keys: movement, .: end turn\n" \
|
105
|
-
"functions: s sentry, n none\n" \
|
106
|
-
"-----------\n"
|
50
|
+
@button = BUTTON_PROCESSED # draw just once after each button release
|
51
|
+
unless $window.state.nil?
|
52
|
+
@state.draw
|
53
|
+
end
|
107
54
|
end
|
108
55
|
end
|
109
56
|
|
110
57
|
# ---------------------------------------------------------------
|
111
58
|
|
112
|
-
window = GameWindow.new
|
113
|
-
window.show
|
59
|
+
$window = GameWindow.new
|
60
|
+
$window.show
|
@@ -0,0 +1,82 @@
|
|
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 closing the game window
|
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
|
+
# TODO hide question?
|
22
|
+
#end
|
23
|
+
|
24
|
+
# Process given button to cursor
|
25
|
+
def update(button)
|
26
|
+
project = nil
|
27
|
+
|
28
|
+
case(button)
|
29
|
+
when Gosu::KbEscape then
|
30
|
+
# If there was no project selected before then behave same as "none" option
|
31
|
+
unless @unit.project
|
32
|
+
reset_function!()
|
33
|
+
else
|
34
|
+
puts PROMPT + @unit.to_s + ": cancelling, nothing changed"
|
35
|
+
GameState.switch!(PlayState.instance)
|
36
|
+
end
|
37
|
+
when Gosu::Kb0, Gosu::KbN then
|
38
|
+
reset_function!()
|
39
|
+
when Gosu::Kb1, Gosu::KbA then
|
40
|
+
project = Army
|
41
|
+
when Gosu::Kb2, Gosu::KbS then
|
42
|
+
project = Ship
|
43
|
+
end
|
44
|
+
|
45
|
+
# Did we get any proper answer?
|
46
|
+
if project
|
47
|
+
@unit.set_project!(project)
|
48
|
+
GameState.switch!(PlayState.instance)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# If "none" project was selected reset also the function
|
53
|
+
def reset_function!()
|
54
|
+
puts PROMPT + @unit.to_s + ": no project selected, resetting function"
|
55
|
+
@unit.set_function!(FUNCNONE, @unit.faction)
|
56
|
+
GameState.switch!(PlayState.instance)
|
57
|
+
end
|
58
|
+
|
59
|
+
def draw
|
60
|
+
# Combine parts according to if there already is some project set
|
61
|
+
unit_text = "Built so far in " + @unit.to_s + ":"
|
62
|
+
if @unit.project
|
63
|
+
project_text = "
|
64
|
+
#{@unit.parts_built} " +
|
65
|
+
"part#{ 's' unless @unit.parts_built == 1 } of " +
|
66
|
+
@unit.project.name + " (" + @unit.build_info + ")"
|
67
|
+
else
|
68
|
+
project_text = "
|
69
|
+
no project selected"
|
70
|
+
end
|
71
|
+
|
72
|
+
options_text = "Select the project:\n
|
73
|
+
1, A – Army (#{ @unit.price_list[Army] } turns)
|
74
|
+
2, S – Ship (#{ @unit.price_list[Ship] } turns)\n
|
75
|
+
0, N – none
|
76
|
+
Esc – cancel project #{ @unit.project ? 'change' : 'setup'}"
|
77
|
+
|
78
|
+
build_project = Gosu::Image.from_text(
|
79
|
+
unit_text + "\n" + project_text + "\n\n" + options_text, 20)
|
80
|
+
build_project.draw((2*TILESIZE) + XTEXT, (2*TILESIZE) + YTEXT, ZTEXT)
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Managing of active game states
|
2
|
+
class GameState
|
3
|
+
# Switch active state to next one
|
4
|
+
def self.switch!(next_state)
|
5
|
+
#puts 'DEBUG: switching to state ' + next_state.to_s
|
6
|
+
|
7
|
+
unless $window.state.nil?
|
8
|
+
$window.state.before_end
|
9
|
+
end
|
10
|
+
$window.state = next_state
|
11
|
+
$window.state.after_start
|
12
|
+
end
|
13
|
+
|
14
|
+
# What to do just after state gets activated
|
15
|
+
def after_start
|
16
|
+
end
|
17
|
+
|
18
|
+
# What to do just before state gets deactivated
|
19
|
+
def before_end
|
20
|
+
end
|
21
|
+
|
22
|
+
def update(button)
|
23
|
+
end
|
24
|
+
|
25
|
+
def draw
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './welcome_state'
|
5
|
+
|
6
|
+
require_relative './../user_interface/cursor'
|
7
|
+
require_relative './../user_interface/infopane'
|
8
|
+
require_relative './../user_interface/map'
|
9
|
+
|
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
|
+
load_new_map!
|
36
|
+
help # show help after each loading of a new map
|
37
|
+
@desired_new_map = nil
|
38
|
+
|
39
|
+
next_faction_turn! # so FAC1 will be the first active faction, with announcement
|
40
|
+
else
|
41
|
+
# Make sure everything is set up
|
42
|
+
unless @infopane and @map and @cursor
|
43
|
+
abort("PlayState.after_start(): Map parts are not properly loaded
|
44
|
+
(#{@infopane}, #{@map}, #{@cursor})")
|
45
|
+
end
|
46
|
+
|
47
|
+
@cursor.info_stopped = false
|
48
|
+
|
49
|
+
# Remind player the current status
|
50
|
+
if @cursor.freeroam
|
51
|
+
@infopane.text = 'freeroam is enabled'
|
52
|
+
puts 'freeroam is enabled'
|
53
|
+
else
|
54
|
+
@cursor.info
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# What to do just before state gets deactivated
|
60
|
+
def before_end
|
61
|
+
@cursor.info_stopped = true
|
62
|
+
end
|
63
|
+
|
64
|
+
# Process given button or send it to cursor
|
65
|
+
def update(button)
|
66
|
+
case(button)
|
67
|
+
when Gosu::KbEscape then
|
68
|
+
GameState.switch!(WelcomeState.instance)
|
69
|
+
when Gosu::KbPeriod then
|
70
|
+
next_faction_turn!
|
71
|
+
when Gosu::KbH then
|
72
|
+
help
|
73
|
+
else
|
74
|
+
@cursor.update(button)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Draw all parts of main window
|
79
|
+
def draw
|
80
|
+
@map.draw_tiles
|
81
|
+
@cursor.draw
|
82
|
+
@infopane.draw
|
83
|
+
end
|
84
|
+
|
85
|
+
# Load the desired map
|
86
|
+
def load_new_map!
|
87
|
+
puts("=============\n" \
|
88
|
+
"=============\n" \
|
89
|
+
"Loading save: #{@desired_new_map}")
|
90
|
+
@infopane = Infopane.new
|
91
|
+
@map = Map.new(@desired_new_map, @infopane)
|
92
|
+
@cursor = Cursor.new(0, 0, @map, @infopane)
|
93
|
+
end
|
94
|
+
|
95
|
+
# End turn of the active faction
|
96
|
+
def next_faction_turn!
|
97
|
+
@infopane.next_faction!
|
98
|
+
|
99
|
+
# Have all factions played this turn so we are now back at the first one?
|
100
|
+
if @infopane.faction == 1
|
101
|
+
puts "=============\n" \
|
102
|
+
"End of turn\n" \
|
103
|
+
"=============\n"
|
104
|
+
@infopane.next_turn!
|
105
|
+
end
|
106
|
+
|
107
|
+
# Announce game state at the start of turn of the next faction
|
108
|
+
# TODO add change-of-active-faction screen
|
109
|
+
puts "-----------\n" + @infopane.turnscore
|
110
|
+
|
111
|
+
# Activate functions and reset moves for units of the next faction
|
112
|
+
functionable_faction_units = @map.all_units.select { |uu|
|
113
|
+
uu.faction == @infopane.faction and
|
114
|
+
uu.function != FUNCNONE
|
115
|
+
}
|
116
|
+
functionable_faction_units.each { |uu| uu.function! }
|
117
|
+
|
118
|
+
all_faction_units = @map.all_units.select { |uu|
|
119
|
+
uu.faction == @infopane.faction
|
120
|
+
}
|
121
|
+
all_faction_units.each { |uu| uu.reset_moves!}
|
122
|
+
|
123
|
+
# Lock the cursor to the first waiting unit
|
124
|
+
@cursor.reset!
|
125
|
+
end
|
126
|
+
|
127
|
+
# Printout the controls
|
128
|
+
def help
|
129
|
+
puts "-----------\n" \
|
130
|
+
"h: help, Esc: menu, Enter: info, j: switch freeroam\n" \
|
131
|
+
"QWEADZXC or arrow keys: movement, .: end your turn\n" \
|
132
|
+
"functions: s sentry, b build, n none\n" \
|
133
|
+
"-----------\n"
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './welcome_state'
|
5
|
+
|
6
|
+
# Game state of closing the game window
|
7
|
+
class QuitState < GameState
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
# What to do just after state gets activated
|
11
|
+
#def after_start
|
12
|
+
#end
|
13
|
+
|
14
|
+
# What to do just before state gets deactivated
|
15
|
+
#def before_end
|
16
|
+
#end
|
17
|
+
|
18
|
+
# Process given button to cursor
|
19
|
+
def update(button)
|
20
|
+
case(button)
|
21
|
+
when Gosu::KbY then
|
22
|
+
$window.close
|
23
|
+
when Gosu::KbN, Gosu::KbEscape then
|
24
|
+
GameState.switch!(WelcomeState.instance)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def draw
|
29
|
+
confirmation = Gosu::Image.from_text(
|
30
|
+
"Are you sure you want to quit? Y/N", 20)
|
31
|
+
confirmation.draw((3*TILESIZE) + XTEXT, (4*TILESIZE) + YTEXT, ZTEXT)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './play_state'
|
5
|
+
require_relative './quit_state'
|
6
|
+
|
7
|
+
# Game state of closing the game window
|
8
|
+
class WelcomeState < GameState
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
# What to do just after state gets activated
|
12
|
+
#def after_start
|
13
|
+
#end
|
14
|
+
|
15
|
+
# What to do just before state gets deactivated
|
16
|
+
#def before_end
|
17
|
+
#end
|
18
|
+
|
19
|
+
# Process given button to cursor
|
20
|
+
def update(button)
|
21
|
+
case(button)
|
22
|
+
when Gosu::Kb0, Gosu::KbQ then
|
23
|
+
GameState.switch!(QuitState.instance)
|
24
|
+
when Gosu::KbEscape then
|
25
|
+
if PlayState.instance.map
|
26
|
+
GameState.switch!(PlayState.instance)
|
27
|
+
end
|
28
|
+
when Gosu::Kb1, Gosu::Kb2, Gosu::Kb3 then
|
29
|
+
PlayState.instance.desired_new_map = {
|
30
|
+
Gosu::Kb1 => 'm01',
|
31
|
+
Gosu::Kb2 => 'm02',
|
32
|
+
Gosu::Kb3 => 'm03'
|
33
|
+
}[button]
|
34
|
+
GameState.switch!(PlayState.instance)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def draw
|
39
|
+
header_text = '
|
40
|
+
/-- /// /-/ -/-
|
41
|
+
/-- ||| /-/ |
|
42
|
+
/-- ||| | -/-'
|
43
|
+
|
44
|
+
if PlayState.instance.map # some map is loaded
|
45
|
+
space_text = "\n\n\n"
|
46
|
+
options_text = "
|
47
|
+
Esc – Resume"
|
48
|
+
else
|
49
|
+
space_text = "\n\n\n\n"
|
50
|
+
options_text = ""
|
51
|
+
end
|
52
|
+
|
53
|
+
options_text += "
|
54
|
+
1 – Start New: Map 01
|
55
|
+
2 – Start New: Map 02
|
56
|
+
3 – Start New: Map 03\n
|
57
|
+
0, Q – Quit"
|
58
|
+
|
59
|
+
menu = Gosu::Image.from_text(
|
60
|
+
header_text + space_text + options_text, 20)
|
61
|
+
|
62
|
+
menu.draw((3*TILESIZE) + XTEXT, (2*TILESIZE) + YTEXT, ZTEXT)
|
63
|
+
end
|
64
|
+
end
|