empi 0.19 → 0.24
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 +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
|