Merge lp:~widelands-dev/widelands/bug-1751440-smugglers-desync-single-coroutine into lp:widelands

Proposed by GunChleoc
Status: Merged
Merged at revision: 8860
Proposed branch: lp:~widelands-dev/widelands/bug-1751440-smugglers-desync-single-coroutine
Merge into: lp:widelands
Diff against target: 620 lines (+431/-102)
4 files modified
data/maps/MP_Scenarios/Smugglers.wmf/scripting/multiplayer_init.lua (+34/-63)
data/maps/MP_Scenarios/Smugglers.wmf/scripting/smuggling.lua (+142/-38)
data/maps/MP_Scenarios/Smugglers.wmf/scripting/starting_conditions.lua (+254/-0)
src/scripting/lua_game.cc (+1/-1)
To merge this branch: bzr merge lp:~widelands-dev/widelands/bug-1751440-smugglers-desync-single-coroutine
Reviewer Review Type Date Requested Status
Klaus Halfmann compile, review, testplay (osx, win10, linux) Approve
Review via email: mp+354747@code.launchpad.net

Commit message

Fixed desync in the Smugglers scenario by using a single coroutine and selecting the wares round robin. The scenario can now be played with any tribe combination as soon as we implement the selection code in the UI.

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

For testing, hack the player_names packet and change the tribes there. You can also replace some players with empty AI if you don't want to run 4 instances of Widelands.

Revision history for this message
GunChleoc (gunchleoc) wrote :

There is also some NOCOM log output for testing that we need to delete before merging.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 3948. State: errored. Details: https://travis-ci.org/widelands/widelands/builds/427560056.
Appveyor build 3746. State: failed. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1751440_smugglers_desync_single_coroutine-3746.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 3974. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/428601743.
Appveyor build 3772. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_bug_1751440_smugglers_desync_single_coroutine-3772.

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

OK after cleaning my confusion about the two builds I will try a 2xWIN/ 2xOSX Smugglers game.

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

When trying to Debug WIndows I gita Problem with system.out, as described in: #1398536

I will try to debug this anyway ....

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

OK after cleaning my confusion about the two builds I will try a 2xWIN/ 2xOSX Smugglers game.
... some hours later ...
Did so and it was quite ok until I ran into #1794965 I think this is unrelated. But I may not be
able to continue testing. I will try other variants, later

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

Played this on OSX/localhost only, stating on the last save, no Issues.

Gun: perhpas we need som real world unreliable network to do more test?

I will try to come online this weekend perhpas we can do some smuggling?

Revision history for this message
Klaus Halfmann (klaus-halfmann) wrote :

Played this with kapputnik yesterday for about an hour or such.
We both finally got the Idea about the Map and how smuggling works :-)

We had no desnycs whatsover so this can go in.

Gun: Do you want to open Smugglers for all tribes in R20 or defer this?

@bunnybot merge

review: Approve (compile, review, testplay (osx, win10, linux))
Revision history for this message
GunChleoc (gunchleoc) wrote :

We need to defer opening this up for all tribes, because that needs further changes in the game setup logic.

Thanks for testing!

@bunnybot merge

