empi 0.17 → 0.22.3
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/lib/empi.rb +22 -108
- data/lib/lib/game_states/build_state.rb +82 -0
- data/lib/lib/game_states/escape_state.rb +34 -0
- data/lib/lib/game_states/game_state.rb +27 -0
- data/lib/lib/game_states/play_state.rb +100 -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/{unit.rb → lib/units/unit.rb} +103 -106
- data/lib/lib/units/unitFunction.rb +63 -0
- data/lib/lib/user_interface/cursor.rb +168 -0
- data/lib/{infopane.rb → lib/user_interface/infopane.rb} +7 -5
- data/lib/{map.rb → lib/user_interface/map.rb} +32 -37
- data/lib/{tile.rb → lib/user_interface/tile.rb} +7 -4
- data/lib/media/Empi v18.png +0 -0
- data/lib/save/m02-err.esf +26 -0
- metadata +40 -37
- data/lib/cursor.rb +0 -103
- data/lib/docu/Empi v14.png +0 -0
- data/lib/docu/info.txt +0 -219
- data/lib/town.rb +0 -28
- data/lib/unitFunction.rb +0 -47
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6ad13787b5a8797ab609b5b7a907cf5c496eaeb1e6dd6f6cca7d639eeb8ea806
|
4
|
+
data.tar.gz: 260e7ffb1be2609e55edef0e37fe1d74409a107f15b269472154514ada633f36
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 138cf192068da984a0a415346d9210ef81e20c968bf86f4c0a37dd71201ec233eb224e1aa400a5199143badbf649e2c45a1dd7fafa33aecc2afcbc8e58a27a19
|
7
|
+
data.tar.gz: 971e0ec6b97089ede1598648cb114cecdcd88a6fceb49a90fd9da162539afc50896569ae08bc394676dda6c5a833db6dedab9216173d4ed6100dc3759daeec00
|
data/lib/empi.rb
CHANGED
@@ -1,146 +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/play_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.22 dev'
|
40
23
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
new_turn
|
24
|
+
# Activate first state
|
25
|
+
$window = self
|
26
|
+
GameState.switch!(PlayState.instance)
|
46
27
|
end
|
47
28
|
|
29
|
+
# Catch the released button
|
48
30
|
def button_up(key)
|
49
31
|
@button = key
|
50
|
-
|
51
|
-
case(key)
|
52
|
-
when Gosu::KbEscape then
|
53
|
-
close
|
54
|
-
when Gosu::KbPeriod then
|
55
|
-
new_turn
|
56
|
-
when Gosu::KbH then
|
57
|
-
help
|
58
|
-
when Gosu::KbJ then
|
59
|
-
unit_to_move = 0
|
60
|
-
@cursor.switch_freeroam
|
61
|
-
end
|
62
32
|
end
|
63
33
|
|
64
|
-
# Process given button to
|
34
|
+
# Process given button according to current state
|
65
35
|
def update
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# If there are any movable units without functions select one of them with the cursor
|
70
|
-
if @cursor.freeroam == false && movable_units.size > 0
|
71
|
-
unit_to_move = movable_units[0]
|
72
|
-
unit_to_move.update(@button)
|
73
|
-
|
74
|
-
# Can it still move?
|
75
|
-
if unit_to_move.can_move? && unit_to_move.function == FUNCNONE
|
76
|
-
# Move the cursor to it unless it is already there
|
77
|
-
if (@cursor.x != unit_to_move.x \
|
78
|
-
|| @cursor.y != unit_to_move.y)
|
79
|
-
@cursor.warp(unit_to_move.x, unit_to_move.y)
|
80
|
-
end
|
81
|
-
@cursor.info
|
82
|
-
else
|
83
|
-
# Was that the last currently avaiable non-function move?
|
84
|
-
movable_units = @map.all_units.select { |uu| uu.can_move? && uu.function == FUNCNONE}
|
85
|
-
if movable_units.size == 0
|
86
|
-
puts 'all movable units without functions moved'
|
87
|
-
@cursor.switch_freeroam
|
88
|
-
else
|
89
|
-
# Move cursor to next avaiable unit
|
90
|
-
unit_to_move = movable_units[0]
|
91
|
-
@cursor.warp(unit_to_move.x, unit_to_move.y)
|
92
|
-
@cursor.info
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
else
|
97
|
-
# Cursor in freeroam mode
|
98
|
-
@cursor.update(@button)
|
36
|
+
# No (new) keys
|
37
|
+
unless @button == BUTTON_PROCESSED || @button.nil?
|
38
|
+
@state.update(@button)
|
99
39
|
end
|
100
40
|
end
|
101
41
|
|
102
42
|
# Draw only after some button was released and in the start
|
103
43
|
def needs_redraw?
|
104
|
-
@button !=
|
44
|
+
@button != BUTTON_PROCESSED
|
105
45
|
end
|
106
46
|
|
47
|
+
# Draw according to current state
|
107
48
|
def draw
|
108
|
-
@button = -1 # use each button just once
|
109
|
-
|
110
|
-
# Draw map tiles and units
|
111
|
-
@map.draw_tiles
|
112
|
-
@map.draw_units
|
113
|
-
# DEBUG @map.all_units.each { |uu| puts uu.info}
|
114
|
-
|
115
|
-
@cursor.draw
|
116
|
-
@infopane.draw
|
117
|
-
|
118
|
-
# @message = Gosu::Image.from_text(
|
119
|
-
# self, "Empire", Gosu.default_font_name, 20)
|
120
|
-
# @message.draw(10, 10, 2)
|
121
|
-
end
|
122
49
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
functionable_units = @map.all_units.select { |uu| uu.function != FUNCNONE}
|
129
|
-
functionable_units.each { |uu| uu.function! }
|
130
|
-
|
131
|
-
@map.all_units.each { |uu| uu.reset_moves!}
|
132
|
-
@infopane.next_turn
|
133
|
-
end
|
134
|
-
|
135
|
-
def help
|
136
|
-
puts "----------\n" \
|
137
|
-
"QWEADZXC movement, h help, Enter info, j switch freeroam\n" \
|
138
|
-
"functions: s sentry, n none\n" \
|
139
|
-
"----------\n"
|
50
|
+
@button = BUTTON_PROCESSED # draw just once after each button release
|
51
|
+
unless $window.state.nil?
|
52
|
+
@state.draw
|
53
|
+
end
|
140
54
|
end
|
141
55
|
end
|
142
56
|
|
143
57
|
# ---------------------------------------------------------------
|
144
58
|
|
145
|
-
window = GameWindow.new
|
146
|
-
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)
|
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,34 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './play_state'
|
5
|
+
|
6
|
+
# Game state of closing the game window
|
7
|
+
class EscapeState < 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
|
+
# TODO hide question?
|
17
|
+
#end
|
18
|
+
|
19
|
+
# Process given button to cursor
|
20
|
+
def update(button)
|
21
|
+
case(button)
|
22
|
+
when Gosu::KbY then
|
23
|
+
$window.close
|
24
|
+
when Gosu::KbN, Gosu::KbEscape then
|
25
|
+
GameState.switch!(PlayState.instance) # TODO return to state that called you
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def draw
|
30
|
+
confirmation = Gosu::Image.from_text(
|
31
|
+
"Are you sure you want to quit? Y/N", 20)
|
32
|
+
confirmation.draw((3*TILESIZE) + XTEXT, (4*TILESIZE) + YTEXT, ZTEXT)
|
33
|
+
end
|
34
|
+
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,100 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
require_relative './game_state'
|
4
|
+
require_relative './escape_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
|
+
# Load new scenario or resume game
|
30
|
+
def after_start
|
31
|
+
unless @infopane and @map and @cursor # is everything set up yet?
|
32
|
+
@infopane = Infopane.new
|
33
|
+
@map = Map.new(@infopane)
|
34
|
+
@cursor = Cursor.new(0, 0, @map, @infopane)
|
35
|
+
help # show help after loading of map
|
36
|
+
new_turn
|
37
|
+
else
|
38
|
+
@cursor.info_stopped = false
|
39
|
+
|
40
|
+
# Remind player the current status
|
41
|
+
if @cursor.freeroam
|
42
|
+
@infopane.text = 'freeroam is enabled'
|
43
|
+
puts 'freeroam is enabled'
|
44
|
+
else
|
45
|
+
@cursor.info
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# What to do just before state gets deactivated
|
51
|
+
def before_end
|
52
|
+
@cursor.info_stopped = true
|
53
|
+
end
|
54
|
+
|
55
|
+
# Process given button or send it to cursor
|
56
|
+
def update(button)
|
57
|
+
case(button)
|
58
|
+
when Gosu::KbEscape then
|
59
|
+
GameState.switch!(EscapeState.instance)
|
60
|
+
when Gosu::KbPeriod then
|
61
|
+
new_turn
|
62
|
+
when Gosu::KbH then
|
63
|
+
help
|
64
|
+
else
|
65
|
+
@cursor.update(button)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Draw all parts of main window
|
70
|
+
def draw
|
71
|
+
@map.draw_tiles
|
72
|
+
@cursor.draw
|
73
|
+
@infopane.draw
|
74
|
+
end
|
75
|
+
|
76
|
+
# End current turn and start the next one
|
77
|
+
def new_turn
|
78
|
+
puts "=============\n" \
|
79
|
+
"End of turn\n" \
|
80
|
+
"=============\n"
|
81
|
+
|
82
|
+
functionable_units = @map.all_units.select { |uu| uu.function != FUNCNONE}
|
83
|
+
functionable_units.each { |uu| uu.function! }
|
84
|
+
|
85
|
+
@map.all_units.each { |uu| uu.reset_moves!}
|
86
|
+
@infopane.next_turn
|
87
|
+
|
88
|
+
@cursor.freeroam = true
|
89
|
+
@cursor.switch_freeroam! # so freeroam = false, with messages
|
90
|
+
end
|
91
|
+
|
92
|
+
# Printout the controls
|
93
|
+
def help
|
94
|
+
puts "-----------\n" \
|
95
|
+
"h: help, Esc: end game, Enter: info, j: switch freeroam\n" \
|
96
|
+
"QWEADZXC or arrow keys: movement, .: end turn\n" \
|
97
|
+
"functions: s sentry, b build, n none\n" \
|
98
|
+
"-----------\n"
|
99
|
+
end
|
100
|
+
end
|
@@ -1,13 +1,16 @@
|
|
1
1
|
require_relative './unit'
|
2
2
|
|
3
3
|
class Army < Unit
|
4
|
+
@name = 'army'
|
5
|
+
@map_symbol = 'A'
|
6
|
+
@price = 3
|
7
|
+
@value = 5
|
8
|
+
|
4
9
|
def initialize(x, y, faction, map, infopane)
|
5
10
|
super
|
6
11
|
dir_path = File.dirname(__FILE__)
|
7
|
-
@image = Gosu::Image.new(dir_path + '
|
12
|
+
@image = Gosu::Image.new(dir_path + '/../../media/army.png')
|
8
13
|
|
9
|
-
@name = 'army'
|
10
|
-
@value = 5
|
11
14
|
@armor_left = @armor_max = 3
|
12
15
|
@moves_max = 5
|
13
16
|
end
|
@@ -1,13 +1,16 @@
|
|
1
1
|
require_relative './unit'
|
2
2
|
|
3
3
|
class Ship < Unit
|
4
|
+
@name = 'ship'
|
5
|
+
@map_symbol = 'S'
|
6
|
+
@price = 5
|
7
|
+
@value = 10
|
8
|
+
|
4
9
|
def initialize(x, y, faction, map, infopane)
|
5
10
|
super
|
6
11
|
dir_path = File.dirname(__FILE__)
|
7
|
-
@image = Gosu::Image.new(dir_path + '
|
12
|
+
@image = Gosu::Image.new(dir_path + '/../../media/ship.png')
|
8
13
|
|
9
|
-
@name = 'ship'
|
10
|
-
@value = 10
|
11
14
|
@armor_left = @armor_max = 1
|
12
15
|
@moves_max = 2
|
13
16
|
@cargo_max = 3
|