Merge lp:~widelands-dev/widelands/dynamic_tribe_loading into lp:widelands

Proposed by GunChleoc
Status: Work in progress
Proposed branch: lp:~widelands-dev/widelands/dynamic_tribe_loading
Merge into: lp:widelands
Diff against target: 1507 lines (+303/-549)
28 files modified
data/tribes/init.lua (+32/-384)
src/logic/map_objects/tribes/building.cc (+17/-20)
src/logic/map_objects/tribes/building.h (+4/-1)
src/logic/map_objects/tribes/carrier.cc (+1/-1)
src/logic/map_objects/tribes/carrier.h (+1/-1)
src/logic/map_objects/tribes/constructionsite.cc (+1/-1)
src/logic/map_objects/tribes/constructionsite.h (+1/-1)
src/logic/map_objects/tribes/dismantlesite.cc (+1/-1)
src/logic/map_objects/tribes/dismantlesite.h (+1/-1)
src/logic/map_objects/tribes/market.cc (+3/-3)
src/logic/map_objects/tribes/market.h (+1/-1)
src/logic/map_objects/tribes/militarysite.cc (+1/-1)
src/logic/map_objects/tribes/militarysite.h (+1/-1)
src/logic/map_objects/tribes/production_program.cc (+1/-1)
src/logic/map_objects/tribes/productionsite.cc (+12/-12)
src/logic/map_objects/tribes/productionsite.h (+2/-2)
src/logic/map_objects/tribes/soldier.cc (+1/-1)
src/logic/map_objects/tribes/soldier.h (+1/-1)
src/logic/map_objects/tribes/trainingsite.cc (+1/-1)
src/logic/map_objects/tribes/trainingsite.h (+1/-1)
src/logic/map_objects/tribes/tribe_descr.h (+2/-0)
src/logic/map_objects/tribes/tribes.cc (+99/-44)
src/logic/map_objects/tribes/tribes.h (+53/-26)
src/logic/map_objects/tribes/warehouse.cc (+1/-1)
src/logic/map_objects/tribes/warehouse.h (+1/-1)
src/logic/map_objects/tribes/worker_descr.cc (+32/-18)
src/logic/map_objects/tribes/worker_descr.h (+11/-3)
src/scripting/lua_root.cc (+20/-20)
To merge this branch: bzr merge lp:~widelands-dev/widelands/dynamic_tribe_loading
Reviewer Review Type Date Requested Status
GunChleoc Needs Fixing
SirVer Approve
Review via email: mp+329198@code.launchpad.net

Commit message

Dynamic loading of the tribes' map objects and of custom scenario tribe objects:

- Simplified tribes/init.lua: The tribe directory is now walked automatically, without the need of manually getting the load order right. Missing prerequisite map objects are parsed during postload.

- If scripting/tribes/init.lua exists in a map, run it to load custom tribe objects when starting a new scenario. So far, only buildings are supported via a new function Tribes::add_custom_building{table} in lua_root.

Description of the change

Reworked the tribe loading to make it more moddable. I'd like this branch to have priority, because it affects hessenfarmer's work on the Empire 4 scenario.

An adjusted version of the new scenario for testing is available in https://code.launchpad.net/~widelands-dev/widelands/dynamic_tribe_loading_datadir

To post a comment you must log in.
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 2568. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/265695435.
Appveyor build 2390. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_dynamic_tribe_loading-2390.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 2572. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/265868340.
Appveyor build 2394. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_dynamic_tribe_loading-2394.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 2615. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/269986493.
Appveyor build 2437. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_dynamic_tribe_loading-2437.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 2646. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/271368683.
Appveyor build 2468. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_dynamic_tribe_loading-2468.

Revision history for this message
SirVer (sirver) wrote :

I think this is a cool feature, thanks for working on this.

I am a bit unhappy about the postload() design approach, but that is not the fault of this branch. We are constructing partially initialized objects right and left and that gets pretty confusing - when is which data valid? I think it would be better to collecting all inter-object dependencies while loading the objects into a collection that is passed around to the loading functions. Later, they are all resolved at one point and missing objects can be reported then. What do you think? Do you want to try this in this branch or defer?

review: Needs Fixing
Revision history for this message
GunChleoc (gunchleoc) wrote :

I'd definitely want to try this in a different branch, as I expect the changes to be big.

I also can't deal with all your suggestions below in a teeny tiny VM window, so finishing this branch will have to wait until next month. It would still be great though if you had time for more reviews while I'm gone, so that I can start proposing more of my branches for merge when I get back home.

Revision history for this message
GunChleoc (gunchleoc) wrote :

I have added comments to the things that I plan not to change - will need to go through the rest in detail.

Revision history for this message
SirVer (sirver) :
Revision history for this message
GunChleoc (gunchleoc) wrote :

Making the Lua code prettier does not work - it will give me a crash with unknown function.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 2739. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/296435108.
Appveyor build 2551. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_dynamic_tribe_loading-2551.

Revision history for this message
GunChleoc (gunchleoc) wrote :

This should be ready now.

I added the remaining comments as NOCOM to the code for easier review and addressed all the rest. I have answered in the code.

For full testing, take the datadir from

https://code.launchpad.net/~widelands-dev/widelands/dynamic_tribe_loading_datadir

And start Empire Scenario 4.

review: Needs Resubmitting
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 2748. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/296945317.
Appveyor build 2560. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_dynamic_tribe_loading-2560.

Revision history for this message
SirVer (sirver) wrote :

Reviewed and tested. The new scenario is a lot of fun!

@bunnybot merge

review: Approve
Revision history for this message
bunnybot (widelandsofficial) wrote :

Refusing to merge, since Travis is not green. Use @bunnybot merge force for merging anyways.

Travis build 2748. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/296945317.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks for the review!

@bunnybot merge

Revision history for this message
bunnybot (widelandsofficial) wrote :

Refusing to merge, since Travis is not green. Use @bunnybot merge force for merging anyways.

Travis build 2780. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/298994801.

Revision history for this message
GunChleoc (gunchleoc) wrote :

r8439 broke the test suite.

Revision history for this message
SirVer (sirver) wrote :

Hooray for testing!

Revision history for this message
GunChleoc (gunchleoc) wrote :

Indeed! Now I need to find out where the extra 200 builders come from :P

Revision history for this message
hessenfarmer (stephan-lutz) wrote :

As soon as this branch will be in trunk I will adapt Mission 4 data according to the changes in dynamic_tribe_loading_datadir and ask for merge then. Does this sound ok? Or should we do this in different order?

Revision history for this message
GunChleoc (gunchleoc) wrote :

Sounds good to me.

Revision history for this message
GunChleoc (gunchleoc) wrote :

I have been fiddling with a test branch https://code.launchpad.net/~widelands-dev/widelands/dynamic_tribe_loading_test and I have found the change that broke it:

http://bazaar.launchpad.net/~widelands-dev/widelands/dynamic_tribe_loading_test/view/head:/src/logic/map_objects/tribes/worker_descr.cc#L72

The problem is that I have no idea why, so I'm not comfortable with merging this. Maybe I have uncovered an underlying bug, or I have done something stupid that I'm not seeing.

Does anybody have any idea?

review: Needs Fixing
Revision history for this message
GunChleoc (gunchleoc) wrote :

I'm giving up on this for now, so I have created a new branch that contains only the bits that the scenario editors need to continue their work:

https://code.launchpad.net/~widelands-dev/widelands/add_custom_building/+merge/334062

Revision history for this message
SirVer (sirver) wrote :

I cannot look into this right now, but here is what I usually do in such scenarios: I try to pull out independent changes from a branch into always smaller patches and check them in independently. Eventually the problem surfaces more clearly.

Revision history for this message
GunChleoc (gunchleoc) wrote :

