empi 0.19 → 0.24
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 +68 -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} +7 -4
- data/lib/{ship.rb → lib/units/ship.rb} +7 -4
- data/lib/lib/units/town.rb +108 -0
- data/lib/{unit.rb → lib/units/unit.rb} +66 -41
- data/lib/{unitFunction.rb → lib/units/unitFunction.rb} +15 -6
- data/lib/lib/user_interface/cursor.rb +190 -0
- data/lib/lib/user_interface/infopane.rb +49 -0
- data/lib/{map.rb → lib/user_interface/map.rb} +31 -25
- data/lib/lib/user_interface/tile.rb +52 -0
- data/lib/docu/Empi v18.png b/data/lib/media/Empi → v18.png +0 -0
- metadata +30 -20
- data/lib/cursor.rb +0 -166
- data/lib/docu/info.txt +0 -372
- data/lib/infopane.rb +0 -36
- data/lib/tile.rb +0 -36
- data/lib/town.rb +0 -77
@@ -1,14 +1,17 @@
|
|
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
|
-
@
|
10
|
-
@value = 5
|
11
|
-
@armor_left = @armor_max = 3
|
14
|
+
@armour_left = @armour_max = 3
|
12
15
|
@moves_max = 5
|
13
16
|
end
|
14
17
|
|
@@ -1,14 +1,17 @@
|
|
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
|
-
@
|
10
|
-
@value = 10
|
11
|
-
@armor_left = @armor_max = 1
|
14
|
+
@armour_left = @armour_max = 1
|
12
15
|
@moves_max = 2
|
13
16
|
@cargo_max = 3
|
14
17
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require_relative './army'
|
2
|
+
require_relative './ship'
|
3
|
+
require_relative './unit'
|
4
|
+
|
5
|
+
require_relative './../game_states/game_state'
|
6
|
+
require_relative './../game_states/build_state'
|
7
|
+
|
8
|
+
class Town < Unit
|
9
|
+
@name = 'town'
|
10
|
+
@map_symbol = 'T'
|
11
|
+
@value = 20
|
12
|
+
|
13
|
+
attr_accessor :project, :parts_built, :parts_needed
|
14
|
+
|
15
|
+
def initialize(x, y, faction, map, infopane)
|
16
|
+
super
|
17
|
+
dir_path = File.dirname(__FILE__)
|
18
|
+
@image = Gosu::Image.new(dir_path + '/../../media/town.png')
|
19
|
+
|
20
|
+
@armour_left = @armour_max = 1
|
21
|
+
@moves_max = 0
|
22
|
+
@cargo_max = 10
|
23
|
+
|
24
|
+
@starting_project = Army unless @faction == 0 # used once at the game start
|
25
|
+
@default_project = Army # used after capture
|
26
|
+
@project = nil
|
27
|
+
@parts_built = 0
|
28
|
+
@parts_needed = 0
|
29
|
+
|
30
|
+
set_function!(FUNCBUILD, @faction) unless @faction == 0
|
31
|
+
end
|
32
|
+
|
33
|
+
def can_build?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def can_be_captured?
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
# Tell the state of current build project
|
42
|
+
def build_info
|
43
|
+
"#{@parts_built}/#{@parts_needed}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# Process capture targeted at this town and reset build process
|
47
|
+
def capture!(by_whom)
|
48
|
+
super
|
49
|
+
|
50
|
+
# Reset build process
|
51
|
+
# 1) remove old project so that it is not disclosed
|
52
|
+
# 2) set default project so that there is always some set (remove old parts)
|
53
|
+
# 3) offer change of the project to the new owner
|
54
|
+
@function.func = FUNCNONE
|
55
|
+
@project = nil
|
56
|
+
set_project!(@default_project)
|
57
|
+
set_function!(FUNCBUILD, @faction)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Set desired function and possibly also project
|
61
|
+
def set_function!(func, commanding_faction)
|
62
|
+
super
|
63
|
+
|
64
|
+
if @faction != 0 and commanding_faction == @faction and func == FUNCBUILD
|
65
|
+
# Set starting project once or ask player about next project
|
66
|
+
if @starting_project
|
67
|
+
set_project!(@starting_project)
|
68
|
+
@starting_project = nil
|
69
|
+
else
|
70
|
+
GameState.switch!(BuildState.instance)
|
71
|
+
BuildState.instance.unit = self
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Set desired project
|
77
|
+
def set_project!(desired_project)
|
78
|
+
unless price_list.key?(desired_project)
|
79
|
+
abort("town.set_project!(): Unknown project (#{desired_project})")
|
80
|
+
end
|
81
|
+
@parts_needed = price_list[desired_project]
|
82
|
+
|
83
|
+
# Compare new setting with the old one
|
84
|
+
if desired_project == @project
|
85
|
+
puts PROMPT + to_s + ": project has already been set to #{@project.name} (#{build_info} done)"
|
86
|
+
else
|
87
|
+
previous_project = @project
|
88
|
+
@project = desired_project
|
89
|
+
lost_parts = @parts_built
|
90
|
+
@parts_built = 0
|
91
|
+
|
92
|
+
new_project_set_text = PROMPT + to_s + ": project set to #{@project.name} (#{build_info} done)"
|
93
|
+
if previous_project and lost_parts > 0 # parts were lost but not due to capture
|
94
|
+
puts new_project_set_text + ", losing #{lost_parts} " +
|
95
|
+
"part#{ 's' unless lost_parts == 1 } of #{previous_project.name}"
|
96
|
+
else
|
97
|
+
puts new_project_set_text
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Load all prices
|
103
|
+
def price_list
|
104
|
+
prices = Hash[
|
105
|
+
[Army, Ship].collect { |ii| [ii, ii.price] } # TODO all subclasses of Unit which can_be_built?
|
106
|
+
]
|
107
|
+
end
|
108
|
+
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require_relative './unitFunction'
|
2
2
|
|
3
|
-
PARTS_TO_BE_BUILT = 0
|
4
|
-
|
5
3
|
# Both capturable and movable game pieces
|
6
4
|
class Unit
|
7
|
-
|
5
|
+
class << self
|
6
|
+
attr_reader :name, :map_symbol, :price, :value
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :armour_left
|
10
|
+
attr_accessor :x, :y, :faction, :function, :cargo, :cargo_max
|
8
11
|
|
9
12
|
def initialize(x, y, faction, map, infopane)
|
10
13
|
@x = x
|
@@ -13,10 +16,8 @@ class Unit
|
|
13
16
|
@map = map
|
14
17
|
@infopane = infopane
|
15
18
|
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@armor_max = 1
|
19
|
-
@armor_left = @armor_max
|
19
|
+
@armour_max = 1
|
20
|
+
@armour_left = @armour_max
|
20
21
|
@moves_max = 1
|
21
22
|
@moves_left = @moves_max
|
22
23
|
@cargo = [] # transported units
|
@@ -72,16 +73,18 @@ class Unit
|
|
72
73
|
end
|
73
74
|
|
74
75
|
# Add <value> to the capturing faction
|
75
|
-
@infopane.add_score(by_whom - 1,
|
76
|
+
@infopane.add_score(by_whom - 1, self.class.value)
|
76
77
|
@faction = by_whom
|
77
78
|
end
|
78
79
|
|
79
80
|
# Add <value> to the other faction and remove links to given unit
|
80
81
|
def destroy!
|
82
|
+
@armour_left = 0 # for non-attack damage
|
83
|
+
|
81
84
|
# If you are transporting somebody, destroy them first
|
82
85
|
@cargo.each { |uu| uu.destroy! }
|
83
86
|
|
84
|
-
@infopane.add_score(3 - @faction - 1,
|
87
|
+
@infopane.add_score(3 - @faction - 1, self.class.value) # TODO more factions?
|
85
88
|
|
86
89
|
if is_transported?
|
87
90
|
coords_unit = @map.get_unit(@x, @y)
|
@@ -101,10 +104,11 @@ class Unit
|
|
101
104
|
oldcoords_unit = @map.get_unit(old_x, old_y)
|
102
105
|
newcoords_unit = @map.get_unit(@x, @y)
|
103
106
|
|
104
|
-
# If there is nobody or is there friendly unit with some cargo space
|
107
|
+
# If there is nobody or is there friendly unit with some cargo space (and bigger cargo space)
|
105
108
|
if !newcoords_unit || \
|
106
109
|
(newcoords_unit.faction == @faction && \
|
107
110
|
newcoords_unit.can_transport? && \
|
111
|
+
@cargo_max < newcoords_unit.cargo_max && \
|
108
112
|
!newcoords_unit.is_full?)
|
109
113
|
|
110
114
|
# Leave old coordinates
|
@@ -115,35 +119,39 @@ class Unit
|
|
115
119
|
end
|
116
120
|
|
117
121
|
# Get to new coordinates
|
118
|
-
if newcoords_unit
|
122
|
+
if !newcoords_unit
|
119
123
|
@map.set_unit(@x, @y, self)
|
120
124
|
@cargo.each { |uu|
|
121
125
|
uu.x = @x
|
122
126
|
uu.y = @y
|
123
127
|
}
|
124
128
|
|
125
|
-
else
|
129
|
+
else # if you are going to be transported
|
126
130
|
newcoords_unit.cargo.insert(-1, self) # -1 = to the end
|
127
131
|
puts PROMPT + to_s + ' got loaded into '+ newcoords_unit.to_s
|
128
132
|
@moves_left = 1 unless newcoords_unit.can_build? # use all your left moves unless you are getting loaded into a town
|
129
133
|
end
|
130
134
|
|
131
135
|
else # if there already is somebody that can't transport you (enemy or full friend)
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
136
|
+
# Stay on your original tile
|
137
|
+
@x = old_x
|
138
|
+
@y = old_y
|
139
|
+
|
140
|
+
# If it was a friend unit
|
141
|
+
if newcoords_unit.faction == @faction
|
142
|
+
if !newcoords_unit.can_transport?
|
143
|
+
puts PROMPT + newcoords_unit.to_s + ' can\'t transport other units'
|
144
|
+
else
|
145
|
+
if @cargo_max >= newcoords_unit.cargo_max
|
146
|
+
puts PROMPT + "#{self.class.name} can\'t fit in #{newcoords_unit.class.name}"
|
147
|
+
else # thus newcoords_unit.is_full? is true
|
141
148
|
puts PROMPT + newcoords_unit.to_s + ' is already full'
|
142
149
|
end
|
143
|
-
else
|
144
|
-
# Enemy!
|
145
|
-
newcoords_unit.engage!(self)
|
146
150
|
end
|
151
|
+
else
|
152
|
+
# Enemy!
|
153
|
+
newcoords_unit.engage!(self)
|
154
|
+
end
|
147
155
|
end
|
148
156
|
@moves_left -= 1
|
149
157
|
|
@@ -155,12 +163,17 @@ class Unit
|
|
155
163
|
end
|
156
164
|
end
|
157
165
|
|
158
|
-
|
159
166
|
def draw
|
160
167
|
@image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZUNIT,
|
161
168
|
scale_x = 1, scale_y = 1, color = COLOUR[@faction])
|
162
169
|
end
|
163
170
|
|
171
|
+
def is_waiting_for_commands?
|
172
|
+
@faction == @infopane.faction and
|
173
|
+
function == FUNCNONE and
|
174
|
+
can_move?
|
175
|
+
end
|
176
|
+
|
164
177
|
def can_move?
|
165
178
|
(can_fly? || can_sail? || can_ride?) && @moves_left > 0
|
166
179
|
end
|
@@ -182,7 +195,7 @@ class Unit
|
|
182
195
|
end
|
183
196
|
|
184
197
|
def can_be_built?
|
185
|
-
|
198
|
+
self.class.price > 0
|
186
199
|
end
|
187
200
|
|
188
201
|
def can_transport?
|
@@ -227,19 +240,31 @@ class Unit
|
|
227
240
|
end
|
228
241
|
|
229
242
|
# Set desired function
|
230
|
-
def set_function!(func)
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
243
|
+
def set_function!(func, commanding_faction)
|
244
|
+
# Check your neutrality
|
245
|
+
if @faction == 0
|
246
|
+
puts PROMPT + to_s + ": neutral units can't have functions set"
|
247
|
+
return
|
248
|
+
end
|
236
249
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
250
|
+
# Check origin of command
|
251
|
+
if commanding_faction != @faction
|
252
|
+
puts PROMPT + to_s + ": this unit does not take commands from other factions"
|
253
|
+
return
|
254
|
+
end
|
255
|
+
|
256
|
+
# Check your abilities
|
257
|
+
if func == FUNCBUILD and !can_build?
|
258
|
+
puts PROMPT + to_s + ": this unit can't build other units"
|
259
|
+
return
|
260
|
+
end
|
261
|
+
|
262
|
+
# Check current function and set the new one
|
263
|
+
if @function.func == func
|
264
|
+
puts PROMPT + to_s + ": function is already set to #{@function.func}"
|
265
|
+
else
|
266
|
+
@function.func = func
|
267
|
+
puts PROMPT + to_s + ": function set to #{@function.func}"
|
243
268
|
end
|
244
269
|
end
|
245
270
|
|
@@ -250,12 +275,12 @@ class Unit
|
|
250
275
|
|
251
276
|
# Set short info string: type, faction, coordinates
|
252
277
|
def to_s
|
253
|
-
"#{
|
278
|
+
"#{self.class.name} (FAC#{@faction} #{@x}-#{@y})"
|
254
279
|
end
|
255
280
|
|
256
|
-
# Set long info string: short info string,
|
281
|
+
# Set long info string: short info string, armour, moves, function, cargo
|
257
282
|
def info
|
258
|
-
ret = to_s + ":
|
283
|
+
ret = to_s + ": armour #{@armour_left}/#{@armour_max}"
|
259
284
|
|
260
285
|
if @moves_max > 0
|
261
286
|
ret = ret + ", moves #{@moves_left}/#{@moves_max}"
|
@@ -12,26 +12,31 @@ class UnitFunction
|
|
12
12
|
when FUNCNONE
|
13
13
|
"no function"
|
14
14
|
when FUNCBUILD
|
15
|
-
|
15
|
+
unless @unit.project
|
16
|
+
abort("unitFunction.info(): No project set (" + @unit.to_s + ")")
|
17
|
+
end
|
18
|
+
"building #{@unit.project.name} (#{@unit.build_info})"
|
16
19
|
when FUNCSENTRY
|
17
20
|
"sentrying"
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
21
24
|
def func!(map, infopane)
|
22
|
-
ret = " didn't actually do anything (ERROR)"
|
23
|
-
|
24
25
|
case @func
|
25
26
|
# Build given unit
|
26
27
|
when FUNCBUILD
|
28
|
+
unless @unit.project
|
29
|
+
abort("unitFunction.func!(): No project set (" + @unit.to_s + ")")
|
30
|
+
end
|
31
|
+
|
27
32
|
@unit.parts_built += 1
|
28
33
|
|
29
34
|
unless @unit.parts_built >= @unit.parts_needed # just == should be enough
|
30
|
-
ret = " built next part of #{@unit.project} (#{@unit.build_info} done)"
|
35
|
+
ret = " built next part of #{@unit.project.name} (#{@unit.build_info} done)"
|
31
36
|
else
|
32
|
-
ret = " completed building of #{@unit.project}"
|
37
|
+
ret = " completed building of #{@unit.project.name}"
|
33
38
|
@unit.parts_built = 0
|
34
|
-
|
39
|
+
@unit.project.new(@unit.x, @unit.y, @unit.faction, map, infopane)
|
35
40
|
end
|
36
41
|
|
37
42
|
# Wake when enemies are nearby
|
@@ -49,6 +54,10 @@ class UnitFunction
|
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
57
|
+
unless ret
|
58
|
+
abort("unitFunction.func!(): Functionable unit didn't function (" + @unit.to_s + ")")
|
59
|
+
end
|
60
|
+
|
52
61
|
ret
|
53
62
|
end
|
54
63
|
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
class Cursor
|
2
|
+
attr_accessor :freeroam, :info_stopped
|
3
|
+
|
4
|
+
def initialize(x, y, map, infopane)
|
5
|
+
dir_path = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
@x = x
|
8
|
+
@y = y
|
9
|
+
@map = map
|
10
|
+
@infopane = infopane
|
11
|
+
|
12
|
+
@image = Gosu::Image.new(dir_path + '/../../media/cursor.png')
|
13
|
+
@freeroam = false
|
14
|
+
@info_stopped = false
|
15
|
+
|
16
|
+
# Give to Infopane link to yourself (for freeroam marker)
|
17
|
+
if !@infopane
|
18
|
+
abort("Cursor.initialize!(): Infopane is not set")
|
19
|
+
end
|
20
|
+
@infopane.cursor = self
|
21
|
+
end
|
22
|
+
|
23
|
+
def update(button)
|
24
|
+
case button
|
25
|
+
# Cardinal directions
|
26
|
+
when Gosu::KbLeft, Gosu::KbA, Gosu::KB_NUMPAD_4 then
|
27
|
+
move!(-1, 0) unless @x <= 0
|
28
|
+
when Gosu::KbRight, Gosu::KbD, Gosu::KB_NUMPAD_6 then
|
29
|
+
move!(1, 0) unless @x >= MAPX
|
30
|
+
when Gosu::KbUp, Gosu::KbW, Gosu::KB_NUMPAD_8 then
|
31
|
+
move!(0, -1) unless @y <= 0
|
32
|
+
when Gosu::KbDown, Gosu::KbX, Gosu::KB_NUMPAD_2 then
|
33
|
+
move!(0, 1) unless @y >= MAPY
|
34
|
+
|
35
|
+
# Intercardinal directions
|
36
|
+
when Gosu::KbQ, Gosu::KB_NUMPAD_7 then
|
37
|
+
move!(-1, -1) unless @x <= 0 || @y <= 0
|
38
|
+
when Gosu::KbE, Gosu::KB_NUMPAD_9 then
|
39
|
+
move!(1, -1) unless @x >= MAPX || @y <= 0
|
40
|
+
when Gosu::KbZ, Gosu::KB_NUMPAD_1 then
|
41
|
+
move!(-1, 1) unless @x <= 0 || @y >= MAPY
|
42
|
+
when Gosu::KbC, Gosu::KB_NUMPAD_3 then
|
43
|
+
move!(1, 1) unless @x >= MAPX || @y >= MAPY
|
44
|
+
|
45
|
+
# Functions
|
46
|
+
when Gosu::KbS then
|
47
|
+
set_function_to_unit(FUNCSENTRY)
|
48
|
+
when Gosu::KbB then
|
49
|
+
set_function_to_unit(FUNCBUILD)
|
50
|
+
when Gosu::KbN then
|
51
|
+
set_function_to_unit(FUNCNONE)
|
52
|
+
|
53
|
+
# The rest
|
54
|
+
when Gosu::KbJ, Gosu::KB_NUMPAD_0 then
|
55
|
+
switch_freeroam!
|
56
|
+
when Gosu::KbReturn, Gosu::KB_NUMPAD_5 then
|
57
|
+
info
|
58
|
+
end
|
59
|
+
|
60
|
+
# If in locked mode, stay at current/jump to next movable unit
|
61
|
+
to_next_unit! unless @freeroam
|
62
|
+
end
|
63
|
+
|
64
|
+
def draw
|
65
|
+
@image.draw(@x * TILESIZE, (@y + 1) * TILESIZE, ZCURSOR)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Move to coordinates of unit the cursor is locked to
|
69
|
+
def warp_to_locked!()
|
70
|
+
@x = @locked_to.x
|
71
|
+
@y = @locked_to.y
|
72
|
+
@local_unit = @locked_to
|
73
|
+
end
|
74
|
+
|
75
|
+
# Move by given change of coordinates
|
76
|
+
def move!(xx, yy)
|
77
|
+
if freeroam
|
78
|
+
@x += xx
|
79
|
+
@y += yy
|
80
|
+
@local_unit = @map.get_unit(@x, @y)
|
81
|
+
# TODO show some basic tile info in infopane
|
82
|
+
else
|
83
|
+
check_unit
|
84
|
+
|
85
|
+
# Move the unit first
|
86
|
+
@locked_to.x += xx
|
87
|
+
@locked_to.y += yy
|
88
|
+
@locked_to.check_movement(@x, @y) # cursor coordinates work like old_x, old_y
|
89
|
+
|
90
|
+
# Is the unit still alive?
|
91
|
+
if @locked_to.armour_left > 0
|
92
|
+
warp_to_locked! # whether it moved or not
|
93
|
+
else
|
94
|
+
# It got destroyed so clear last links then so that (object of)
|
95
|
+
# given unit can be truly destroyed
|
96
|
+
@local_unit = nil
|
97
|
+
@locked_to = nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Tries to set function <func> to local unit
|
103
|
+
def set_function_to_unit(func)
|
104
|
+
check_unit
|
105
|
+
|
106
|
+
if @local_unit
|
107
|
+
@local_unit.set_function!(func, @infopane.faction)
|
108
|
+
|
109
|
+
# Update infopane with the new (possibly changed) state
|
110
|
+
# (visible only in freeroam mode as in locked one the infopane is
|
111
|
+
# overwritten as cursor either jumps away or switches to freeroam mode)
|
112
|
+
@infopane.text = @local_unit.info
|
113
|
+
else
|
114
|
+
puts "no unit to set that function to (at #{@x}-#{@y})"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Reset to locked mode
|
119
|
+
def reset!
|
120
|
+
@freeroam = true
|
121
|
+
switch_freeroam!
|
122
|
+
@local_unit = nil
|
123
|
+
@locked_to = nil
|
124
|
+
to_next_unit!
|
125
|
+
end
|
126
|
+
|
127
|
+
# Find next unit which is still waiting for commands and lock to it
|
128
|
+
# (local -> last locked to -> next waiting) or switch (back) to freeroaming
|
129
|
+
def to_next_unit!
|
130
|
+
if @local_unit and @local_unit.is_waiting_for_commands?
|
131
|
+
# Lock to such unit (though it may have already been locked)
|
132
|
+
@locked_to = @local_unit
|
133
|
+
else
|
134
|
+
unless @locked_to and @locked_to.is_waiting_for_commands?
|
135
|
+
waiting = @map.all_units.select { |uu| uu.is_waiting_for_commands? }
|
136
|
+
|
137
|
+
# Are there still some units of active faction waiting for commands?
|
138
|
+
if waiting.size <= 0 # == would be enough
|
139
|
+
puts 'all movable units without functions moved'
|
140
|
+
switch_freeroam!
|
141
|
+
return
|
142
|
+
end
|
143
|
+
|
144
|
+
@locked_to = waiting[0] # newly selected one
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
warp_to_locked! # stay at old or go to new
|
149
|
+
info unless @info_stopped # due to switching out of the play game state
|
150
|
+
end
|
151
|
+
|
152
|
+
# When cursor is in locked mode there needs to be a local unit it is locked to
|
153
|
+
# When cursor is in freeroam mode the local unit should still be loaded
|
154
|
+
def check_unit
|
155
|
+
if !@freeroam and !@local_unit
|
156
|
+
abort("cursor.set_function_to_unit(): Cursor is in locked mode " \
|
157
|
+
"but there is no unit it is locked to (at #{@x}-#{@y})")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# Switch between being attached to unit and being able to freeroam
|
162
|
+
def switch_freeroam!
|
163
|
+
if freeroam
|
164
|
+
@infopane.text = 'freeroam disabled'
|
165
|
+
puts 'freeroam disabled'
|
166
|
+
@freeroam = false
|
167
|
+
else
|
168
|
+
@infopane.text = 'freeroam enabled'
|
169
|
+
puts 'freeroam enabled'
|
170
|
+
@freeroam = true
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# Find some info about units on the current tile
|
175
|
+
def info
|
176
|
+
check_unit
|
177
|
+
|
178
|
+
if @local_unit
|
179
|
+
@infopane.text = @local_unit.info
|
180
|
+
puts @local_unit.info
|
181
|
+
|
182
|
+
if @local_unit.is_transporting?
|
183
|
+
@local_unit.cargo.each { |uu| puts '- cargo: ' + uu.info }
|
184
|
+
end
|
185
|
+
else
|
186
|
+
@infopane.text = ''
|
187
|
+
puts "no unit to show info of (at #{@x}-#{@y})"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|