empi 0.17 → 0.22.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|