Merge lp:~widelands-dev/widelands/bug-1380287 into lp:widelands
- bug-1380287
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 7441 | ||||
Proposed branch: | lp:~widelands-dev/widelands/bug-1380287 | ||||
Merge into: | lp:widelands | ||||
Diff against target: |
1463 lines (+610/-173) 23 files modified
src/ai/ai_help_structs.h (+1/-1) src/ai/defaultai.cc (+4/-4) src/economy/portdock.cc (+1/-2) src/logic/game.cc (+2/-2) src/logic/game.h (+3/-2) src/logic/playercommand.cc (+10/-10) src/logic/playercommand.h (+5/-5) src/logic/ship.cc (+41/-26) src/logic/ship.h (+16/-6) src/logic/walkingdir.cc (+42/-42) src/logic/walkingdir.h (+3/-3) src/scripting/lua_game.cc (+37/-0) src/scripting/lua_game.h (+1/-0) src/scripting/lua_map.cc (+273/-9) src/scripting/lua_map.h (+10/-1) src/wui/shipwindow.cc (+8/-8) test/maps/expedition.wmf/scripting/init.lua (+15/-30) test/maps/expedition.wmf/scripting/test_ship_movement_controls.lua (+115/-0) test/maps/expedition.wmf/scripting/test_starting_and_immediately_canceling.lua (+6/-2) test/maps/expedition.wmf/scripting/test_starting_wait_a_while_cancel.lua (+2/-2) test/maps/ship_transportation.wmf/scripting/init.lua (+0/-17) test/maps/ship_transportation.wmf/scripting/test_rip_portdock_with_worker_and_ware_in_transit.lua (+3/-1) test/maps/ship_transportation.wmf/scripting/test_rip_second_port_with_worker_in_portdock.lua (+12/-0) |
||||
To merge this branch: | bzr merge lp:~widelands-dev/widelands/bug-1380287 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
SirVer | Needs Fixing | ||
GunChleoc | Approve | ||
Review via email:
|
Commit message
Description of the change
I implemented some LUA interface for ships, f.e.:
map:get_ships - to get list of player' ships on map
ships.field - to get a field where ship is located
ships.status - to get status of ship (what is it doing)
port:start_
ship.scout_
ship:build_
Please review
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
GunChleoc (gunchleoc) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
TiborB (tiborb95) wrote : | # |
@GunChleoc - of course I was thinking about this - using text instead of integers for directions. But I failed to find good conventor string<->integer like nw=6 and so. I mean a pair of functions that would change them forth and back.
I could implement the conversion in this code, but it would broke if somebody changed the enum somewhere... But I could do this, allright... I will consider it....
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
GunChleoc (gunchleoc) wrote : | # |
Do something like this (I don't remember the exact enum variable names):
if (direction == Ship::Direction
lua_
} elseif ...
then everything will always be referenced by a name.
I have done something similar in lua_map.cc for the BuildingDescription types, in case you want to steal some code.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
TiborB (tiborb95) wrote : | # |
This is the easier conversion, but I need also backward conversion... But it seems there is also example for this.... I will look at it once more...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
GunChleoc (gunchleoc) wrote : | # |
I forgot that in this direction, it is better to use a switch statement. Something I learned from SirVer - the code will run faster, because it just jumps using the variable as an address instead of making a full comparison.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
TiborB (tiborb95) wrote : | # |
reworked to use the strings
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
GunChleoc (gunchleoc) wrote : | # |
I refactored the enums, made the status function return strings, and added some tests. Please review my code before merging.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
SirVer (sirver) wrote : | # |
I found a couple more nits. Otherwise LGTM, please merge after fixing them.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
TiborB (tiborb95) wrote : | # |
comments fixed, I rerun the regression test (all OK) and merged it to trunk
Preview Diff
1 | === modified file 'src/ai/ai_help_structs.h' |
2 | --- src/ai/ai_help_structs.h 2015-03-26 06:59:37 +0000 |
3 | +++ src/ai/ai_help_structs.h 2015-04-07 20:58:43 +0000 |
4 | @@ -438,7 +438,7 @@ |
5 | |
6 | // a ship circumvents all islands in the same direction, the value |
7 | // is assigned only once |
8 | - Widelands::ScoutingDirection island_circ_direction = Widelands::ScoutingDirection::kClockwise; |
9 | + Widelands::IslandExploreDirection island_circ_direction = Widelands::IslandExploreDirection::kClockwise; |
10 | bool waiting_for_command_ = false; |
11 | int32_t last_command_time = 0; |
12 | }; |
13 | |
14 | === modified file 'src/ai/defaultai.cc' |
15 | --- src/ai/defaultai.cc 2015-03-26 20:35:19 +0000 |
16 | +++ src/ai/defaultai.cc 2015-04-07 20:58:43 +0000 |
17 | @@ -3795,9 +3795,9 @@ |
18 | allships.push_back(ShipObserver()); |
19 | allships.back().ship = &ship; |
20 | if (game().get_gametime() % 2 == 0) { |
21 | - allships.back().island_circ_direction = ScoutingDirection::kClockwise; |
22 | + allships.back().island_circ_direction = IslandExploreDirection::kClockwise; |
23 | } else { |
24 | - allships.back().island_circ_direction = ScoutingDirection::kCounterClockwise; |
25 | + allships.back().island_circ_direction = IslandExploreDirection::kCounterClockwise; |
26 | } |
27 | } |
28 | |
29 | @@ -4058,10 +4058,10 @@ |
30 | so.waiting_for_command_ = false; |
31 | ; |
32 | } else { |
33 | - // 2.B Yes, pick one of avaiable directions |
34 | + // 2.B Yes, pick one of avaliable directions |
35 | const Direction final_direction = |
36 | possible_directions.at(gametime % possible_directions.size()); |
37 | - game().send_player_ship_scout_direction(*so.ship, final_direction); |
38 | + game().send_player_ship_scouting_direction(*so.ship, static_cast<WalkingDir>(final_direction)); |
39 | so.last_command_time = gametime; |
40 | so.waiting_for_command_ = false; |
41 | } |
42 | |
43 | === modified file 'src/economy/portdock.cc' |
44 | --- src/economy/portdock.cc 2015-02-16 20:23:15 +0000 |
45 | +++ src/economy/portdock.cc 2015-04-07 20:58:43 +0000 |
46 | @@ -213,12 +213,11 @@ |
47 | |
48 | PlayerImmovable::cleanup(egbase); |
49 | |
50 | - //now let attempt to recreate the portdock |
51 | + // Now let's attempt to recreate the portdock. |
52 | if (wh) { |
53 | if (!wh->m_cleanup_in_progress){ |
54 | if (upcast(Game, game, &egbase)) { |
55 | if (game->is_loaded()) { //do not attempt when shutting down |
56 | - Player& player = owner(); |
57 | wh->restore_portdock_or_destroy(egbase); |
58 | } |
59 | } |
60 | |
61 | === modified file 'src/logic/game.cc' |
62 | --- src/logic/game.cc 2015-02-08 19:08:36 +0000 |
63 | +++ src/logic/game.cc 2015-04-07 20:58:43 +0000 |
64 | @@ -874,7 +874,7 @@ |
65 | } |
66 | |
67 | |
68 | -void Game::send_player_ship_scout_direction(Ship & ship, uint8_t direction) |
69 | +void Game::send_player_ship_scouting_direction(Ship & ship, WalkingDir direction) |
70 | { |
71 | send_player_command |
72 | (*new CmdShipScoutDirection |
73 | @@ -888,7 +888,7 @@ |
74 | (get_gametime(), ship.get_owner()->player_number(), ship.serial(), coords)); |
75 | } |
76 | |
77 | -void Game::send_player_ship_explore_island(Ship & ship, ScoutingDirection direction) |
78 | +void Game::send_player_ship_explore_island(Ship & ship, IslandExploreDirection direction) |
79 | { |
80 | send_player_command |
81 | (*new CmdShipExploreIsland |
82 | |
83 | === modified file 'src/logic/game.h' |
84 | --- src/logic/game.h 2015-02-08 19:08:36 +0000 |
85 | +++ src/logic/game.h 2015-04-07 20:58:43 +0000 |
86 | @@ -41,6 +41,7 @@ |
87 | struct Flag; |
88 | struct Path; |
89 | struct PlayerImmovable; |
90 | +enum class IslandExploreDirection; |
91 | enum class ScoutingDirection; |
92 | struct Ship; |
93 | struct PlayerEndStatus; |
94 | @@ -181,9 +182,9 @@ |
95 | void send_player_enemyflagaction |
96 | (const Flag &, PlayerNumber, uint32_t count); |
97 | |
98 | - void send_player_ship_scout_direction(Ship &, uint8_t); |
99 | + void send_player_ship_scouting_direction(Ship &, WalkingDir); |
100 | void send_player_ship_construct_port(Ship &, Coords); |
101 | - void send_player_ship_explore_island(Ship &, ScoutingDirection); |
102 | + void send_player_ship_explore_island(Ship &, IslandExploreDirection); |
103 | void send_player_sink_ship(Ship &); |
104 | void send_player_cancel_expedition_ship(Ship &); |
105 | |
106 | |
107 | === modified file 'src/logic/playercommand.cc' |
108 | --- src/logic/playercommand.cc 2015-02-19 19:37:09 +0000 |
109 | +++ src/logic/playercommand.cc 2015-04-07 20:58:43 +0000 |
110 | @@ -777,7 +777,7 @@ |
111 | PlayerCommand (0, des.unsigned_8()) |
112 | { |
113 | serial = des.unsigned_32(); |
114 | - dir = des.unsigned_8(); |
115 | + dir = static_cast<WalkingDir>(des.unsigned_8()); |
116 | } |
117 | |
118 | void CmdShipScoutDirection::execute (Game & game) |
119 | @@ -796,7 +796,7 @@ |
120 | (ship->state_is_expedition())?"Y":"N"); |
121 | return; |
122 | } |
123 | - ship->exp_scout_direction(game, dir); |
124 | + ship->exp_scouting_direction(game, dir); |
125 | } |
126 | } |
127 | |
128 | @@ -805,7 +805,7 @@ |
129 | ser.unsigned_8 (PLCMD_SHIP_SCOUT); |
130 | ser.unsigned_8 (sender()); |
131 | ser.unsigned_32(serial); |
132 | - ser.unsigned_8 (dir); |
133 | + ser.unsigned_8 (static_cast<uint8_t>(dir)); |
134 | } |
135 | |
136 | #define PLAYER_CMD_SHIP_SCOUT_DIRECTION_VERSION 1 |
137 | @@ -818,7 +818,7 @@ |
138 | PlayerCommand::read(fr, egbase, mol); |
139 | serial = get_object_serial_or_zero<Ship>(fr.unsigned_32(), mol); |
140 | // direction |
141 | - dir = fr.unsigned_8(); |
142 | + dir = static_cast<WalkingDir>(fr.unsigned_8()); |
143 | } else |
144 | throw GameDataError("unknown/unhandled version %u", packet_version); |
145 | } catch (const WException & e) { |
146 | @@ -837,7 +837,7 @@ |
147 | fw.unsigned_32(mos.get_object_file_index_or_zero(egbase.objects().get_object(serial))); |
148 | |
149 | // direction |
150 | - fw.unsigned_8(dir); |
151 | + fw.unsigned_8(static_cast<uint8_t>(dir)); |
152 | } |
153 | |
154 | |
155 | @@ -912,7 +912,7 @@ |
156 | PlayerCommand (0, des.unsigned_8()) |
157 | { |
158 | serial = des.unsigned_32(); |
159 | - scouting_direction = static_cast<ScoutingDirection>(des.unsigned_8()); |
160 | + island_explore_direction = static_cast<IslandExploreDirection>(des.unsigned_8()); |
161 | } |
162 | |
163 | void CmdShipExploreIsland::execute (Game & game) |
164 | @@ -931,7 +931,7 @@ |
165 | (ship->state_is_expedition())?"Y":"N"); |
166 | return; |
167 | } |
168 | - ship->exp_explore_island(game, scouting_direction); |
169 | + ship->exp_explore_island(game, island_explore_direction); |
170 | } |
171 | } |
172 | |
173 | @@ -940,7 +940,7 @@ |
174 | ser.unsigned_8 (PLCMD_SHIP_EXPLORE); |
175 | ser.unsigned_8 (sender()); |
176 | ser.unsigned_32(serial); |
177 | - ser.unsigned_8 (static_cast<uint8_t>(scouting_direction)); |
178 | + ser.unsigned_8 (static_cast<uint8_t>(island_explore_direction)); |
179 | } |
180 | |
181 | #define PLAYER_CMD_SHIP_EXPLORE_ISLAND_VERSION 1 |
182 | @@ -952,7 +952,7 @@ |
183 | if (packet_version == PLAYER_CMD_SHIP_EXPLORE_ISLAND_VERSION) { |
184 | PlayerCommand::read(fr, egbase, mol); |
185 | serial = get_object_serial_or_zero<Ship>(fr.unsigned_32(), mol); |
186 | - scouting_direction = static_cast<ScoutingDirection>(fr.unsigned_8()); |
187 | + island_explore_direction = static_cast<IslandExploreDirection>(fr.unsigned_8()); |
188 | } else |
189 | throw GameDataError("unknown/unhandled version %u", packet_version); |
190 | } catch (const WException & e) { |
191 | @@ -971,7 +971,7 @@ |
192 | fw.unsigned_32(mos.get_object_file_index_or_zero(egbase.objects().get_object(serial))); |
193 | |
194 | // Direction of exploration |
195 | - fw.unsigned_8(static_cast<uint8_t>(scouting_direction)); |
196 | + fw.unsigned_8(static_cast<uint8_t>(island_explore_direction)); |
197 | } |
198 | |
199 | |
200 | |
201 | === modified file 'src/logic/playercommand.h' |
202 | --- src/logic/playercommand.h 2015-02-05 12:11:20 +0000 |
203 | +++ src/logic/playercommand.h 2015-04-07 20:58:43 +0000 |
204 | @@ -313,7 +313,7 @@ |
205 | struct CmdShipScoutDirection : public PlayerCommand { |
206 | CmdShipScoutDirection() : PlayerCommand(), serial(0) {} // For savegame loading |
207 | CmdShipScoutDirection |
208 | - (int32_t const t, PlayerNumber const p, Serial s, uint8_t direction) |
209 | + (int32_t const t, PlayerNumber const p, Serial s, WalkingDir direction) |
210 | : PlayerCommand(t, p), serial(s), dir(direction) |
211 | {} |
212 | |
213 | @@ -329,7 +329,7 @@ |
214 | |
215 | private: |
216 | Serial serial; |
217 | - uint8_t dir; |
218 | + WalkingDir dir; |
219 | }; |
220 | |
221 | struct CmdShipConstructPort : public PlayerCommand { |
222 | @@ -357,8 +357,8 @@ |
223 | struct CmdShipExploreIsland : public PlayerCommand { |
224 | CmdShipExploreIsland() : PlayerCommand(), serial(0) {} // For savegame loading |
225 | CmdShipExploreIsland |
226 | - (int32_t const t, PlayerNumber const p, Serial s, ScoutingDirection direction) |
227 | - : PlayerCommand(t, p), serial(s), scouting_direction(direction) |
228 | + (int32_t const t, PlayerNumber const p, Serial s, IslandExploreDirection direction) |
229 | + : PlayerCommand(t, p), serial(s), island_explore_direction(direction) |
230 | {} |
231 | |
232 | void write(FileWrite &, EditorGameBase &, MapObjectSaver &) override; |
233 | @@ -373,7 +373,7 @@ |
234 | |
235 | private: |
236 | Serial serial; |
237 | - ScoutingDirection scouting_direction; |
238 | + IslandExploreDirection island_explore_direction; |
239 | }; |
240 | |
241 | struct CmdShipSink : public PlayerCommand { |
242 | |
243 | === modified file 'src/logic/ship.cc' |
244 | --- src/logic/ship.cc 2015-02-05 12:11:20 +0000 |
245 | +++ src/logic/ship.cc 2015-04-07 20:58:43 +0000 |
246 | @@ -550,15 +550,15 @@ |
247 | case EXP_SCOUTING: { |
248 | if (m_expedition->island_exploration) { // Exploration of the island |
249 | if (exp_close_to_coast()) { |
250 | - if (m_expedition->direction == 0) { |
251 | + if (m_expedition->scouting_direction == WalkingDir::IDLE) { |
252 | // Make sure we know the location of the coast and use it as initial direction we |
253 | // come from |
254 | - m_expedition->direction = WALK_SE; |
255 | - for (uint8_t secure = 0; exp_dir_swimable(m_expedition->direction); ++secure) { |
256 | + m_expedition->scouting_direction = WALK_SE; |
257 | + for (uint8_t secure = 0; exp_dir_swimable(m_expedition->scouting_direction); ++secure) { |
258 | assert(secure < 6); |
259 | - m_expedition->direction = get_cw_neighbour(m_expedition->direction); |
260 | + m_expedition->scouting_direction = get_cw_neighbour(m_expedition->scouting_direction); |
261 | } |
262 | - m_expedition->direction = get_backward_dir(m_expedition->direction); |
263 | + m_expedition->scouting_direction = get_backward_dir(m_expedition->scouting_direction); |
264 | // Save the position - this is where we start |
265 | m_expedition->exploration_start = get_position(); |
266 | } else { |
267 | @@ -579,18 +579,18 @@ |
268 | // The ship is supposed to follow the coast as close as possible, therefore the check |
269 | // for |
270 | // a swimable field begins at the neighbour field of the direction we came from. |
271 | - m_expedition->direction = get_backward_dir(m_expedition->direction); |
272 | - if (m_expedition->scouting_direction == ScoutingDirection::kClockwise) { |
273 | + m_expedition->scouting_direction = get_backward_dir(m_expedition->scouting_direction); |
274 | + if (m_expedition->island_explore_direction == IslandExploreDirection::kClockwise) { |
275 | do { |
276 | - m_expedition->direction = get_ccw_neighbour(m_expedition->direction); |
277 | - } while (!exp_dir_swimable(m_expedition->direction)); |
278 | + m_expedition->scouting_direction = get_ccw_neighbour(m_expedition->scouting_direction); |
279 | + } while (!exp_dir_swimable(m_expedition->scouting_direction)); |
280 | } else { |
281 | do { |
282 | - m_expedition->direction = get_cw_neighbour(m_expedition->direction); |
283 | - } while (!exp_dir_swimable(m_expedition->direction)); |
284 | + m_expedition->scouting_direction = get_cw_neighbour(m_expedition->scouting_direction); |
285 | + } while (!exp_dir_swimable(m_expedition->scouting_direction)); |
286 | } |
287 | state.ivar1 = 1; |
288 | - return start_task_move(game, m_expedition->direction, descr().get_sail_anims(), false); |
289 | + return start_task_move(game, m_expedition->scouting_direction, descr().get_sail_anims(), false); |
290 | } else { |
291 | // The ship got the command to scout around an island, but is not close to any island |
292 | // Most likely the command was send as the ship was on an exploration and just leaving |
293 | @@ -615,10 +615,10 @@ |
294 | return start_task_idle(game, descr().main_animation(), 1500); |
295 | } |
296 | } else { // scouting towards a specific direction |
297 | - if (exp_dir_swimable(m_expedition->direction)) { |
298 | + if (exp_dir_swimable(m_expedition->scouting_direction)) { |
299 | // the scouting direction is still free to move |
300 | state.ivar1 = 1; |
301 | - start_task_move(game, m_expedition->direction, descr().get_sail_anims(), false); |
302 | + start_task_move(game, m_expedition->scouting_direction, descr().get_sail_anims(), false); |
303 | return; |
304 | } |
305 | // coast reached |
306 | @@ -791,9 +791,9 @@ |
307 | m_expedition.reset(new Expedition()); |
308 | m_expedition->seen_port_buildspaces.reset(new std::list<Coords>()); |
309 | m_expedition->island_exploration = false; |
310 | - m_expedition->direction = 0; |
311 | + m_expedition->scouting_direction = WalkingDir::IDLE; |
312 | m_expedition->exploration_start = Coords(0, 0); |
313 | - m_expedition->scouting_direction = ScoutingDirection::kClockwise; |
314 | + m_expedition->island_explore_direction = IslandExploreDirection::kClockwise; |
315 | m_expedition->economy.reset(new Economy(*get_owner())); |
316 | |
317 | // We are no longer in any other economy, but instead are an economy of our |
318 | @@ -824,13 +824,20 @@ |
319 | |
320 | /// Initializes / changes the direction of scouting to @arg direction |
321 | /// @note only called via player command |
322 | -void Ship::exp_scout_direction(Game&, uint8_t direction) { |
323 | +void Ship::exp_scouting_direction(Game&, WalkingDir scouting_direction) { |
324 | assert(m_expedition); |
325 | m_ship_state = EXP_SCOUTING; |
326 | - m_expedition->direction = direction; |
327 | + m_expedition->scouting_direction = scouting_direction; |
328 | m_expedition->island_exploration = false; |
329 | } |
330 | |
331 | +WalkingDir Ship::get_scouting_direction() { |
332 | + if (m_expedition && m_ship_state == EXP_SCOUTING && !m_expedition->island_exploration) { |
333 | + return m_expedition->scouting_direction; |
334 | + } |
335 | + return WalkingDir::IDLE; |
336 | +} |
337 | + |
338 | /// Initializes the construction of a port at @arg c |
339 | /// @note only called via player command |
340 | void Ship::exp_construct_port(Game&, const Coords& c) { |
341 | @@ -840,16 +847,24 @@ |
342 | m_ship_state = EXP_COLONIZING; |
343 | } |
344 | |
345 | -/// Initializes / changes the direction the island exploration in @arg scouting_direction direction |
346 | +/// Initializes / changes the direction the island exploration in @arg island_explore_direction direction |
347 | /// @note only called via player command |
348 | -void Ship::exp_explore_island(Game&, ScoutingDirection scouting_direction) { |
349 | +void Ship::exp_explore_island(Game&, IslandExploreDirection island_explore_direction) { |
350 | assert(m_expedition); |
351 | m_ship_state = EXP_SCOUTING; |
352 | - m_expedition->scouting_direction = scouting_direction; |
353 | - m_expedition->direction = 0; |
354 | + m_expedition->island_explore_direction = island_explore_direction; |
355 | + m_expedition->scouting_direction = WalkingDir::IDLE; |
356 | m_expedition->island_exploration = true; |
357 | } |
358 | |
359 | +IslandExploreDirection Ship::get_island_explore_direction() { |
360 | + if (m_expedition && m_ship_state == EXP_SCOUTING && m_expedition->island_exploration) { |
361 | + return m_expedition->island_explore_direction; |
362 | + } |
363 | + return IslandExploreDirection::kNotSet; |
364 | +} |
365 | + |
366 | + |
367 | /// Cancels a currently running expedition |
368 | /// @note only called via player command |
369 | void Ship::exp_cancel(Game& game) { |
370 | @@ -995,11 +1010,11 @@ |
371 | // whether scouting or exploring |
372 | m_expedition->island_exploration = fr.unsigned_8() == 1; |
373 | // current direction |
374 | - m_expedition->direction = fr.unsigned_8(); |
375 | + m_expedition->scouting_direction = static_cast<WalkingDir>(fr.unsigned_8()); |
376 | // Start coordinates of an island exploration |
377 | m_expedition->exploration_start = read_coords_32(&fr); |
378 | // Whether the exploration is done clockwise or counter clockwise |
379 | - m_expedition->scouting_direction = static_cast<ScoutingDirection>(fr.unsigned_8()); |
380 | + m_expedition->island_explore_direction = static_cast<IslandExploreDirection>(fr.unsigned_8()); |
381 | } |
382 | } else |
383 | m_ship_state = TRANSPORT; |
384 | @@ -1114,11 +1129,11 @@ |
385 | // whether scouting or exploring |
386 | fw.unsigned_8(m_expedition->island_exploration ? 1 : 0); |
387 | // current direction |
388 | - fw.unsigned_8(m_expedition->direction); |
389 | + fw.unsigned_8(static_cast<uint8_t>(m_expedition->scouting_direction)); |
390 | // Start coordinates of an island exploration |
391 | write_coords_32(&fw, m_expedition->exploration_start); |
392 | // Whether the exploration is done clockwise or counter clockwise |
393 | - fw.unsigned_8(static_cast<uint8_t>(m_expedition->scouting_direction)); |
394 | + fw.unsigned_8(static_cast<uint8_t>(m_expedition->island_explore_direction)); |
395 | } |
396 | |
397 | fw.unsigned_32(mos.get_object_file_index_or_zero(m_lastdock.get(egbase))); |
398 | |
399 | === modified file 'src/logic/ship.h' |
400 | --- src/logic/ship.h 2015-02-05 12:11:20 +0000 |
401 | +++ src/logic/ship.h 2015-04-07 20:58:43 +0000 |
402 | @@ -38,9 +38,10 @@ |
403 | class PortDock; |
404 | |
405 | // This can't be part of the Ship class because of forward declaration in game.h |
406 | -enum class ScoutingDirection { |
407 | +enum class IslandExploreDirection { |
408 | kCounterClockwise = 0, // This comes first for savegame compatibility (used to be = 0) |
409 | - kClockwise = 1 |
410 | + kClockwise = 1, |
411 | + kNotSet |
412 | }; |
413 | |
414 | struct NoteShipMessage { |
415 | @@ -202,9 +203,18 @@ |
416 | return m_expedition->seen_port_buildspaces.get(); |
417 | } |
418 | |
419 | - void exp_scout_direction(Game &, uint8_t); |
420 | + void exp_scouting_direction(Game &, WalkingDir); |
421 | void exp_construct_port (Game &, const Coords&); |
422 | - void exp_explore_island (Game &, ScoutingDirection); |
423 | + void exp_explore_island (Game &, IslandExploreDirection); |
424 | + |
425 | + //Returns integer of direction, or WalkingDir::IDLE if query invalid |
426 | + //Intended for LUA scripting |
427 | + WalkingDir get_scouting_direction(); |
428 | + |
429 | + //Returns integer of direction, or IslandExploreDirection::kNotSet |
430 | + //if query invalid |
431 | + //Intended for LUA scripting |
432 | + IslandExploreDirection get_island_explore_direction(); |
433 | |
434 | void exp_cancel (Game &); |
435 | void sink_ship (Game &); |
436 | @@ -242,9 +252,9 @@ |
437 | std::unique_ptr<std::list<Coords> > seen_port_buildspaces; |
438 | bool swimable[LAST_DIRECTION]; |
439 | bool island_exploration; |
440 | - uint8_t direction; |
441 | + WalkingDir scouting_direction; |
442 | Coords exploration_start; |
443 | - ScoutingDirection scouting_direction; |
444 | + IslandExploreDirection island_explore_direction; |
445 | std::unique_ptr<Economy> economy; |
446 | }; |
447 | std::unique_ptr<Expedition> m_expedition; |
448 | |
449 | === modified file 'src/logic/walkingdir.cc' |
450 | --- src/logic/walkingdir.cc 2014-07-14 10:45:44 +0000 |
451 | +++ src/logic/walkingdir.cc 2015-04-07 20:58:43 +0000 |
452 | @@ -22,61 +22,61 @@ |
453 | namespace Widelands { |
454 | |
455 | /// \returns the neighbour direction in clockwise |
456 | -uint8_t get_cw_neighbour(uint8_t dir) { |
457 | +WalkingDir get_cw_neighbour(WalkingDir dir) { |
458 | switch (dir) { |
459 | - case WALK_NE: |
460 | - return WALK_E; |
461 | - case WALK_E: |
462 | - return WALK_SE; |
463 | - case WALK_SE: |
464 | - return WALK_SW; |
465 | - case WALK_SW: |
466 | - return WALK_W; |
467 | - case WALK_W: |
468 | - return WALK_NW; |
469 | - case WALK_NW: |
470 | - return WALK_NE; |
471 | + case WalkingDir::WALK_NE: |
472 | + return WalkingDir::WALK_E; |
473 | + case WalkingDir::WALK_E: |
474 | + return WalkingDir::WALK_SE; |
475 | + case WalkingDir::WALK_SE: |
476 | + return WalkingDir::WALK_SW; |
477 | + case WalkingDir::WALK_SW: |
478 | + return WalkingDir::WALK_W; |
479 | + case WalkingDir::WALK_W: |
480 | + return WalkingDir::WALK_NW; |
481 | + case WalkingDir::WALK_NW: |
482 | + return WalkingDir::WALK_NE; |
483 | default: |
484 | - return 0; |
485 | + return WalkingDir::IDLE; |
486 | } |
487 | } |
488 | |
489 | /// \returns the neighbour direction in counterclockwise |
490 | -uint8_t get_ccw_neighbour(uint8_t dir) { |
491 | +WalkingDir get_ccw_neighbour(WalkingDir dir) { |
492 | switch (dir) { |
493 | - case WALK_E: |
494 | - return WALK_NE; |
495 | - case WALK_NE: |
496 | - return WALK_NW; |
497 | - case WALK_NW: |
498 | - return WALK_W; |
499 | - case WALK_W: |
500 | - return WALK_SW; |
501 | - case WALK_SW: |
502 | - return WALK_SE; |
503 | - case WALK_SE: |
504 | - return WALK_E; |
505 | + case WalkingDir::WALK_E: |
506 | + return WalkingDir::WALK_NE; |
507 | + case WalkingDir::WALK_NE: |
508 | + return WalkingDir::WALK_NW; |
509 | + case WalkingDir::WALK_NW: |
510 | + return WalkingDir::WALK_W; |
511 | + case WalkingDir::WALK_W: |
512 | + return WalkingDir::WALK_SW; |
513 | + case WalkingDir::WALK_SW: |
514 | + return WalkingDir::WALK_SE; |
515 | + case WalkingDir::WALK_SE: |
516 | + return WalkingDir::WALK_E; |
517 | default: |
518 | - return 0; |
519 | + return WalkingDir::IDLE; |
520 | } |
521 | } |
522 | |
523 | -uint8_t get_backward_dir(uint8_t dir) { |
524 | +WalkingDir get_backward_dir(WalkingDir dir) { |
525 | switch (dir) { |
526 | - case WALK_E: |
527 | - return WALK_W; |
528 | - case WALK_NE: |
529 | - return WALK_SW; |
530 | - case WALK_NW: |
531 | - return WALK_SE; |
532 | - case WALK_W: |
533 | - return WALK_E; |
534 | - case WALK_SW: |
535 | - return WALK_NE; |
536 | - case WALK_SE: |
537 | - return WALK_NW; |
538 | + case WalkingDir::WALK_E: |
539 | + return WalkingDir::WALK_W; |
540 | + case WalkingDir::WALK_NE: |
541 | + return WalkingDir::WALK_SW; |
542 | + case WalkingDir::WALK_NW: |
543 | + return WalkingDir::WALK_SE; |
544 | + case WalkingDir::WALK_W: |
545 | + return WalkingDir::WALK_E; |
546 | + case WalkingDir::WALK_SW: |
547 | + return WalkingDir::WALK_NE; |
548 | + case WalkingDir::WALK_SE: |
549 | + return WalkingDir::WALK_NW; |
550 | default: |
551 | - return 0; |
552 | + return WalkingDir::IDLE; |
553 | } |
554 | } |
555 | |
556 | |
557 | === modified file 'src/logic/walkingdir.h' |
558 | --- src/logic/walkingdir.h 2014-07-05 16:41:51 +0000 |
559 | +++ src/logic/walkingdir.h 2015-04-07 20:58:43 +0000 |
560 | @@ -37,9 +37,9 @@ |
561 | LAST_DIRECTION = 6, |
562 | }; |
563 | |
564 | -uint8_t get_cw_neighbour(uint8_t dir); |
565 | -uint8_t get_ccw_neighbour(uint8_t dir); |
566 | -uint8_t get_backward_dir(uint8_t dir); |
567 | +WalkingDir get_cw_neighbour(WalkingDir dir); |
568 | +WalkingDir get_ccw_neighbour(WalkingDir dir); |
569 | +WalkingDir get_backward_dir(WalkingDir dir); |
570 | |
571 | } |
572 | |
573 | |
574 | === modified file 'src/scripting/lua_game.cc' |
575 | --- src/scripting/lua_game.cc 2015-01-31 16:03:59 +0000 |
576 | +++ src/scripting/lua_game.cc 2015-04-07 20:58:43 +0000 |
577 | @@ -97,6 +97,7 @@ |
578 | METHOD(LuaPlayer, hide_fields), |
579 | METHOD(LuaPlayer, reveal_scenario), |
580 | METHOD(LuaPlayer, reveal_campaign), |
581 | + METHOD(LuaPlayer, get_ships), |
582 | METHOD(LuaPlayer, get_buildings), |
583 | METHOD(LuaPlayer, get_suitability), |
584 | METHOD(LuaPlayer, allow_workers), |
585 | @@ -628,6 +629,7 @@ |
586 | int LuaPlayer::reveal_campaign(lua_State * L) { |
587 | if (get_game(L).get_ipl()->player_number() != player_number()) |
588 | report_error(L, "Can only be called for interactive player!"); |
589 | + report_error(L, "Can only be called for interactive player!"); |
590 | |
591 | CampaignVisibilitySave cvs; |
592 | cvs.set_campaign_visibility(luaL_checkstring(L, 2), true); |
593 | @@ -635,6 +637,41 @@ |
594 | return 0; |
595 | } |
596 | |
597 | +/* RST |
598 | + .. method:: get_ships() |
599 | + |
600 | + :returns: array of player's ships |
601 | + :rtype: :class:`array` or :class:`table` |
602 | +*/ |
603 | +int LuaPlayer::get_ships(lua_State * L) { |
604 | + EditorGameBase & egbase = get_egbase(L); |
605 | + Map * map = egbase.get_map(); |
606 | + PlayerNumber p = (get(L, egbase)).player_number(); |
607 | + lua_newtable(L); |
608 | + uint32_t cidx = 1; |
609 | + |
610 | + std::set<OPtr<Ship>> found_ships; |
611 | + for (int16_t y = 0; y < map->get_height(); ++y) { |
612 | + for (int16_t x = 0; x < map->get_width(); ++x) { |
613 | + FCoords f = map->get_fcoords(Coords(x, y)); |
614 | + // there are too many bobs on the map so we investigate |
615 | + // only bobs on water |
616 | + if (f.field->nodecaps() & MOVECAPS_SWIM) { |
617 | + for (Bob* bob = f.field->get_first_bob(); bob; bob = bob->get_next_on_field()) { |
618 | + if (upcast(Ship, ship, bob)) { |
619 | + if (ship->get_owner()->player_number() == p && !found_ships.count(ship)) { |
620 | + found_ships.insert(ship); |
621 | + lua_pushuint32(L, cidx++); |
622 | + LuaMaps::upcasted_map_object_to_lua(L, ship); |
623 | + lua_rawset(L, -3); |
624 | + } |
625 | + } |
626 | + } |
627 | + } |
628 | + } |
629 | + } |
630 | + return 1; |
631 | +} |
632 | |
633 | /* RST |
634 | .. method:: get_buildings(which) |
635 | |
636 | === modified file 'src/scripting/lua_game.h' |
637 | --- src/scripting/lua_game.h 2015-02-09 05:57:08 +0000 |
638 | +++ src/scripting/lua_game.h 2015-04-07 20:58:43 +0000 |
639 | @@ -83,6 +83,7 @@ |
640 | int hide_fields(lua_State * L); |
641 | int reveal_scenario(lua_State * L); |
642 | int reveal_campaign(lua_State * L); |
643 | + int get_ships(lua_State * L); |
644 | int get_buildings(lua_State * L); |
645 | int get_suitability(lua_State * L); |
646 | int allow_workers(lua_State * L); |
647 | |
648 | === modified file 'src/scripting/lua_map.cc' |
649 | --- src/scripting/lua_map.cc 2015-02-12 21:03:20 +0000 |
650 | +++ src/scripting/lua_map.cc 2015-04-07 20:58:43 +0000 |
651 | @@ -32,6 +32,7 @@ |
652 | #include "logic/maphollowregion.h" |
653 | #include "logic/mapregion.h" |
654 | #include "logic/player.h" |
655 | +#include "logic/ship.h" |
656 | #include "logic/soldier.h" |
657 | #include "logic/warelist.h" |
658 | #include "logic/widelands_geometry.h" |
659 | @@ -2681,13 +2682,13 @@ |
660 | ========================================================== |
661 | */ |
662 | |
663 | + |
664 | /* |
665 | ========================================================== |
666 | C METHODS |
667 | ========================================================== |
668 | */ |
669 | |
670 | - |
671 | /* RST |
672 | Building |
673 | -------- |
674 | @@ -2806,10 +2807,13 @@ |
675 | METHOD(LuaWarehouse, get_workers), |
676 | METHOD(LuaWarehouse, set_soldiers), |
677 | METHOD(LuaWarehouse, get_soldiers), |
678 | + METHOD(LuaWarehouse, start_expedition), |
679 | + METHOD(LuaWarehouse, cancel_expedition), |
680 | {nullptr, nullptr}, |
681 | }; |
682 | const PropertyType<LuaWarehouse> LuaWarehouse::Properties[] = { |
683 | PROP_RO(LuaWarehouse, portdock), |
684 | + PROP_RO(LuaWarehouse, expedition_in_progress), |
685 | {nullptr, nullptr, nullptr}, |
686 | }; |
687 | |
688 | @@ -2829,6 +2833,26 @@ |
689 | return upcasted_map_object_to_lua(L, get(L, get_egbase(L))->get_portdock()); |
690 | } |
691 | |
692 | +/* RST |
693 | + .. attribute:: expedition_in_progress |
694 | + |
695 | + (RO) If this Warehouse is a port, and an expedition is in |
696 | + progress, returns true, otherwise nil |
697 | +*/ |
698 | +int LuaWarehouse::get_expedition_in_progress(lua_State * L) { |
699 | + |
700 | + Warehouse* wh = get(L, get_egbase(L)); |
701 | + |
702 | + if (upcast(Game, game, &get_egbase(L))) { |
703 | + PortDock* pd = wh->get_portdock(); |
704 | + if (pd) { |
705 | + if (pd->expedition_started()){ |
706 | + return 1; |
707 | + } |
708 | + } |
709 | + } |
710 | + return 0; |
711 | +} |
712 | |
713 | /* |
714 | ========================================================== |
715 | @@ -2895,13 +2919,72 @@ |
716 | return do_set_soldiers(L, wh->get_position(), wh, wh->get_owner()); |
717 | } |
718 | |
719 | +/* RST |
720 | + .. method:: start_expedition(port) |
721 | + |
722 | + :arg port |
723 | + |
724 | + Starts preparation for expedition |
725 | + |
726 | +*/ |
727 | +int LuaWarehouse::start_expedition(lua_State* L) { |
728 | + |
729 | + Warehouse* Wh = get(L, get_egbase(L)); |
730 | + |
731 | + if (!Wh) { |
732 | + return 0; |
733 | + } |
734 | + |
735 | + if (upcast(Game, game, &get_egbase(L))) { |
736 | + PortDock* pd = Wh->get_portdock(); |
737 | + if (!pd) { |
738 | + return 0; |
739 | + } |
740 | + if (!pd->expedition_started()){ |
741 | + game->send_player_start_or_cancel_expedition(*Wh); |
742 | + return 1; |
743 | + } |
744 | + } |
745 | + |
746 | + return 0; |
747 | +} |
748 | + |
749 | +/* RST |
750 | + .. method:: cancel_expedition(port) |
751 | + |
752 | + :arg port |
753 | + |
754 | + Cancels an expedition if in progress |
755 | + |
756 | +*/ |
757 | +int LuaWarehouse::cancel_expedition(lua_State* L) { |
758 | + |
759 | + Warehouse* Wh = get(L, get_egbase(L)); |
760 | + |
761 | + if (!Wh) { |
762 | + return 0; |
763 | + } |
764 | + |
765 | + if (upcast(Game, game, &get_egbase(L))) { |
766 | + PortDock* pd = Wh->get_portdock(); |
767 | + if (!pd) { |
768 | + return 0; |
769 | + } |
770 | + if (pd->expedition_started()){ |
771 | + game->send_player_start_or_cancel_expedition(*Wh); |
772 | + return 1; |
773 | + } |
774 | + } |
775 | + |
776 | + return 0; |
777 | +} |
778 | + |
779 | /* |
780 | ========================================================== |
781 | C METHODS |
782 | ========================================================== |
783 | */ |
784 | |
785 | - |
786 | /* RST |
787 | ProductionSite |
788 | -------------- |
789 | @@ -3179,6 +3262,7 @@ |
790 | {nullptr, nullptr}, |
791 | }; |
792 | const PropertyType<LuaBob> LuaBob::Properties[] = { |
793 | + PROP_RO(LuaBob, field), |
794 | {nullptr, nullptr, nullptr}, |
795 | }; |
796 | |
797 | @@ -3189,6 +3273,27 @@ |
798 | */ |
799 | |
800 | /* RST |
801 | + .. attribute:: field //working here |
802 | + |
803 | + (RO) The field the bob is located on |
804 | +*/ |
805 | +// UNTESTED |
806 | +int LuaBob::get_field(lua_State * L) { |
807 | + |
808 | + EditorGameBase & egbase = get_egbase(L); |
809 | + |
810 | + Coords coords = get(L, egbase)->get_position(); |
811 | + |
812 | + return to_lua<LuaMaps::LuaField>(L, new LuaMaps::LuaField(coords.x, coords.y)); |
813 | +} |
814 | + |
815 | + |
816 | +/* |
817 | + ========================================================== |
818 | + LUA METHODS |
819 | + ========================================================== |
820 | + */ |
821 | +/* RST |
822 | .. method:: has_caps(capname) |
823 | |
824 | Similar to :meth:`Field::has_caps`. |
825 | @@ -3214,13 +3319,6 @@ |
826 | return 1; |
827 | } |
828 | |
829 | - |
830 | -/* |
831 | - ========================================================== |
832 | - LUA METHODS |
833 | - ========================================================== |
834 | - */ |
835 | - |
836 | /* |
837 | ========================================================== |
838 | C METHODS |
839 | @@ -3240,12 +3338,16 @@ |
840 | const MethodType<LuaShip> LuaShip::Methods[] = { |
841 | METHOD(LuaShip, get_wares), |
842 | METHOD(LuaShip, get_workers), |
843 | + METHOD(LuaShip, build_colonization_port), |
844 | {nullptr, nullptr}, |
845 | }; |
846 | const PropertyType<LuaShip> LuaShip::Properties[] = { |
847 | PROP_RO(LuaShip, debug_economy), |
848 | PROP_RO(LuaShip, last_portdock), |
849 | PROP_RO(LuaShip, destination), |
850 | + PROP_RO(LuaShip, state), |
851 | + PROP_RW(LuaShip, scouting_direction), |
852 | + PROP_RW(LuaShip, island_explore_direction), |
853 | {nullptr, nullptr, nullptr}, |
854 | }; |
855 | |
856 | @@ -3285,6 +3387,149 @@ |
857 | return upcasted_map_object_to_lua(L, get(L, egbase)->get_lastdock(egbase)); |
858 | } |
859 | |
860 | +/* RST |
861 | + .. attribute:: state |
862 | + |
863 | + Query which state the ship is in: |
864 | + |
865 | + - transport, |
866 | + - exp_waiting, exp_scouting, exp_found_port_space, exp_colonizing, |
867 | + - sink_request, sink_animation |
868 | + |
869 | + (RW) returns the :class:`string` ship's state, or :const:`nil` if there is no valid state. |
870 | + |
871 | + |
872 | +*/ |
873 | +// UNTESTED sink states |
874 | +int LuaShip::get_state(lua_State* L) { |
875 | + if (upcast(Game, game, &get_egbase(L))) { |
876 | + switch (get(L, get_egbase(L))->get_ship_state()) { |
877 | + case Ship::TRANSPORT: |
878 | + lua_pushstring(L, "transport"); |
879 | + break; |
880 | + case Ship::EXP_WAITING: |
881 | + lua_pushstring(L, "exp_waiting"); |
882 | + break; |
883 | + case Ship::EXP_SCOUTING: |
884 | + lua_pushstring(L, "exp_scouting"); |
885 | + break; |
886 | + case Ship::EXP_FOUNDPORTSPACE: |
887 | + lua_pushstring(L, "exp_found_port_space"); |
888 | + break; |
889 | + case Ship::EXP_COLONIZING: |
890 | + lua_pushstring(L, "exp_colonizing"); |
891 | + break; |
892 | + case Ship::SINK_REQUEST: |
893 | + lua_pushstring(L, "sink_request"); |
894 | + break; |
895 | + case Ship::SINK_ANIMATION: |
896 | + lua_pushstring(L, "sink_animation"); |
897 | + break; |
898 | + default: |
899 | + lua_pushnil(L); |
900 | + return 0; |
901 | + } |
902 | + return 1; |
903 | + } |
904 | + return 0; |
905 | +} |
906 | + |
907 | +int LuaShip::get_scouting_direction(lua_State* L) { |
908 | + if (upcast(Game, game, &get_egbase(L))) { |
909 | + switch (get(L, get_egbase(L))->get_scouting_direction()) { |
910 | + case WalkingDir::WALK_NE: |
911 | + lua_pushstring(L, "ne"); |
912 | + break; |
913 | + case WalkingDir::WALK_E: |
914 | + lua_pushstring(L, "e"); |
915 | + break; |
916 | + case WalkingDir::WALK_SE: |
917 | + lua_pushstring(L, "se"); |
918 | + break; |
919 | + case WalkingDir::WALK_SW: |
920 | + lua_pushstring(L, "sw"); |
921 | + break; |
922 | + case WalkingDir::WALK_W: |
923 | + lua_pushstring(L, "w"); |
924 | + break; |
925 | + case WalkingDir::WALK_NW: |
926 | + lua_pushstring(L, "nw"); |
927 | + break; |
928 | + default: |
929 | + return 0; |
930 | + } |
931 | + return 1; |
932 | + } |
933 | + return 0; |
934 | +} |
935 | + |
936 | +int LuaShip::set_scouting_direction(lua_State* L) { |
937 | + if (upcast(Game, game, &get_egbase(L))) { |
938 | + std::string dirname = luaL_checkstring(L, 3); |
939 | + WalkingDir dir = WalkingDir::IDLE; |
940 | + |
941 | + if (dirname == "ne") { |
942 | + dir = WalkingDir::WALK_NE; |
943 | + } else if (dirname == "e") { |
944 | + dir = WalkingDir::WALK_E; |
945 | + } else if (dirname == "se") { |
946 | + dir = WalkingDir::WALK_SE; |
947 | + } else if (dirname == "sw") { |
948 | + dir = WalkingDir::WALK_SW; |
949 | + } else if (dirname == "w") { |
950 | + dir = WalkingDir::WALK_W; |
951 | + } else if (dirname == "nw") { |
952 | + dir = WalkingDir::WALK_NW; |
953 | + } else { |
954 | + return 0; |
955 | + } |
956 | + game->send_player_ship_scouting_direction(*get(L, get_egbase(L)), dir); |
957 | + return 1; |
958 | + } |
959 | + return 0; |
960 | + |
961 | +} |
962 | + |
963 | +/* RST |
964 | + .. attribute:: island_explore_direction |
965 | + |
966 | + (RW) actual direction if the ship sails around an island. |
967 | + Sets/returns cw, ccw or nil |
968 | + |
969 | +*/ |
970 | +int LuaShip::get_island_explore_direction(lua_State* L) { |
971 | + if (upcast(Game, game, &get_egbase(L))) { |
972 | + switch (get(L, get_egbase(L))->get_island_explore_direction()) { |
973 | + case IslandExploreDirection::kCounterClockwise: |
974 | + lua_pushstring(L, "ccw"); |
975 | + break; |
976 | + case IslandExploreDirection::kClockwise: |
977 | + lua_pushstring(L, "cw"); |
978 | + break; |
979 | + default: |
980 | + return 0; |
981 | + } |
982 | + return 1; |
983 | + } |
984 | + return 0; |
985 | +} |
986 | + |
987 | +int LuaShip::set_island_explore_direction(lua_State* L) { |
988 | + if (upcast(Game, game, &get_egbase(L))) { |
989 | + Ship* ship = get(L, get_egbase(L)); |
990 | + std::string dir = luaL_checkstring(L, 3); |
991 | + if (dir == "ccw"){ |
992 | + game->send_player_ship_explore_island(*ship, IslandExploreDirection::kCounterClockwise); |
993 | + } else if (dir == "cw") { |
994 | + game->send_player_ship_explore_island(*ship, IslandExploreDirection::kClockwise); |
995 | + } else { |
996 | + return 0; |
997 | + } |
998 | + return 1; |
999 | + } |
1000 | + return 0; |
1001 | +} |
1002 | + |
1003 | /* |
1004 | ========================================================== |
1005 | LUA METHODS |
1006 | @@ -3341,6 +3586,25 @@ |
1007 | return 1; |
1008 | } |
1009 | |
1010 | +/* RST |
1011 | + .. method:: build_colonization_port() |
1012 | + |
1013 | + Returns true if port space construction was started (ship was in adequate |
1014 | + status and a found portspace was nearby) |
1015 | + |
1016 | + :returns: true/false |
1017 | +*/ |
1018 | +int LuaShip::build_colonization_port(lua_State* L) { |
1019 | + Ship* ship = get(L, get_egbase(L)); |
1020 | + if (ship->get_ship_state() == Widelands::Ship::EXP_FOUNDPORTSPACE) { |
1021 | + if (upcast(Game, game, &get_egbase(L))) { |
1022 | + game->send_player_ship_construct_port(*ship, ship->exp_port_spaces()->front()); |
1023 | + return 1; |
1024 | + } |
1025 | + } |
1026 | + return 0; |
1027 | +} |
1028 | + |
1029 | /* |
1030 | ========================================================== |
1031 | C METHODS |
1032 | |
1033 | === modified file 'src/scripting/lua_map.h' |
1034 | --- src/scripting/lua_map.h 2015-02-12 21:03:20 +0000 |
1035 | +++ src/scripting/lua_map.h 2015-04-07 20:58:43 +0000 |
1036 | @@ -688,6 +688,7 @@ |
1037 | * Properties |
1038 | */ |
1039 | int get_portdock(lua_State* L); |
1040 | + int get_expedition_in_progress(lua_State* L); |
1041 | |
1042 | /* |
1043 | * Lua Methods |
1044 | @@ -698,6 +699,8 @@ |
1045 | int set_workers(lua_State*); |
1046 | int set_soldiers(lua_State*); |
1047 | int get_soldiers(lua_State*); |
1048 | + int start_expedition(lua_State*); |
1049 | + int cancel_expedition(lua_State*); |
1050 | |
1051 | /* |
1052 | * C Methods |
1053 | @@ -806,6 +809,7 @@ |
1054 | /* |
1055 | * Properties |
1056 | */ |
1057 | + int get_field(lua_State *); |
1058 | int has_caps(lua_State *); |
1059 | |
1060 | /* |
1061 | @@ -885,12 +889,17 @@ |
1062 | int get_debug_economy(lua_State * L); |
1063 | int get_last_portdock(lua_State* L); |
1064 | int get_destination(lua_State* L); |
1065 | - |
1066 | + int get_state(lua_State* L); |
1067 | + int get_scouting_direction(lua_State* L); |
1068 | + int set_scouting_direction(lua_State* L); |
1069 | + int get_island_explore_direction(lua_State* L); |
1070 | + int set_island_explore_direction(lua_State* L); |
1071 | /* |
1072 | * Lua methods |
1073 | */ |
1074 | int get_wares(lua_State* L); |
1075 | int get_workers(lua_State* L); |
1076 | + int build_colonization_port(lua_State* L); |
1077 | |
1078 | /* |
1079 | * C methods |
1080 | |
1081 | === modified file 'src/wui/shipwindow.cc' |
1082 | --- src/wui/shipwindow.cc 2015-02-05 12:11:20 +0000 |
1083 | +++ src/wui/shipwindow.cc 2015-04-07 20:58:43 +0000 |
1084 | @@ -68,9 +68,9 @@ |
1085 | void act_destination(); |
1086 | void act_sink(); |
1087 | void act_cancel_expedition(); |
1088 | - void act_scout_towards(uint8_t); |
1089 | + void act_scout_towards(WalkingDir); |
1090 | void act_construct_port(); |
1091 | - void act_explore_island(ScoutingDirection); |
1092 | + void act_explore_island(IslandExploreDirection); |
1093 | |
1094 | private: |
1095 | InteractiveGameBase & m_igbase; |
1096 | @@ -120,7 +120,7 @@ |
1097 | m_btn_explore_island_cw = |
1098 | make_button |
1099 | (exp_top, "expcw", _("Explore the island’s coast clockwise"), pic_explore_cw, |
1100 | - boost::bind(&ShipWindow::act_explore_island, this, ScoutingDirection::kClockwise)); |
1101 | + boost::bind(&ShipWindow::act_explore_island, this, IslandExploreDirection::kClockwise)); |
1102 | exp_top->add(m_btn_explore_island_cw, 0, false); |
1103 | |
1104 | m_btn_scout[WALK_NE - 1] = |
1105 | @@ -156,7 +156,7 @@ |
1106 | m_btn_explore_island_ccw = |
1107 | make_button |
1108 | (exp_bot, "expccw", _("Explore the island’s coast counter clockwise"), pic_explore_ccw, |
1109 | - boost::bind(&ShipWindow::act_explore_island, this, ScoutingDirection::kCounterClockwise)); |
1110 | + boost::bind(&ShipWindow::act_explore_island, this, IslandExploreDirection::kCounterClockwise)); |
1111 | exp_bot->add(m_btn_explore_island_ccw, 0, false); |
1112 | |
1113 | m_btn_scout[WALK_SE - 1] = |
1114 | @@ -312,11 +312,11 @@ |
1115 | } |
1116 | |
1117 | /// Sends a player command to the ship to scout towards a specific direction |
1118 | -void ShipWindow::act_scout_towards(uint8_t direction) { |
1119 | +void ShipWindow::act_scout_towards(WalkingDir direction) { |
1120 | // ignore request if the direction is not swimable at all |
1121 | - if (!m_ship.exp_dir_swimable(direction)) |
1122 | + if (!m_ship.exp_dir_swimable(static_cast<Direction>(direction))) |
1123 | return; |
1124 | - m_igbase.game().send_player_ship_scout_direction(m_ship, direction); |
1125 | + m_igbase.game().send_player_ship_scouting_direction(m_ship, direction); |
1126 | } |
1127 | |
1128 | /// Constructs a port at the port build space in vision range |
1129 | @@ -327,7 +327,7 @@ |
1130 | } |
1131 | |
1132 | /// Explores the island cw or ccw |
1133 | -void ShipWindow::act_explore_island(ScoutingDirection direction) { |
1134 | +void ShipWindow::act_explore_island(IslandExploreDirection direction) { |
1135 | bool coast_nearby = false; |
1136 | bool moveable = false; |
1137 | for (Direction dir = 1; (dir <= LAST_DIRECTION) && (!coast_nearby || !moveable); ++dir) { |
1138 | |
1139 | === modified file 'test/maps/expedition.wmf/scripting/init.lua' |
1140 | --- test/maps/expedition.wmf/scripting/init.lua 2014-08-01 15:30:12 +0000 |
1141 | +++ test/maps/expedition.wmf/scripting/init.lua 2015-04-07 20:58:43 +0000 |
1142 | @@ -93,24 +93,6 @@ |
1143 | assert_equal(1, port:get_workers("builder")) |
1144 | end |
1145 | |
1146 | -function start_expedition() |
1147 | - assert_true(click_building(p1, "port")) |
1148 | - sleep(100) |
1149 | - assert_true(click_button("start_expedition")) |
1150 | - sleep(100) |
1151 | - close_windows() |
1152 | - sleep(100) |
1153 | -end |
1154 | - |
1155 | -function cancel_expedition_in_port() |
1156 | - assert_true(click_building(p1, "port")) |
1157 | - sleep(100) |
1158 | - assert_true(click_button("cancel_expedition")) |
1159 | - sleep(100) |
1160 | - close_windows() |
1161 | - sleep(100) |
1162 | -end |
1163 | - |
1164 | function cancel_expedition_in_shipwindow(which_ship) |
1165 | click_on_ship(which_ship or first_ship) |
1166 | assert_true(click_button("cancel_expedition")) |
1167 | @@ -174,7 +156,7 @@ |
1168 | game.desired_speed = 10 * 1000 |
1169 | |
1170 | -- Start a new expedition. |
1171 | - start_expedition() |
1172 | + port:start_expedition() |
1173 | wait_for_message("Expedition Ready") |
1174 | game.desired_speed = 10 * 1000 |
1175 | sleep(10000) |
1176 | @@ -205,14 +187,15 @@ |
1177 | game.desired_speed = 10 * 1000 |
1178 | |
1179 | -- Start a new expedition. |
1180 | - start_expedition() |
1181 | + port:start_expedition() |
1182 | wait_for_message("Expedition Ready") |
1183 | game.desired_speed = 10 * 1000 |
1184 | sleep(10000) |
1185 | |
1186 | - click_on_ship(first_ship) |
1187 | - assert_true(click_button("expccw")) |
1188 | - sleep(8000) |
1189 | + first_ship.island_explore_direction="ccw" |
1190 | + sleep(2000) |
1191 | + assert_equal("ccw",first_ship.island_explore_direction) |
1192 | + sleep(6000) |
1193 | |
1194 | stable_save("sailing") |
1195 | assert_equal(1, p1:get_workers("builder")) |
1196 | @@ -235,13 +218,14 @@ |
1197 | game.desired_speed = 10 * 1000 |
1198 | |
1199 | -- Send expedition to port space. |
1200 | - start_expedition() |
1201 | + port:start_expedition() |
1202 | wait_for_message("Expedition Ready") |
1203 | assert_equal(1, p1:get_workers("builder")) |
1204 | sleep(500) |
1205 | |
1206 | - click_on_ship(first_ship) |
1207 | - assert_true(click_button("expccw")) |
1208 | + first_ship.island_explore_direction="ccw" |
1209 | + sleep(2000) |
1210 | + assert_equal("ccw",first_ship.island_explore_direction) |
1211 | wait_for_message("Port Space Found") |
1212 | sleep(500) |
1213 | assert_equal(1, p1:get_workers("builder")) |
1214 | @@ -272,12 +256,13 @@ |
1215 | port:set_wares("blackwood", 100) |
1216 | |
1217 | |
1218 | - start_expedition() |
1219 | + port:start_expedition() |
1220 | wait_for_message("Expedition Ready") |
1221 | - click_on_ship(first_ship) |
1222 | - assert_true(click_button("expccw")) |
1223 | + first_ship.island_explore_direction="ccw" |
1224 | + sleep(2000) |
1225 | + assert_equal("ccw",first_ship.island_explore_direction) |
1226 | wait_for_message("Port Space Found") |
1227 | - assert_true(click_button("buildport")) |
1228 | + first_ship:build_colonization_port() |
1229 | sleep(500) |
1230 | assert_equal(1, p1:get_workers("builder")) |
1231 | wait_for_message("Port") |
1232 | |
1233 | === added file 'test/maps/expedition.wmf/scripting/test_ship_movement_controls.lua' |
1234 | --- test/maps/expedition.wmf/scripting/test_ship_movement_controls.lua 1970-01-01 00:00:00 +0000 |
1235 | +++ test/maps/expedition.wmf/scripting/test_ship_movement_controls.lua 2015-04-07 20:58:43 +0000 |
1236 | @@ -0,0 +1,115 @@ |
1237 | +run(function() |
1238 | + game.desired_speed = 30 * 1000 |
1239 | + p1:place_bob("ship", map:get_field(10, 10)) |
1240 | + |
1241 | + port = map:get_field(16, 16).immovable |
1242 | + port:set_wares("log", 10) -- no sense to wait |
1243 | + port:set_wares("blackwood", 10) |
1244 | + |
1245 | + --getting table with all our ships (single one only) |
1246 | + ships = p1:get_ships() |
1247 | + |
1248 | + --veryfing that ship is indeed placed where should be :) |
1249 | + assert_equal(10,ships[1].field.x) |
1250 | + assert_equal(10,ships[1].field.y) |
1251 | + |
1252 | + --ships table should contain 1 item (1 ship) |
1253 | + assert_equal(1, #ships) |
1254 | + |
1255 | + --ship has no wares on it |
1256 | + assert_equal(0,ships[1]:get_wares()) |
1257 | + |
1258 | + --no destination is set |
1259 | + assert(not ships[1].destination) |
1260 | + |
1261 | + --ships in transport state |
1262 | + assert_equal("transport", ships[1].state) |
1263 | + |
1264 | + --the warehouse is probably not in expedition state :) |
1265 | + assert(not map:get_field(8, 18).immovable.expedition_in_progress) |
1266 | + |
1267 | + --starting prepartion for expedition |
1268 | + assert(not port.expedition_in_progress) |
1269 | + port:start_expedition() |
1270 | + sleep (300) |
1271 | + assert(port.expedition_in_progress) |
1272 | + |
1273 | + --ships changes state when exp ready |
1274 | + while ships[1].state == "transport" do sleep(2000) end |
1275 | + assert_equal("exp_waiting", ships[1].state) |
1276 | + |
1277 | + --sending NW and verifying |
1278 | + ships[1].scouting_direction="nw" |
1279 | + sleep(6000) |
1280 | + assert_equal("nw", ships[1].scouting_direction) |
1281 | + assert_equal("exp_scouting", ships[1].state) |
1282 | + |
1283 | + while ships[1].scouting_direction == "nw" do |
1284 | + sleep (2000) |
1285 | + end |
1286 | + |
1287 | + --now ships stops nearby NW coast, so sending it back |
1288 | + ships[1].scouting_direction="se" |
1289 | + sleep(4000) |
1290 | + assert_equal("se", ships[1].scouting_direction) |
1291 | + |
1292 | + --testing remaining directions |
1293 | + ships[1].scouting_direction="e" |
1294 | + sleep(2000) |
1295 | + assert_equal("e", ships[1].scouting_direction) |
1296 | + |
1297 | + ships[1].scouting_direction="w" |
1298 | + sleep(2000) |
1299 | + assert_equal("w", ships[1].scouting_direction) |
1300 | + |
1301 | + ships[1].scouting_direction="sw" |
1302 | + sleep(2000) |
1303 | + assert_equal("sw", ships[1].scouting_direction) |
1304 | + |
1305 | + ships[1].scouting_direction="ne" |
1306 | + sleep(2000) |
1307 | + assert_equal("ne", ships[1].scouting_direction) |
1308 | + |
1309 | + --back to original course |
1310 | + ships[1].scouting_direction="se" |
1311 | + sleep(2000) |
1312 | + assert_equal("se", ships[1].scouting_direction) |
1313 | + |
1314 | + --waiting till it stops (no direction/nil is returned) |
1315 | + while ships[1].scouting_direction do sleep(2000) end |
1316 | + |
1317 | + --sending to scout the island |
1318 | + ships[1].island_explore_direction="ccw"; |
1319 | + sleep(3000) |
1320 | + assert_equal("ccw", ships[1].island_explore_direction) |
1321 | + assert_equal("exp_scouting", ships[1].state) |
1322 | + |
1323 | + --fine, now change the direction |
1324 | + ships[1].island_explore_direction="cw"; |
1325 | + sleep(3000) |
1326 | + assert_equal("cw", ships[1].island_explore_direction) |
1327 | + |
1328 | + -- wait till it finds a port |
1329 | + wait_for_message("Port Space Found") |
1330 | + sleep(500) |
1331 | + assert_equal("exp_found_port_space", ships[1].state) |
1332 | + |
1333 | + --starting colonization port here |
1334 | + assert(ships[1]:build_colonization_port()) |
1335 | + sleep(500) |
1336 | + assert_equal("exp_colonizing", ships[1].state) |
1337 | + sleep(15000) |
1338 | + stable_save("port_in_constr") |
1339 | + |
1340 | + -- while unfinished yet, removing it |
1341 | + new_port=map:get_field(16,2).immovable |
1342 | + assert(new_port) |
1343 | + new_port:remove() |
1344 | + sleep(3000) |
1345 | + |
1346 | + --yes, the ships is back in transport mode |
1347 | + assert_equal("transport", ships[1].state) |
1348 | + |
1349 | + print("# All Tests passed.") |
1350 | + wl.ui.MapView():close() |
1351 | +end) |
1352 | |
1353 | === modified file 'test/maps/expedition.wmf/scripting/test_starting_and_immediately_canceling.lua' |
1354 | --- test/maps/expedition.wmf/scripting/test_starting_and_immediately_canceling.lua 2013-10-29 20:22:08 +0000 |
1355 | +++ test/maps/expedition.wmf/scripting/test_starting_and_immediately_canceling.lua 2015-04-07 20:58:43 +0000 |
1356 | @@ -5,8 +5,12 @@ |
1357 | |
1358 | -- Start and immediately cancel an expedition. |
1359 | print("---- 1 -----") |
1360 | - start_expedition() |
1361 | - cancel_expedition_in_port() |
1362 | + port:start_expedition() |
1363 | + sleep(500) |
1364 | + assert(port.expedition_in_progress) |
1365 | + port:cancel_expedition() |
1366 | + sleep(500) |
1367 | + assert(not port.expedition_in_progress) |
1368 | sleep(500) |
1369 | assert_equal(1, p1:get_workers("builder")) |
1370 | |
1371 | |
1372 | === modified file 'test/maps/expedition.wmf/scripting/test_starting_wait_a_while_cancel.lua' |
1373 | --- test/maps/expedition.wmf/scripting/test_starting_wait_a_while_cancel.lua 2013-10-29 20:22:08 +0000 |
1374 | +++ test/maps/expedition.wmf/scripting/test_starting_wait_a_while_cancel.lua 2015-04-07 20:58:43 +0000 |
1375 | @@ -4,12 +4,12 @@ |
1376 | |
1377 | -- Start an expedition, but let them carry some wares into it. This also |
1378 | -- gives the builder enough time to walk over. |
1379 | - start_expedition() |
1380 | + port:start_expedition() |
1381 | sleep(50000) |
1382 | stable_save("cancel_in_port") |
1383 | assert_equal(1, p1:get_workers("builder")) |
1384 | |
1385 | - cancel_expedition_in_port() |
1386 | + port:cancel_expedition() |
1387 | sleep(500) |
1388 | assert_equal(1, p1:get_workers("builder")) |
1389 | |
1390 | |
1391 | === modified file 'test/maps/ship_transportation.wmf/scripting/init.lua' |
1392 | --- test/maps/ship_transportation.wmf/scripting/init.lua 2015-02-10 21:25:14 +0000 |
1393 | +++ test/maps/ship_transportation.wmf/scripting/init.lua 2015-04-07 20:58:43 +0000 |
1394 | @@ -37,23 +37,6 @@ |
1395 | return nil |
1396 | end |
1397 | |
1398 | -function portdock2() |
1399 | - local portdock = map:get_field(15, 4).immovable |
1400 | - if portdock then |
1401 | - return portdock |
1402 | - end |
1403 | - local portdock = map:get_field(14, 5).immovable |
1404 | - if portdock then |
1405 | - return portdock |
1406 | - end |
1407 | - local portdock = map:get_field(14, 4).immovable |
1408 | - if portdock then |
1409 | - return portdock |
1410 | - end |
1411 | - print ("portdock not found") |
1412 | - return nill |
1413 | -end |
1414 | - |
1415 | function start_building_farm() |
1416 | p1:place_building("farm", map:get_field(18, 4), true, true) |
1417 | connected_road(p1, map:get_field(18,5).immovable, "l,l|tl,tr|", true) |
1418 | |
1419 | === modified file 'test/maps/ship_transportation.wmf/scripting/test_rip_portdock_with_worker_and_ware_in_transit.lua' |
1420 | --- test/maps/ship_transportation.wmf/scripting/test_rip_portdock_with_worker_and_ware_in_transit.lua 2015-02-10 21:25:14 +0000 |
1421 | +++ test/maps/ship_transportation.wmf/scripting/test_rip_portdock_with_worker_and_ware_in_transit.lua 2015-04-07 20:58:43 +0000 |
1422 | @@ -32,7 +32,9 @@ |
1423 | stable_save("restored_port") |
1424 | |
1425 | -- remove the portdock while the blackwood is in transit. |
1426 | - portdock2():remove() |
1427 | + port2_portdock=port2().portdock |
1428 | + assert(port2_portdock) |
1429 | + port2_portdock:remove() |
1430 | |
1431 | sleep(5000) |
1432 | |
1433 | |
1434 | === modified file 'test/maps/ship_transportation.wmf/scripting/test_rip_second_port_with_worker_in_portdock.lua' |
1435 | --- test/maps/ship_transportation.wmf/scripting/test_rip_second_port_with_worker_in_portdock.lua 2014-01-18 12:40:08 +0000 |
1436 | +++ test/maps/ship_transportation.wmf/scripting/test_rip_second_port_with_worker_in_portdock.lua 2015-04-07 20:58:43 +0000 |
1437 | @@ -5,6 +5,13 @@ |
1438 | create_first_port() |
1439 | create_second_port() |
1440 | |
1441 | + --removing portdock first |
1442 | + portdock_fields=port2().portdock.fields |
1443 | + portdock_fields[1].immovable:remove() |
1444 | + sleep(100) |
1445 | + --portdock should be back, as port is still there |
1446 | + assert (portdock_fields[1].immovable) |
1447 | + |
1448 | start_building_farm() |
1449 | port1():set_workers{ |
1450 | builder = 1, |
1451 | @@ -16,8 +23,13 @@ |
1452 | assert_equal(p1:get_workers("builder"), 1) |
1453 | assert_equal(port1():get_workers("builder"), 0) |
1454 | |
1455 | + portdock_fields=port2().portdock.fields |
1456 | port2():remove() |
1457 | sleep(100) |
1458 | + --verify that also portdock was removed |
1459 | + assert (not portdock_fields[1].immovable) |
1460 | + |
1461 | + sleep(100) |
1462 | |
1463 | stable_save("worker_in_portdock") |
1464 |
I just had a very quick look and it seems to be OK overall - I will have to look at the code properly. One thing though: it might be better to have strings rather than numbers in Lua for the scouting direction. Operating on the pure numbers will make the code hard to read, and also break the code if the C++ enum should change.