Revision history for this message
GunChleoc (gunchleoc) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/maps/MP_Scenarios/Smugglers.wmf/scripting/multiplayer_init.lua'
2--- data/maps/MP_Scenarios/Smugglers.wmf/scripting/multiplayer_init.lua 2017-12-10 10:52:45 +0000
3+++ data/maps/MP_Scenarios/Smugglers.wmf/scripting/multiplayer_init.lua 2018-09-26 16:22:20 +0000
4@@ -17,19 +17,6 @@
5
6 points_to_win = 2000
7
8-route_descrs = {
9- { value = 2, send = map:get_field(35, 52):region(2), recv = map:get_field(96, 77):region(2) },
10- { value = 2, send = map:get_field(98, 55):region(2), recv = map:get_field(34, 76):region(2) },
11-
12- { value = 3, send = map:get_field(64, 57):region(2), recv = map:get_field(78, 73):region(2) },
13- { value = 3, send = map:get_field(77, 58):region(2), recv = map:get_field(65, 72):region(2) },
14-
15- { value = 2, send = map:get_field(62, 93):region(2), recv = map:get_field(78, 34):region(2) },
16- { value = 2, send = map:get_field(80, 95):region(2), recv = map:get_field(63, 29):region(2) },
17- { value = 2, send = map:get_field(18, 66):region(2), recv = map:get_field(121, 61):region(2) },
18- { value = 2, send = map:get_field(124, 72):region(2), recv = map:get_field(19, 57):region(2) }
19-}
20-
21 -- =================
22 -- Global Variables
23 -- =================
24@@ -41,66 +28,48 @@
25 -- ================
26 -- Initializations
27 -- ================
28+
29+-- If the tribes don't have any wares in common, nothing can be smuggled
30+-- This should not happen, but let's have a safeguard anyway.
31+function check_ware_compatiblity(player1, player2)
32+ local has_compatible_ware = false
33+ for idx,ware in pairs(player1.tribe.wares) do
34+ if player2.tribe:has_ware(ware.name) then
35+ has_compatible_ware = true
36+ break
37+ end
38+ end
39+ if not has_compatible_ware then
40+ do_game_over()
41+ end
42+end
43+
44 function assign_teams()
45 game.players[1].team = 1
46 game.players[2].team = 1
47 game.players[3].team = 2
48 game.players[4].team = 2
49+ check_ware_compatiblity(game.players[1], game.players[2])
50+ check_ware_compatiblity(game.players[3], game.players[4])
51 end
52
53 function place_headquarters()
54+ include "map:scripting/starting_conditions.lua"
55 for idx,player in ipairs(game.players) do
56 local sf = map.player_slots[player.number].starting_field
57-
58- prefilled_buildings(player, { "barbarians_headquarters", sf.x, sf.y,
59- wares = {
60- ax = 5,
61- bread_paddle = 2,
62- blackwood = 32,
63- cloth = 5,
64- coal = 12,
65- felling_ax = 4,
66- fire_tongs = 2,
67- fish = 6,
68- fishing_rod = 2,
69- gold = 4,
70- grout = 12,
71- hammer = 12,
72- hunting_spear = 2,
73- iron = 12,
74- iron_ore = 5,
75- kitchen_tools = 4,
76- meal = 4,
77- meat = 6,
78- pick = 14,
79- barbarians_bread = 8,
80- ration = 12,
81- granite = 40,
82- scythe = 6,
83- shovel = 4,
84- snack = 3,
85- thatch_reed = 24,
86- log = 80,
87- },
88- workers = {
89- barbarians_blacksmith = 2,
90- barbarians_brewer = 1,
91- barbarians_builder = 10,
92- barbarians_carrier = 40,
93- barbarians_charcoal_burner = 1,
94- barbarians_gardener = 1,
95- barbarians_geologist = 4,
96- barbarians_lime_burner = 1,
97- barbarians_lumberjack = 3,
98- barbarians_miner = 4,
99- barbarians_ranger = 1,
100- barbarians_stonemason = 2,
101- barbarians_ox = 5,
102- },
103- soldiers = {
104- [{0,0,0,0}] = 45,
105- }
106- })
107+ local tribename = player.tribe.name
108+ if tribename == "barbarians" then
109+ set_starting_conditions_barbarians(player, sf)
110+ elseif tribename == "empire" then
111+ set_starting_conditions_empire(player, sf)
112+ elseif tribename == "atlanteans" then
113+ set_starting_conditions_atlanteans(player, sf)
114+ elseif tribename == "frisians" then
115+ set_starting_conditions_frisians(player, sf)
116+ else
117+ print("We don't have starting conditions for tribe " .. tribename)
118+ do_game_over()
119+ end
120 end
121 end
122
123@@ -137,6 +106,8 @@
124 for idx,descr in ipairs(route_descrs) do
125 run(wait_for_established_route, descr)
126 end
127+
128+ do_smuggling()
129 end
130
131 setup_statistics_hook()
132
133=== modified file 'data/maps/MP_Scenarios/Smugglers.wmf/scripting/smuggling.lua'
134--- data/maps/MP_Scenarios/Smugglers.wmf/scripting/smuggling.lua 2016-03-26 09:09:43 +0000
135+++ data/maps/MP_Scenarios/Smugglers.wmf/scripting/smuggling.lua 2018-09-26 16:22:20 +0000
136@@ -4,6 +4,76 @@
137
138 include "scripting/messages.lua"
139
140+-- Init routes
141+route_descrs = {
142+ {
143+ value = 2,
144+ send = map:get_field(35, 52):region(2),
145+ recv = map:get_field(96, 77):region(2),
146+ sending_warehouse = nil,
147+ receiving_warehouse = nil,
148+ wares = {}
149+ },
150+ {
151+ value = 2,
152+ send = map:get_field(98, 55):region(2),
153+ recv = map:get_field(34, 76):region(2),
154+ sending_warehouse = nil,
155+ receiving_warehouse = nil,
156+ wares = {}
157+ },
158+
159+ {
160+ value = 3,
161+ send = map:get_field(64, 57):region(2),
162+ recv = map:get_field(78, 73):region(2),
163+ sending_warehouse = nil,
164+ receiving_warehouse = nil,
165+ wares = {}
166+ },
167+ {
168+ value = 3,
169+ send = map:get_field(77, 58):region(2),
170+ recv = map:get_field(65, 72):region(2),
171+ sending_warehouse = nil,
172+ receiving_warehouse = nil,
173+ wares = {}
174+ },
175+
176+ {
177+ value = 2,
178+ send = map:get_field(62, 93):region(2),
179+ recv = map:get_field(78, 34):region(2),
180+ sending_warehouse = nil,
181+ receiving_warehouse = nil,
182+ wares = {}
183+ },
184+ {
185+ value = 2,
186+ send = map:get_field(80, 95):region(2),
187+ recv = map:get_field(63, 29):region(2),
188+ sending_warehouse = nil,
189+ receiving_warehouse = nil,
190+ wares = {}
191+ },
192+ {
193+ value = 2,
194+ send = map:get_field(18, 66):region(2),
195+ recv = map:get_field(121, 61):region(2),
196+ sending_warehouse = nil,
197+ receiving_warehouse = nil,
198+ wares = {}
199+ },
200+ {
201+ value = 2,
202+ send = map:get_field(124, 72):region(2),
203+ recv = map:get_field(19, 57):region(2),
204+ sending_warehouse = nil,
205+ receiving_warehouse = nil,
206+ wares = {}
207+ }
208+}
209+
210 -- =================
211 -- Helper functions
212 -- =================
213@@ -35,56 +105,92 @@
214 game_over_done = true
215 end
216
217-function do_smuggling(route_descr, recv_plr, send_plr, recv_whf, send_whf)
218- while 1 do
219+function do_smuggling()
220+ while true do
221 sleep(10000) -- Sleep 10s
222-
223 if points[1] >= points_to_win or
224 points[2] >= points_to_win
225 then
226 do_game_over()
227- break
228- end
229-
230- if not send_whf.immovable or
231- send_whf.immovable.descr.type_name ~= "warehouse" or
232- send_whf.immovable.owner ~= send_plr or
233- not recv_whf.immovable or
234- recv_whf.immovable.descr.type_name ~= "warehouse" or
235- recv_whf.immovable.owner ~= recv_plr
236- then
237- send_to_all(smuggling_route_broken:bformat(
238- (ngettext("%i point", "%i points", route_descr.value)):format(route_descr.value), recv_plr.name, send_plr.name)
239- )
240- run(wait_for_established_route, route_descr)
241- break
242- end
243-
244- -- Warp one ware
245- local wares = send_whf.immovable:get_wares("all")
246- local wn = {}
247- for name,count in pairs(wares) do
248- if count > 0 then
249- wn[#wn + 1] = name
250+ return
251+ end
252+
253+ for idx, route_descr in ipairs(route_descrs) do
254+ if (route_descr.sending_warehouse ~= nil and route_descr.receiving_warehouse ~= nil) then
255+ print("NOCOM do smuggling for route " .. idx)
256+
257+ local send_plr = route_descr.sending_warehouse.owner
258+ local recv_plr = route_descr.receiving_warehouse.owner
259+ local send_whf = route_descr.sending_warehouse.fields[1]
260+ local recv_whf = route_descr.receiving_warehouse.fields[1]
261+
262+ -- Ensure that the warehouses are still there and owned by the same player
263+ if not send_whf.immovable or
264+ send_whf.immovable.descr.type_name ~= "warehouse" or
265+ send_whf.immovable.owner ~= send_plr or
266+ not recv_whf.immovable or
267+ recv_whf.immovable.descr.type_name ~= "warehouse" or
268+ recv_whf.immovable.owner ~= recv_plr
269+ then
270+ send_to_all(smuggling_route_broken:bformat(
271+ (ngettext("%i point", "%i points", route_descr.value)):format(route_descr.value), recv_plr.name, send_plr.name)
272+ )
273+ run(wait_for_established_route, route_descr)
274+ else
275+ -- Only use ware types that both sending and receiving player can use
276+ local wares = route_descr.wares
277+
278+ -- We start counting at 0 so that we can use the modulo (%) operator
279+ -- for going round robin
280+ local last_ware_index = 0;
281+
282+ -- Warp the next available ware, going round robin
283+ local empty_warehouse_guard = #wares
284+ local warp_index = last_ware_index
285+ while empty_warehouse_guard > 0 do
286+ -- Index shift, because Lua tables start counting at 1
287+ local ware_to_warp = wares[warp_index + 1]
288+ if send_whf.immovable:get_wares(ware_to_warp) > 0 then
289+ print("NOCOM Route " .. idx .. " (" .. send_whf.x .. ", " .. send_whf.y .. ") warping ware " .. ware_to_warp .. ": " .. send_plr.name .. " -> " .. recv_plr.name)
290+ send_whf.immovable:set_wares(ware_to_warp, send_whf.immovable:get_wares(ware_to_warp) - 1)
291+ recv_whf.immovable:set_wares(
292+ ware_to_warp, recv_whf.immovable:get_wares(ware_to_warp) + 1
293+ )
294+ points[recv_plr.team] = points[recv_plr.team] + route_descr.value
295+ break
296+ end
297+ warp_index = (warp_index + 1) % #wares;
298+ empty_warehouse_guard = empty_warehouse_guard - 1
299+ end
300+ -- Next round robin index
301+ last_ware_index = (last_ware_index + 1) % #wares;
302+ end
303 end
304 end
305- if #wn > 0 then
306- local ware_to_warp = wn[math.random(#wn)]
307- send_whf.immovable:set_wares(ware_to_warp, wares[ware_to_warp] - 1)
308- recv_whf.immovable:set_wares(
309- ware_to_warp, recv_whf.immovable:get_wares(ware_to_warp) + 1
310- )
311- points[recv_plr.team] = points[recv_plr.team] + route_descr.value
312- end
313 end
314 end
315
316 function wait_for_established_route(route_descr)
317 local receiving_wh, sending_wh
318- while 1 do
319+ route_descr.sending_warehouse = nil
320+ route_descr.receiving_warehouse = nil
321+ route_descr.wares = {}
322+
323+ while true do
324 receiving_wh = find_warehouse(route_descr.recv)
325 sending_wh = find_warehouse(route_descr.send)
326- if receiving_wh and sending_wh and receiving_wh.owner.team == sending_wh.owner.team then break end
327+ if receiving_wh and sending_wh and receiving_wh.owner.team == sending_wh.owner.team then
328+ route_descr.sending_warehouse = sending_wh
329+ route_descr.receiving_warehouse = receiving_wh
330+
331+ -- Collect ware types that both sending and receiving player can use
332+ for idx,ware in pairs(sending_wh.owner.tribe.wares) do
333+ if receiving_wh.owner.tribe:has_ware(ware.name) then
334+ table.insert(route_descr.wares, ware.name)
335+ end
336+ end
337+ break
338+ end
339 sleep(7138)
340 end
341
342@@ -104,6 +210,4 @@
343 send_message(sending_wh.owner, _"Status",
344 smuggling_route_established_sender:format(points), {popup=true, field=sending_wh.fields[1]}
345 )
346-
347- run(do_smuggling, route_descr, receiving_wh.owner, sending_wh.owner, receiving_wh.fields[1], sending_wh.fields[1])
348 end
349
350=== added file 'data/maps/MP_Scenarios/Smugglers.wmf/scripting/starting_conditions.lua'
351--- data/maps/MP_Scenarios/Smugglers.wmf/scripting/starting_conditions.lua 1970-01-01 00:00:00 +0000
352+++ data/maps/MP_Scenarios/Smugglers.wmf/scripting/starting_conditions.lua 2018-09-26 16:22:20 +0000
353@@ -0,0 +1,254 @@
354+-- Give the player a Barbarian headquarters
355+function set_starting_conditions_barbarians(player, sf)
356+ prefilled_buildings(player, { "barbarians_headquarters", sf.x, sf.y,
357+ wares = {
358+ ax = 5,
359+ bread_paddle = 2,
360+ blackwood = 32,
361+ cloth = 5,
362+ coal = 12,
363+ felling_ax = 4,
364+ fire_tongs = 2,
365+ fish = 6,
366+ fishing_rod = 2,
367+ gold = 4,
368+ grout = 12,
369+ hammer = 12,
370+ hunting_spear = 2,
371+ iron = 12,
372+ iron_ore = 5,
373+ kitchen_tools = 4,
374+ meal = 4,
375+ meat = 6,
376+ pick = 8,
377+ barbarians_bread = 8,
378+ ration = 12,
379+ granite = 40,
380+ scythe = 6,
381+ shovel = 4,
382+ snack = 3,
383+ thatch_reed = 24,
384+ log = 80,
385+ },
386+ workers = {
387+ barbarians_blacksmith = 2,
388+ barbarians_brewer = 1,
389+ barbarians_builder = 10,
390+ barbarians_charcoal_burner = 1,
391+ barbarians_carrier = 40,
392+ barbarians_gardener = 1,
393+ barbarians_geologist = 4,
394+ barbarians_lime_burner = 1,
395+ barbarians_lumberjack = 3,
396+ barbarians_miner = 4,
397+ barbarians_miner_master = 4,
398+ barbarians_ranger = 1,
399+ barbarians_stonemason = 2,
400+ barbarians_trainer = 3,
401+ barbarians_ox = 5,
402+ },
403+ soldiers = {
404+ [{0,0,0,0}] = 45,
405+ }
406+ })
407+end
408+
409+-- Give the player an Empire headquarters
410+function set_starting_conditions_empire(player, sf)
411+ prefilled_buildings(player, { "empire_headquarters", sf.x, sf.y,
412+ wares = {
413+ armor_helmet = 4,
414+ spear_wooden = 5,
415+ felling_ax = 6,
416+ bread_paddle = 2,
417+ basket = 2,
418+ empire_bread = 8,
419+ cloth = 5,
420+ coal = 12,
421+ fire_tongs = 2,
422+ fish = 6,
423+ fishing_rod = 2,
424+ flour = 4,
425+ gold = 4,
426+ grape = 4,
427+ hammer = 14,
428+ hunting_spear = 2,
429+ iron = 12,
430+ iron_ore = 5,
431+ kitchen_tools = 4,
432+ marble = 25,
433+ marble_column = 6,
434+ meal = 4,
435+ meat = 6,
436+ pick = 8,
437+ ration = 12,
438+ saw = 2,
439+ scythe = 5,
440+ shovel = 6,
441+ granite = 40,
442+ log = 30,
443+ water = 12,
444+ wheat = 4,
445+ wine = 8,
446+ planks = 45,
447+ wool = 2,
448+ },
449+ workers = {
450+ empire_armorsmith = 1,
451+ empire_brewer = 1,
452+ empire_builder = 10,
453+ empire_carrier = 40,
454+ empire_charcoal_burner = 1,
455+ empire_geologist = 4,
456+ empire_lumberjack = 3,
457+ empire_miner = 4,
458+ empire_stonemason = 2,
459+ empire_toolsmith = 2,
460+ empire_trainer = 3,
461+ empire_weaponsmith = 1,
462+ empire_donkey = 5,
463+ },
464+ soldiers = {
465+ [{0,0,0,0}] = 45,
466+ }
467+ })
468+end
469+
470+-- Give the player an Atlantean headquarters
471+function set_starting_conditions_atlanteans(player, sf)
472+ prefilled_buildings(player, { "atlanteans_headquarters", sf.x, sf.y,
473+ wares = {
474+ diamond = 7,
475+ iron_ore = 5,
476+ quartz = 9,
477+ granite = 50,
478+ spider_silk = 9,
479+ log = 20,
480+ coal = 12,
481+ gold = 4,
482+ gold_thread = 6,
483+ iron = 8,
484+ planks = 45,
485+ spidercloth = 5,
486+ blackroot = 5,
487+ blackroot_flour = 12,
488+ atlanteans_bread = 8,
489+ corn = 5,
490+ cornmeal = 12,
491+ fish = 3,
492+ meat = 3,
493+ smoked_fish = 6,
494+ smoked_meat = 6,
495+ water = 12,
496+ bread_paddle = 2,
497+ buckets = 2,
498+ fire_tongs = 2,
499+ fishing_net = 4,
500+ hammer = 11,
501+ hunting_bow = 1,
502+ milking_tongs = 2,
503+ hook_pole = 2,
504+ pick = 8,
505+ saw = 9,
506+ scythe = 4,
507+ shovel = 9,
508+ tabard = 5,
509+ trident_light = 5,
510+ },
511+ workers = {
512+ atlanteans_armorsmith = 1,
513+ atlanteans_blackroot_farmer = 1,
514+ atlanteans_builder = 10,
515+ atlanteans_charcoal_burner = 1,
516+ atlanteans_carrier = 40,
517+ atlanteans_fishbreeder = 1,
518+ atlanteans_geologist = 4,
519+ atlanteans_miner = 4,
520+ atlanteans_sawyer = 1,
521+ atlanteans_stonecutter = 2,
522+ atlanteans_toolsmith = 2,
523+ atlanteans_trainer = 3,
524+ atlanteans_weaponsmith = 1,
525+ atlanteans_woodcutter = 3,
526+ atlanteans_horse = 5,
527+ },
528+ soldiers = {
529+ [{0,0,0,0}] = 35,
530+ }
531+ })
532+end
533+
534+-- Give the player a Frisian headquarters
535+function set_starting_conditions_frisians(player, sf)
536+ prefilled_buildings(player, { "frisians_headquarters", sf.x, sf.y,
537+ wares = {
538+ log = 40,
539+ granite = 50,
540+ thatch_reed = 50,
541+ brick = 80,
542+ clay = 30,
543+ water = 10,
544+ fish = 10,
545+ meat = 10,
546+ fruit = 10,
547+ barley = 5,
548+ ration = 20,
549+ honey = 10,
550+ smoked_meat = 5,
551+ smoked_fish = 5,
552+ mead = 5,
553+ meal = 2,
554+ coal = 20,
555+ iron = 5,
556+ gold = 4,
557+ iron_ore = 10,
558+ bread_frisians = 15,
559+ honey_bread = 5,
560+ beer = 5,
561+ cloth = 5,
562+ fur = 10,
563+ fur_garment = 5,
564+ sword_short = 5,
565+ hammer = 5,
566+ fire_tongs = 2,
567+ bread_paddle = 2,
568+ kitchen_tools = 2,
569+ felling_ax = 3,
570+ needles = 2,
571+ basket = 2,
572+ pick = 5,
573+ shovel = 5,
574+ scythe = 3,
575+ hunting_spear = 2,
576+ fishing_net = 3,
577+ },
578+ workers = {
579+ frisians_blacksmith = 3,
580+ frisians_baker = 1,
581+ frisians_brewer = 1,
582+ frisians_builder = 10,
583+ frisians_charcoal_burner = 1,
584+ frisians_claydigger = 2,
585+ frisians_brickmaker = 2,
586+ frisians_carrier = 40,
587+ frisians_reed_farmer = 2,
588+ frisians_berry_farmer = 2,
589+ frisians_fruit_collector = 2,
590+ frisians_farmer = 1,
591+ frisians_landlady = 1,
592+ frisians_smoker = 1,
593+ frisians_geologist = 4,
594+ frisians_woodcutter = 3,
595+ frisians_beekeeper = 1,
596+ frisians_miner = 4,
597+ frisians_miner_master = 2,
598+ frisians_forester = 2,
599+ frisians_stonemason = 2,
600+ frisians_reindeer = 5,
601+ frisians_trainer = 3,
602+ },
603+ soldiers = {
604+ [{0,0,0,0}] = 45,
605+ }
606+ })
607+end
608
609=== modified file 'src/scripting/lua_game.cc'
610--- src/scripting/lua_game.cc 2018-07-28 19:08:34 +0000
611+++ src/scripting/lua_game.cc 2018-09-26 16:22:20 +0000
612@@ -851,7 +851,7 @@
613 /* RST
614 .. method:: produced_wares_count(what)
615
616- Returns count of wares produced byt the player up to now.
617+ Returns count of wares produced by the player up to now.
618 'what' can be either an "all" or single ware name or an array of names. If single
619 ware name is given, integer is returned, otherwise the table is returned.
620 */

Subscribers

People subscribed via source and target branches

to status/vote changes: