← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/reveal_hide_animations into lp:widelands

 

kaputtnik has proposed merging lp:~widelands-dev/widelands/reveal_hide_animations into lp:widelands with lp:~widelands-dev/widelands/bug-1687100-reveal_fields as a prerequisite.

Commit message:
Adding lua-animations for reveal/hide fields; Adjusted Tutorials and Campaigns to use it.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1687100 in widelands: "Lua: reveal_fields after hide_fields(fields, hide_completely) does not respect seen fields"
  https://bugs.launchpad.net/widelands/+bug/1687100

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/reveal_hide_animations/+merge/327062

Added a file "field_animations.lua" containing some animations for hiding and revealing fields.

- Added RST documentation for the functions
- Adjusted all tutorials and campaigns to use the animations. The animations are used mostly when a game is started.
- Modified campaign emp03 which uses prior the initial implementations to use now the new ones. In this campaign i have also removed a useless animation.

Prerequisite branch is https://code.launchpad.net/~widelands-dev/widelands/bug-1687100-reveal_fields

For testing one has to compile https://code.launchpad.net/~widelands-dev/widelands/bug-1687100-reveal_fields and use the option  --datadir= pointing to the datadir of this branch.


-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/reveal_hide_animations into lp:widelands.
=== modified file 'data/campaigns/bar01.wmf/scripting/init.lua'
--- data/campaigns/bar01.wmf/scripting/init.lua	2016-12-27 23:04:02 +0000
+++ data/campaigns/bar01.wmf/scripting/init.lua	2017-07-09 10:09:27 +0000
@@ -8,6 +8,7 @@
 include "scripting/objective_utils.lua"
 include "scripting/infrastructure.lua"
 include "scripting/messages.lua"
+include "scripting/field_animations.lua"
 
 -- ==========
 -- Constants

=== modified file 'data/campaigns/bar01.wmf/scripting/mission_thread.lua'
--- data/campaigns/bar01.wmf/scripting/mission_thread.lua	2016-12-29 10:31:07 +0000
+++ data/campaigns/bar01.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -15,15 +15,21 @@
 -- =====================================================
 
 function introduction_thread()
+   reveal_concentric(plr, sf, 13)
    sleep(2000)
 
    message_box_objective(plr, briefing_msg_01)
    -- these buildings are still burning, but only for a while
    map:place_immovable("destroyed_building",map:get_field(7,41),"tribes")
    map:place_immovable("destroyed_building",map:get_field(5,52),"tribes")
-   plr:reveal_fields(al_thunran:region(8))
+   -- plr:reveal_fields(al_thunran:region(8))
+   scroll_to_field(al_thunran)
+   reveal_concentric(plr, al_thunran, 8, true, 50)
    message_box_objective(plr, briefing_msg_02) -- Al'thunran
-   plr:reveal_fields(grave:region(4))
+   scroll_to_field(sf)
+   sleep(1000)
+   scroll_to_field(grave)
+   reveal_concentric(plr, grave, 4)
    message_box_objective(plr, briefing_msg_03) -- grave, Boldreth
    message_box_objective(plr, briefing_msg_04) -- wait
    -- introduction of Khantrukh
@@ -52,8 +58,8 @@
 
    -- Reveal the rocks
    local rocks = wl.Game().map:get_field(27, 48)
-   plr:reveal_fields(rocks:region(6))
    local prior_center = scroll_to_field(rocks)
+   reveal_concentric(plr, rocks, 5)
    message_box_objective(plr, order_msg_3)
    obj = add_campaign_objective(obj_claim_northeastern_rocks)
    message_box_objective(plr, order_msg_4)

=== modified file 'data/campaigns/bar01.wmf/scripting/texts.lua'
--- data/campaigns/bar01.wmf/scripting/texts.lua	2016-11-30 20:07:08 +0000
+++ data/campaigns/bar01.wmf/scripting/texts.lua	2017-07-09 10:09:27 +0000
@@ -172,9 +172,7 @@
       .. paragraphdivider() ..
       -- TRANSLATORS: Thron
       _[[The red lights flash in the darkness and dance to the rhythm of the war drums that haunt me even in my nightmares.]]),
-   field = al_thunran,
    position = "topleft",
-   scroll_back = true
 }
 
 
@@ -186,7 +184,6 @@
       .. paragraphdivider() ..
       -- TRANSLATORS: Thron
       _[[Boldreth, my loyal companion and friend is a source of peace and comfort to me in these dark times. He keeps my spirits high and those of my warriors awake, preventing greed or despair from destroying the bonds between us as well.]]),
