empi 0.18 → 0.23
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 +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
|