This is exactly what I have done. The problem is that the changed line should not cause a segfault at all, so I'm stumped.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/tribes/init.lua'
2--- data/tribes/init.lua 2017-12-13 07:47:36 +0000
3+++ data/tribes/init.lua 2018-03-01 07:56:38 +0000
4@@ -11,12 +11,33 @@
5 --
6 -- Basic load order (first wares, then immovables etc.) is important,
7 -- because checks will be made in C++.
8--- Also, enhanced/upgraded units need to come before their basic units.
9 --
10
11 tribes = wl.Tribes()
12 include "scripting/mapobjects.lua"
13
14+-- Load all init.lua files in the given table of directory names
15+function load_directories(directories)
16+ -- Helper function to check for file name endings
17+ function string.ends(haystack, needle)
18+ return needle == '' or string.sub(haystack, -string.len(needle)) == needle
19+ end
20+
21+ while #directories > 0 do
22+ local filepath = directories[1]
23+ table.remove(directories, 1)
24+ if path.is_directory(filepath) then
25+ for idx, listed_path in ipairs(path.list_directory(filepath)) do
26+ if path.is_directory(listed_path) then
27+ table.insert(directories, listed_path)
28+ elseif string.ends(listed_path , "init.lua") then
29+ include(listed_path)
30+ end
31+ end
32+ end
33+ end
34+end
35+
36 print("┏━ Running Lua for tribes:")
37
38 print_loading_message("┗━ took", function()
39@@ -25,9 +46,7 @@
40 -- ===================================
41
42 print_loading_message("┃ Ships", function()
43- include "tribes/ships/atlanteans/init.lua"
44- include "tribes/ships/barbarians/init.lua"
45- include "tribes/ships/empire/init.lua"
46+ load_directories({"tribes/ships"})
47 end)
48
49 -- ===================================
50@@ -35,91 +54,7 @@
51 -- ===================================
52
53 print_loading_message("┃ Wares", function()
54- include "tribes/wares/armor/init.lua"
55- include "tribes/wares/armor_chain/init.lua"
56- include "tribes/wares/armor_gilded/init.lua"
57- include "tribes/wares/armor_helmet/init.lua"
58- include "tribes/wares/ax/init.lua"
59- include "tribes/wares/ax_battle/init.lua"
60- include "tribes/wares/ax_broad/init.lua"
61- include "tribes/wares/ax_bronze/init.lua"
62- include "tribes/wares/ax_sharp/init.lua"
63- include "tribes/wares/ax_warriors/init.lua"
64- include "tribes/wares/basket/init.lua"
65- include "tribes/wares/beer/init.lua"
66- include "tribes/wares/beer_strong/init.lua"
67- include "tribes/wares/blackroot/init.lua"
68- include "tribes/wares/blackroot_flour/init.lua"
69- include "tribes/wares/blackwood/init.lua"
70- include "tribes/wares/bread_atlanteans/init.lua"
71- include "tribes/wares/bread_barbarians/init.lua"
72- include "tribes/wares/bread_empire/init.lua"
73- include "tribes/wares/bread_paddle/init.lua"
74- include "tribes/wares/buckets/init.lua"
75- include "tribes/wares/cloth/init.lua"
76- include "tribes/wares/coal/init.lua"
77- include "tribes/wares/corn/init.lua"
78- include "tribes/wares/cornmeal/init.lua"
79- include "tribes/wares/diamond/init.lua"
80- include "tribes/wares/felling_ax/init.lua"
81- include "tribes/wares/fire_tongs/init.lua"
82- include "tribes/wares/fish/init.lua"
83- include "tribes/wares/fishing_net/init.lua"
84- include "tribes/wares/fishing_rod/init.lua"
85- include "tribes/wares/flour/init.lua"
86- include "tribes/wares/gold/init.lua"
87- include "tribes/wares/gold_ore/init.lua"
88- include "tribes/wares/gold_thread/init.lua"
89- include "tribes/wares/granite/init.lua"
90- include "tribes/wares/grape/init.lua"
91- include "tribes/wares/grout/init.lua"
92- include "tribes/wares/hammer/init.lua"
93- include "tribes/wares/helmet/init.lua"
94- include "tribes/wares/helmet_mask/init.lua"
95- include "tribes/wares/helmet_warhelm/init.lua"
96- include "tribes/wares/hook_pole/init.lua"
97- include "tribes/wares/hunting_bow/init.lua"
98- include "tribes/wares/hunting_spear/init.lua"
99- include "tribes/wares/iron/init.lua"
100- include "tribes/wares/iron_ore/init.lua"
101- include "tribes/wares/kitchen_tools/init.lua"
102- include "tribes/wares/log/init.lua"
103- include "tribes/wares/marble/init.lua"
104- include "tribes/wares/marble_column/init.lua"
105- include "tribes/wares/meal/init.lua"
106- include "tribes/wares/meat/init.lua"
107- include "tribes/wares/milking_tongs/init.lua"
108- include "tribes/wares/pick/init.lua"
109- include "tribes/wares/planks/init.lua"
110- include "tribes/wares/quartz/init.lua"
111- include "tribes/wares/ration/init.lua"
112- include "tribes/wares/saw/init.lua"
113- include "tribes/wares/scythe/init.lua"
114- include "tribes/wares/shield_advanced/init.lua"
115- include "tribes/wares/shield_steel/init.lua"
116- include "tribes/wares/shovel/init.lua"
117- include "tribes/wares/smoked_fish/init.lua"
118- include "tribes/wares/smoked_meat/init.lua"
119- include "tribes/wares/snack/init.lua"
120- include "tribes/wares/spear/init.lua"
121- include "tribes/wares/spear_advanced/init.lua"
122- include "tribes/wares/spear_heavy/init.lua"
123- include "tribes/wares/spear_war/init.lua"
124- include "tribes/wares/spear_wooden/init.lua"
125- include "tribes/wares/spidercloth/init.lua"
126- include "tribes/wares/spider_silk/init.lua"
127- include "tribes/wares/tabard/init.lua"
128- include "tribes/wares/tabard_golden/init.lua"
129- include "tribes/wares/thatch_reed/init.lua"
130- include "tribes/wares/trident_double/init.lua"
131- include "tribes/wares/trident_heavy_double/init.lua"
132- include "tribes/wares/trident_light/init.lua"
133- include "tribes/wares/trident_long/init.lua"
134- include "tribes/wares/trident_steel/init.lua"
135- include "tribes/wares/water/init.lua"
136- include "tribes/wares/wheat/init.lua"
137- include "tribes/wares/wine/init.lua"
138- include "tribes/wares/wool/init.lua"
139+ load_directories({"tribes/wares"})
140 end)
141
142 -- ===================================
143@@ -127,44 +62,7 @@
144 -- ===================================
145
146 print_loading_message("┃ Immovables", function()
147- include "tribes/immovables/ashes/init.lua"
148- include "tribes/immovables/blackrootfield_harvested/init.lua"
149- include "tribes/immovables/blackrootfield_medium/init.lua"
150- include "tribes/immovables/blackrootfield_ripe/init.lua"
151- include "tribes/immovables/blackrootfield_small/init.lua"
152- include "tribes/immovables/blackrootfield_tiny/init.lua"
153- include "tribes/immovables/cornfield_harvested/init.lua"
154- include "tribes/immovables/cornfield_medium/init.lua"
155- include "tribes/immovables/cornfield_ripe/init.lua"
156- include "tribes/immovables/cornfield_small/init.lua"
157- include "tribes/immovables/cornfield_tiny/init.lua"
158- include "tribes/immovables/destroyed_building/init.lua"
159- include "tribes/immovables/field_harvested/init.lua"
160- include "tribes/immovables/field_medium/init.lua"
161- include "tribes/immovables/field_ripe/init.lua"
162- include "tribes/immovables/field_small/init.lua"
163- include "tribes/immovables/field_tiny/init.lua"
164- include "tribes/immovables/grapevine_medium/init.lua"
165- include "tribes/immovables/grapevine_ripe/init.lua"
166- include "tribes/immovables/grapevine_small/init.lua"
167- include "tribes/immovables/grapevine_tiny/init.lua"
168- include "tribes/immovables/reed_medium/init.lua"
169- include "tribes/immovables/reed_ripe/init.lua"
170- include "tribes/immovables/reed_small/init.lua"
171- include "tribes/immovables/reed_tiny/init.lua"
172- include "tribes/immovables/resi_coal1/init.lua"
173- include "tribes/immovables/resi_coal2/init.lua"
174- include "tribes/immovables/resi_gold1/init.lua"
175- include "tribes/immovables/resi_gold2/init.lua"
176- include "tribes/immovables/resi_iron1/init.lua"
177- include "tribes/immovables/resi_iron2/init.lua"
178- include "tribes/immovables/resi_none/init.lua"
179- include "tribes/immovables/resi_stones1/init.lua"
180- include "tribes/immovables/resi_stones2/init.lua"
181- include "tribes/immovables/resi_water1/init.lua"
182- include "tribes/immovables/shipconstruction_atlanteans/init.lua"
183- include "tribes/immovables/shipconstruction_barbarians/init.lua"
184- include "tribes/immovables/shipconstruction_empire/init.lua"
185+ load_directories({"tribes/immovables"})
186 end)
187
188 -- ===================================
189@@ -172,103 +70,7 @@
190 -- ===================================
191
192 print_loading_message("┃ Workers", function()
193- include "tribes/workers/atlanteans/carrier/init.lua"
194- include "tribes/workers/atlanteans/armorsmith/init.lua"
195- include "tribes/workers/atlanteans/baker/init.lua"
196- include "tribes/workers/atlanteans/blackroot_farmer/init.lua"
197- include "tribes/workers/atlanteans/builder/init.lua"
198- include "tribes/workers/atlanteans/charcoal_burner/init.lua"
199- include "tribes/workers/atlanteans/farmer/init.lua"
200- include "tribes/workers/atlanteans/fishbreeder/init.lua"
201- include "tribes/workers/atlanteans/fisher/init.lua"
202- include "tribes/workers/atlanteans/forester/init.lua"
203- include "tribes/workers/atlanteans/geologist/init.lua"
204- include "tribes/workers/atlanteans/horse/init.lua"
205- include "tribes/workers/atlanteans/horsebreeder/init.lua"
206- include "tribes/workers/atlanteans/hunter/init.lua"
207- include "tribes/workers/atlanteans/miller/init.lua"
208- include "tribes/workers/atlanteans/miner/init.lua"
209- include "tribes/workers/atlanteans/recruit/init.lua"
210- include "tribes/workers/atlanteans/sawyer/init.lua"
211- include "tribes/workers/atlanteans/scout/init.lua"
212- include "tribes/workers/atlanteans/shipwright/init.lua"
213- include "tribes/workers/atlanteans/smelter/init.lua"
214- include "tribes/workers/atlanteans/smoker/init.lua"
215- include "tribes/workers/atlanteans/soldier/init.lua"
216- include "tribes/workers/atlanteans/spiderbreeder/init.lua"
217- include "tribes/workers/atlanteans/stonecutter/init.lua"
218- include "tribes/workers/atlanteans/toolsmith/init.lua"
219- include "tribes/workers/atlanteans/trainer/init.lua"
220- include "tribes/workers/atlanteans/weaponsmith/init.lua"
221- include "tribes/workers/atlanteans/weaver/init.lua"
222- include "tribes/workers/atlanteans/woodcutter/init.lua"
223-
224- include "tribes/workers/barbarians/carrier/init.lua"
225- include "tribes/workers/barbarians/baker/init.lua"
226- include "tribes/workers/barbarians/blacksmith_master/init.lua"
227- include "tribes/workers/barbarians/blacksmith/init.lua"
228- include "tribes/workers/barbarians/brewer_master/init.lua"
229- include "tribes/workers/barbarians/brewer/init.lua"
230- include "tribes/workers/barbarians/builder/init.lua"
231- include "tribes/workers/barbarians/cattlebreeder/init.lua"
232- include "tribes/workers/barbarians/charcoal_burner/init.lua"
233- include "tribes/workers/barbarians/farmer/init.lua"
234- include "tribes/workers/barbarians/fisher/init.lua"
235- include "tribes/workers/barbarians/gamekeeper/init.lua"
236- include "tribes/workers/barbarians/gardener/init.lua"
237- include "tribes/workers/barbarians/geologist/init.lua"
238- include "tribes/workers/barbarians/helmsmith/init.lua"
239- include "tribes/workers/barbarians/hunter/init.lua"
240- include "tribes/workers/barbarians/innkeeper/init.lua"
241- include "tribes/workers/barbarians/lime_burner/init.lua"
242- include "tribes/workers/barbarians/lumberjack/init.lua"
243- include "tribes/workers/barbarians/miner_master/init.lua"
244- include "tribes/workers/barbarians/miner_chief/init.lua"
245- include "tribes/workers/barbarians/miner/init.lua"
246- include "tribes/workers/barbarians/ox/init.lua"
247- include "tribes/workers/barbarians/ranger/init.lua"
248- include "tribes/workers/barbarians/recruit/init.lua"
249- include "tribes/workers/barbarians/scout/init.lua"
250- include "tribes/workers/barbarians/shipwright/init.lua"
251- include "tribes/workers/barbarians/smelter/init.lua"
252- include "tribes/workers/barbarians/soldier/init.lua"
253- include "tribes/workers/barbarians/stonemason/init.lua"
254- include "tribes/workers/barbarians/trainer/init.lua"
255- include "tribes/workers/barbarians/weaver/init.lua"
256-
257- include "tribes/workers/empire/carrier/init.lua"
258- include "tribes/workers/empire/armorsmith/init.lua"
259- include "tribes/workers/empire/baker/init.lua"
260- include "tribes/workers/empire/brewer/init.lua"
261- include "tribes/workers/empire/builder/init.lua"
262- include "tribes/workers/empire/carpenter/init.lua"
263- include "tribes/workers/empire/charcoal_burner/init.lua"
264- include "tribes/workers/empire/donkey/init.lua"
265- include "tribes/workers/empire/donkeybreeder/init.lua"
266- include "tribes/workers/empire/farmer/init.lua"
267- include "tribes/workers/empire/fisher/init.lua"
268- include "tribes/workers/empire/forester/init.lua"
269- include "tribes/workers/empire/geologist/init.lua"
270- include "tribes/workers/empire/hunter/init.lua"
271- include "tribes/workers/empire/innkeeper/init.lua"
272- include "tribes/workers/empire/lumberjack/init.lua"
273- include "tribes/workers/empire/miller/init.lua"
274- include "tribes/workers/empire/miner_master/init.lua"
275- include "tribes/workers/empire/miner/init.lua"
276- include "tribes/workers/empire/pigbreeder/init.lua"
277- include "tribes/workers/empire/recruit/init.lua"
278- include "tribes/workers/empire/scout/init.lua"
279- include "tribes/workers/empire/shepherd/init.lua"
280- include "tribes/workers/empire/shipwright/init.lua"
281- include "tribes/workers/empire/smelter/init.lua"
282- include "tribes/workers/empire/soldier/init.lua"
283- include "tribes/workers/empire/stonemason/init.lua"
284- include "tribes/workers/empire/toolsmith/init.lua"
285- include "tribes/workers/empire/trainer/init.lua"
286- include "tribes/workers/empire/vinefarmer/init.lua"
287- include "tribes/workers/empire/vintner/init.lua"
288- include "tribes/workers/empire/weaponsmith/init.lua"
289- include "tribes/workers/empire/weaver/init.lua"
290+ load_directories({"tribes/workers"})
291 end)
292
293 -- ===================================
294@@ -276,17 +78,7 @@
295 -- ===================================
296
297 print_loading_message("┃ Warehouses", function()
298- include "tribes/buildings/warehouses/atlanteans/headquarters/init.lua"
299- include "tribes/buildings/warehouses/atlanteans/port/init.lua"
300- include "tribes/buildings/warehouses/atlanteans/warehouse/init.lua"
301- include "tribes/buildings/warehouses/barbarians/headquarters/init.lua"
302- include "tribes/buildings/warehouses/barbarians/headquarters_interim/init.lua"
303- include "tribes/buildings/warehouses/barbarians/port/init.lua"
304- include "tribes/buildings/warehouses/barbarians/warehouse/init.lua"
305- include "tribes/buildings/warehouses/empire/headquarters/init.lua"
306- include "tribes/buildings/warehouses/empire/headquarters_shipwreck/init.lua"
307- include "tribes/buildings/warehouses/empire/port/init.lua"
308- include "tribes/buildings/warehouses/empire/warehouse/init.lua"
309+ load_directories({"tribes/buildings/warehouses"})
310 end)
311
312 -- ===================================
313@@ -294,132 +86,14 @@
314 -- ===================================
315
316 print_loading_message("┃ Markets", function()
317- include "tribes/buildings/markets/barbarians/market/init.lua"
318+ load_directories({"tribes/buildings/markets"})
319 end)
320 -- ===================================
321 -- Productionsites
322 -- ===================================
323
324 print_loading_message("┃ Productionsites", function()
325- -- Atlanteans small
326- include "tribes/buildings/productionsites/atlanteans/quarry/init.lua"
327- include "tribes/buildings/productionsites/atlanteans/woodcutters_house/init.lua"
328- include "tribes/buildings/productionsites/atlanteans/foresters_house/init.lua"
329- include "tribes/buildings/productionsites/atlanteans/fishers_house/init.lua"
330- include "tribes/buildings/productionsites/atlanteans/fishbreeders_house/init.lua"
331- include "tribes/buildings/productionsites/atlanteans/hunters_house/init.lua"
332- include "tribes/buildings/productionsites/atlanteans/well/init.lua"
333- include "tribes/buildings/productionsites/atlanteans/gold_spinning_mill/init.lua"
334- include "tribes/buildings/productionsites/atlanteans/scouts_house/init.lua"
335- -- Atlanteans medium
336- include "tribes/buildings/productionsites/atlanteans/sawmill/init.lua"
337- include "tribes/buildings/productionsites/atlanteans/smokery/init.lua"
338- include "tribes/buildings/productionsites/atlanteans/mill/init.lua"
339- include "tribes/buildings/productionsites/atlanteans/bakery/init.lua"
340- include "tribes/buildings/productionsites/atlanteans/charcoal_kiln/init.lua"
341- include "tribes/buildings/productionsites/atlanteans/smelting_works/init.lua"
342- include "tribes/buildings/productionsites/atlanteans/shipyard/init.lua"
343- include "tribes/buildings/productionsites/atlanteans/toolsmithy/init.lua"
344- include "tribes/buildings/productionsites/atlanteans/weaponsmithy/init.lua"
345- include "tribes/buildings/productionsites/atlanteans/armorsmithy/init.lua"
346- include "tribes/buildings/productionsites/atlanteans/barracks/init.lua"
347-
348- -- Atlanteans big
349- include "tribes/buildings/productionsites/atlanteans/horsefarm/init.lua"
350- include "tribes/buildings/productionsites/atlanteans/farm/init.lua"
351- include "tribes/buildings/productionsites/atlanteans/blackroot_farm/init.lua"
352- include "tribes/buildings/productionsites/atlanteans/spiderfarm/init.lua"
353- include "tribes/buildings/productionsites/atlanteans/weaving_mill/init.lua"
354-
355- -- Atlanteans mines
356- include "tribes/buildings/productionsites/atlanteans/crystalmine/init.lua"
357- include "tribes/buildings/productionsites/atlanteans/coalmine/init.lua"
358- include "tribes/buildings/productionsites/atlanteans/ironmine/init.lua"
359- include "tribes/buildings/productionsites/atlanteans/goldmine/init.lua"
360- -- Barbarians small
361- include "tribes/buildings/productionsites/barbarians/quarry/init.lua"
362- include "tribes/buildings/productionsites/barbarians/lumberjacks_hut/init.lua"
363- include "tribes/buildings/productionsites/barbarians/rangers_hut/init.lua"
364- include "tribes/buildings/productionsites/barbarians/fishers_hut/init.lua"
365- include "tribes/buildings/productionsites/barbarians/hunters_hut/init.lua"
366- include "tribes/buildings/productionsites/barbarians/gamekeepers_hut/init.lua"
367- include "tribes/buildings/productionsites/barbarians/well/init.lua"
368- include "tribes/buildings/productionsites/barbarians/scouts_hut/init.lua"
369- -- Barbarians medium
370- include "tribes/buildings/productionsites/barbarians/wood_hardener/init.lua"
371- include "tribes/buildings/productionsites/barbarians/lime_kiln/init.lua"
372- include "tribes/buildings/productionsites/barbarians/reed_yard/init.lua"
373- include "tribes/buildings/productionsites/barbarians/bakery/init.lua"
374- include "tribes/buildings/productionsites/barbarians/brewery/init.lua"
375- include "tribes/buildings/productionsites/barbarians/micro_brewery/init.lua"
376- include "tribes/buildings/productionsites/barbarians/big_inn/init.lua"
377- include "tribes/buildings/productionsites/barbarians/inn/init.lua"
378- include "tribes/buildings/productionsites/barbarians/tavern/init.lua"
379- include "tribes/buildings/productionsites/barbarians/charcoal_kiln/init.lua"
380- include "tribes/buildings/productionsites/barbarians/smelting_works/init.lua"
381- include "tribes/buildings/productionsites/barbarians/shipyard/init.lua"
382- include "tribes/buildings/productionsites/barbarians/warmill/init.lua"
383- include "tribes/buildings/productionsites/barbarians/ax_workshop/init.lua"
384- include "tribes/buildings/productionsites/barbarians/metal_workshop/init.lua"
385- include "tribes/buildings/productionsites/barbarians/barracks/init.lua"
386-
387- -- Barbarians big
388- include "tribes/buildings/productionsites/barbarians/cattlefarm/init.lua"
389- include "tribes/buildings/productionsites/barbarians/farm/init.lua"
390- include "tribes/buildings/productionsites/barbarians/weaving_mill/init.lua"
391- include "tribes/buildings/productionsites/barbarians/helmsmithy/init.lua"
392- -- Barbarians mines
393- include "tribes/buildings/productionsites/barbarians/granitemine/init.lua"
394- include "tribes/buildings/productionsites/barbarians/coalmine_deeper/init.lua"
395- include "tribes/buildings/productionsites/barbarians/coalmine_deep/init.lua"
396- include "tribes/buildings/productionsites/barbarians/coalmine/init.lua"
397- include "tribes/buildings/productionsites/barbarians/ironmine_deeper/init.lua"
398- include "tribes/buildings/productionsites/barbarians/ironmine_deep/init.lua"
399- include "tribes/buildings/productionsites/barbarians/ironmine/init.lua"
400- include "tribes/buildings/productionsites/barbarians/goldmine_deeper/init.lua"
401- include "tribes/buildings/productionsites/barbarians/goldmine_deep/init.lua"
402- include "tribes/buildings/productionsites/barbarians/goldmine/init.lua"
403- -- Empire small
404- include "tribes/buildings/productionsites/empire/quarry/init.lua"
405- include "tribes/buildings/productionsites/empire/lumberjacks_house/init.lua"
406- include "tribes/buildings/productionsites/empire/foresters_house/init.lua"
407- include "tribes/buildings/productionsites/empire/fishers_house/init.lua"
408- include "tribes/buildings/productionsites/empire/hunters_house/init.lua"
409- include "tribes/buildings/productionsites/empire/well/init.lua"
410- include "tribes/buildings/productionsites/empire/scouts_house/init.lua"
411- -- Empire medium
412- include "tribes/buildings/productionsites/empire/stonemasons_house/init.lua"
413- include "tribes/buildings/productionsites/empire/sawmill/init.lua"
414- include "tribes/buildings/productionsites/empire/mill/init.lua"
415- include "tribes/buildings/productionsites/empire/bakery/init.lua"
416- include "tribes/buildings/productionsites/empire/brewery/init.lua"
417- include "tribes/buildings/productionsites/empire/vineyard/init.lua"
418- include "tribes/buildings/productionsites/empire/winery/init.lua"
419- include "tribes/buildings/productionsites/empire/inn/init.lua"
420- include "tribes/buildings/productionsites/empire/tavern/init.lua"
421- include "tribes/buildings/productionsites/empire/charcoal_kiln/init.lua"
422- include "tribes/buildings/productionsites/empire/smelting_works/init.lua"
423- include "tribes/buildings/productionsites/empire/shipyard/init.lua"
424- include "tribes/buildings/productionsites/empire/toolsmithy/init.lua"
425- include "tribes/buildings/productionsites/empire/armorsmithy/init.lua"
426- -- Empire big
427- include "tribes/buildings/productionsites/empire/donkeyfarm/init.lua"
428- include "tribes/buildings/productionsites/empire/farm/init.lua"
429- include "tribes/buildings/productionsites/empire/piggery/init.lua"
430- include "tribes/buildings/productionsites/empire/sheepfarm/init.lua"
431- include "tribes/buildings/productionsites/empire/weaving_mill/init.lua"
432- include "tribes/buildings/productionsites/empire/weaponsmithy/init.lua"
433- include "tribes/buildings/productionsites/empire/barracks/init.lua"
434-
435- -- Empire mines
436- include "tribes/buildings/productionsites/empire/coalmine_deep/init.lua"
437- include "tribes/buildings/productionsites/empire/coalmine/init.lua"
438- include "tribes/buildings/productionsites/empire/ironmine_deep/init.lua"
439- include "tribes/buildings/productionsites/empire/ironmine/init.lua"
440- include "tribes/buildings/productionsites/empire/marblemine_deep/init.lua"
441- include "tribes/buildings/productionsites/empire/marblemine/init.lua"
442- include "tribes/buildings/productionsites/empire/goldmine_deep/init.lua"
443- include "tribes/buildings/productionsites/empire/goldmine/init.lua"
444+ load_directories({"tribes/buildings/productionsites"})
445 end)
446
447 -- ===================================
448@@ -427,13 +101,7 @@
449 -- ===================================
450
451 print_loading_message("┃ Trainingsites", function()
452- include "tribes/buildings/trainingsites/atlanteans/dungeon/init.lua"
453- include "tribes/buildings/trainingsites/atlanteans/labyrinth/init.lua"
454- include "tribes/buildings/trainingsites/barbarians/battlearena/init.lua"
455- include "tribes/buildings/trainingsites/barbarians/trainingcamp/init.lua"
456- include "tribes/buildings/trainingsites/empire/colosseum/init.lua"
457- include "tribes/buildings/trainingsites/empire/arena/init.lua"
458- include "tribes/buildings/trainingsites/empire/trainingcamp/init.lua"
459+ load_directories({"tribes/buildings/trainingsites"})
460 end)
461
462 -- ===================================
463@@ -441,26 +109,7 @@
464 -- ===================================
465
466 print_loading_message("┃ Militarysites", function()
467- include "tribes/buildings/militarysites/atlanteans/guardhouse/init.lua"
468- include "tribes/buildings/militarysites/atlanteans/guardhall/init.lua"
469- include "tribes/buildings/militarysites/atlanteans/tower_small/init.lua"
470- include "tribes/buildings/militarysites/atlanteans/tower_high/init.lua"
471- include "tribes/buildings/militarysites/atlanteans/tower/init.lua"
472- include "tribes/buildings/militarysites/atlanteans/castle/init.lua"
473-
474- include "tribes/buildings/militarysites/barbarians/sentry/init.lua"
475- include "tribes/buildings/militarysites/barbarians/barrier/init.lua"
476- include "tribes/buildings/militarysites/barbarians/tower/init.lua"
477- include "tribes/buildings/militarysites/barbarians/citadel/init.lua"
478- include "tribes/buildings/militarysites/barbarians/fortress/init.lua"
479-
480- include "tribes/buildings/militarysites/empire/sentry/init.lua"
481- include "tribes/buildings/militarysites/empire/blockhouse/init.lua"
482- include "tribes/buildings/militarysites/empire/barrier/init.lua"
483- include "tribes/buildings/militarysites/empire/outpost/init.lua"
484- include "tribes/buildings/militarysites/empire/tower/init.lua"
485- include "tribes/buildings/militarysites/empire/castle/init.lua"
486- include "tribes/buildings/militarysites/empire/fortress/init.lua"
487+ load_directories({"tribes/buildings/militarysites"})
488 end)
489
490 -- ===================================
491@@ -468,8 +117,7 @@
492 -- ===================================
493
494 print_loading_message("┃ Partially finished buildings", function()
495- include "tribes/buildings/partially_finished/constructionsite/init.lua"
496- include "tribes/buildings/partially_finished/dismantlesite/init.lua"
497+ load_directories({"tribes/buildings/partially_finished"})
498 end)
499
500 -- ===================================
501
502=== modified file 'src/logic/map_objects/tribes/building.cc'
503--- src/logic/map_objects/tribes/building.cc 2018-01-11 11:40:45 +0000
504+++ src/logic/map_objects/tribes/building.cc 2018-03-01 07:56:38 +0000
505@@ -57,9 +57,9 @@
506 BuildingDescr::BuildingDescr(const std::string& init_descname,
507 const MapObjectType init_type,
508 const LuaTable& table,
509- const EditorGameBase& egbase)
510+ EditorGameBase* egbase)
511 : MapObjectDescr(init_type, table.get_string("name"), init_descname, table),
512- egbase_(egbase),
513+ egbase_(*egbase),
514 buildable_(false),
515 size_(BaseImmovable::SMALL),
516 mine_(false),
517@@ -111,27 +111,11 @@
518
519 if (table.has_key("enhancement")) {
520 const std::string enh = table.get_string("enhancement");
521-
522 if (enh == name()) {
523 throw wexception("enhancement to same type");
524 }
525- DescriptionIndex const en_i = egbase_.tribes().building_index(enh);
526- if (egbase_.tribes().building_exists(en_i)) {
527- enhancement_ = en_i;
528-
529- // Merge the enhancements workarea info into this building's
530- // workarea info.
531- const BuildingDescr* tmp_enhancement = egbase_.tribes().get_building_descr(en_i);
532- for (auto area : tmp_enhancement->workarea_info_) {
533- std::set<std::string>& strs = workarea_info_[area.first];
534- for (std::string str : area.second)
535- strs.insert(str);
536- }
537- } else {
538- throw wexception(
539- "\"%s\" has not been defined as a building type (wrong declaration order?)",
540- enh.c_str());
541- }
542+ // The advanced building might not have been loaded yet, so we'll do this in postload.
543+ egbase->mutable_tribes()->add_mapobject_enhancement({MapObjectType::BUILDING, name(), enh});
544 }
545
546 if (table.has_key("buildcost")) {
547@@ -165,6 +149,19 @@
548 }
549 }
550
551+void BuildingDescr::set_enhances_to(const std::string& enhancement_name) {
552+ enhancement_ = egbase_.tribes().safe_building_index(enhancement_name);
553+
554+ // Merge the enhancement's workarea info into this building's
555+ // workarea info.
556+ for (auto area : egbase_.tribes().get_building_descr(enhancement_)->workarea_info_) {
557+ std::set<std::string>& strs = workarea_info_[area.first];
558+ for (std::string str : area.second) {
559+ strs.insert(str);
560+ }
561+ }
562+}
563+
564 Building& BuildingDescr::create(EditorGameBase& egbase,
565 Player& owner,
566 Coords const pos,
567
568=== modified file 'src/logic/map_objects/tribes/building.h'
569--- src/logic/map_objects/tribes/building.h 2018-01-23 00:23:13 +0000
570+++ src/logic/map_objects/tribes/building.h 2018-03-01 07:56:38 +0000
571@@ -66,7 +66,7 @@
572 BuildingDescr(const std::string& init_descname,
573 MapObjectType type,
574 const LuaTable& t,
575- const EditorGameBase& egbase);
576+ EditorGameBase* egbase);
577 ~BuildingDescr() override {
578 }
579
580@@ -80,6 +80,9 @@
581 return enhanced_building_;
582 }
583
584+ /// Define a building that this building can be enhanced to. 'name' is the descr().name() of the other building.
585+ void set_enhances_to(const std::string& name);
586+
587 /**
588 * The build cost for direct construction
589 */
590
591=== modified file 'src/logic/map_objects/tribes/carrier.cc'
592--- src/logic/map_objects/tribes/carrier.cc 2017-08-19 22:22:20 +0000
593+++ src/logic/map_objects/tribes/carrier.cc 2018-03-01 07:56:38 +0000
594@@ -568,7 +568,7 @@
595
596 CarrierDescr::CarrierDescr(const std::string& init_descname,
597 const LuaTable& table,
598- const EditorGameBase& egbase)
599+ EditorGameBase* egbase)
600 : WorkerDescr(init_descname, MapObjectType::CARRIER, table, egbase),
601 ware_hotspot_(Vector2i(0, 15)) {
602 if (table.has_key("ware_hotspot")) {
603
604=== modified file 'src/logic/map_objects/tribes/carrier.h'
605--- src/logic/map_objects/tribes/carrier.h 2017-11-26 14:44:23 +0000
606+++ src/logic/map_objects/tribes/carrier.h 2018-03-01 07:56:38 +0000
607@@ -29,7 +29,7 @@
608 public:
609 CarrierDescr(const std::string& init_descname,
610 const LuaTable& table,
611- const EditorGameBase& egbase);
612+ EditorGameBase* egbase);
613 ~CarrierDescr() override {
614 }
615
616
617=== modified file 'src/logic/map_objects/tribes/constructionsite.cc'
618--- src/logic/map_objects/tribes/constructionsite.cc 2017-12-17 17:47:34 +0000
619+++ src/logic/map_objects/tribes/constructionsite.cc 2018-03-01 07:56:38 +0000
620@@ -77,7 +77,7 @@
621 */
622 ConstructionSiteDescr::ConstructionSiteDescr(const std::string& init_descname,
623 const LuaTable& table,
624- const EditorGameBase& egbase)
625+ EditorGameBase* egbase)
626 : BuildingDescr(init_descname, MapObjectType::CONSTRUCTIONSITE, table, egbase) {
627 add_attribute(MapObject::CONSTRUCTIONSITE);
628 }
629
630=== modified file 'src/logic/map_objects/tribes/constructionsite.h'
631--- src/logic/map_objects/tribes/constructionsite.h 2017-12-17 17:47:34 +0000
632+++ src/logic/map_objects/tribes/constructionsite.h 2018-03-01 07:56:38 +0000
633@@ -72,7 +72,7 @@
634 public:
635 ConstructionSiteDescr(const std::string& init_descname,
636 const LuaTable& t,
637- const EditorGameBase& egbase);
638+ EditorGameBase* egbase);
639 ~ConstructionSiteDescr() override {
640 }
641
642
643=== modified file 'src/logic/map_objects/tribes/dismantlesite.cc'
644--- src/logic/map_objects/tribes/dismantlesite.cc 2017-12-17 17:47:34 +0000
645+++ src/logic/map_objects/tribes/dismantlesite.cc 2018-03-01 07:56:38 +0000
646@@ -45,7 +45,7 @@
647
648 DismantleSiteDescr::DismantleSiteDescr(const std::string& init_descname,
649 const LuaTable& table,
650- const EditorGameBase& egbase)
651+ EditorGameBase* egbase)
652 : BuildingDescr(init_descname, MapObjectType::DISMANTLESITE, table, egbase) {
653 add_attribute(MapObject::Attribute::CONSTRUCTIONSITE); // Yep, this is correct.
654 }
655
656=== modified file 'src/logic/map_objects/tribes/dismantlesite.h'
657--- src/logic/map_objects/tribes/dismantlesite.h 2017-08-18 17:32:16 +0000
658+++ src/logic/map_objects/tribes/dismantlesite.h 2018-03-01 07:56:38 +0000
659@@ -47,7 +47,7 @@
660 public:
661 DismantleSiteDescr(const std::string& init_descname,
662 const LuaTable& t,
663- const EditorGameBase& egbase);
664+ EditorGameBase* egbase);
665 ~DismantleSiteDescr() override {
666 }
667
668
669=== modified file 'src/logic/map_objects/tribes/market.cc'
670--- src/logic/map_objects/tribes/market.cc 2017-10-04 00:27:47 +0000
671+++ src/logic/map_objects/tribes/market.cc 2018-03-01 07:56:38 +0000
672@@ -29,12 +29,12 @@
673
674 MarketDescr::MarketDescr(const std::string& init_descname,
675 const LuaTable& table,
676- const EditorGameBase& egbase)
677+ EditorGameBase* egbase)
678 : BuildingDescr(init_descname, MapObjectType::MARKET, table, egbase) {
679 i18n::Textdomain td("tribes");
680
681- DescriptionIndex const woi = egbase.tribes().worker_index(table.get_string("carrier"));
682- if (!egbase.tribes().worker_exists(woi)) {
683+ DescriptionIndex const woi = egbase->tribes().worker_index(table.get_string("carrier"));
684+ if (!egbase->tribes().worker_exists(woi)) {
685 throw wexception("The tribe does not define the worker in 'carrier'.");
686 }
687 carrier_ = woi;
688
689=== modified file 'src/logic/map_objects/tribes/market.h'
690--- src/logic/map_objects/tribes/market.h 2017-10-04 00:27:47 +0000
691+++ src/logic/map_objects/tribes/market.h 2018-03-01 07:56:38 +0000
692@@ -30,7 +30,7 @@
693
694 class MarketDescr : public BuildingDescr {
695 public:
696- MarketDescr(const std::string& init_descname, const LuaTable& t, const EditorGameBase& egbase);
697+ MarketDescr(const std::string& init_descname, const LuaTable& t, EditorGameBase* egbase);
698 ~MarketDescr() override {
699 }
700
701
702=== modified file 'src/logic/map_objects/tribes/militarysite.cc'
703--- src/logic/map_objects/tribes/militarysite.cc 2017-11-30 10:59:06 +0000
704+++ src/logic/map_objects/tribes/militarysite.cc 2018-03-01 07:56:38 +0000
705@@ -295,7 +295,7 @@
706 */
707 MilitarySiteDescr::MilitarySiteDescr(const std::string& init_descname,
708 const LuaTable& table,
709- const EditorGameBase& egbase)
710+ EditorGameBase* egbase)
711 : BuildingDescr(init_descname, MapObjectType::MILITARYSITE, table, egbase),
712 conquer_radius_(0),
713 num_soldiers_(0),
714
715=== modified file 'src/logic/map_objects/tribes/militarysite.h'
716--- src/logic/map_objects/tribes/militarysite.h 2017-11-26 14:44:23 +0000
717+++ src/logic/map_objects/tribes/militarysite.h 2018-03-01 07:56:38 +0000
718@@ -45,7 +45,7 @@
719 public:
720 MilitarySiteDescr(const std::string& init_descname,
721 const LuaTable& t,
722- const EditorGameBase& egbase);
723+ EditorGameBase* egbase);
724 ~MilitarySiteDescr() override {
725 }
726
727
728=== modified file 'src/logic/map_objects/tribes/production_program.cc'
729--- src/logic/map_objects/tribes/production_program.cc 2017-12-02 11:41:19 +0000
730+++ src/logic/map_objects/tribes/production_program.cc 2018-03-01 07:56:38 +0000
731@@ -141,7 +141,7 @@
732 }
733 }
734 return new ProductionProgram::ActReturn::EconomyNeedsWare(wareindex);
735- } else if (tribes.worker_exists(tribes.worker_index(type_name))) {
736+ } else if (tribes.worker_exists(type_name)) {
737 const DescriptionIndex& workerindex = tribes.worker_index(type_name);
738 for (int i = 0; i < static_cast<int>(tribes.nrtribes()); ++i) {
739 const TribeDescr* tribe_descr = tribes.get_tribe_descr(i);
740
741=== modified file 'src/logic/map_objects/tribes/productionsite.cc'
742--- src/logic/map_objects/tribes/productionsite.cc 2017-09-15 19:45:11 +0000
743+++ src/logic/map_objects/tribes/productionsite.cc 2018-03-01 07:56:38 +0000
744@@ -90,7 +90,7 @@
745 const std::string& msgctxt,
746 MapObjectType init_type,
747 const LuaTable& table,
748- const EditorGameBase& egbase)
749+ EditorGameBase* egbase)
750 : BuildingDescr(init_descname, init_type, table, egbase),
751 out_of_resource_productivity_threshold_(100) {
752 i18n::Textdomain td("tribes");
753@@ -113,15 +113,15 @@
754 if (table.has_key("outputs")) {
755 for (const std::string& output : table.get_table("outputs")->array_entries<std::string>()) {
756 try {
757- DescriptionIndex idx = egbase.tribes().ware_index(output);
758- if (egbase.tribes().ware_exists(idx)) {
759+ DescriptionIndex idx = egbase->tribes().ware_index(output);
760+ if (egbase->tribes().ware_exists(idx)) {
761 if (output_ware_types_.count(idx)) {
762 throw wexception("this ware type has already been declared as an output");
763 }
764 output_ware_types_.insert(idx);
765 } else {
766- idx = egbase.tribes().worker_index(output);
767- if (egbase.tribes().worker_exists(idx)) {
768+ idx = egbase->tribes().worker_index(output);
769+ if (egbase->tribes().worker_exists(idx)) {
770 if (output_worker_types_.count(idx)) {
771 throw wexception("this worker type has already been declared as an output");
772 }
773@@ -146,8 +146,8 @@
774 if (amount < 1 || 255 < amount) {
775 throw wexception("amount is out of range 1 .. 255");
776 }
777- DescriptionIndex idx = egbase.tribes().ware_index(ware_name);
778- if (egbase.tribes().ware_exists(idx)) {
779+ DescriptionIndex idx = egbase->tribes().ware_index(ware_name);
780+ if (egbase->tribes().ware_exists(idx)) {
781 for (const auto& temp_inputs : input_wares()) {
782 if (temp_inputs.first == idx) {
783 throw wexception("duplicated");
784@@ -155,8 +155,8 @@
785 }
786 input_wares_.push_back(WareAmount(idx, amount));
787 } else {
788- idx = egbase.tribes().worker_index(ware_name);
789- if (egbase.tribes().worker_exists(idx)) {
790+ idx = egbase->tribes().worker_index(ware_name);
791+ if (egbase->tribes().worker_exists(idx)) {
792 for (const auto& temp_inputs : input_workers()) {
793 if (temp_inputs.first == idx) {
794 throw wexception("duplicated");
795@@ -173,7 +173,7 @@
796 }
797 }
798
799- parse_working_positions(egbase, table.get_table("working_positions").get(), &working_positions_);
800+ parse_working_positions(*egbase, table.get_table("working_positions").get(), &working_positions_);
801
802 // Get programs
803 items_table = table.get_table("programs");
804@@ -193,7 +193,7 @@
805 program_descname = pgettext_expr(msgctxt.c_str(), program_descname_unlocalized.c_str());
806 }
807 programs_[program_name] = std::unique_ptr<ProductionProgram>(new ProductionProgram(
808- program_name, program_descname, program_table->get_table("actions"), egbase, this));
809+ program_name, program_descname, program_table->get_table("actions"), *egbase, this));
810 } catch (const std::exception& e) {
811 throw wexception("program %s: %s", program_name.c_str(), e.what());
812 }
813@@ -203,7 +203,7 @@
814 ProductionSiteDescr::ProductionSiteDescr(const std::string& init_descname,
815 const std::string& msgctxt,
816 const LuaTable& table,
817- const EditorGameBase& egbase)
818+ EditorGameBase* egbase)
819 : ProductionSiteDescr(init_descname, msgctxt, MapObjectType::PRODUCTIONSITE, table, egbase) {
820 }
821
822
823=== modified file 'src/logic/map_objects/tribes/productionsite.h'
824--- src/logic/map_objects/tribes/productionsite.h 2017-11-26 14:44:23 +0000
825+++ src/logic/map_objects/tribes/productionsite.h 2018-03-01 07:56:38 +0000
826@@ -63,11 +63,11 @@
827 const std::string& msgctxt,
828 MapObjectType type,
829 const LuaTable& t,
830- const EditorGameBase& egbase);
831+ EditorGameBase* egbase);
832 ProductionSiteDescr(const std::string& init_descname,
833 const std::string& msgctxt,
834 const LuaTable& t,
835- const EditorGameBase& egbase);
836+ EditorGameBase* egbase);
837
838 Building& create_object() const override;
839
840
841=== modified file 'src/logic/map_objects/tribes/soldier.cc'
842--- src/logic/map_objects/tribes/soldier.cc 2017-12-17 17:47:34 +0000
843+++ src/logic/map_objects/tribes/soldier.cc 2018-03-01 07:56:38 +0000
844@@ -63,7 +63,7 @@
845
846 SoldierDescr::SoldierDescr(const std::string& init_descname,
847 const LuaTable& table,
848- const EditorGameBase& egbase)
849+ EditorGameBase* egbase)
850 : WorkerDescr(init_descname, MapObjectType::SOLDIER, table, egbase),
851 health_(table.get_table("health")),
852 attack_(table.get_table("attack")),
853
854=== modified file 'src/logic/map_objects/tribes/soldier.h'
855--- src/logic/map_objects/tribes/soldier.h 2017-06-24 08:47:46 +0000
856+++ src/logic/map_objects/tribes/soldier.h 2018-03-01 07:56:38 +0000
857@@ -41,7 +41,7 @@
858 public:
859 friend class Economy;
860
861- SoldierDescr(const std::string& init_descname, const LuaTable& t, const EditorGameBase& egbase);
862+ SoldierDescr(const std::string& init_descname, const LuaTable& t, EditorGameBase* egbase);
863 ~SoldierDescr() override {
864 }
865
866
867=== modified file 'src/logic/map_objects/tribes/trainingsite.cc'
868--- src/logic/map_objects/tribes/trainingsite.cc 2017-11-09 17:37:13 +0000
869+++ src/logic/map_objects/tribes/trainingsite.cc 2018-03-01 07:56:38 +0000
870@@ -47,7 +47,7 @@
871 */
872 TrainingSiteDescr::TrainingSiteDescr(const std::string& init_descname,
873 const LuaTable& table,
874- const EditorGameBase& egbase)
875+ EditorGameBase* egbase)
876 : ProductionSiteDescr(init_descname, "", MapObjectType::TRAININGSITE, table, egbase),
877 num_soldiers_(table.get_int("soldier_capacity")),
878 max_stall_(table.get_int("trainer_patience")),
879
880=== modified file 'src/logic/map_objects/tribes/trainingsite.h'
881--- src/logic/map_objects/tribes/trainingsite.h 2017-06-25 19:12:30 +0000
882+++ src/logic/map_objects/tribes/trainingsite.h 2018-03-01 07:56:38 +0000
883@@ -35,7 +35,7 @@
884 public:
885 TrainingSiteDescr(const std::string& init_descname,
886 const LuaTable& table,
887- const EditorGameBase& egbase);
888+ EditorGameBase* egbase);
889 ~TrainingSiteDescr() override {
890 }
891
892
893=== modified file 'src/logic/map_objects/tribes/tribe_descr.h'
894--- src/logic/map_objects/tribes/tribe_descr.h 2018-01-10 16:21:50 +0000
895+++ src/logic/map_objects/tribes/tribe_descr.h 2018-03-01 07:56:38 +0000
896@@ -162,6 +162,8 @@
897 void add_building(const std::string& buildingname);
898
899 private:
900+ void calculate_trainingsites_proportions();
901+
902 // Helper function for adding a special worker type (carriers etc.)
903 DescriptionIndex add_special_worker(const std::string& workername);
904 // Helper function for adding a special building type (port etc.)
905
906=== modified file 'src/logic/map_objects/tribes/tribes.cc'
907--- src/logic/map_objects/tribes/tribes.cc 2017-12-03 10:28:16 +0000
908+++ src/logic/map_objects/tribes/tribes.cc 2018-03-01 07:56:38 +0000
909@@ -34,31 +34,32 @@
910 ships_(new DescriptionMaintainer<ShipDescr>()),
911 wares_(new DescriptionMaintainer<WareDescr>()),
912 workers_(new DescriptionMaintainer<WorkerDescr>()),
913- tribes_(new DescriptionMaintainer<TribeDescr>()) {
914+ tribes_(new DescriptionMaintainer<TribeDescr>()),
915+ postload_data_(new PostloadData()) {
916 }
917
918-void Tribes::add_constructionsite_type(const LuaTable& table, const EditorGameBase& egbase) {
919+void Tribes::add_constructionsite_type(const LuaTable& table, EditorGameBase* egbase) {
920 i18n::Textdomain td("tribes");
921 buildings_->add(new ConstructionSiteDescr(
922 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
923 table, egbase));
924 }
925
926-void Tribes::add_dismantlesite_type(const LuaTable& table, const EditorGameBase& egbase) {
927+void Tribes::add_dismantlesite_type(const LuaTable& table, EditorGameBase* egbase) {
928 i18n::Textdomain td("tribes");
929 buildings_->add(new DismantleSiteDescr(
930 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
931 table, egbase));
932 }
933
934-void Tribes::add_militarysite_type(const LuaTable& table, const EditorGameBase& egbase) {
935+void Tribes::add_militarysite_type(const LuaTable& table, EditorGameBase* egbase) {
936 i18n::Textdomain td("tribes");
937 buildings_->add(new MilitarySiteDescr(
938 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
939 table, egbase));
940 }
941
942-void Tribes::add_productionsite_type(const LuaTable& table, const EditorGameBase& egbase) {
943+void Tribes::add_productionsite_type(const LuaTable& table, EditorGameBase* egbase) {
944 i18n::Textdomain td("tribes");
945 const std::string msgctxt = table.get_string("msgctxt");
946 buildings_->add(
947@@ -66,21 +67,21 @@
948 msgctxt, table, egbase));
949 }
950
951-void Tribes::add_trainingsite_type(const LuaTable& table, const EditorGameBase& egbase) {
952+void Tribes::add_trainingsite_type(const LuaTable& table, EditorGameBase* egbase) {
953 i18n::Textdomain td("tribes");
954 buildings_->add(new TrainingSiteDescr(
955 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
956 table, egbase));
957 }
958
959-void Tribes::add_warehouse_type(const LuaTable& table, const EditorGameBase& egbase) {
960+void Tribes::add_warehouse_type(const LuaTable& table, EditorGameBase* egbase) {
961 i18n::Textdomain td("tribes");
962 buildings_->add(new WarehouseDescr(
963 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
964 table, egbase));
965 }
966
967-void Tribes::add_market_type(const LuaTable& table, const EditorGameBase& egbase) {
968+void Tribes::add_market_type(const LuaTable& table, EditorGameBase* egbase) {
969 i18n::Textdomain td("tribes");
970 buildings_->add(new MarketDescr(
971 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
972@@ -106,21 +107,21 @@
973 table));
974 }
975
976-void Tribes::add_carrier_type(const LuaTable& table, const EditorGameBase& egbase) {
977+void Tribes::add_carrier_type(const LuaTable& table, EditorGameBase* egbase) {
978 i18n::Textdomain td("tribes");
979 workers_->add(new CarrierDescr(
980 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
981 table, egbase));
982 }
983
984-void Tribes::add_soldier_type(const LuaTable& table, const EditorGameBase& egbase) {
985+void Tribes::add_soldier_type(const LuaTable& table, EditorGameBase* egbase) {
986 i18n::Textdomain td("tribes");
987 workers_->add(new SoldierDescr(
988 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
989 table, egbase));
990 }
991
992-void Tribes::add_worker_type(const LuaTable& table, const EditorGameBase& egbase) {
993+void Tribes::add_worker_type(const LuaTable& table, EditorGameBase* egbase) {
994 i18n::Textdomain td("tribes");
995 workers_->add(new WorkerDescr(
996 pgettext_expr(table.get_string("msgctxt").c_str(), table.get_string("descname").c_str()),
997@@ -312,42 +313,96 @@
998 }
999 }
1000
1001+void Tribes::add_worker_buildcost(const WorkerBuildcost& buildcost) {
1002+ postload_data_->workers_buildcost_.push_back(buildcost);
1003+}
1004+
1005+void Tribes::add_mapobject_enhancement(const MapObjectEnhancement& becomes) {
1006+ postload_data_->mapobject_enhancements_.push_back(becomes);
1007+}
1008+
1009 void Tribes::postload() {
1010- for (DescriptionIndex i = 0; i < buildings_->size(); ++i) {
1011- BuildingDescr& building_descr = *buildings_->get_mutable(i);
1012-
1013- // Add consumers and producers to wares.
1014- if (upcast(ProductionSiteDescr, de, &building_descr)) {
1015- for (const auto& ware_amount : de->input_wares()) {
1016- wares_->get_mutable(ware_amount.first)->add_consumer(i);
1017- }
1018- for (const DescriptionIndex& wareindex : de->output_ware_types()) {
1019- wares_->get_mutable(wareindex)->add_producer(i);
1020- }
1021- for (const auto& job : de->working_positions()) {
1022- workers_->get_mutable(job.first)->add_employer(i);
1023- }
1024- }
1025-
1026- // Register which buildings buildings can have been enhanced from
1027- const DescriptionIndex& enhancement = building_descr.enhancement();
1028- if (building_exists(enhancement)) {
1029- buildings_->get_mutable(enhancement)->set_enhanced_from(i);
1030- }
1031- }
1032-
1033- // Calculate the trainingsites proportions.
1034- postload_calculate_trainingsites_proportions();
1035-
1036- // Resize the configuration of our wares if they won't fit in the current window (12 = info label
1037- // size).
1038- int number = (g_gr->get_yres() - 290) / (WARE_MENU_PIC_HEIGHT + WARE_MENU_PIC_PAD_Y + 12);
1039- for (DescriptionIndex i = 0; i < tribes_->size(); ++i) {
1040- TribeDescr* tribe_descr = tribes_->get_mutable(i);
1041- tribe_descr->resize_ware_orders(number);
1042- }
1043+ try {
1044+ // Some workers have other workers as build cost, so we postload those in order to perform the necessary checks.
1045+ for (const WorkerBuildcost& buildcost : postload_data_->workers_buildcost_) {
1046+ if (!worker_exists(buildcost.worker)) {
1047+ throw GameDataError(
1048+ "Trying to add a worker buildcost to non-existing worker '%s'", buildcost.worker.c_str());
1049+ }
1050+ workers_->get_mutable(safe_worker_index(buildcost.worker))->add_wareworker_to_buildcost(buildcost.needed_worker, buildcost.quantity);
1051+ }
1052+
1053+ // Likewise, more experienced workers and advanced buildings might not have been available yet when a lower-level worker or building was loaded.
1054+ for (const MapObjectEnhancement& enhancement : postload_data_->mapobject_enhancements_) {
1055+ switch (enhancement.type) {
1056+ case MapObjectType::BUILDING:
1057+ if (!building_exists(enhancement.name)) {
1058+ throw GameDataError(
1059+ "Trying to add a building enhancement to non-existing building '%s'", enhancement.name.c_str());
1060+ }
1061+ if (!building_exists(enhancement.enhanced_name)) {
1062+ throw GameDataError(
1063+ "The building '%s' to be added as enhancement to the building '%s' does not exist", enhancement.enhanced_name.c_str(), enhancement.name.c_str());
1064+ }
1065+ buildings_->get_mutable(safe_building_index(enhancement.name))->set_enhances_to(enhancement.enhanced_name);
1066+ break;
1067+ case MapObjectType::WORKER:
1068+ if (!worker_exists(enhancement.name)) {
1069+ throw GameDataError(
1070+ "Trying to add a worker enhancement to non-existing worker '%s'", enhancement.name.c_str());
1071+ }
1072+ if (!worker_exists(enhancement.enhanced_name)) {
1073+ throw GameDataError(
1074+ "The worker '%s' to be added as enhancement to the worker '%s' does not exist", enhancement.enhanced_name.c_str(), enhancement.name.c_str());
1075+ }
1076+ workers_->get_mutable(safe_worker_index(enhancement.name))->set_becomes(enhancement.enhanced_name);
1077+ break;
1078+ default:
1079+ NEVER_HERE();
1080+ }
1081+ }
1082+
1083+ // Add building info to wares here, since wares were loaded first.
1084+ for (DescriptionIndex i = 0; i < buildings_->size(); ++i) {
1085+ BuildingDescr& building_descr = *buildings_->get_mutable(i);
1086+
1087+ // Add consumers and producers to wares.
1088+ if (upcast(ProductionSiteDescr, de, &building_descr)) {
1089+ for (const auto& ware_amount : de->input_wares()) {
1090+ wares_->get_mutable(ware_amount.first)->add_consumer(i);
1091+ }
1092+ for (const DescriptionIndex& wareindex : de->output_ware_types()) {
1093+ wares_->get_mutable(wareindex)->add_producer(i);
1094+ }
1095+ for (const auto& job : de->working_positions()) {
1096+ workers_->get_mutable(job.first)->add_employer(i);
1097+ }
1098+ }
1099+
1100+ // Register which buildings buildings can have been enhanced from
1101+ const DescriptionIndex& enhancement = building_descr.enhancement();
1102+ if (building_exists(enhancement)) {
1103+ buildings_->get_mutable(enhancement)->set_enhanced_from(i);
1104+ }
1105+ }
1106+
1107+ // Calculate the trainingsites proportions.
1108+ postload_calculate_trainingsites_proportions();
1109+
1110+ // Resize the configuration of our wares if they won't fit in the current window (12 = info label
1111+ // size)
1112+ int number = (g_gr->get_yres() - 290) / (WARE_MENU_PIC_HEIGHT + WARE_MENU_PIC_PAD_Y + 12);
1113+ for (DescriptionIndex i = 0; i < tribes_->size(); ++i) {
1114+ tribes_->get_mutable(i)->resize_ware_orders(number);
1115+ }
1116+ } catch (const WException& e) {
1117+ throw GameDataError("Error during tribes postload: %s", e.what());
1118+ }
1119+
1120+ postload_data_.reset(new PostloadData());
1121 }
1122
1123+
1124 // Set default trainingsites proportions for AI. Make sure that we get a sum of ca. 100
1125 void Tribes::postload_calculate_trainingsites_proportions() {
1126 for (DescriptionIndex i = 0; i < tribes_->size(); ++i) {
1127
1128=== modified file 'src/logic/map_objects/tribes/tribes.h'
1129--- src/logic/map_objects/tribes/tribes.h 2017-12-02 12:43:38 +0000
1130+++ src/logic/map_objects/tribes/tribes.h 2018-03-01 07:56:38 +0000
1131@@ -53,25 +53,25 @@
1132 }
1133
1134 /// Adds this building type to the tribe description.
1135- void add_constructionsite_type(const LuaTable& table, const EditorGameBase& egbase);
1136-
1137- /// Adds this building type to the tribe description.
1138- void add_dismantlesite_type(const LuaTable& table, const EditorGameBase& egbase);
1139-
1140- /// Adds this building type to the tribe description.
1141- void add_militarysite_type(const LuaTable& table, const EditorGameBase& egbase);
1142-
1143- /// Adds this building type to the tribe description.
1144- void add_productionsite_type(const LuaTable& table, const EditorGameBase& egbase);
1145-
1146- /// Adds this building type to the tribe description.
1147- void add_trainingsite_type(const LuaTable& table, const EditorGameBase& egbase);
1148-
1149- /// Adds this building type to the tribe description.
1150- void add_warehouse_type(const LuaTable& table, const EditorGameBase& egbase);
1151-
1152- /// Adds this building type to the tribe description.
1153- void add_market_type(const LuaTable& table, const EditorGameBase& egbase);
1154+ void add_constructionsite_type(const LuaTable& table, EditorGameBase* egbase);
1155+
1156+ /// Adds this building type to the tribe description.
1157+ void add_dismantlesite_type(const LuaTable& table, EditorGameBase* egbase);
1158+
1159+ /// Adds this building type to the tribe description.
1160+ void add_militarysite_type(const LuaTable& table, EditorGameBase* egbase);
1161+
1162+ /// Adds this building type to the tribe description.
1163+ void add_productionsite_type(const LuaTable& table, EditorGameBase* egbase);
1164+
1165+ /// Adds this building type to the tribe description.
1166+ void add_trainingsite_type(const LuaTable& table, EditorGameBase* egbase);
1167+
1168+ /// Adds this building type to the tribe description.
1169+ void add_warehouse_type(const LuaTable& table, EditorGameBase* egbase);
1170+
1171+ /// Adds this building type to the tribe description.
1172+ void add_market_type(const LuaTable& table, EditorGameBase* egbase);
1173
1174 /// Adds this immovable type to the tribe description.
1175 void add_immovable_type(const LuaTable& table);
1176@@ -83,13 +83,13 @@
1177 void add_ware_type(const LuaTable& table);
1178
1179 /// Adds this worker type to the tribe description.
1180- void add_carrier_type(const LuaTable& table, const EditorGameBase& egbase);
1181-
1182- /// Adds this worker type to the tribe description.
1183- void add_soldier_type(const LuaTable& table, const EditorGameBase& egbase);
1184-
1185- /// Adds this worker type to the tribe description.
1186- void add_worker_type(const LuaTable& table, const EditorGameBase& egbase);
1187+ void add_carrier_type(const LuaTable& table, EditorGameBase* egbase);
1188+
1189+ /// Adds this worker type to the tribe description.
1190+ void add_soldier_type(const LuaTable& table, EditorGameBase* egbase);
1191+
1192+ /// Adds this worker type to the tribe description.
1193+ void add_worker_type(const LuaTable& table, EditorGameBase* egbase);
1194
1195 /// Adds a specific tribe's configuration.
1196 void add_tribe(const LuaTable& table, const EditorGameBase& egbase);
1197@@ -143,6 +143,22 @@
1198 /// Complete the Description objects' information with data from other Description objects.
1199 void postload();
1200
1201+ /// Some workers have other workers as part of their buildcost. If the other worker hasn't been loaded yet, it will need to be added during postload.
1202+ struct WorkerBuildcost {
1203+ const std::string worker;
1204+ const std::string needed_worker;
1205+ const Quantity quantity;
1206+ };
1207+ void add_worker_buildcost(const WorkerBuildcost& buildcost);
1208+
1209+ /// Enhanced buildings/workers might not have been loaded yet when a more basic type is being loaded, so we will need to add some of them during postload.
1210+ struct MapObjectEnhancement {
1211+ const MapObjectType type; // Worker or building
1212+ const std::string name;
1213+ const std::string enhanced_name;
1214+ };
1215+ void add_mapobject_enhancement(const MapObjectEnhancement& becomes);
1216+
1217 private:
1218 void postload_calculate_trainingsites_proportions();
1219
1220@@ -153,6 +169,17 @@
1221 std::unique_ptr<DescriptionMaintainer<WorkerDescr>> workers_;
1222 std::unique_ptr<DescriptionMaintainer<TribeDescr>> tribes_;
1223
1224+ struct PostloadData {
1225+ /// Worker buildcost records to be added in postload.
1226+ std::vector<WorkerBuildcost> workers_buildcost_;
1227+ /// Worker/Building enhancement records to be added in postload.
1228+ std::vector<MapObjectEnhancement> mapobject_enhancements_;
1229+
1230+ };
1231+
1232+ /// Records to be added in postload. This will be empty after postload.
1233+ std::unique_ptr<PostloadData> postload_data_;
1234+
1235 DISALLOW_COPY_AND_ASSIGN(Tribes);
1236 };
1237
1238
1239=== modified file 'src/logic/map_objects/tribes/warehouse.cc'
1240--- src/logic/map_objects/tribes/warehouse.cc 2017-08-30 12:06:20 +0000
1241+++ src/logic/map_objects/tribes/warehouse.cc 2018-03-01 07:56:38 +0000
1242@@ -292,7 +292,7 @@
1243 */
1244 WarehouseDescr::WarehouseDescr(const std::string& init_descname,
1245 const LuaTable& table,
1246- const EditorGameBase& egbase)
1247+ EditorGameBase* egbase)
1248 : BuildingDescr(init_descname, MapObjectType::WAREHOUSE, table, egbase),
1249 conquers_(0),
1250 heal_per_second_(0) {
1251
1252=== modified file 'src/logic/map_objects/tribes/warehouse.h'
1253--- src/logic/map_objects/tribes/warehouse.h 2017-11-26 14:44:23 +0000
1254+++ src/logic/map_objects/tribes/warehouse.h 2018-03-01 07:56:38 +0000
1255@@ -50,7 +50,7 @@
1256 public:
1257 WarehouseDescr(const std::string& init_descname,
1258 const LuaTable& t,
1259- const EditorGameBase& egbase);
1260+ EditorGameBase* egbase);
1261 ~WarehouseDescr() override {
1262 }
1263
1264
1265=== modified file 'src/logic/map_objects/tribes/worker_descr.cc'
1266--- src/logic/map_objects/tribes/worker_descr.cc 2017-11-12 16:30:35 +0000
1267+++ src/logic/map_objects/tribes/worker_descr.cc 2018-03-01 07:56:38 +0000
1268@@ -38,12 +38,12 @@
1269 WorkerDescr::WorkerDescr(const std::string& init_descname,
1270 MapObjectType init_type,
1271 const LuaTable& table,
1272- const EditorGameBase& egbase)
1273+ EditorGameBase* egbase)
1274 : BobDescr(init_descname, init_type, MapObjectDescr::OwnerType::kTribe, table),
1275 buildable_(false),
1276 needed_experience_(INVALID_INDEX),
1277 becomes_(INVALID_INDEX),
1278- egbase_(egbase) {
1279+ egbase_(*egbase) {
1280 if (helptext_script().empty()) {
1281 throw GameDataError("Worker %s has no helptext script", name().c_str());
1282 }
1283@@ -59,21 +59,17 @@
1284 items_table = table.get_table("buildcost");
1285 for (const std::string& key : items_table->keys<std::string>()) {
1286 try {
1287- if (buildcost_.count(key)) {
1288- throw GameDataError(
1289- "a buildcost item of this ware type has already been defined: %s", key.c_str());
1290- }
1291- if (!tribes.ware_exists(tribes.ware_index(key)) &&
1292- !tribes.worker_exists(tribes.worker_index(key))) {
1293- throw GameDataError("\"%s\" has not been defined as a ware/worker type (wrong "
1294- "declaration order?)",
1295- key.c_str());
1296- }
1297- int32_t value = items_table->get_int(key);
1298- uint8_t const count = value;
1299- if (count != value)
1300+ int32_t temp_quantity = items_table->get_int(key);
1301+ const uint8_t quantity = temp_quantity;
1302+ if (quantity != temp_quantity) {
1303 throw GameDataError("count is out of range 1 .. 255");
1304- buildcost_.insert(std::pair<std::string, uint8_t>(key, count));
1305+ }
1306+ if (tribes.ware_exists(key)) {
1307+ add_wareworker_to_buildcost(key, quantity);
1308+ } else {
1309+ // The buildcost's worker might not have been loaded yet, so we'll try this again in postload.
1310+ egbase->mutable_tribes()->add_worker_buildcost({name(), key, quantity});
1311+ }
1312 } catch (const WException& e) {
1313 throw GameDataError("[buildcost] \"%s\": %s", key.c_str(), e.what());
1314 }
1315@@ -92,8 +88,9 @@
1316
1317 // Read what the worker can become and the needed experience
1318 if (table.has_key("becomes")) {
1319- becomes_ = egbase_.tribes().safe_worker_index(table.get_string("becomes"));
1320 needed_experience_ = table.get_int("experience");
1321+ // The expert worker might not have been loaded yet, so we'll do this in postload.
1322+ egbase->mutable_tribes()->add_mapobject_enhancement({MapObjectType::WORKER, name(), table.get_string("becomes")});
1323 }
1324
1325 // Read programs
1326@@ -123,13 +120,30 @@
1327
1328 WorkerDescr::WorkerDescr(const std::string& init_descname,
1329 const LuaTable& table,
1330- const EditorGameBase& egbase)
1331+ EditorGameBase* egbase)
1332 : WorkerDescr(init_descname, MapObjectType::WORKER, table, egbase) {
1333 }
1334
1335 WorkerDescr::~WorkerDescr() {
1336 }
1337
1338+void WorkerDescr::add_wareworker_to_buildcost(const std::string& ww_name, uint8_t quantity) {
1339+ if (buildcost_.count(ww_name) != 0) {
1340+ throw GameDataError("\"%s\" already exists as build cost for %s", ww_name.c_str(), name().c_str());
1341+ }
1342+ if (!egbase_.tribes().ware_exists(ww_name) && !egbase_.tribes().worker_exists(ww_name)) {
1343+ throw GameDataError("\"%s\" has not been defined as a ware/worker type (wrong "
1344+ "declaration order?) while loading %s",
1345+ ww_name.c_str(), name().c_str());
1346+ }
1347+ buildcost_.insert(std::make_pair(ww_name, quantity));
1348+}
1349+
1350+void WorkerDescr::set_becomes(const std::string& becomes_name) {
1351+ assert(needed_experience_ > 0 && needed_experience_ != INVALID_INDEX);
1352+ becomes_ = egbase_.tribes().safe_worker_index(becomes_name);
1353+}
1354+
1355 /**
1356 * Get a program from the workers description.
1357 */
1358
1359=== modified file 'src/logic/map_objects/tribes/worker_descr.h'
1360--- src/logic/map_objects/tribes/worker_descr.h 2017-11-12 14:54:46 +0000
1361+++ src/logic/map_objects/tribes/worker_descr.h 2018-03-01 07:56:38 +0000
1362@@ -43,13 +43,13 @@
1363 friend struct WorkerProgram;
1364
1365 public:
1366- using Buildcost = std::map<std::string, Quantity>;
1367+ using Buildcost = std::map<std::string, uint8_t>;
1368
1369 WorkerDescr(const std::string& init_descname,
1370 MapObjectType type,
1371 const LuaTable& table,
1372- const EditorGameBase& egbase);
1373- WorkerDescr(const std::string& init_descname, const LuaTable& t, const EditorGameBase& egbase);
1374+ EditorGameBase* egbase);
1375+ WorkerDescr(const std::string& init_descname, const LuaTable& t, EditorGameBase* egbase);
1376 ~WorkerDescr() override;
1377
1378 Bob& create_object() const override;
1379@@ -62,6 +62,14 @@
1380 return buildcost_;
1381 }
1382
1383+ /// Some workers need to be added to the buildcost in postload, because the other worker might not have been loaded into the engine yet.
1384+ /// 'name' is the descr().name() of the other worker, 'quantity' is the amount of that woker type needed.
1385+ void add_wareworker_to_buildcost(const std::string& name, uint8_t quantity);
1386+
1387+ /// Sets the descr().name() of the worker that this worker will enhance to, given enough experience.
1388+ /// 'needed_experience_' needs to be set first.
1389+ void set_becomes(const std::string& name);
1390+
1391 /// How much of the worker type that an economy should store in warehouses.
1392 /// The special value std::numeric_limits<uint32_t>::max() means that the
1393 /// the target quantity of this ware type will never be checked and should
1394
1395=== modified file 'src/scripting/lua_root.cc'
1396--- src/scripting/lua_root.cc 2017-11-25 18:29:22 +0000
1397+++ src/scripting/lua_root.cc 2018-03-01 07:56:38 +0000
1398@@ -564,8 +564,8 @@
1399
1400 try {
1401 LuaTable table(L); // Will pop the table eventually.
1402- EditorGameBase& egbase = get_egbase(L);
1403- egbase.mutable_tribes()->add_constructionsite_type(table, egbase);
1404+ EditorGameBase* egbase = &get_egbase(L);
1405+ egbase->mutable_tribes()->add_constructionsite_type(table, egbase);
1406 } catch (std::exception& e) {
1407 report_error(L, "%s", e.what());
1408 }
1409@@ -588,8 +588,8 @@
1410
1411 try {
1412 LuaTable table(L); // Will pop the table eventually.
1413- EditorGameBase& egbase = get_egbase(L);
1414- egbase.mutable_tribes()->add_dismantlesite_type(table, egbase);
1415+ EditorGameBase* egbase = &get_egbase(L);
1416+ egbase->mutable_tribes()->add_dismantlesite_type(table, egbase);
1417 } catch (std::exception& e) {
1418 report_error(L, "%s", e.what());
1419 }
1420@@ -612,8 +612,8 @@
1421
1422 try {
1423 LuaTable table(L); // Will pop the table eventually.
1424- EditorGameBase& egbase = get_egbase(L);
1425- egbase.mutable_tribes()->add_militarysite_type(table, egbase);
1426+ EditorGameBase* egbase = &get_egbase(L);
1427+ egbase->mutable_tribes()->add_militarysite_type(table, egbase);
1428 } catch (std::exception& e) {
1429 report_error(L, "%s", e.what());
1430 }
1431@@ -636,8 +636,8 @@
1432
1433 try {
1434 LuaTable table(L); // Will pop the table eventually.
1435- EditorGameBase& egbase = get_egbase(L);
1436- egbase.mutable_tribes()->add_productionsite_type(table, egbase);
1437+ EditorGameBase* egbase = &get_egbase(L);
1438+ egbase->mutable_tribes()->add_productionsite_type(table, egbase);
1439 } catch (std::exception& e) {
1440 report_error(L, "%s", e.what());
1441 }
1442@@ -660,8 +660,8 @@
1443
1444 try {
1445 LuaTable table(L); // Will pop the table eventually.
1446- EditorGameBase& egbase = get_egbase(L);
1447- egbase.mutable_tribes()->add_trainingsite_type(table, egbase);
1448+ EditorGameBase* egbase = &get_egbase(L);
1449+ egbase->mutable_tribes()->add_trainingsite_type(table, egbase);
1450 } catch (std::exception& e) {
1451 report_error(L, "%s", e.what());
1452 }
1453@@ -684,8 +684,8 @@
1454
1455 try {
1456 LuaTable table(L); // Will pop the table eventually.
1457- EditorGameBase& egbase = get_egbase(L);
1458- egbase.mutable_tribes()->add_warehouse_type(table, egbase);
1459+ EditorGameBase* egbase = &get_egbase(L);
1460+ egbase->mutable_tribes()->add_warehouse_type(table, egbase);
1461 } catch (std::exception& e) {
1462 report_error(L, "%s", e.what());
1463 }
1464@@ -708,8 +708,8 @@
1465
1466 try {
1467 LuaTable table(L); // Will pop the table eventually.
1468- EditorGameBase& egbase = get_egbase(L);
1469- egbase.mutable_tribes()->add_market_type(table, egbase);
1470+ EditorGameBase* egbase = &get_egbase(L);
1471+ egbase->mutable_tribes()->add_market_type(table, egbase);
1472 } catch (std::exception& e) {
1473 report_error(L, "%s", e.what());
1474 }
1475@@ -800,8 +800,8 @@
1476
1477 try {
1478 LuaTable table(L); // Will pop the table eventually.
1479- EditorGameBase& egbase = get_egbase(L);
1480- egbase.mutable_tribes()->add_carrier_type(table, egbase);
1481+ EditorGameBase* egbase = &get_egbase(L);
1482+ egbase->mutable_tribes()->add_carrier_type(table, egbase);
1483 } catch (std::exception& e) {
1484 report_error(L, "%s", e.what());
1485 }
1486@@ -823,8 +823,8 @@
1487
1488 try {
1489 LuaTable table(L); // Will pop the table eventually.
1490- EditorGameBase& egbase = get_egbase(L);
1491- egbase.mutable_tribes()->add_soldier_type(table, egbase);
1492+ EditorGameBase* egbase = &get_egbase(L);
1493+ egbase->mutable_tribes()->add_soldier_type(table, egbase);
1494 } catch (std::exception& e) {
1495 report_error(L, "%s", e.what());
1496 }
1497@@ -846,8 +846,8 @@
1498
1499 try {
1500 LuaTable table(L); // Will pop the table eventually.
1501- EditorGameBase& egbase = get_egbase(L);
1502- egbase.mutable_tribes()->add_worker_type(table, egbase);
1503+ EditorGameBase* egbase = &get_egbase(L);
1504+ egbase->mutable_tribes()->add_worker_type(table, egbase);
1505 } catch (std::exception& e) {
1506 report_error(L, "%s", e.what());
1507 }

Subscribers

People subscribed via source and target branches

to status/vote changes: