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
=== modified file 'data/maps/MP_Scenarios/Smugglers.wmf/scripting/multiplayer_init.lua'
--- data/maps/MP_Scenarios/Smugglers.wmf/scripting/multiplayer_init.lua 2017-12-10 10:52:45 +0000
+++ data/maps/MP_Scenarios/Smugglers.wmf/scripting/multiplayer_init.lua 2018-09-26 16:22:20 +0000
@@ -17,19 +17,6 @@
1717
18points_to_win = 200018points_to_win = 2000
1919
20route_descrs = {
21 { value = 2, send = map:get_field(35, 52):region(2), recv = map:get_field(96, 77):region(2) },
22 { value = 2, send = map:get_field(98, 55):region(2), recv = map:get_field(34, 76):region(2) },
23
24 { value = 3, send = map:get_field(64, 57):region(2), recv = map:get_field(78, 73):region(2) },
25 { value = 3, send = map:get_field(77, 58):region(2), recv = map:get_field(65, 72):region(2) },
26
27 { value = 2, send = map:get_field(62, 93):region(2), recv = map:get_field(78, 34):region(2) },
28 { value = 2, send = map:get_field(80, 95):region(2), recv = map:get_field(63, 29):region(2) },
29 { value = 2, send = map:get_field(18, 66):region(2), recv = map:get_field(121, 61):region(2) },
30 { value = 2, send = map:get_field(124, 72):region(2), recv = map:get_field(19, 57):region(2) }
31}
32
33-- =================20-- =================
34-- Global Variables21-- Global Variables
35-- =================22-- =================
@@ -41,66 +28,48 @@
41-- ================28-- ================
42-- Initializations29-- Initializations
43-- ================30-- ================
31
32-- If the tribes don't have any wares in common, nothing can be smuggled
33-- This should not happen, but let's have a safeguard anyway.
34function check_ware_compatiblity(player1, player2)
35 local has_compatible_ware = false
36 for idx,ware in pairs(player1.tribe.wares) do
37 if player2.tribe:has_ware(ware.name) then
38 has_compatible_ware = true
39 break
40 end
41 end
42 if not has_compatible_ware then
43 do_game_over()
44 end
45end
46
44function assign_teams()47function assign_teams()
45 game.players[1].team = 148 game.players[1].team = 1
46 game.players[2].team = 149 game.players[2].team = 1
47 game.players[3].team = 250 game.players[3].team = 2
48 game.players[4].team = 251 game.players[4].team = 2
52 check_ware_compatiblity(game.players[1], game.players[2])
53 check_ware_compatiblity(game.players[3], game.players[4])
49end54end
5055
51function place_headquarters()56function place_headquarters()
57 include "map:scripting/starting_conditions.lua"
52 for idx,player in ipairs(game.players) do58 for idx,player in ipairs(game.players) do
53 local sf = map.player_slots[player.number].starting_field59 local sf = map.player_slots[player.number].starting_field
5460 local tribename = player.tribe.name
55 prefilled_buildings(player, { "barbarians_headquarters", sf.x, sf.y,61 if tribename == "barbarians" then
56 wares = {62 set_starting_conditions_barbarians(player, sf)
57 ax = 5,63 elseif tribename == "empire" then
58 bread_paddle = 2,64 set_starting_conditions_empire(player, sf)
59 blackwood = 32,65 elseif tribename == "atlanteans" then
60 cloth = 5,66 set_starting_conditions_atlanteans(player, sf)
61 coal = 12,67 elseif tribename == "frisians" then
62 felling_ax = 4,68 set_starting_conditions_frisians(player, sf)
63 fire_tongs = 2,69 else
64 fish = 6,70 print("We don't have starting conditions for tribe " .. tribename)
65 fishing_rod = 2,71 do_game_over()
66 gold = 4,72 end
67 grout = 12,
68 hammer = 12,
69 hunting_spear = 2,
70 iron = 12,
71 iron_ore = 5,
72 kitchen_tools = 4,
73 meal = 4,
74 meat = 6,
75 pick = 14,
76 barbarians_bread = 8,
77 ration = 12,
78 granite = 40,
79 scythe = 6,
80 shovel = 4,
81 snack = 3,
82 thatch_reed = 24,
83 log = 80,
84 },
85 workers = {
86 barbarians_blacksmith = 2,
87 barbarians_brewer = 1,
88 barbarians_builder = 10,
89 barbarians_carrier = 40,
90 barbarians_charcoal_burner = 1,
91 barbarians_gardener = 1,
92 barbarians_geologist = 4,
93 barbarians_lime_burner = 1,
94 barbarians_lumberjack = 3,
95 barbarians_miner = 4,
96 barbarians_ranger = 1,
97 barbarians_stonemason = 2,
98 barbarians_ox = 5,
99 },
100 soldiers = {
101 [{0,0,0,0}] = 45,
102 }
103 })
104 end73 end
105end74end
10675
@@ -137,6 +106,8 @@
137 for idx,descr in ipairs(route_descrs) do106 for idx,descr in ipairs(route_descrs) do
138 run(wait_for_established_route, descr)107 run(wait_for_established_route, descr)
139 end108 end
109
110 do_smuggling()
140end111end
141112
142setup_statistics_hook()113setup_statistics_hook()
143114
=== modified file 'data/maps/MP_Scenarios/Smugglers.wmf/scripting/smuggling.lua'
--- data/maps/MP_Scenarios/Smugglers.wmf/scripting/smuggling.lua 2016-03-26 09:09:43 +0000
+++ data/maps/MP_Scenarios/Smugglers.wmf/scripting/smuggling.lua 2018-09-26 16:22:20 +0000
@@ -4,6 +4,76 @@
44
5include "scripting/messages.lua"5include "scripting/messages.lua"
66
7-- Init routes
8route_descrs = {
9 {
10 value = 2,
11 send = map:get_field(35, 52):region(2),
12 recv = map:get_field(96, 77):region(2),
13 sending_warehouse = nil,
14 receiving_warehouse = nil,
15 wares = {}
16 },
17 {
18 value = 2,
19 send = map:get_field(98, 55):region(2),
20 recv = map:get_field(34, 76):region(2),
21 sending_warehouse = nil,
22 receiving_warehouse = nil,
23 wares = {}
24 },
25
26 {
27 value = 3,
28 send = map:get_field(64, 57):region(2),
29 recv = map:get_field(78, 73):region(2),
30 sending_warehouse = nil,
31 receiving_warehouse = nil,
32 wares = {}
33 },
34 {
35 value = 3,
36 send = map:get_field(77, 58):region(2),
37 recv = map:get_field(65, 72):region(2),
38 sending_warehouse = nil,
39 receiving_warehouse = nil,
40 wares = {}
41 },
42
43 {
44 value = 2,
45 send = map:get_field(62, 93):region(2),
46 recv = map:get_field(78, 34):region(2),
47 sending_warehouse = nil,
48 receiving_warehouse = nil,
49 wares = {}
50 },
51 {
52 value = 2,
53 send = map:get_field(80, 95):region(2),
54 recv = map:get_field(63, 29):region(2),
55 sending_warehouse = nil,
56 receiving_warehouse = nil,
57 wares = {}
58 },
59 {
60 value = 2,
61 send = map:get_field(18, 66):region(2),
62 recv = map:get_field(121, 61):region(2),
63 sending_warehouse = nil,
64 receiving_warehouse = nil,
65 wares = {}
66 },
67 {
68 value = 2,
69 send = map:get_field(124, 72):region(2),
70 recv = map:get_field(19, 57):region(2),
71 sending_warehouse = nil,
72 receiving_warehouse = nil,
73 wares = {}
74 }
75}
76
7-- =================77-- =================
8-- Helper functions78-- Helper functions
9-- =================79-- =================
@@ -35,56 +105,92 @@
35 game_over_done = true105 game_over_done = true
36end106end
37107
38function do_smuggling(route_descr, recv_plr, send_plr, recv_whf, send_whf)108function do_smuggling()
39 while 1 do109 while true do
40 sleep(10000) -- Sleep 10s110 sleep(10000) -- Sleep 10s
41
42 if points[1] >= points_to_win or111 if points[1] >= points_to_win or
43 points[2] >= points_to_win112 points[2] >= points_to_win
44 then113 then
45 do_game_over()114 do_game_over()
46 break115 return
47 end116 end
48117
49 if not send_whf.immovable or118 for idx, route_descr in ipairs(route_descrs) do
50 send_whf.immovable.descr.type_name ~= "warehouse" or119 if (route_descr.sending_warehouse ~= nil and route_descr.receiving_warehouse ~= nil) then
51 send_whf.immovable.owner ~= send_plr or120 print("NOCOM do smuggling for route " .. idx)
52 not recv_whf.immovable or121
53 recv_whf.immovable.descr.type_name ~= "warehouse" or122 local send_plr = route_descr.sending_warehouse.owner
54 recv_whf.immovable.owner ~= recv_plr123 local recv_plr = route_descr.receiving_warehouse.owner
55 then124 local send_whf = route_descr.sending_warehouse.fields[1]
56 send_to_all(smuggling_route_broken:bformat(125 local recv_whf = route_descr.receiving_warehouse.fields[1]
57 (ngettext("%i point", "%i points", route_descr.value)):format(route_descr.value), recv_plr.name, send_plr.name)126
58 )127 -- Ensure that the warehouses are still there and owned by the same player
59 run(wait_for_established_route, route_descr)128 if not send_whf.immovable or
60 break129 send_whf.immovable.descr.type_name ~= "warehouse" or
61 end130 send_whf.immovable.owner ~= send_plr or
62131 not recv_whf.immovable or
63 -- Warp one ware132 recv_whf.immovable.descr.type_name ~= "warehouse" or
64 local wares = send_whf.immovable:get_wares("all")133 recv_whf.immovable.owner ~= recv_plr
65 local wn = {}134 then
66 for name,count in pairs(wares) do135 send_to_all(smuggling_route_broken:bformat(
67 if count > 0 then136 (ngettext("%i point", "%i points", route_descr.value)):format(route_descr.value), recv_plr.name, send_plr.name)
68 wn[#wn + 1] = name137 )
138 run(wait_for_established_route, route_descr)
139 else
140 -- Only use ware types that both sending and receiving player can use
141 local wares = route_descr.wares
142
143 -- We start counting at 0 so that we can use the modulo (%) operator
144 -- for going round robin
145 local last_ware_index = 0;
146
147 -- Warp the next available ware, going round robin
148 local empty_warehouse_guard = #wares
149 local warp_index = last_ware_index
150 while empty_warehouse_guard > 0 do
151 -- Index shift, because Lua tables start counting at 1
152 local ware_to_warp = wares[warp_index + 1]
153 if send_whf.immovable:get_wares(ware_to_warp) > 0 then
154 print("NOCOM Route " .. idx .. " (" .. send_whf.x .. ", " .. send_whf.y .. ") warping ware " .. ware_to_warp .. ": " .. send_plr.name .. " -> " .. recv_plr.name)
155 send_whf.immovable:set_wares(ware_to_warp, send_whf.immovable:get_wares(ware_to_warp) - 1)
156 recv_whf.immovable:set_wares(
157 ware_to_warp, recv_whf.immovable:get_wares(ware_to_warp) + 1
158 )
159 points[recv_plr.team] = points[recv_plr.team] + route_descr.value
160 break
161 end
162 warp_index = (warp_index + 1) % #wares;
163 empty_warehouse_guard = empty_warehouse_guard - 1
164 end
165 -- Next round robin index
166 last_ware_index = (last_ware_index + 1) % #wares;
167 end
69 end168 end
70 end169 end
71 if #wn > 0 then
72 local ware_to_warp = wn[math.random(#wn)]
73 send_whf.immovable:set_wares(ware_to_warp, wares[ware_to_warp] - 1)
74 recv_whf.immovable:set_wares(
75 ware_to_warp, recv_whf.immovable:get_wares(ware_to_warp) + 1
76 )
77 points[recv_plr.team] = points[recv_plr.team] + route_descr.value
78 end
79 end170 end
80end171end
81172
82function wait_for_established_route(route_descr)173function wait_for_established_route(route_descr)
83 local receiving_wh, sending_wh174 local receiving_wh, sending_wh
84 while 1 do175 route_descr.sending_warehouse = nil
176 route_descr.receiving_warehouse = nil
177 route_descr.wares = {}
178
179 while true do
85 receiving_wh = find_warehouse(route_descr.recv)180 receiving_wh = find_warehouse(route_descr.recv)
86 sending_wh = find_warehouse(route_descr.send)181 sending_wh = find_warehouse(route_descr.send)
87 if receiving_wh and sending_wh and receiving_wh.owner.team == sending_wh.owner.team then break end182 if receiving_wh and sending_wh and receiving_wh.owner.team == sending_wh.owner.team then
183 route_descr.sending_warehouse = sending_wh
184 route_descr.receiving_warehouse = receiving_wh
185
186 -- Collect ware types that both sending and receiving player can use
187 for idx,ware in pairs(sending_wh.owner.tribe.wares) do
188 if receiving_wh.owner.tribe:has_ware(ware.name) then
189 table.insert(route_descr.wares, ware.name)
190 end
191 end
192 break
193 end
88 sleep(7138)194 sleep(7138)
89 end195 end
90196
@@ -104,6 +210,4 @@
104 send_message(sending_wh.owner, _"Status",210 send_message(sending_wh.owner, _"Status",
105 smuggling_route_established_sender:format(points), {popup=true, field=sending_wh.fields[1]}211 smuggling_route_established_sender:format(points), {popup=true, field=sending_wh.fields[1]}
106 )212 )
107
108 run(do_smuggling, route_descr, receiving_wh.owner, sending_wh.owner, receiving_wh.fields[1], sending_wh.fields[1])
109end213end
110214
=== added file 'data/maps/MP_Scenarios/Smugglers.wmf/scripting/starting_conditions.lua'
--- data/maps/MP_Scenarios/Smugglers.wmf/scripting/starting_conditions.lua 1970-01-01 00:00:00 +0000
+++ data/maps/MP_Scenarios/Smugglers.wmf/scripting/starting_conditions.lua 2018-09-26 16:22:20 +0000
@@ -0,0 +1,254 @@
1-- Give the player a Barbarian headquarters
2function set_starting_conditions_barbarians(player, sf)
3 prefilled_buildings(player, { "barbarians_headquarters", sf.x, sf.y,
4 wares = {
5 ax = 5,
6 bread_paddle = 2,
7 blackwood = 32,
8 cloth = 5,
9 coal = 12,
10 felling_ax = 4,
11 fire_tongs = 2,
12 fish = 6,
13 fishing_rod = 2,
14 gold = 4,
15 grout = 12,
16 hammer = 12,
17 hunting_spear = 2,
18 iron = 12,
19 iron_ore = 5,
20 kitchen_tools = 4,
21 meal = 4,
22 meat = 6,
23 pick = 8,
24 barbarians_bread = 8,
25 ration = 12,
26 granite = 40,
27 scythe = 6,
28 shovel = 4,
29 snack = 3,
30 thatch_reed = 24,
31 log = 80,
32 },
33 workers = {
34 barbarians_blacksmith = 2,
35 barbarians_brewer = 1,
36 barbarians_builder = 10,
37 barbarians_charcoal_burner = 1,
38 barbarians_carrier = 40,
39 barbarians_gardener = 1,
40 barbarians_geologist = 4,
41 barbarians_lime_burner = 1,
42 barbarians_lumberjack = 3,
43 barbarians_miner = 4,
44 barbarians_miner_master = 4,
45 barbarians_ranger = 1,
46 barbarians_stonemason = 2,
47 barbarians_trainer = 3,
48 barbarians_ox = 5,
49 },
50 soldiers = {
51 [{0,0,0,0}] = 45,
52 }
53 })
54end
55
56-- Give the player an Empire headquarters
57function set_starting_conditions_empire(player, sf)
58 prefilled_buildings(player, { "empire_headquarters", sf.x, sf.y,
59 wares = {
60 armor_helmet = 4,
61 spear_wooden = 5,
62 felling_ax = 6,
63 bread_paddle = 2,
64 basket = 2,
65 empire_bread = 8,
66 cloth = 5,
67 coal = 12,
68 fire_tongs = 2,
69 fish = 6,
70 fishing_rod = 2,
71 flour = 4,
72 gold = 4,
73 grape = 4,
74 hammer = 14,
75 hunting_spear = 2,
76 iron = 12,
77 iron_ore = 5,
78 kitchen_tools = 4,
79 marble = 25,
80 marble_column = 6,
81 meal = 4,
82 meat = 6,
83 pick = 8,
84 ration = 12,
85 saw = 2,
86 scythe = 5,
87 shovel = 6,
88 granite = 40,
89 log = 30,
90 water = 12,
91 wheat = 4,
92 wine = 8,
93 planks = 45,
94 wool = 2,
95 },
96 workers = {
97 empire_armorsmith = 1,
98 empire_brewer = 1,
99 empire_builder = 10,
100 empire_carrier = 40,
101 empire_charcoal_burner = 1,
102 empire_geologist = 4,
103 empire_lumberjack = 3,
104 empire_miner = 4,
105 empire_stonemason = 2,
106 empire_toolsmith = 2,
107 empire_trainer = 3,
108 empire_weaponsmith = 1,
109 empire_donkey = 5,
110 },
111 soldiers = {
112 [{0,0,0,0}] = 45,
113 }
114 })
115end
116
117-- Give the player an Atlantean headquarters
118function set_starting_conditions_atlanteans(player, sf)
119 prefilled_buildings(player, { "atlanteans_headquarters", sf.x, sf.y,
120 wares = {
121 diamond = 7,
122 iron_ore = 5,
123 quartz = 9,
124 granite = 50,
125 spider_silk = 9,
126 log = 20,
127 coal = 12,
128 gold = 4,
129 gold_thread = 6,
130 iron = 8,
131 planks = 45,
132 spidercloth = 5,
133 blackroot = 5,
134 blackroot_flour = 12,
135 atlanteans_bread = 8,
136 corn = 5,
137 cornmeal = 12,
138 fish = 3,
139 meat = 3,
140 smoked_fish = 6,
141 smoked_meat = 6,
142 water = 12,
143 bread_paddle = 2,
144 buckets = 2,
145 fire_tongs = 2,
146 fishing_net = 4,
147 hammer = 11,
148 hunting_bow = 1,
149 milking_tongs = 2,
150 hook_pole = 2,
151 pick = 8,
152 saw = 9,
153 scythe = 4,
154 shovel = 9,
155 tabard = 5,
156 trident_light = 5,
157 },
158 workers = {
159 atlanteans_armorsmith = 1,
160 atlanteans_blackroot_farmer = 1,
161 atlanteans_builder = 10,
162 atlanteans_charcoal_burner = 1,
163 atlanteans_carrier = 40,
164 atlanteans_fishbreeder = 1,
165 atlanteans_geologist = 4,
166 atlanteans_miner = 4,
167 atlanteans_sawyer = 1,
168 atlanteans_stonecutter = 2,
169 atlanteans_toolsmith = 2,
170 atlanteans_trainer = 3,
171 atlanteans_weaponsmith = 1,
172 atlanteans_woodcutter = 3,
173 atlanteans_horse = 5,
174 },
175 soldiers = {
176 [{0,0,0,0}] = 35,
177 }
178 })
179end
180
181-- Give the player a Frisian headquarters
182function set_starting_conditions_frisians(player, sf)
183 prefilled_buildings(player, { "frisians_headquarters", sf.x, sf.y,
184 wares = {
185 log = 40,
186 granite = 50,
187 thatch_reed = 50,
188 brick = 80,
189 clay = 30,
190 water = 10,
191 fish = 10,
192 meat = 10,
193 fruit = 10,
194 barley = 5,
195 ration = 20,
196 honey = 10,
197 smoked_meat = 5,
198 smoked_fish = 5,
199 mead = 5,
200 meal = 2,
201 coal = 20,
202 iron = 5,
203 gold = 4,
204 iron_ore = 10,
205 bread_frisians = 15,
206 honey_bread = 5,
207 beer = 5,
208 cloth = 5,
209 fur = 10,
210 fur_garment = 5,
211 sword_short = 5,
212 hammer = 5,
213 fire_tongs = 2,
214 bread_paddle = 2,
215 kitchen_tools = 2,
216 felling_ax = 3,
217 needles = 2,
218 basket = 2,
219 pick = 5,
220 shovel = 5,
221 scythe = 3,
222 hunting_spear = 2,
223 fishing_net = 3,
224 },
225 workers = {
226 frisians_blacksmith = 3,
227 frisians_baker = 1,
228 frisians_brewer = 1,
229 frisians_builder = 10,
230 frisians_charcoal_burner = 1,
231 frisians_claydigger = 2,
232 frisians_brickmaker = 2,
233 frisians_carrier = 40,
234 frisians_reed_farmer = 2,
235 frisians_berry_farmer = 2,
236 frisians_fruit_collector = 2,
237 frisians_farmer = 1,
238 frisians_landlady = 1,
239 frisians_smoker = 1,
240 frisians_geologist = 4,
241 frisians_woodcutter = 3,
242 frisians_beekeeper = 1,
243 frisians_miner = 4,
244 frisians_miner_master = 2,
245 frisians_forester = 2,
246 frisians_stonemason = 2,
247 frisians_reindeer = 5,
248 frisians_trainer = 3,
249 },
250 soldiers = {
251 [{0,0,0,0}] = 45,
252 }
253 })
254end
0255
=== modified file 'src/scripting/lua_game.cc'
--- src/scripting/lua_game.cc 2018-07-28 19:08:34 +0000
+++ src/scripting/lua_game.cc 2018-09-26 16:22:20 +0000
@@ -851,7 +851,7 @@
851/* RST851/* RST
852 .. method:: produced_wares_count(what)852 .. method:: produced_wares_count(what)
853853
854 Returns count of wares produced byt the player up to now.854 Returns count of wares produced by the player up to now.
855 'what' can be either an "all" or single ware name or an array of names. If single855 'what' can be either an "all" or single ware name or an array of names. If single
856 ware name is given, integer is returned, otherwise the table is returned.856 ware name is given, integer is returned, otherwise the table is returned.
857*/857*/

Subscribers

People subscribed via source and target branches

to status/vote changes: