← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/toolbar-dropdown-scripting-review-only into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/toolbar-dropdown-scripting-review-only into lp:widelands with lp:~widelands-dev/widelands/fix-dropdowns as a prerequisite.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/toolbar-dropdown-scripting-review-only/+merge/368228

DO NOT MERGE, THIS WILL BREAK THE TUTORIALS!

Split off tutorial and scripting changes from 

https://code.launchpad.net/~widelands-dev/widelands/toolbar-dropdown-menus

for easier review.

Use this merge request for reviewing the scripting changes, and the other branch's merge request for reviewing the C++ changes. When the review is done, merge the other branch and delete this one.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/toolbar-dropdown-scripting-review-only into lp:widelands.
=== modified file 'data/campaigns/tutorial01_basic_control.wmf/elemental'
--- data/campaigns/tutorial01_basic_control.wmf/elemental	2014-10-28 09:24:36 +0000
+++ data/campaigns/tutorial01_basic_control.wmf/elemental	2019-06-01 15:39:16 +0000
@@ -6,5 +6,5 @@
 map_h="64"
 nr_players="1"
 name=_"Basic Control"
-author="Winterwind,SirVer,Nasenbaer,wl-zocker"
+author="Winterwind,SirVer,Nasenbaer,wl-zocker,GunChleoc"
 descr=_"In this tutorial, you will learn how to navigate in Widelands and how to build buildings and roads."

=== modified file 'data/campaigns/tutorial01_basic_control.wmf/scripting/helper_functions_demonstration.lua'
--- data/campaigns/tutorial01_basic_control.wmf/scripting/helper_functions_demonstration.lua	2016-12-28 22:11:45 +0000
+++ data/campaigns/tutorial01_basic_control.wmf/scripting/helper_functions_demonstration.lua	2019-06-01 15:39:16 +0000
@@ -68,6 +68,18 @@
    blocker:lift_blocks()
 end
 
+
+function select_item_from_dropdown(name, item)
+   local blocker = UserInputDisabler:new()
+
+   wl.ui.MapView().dropdowns[name]:highlight_item(item)
+   sleep(5000)
+   wl.ui.MapView().dropdowns[name]:select()
+   sleep(3000)
+
+   blocker:lift_blocks()
+end
+
 -- Make sure the user is in road building mode starting from the given flag
 function enter_road_building_mode(flag)
    local mv = wl.ui.MapView()

=== modified file 'data/campaigns/tutorial01_basic_control.wmf/scripting/mission_thread.lua'
--- data/campaigns/tutorial01_basic_control.wmf/scripting/mission_thread.lua	2017-06-25 12:53:48 +0000
+++ data/campaigns/tutorial01_basic_control.wmf/scripting/mission_thread.lua	2019-06-01 15:39:16 +0000
@@ -2,17 +2,61 @@
 -- Mission thread
 -- ================
 
+local objective_to_explain_objectives = add_campaign_objective(obj_initial_close_objectives_window)
+
+local function wait_for_quarry_road_connection(field, cs, objective)
+   -- Wait till the construction site is connected to the headquarters
+   sleep(10 * wl.Game().desired_speed)
+   while not field.immovable or field.brn.immovable.debug_economy ~= sf.brn.immovable.debug_economy do
+      if not field.immovable then
+         campaign_message_box(quarry_illegally_destroyed)
+         scroll_to_field(field)
+         mouse_to_field(field)
+
+         cs = nil
+         immovable_is_legal = function(i)
+            -- only allow quarry and flag at this position because the road building below relies on this
+            if (i.fields[1] == field) or (i.fields[1] == field.brn) then
+               cs = allow_constructionsite(i, {"barbarians_quarry"})
+               return cs
+            elseif(i.descr.type_name == "flag") or (i.descr.type_name == "road") then
+               register_immovable_as_allowed(i)
+               return true
+            else return false end
+         end
+
+         -- Wait for a new constructionsite to be placed
+         while not cs do sleep(200) end
+         register_immovable_as_allowed(cs)
+      else
+         campaign_message_box(quarry_not_connected)
+      end
+      sleep(60*1000)
+   end
+   set_objective_done(objective, 0)
+   register_immovable_as_allowed(cs)
+end
+
 function starting_infos()
+   -- So that the player cannot build anything here
+   map:place_immovable("debris00", second_quarry_field, "world")
    reveal_concentric(plr, sf, 13, true, 80)
-   map:place_immovable("debris00",second_quarry_field, "world")
-   -- so that the player cannot build anything here
-
    sleep(1000)
 
-   message_box_objective(plr, initial_message_01)
+   -- Welcome and teach objectives
+   local o = campaign_message_with_objective(initial_message_01, obj_initial_close_story_window)
+   set_objective_done(o, 100)
+
+   wl.ui.MapView().buttons.objectives:click()
+   while not wl.ui.MapView().windows.objectives do sleep(100) end
+   while wl.ui.MapView().windows.objectives do sleep(100) end
    sleep(500)
 
-   local o = message_box_objective(plr, initial_message_02)
+   -- Teach building spaces
+   campaign_message_box(initial_message_02, 200)
+   select_item_from_dropdown("dropdown_menu_showhide", 1)
+   select_item_from_dropdown("dropdown_menu_showhide", 1)
+   local o = campaign_message_with_objective(initial_message_03, obj_initial_toggle_building_spaces)
 
    -- Wait for buildhelp to come on
    while not wl.ui.MapView().buildhelp do
@@ -30,7 +74,7 @@
    -- We take control, everything that we build is legal
    immovable_is_legal = function(i) return true end
 
-   message_box_objective(plr, lumberjack_message_01)
+   campaign_message_box(lumberjack_message_01)
 
    local blocker = UserInputDisabler:new()
    close_windows()
@@ -38,7 +82,7 @@
    scroll_to_field(first_lumberjack_field)
    mouse_to_field(first_lumberjack_field)
    sleep(500)
-   message_box_objective(plr, lumberjack_message_02)
+   campaign_message_box(lumberjack_message_02)
    sleep(500)
 
    click_on_field(first_lumberjack_field)
@@ -48,16 +92,16 @@
    sleep(500)
 
    if wl.ui.MapView().is_building_road then
-      message_box_objective(plr, lumberjack_message_03a)
+      campaign_message_box(lumberjack_message_03a)
    else
       enter_road_building_mode(first_lumberjack_field.brn.immovable)
-      message_box_objective(plr, lumberjack_message_03b)
+      campaign_message_box(lumberjack_message_03b)
    end
    sleep(500)
 
    click_on_field(sf.brn)
 
-   message_box_objective(plr, lumberjack_message_04)
+   campaign_message_box(lumberjack_message_04)
 
    register_immovable_as_allowed(first_lumberjack_field.immovable) -- hut + flag
 
@@ -72,7 +116,7 @@
 
    if not (f.immovable and f.immovable.descr.type_name == "flag") then
       -- only show this if the user has not already built a flag
-      local o = message_box_objective(plr, lumberjack_message_05)
+      local o = campaign_message_with_objective(lumberjack_message_05, obj_lumberjack_place_flag)
 
       local blocker = UserInputDisabler:new()
       close_windows()
@@ -85,27 +129,35 @@
 
       -- Wait for flag
       while not (f.immovable and f.immovable.descr.type_name == "flag") do sleep(300) end
-      set_objective_done(o, 300)
-
-      message_box_objective(plr, lumberjack_message_06)
+      set_objective_done(o, 16 * 1000)
    else
       -- if the flag is already built, show the player a different message box
-      message_box_objective(plr, flag_built)
+      campaign_message_box(lumberjack_message_06, 3 * 1000)
    end
 
-   sleep(30*1000) -- let the player experiment a bit with the speed
-   message_box_objective(plr, construction_site_window)
+   local o = campaign_message_with_objective(lumberjack_message_07, obj_lumberjack_progress)
+   scroll_to_field(first_lumberjack_field)
+   mouse_to_field(first_lumberjack_field)
+
+   while not wl.ui.MapView().windows.building_window do sleep(100) end
+   while wl.ui.MapView().windows.building_window do sleep(100) end
+   set_objective_done(o)
+
+   campaign_message_box(lumberjack_message_08)
+   wl.ui.MapView().dropdowns["dropdown_menu_gamespeed"]:open()
+
+   sleep(20*1000) -- let the player experiment a bit with the window
 
    while #plr:get_buildings("barbarians_lumberjacks_hut") < 1 do sleep(300) end
 
-   message_box_objective(plr, lumberjack_message_07)
+   campaign_message_box(lumberjack_message_09)
 
    learn_to_move()
 end
 
 function learn_to_move()
    -- Teaching the user how to scroll on the map
-   local o = message_box_objective(plr, inform_about_rocks)
+   local o = campaign_message_with_objective(tell_about_keyboard_move, obj_moving_keyboard)
 
    function _wait_for_move()
       local center_map_pixel = wl.ui.MapView().center_map_pixel
@@ -118,12 +170,17 @@
    _wait_for_move()
    set_objective_done(o)
 
-   o = message_box_objective(plr, tell_about_right_drag_move)
+   o = campaign_message_with_objective(tell_about_right_drag_move, obj_moving_right_drag)
 
    _wait_for_move()
    set_objective_done(o)
 
-   o = message_box_objective(plr, tell_about_minimap)
+   -- Teach the minimap
+   campaign_message_box(tell_about_minimap_1)
+
+   -- Open the minimap
+   select_item_from_dropdown("dropdown_menu_mapview", 1)
+   o = campaign_message_with_objective(tell_about_minimap_2, obj_moving_minimap)
 
    -- Wait until the minimap has been opened and closed again
    while not wl.ui.MapView().windows.minimap do sleep(100) end
@@ -131,7 +188,7 @@
 
    set_objective_done(o, 500)
 
-   message_box_objective(plr, congratulate_and_on_to_quarry)
+   campaign_message_box(congratulate_and_on_to_quarry)
 
    build_a_quarry()
 end
@@ -140,7 +197,7 @@
    sleep(200)
 
    -- Teaching how to build a quarry and the nits and knacks of road building.
-   local o = message_box_objective(plr, order_quarry_recap_how_to_build)
+   local o = campaign_message_with_objective(order_quarry_recap_how_to_build, obj_build_a_quarry)
 
    local cs = nil
    immovable_is_legal = function(i)
@@ -174,12 +231,12 @@
 
    immovable_is_legal = function() return true end
 
-   sleep(3000) -- give the game some time to enter road building mode
+   sleep(wl.Game().desired_speed) -- give the game some time to enter road building mode
    if wl.ui.MapView().is_building_road then
-      message_box_objective(plr, talk_about_roadbuilding_00a)
+      campaign_message_box(talk_about_roadbuilding_00a)
    else
       -- show the user how to enter road building mode manually
-      message_box_objective(plr, talk_about_roadbuilding_00b)
+      campaign_message_box(talk_about_roadbuilding_00b)
       click_on_field(first_quarry_field.brn)
       click_on_panel(wl.ui.MapView().windows.field_action.buttons.build_road, 300)
    end
@@ -195,7 +252,7 @@
 
    _rip_road()
 
-   message_box_objective(plr, talk_about_roadbuilding_01)
+   campaign_message_box(talk_about_roadbuilding_01)
    -- Showoff direct roadbuilding
    click_on_field(first_quarry_field.brn)
    click_on_panel(wl.ui.MapView().windows.field_action.buttons.build_road, 300)
@@ -207,7 +264,7 @@
 
    blocker:lift_blocks()
 
-   local o = message_box_objective(plr, talk_about_roadbuilding_02)
+   local o = campaign_message_with_objective(talk_about_roadbuilding_02, obj_build_road_to_quarry)
 
    -- The player is allowed to build roads and flags at will
    immovable_is_legal = function(i)
@@ -217,13 +274,7 @@
       else return false end
    end
 
-   -- Wait till the construction site is connected to the headquarters
-   sleep(20*1000)
-   while first_quarry_field.brn.immovable.debug_economy ~= sf.brn.immovable.debug_economy do
-      message_box_objective(plr,quarry_not_connected)
-      sleep(60*1000)
-      if not first_quarry_field.immovable then message_box_objective(plr,quarry_illegally_destroyed) return end
-   end
+   wait_for_quarry_road_connection(first_quarry_field, cs, o)
 
    second_quarry()
 
@@ -231,7 +282,6 @@
    census_and_statistics()
 
    while #plr:get_buildings("barbarians_quarry") < 2 do sleep(1400) end
-   set_objective_done(o, 0)
 
    messages()
 end
@@ -239,9 +289,11 @@
 function second_quarry()
    sleep(2000)
 
-   local o = message_box_objective(plr, build_second_quarry)
+   local o = campaign_message_with_objective(build_second_quarry, obj_build_the_second_quarry)
+   -- Remove this immovable (debris)
    second_quarry_field.immovable:remove()
-   -- remove this immovable (debris)
+   scroll_to_field(first_quarry_field)
+   mouse_to_field(second_quarry_field)
 
    local cs = nil
    immovable_is_legal = function(i)
@@ -257,18 +309,9 @@
    -- Wait for the constructionsite to be placed
    while not cs do sleep(200) end
 
-   sleep(60*1000)
-   while second_quarry_field.brn.immovable.debug_economy ~= sf.brn.immovable.debug_economy do
-      message_box_objective(plr,quarry_not_connected)
-      sleep(60*1000)
-      if not second_quarry_field.immovable then message_box_objective(plr,quarry_illegally_destroyed) return end
-   end
-
-   set_objective_done(o, 0)
-   register_immovable_as_allowed(cs)
+   wait_for_quarry_road_connection(second_quarry_field, cs, o)
 end
 
-
 function census_and_statistics()
    sleep(15000)
 
@@ -280,40 +323,45 @@
 
    wl.ui.MapView():abort_road_building()
 
-   message_box_objective(plr, census_and_statistics_00)
-
-   click_on_field(first_quarry_field.bln)
-   click_on_panel(wl.ui.MapView().windows.field_action.tabs.watch)
-   click_on_panel(wl.ui.MapView().windows.field_action.buttons.census)
-   sleep(300)
-   click_on_field(first_quarry_field.brn)
-   click_on_panel(wl.ui.MapView().windows.field_action.tabs.watch)
-   click_on_panel(wl.ui.MapView().windows.field_action.buttons.statistics)
-
-   message_box_objective(plr, census_and_statistics_01)
+   campaign_message_box(census_and_statistics_00)
+
+   select_item_from_dropdown("dropdown_menu_showhide", 2)
+   sleep(200)
 
    blocker:lift_blocks()
+
+   local o = campaign_message_with_objective(census_and_statistics_01, obj_show_statistics)
+
+   -- Wait for statistics to come on
+   while not wl.ui.MapView().statistics do sleep(200) end
+   set_objective_done(o, 5 * wl.Game().desired_speed)
+
+   if (#plr:get_buildings("barbarians_quarry") < 2) then
+      campaign_message_box(census_and_statistics_02, 200)
+   end
 end
 
 function messages()
    -- Teach the player about receiving messages
    sleep(10)
+   local old_gamespeed = wl.Game().desired_speed
+   wl.Game().desired_speed = 1000
 
    send_message(plr, teaching_about_messages.title, teaching_about_messages.body, teaching_about_messages, {heading = teaching_about_messages.heading})
-   local o = add_campaign_objective(teaching_about_messages)
+   local o = add_campaign_objective(obj_archive_all_messages)
 
    while #plr.inbox > 0 do sleep(200) end
    set_objective_done(o, 500)
 
-   local o = message_box_objective(plr, closing_msg_window_00)
+   local o = campaign_message_with_objective(closing_msg_window_00, obj_close_message_window)
 
    -- Wait for messages window to close
    while wl.ui.MapView().windows.messages do sleep(300) end
-   set_objective_done(o, 0)
-
-   message_box_objective(plr, closing_msg_window_01)
-
-   sleep(800)
+   set_objective_done(o, 300)
+
+   campaign_message_box(closing_msg_window_01, 800)
+
+   if (wl.Game().desired_speed == 1000) then wl.Game().desired_speed = old_gamespeed end
 
    destroy_quarries()
 end
@@ -336,10 +384,7 @@
    -- Wait for messages to arrive
    while count_quarry_messages() < 2 do sleep(300) end
 
-   local o = message_box_objective(plr, destroy_quarries_message)
-
-   -- From now on, the player can build whatever he wants
-   terminate_bad_boy_sentinel = true
+   local o = campaign_message_with_objective(destroy_quarries_message, obj_destroy_quarries)
 
    while #plr:get_buildings("barbarians_quarry") > 0 do sleep(200) end
    set_objective_done(o)
@@ -351,7 +396,10 @@
    -- Teach about expanding the territory
    sleep(10)
 
-   local o = message_box_objective(plr, introduce_expansion)
+   -- From now on, the player can build whatever he wants
+   terminate_bad_boy_sentinel = true
+
+   local o = campaign_message_with_objective(introduce_expansion, obj_expand_territory)
 
    -- wait until there are soldiers inside so that the player sees the expansion
    local soldier_inside = false
@@ -371,19 +419,20 @@
       sleep(500)
    end
 
-   set_objective_done(o)
-   message_box_objective(plr, military_building_finished)
+   set_objective_done(o, 4 * wl.Game().desired_speed)
+   campaign_message_box(military_building_finished)
 
    conclusion()
 end
 
 function conclusion()
+   set_objective_done(objective_to_explain_objectives)
+
    sleep(5000) -- to give the player time to see his expanded area
 
    -- Conclude the tutorial with final words and information
    -- on how to quit
-   message_box_objective(plr, conclude_tutorial)
-
+   campaign_message_box(conclude_tutorial)
 end
 
 run(bad_boy_sentry)

=== modified file 'data/campaigns/tutorial01_basic_control.wmf/scripting/texts.lua'
--- data/campaigns/tutorial01_basic_control.wmf/scripting/texts.lua	2019-02-03 12:02:57 +0000
+++ data/campaigns/tutorial01_basic_control.wmf/scripting/texts.lua	2019-06-01 15:39:16 +0000
@@ -2,15 +2,14 @@
 --                      Texts for the tutorial mission
 -- =======================================================================
 
--- =========================
--- Some formating functions
--- =========================
-
 include "scripting/richtext_scenarios.lua"
 
--- =============
--- Texts below
--- =============
+-- ================
+-- General messages
+-- ================
+
+local close_story_window_instructions = _[[Click on the ‘OK’ button or press the ‘Enter ⏎’ key on the keyboard to close this window.]]
+
 scold_player = {
    title = _"Nice And Easy Does It All the Time",
    body = (
@@ -21,50 +20,93 @@
    show_instantly = true
 }
 
+-- Teaching basic UI controls
+
+-- ==============
+-- Starting Infos
+-- ==============
+
+obj_initial_close_story_window = {
+   name = "initial_close_story_window",
+   title=_"Close this window",
+   number = 1,
+   body = objective_text(_"Close this window",
+      li(close_story_window_instructions)
+   )
+}
 initial_message_01 = {
    title = _"Welcome to the Widelands Tutorial!",
    body = (
       h1(_"Welcome to Widelands!") ..
-      p(_[[Widelands is a slow-paced build-up strategy game with an emphasis on construction rather than destruction. This tutorial will guide you through the basics of the game.]]) ..
-      li(_[[Dismiss this box by left-clicking on the button below.]])
-   ),
-   h = 300,
-   w = 400
-}
+      li_image("images/logos/wl-ico-64.png",
+         _[[Widelands is a slow-paced build-up strategy game with an emphasis on construction rather than destruction. This tutorial will guide you through the basics of the game.]]) ..
+      li_arrow(_[[You will be guided through this tutorial by objectives]]) ..
+      li(_[[Follow the intructions in the objective below so that I can show you where to find them.]])
+   )
+}
+
+obj_initial_close_objectives_window = {
+   name = "obj_initial_close_objectives_window",
+   title=_"Objectives and how to close this window",
+   number = 1,
+   body = objective_text(_"Closing this window",
+      p(_[[This is the ‘Objectives’ window. You can return to this window for instructions at any time.]]) ..
+      li_image("images/wui/menus/objectives.png", _[[ You can open and close this window by clicking on the ‘Objectives’ button in the toolbar on the bottom of the screen.]]) ..
+      li_arrow(_[[Like any other window, you can also close the ‘Objectives’ window by right-clicking on it.]]) ..
+      li_arrow(_[[When you have accomplished an objective, it will disappear from the list above.]]) ..
+      li(_[[Try it out.]])
+   )
+}
+
+obj_initial_toggle_building_spaces = {
+   name = "initial_toggle_building_spaces",
+   title=_"Show building spaces",
+   number = 1,
+   body = objective_text(_"Show building spaces",
+      p(_[[We need to find a nice place for the lumberjack’s hut. To make this easier, we can activate ‘Show Building Spaces’. There are two ways you can do this:]]) ..
+      li_image("images/wui/menus/showhide.png", _[[Press the Space bar to toggle them, or select ‘Show Building Spaces’ in the ‘Show / Hide’ menu.]]) ..
+      li(_[[Show the building spaces now.]])
+   )
+}
+
 initial_message_02 = {
-   title = _"Diving In",
-   position = "topright",
-   field = sf,
-   body = (
-      h1(_"Let’s dive right in!") ..
-      p(_[[There are three different tribes in Widelands: the Barbarians, the Empire and the Atlanteans. All tribes have a different economy, strength and weaknesses, but the general gameplay is the same for all. We will play the Barbarians for now.]]) ..
-      p(_[[You will usually start the game with one headquarters. This is the big building with the blue flag in front of it. The headquarters is a warehouse that stores wares, workers and soldiers. Some wares are needed for building houses, others for making other wares. Obviously, the wares in the headquarters will not last forever, so you must make sure to replace them. The most important wares in the early game are the basic construction wares: logs and granite. Let’s make sure that we do not run out of logs. For this, we need a lumberjack and a hut for him to stay in.]]) ..
-      p(_[[We need to find a nice place for the lumberjack’s hut. To make this easier, we can activate ‘Show building spaces’. There are two ways you can do this:]]) ..
-      li_arrow(_[[Press the Space bar to toggle them, or]]) ..
-      -- TRANSLATORS: List item. Has an image of the button next to it.
-      li_image("images/wui/menus/menu_toggle_buildhelp.png", _[[click the ‘Show building spaces’ button on the bottom of the screen.]]) ..
-      li(_[[Left-click the ‘OK’ button to close this box and then try it.]])
-   ),
-   obj_name = "enable_buildhelp",
-   obj_title = _"Enable the showing of building spaces",
-   obj_body = (
-      h1(_"Show Building Spaces") ..
-      p(_[[It is easier to understand what type of buildings can be built on which field when the symbols for the building spaces are enabled.]]) ..
-      li_arrow(_[[Press the Space bar to toggle them, or]]) ..
-      -- TRANSLATORS: List item. Has an image of the button next to it.
-      li_image("images/wui/menus/menu_toggle_buildhelp.png", _[[click the ‘Show building spaces’ button on the bottom of the screen.]]) ..
-      li(_[[Right-click on this window now and then give it a try.]])
-   )
-}
+   title = _"Building Spaces",
+   position = "topright",
+   field = sf,
+   body = (
+      h1(_"Let’s dive right in!") ..
+      li_image("tribes/images/barbarians/icon.png",
+         _[[There are four different tribes in Widelands: the Barbarians, the Empire, the Atlanteans and the Frisians. All tribes have a different economy, strength and weaknesses, but the general gameplay is the same for all. We will play the Barbarians for now.]]) ..
+      li_object("barbarians_headquarters", _[[You will usually start the game with one headquarters. This is the big building with the blue flag in front of it. The headquarters is a warehouse that stores wares, workers and soldiers. Some wares are needed for building houses, others for making other wares. Obviously, the wares in the headquarters will not last forever, so you must make sure to replace them. The most important wares in the early game are the basic construction wares: logs and granite. Let’s make sure that we do not run out of logs. For this, we need a lumberjack and a hut for him to stay in.]], plr.color) ..
+      p(_[[We need to find a nice place for the lumberjack’s hut. To make this easier, we can activate ‘Show Building Spaces’.]]) ..
+      li(_[[Left-click the ‘OK’ button to close this window so that I can show you how.]]) ..
+      li_arrow(_[[Note that you cannot close this window by right-clicking on it. I have blocked this so that you will not close it by accident and miss important information.]])
+   )
+}
+
+initial_message_03 = {
+   title = _"Building Spaces",
+   position = "topright",
+   field = sf,
+   body = (
+      h1(_"Let’s dive right in!") ..
+      li_object("barbarians_lumberjacks_hut", _[[Now that I have shown you how to show and hide the building spaces, please switch them on again so that we can place our first building.]], plr.color)
+   )
+}
+
+-- ==========
+-- Lumberjack
+-- ==========
 
 lumberjack_message_01 = {
    title = _"Lumberjack’s Spot",
    position = "topright",
    field = first_lumberjack_field,
    body = (
-      p(_[[There you go. I will explain about all those symbols in a minute. First, let me show you how to make a lumberjack’s hut and how to connect it with a road. There is a sweet spot for a lumberjack right next to those trees. I’ll describe the steps I will take and then ask you to click on the ‘OK’ button for me to demonstrate.]])
+      li_object("barbarians_lumberjacks_hut",
+         _[[There you go. I will explain about all those symbols in a minute. First, let me show you how to make a lumberjack’s hut and how to connect it with a road. There is a sweet spot for a lumberjack right next to those trees. I’ll describe the steps I will take and then ask you to click on the ‘OK’ button for me to demonstrate.]], plr.color)
    ),
-   h = 300,
+   h = 250,
    w = 350
 }
 
@@ -72,20 +114,23 @@
    title = _"Building the Lumberjack",
    position = "topright",
    body = (
-      p(_[[First, I’ll left-click on the symbol where I want the lumberjack’s hut to be built. A window will appear where I can choose between buildings. Because I’ll click a yellow house symbol – which means that its field can house medium and small buildings – I am presented with all the medium buildings that I can build. The lumberjack’s hut is a small building, so I will go on to select the small buildings tab. Then I’ll choose the lumberjack’s hut.]]) ..
+      li_object("barbarians_lumberjacks_hut",
+         _[[First, I’ll left-click on the symbol where I want the lumberjack’s hut to be built. A window will appear where I can choose between buildings. Because I’ll click a yellow house symbol – which means that its field can house medium and small buildings – I am presented with all the medium buildings that I can build. The lumberjack’s hut is a small building, so I will go on to select the small buildings tab. Then I’ll choose the lumberjack’s hut.]], plr.color) ..
       li(_[[Click the ‘OK’ button to watch me. I’ll go really slowly: I will click – then select the tab – and finally I’ll choose the building.]])
    ),
-   h = 300
+   h = 300,
+   w = 350
 }
 
 lumberjack_message_03a = {
    title = _"Building a Connecting Road",
    position = "topright",
    body = (
-      p(_[[That won’t do yet. I still need to connect the lumberjack’s hut to the rest of my road network. After ordering the construction site, I was automatically put into road building mode, so all I have to do is click on the blue flag in front of my headquarters.]])
+      li_image("images/wui/fieldaction/menu_tab_buildroad.png", _[[That won’t do yet. I still need to connect the lumberjack’s hut to the rest of my road network. After ordering the construction site, I was automatically put into road building mode, so all I have to do is click on the blue flag in front of my headquarters.]]) ..
+      li(close_story_window_instructions)
    ),
    show_instantly = true,
-   h = 300,
+   h = 200,
    w = 350
 }
 
@@ -93,10 +138,12 @@
    title = _"Building a Connecting Road",
    position = "topright",
    body = (
-      p(_[[That won’t do yet. I still need to connect the lumberjack’s hut to the rest of my road network. You have disabled the option ‘Start building road after placing a flag’ (to change that, choose ‘Options’ in the Widelands main menu). Therefore, I have entered the road building mode manually. I will tell you later how to do that. To build the road, all I have to do now is click on the blue flag in front of my headquarters.]])
+      li_image("images/wui/fieldaction/menu_tab_buildroad.png",
+         _[[That won’t do yet. I still need to connect the lumberjack’s hut to the rest of my road network. You have disabled the option ‘Start building road after placing a flag’ (to change that, choose ‘Options’ in the Widelands main menu). Therefore, I have entered the road building mode manually. I will tell you later how to do that. To build the road, all I have to do now is click on the blue flag in front of my headquarters.]]) ..
+         li(close_story_window_instructions)
    ),
    show_instantly = true,
-   h = 300,
+   h = 250,
    w = 350
 }
 
@@ -104,169 +151,230 @@
    title = _"Waiting for the Lumberjack to Go Up",
    position = "topright",
    body = (
-      p(_[[Now watch closely while a builder leaves the headquarters and goes to the construction site. Also, a carrier will take position in between the two blue flags and carry wares from one blue flag to the other.]])
+      li_object("barbarians_builder",
+         _[[Now watch closely while a builder leaves the headquarters and goes to the construction site. Also, a carrier will take position in between the two blue flags and carry wares from one blue flag to the other.]], plr.color) ..
+         li(close_story_window_instructions)
+   ),
+   h = 200,
+   w = 350
+}
+
+obj_lumberjack_place_flag = {
+   name = "obj_lumberjack_place_flag",
+   title=_"Build a flag to divide the road to the lumberjack",
+   number = 1,
+   body = objective_text(_"Build a Flag on the Road",
+      p(_[[The shorter your road segments are, the faster your wares will be transported. You should therefore make sure that your roads have as many flags as possible.]]) ..
+      li(_[[Build a blue flag now in the middle of the road that connects your headquarters to your lumberjack’s hut.]]) ..
+      li_image("images/wui/fieldaction/menu_build_flag.png",_[[To build the flag, click on the yellow flag symbol in between the two blue flags we just placed and then click on the build flag symbol.]])
    ),
    h = 300,
    w = 350
 }