-   field = grave,
    position = "topleft",
 }
 

=== modified file 'data/campaigns/bar02.wmf/scripting/mission_thread.lua'
--- data/campaigns/bar02.wmf/scripting/mission_thread.lua	2017-01-17 08:52:14 +0000
+++ data/campaigns/bar02.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -3,6 +3,7 @@
 -- =======================================================================
 
 include "scripting/messages.lua"
+include "scripting/field_animations.lua"
 
 game = wl.Game()
 -- Mountain and frontier fields
@@ -11,6 +12,9 @@
 fr2 = game.map:get_field(85,1)
 fr3 = game.map:get_field(85,11)
 
+-- Starting field
+sf = game.map.player_slots[1].starting_field
+
 function check_conquered_footprints()
     if p1:seen_field(game.map:get_field(65, 28))
     then
@@ -35,6 +39,7 @@
 end
 
 function initial_message_and_small_food_economy()
+   reveal_concentric(p1, sf, 13)
    wake_me(2000)
    campaign_message_box(story_msg_1)
 
@@ -95,10 +100,17 @@
       game.map:get_field(65, 19):region(2),
       game.map:get_field(69, 18):region(2)
    )
-   p1:reveal_fields(fields)
-
-   local prior_center = scroll_to_field(game.map:get_field(67,19))
-
+
+   p1:hide_fields(fields)
+   local prior_center = scroll_to_field(game.map:get_field(65,19))
+   -- reveal the tracks one by one from right to left
+   sleep(1000)
+   reveal_concentric(p1, game.map:get_field(69, 19), 1, false)
+   sleep(1000)
+   reveal_concentric(p1, game.map:get_field(67, 19), 1, false)
+   sleep(1000)
+   reveal_concentric(p1, game.map:get_field(65, 19), 1, false)
+   sleep(1000)
    campaign_message_box(order_msg_2_build_a_tower)
    local o = add_campaign_objective(obj_build_a_tower)
    p1:forbid_buildings{"barbarians_sentry"}

=== modified file 'data/campaigns/bar02.wmf/scripting/texts.lua'
--- data/campaigns/bar02.wmf/scripting/texts.lua	2017-06-25 06:54:53 +0000
+++ data/campaigns/bar02.wmf/scripting/texts.lua	2017-07-09 10:09:27 +0000
@@ -259,6 +259,7 @@
 
 order_msg_2_build_a_tower = {
    posy = 1,
+   posx = 1,
    title = _"Tracks",
    body = boldreth(_"Boldreth says:",
       -- TRANSLATORS: Boldreth

=== modified file 'data/campaigns/emp01.wmf/scripting/mission_thread.lua'
--- data/campaigns/emp01.wmf/scripting/mission_thread.lua	2017-05-09 05:47:20 +0000
+++ data/campaigns/emp01.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -1,30 +1,34 @@
 include "scripting/messages.lua"
 include "map:scripting/helper_functions.lua"
+include "scripting/field_animations.lua"
 
 function mission_thread()
    sleep(1000)
 
    -- Initial messages
    local sea = wl.Game().map:get_field(50,25)
+   local ship = p1:place_ship(sea)
+   p1:hide_fields(sea:region(6),true)
    scroll_to_field(sea,0)
 
    campaign_message_box(diary_page_1)
    sleep(200)
 
    -- Show the sea
-   p1:reveal_fields(sea:region(6))
-   local ship = p1:place_ship(sea)
+   reveal_concentric(p1, sea, 5)
    sleep(1000)
    campaign_message_box(diary_page_2)
-   -- Hide the sea after 2 seconds
-   run(function() sleep(2000) p1:hide_fields(sea:region(6), true) end)
+   sleep(500)
+   hide_concentric(p1, sea, 5)
+   ship:remove()
 
    -- Back home
    include "map:scripting/starting_conditions.lua"
+   p1:hide_fields(wl.Game().map.player_slots[1].starting_field:region(13),true)
    scroll_to_field(wl.Game().map.player_slots[1].starting_field)
    campaign_message_box(diary_page_3)
-   ship:remove()
-
+   sleep(1000)
+   reveal_concentric(p1, wl.Game().map.player_slots[1].starting_field, 13)
    sleep(400)
 
    -- Check for trees and remove them

=== modified file 'data/campaigns/emp02.wmf/scripting/mission_thread.lua'
--- data/campaigns/emp02.wmf/scripting/mission_thread.lua	2017-03-16 21:54:07 +0000
+++ data/campaigns/emp02.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -3,8 +3,10 @@
 -- =======================================================================
 
 include "scripting/messages.lua"
+include "scripting/field_animations.lua"
 
 function building_materials()
+   reveal_concentric(p1, wl.Game().map.player_slots[1].starting_field, 13)
    sleep(1000)
    campaign_message_box(diary_page_5)
 
@@ -111,16 +113,16 @@
    -- Reveal the other mountains
    local coal_mountain = wl.Game().map:get_field(49,22)
    local iron_mountain = wl.Game().map:get_field(38,37)
-   p1:reveal_fields(coal_mountain:region(6))
+
+   --local move_point = wl.Game().map:get_field(49,22)
+   wait_for_roadbuilding_and_scroll(coal_mountain)
+   reveal_concentric(p1, coal_mountain, 6, false)
    p1:reveal_fields(iron_mountain:region(6))
    run(function() sleep(5000)
       p1:hide_fields(coal_mountain:region(6))
       p1:hide_fields(iron_mountain:region(6))
    end)
 
-   local move_point = wl.Game().map:get_field(49,22)
-   wait_for_roadbuilding_and_scroll(move_point)
-
    campaign_message_box(saledus_3)
    p1:allow_buildings{
       "empire_coalmine",
@@ -166,13 +168,11 @@
 function expand_and_build_marblemine()
    sleep(40000)
 
+   -- Move to the shipparts
    local shipparts = wl.Game().map:get_field(15,46)
-   p1:reveal_fields(shipparts:region(5))
+   local prior_center = wait_for_roadbuilding_and_scroll(wl.Game().map:get_field(12,43))
+   reveal_concentric(p1, shipparts, 5)
    run(function() sleep(10000) p1:hide_fields(shipparts:region(5)) end)
-
-   -- Move to the shipparts
-   local prior_center = wait_for_roadbuilding_and_scroll(shipparts)
-
    campaign_message_box(saledus_1)
    local o = add_campaign_objective(obj_build_military_buildings)
    p1:allow_buildings{"empire_blockhouse", "empire_sentry"}
@@ -186,11 +186,11 @@
 
    -- Marble Mountains
    local marblemountains = wl.Game().map:get_field(35,19)
-   p1:reveal_fields(marblemountains:region(5))
+
+   prior_center = wait_for_roadbuilding_and_scroll(marblemountains)
+   reveal_concentric(p1, marblemountains, 5, false)
    run(function() sleep(10000) p1:hide_fields(marblemountains:region(5)) end)
 
-   prior_center = wait_for_roadbuilding_and_scroll(marblemountains)
-
    campaign_message_box(saledus_2)
    p1:allow_buildings{"empire_marblemine", "empire_marblemine_deep"}
    o = add_campaign_objective(obj_build_marblemine)

=== modified file 'data/campaigns/emp02.wmf/scripting/texts.lua'
--- data/campaigns/emp02.wmf/scripting/texts.lua	2017-01-05 21:38:03 +0000
+++ data/campaigns/emp02.wmf/scripting/texts.lua	2017-07-09 10:09:27 +0000
@@ -160,6 +160,7 @@
 
 saledus_1 = {
    title =_ "Dangerous Ship Parts",
+   posx = 1,
    posy = 1,
    body= saledus(_"Saledus looks unhappy",
       -- TRANSLATORS: Saledus
@@ -174,6 +175,8 @@
 }
 
 saledus_2 = {
+   posx = 1,
+   posy = 1,
    title =_ "Marble on the Mountain",
    body= saledus(_"Saledus smiles",
       -- TRANSLATORS: Saledus
@@ -188,6 +191,8 @@
 }
 
 saledus_3 = {
+   posx = 1,
+   posy = 1,
    title =_ "Further Mountains",
    body= saledus(_"Saledus is excited",
       -- TRANSLATORS: Saledus

=== modified file 'data/campaigns/emp03.wmf/scripting/helper_functions.lua'
--- data/campaigns/emp03.wmf/scripting/helper_functions.lua	2017-05-16 10:16:22 +0000
+++ data/campaigns/emp03.wmf/scripting/helper_functions.lua	2017-07-09 10:09:27 +0000
@@ -62,56 +62,3 @@
    end
    return rv
 end
-
-function concentric_reveal(plr, center, max_radius, delay)
-   if not delay then delay = 100 end
-   local steps = 0
-   while steps < max_radius do
-      plr:reveal_fields(center:region(steps))
-      steps = steps + 1
-      sleep(delay)
-   end
-end
-
-function concentric_hide(plr, center, max_radius, delay)
-   if not delay then delay = 100 end
-   while max_radius > 0 do
-      local to_hide = center:region(max_radius, max_radius - 1)
-      plr:hide_fields(to_hide, true)
-      sleep(delay)
-      max_radius = max_radius -1
-   end
-   -- Hide the remaining field
-   plr:hide_fields({center},true)
-end
-
-function random_reveal(plr, region, time)
-   -- if no time is given the default '1000' (1 sec) is used
-   if not time then time = 1000 end
-   -- Calculate the sleep time as an integer
-   delay = math.floor(time / #region)
-   -- Create a table with randomized fields
-   -- This is done for efficiency reasons
-   rand_tbl = {}
-   while #region > 0 do
-      f = math.random(1, #region)
-      table.insert(rand_tbl, region[f])
-      table.remove(region, f)
-   end
-   --reveal field by field:
-   for i, f in ipairs(rand_tbl) do
-      plr:reveal_fields({f})
-      sleep(delay)
-   end
-end
-
-function random_hide(plr, region, time)
-   if not time then time = 1000 end
-   delay = math.floor(time / #region)
-   while #region > 0 do
-      f = math.random(1, #region)
-      plr:hide_fields({region[f]}, true)
-      table.remove(region, f)
-      sleep(delay)
-   end
-end

=== modified file 'data/campaigns/emp03.wmf/scripting/mission_thread.lua'
--- data/campaigns/emp03.wmf/scripting/mission_thread.lua	2017-05-17 09:03:50 +0000
+++ data/campaigns/emp03.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -1,5 +1,7 @@
 include "scripting/messages.lua"
 include "map:scripting/helper_functions.lua"
+include "scripting/field_animations.lua"
+
 
 -- Some objectives need to be waited for in separate threads
 local obj_build_port_and_shipyard_done = false
@@ -275,9 +277,7 @@
 
    while not p1:sees_field(ruins) do sleep(3000) end
    scroll_to_field(ruin_fortress,5)
-   sleep(500)
-   random_reveal(p1, ruin_fortress:region(5), 1000)
-   sleep(500)
+   sleep(1000)
    campaign_message_box(saledus_12)
 
    -- If we don't have enough training sites yet, add a message and objective to complete them.
@@ -307,7 +307,7 @@
    campaign_message_box(diary_page_1)
 
    -- Show the sea
-   random_reveal(p1, sea:region(5), 1000)
+   reveal_randomly(p1, sea:region(5), 1000)
    sleep(100)
    local ship = p1:place_ship(sea)
    sleep(2500)
@@ -317,15 +317,14 @@
    sleep(400)
    ship:remove()
    sleep(300)
-   random_hide(p1, sea:region(6), 1000)
+   hide_randomly(p1, sea:region(6), 1000)
    sleep(300)
 
    -- Scroll to the place where the ship is finally stranded
    scroll_to_field(sf)
    -- Now we place the shipwreck headquarters and fill it with workers and wares
    include "map:scripting/starting_conditions.lua"
-   p1:hide_fields(sf:region(13), true)
-   concentric_reveal(p1, sf, 13, 100)
+   reveal_concentric(p1, sf, 13, 100)
    campaign_message_box(diary_page_3)
    sleep(400)
    campaign_message_box(saledus)

=== modified file 'data/campaigns/tutorial01_basic_control.wmf/scripting/init.lua'
--- data/campaigns/tutorial01_basic_control.wmf/scripting/init.lua	2016-01-28 05:24:34 +0000
+++ data/campaigns/tutorial01_basic_control.wmf/scripting/init.lua	2017-07-09 10:09:27 +0000
@@ -10,6 +10,7 @@
 include "scripting/messages.lua"
 include "scripting/table.lua"
 include "scripting/ui.lua"
+include "scripting/field_animations.lua"
 
 -- Constants
 sf = map.player_slots[1].starting_field

=== modified file 'data/campaigns/tutorial01_basic_control.wmf/scripting/mission_thread.lua'
--- data/campaigns/tutorial01_basic_control.wmf/scripting/mission_thread.lua	2016-12-29 10:31:07 +0000
+++ data/campaigns/tutorial01_basic_control.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -3,6 +3,7 @@
 -- ================
 
 function starting_infos()
+   reveal_concentric(plr, sf, 13, true, 80)
    map:place_immovable("debris00",second_quarry_field, "world")
    -- so that the player cannot build anything here
 

=== modified file 'data/campaigns/tutorial02_warfare.wmf/scripting/init.lua'
--- data/campaigns/tutorial02_warfare.wmf/scripting/init.lua	2016-01-28 05:24:34 +0000
+++ data/campaigns/tutorial02_warfare.wmf/scripting/init.lua	2017-07-09 10:09:27 +0000
@@ -11,6 +11,7 @@
 include "scripting/messages.lua"
 include "scripting/table.lua"
 include "scripting/ui.lua"
+include "scripting/field_animations.lua"
 
 include "map:scripting/starting_conditions.lua"
 

=== modified file 'data/campaigns/tutorial02_warfare.wmf/scripting/mission_thread.lua'
--- data/campaigns/tutorial02_warfare.wmf/scripting/mission_thread.lua	2016-11-30 09:14:27 +0000
+++ data/campaigns/tutorial02_warfare.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -3,6 +3,7 @@
 -- ================
 
 function intro()
+   reveal_concentric(plr, wl.Game().map:get_field(32, 59), 15)
    sleep(1000)
    message_box_objective(plr, introduction)
 

=== modified file 'data/campaigns/tutorial03_seafaring.wmf/scripting/init.lua'
--- data/campaigns/tutorial03_seafaring.wmf/scripting/init.lua	2016-01-28 05:24:34 +0000
+++ data/campaigns/tutorial03_seafaring.wmf/scripting/init.lua	2017-07-09 10:09:27 +0000
@@ -12,6 +12,7 @@
 include "scripting/messages.lua"
 include "scripting/table.lua"
 include "scripting/ui.lua"
+include "scripting/field_animations.lua"
 
 sf = map.player_slots[1].starting_field
 second_port_field = map:get_field(37, 27)

=== modified file 'data/campaigns/tutorial03_seafaring.wmf/scripting/mission_thread.lua'
--- data/campaigns/tutorial03_seafaring.wmf/scripting/mission_thread.lua	2016-10-23 11:31:25 +0000
+++ data/campaigns/tutorial03_seafaring.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -3,6 +3,8 @@
 -- ===============
 
 function introduction()
+   fields = get_sees_fields(plr)
+   reveal_randomly(plr, fields, 2000)
    additional_port_space.terr = "summer_water" -- disable the port space
    sleep(1000)
    message_box_objective(plr, intro_south)

=== modified file 'data/campaigns/tutorial04_economy.wmf/scripting/init.lua'
--- data/campaigns/tutorial04_economy.wmf/scripting/init.lua	2016-01-28 05:24:34 +0000
+++ data/campaigns/tutorial04_economy.wmf/scripting/init.lua	2017-07-09 10:09:27 +0000
@@ -12,6 +12,7 @@
 include "scripting/messages.lua"
 include "scripting/table.lua"
 include "scripting/ui.lua"
+include "scripting/field_animations.lua"
 
 map = wl.Game().map
 mv = wl.ui.MapView()

=== modified file 'data/campaigns/tutorial04_economy.wmf/scripting/mission_thread.lua'
--- data/campaigns/tutorial04_economy.wmf/scripting/mission_thread.lua	2017-01-21 21:10:21 +0000
+++ data/campaigns/tutorial04_economy.wmf/scripting/mission_thread.lua	2017-07-09 10:09:27 +0000
@@ -3,7 +3,13 @@
 -- ===============
 
 function introduction()
+   init_player()
+   fields = get_sees_fields(plr)
+   reveal_randomly(plr, fields, 2000)
+   remaining_roads()
+
    sleep(1000)
+   
    message_box_objective(plr, intro1)
    message_box_objective(plr, intro2)
 
@@ -156,6 +162,4 @@
    message_box_objective(plr, conclusion)
 end
 
-
-run(init_player)
 run(introduction)

=== modified file 'data/campaigns/tutorial04_economy.wmf/scripting/starting_conditions.lua'
--- data/campaigns/tutorial04_economy.wmf/scripting/starting_conditions.lua	2016-11-01 13:58:24 +0000
+++ data/campaigns/tutorial04_economy.wmf/scripting/starting_conditions.lua	2017-07-09 10:09:27 +0000
@@ -138,30 +138,21 @@
       {"empire_fortress",71,66},
       {"empire_fortress",75,72}
    )
-   plr:place_building("empire_quarry", map:get_field(87,36), true, true) -- a construction site
 
    plr:conquer(map:get_field(111,34),3) -- some remaining fields inside
 
    connected_road(plr,map:get_field(97,54).immovable,"tr,tr|tr,tl")
-   connected_road(plr,map:get_field(98,52).immovable,"br,r|r,r|tr,r,tr|tr,r|r,r|tr,tr|tr,tr|tr,tr|r,r|r,r|r,r|br,br|r,r")
-   connected_road(plr,map:get_field(99,53).immovable,"tr,tr|tr,tr|tl,tr|tr,tr|tr,tr|tr,tl|tl,tl|l,l|l,l|l,l|l,bl")
-   connected_road(plr,map:get_field(97,54).immovable,"bl,br|br,bl,bl|bl,bl|bl,l|bl,bl|br,bl|bl,bl,l|l,l|l,l|l,l|l,l|l,l|l,l|l,l|l,l|l,l|l,tl|l,l|l,tl|tl,tl")
-   connected_road(plr,map:get_field(97,56).immovable,"r,br|br,r|r,r|r,tr|r,r|br,br|br,r")
    connected_road(plr,map:get_field(97,54).immovable,"l,l|l,tl|tl,tl|bl,l|l,bl")
    connected_road(plr,map:get_field(88,49).immovable,"br,br|r,br")
    connected_road(plr,map:get_field(92,51).immovable,"tr,tl|tr,tl,tl|tr,tr|tr,tr|tr,tr")
-   connected_road(plr,map:get_field(94,42).immovable,"tl,l|tl,tl|l,l|l,tl,tl|tr,tr|tr,tr,tr")
    connected_road(plr,map:get_field(75,73).immovable,"tr,tr|tr,r|tr,tr")
    connected_road(plr,map:get_field(92,54).immovable,"tr,r")
    connected_road(plr,map:get_field(93,58).immovable,"tr,tr|tr,tr")
-   connected_road(plr,map:get_field(102,45).immovable,"br,r|br,r|br,bl,bl")
    connected_road(plr,map:get_field(105,47).immovable,"tr,tl|r,r|br,r")
-   connected_road(plr,map:get_field(116,44).immovable,"tr,tr|tr,tr|r,r")
    connected_road(plr,map:get_field(105,45).immovable,"tr,tr|tr,tr|r,tr|tr,r|tr,tr|tr,tr|tr,tr|r,r|tr,tr|tr,tl|l,tl,tl|l,tl|l,tl,tl")
    connected_road(plr,map:get_field(114,22).immovable,"br,bl|bl,bl|bl,bl|bl,bl|bl,bl|bl,bl|bl,bl|bl,bl|bl,bl|bl,bl|bl,l")
    connected_road(plr,map:get_field(105,42).immovable,"br,r")
    connected_road(plr,map:get_field(111,37).immovable,"br,r|r,br|bl,bl|bl,bl,bl")
-   connected_road(plr,map:get_field(106,59).immovable,"bl,bl|bl,br|bl,bl|l,bl,bl|bl,br|br,br|r,r|br,bl|br,br|br,br,bl|l,l|bl,bl|l,tl|tl,tl|tl,tl|tr,tr,tr|tr,r")
    connected_road(plr,map:get_field(100,78).immovable,"tr,r|r,r")
    connected_road(plr,map:get_field(104,48).immovable,"r,tr")
    connected_road(plr,map:get_field(105,52).immovable,"tr,tl")
@@ -169,4 +160,26 @@
    connected_road(plr,map:get_field(112,32).immovable,"l,l")
    connected_road(plr,map:get_field(115,25).immovable,"bl,bl")
    connected_road(plr,map:get_field(97,54).immovable,"r,r,tr")
-end
+   connected_road(plr,map:get_field(97,54).immovable,"bl,br|br,bl,bl|bl,bl|bl,l|bl,bl|br,bl|bl,bl,l|l,l|l,l|l,l|l,l|l,l|l,l|l,l|l,l|l,l|l,tl|l,l|l,tl|tl,tl")
+   connected_road(plr,map:get_field(98,52).immovable,"br,r|r,r|tr,r,tr|tr,r|r,r|tr,tr|tr,tr|tr,tr|r,r|r,r|r,r|br,br")
+   connected_road(plr,map:get_field(99,53).immovable,"tr,tr|tr,tr|tl,tr|tr,tr|tr,tr|tr,tl")
+   connected_road(plr,map:get_field(95,40).immovable,"tr,r")
+   connected_road(plr,map:get_field(97,56).immovable,"r,br|br,r|r,r|r,tr|r,r|br,br")
+   connected_road(plr,map:get_field(94,42).immovable,"tl,l|tl,tl|l,l|l,tl,tl|tr,tr|tr,tr,tr")
+   connected_road(plr,map:get_field(102,45).immovable,"br,r|br,r|br,bl,bl")
+   connected_road(plr,map:get_field(116,44).immovable,"tr,tr|tr,tr")
+   connected_road(plr,map:get_field(106,59).immovable,"bl,bl|bl,br|bl,bl|l,bl,bl|bl,br|br,br|r,r|br,bl|br,br|br,br,bl|l,l|bl,bl|l,tl|tl,tl|tl,tl|tr,tr,tr|tr,r")
+end
+
+-- Roads to mines and constructionsites mess up the hide field function, so we add them later
+function remaining_roads()
+-- Mines
+   connected_road(plr,map:get_field(119,46).immovable,"l,l")
+   connected_road(plr,map:get_field(103,41).immovable,"tl,tl|l,l|l,l|l,l")
+   connected_road(plr,map:get_field(108,60).immovable,"l,tl")
+   connected_road(plr,map:get_field(120,40).immovable,"l,l")
+
+-- Constructionsite
+   plr:place_building("empire_quarry", map:get_field(87,36), true, true)
+end
+

=== added file 'data/scripting/field_animations.lua'
--- data/scripting/field_animations.lua	1970-01-01 00:00:00 +0000
+++ data/scripting/field_animations.lua	2017-07-09 10:09:27 +0000
@@ -0,0 +1,173 @@
+-- RST
+-- .. _field_animations:
+--
+-- field_animations.lua
+-- --------------------
+--
+-- This script contain some animations to reveal and hide fields seen 
+-- by a player. This functions are currently used in the campaigns and scenarios
+-- to tell the prologue to a story.
+
+-- RST
+-- .. function:: reveal_randomly(player, region, time)
+--
+--    Reveal a given region field by field, where the fields 
+--    are chosen randomly. The region get hidden prior revealing.
+--    The animation runs the specified time.
+--    See also :meth:`wl.map.Field.region`
+--
+--    :arg player: The player who get sight to the region
+--    :arg region: The region that has to be revealed
+--    :type region: :class:`array` of :class:`wl.map.Fields`
+--    :arg time: Optional. The time the whole animation will run. 
+--               Defaults to 1000 (1 sec)
+
+function reveal_randomly(plr, region, time)
+   -- If no 'time' is given use a default
+   time = time or 1000
+
+   -- Make sure the region is hidden
+   plr:hide_fields(region, true)
+
+   -- Turn off buildhelp during animation
+   local buildhelp_state = wl.ui.MapView().buildhelp
+   if buildhelp_state then
+      wl.ui.MapView().buildhelp = false
+   end
+   
+   -- Calculate delay as integer
+   local delay = math.floor(time / #region)
+   -- Make sure 'delay' is valid
+   if delay < 1 then delay = 1 end
+
+   -- Reveal field by field
+   while #region > 0 do
+      local t = {}
+      local id = math.random(1, #region)
+      table.insert(t, region[id])
+      plr:reveal_fields(t)
+      sleep(delay)
+      table.remove(region, id)
+   end
+   -- Restore buildhelp status
+   wl.ui.MapView().buildhelp = buildhelp_state
+end
+
+-- RST
+-- .. function:: hide_randomly(player, region, time)
+--
+--    Hide a given region field by field, where the fields 
+--    are chosen randomly. The animation runs the specified time regardless
+--    how big the given region is. So region(6) and region(13) will take
+--    the same time. See also :meth:`wl.map.Field.region`
+--
+--    :arg player: The player who's sight get hidden
+--    :arg region: The region that has to be hidden
+--    :type region: :class:`array` of :class:`wl.map.Fields`
+--    :arg time: Optional. The time the whole animation will run. 
+--               Defaults to 1000 (1 sec)
+
+function hide_randomly(plr, region, time)
+   time = time or 1000
+   -- Turn off buildhelp
+   wl.ui.MapView().buildhelp = false
+
+   local delay = math.floor(time / #region)
+   if delay < 1 then delay = 1 end
+   while #region > 0 do
+      local id = math.random(1, #region)
+      plr:hide_fields({region[id]},true)
+      table.remove(region, id)
+      sleep(delay)
+   end
+end
+
+-- RST
+-- .. function:: reveal_concentric(player, center, max_radius, hide, delay)
+--
+--    Reveal a part of the map in a concentric way beginning from center onto
+--    max_radius. The region get hidden prior revealing as default.
+--
+--    :arg player: The player who get sight to the region
+--    :arg center: The field from where the animation should start revealing
+--    :arg max_radius: The last ring to reveal
+--    :arg hide: Optional, if `false` automatic hiding is disabled
+--    :type hide: :class:`boolean`
+--    :arg delay: Optional, defaults to 100. The delay between each ring is 
+--                revealed. If you want to set the delay, you must also set `hide`
+
+function reveal_concentric(plr, center, max_radius, hide, delay)
+   delay = delay or 100
+   if hide == nil then hide = true end
+
+   local buildhelp_state = wl.ui.MapView().buildhelp
+   if buildhelp_state then
+      -- Turn off buildhelp during animation
+      wl.ui.MapView().buildhelp = false
+   end
+
+   if hide then
+      plr:hide_fields(center:region(max_radius), true)
+   end
+
+   local radius = 0
+   while radius <= max_radius do
+      plr:reveal_fields(center:region(radius))
+      radius = radius + 1
+      sleep(delay)
+   end
+   wl.ui.MapView().buildhelp = buildhelp_state
+end
+
+-- RST
+-- .. function:: hide_concentric(player, center, max_radius, delay)
+--
+--    Hide a part of the map in a concentric way beginning from max_radius onto
+--    center.
+--
+--    :arg player: The player who's sight get hidden
+--    :arg center: The field where the animation should end hiding
+--    :arg max_radius: The first ring to hide
+--    :arg delay: Optional, defaults to 100. The delay between each ring is 
+--                revealed
+
+function hide_concentric(plr, center, max_radius, delay)
+   delay = delay or 100
+   -- Turn off buildhelp
+   wl.ui.MapView().buildhelp = false
+   while max_radius > 0 do
+      local to_hide = center:region(max_radius, max_radius - 1)
+      plr:hide_fields(to_hide, true)
+      sleep(delay)
+      max_radius = max_radius -1
+   end
+   -- Hide the remaining field
+   plr:hide_fields({center},true)
+end
+
+-- RST
+-- .. function:: get_sees_fields(player)
+--
+--    Gather all fields a player can see in the current view. The current view 
+--    is the whole area of the map in the current game window. You can use this
+--    function to get an unregular (non hexagonal) region and feed e.g. 
+--    :meth:`reveal_randomly()` with it.
+--
+--    :arg player: The player for whom the fields get gathered
+--    :returns: A table containing all visible fields in the current view
+
+function get_sees_fields(plr)
+   local sees_fields = {}
+   for x=0, wl.Game().map.width-1 do
+      for y=0, wl.Game().map.height-1  do
+         f = wl.Game().map:get_field(x,y)
+         if wl.ui.MapView():is_visible(f) then
+            -- Gather only fields which are seen in the view
+            if plr:sees_field(f) then
+               table.insert(sees_fields, f)
+            end
+         end
+      end
+   end
+   return sees_fields
+end

=== modified file 'data/scripting/infrastructure.lua'
--- data/scripting/infrastructure.lua	2017-05-06 19:21:47 +0000
+++ data/scripting/infrastructure.lua	2017-07-09 10:09:27 +0000
@@ -33,7 +33,10 @@
 --       the roads. Otherwise no carriers will be created.
 --    :type create_carriers: :class:`boolean`
 function connected_road(p, start, cmd, g_create_carriers)
-   create_carriers = g_create_carriers or true
+   create_carriers = true
+   if g_create_carriers ~= nil then
+      create_carriers = g_create_carriers
+   end
 
    if cmd:sub(-1) ~= "|" then
       cmd = cmd .. "|"

=== modified file 'src/scripting/lua_game.cc'
--- src/scripting/lua_game.cc	2017-07-02 18:58:30 +0000
+++ src/scripting/lua_game.cc	2017-07-09 10:09:27 +0000
@@ -586,7 +586,8 @@
    .. method:: reveal_fields(fields)
 
       Make these fields visible for the current player. The fields will remain
-      visible until they are hidden again.
+      visible until they are hidden again. See also :ref:`field_animations` for
+      animated revealing.
 
       :arg fields: The fields to show
       :type fields: :class:`array` of :class:`wl.map.Fields`
@@ -613,7 +614,8 @@
    .. method:: hide_fields(fields)
 
       Make these fields hidden for the current player if they are not
-      seen by a military building.
+      seen by a military building. See also :ref:`field_animations` for
+      animated hiding.
 
       :arg fields: The fields to hide
       :type fields: :class:`array` of :class:`wl.map.Fields`


Follow ups