Merge lp:~widelands-dev/widelands/amazons-coding-changes into lp:widelands

Proposed by Benedikt Straub on 2019-08-23
Status: Merged
Merged at revision: 9195
Proposed branch: lp:~widelands-dev/widelands/amazons-coding-changes
Merge into: lp:widelands
Diff against target: 4790 lines (+888/-568)
92 files modified
data/world/terrains/init.lua (+64/-1)
src/ai/ai_help_structs.cc (+13/-13)
src/ai/ai_help_structs.h (+12/-12)
src/ai/defaultai.cc (+26/-26)
src/ai/defaultai_seafaring.cc (+1/-1)
src/ai/defaultai_warfare.cc (+2/-2)
src/editor/editorinteractive.cc (+8/-8)
src/editor/map_generator.cc (+2/-2)
src/editor/tools/decrease_height_tool.cc (+6/-9)
src/editor/tools/decrease_height_tool.h (+2/-4)
src/editor/tools/decrease_resources_tool.cc (+5/-6)
src/editor/tools/decrease_resources_tool.h (+2/-4)
src/editor/tools/delete_critter_tool.cc (+3/-6)
src/editor/tools/delete_critter_tool.h (+2/-4)
src/editor/tools/delete_immovable_tool.cc (+4/-7)
src/editor/tools/delete_immovable_tool.h (+2/-4)
src/editor/tools/draw_tool.cc (+4/-6)
src/editor/tools/draw_tool.h (+2/-4)
src/editor/tools/history.cc (+5/-6)
src/editor/tools/history.h (+2/-3)
src/editor/tools/increase_height_tool.cc (+5/-7)
src/editor/tools/increase_height_tool.h (+2/-4)
src/editor/tools/increase_resources_tool.cc (+5/-5)
src/editor/tools/increase_resources_tool.h (+2/-4)
src/editor/tools/info_tool.cc (+4/-4)
src/editor/tools/info_tool.h (+1/-2)
src/editor/tools/noise_height_tool.cc (+5/-7)
src/editor/tools/noise_height_tool.h (+2/-4)
src/editor/tools/place_critter_tool.cc (+7/-9)
src/editor/tools/place_critter_tool.h (+2/-4)
src/editor/tools/place_immovable_tool.cc (+5/-7)
src/editor/tools/place_immovable_tool.h (+2/-4)
src/editor/tools/resize_tool.cc (+9/-14)
src/editor/tools/resize_tool.h (+2/-4)
src/editor/tools/set_height_tool.cc (+6/-8)
src/editor/tools/set_height_tool.h (+2/-4)
src/editor/tools/set_origin_tool.cc (+2/-4)
src/editor/tools/set_origin_tool.h (+2/-4)
src/editor/tools/set_port_space_tool.cc (+12/-16)
src/editor/tools/set_port_space_tool.h (+4/-8)
src/editor/tools/set_resources_tool.cc (+6/-6)
src/editor/tools/set_resources_tool.h (+2/-4)
src/editor/tools/set_starting_pos_tool.cc (+1/-2)
src/editor/tools/set_starting_pos_tool.h (+1/-2)
src/editor/tools/set_terrain_tool.cc (+6/-8)
src/editor/tools/set_terrain_tool.h (+2/-4)
src/editor/tools/tool.h (+4/-9)
src/editor/ui_menus/main_menu_new_map.cc (+2/-2)
src/editor/ui_menus/main_menu_random_map.cc (+2/-2)
src/editor/ui_menus/main_menu_save_map.cc (+1/-1)
src/logic/editor_game_base.cc (+9/-7)
src/logic/editor_game_base.h (+3/-3)
src/logic/map.cc (+71/-69)
src/logic/map.h (+29/-29)
src/logic/map_objects/bob.cc (+2/-2)
src/logic/map_objects/findnode.cc (+28/-11)
src/logic/map_objects/findnode.h (+19/-12)
src/logic/map_objects/immovable.cc (+2/-2)
src/logic/map_objects/tribes/building.cc (+74/-5)
src/logic/map_objects/tribes/building.h (+13/-4)
src/logic/map_objects/tribes/constructionsite.cc (+23/-11)
src/logic/map_objects/tribes/dismantlesite.cc (+37/-9)
src/logic/map_objects/tribes/dismantlesite.h (+3/-1)
src/logic/map_objects/tribes/militarysite.cc (+3/-3)
src/logic/map_objects/tribes/production_program.cc (+3/-3)
src/logic/map_objects/tribes/ship.cc (+5/-5)
src/logic/map_objects/tribes/soldier.cc (+7/-7)
src/logic/map_objects/tribes/warehouse.cc (+1/-1)
src/logic/map_objects/tribes/worker.cc (+64/-13)
src/logic/map_objects/tribes/worker.h (+2/-0)
src/logic/map_objects/tribes/worker_program.cc (+34/-2)
src/logic/map_objects/tribes/worker_program.h (+1/-0)
src/logic/map_objects/world/terrain_description.cc (+14/-0)
src/logic/map_objects/world/terrain_description.h (+4/-0)
src/logic/map_objects/world/world.cc (+20/-0)
src/logic/map_objects/world/world.h (+3/-0)
src/logic/player.cc (+45/-22)
src/logic/player.h (+4/-4)
src/logic/playercommand.cc (+1/-1)
src/map_io/map_bob_packet.cc (+1/-1)
src/map_io/map_building_packet.cc (+1/-1)
src/map_io/map_buildingdata_packet.cc (+18/-8)
src/map_io/map_port_spaces_packet.cc (+1/-1)
src/map_io/s2map.cc (+8/-8)
src/map_io/s2map.h (+1/-1)
src/map_io/widelands_map_loader.cc (+1/-1)
src/scripting/lua_bases.cc (+1/-1)
src/scripting/lua_map.cc (+7/-9)
src/wui/fieldaction.cc (+46/-16)
src/wui/game_debug_ui.cc (+1/-1)
src/wui/interactive_gamebase.cc (+2/-2)
src/wui/watchwindow.cc (+1/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/amazons-coding-changes
Reviewer Review Type Date Requested Status
GunChleoc Approve on 2019-09-05
hessenfarmer test 2019-08-23 Approve on 2019-09-04
Review via email: mp+371725@code.launchpad.net

Commit message

Implements the coding changes required for the new amazons tribe:
- findspace:swim (for water gatherers)
- Enhancing terrains (for gardening center)
- Constructing buildings over immovables (for treetop sentry)

Description of the change

Testcases in this branch:
– barbarian well works as water gatherer
– barbarian forester works as gardening center
– barbarian sentry is constructed over trees

data/tribes needs to be reverted before merging! (The data/world/terrains/init.lua should not be reverted, its changes are intended for merge)

To post a comment you must log in.
TiborB (tiborb95) wrote :

So some sites (barbarian well and forester) will also "upgrade" land types as a side effect of cutting wood or mining water? Anyway this does not seem dangerous to me.
What I dont understand is capability to build a sentry over a tree. Did you create another buildable field type, because this can not be handled by SMALL buildcaps... (I know that I can look into code, but the diff is toooooo long.
My basic question is - does this affect AI on current 4 tribes?

TiborB (tiborb95) wrote :

"treetop" means - in the branches of the mature tree, or does the building replace a tree?

Benedikt Straub (nordfriese) wrote :

The barbarian sites modified in this branch are only testcases, not intended for merging.
The new amazons tribe (under development in another branch) will have a "Gardening Center" whose only purpose is that the worker walks around and turns the terrain nearby into a different, more fertile terrain type.

The sentry idea is that this "Treetop Sentry" is a platform in the branches of a tree. Internally, I have created a value "built_over_immovable" in addition to the Size value – a building with this value set can be built only on a player-owned node where the max nodecaps is >= the building´s size and an immovable with the required attribute (in this case: big tree) stands on the node. The immovable is then removed when placing the building, but I hacked the animations so it looks as if it were still there.

The AI is currently unable to build this sentry, and it won´t build a gardening center either, but otherwise it should be unaffected.

Benedikt Straub (nordfriese) wrote :

For more information about the concepts, see the discussion at https://www.widelands.org/forum/post/29315/ onwards…

bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 5337. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/575756820.
Appveyor build 5108. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_amazons_coding_changes-5108.

9190. By Nordfriese on 2019-08-23

Testcases masked the regression tests

9191. By Nordfriese on 2019-08-23

Corrected a building requirement

9192. By Nordfriese on 2019-08-23

typo

GunChleoc (gunchleoc) wrote :

I have done a first round of code review, no testing yet.

hessenfarmer (stephan-lutz) wrote :

I just tested it with my first loadable(playable?) amazons data dir. However I didn't get a building menu when clicking on buildcap that already had a flg built. I got a view only menu instead.

hessenfarmer (stephan-lutz) wrote :

I confirmed the critical behaviour (not having the build menu with buildcaps already have a flg build) is not in trunk so this needs fixing

review: Needs Fixing (playtest)
Benedikt Straub (nordfriese) wrote :

Fixed the fieldaction bug and split off FindNodeTerraform.
New terraform syntax:
 "findspace=size:any radius:6 terraform",
 "walk=coords",
 "terraform",
 "return"

There´s no real reason why we need a World or EGBase in Tool parameters, is there? I removed it, as it can be fetched directly from the provided EIA.

I would prefer to keep the EGBase parameter in FindNode::accept. For now World and Map would suffice, but if we want to write some other new worker program for a new tribe someday (e.g. a forester that plants trees only in the territory of enemy players?) there´s no way around an EGBase param, no need to do the whole rework again then IMHO.

9193. By Nordfriese on 2019-09-03

Addressed code review

bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 5383. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/580196177.
Appveyor build 5153. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_amazons_coding_changes-5153.

9194. By Nordfriese on 2019-09-04

Merged trunk

hessenfarmer (stephan-lutz) wrote :

tested all the features of this branch with my data branch.
if this is good to go code wise we should think about a merge strategy.
I believe we can let this go in. as it doesn't change the game and then concentrate on the data and graphics. Otherwise we can merge this into the data branch and merge if the amazons are more mature.

review: Approve (test)
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 5386. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/580710729.
Appveyor build 5156. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_amazons_coding_changes-5156.

hessenfarmer (stephan-lutz) wrote :

While running an Ai only local multiplayer with 4 amazon tribes I get a crash with not very much information logged. Currently I don't know where this is coming from.

TiborB (tiborb95) wrote :

try with gdb if you can....

GunChleoc (gunchleoc) wrote :

Looks like the crash has been identified: https://www.widelands.org/forum/topic/2897/?page=11#post-29630

So, this is a data issue unrelated to this branch.

I'll revert the tribes and merge.

review: Approve
9195. By GunChleoc on 2019-09-05

Reverted changes to tribes.

GunChleoc (gunchleoc) wrote :

@bunnybot merge

review: Approve
hessenfarmer (stephan-lutz) wrote :

Hm I still get the following error in a release build.

Unexpected error during the game
vector::_M_range_check: __n (which is 255) >= this->size() (which is 131)

will install a debug build now

bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 5389. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/581267547.
Appveyor build 5159. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_amazons_coding_changes-5159.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/world/terrains/init.lua'
2--- data/world/terrains/init.lua 2018-12-19 07:04:55 +0000
3+++ data/world/terrains/init.lua 2019-09-05 15:29:33 +0000
4@@ -142,6 +142,12 @@
5 --
6 -- fertility = 700,
7 --
8+-- **enhancement**
9+-- *Optional*. The terrain this terrain can be turned into by buildings like
10+-- the amazon gardening center. Example::
11+--
12+-- enhancement = "summer_meadow3",
13+--
14
15 ------------------------
16 -- Former greenland --
17@@ -188,7 +194,6 @@
18 temperature = 100,
19 humidity = 600,
20 fertility = 650,
21-
22 }
23
24
25@@ -245,6 +250,8 @@
26 temperature = 100,
27 humidity = 400,
28 fertility = 400,
29+
30+ enhancement = "summer_mountain_meadow"
31 }
32
33
34@@ -261,6 +268,8 @@
35 temperature = 100,
36 humidity = 150,
37 fertility = 150,
38+
39+ enhancement = "summer_steppe"
40 }
41
42
43@@ -277,6 +286,8 @@
44 temperature = 75,
45 humidity = 800,
46 fertility = 450,
47+
48+ enhancement = "summer_meadow1"
49 }
50
51 world:new_terrain_type{
52@@ -332,6 +343,8 @@
53 temperature = 80,
54 humidity = 100,
55 fertility = 100,
56+
57+ enhancement = "summer_forested_mountain1"
58 }
59
60
61@@ -348,6 +361,8 @@
62 temperature = 80,
63 humidity = 100,
64 fertility = 100,
65+
66+ enhancement = "summer_forested_mountain1"
67 }
68
69
70@@ -364,6 +379,8 @@
71 temperature = 80,
72 humidity = 100,
73 fertility = 100,
74+
75+ enhancement = "summer_forested_mountain2"
76 }
77
78
79@@ -380,6 +397,8 @@
80 temperature = 80,
81 humidity = 100,
82 fertility = 100,
83+
84+ enhancement = "summer_forested_mountain2"
85 }
86
87 world:new_terrain_type{
88@@ -483,6 +502,8 @@
89 temperature = 120,
90 humidity = 150,
91 fertility = 900,
92+
93+ enhancement = "hardground3"
94 }
95
96
97@@ -503,6 +524,8 @@
98 temperature = 118,
99 humidity = 130,
100 fertility = 999,
101+
102+ enhancement = "hardground1"
103 }
104
105
106@@ -599,6 +622,8 @@
107 temperature = 120,
108 humidity = 100,
109 fertility = 200,
110+
111+ enhancement = "drysoil"
112 }
113
114
115@@ -653,6 +678,8 @@
116 temperature = 80,
117 humidity = 50,
118 fertility = 200,
119+
120+ enhancement = "wasteland_forested_mountain1"
121 }
122
123
124@@ -669,6 +696,8 @@
125 temperature = 80,
126 humidity = 50,
127 fertility = 200,
128+
129+ enhancement = "wasteland_forested_mountain1"
130 }
131
132
133@@ -685,6 +714,8 @@
134 temperature = 80,
135 humidity = 50,
136 fertility = 200,
137+
138+ enhancement = "wasteland_forested_mountain2"
139 }
140
141
142@@ -701,6 +732,8 @@
143 temperature = 80,
144 humidity = 50,
145 fertility = 200,
146+
147+ enhancement = "wasteland_forested_mountain2"
148 }
149
150
151@@ -849,6 +882,8 @@
152 temperature = 40,
153 humidity = 750,
154 fertility = 400,
155+
156+ enhancement = "tundra2"
157 }
158
159
160@@ -865,6 +900,8 @@
161 temperature = 35,
162 humidity = 750,
163 fertility = 300,
164+
165+ enhancement = "tundra_taiga"
166 }
167
168
169@@ -881,6 +918,8 @@
170 temperature = 25,
171 humidity = 800,
172 fertility = 100,
173+
174+ enhancement = "taiga"
175 }
176
177
178@@ -935,6 +974,8 @@
179 temperature = 20,
180 humidity = 300,
181 fertility = 50,
182+
183+ enhancement = "winter_forested_mountain1"
184 }
185
186
187@@ -951,6 +992,8 @@
188 temperature = 20,
189 humidity = 300,
190 fertility = 50,
191+
192+ enhancement = "winter_forested_mountain1"
193 }
194
195
196@@ -967,6 +1010,8 @@
197 temperature = 20,
198 humidity = 300,
199 fertility = 50,
200+
201+ enhancement = "winter_forested_mountain2"
202 }
203
204
205@@ -983,6 +1028,8 @@
206 temperature = 20,
207 humidity = 300,
208 fertility = 50,
209+
210+ enhancement = "winter_forested_mountain2"
211 }
212 world:new_terrain_type{
213 name = "ice",
214@@ -1084,6 +1131,8 @@
215 temperature = 168,
216 humidity = 1,
217 fertility = 100,
218+
219+ enhancement = "drysoil"
220 }
221
222 world:new_terrain_type{
223@@ -1099,6 +1148,8 @@
224 temperature = 172,
225 humidity = 200,
226 fertility = 200,
227+
228+ enhancement = "highmountainmeadow"
229 }
230 world:new_terrain_type{
231 name = "desert_steppe",
232@@ -1157,6 +1208,8 @@
233 temperature = 145,
234 humidity = 500,
235 fertility = 500,
236+
237+ enhancement = "desert_steppe"
238 }
239
240
241@@ -1177,6 +1230,8 @@
242 temperature = 140,
243 humidity = 400,
244 fertility = 400,
245+
246+ enhancement = "mountainmeadow"
247 }
248
249
250@@ -1232,6 +1287,8 @@
251 temperature = 130,
252 humidity = 50,
253 fertility = 50,
254+
255+ enhancement = "desert_forested_mountain1"
256 }
257
258
259@@ -1248,6 +1305,8 @@
260 temperature = 130,
261 humidity = 50,
262 fertility = 50,
263+
264+ enhancement = "desert_forested_mountain1"
265 }
266
267
268@@ -1264,6 +1323,8 @@
269 temperature = 130,
270 humidity = 50,
271 fertility = 50,
272+
273+ enhancement = "desert_forested_mountain2"
274 }
275
276
277@@ -1280,6 +1341,8 @@
278 temperature = 130,
279 humidity = 50,
280 fertility = 50,
281+
282+ enhancement = "desert_forested_mountain2"
283 }
284 world:new_terrain_type{
285 name = "desert1",
286
287=== modified file 'src/ai/ai_help_structs.cc'
288--- src/ai/ai_help_structs.cc 2019-08-02 09:54:55 +0000
289+++ src/ai/ai_help_structs.cc 2019-09-05 15:29:33 +0000
290@@ -136,7 +136,7 @@
291 FindNodeEnemy::FindNodeEnemy(Player* p, Game& g) : player(p), game(g) {
292 }
293
294-bool FindNodeEnemy::accept(const Map&, const FCoords& fc) const {
295+bool FindNodeEnemy::accept(const EditorGameBase&, const FCoords& fc) const {
296 return (fc.field->nodecaps() & MOVECAPS_WALK) && fc.field->get_owned_by() != 0 &&
297 player->is_hostile(*game.get_player(fc.field->get_owned_by()));
298 }
299@@ -147,7 +147,7 @@
300 FindNodeEnemiesBuilding::FindNodeEnemiesBuilding(Player* p, Game& g) : player(p), game(g) {
301 }
302
303-bool FindNodeEnemiesBuilding::accept(const Map&, const FCoords& fc) const {
304+bool FindNodeEnemiesBuilding::accept(const EditorGameBase&, const FCoords& fc) const {
305 return (fc.field->get_immovable()) && fc.field->get_owned_by() != 0 &&
306 player->is_hostile(*game.get_player(fc.field->get_owned_by()));
307 }
308@@ -158,7 +158,7 @@
309 FindEnemyNodeWalkable::FindEnemyNodeWalkable(Player* p, Game& g) : player(p), game(g) {
310 }
311
312-bool FindEnemyNodeWalkable::accept(const Map&, const FCoords& fc) const {
313+bool FindEnemyNodeWalkable::accept(const EditorGameBase&, const FCoords& fc) const {
314 return ((fc.field->nodecaps() & MOVECAPS_WALK) && (fc.field->get_owned_by() > 0) &&
315 player->is_hostile(*game.get_player(fc.field->get_owned_by())));
316 }
317@@ -168,7 +168,7 @@
318 : player(p), game(g), player_number(n) {
319 }
320
321-bool FindNodeAllyOwned::accept(const Map&, const FCoords& fc) const {
322+bool FindNodeAllyOwned::accept(const EditorGameBase&, const FCoords& fc) const {
323 return (fc.field->nodecaps() & MOVECAPS_WALK) && (fc.field->get_owned_by() != 0) &&
324 (fc.field->get_owned_by() != player_number) &&
325 !player->is_hostile(*game.get_player(fc.field->get_owned_by()));
326@@ -181,7 +181,7 @@
327 : player(p), game(g), ore_type(t) {
328 }
329
330-bool FindNodeUnownedMineable::accept(const Map&, const FCoords& fc) const {
331+bool FindNodeUnownedMineable::accept(const EditorGameBase&, const FCoords& fc) const {
332 if (ore_type == INVALID_INDEX) {
333 return (fc.field->nodecaps() & BUILDCAPS_MINE) && (fc.field->get_owned_by() == neutral());
334 }
335@@ -192,7 +192,7 @@
336 FindNodeUnownedBuildable::FindNodeUnownedBuildable(Player* p, Game& g) : player(p), game(g) {
337 }
338
339-bool FindNodeUnownedBuildable::accept(const Map&, const FCoords& fc) const {
340+bool FindNodeUnownedBuildable::accept(const EditorGameBase&, const FCoords& fc) const {
341 return ((fc.field->nodecaps() & BUILDCAPS_SIZEMASK) ||
342 (fc.field->nodecaps() & BUILDCAPS_MINE)) &&
343 (fc.field->get_owned_by() == neutral());
344@@ -202,7 +202,7 @@
345 FindNodeUnownedWalkable::FindNodeUnownedWalkable(Player* p, Game& g) : player(p), game(g) {
346 }
347
348-bool FindNodeUnownedWalkable::accept(const Map&, const FCoords& fc) const {
349+bool FindNodeUnownedWalkable::accept(const EditorGameBase&, const FCoords& fc) const {
350 return (fc.field->nodecaps() & MOVECAPS_WALK) && (fc.field->get_owned_by() == neutral());
351 }
352
353@@ -211,7 +211,7 @@
354 FindNodeMineable::FindNodeMineable(Game& g, DescriptionIndex r) : game(g), res(r) {
355 }
356
357-bool FindNodeMineable::accept(const Map&, const FCoords& fc) const {
358+bool FindNodeMineable::accept(const EditorGameBase&, const FCoords& fc) const {
359
360 return (fc.field->nodecaps() & BUILDCAPS_MINE) && (fc.field->get_resources() == res);
361 }
362@@ -220,21 +220,21 @@
363 FindNodeWater::FindNodeWater(const World& world) : world_(world) {
364 }
365
366-bool FindNodeWater::accept(const Map& map, const FCoords& coord) const {
367+bool FindNodeWater::accept(const EditorGameBase& egbase, const FCoords& coord) const {
368 return (world_.terrain_descr(coord.field->terrain_d()).get_is() &
369 TerrainDescription::Is::kWater) ||
370- (world_.terrain_descr(map.get_neighbour(coord, WALK_W).field->terrain_r()).get_is() &
371+ (world_.terrain_descr(egbase.map().get_neighbour(coord, WALK_W).field->terrain_r()).get_is() &
372 TerrainDescription::Is::kWater) ||
373- (world_.terrain_descr(map.get_neighbour(coord, WALK_NW).field->terrain_r()).get_is() &
374+ (world_.terrain_descr(egbase.map().get_neighbour(coord, WALK_NW).field->terrain_r()).get_is() &
375 TerrainDescription::Is::kWater);
376 }
377
378-bool FindNodeOpenWater::accept(const Map& /* map */, const FCoords& coord) const {
379+bool FindNodeOpenWater::accept(const EditorGameBase&, const FCoords& coord) const {
380 return !(coord.field->nodecaps() & MOVECAPS_WALK) && (coord.field->nodecaps() & MOVECAPS_SWIM);
381 }
382
383 // FindNodeWithFlagOrRoad
384-bool FindNodeWithFlagOrRoad::accept(const Map&, FCoords fc) const {
385+bool FindNodeWithFlagOrRoad::accept(const EditorGameBase&, FCoords fc) const {
386 if (upcast(PlayerImmovable const, pimm, fc.field->get_immovable()))
387 return (dynamic_cast<Flag const*>(pimm) ||
388 (dynamic_cast<Road const*>(pimm) && (fc.field->nodecaps() & BUILDCAPS_FLAG)));
389
390=== modified file 'src/ai/ai_help_structs.h'
391--- src/ai/ai_help_structs.h 2019-08-02 09:54:55 +0000
392+++ src/ai/ai_help_structs.h 2019-09-05 15:29:33 +0000
393@@ -168,7 +168,7 @@
394 struct FindNodeEnemy {
395 FindNodeEnemy(Player* p, Game& g);
396
397- bool accept(const Map&, const FCoords& fc) const;
398+ bool accept(const EditorGameBase&, const FCoords& fc) const;
399
400 Player* player;
401 Game& game;
402@@ -181,7 +181,7 @@
403 struct FindNodeEnemiesBuilding {
404 FindNodeEnemiesBuilding(Player* p, Game& g);
405
406- bool accept(const Map&, const FCoords& fc) const;
407+ bool accept(const EditorGameBase&, const FCoords& fc) const;
408
409 Player* player;
410 Game& game;
411@@ -191,7 +191,7 @@
412 struct FindEnemyNodeWalkable {
413 FindEnemyNodeWalkable(Player* p, Game& g);
414
415- bool accept(const Map&, const FCoords& fc) const;
416+ bool accept(const EditorGameBase&, const FCoords& fc) const;
417
418 Player* player;
419 Game& game;
420@@ -201,7 +201,7 @@
421 struct FindNodeAllyOwned {
422 FindNodeAllyOwned(Player* p, Game& g, PlayerNumber n);
423
424- bool accept(const Map&, const FCoords& fc) const;
425+ bool accept(const EditorGameBase&, const FCoords& fc) const;
426
427 Player* player;
428 Game& game;
429@@ -214,7 +214,7 @@
430 struct FindNodeUnownedMineable {
431 FindNodeUnownedMineable(Player* p, Game& g, int32_t t = INVALID_INDEX);
432
433- bool accept(const Map&, const FCoords& fc) const;
434+ bool accept(const EditorGameBase&, const FCoords& fc) const;
435
436 Player* player;
437 Game& game;
438@@ -226,7 +226,7 @@
439 struct FindNodeUnownedBuildable {
440 FindNodeUnownedBuildable(Player* p, Game& g);
441
442- bool accept(const Map&, const FCoords& fc) const;
443+ bool accept(const EditorGameBase&, const FCoords& fc) const;
444
445 Player* player;
446 Game& game;
447@@ -236,7 +236,7 @@
448 struct FindNodeUnownedWalkable {
449 FindNodeUnownedWalkable(Player* p, Game& g);
450
451- bool accept(const Map&, const FCoords& fc) const;
452+ bool accept(const EditorGameBase&, const FCoords& fc) const;
453
454 Player* player;
455 Game& game;
456@@ -247,7 +247,7 @@
457 struct FindNodeMineable {
458 FindNodeMineable(Game& g, DescriptionIndex r);
459
460- bool accept(const Map&, const FCoords& fc) const;
461+ bool accept(const EditorGameBase&, const FCoords& fc) const;
462
463 Game& game;
464 int32_t res;
465@@ -257,7 +257,7 @@
466 struct FindNodeWater {
467 explicit FindNodeWater(const World& world);
468
469- bool accept(const Map& /* map */, const FCoords& coord) const;
470+ bool accept(const EditorGameBase&, const FCoords& coord) const;
471
472 private:
473 const World& world_;
474@@ -270,16 +270,16 @@
475 explicit FindNodeOpenWater(const World& /* world */) {
476 }
477
478- bool accept(const Map& /* map */, const FCoords& coord) const;
479+ bool accept(const EditorGameBase&, const FCoords& coord) const;
480 };
481
482 struct FindNodeWithFlagOrRoad {
483- bool accept(const Map&, FCoords) const;
484+ bool accept(const EditorGameBase&, FCoords) const;
485 };
486
487 // Accepts any field
488 struct FindNodeAcceptAll {
489- bool accept(const Map&, FCoords) const {
490+ bool accept(const EditorGameBase&, FCoords) const {
491 return true;
492 }
493 };
494
495=== modified file 'src/ai/defaultai.cc'
496--- src/ai/defaultai.cc 2019-08-02 09:54:55 +0000
497+++ src/ai/defaultai.cc 2019-09-05 15:29:33 +0000
498@@ -1342,10 +1342,10 @@
499 }
500 }
501
502- field.unowned_land_nearby = map.find_fields(
503+ field.unowned_land_nearby = map.find_fields(game(),
504 Area<FCoords>(field.coords, actual_enemy_check_area), nullptr, find_unowned_walkable);
505
506- field.enemy_owned_land_nearby = map.find_fields(
507+ field.enemy_owned_land_nearby = map.find_fields(game(),
508 Area<FCoords>(field.coords, actual_enemy_check_area), nullptr, find_enemy_owned_walkable);
509
510 field.nearest_buildable_spot_nearby = std::numeric_limits<uint16_t>::max();
511@@ -1359,10 +1359,10 @@
512
513 // first looking for unowned buildable spots
514 field.unowned_buildable_spots_nearby =
515- map.find_fields(Area<FCoords>(field.coords, kBuildableSpotsCheckArea),
516+ map.find_fields(game(), Area<FCoords>(field.coords, kBuildableSpotsCheckArea),
517 &found_buildable_fields, find_unowned_buildable);
518 field.unowned_buildable_spots_nearby +=
519- map.find_fields(Area<FCoords>(field.coords, kBuildableSpotsCheckArea),
520+ map.find_fields(game(), Area<FCoords>(field.coords, kBuildableSpotsCheckArea),
521 &found_buildable_fields, find_enemy_owned_walkable);
522 // Now iterate over fields to collect statistics
523 for (auto& coords : found_buildable_fields) {
524@@ -1389,8 +1389,8 @@
525 }
526
527 // Is this near the border? Get rid of fields owned by ally
528- if (map.find_fields(Area<FCoords>(field.coords, 3), nullptr, find_ally) ||
529- map.find_fields(Area<FCoords>(field.coords, 3), nullptr, find_unowned_walkable)) {
530+ if (map.find_fields(game(), Area<FCoords>(field.coords, 3), nullptr, find_ally) ||
531+ map.find_fields(game(), Area<FCoords>(field.coords, 3), nullptr, find_unowned_walkable)) {
532 field.near_border = true;
533 } else {
534 field.near_border = false;
535@@ -1408,10 +1408,10 @@
536
537 // testing mines
538 if (resource_count_now) {
539- uint32_t close_mines = map.find_fields(
540+ uint32_t close_mines = map.find_fields(game(),
541 Area<FCoords>(field.coords, kProductionArea), nullptr, find_unowned_mines_pots);
542 uint32_t distant_mines =
543- map.find_fields(Area<FCoords>(field.coords, kDistantResourcesArea), nullptr,
544+ map.find_fields(game(), Area<FCoords>(field.coords, kDistantResourcesArea), nullptr,
545
546 find_unowned_mines_pots);
547 distant_mines = distant_mines - close_mines;
548@@ -1425,7 +1425,7 @@
549 (mines_per_type[iron_resource_id].in_construction +
550 mines_per_type[iron_resource_id].finished) <= 1) {
551 // counting iron mines, if we have less than two iron mines
552- field.unowned_iron_mines_nearby = map.find_fields(
553+ field.unowned_iron_mines_nearby = map.find_fields(game(),
554 Area<FCoords>(field.coords, kDistantResourcesArea), nullptr, find_unowned_iron_mines);
555 } else {
556 field.unowned_iron_mines_nearby = 0;
557@@ -1488,16 +1488,16 @@
558
559 FindNodeWater find_water(game().world());
560 field.water_nearby =
561- map.find_fields(Area<FCoords>(field.coords, kProductionArea), nullptr, find_water);
562+ map.find_fields(game(), Area<FCoords>(field.coords, kProductionArea), nullptr, find_water);
563
564 if (field.water_nearby > 0) {
565 FindNodeOpenWater find_open_water(game().world());
566 field.open_water_nearby =
567- map.find_fields(Area<FCoords>(field.coords, kProductionArea), nullptr, find_open_water);
568+ map.find_fields(game(), Area<FCoords>(field.coords, kProductionArea), nullptr, find_open_water);
569 }
570
571 if (resource_necessity_water_needed_) { // for atlanteans
572- field.distant_water = map.find_fields(Area<FCoords>(field.coords, kDistantResourcesArea),
573+ field.distant_water = map.find_fields(game(), Area<FCoords>(field.coords, kDistantResourcesArea),
574 nullptr, find_water) -
575 field.water_nearby;
576 assert(field.open_water_nearby <= field.water_nearby);
577@@ -1520,7 +1520,7 @@
578 CheckStepWalkOn fisher_cstep(MOVECAPS_WALK, true);
579 static std::vector<Coords> fish_fields_list; // pity this contains duplicates
580 fish_fields_list.clear();
581- map.find_reachable_fields(Area<FCoords>(field.coords, kProductionArea), &fish_fields_list,
582+ map.find_reachable_fields(game(), Area<FCoords>(field.coords, kProductionArea), &fish_fields_list,
583 fisher_cstep, FindNodeResource(world.get_resource("fish")));
584
585 // This is "list" of unique fields in fish_fields_list we got above
586@@ -1538,11 +1538,11 @@
587 if (resource_count_now) {
588 // Counting fields with critters (game)
589 field.critters_nearby =
590- map.find_bobs(Area<FCoords>(field.coords, kProductionArea), nullptr, FindBobCritter());
591+ map.find_bobs(game(), Area<FCoords>(field.coords, kProductionArea), nullptr, FindBobCritter());
592
593 // Rocks are not renewable, we will count them only if previous state is nonzero
594 if (field.rocks_nearby > 0) {
595- field.rocks_nearby = map.find_immovables(
596+ field.rocks_nearby = map.find_immovables(game(),
597 Area<FCoords>(map.get_fcoords(field.coords), kProductionArea), nullptr,
598 FindImmovableAttribute(MapObjectDescr::get_attribute_id("rocks")));
599
600@@ -1559,13 +1559,13 @@
601 // Counting trees nearby
602 int32_t const tree_attr = MapObjectDescr::get_attribute_id("tree");
603 field.trees_nearby =
604- map.find_immovables(Area<FCoords>(map.get_fcoords(field.coords), kProductionArea), nullptr,
605+ map.find_immovables(game(), Area<FCoords>(map.get_fcoords(field.coords), kProductionArea), nullptr,
606 FindImmovableAttribute(tree_attr));
607
608 // Counting bushes nearby
609 int32_t const bush_attr = MapObjectDescr::get_attribute_id("ripe_bush");
610 field.bushes_nearby =
611- map.find_immovables(Area<FCoords>(map.get_fcoords(field.coords), kProductionArea), nullptr,
612+ map.find_immovables(game(), Area<FCoords>(map.get_fcoords(field.coords), kProductionArea), nullptr,
613 FindImmovableAttribute(bush_attr));
614 }
615
616@@ -1607,7 +1607,7 @@
617 immovables.reserve(50);
618 immovables.clear();
619 // Search in a radius of range
620- map.find_immovables(Area<FCoords>(field.coords, kProductionArea + 2), &immovables);
621+ map.find_immovables(game(), Area<FCoords>(field.coords, kProductionArea + 2), &immovables);
622
623 // function seems to return duplicates, so we will use serial numbers to filter them out
624 static std::set<uint32_t> unique_serials;
625@@ -1641,7 +1641,7 @@
626
627 // Now testing military aspects
628 immovables.clear();
629- map.find_immovables(Area<FCoords>(field.coords, actual_enemy_check_area), &immovables);
630+ map.find_immovables(game(), Area<FCoords>(field.coords, actual_enemy_check_area), &immovables);
631
632 // We are interested in unconnected immovables, but we must be also close to connected ones
633 static bool any_connected_imm = false;
634@@ -2000,7 +2000,7 @@
635 // collect information about resources in the area
636 std::vector<ImmovableFound> immovables;
637 const Map& map = game().map();
638- map.find_immovables(Area<FCoords>(field.coords, 5), &immovables);
639+ map.find_immovables(game(), Area<FCoords>(field.coords, 5), &immovables);
640 field.preferred = false;
641 field.mines_nearby = 0;
642 FCoords fse;
643@@ -2038,7 +2038,7 @@
644 if (field.same_mine_fields_nearby == 0) {
645 FindNodeMineable find_mines_spots_nearby(game(), field.coords.field->get_resources());
646 field.same_mine_fields_nearby =
647- map.find_fields(Area<FCoords>(field.coords, 4), nullptr, find_mines_spots_nearby);
648+ map.find_fields(game(), Area<FCoords>(field.coords, 4), nullptr, find_mines_spots_nearby);
649 }
650 }
651
652@@ -3917,7 +3917,7 @@
653
654 // get all flags within radius
655 std::vector<Coords> reachable;
656- map.find_reachable_fields(
657+ map.find_reachable_fields(game(),
658 Area<FCoords>(map.get_fcoords(flag.get_position()), checkradius), &reachable, check, functor);
659
660 for (const Coords& reachable_coords : reachable) {
661@@ -4066,7 +4066,7 @@
662
663 // get all flags within radius
664 std::vector<Coords> reachable_to_block;
665- map.find_reachable_fields(Area<FCoords>(map.get_fcoords(flag.get_position()), checkradius),
666+ map.find_reachable_fields(game(), Area<FCoords>(map.get_fcoords(flag.get_position()), checkradius),
667 &reachable_to_block, check_own, buildable_functor);
668
669 for (auto coords : reachable_to_block) {
670@@ -4467,7 +4467,7 @@
671 return false;
672 }
673
674- const uint32_t remaining_trees = map.find_immovables(
675+ const uint32_t remaining_trees = map.find_immovables(game(),
676 Area<FCoords>(map.get_fcoords(site.site->get_position()), radius), nullptr,
677 FindImmovableAttribute(MapObjectDescr::get_attribute_id("tree")));
678
679@@ -4534,7 +4534,7 @@
680 // Quarry handling
681 if (site.bo->is(BuildingAttribute::kNeedsRocks)) {
682
683- if (map.find_immovables(Area<FCoords>(map.get_fcoords(site.site->get_position()), 6), nullptr,
684+ if (map.find_immovables(game(), Area<FCoords>(map.get_fcoords(site.site->get_position()), 6), nullptr,
685
686 FindImmovableAttribute(MapObjectDescr::get_attribute_id("rocks"))) ==
687 0) {
688@@ -4690,7 +4690,7 @@
689 }
690
691 const uint32_t trees_in_vicinity =
692- map.find_immovables(Area<FCoords>(map.get_fcoords(site.site->get_position()), 5), nullptr,
693+ map.find_immovables(game(), Area<FCoords>(map.get_fcoords(site.site->get_position()), 5), nullptr,
694 FindImmovableAttribute(MapObjectDescr::get_attribute_id("tree")));
695
696 // stop ranger if enough trees around regardless of policy
697
698=== modified file 'src/ai/defaultai_seafaring.cc'
699--- src/ai/defaultai_seafaring.cc 2019-05-13 12:10:28 +0000
700+++ src/ai/defaultai_seafaring.cc 2019-09-05 15:29:33 +0000
701@@ -74,7 +74,7 @@
702 immovables.clear();
703 immovables.reserve(50);
704 // Search in a radius of range
705- map.find_immovables(Area<FCoords>(map.get_fcoords(candidate_spot), 10), &immovables);
706+ map.find_immovables(game(), Area<FCoords>(map.get_fcoords(candidate_spot), 10), &immovables);
707
708 int32_t const rocks_attr = MapObjectDescr::get_attribute_id("rocks");
709 uint16_t rocks = 0;
710
711=== modified file 'src/ai/defaultai_warfare.cc'
712--- src/ai/defaultai_warfare.cc 2019-05-07 12:14:02 +0000
713+++ src/ai/defaultai_warfare.cc 2019-09-05 15:29:33 +0000
714@@ -53,7 +53,7 @@
715 static std::vector<ImmovableFound> immovables;
716 immovables.clear();
717 immovables.reserve(40);
718- map.find_immovables(Area<FCoords>(f, (vision + 3 < 13) ? 13 : vision + 3), &immovables,
719+ map.find_immovables(game(), Area<FCoords>(f, (vision + 3 < 13) ? 13 : vision + 3), &immovables,
720 FindImmovableAttackTarget());
721
722 for (uint32_t j = 0; j < immovables.size(); ++j) {
723@@ -203,7 +203,7 @@
724 if (site->second.mines_nearby == ExtendedBool::kUnset) {
725 FindNodeMineable find_mines_spots_nearby(game(), f.field->get_resources());
726 const int32_t minescount =
727- map.find_fields(Area<FCoords>(f, 6), nullptr, find_mines_spots_nearby);
728+ map.find_fields(game(), Area<FCoords>(f, 6), nullptr, find_mines_spots_nearby);
729 if (minescount > 0) {
730 site->second.mines_nearby = ExtendedBool::kTrue;
731 } else {
732
733=== modified file 'src/editor/editorinteractive.cc'
734--- src/editor/editorinteractive.cc 2019-08-28 06:12:07 +0000
735+++ src/editor/editorinteractive.cc 2019-09-05 15:29:33 +0000
736@@ -150,8 +150,8 @@
737
738 history_.reset(new EditorHistory(*undo_, *redo_));
739
740- undo_->sigclicked.connect([this] { history_->undo_action(egbase().world()); });
741- redo_->sigclicked.connect([this] { history_->redo_action(egbase().world()); });
742+ undo_->sigclicked.connect([this] { history_->undo_action(); });
743+ redo_->sigclicked.connect([this] { history_->redo_action(); });
744
745 toolbar()->add_space(15);
746
747@@ -529,7 +529,7 @@
748 void EditorInteractive::map_clicked(const Widelands::NodeAndTriangle<>& node_and_triangle,
749 const bool should_draw) {
750 history_->do_action(tools_->current(), tools_->use_tool, *egbase().mutable_map(),
751- egbase().world(), node_and_triangle, *this, should_draw);
752+ node_and_triangle, *this, should_draw);
753 set_need_save(true);
754 }
755
756@@ -827,14 +827,14 @@
757
758 case SDLK_y:
759 if (code.mod & (KMOD_LCTRL | KMOD_RCTRL))
760- history_->redo_action(egbase().world());
761+ history_->redo_action();
762 return true;
763
764 case SDLK_z:
765 if ((code.mod & (KMOD_LCTRL | KMOD_RCTRL)) && (code.mod & (KMOD_LSHIFT | KMOD_RSHIFT)))
766- history_->redo_action(egbase().world());
767+ history_->redo_action();
768 else if (code.mod & (KMOD_LCTRL | KMOD_RCTRL))
769- history_->undo_action(egbase().world());
770+ history_->undo_action();
771 return true;
772
773 case SDLK_F1:
774@@ -879,7 +879,7 @@
775 toolsize_menu.update(toolsize_menu.value());
776 }
777 }
778- egbase().mutable_map()->recalc_whole_map(egbase().world());
779+ egbase().mutable_map()->recalc_whole_map(egbase());
780 }
781 tools_->current_pointer = &primary;
782 tools_->use_tool = which;
783@@ -906,7 +906,7 @@
784 if (filename.empty()) {
785 loader_ui.step(_("Creating empty map…"));
786 egbase.mutable_map()->create_empty_map(
787- egbase.world(), 64, 64, 0,
788+ egbase, 64, 64, 0,
789 /** TRANSLATORS: Default name for new map */
790 _("No Name"),
791 get_config_string("realname",
792
793=== modified file 'src/editor/map_generator.cc'
794--- src/editor/map_generator.cc 2019-02-27 19:00:36 +0000
795+++ src/editor/map_generator.cc 2019-09-05 15:29:33 +0000
796@@ -657,7 +657,7 @@
797 }
798
799 // Aftermaths...
800- map_.recalc_whole_map(egbase_.world());
801+ map_.recalc_whole_map(egbase_);
802
803 // Care about players and place their start positions
804 map_.set_nrplayers(map_info_.numPlayers);
805@@ -752,7 +752,7 @@
806 // Now try to find a place as near as possible to the wished
807 // starting position
808 std::vector<Coords> coords;
809- map_.find_fields(Area<FCoords>(map_.get_fcoords(playerstart), 20), &coords, functor);
810+ map_.find_fields(egbase_, Area<FCoords>(map_.get_fcoords(playerstart), 20), &coords, functor);
811
812 // Take the nearest ones
813 uint32_t min_distance = std::numeric_limits<uint32_t>::max();
814
815=== modified file 'src/editor/tools/decrease_height_tool.cc'
816--- src/editor/tools/decrease_height_tool.cc 2019-02-23 11:00:49 +0000
817+++ src/editor/tools/decrease_height_tool.cc 2019-09-05 15:29:33 +0000
818@@ -26,9 +26,8 @@
819 #include "logic/mapregion.h"
820
821 /// Decreases the heights by a value. Chages surrounding nodes if necessary.
822-int32_t EditorDecreaseHeightTool::handle_click_impl(const Widelands::World& world,
823- const Widelands::NodeAndTriangle<>& center,
824- EditorInteractive& /* parent */,
825+int32_t EditorDecreaseHeightTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
826+ EditorInteractive& eia,
827 EditorActionArgs* args,
828 Widelands::Map* map) {
829 if (args->original_heights.empty()) {
830@@ -42,13 +41,12 @@
831 }
832
833 return map->change_height(
834- world, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius),
835+ eia.egbase(), Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius),
836 -args->change_by);
837 }
838
839-int32_t EditorDecreaseHeightTool::handle_undo_impl(const Widelands::World& world,
840- const Widelands::NodeAndTriangle<>& center,
841- EditorInteractive& /* parent */,
842+int32_t EditorDecreaseHeightTool::handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
843+ EditorInteractive& eia,
844 EditorActionArgs* args,
845 Widelands::Map* map) {
846 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
847@@ -62,8 +60,7 @@
848 ++i;
849 } while (mr.advance(*map));
850
851- map->recalc_for_field_area(
852- world, Widelands::Area<Widelands::FCoords>(
853+ map->recalc_for_field_area(eia.egbase(), Widelands::Area<Widelands::FCoords>(
854 map->get_fcoords(center.node),
855 args->sel_radius + MAX_FIELD_HEIGHT / MAX_FIELD_HEIGHT_DIFF + 2));
856
857
858=== modified file 'src/editor/tools/decrease_height_tool.h'
859--- src/editor/tools/decrease_height_tool.h 2019-02-23 11:00:49 +0000
860+++ src/editor/tools/decrease_height_tool.h 2019-09-05 15:29:33 +0000
861@@ -27,14 +27,12 @@
862 EditorDecreaseHeightTool() : EditorTool(*this, *this), change_by_(1) {
863 }
864
865- int32_t handle_click_impl(const Widelands::World& world,
866- const Widelands::NodeAndTriangle<>& center,
867+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
868 EditorInteractive& parent,
869 EditorActionArgs* args,
870 Widelands::Map* map) override;
871
872- int32_t handle_undo_impl(const Widelands::World& world,
873- const Widelands::NodeAndTriangle<>& center,
874+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
875 EditorInteractive& parent,
876 EditorActionArgs* args,
877 Widelands::Map* map) override;
878
879=== modified file 'src/editor/tools/decrease_resources_tool.cc'
880--- src/editor/tools/decrease_resources_tool.cc 2019-02-23 11:00:49 +0000
881+++ src/editor/tools/decrease_resources_tool.cc 2019-09-05 15:29:33 +0000
882@@ -31,11 +31,11 @@
883 * Decrease the resources of the current field by the given value if
884 * there is not already another resource there.
885 */
886-int32_t EditorDecreaseResourcesTool::handle_click_impl(const Widelands::World& world,
887- const Widelands::NodeAndTriangle<>& center,
888- EditorInteractive& /* parent */,
889+int32_t EditorDecreaseResourcesTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
890+ EditorInteractive& eia,
891 EditorActionArgs* args,
892 Widelands::Map* map) {
893+ const Widelands::World& world = eia.egbase().world();
894 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
895 *map, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius));
896 do {
897@@ -58,12 +58,11 @@
898 return mr.radius();
899 }
900
901-int32_t EditorDecreaseResourcesTool::handle_undo_impl(const Widelands::World& world,
902- const Widelands::NodeAndTriangle<>& center,
903+int32_t EditorDecreaseResourcesTool::handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
904 EditorInteractive& parent,
905 EditorActionArgs* args,
906 Widelands::Map* map) {
907- return parent.tools()->set_resources.handle_undo_impl(world, center, parent, args, map);
908+ return parent.tools()->set_resources.handle_undo_impl(center, parent, args, map);
909 }
910
911 EditorActionArgs EditorDecreaseResourcesTool::format_args_impl(EditorInteractive& parent) {
912
913=== modified file 'src/editor/tools/decrease_resources_tool.h'
914--- src/editor/tools/decrease_resources_tool.h 2019-02-23 11:00:49 +0000
915+++ src/editor/tools/decrease_resources_tool.h 2019-09-05 15:29:33 +0000
916@@ -28,14 +28,12 @@
917 EditorDecreaseResourcesTool() : EditorTool(*this, *this), cur_res_(0), change_by_(1) {
918 }
919
920- int32_t handle_click_impl(const Widelands::World& world,
921- const Widelands::NodeAndTriangle<>& center,
922+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
923 EditorInteractive& parent,
924 EditorActionArgs* args,
925 Widelands::Map* map) override;
926
927- int32_t handle_undo_impl(const Widelands::World& world,
928- const Widelands::NodeAndTriangle<>& center,
929+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
930 EditorInteractive& parent,
931 EditorActionArgs* args,
932 Widelands::Map* map) override;
933
934=== modified file 'src/editor/tools/delete_critter_tool.cc'
935--- src/editor/tools/delete_critter_tool.cc 2019-02-23 11:00:49 +0000
936+++ src/editor/tools/delete_critter_tool.cc 2019-09-05 15:29:33 +0000
937@@ -28,12 +28,10 @@
938 * Deletes the bob at the given location
939 */
940 int32_t EditorDeleteCritterTool::handle_click_impl(
941- const Widelands::World&,
942 const Widelands::NodeAndTriangle<Widelands::Coords>& center,
943- EditorInteractive& parent,
944+ EditorInteractive& eia,
945 EditorActionArgs* args,
946 Widelands::Map* map) {
947- Widelands::EditorGameBase& egbase = parent.egbase();
948 const int32_t radius = args->sel_radius;
949 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
950 *map, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), radius));
951@@ -41,7 +39,7 @@
952 do
953 if (Widelands::Bob* const bob = mr.location().field->get_first_bob()) {
954 args->old_bob_type.push_back(&bob->descr());
955- bob->remove(egbase);
956+ bob->remove(eia.egbase());
957 } else {
958 args->old_bob_type.push_back(nullptr);
959 }
960@@ -50,13 +48,12 @@
961 }
962
963 int32_t EditorDeleteCritterTool::handle_undo_impl(
964- const Widelands::World& world,
965 const Widelands::NodeAndTriangle<Widelands::Coords>& center,
966 EditorInteractive& parent,
967 EditorActionArgs* args,
968 Widelands::Map* map) {
969
970- uint32_t ret = parent.tools()->place_critter.handle_undo_impl(world, center, parent, args, map);
971+ uint32_t ret = parent.tools()->place_critter.handle_undo_impl(center, parent, args, map);
972 args->old_bob_type.clear();
973 return ret;
974 }
975
976=== modified file 'src/editor/tools/delete_critter_tool.h'
977--- src/editor/tools/delete_critter_tool.h 2019-02-23 11:00:49 +0000
978+++ src/editor/tools/delete_critter_tool.h 2019-09-05 15:29:33 +0000
979@@ -27,14 +27,12 @@
980 EditorDeleteCritterTool() : EditorTool(*this, *this) {
981 }
982
983- int32_t handle_click_impl(const Widelands::World& world,
984- const Widelands::NodeAndTriangle<>& center,
985+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
986 EditorInteractive& parent,
987 EditorActionArgs* args,
988 Widelands::Map* map) override;
989
990- int32_t handle_undo_impl(const Widelands::World& world,
991- const Widelands::NodeAndTriangle<>& center,
992+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
993 EditorInteractive& parent,
994 EditorActionArgs* args,
995 Widelands::Map* map) override;
996
997=== modified file 'src/editor/tools/delete_immovable_tool.cc'
998--- src/editor/tools/delete_immovable_tool.cc 2019-02-23 11:00:49 +0000
999+++ src/editor/tools/delete_immovable_tool.cc 2019-09-05 15:29:33 +0000
1000@@ -28,18 +28,16 @@
1001 /**
1002 * Deletes the immovable at the given location
1003 */
1004-int32_t EditorDeleteImmovableTool::handle_click_impl(const Widelands::World&,
1005- const Widelands::NodeAndTriangle<>& center,
1006- EditorInteractive& parent,
1007+int32_t EditorDeleteImmovableTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1008+ EditorInteractive& eia,
1009 EditorActionArgs* args,
1010 Widelands::Map* map) {
1011- Widelands::EditorGameBase& egbase = parent.egbase();
1012 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1013 *map, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius));
1014 do
1015 if (upcast(Widelands::Immovable, immovable, mr.location().field->get_immovable())) {
1016 args->old_immovable_types.push_back(immovable->descr().name());
1017- immovable->remove(egbase); // Delete no buildings or stuff.
1018+ immovable->remove(eia.egbase()); // Delete no buildings or stuff.
1019 } else {
1020 args->old_immovable_types.push_back("");
1021 }
1022@@ -48,12 +46,11 @@
1023 }
1024
1025 int32_t EditorDeleteImmovableTool::handle_undo_impl(
1026- const Widelands::World& world,
1027 const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1028 EditorInteractive& parent,
1029 EditorActionArgs* args,
1030 Widelands::Map* map) {
1031- return parent.tools()->place_immovable.handle_undo_impl(world, center, parent, args, map);
1032+ return parent.tools()->place_immovable.handle_undo_impl(center, parent, args, map);
1033 }
1034
1035 EditorActionArgs EditorDeleteImmovableTool::format_args_impl(EditorInteractive& parent) {
1036
1037=== modified file 'src/editor/tools/delete_immovable_tool.h'
1038--- src/editor/tools/delete_immovable_tool.h 2019-02-23 11:00:49 +0000
1039+++ src/editor/tools/delete_immovable_tool.h 2019-09-05 15:29:33 +0000
1040@@ -27,14 +27,12 @@
1041 EditorDeleteImmovableTool() : EditorTool(*this, *this) {
1042 }
1043
1044- int32_t handle_click_impl(const Widelands::World& world,
1045- const Widelands::NodeAndTriangle<>& center,
1046+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1047 EditorInteractive& parent,
1048 EditorActionArgs* args,
1049 Widelands::Map* map) override;
1050
1051- int32_t handle_undo_impl(const Widelands::World& world,
1052- const Widelands::NodeAndTriangle<>& center,
1053+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1054 EditorInteractive& parent,
1055 EditorActionArgs* args,
1056 Widelands::Map* map) override;
1057
1058=== modified file 'src/editor/tools/draw_tool.cc'
1059--- src/editor/tools/draw_tool.cc 2019-02-23 11:00:49 +0000
1060+++ src/editor/tools/draw_tool.cc 2019-09-05 15:29:33 +0000
1061@@ -30,29 +30,27 @@
1062 }
1063
1064 int32_t
1065-EditorDrawTool::handle_click_impl(const Widelands::World& world,
1066- const Widelands::NodeAndTriangle<Widelands::Coords>& /* center */,
1067+EditorDrawTool::handle_click_impl(const Widelands::NodeAndTriangle<Widelands::Coords>& /* center */,
1068 EditorInteractive& /* parent */,
1069 EditorActionArgs* args,
1070 Widelands::Map* /* map */) {
1071
1072 for (std::list<EditorToolAction*>::iterator i = args->draw_actions.begin();
1073 i != args->draw_actions.end(); ++i) {
1074- (*i)->tool.handle_click(static_cast<EditorTool::ToolIndex>((*i)->i), world, (*i)->center,
1075+ (*i)->tool.handle_click(static_cast<EditorTool::ToolIndex>((*i)->i), (*i)->center,
1076 (*i)->parent, (*i)->args, &((*i)->map));
1077 }
1078 return args->draw_actions.size();
1079 }
1080
1081 int32_t
1082-EditorDrawTool::handle_undo_impl(const Widelands::World& world,
1083- const Widelands::NodeAndTriangle<Widelands::Coords>& /* center */,
1084+EditorDrawTool::handle_undo_impl(const Widelands::NodeAndTriangle<Widelands::Coords>& /* center */,
1085 EditorInteractive& /* parent */,
1086 EditorActionArgs* args,
1087 Widelands::Map* /* map */) {
1088 for (std::list<EditorToolAction*>::reverse_iterator i = args->draw_actions.rbegin();
1089 i != args->draw_actions.rend(); ++i) {
1090- (*i)->tool.handle_undo(static_cast<EditorTool::ToolIndex>((*i)->i), world, (*i)->center,
1091+ (*i)->tool.handle_undo(static_cast<EditorTool::ToolIndex>((*i)->i), (*i)->center,
1092 (*i)->parent, (*i)->args, &((*i)->map));
1093 }
1094 return args->draw_actions.size();
1095
1096=== modified file 'src/editor/tools/draw_tool.h'
1097--- src/editor/tools/draw_tool.h 2019-02-23 11:00:49 +0000
1098+++ src/editor/tools/draw_tool.h 2019-09-05 15:29:33 +0000
1099@@ -29,14 +29,12 @@
1100 EditorDrawTool() : EditorTool(*this, *this) {
1101 }
1102
1103- int32_t handle_click_impl(const Widelands::World& world,
1104- const Widelands::NodeAndTriangle<>& center,
1105+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1106 EditorInteractive& parent,
1107 EditorActionArgs* args,
1108 Widelands::Map* map) override;
1109
1110- int32_t handle_undo_impl(const Widelands::World& world,
1111- const Widelands::NodeAndTriangle<>& center,
1112+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1113 EditorInteractive& parent,
1114 EditorActionArgs* args,
1115 Widelands::Map* map) override;
1116
1117=== modified file 'src/editor/tools/history.cc'
1118--- src/editor/tools/history.cc 2019-04-03 13:22:14 +0000
1119+++ src/editor/tools/history.cc 2019-09-05 15:29:33 +0000
1120@@ -57,7 +57,7 @@
1121
1122 // === EditorHistory === //
1123
1124-uint32_t EditorHistory::undo_action(const Widelands::World& world) {
1125+uint32_t EditorHistory::undo_action() {
1126 if (undo_stack_.empty())
1127 return 0;
1128
1129@@ -68,11 +68,11 @@
1130 undo_button_.set_enabled(!undo_stack_.empty());
1131 redo_button_.set_enabled(true);
1132
1133- return uac.tool.handle_undo(static_cast<EditorTool::ToolIndex>(uac.i), world, uac.center,
1134+ return uac.tool.handle_undo(static_cast<EditorTool::ToolIndex>(uac.i), uac.center,
1135 uac.parent, uac.args, &(uac.map));
1136 }
1137
1138-uint32_t EditorHistory::redo_action(const Widelands::World& world) {
1139+uint32_t EditorHistory::redo_action() {
1140 if (redo_stack_.empty())
1141 return 0;
1142
1143@@ -83,14 +83,13 @@
1144 undo_button_.set_enabled(true);
1145 redo_button_.set_enabled(!redo_stack_.empty());
1146
1147- return rac.tool.handle_click(static_cast<EditorTool::ToolIndex>(rac.i), world, rac.center,
1148+ return rac.tool.handle_click(static_cast<EditorTool::ToolIndex>(rac.i), rac.center,
1149 rac.parent, rac.args, &(rac.map));
1150 }
1151
1152 uint32_t EditorHistory::do_action(EditorTool& tool,
1153 EditorTool::ToolIndex ind,
1154 Widelands::Map& map,
1155- const Widelands::World& world,
1156 const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1157 EditorInteractive& parent,
1158 bool draw) {
1159@@ -125,5 +124,5 @@
1160 }
1161 }
1162 }
1163- return tool.handle_click(ind, world, center, parent, ac.args, &map);
1164+ return tool.handle_click(ind, center, parent, ac.args, &map);
1165 }
1166
1167=== modified file 'src/editor/tools/history.h'
1168--- src/editor/tools/history.h 2019-02-23 11:00:49 +0000
1169+++ src/editor/tools/history.h 2019-09-05 15:29:33 +0000
1170@@ -42,12 +42,11 @@
1171 uint32_t do_action(EditorTool& tool,
1172 EditorTool::ToolIndex ind,
1173 Widelands::Map& map,
1174- const Widelands::World& world,
1175 const Widelands::NodeAndTriangle<>& center,
1176 EditorInteractive& parent,
1177 bool draw = false);
1178- uint32_t undo_action(const Widelands::World& world);
1179- uint32_t redo_action(const Widelands::World& world);
1180+ uint32_t undo_action();
1181+ uint32_t redo_action();
1182
1183 private:
1184 UI::Button& undo_button_;
1185
1186=== modified file 'src/editor/tools/increase_height_tool.cc'
1187--- src/editor/tools/increase_height_tool.cc 2019-02-23 11:00:49 +0000
1188+++ src/editor/tools/increase_height_tool.cc 2019-09-05 15:29:33 +0000
1189@@ -24,9 +24,8 @@
1190 #include "logic/mapregion.h"
1191
1192 /// Increases the heights by a value. Changes surrounding nodes if necessary.
1193-int32_t EditorIncreaseHeightTool::handle_click_impl(const Widelands::World& world,
1194- const Widelands::NodeAndTriangle<>& center,
1195- EditorInteractive& /* parent */,
1196+int32_t EditorIncreaseHeightTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1197+ EditorInteractive& eia,
1198 EditorActionArgs* args,
1199 Widelands::Map* map) {
1200 if (args->original_heights.empty()) {
1201@@ -40,16 +39,15 @@
1202 }
1203
1204 return map->change_height(
1205- world, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius),
1206+ eia.egbase(), Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius),
1207 args->change_by);
1208 }
1209
1210-int32_t EditorIncreaseHeightTool::handle_undo_impl(const Widelands::World& world,
1211- const Widelands::NodeAndTriangle<>& center,
1212+int32_t EditorIncreaseHeightTool::handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1213 EditorInteractive& parent,
1214 EditorActionArgs* args,
1215 Widelands::Map* map) {
1216- return decrease_tool_.handle_undo_impl(world, center, parent, args, map);
1217+ return decrease_tool_.handle_undo_impl(center, parent, args, map);
1218 }
1219
1220 EditorActionArgs EditorIncreaseHeightTool::format_args_impl(EditorInteractive& parent) {
1221
1222=== modified file 'src/editor/tools/increase_height_tool.h'
1223--- src/editor/tools/increase_height_tool.h 2019-02-23 11:00:49 +0000
1224+++ src/editor/tools/increase_height_tool.h 2019-09-05 15:29:33 +0000
1225@@ -33,14 +33,12 @@
1226 change_by_(1) {
1227 }
1228
1229- int32_t handle_click_impl(const Widelands::World& world,
1230- const Widelands::NodeAndTriangle<>& center,
1231+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1232 EditorInteractive& parent,
1233 EditorActionArgs* args,
1234 Widelands::Map* map) override;
1235
1236- int32_t handle_undo_impl(const Widelands::World& world,
1237- const Widelands::NodeAndTriangle<>& center,
1238+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1239 EditorInteractive& parent,
1240 EditorActionArgs* args,
1241 Widelands::Map* map) override;
1242
1243=== modified file 'src/editor/tools/increase_resources_tool.cc'
1244--- src/editor/tools/increase_resources_tool.cc 2019-02-23 11:00:49 +0000
1245+++ src/editor/tools/increase_resources_tool.cc 2019-09-05 15:29:33 +0000
1246@@ -23,15 +23,16 @@
1247 #include "logic/field.h"
1248 #include "logic/map_objects/world/resource_description.h"
1249 #include "logic/map_objects/world/terrain_description.h"
1250+#include "logic/map_objects/world/world.h"
1251 #include "logic/mapregion.h"
1252
1253 using Widelands::TCoords;
1254
1255-int32_t EditorIncreaseResourcesTool::handle_click_impl(const Widelands::World& world,
1256- const Widelands::NodeAndTriangle<>& center,
1257- EditorInteractive& /* parent */,
1258+int32_t EditorIncreaseResourcesTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1259+ EditorInteractive& eia,
1260 EditorActionArgs* args,
1261 Widelands::Map* map) {
1262+ const Widelands::World& world = eia.egbase().world();
1263 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1264 *map, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius));
1265 do {
1266@@ -61,12 +62,11 @@
1267 }
1268
1269 int32_t EditorIncreaseResourcesTool::handle_undo_impl(
1270- const Widelands::World& world,
1271 const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1272 EditorInteractive& parent,
1273 EditorActionArgs* args,
1274 Widelands::Map* map) {
1275- return set_tool_.handle_undo_impl(world, center, parent, args, map);
1276+ return set_tool_.handle_undo_impl(center, parent, args, map);
1277 }
1278
1279 EditorActionArgs EditorIncreaseResourcesTool::format_args_impl(EditorInteractive& parent) {
1280
1281=== modified file 'src/editor/tools/increase_resources_tool.h'
1282--- src/editor/tools/increase_resources_tool.h 2019-02-23 11:00:49 +0000
1283+++ src/editor/tools/increase_resources_tool.h 2019-09-05 15:29:33 +0000
1284@@ -39,14 +39,12 @@
1285 * Increase the resources of the current field by one if there is not already
1286 * another resource there.
1287 */
1288- int32_t handle_click_impl(const Widelands::World& world,
1289- const Widelands::NodeAndTriangle<>& center,
1290+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1291 EditorInteractive& parent,
1292 EditorActionArgs* args,
1293 Widelands::Map* map) override;
1294
1295- int32_t handle_undo_impl(const Widelands::World& world,
1296- const Widelands::NodeAndTriangle<>& center,
1297+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1298 EditorInteractive& parent,
1299 EditorActionArgs* args,
1300 Widelands::Map* map) override;
1301
1302=== modified file 'src/editor/tools/info_tool.cc'
1303--- src/editor/tools/info_tool.cc 2019-05-26 17:21:15 +0000
1304+++ src/editor/tools/info_tool.cc 2019-09-05 15:29:33 +0000
1305@@ -29,12 +29,12 @@
1306 #include "graphic/text_layout.h"
1307 #include "logic/map_objects/world/editor_category.h"
1308 #include "logic/map_objects/world/terrain_description.h"
1309+#include "logic/map_objects/world/world.h"
1310 #include "ui_basic/multilinetextarea.h"
1311 #include "ui_basic/window.h"
1312
1313 /// Show a window with information about the pointed at node and triangle.
1314-int32_t EditorInfoTool::handle_click_impl(const Widelands::World& world,
1315- const Widelands::NodeAndTriangle<>& center,
1316+int32_t EditorInfoTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1317 EditorInteractive& parent,
1318 EditorActionArgs* /* args */,
1319 Widelands::Map* map) {
1320@@ -116,7 +116,7 @@
1321 buf += as_heading(_("Terrain"), UI::PanelStyle::kWui);
1322
1323 const Widelands::Field& tf = (*map)[center.triangle.node];
1324- const Widelands::TerrainDescription& ter = world.terrain_descr(
1325+ const Widelands::TerrainDescription& ter = parent.egbase().world().terrain_descr(
1326 center.triangle.t == Widelands::TriangleIndex::D ? tf.terrain_d() : tf.terrain_r());
1327
1328 buf += as_listitem(
1329@@ -202,7 +202,7 @@
1330 buf += as_heading(_("Resources"), UI::PanelStyle::kWui);
1331 buf += as_listitem(
1332 (boost::format(pgettext("resources", "%1%x %2%")) % static_cast<unsigned int>(ramount) %
1333- world.get_resource(f.get_resources())->descname())
1334+ parent.egbase().world().get_resource(f.get_resources())->descname())
1335 .str(),
1336 font_style);
1337 }
1338
1339=== modified file 'src/editor/tools/info_tool.h'
1340--- src/editor/tools/info_tool.h 2019-02-23 11:00:49 +0000
1341+++ src/editor/tools/info_tool.h 2019-09-05 15:29:33 +0000
1342@@ -27,8 +27,7 @@
1343 EditorInfoTool() : EditorTool(*this, *this, false) {
1344 }
1345
1346- int32_t handle_click_impl(const Widelands::World& world,
1347- const Widelands::NodeAndTriangle<>& center,
1348+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1349 EditorInteractive& parent,
1350 EditorActionArgs* args,
1351 Widelands::Map* map) override;
1352
1353=== modified file 'src/editor/tools/noise_height_tool.cc'
1354--- src/editor/tools/noise_height_tool.cc 2019-02-23 11:00:49 +0000
1355+++ src/editor/tools/noise_height_tool.cc 2019-09-05 15:29:33 +0000
1356@@ -27,9 +27,8 @@
1357 #include "logic/mapregion.h"
1358
1359 /// Sets the heights to random values. Changes surrounding nodes if necessary.
1360-int32_t EditorNoiseHeightTool::handle_click_impl(const Widelands::World& world,
1361- const Widelands::NodeAndTriangle<>& center,
1362- EditorInteractive& /* parent */,
1363+int32_t EditorNoiseHeightTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1364+ EditorInteractive& eia,
1365 EditorActionArgs* args,
1366 Widelands::Map* map) {
1367 if (args->original_heights.empty()) {
1368@@ -48,7 +47,7 @@
1369 *map, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius));
1370 do {
1371 max = std::max(
1372- max, map->set_height(world, mr.location(),
1373+ max, map->set_height(eia.egbase(), mr.location(),
1374 args->interval.min +
1375 static_cast<int32_t>(static_cast<double>(args->interval.max -
1376 args->interval.min + 1) *
1377@@ -58,12 +57,11 @@
1378 }
1379
1380 int32_t
1381-EditorNoiseHeightTool::handle_undo_impl(const Widelands::World& world,
1382- const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1383+EditorNoiseHeightTool::handle_undo_impl(const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1384 EditorInteractive& parent,
1385 EditorActionArgs* args,
1386 Widelands::Map* map) {
1387- return set_tool_.handle_undo_impl(world, center, parent, args, map);
1388+ return set_tool_.handle_undo_impl(center, parent, args, map);
1389 }
1390
1391 EditorActionArgs EditorNoiseHeightTool::format_args_impl(EditorInteractive& parent) {
1392
1393=== modified file 'src/editor/tools/noise_height_tool.h'
1394--- src/editor/tools/noise_height_tool.h 2019-02-23 11:00:49 +0000
1395+++ src/editor/tools/noise_height_tool.h 2019-09-05 15:29:33 +0000
1396@@ -30,14 +30,12 @@
1397 : EditorTool(the_set_tool, the_set_tool), set_tool_(the_set_tool), interval_(the_interval) {
1398 }
1399
1400- int32_t handle_click_impl(const Widelands::World& world,
1401- const Widelands::NodeAndTriangle<>& center,
1402+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1403 EditorInteractive& parent,
1404 EditorActionArgs* args,
1405 Widelands::Map* map) override;
1406
1407- int32_t handle_undo_impl(const Widelands::World& world,
1408- const Widelands::NodeAndTriangle<>& center,
1409+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1410 EditorInteractive& parent,
1411 EditorActionArgs* args,
1412 Widelands::Map* map) override;
1413
1414=== modified file 'src/editor/tools/place_critter_tool.cc'
1415--- src/editor/tools/place_critter_tool.cc 2019-02-23 11:00:49 +0000
1416+++ src/editor/tools/place_critter_tool.cc 2019-09-05 15:29:33 +0000
1417@@ -24,18 +24,18 @@
1418 #include "logic/field.h"
1419 #include "logic/map_objects/bob.h"
1420 #include "logic/map_objects/world/critter.h"
1421+#include "logic/map_objects/world/world.h"
1422 #include "logic/mapregion.h"
1423
1424 /**
1425 * Choses an object to place randomly from all enabled
1426 * and places this on the current field
1427 */
1428-int32_t EditorPlaceCritterTool::handle_click_impl(const Widelands::World& world,
1429- const Widelands::NodeAndTriangle<>& center,
1430- EditorInteractive& parent,
1431+int32_t EditorPlaceCritterTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1432+ EditorInteractive& eia,
1433 EditorActionArgs* args,
1434 Widelands::Map* map) {
1435-
1436+ Widelands::EditorGameBase& egbase = eia.egbase();
1437 if (get_nr_enabled() && args->old_bob_type.empty()) {
1438 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1439 *map,
1440@@ -44,12 +44,11 @@
1441 Widelands::Bob* const mbob = mr.location().field->get_first_bob();
1442 args->old_bob_type.push_back((mbob ? &mbob->descr() : nullptr));
1443 args->new_bob_type.push_back(dynamic_cast<const Widelands::BobDescr*>(
1444- world.get_critter_descr(get_random_enabled())));
1445+ egbase.world().get_critter_descr(get_random_enabled())));
1446 } while (mr.advance(*map));
1447 }
1448
1449 if (!args->new_bob_type.empty()) {
1450- Widelands::EditorGameBase& egbase = parent.egbase();
1451 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1452 *map,
1453 Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius));
1454@@ -69,13 +68,12 @@
1455 }
1456
1457 int32_t EditorPlaceCritterTool::handle_undo_impl(
1458- const Widelands::World&,
1459 const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1460- EditorInteractive& parent,
1461+ EditorInteractive& eia,
1462 EditorActionArgs* args,
1463 Widelands::Map* map) {
1464+ Widelands::EditorGameBase& egbase = eia.egbase();
1465 if (!args->new_bob_type.empty()) {
1466- Widelands::EditorGameBase& egbase = parent.egbase();
1467 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1468 *map,
1469 Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius));
1470
1471=== modified file 'src/editor/tools/place_critter_tool.h'
1472--- src/editor/tools/place_critter_tool.h 2019-02-23 11:00:49 +0000
1473+++ src/editor/tools/place_critter_tool.h 2019-09-05 15:29:33 +0000
1474@@ -28,14 +28,12 @@
1475 explicit EditorPlaceCritterTool(EditorDeleteCritterTool& tool) : EditorTool(tool, tool) {
1476 }
1477
1478- int32_t handle_click_impl(const Widelands::World& world,
1479- const Widelands::NodeAndTriangle<>& center,
1480+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1481 EditorInteractive& parent,
1482 EditorActionArgs* args,
1483 Widelands::Map* map) override;
1484
1485- int32_t handle_undo_impl(const Widelands::World& world,
1486- const Widelands::NodeAndTriangle<>& center,
1487+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1488 EditorInteractive& parent,
1489 EditorActionArgs* args,
1490 Widelands::Map* map) override;
1491
1492=== modified file 'src/editor/tools/place_immovable_tool.cc'
1493--- src/editor/tools/place_immovable_tool.cc 2019-02-23 11:00:49 +0000
1494+++ src/editor/tools/place_immovable_tool.cc 2019-09-05 15:29:33 +0000
1495@@ -32,15 +32,14 @@
1496 * Choses an object to place randomly from all enabled
1497 * and places this on the current field
1498 */
1499-int32_t EditorPlaceImmovableTool::handle_click_impl(const Widelands::World&,
1500- const Widelands::NodeAndTriangle<>& center,
1501- EditorInteractive& parent,
1502+int32_t EditorPlaceImmovableTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1503+ EditorInteractive& eia,
1504 EditorActionArgs* args,
1505 Widelands::Map* map) {
1506 const int32_t radius = args->sel_radius;
1507 if (!get_nr_enabled())
1508 return radius;
1509- Widelands::EditorGameBase& egbase = parent.egbase();
1510+ Widelands::EditorGameBase& egbase = eia.egbase();
1511 if (args->old_immovable_types.empty()) {
1512 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1513 *map, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), radius));
1514@@ -67,16 +66,15 @@
1515 }
1516
1517 int32_t EditorPlaceImmovableTool::handle_undo_impl(
1518- const Widelands::World&,
1519 const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1520- EditorInteractive& parent,
1521+ EditorInteractive& eia,
1522 EditorActionArgs* args,
1523 Widelands::Map* map) {
1524 const int32_t radius = args->sel_radius;
1525 if (args->old_immovable_types.empty())
1526 return radius;
1527
1528- Widelands::EditorGameBase& egbase = parent.egbase();
1529+ Widelands::EditorGameBase& egbase = eia.egbase();
1530 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1531 *map, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), radius));
1532 std::list<std::string>::iterator i = args->old_immovable_types.begin();
1533
1534=== modified file 'src/editor/tools/place_immovable_tool.h'
1535--- src/editor/tools/place_immovable_tool.h 2019-02-23 11:00:49 +0000
1536+++ src/editor/tools/place_immovable_tool.h 2019-09-05 15:29:33 +0000
1537@@ -30,14 +30,12 @@
1538 explicit EditorPlaceImmovableTool(EditorDeleteImmovableTool& tool) : EditorTool(tool, tool) {
1539 }
1540
1541- int32_t handle_click_impl(const Widelands::World& world,
1542- const Widelands::NodeAndTriangle<>& center,
1543+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1544 EditorInteractive& parent,
1545 EditorActionArgs* args,
1546 Widelands::Map* map) override;
1547
1548- int32_t handle_undo_impl(const Widelands::World& world,
1549- const Widelands::NodeAndTriangle<>& center,
1550+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1551 EditorInteractive& parent,
1552 EditorActionArgs* args,
1553 Widelands::Map* map) override;
1554
1555=== modified file 'src/editor/tools/resize_tool.cc'
1556--- src/editor/tools/resize_tool.cc 2019-04-24 07:09:29 +0000
1557+++ src/editor/tools/resize_tool.cc 2019-09-05 15:29:33 +0000
1558@@ -23,13 +23,10 @@
1559 #include "logic/field.h"
1560 #include "logic/widelands_geometry.h"
1561
1562-int32_t EditorResizeTool::handle_click_impl(const Widelands::World& world,
1563- const Widelands::NodeAndTriangle<>& center,
1564- EditorInteractive& parent,
1565+int32_t EditorResizeTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1566+ EditorInteractive& eia,
1567 EditorActionArgs* args,
1568 Widelands::Map* map) {
1569- Widelands::EditorGameBase& egbase = parent.egbase();
1570-
1571 args->resized.old_map_size = map->extent();
1572 args->resized.port_spaces.clear();
1573 args->resized.starting_positions.clear();
1574@@ -41,20 +38,18 @@
1575 }
1576
1577 args->resized.deleted_fields =
1578- map->resize(egbase, center.node, args->new_map_size.w, args->new_map_size.h);
1579+ map->resize(eia.egbase(), center.node, args->new_map_size.w, args->new_map_size.h);
1580
1581- map->recalc_whole_map(world);
1582+ map->recalc_whole_map(eia.egbase());
1583 return 0;
1584 }
1585
1586 int32_t
1587-EditorResizeTool::handle_undo_impl(const Widelands::World& world,
1588- const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1589- EditorInteractive& parent,
1590+EditorResizeTool::handle_undo_impl(const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1591+ EditorInteractive& eia,
1592 EditorActionArgs* args,
1593 Widelands::Map* map) {
1594- Widelands::EditorGameBase& egbase = parent.egbase();
1595-
1596+ Widelands::EditorGameBase& egbase = eia.egbase();
1597 map->resize(egbase, center.node, args->resized.old_map_size.w, args->resized.old_map_size.h);
1598
1599 for (const auto& it : args->resized.deleted_fields) {
1600@@ -82,13 +77,13 @@
1601 }
1602
1603 for (const Widelands::Coords& c : args->resized.port_spaces) {
1604- map->set_port_space(world, c, true, true);
1605+ map->set_port_space(egbase, c, true, true);
1606 }
1607 for (uint8_t i = 1; i <= map->get_nrplayers(); ++i) {
1608 map->set_starting_pos(i, args->resized.starting_positions[i - 1]);
1609 }
1610
1611- map->recalc_whole_map(world);
1612+ map->recalc_whole_map(egbase);
1613 return 0;
1614 }
1615
1616
1617=== modified file 'src/editor/tools/resize_tool.h'
1618--- src/editor/tools/resize_tool.h 2019-04-24 07:09:29 +0000
1619+++ src/editor/tools/resize_tool.h 2019-09-05 15:29:33 +0000
1620@@ -31,14 +31,12 @@
1621 /**
1622 * Change the map size
1623 */
1624- int32_t handle_click_impl(const Widelands::World& world,
1625- const Widelands::NodeAndTriangle<>& center,
1626+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1627 EditorInteractive& parent,
1628 EditorActionArgs* args,
1629 Widelands::Map* map) override;
1630
1631- int32_t handle_undo_impl(const Widelands::World& world,
1632- const Widelands::NodeAndTriangle<>& center,
1633+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1634 EditorInteractive& parent,
1635 EditorActionArgs* args,
1636 Widelands::Map* map) override;
1637
1638=== modified file 'src/editor/tools/set_height_tool.cc'
1639--- src/editor/tools/set_height_tool.cc 2019-02-23 11:00:49 +0000
1640+++ src/editor/tools/set_height_tool.cc 2019-09-05 15:29:33 +0000
1641@@ -25,9 +25,8 @@
1642 #include "logic/field.h"
1643 #include "logic/mapregion.h"
1644
1645-int32_t EditorSetHeightTool::handle_click_impl(const Widelands::World& world,
1646- const Widelands::NodeAndTriangle<>& center,
1647- EditorInteractive& /* parent */,
1648+int32_t EditorSetHeightTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1649+ EditorInteractive& eia,
1650 EditorActionArgs* args,
1651 Widelands::Map* map) {
1652 if (args->original_heights.empty()) {
1653@@ -40,14 +39,13 @@
1654 while (mr.advance(*map));
1655 }
1656 return map->set_height(
1657- world, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius),
1658+ eia.egbase(), Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius),
1659 args->interval);
1660 }
1661
1662 int32_t
1663-EditorSetHeightTool::handle_undo_impl(const Widelands::World& world,
1664- const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1665- EditorInteractive& /* parent */,
1666+EditorSetHeightTool::handle_undo_impl(const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1667+ EditorInteractive& eia,
1668 EditorActionArgs* args,
1669 Widelands::Map* map) {
1670 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1671@@ -63,7 +61,7 @@
1672 } while (mr.advance(*map));
1673
1674 map->recalc_for_field_area(
1675- world, Widelands::Area<Widelands::FCoords>(
1676+ eia.egbase(), Widelands::Area<Widelands::FCoords>(
1677 map->get_fcoords(center.node),
1678 args->sel_radius + MAX_FIELD_HEIGHT / MAX_FIELD_HEIGHT_DIFF + 2));
1679
1680
1681=== modified file 'src/editor/tools/set_height_tool.h'
1682--- src/editor/tools/set_height_tool.h 2019-02-23 11:00:49 +0000
1683+++ src/editor/tools/set_height_tool.h 2019-09-05 15:29:33 +0000
1684@@ -29,14 +29,12 @@
1685 EditorSetHeightTool() : EditorTool(*this, *this), interval_(10, 10) {
1686 }
1687
1688- int32_t handle_click_impl(const Widelands::World& world,
1689- const Widelands::NodeAndTriangle<>& center,
1690+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1691 EditorInteractive& parent,
1692 EditorActionArgs* args,
1693 Widelands::Map* map) override;
1694
1695- int32_t handle_undo_impl(const Widelands::World& world,
1696- const Widelands::NodeAndTriangle<>& center,
1697+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1698 EditorInteractive& parent,
1699 EditorActionArgs* args,
1700 Widelands::Map* map) override;
1701
1702=== modified file 'src/editor/tools/set_origin_tool.cc'
1703--- src/editor/tools/set_origin_tool.cc 2019-02-23 11:00:49 +0000
1704+++ src/editor/tools/set_origin_tool.cc 2019-09-05 15:29:33 +0000
1705@@ -22,8 +22,7 @@
1706 #include "editor/editorinteractive.h"
1707 #include "wui/mapviewpixelconstants.h"
1708
1709-int32_t EditorSetOriginTool::handle_click_impl(const Widelands::World&,
1710- const Widelands::NodeAndTriangle<>& center,
1711+int32_t EditorSetOriginTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1712 EditorInteractive& eia,
1713 EditorActionArgs* /* args */,
1714 Widelands::Map* map) {
1715@@ -34,8 +33,7 @@
1716 }
1717
1718 int32_t
1719-EditorSetOriginTool::handle_undo_impl(const Widelands::World&,
1720- const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1721+EditorSetOriginTool::handle_undo_impl(const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1722 EditorInteractive& eia,
1723 EditorActionArgs* /* args */,
1724 Widelands::Map* map) {
1725
1726=== modified file 'src/editor/tools/set_origin_tool.h'
1727--- src/editor/tools/set_origin_tool.h 2019-02-27 19:00:36 +0000
1728+++ src/editor/tools/set_origin_tool.h 2019-09-05 15:29:33 +0000
1729@@ -27,14 +27,12 @@
1730 EditorSetOriginTool() : EditorTool(*this, *this) {
1731 }
1732
1733- int32_t handle_click_impl(const Widelands::World& world,
1734- const Widelands::NodeAndTriangle<>& center,
1735+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1736 EditorInteractive& eia,
1737 EditorActionArgs* args,
1738 Widelands::Map* map) override;
1739
1740- int32_t handle_undo_impl(const Widelands::World& world,
1741- const Widelands::NodeAndTriangle<>& center,
1742+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1743 EditorInteractive& parent,
1744 EditorActionArgs* args,
1745 Widelands::Map* map) override;
1746
1747=== modified file 'src/editor/tools/set_port_space_tool.cc'
1748--- src/editor/tools/set_port_space_tool.cc 2019-02-23 11:00:49 +0000
1749+++ src/editor/tools/set_port_space_tool.cc 2019-09-05 15:29:33 +0000
1750@@ -47,9 +47,8 @@
1751 EditorUnsetPortSpaceTool::EditorUnsetPortSpaceTool() : EditorTool(*this, *this) {
1752 }
1753
1754-int32_t EditorSetPortSpaceTool::handle_click_impl(const Widelands::World& world,
1755- const Widelands::NodeAndTriangle<>& center,
1756- EditorInteractive&,
1757+int32_t EditorSetPortSpaceTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1758+ EditorInteractive& eia,
1759 EditorActionArgs* args,
1760 Map* map) {
1761 assert(0 <= center.node.x);
1762@@ -64,9 +63,9 @@
1763 do {
1764 // check if field is valid
1765 if (port_tool_nodecaps(mr.location(), *map) != NodeCaps::CAPS_NONE) {
1766- map->set_port_space(world, mr.location(), true);
1767+ map->set_port_space(eia.egbase(), mr.location(), true);
1768 Area<FCoords> a(mr.location(), 0);
1769- map->recalc_for_field_area(world, a);
1770+ map->recalc_for_field_area(eia.egbase(), a);
1771 ++nr;
1772 }
1773 } while (mr.advance(*map));
1774@@ -80,17 +79,15 @@
1775 return port_tool_nodecaps(fcoords, egbase.map());
1776 }
1777
1778-int32_t EditorSetPortSpaceTool::handle_undo_impl(const Widelands::World& world,
1779- const NodeAndTriangle<Coords>& center,
1780+int32_t EditorSetPortSpaceTool::handle_undo_impl(const NodeAndTriangle<Coords>& center,
1781 EditorInteractive& parent,
1782 EditorActionArgs* args,
1783 Map* map) {
1784- return parent.tools()->unset_port_space.handle_click_impl(world, center, parent, args, map);
1785+ return parent.tools()->unset_port_space.handle_click_impl(center, parent, args, map);
1786 }
1787
1788-int32_t EditorUnsetPortSpaceTool::handle_click_impl(const Widelands::World& world,
1789- const Widelands::NodeAndTriangle<>& center,
1790- EditorInteractive&,
1791+int32_t EditorUnsetPortSpaceTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1792+ EditorInteractive& eia,
1793 EditorActionArgs* args,
1794 Map* map) {
1795 assert(0 <= center.node.x);
1796@@ -105,9 +102,9 @@
1797 do {
1798 // check if field is valid
1799 if (port_tool_nodecaps(mr.location(), *map)) {
1800- map->set_port_space(world, mr.location(), false);
1801+ map->set_port_space(eia.egbase(), mr.location(), false);
1802 Area<FCoords> a(mr.location(), 0);
1803- map->recalc_for_field_area(world, a);
1804+ map->recalc_for_field_area(eia.egbase(), a);
1805 ++nr;
1806 }
1807 } while (mr.advance(*map));
1808@@ -115,12 +112,11 @@
1809 return nr;
1810 }
1811
1812-int32_t EditorUnsetPortSpaceTool::handle_undo_impl(const Widelands::World& world,
1813- const NodeAndTriangle<Coords>& center,
1814+int32_t EditorUnsetPortSpaceTool::handle_undo_impl(const NodeAndTriangle<Coords>& center,
1815 EditorInteractive& parent,
1816 EditorActionArgs* args,
1817 Map* map) {
1818- return parent.tools()->set_port_space.handle_click_impl(world, center, parent, args, map);
1819+ return parent.tools()->set_port_space.handle_click_impl(center, parent, args, map);
1820 }
1821
1822 Widelands::NodeCaps
1823
1824=== modified file 'src/editor/tools/set_port_space_tool.h'
1825--- src/editor/tools/set_port_space_tool.h 2019-02-27 19:00:36 +0000
1826+++ src/editor/tools/set_port_space_tool.h 2019-09-05 15:29:33 +0000
1827@@ -30,14 +30,12 @@
1828 public:
1829 explicit EditorUnsetPortSpaceTool();
1830
1831- int32_t handle_click_impl(const Widelands::World& world,
1832- const Widelands::NodeAndTriangle<>& center,
1833+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1834 EditorInteractive& parent,
1835 EditorActionArgs* args,
1836 Widelands::Map* map) override;
1837
1838- int32_t handle_undo_impl(const Widelands::World& world,
1839- const Widelands::NodeAndTriangle<>& center,
1840+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1841 EditorInteractive& parent,
1842 EditorActionArgs* args,
1843 Widelands::Map* map) override;
1844@@ -54,14 +52,12 @@
1845 public:
1846 explicit EditorSetPortSpaceTool(EditorUnsetPortSpaceTool&);
1847
1848- int32_t handle_click_impl(const Widelands::World& world,
1849- const Widelands::NodeAndTriangle<>& center,
1850+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1851 EditorInteractive& parent,
1852 EditorActionArgs* args,
1853 Widelands::Map* map) override;
1854
1855- int32_t handle_undo_impl(const Widelands::World& world,
1856- const Widelands::NodeAndTriangle<>& center,
1857+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1858 EditorInteractive& parent,
1859 EditorActionArgs* args,
1860 Widelands::Map* map) override;
1861
1862=== modified file 'src/editor/tools/set_resources_tool.cc'
1863--- src/editor/tools/set_resources_tool.cc 2019-02-23 11:00:49 +0000
1864+++ src/editor/tools/set_resources_tool.cc 2019-09-05 15:29:33 +0000
1865@@ -24,13 +24,14 @@
1866 #include "editor/tools/increase_resources_tool.h"
1867 #include "logic/field.h"
1868 #include "logic/map_objects/world/resource_description.h"
1869+#include "logic/map_objects/world/world.h"
1870 #include "logic/mapregion.h"
1871
1872-int32_t EditorSetResourcesTool::handle_click_impl(const Widelands::World& world,
1873- const Widelands::NodeAndTriangle<>& center,
1874- EditorInteractive& /* parent */,
1875+int32_t EditorSetResourcesTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1876+ EditorInteractive& eia,
1877 EditorActionArgs* args,
1878 Widelands::Map* map) {
1879+ const Widelands::World& world = eia.egbase().world();
1880 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
1881 *map, Widelands::Area<Widelands::FCoords>(map->get_fcoords(center.node), args->sel_radius));
1882 do {
1883@@ -56,15 +57,14 @@
1884 }
1885
1886 int32_t EditorSetResourcesTool::handle_undo_impl(
1887- const Widelands::World& world,
1888 const Widelands::NodeAndTriangle<Widelands::Coords>& /* center */,
1889- EditorInteractive& /* parent */,
1890+ EditorInteractive& eia,
1891 EditorActionArgs* args,
1892 Widelands::Map* map) {
1893 for (const auto& res : args->original_resource) {
1894 Widelands::ResourceAmount amount = res.amount;
1895 Widelands::ResourceAmount max_amount =
1896- world.get_resource(args->current_resource)->max_amount();
1897+ eia.egbase().world().get_resource(args->current_resource)->max_amount();
1898
1899 if (amount > max_amount)
1900 amount = max_amount;
1901
1902=== modified file 'src/editor/tools/set_resources_tool.h'
1903--- src/editor/tools/set_resources_tool.h 2019-02-27 19:00:36 +0000
1904+++ src/editor/tools/set_resources_tool.h 2019-09-05 15:29:33 +0000
1905@@ -35,14 +35,12 @@
1906 /**
1907 * Sets the resources of the current to a fixed value
1908 */
1909- int32_t handle_click_impl(const Widelands::World& world,
1910- const Widelands::NodeAndTriangle<>& center,
1911+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1912 EditorInteractive& parent,
1913 EditorActionArgs* args,
1914 Widelands::Map* map) override;
1915
1916- int32_t handle_undo_impl(const Widelands::World& world,
1917- const Widelands::NodeAndTriangle<>& center,
1918+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
1919 EditorInteractive& parent,
1920 EditorActionArgs* args,
1921 Widelands::Map* map) override;
1922
1923=== modified file 'src/editor/tools/set_starting_pos_tool.cc'
1924--- src/editor/tools/set_starting_pos_tool.cc 2019-02-23 11:00:49 +0000
1925+++ src/editor/tools/set_starting_pos_tool.cc 2019-09-05 15:29:33 +0000
1926@@ -59,8 +59,7 @@
1927 current_player_ = 1;
1928 }
1929
1930-int32_t EditorSetStartingPosTool::handle_click_impl(const Widelands::World&,
1931- const Widelands::NodeAndTriangle<>& center,
1932+int32_t EditorSetStartingPosTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1933 EditorInteractive&,
1934 EditorActionArgs*,
1935 Widelands::Map* map) {
1936
1937=== modified file 'src/editor/tools/set_starting_pos_tool.h'
1938--- src/editor/tools/set_starting_pos_tool.h 2019-02-27 19:00:36 +0000
1939+++ src/editor/tools/set_starting_pos_tool.h 2019-09-05 15:29:33 +0000
1940@@ -33,8 +33,7 @@
1941 struct EditorSetStartingPosTool : public EditorTool {
1942 EditorSetStartingPosTool();
1943
1944- int32_t handle_click_impl(const Widelands::World& world,
1945- const Widelands::NodeAndTriangle<>&,
1946+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>&,
1947 EditorInteractive&,
1948 EditorActionArgs*,
1949 Widelands::Map*) override;
1950
1951=== modified file 'src/editor/tools/set_terrain_tool.cc'
1952--- src/editor/tools/set_terrain_tool.cc 2019-02-23 11:00:49 +0000
1953+++ src/editor/tools/set_terrain_tool.cc 2019-09-05 15:29:33 +0000
1954@@ -24,9 +24,8 @@
1955
1956 using Widelands::TCoords;
1957
1958-int32_t EditorSetTerrainTool::handle_click_impl(const Widelands::World& world,
1959- const Widelands::NodeAndTriangle<>& center,
1960- EditorInteractive& /* parent */,
1961+int32_t EditorSetTerrainTool::handle_click_impl(const Widelands::NodeAndTriangle<>& center,
1962+ EditorInteractive& eia,
1963 EditorActionArgs* args,
1964 Widelands::Map* map) {
1965 assert(center.triangle.t == Widelands::TriangleIndex::D ||
1966@@ -56,7 +55,7 @@
1967 radius));
1968 std::list<Widelands::DescriptionIndex>::iterator i = args->terrain_type.begin();
1969 do {
1970- max = std::max(max, map->change_terrain(world, mr.location(), *i));
1971+ max = std::max(max, map->change_terrain(eia.egbase(), mr.location(), *i));
1972 ++i;
1973 } while (mr.advance(*map));
1974 }
1975@@ -64,9 +63,8 @@
1976 }
1977
1978 int32_t
1979-EditorSetTerrainTool::handle_undo_impl(const Widelands::World& world,
1980- const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1981- EditorInteractive& /* parent */,
1982+EditorSetTerrainTool::handle_undo_impl(const Widelands::NodeAndTriangle<Widelands::Coords>& center,
1983+ EditorInteractive& eia,
1984 EditorActionArgs* args,
1985 Widelands::Map* map) {
1986 assert(center.triangle.t == Widelands::TriangleIndex::D ||
1987@@ -82,7 +80,7 @@
1988
1989 std::list<Widelands::DescriptionIndex>::iterator i = args->original_terrain_type.begin();
1990 do {
1991- max = std::max(max, map->change_terrain(world, mr.location(), *i));
1992+ max = std::max(max, map->change_terrain(eia.egbase(), mr.location(), *i));
1993 ++i;
1994 } while (mr.advance(*map));
1995 return radius + max;
1996
1997=== modified file 'src/editor/tools/set_terrain_tool.h'
1998--- src/editor/tools/set_terrain_tool.h 2019-02-23 11:00:49 +0000
1999+++ src/editor/tools/set_terrain_tool.h 2019-09-05 15:29:33 +0000
2000@@ -27,14 +27,12 @@
2001 EditorSetTerrainTool() : EditorTool(*this, *this) {
2002 }
2003
2004- int32_t handle_click_impl(const Widelands::World& world,
2005- const Widelands::NodeAndTriangle<>& center,
2006+ int32_t handle_click_impl(const Widelands::NodeAndTriangle<>& center,
2007 EditorInteractive& parent,
2008 EditorActionArgs* args,
2009 Widelands::Map* map) override;
2010
2011- int32_t handle_undo_impl(const Widelands::World& world,
2012- const Widelands::NodeAndTriangle<>& center,
2013+ int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>& center,
2014 EditorInteractive& parent,
2015 EditorActionArgs* args,
2016 Widelands::Map* map) override;
2017
2018=== modified file 'src/editor/tools/tool.h'
2019--- src/editor/tools/tool.h 2019-02-23 11:00:49 +0000
2020+++ src/editor/tools/tool.h 2019-09-05 15:29:33 +0000
2021@@ -26,7 +26,6 @@
2022 #include "editor/tools/action_args.h"
2023 #include "graphic/image.h"
2024 #include "logic/editor_game_base.h"
2025-#include "logic/map_objects/world/world.h"
2026 #include "logic/widelands_geometry.h"
2027
2028 class EditorInteractive;
2029@@ -47,23 +46,21 @@
2030
2031 enum ToolIndex { First, Second, Third };
2032 int32_t handle_click(ToolIndex i,
2033- const Widelands::World& world,
2034 const Widelands::NodeAndTriangle<>& center,
2035 EditorInteractive& parent,
2036 EditorActionArgs* args,
2037 Widelands::Map* map) {
2038 return (i == First ? *this : i == Second ? second_ : third_)
2039- .handle_click_impl(world, center, parent, args, map);
2040+ .handle_click_impl(center, parent, args, map);
2041 }
2042
2043 int32_t handle_undo(ToolIndex i,
2044- const Widelands::World& world,
2045 const Widelands::NodeAndTriangle<>& center,
2046 EditorInteractive& parent,
2047 EditorActionArgs* args,
2048 Widelands::Map* map) {
2049 return (i == First ? *this : i == Second ? second_ : third_)
2050- .handle_undo_impl(world, center, parent, args, map);
2051+ .handle_undo_impl(center, parent, args, map);
2052 }
2053
2054 const Image* get_sel(const ToolIndex i) {
2055@@ -83,13 +80,11 @@
2056 virtual EditorActionArgs format_args_impl(EditorInteractive& parent) {
2057 return EditorActionArgs(parent);
2058 }
2059- virtual int32_t handle_click_impl(const Widelands::World& world,
2060- const Widelands::NodeAndTriangle<>&,
2061+ virtual int32_t handle_click_impl(const Widelands::NodeAndTriangle<>&,
2062 EditorInteractive&,
2063 EditorActionArgs*,
2064 Widelands::Map*) = 0;
2065- virtual int32_t handle_undo_impl(const Widelands::World&,
2066- const Widelands::NodeAndTriangle<>&,
2067+ virtual int32_t handle_undo_impl(const Widelands::NodeAndTriangle<>&,
2068 EditorInteractive&,
2069 EditorActionArgs*,
2070 Widelands::Map*) {
2071
2072=== modified file 'src/editor/ui_menus/main_menu_new_map.cc'
2073--- src/editor/ui_menus/main_menu_new_map.cc 2019-08-28 06:12:07 +0000
2074+++ src/editor/ui_menus/main_menu_new_map.cc 2019-09-05 15:29:33 +0000
2075@@ -106,14 +106,14 @@
2076
2077 parent.cleanup_for_load();
2078
2079- map->create_empty_map(egbase.world(), map_size_box_.selected_width(),
2080+ map->create_empty_map(egbase, map_size_box_.selected_width(),
2081 map_size_box_.selected_height(), list_.get_selected(), _("No Name"),
2082 get_config_string("realname", pgettext("author_name", "Unknown")));
2083
2084 egbase.postload();
2085 egbase.load_graphics(loader_ui);
2086
2087- map->recalc_whole_map(egbase.world());
2088+ map->recalc_whole_map(egbase);
2089 parent.map_changed(EditorInteractive::MapWas::kReplaced);
2090 die();
2091 }
2092
2093=== modified file 'src/editor/ui_menus/main_menu_random_map.cc'
2094--- src/editor/ui_menus/main_menu_random_map.cc 2019-08-28 06:12:07 +0000
2095+++ src/editor/ui_menus/main_menu_random_map.cc 2019-09-05 15:29:33 +0000
2096@@ -485,7 +485,7 @@
2097 << "ID = " << map_id_edit_.text() << "\n";
2098
2099 MapGenerator gen(*map, map_info, egbase);
2100- map->create_empty_map(egbase.world(), map_info.w, map_info.h, 0, _("No Name"),
2101+ map->create_empty_map(egbase, map_info.w, map_info.h, 0, _("No Name"),
2102 get_config_string("realname", pgettext("author_name", "Unknown")),
2103 sstrm.str().c_str());
2104 loader_ui.step(_("Generating random map…"));
2105@@ -519,7 +519,7 @@
2106 egbase.postload();
2107 egbase.load_graphics(loader_ui);
2108
2109- map->recalc_whole_map(egbase.world());
2110+ map->recalc_whole_map(egbase);
2111 eia.map_changed(EditorInteractive::MapWas::kReplaced);
2112 UI::WLMessageBox mbox(
2113 &eia,
2114
2115=== modified file 'src/editor/ui_menus/main_menu_save_map.cc'
2116--- src/editor/ui_menus/main_menu_save_map.cc 2019-08-25 14:50:16 +0000
2117+++ src/editor/ui_menus/main_menu_save_map.cc 2019-09-05 15:29:33 +0000
2118@@ -315,7 +315,7 @@
2119 Widelands::Map* map = egbase.mutable_map();
2120
2121 // Recompute seafaring tag
2122- map->cleanup_port_spaces(egbase.world());
2123+ map->cleanup_port_spaces(egbase);
2124 if (map->allows_seafaring()) {
2125 map->add_tag("seafaring");
2126 } else {
2127
2128=== modified file 'src/logic/editor_game_base.cc'
2129--- src/logic/editor_game_base.cc 2019-06-23 11:41:17 +0000
2130+++ src/logic/editor_game_base.cc 2019-09-05 15:29:33 +0000
2131@@ -291,9 +291,11 @@
2132 }
2133 }
2134
2135- // Postload tribes
2136+ // Postload tribes and world
2137 assert(tribes_);
2138 tribes_->postload();
2139+ assert(world_);
2140+ world_->postload();
2141
2142 for (DescriptionIndex i = 0; i < tribes_->nrtribes(); i++) {
2143 const TribeDescr* tribe = tribes_->get_tribe_descr(i);
2144@@ -333,7 +335,7 @@
2145 Building& EditorGameBase::warp_building(const Coords& c,
2146 PlayerNumber const owner,
2147 DescriptionIndex const idx,
2148- Building::FormerBuildings former_buildings) {
2149+ FormerBuildings former_buildings) {
2150 Player* plr = get_player(owner);
2151 const TribeDescr& tribe = plr->tribe();
2152 return tribe.get_building_descr(idx)->create(*this, plr, c, false, true, former_buildings);
2153@@ -350,7 +352,7 @@
2154 PlayerNumber const owner,
2155 DescriptionIndex idx,
2156 bool loading,
2157- Building::FormerBuildings former_buildings,
2158+ FormerBuildings former_buildings,
2159 const BuildingSettings* settings) {
2160 Player* plr = get_player(owner);
2161 const TribeDescr& tribe = plr->tribe();
2162@@ -370,7 +372,7 @@
2163 Building& EditorGameBase::warp_dismantlesite(const Coords& c,
2164 PlayerNumber const owner,
2165 bool loading,
2166- Building::FormerBuildings former_buildings) {
2167+ FormerBuildings former_buildings) {
2168 Player* plr = get_player(owner);
2169 const TribeDescr& tribe = plr->tribe();
2170
2171@@ -646,7 +648,7 @@
2172 // This must reach two steps beyond the conquered area to adjust the borders
2173 // of neighbour players.
2174 player_area.radius += 2;
2175- map_.recalc_for_field_area(world(), player_area);
2176+ map_.recalc_for_field_area(*this, player_area);
2177 }
2178
2179 /// Conquers the given area for that player; does the actual work.
2180@@ -721,7 +723,7 @@
2181 // This must reach two steps beyond the conquered area to adjust the borders
2182 // of neighbour players.
2183 player_area.radius += 2;
2184- map_.recalc_for_field_area(world(), player_area);
2185+ map_.recalc_for_field_area(*this, player_area);
2186
2187 // Deal with player immovables in the lost area
2188 // Players are not allowed to have their immovables on their borders.
2189@@ -741,7 +743,7 @@
2190 std::vector<PlayerImmovable*> burnlist;
2191
2192 // find all immovables that need fixing
2193- map_.find_immovables(area, &immovables, FindImmovablePlayerImmovable());
2194+ map_.find_immovables(*this, area, &immovables, FindImmovablePlayerImmovable());
2195
2196 for (const ImmovableFound& temp_imm : immovables) {
2197 upcast(PlayerImmovable, imm, temp_imm.object);
2198
2199=== modified file 'src/logic/editor_game_base.h'
2200--- src/logic/editor_game_base.h 2019-05-14 16:25:57 +0000
2201+++ src/logic/editor_game_base.h 2019-09-05 15:29:33 +0000
2202@@ -125,19 +125,19 @@
2203 warp_building(const Coords&,
2204 PlayerNumber,
2205 DescriptionIndex,
2206- Building::FormerBuildings former_buildings = Building::FormerBuildings());
2207+ FormerBuildings former_buildings = FormerBuildings());
2208 Building&
2209 warp_constructionsite(const Coords&,
2210 PlayerNumber,
2211 DescriptionIndex,
2212 bool loading = false,
2213- Building::FormerBuildings former_buildings = Building::FormerBuildings(),
2214+ FormerBuildings former_buildings = FormerBuildings(),
2215 const BuildingSettings* settings = nullptr);
2216 Building&
2217 warp_dismantlesite(const Coords&,
2218 PlayerNumber,
2219 bool loading = false,
2220- Building::FormerBuildings former_buildings = Building::FormerBuildings());
2221+ FormerBuildings former_buildings = FormerBuildings());
2222 Bob& create_critter(const Coords&, DescriptionIndex bob_type_idx, Player* owner = nullptr);
2223 Bob& create_critter(const Coords&, const std::string& name, Player* owner = nullptr);
2224 Immovable&
2225
2226=== modified file 'src/logic/map.cc'
2227--- src/logic/map.cc 2019-06-25 08:03:30 +0000
2228+++ src/logic/map.cc 2019-09-05 15:29:33 +0000
2229@@ -122,7 +122,7 @@
2230 and recalcs the interactive player's overlay.
2231 ===============
2232 */
2233-void Map::recalc_for_field_area(const World& world, const Area<FCoords> area) {
2234+void Map::recalc_for_field_area(const EditorGameBase& egbase, const Area<FCoords> area) {
2235 assert(0 <= area.x);
2236 assert(area.x < width_);
2237 assert(0 <= area.y);
2238@@ -135,14 +135,14 @@
2239 do {
2240 recalc_brightness(mr.location());
2241 recalc_border(mr.location());
2242- recalc_nodecaps_pass1(world, mr.location());
2243+ recalc_nodecaps_pass1(egbase, mr.location());
2244 } while (mr.advance(*this));
2245 }
2246
2247 { // Second pass.
2248 MapRegion<Area<FCoords>> mr(*this, area);
2249 do
2250- recalc_nodecaps_pass2(world, mr.location());
2251+ recalc_nodecaps_pass2(egbase, mr.location());
2252 while (mr.advance(*this));
2253 }
2254 }
2255@@ -156,7 +156,7 @@
2256 the overlays have completely changed.
2257 ===========
2258 */
2259-void Map::recalc_whole_map(const World& world) {
2260+void Map::recalc_whole_map(const EditorGameBase& egbase) {
2261 // Post process the map in the necessary two passes to calculate
2262 // brightness and building caps
2263 FCoords f;
2264@@ -168,13 +168,13 @@
2265 check_neighbour_heights(f, radius);
2266 recalc_brightness(f);
2267 recalc_border(f);
2268- recalc_nodecaps_pass1(world, f);
2269+ recalc_nodecaps_pass1(egbase, f);
2270 }
2271
2272 for (int16_t y = 0; y < height_; ++y)
2273 for (int16_t x = 0; x < width_; ++x) {
2274 f = get_fcoords(Coords(x, y));
2275- recalc_nodecaps_pass2(world, f);
2276+ recalc_nodecaps_pass2(egbase, f);
2277 }
2278 recalculate_allows_seafaring();
2279 }
2280@@ -442,7 +442,7 @@
2281 the given data
2282 ===========
2283 */
2284-void Map::create_empty_map(const World& world,
2285+void Map::create_empty_map(const EditorGameBase& egbase,
2286 uint32_t const w,
2287 uint32_t const h,
2288 const Widelands::DescriptionIndex default_terrain,
2289@@ -467,7 +467,7 @@
2290 }
2291 }
2292 }
2293- recalc_whole_map(world);
2294+ recalc_whole_map(egbase);
2295
2296 filesystem_.reset(nullptr);
2297 }
2298@@ -871,9 +871,9 @@
2299 }
2300 }
2301
2302-NodeCaps Map::get_max_nodecaps(const World& world, const FCoords& fc) const {
2303- NodeCaps max_caps = calc_nodecaps_pass1(world, fc, false);
2304- max_caps = calc_nodecaps_pass2(world, fc, false, max_caps);
2305+NodeCaps Map::get_max_nodecaps(const EditorGameBase& egbase, const FCoords& fc) const {
2306+ NodeCaps max_caps = calc_nodecaps_pass1(egbase, fc, false);
2307+ max_caps = calc_nodecaps_pass2(egbase, fc, false, max_caps);
2308 return static_cast<NodeCaps>(max_caps);
2309 }
2310
2311@@ -891,7 +891,7 @@
2312 ===============
2313 */
2314 template <typename functorT>
2315-void Map::find_reachable(const Area<FCoords>& area,
2316+void Map::find_reachable(const EditorGameBase& egbase, const Area<FCoords>& area,
2317 const CheckStep& checkstep,
2318 functorT& functor) const {
2319 std::vector<Coords> queue;
2320@@ -906,7 +906,7 @@
2321 Pathfield& curpf = pathfields->fields[cur.field - fields_.get()];
2322
2323 // handle this node
2324- functor(*this, cur);
2325+ functor(egbase, cur);
2326 curpf.cycle = pathfields->cycle;
2327
2328 // Get neighbours
2329@@ -934,10 +934,10 @@
2330 Functor is of the form: functor(Map &, FCoords)
2331 ===============
2332 */
2333-template <typename functorT> void Map::find(const Area<FCoords>& area, functorT& functor) const {
2334+template <typename functorT> void Map::find(const EditorGameBase& egbase, const Area<FCoords>& area, functorT& functor) const {
2335 MapRegion<Area<FCoords>> mr(*this, area);
2336 do
2337- functor(*this, mr.location());
2338+ functor(egbase, mr.location());
2339 while (mr.advance(*this));
2340 }
2341
2342@@ -953,7 +953,7 @@
2343 : list_(list), functor_(functor), found_(0) {
2344 }
2345
2346- void operator()(const Map&, const FCoords& cur) {
2347+ void operator()(const EditorGameBase&, const FCoords& cur) {
2348 for (Bob* bob = cur.field->get_first_bob(); bob; bob = bob->get_next_bob()) {
2349 if (list_ && std::find(list_->begin(), list_->end(), bob) != list_->end())
2350 continue;
2351@@ -982,12 +982,12 @@
2352 Returns the number of objects found.
2353 ===============
2354 */
2355-uint32_t Map::find_bobs(Area<FCoords> const area,
2356+uint32_t Map::find_bobs(const EditorGameBase& egbase, Area<FCoords> const area,
2357 std::vector<Bob*>* const list,
2358 const FindBob& functor) const {
2359 FindBobsCallback cb(list, functor);
2360
2361- find(area, cb);
2362+ find(egbase, area, cb);
2363
2364 return cb.found_;
2365 }
2366@@ -1004,13 +1004,13 @@
2367 Returns the number of objects found.
2368 ===============
2369 */
2370-uint32_t Map::find_reachable_bobs(Area<FCoords> const area,
2371+uint32_t Map::find_reachable_bobs(const EditorGameBase& egbase, Area<FCoords> const area,
2372 std::vector<Bob*>* const list,
2373 const CheckStep& checkstep,
2374 const FindBob& functor) const {
2375 FindBobsCallback cb(list, functor);
2376
2377- find_reachable(area, checkstep, cb);
2378+ find_reachable(egbase, area, checkstep, cb);
2379
2380 return cb.found_;
2381 }
2382@@ -1027,7 +1027,7 @@
2383 : list_(list), functor_(functor), found_(0) {
2384 }
2385
2386- void operator()(const Map&, const FCoords& cur) {
2387+ void operator()(const EditorGameBase&, const FCoords& cur) {
2388 BaseImmovable* const imm = cur.field->get_immovable();
2389
2390 if (!imm)
2391@@ -1058,12 +1058,12 @@
2392 If list is not 0, found immovables are stored in list.
2393 ===============
2394 */
2395-uint32_t Map::find_immovables(Area<FCoords> const area,
2396+uint32_t Map::find_immovables(const EditorGameBase& egbase, Area<FCoords> const area,
2397 std::vector<ImmovableFound>* const list,
2398 const FindImmovable& functor) const {
2399 FindImmovablesCallback cb(list, functor);
2400
2401- find(area, cb);
2402+ find(egbase, area, cb);
2403
2404 return cb.found_;
2405 }
2406@@ -1078,13 +1078,13 @@
2407 Returns the number of immovables we found.
2408 ===============
2409 */
2410-uint32_t Map::find_reachable_immovables(Area<FCoords> const area,
2411+uint32_t Map::find_reachable_immovables(const EditorGameBase& egbase, Area<FCoords> const area,
2412 std::vector<ImmovableFound>* const list,
2413 const CheckStep& checkstep,
2414 const FindImmovable& functor) const {
2415 FindImmovablesCallback cb(list, functor);
2416
2417- find_reachable(area, checkstep, cb);
2418+ find_reachable(egbase, area, checkstep, cb);
2419
2420 return cb.found_;
2421 }
2422@@ -1096,14 +1096,14 @@
2423 *
2424 * \return the number of immovables found.
2425 */
2426-uint32_t Map::find_reachable_immovables_unique(const Area<FCoords> area,
2427+uint32_t Map::find_reachable_immovables_unique(const EditorGameBase& egbase, const Area<FCoords> area,
2428 std::vector<BaseImmovable*>& list,
2429 const CheckStep& checkstep,
2430 const FindImmovable& functor) const {
2431 std::vector<ImmovableFound> duplist;
2432 FindImmovablesCallback cb(&duplist, find_immovable_always_true());
2433
2434- find_reachable(area, checkstep, cb);
2435+ find_reachable(egbase, area, checkstep, cb);
2436
2437 for (ImmovableFound& imm_found : duplist) {
2438 BaseImmovable& obj = *imm_found.object;
2439@@ -1129,8 +1129,8 @@
2440 : list_(list), functor_(functor), found_(0) {
2441 }
2442
2443- void operator()(const Map& map, const FCoords& cur) {
2444- if (functor_.accept(map, cur)) {
2445+ void operator()(const EditorGameBase& egbase, const FCoords& cur) {
2446+ if (functor_.accept(egbase, cur)) {
2447 if (list_)
2448 list_->push_back(cur);
2449
2450@@ -1152,12 +1152,12 @@
2451 Note that list can be 0.
2452 ===============
2453 */
2454-uint32_t Map::find_fields(Area<FCoords> const area,
2455+uint32_t Map::find_fields(const EditorGameBase& egbase, Area<FCoords> const area,
2456 std::vector<Coords>* list,
2457 const FindNode& functor) const {
2458 FindNodesCallback cb(list, functor);
2459
2460- find(area, cb);
2461+ find(egbase, area, cb);
2462
2463 return cb.found_;
2464 }
2465@@ -1171,13 +1171,13 @@
2466 Note that list can be 0.
2467 ===============
2468 */
2469-uint32_t Map::find_reachable_fields(Area<FCoords> const area,
2470+uint32_t Map::find_reachable_fields(const EditorGameBase& egbase, Area<FCoords> const area,
2471 std::vector<Coords>* list,
2472 const CheckStep& checkstep,
2473 const FindNode& functor) const {
2474 FindNodesCallback cb(list, functor);
2475
2476- find_reachable(area, checkstep, cb);
2477+ find_reachable(egbase, area, checkstep, cb);
2478
2479 return cb.found_;
2480 }
2481@@ -1258,13 +1258,14 @@
2482 above recalc_brightness.
2483 ===============
2484 */
2485-void Map::recalc_nodecaps_pass1(const World& world, const FCoords& f) {
2486- f.field->caps = calc_nodecaps_pass1(world, f, true);
2487- f.field->max_caps = calc_nodecaps_pass1(world, f, false);
2488+void Map::recalc_nodecaps_pass1(const EditorGameBase& egbase, const FCoords& f) {
2489+ f.field->caps = calc_nodecaps_pass1(egbase, f, true);
2490+ f.field->max_caps = calc_nodecaps_pass1(egbase, f, false);
2491 }
2492
2493-NodeCaps Map::calc_nodecaps_pass1(const World& world, const FCoords& f, bool consider_mobs) const {
2494+NodeCaps Map::calc_nodecaps_pass1(const EditorGameBase& egbase, const FCoords& f, bool consider_mobs) const {
2495 uint8_t caps = CAPS_NONE;
2496+ const World& world = egbase.world();
2497
2498 // 1a) Get all the neighbours to make life easier
2499 const FCoords tr = tr_n(f);
2500@@ -1362,7 +1363,7 @@
2501 if (caps & MOVECAPS_WALK) {
2502 // 4b) Flags must be at least 2 edges apart
2503 if (consider_mobs &&
2504- find_immovables(Area<FCoords>(f, 1), nullptr, FindImmovableType(MapObjectType::FLAG)))
2505+ find_immovables(egbase, Area<FCoords>(f, 1), nullptr, FindImmovableType(MapObjectType::FLAG)))
2506 return static_cast<NodeCaps>(caps);
2507 caps |= BUILDCAPS_FLAG;
2508 }
2509@@ -1377,13 +1378,13 @@
2510 Important: flag buildability has already been checked in the first pass.
2511 ===============
2512 */
2513-void Map::recalc_nodecaps_pass2(const World& world, const FCoords& f) {
2514- f.field->caps = calc_nodecaps_pass2(world, f, true);
2515+void Map::recalc_nodecaps_pass2(const EditorGameBase& egbase, const FCoords& f) {
2516+ f.field->caps = calc_nodecaps_pass2(egbase, f, true);
2517 f.field->max_caps =
2518- calc_nodecaps_pass2(world, f, false, static_cast<NodeCaps>(f.field->max_caps));
2519+ calc_nodecaps_pass2(egbase, f, false, static_cast<NodeCaps>(f.field->max_caps));
2520 }
2521
2522-NodeCaps Map::calc_nodecaps_pass2(const World& world,
2523+NodeCaps Map::calc_nodecaps_pass2(const EditorGameBase& egbase,
2524 const FCoords& f,
2525 bool consider_mobs,
2526 NodeCaps initcaps) const {
2527@@ -1400,22 +1401,22 @@
2528 br.field->get_immovable()->descr().type() != MapObjectType::FLAG))
2529 return static_cast<NodeCaps>(caps);
2530 } else {
2531- if (!(calc_nodecaps_pass1(world, br, false) & BUILDCAPS_FLAG))
2532+ if (!(calc_nodecaps_pass1(egbase, br, false) & BUILDCAPS_FLAG))
2533 return static_cast<NodeCaps>(caps);
2534 }
2535
2536 bool mine;
2537- uint8_t buildsize = calc_buildsize(world, f, true, &mine, consider_mobs, initcaps);
2538+ uint8_t buildsize = calc_buildsize(egbase, f, true, &mine, consider_mobs, initcaps);
2539 if (buildsize < BaseImmovable::SMALL)
2540 return static_cast<NodeCaps>(caps);
2541 assert(buildsize >= BaseImmovable::SMALL && buildsize <= BaseImmovable::BIG);
2542
2543 if (buildsize == BaseImmovable::BIG) {
2544- if (calc_buildsize(world, l_n(f), false, nullptr, consider_mobs, initcaps) <
2545- BaseImmovable::BIG ||
2546- calc_buildsize(world, tl_n(f), false, nullptr, consider_mobs, initcaps) <
2547- BaseImmovable::BIG ||
2548- calc_buildsize(world, tr_n(f), false, nullptr, consider_mobs, initcaps) <
2549+ if (calc_buildsize(egbase, l_n(f), false, nullptr, consider_mobs, initcaps) <
2550+ BaseImmovable::BIG ||
2551+ calc_buildsize(egbase, tl_n(f), false, nullptr, consider_mobs, initcaps) <
2552+ BaseImmovable::BIG ||
2553+ calc_buildsize(egbase, tr_n(f), false, nullptr, consider_mobs, initcaps) <
2554 BaseImmovable::BIG)
2555 buildsize = BaseImmovable::MEDIUM;
2556 }
2557@@ -1489,7 +1490,7 @@
2558 * for the calculation. If not (calculation of maximum theoretical possible buildsize) initcaps must
2559 * be set.
2560 */
2561-int Map::calc_buildsize(const World& world,
2562+int Map::calc_buildsize(const EditorGameBase& egbase,
2563 const FCoords& f,
2564 bool avoidnature,
2565 bool* ismine,
2566@@ -1509,6 +1510,7 @@
2567 const FCoords tl = tl_n(f);
2568 const FCoords l = l_n(f);
2569
2570+ const World& world = egbase.world();
2571 const TerrainDescription::Is terrains[6] = {world.terrain_descr(tr.field->terrain_d()).get_is(),
2572 world.terrain_descr(tl.field->terrain_r()).get_is(),
2573 world.terrain_descr(tl.field->terrain_d()).get_is(),
2574@@ -1540,7 +1542,7 @@
2575 int buildsize = BaseImmovable::BIG;
2576 if (consider_mobs) {
2577 std::vector<ImmovableFound> objectlist;
2578- find_immovables(Area<FCoords>(f, 1), &objectlist,
2579+ find_immovables(egbase, Area<FCoords>(f, 1), &objectlist,
2580 FindImmovableSize(BaseImmovable::SMALL, BaseImmovable::BIG));
2581 for (uint32_t i = 0; i < objectlist.size(); ++i) {
2582 const BaseImmovable* obj = objectlist[i].object;
2583@@ -1632,8 +1634,8 @@
2584 return portdock;
2585 }
2586
2587-bool Map::is_port_space_allowed(const World& world, const FCoords& fc) const {
2588- return (get_max_nodecaps(world, fc) & BUILDCAPS_SIZEMASK) == BUILDCAPS_BIG &&
2589+bool Map::is_port_space_allowed(const EditorGameBase& egbase, const FCoords& fc) const {
2590+ return (get_max_nodecaps(egbase, fc) & BUILDCAPS_SIZEMASK) == BUILDCAPS_BIG &&
2591 !find_portdock(fc).empty();
2592 }
2593
2594@@ -1643,10 +1645,10 @@
2595 }
2596
2597 bool Map::set_port_space(
2598- const World& world, const Coords& c, bool set, bool force, bool recalculate_seafaring) {
2599+ const EditorGameBase& egbase, const Coords& c, bool set, bool force, bool recalculate_seafaring) {
2600 bool success = false;
2601 if (set) {
2602- success = force || is_port_space_allowed(world, get_fcoords(c));
2603+ success = force || is_port_space_allowed(egbase, get_fcoords(c));
2604 if (success) {
2605 port_spaces_.insert(c);
2606 recalculate_seafaring &= !allows_seafaring();
2607@@ -2093,26 +2095,26 @@
2608 }
2609
2610 int32_t
2611-Map::change_terrain(const World& world, TCoords<FCoords> const c, DescriptionIndex const terrain) {
2612+Map::change_terrain(const EditorGameBase& egbase, TCoords<FCoords> const c, DescriptionIndex const terrain) {
2613 c.node.field->set_terrain(c.t, terrain);
2614
2615 // remove invalid resources if necessary
2616 // check vertex to which the triangle belongs
2617- if (!is_resource_valid(world, c.node, c.node.field->get_resources())) {
2618+ if (!is_resource_valid(egbase.world(), c.node, c.node.field->get_resources())) {
2619 clear_resources(c.node);
2620 }
2621
2622 // always check south-east vertex
2623 Widelands::FCoords f_se(c.node);
2624 get_neighbour(f_se, Widelands::WALK_SE, &f_se);
2625- if (!is_resource_valid(world, f_se, f_se.field->get_resources())) {
2626+ if (!is_resource_valid(egbase.world(), f_se, f_se.field->get_resources())) {
2627 clear_resources(f_se);
2628 }
2629
2630 // check south-west vertex if d-Triangle is changed, check east vertex if r-Triangle is changed
2631 Widelands::FCoords f_sw_e(c.node);
2632 get_neighbour(f_sw_e, c.t == TriangleIndex::D ? Widelands::WALK_SW : Widelands::WALK_E, &f_sw_e);
2633- if (!is_resource_valid(world, f_sw_e, f_sw_e.field->get_resources())) {
2634+ if (!is_resource_valid(egbase.world(), f_sw_e, f_sw_e.field->get_resources())) {
2635 clear_resources(f_sw_e);
2636 }
2637
2638@@ -2121,7 +2123,7 @@
2639
2640 // Changing the terrain can affect ports, which can be up to 3 fields away.
2641 constexpr int kPotentiallyAffectedNeighbors = 3;
2642- recalc_for_field_area(world, Area<FCoords>(c.node, kPotentiallyAffectedNeighbors));
2643+ recalc_for_field_area(egbase, Area<FCoords>(c.node, kPotentiallyAffectedNeighbors));
2644 return kPotentiallyAffectedNeighbors;
2645 }
2646
2647@@ -2189,18 +2191,18 @@
2648 initialize_resources(c, Widelands::kNoResource, 0);
2649 }
2650
2651-uint32_t Map::set_height(const World& world, const FCoords fc, uint8_t const new_value) {
2652+uint32_t Map::set_height(const EditorGameBase& egbase, const FCoords fc, uint8_t const new_value) {
2653 assert(new_value <= MAX_FIELD_HEIGHT);
2654 assert(fields_.get() <= fc.field);
2655 assert(fc.field < fields_.get() + max_index());
2656 fc.field->height = new_value;
2657 uint32_t radius = 2;
2658 check_neighbour_heights(fc, radius);
2659- recalc_for_field_area(world, Area<FCoords>(fc, radius));
2660+ recalc_for_field_area(egbase, Area<FCoords>(fc, radius));
2661 return radius;
2662 }
2663
2664-uint32_t Map::change_height(const World& world, Area<FCoords> area, int16_t const difference) {
2665+uint32_t Map::change_height(const EditorGameBase& egbase, Area<FCoords> area, int16_t const difference) {
2666 {
2667 MapRegion<Area<FCoords>> mr(*this, area);
2668 do {
2669@@ -2221,11 +2223,11 @@
2670 regional_radius = std::max(regional_radius, local_radius);
2671 } while (mr.advance(*this));
2672 area.radius += regional_radius + 2;
2673- recalc_for_field_area(world, area);
2674+ recalc_for_field_area(egbase, area);
2675 return area.radius;
2676 }
2677
2678-uint32_t Map::set_height(const World& world, Area<FCoords> area, HeightInterval height_interval) {
2679+uint32_t Map::set_height(const EditorGameBase& egbase, Area<FCoords> area, HeightInterval height_interval) {
2680 assert(height_interval.valid());
2681 assert(height_interval.max <= MAX_FIELD_HEIGHT);
2682 {
2683@@ -2262,7 +2264,7 @@
2684 } while (changed);
2685 area.radius = mr.radius();
2686 }
2687- recalc_for_field_area(world, area);
2688+ recalc_for_field_area(egbase, area);
2689 return area.radius;
2690 }
2691
2692@@ -2368,16 +2370,16 @@
2693 Notifications::publish(NoteMapOptions());
2694 }
2695
2696-void Map::cleanup_port_spaces(const World& world) {
2697+void Map::cleanup_port_spaces(const EditorGameBase& egbase) {
2698 // Temporary set to avoid problems with concurrent container operations
2699 PortSpacesSet clean_me_up;
2700 for (const Coords& c : get_port_spaces()) {
2701- if (!is_port_space_allowed(world, get_fcoords(c))) {
2702+ if (!is_port_space_allowed(egbase, get_fcoords(c))) {
2703 clean_me_up.insert(c);
2704 }
2705 }
2706 for (const Coords& c : clean_me_up) {
2707- set_port_space(world, c, false);
2708+ set_port_space(egbase, c, false);
2709 }
2710 recalculate_allows_seafaring();
2711 }
2712
2713=== modified file 'src/logic/map.h'
2714--- src/logic/map.h 2019-06-25 08:03:30 +0000
2715+++ src/logic/map.h 2019-09-05 15:29:33 +0000
2716@@ -48,10 +48,10 @@
2717
2718 class MapLoader;
2719 class Objective;
2720-class World;
2721 struct BaseImmovable;
2722 struct MapGenerator;
2723 struct PathfieldManager;
2724+class World;
2725
2726 // Global list of available map dimensions.
2727 const std::vector<int32_t> kMapDimensions = {64, 80, 96, 112, 128, 144, 160, 176, 192, 208,
2728@@ -164,7 +164,7 @@
2729 void cleanup();
2730
2731 void create_empty_map // for editor
2732- (const World& world,
2733+ (const EditorGameBase&,
2734 uint32_t w = 64,
2735 uint32_t h = 64,
2736 const Widelands::DescriptionIndex default_terrain = 0,
2737@@ -172,8 +172,8 @@
2738 const std::string& author = pgettext("author_name", "Unknown"),
2739 const std::string& description = _("No description defined"));
2740
2741- void recalc_whole_map(const World& world);
2742- void recalc_for_field_area(const World& world, Area<FCoords>);
2743+ void recalc_whole_map(const EditorGameBase&);
2744+ void recalc_for_field_area(const EditorGameBase&, Area<FCoords>);
2745
2746 /**
2747 * If the valuable fields are empty, calculates all fields that could be conquered by a player
2748@@ -199,7 +199,7 @@
2749 /***
2750 * Ensures that resources match their adjacent terrains.
2751 */
2752- void ensure_resource_consistency(const World& world);
2753+ void ensure_resource_consistency(const World&);
2754
2755 /***
2756 * Recalculates all default resources.
2757@@ -208,7 +208,7 @@
2758 * the editor. Since there, default resources
2759 * are not shown.
2760 */
2761- void recalc_default_resources(const World& world);
2762+ void recalc_default_resources(const World&);
2763
2764 void set_nrplayers(PlayerNumber);
2765
2766@@ -303,31 +303,31 @@
2767 void set_scenario_player_closeable(PlayerNumber, bool);
2768
2769 /// \returns the maximum theoretical possible nodecaps (no blocking bobs, immovables etc.)
2770- NodeCaps get_max_nodecaps(const World& world, const FCoords&) const;
2771+ NodeCaps get_max_nodecaps(const EditorGameBase&, const FCoords&) const;
2772
2773 BaseImmovable* get_immovable(const Coords&) const;
2774- uint32_t find_bobs(const Area<FCoords>,
2775+ uint32_t find_bobs(const EditorGameBase&, const Area<FCoords>,
2776 std::vector<Bob*>* list,
2777 const FindBob& functor = FindBobAlwaysTrue()) const;
2778- uint32_t find_reachable_bobs(const Area<FCoords>,
2779+ uint32_t find_reachable_bobs(const EditorGameBase&, const Area<FCoords>,
2780 std::vector<Bob*>* list,
2781 const CheckStep&,
2782 const FindBob& functor = FindBobAlwaysTrue()) const;
2783- uint32_t find_immovables(const Area<FCoords>,
2784+ uint32_t find_immovables(const EditorGameBase&, const Area<FCoords>,
2785 std::vector<ImmovableFound>* list,
2786 const FindImmovable& = find_immovable_always_true()) const;
2787- uint32_t find_reachable_immovables(const Area<FCoords>,
2788+ uint32_t find_reachable_immovables(const EditorGameBase&, const Area<FCoords>,
2789 std::vector<ImmovableFound>* list,
2790 const CheckStep&,
2791 const FindImmovable& = find_immovable_always_true()) const;
2792 uint32_t
2793- find_reachable_immovables_unique(const Area<FCoords>,
2794+ find_reachable_immovables_unique(const EditorGameBase&, const Area<FCoords>,
2795 std::vector<BaseImmovable*>& list,
2796 const CheckStep&,
2797 const FindImmovable& = find_immovable_always_true()) const;
2798 uint32_t
2799- find_fields(const Area<FCoords>, std::vector<Coords>* list, const FindNode& functor) const;
2800- uint32_t find_reachable_fields(const Area<FCoords>,
2801+ find_fields(const EditorGameBase&, const Area<FCoords>, std::vector<Coords>* list, const FindNode& functor) const;
2802+ uint32_t find_reachable_fields(const EditorGameBase&, const Area<FCoords>,
2803 std::vector<Coords>* list,
2804 const CheckStep&,
2805 const FindNode&) const;
2806@@ -410,10 +410,10 @@
2807 /// value, because it adjusts the heights of surrounding nodes in each call,
2808 /// so it will be terribly slow. Use set_height for Area for that purpose
2809 /// instead.
2810- uint32_t set_height(const World& world, FCoords, Field::Height);
2811+ uint32_t set_height(const EditorGameBase&, FCoords, Field::Height);
2812
2813 /// Changes the height of the nodes in an Area by a difference.
2814- uint32_t change_height(const World& world, Area<FCoords>, int16_t difference);
2815+ uint32_t change_height(const EditorGameBase&, Area<FCoords>, int16_t difference);
2816
2817 /// Initializes the 'initial_resources' on 'coords' to the 'resource_type'
2818 /// with the given 'amount'.
2819@@ -442,7 +442,7 @@
2820 * the area, because this adjusts the surrounding nodes only once, after all
2821 * nodes in the area had their new height set.
2822 */
2823- uint32_t set_height(const World& world, Area<FCoords>, HeightInterval height_interval);
2824+ uint32_t set_height(const EditorGameBase&, Area<FCoords>, HeightInterval height_interval);
2825
2826 /***
2827 * Changes the given triangle's terrain. This happens in the editor and might
2828@@ -452,14 +452,14 @@
2829 *
2830 * @return the radius of changes.
2831 */
2832- int32_t change_terrain(const World& world, TCoords<FCoords>, DescriptionIndex);
2833+ int32_t change_terrain(const EditorGameBase&, TCoords<FCoords>, DescriptionIndex);
2834
2835 /***
2836 * Verify if a resource attached to a vertex has enough adjacent matching terrains to be valid.
2837 *
2838 * To qualify as valid, resources need to be surrounded by at least two matching terrains.
2839 */
2840- bool is_resource_valid(const Widelands::World& world,
2841+ bool is_resource_valid(const Widelands::World&,
2842 const Widelands::FCoords& c,
2843 DescriptionIndex curres) const;
2844
2845@@ -485,13 +485,13 @@
2846
2847 /// Checks whether the maximum theoretical possible NodeCap of the field is big,
2848 /// and there is room for a port space
2849- bool is_port_space_allowed(const World& world, const FCoords& fc) const;
2850+ bool is_port_space_allowed(const EditorGameBase&, const FCoords& fc) const;
2851 bool is_port_space(const Coords& c) const;
2852
2853 /// If 'set', set the space at 'c' as port space, otherwise unset.
2854 /// 'force' sets the port space even if it isn't viable, and is to be used for map loading only.
2855 /// Returns whether the port space was set/unset successfully.
2856- bool set_port_space(const World& world,
2857+ bool set_port_space(const EditorGameBase&,
2858 const Widelands::Coords& c,
2859 bool set,
2860 bool force = false,
2861@@ -508,7 +508,7 @@
2862 void recalculate_allows_seafaring();
2863 /// Remove all port spaces that are not valid (Buildcap < big or not enough space for a
2864 /// portdock).
2865- void cleanup_port_spaces(const World& world);
2866+ void cleanup_port_spaces(const EditorGameBase&);
2867
2868 /// Checks whether there are any artifacts on the map
2869 bool has_artifacts();
2870@@ -529,16 +529,16 @@
2871 private:
2872 void recalc_border(const FCoords&);
2873 void recalc_brightness(const FCoords&);
2874- void recalc_nodecaps_pass1(const World& world, const FCoords&);
2875- void recalc_nodecaps_pass2(const World& world, const FCoords& f);
2876+ void recalc_nodecaps_pass1(const EditorGameBase&, const FCoords&);
2877+ void recalc_nodecaps_pass2(const EditorGameBase&, const FCoords& f);
2878 NodeCaps
2879- calc_nodecaps_pass1(const World& world, const FCoords&, bool consider_mobs = true) const;
2880- NodeCaps calc_nodecaps_pass2(const World& world,
2881+ calc_nodecaps_pass1(const EditorGameBase&, const FCoords&, bool consider_mobs = true) const;
2882+ NodeCaps calc_nodecaps_pass2(const EditorGameBase&,
2883 const FCoords&,
2884 bool consider_mobs = true,
2885 NodeCaps initcaps = CAPS_NONE) const;
2886 void check_neighbour_heights(FCoords, uint32_t& radius);
2887- int calc_buildsize(const World& world,
2888+ int calc_buildsize(const EditorGameBase&,
2889 const FCoords& f,
2890 bool avoidnature,
2891 bool* ismine = nullptr,
2892@@ -546,8 +546,8 @@
2893 NodeCaps initcaps = CAPS_NONE) const;
2894 bool is_cycle_connected(const FCoords& start, uint32_t length, const WalkingDir* dirs) const;
2895 template <typename functorT>
2896- void find_reachable(const Area<FCoords>&, const CheckStep&, functorT&) const;
2897- template <typename functorT> void find(const Area<FCoords>&, functorT&) const;
2898+ void find_reachable(const EditorGameBase&, const Area<FCoords>&, const CheckStep&, functorT&) const;
2899+ template <typename functorT> void find(const EditorGameBase&, const Area<FCoords>&, functorT&) const;
2900
2901 /// # of players this map supports (!= Game's number of players!)
2902 PlayerNumber nrplayers_;
2903
2904=== modified file 'src/logic/map_objects/bob.cc'
2905--- src/logic/map_objects/bob.cc 2019-05-11 13:48:12 +0000
2906+++ src/logic/map_objects/bob.cc 2019-09-05 15:29:33 +0000
2907@@ -638,7 +638,7 @@
2908 // Using probability of 1/8 and pausing it for 5, 10 or 15 seconds
2909 if (game.logic_rand() % 8 == 0) {
2910 if (is_a(Ship, this)) {
2911- const uint32_t ships_count = game.map().find_bobs(
2912+ const uint32_t ships_count = game.map().find_bobs(game,
2913 Widelands::Area<Widelands::FCoords>(get_position(), 0), nullptr, FindBobShip());
2914 assert(ships_count > 0);
2915 if (ships_count > 1) {
2916@@ -825,7 +825,7 @@
2917 bool Bob::check_node_blocked(Game& game, const FCoords& field, bool) {
2918 // Battles always block movement!
2919 std::vector<Bob*> soldiers;
2920- game.map().find_bobs(Area<FCoords>(field, 0), &soldiers, FindBobEnemySoldier(get_owner()));
2921+ game.map().find_bobs(game, Area<FCoords>(field, 0), &soldiers, FindBobEnemySoldier(get_owner()));
2922
2923 if (!soldiers.empty()) {
2924 for (Bob* temp_bob : soldiers) {
2925
2926=== modified file 'src/logic/map_objects/findnode.cc'
2927--- src/logic/map_objects/findnode.cc 2019-02-27 19:00:36 +0000
2928+++ src/logic/map_objects/findnode.cc 2019-09-05 15:29:33 +0000
2929@@ -20,9 +20,12 @@
2930 #include "logic/map_objects/findnode.h"
2931
2932 #include "base/wexception.h"
2933+#include "logic/editor_game_base.h"
2934 #include "logic/field.h"
2935 #include "logic/map.h"
2936 #include "logic/map_objects/immovable.h"
2937+#include "logic/map_objects/world/terrain_description.h"
2938+#include "logic/map_objects/world/world.h"
2939
2940 namespace Widelands {
2941
2942@@ -34,16 +37,16 @@
2943 subfunctors.push_back(Subfunctor(findfield, negate));
2944 }
2945
2946-bool FindNodeAnd::accept(const Map& map, const FCoords& coord) const {
2947+bool FindNodeAnd::accept(const EditorGameBase& egbase, const FCoords& coord) const {
2948 for (const Subfunctor& subfunctor : subfunctors) {
2949- if (subfunctor.findfield.accept(map, coord) == subfunctor.negate) {
2950+ if (subfunctor.findfield.accept(egbase, coord) == subfunctor.negate) {
2951 return false;
2952 }
2953 }
2954 return true;
2955 }
2956
2957-bool FindNodeCaps::accept(const Map&, const FCoords& coord) const {
2958+bool FindNodeCaps::accept(const EditorGameBase&, const FCoords& coord) const {
2959 NodeCaps nodecaps = coord.field->nodecaps();
2960
2961 if ((nodecaps & BUILDCAPS_SIZEMASK) < (mincaps & BUILDCAPS_SIZEMASK))
2962@@ -55,11 +58,12 @@
2963 return true;
2964 }
2965
2966-bool FindNodeSize::accept(const Map&, const FCoords& coord) const {
2967+bool FindNodeSize::accept(const EditorGameBase& egbase, const FCoords& coord) const {
2968 if (BaseImmovable const* const immovable = coord.field->get_immovable())
2969 if (immovable->get_size() > BaseImmovable::NONE)
2970 return false;
2971 NodeCaps const nodecaps = coord.field->nodecaps();
2972+ const Map& map = egbase.map();
2973
2974 switch (size) {
2975 case sizeBuild:
2976@@ -74,13 +78,26 @@
2977 return (nodecaps & BUILDCAPS_SIZEMASK) >= BUILDCAPS_MEDIUM;
2978 case sizeBig:
2979 return (nodecaps & BUILDCAPS_SIZEMASK) >= BUILDCAPS_BIG;
2980+ case sizeSwim:
2981+ return map.can_reach_by_water(coord);
2982 case sizeAny:
2983 return true;
2984 }
2985 NEVER_HERE();
2986 }
2987
2988-bool FindNodeImmovableSize::accept(const Map&, const FCoords& coord) const {
2989+bool FindNodeTerraform::accept(const EditorGameBase& egbase, const FCoords& coord) const {
2990+ const Map& map = egbase.map();
2991+ const World& world = egbase.world();
2992+ return !(world.terrain_descr(coord.field->terrain_d()).enhancement().empty() &&
2993+ world.terrain_descr(coord.field->terrain_r()).enhancement().empty() &&
2994+ world.terrain_descr(map.tl_n(coord).field->terrain_d()).enhancement().empty() &&
2995+ world.terrain_descr(map.tl_n(coord).field->terrain_r()).enhancement().empty() &&
2996+ world.terrain_descr(map.tr_n(coord).field->terrain_d()).enhancement().empty() &&
2997+ world.terrain_descr(map.l_n(coord).field->terrain_r()).enhancement().empty());
2998+}
2999+
3000+bool FindNodeImmovableSize::accept(const EditorGameBase&, const FCoords& coord) const {
3001 int32_t size = BaseImmovable::NONE;
3002
3003 if (BaseImmovable* const imm = coord.field->get_immovable())
3004@@ -100,17 +117,17 @@
3005 }
3006 }
3007
3008-bool FindNodeImmovableAttribute::accept(const Map&, const FCoords& coord) const {
3009+bool FindNodeImmovableAttribute::accept(const EditorGameBase&, const FCoords& coord) const {
3010 if (BaseImmovable* const imm = coord.field->get_immovable())
3011 return imm->has_attribute(attribute);
3012 return false;
3013 }
3014
3015-bool FindNodeResource::accept(const Map&, const FCoords& coord) const {
3016+bool FindNodeResource::accept(const EditorGameBase&, const FCoords& coord) const {
3017 return resource == coord.field->get_resources() && coord.field->get_resources_amount();
3018 }
3019
3020-bool FindNodeResourceBreedable::accept(const Map& map, const FCoords& coord) const {
3021+bool FindNodeResourceBreedable::accept(const EditorGameBase& egbase, const FCoords& coord) const {
3022 // Accept a tile that is full only if a neighbor also matches resource and
3023 // is not full.
3024 if (resource != coord.field->get_resources()) {
3025@@ -131,7 +148,7 @@
3026 break;
3027 }
3028 for (Direction dir = FIRST_DIRECTION; dir <= LAST_DIRECTION; ++dir) {
3029- const FCoords neighb = map.get_neighbour(coord, dir);
3030+ const FCoords neighb = egbase.map().get_neighbour(coord, dir);
3031 if (resource == neighb.field->get_resources()) {
3032 switch (strictness) {
3033 case AnimalBreedable::kDefault:
3034@@ -150,7 +167,7 @@
3035 return false;
3036 }
3037
3038-bool FindNodeShore::accept(const Map& map, const FCoords& coords) const {
3039+bool FindNodeShore::accept(const EditorGameBase& egbase, const FCoords& coords) const {
3040 if (!(coords.field->nodecaps() & MOVECAPS_WALK))
3041 return false;
3042
3043@@ -169,7 +186,7 @@
3044
3045 // Now test all neighbours
3046 for (Direction dir = FIRST_DIRECTION; dir <= LAST_DIRECTION; ++dir) {
3047- FCoords neighb = map.get_neighbour(cur, dir);
3048+ FCoords neighb = egbase.map().get_neighbour(cur, dir);
3049 if (accepted_nodes.count(neighb.hash()) > 0 || rejected_nodes.count(neighb.hash()) > 0) {
3050 // We already processed this node
3051 continue;
3052
3053=== modified file 'src/logic/map_objects/findnode.h'
3054--- src/logic/map_objects/findnode.h 2019-02-27 19:00:36 +0000
3055+++ src/logic/map_objects/findnode.h 2019-09-05 15:29:33 +0000
3056@@ -30,8 +30,8 @@
3057
3058 enum class AnimalBreedable { kDefault, kAnimalFull };
3059
3060+class EditorGameBase;
3061 struct FCoords;
3062-class Map;
3063
3064 struct FindNode {
3065 private:
3066@@ -48,14 +48,14 @@
3067 if (--refcount == 0)
3068 delete this;
3069 }
3070- virtual bool accept(const Map&, const FCoords& coord) const = 0;
3071+ virtual bool accept(const EditorGameBase&, const FCoords& coord) const = 0;
3072
3073 int refcount;
3074 };
3075 template <typename T> struct Capsule : public BaseCapsule {
3076 explicit Capsule(const T& init_op) : op(init_op) {
3077 }
3078- bool accept(const Map& map, const FCoords& coord) const override {
3079+ bool accept(const EditorGameBase& map, const FCoords& coord) const override {
3080 return op.accept(map, coord);
3081 }
3082
3083@@ -85,7 +85,7 @@
3084 }
3085
3086 // Return true if this node should be returned by find_fields()
3087- bool accept(const Map& map, const FCoords& coord) const {
3088+ bool accept(const EditorGameBase& map, const FCoords& coord) const {
3089 return capsule->accept(map, coord);
3090 }
3091 };
3092@@ -94,7 +94,7 @@
3093 explicit FindNodeCaps(uint8_t init_mincaps) : mincaps(init_mincaps) {
3094 }
3095
3096- bool accept(const Map&, const FCoords&) const;
3097+ bool accept(const EditorGameBase&, const FCoords&) const;
3098
3099 private:
3100 uint8_t mincaps;
3101@@ -107,7 +107,7 @@
3102
3103 void add(const FindNode&, bool negate = false);
3104
3105- bool accept(const Map&, const FCoords&) const;
3106+ bool accept(const EditorGameBase&, const FCoords&) const;
3107
3108 private:
3109 struct Subfunctor {
3110@@ -130,12 +130,13 @@
3111 sizeBig,
3112 sizeMine, // can build a mine on this field
3113 sizePort, // can build a port on this field
3114+ sizeSwim // coast
3115 };
3116
3117 explicit FindNodeSize(Size init_size) : size(init_size) {
3118 }
3119
3120- bool accept(const Map&, const FCoords&) const;
3121+ bool accept(const EditorGameBase&, const FCoords&) const;
3122
3123 private:
3124 Size size;
3125@@ -148,7 +149,7 @@
3126 explicit FindNodeImmovableSize(uint32_t init_sizes) : sizes(init_sizes) {
3127 }
3128
3129- bool accept(const Map&, const FCoords&) const;
3130+ bool accept(const EditorGameBase&, const FCoords&) const;
3131
3132 private:
3133 uint32_t sizes;
3134@@ -159,7 +160,7 @@
3135 explicit FindNodeImmovableAttribute(uint32_t attrib) : attribute(attrib) {
3136 }
3137
3138- bool accept(const Map&, const FCoords&) const;
3139+ bool accept(const EditorGameBase&, const FCoords&) const;
3140
3141 private:
3142 uint32_t attribute;
3143@@ -170,7 +171,7 @@
3144 explicit FindNodeResource(DescriptionIndex res) : resource(res) {
3145 }
3146
3147- bool accept(const Map&, const FCoords&) const;
3148+ bool accept(const EditorGameBase&, const FCoords&) const;
3149
3150 private:
3151 DescriptionIndex resource;
3152@@ -184,20 +185,26 @@
3153 : resource(res), strictness(br) {
3154 }
3155
3156- bool accept(const Map&, const FCoords&) const;
3157+ bool accept(const EditorGameBase&, const FCoords&) const;
3158
3159 private:
3160 DescriptionIndex resource;
3161 AnimalBreedable strictness;
3162 };
3163
3164+/// Accepts a node where at least 1 adjacent triangle has enhancable terrain
3165+struct FindNodeTerraform {
3166+ FindNodeTerraform() = default;
3167+ bool accept(const EditorGameBase&, const FCoords&) const;
3168+};
3169+
3170 /// Accepts a node if it is a shore node in the sense that it is walkable
3171 /// and has at least one neighbouring field that is swimmable
3172 struct FindNodeShore {
3173 explicit FindNodeShore(uint16_t f = 1) : min_fields(f) {
3174 }
3175
3176- bool accept(const Map&, const FCoords&) const;
3177+ bool accept(const EditorGameBase&, const FCoords&) const;
3178
3179 private:
3180 // Minimal number of reachable swimmable fields. 1 is minimum for this to be considered "shore"
3181
3182=== modified file 'src/logic/map_objects/immovable.cc'
3183--- src/logic/map_objects/immovable.cc 2019-05-28 17:01:30 +0000
3184+++ src/logic/map_objects/immovable.cc 2019-09-05 15:29:33 +0000
3185@@ -107,7 +107,7 @@
3186 f.field->immovable = this;
3187
3188 if (get_size() >= SMALL) {
3189- map->recalc_for_field_area(egbase.world(), Area<FCoords>(f, 2));
3190+ map->recalc_for_field_area(egbase, Area<FCoords>(f, 2));
3191 }
3192 }
3193
3194@@ -133,7 +133,7 @@
3195 egbase.inform_players_about_immovable(f.field - &(*map)[0], nullptr);
3196
3197 if (get_size() >= SMALL) {
3198- map->recalc_for_field_area(egbase.world(), Area<FCoords>(f, 2));
3199+ map->recalc_for_field_area(egbase, Area<FCoords>(f, 2));
3200 }
3201 }
3202
3203
3204=== modified file 'src/logic/map_objects/tribes/building.cc'
3205--- src/logic/map_objects/tribes/building.cc 2019-06-25 08:03:30 +0000
3206+++ src/logic/map_objects/tribes/building.cc 2019-09-05 15:29:33 +0000
3207@@ -45,6 +45,7 @@
3208 #include "logic/map_objects/tribes/tribe_descr.h"
3209 #include "logic/map_objects/tribes/tribes.h"
3210 #include "logic/map_objects/tribes/worker.h"
3211+#include "logic/map_objects/world/world.h"
3212 #include "logic/player.h"
3213
3214 namespace Widelands {
3215@@ -107,6 +108,12 @@
3216 throw GameDataError("size: %s", e.what());
3217 }
3218 }
3219+ if (table.has_key("built_over_immovable")) {
3220+ // Throws an error if no matching immovable exists
3221+ built_over_immovable_ = get_attribute_id(table.get_string("built_over_immovable"), false);
3222+ } else {
3223+ built_over_immovable_ = INVALID_INDEX;
3224+ }
3225
3226 // Parse build options
3227 if (table.has_key("enhancement")) {
3228@@ -172,12 +179,51 @@
3229 Coords const pos,
3230 bool const construct,
3231 bool loading,
3232- Building::FormerBuildings const former_buildings) const {
3233+ FormerBuildings const former_buildings) const {
3234+ std::pair<DescriptionIndex, std::string> immovable = std::make_pair(INVALID_INDEX, "");
3235+ if (built_over_immovable_ != INVALID_INDEX) {
3236+ bool immovable_previously_found = false;
3237+ for (const auto& pair : former_buildings) {
3238+ if (!pair.second.empty()) {
3239+ const MapObjectDescr* d;
3240+ if (pair.second == "world") {
3241+ d = egbase.world().get_immovable_descr(pair.first);
3242+ } else if (pair.second == "tribe") {
3243+ d = egbase.tribes().get_immovable_descr(pair.first);
3244+ } else {
3245+ throw wexception("Invalid FormerBuildings type: %s", pair.second.c_str());
3246+ }
3247+ if (d->has_attribute(built_over_immovable_)) {
3248+ immovable_previously_found = true;
3249+ break;
3250+ }
3251+ }
3252+ }
3253+ if (!immovable_previously_found) {
3254+ // Must be done first, because the immovable will be gone the moment the building is placed
3255+ const FCoords f = egbase.map().get_fcoords(pos);
3256+ if (f.field->get_immovable() && f.field->get_immovable()->has_attribute(built_over_immovable_)) {
3257+ upcast(const ImmovableDescr, imm, &f.field->get_immovable()->descr());
3258+ assert(imm);
3259+ immovable = imm->owner_type() == MapObjectDescr::OwnerType::kWorld ?
3260+ std::make_pair(egbase.world().get_immovable_index(imm->name()), "world") :
3261+ std::make_pair(egbase.tribes().safe_immovable_index(imm->name()), "tribe");
3262+ } else {
3263+ throw wexception("Attempting to build %s at %dx%d – no immovable with required attribute %i found",
3264+ name().c_str(), pos.x, pos.y, built_over_immovable_);
3265+ }
3266+ }
3267+ }
3268+
3269 Building& b = construct ? create_constructionsite() : create_object();
3270 b.position_ = pos;
3271 b.set_owner(owner);
3272- for (DescriptionIndex idx : former_buildings) {
3273- b.old_buildings_.push_back(idx);
3274+ if (immovable.first != INVALID_INDEX) {
3275+ assert(!immovable.second.empty());
3276+ b.old_buildings_.push_back(immovable);
3277+ }
3278+ for (const auto& pair : former_buildings) {
3279+ b.old_buildings_.push_back(pair);
3280 }
3281 if (loading) {
3282 b.Building::init(egbase);
3283@@ -188,8 +234,10 @@
3284 }
3285
3286 bool BuildingDescr::suitability(const Map&, const FCoords& fc) const {
3287- return mine_ ? fc.field->nodecaps() & Widelands::BUILDCAPS_MINE :
3288- size_ <= (fc.field->nodecaps() & Widelands::BUILDCAPS_SIZEMASK);
3289+ return (mine_ ? fc.field->nodecaps() & Widelands::BUILDCAPS_MINE :
3290+ size_ <= (fc.field->nodecaps() & Widelands::BUILDCAPS_SIZEMASK)) &&
3291+ (built_over_immovable_ == INVALID_INDEX ||
3292+ (fc.field->get_immovable() && fc.field->get_immovable()->has_attribute(built_over_immovable_)));
3293 }
3294
3295 const BuildingHints& BuildingDescr::hints() const {
3296@@ -251,6 +299,7 @@
3297 leave_time_(0),
3298 defeating_player_(0),
3299 seeing_(false),
3300+ was_immovable_(nullptr),
3301 attack_target_(nullptr),
3302 soldier_control_(nullptr) {
3303 }
3304@@ -365,6 +414,21 @@
3305 flag->attach_building(egbase, *this);
3306 }
3307
3308+ for (const auto& pair : old_buildings_) {
3309+ if (!pair.second.empty()) {
3310+ assert(!was_immovable_);
3311+ if (pair.second == "world") {
3312+ was_immovable_ = egbase.world().get_immovable_descr(pair.first);
3313+ } else if (pair.second == "tribe") {
3314+ was_immovable_ = egbase.tribes().get_immovable_descr(pair.first);
3315+ } else {
3316+ throw wexception("Invalid FormerBuildings type: %s", pair.second.c_str());
3317+ }
3318+ assert(was_immovable_);
3319+ break;
3320+ }
3321+ }
3322+
3323 // Start the animation
3324 start_animation(egbase, descr().get_unoccupied_animation());
3325
3326@@ -610,6 +674,11 @@
3327 const Widelands::Coords& coords,
3328 const float scale,
3329 RenderTarget* dst) {
3330+ if (was_immovable_) {
3331+ dst->blit_animation(point_on_dst, coords, scale, was_immovable_->main_animation(),
3332+ gametime - animstart_, &get_owner()->get_playercolor());
3333+ }
3334+
3335 dst->blit_animation(
3336 point_on_dst, coords, scale, anim_, gametime - animstart_, &get_owner()->get_playercolor());
3337
3338
3339=== modified file 'src/logic/map_objects/tribes/building.h'
3340--- src/logic/map_objects/tribes/building.h 2019-06-23 11:41:17 +0000
3341+++ src/logic/map_objects/tribes/building.h 2019-09-05 15:29:33 +0000
3342@@ -56,13 +56,18 @@
3343 constexpr int32_t kPriorityNormal = 4;
3344 constexpr int32_t kPriorityHigh = 8;
3345
3346+/* The value "" means that the DescriptionIndex is a normal building, as happens e.g. when enhancing a building.
3347+ * The value "tribe"/"world" means that the DescriptionIndex refers to an immovable of
3348+ * OwnerType kTribe/kWorld, as happens e.g. with amazon treetop sentry. This immovable
3349+ * should therefore always be painted below the building image.
3350+ */
3351+using FormerBuildings = std::vector<std::pair<DescriptionIndex, std::string>>;
3352+
3353 /*
3354 * Common to all buildings!
3355 */
3356 class BuildingDescr : public MapObjectDescr {
3357 public:
3358- using FormerBuildings = std::vector<DescriptionIndex>;
3359-
3360 BuildingDescr(const std::string& init_descname,
3361 MapObjectType type,
3362 const LuaTable& t,
3363@@ -169,6 +174,10 @@
3364
3365 uint32_t get_unoccupied_animation() const;
3366
3367+ DescriptionIndex get_built_over_immovable() const {
3368+ return built_over_immovable_;
3369+ }
3370+
3371 protected:
3372 virtual Building& create_object() const = 0;
3373 Building& create_constructionsite() const;
3374@@ -191,6 +200,7 @@
3375 enhanced_from_; // The building this building was enhanced from, or INVALID_INDEX
3376 bool enhanced_building_; // if it is one, it is bulldozable
3377 BuildingHints hints_; // hints (knowledge) for computer players
3378+ DescriptionIndex built_over_immovable_; // can be built only on nodes where an immovable with this attribute stands
3379
3380 // for migration, 0 is the default, meaning get_conquers() + 4
3381 uint32_t vision_range_;
3382@@ -224,8 +234,6 @@
3383 PCap_Enhancable = 1 << 2, // can be enhanced to something
3384 };
3385
3386- using FormerBuildings = std::vector<DescriptionIndex>;
3387-
3388 public:
3389 enum class InfoStringFormat { kCensus, kStatistics, kTooltip };
3390
3391@@ -377,6 +385,7 @@
3392
3393 // The former buildings names, with the current one in last position.
3394 FormerBuildings old_buildings_;
3395+ const MapObjectDescr* was_immovable_;
3396
3397 private:
3398 std::string statistics_string_;
3399
3400=== modified file 'src/logic/map_objects/tribes/constructionsite.cc'
3401--- src/logic/map_objects/tribes/constructionsite.cc 2019-06-23 11:41:17 +0000
3402+++ src/logic/map_objects/tribes/constructionsite.cc 2019-09-05 15:29:33 +0000
3403@@ -39,6 +39,7 @@
3404 #include "logic/map_objects/tribes/trainingsite.h"
3405 #include "logic/map_objects/tribes/tribe_descr.h"
3406 #include "logic/map_objects/tribes/worker.h"
3407+#include "logic/map_objects/world/world.h"
3408 #include "sound/note_sound.h"
3409 #include "sound/sound_handler.h"
3410 #include "ui_basic/window.h"
3411@@ -196,16 +197,23 @@
3412 NoteSound(SoundType::kAmbient, descr().creation_fx(), position_, kFxPriorityAlwaysPlay));
3413 PartiallyFinishedBuilding::init(egbase);
3414
3415- const std::map<DescriptionIndex, uint8_t>* buildcost;
3416+ const std::map<DescriptionIndex, uint8_t>* buildcost = nullptr;
3417 if (!old_buildings_.empty()) {
3418- // Enhancement
3419- DescriptionIndex was_index = old_buildings_.back();
3420- const BuildingDescr* was_descr = owner().tribe().get_building_descr(was_index);
3421- info_.was = was_descr;
3422- buildcost = &building_->enhancement_cost();
3423- } else {
3424+ // Enhancement and/or built over immovable
3425+ for (auto it = old_buildings_.end(); it != old_buildings_.begin();) {
3426+ --it;
3427+ if (it->second.empty()) {
3428+ const BuildingDescr* was_descr = owner().tribe().get_building_descr(it->first);
3429+ info_.was = was_descr;
3430+ buildcost = &building_->enhancement_cost();
3431+ break;
3432+ }
3433+ }
3434+ }
3435+ if (!buildcost) {
3436 buildcost = &building_->buildcost();
3437 }
3438+ assert(buildcost);
3439
3440 // TODO(unknown): figure out whether planing is necessary
3441
3442@@ -263,7 +271,7 @@
3443 if (work_steps_ <= work_completed_) {
3444 // Put the real building in place
3445 DescriptionIndex becomes_idx = owner().tribe().building_index(building_->name());
3446- old_buildings_.push_back(becomes_idx);
3447+ old_buildings_.push_back(std::make_pair(becomes_idx, ""));
3448 Building& b = building_->create(egbase, get_owner(), position_, false, false, old_buildings_);
3449 if (Worker* const builder = builder_.get(egbase)) {
3450 builder->reset_tasks(dynamic_cast<Game&>(egbase));
3451@@ -330,7 +338,7 @@
3452 Notifications::publish(NoteImmovable(this, NoteImmovable::Ownership::LOST));
3453
3454 info_.intermediates.push_back(building_);
3455- old_buildings_.push_back(owner().tribe().building_index(building_->name()));
3456+ old_buildings_.push_back(std::make_pair(owner().tribe().building_index(building_->name()), ""));
3457 building_ = owner().tribe().get_building_descr(building_->enhancement());
3458 assert(building_);
3459 info_.becomes = building_;
3460@@ -609,9 +617,13 @@
3461 float scale,
3462 RenderTarget* dst) {
3463 uint32_t tanim = gametime - animstart_;
3464- // Draw the construction site marker
3465 const RGBColor& player_color = get_owner()->get_playercolor();
3466- dst->blit_animation(point_on_dst, Widelands::Coords::null(), scale, anim_, tanim, &player_color);
3467+ if (was_immovable_) {
3468+ dst->blit_animation(point_on_dst, coords, scale, was_immovable_->main_animation(), tanim, &player_color);
3469+ } else {
3470+ // Draw the construction site marker
3471+ dst->blit_animation(point_on_dst, Widelands::Coords::null(), scale, anim_, tanim, &player_color);
3472+ }
3473
3474 // Draw the partially finished building
3475
3476
3477=== modified file 'src/logic/map_objects/tribes/dismantlesite.cc'
3478--- src/logic/map_objects/tribes/dismantlesite.cc 2019-05-26 17:21:15 +0000
3479+++ src/logic/map_objects/tribes/dismantlesite.cc 2019-09-05 15:29:33 +0000
3480@@ -76,16 +76,16 @@
3481 const Coords& c,
3482 Player* plr,
3483 bool loading,
3484- Building::FormerBuildings& former_buildings)
3485+ FormerBuildings& former_buildings)
3486 : PartiallyFinishedBuilding(gdescr) {
3487 position_ = c;
3488 set_owner(plr);
3489
3490 assert(!former_buildings.empty());
3491- for (DescriptionIndex former_idx : former_buildings) {
3492- old_buildings_.push_back(former_idx);
3493+ for (const auto& pair : former_buildings) {
3494+ old_buildings_.push_back(pair);
3495 }
3496- const BuildingDescr* cur_descr = owner().tribe().get_building_descr(old_buildings_.back());
3497+ const BuildingDescr* cur_descr = owner().tribe().get_building_descr(old_buildings_.back().first);
3498 set_building(*cur_descr);
3499
3500 if (loading) {
3501@@ -95,6 +95,22 @@
3502 }
3503 }
3504
3505+void DismantleSite::cleanup(EditorGameBase& egbase) {
3506+ PartiallyFinishedBuilding::cleanup(egbase);
3507+
3508+ if (was_immovable_ && work_completed_ >= work_steps_) {
3509+ // Put the old immovable in place again
3510+ for (const auto& pair : old_buildings_) {
3511+ if (!pair.second.empty()) {
3512+ egbase.create_immovable(position_, pair.first,
3513+ pair.second == "world" ? MapObjectDescr::OwnerType::kWorld :
3514+ MapObjectDescr::OwnerType::kTribe, get_owner());
3515+ break;
3516+ }
3517+ }
3518+ }
3519+}
3520+
3521 /*
3522 ===============
3523 Print completion percentage.
3524@@ -133,9 +149,17 @@
3525 */
3526 const Buildcost DismantleSite::count_returned_wares(Building* building) {
3527 Buildcost result;
3528- for (DescriptionIndex former_idx : building->get_former_buildings()) {
3529- const BuildingDescr* former_descr = building->owner().tribe().get_building_descr(former_idx);
3530- const Buildcost& return_wares = former_idx != building->get_former_buildings().front() ?
3531+ DescriptionIndex first_idx = INVALID_INDEX;
3532+ for (const auto& pair : building->get_former_buildings()) {
3533+ if (pair.second.empty()) {
3534+ first_idx = pair.first;
3535+ break;
3536+ }
3537+ }
3538+ assert(first_idx != INVALID_INDEX);
3539+ for (const auto& pair : building->get_former_buildings()) {
3540+ const BuildingDescr* former_descr = building->owner().tribe().get_building_descr(pair.first);
3541+ const Buildcost& return_wares = pair.first != first_idx ?
3542 former_descr->returned_wares_enhanced() :
3543 former_descr->returned_wares();
3544
3545@@ -236,8 +260,12 @@
3546 uint32_t tanim = gametime - animstart_;
3547 const RGBColor& player_color = get_owner()->get_playercolor();
3548
3549- // Draw the construction site marker
3550- dst->blit_animation(point_on_dst, Widelands::Coords::null(), scale, anim_, tanim, &player_color);
3551+ if (was_immovable_) {
3552+ dst->blit_animation(point_on_dst, coords, scale, was_immovable_->main_animation(), tanim, &player_color);
3553+ } else {
3554+ // Draw the construction site marker
3555+ dst->blit_animation(point_on_dst, Widelands::Coords::null(), scale, anim_, tanim, &player_color);
3556+ }
3557
3558 // Blit bottom part of the animation according to dismantle progress
3559 dst->blit_animation(point_on_dst, coords, scale, building_->get_unoccupied_animation(), tanim,
3560
3561=== modified file 'src/logic/map_objects/tribes/dismantlesite.h'
3562--- src/logic/map_objects/tribes/dismantlesite.h 2019-05-05 14:05:07 +0000
3563+++ src/logic/map_objects/tribes/dismantlesite.h 2019-09-05 15:29:33 +0000
3564@@ -73,7 +73,7 @@
3565 const Coords&,
3566 Player*,
3567 bool,
3568- Building::FormerBuildings& former_buildings);
3569+ FormerBuildings& former_buildings);
3570
3571 bool burn_on_destroy() override;
3572 bool init(EditorGameBase&) override;
3573@@ -85,6 +85,8 @@
3574 protected:
3575 void update_statistics_string(std::string*) override;
3576
3577+ void cleanup(EditorGameBase&) override;
3578+
3579 uint32_t build_step_time() const override {
3580 return DISMANTLESITE_STEP_TIME;
3581 }
3582
3583=== modified file 'src/logic/map_objects/tribes/militarysite.cc'
3584--- src/logic/map_objects/tribes/militarysite.cc 2019-06-23 11:41:17 +0000
3585+++ src/logic/map_objects/tribes/militarysite.cc 2019-09-05 15:29:33 +0000
3586@@ -162,7 +162,7 @@
3587 map.calc_distance(enemy.get_position(), military_site_->get_position()))
3588 return;
3589
3590- if (map.find_bobs(Area<FCoords>(map.get_fcoords(military_site_->base_flag().get_position()), 2),
3591+ if (map.find_bobs(game, Area<FCoords>(map.get_fcoords(military_site_->base_flag().get_position()), 2),
3592 nullptr, FindBobEnemySoldier(owner)))
3593 return;
3594
3595@@ -261,7 +261,7 @@
3596 // In fact we do not conquer it, but place a new building of same type at
3597 // the old location.
3598
3599- Building::FormerBuildings former_buildings = military_site_->old_buildings_;
3600+ FormerBuildings former_buildings = military_site_->old_buildings_;
3601
3602 // The enemy conquers the building
3603 // In fact we do not conquer it, but place a new building of same type at
3604@@ -844,7 +844,7 @@
3605
3606 // Search in a radius of 3 (needed for big militarysites)
3607 FCoords const fc = game.map().get_fcoords(get_position());
3608- game.map().find_immovables(Area<FCoords>(fc, 3), &immovables);
3609+ game.map().find_immovables(game, Area<FCoords>(fc, 3), &immovables);
3610
3611 for (uint32_t i = 0; i < immovables.size(); ++i)
3612 if (upcast(MilitarySite const, militarysite, immovables[i].object))
3613
3614=== modified file 'src/logic/map_objects/tribes/production_program.cc'
3615--- src/logic/map_objects/tribes/production_program.cc 2019-05-18 11:58:43 +0000
3616+++ src/logic/map_objects/tribes/production_program.cc 2019-09-05 15:29:33 +0000
3617@@ -1519,7 +1519,7 @@
3618 std::vector<ImmovableFound> immovables;
3619 CheckStepWalkOn cstep(MOVECAPS_WALK, true);
3620 Area<FCoords> area(map.get_fcoords(psite.base_flag().get_position()), radius);
3621- if (map.find_reachable_immovables(area, &immovables, cstep, FindImmovableByDescr(descr))) {
3622+ if (map.find_reachable_immovables(game, area, &immovables, cstep, FindImmovableByDescr(descr))) {
3623 state.objvar = immovables[0].object;
3624
3625 psite.working_positions_[psite.main_worker_].worker->update_task_buildingwork(game);
3626@@ -1532,7 +1532,7 @@
3627 // 10 is custom value to make sure the "water" is at least 10 nodes big
3628 fna.add(FindNodeShore(10));
3629 fna.add(FindNodeImmovableSize(FindNodeImmovableSize::sizeNone));
3630- if (map.find_reachable_fields(area, &fields, cstep, fna)) {
3631+ if (map.find_reachable_fields(game, area, &fields, cstep, fna)) {
3632 // Testing received fields to get one with less immovables nearby
3633 Coords best_coords = fields.back(); // Just to initialize it
3634 uint32_t best_score = std::numeric_limits<uint32_t>::max();
3635@@ -1542,7 +1542,7 @@
3636 // Counting immovables nearby
3637 std::vector<ImmovableFound> found_immovables;
3638 const uint32_t imm_count =
3639- map.find_immovables(Area<FCoords>(map.get_fcoords(coords), 2), &found_immovables);
3640+ map.find_immovables(game, Area<FCoords>(map.get_fcoords(coords), 2), &found_immovables);
3641 if (best_score > imm_count) {
3642 best_score = imm_count;
3643 best_coords = coords;
3644
3645=== modified file 'src/logic/map_objects/tribes/ship.cc'
3646--- src/logic/map_objects/tribes/ship.cc 2019-05-27 14:28:34 +0000
3647+++ src/logic/map_objects/tribes/ship.cc 2019-09-05 15:29:33 +0000
3648@@ -207,7 +207,7 @@
3649 FCoords position = get_position();
3650 Area<FCoords> area(position, 1);
3651 std::vector<Bob*> ships;
3652- game.map().find_bobs(area, &ships, FindBobShip());
3653+ game.map().find_bobs(game, area, &ships, FindBobShip());
3654
3655 for (std::vector<Bob*>::const_iterator it = ships.begin(); it != ships.end(); ++it) {
3656 if (*it == this)
3657@@ -406,7 +406,7 @@
3658
3659 // Check whether the maximum theoretical possible NodeCap of the field
3660 // is of the size big and whether it can theoretically be a port space
3661- if ((map->get_max_nodecaps(game.world(), fc) & BUILDCAPS_SIZEMASK) != BUILDCAPS_BIG ||
3662+ if ((map->get_max_nodecaps(game, fc) & BUILDCAPS_SIZEMASK) != BUILDCAPS_BIG ||
3663 map->find_portdock(fc).empty()) {
3664 continue;
3665 }
3666@@ -463,7 +463,7 @@
3667
3668 Area<FCoords> area(node, 0);
3669 std::vector<Bob*> ships;
3670- map.find_bobs(area, &ships, FindBobShip());
3671+ map.find_bobs(game, area, &ships, FindBobShip());
3672
3673 for (std::vector<Bob*>::const_iterator it = ships.begin(); it != ships.end(); ++it) {
3674 if (*it == this)
3675@@ -922,9 +922,9 @@
3676
3677 // Make sure that we have space to squeeze in a lumberjack
3678 std::vector<ImmovableFound> trees_rocks;
3679- game.map().find_immovables(Area<FCoords>(game.map().get_fcoords(c), 3), &trees_rocks,
3680+ game.map().find_immovables(game, Area<FCoords>(game.map().get_fcoords(c), 3), &trees_rocks,
3681 FindImmovableAttribute(MapObjectDescr::get_attribute_id("tree")));
3682- game.map().find_immovables(Area<FCoords>(game.map().get_fcoords(c), 3), &trees_rocks,
3683+ game.map().find_immovables(game, Area<FCoords>(game.map().get_fcoords(c), 3), &trees_rocks,
3684 FindImmovableAttribute(MapObjectDescr::get_attribute_id("rocks")));
3685 for (auto& immo : trees_rocks) {
3686 immo.object->remove(game);
3687
3688=== modified file 'src/logic/map_objects/tribes/soldier.cc'
3689--- src/logic/map_objects/tribes/soldier.cc 2019-05-27 14:25:47 +0000
3690+++ src/logic/map_objects/tribes/soldier.cc 2019-09-05 15:29:33 +0000
3691@@ -781,7 +781,7 @@
3692 struct FindNodeOwned {
3693 explicit FindNodeOwned(PlayerNumber owner) : owner_(owner) {
3694 }
3695- bool accept(const Map&, const FCoords& coords) const {
3696+ bool accept(const EditorGameBase&, const FCoords& coords) const {
3697 return (coords.field->get_owned_by() == owner_);
3698 }
3699
3700@@ -926,7 +926,7 @@
3701 std::vector<Coords> coords;
3702 uint32_t maxdist = descr().vision_range() * 2;
3703 Area<FCoords> area(map.get_fcoords(get_position()), maxdist);
3704- if (map.find_reachable_fields(area, &coords, CheckStepDefault(descr().movecaps()),
3705+ if (map.find_reachable_fields(game, area, &coords, CheckStepDefault(descr().movecaps()),
3706 FindNodeOwned(get_owner()->player_number()))) {
3707 // Found home land
3708 target = coords.front();
3709@@ -971,7 +971,7 @@
3710 }
3711 // Any enemy soldier at baseflag count as defender.
3712 std::vector<Bob*> soldiers;
3713- map.find_bobs(Area<FCoords>(map.get_fcoords(enemy->base_flag().get_position()), 0), &soldiers,
3714+ map.find_bobs(game, Area<FCoords>(map.get_fcoords(enemy->base_flag().get_position()), 0), &soldiers,
3715 FindBobEnemySoldier(get_owner()));
3716 defenders += soldiers.size();
3717 }
3718@@ -1172,7 +1172,7 @@
3719 // Check if any attacker is waiting us to fight
3720 std::vector<Bob*> soldiers;
3721 game.map().find_bobs(
3722- Area<FCoords>(get_position(), 0), &soldiers, FindBobEnemySoldier(get_owner()));
3723+ game, Area<FCoords>(get_position(), 0), &soldiers, FindBobEnemySoldier(get_owner()));
3724
3725 for (Bob* temp_bob : soldiers) {
3726 if (upcast(Soldier, temp_soldier, temp_bob)) {
3727@@ -1196,7 +1196,7 @@
3728
3729 // We are outside our building, get list of enemy soldiers attacking us
3730 std::vector<Bob*> soldiers;
3731- game.map().find_bobs(Area<FCoords>(get_position(), 10), &soldiers,
3732+ game.map().find_bobs(game, Area<FCoords>(get_position(), 10), &soldiers,
3733 FindBobSoldierAttackingPlayer(game, *get_owner()));
3734
3735 if (soldiers.empty() || (get_current_health() < get_retreat_health())) {
3736@@ -1643,7 +1643,7 @@
3737 void Soldier::send_space_signals(Game& game) {
3738 std::vector<Bob*> soldiers;
3739
3740- game.map().find_bobs(Area<FCoords>(get_position(), 1), &soldiers, FindBobSoldierOnBattlefield());
3741+ game.map().find_bobs(game, Area<FCoords>(get_position(), 1), &soldiers, FindBobSoldierOnBattlefield());
3742
3743 for (Bob* temp_soldier : soldiers) {
3744 if (upcast(Soldier, soldier, temp_soldier)) {
3745@@ -1659,7 +1659,7 @@
3746 // Let's collect all reachable attack_target sites in vicinity (militarysites mainly)
3747 std::vector<BaseImmovable*> attack_targets;
3748 game.map().find_reachable_immovables_unique(
3749- Area<FCoords>(get_position(), kMaxProtectionRadius), attack_targets,
3750+ game, Area<FCoords>(get_position(), kMaxProtectionRadius), attack_targets,
3751 CheckStepWalkOn(descr().movecaps(), false), FindImmovableAttackTarget());
3752
3753 for (BaseImmovable* temp_attack_target : attack_targets) {
3754
3755=== modified file 'src/logic/map_objects/tribes/warehouse.cc'
3756--- src/logic/map_objects/tribes/warehouse.cc 2019-06-23 11:41:17 +0000
3757+++ src/logic/map_objects/tribes/warehouse.cc 2019-09-05 15:29:33 +0000
3758@@ -86,7 +86,7 @@
3759 map.calc_distance(enemy.get_position(), warehouse_->get_position()))
3760 return;
3761
3762- if (map.find_bobs(Area<FCoords>(map.get_fcoords(warehouse_->base_flag().get_position()), 2),
3763+ if (map.find_bobs(game, Area<FCoords>(map.get_fcoords(warehouse_->base_flag().get_position()), 2),
3764 nullptr, FindBobEnemySoldier(owner)))
3765 return;
3766
3767
3768=== modified file 'src/logic/map_objects/tribes/worker.cc'
3769--- src/logic/map_objects/tribes/worker.cc 2019-05-28 17:01:30 +0000
3770+++ src/logic/map_objects/tribes/worker.cc 2019-09-05 15:29:33 +0000
3771@@ -346,10 +346,10 @@
3772 }
3773 std::vector<ImmovableFound> list;
3774 if (action.iparam2 < 0)
3775- map.find_reachable_immovables(area, &list, cstep);
3776+ map.find_reachable_immovables(game, area, &list, cstep);
3777 else
3778 map.find_reachable_immovables(
3779- area, &list, cstep, FindImmovableAttribute(action.iparam2));
3780+ game, area, &list, cstep, FindImmovableAttribute(action.iparam2));
3781
3782 for (int idx = list.size() - 1; idx >= 0; idx--) {
3783 if (upcast(Immovable, imm, list[idx].object)) {
3784@@ -377,9 +377,9 @@
3785 }
3786 std::vector<Bob*> list;
3787 if (action.iparam2 < 0)
3788- map.find_reachable_bobs(area, &list, cstep);
3789+ map.find_reachable_bobs(game, area, &list, cstep);
3790 else
3791- map.find_reachable_bobs(area, &list, cstep, FindBobAttribute(action.iparam2));
3792+ map.find_reachable_bobs(game, area, &list, cstep, FindBobAttribute(action.iparam2));
3793
3794 for (int idx = list.size() - 1; idx >= 0; idx--) {
3795 if (upcast(MapObject, bob, list[idx])) {
3796@@ -530,12 +530,12 @@
3797 explicit FindNodeSpace(BaseImmovable* const ignoreimm) : ignoreimmovable(ignoreimm) {
3798 }
3799
3800- bool accept(const Map& map, const FCoords& coords) const {
3801+ bool accept(const EditorGameBase& egbase, const FCoords& coords) const {
3802 if (!(coords.field->nodecaps() & MOVECAPS_WALK))
3803 return false;
3804
3805 for (uint8_t dir = FIRST_DIRECTION; dir <= LAST_DIRECTION; ++dir) {
3806- FCoords const neighb = map.get_neighbour(coords, dir);
3807+ FCoords const neighb = egbase.map().get_neighbour(coords, dir);
3808
3809 if (!(neighb.field->nodecaps() & MOVECAPS_WALK) &&
3810 neighb.field->get_immovable() != ignoreimmovable)
3811@@ -573,7 +573,10 @@
3812 if (action.iparam3)
3813 functor.add(FindNodeSpace(get_location(game)));
3814
3815- if (!map.find_reachable_fields(area, &list, cstep, functor)) {
3816+ if (action.iparam7)
3817+ functor.add(FindNodeTerraform());
3818+
3819+ if (!map.find_reachable_fields(game, area, &list, cstep, functor)) {
3820
3821 // This is default note "out of resources" sent to a player
3822 FailNotificationType fail_notification_type = FailNotificationType::kDefault;
3823@@ -593,7 +596,7 @@
3824 functorAnyFull.add(FindNodeSpace(get_location(game)));
3825
3826 // If there are fields full of fish, we change the type of notification
3827- if (map.find_reachable_fields(area, &list, cstep, functorAnyFull)) {
3828+ if (map.find_reachable_fields(game, area, &list, cstep, functorAnyFull)) {
3829 fail_notification_type = FailNotificationType::kFull;
3830 }
3831 }
3832@@ -920,6 +923,54 @@
3833 return true;
3834 }
3835
3836+bool Worker::run_terraform(Game& game, State& state, const Action&) {
3837+ const World& world = game.world();
3838+ std::map<TCoords<FCoords>, DescriptionIndex> triangles;
3839+ const FCoords f = get_position();
3840+ FCoords tln, ln, trn;
3841+ game.map().get_tln(f, &tln);
3842+ game.map().get_trn(f, &trn);
3843+ game.map().get_ln(f, &ln);
3844+
3845+ DescriptionIndex di = world.get_terrain_index(world.terrain_descr(f.field->terrain_r()).enhancement());
3846+ if (di != INVALID_INDEX) {
3847+ triangles.emplace(std::make_pair(TCoords<FCoords>(f, TriangleIndex::R), di));
3848+ }
3849+ di = world.get_terrain_index(world.terrain_descr(f.field->terrain_d()).enhancement());
3850+ if (di != INVALID_INDEX) {
3851+ triangles.emplace(std::make_pair(TCoords<FCoords>(f, TriangleIndex::D), di));
3852+ }
3853+ di = world.get_terrain_index(world.terrain_descr(tln.field->terrain_r()).enhancement());
3854+ if (di != INVALID_INDEX) {
3855+ triangles.emplace(std::make_pair(TCoords<FCoords>(tln, TriangleIndex::R), di));
3856+ }
3857+ di = world.get_terrain_index(world.terrain_descr(tln.field->terrain_d()).enhancement());
3858+ if (di != INVALID_INDEX) {
3859+ triangles.emplace(std::make_pair(TCoords<FCoords>(tln, TriangleIndex::D), di));
3860+ }
3861+ di = world.get_terrain_index(world.terrain_descr(ln.field->terrain_r()).enhancement());
3862+ if (di != INVALID_INDEX) {
3863+ triangles.emplace(std::make_pair(TCoords<FCoords>(ln, TriangleIndex::R), di));
3864+ }
3865+ di = world.get_terrain_index(world.terrain_descr(trn.field->terrain_d()).enhancement());
3866+ if (di != INVALID_INDEX) {
3867+ triangles.emplace(std::make_pair(TCoords<FCoords>(trn, TriangleIndex::D), di));
3868+ }
3869+
3870+ if (triangles.empty()) {
3871+ send_signal(game, "fail");
3872+ pop_task(game);
3873+ return false;
3874+ }
3875+ assert(game.mutable_map());
3876+ auto it = triangles.begin();
3877+ for (size_t rand = game.logic_rand() % triangles.size(); rand > 0; --rand) ++it;
3878+ game.mutable_map()->change_terrain(game, it->first, it->second);
3879+ ++state.ivar1;
3880+ schedule_act(game, 10);
3881+ return true;
3882+}
3883+
3884 /**
3885 * Simply remove the currently selected object - make no fuss about it.
3886 */
3887@@ -2462,7 +2513,7 @@
3888 std::vector<ImmovableFound> flags;
3889 uint32_t vision = descr().vision_range();
3890 uint32_t maxdist = 4 * vision;
3891- if (map.find_immovables(Area<FCoords>(map.get_fcoords(get_position()), maxdist), &flags,
3892+ if (map.find_immovables(game, Area<FCoords>(map.get_fcoords(get_position()), maxdist), &flags,
3893 FindFlagWithPlayersWarehouse(*get_owner()))) {
3894 uint32_t bestdist = 0;
3895 Flag* best = nullptr;
3896@@ -2576,7 +2627,7 @@
3897 ffa.add(FindNodeImmovableSize(FindNodeImmovableSize::sizeNone), false);
3898 ffa.add(FindNodeImmovableAttribute(RESI), true);
3899
3900- if (map.find_reachable_fields(owner_area, &list, cstep, ffa)) {
3901+ if (map.find_reachable_fields(game, owner_area, &list, cstep, ffa)) {
3902 FCoords target;
3903
3904 // is center a mountain piece?
3905@@ -2840,7 +2891,7 @@
3906 std::vector<ImmovableFound> found_sites;
3907 CheckStepWalkOn csteb(MOVECAPS_WALK, true);
3908 map.find_reachable_immovables(
3909- revealations, &found_sites, csteb, FindFlagOf(FindForeignMilitarysite(player)));
3910+ game, revealations, &found_sites, csteb, FindFlagOf(FindForeignMilitarysite(player)));
3911
3912 add_sites(game, map, player, found_sites);
3913
3914@@ -2868,7 +2919,7 @@
3915 Time oldest_time = game.get_gametime();
3916
3917 // if some fields can be reached
3918- if (map.find_reachable_fields(exploring_area, &list, cstep, ffa) > 0) {
3919+ if (map.find_reachable_fields(game, exploring_area, &list, cstep, ffa) > 0) {
3920 // Parse randomly the reachable fields, maximum 50 iterations
3921 uint8_t iterations = list.size() % 51;
3922 uint8_t oldest_distance = 0;
3923@@ -2942,7 +2993,7 @@
3924 // would fail. Therefore, the looping can be a bit silly to more knowledgeable readers.
3925 for (unsigned vicinity = 1; vicinity < 4; vicinity++) {
3926 Area<FCoords> exploring_area(map.get_fcoords(scoutat.scoutme), vicinity);
3927- if (map.find_reachable_fields(exploring_area, &surrounding_places, cstep, fna) > 0) {
3928+ if (map.find_reachable_fields(game, exploring_area, &surrounding_places, cstep, fna) > 0) {
3929 unsigned formax = surrounding_places.size();
3930 if (3 + vicinity < formax) {
3931 formax = 3 + vicinity;
3932
3933=== modified file 'src/logic/map_objects/tribes/worker.h'
3934--- src/logic/map_objects/tribes/worker.h 2019-04-24 06:01:37 +0000
3935+++ src/logic/map_objects/tribes/worker.h 2019-09-05 15:29:33 +0000
3936@@ -67,6 +67,7 @@
3937 int32_t iparam4;
3938 int32_t iparam5;
3939 int32_t iparam6;
3940+ int32_t iparam7;
3941 std::string sparam1;
3942
3943 std::vector<std::string> sparamv;
3944@@ -256,6 +257,7 @@
3945 bool run_scout(Game&, State&, const Action&);
3946 bool run_playsound(Game&, State&, const Action&);
3947 bool run_construct(Game&, State&, const Action&);
3948+ bool run_terraform(Game&, State&, const Action&);
3949
3950 // Forester considers multiple spaces in findspace, unlike others.
3951 int16_t findspace_helper_for_forester(const Coords& pos, const Map& map, Game& game);
3952
3953=== modified file 'src/logic/map_objects/tribes/worker_program.cc'
3954--- src/logic/map_objects/tribes/worker_program.cc 2019-05-11 13:48:12 +0000
3955+++ src/logic/map_objects/tribes/worker_program.cc 2019-09-05 15:29:33 +0000
3956@@ -75,6 +75,7 @@
3957 - `scout`_
3958 - `playsound`_
3959 - `construct`_
3960+- `terraform`_
3961 */
3962
3963 const WorkerProgram::ParseMap WorkerProgram::parsemap_[] = {
3964@@ -95,6 +96,7 @@
3965 {"scout", &WorkerProgram::parse_scout},
3966 {"playsound", &WorkerProgram::parse_playsound},
3967 {"construct", &WorkerProgram::parse_construct},
3968+ {"terraform", &WorkerProgram::parse_terraform},
3969
3970 {nullptr, nullptr}};
3971
3972@@ -334,7 +336,7 @@
3973 findspace
3974 ^^^^^^^^^
3975 .. function:: findspace=size:\<plot\> radius:\<distance\> [breed] [resource:\<name\>]
3976- [avoid:\<immovable_attribute\>] [saplingsearches:\<number\>] [space]
3977+ [avoid:\<immovable_attribute\>] [saplingsearches:\<number\>] [space] [terraform]
3978
3979 :arg string size: The size or building plot type of the free space.
3980 The possible values are:
3981@@ -346,6 +348,7 @@
3982 * ``big``: Big building plots only.
3983 * ``mine``: Mining plots only.
3984 * ``port``: Port spaces only.
3985+ * ``swim``: Anything on the coast.
3986
3987 :arg int radius: Search for map fields within the given radius around the worker.
3988
3989@@ -365,6 +368,8 @@
3990 neighbors are also walkable (an exception is made if one of the neighboring
3991 fields is owned by this worker's location).
3992
3993+ :arg empty terraform: Find only nodes where at least one adjacent triangle has terrain that can be enhanced
3994+
3995 Find a map field based on a number of predicates.
3996 The field can then be used in other commands like ``walk``. Examples::
3997
3998@@ -405,6 +410,7 @@
3999 * iparam4 = whether the "breed" flag is set
4000 * iparam5 = Immovable attribute id
4001 * iparam6 = Forester retries
4002+ * iparam7 = whether the "terraform" flag is set
4003 * sparam1 = Resource
4004 */
4005 void WorkerProgram::parse_findspace(Worker::Action* act, const std::vector<std::string>& cmd) {
4006@@ -417,6 +423,7 @@
4007 act->iparam4 = 0;
4008 act->iparam5 = -1;
4009 act->iparam6 = 1;
4010+ act->iparam7 = 0;
4011 act->sparam1 = "";
4012
4013 // Parse predicates
4014@@ -439,7 +446,8 @@
4015 } sizenames[] = {{"any", FindNodeSize::sizeAny}, {"build", FindNodeSize::sizeBuild},
4016 {"small", FindNodeSize::sizeSmall}, {"medium", FindNodeSize::sizeMedium},
4017 {"big", FindNodeSize::sizeBig}, {"mine", FindNodeSize::sizeMine},
4018- {"port", FindNodeSize::sizePort}, {nullptr, 0}};
4019+ {"port", FindNodeSize::sizePort}, {"swim", FindNodeSize::sizeSwim},
4020+ {nullptr, 0}};
4021
4022 int32_t index;
4023
4024@@ -453,6 +461,8 @@
4025 act->iparam2 = sizenames[index].val;
4026 } else if (key == "breed") {
4027 act->iparam4 = 1;
4028+ } else if (key == "terraform") {
4029+ act->iparam7 = 1;
4030 } else if (key == "resource") {
4031 act->sparam1 = value;
4032 } else if (key == "space") {
4033@@ -761,6 +771,28 @@
4034 }
4035
4036 /* RST
4037+terraform
4038+^^^^^^^^^
4039+.. function:: terraform
4040+
4041+ Turns the terrain of one of the triangles around the current node into its enhancement terrain. Example::
4042+
4043+ terraform = {
4044+ "findspace=size:terraform radius:6",
4045+ "walk=coords",
4046+ "animate=dig 2000",
4047+ "terraform",
4048+ "return"
4049+ }
4050+*/
4051+void WorkerProgram::parse_terraform(Worker::Action* act, const std::vector<std::string>& cmd) {
4052+ if (cmd.size() > 1) {
4053+ throw wexception("terraform takes no arguments");
4054+ }
4055+ act->function = &Worker::run_terraform;
4056+}
4057+
4058+/* RST
4059 removeobject
4060 ^^^^^^^^^^^^
4061 .. function:: removeobject
4062
4063=== modified file 'src/logic/map_objects/tribes/worker_program.h'
4064--- src/logic/map_objects/tribes/worker_program.h 2019-02-23 11:00:49 +0000
4065+++ src/logic/map_objects/tribes/worker_program.h 2019-09-05 15:29:33 +0000
4066@@ -91,6 +91,7 @@
4067 void parse_scout(Worker::Action* act, const std::vector<std::string>& cmd);
4068 void parse_playsound(Worker::Action* act, const std::vector<std::string>& cmd);
4069 void parse_construct(Worker::Action* act, const std::vector<std::string>& cmd);
4070+ void parse_terraform(Worker::Action* act, const std::vector<std::string>& cmd);
4071
4072 const std::string name_;
4073 const WorkerDescr& worker_;
4074
4075=== modified file 'src/logic/map_objects/world/terrain_description.cc'
4076--- src/logic/map_objects/world/terrain_description.cc 2019-02-23 11:00:49 +0000
4077+++ src/logic/map_objects/world/terrain_description.cc 2019-09-05 15:29:33 +0000
4078@@ -113,6 +113,16 @@
4079 custom_tooltips_ = table.get_table("tooltips")->array_entries<std::string>();
4080 }
4081
4082+ if (table.has_key("enhancement")) {
4083+ enhancement_ = table.get_string("enhancement");
4084+ if (enhancement_ == name_) {
4085+ throw GameDataError("%s: a terrain cannot be enhanced to itself", name_.c_str());
4086+ }
4087+ // Other invalid terrains will be detected in World::postload
4088+ } else {
4089+ enhancement_ = "";
4090+ }
4091+
4092 if (!(0 < fertility_ && fertility_ < 1000)) {
4093 throw GameDataError("%s: fertility is not in (0, 1000).", name_.c_str());
4094 }
4095@@ -256,6 +266,10 @@
4096 return fertility_;
4097 }
4098
4099+const std::string& TerrainDescription::enhancement() const {
4100+ return enhancement_;
4101+}
4102+
4103 void TerrainDescription::set_minimap_color(const RGBColor& color) {
4104 for (int i = -128; i < 128; i++) {
4105 const int shade = 128 + i;
4106
4107=== modified file 'src/logic/map_objects/world/terrain_description.h'
4108--- src/logic/map_objects/world/terrain_description.h 2019-04-11 05:45:55 +0000
4109+++ src/logic/map_objects/world/terrain_description.h 2019-09-05 15:29:33 +0000
4110@@ -123,6 +123,9 @@
4111 /// Fertility, ranging from 0 to 1000.
4112 int fertility() const;
4113
4114+ // The terrain which certain workers can transform this terrain into.
4115+ const std::string& enhancement() const;
4116+
4117 /// Additional tooptip entries for the editor
4118 const std::vector<std::string>& custom_tooltips() const {
4119 return custom_tooltips_;
4120@@ -142,6 +145,7 @@
4121 int temperature_;
4122 int fertility_;
4123 int humidity_;
4124+ std::string enhancement_;
4125 std::vector<std::string> texture_paths_;
4126 std::vector<const Image*> textures_;
4127 RGBColor minimap_colors_[256];
4128
4129=== modified file 'src/logic/map_objects/world/world.cc'
4130--- src/logic/map_objects/world/world.cc 2019-02-23 11:00:49 +0000
4131+++ src/logic/map_objects/world/world.cc 2019-09-05 15:29:33 +0000
4132@@ -66,6 +66,18 @@
4133 }
4134 }
4135
4136+void World::postload() {
4137+ const size_t nr_t = get_nr_terrains();
4138+ for (size_t i = 0; i < nr_t; ++i) {
4139+ const TerrainDescription& t = terrain_descr(i);
4140+ if (!t.enhancement().empty()) {
4141+ if (!terrain_descr(t.enhancement())) {
4142+ throw GameDataError("Terrain %s: Unknown enhancement %s", t.name().c_str(), t.enhancement().c_str());
4143+ }
4144+ }
4145+ }
4146+}
4147+
4148 const DescriptionMaintainer<TerrainDescription>& World::terrains() const {
4149 return *terrains_;
4150 }
4151@@ -133,6 +145,14 @@
4152 return i != INVALID_INDEX ? terrains_->get_mutable(i) : nullptr;
4153 }
4154
4155+DescriptionIndex World::get_terrain_index(const std::string& name) const {
4156+ return terrains_->get_index(name);
4157+}
4158+
4159+DescriptionIndex World::get_nr_terrains() const {
4160+ return terrains_->size();
4161+}
4162+
4163 DescriptionIndex World::get_critter(char const* const l) const {
4164 return critters_->get_index(l);
4165 }
4166
4167=== modified file 'src/logic/map_objects/world/world.h'
4168--- src/logic/map_objects/world/world.h 2019-03-01 04:19:53 +0000
4169+++ src/logic/map_objects/world/world.h 2019-09-05 15:29:33 +0000
4170@@ -48,6 +48,8 @@
4171 const DescriptionMaintainer<TerrainDescription>& terrains() const;
4172 TerrainDescription& terrain_descr(DescriptionIndex i) const;
4173 const TerrainDescription* terrain_descr(const std::string& name) const;
4174+ DescriptionIndex get_terrain_index(const std::string& name) const;
4175+ DescriptionIndex get_nr_terrains() const;
4176
4177 const DescriptionMaintainer<CritterDescr>& critters() const;
4178 DescriptionIndex get_critter(char const* const l) const;
4179@@ -89,6 +91,7 @@
4180 // Load the graphics for the world. Animations are loaded on
4181 // demand.
4182 void load_graphics();
4183+ void postload();
4184
4185 private:
4186 std::unique_ptr<DescriptionMaintainer<CritterDescr>> critters_;
4187
4188=== modified file 'src/logic/player.cc'
4189--- src/logic/player.cc 2019-06-24 19:44:35 +0000
4190+++ src/logic/player.cc 2019-09-05 15:29:33 +0000
4191@@ -98,12 +98,12 @@
4192 */
4193 void find_former_buildings(const Tribes& tribes,
4194 const Widelands::DescriptionIndex bi,
4195- Widelands::Building::FormerBuildings* former_buildings) {
4196+ Widelands::FormerBuildings* former_buildings) {
4197 assert(former_buildings && former_buildings->empty());
4198- former_buildings->push_back(bi);
4199+ former_buildings->push_back(std::make_pair(bi, ""));
4200
4201 for (;;) {
4202- Widelands::DescriptionIndex oldest_idx = former_buildings->front();
4203+ Widelands::DescriptionIndex oldest_idx = former_buildings->front().first;
4204 const Widelands::BuildingDescr* oldest = tribes.get_building_descr(oldest_idx);
4205 if (!oldest->is_enhanced()) {
4206 break;
4207@@ -111,7 +111,7 @@
4208 for (DescriptionIndex i = 0; i < tribes.nrbuildings(); ++i) {
4209 const BuildingDescr* building_descr = tribes.get_building_descr(i);
4210 if (building_descr->enhancement() == oldest_idx) {
4211- former_buildings->insert(former_buildings->begin(), i);
4212+ former_buildings->insert(former_buildings->begin(), std::make_pair(i, ""));
4213 break;
4214 }
4215 }
4216@@ -534,9 +534,9 @@
4217 }
4218
4219 Building& Player::force_building(Coords const location,
4220- const BuildingDescr::FormerBuildings& former_buildings) {
4221+ const FormerBuildings& former_buildings) {
4222 const Map& map = egbase().map();
4223- DescriptionIndex idx = former_buildings.back();
4224+ DescriptionIndex idx = former_buildings.back().first;
4225 const BuildingDescr* descr = egbase().tribes().get_building_descr(idx);
4226 terraform_for_building(egbase(), player_number(), location, descr);
4227 FCoords flag_loc;
4228@@ -548,14 +548,14 @@
4229
4230 Building& Player::force_csite(Coords const location,
4231 DescriptionIndex b_idx,
4232- const BuildingDescr::FormerBuildings& former_buildings) {
4233+ const FormerBuildings& former_buildings) {
4234 EditorGameBase& eg = egbase();
4235 const Map& map = eg.map();
4236 const Tribes& tribes = eg.tribes();
4237 const PlayerNumber pn = player_number();
4238
4239 if (!former_buildings.empty()) {
4240- DescriptionIndex idx = former_buildings.back();
4241+ DescriptionIndex idx = former_buildings.back().first;
4242 const BuildingDescr* descr = tribes.get_building_descr(idx);
4243 terraform_for_building(eg, pn, location, descr);
4244 }
4245@@ -577,9 +577,7 @@
4246 Building* Player::build(Coords c,
4247 DescriptionIndex const idx,
4248 bool constructionsite,
4249- BuildingDescr::FormerBuildings& former_buildings) {
4250- int32_t buildcaps;
4251-
4252+ FormerBuildings& former_buildings) {
4253 // Validate building type
4254 if (!tribe().has_building(idx)) {
4255 return nullptr;
4256@@ -594,21 +592,46 @@
4257 // Validate build position
4258 const Map& map = egbase().map();
4259 map.normalize_coords(c);
4260- buildcaps = get_buildcaps(map.get_fcoords(c));
4261-
4262+ const FCoords fc = map.get_fcoords(c);
4263+ const FCoords brn = map.br_n(fc);
4264+ if (!fc.field->is_interior(player_number()) || !brn.field->is_interior(player_number())) {
4265+ return nullptr;
4266+ }
4267+ if (descr->get_size() >= BaseImmovable::BIG &&
4268+ !((map.l_n(fc).field->is_interior(player_number())) &&
4269+ (map.tr_n(fc).field->is_interior(player_number())) &&
4270+ (map.tl_n(fc).field->is_interior(player_number())))) {
4271+ return nullptr;
4272+ }
4273+
4274+ if (descr->get_built_over_immovable() != INVALID_INDEX &&
4275+ !(fc.field->get_immovable() &&
4276+ fc.field->get_immovable()->has_attribute(descr->get_built_over_immovable()))) {
4277+ return nullptr;
4278+ }
4279+
4280+ const NodeCaps buildcaps = descr->get_built_over_immovable() == INVALID_INDEX ?
4281+ get_buildcaps(fc) : map.get_max_nodecaps(egbase(), fc);
4282 if (descr->get_ismine()) {
4283- if (!(buildcaps & BUILDCAPS_MINE))
4284+ if (!(buildcaps & BUILDCAPS_MINE)) {
4285 return nullptr;
4286+ }
4287 } else {
4288- if ((buildcaps & BUILDCAPS_SIZEMASK) < descr->get_size() - BaseImmovable::SMALL + 1)
4289- return nullptr;
4290- if (descr->get_isport() && !(buildcaps & BUILDCAPS_PORT))
4291- return nullptr;
4292+ if ((buildcaps & BUILDCAPS_SIZEMASK) < descr->get_size() - BaseImmovable::SMALL + 1) {
4293+ return nullptr;
4294+ }
4295+ if (descr->get_isport() && !(buildcaps & BUILDCAPS_PORT)) {
4296+ return nullptr;
4297+ }
4298+ }
4299+ if (!(brn.field->get_immovable() && brn.field->get_immovable()->descr().type() == MapObjectType::FLAG) &&
4300+ !(get_buildcaps(brn) & BUILDCAPS_FLAG)) {
4301+ return nullptr;
4302 }
4303
4304- if (constructionsite)
4305+ if (constructionsite) {
4306 return &egbase().warp_constructionsite(c, player_number_, idx, false, former_buildings);
4307- else {
4308+ } else {
4309 return &descr->create(egbase(), this, c, false, false, former_buildings);
4310 }
4311 }
4312@@ -747,7 +770,7 @@
4313 if (building->get_owner() == this &&
4314 (index_of_new_building == INVALID_INDEX ||
4315 building->descr().enhancement() == index_of_new_building)) {
4316- Building::FormerBuildings former_buildings = building->get_former_buildings();
4317+ FormerBuildings former_buildings = building->get_former_buildings();
4318 const Coords position = building->get_position();
4319
4320 // Get workers and soldiers
4321@@ -925,7 +948,7 @@
4322 const Map& map = egbase().map();
4323 std::vector<BaseImmovable*> flags;
4324
4325- map.find_reachable_immovables_unique(Area<FCoords>(map.get_fcoords(flag.get_position()), 25),
4326+ map.find_reachable_immovables_unique(egbase(), Area<FCoords>(map.get_fcoords(flag.get_position()), 25),
4327 flags, CheckStepDefault(MOVECAPS_WALK),
4328 FindFlagOf(FindImmovablePlayerMilitarySite(*this)));
4329
4330
4331=== modified file 'src/logic/player.h'
4332--- src/logic/player.h 2019-05-25 10:47:18 +0000
4333+++ src/logic/player.h 2019-09-05 15:29:33 +0000
4334@@ -507,11 +507,11 @@
4335 Flag* build_flag(const Coords&); /// Build a flag if it is allowed.
4336 Road& force_road(const Path&);
4337 Road* build_road(const Path&); /// Build a road if it is allowed.
4338- Building& force_building(Coords, const Building::FormerBuildings&);
4339+ Building& force_building(Coords, const FormerBuildings&);
4340 Building& force_csite(Coords,
4341 DescriptionIndex,
4342- const Building::FormerBuildings& = Building::FormerBuildings());
4343- Building* build(Coords, DescriptionIndex, bool, Building::FormerBuildings&);
4344+ const FormerBuildings& = FormerBuildings());
4345+ Building* build(Coords, DescriptionIndex, bool, FormerBuildings&);
4346 void bulldoze(PlayerImmovable&, bool recurse = false);
4347 void flagaction(Flag&);
4348 void start_stop_building(PlayerImmovable&);
4349@@ -698,7 +698,7 @@
4350
4351 void find_former_buildings(const Tribes& tribes,
4352 const DescriptionIndex bi,
4353- Building::FormerBuildings* former_buildings);
4354+ FormerBuildings* former_buildings);
4355 } // namespace Widelands
4356
4357 #endif // end of include guard: WL_LOGIC_PLAYER_H
4358
4359=== modified file 'src/logic/playercommand.cc'
4360--- src/logic/playercommand.cc 2019-07-27 12:58:07 +0000
4361+++ src/logic/playercommand.cc 2019-09-05 15:29:33 +0000
4362@@ -242,7 +242,7 @@
4363
4364 void CmdBuild::execute(Game& game) {
4365 // Empty former vector since its a new csite.
4366- Building::FormerBuildings former_buildings;
4367+ FormerBuildings former_buildings;
4368 game.get_player(sender())->build(coords, bi, true, former_buildings);
4369 }
4370
4371
4372=== modified file 'src/map_io/map_bob_packet.cc'
4373--- src/map_io/map_bob_packet.cc 2019-06-23 10:30:26 +0000
4374+++ src/map_io/map_bob_packet.cc 2019-09-05 15:29:33 +0000
4375@@ -77,7 +77,7 @@
4376 fr.open(fs, "binary/bob");
4377
4378 Map* map = egbase.mutable_map();
4379- map->recalc_whole_map(egbase.world()); // for movecaps checks in ReadBob
4380+ map->recalc_whole_map(egbase); // for movecaps checks in ReadBob
4381 try {
4382 uint16_t const packet_version = fr.unsigned_16();
4383 if (packet_version == kCurrentPacketVersion)
4384
4385=== modified file 'src/map_io/map_building_packet.cc'
4386--- src/map_io/map_building_packet.cc 2019-02-23 11:00:49 +0000
4387+++ src/map_io/map_building_packet.cc 2019-09-05 15:29:33 +0000
4388@@ -90,7 +90,7 @@
4389 if (building_type == kTypeConstructionSite) {
4390 building = &egbase.warp_constructionsite(c, p, index, true);
4391 } else if (building_type == kTypeDismantleSite) {
4392- Building::FormerBuildings formers = {index};
4393+ FormerBuildings formers = {{index, ""}};
4394 building = &egbase.warp_dismantlesite(c, p, true, formers);
4395 } else {
4396 building = &egbase.warp_building(c, p, index);
4397
4398=== modified file 'src/map_io/map_buildingdata_packet.cc'
4399--- src/map_io/map_buildingdata_packet.cc 2019-06-23 11:41:17 +0000
4400+++ src/map_io/map_buildingdata_packet.cc 2019-09-05 15:29:33 +0000
4401@@ -56,7 +56,7 @@
4402 namespace Widelands {
4403
4404 // Overall package version
4405-constexpr uint16_t kCurrentPacketVersion = 4;
4406+constexpr uint16_t kCurrentPacketVersion = 5;
4407
4408 // Building type package versions
4409 constexpr uint16_t kCurrentPacketVersionDismantlesite = 1;
4410@@ -85,7 +85,7 @@
4411
4412 try {
4413 uint16_t const packet_version = fr.unsigned_16();
4414- if (packet_version == kCurrentPacketVersion) {
4415+ if (packet_version <= kCurrentPacketVersion && packet_version >= 4) {
4416 while (!fr.end_of_file()) {
4417 Serial const serial = fr.unsigned_32();
4418 try {
4419@@ -144,10 +144,19 @@
4420 building.leave_allow_ = nullptr;
4421 }
4422
4423- while (fr.unsigned_8()) {
4424- DescriptionIndex oldidx =
4425- building.owner().tribe().safe_building_index(fr.c_string());
4426- building.old_buildings_.push_back(oldidx);
4427+ if (packet_version >= kCurrentPacketVersion) {
4428+ while (fr.unsigned_8()) {
4429+ DescriptionIndex oldidx =
4430+ building.owner().tribe().safe_building_index(fr.c_string());
4431+ const std::string type(fr.c_string());
4432+ building.old_buildings_.push_back(std::make_pair(oldidx, type));
4433+ }
4434+ } else {
4435+ while (fr.unsigned_8()) {
4436+ DescriptionIndex oldidx =
4437+ building.owner().tribe().safe_building_index(fr.c_string());
4438+ building.old_buildings_.push_back(std::make_pair(oldidx, ""));
4439+ }
4440 }
4441 // Only construction sites may have an empty list
4442 if (building.old_buildings_.empty() && !is_a(ConstructionSite, &building)) {
4443@@ -905,10 +914,11 @@
4444 }
4445 {
4446 const TribeDescr& td = building->owner().tribe();
4447- for (DescriptionIndex b_idx : building->old_buildings_) {
4448- const BuildingDescr* b_descr = td.get_building_descr(b_idx);
4449+ for (const auto& pair : building->old_buildings_) {
4450+ const BuildingDescr* b_descr = td.get_building_descr(pair.first);
4451 fw.unsigned_8(1);
4452 fw.string(b_descr->name());
4453+ fw.string(pair.second);
4454 }
4455 fw.unsigned_8(0);
4456 }
4457
4458=== modified file 'src/map_io/map_port_spaces_packet.cc'
4459--- src/map_io/map_port_spaces_packet.cc 2019-04-25 07:21:27 +0000
4460+++ src/map_io/map_port_spaces_packet.cc 2019-09-05 15:29:33 +0000
4461@@ -52,7 +52,7 @@
4462 Section& s2 = prof.get_safe_section("port_spaces");
4463 for (uint16_t i = 0; i < num; ++i) {
4464 map->set_port_space(
4465- egbase.world(),
4466+ egbase,
4467 get_safe_coords(std::to_string(static_cast<unsigned int>(i)), ext, &s2), true, true);
4468 }
4469 } else {
4470
4471=== modified file 'src/map_io/s2map.cc'
4472--- src/map_io/s2map.cc 2019-04-20 05:44:37 +0000
4473+++ src/map_io/s2map.cc 2019-09-05 15:29:33 +0000
4474@@ -413,9 +413,9 @@
4475
4476 load_s2mf(egbase);
4477
4478- map_.recalc_whole_map(egbase.world());
4479+ map_.recalc_whole_map(egbase);
4480
4481- postload_set_port_spaces(egbase.world());
4482+ postload_set_port_spaces(egbase);
4483
4484 set_state(STATE_LOADED);
4485
4486@@ -1025,7 +1025,7 @@
4487 // loading of Settlers 2 maps in the majority of cases, check all
4488 // starting positions and try to make it Widelands compatible, if its
4489 // size is too small.
4490- map_.recalc_whole_map(world); // to initialize buildcaps
4491+ map_.recalc_whole_map(egbase); // to initialize buildcaps
4492
4493 const Widelands::PlayerNumber nr_players = map_.get_nrplayers();
4494 log("Checking starting position for all %u players:\n", nr_players);
4495@@ -1042,14 +1042,14 @@
4496 }
4497 Widelands::FCoords fpos = map_.get_fcoords(starting_pos);
4498
4499- if (!(map_.get_max_nodecaps(world, fpos) & Widelands::BUILDCAPS_BIG)) {
4500+ if (!(map_.get_max_nodecaps(egbase, fpos) & Widelands::BUILDCAPS_BIG)) {
4501 log("wrong size - trying to fix it: ");
4502 bool fixed = false;
4503
4504 Widelands::MapRegion<Widelands::Area<Widelands::FCoords>> mr(
4505 map_, Widelands::Area<Widelands::FCoords>(fpos, 3));
4506 do {
4507- if (map_.get_max_nodecaps(world, const_cast<Widelands::FCoords&>(mr.location())) &
4508+ if (map_.get_max_nodecaps(egbase, const_cast<Widelands::FCoords&>(mr.location())) &
4509 Widelands::BUILDCAPS_BIG) {
4510 map_.set_starting_pos(p, mr.location());
4511 fixed = true;
4512@@ -1075,10 +1075,10 @@
4513
4514 /// Try to fix data which is incompatible between S2 and Widelands.
4515 /// This is only the port space locations.
4516-void S2MapLoader::postload_set_port_spaces(const Widelands::World& world) {
4517+void S2MapLoader::postload_set_port_spaces(const Widelands::EditorGameBase& egbase) {
4518 // Set port spaces near desired locations if possible
4519 for (const Widelands::Coords& coords : port_spaces_to_set_) {
4520- bool was_set = map_.set_port_space(world, coords, true);
4521+ bool was_set = map_.set_port_space(egbase, coords, true);
4522 const Widelands::FCoords fc = map_.get_fcoords(coords);
4523 if (!was_set) {
4524 // Try to set a port space at alternative location
4525@@ -1086,7 +1086,7 @@
4526 map_, Widelands::Area<Widelands::FCoords>(fc, 3));
4527 do {
4528 was_set = map_.set_port_space(
4529- world, Widelands::Coords(mr.location().x, mr.location().y), true);
4530+ egbase, Widelands::Coords(mr.location().x, mr.location().y), true);
4531 } while (!was_set && mr.advance(map_));
4532 }
4533 if (!was_set) {
4534
4535=== modified file 'src/map_io/s2map.h'
4536--- src/map_io/s2map.h 2019-02-23 11:00:49 +0000
4537+++ src/map_io/s2map.h 2019-09-05 15:29:33 +0000
4538@@ -46,7 +46,7 @@
4539
4540 void load_s2mf_header(FileRead&);
4541 void load_s2mf(Widelands::EditorGameBase&);
4542- void postload_set_port_spaces(const Widelands::World& world);
4543+ void postload_set_port_spaces(const Widelands::EditorGameBase& world);
4544 };
4545
4546 #endif // end of include guard: WL_MAP_IO_S2MAP_H
4547
4548=== modified file 'src/map_io/widelands_map_loader.cc'
4549--- src/map_io/widelands_map_loader.cc 2019-06-22 11:13:39 +0000
4550+++ src/map_io/widelands_map_loader.cc 2019-09-05 15:29:33 +0000
4551@@ -352,7 +352,7 @@
4552 }
4553 } // load_type != MapLoader::LoadType::kEditor
4554
4555- map_.recalc_whole_map(egbase.world());
4556+ map_.recalc_whole_map(egbase);
4557
4558 map_.ensure_resource_consistency(egbase.world());
4559
4560
4561=== modified file 'src/scripting/lua_bases.cc'
4562--- src/scripting/lua_bases.cc 2019-04-25 07:21:27 +0000
4563+++ src/scripting/lua_bases.cc 2019-09-05 15:29:33 +0000
4564@@ -785,7 +785,7 @@
4565 }
4566 DescriptionIndex building_index = tribes.building_index(name);
4567
4568- BuildingDescr::FormerBuildings former_buildings;
4569+ FormerBuildings former_buildings;
4570 find_former_buildings(tribes, building_index, &former_buildings);
4571 if (constructionsite) {
4572 former_buildings.pop_back();
4573
4574=== modified file 'src/scripting/lua_map.cc'
4575--- src/scripting/lua_map.cc 2019-06-23 11:41:17 +0000
4576+++ src/scripting/lua_map.cc 2019-09-05 15:29:33 +0000
4577@@ -1452,7 +1452,7 @@
4578 // TODO(unknown): do we really want this function?
4579 int LuaMap::recalculate(lua_State* L) {
4580 EditorGameBase& egbase = get_egbase(L);
4581- egbase.mutable_map()->recalc_whole_map(egbase.world());
4582+ egbase.mutable_map()->recalc_whole_map(egbase);
4583 return 0;
4584 }
4585
4586@@ -1489,7 +1489,7 @@
4587 const int y = luaL_checkint32(L, 3);
4588 const bool allowed = luaL_checkboolean(L, 4);
4589 const bool success = get_egbase(L).mutable_map()->set_port_space(
4590- get_egbase(L).world(), Widelands::Coords(x, y), allowed, false, true);
4591+ get_egbase(L), Widelands::Coords(x, y), allowed, false, true);
4592 lua_pushboolean(L, success);
4593 return 1;
4594 }
4595@@ -6217,7 +6217,7 @@
4596 report_error(L, "height must be <= %i", MAX_FIELD_HEIGHT);
4597
4598 EditorGameBase& egbase = get_egbase(L);
4599- egbase.mutable_map()->set_height(egbase.world(), f, height);
4600+ egbase.mutable_map()->set_height(egbase, f, height);
4601
4602 return 0;
4603 }
4604@@ -6401,12 +6401,11 @@
4605 int LuaField::set_terr(lua_State* L) {
4606 const char* name = luaL_checkstring(L, -1);
4607 EditorGameBase& egbase = get_egbase(L);
4608- const World& world = egbase.world();
4609- const DescriptionIndex td = world.terrains().get_index(name);
4610+ const DescriptionIndex td = egbase.world().terrains().get_index(name);
4611 if (td == static_cast<DescriptionIndex>(Widelands::INVALID_INDEX))
4612 report_error(L, "Unknown terrain '%s'", name);
4613
4614- egbase.mutable_map()->change_terrain(world, TCoords<FCoords>(fcoords(L), TriangleIndex::R), td);
4615+ egbase.mutable_map()->change_terrain(egbase, TCoords<FCoords>(fcoords(L), TriangleIndex::R), td);
4616
4617 lua_pushstring(L, name);
4618 return 1;
4619@@ -6420,12 +6419,11 @@
4620 int LuaField::set_terd(lua_State* L) {
4621 const char* name = luaL_checkstring(L, -1);
4622 EditorGameBase& egbase = get_egbase(L);
4623- const World& world = egbase.world();
4624- const DescriptionIndex td = world.terrains().get_index(name);
4625+ const DescriptionIndex td = egbase.world().terrains().get_index(name);
4626 if (td == static_cast<DescriptionIndex>(INVALID_INDEX))
4627 report_error(L, "Unknown terrain '%s'", name);
4628
4629- egbase.mutable_map()->change_terrain(world, TCoords<FCoords>(fcoords(L), TriangleIndex::D), td);
4630+ egbase.mutable_map()->change_terrain(egbase, TCoords<FCoords>(fcoords(L), TriangleIndex::D), td);
4631
4632 lua_pushstring(L, name);
4633 return 1;
4634
4635=== modified file 'src/wui/fieldaction.cc'
4636--- src/wui/fieldaction.cc 2019-06-25 08:03:30 +0000
4637+++ src/wui/fieldaction.cc 2019-09-05 15:29:33 +0000
4638@@ -158,7 +158,7 @@
4639
4640 void init();
4641 void add_buttons_auto();
4642- void add_buttons_build(int32_t buildcaps);
4643+ void add_buttons_build(int32_t buildcaps, int32_t max_nodecaps);
4644 void add_buttons_road(bool flag);
4645 void add_buttons_attack();
4646
4647@@ -357,12 +357,13 @@
4648 }
4649 } else {
4650 const int32_t buildcaps = player_ ? player_->get_buildcaps(node_) : 0;
4651+ const int32_t nodecaps = map_.get_max_nodecaps(ibase().egbase(), node_);
4652
4653 // Add house building
4654- if ((buildcaps & Widelands::BUILDCAPS_SIZEMASK) ||
4655- (buildcaps & Widelands::BUILDCAPS_MINE)) {
4656- assert(igbase->get_player());
4657- add_buttons_build(buildcaps);
4658+ const int32_t caps = buildcaps | nodecaps;
4659+ if (player_ && ((caps & Widelands::BUILDCAPS_SIZEMASK) ||
4660+ (caps & Widelands::BUILDCAPS_MINE))) {
4661+ add_buttons_build(buildcaps, nodecaps);
4662 }
4663
4664 // Add build actions
4665@@ -422,9 +423,20 @@
4666 Add buttons for house building.
4667 ===============
4668 */
4669-void FieldActionWindow::add_buttons_build(int32_t buildcaps) {
4670- if (!player_)
4671- return;
4672+void FieldActionWindow::add_buttons_build(int32_t buildcaps, int32_t max_nodecaps) {
4673+ if (!player_) {
4674+ return;
4675+ }
4676+ const Widelands::FCoords brn = map_.br_n(node_);
4677+ if (!node_.field->is_interior(player_->player_number()) ||
4678+ !brn.field->is_interior(player_->player_number())) {
4679+ return;
4680+ }
4681+ if (!(brn.field->get_immovable() &&
4682+ brn.field->get_immovable()->descr().type() == Widelands::MapObjectType::FLAG) &&
4683+ !(player_->get_buildcaps(brn) & Widelands::BUILDCAPS_FLAG)) {
4684+ return;
4685+ }
4686 BuildGrid* bbg_house[4] = {nullptr, nullptr, nullptr, nullptr};
4687 BuildGrid* bbg_mine = nullptr;
4688
4689@@ -446,27 +458,45 @@
4690 if (building_descr->needs_seafaring() && !ibase().egbase().map().allows_seafaring()) {
4691 continue;
4692 }
4693- } else if (!building_descr->is_buildable() && !building_descr->is_enhanced())
4694+ } else if (!building_descr->is_buildable() && !building_descr->is_enhanced()) {
4695 continue;
4696+ }
4697
4698+ if (building_descr->get_built_over_immovable() != Widelands::INVALID_INDEX &&
4699+ !(node_.field->get_immovable() &&
4700+ node_.field->get_immovable()->has_attribute(building_descr->get_built_over_immovable()))) {
4701+ continue;
4702+ }
4703 // Figure out if we can build it here, and in which tab it belongs
4704 if (building_descr->get_ismine()) {
4705- if (!(buildcaps & Widelands::BUILDCAPS_MINE))
4706+ if (!((building_descr->get_built_over_immovable() == Widelands::INVALID_INDEX ?
4707+ buildcaps : max_nodecaps) & Widelands::BUILDCAPS_MINE)) {
4708 continue;
4709+ }
4710
4711 ppgrid = &bbg_mine;
4712 } else {
4713 int32_t size = building_descr->get_size() - Widelands::BaseImmovable::SMALL;
4714
4715- if ((buildcaps & Widelands::BUILDCAPS_SIZEMASK) < size + 1)
4716- continue;
4717- if (building_descr->get_isport() && !(buildcaps & Widelands::BUILDCAPS_PORT))
4718- continue;
4719+ if (((building_descr->get_built_over_immovable() == Widelands::INVALID_INDEX ?
4720+ buildcaps : max_nodecaps) & Widelands::BUILDCAPS_SIZEMASK) < size + 1) {
4721+ continue;
4722+ }
4723+ if (building_descr->get_isport() && !(buildcaps & Widelands::BUILDCAPS_PORT)) {
4724+ continue;
4725+ }
4726+ if (building_descr->get_size() >= Widelands::BaseImmovable::BIG &&
4727+ !((map_.l_n(node_).field->is_interior(player_->player_number())) &&
4728+ (map_.tr_n(node_).field->is_interior(player_->player_number())) &&
4729+ (map_.tl_n(node_).field->is_interior(player_->player_number())))) {
4730+ continue;
4731+ }
4732
4733- if (building_descr->get_isport())
4734+ if (building_descr->get_isport()) {
4735 ppgrid = &bbg_house[3];
4736- else
4737+ } else {
4738 ppgrid = &bbg_house[size];
4739+ }
4740 }
4741
4742 // Allocate the tab's grid if necessary
4743
4744=== modified file 'src/wui/game_debug_ui.cc'
4745--- src/wui/game_debug_ui.cc 2019-02-23 11:00:49 +0000
4746+++ src/wui/game_debug_ui.cc 2019-09-05 15:29:33 +0000
4747@@ -359,7 +359,7 @@
4748
4749 // Bobs information
4750 std::vector<Widelands::Bob*> bobs;
4751- map_.find_bobs(Widelands::Area<Widelands::FCoords>(coords_, 0), &bobs);
4752+ map_.find_bobs(egbase, Widelands::Area<Widelands::FCoords>(coords_, 0), &bobs);
4753
4754 // Do not clear the list. Instead parse all bobs and sync lists
4755 for (uint32_t idx = 0; idx < ui_bobs_.size(); idx++) {
4756
4757=== modified file 'src/wui/interactive_gamebase.cc'
4758--- src/wui/interactive_gamebase.cc 2019-08-25 14:50:16 +0000
4759+++ src/wui/interactive_gamebase.cc 2019-09-05 15:29:33 +0000
4760@@ -444,7 +444,7 @@
4761 show_buildhelp(false);
4762
4763 // Recalc whole map for changed owner stuff
4764- egbase().mutable_map()->recalc_whole_map(egbase().world());
4765+ egbase().mutable_map()->recalc_whole_map(egbase());
4766
4767 // Close game-relevant UI windows (but keep main menu open)
4768 fieldaction_.destroy();
4769@@ -550,7 +550,7 @@
4770 }
4771
4772 std::vector<Widelands::Bob*> ships;
4773- if (map.find_bobs(area, &ships, Widelands::FindBobShip())) {
4774+ if (map.find_bobs(egbase(), area, &ships, Widelands::FindBobShip())) {
4775 for (Widelands::Bob* ship : ships) {
4776 if (can_see(ship->owner().player_number())) {
4777 // FindBobShip should have returned only ships
4778
4779=== modified file 'src/wui/watchwindow.cc'
4780--- src/wui/watchwindow.cc 2019-08-25 14:50:16 +0000
4781+++ src/wui/watchwindow.cc 2019-09-05 15:29:33 +0000
4782@@ -240,7 +240,7 @@
4783 .node),
4784 2);
4785 area.radius <= 32; area.radius *= 2)
4786- if (map.find_bobs(area, &bobs))
4787+ if (map.find_bobs(g, area, &bobs))
4788 break;
4789 // Find the bob closest to us
4790 float closest_dist = 0;