-
 lumberjack_message_05 = {
    title = _"Placing Another Flag",
    position = "topright",
    body = (
-      p(_[[Nice how they are working, isn’t it? But the poor carrier has a very long way to go. We can make it easier for him (and more efficient for us) by placing another blue flag on the road.]]) ..
-      li(_[[You try it this time: click on the yellow flag symbol in between the two blue flags we just placed and then click on the]]) ..
-      li_image("images/wui/fieldaction/menu_build_flag.png", _"build flag symbol.")
+      li_object("barbarians_carrier",
+         _[[Nice how they are working, isn’t it? But the poor carrier has a very long way to go. We can make it easier for him (and more efficient for us) by placing another blue flag on the road. You try it this time.]], plr.color)
    ),
-   h = 300,
-   obj_name = "build_flag_on_road_to_lumberjack",
-   obj_title = _"Build a flag to divide the road to the lumberjack",
-   obj_body = (
-      h1(_"Build a Flag on the Road") ..
-      p(_[[The shorter your road segments are, the faster your wares will be transported. You should therefore make sure that your roads have as many flags as possible.]]) ..
-      li(_[[Build a blue flag now in the middle of the road that connects your headquarters to your lumberjack’s hut.]])
-   )
+   h = 450,
+   w = 350
 }
 
 lumberjack_message_06 = {
-   title = _"Waiting For the Hut to be Finished",
-   position = "topright",
-   body = (
-      p(_[[Well done! Let’s wait till the hut is finished.]]) ..
-      p(_[[If you want things to go faster, simply use the Page Up key on your keyboard to increase the game speed. You can use Page Down to make the game slower again.]])
-   ),
-   h = 300,
-   w = 350
-}
-
-flag_built = {
-   title = _"Waiting for the Hut to be Finished",
-   position = "topright",
-   body = (
-      p(_[[I wanted to teach you how to build new flags, but it seems you have already found out on your own. Well done!]]) ..
+   title = _"Waiting for the Lumberjack to Go Up",
+   position = "topright",
+   body = (
+      li_image("images/wui/fieldaction/menu_tab_buildroad.png",
+         _[[I wanted to teach you how to build new flags, but it seems you have already found out on your own. Well done!]]) ..
       p(_[[Now you have split the road in two parts with a carrier each. This means less work for him and higher efficiency for us. You should therefore always place as many flags as possible on your roads.]]) ..
-      p(_[[Now we only have to wait till the hut is finished.]]) ..
-      p(_[[If you want things to go faster, simply use the Page Up key on your keyboard to increase the game speed. You can use Page Down to make the game slower again.]])
+      li(close_story_window_instructions)
    ),
-   h = 350
+   h = 250,
+   w = 350
 }
 
-construction_site_window = {
+obj_lumberjack_progress = {
+   name = "obj_lumberjack_progress",
+   title=_"Let’s see the progress",
+   number = 1,
+   body = objective_text(_"Let’s see the progress",
+      li(_[[Click on the construction site to have a look at it, then close it again when you have seen enough.]]) ..
+      li_arrow(_[[To close the construction site’s window, simply right-click on it.]])
+   ),
+   h = 300,
+   w = 350
+}
+lumberjack_message_07 = {
    title = _"The Construction Site",
-   body = (
-      h1(_"Let's see the progress") ..
-      p(_[[If you click on the construction site, a window will open. You can see the wares that are still missing grayed out. You can also see the progress of this construction site.]]) ..
-      -- The player doesn't know about the statistics yet. First things first.
-      p(_[[To close the window, simply right-click on it. All windows in Widelands can be closed that way, except the ones with instructions, like this one. Try it out!]])
-   ),
-   h = 300,
-   w = 350
-}
-
-lumberjack_message_07 = {
+   position = "topright",
+   body = (
+      h1(_"Let’s see the progress") ..
+      li_object("barbarians_builder", _[[If you click on the construction site, a window will open. You can see the wares that are still missing grayed out. You can also see the progress of this construction site.]], plr.color)
+   ),
+   h = 450,
+   w = 350
+}
+
+lumberjack_message_08 = {
+   title = _"Waiting for the Lumberjack to Go Up",
+   position = "topright",
+   body = (
+      p(_[[Well done! Let’s wait till the hut is finished.]]) ..
+      li_image("images/wui/menus/gamespeed.png",
+   _[[If you want things to go faster, simply use the Page Up key on your keyboard to increase the game speed. You can use Page Down to make the game slower again.]])
+   ),
+   h = 200,
+   w = 350
+}
+
+lumberjack_message_09 = {
    title = _"The Lumberjack’s Hut is Done",
    position = "topright",
    body = (
-      p(_[[Excellent. The lumberjack’s hut is done. A lumberjack will now move in and start chopping down trees, so our log income is secured for now. Now on to the granite.]])
+      li_object("barbarians_lumberjacks_hut", _[[Excellent. The lumberjack’s hut is done. A lumberjack will now move in and start chopping down trees, so our log income is secured for now. Now on to the granite.]], plr.color)
    ),
-   h = 300,
+   h = 200,
    w = 350
 }
 
-inform_about_rocks = {
+-- ==================
+-- Moving the mapview
+-- ==================
+
+local moving_view_instructions =
+   h2(_"Moving Your View") ..
+   p(_[[Moving your view is essential to get a complete overview of your whole economy. There are three ways to move your view in Widelands.]]) ..
+   li_arrow(_[[The first one is to use the cursor keys on your keyboard.]]) ..
+   li_arrow(_[[The second one is the more common and faster one: press-and-hold the right mouse button anywhere on the map, then move your mouse around and you’ll see the view scroll.]]) ..
+   li_arrow(_[[The third one is to use the minimap. It is especially useful for traveling big distances.]])
+
+
+obj_moving_keyboard = {
+   name = "move_view_with_cursor_keys",
+   title=_"Move your view with the cursor keys",
+   number = 1,
+   body = objective_text(_"Move your view with the cursor keys",
+      li(_[[There are three ways to move your view. The first one is using the cursor keys on your keyboard. Go ahead and try this out.]]) .. moving_view_instructions
+   ),
+}
+tell_about_keyboard_move = {
    title = _"Some Rocks Were Found",
    body = (
       h1(_"Getting a Quarry Up") ..
-      p(_[[Granite can be mined in granite mines, but the easier way is to build a quarry next to some rocks lying around. As it happens, there is a pile of them just to the west (left) of your headquarters. I will teach you now how to move your view over there.]]) ..
-      li(_[[There are three ways to move your view. The first one is using the cursor keys on your keyboard. Go ahead and try this out.]]) ..
-      li(_[[Click the ‘OK’ button and then move the view using the cursor keys.]])
+      li_object("greenland_rocks6",
+         _[[Granite can be mined in granite mines, but the easier way is to build a quarry next to some rocks lying around. As it happens, there is a pile of them just to the west (left) of your headquarters. I will teach you now how to move your view over there.]])
    ),
-   h = 350,
-   obj_name = "move_view_with_cursor_keys",
-   obj_title = _"Move your view with the cursor keys",
-   obj_body = (
-      h1(_"Moving Your View") ..
-      p(_[[Moving your view is essential to get a complete overview of your whole economy. There are three ways to move your view in Widelands.]]) ..
-      li(_[[The first one is to use the cursor keys on your keyboard.]]) ..
-      li(_[[The second one is the more common and faster one: press-and-hold the right mouse button anywhere on the map, then move your mouse around and you’ll see the view scroll.]]) ..
-      li(_[[The third one is to use the minimap. It is especially useful for traveling big distances.]])
-   )
+   h = 450,
 }
 
+obj_moving_right_drag = {
+   name = "move_view_with_mouse",
+   title=_"Move your view with the mouse",
+   number = 1,
+   body = objective_text(_"Move your view with the mouse",
+      li(_[[Simply right-click-and-hold anywhere on the map, then drag the mouse and instead of the cursor, the view will be moved. Try it.]]) .. moving_view_instructions
+   ),
+}
 tell_about_right_drag_move = {
-   title = _"Other Ways to Move the View",
+   title = _"Moving Your View",
    body = (
-      p(_[[Excellent. Now there is a faster way to move, using the mouse instead:]]) ..
-      li(_[[Simply right-click-and-hold anywhere on the map, then drag the mouse and instead of the cursor, the view will be moved. Try it.]])
+      h1(_"Other Ways to Move the View") ..
+      li_image("images/ui_basic/cursor_click.png",
+         _[[Excellent. Now there is a faster way to move, using the mouse instead.]])
    ),
-   h = 300,
-   w = 350,
-   obj_name = "move_view_with_mouse",
-   obj_title = _"Move your view with the mouse",
-   obj_body = inform_about_rocks.obj_body,
+   h = 450,
 }
 
-tell_about_minimap = {
-   title = _"Use the minimap",
-   body = (
-      p(_[[Very good. And now about the minimap. You can open it by clicking on the]]) ..
-      li_image("images/wui/menus/menu_toggle_minimap.png", _[[minimap button at the bottom of the screen or simply by using the keyboard shortcut ‘m’.]]) ..
-      p(_[[The minimap shows the complete map in miniature. You can directly jump to any field by left-clicking on it. You can also toggle buildings, roads, flags and player indicators on and off inside the minimap.]]) ..
-      li(_[[Try it out. Open the minimap, click on a few buttons and try moving around. Close it when you have experimented enough.]])
-   ),
-   h = 350,
-   obj_name = "use_minimap",
-   obj_title = _"Learn to use the minimap",
-   obj_body = (
-      li(_[[Open the minimap by using the third button from the left on the bottom of your screen or the ‘m’ key.]]) ..
+obj_moving_minimap = {
+   name = "use_minimap",
+   title=_"Learn to use the minimap",
+   number = 1,
+   body = objective_text(_"Learn to use the minimap",
+      li(_[[Try moving around by clicking on the minimap]]) ..
       li(_[[Play around a bit with the different overlays (roads, flags, etc.)]]) ..
-      li(_[[Close the minimap when you are ready to continue by using the same button or ‘m’ again. Of course, a right-click also works.]])
-   )
+      li(_[[When you are ready to continue, close the minimap by selecting ‘Hide Minimap’ in the ‘Map View’ menu or by pressing ‘m’. Of course, a right-click also works.]])
+   ),
+}
+tell_about_minimap_1 = {
+   title = _"Moving Your View",
+   body = (
+      h1(_"Using the Minimap") ..
+      li_image("images/wui/menus/toggle_minimap.png",
+         p(_[[Very good. And now about the minimap. ]]) ..
+         -- TRANSLATORS it = the minimap
+         p(_[[You can open it by selecting the ‘Show Minimap’ entry in the ‘Map View’ menu at the bottom of the screen or simply by using the keyboard shortcut ‘m’.]])) ..
+      -- TRANSLATORS it = the minimap
+      li_arrow(_[[I will open it for you.]])
+   ),
+   w = 350,
+   h = 250,
+}
+
+tell_about_minimap_2 = {
+   title = _"Moving Your View",
+   body = (
+   h1(_"Using the Minimap") ..
+      li_image("images/wui/menus/toggle_minimap.png",
+         _([[The minimap shows the complete map in miniature. ]]
+         .. [[You can directly jump to any field by left-clicking on it. ]]
+         .. [[You can also toggle buildings, roads, flags and player indicators on and off inside the minimap.]]))
+   ),
+   h = 450,
 }
 
 congratulate_and_on_to_quarry = {
    title = _"Onward to the Quarry",
-   body = p(_[[Great. Now about that quarry…]]),
+   body = li_object("greenland_rocks6",_[[Great. Now about that quarry…]]),
    h = 200,
    w = 250
 }
 
+-- ======
+-- Quarry
+-- ======
+
+obj_build_a_quarry = {
+   name = "build_a_quarry",
+   title=_"Build a quarry next to the rocks",
+   number = 1,
+   body = objective_text(_"Build a Quarry",
+      li(_[[There are some rocks to the west of your headquarters. Build a quarry right next to them.]]) ..
+      li_image("images/wui/overlays/small.png", _[[The quarry is a small building like the lumberjack’s hut. You can therefore build it on any field that shows a red, yellow or green house when the building spaces symbols are enabled (Press Space for that).]]) ..
+      li_arrow(_[[Just click on any house symbol next to the rocks, select the small buildings tab in the window that opens up, then click on the quarry symbol.]])
+   ),
+}
 order_quarry_recap_how_to_build = {
    field = first_quarry_field,
    position = "topright",
    title = _"How to Build a Quarry",
    body = (
-      p(_[[Build a quarry next to those rocks here. Remember how I did it earlier?]]) ..
-      p(_[[Make sure that you are showing the building spaces, then just click on the space where you want the building to be, choose it from the window that appears, and it is placed. Maybe this is a good time to explain about all those building space symbols we activated earlier.]]) ..
-      p(_[[You can build four things on fields in Widelands: flags, small houses, medium houses and big houses. But not every field can hold everything. The build space symbols ease recognition:]]) ..
+      li_object("barbarians_quarry",
+         p(_[[Build a quarry next to those rocks here. Remember how I did it earlier?]]) ..
+         p(_[[Make sure that you are showing the building spaces, then just click on the space where you want the building to be, choose it from the window that appears, and it is placed. Maybe this is a good time to explain about all those building space symbols we activated earlier.]]) ..
+         p(_[[You can build four things on fields in Widelands: flags, small houses, medium houses and big houses. But not every field can hold everything. The build space symbols ease recognition:]]), plr.color) ..
       li_image("images/wui/overlays/big.png", _[[Everything can be built on the green house symbol.]]) ..
       li_image("images/wui/overlays/medium.png", _[[Everything except for big buildings can be built on a yellow house symbol.]]) ..
       li_image("images/wui/overlays/small.png", _[[Red building symbols can only hold small buildings and flags.]]) ..
       li_image("images/wui/overlays/set_flag.png", _[[And finally, the yellow flag symbol only allows for flags.]]) ..
-      p(_[[If you place something on a field, the surrounding fields might have less space for holding buildings, so choose your fields wisely.]]) ..
-      li(_[[Now go ahead, try it. The quarry is a small building, so if you click on a medium or big building symbol, you will have to select the small buildings tab first to find it. Go on, check it out!]])
-   ),
-   obj_name = "build_a_quarry",
-   obj_title = _"Build a quarry next to the rocks",
-   obj_body = (
-      h1(_"Build a Quarry") ..
-      li(_[[There are some rocks to the west of your headquarters. Build a quarry right next to them.]]) ..
-      li(_[[The quarry is a small building like the lumberjack’s hut. You can therefore build it on any field that shows a red, yellow or green house when the building spaces symbols are enabled (Press Space for that).]]) ..
-      li(_[[Just click on any house symbol next to the rocks, select the small buildings tab in the window that opens up, then click on the quarry symbol.]])
+      p(_[[If you place something on a field, the surrounding fields might have less space for holding buildings, so choose your fields wisely.]])
    )
 }
 
+local explain_abort_roadbuilding = li_image("images/wui/menu_abort.png", _[[If you decide you do not want to build a road at this time, you can cancel road building by clicking on the starting flag of the road and selecting the abort symbol.]])
+
 talk_about_roadbuilding_00a = {
    position = "topright",
    field = wl.Game().map:get_field(9,12),
    title = _"Road Building",
    body = (
-      p(_[[Excellent! Directly after placing the building, you have been switched into road building mode. The new road will start at the flag in front of your newly placed construction site. You can enter road building mode for any flag by left-clicking on a flag and selecting]]) ..
-      li_image("images/wui/fieldaction/menu_build_way.png", _[[the road building symbol.]]) ..
-      p(_[[If you decide you do not want to build a road at this time, you can cancel road building by clicking on the starting flag of the road and selecting]]) ..
-      li_image("images/wui/menu_abort.png", _[[the abort symbol.]]) ..
+      li_image("images/wui/fieldaction/menu_tab_buildroad.png", _[[Excellent! Directly after placing the building, you have been switched into road building mode. The new road will start at the flag in front of your newly placed construction site.]]) ..
+      li_image("images/wui/fieldaction/menu_build_way.png", _[[You can enter road building mode for any flag by left-clicking on a flag and selecting the road building symbol.]]) ..
+      explain_abort_roadbuilding ..
       p(_[[Now, about this road. Remember: we are already in road building mode since you just ordered the quarry. You can either make it longer by one field at a time by left-clicking multiple times on neighboring fields for perfect control over the route the road takes, like so:]])
    ),
+   h = 300,
    show_instantly = true
 }
 
@@ -275,12 +383,11 @@
    field = road_building_field,
    title = _"Road Building",
    body = (
-      p(_[[Excellent! To enter road building mode for any flag, left-click on a flag and select]]) ..
-      li_image("images/wui/fieldaction/menu_build_way.png", _[[the road building symbol.]]) ..
-      p(_[[If you decide that you do not want to build a road at this time, you can cancel road building by clicking on the starting flag of the road and selecting]]) ..
-      li_image("images/wui/menu_abort.png", _[[the abort symbol.]]) ..
+      li_image("images/wui/fieldaction/menu_build_way.png", _[[ Excellent! To enter road building mode for any flag, left-click on a flag and select the road building symbol.]]) ..
+      explain_abort_roadbuilding ..
       p(_[[Now, about this road. I’ll enter the road building mode and then make it longer by one field at a time by left-clicking multiple times on neighboring fields for perfect control over the route the road takes, like so:]])
    ),
+   h = 300,
    show_instantly = true
 }
 
@@ -288,38 +395,38 @@
    position = "topright",
    field = road_building_field,
    title = _"Road Building",
-   body = p(_[[Or, you can directly click the flag where the road should end, like so:]]),
+   body = li_object("barbarians_flag", _[[Or, you can directly click the flag where the road should end, like so:]], plr.color),
    h = 200,
    w = 250
 }
 
+obj_build_road_to_quarry = {
+   name = "build_road_to_quarry",
+   title=_"Connect the quarry to the headquarters",
+   number = 1,
+   body = objective_text(_"Connect Your Construction Site",
+      li(_[[Connect your quarry construction site to your headquarters with a road. You would have been put directly into road building mode after ordering a new site. But now, you aren’t.]]) ..
+      li_arrow(_[[To build a completely new road, just click on the flag in front of your construction site, click on the build road icon and then click on the flag in front of your headquarters. Wait for the completion of the quarry.]]) ..
+      li_arrow(_[[If you hold Ctrl or Shift+Ctrl while you finish the road, flags are placed automatically.]])
+   ),
+}
 talk_about_roadbuilding_02 = {
    position = "topright",
    title = _"Road Building",
    body = (
-      p(_[[One more thing: around the field where your road would end, you can see different markers. They have the following meaning:]]) ..
+      li_image("images/wui/fieldaction/menu_tab_buildroad.png", _[[One more thing: around the field where your road would end, you can see different markers. They have the following meaning:]]) ..
       li_image("images/wui/overlays/roadb_green.png", _[[The terrain is flat here. Your carriers will be very swift on this terrain.]]) ..
       li_image("images/wui/overlays/roadb_yellow.png", _[[There is a small slope to climb to reach this field. This means that your workers will be faster walking downhill than they will be walking uphill.]]) ..
       li_image("images/wui/overlays/roadb_red.png", _[[The connection between the fields is extremely steep. The speed increase in one direction is huge while the slowdown in the other is also substantial.]]) ..
-      p(_[[Keep the slopes in mind while placing roads and use them to your advantage. Also, try to keep roads as short as possible and always remember to place as many flags as you can on road segments to share the load better.]]) ..
-      li_arrow(_[[If you hold Ctrl or Shift+Ctrl while you finish the road, flags are placed automatically.]]) ..
-      li(_[[Now please rebuild the road between your quarry and your headquarters.]])
+      p(_[[Keep the slopes in mind while placing roads and use them to your advantage. Also, try to keep roads as short as possible and always remember to place as many flags as you can on road segments to share the load better.]])
    ),
-   h = 450,
-   obj_name = "build_road_to_quarry",
-   obj_title = _"Connect the quarry to the headquarters",
-   obj_body = (
-      h1(_"Connect Your Construction Site") ..
-      p(_[[Connect your quarry construction site to your headquarters with a road. You would have been put directly into road building mode after ordering a new site. But now, you aren’t.]]) ..
-      li_arrow(_[[To build a completely new road, just click on the flag in front of your construction site, click on the build road icon and then click on the flag in front of your headquarters. Wait for the completion of the quarry.]]) ..
-      li_arrow(_[[If you hold Ctrl or Shift+Ctrl while you finish the road, flags are placed automatically.]])
-   )
+   h = 450
 }
 
 quarry_not_connected = {
    title = _"Quarry not Connected",
    body = (
-      p(_[[Your workers do not like to walk across country. You have to build a road from your headquarters to the construction site so that carriers can transport wares. The simplest way is to click on the construction site’s flag, choose ‘Build road’, and then click on the destination flag (the one in front of your headquarters), just like I’ve demonstrated.]])
+      li_object("barbarians_carrier", _[[Your workers do not like to walk across country. You have to build a road from your headquarters to the construction site so that carriers can transport wares. The simplest way is to click on the construction site’s flag, choose ‘Build road’, and then click on the destination flag (the one in front of your headquarters), just like I’ve demonstrated.]], plr.color)
    ),
    w = 350,
    h = 250
@@ -328,87 +435,125 @@
 quarry_illegally_destroyed = {
    title = _"You Destroyed the Construction Site!",
    body = (
-      p(_[[It seems like you destroyed a construction site for a quarry we wanted to build. Since we need the granite, I suggest you reload the game from a previous savegame. Luckily, these are created from time to time. To do so, you have to go back to the main menu and choose ‘Single Player’ → ‘Load Game’. And please be a bit more careful next time.]])
+      li_object("barbarians_quarry", _[[It seems like you destroyed a construction site for a quarry we wanted to build. Luckily, we still have enough logs left this time, so you can simply build another one.]], plr.color) ..
+      li_arrow(_[[You can also reload the game from a previous savegame. Luckily, these are created from time to time. To do so, you will have to go back to the main menu and choose ‘Single Player’ → ‘Load Game’. And please be a bit more careful next time.]])
    ),
    w = 350,
    h = 250
 }
 
+obj_build_the_second_quarry = {
+   name = "build_the_second_quarry",
+   title=_"Build another quarry",
+   number = 1,
+   body = objective_text(_"Build another quarry",
+      li(_[[Build a second quarry near the rocks and connect it to your road network.]]) ..
+      li_arrow(_[[You can connect the new road to any flag of your existing road network. You can create junctions everywhere, not only in front of buildings.]])
+   ),
+}
 build_second_quarry = {
    position = "topright",
    title = _"Build a second quarry",
    body = (
-      p(_[[When there are many rocks, you can consider building another quarry. This will make the granite production faster.]]) ..
-      li(_[[Build a second quarry near the rocks and connect it to your road network.]])
-   ),
-   obj_name = "build_the_second_quarry",
-   obj_title = _"Build another quarry",
-   obj_body = (
-      h1(_"Build another quarry") ..
-      p(_[[Build a second quarry next to the rocks. Do not forget to connect it to another flag.]]) ..
-      li(_[[You can connect the new road to any flag of your existing road network. You can create junctions everywhere, not only in front of buildings.]])
-   ),
-   h = 300,
-   w = 350
+      li_object("barbarians_quarry", _[[When there are many rocks, you can consider building another quarry. This will make the granite production faster.]], plr.color)
+   ),
+   h = 300
 }
 
+-- ===================
+-- Census & Statistics
+-- ===================
+
 census_and_statistics_00 = {
    title = _"Census and Statistics",
    body = (
-      p(_[[While we wait, I’ll quickly show you another useful feature. All construction sites look the same, and some buildings look alike. It is sometimes hard to tell them apart. Widelands offers a feature to show label texts over the buildings. They are called the ‘census’ and you can toggle them via the ‘c’ key or via the button on the ‘Watch’ tab of any field.]]) ..
-      p(_[[Similar to this are the building statistics, which are also toggled via a button on the ‘Watch’ tab of any field. The hotkey for it is ‘s’. This will display information about the productivity of buildings or the progress of construction sites.]]) ..
-      p(_[[Let me quickly enable these two for you. Remember: ‘c’ and ‘s’ are the keys. Alternatively, you can click on any field without a building on it, select the watch tab and then click on the corresponding buttons.]])
+      li_image("images/wui/menus/toggle_census.png", _[[While we wait, I’ll quickly show you another useful feature. All construction sites look the same, and some buildings look alike. It is sometimes hard to tell them apart. Widelands offers a feature to show label texts over the buildings. They are called the ‘census’.]]) ..
+      li_arrow(_[[In order to show or hide the building census labels, you can select the ‘Show Census’ / ‘Hide Census’ entry from the ‘Show / Hide’ menu on the bottom, or press the ‘c’ key on the keyboard.]]) ..
+      p(_[[Let me enable the census for you.]])
+   ),
+   position = "topright",
+   h = 300,
+   w = 350
+}
+
+obj_show_statistics = {
+   name = "show_statistics",
+   title=_"Show the building statistics",
+   number = 1,
+   body = objective_text(_"Show the building statistics",
+      li(_[[Show the building statistics labels, so that we can check the progress of our quarry construction more easily.]]) ..
+      li_arrow(_[[In order to show or hide the building statistics labels, you can select the ‘Show Statistics’ entry from the ‘Show / Hide’ menu on the bottom, or press the ‘s’ key on the keyboard.]])
    )
 }
-
 census_and_statistics_01 = {
    title = _"Census and Statistics",
-   body = (p(_[[Now we know what’s going on. Let’s wait for the quarries to finish.]])),
-   h = 200,
+   body = (
+      li_image("images/wui/menus/toggle_statistics.png",
+         p(_[[Now, wouldn’t it be nice to check on our quarries’ progress without having to open their windows?]]) ..
+         p(_[[In addition to the buildings’ census, you can also activate statictics labels on them. This will display information about the productivity of buildings or the progress of construction sites.]]))
+   ),
+   position = "topright",
+   h = 400,
+   w = 350
+}
+
+census_and_statistics_02 = {
+   title = _"Census and Statistics",
+   body = (
+      li_object("barbarians_quarry", _[[Now we know what’s going on. Let’s wait for the quarries to finish.]], plr.color)
+   ),
+   position = "topright",
+   h = 150,
    w = 250
 }
 
+-- ========
+-- Messages
+-- ========
+
+obj_archive_all_messages = {
+   name = "archive_all_messages",
+   title=_"Archive all messages in your inbox",
+   number = 1,
+   body = objective_text(_"Archive Your Inbox Messages",
+      li(_[[Archive all your messages in your inbox now.]]) ..
+      li_image("images/wui/messages/message_archive.png", _[[Keep clicking the ‘Archive selected message’ button until all messages have been archived and the list is empty.]]) ..
+      li_arrow(_[[Once you have archived a message, another message will be selected automatically from the list.]]) ..
+      li_arrow(_[[You can also hold down the Ctrl or Shift key to select multiple messages, or press Ctrl + A to select them all.]]) ..
+      li_arrow(_[[You can toggle the message window by pressing ‘n’ or clicking the second button from the right at the very bottom of the screen. The newest message will be marked for you automatically.]]) ..
+      li_arrow(_[[The message window is central to fully controlling your tribe’s fortune. However, you will get a lot of messages in a real game. To keep your head straight, you should try to keep the inbox empty.]])
+   )
+}
 teaching_about_messages = {
    popup = true,
    title = _"Messages",
    heading = _"Introducing Messages",
    body = (
-      p(_[[Hi, it’s me again! This time, I have sent you a message. Messages are sent to you by Widelands to inform you about important events: empty mines, attacks on your tribe, won or lost military buildings, resources found…]]) ..
+      li_image("images/wui/menus/message_new.png",_[[Hi, it’s me again! This time, I have sent you a message. Messages are sent to you by Widelands to inform you about important events: empty mines, attacks on your tribe, won or lost military buildings, resources found…]]) ..
       p(_[[The message window can be toggled by the second button from the right at the bottom of the screen. This button will also change appearance whenever new messages are available, but there is also a bell sound played whenever you receive a new message.]]) ..
-      p(_[[You have two messages at the moment. This one, which you are currently reading, and the one that informed you that a new headquarters was added to your economy. Let’s learn how to archive messages: first, select the message that you wish to archive by clicking on it in the list. Then, click the]]) ..
-      li_image("images/wui/messages/message_archive.png", _[[‘Archive selected message’ button to move it into your archive.]]) ..
-      p(_[[Once you have archived a message, another message will be selected automatically from the list.]]) ..
-      li_arrow(_[[You can also hold down the Ctrl or Shift key to select multiple messages, or press Ctrl + A to select them all.]]) ..
-      li(_[[Archive all messages that you currently have in your inbox, including this one.]])
-   ),
-   obj_name = "archive_all_messages",
-   obj_title = _"Archive all messages in your inbox",
-   obj_body = (
-      h1(_"Archive Your Inbox Messages") ..
-      p(_[[The message window is central to fully controlling your tribe’s fortune. However, you will get a lot of messages in a real game. To keep your head straight, you should try to keep the inbox empty.]]) ..
-      li(_[[Archive all your messages in your inbox now.]]) ..
-      li_arrow(_[[To do so, open the message window by pressing ‘n’ or clicking the second button from the right at the very bottom of the screen. The newest message will be marked for you automatically. Keep clicking the ‘Archive selected message’ button until all messages have been archived and the list is empty.]]) ..
-      li_arrow(_[[You can also hold down the Ctrl or Shift key to select multiple messages, or press Ctrl + A to select them all.]])
+      p(_[[You have two messages at the moment. This one, which you are currently reading, and the one that informed you that a new headquarters was added to your economy. Let’s learn how to archive messages:]]) ..
+      new_objectives(obj_archive_all_messages)
    )
 }
 
+obj_close_message_window = {
+   name = "close_message_window",
+   title=_"Close the messages window",
+   number = 1,
+   body = objective_text(_"Close the Messages Window",
+      p(_[[All windows in Widelands can be closed by right-clicking into them. Some windows can also be toggled with the buttons and menus at the very bottom of the screen.]]) ..
+      li(_[[Close the messages window now by right-clicking into it.]])
+   )
+}
 closing_msg_window_00 = {
    position = "topright",
    field = first_quarry_field,
    title = _"Closing Windows",
    body = (
-      p(_[[Excellent. Do you remember how to close windows? You simply have to right-click on them. This will work with all windows except for story message windows like this one. Go ahead and try it.]]) ..
-      li(_[[First, close this window by pressing the button below, then right-click into the messages window to close it.]])
+      li_image("images/wui/menus/message_old.png",_[[Excellent. Do you remember how to close windows? You simply have to right-click on them. This will work with all windows except for story message windows like this one. Go ahead and try it.]])
    ),
-   h = 300,
-   w = 350,
-   obj_name = "close_message_window",
-   obj_title = _"Close the messages window",
-   obj_body = (
-      h1(_"Close the Messages Window") ..
-      p(_[[All windows in Widelands can be closed by right-clicking into them. Some windows can also be toggled with the buttons at the very bottom of the screen.]]) ..
-      li(_[[Close the messages window now by right-clicking into it.]])
-   )
+   h = 400,
+   w = 350
 }
 
 closing_msg_window_01 = {
@@ -416,71 +561,85 @@
    field = first_quarry_field,
    title = _"Closing Windows",
    body = (
-      p(_[[Well done! Let’s see how messages work in a real game, shall we? For this, I’ll take all rocks away from the poor stonemasons in the quarries. They will then send a message each that they can’t find any in their work areas the next time they try to do some work.]])
+      li_object("barbarians_quarry", _[[Well done! Let’s see how messages work in a real game, shall we? For this, I’ll take all rocks away from the poor stonemasons in the quarries. They will then send a message each that they can’t find any in their work areas the next time they try to do some work.]], plr.color)
    ),
-   h = 300,
+   h = 250,
    w = 350
 }
 
+obj_destroy_quarries = {
+   name = "destroy_quarries",
+   title=_"Destroy the two quarries",
+   number = 1,
+   body = objective_text(_"Destroy the Quarries",
+      li(_[[Since our quarries are useless now, you can destroy them and reuse the space later on.]]) ..
+      p(_[[There are two different ways of destroying a building: burning down and dismantling. Try them both out on your quarries.]]) ..
+      li_image("images/wui/buildings/menu_bld_bulldoze.png", _[[Burning down the quarry: This is the fastest way of clearing the space. While the worker abandons the building, the wares are lost.]]) ..
+      li_image("images/wui/buildings/menu_bld_dismantle.png", _[[Dismantling the quarry: A builder will walk from the headquarters to dismantle the quarry piece by piece. Thereby, you regain some of the resources you used for the construction.]])
+   )
+}
 destroy_quarries_message = {
    position = "topright",
    title = _"Messages Arrived!",
    body = (
-      p(_[[You received some messages. See how the button at the bottom of the screen has changed appearance? You can destroy the quarries now as they are no longer of any use and just blocking space. To do so, there are two possibilities:]]) ..
-      li_image("images/wui/buildings/menu_bld_bulldoze.png", _[[Burning down the quarry: this is the fastest way of clearing the space. While the worker abandons the building, the wares are lost.]]) ..
-      li_image("images/wui/buildings/menu_bld_dismantle.png", _[[Dismantling the quarry: a builder will walk from the headquarters to dismantle the quarry piece by piece. Thereby, you regain some of the resources you used for the construction.]])
+      li_image("images/wui/menus/message_new.png", _[[You received some messages. See how the button at the bottom of the screen has changed appearance?]])
    ),
-   h = 300,
-   obj_name = "destroy_quarries",
-   obj_title = _"Destroy the two quarries",
-   obj_body = (
-      p(_[[Since our quarries are useless now, you can destroy them and reuse the space later on.]]) ..
-      li_arrow(_[[There are two different ways of destroying a building: burning down and dismantling. Try them both out on your quarries.]]) ..
-      li_image("images/wui/buildings/menu_bld_bulldoze.png", _[[Burning down the quarry: This is the fastest way of clearing the space. While the worker abandons the building, the wares are lost.]]) ..
-      li_image("images/wui/buildings/menu_bld_dismantle.png", _[[Dismantling the quarry: A builder will walk from the headquarters to dismantle the quarry piece by piece. Thereby, you regain some of the resources you used for the construction.]])
+   h = 400,
+   w = 350
+}
+
+-- =========
+-- Expansion
+-- =========
+
+obj_expand_territory = {
+   name = "expand_territory",
+   title=_"Expand your territory",
+   number = 1,
+   body = objective_text(_"Make your Territory Grow",
+      li(_[[Build a military building on your border.]]) ..
+      li_arrow(_[[In Widelands, it is necessary to build many buildings, which take up a lot of space. To expand your territory, you have to build military buildings next to your border. Every tribe has several military buildings.]]) ..
+      li_arrow(_[[The Barbarians have four different military buildings you can build: the sentry (small), the barrier and the tower (both medium) and the fortress (big). Just choose the one you like most.]]) ..
+      li_arrow(_[[The sentry is the only military site that fits on a small building plot. If your lumberjack has cleared enough space, you can also build another military building.]]) ..
+      li_arrow(_[[Remember that big buildings (green icon) cannot be built on small (red) or medium (yellow) building plots, but buildings can be built on a building plot that provides more space than they need. You should always keep that in mind when you search for a suitable place.]])
    )
 }
-
 introduce_expansion = {
    title = _"Expanding Your Territory!",
    body = (
-      p(_[[There is one more thing I’d like to teach you now: Expanding your territory. The place that we started with around our headquarters is barely enough for a basic building infrastructure, and we do not have access to mountains, which we need to mine minerals and coal. So, we have to expand our territory.]]) ..
-      p(_[[Expanding is as simple as building a military building at the edge of your territory. The Barbarians have a selection of different military buildings: sentries, barriers, towers, fortresses and citadels. The bigger the building, the more expensive it is to build, but the more land it will conquer around itself and the more soldiers can be stationed there. The buildings also vary in their vision range: buildings with a tower see farther than others.]]) ..
-      p(_[[As soon as a military building is manned, it will extend your land. I will tell your more about military buildings in another tutorial.]]) ..
-      li(_[[Let’s try it out now: build a military building on your border.]]) ..
-      li_arrow(_[[The sentry is the only military site that fits on a small building plot. If your lumberjack has cleared enough space, you can also build another military building.]])
-   ),
-   obj_name = "expand_territory",
-   obj_title = _"Expand your territory",
-   obj_body = (
-      h1(_"Make your territory grow") ..
-      p(_[[In Widelands, it is necessary to build many buildings, which take up a lot of space. To expand your territory, you have to build military buildings next to your border. Every tribe has several military buildings.]]) ..
-      li(_[[The Barbarians have four different military buildings you can build: the sentry (small), the barrier and the tower (both medium) and the fortress (big). Just choose the one you like most.]]) ..
-      li_arrow(_[[Remember that big buildings (green icon) cannot be built on small (red) or medium (yellow) building plots, but buildings can be built on a building plot that provides more space than they need. You should always keep that in mind when you search for a suitable place.]])
+      li_object("barbarians_sentry",
+         p(_[[There is one more thing I’d like to teach you now: Expanding your territory. The place that we started with around our headquarters is barely enough for a basic building infrastructure, and we do not have access to mountains, which we need to mine minerals and coal. So, we have to expand our territory.]]) ..
+         p(_[[Expanding is as simple as building a military building at the edge of your territory. The Barbarians have a selection of different military buildings: sentries, barriers, towers, fortresses and citadels. The bigger the building, the more expensive it is to build, but the more land it will conquer around itself and the more soldiers can be stationed there. The buildings also vary in their vision range: buildings with a tower see farther than others.]]) ..
+         p(_[[As soon as a military building is manned, it will extend your land. I will tell you more about military buildings in another tutorial.]]), plr.color)
    )
 }
 
-
 military_building_finished = {
    title = _"Military Site Occupied",
    body = (
       h1(_"Your territory has just grown!") ..
-      p(_[[Great. Do you see how your territory has grown since your soldiers entered your new military building?]]) ..
-      p(_[[Every military building has a certain conquer area – the more expensive the building, the more land it conquers.]])
+      li_object("barbarians_tower",
+         p(_[[Great. Do you see how your territory has grown since your soldiers entered your new military building?]]) ..
+         p(_[[Every military building has a certain conquer area – the more expensive the building, the more land it conquers.]]), plr.color)
    ),
    h = 300,
    w = 350
 }
 
+-- ==========
+-- Conclusion
+-- ==========
+
 conclude_tutorial = {
    title = _"Conclusion",
    body = (
       h1(_"Conclusion") ..
-      p(_[[This concludes the first tutorial. In order to learn more about the game, I suggest to play one of the other tutorials. Each of them covers a different topic.]]) ..
-      p(_[[However, since you now know how to control Widelands, you can also start a game (or continue this one) and discover more by yourself.]]) ..
-      p(_[[To leave this game and return to the main menu, click on the]]) ..
-      li_image("images/wui/menus/menu_options_menu.png", _[[‘Main Menu’ button on the very left at the bottom of the screen. Then click the]]) ..
-      li_image("images/wui/menus/menu_exit_game.png", _[[‘Exit Game’ button.]]) ..
+      li_image("images/logos/wl-ico-64.png",
+         p(_[[This concludes the first tutorial. In order to learn more about the game, I suggest to play one of the other tutorials. Each of them covers a different topic.]]) ..
+         p(_[[However, since you now know how to control Widelands, you can also start a game (or continue this one) and discover more by yourself.]])) ..
+      p(_[[To leave this game and return to the main menu:]]) ..
+      li_image("images/wui/menus/main_menu.png", _[[Click on the ‘Main Menu’ button on the very left at the bottom of the screen.]]) ..
+      li_image("images/wui/menus/exit.png", _[[Then click on the ‘Exit Game’ entry.]]) ..
       p(_[[Thanks for playing this tutorial. Enjoy Widelands and remember to visit us at]]) ..
       h1(p("align=center", u("widelands.org")))
    ),

=== modified file 'data/campaigns/tutorial04_economy.wmf/scripting/mission_thread.lua'
--- data/campaigns/tutorial04_economy.wmf/scripting/mission_thread.lua	2018-07-07 10:53:30 +0000
+++ data/campaigns/tutorial04_economy.wmf/scripting/mission_thread.lua	2019-06-01 15:39:16 +0000
@@ -10,8 +10,8 @@
 
    sleep(1000)
 
-   message_box_objective(plr, intro1)
-   message_box_objective(plr, intro2)
+   campaign_message_box(intro1)
+   campaign_message_box(intro2)
 
    burn_tavern_down()
 end
@@ -19,15 +19,19 @@
 function wait_for_window_and_tab_or_complain(
    window_name,
    tab_name,
-   objective, complain_msg
-)
+   complain_msg,
+   objective)
+
+   local obj_open_window = add_campaign_objective(objective)
+   obj_open_window.visible = false
+
    while true do
       -- This waits for the window to be opened.
       if not mv.windows[window_name] then
-         objective.visible = true
-         message_box_objective(plr, complain_msg)
+         obj_open_window.visible = true
+         campaign_message_box(complain_msg)
          while not mv.windows[window_name] do sleep(200) end
-         objective.visible = false
+         obj_open_window.visible = false
       end
 
       -- But it might be closed at any point in time. If it is open and the
@@ -39,21 +43,20 @@
       end
       sleep(200)
    end
+   set_objective_done(obj_open_window)
 end
 
 function encyclopedia_tutorial()
    sleep(100*1000)
-   local o = message_box_objective(plr, ware_encyclopedia) -- where to get help
+   local o = campaign_message_with_objective(ware_encyclopedia, obj_open_encyclopedia) -- where to get help
    while not mv.windows.encyclopedia do sleep(200) end
    set_objective_done(o, wl.Game().real_speed)
 
-   o = message_box_objective(plr, explain_encyclopedia) -- what information is available
-   local o2 = add_campaign_objective(reopen_encyclopedia_obj)
-   o2.visible = false
+   o = campaign_message_with_objective(explain_encyclopedia, obj_lookup_wares) -- what information is available
    wait_for_window_and_tab_or_complain(
       "encyclopedia",
       "encyclopedia_wares",
-      o2, reopen_encyclopedia
+      reopen_encyclopedia, obj_reopen_encyclopedia
    )
    while mv.windows.encyclopedia do sleep(200) end
    set_objective_done(o, wl.Game().real_speed)
@@ -65,44 +68,38 @@
    sleep(1000)
    tavern_field.immovable:destroy()
    sleep(1000)
-   message_box_objective(plr, tavern_burnt_down)
+   campaign_message_box(tavern_burnt_down)
    sleep(500)
-   local o = message_box_objective(plr, building_stat)
+   local o = campaign_message_with_objective(building_stats, obj_open_building_stats)
+   wl.ui.MapView().dropdowns["dropdown_menu_statistics"]:open()
+
    while not mv.windows.building_statistics do sleep(100) end
    set_objective_done(o, wl.Game().real_speed)
 
-   o = message_box_objective(plr,explain_building_stat)
-   -- We cannot create several objectives with the same name. Therefore, we create o2 here once and change its visibility
-   local o2 = add_campaign_objective(reopen_building_stat_obj)
-   o2.visible = false
+   o = campaign_message_with_objective(explain_building_stats, obj_check_taverns)
    wait_for_window_and_tab_or_complain(
       "building_statistics",
       "building_stats_medium",
-      o2, reopen_building_stat
+      reopen_building_stats, obj_reopen_building_stats
    )
    while mv.windows.building_statistics do sleep(100) end
    set_objective_done(o, 0)
 
-   o = message_box_objective(plr, inventory1)
+   o = campaign_message_with_objective(inventory1, obj_open_inventory)
    while not mv.windows.stock_menu do sleep(200) end
    set_objective_done(o, wl.Game().real_speed)
 
-   o = message_box_objective(plr, inventory2)
-   -- We cannot create several objectives with the same name. Therefore, we
-   -- create o2 here once and change its visibility
-   o2 = add_campaign_objective(reopen_stock_menu_obj)
-   o2.visible = false
-
+   o = campaign_message_with_objective(inventory2, obj_switch_stock_tab)
    wait_for_window_and_tab_or_complain(
       "stock_menu",
       "wares_in_warehouses",
-      o2, reopen_stock_menu
+      reopen_stock_menu, obj_reopen_stock_menu
    )
    set_objective_done(o, 0)
-   message_box_objective(plr, inventory3)
+   campaign_message_box(inventory3)
 
    sleep(2000)
-   o = message_box_objective(plr, build_taverns)
+   o = campaign_message_with_objective(build_taverns, obj_build_taverns)
 
    encyclopedia_tutorial()
 
@@ -113,44 +110,38 @@
 end
 
 function plan_the_future()
-   message_box_objective(plr, building_priority_settings)
+   campaign_message_box(building_priority_settings)
    sleep(30*1000) -- give the user time to try it out
 
-   local o = message_box_objective(plr, ware_stats1)
+   local o = campaign_message_with_objective(ware_stats1, obj_open_ware_stats)
    while not mv.windows.ware_statistics do sleep(200) end
    set_objective_done(o, 0)
 
-   o = message_box_objective(plr, ware_stats2)
-   local o2 = add_campaign_objective(reopen_ware_stats1_obj)
-   o2.visible = false
-
+   o = campaign_message_with_objective(ware_stats2, obj_switch_ware_stats_tab_to_third)
    wait_for_window_and_tab_or_complain(
       "ware_statistics",
       "economy_health",
-      o2, reopen_ware_stats1
+      reopen_ware_stats1, obj_reopen_ware_stats1
    )
    set_objective_done(o, 0)
 
-   o = message_box_objective(plr, ware_stats3)
-   o2 = add_campaign_objective(reopen_ware_stats2_obj)
-   o2.visible = false
-
+   o = campaign_message_with_objective(ware_stats3, obj_switch_ware_stats_tab_to_fourth)
    wait_for_window_and_tab_or_complain(
       "ware_statistics",
       "stock",
-      o2, reopen_ware_stats2
+      reopen_ware_stats2, obj_reopen_ware_stats2
    )
    set_objective_done(o, 0)
 
-   o = message_box_objective(plr, ware_stats4)
+   o = campaign_message_with_objective(ware_stats4, obj_close_ware_stats)
    while mv.windows.ware_statistics do sleep(500) end
    set_objective_done(o)
 
-   o = message_box_objective(plr, economy_settings1)
+   o = campaign_message_with_objective(economy_settings1, obj_open_economy_settings)
    while not mv.windows.economy_options do sleep(200) end
    set_objective_done(o, 0)
-   message_box_objective(plr, economy_settings2)
-   o = message_box_objective(plr, economy_settings3)
+   campaign_message_box(economy_settings2)
+   o = campaign_message_with_objective(economy_settings3, obj_produce_marble_columns)
 
    while sf.brn.immovable.economy:ware_target_quantity("marble_column") ~= 20 do
       sleep(200)
@@ -159,7 +150,7 @@
    set_objective_done(o)
 
    -- new objective all has to be transported to the front
-   o = message_box_objective(plr, warehouse_preference_settings)
+   o = campaign_message_with_objective(warehouse_preference_settings, obj_bring_marble_columns_to_front)
 
    local enough_wares = false
    while not enough_wares do
@@ -178,7 +169,7 @@
 end
 
 function conclude()
-   message_box_objective(plr, conclusion)
+   campaign_message_box(conclusion)
 end
 
 run(introduction)

=== modified file 'data/campaigns/tutorial04_economy.wmf/scripting/texts.lua'
--- data/campaigns/tutorial04_economy.wmf/scripting/texts.lua	2018-09-12 15:58:07 +0000
+++ data/campaigns/tutorial04_economy.wmf/scripting/texts.lua	2019-06-01 15:39:16 +0000
@@ -8,7 +8,6 @@
 
 include "scripting/richtext_scenarios.lua"
 
-
 -- =============
 -- Texts below
 -- =============
@@ -17,7 +16,7 @@
    title = _"Your Economy and its Settings",
    body = (
       h1(_[[Economy]]) ..
-      p(_[[Welcome back. In this tutorial, I’ll tell you what you can do to check how well your economy works.]]) ..
+      li_image("images/wui/stats/genstats_nrwares.png", _[[Welcome back. In this tutorial, I’ll tell you what you can do to check how well your economy works.]]) ..
       p(_[[Building your economy up and making it work well and grow is the main part of Widelands. But you can’t control the workers directly – they will follow the general conditions you set.]]) ..
       p(_[[This is what I’ll show you in this tutorial: what actions can you take to define those general conditions?]])
    ),
@@ -29,49 +28,65 @@
    field = field_near_border,
    title = _"A Peaceful Land",
    body = (
-      p(_[[Now about the map: you have settled in a nice valley between two mountains, rich in marble, iron ore and coal. All were hoping for a peaceful life.]]) ..
-      p(_[[But one day, you discovered a barren wasteland with abandoned buildings in the east. A strange aura came from there, and no one wanted to set foot there. But the border could not be left undefended, and so you constructed three castles.]]) ..
-      p(_[[You had not been prepared for war, and you have to hurry now to build up an army.]])
+      li_object("empire_fortress",
+         p(_[[Now about the map: you have settled in a nice valley between two mountains, rich in marble, iron ore and coal. All were hoping for a peaceful life.]]) ..
+         p(_[[But one day, you discovered a barren wasteland with abandoned buildings in the east. A strange aura came from there, and no one wanted to set foot there. But the border could not be left undefended, and so you constructed three fortresses.]]) ..
+         p(_[[You had not been prepared for war, and you have to hurry now to build up an army.]]), plr.color)
    ),
    h = 300
 }
 
 tavern_burnt_down = {
    position = "topright",
-   title = _"The Tavern is Burning!",
+   title = _"An accident",
    body = (
-      h1(_[[An accident]]) ..
-      p(_[[Oh no, look at this: our tavern is burning! In all the hurry, our innkeeper accidentally dropped a torch. She is fine, but we could not extinguish the fire in time.]])
+      h1(_[[The Tavern is Burning!]]) ..
+      li_object("destroyed_building",
+         _[[Oh no, look at this: our tavern is burning! In all the hurry, our innkeeper accidentally dropped a torch. She is fine, but we could not extinguish the fire in time.]], plr.color)
    ),
    w = 300,
    h = 250
 }
 
-building_stat = {
+obj_open_building_stats = {
+   name = "open_building_stats",
+   title=_"Open the building statistics window",
+   number = 1,
+   body = objective_text(_"Open the building statistics window",
+      li(_[[Open the building statistics window for an overview over the buildings you have.]]) ..
+      li_image("images/wui/menus/statistics.png", _[[First, you will have to open the ‘Statistics’ menu at the bottom of the screen.]]) ..
+      li_image("images/wui/menus/statistics_buildings.png", _[[Afterwards, choose ‘Buildings’.]]) ..
+      li_arrow(_[[You can also use the hotkey ‘b’.]])
+   )
+}
+building_stats = {
    position = "topright",
    title = _"Building statistics",
    body = (
       h1(_[[Check out your taverns]]) ..
-      p(_[[At first, we should find out how many taverns we currently have. Widelands offers you a window where you can easily check this.]]) ..
-      li_image("images/wui/menus/menu_toggle_menu.png", _[[First, you will have to open the statistics menu (you can find the corresponding button at the bottom). We will need this menu several times.]]) ..
-      li_image("images/wui/menus/menu_building_stats.png", _[[Afterwards, choose the ‘Building statistics’.]]) ..
-      li(_[[Open the building statistics window.]]) ..
-      li_arrow(_[[You can also use the hotkey ‘b’.]])
-   ),
-   h = 350,
-   obj_name = "open_building_stat",
-   obj_title = _"Open the building statistics window",
-   obj_body =
-      li_image("images/wui/menus/menu_building_stats.png", _[[The building statistics window gives you an overview over the buildings you have.]]) ..
-      -- TRANSLATORS: "it" refers to the building statistics window
-      li(_[[Open it. You can access it from the statistics menu.]]) ..
-      li_arrow(_[[The statistics menu is accessed via the second button at the bottom. It provides several windows that give you information about the game.]])
+      p(_[[At first, we should find out how many taverns we currently have. Widelands offers you a window where you can easily check this.]])
+   )
 }
 
-explain_building_stat = {
+obj_check_taverns = {
+   name = "check_taverns",
+   title=_"Look up how many taverns you have",
+   number = 1,
+   body = objective_text(_"Look up how many taverns you have",
+      p(_[[We want to know whether we still have taverns.]]) ..
+      li_image("images/wui/fieldaction/menu_tab_buildmedium.png",
+         _[[Choose the ‘Medium buildings’ tab in the building statistics window.]]) ..
+      li(_[[Look up how many taverns you have.]]) ..
+      li_arrow(_[[Below every building, there are two lines. The first one shows the number of buildings you own and how many are under construction. The second line shows the average productivity if it is a production site or training site, or the stationed and desired soldiers in military buildings.]]) ..
+      li(_[[Close the building statistics window when you are done.]])
+   )
+}
+explain_building_stats = {
+   position = "topright",
    title = _"Building Statistics",
    body = (
-      p(_[[This is the building statistics window. It shows you all buildings you can own, sorted by their size.]]) ..
+      li_image("images/wui/menus/statistics_buildings.png",
+         _[[This is the building statistics window. It shows you all buildings you can own, sorted by their size.]]) ..
       p(_[[Let me now explain what all those numbers mean:]]) ..
       li(_[[‘2/1’ below the quarry: This means that you have two quarries, plus another one which is under construction.]]) ..
       li(_[[‘0%’: This indicates the average productivity of all buildings of that type. You have just started this game, therefore none of your buildings has done any work yet, but they are going to start working soon.]]) ..
@@ -79,149 +94,170 @@
       li_arrow(_[[In both cases, the color (green - yellow - red) signals you how good the value is.]]) ..
       li(_[[If you click on a building, you can scroll through the buildings of the selected type.]]) ..
       li(_[[If you don’t have any building of a particular building type, it will be shown greyed out.]]) ..
-      h2(_[[Now it’s your turn]]) ..
-      p(_[[This is enough explanation for now. Now try it out yourself. We want to know whether we still have taverns, so you have to choose the ‘Medium buildings’ tab. Close the building statistics menu afterwards.]])
+      p(_[[This is enough explanation for now. Now try it out yourself.]])
    ),
-   obj_name = "check_taverns",
-   obj_title = _"Look up how many taverns you have",
-   obj_body = (
-      li(_[[Choose the ‘Medium buildings’ tab in the building statistics window.]]) ..
-      li(_[[Look up how many taverns you have.]]) ..
-      li_arrow(_[[Below every building, there are two lines. The first one shows the number of buildings you own and how many are under construction. The second line shows the average productivity if it is a production site or training site, or the stationed and desired soldiers in military buildings.]]) ..
-      li(_[[Close the building statistics window when you are done.]])
-   )
+   h = 500,
 }
 
-reopen_building_stat = {
+reopen_building_stats = {
    title = _"You closed the building statistics window!",
    body = (
-      p(_[[You have closed the building statistics window. I didn’t notice that you switched to the medium buildings to look up the number of taverns. Would you please be so nice and show it to me?]])
+      li_image("images/wui/menus/statistics_buildings.png",
+         _[[You have closed the building statistics window. I didn’t notice that you switched to the medium buildings to look up the number of taverns. Would you please be so nice and show it to me?]])
    ),
    show_instantly = true,
    w = 300,
    h = 250
 }
 
-reopen_building_stat_obj = {
-   obj_name = "open_building_stat_again",
-   obj_title = _"Open the building statistics window again",
-   obj_body = (
-      p(_[[You closed the building statistics window, although you have not yet looked up the number of taverns.]]) ..
+obj_reopen_building_stats = {
+   name = "reopen_building_stats",
+   title = _"Open the building statistics window again",
+   number = 1,
+   body = objective_text(_"Open the building statistics window again",
+      li_image("images/wui/menus/statistics_buildings.png",
+         _[[You closed the building statistics window, although you have not yet looked up the number of taverns.]]) ..
       -- TRANSLATORS: "it" refers to the building statistics window.
       li(_[[Please reopen it and choose the second tab (medium buildings).]])
-   ),
-   h = 250
+   )
 }
 
+obj_open_inventory = {
+   name = "open_inventory",
+   title=_"Open your stock window",
+   number = 1,
+   body = objective_text(_"Open your stock window",
+      p(_[[The stock window gives you an overview over the wares you currently have.]]) ..
+      li_image("images/wui/menus/statistics.png", _[[First, you will have to open the ‘Statistics’ menu at the bottom of the screen.]]) ..
+      li_image("images/wui/menus/statistics_stock.png", _[[Afterwards, choose ‘Stock’.]]) ..
+      li_arrow(_[[You can also use the hotkey ‘i’ (as in ‘inventory’) to access this window quickly.]])
+   )
+}
 inventory1 = {
    position = "topright",
    title = _"Stock",
    body = (
       h1(_[[Check for rations]]) ..
-      p(_[[OK. In the list, you’ve seen that you have no more taverns or inns. That means that you’re not producing any rations. But let’s see what we still have in stock.]]) ..
-      li_image("images/wui/menus/menu_stock.png", _[[Click on the ‘Stock’ button.]]) ..
-      li_arrow(_[[You can also use the hotkey ‘i’ (as in ‘inventory’) to access this window quickly.]])
-   ),
-   h = 300,
-   obj_name = "open_inventory",
-   obj_title = _"Open your stock window",
-   obj_body = (
-      p(_[[The stock menu window gives you an overview over the wares you currently have.]]) ..
-      -- TRANSLATORS: "it" refers to the stock menu window
-      li(_[[Open it. You can access it from the statistics menu.]]) ..
-      li_arrow(_[[The statistics menu is accessed via the second button at the bottom. It provides several windows that give you information about the game.]])
+      li_image(wl.Game():get_ware_description("ration").icon_name,
+         _[[OK. In the list, you’ve seen that you have no more taverns or inns. That means that you’re not producing any rations. But let’s see what we still have in stock.]])
    )
 }
 
+obj_switch_stock_tab = {
+   name = "switch_stock_tab",
+   title=_"Examine the first two tabs in the stock window",
+   number = 1,
+   body = objective_text(_"Examine the first two tabs in the stock window",
+      p(_[[Have a look at the first two tabs in the stock window. They show all the wares and workers you have.]]) ..
+      li_image("images/wui/stats/menu_tab_wares_warehouse.png",
+         _[[When you have seen enough, switch to the third tab (‘Wares in warehouses’).]])
+   )
+}
 inventory2 = {
+   position = "topright",
    title = _"Stock",
    body = (
-      p(_[[The stock menu window has four tabs. The first (and currently selected) one shows you all your current wares, including those on roads, at flags and inside buildings waiting for processing.]]) ..
+      li_image("images/wui/buildings/menu_tab_wares.png",
+         _[[The stock window has four tabs. The first (and currently selected) one shows you all your current wares, including those on roads, at flags and inside buildings waiting for processing.]]) ..
       p(_[[Looking at the rations, there are currently only five in total, probably on their way to somewhere. Five rations are not much for such a big economy.]]) ..
-      p(_[[The second tab shows you all your workers, again those on roads and in buildings summed up.]]) ..
-      p(_[[Now have a look at these two tabs. When you click on the]]) ..
-      li_image("images/wui/stats/menu_tab_wares_warehouse.png", _[[third tab (‘Wares in warehouses’), I’ll continue.]])
-   ),
-   h = 350,
-   show_instantly = true,
-   obj_name = "switch_stock_tab",
-   obj_title = _"Switch to the third tab in the stock menu window",
-   obj_body = (
-      p(_[[Have a look at the first two tabs in the stock menu window. They show all the wares and workers you have.]]) ..
-      li(_[[When you have seen enough, switch to the third tab.]])
-   ),
+      li_image("images/wui/buildings/menu_tab_workers.png",
+         _[[The second tab shows you all your workers, again those on roads and in buildings summed up.]])
+   ),
+   show_instantly = true
 }
 
 inventory3 = {
+position = "topright",
    title = _"Stock",
    body = (
-      p(_[[The third tab shows you the wares that are stored in your headquarters, your warehouses and ports. They are not needed anywhere and are therefore your reserve.]]) ..
-      p(_[[The fourth tab shows the same thing for workers.]]) ..
+      li_image("images/wui/stats/menu_tab_wares_warehouse.png",
+         _[[The third tab shows you the wares that are stored in your headquarters, your warehouses and ports. They are not needed anywhere and are therefore your reserve.]]) ..
+      li_image("images/wui/stats/menu_tab_workers_warehouse.png", _[[The fourth tab shows the same thing for workers.]]) ..
       p(_[[The third tab tells you that there are no rations left in your headquarters – that’s not good!]])
    ),
    show_instantly = true,
-   h = 300
+   h = 250
 }
 
 reopen_stock_menu = {
    title = _"You closed the stock window!",
    body = (
-      p(_[[You have closed the stock menu window, but I have not yet finished with my explanation. Would you please reopen it and choose the third tab?]])
+      li_image("images/wui/menus/statistics_stock.png",
+         _[[You have closed the stock window, but I have not yet finished with my explanation. Would you please reopen it and choose the third tab?]])
    ),
    show_instantly = true,
    w = 300,
    h = 250
 }
 
-reopen_stock_menu_obj = {
-   obj_name = "open_stock_menu_again",
-   obj_title = _"Open the stock window again",
-   obj_body = (
-      p(_[[You closed the stock menu window before I finished telling you everything about it. If you already know everything, please feel free to leave this tutorial at any time.]]) ..
-      -- TRANSLATORS: "it" refers to the stock menu window.
+obj_reopen_stock_menu = {
+   name = "open_stock_menu_again",
+   title = _"Open the stock window again",
+   number = 1,
+   body = objective_text(_"Open the stock window again",
+      li_image("images/wui/menus/statistics_stock.png",
+         _[[You closed the stock window before I finished telling you everything about it. If you already know everything, please feel free to leave this tutorial at any time.]]) ..
+      -- TRANSLATORS: "it" refers to the "Stock" window.
       li(_[[Otherwise, please reopen it and choose the third tab.]])
-   ),
-   h = 250
+   )
 }
 
+obj_build_taverns = {
+   name = "build_taverns",
+   title=_"Build new taverns",
+   number = 1,
+   body = objective_text(_"Build new taverns",
+      li(_[[Build at least two taverns.]]) ..
+      li_arrow(_[[As long as we don’t produce rations, our miners won’t dig for ore. And without iron, we cannot forge a single helm.]])
+   )
+}
 build_taverns = {
    position = "topright",
    title = _"New taverns",
    body = (
       h1(_[[We need new taverns]]) ..
-      p(_[[Now that you have an overview, you should act. I think we should build more than one tavern – two or three are better. Remember: as long as we don’t produce rations, our miners won’t dig for ore. And without iron, we cannot forge a single helm.]]) ..
-      li(_[[Build at least two taverns.]])
-   ),
-   h = 300,
-   obj_name = "build_taverns",
-   obj_title = _"Build new taverns",
-   obj_body = (
-      p(_[[To make our mines work, we need rations again – the more, the better.]]) ..
-      li(_[[Build at least two taverns.]])
+      li_object("empire_tavern",
+         _[[Now that you have an overview, you should act. I think we should build more than one tavern – two or three are better.]],
+         plr.color)
    )
 }
 
-ware_encyclopedia = {
-   title = _"Encyclopedia",
-   body = (
-      h1(_[[How to get help]]) ..
-      p(_[[Of course, it is difficult to remember all of my remarks and advice. For example, you might ask yourself: ‘Why do we need rations to get soldiers?’]]) ..
-      p(_[[When you’ve played a lot, you will know all these things by heart. But until then or if you’re unsure about your tribe’s needs and abilities and how its buildings and workers operate, you can look it up easily in our tribe-specific in-game help and encyclopedia.]]) ..
-      p(_[[This encyclopedia can be accessed via the help button at the bottom right.]])..
-      li_image("images/ui_basic/menu_help.png", _[[Please open the in-game help, and I’ll explain its contents to you.]])
-   ),
-   h = 350,
-   show_instantly = true,
-   obj_name = "open_encyclopedia",
-   obj_title = _"Open the in-game help window",
-   obj_body = (
+obj_open_encyclopedia = {
+   name = "open_encyclopedia",
+   title=_"Open the in-game help window",
+   number = 1,
+   body = objective_text(_"Open the in-game help window",
       li_image("images/ui_basic/menu_help.png", _[[The encyclopedia window contains the in-game help and an encyclopedia of the tribe you’re currently playing.]]) ..
       -- TRANSLATORS: "it" refers to the encyclopedia window
       li(_[[Open it. You can access it via the button at the bottom of the screen.]]) ..
       li_arrow(_[[Alternatively, you can access it directly with the ‘F1’ key.]])
+   )
+}
+ware_encyclopedia = {
+   title = _"Encyclopedia",
+   body = (
+      h1(_[[How to get help]]) ..
+      li_object("empire_soldier",
+         _[[Of course, it is difficult to remember all of my remarks and advice. For example, you might ask yourself: ‘Why do we need rations to get soldiers?’]], plr.color) ..
+      p(_[[When you’ve played a lot, you will know all these things by heart. But until then or if you’re unsure about your tribe’s needs and abilities and how its buildings and workers operate, you can look it up easily in our tribe-specific in-game help and encyclopedia.]])
    ),
+   h = 450,
+   show_instantly = true,
 }
 
+obj_lookup_wares = {
+   name = "lookup_wares",
+   title=_"Look up which wares are needed to recruit soldiers",
+   number = 1,
+   body = objective_text(_"Look up which wares are needed to recruit soldiers",
+      p(_[[A soldier needs a wooden spear and a helmet – from there on out, you can search backwards to find the wares and the buildings you need to supply your barracks where the soldier is recruited. When you are finished, just close the encyclopedia window.]]) ..
+      li(_[[Use the encyclopedia to find out how to create new soldiers.]]) ..
+      li_arrow(_[[Choose the ‘Wares’ tab in the encyclopedia window.]]) ..
+      li_arrow(_[[Look up what is needed to produce a helmet and what is needed to produce a wooden spear.]]) ..
+      li_arrow(_[[If you want, you may further look up what is needed to produce the wares you just looked up.]]) ..
+      li(_[[Close the encyclopedia window when you are done.]])
+   )
+}
 explain_encyclopedia = {
    position = "topright",
    title = _"Encyclopedia details",
@@ -232,140 +268,143 @@
       div("width=100%", div("float=left padding_r=18 padding_t=15 padding_b=15 padding_l=4",p(img("images/wui/buildings/menu_tab_wares.png"))) .. p(_[[The ‘Wares’ tab shows information about the wares that your tribe needs, including a short help text, a list of buildings that produce each ware, the needed wares to produce it and where the ware is consumed.]])) ..
       div("width=100%", div("float=left padding_r=16",p(img("images/wui/buildings/menu_tab_workers.png"))) .. p(_[[The ‘Workers’ tab shows information about your tribe’s workers in a similar manner to the wares in the second tab.]])) ..
       div("width=100%", div("float=left padding_r=18 padding_t=5 padding_l=4",p(img("images/wui/stats/genstats_nrbuildings.png"))) .. p(_[[The ‘Buildings’ tab contains all the necessary information about the buildings of your tribe.]])) ..
-      li_image("tribes/immovables/field_harvested/idle_00.png", _[[Finally, the ‘Immovables’ tab shows information about the specific immovables that your tribe’s workers can place on the map.]]) ..
-      li(_[[Now use the encyclopedia to find out how to create new soldiers.]]) ..
-      li_arrow(_[[A soldier needs a wooden spear and a helmet – from there on out, you can search backwards to find the wares and the buildings you need to supply your barracks where the soldier is recruited. When you are finished, just close the encyclopedia window.]])
+      div("width=100%", div("float=left padding_r=18 padding_t=5 padding_l=4",p(img("tribes/immovables/field_ripe/idle_00.png"))) .. p(_[[Finally, the ‘Immovables’ tab shows information about the specific immovables that your tribe’s workers can place on the map.]]))
    ),
-   h = 450,
+   h = 500,
    show_instantly = true,
-   obj_name = "check_wares",
-   obj_title = _"Look up which wares are needed to recruit soldiers",
-   obj_body = (
-      li(_[[Choose the ‘Wares’ tab in the encyclopedia window.]]) ..
-      li(_[[Look up what is needed to produce a helmet and what is needed to produce a wooden spear.]]) ..
-      li_arrow(_[[If you want, you may further look up what is needed to produce the wares you just looked up.]]) ..
-      li(_[[Close the encyclopedia window when you are done.]])
-   )
 }
 
 reopen_encyclopedia = {
    title = _"You closed the encyclopedia!",
    body = (
-      p(_[[You have closed the encyclopedia window, but I didn’t notice that you were trying to find out which wares are needed to recruit a soldier. Would you please reopen it and do so?]])
+      li_image("images/ui_basic/menu_help.png",
+         _[[You have closed the encyclopedia window, but I didn’t notice that you were trying to find out which wares are needed to recruit a soldier. Would you please reopen it and do so?]])
    ),
    show_instantly = true,
    w = 300,
    h = 250
 }
 
-reopen_encyclopedia_obj = {
-   obj_name = "open_encyclopedia_again",
-   obj_title = _"Open the encyclopedia window again",
-   obj_body = (
-      p(_[[You closed the encyclopedia window without searching for the information we need. If you already know everything, please feel free to leave this tutorial at any time.]]) ..
+obj_reopen_encyclopedia = {
+   name = "reopen_encyclopedia",
+   title = _"Open the encyclopedia window again",
+   number = 1,
+   body = objective_text(_"Open the encyclopedia window again",
+      li_image("images/ui_basic/menu_help.png",
+         _[[You closed the encyclopedia window without searching for the information we need. If you already know everything, please feel free to leave this tutorial at any time.]]) ..
       li(_[[Otherwise, please reopen the encyclopedia window and choose the second tab.]])
-   ),
-   h = 250
+   )
 }
-
 building_priority_settings = {
    position = "topright",
    title = _"Priority Settings",
    body = (
       h1(_[[Send the wares where they’re needed]]) ..
-      p(_[[Great. Our taverns have now been built up and are supplying us with rations.]]) ..
-      p(_[[At the moment, all mines are supplied with rations. If you want to prioritize a special mine, you simply have to open its window. In the wares tab, behind every ware, you can see ‘traffic lights’.]]) ..
-      p(_[[When you click on the red dot (low priority), the corresponding ware gets delivered less frequently. Green means that as many wares as possible should be delivered to this building, maybe because it produces something important.]]) ..
-      p(_[[In our situation, you might want to work the bakeries as fast as possible because they supply our taverns, so you could set water to the highest priority for them. The other buildings (for example the donkey farm) would then get less water, but the bakery could work faster.]])
+      li_object("empire_marblemine", p(_[[Great. Our taverns have now been built up and are supplying us with rations.]]) ..
+         p(_[[At the moment, all mines are supplied with rations. If you want to prioritize a special mine, you simply have to open its window. In the wares tab, behind every ware, you can see ‘traffic lights’.]]) ..
+         p(_[[When you click on the red dot (low priority), the corresponding ware gets delivered less frequently. Green means that as many wares as possible should be delivered to this building, maybe because it produces something important.]]) ..
+         p(_[[In our situation, you might want to work the bakeries as fast as possible because they supply our taverns, so you could set water to the highest priority for them. The other buildings (for example the donkey farm) would then get less water, but the bakery could work faster.]]), plr.color)
       -- we cannot check whether the user does this, so no objective
       -- see bug https://bugs.launchpad.net/widelands/+bug/1380288
    )
 }
 
+obj_open_ware_stats = {
+   name = "open_ware_stats",
+   title = _"Open the ware statistics window",
+   number = 1,
+   body = objective_text(_"Open the ware statistics window",
+      li(_[[Select the ‘Wares’ entry from the ‘Statistics’ menu.]])
+   )
+}
 ware_stats1 = {
-   position = "top",
    title = _"Ware Statistics",
    body = (
-      p(_[[In the statistics menu, there is also a]]) ..
-      li_image("images/wui/menus/menu_ware_stats.png", _[[‘Ware statistics’ button.]]) ..
-      -- TRANSLATORS: "it" refers to the ware statistics button
-      li(_[[Click on it.]])
+      li_image("images/wui/menus/statistics_wares.png", _[[Let’s have a look at how our wares production is doing.]])
    ),
-   w = 200,
-   h = 200,
-   obj_name = "open_ware_stat",
-   obj_title = _"Open the ware statistics window",
-   obj_body = (
-      li(_[[Open the ‘Ware statistics’ window, accessed via the statistics menu.]])
+   h = 250
+}
+
+obj_switch_ware_stats_tab_to_third = {
+   name = "switch_ware_stats_tab_to_third",
+   title = _"Examine your ware production and consumption",
+   number = 1,
+   body = objective_text(_"Examine your ware production and consumption",
+      p(_[[The first two tabs show you the production and consumption of any ware. You can toggle them by simply clicking on them.]]) ..
+      li(_[[When you have seen enough, switch to the third tab (‘Economy health’).]])
    )
 }
-
 ware_stats2 = {
+   position = "topright",
    title = _"Ware Statistics",
    body = (
-      p(_[[In this menu window, you can select wares to see how their production or consumption has changed over time. Try it out with some wares.]]) ..
-      li(_[[I’ll continue as soon as you click on the]]) ..
-      li_image("images/wui/stats/menu_tab_wares_econ_health.png", _[[third tab (‘Economy health’).]])
+      p(_[[In this window, you can select wares to see how their production or consumption has changed over time. Try it out with some wares.]]) ..
+      li_image("images/wui/stats/menu_tab_wares_econ_health.png", _[[I’ll continue as soon as you click on the third tab (‘Economy health’).]])
    ),
-   h = 250,
-   show_instantly = true,
-   obj_name = "switch_ware_stat_tab_to_third",
-   obj_title = _"Switch to the third tab in the ware statistics menu window",
-   obj_body = (
-      p(_[[The first two tabs show you the production and consumption of any ware. You can toggle them by simply clicking on them.]]) ..
-      li(_[[When you have seen enough, switch to the third tab.]])
+   h = 350,
+   show_instantly = true
+}
+
+obj_switch_ware_stats_tab_to_fourth = {
+   name = "switch_ware_stats_tab_to_fourth",
+   title = _"Examine your economy’s health",
+   number = 1,
+   body = objective_text(_"Examine your economy’s health",
+      p(_[[The third tab shows you the economy health of the ware. When the value is positive, this means your stock is growing.]]) ..
+      p(_[[Now try this out. You can also compare it with the two previous tabs.]]) ..
+      li(_[[When you have seen enough, switch to the fourth tab (‘Stock’).]])
    )
 }
-
 ware_stats3 = {
+   position = "topright",
    title = _"Ware Statistics",
    body = (
-      p(_[[In this tab, you can see the difference between production and consumption, called ‘economy health’. You can see at one glance which one of those two is higher for the selected ware, that means whether the amount increases or decreases.]]) ..
-      p(_[[Now try this out. You can also compare it with the two previous tabs.]]) ..
-      li(_[[Click on the last tab when I should continue.]])
+      li_image("images/wui/stats/menu_tab_wares_econ_health.png",
+         _[[In this tab, you can see the difference between production and consumption, called ‘economy health’. You can see at one glance which one of those two is higher for the selected ware, that means whether the amount increases or decreases.]])
    ),
-   h = 250,
-   show_instantly = true,
-   obj_name = "switch_ware_stat_tab_to_forth",
-   obj_title = _"Switch to the last tab in the ware statistics menu window",
-   obj_body = (
-      p(_[[The third tab shows you the economy health of the ware. When the value is positive, this means your stock is growing.]]) ..
-      li(_[[When you have seen enough, switch to the fourth tab.]])
-   )
+   h = 350,
+   show_instantly = true
 }
 
+obj_close_ware_stats = {
+   name = "close_ware_stats",
+   title = _"Examine your stock",
+   number = 1,
+   body = objective_text(_"Examine your stock",
+      li_arrow(_[[The stock tab shows you how many wares you have. Compare the information from the four tabs to understand the correlation.]]) ..
+      li(_[[When you have finished, close the ware statistics window.]])
+   ),
+   h = 250
+}
 ware_stats4 = {
+   position = "topright",
    title = _"Ware Statistics",
    body = (
-      p(_[[In the last tab, you can also see your absolute stock. It will increase when the economy health is positive, and decrease otherwise. Compare the two graphs!]]) ..
-      p(_[[The last two tabs are good indicators to see whether shortages are about to come. Don’t forget to check them regularly!]]) ..
-      li(_[[Close this window when you’re done.]])
-   ),
-   h = 250,
-   show_instantly = true,
-   obj_name = "close_ware_stats",
-   obj_title = _"Close the ware statistics window",
-   obj_body = (
-      p(_[[The stock tab shows you how many wares you have. Compare the information from the four tabs to understand the correlation.]]) ..
-      li(_[[When you have finished, close the ware statistics window.]])
-   ),
+      li_image("images/wui/stats/menu_tab_wares_stock.png",
+         p(_[[In the last tab, you can also see your absolute stock. It will increase when the economy health is positive, and decrease otherwise. Compare the two graphs!]]) ..
+         p(_[[The last two tabs are good indicators to see whether shortages are about to come. Don’t forget to check them regularly!]]))
+   ),
+   show_instantly = true
 }
 
 reopen_ware_stats1 = {
    title = _"You closed the ware statistics window!",
    body = (
-      p(_[[You have closed the ware statistics menu window, but I have not yet finished with my explanation. Would you please reopen it and choose the third tab?]])
+      li_image("images/wui/menus/statistics_wares.png",
+         _[[You have closed the ware statistics window, but I have not yet finished with my explanation. Would you please reopen it and choose the third tab?]])
    ),
    show_instantly = true,
    w = 300,
    h = 250
 }
 
-reopen_ware_stats1_obj = {
-   obj_name = "open_ware_stats_menu_again1",
+obj_reopen_ware_stats1 = {
+   obj_name = "reopen_ware_stats1",
    obj_title = _"Open the ware statistics window again",
+   number = 1,
    obj_body = (
-      p(_[[You closed the ware statistics menu window before I finished telling you everything about it. If you already know everything, please feel free to leave this tutorial at any time.]]) ..
+      li_image("images/wui/menus/statistics_wares.png",
+         _[[You closed the ware statistics window before I finished telling you everything about it. If you already know everything, please feel free to leave this tutorial at any time.]]) ..
       -- TRANSLATORS: "it" refers to the ware statistics window.
       li(_[[Otherwise, please reopen it and choose the third tab.]])
    )
@@ -374,102 +413,122 @@
 reopen_ware_stats2 = {
    title = _"You closed the ware statistics window!",
    body = (
-      p(_[[You have closed the ware statistics menu window, but I have not yet finished with my explanation. Would you please reopen it and choose the fourth tab?]])
+      li_image("images/wui/menus/statistics_wares.png",
+         _[[You have closed the ware statistics window, but I have not yet finished with my explanation. Would you please reopen it and choose the fourth tab?]])
    ),
    show_instantly = true,
    w = 300,
    h = 250
 }
 
-reopen_ware_stats2_obj = {
-   obj_name = "open_ware_stats_menu_again2",
-   obj_title = _"Open the ware statistics window again",
-   obj_body = (
-      p(_[[You closed the ware statistics menu window before I finished telling you everything about it. If you already know everything, please feel free to leave this tutorial at any time.]]) ..
+obj_reopen_ware_stats2 = {
+   name = "open_ware_stats_menu_again2",
+   title = _"Open the ware statistics window again",
+   number = 1,
+   body = (
+      li_image("images/wui/menus/statistics_wares.png",
+         _[[You closed the ware statistics window before I finished telling you everything about it. If you already know everything, please feel free to leave this tutorial at any time.]]) ..
       -- TRANSLATORS: "it" refers to the ware statistics window.
       li(_[[Otherwise, please reopen it and choose the fourth tab.]])
    )
 }
 
+obj_open_economy_settings = {
+   name = "open_economy_settings",
+   title = _"Open the ‘Configure economy’ window",
+   number = 1,
+   body = objective_text(_"Open the ‘Configure economy’ window",
+      li(_[[Open the ‘Configure economy’ window.]]) ..
+      li_arrow(_[[The window can be accessed by clicking on any flag you own.]])
+   )
+}
 economy_settings1 = {
    position = "topright",
    title = _"Economy options",
    body = (
-      p(_[[I’ve shown you our stock menu window, where you could see which wares are at the warehouses. You remember?]]) ..
-      p(_[[Now I’ll tell you how you can determine how many wares you want to have. The menu window for this purpose can be accessed via any flag and is called ‘Configure economy’.]]) ..
+      li_object("empire_flag",
+         p(_[[I’ve shown you our stock window, where you could see which wares are at the warehouses. You remember?]]) ..
+         p(_[[Now I’ll tell you how you can determine how many wares you want to have. The window for this purpose can be accessed via any flag and is called ‘Configure economy’.]]), plr.color) ..
       -- Yup, that's indeed the correct icon
-      li_image("images/wui/stats/genstats_nrwares.png", _[[This is the icon.]]) ..
-      li(_[[Open this window.]])
+      li_image("images/wui/stats/genstats_nrwares.png", _[[This is the icon.]])
    ),
-   h = 350,
-   obj_name = "open_economy_settings",
-   obj_title = _"Open the ‘Configure economy’ window",
-   obj_body = (
-      li(_[[Open the ‘Configure economy’ window.]]) ..
-      li_arrow(_[[The window can be accessed by clicking on any flag you own.]])
-   )
+   h = 350
 }
 
 economy_settings2 = {
+   position = "topright",
    title = _"Economy options",
    body = (
-      p(_[[This window looks similar to the stock window, but it has additional buttons at the bottom.]]) ..
+      li_image("images/wui/stats/genstats_nrwares.png",
+            _[[This window looks similar to the stock window, but it has additional buttons at the bottom.]]) ..
       p(_[[You first have to select one or more wares (you can also left-click and drag). Then you can set the desired target quantity for the selected wares.]]) ..
       p(_[[Most buildings will only produce something when the stock level in your warehouses falls below the target quantity, so you should indicate the reserve you want to stockpile.]]) ..
-      p(_[[An example: the default value for scythes is 1. If you build a farm, a carrier will take a scythe and become a farmer. Then there will be no scythes left, but the target quantity is 1, therefore your toolsmith will start producing another one.]]) ..
-      p(_[[If you build two farms, only one of them will start working immediately. The second farm will have to wait for its worker, who will lack a scythe. If you had set the target quantity to 2 before, two scythes would have been available and both farms would have been able to start working right away.]])
-   ),
-   h = 450
+      li_image(wl.Game():get_ware_description("scythe").icon_name,
+         _[[An example: the default value for scythes is 1. If you build a farm, a carrier will take a scythe and become a farmer. Then there will be no scythes left, but the target quantity is 1, therefore your toolsmith will start producing another one.]]) ..
+      li_object("empire_farmer",
+         _[[If you build two farms, only one of them will start working immediately. The second farm will have to wait for its worker, who will lack a scythe. If you had set the target quantity to 2 before, two scythes would have been available and both farms would have been able to start working right away.]], plr.color)
+   )
 }
 
+obj_produce_marble_columns = {
+   name = "produce_marble_columns",
+   title = _"Produce 20 marble columns",
+   number = 1,
+   body = objective_text(_"Produce 20 marble columns",
+      li(_[[To be prepared for additional fortifications, you should produce 20 marble columns.]]) ..
+      li_arrow(_[[Your stonemason will not produce marble columns when they are not needed. You have to increase the target quantity.]]) ..
+      li_arrow(_[[To do so, click on any flag and choose ‘Configure economy’. In this window, you can decide how many wares of each type you wish to have in stock.]]) ..
+      li_arrow(_[[Sometimes, you will need many wares at the same time quickly – faster than they can be produced. In this case, it is good to have enough on reserve.]])
+   )
+}
 economy_settings3 = {
+   position = "topright",
    title = _"Economy options",
    body = (
-      p(_[[By changing the target quantity, you can therefore decide which wares/tools your resources (in this case: iron) should be turned into or whether you would like to save your iron and wait until you know what you will need it for.]]) ..
+      li_image(wl.Game():get_ware_description("iron").icon_name,
+         _[[By changing the target quantity, you can therefore decide which wares/tools your resources (in this case: iron) should be turned into or whether you would like to save your iron and wait until you know what you will need it for.]]) ..
       p(_[[Only buildings that consume wares care about this setting. Buildings that produce wares for free (e.g. your farms or wells) will always keep working.]]) ..
-      p(_[[Now let’s try it out: the current target quantity for marble columns is 10. Increase it to be prepared in case you will have to build up your fortifications quickly.]]) ..
-      li(_[[Set the target quantity for marble columns to 20 and wait for your stonemason to produce them.]])
+      li_image(wl.Game():get_ware_description("marble_column").icon_name,
+         _[[Now let’s try it out: the current target quantity for marble columns is 10. Increase it to be prepared in case you will have to build up your fortifications quickly.]])
    ),
-   obj_name = "produce_marble_columns",
-   obj_title = _"Produce 20 marble columns",
-   obj_body = (
-      p(_[[Sometimes, you will need many wares at the same time quickly – faster than they can be produced. In this case, it is good to have enough on reserve.]]) ..
-      li(_[[To be prepared for additional fortifications, you should produce 20 marble columns.]]) ..
-      li_arrow(_[[Your stonemason will not produce marble columns when they are not needed. You have to increase the target quantity.]]) ..
-      li_arrow(_[[To do so, click on any flag and choose ‘Configure economy’. In this menu window, you can decide how many wares of each type you wish to have in stock.]])
+   h = 500,
+}
+
+obj_bring_marble_columns_to_front = {
+   name = "bring_marble_columns_to_front",
+   title = _"Bring 20 marble columns to the front line",
+   number = 1,
+   body = objective_text(_"Bring 20 marble columns to the front line",
+      li(_[[Bring all of the 20 marble columns to the warehouse near the front line.]]) ..
+      li_image("images/wui/buildings/stock_policy_button_prefer.png",
+         _[[To achieve this, you will have to do two things. First, set a preference for marble columns in the desired warehouse. All marble columns produced in the future will be brought there if possible.]]) ..
+      li_image("images/wui/buildings/stock_policy_button_remove.png",
+         _[[Then, to move the marble columns out of your headquarters, you will have to click on the remove button there.]])
    )
 }
-
 warehouse_preference_settings = {
    field = warehouse_field,
    position = "topright",
    title = _"Warehouse Preferences",
    body = (
       h1(_[[Bring the marble columns to the front line]]) ..
-      p(_[[The production of marble columns is working fine now, but it would be great if they were stored where we need them.]]) ..
-      p(_[[Normally, produced wares are brought to the closest warehouse if they are not needed elsewhere. In this case, this means our headquarters. But we would like to have them in the warehouse near our fortresses.]]) ..
-      p(_[[Every warehouse has four buttons to set the preference. If you move your mouse pointer over them, you will see tooltips that explain what the buttons do.]]) ..
-      li(_[[Bring all of the 20 marble columns to the warehouse near the front line.]]) ..
-      li_arrow(_[[To achieve this, you will have to do two things. First, set a preference for marble columns in the desired warehouse. All marble columns produced in the future will be brought there if possible.]]) ..
-      li_arrow(_[[Then, to move the marble columns out of your headquarters, you will have to click on the remove button there.]])
+      li_object("empire_warehouse",
+         p(_[[The production of marble columns is working fine now, but it would be great if they were stored where we need them.]]) ..
+         p(_[[Normally, produced wares are brought to the closest warehouse if they are not needed elsewhere. In this case, this means our headquarters. But we would like to have them in the warehouse near our fortresses.]]) ..
+         p(_[[Every warehouse has four buttons to set the preference. If you move your mouse pointer over them, you will see tooltips that explain what the buttons do.]]), plr.color)
    ),
-   obj_name = "bring_marble_columns_to_front",
-   obj_title = _"Bring 20 marble columns to the front line",
-   obj_body = (
-      p(_[[To decide where your wares get stored, you can use the preference buttons in the warehouses.]]) ..
-      li(_[[Bring all of the 20 marble columns to the warehouse near the front line.]]) ..
-      li_arrow(_[[To achieve this, you will have to do two things. First, set a preference for marble columns in the desired warehouse. All marble columns produced in the future will be brought there if possible.]]) ..
-      li_arrow(_[[Then, to move the marble columns out of your headquarters, you will have to click on the remove button there.]])
-   )
+   h = 500
 }
 
 conclusion = {
    title = _"Borders Secured",
    body =
       h1(_[[We’re safe now]]) ..
-      p(_[[Great. We now have enough marble columns so that in case of an aggressor, we can build up our fortifications. But I do not think that that will be necessary. So far, no enemy has shown up.]]) ..
-      p(_[[I hope I could teach you how you can control the economy in Widelands. There are many options and they can be confusing at first. Even if you’ve only understood a few concepts, you mustn’t give up. Try them out in some games, become familiar with them and experience the possibilities. Then, return to this tutorial and learn the rest!]]) ..
+      li_object("empire_fortress",
+         p(_[[Great. We now have enough marble columns so that in case of an aggressor, we can build up our fortifications. But I do not think that that will be necessary. So far, no enemy has shown up.]]) ..
+         p(_[[I hope I could teach you how you can control the economy in Widelands. There are many options and they can be confusing at first. Even if you’ve only understood a few concepts, you mustn’t give up. Try them out in some games, become familiar with them and experience the possibilities. Then, return to this tutorial and learn the rest!]]), plr.color) ..
       p([[]]) ..
       p(_[[This was the last tutorial I had prepared for you. I’ve now taught you everything I know. There are still secrets hidden in this world even I don’t know about. I will now search for a quiet place to spend my sunset years. If you have still questions, the Widelands community will surely help you. You can find it at:]]) ..
-      h1(p("align=center", u("widelands.org")))
+      h1(p("align=center", u("widelands.org"))),
+   h = 450
 }

=== modified file 'data/scripting/editor/editor_help.lua'
--- data/scripting/editor/editor_help.lua	2018-09-29 09:20:35 +0000
+++ data/scripting/editor/editor_help.lua	2019-06-01 15:39:16 +0000
@@ -79,7 +79,7 @@
          name = "terrains",
          -- TRANSLATORS Tab title: terrain help
          title = _"Terrains",
-         icon = "images/wui/editor/editor_menu_tool_set_terrain.png",
+         icon = "images/wui/editor/tools/terrain.png",
          entries = get_terrains()
       },
       {

=== modified file 'data/scripting/messages.lua'
--- data/scripting/messages.lua	2019-02-09 18:45:42 +0000
+++ data/scripting/messages.lua	2019-06-01 15:39:16 +0000
@@ -6,6 +6,7 @@
 
 include "scripting/coroutine.lua"
 include "scripting/richtext.lua"
+include "scripting/richtext_scenarios.lua"
 include "scripting/table.lua"
 include "scripting/ui.lua"
 
@@ -87,10 +88,57 @@
 --    :arg message: the message to be sent
 --    :arg sleeptime: ms spent sleeping after the message has been dismissed by the player
 --
+--    Besides the normal message arguments (see wl.Game.Player:message_box) the following ones can be used:
+--
+--    :arg position: A string that indicates at which border of the screen the message box shall appear. Can be "top", "bottom", "right", "left" or a combination (e.g. "topright"). Overrides posx and posy. Default: Center. If only one direction is indicated, the other one stays central.
+--    :arg scroll_back: If true, the view scrolls/jumps back to where it came from. If false, the new location stays on the screen when the message box is closed. Default: False.
+--    :arg show_instantly: If true, the message box is shown immediately. If false, this function will wait until the player leaves the roadbuilding mode. Use this with care because it can be very interruptive. Default: false.
+--
 function campaign_message_box(message, sleeptime)
-   if not message.h then message.h = 400 end
-   if not message.w then message.w = 450 end
-   message_box(wl.Game().players[1], message.title, message.body, message)
+   message.show_instantly = message.show_instantly or false
+   message.scroll_back = message.scroll_back or false
+   message.h = message.h or 400
+   message.w = message.w or 450
+
+   if message.position then
+      if string.find(message.position,"top") then
+         -- Set it a bit lover than 0 to prevent overlap with game speed text
+         message.posy = 25
+      elseif string.find(message.position,"bottom") then
+         message.posy = 10000
+      end
+      if string.find(message.position,"left") then
+         message.posx = 0
+      elseif string.find(message.position,"right") then
+         message.posx = 10000
+      end
+   end
+
+   local center_pixel
+
+   if message.field then
+      -- This is necessary. Otherwise, we would scroll and then wait until the road is finished.
+      -- In this time, could user can scroll elsewhere, giving weird results.
+      if not message.show_instantly then
+         wait_for_roadbuilding()
+      end
+      center_pixel = scroll_to_field(message.field);
+   end
+
+   if message.show_instantly then
+      -- message_box takes care of this, but player:message_box does not
+      local user_input = wl.ui.get_user_input_allowed()
+      wl.ui.set_user_input_allowed(true)
+      wl.Game().players[1]:message_box(message.title, rt(message.body), message)
+      wl.ui.set_user_input_allowed(user_input)
+   else
+      message_box(wl.Game().players[1], message.title, message.body, message)
+   end
+
+   if (message.field and message.scroll_back) then
+      scroll_to_map_pixel(center_pixel);
+   end
+
    if sleeptime then sleep(sleeptime) end
 end
 
@@ -112,6 +160,32 @@
    end
 end
 
+
+-- RST
+-- .. function:: campaign_message_box(message, objective [,sleeptime])
+--
+--    Sets message.h and message.w if not set and calls
+--    message_box(player, title, body, parameters) for player 1.
+--
+--    Adds an objective to the scenario afterwards.
+--
+--
+--    :arg message: the message to be sent
+--    :arg objective: The objective to be added. If the variable obj_name exists, obj_name, obj_title and obj_body are used. Otherwise, it needs to have a name, title, and body.
+--    :arg sleeptime: ms spent sleeping after the message has been dismissed by the player
+--
+--    :returns: The new objective.
+--
+-- TODO(wl-zocker): This function should be used by all tutorials, campaigns and scenario maps
+function campaign_message_with_objective(message, objective, sleeptime)
+   -- TODO(GunChleoc): Once everybody is using this function, move new_objectives over from
+   -- richtext_scenarios and add this file to utils/buildcat.py
+   message.body = message.body .. new_objectives(objective)
+   campaign_message_box(message, sleeptime)
+   return add_campaign_objective(objective)
+end
+
+
 -- RST
 -- .. function:: set_objective_done(objective[, sleeptime])
 --
@@ -133,6 +207,7 @@
 -- RST
 -- .. function:: message_box_objective(player, message)
 --
+--    DEPRECATED, use campaign_message_with_objective instead.
 --    Calls message_box(player, message.title, message.body, message). Also adds an objective defined in obj_name, obj_title and obj_body.
 --    This method should gather all options that are used often to avoid reimplementation in every single scenario script.
 --
@@ -146,8 +221,6 @@
 --    :arg show_instantly: If true, the message box is shown immediately. If false, this function calls message_box(), which waits until the player leaves the roadbuilding mode. Use this with care because it can be very interruptive. Default: false.
 --
 --    :returns: the objective if defined, nil otherwise
-
--- TODO(wl-zocker): This function should be used by all tutorials, campaigns and scenario maps
 function message_box_objective(player, message)
    message.show_instantly = message.show_instantly or false
    message.scroll_back = message.scroll_back or false

=== modified file 'data/scripting/richtext.lua'
--- data/scripting/richtext.lua	2018-09-29 09:20:35 +0000
+++ data/scripting/richtext.lua	2019-06-01 15:39:16 +0000
@@ -424,7 +424,7 @@
 end
 
 -- RST
--- .. function:: li_object(name, text)
+-- .. function:: li_object(name, text[, playercolor])
 --
 --    Places a paragraph of text to the right of an image representing the given map object
 --
@@ -434,12 +434,19 @@
 --    :arg text: the text to be placed next to the image
 --    :type text: :class:`string`
 --
+--    :arg playercolor: a playercolor to be applied to the image, in hex notation
+--    :type playercolor: :class:`string`
+--
 --    :returns: the text wrapped in a paragraph and placed next to the image, the outer tag is a div.
 
-function li_object(name, text)
+function li_object(name, text, playercolor)
+   local image = img_object(name)
+   if (playercolor ~= nil) then
+      image = img_object(name, "color=" .. playercolor)
+   end
    return
       div("width=100%",
-         div("float=left padding_r=6", p(img_object(name))) ..
+         div("float=left padding_r=6", p(image)) ..
          p(text)
       )
 end
@@ -607,7 +614,7 @@
 --           h1("6699ff", _[[Colored header]]) ..
 --           p(_[[Normal paragraph, just with a bit more text to show how it looks like.]]) ..
 --           p("align=center", _[[A centered paragraph, just with a bit more text to show how it looks like.]]) ..
---           li_image("images/wui/menus/menu_toggle_menu.png", _[[An image with right aligned text. This is just text to show automatic line breaks and behavior in regard with images]]) ..
+--           li_image("images/wui/menus/statistics.png", _[[An image with right aligned text. This is just text to show automatic line breaks and behavior in regard with images]]) ..
 --           li(_[[A list item]]) ..
 --           li(font("color=6699ff bold=1", _[[Blue and bold]])) ..
 --           li_arrow(_[[A list item with an arrow]]) ..

=== modified file 'data/scripting/richtext_scenarios.lua'
--- data/scripting/richtext_scenarios.lua	2019-05-12 10:35:21 +0000
+++ data/scripting/richtext_scenarios.lua	2019-06-01 15:39:16 +0000
@@ -87,9 +87,17 @@
       text = text .. obj.body
       sum = sum + obj.number
    end
-      local objectives_header = _"New Objective"
+
+   local objectives_header = _"New Objective"
    if (sum > 1) then
       objectives_header = _"New Objectives"
    end
-   return h1(objectives_header) .. text
+
+   return
+      div("width=100%",
+         vspace(18) ..
+         div("float=left padding_r=6", p(img("images/wui/menus/objectives.png"))) ..
+         p_font("", "size=18 bold=1 color=D1D1D1",  vspace(6) .. objectives_header) ..
+         vspace(1) .. text
+      )
 end


Follow ups