widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #12819
[Merge] lp:~widelands-dev/widelands/bug-1751440-smugglers-desync into lp:widelands
GunChleoc has proposed merging lp:~widelands-dev/widelands/bug-1751440-smugglers-desync into lp:widelands.
Commit message:
To address desync problems in Smugglers, going round robin rather than smuggling a random ware. Also, allow smuggling if players are playing different tribes - only wares that both tribes have will be smuggled.
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #1751440 in widelands: "Desync in Smugglers scenario"
https://bugs.launchpad.net/widelands/+bug/1751440
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1751440-smugglers-desync/+merge/340735
I'm not 100% sure if this branch actually fixes the problem, by I was able to play a full game with 2 players having 2 smuggling routes and the 2 other players idle.
Also, we can now expand the scenario in the future to allow players to choose their tribes, but we need to finish the game loading screen UI first before we can start working on that.
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1751440-smugglers-desync into lp:widelands.
=== 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-03-05 10:38:57 +0000
@@ -35,8 +35,27 @@
game_over_done = true
end
-function do_smuggling(route_descr, recv_plr, send_plr, recv_whf, send_whf)
- while 1 do
+function do_smuggling(route_descr, recv_plr, send_plr, recv_wh_field, send_wh_field)
+ -- Collect ware types that both sending and receiving player can use
+ local wares = {}
+ for idx,ware in pairs(send_plr.tribe.wares) do
+ if recv_plr.tribe:has_ware(ware.name) then
+ table.insert(wares, ware.name)
+ end
+ end
+
+ -- If the tribes don't have any wares in common, nothing can be smuggled
+ -- This should not happen, but let's have a safeguard anyway.
+ if #wares < 1 then
+ do_game_over()
+ return
+ end
+
+ -- We start counting at 0 so that we can use the modulo (%) operator
+ -- for going round robin
+ local last_ware_index = 0;
+
+ while true do
sleep(10000) -- Sleep 10s
if points[1] >= points_to_win or
@@ -46,36 +65,45 @@
break
end
- if not send_whf.immovable or
- send_whf.immovable.descr.type_name ~= "warehouse" or
- send_whf.immovable.owner ~= send_plr or
- not recv_whf.immovable or
- recv_whf.immovable.descr.type_name ~= "warehouse" or
- recv_whf.immovable.owner ~= recv_plr
+ if not send_wh_field.immovable or
+ send_wh_field.immovable.descr.type_name ~= "warehouse" or
+ send_wh_field.immovable.owner ~= send_plr or
+ not recv_wh_field.immovable or
+ recv_wh_field.immovable.descr.type_name ~= "warehouse" or
+ recv_wh_field.immovable.owner ~= recv_plr
then
send_to_all(smuggling_route_broken:bformat(
(ngettext("%i point", "%i points", route_descr.value)):format(route_descr.value), recv_plr.name, send_plr.name)
)
run(wait_for_established_route, route_descr)
- break
+ return
end
- -- Warp one ware
- local wares = send_whf.immovable:get_wares("all")
- local wn = {}
- for name,count in pairs(wares) do
- if count > 0 then
- wn[#wn + 1] = name
+ -- Warp the next available ware, going round robin
+ local empty_warehouse_guard = #wares
+ local warp_index = last_ware_index
+ local ware_to_warp = nil
+ while empty_warehouse_guard > 0 do
+ -- Index shift, because Lua tables start counting at 1
+ local candidate = wares[warp_index + 1]
+ if send_wh_field.immovable:get_wares(candidate) > 0 then
+ ware_to_warp = candidate
+ break
end
+
+ warp_index = (warp_index + 1) % #wares;
+ empty_warehouse_guard = empty_warehouse_guard - 1
end
- if #wn > 0 then
- local ware_to_warp = wn[math.random(#wn)]
- send_whf.immovable:set_wares(ware_to_warp, wares[ware_to_warp] - 1)
- recv_whf.immovable:set_wares(
- ware_to_warp, recv_whf.immovable:get_wares(ware_to_warp) + 1
+
+ if ware_to_warp ~= nil then
+ send_wh_field.immovable:set_wares(ware_to_warp, send_wh_field.immovable:get_wares(ware_to_warp) - 1)
+ recv_wh_field.immovable:set_wares(
+ ware_to_warp, recv_wh_field.immovable:get_wares(ware_to_warp) + 1
)
points[recv_plr.team] = points[recv_plr.team] + route_descr.value
end
+ -- Next round robin index
+ last_ware_index = (last_ware_index + 1) % #wares;
end
end
Follow ups