← Back to team overview

widelands-dev team mailing list archive

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

 

hessenfarmer has proposed merging lp:~widelands-dev/widelands/empire04_bug_fix_enhance into lp:widelands.

Commit message:
needs intensive testing

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1785433 in widelands: "empire 4: coroutine failed"
  https://bugs.launchpad.net/widelands/+bug/1785433
  Bug #1785479 in widelands: "Empire 4: temple sacked by barbarians, player blamed"
  https://bugs.launchpad.net/widelands/+bug/1785479

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

scenario has been hardened against unforeseen userinteraction.
some buildings have been changed 
farms can now be upgraded after plans are found 
same with mill and brewery their degraded version can be build by the player
added some soldiers to the temple and added p3 to the same team as p2 to prevent p2 from conquering
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/empire04_bug_fix_enhance into lp:widelands.
=== modified file 'data/campaigns/emp04.wmf/scripting/mission_thread.lua'
--- data/campaigns/emp04.wmf/scripting/mission_thread.lua	2018-05-29 20:14:16 +0000
+++ data/campaigns/emp04.wmf/scripting/mission_thread.lua	2018-08-24 22:48:29 +0000
@@ -13,7 +13,7 @@
    local o = add_campaign_objective(obj_dismantle_buildings)
    local buildmessage = false
    sleep(5000)
-   while count_buildings(p1, {"empire_fishers_house", "empire_quarry", "empire_lumberjacks_house2", "empire_well2"}) > 0 do
+   while count_buildings(p1, {"empire_fishers_house", "empire_quarry", "empire_lumberjacks_house1", "empire_well1"}) > 0 do
       if mv.windows.field_action and mv.windows.field_action.tabs.small and not buildmessage then
          campaign_message_box(amalea_19)
          buildmessage = true
@@ -22,7 +22,7 @@
    end
    sleep(2000)
    p1:allow_buildings("all")
-   p1:forbid_buildings{"empire_farm", "empire_mill", "empire_brewery", "empire_trainingcamp", "empire_colosseum"}
+   p1:forbid_buildings{"empire_farm", "empire_farm2", "empire_mill", "empire_brewery", "empire_mill2", "empire_brewery2","empire_trainingcamp", "empire_colosseum", "empire_lumberjacks_house1", "empire_well1", "empire_foresters_house1"}
    o.done = true
 
    campaign_message_box(amalea_3)
@@ -35,7 +35,7 @@
    local f = map:get_field(47, 10)
    local farmclick = false
    local count = 0
-   while not farmclick do
+   while not (farmclick or p1.defeated) do
       if mv.windows.building_window and not mv.windows.building_window.buttons.dismantle and not mv.windows.building_window.tabs.wares and mv.windows.building_window.tabs.workers then
          farmclick = true
       end
@@ -46,25 +46,27 @@
       sleep(500)
    end
 
-   campaign_message_box(amalea_2)
-   local o = add_campaign_objective(obj_find_farm_plans)
-   while not (f.owner == p1) do
-      sleep(4000)
-   end
-   if f.immovable then
-      local prior_center = scroll_to_field(f)
-      campaign_message_box(amalea_4)
-      sleep(2000)
-      f.immovable:remove()
-      sleep(2000)
-      scroll_to_map_pixel(prior_center)
-   else
-      print("Failed to remove artifact at (" .. f.x .. ", " .. f.y .. ")")
-   end
+   if not p1.defeated then
+      campaign_message_box(amalea_2)
+      local o = add_campaign_objective(obj_find_farm_plans)
+      while not (f.owner == p1) do
+         sleep(4000)
+      end
+      if f.immovable then
+         local prior_center = scroll_to_field(f)
+         campaign_message_box(amalea_4)
+         sleep(2000)
+         f.immovable:remove()
+         sleep(2000)
+         scroll_to_map_pixel(prior_center)
+      else
+         print("Failed to remove artifact at (" .. f.x .. ", " .. f.y .. ")")
+      end
 
-   o.done = true
-   p1:allow_buildings{"empire_farm"}
-   run (wheat_chain)
+      o.done = true
+      p1:allow_buildings{"empire_farm", "empire_farm2"}
+      run (wheat_chain)
+   end
 end
 
 -- the chaotic road network has to be cleared
@@ -98,12 +100,14 @@
          cleared = false
       end
       timer = timer + 1
-      if timer == 100 then
+      if timer == 100 and not p1.defeated then
          campaign_message_box(amalea_20)
       end
    end
-   o.done = true
-   campaign_message_box(amalea_6)
+   if not p1.defeated then
+      o.done = true
+      campaign_message_box(amalea_6)
+   end
 end
 
 -- the foresters have to be replaced too
@@ -121,7 +125,7 @@
          end
       end
    end
-   if #p1:get_buildings("empire_foresters_house2") > 0 then
+   if #p1:get_buildings("empire_foresters_house1") > 0 then
       local o = add_campaign_objective(obj_replace_foresters)
       campaign_message_box(amalea_7)
       while #p1:get_buildings("empire_foresters_house") < 2 do sleep(3249) end
@@ -134,19 +138,23 @@
 function quarries_lumberjacks()
    local o = add_campaign_objective(obj_build_quarries_and_lumberjacks)
    while not check_for_buildings(p1, { empire_lumberjacks_house = 3, empire_quarry = 2}) do sleep(3000) end
-   o.done = true
-   campaign_message_box(amalea_5)
-   run(produce_food)
-   run(no_trees)
+   if not p1.defeated then
+      o.done = true
+      campaign_message_box(amalea_5)
+      run(produce_food)
+      run(no_trees)
+   end
 end
 
 -- now we can start to produce food for our miners
 function produce_food()
    local o = add_campaign_objective(obj_produce_fish)
    while p1:get_produced_wares_count("ration") < 14 do sleep(3000) end
-   o.done = true
-   run(steel)
-   run(charcoal)
+   if not p1.defeated then
+      o.done = true
+      run(steel)
+      run(charcoal)
+   end
 end
 
 -- after having started the metal production we need tools and later on we need soldiers
@@ -170,37 +178,17 @@
       ) < 10) do
    sleep(2500)
    end
-   campaign_message_box(diary_page_2)
-   o.done = true
-   sleep(10000)
-   run(check_enemy)
-
-   -- enough tools produced now start to build weapons
-   local o1 = add_campaign_objective(obj_recruit_soldiers)
-   campaign_message_box(saledus_5)
-   local number_soldiers = 0
-   local bld = array_combine(
-      p1:get_buildings("empire_headquarters"),
-      p1:get_buildings("empire_warehouse"),
-      p1:get_buildings("empire_trainingcamp1"),
-      p1:get_buildings("empire_arena"),
-      p1:get_buildings("empire_sentry"),
-      p1:get_buildings("empire_tower"),
-      p1:get_buildings("empire_fortress"),
-      p1:get_buildings("empire_outpost"),
-      p1:get_buildings("empire_barrier"),
-      p1:get_buildings("empire_blockhouse"),
-      p1:get_buildings("empire_castle")
-   )
-   for idx,site in ipairs(bld) do
-      for descr,count in pairs(site:get_soldiers("all")) do
-         number_soldiers = number_soldiers + count
-      end
-   end
-
-   local enough_soldiers = false
-   while not enough_soldiers do
-      bld = array_combine(
+   if not p1.defeated then
+      campaign_message_box(diary_page_2)
+      o.done = true
+      sleep(10000)
+      run(check_enemy)
+
+      -- enough tools produced now start to build weapons
+      local o1 = add_campaign_objective(obj_recruit_soldiers)
+      campaign_message_box(saledus_5)
+      local number_soldiers = 0
+      local bld = array_combine(
          p1:get_buildings("empire_headquarters"),
          p1:get_buildings("empire_warehouse"),
          p1:get_buildings("empire_trainingcamp1"),
@@ -213,20 +201,44 @@
          p1:get_buildings("empire_blockhouse"),
          p1:get_buildings("empire_castle")
       )
-      local amount = 0
       for idx,site in ipairs(bld) do
          for descr,count in pairs(site:get_soldiers("all")) do
-            amount = amount + count
-         end
-      end
-      if amount > number_soldiers + 9 then
-         enough_soldiers = true
-      end
-      sleep(4273)
+            number_soldiers = number_soldiers + count
+         end
+      end
+
+      local enough_soldiers = false
+      while not enough_soldiers do
+         bld = array_combine(
+            p1:get_buildings("empire_headquarters"),
+            p1:get_buildings("empire_warehouse"),
+            p1:get_buildings("empire_trainingcamp1"),
+            p1:get_buildings("empire_arena"),
+            p1:get_buildings("empire_sentry"),
+            p1:get_buildings("empire_tower"),
+            p1:get_buildings("empire_fortress"),
+            p1:get_buildings("empire_outpost"),
+            p1:get_buildings("empire_barrier"),
+            p1:get_buildings("empire_blockhouse"),
+            p1:get_buildings("empire_castle")
+         )
+         local amount = 0
+         for idx,site in ipairs(bld) do
+            for descr,count in pairs(site:get_soldiers("all")) do
+               amount = amount + count
+            end
+         end
+         if amount > number_soldiers + 9 then
+            enough_soldiers = true
+         end
+         sleep(4273)
+      end
+      if not p1.defeated then
+         o1.done = true
+         campaign_message_box(saledus_6)
+         run(training)
+      end
    end
-   o1.done = true
-   campaign_message_box(saledus_6)
-   run(training)
 end
 
 -- charcoal might be needed to support the metal production
@@ -345,16 +357,18 @@
 function check_enemy()
    local en_see = {}
    while not enemy do
-      en_see = enemy_seen()
-      if en_see then
-         local prior_center = scroll_to_field(en_see)
-         sleep(2000)
-         campaign_message_box(saledus_11)
-         enemy = true
-         run(conquer)
-         scroll_to_map_pixel(prior_center)
+      if not p1.defeated then
+         en_see = enemy_seen()
+         if en_see then
+            local prior_center = scroll_to_field(en_see)
+            sleep(2000)
+            campaign_message_box(saledus_11)
+            enemy = true
+            run(conquer)
+            scroll_to_map_pixel(prior_center)
+         end
+         sleep(8000)
       end
-      sleep(8000)
    end
 end
 
@@ -411,25 +425,38 @@
    scroll_to_map_pixel(prior_center)
 
    local hq = p1:get_buildings("empire_headquarters")
-   local wh = p3:get_buildings("empire_temple_of_vesta")
-   while not ((hq[1]:get_wares("wheat") > 34 and hq[1]:get_wares("wine") > 14) or p3.defeated) do sleep(4000) end
-   if p3.defeated then
+   while sf.immovable.descr.type_name == "warehouse" and (hq[1]:get_wares("wheat") < 35 or hq[1]:get_wares("wine") < 15) and not p3.defeated do 
+      sleep(4000)
+   end
+   if sf.immovable.descr.type_name ~= "warehouse" then
+      if p1.defeated then
+         campaign_message_box(amalea_21)
+         p1.see_all = true
+      else
+         o1.done = true
+         campaign_message_box(amalea_22)
+      end
+   elseif p3.defeated then
       o1.done = true
       julia_conquered = true
-      p1:allow_buildings{"empire_mill", "empire_brewery"}
+      p1:forbid_buildings{"empire_mill1", "empire_brewery1"}
+      p1:allow_buildings{"empire_mill", "empire_brewery", "empire_mill2", "empire_brewery2"}
       campaign_message_box(saledus_2)
       campaign_message_box(julia_2)
       campaign_message_box(amalea_11)
       campaign_message_box(saledus_4)
+      run(karma)
    else
       o1.done = true
-      wh[1]:set_workers("empire_carrier", 0)
-      wh[1]:set_workers("empire_recruit", 0)
+      local wh = p3:get_buildings("empire_temple_of_vesta")
+      --wh[1]:set_workers("empire_carrier", 0)
+      --wh[1]:set_workers("empire_recruit", 0)
       local wheat = hq[1]:get_wares("wheat") - 35
       local wine = hq[1]:get_wares("wine") - 15
       hq[1]:set_wares("wheat", wheat)
       hq[1]:set_wares("wine", wine)
-      p1:allow_buildings{"empire_mill", "empire_brewery"}
+      p1:forbid_buildings{"empire_mill1", "empire_brewery1"}
+      p1:allow_buildings{"empire_mill", "empire_brewery", "empire_mill2", "empire_brewery2"}
       campaign_message_box(julia_1)
 
       --remove all workers from p3 to avoid having them wandering around
@@ -437,6 +464,7 @@
       field_mill.immovable:set_workers("empire_miller", 0)
       wh[1]:set_workers("empire_carrier", 0)
       wh[1]:set_workers("empire_recruit", 0)
+      wh[1]:set_soldiers({0,0,0,0}, 0)
       field_well.immovable:set_workers("empire_carrier", 0)
       r1:set_workers("empire_carrier", 0)
       r2:set_workers("empire_carrier", 0)
@@ -456,25 +484,27 @@
       connected_road(p1, field_mill.immovable.flag, "l, tl, tr", true)
       connected_road(p1, field_mill.immovable.flag, "br, r", true)
 
-
       campaign_message_box(amalea_12)
       campaign_message_box(saledus_3)
+      run(karma)
    end
    obj_find_monastery_done = true
-   run(karma)
 end
 
 -- our actions have an effect positively or negatively
 function karma()
+   -- bad karma for 10 times every 20 minutes a medium building where at least 2 of this type exist will be destroyed
    if julia_conquered then
-      for count = 0, 10 do
+      for count = 1, 11 do
          sleep(1200000)
          bld = {
             "empire_stonemasons_house",
             "empire_sawmill",
             "empire_mill",
+            "empire_mill2",
             "empire_bakery",
             "empire_brewery",
+            "empire_brewery2",
             "empire_vineyard",
             "empire_winery",
             "empire_tavern",
@@ -485,36 +515,46 @@
             "empire_armorsmithy",
             "empire_barracks"
          }
-         local most = 1
-         local selc = 0
+         local cand = {}
          for idx,site in ipairs(bld) do
-            if #p1:get_buildings(site) > most then
-               most = #p1:get_buildings(site)
+            if #p1:get_buildings(site) > 1 then
                local build = p1:get_buildings(site)
-               selc = build[1]
+               for idx,p in ipairs(build) do
+                  table.insert(cand, p)
+               end
             end
          end
-         if selc ~= 0 then
-            local fields = selc.fields
-            local prior_center = scroll_to_field(fields[1])
-            selc:destroy()
+         if #cand > 1 then
+            local i = (count * 1237) % (#cand) + 1
+            local field = cand[i].fields
+            local prior_center = scroll_to_field(field[1])
+            cand[i]:destroy()
             campaign_message_box(amalea_16)
             scroll_to_map_pixel(prior_center)
          end
       end
+   -- good karma for 10 times every 25 minutes the player will be gifted with 20 beer and 10 wine
    else
       for count = 0, 10 do
          sleep(1500000)
-         local hq = p1:get_buildings("empire_headquarters")
-         local beer = hq[1]:get_wares("beer") + 20
-         local wine = hq[1]:get_wares("wine") + 10
-         hq[1]:set_wares("beer", beer)
-         hq[1]:set_wares("wine", wine)
-         campaign_message_box(amalea_17)
+         local hq = p1:get_buildings("empire_temple_of_vesta")
+         if hq then
+            local beer = hq[1]:get_wares("beer") + 20
+            local wine = hq[1]:get_wares("wine") + 10
+            hq[1]:set_wares("beer", beer)
+            hq[1]:set_wares("wine", wine)
+            campaign_message_box(amalea_17)
+         end
       end
    end
 end
 
+function check_defeat()
+   while not p1.defeated do sleep(6000) end
+   campaign_message_box(amalea_23)
+   p1.see_all = true
+end
+
 function mission_thread()
    sleep(1000)
    scroll_to_field(sf)  --scroll to our headquarters
@@ -543,8 +583,10 @@
 
    -- let's start with dismantling the unproductive buildings
    campaign_message_box(amalea_1)
+   
    run(dismantle)
    run(farm_plans)
+   run(check_defeat)
 end
 
 run(mission_thread)

=== modified file 'data/campaigns/emp04.wmf/scripting/starting_conditions.lua'
--- data/campaigns/emp04.wmf/scripting/starting_conditions.lua	2018-07-07 10:53:30 +0000
+++ data/campaigns/emp04.wmf/scripting/starting_conditions.lua	2018-08-24 22:48:29 +0000
@@ -12,7 +12,7 @@
 place_building_in_region(p3, "empire_mill", {field_mill})
 
 field_warehouse = map:get_field(21, 186)
-place_building_in_region(p3, "empire_temple_of_vesta", {field_warehouse}, {workers = {empire_carrier = 0, empire_recruit = 0}, wares = {wheat = 200}})
+place_building_in_region(p3, "empire_temple_of_vesta", {field_warehouse}, {workers = {empire_carrier = 0, empire_recruit = 0}, wares = {wheat = 200}, soldiers = {[{0,0,0,0}] = 3}})
 
    r1 = p3:place_road(field_warehouse.immovable.flag, "l", "tl", true)
    r2 = p3:place_road(field_mill.immovable.flag, "tr", "r", true)
@@ -66,15 +66,15 @@
 place_building_in_region(p1, "empire_fishers_house", {map:get_field(12, 43)})
 
 -- Place well
-place_building_in_region(p1, "empire_well2", sf:region(15))
-place_building_in_region(p1, "empire_well2", sf:region(15))
+place_building_in_region(p1, "empire_well1", sf:region(15))
+place_building_in_region(p1, "empire_well1", sf:region(15))
 
 -- Place lumberjacks
-place_building_in_region(p1, "empire_lumberjacks_house2", sf:region(10))
-place_building_in_region(p1, "empire_lumberjacks_house2", sf:region(10))
-place_building_in_region(p1, "empire_lumberjacks_house2", sf:region(10))
-place_building_in_region(p1, "empire_foresters_house2", {map:get_field(19, 10)})
-place_building_in_region(p1, "empire_foresters_house2", {map:get_field(19, 18)})
+place_building_in_region(p1, "empire_lumberjacks_house1", sf:region(10))
+place_building_in_region(p1, "empire_lumberjacks_house1", sf:region(10))
+place_building_in_region(p1, "empire_lumberjacks_house1", sf:region(10))
+place_building_in_region(p1, "empire_foresters_house1", {map:get_field(19, 10)})
+place_building_in_region(p1, "empire_foresters_house1", {map:get_field(19, 18)})
 
 -- Mines
 place_building_in_region(p1, "empire_ironmine", {map:get_field(33, 14)})
@@ -246,3 +246,7 @@
    }
    }
 )
+
+p1.team = 1
+p2.team = 2
+p3.team = 2

=== modified file 'data/campaigns/emp04.wmf/scripting/texts.lua'
--- data/campaigns/emp04.wmf/scripting/texts.lua	2018-02-23 07:06:48 +0000
+++ data/campaigns/emp04.wmf/scripting/texts.lua	2018-08-24 22:48:29 +0000
@@ -312,13 +312,16 @@
    title=_"Amalea has Bad News",
    body= amalea3(_"Amalea recommends…",
       -- TRANSLATORS: Amalea
-      _([[Brother, I'm really worried that I have to deliver bad news again. As you can see, our farms aren’t producing anything and we can’t dismantle them. The only option is to destroy them.]])
+      _([[Brother, I'm really worried that I have to deliver bad news again. As you can see, our farms aren’t producing anything and we can’t dismantle them.]])
       .. paragraphdivider() ..
       -- TRANSLATORS: Amalea
       _([[This situation was caused by the sad fact that our people lost the instructions on how to construct and operate farms. Therefore they have zero productivity and the constructors don’t know how to dismantle them either.]])
       .. paragraphdivider() ..
       -- TRANSLATORS: Amalea
-      _([[So, we urgently need to recover the plans regarding the construction and operation of farms. One older constructor told me that they might have been concealed in a cave in the hills east of our border.]]))
+      _([[So, we urgently need to recover the plans regarding the construction and operation of farms. One older constructor told me that they might have been concealed in a cave in the hills east of our border.]])
+      .. paragraphdivider() ..
+      -- TRANSLATORS: Amalea
+      _([[Until we have found the plans the only option for our farms is to dismantle them.]]))
       .. new_objectives(obj_find_farm_plans),
    posy=1,
    h=500,
@@ -347,7 +350,7 @@
       _([[Praise the gods, Lutius! We have found the plans on how to build and operate farms.]])
       .. paragraphdivider() ..
       -- TRANSLATORS: Amalea
-      _([[Now we can start building farms to produce the beer which our miners need so desperately.]])
+      _([[Now we can start building farms to produce the beer which our miners need so desperately. Furthermore the plans have enabled us to upgrade our old farms to get to work again.]])
       .. paragraphdivider() ..
       -- TRANSLATORS: Amalea
       _([[But I’m afraid that this problem hasn’t been the last in our economy.]])),
@@ -451,7 +454,7 @@
    title=_"Amalea Looks Sad",
    body= amalea1(_"Amalea is really sad…",
       -- TRANSLATORS: Amalea
-      _([[I’m not sure if that was the right thing to do. Yes, we have obtained the plans, but we will never know if and how Vesta and her priestesses could have helped us against the Barbarians.]])
+      _([[I’m not sure if that was the right thing to do. Yes, we have obtained the plans. But although we are now able to build and upgrade our mills and breweries with the improved technology, we will never know if and how Vesta and her priestesses could have helped us against the Barbarians.]])
       .. paragraphdivider() ..
       -- TRANSLATORS: Amalea
       _([[Furthermore, we will have to live with the guilt of destroying a temple of an Empire goddess on our souls.]])),
@@ -462,7 +465,10 @@
    title=_"Amalea is Very Content",
    body= amalea2(_"Amalea claps her hands…",
       -- TRANSLATORS: Amalea
-      _([[Well done. Now we are able to build more efficient buildings to refine our wheat. And, best of all, we have a new ally who just provided us with lots of water, flour and beer. Now I really think that nothing can prevent us from getting stronger and conquering back our homeland.]])),
+      _([[Well done. Now we are able to build more efficient buildings to refine our wheat. Furthermore the plans enable us to upgrade our current mill and brewery with the improved technology.]])
+      .. paragraphdivider() ..
+      -- TRANSLATORS: Amalea
+      _([[And, best of all, we have a new ally who just provided us with lots of water, flour and beer. Now I really think that nothing can prevent us from getting stronger and conquering back our homeland.]])),
    posy=1,
 }
 
@@ -552,6 +558,32 @@
    posy=1,
 }
 
+amalea_21 = {
+   title=_"Defeated!",
+   body= amalea2(_"Amalea reports our defeat…",
+      -- TRANSLATORS: Amalea
+      _([[Oh no Lutius, I don't know how this could have happened, but the Barbarians have sacked our headquarters. So we have lost this battle and our empire!]])),
+   posy=1,
+}
+
+amalea_22 = {
+   title=_"Amalea has Bad News",
+   body= amalea2(_"Amalea reports our headquarters lost…",
+      -- TRANSLATORS: Amalea
+      _([[Oh no Lutius, I don't know how this could have happened, but the Barbarians have destroyed our headquarters. So we can't deliver the wares to Julia anymore.]])
+      .. paragraphdivider() ..
+      -- TRANSLATORS: Amalea
+      _([[Now we need to try to fulfil our duties without their technology. But this will not be an easy task at all.]])),
+   posy=1,
+}
+
+amalea_23 = {
+   title=_"Defeated!",
+   body= amalea2(_"Amalea reports our defeat…",
+      -- TRANSLATORS: Amalea
+      _([[Oh no Lutius, I don't know how this could have happened, but the Barbarians have destroyed our last warehouse. So we have lost this battle and our empire!]])),
+   posy=1,
+}
 
 -- Saledus
 

=== modified file 'data/campaigns/emp04.wmf/scripting/tribes/brewery1.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/brewery1.lua	2018-07-30 16:56:10 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/brewery1.lua	2018-08-24 22:48:29 +0000
@@ -3,16 +3,23 @@
 tribes:new_productionsite_type {
    msgctxt = "empire_building",
    name = "empire_brewery1",
-   descname = "Brewery",
+   descname = pgettext("empire_building", "Brewery"),
    helptext_script = dirname .. "helptexts.lua",
    icon = dirname .. "menu.png",
    size = "medium",
+   enhancement = "empire_brewery2",
 
+   buildcost = {
+      log = 1,
+      planks = 2,
+      granite = 2
+   },
    return_on_dismantle = {
       planks = 1,
       granite = 1
    },
 
+
    animations = {
       idle = {
          pictures = path.list_files(dirname .. "idle_??.png"),

=== added file 'data/campaigns/emp04.wmf/scripting/tribes/brewery2.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/brewery2.lua	1970-01-01 00:00:00 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/brewery2.lua	2018-08-24 22:48:29 +0000
@@ -0,0 +1,63 @@
+dirname = "tribes/buildings/productionsites/empire/brewery/"
+
+tribes:new_productionsite_type {
+   msgctxt = "empire_building",
+   name = "empire_brewery2",
+   -- TRANSLATORS: This is a building name used in lists of buildings
+   descname = pgettext("empire_building", "Brewery"),
+   helptext_script = dirname .. "helptexts.lua",
+   icon = dirname .. "menu.png",
+   size = "medium",
+
+   enhancement_cost = {
+      planks = 1,
+      granite = 1
+   },
+   return_on_dismantle_on_enhanced = {
+      planks = 0,
+   },
+
+   animations = {
+      idle = {
+         pictures = path.list_files(dirname .. "idle_??.png"),
+         hotspot = { 39, 62 },
+      },
+      working = {
+         pictures = path.list_files(dirname .. "idle_??.png"), -- TODO(GunChleoc): No animation yet.
+         hotspot = { 39, 62 },
+      },
+   },
+
+   aihints = {
+      prohibited_till = 790,
+      very_weak_ai_limit = 1,
+      weak_ai_limit = 2
+   },
+
+   working_positions = {
+      empire_brewer = 1
+   },
+
+   inputs = {
+      { name = "water", amount = 7 },
+      { name = "wheat", amount = 7 }
+   },
+   outputs = {
+      "beer"
+   },
+
+   programs = {
+      work = {
+         -- TRANSLATORS: Completed/Skipped/Did not start brewing beer because ...
+         descname = _"brewing beer",
+         actions = {
+            "sleep=30000",
+            "return=skipped unless economy needs beer",
+            "consume=water wheat",
+            "playsound=sound/empire beerbubble 180",
+            "animate=working 30000",
+            "produce=beer"
+         }
+      },
+   },
+}

=== modified file 'data/campaigns/emp04.wmf/scripting/tribes/farm1.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/farm1.lua	2018-07-31 06:17:07 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/farm1.lua	2018-08-24 22:48:29 +0000
@@ -7,13 +7,14 @@
    helptext_script = dirname .. "helptexts.lua",
    icon = dirname .. "menu.png",
    size = "big",
+   enhancement = "empire_farm2",
 
 
    return_on_dismantle = {
-      planks = 1,
-      granite = 1,
-      marble = 1,
-      marble_column = 1
+      planks = 0,
+      granite = 0,
+      marble = 0,
+      marble_column = 0
    },
 
    animations = {
@@ -24,7 +25,6 @@
    },
 
    aihints = {
-
    },
 
    working_positions = {

=== added file 'data/campaigns/emp04.wmf/scripting/tribes/farm2.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/farm2.lua	1970-01-01 00:00:00 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/farm2.lua	2018-08-24 22:48:29 +0000
@@ -0,0 +1,76 @@
+dirname = "tribes/buildings/productionsites/empire/farm/"
+
+tribes:new_productionsite_type {
+   msgctxt = "empire_building",
+   name = "empire_farm2",
+   -- TRANSLATORS: This is a building name used in lists of buildings
+   descname = pgettext("empire_building", "Farm"),
+   helptext_script = dirname .. "helptexts.lua",
+   icon = dirname .. "menu.png",
+   size = "big",
+
+   enhancement_cost = {
+      planks = 1,
+      marble = 1,
+      marble_column = 2
+   },
+   return_on_dismantle_on_enhanced = {
+      planks = 1,
+      granite = 1,
+      marble = 1,
+      marble_column = 1
+   },
+
+   animations = {
+      idle = {
+         pictures = path.list_files(dirname .. "idle_??.png"),
+         hotspot = { 82, 74 },
+      },
+   },
+
+   aihints = {
+   },
+
+   working_positions = {
+      empire_farmer = 1
+   },
+
+   outputs = {
+      "wheat"
+   },
+
+   programs = {
+      work = {
+         -- TRANSLATORS: Completed/Skipped/Did not start working because ...
+         descname = _"working",
+         actions = {
+            "call=plant",
+            "call=harvest",
+            "return=skipped"
+         }
+      },
+      plant = {
+         -- TRANSLATORS: Completed/Skipped/Did not start planting wheat because ...
+         descname = _"planting wheat",
+         actions = {
+            "sleep=14000",
+            "callworker=plant"
+         }
+      },
+      harvest = {
+         -- TRANSLATORS: Completed/Skipped/Did not start harvesting wheat because ...
+         descname = _"harvesting wheat",
+         actions = {
+            "sleep=4000",
+            "callworker=harvest"
+         }
+      },
+   },
+   out_of_resource_notification = {
+      -- Translators: Short for "Out of ..." for a resource
+      title = _"No Fields",
+      heading = _"Out of Fields",
+      message = pgettext("empire_building", "The farmer working at this farm has no cleared soil to plant his seeds."),
+      productivity_threshold = 30
+   },
+}

=== modified file 'data/campaigns/emp04.wmf/scripting/tribes/foresters_house1.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/foresters_house1.lua	2018-07-30 17:31:02 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/foresters_house1.lua	2018-08-24 22:48:29 +0000
@@ -7,7 +7,6 @@
    helptext_script = dirname .. "helptexts.lua",
    icon = dirname .. "menu.png",
    size = "small",
-   enhancement = "empire_foresters_house2",
 
    buildcost = {
       log = 1,

=== removed file 'data/campaigns/emp04.wmf/scripting/tribes/foresters_house2.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/foresters_house2.lua	2018-07-30 17:31:02 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/foresters_house2.lua	1970-01-01 00:00:00 +0000
@@ -1,44 +0,0 @@
-dirname = "tribes/buildings/productionsites/empire/foresters_house/"
-
-tribes:new_productionsite_type {
-   msgctxt = "empire_building",
-   name = "empire_foresters_house2",
-   descname = "Forester’s House",
-   helptext_script = dirname .. "helptexts.lua",
-   icon = dirname .. "menu.png",
-   size = "small",
-
-   enhancement_cost = {
-      log = 2,
-      planks = 1
-   },
-
-   return_on_dismantle_on_enhanced = {
-      planks = 0
-   },
-
-   animations = {
-      idle = {
-         pictures = path.list_files(dirname .. "idle_??.png"),
-         hotspot = { 52, 54 },
-      },
-   },
-
-   aihints = {
-
-   },
-
-   working_positions = {
-      empire_forester = 1
-   },
-
-   programs = {
-      work = {
-         descname = "planting trees",
-         actions = {
-            "sleep=66000",
-            "callworker=plant"
-         }
-      },
-   },
-}

=== modified file 'data/campaigns/emp04.wmf/scripting/tribes/init.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/init.lua	2018-06-16 19:20:51 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/init.lua	2018-08-24 22:48:29 +0000
@@ -8,15 +8,15 @@
    -- ===================================
    --    Empire Mission 4
    -- ===================================
+   include "map:scripting/tribes/brewery2.lua"
    include "map:scripting/tribes/brewery1.lua"
+   include "map:scripting/tribes/farm2.lua"
    include "map:scripting/tribes/farm1.lua"
-   include "map:scripting/tribes/foresters_house2.lua"
    include "map:scripting/tribes/foresters_house1.lua"
-   include "map:scripting/tribes/lumberjacks_house2.lua"
    include "map:scripting/tribes/lumberjacks_house1.lua"
+   include "map:scripting/tribes/mill2.lua"
    include "map:scripting/tribes/mill1.lua"
    include "map:scripting/tribes/trainingcamp1.lua"
-   include "map:scripting/tribes/well2.lua"
    include "map:scripting/tribes/well1.lua"
    include "map:scripting/tribes/temple_of_vesta.lua"
 end)
@@ -28,17 +28,27 @@
 
 tribes:add_custom_building {
    tribename = "empire",
+   buildingname = "empire_brewery2",
+}
+
+tribes:add_custom_building {
+   tribename = "empire",
    buildingname = "empire_farm1",
 }
 
 tribes:add_custom_building {
    tribename = "empire",
-   buildingname = "empire_foresters_house2",
-}
-
-tribes:add_custom_building {
-   tribename = "empire",
-   buildingname = "empire_lumberjacks_house2",
+   buildingname = "empire_farm2",
+}
+
+tribes:add_custom_building {
+   tribename = "empire",
+   buildingname = "empire_foresters_house1",
+}
+
+tribes:add_custom_building {
+   tribename = "empire",
+   buildingname = "empire_lumberjacks_house1",
 }
 
 tribes:add_custom_building {
@@ -48,12 +58,17 @@
 
 tribes:add_custom_building {
    tribename = "empire",
+   buildingname = "empire_mill2",
+}
+
+tribes:add_custom_building {
+   tribename = "empire",
    buildingname = "empire_trainingcamp1",
 }
 
 tribes:add_custom_building {
    tribename = "empire",
-   buildingname = "empire_well2",
+   buildingname = "empire_well1",
 }
 
 tribes:add_custom_building {

=== modified file 'data/campaigns/emp04.wmf/scripting/tribes/lumberjacks_house1.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/lumberjacks_house1.lua	2018-07-30 17:31:02 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/lumberjacks_house1.lua	2018-08-24 22:48:29 +0000
@@ -7,7 +7,6 @@
    helptext_script = dirname .. "helptexts.lua",
    icon = dirname .. "menu.png",
    size = "small",
-   enhancement = "empire_lumberjacks_house2",
 
    buildcost = {
       log = 2,
@@ -16,6 +15,7 @@
 
    return_on_dismantle = {
       log = 1,
+      planks = 1,
    },
 
    animations = {

=== removed file 'data/campaigns/emp04.wmf/scripting/tribes/lumberjacks_house2.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/lumberjacks_house2.lua	2018-07-30 17:31:02 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/lumberjacks_house2.lua	1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
-dirname = "tribes/buildings/productionsites/empire/lumberjacks_house/"
-
-tribes:new_productionsite_type {
-   msgctxt = "empire_building",
-   name = "empire_lumberjacks_house2",
-   descname = "Lumberjack’s House",
-   helptext_script = dirname .. "helptexts.lua",
-   icon = dirname .. "menu.png",
-   size = "small",
-
-   enhancement_cost = {
-      log = 2,
-      planks = 1
-   },
-
-   return_on_dismantle_on_enhanced = {
-      planks = 1,
-   },
-
-   animations = {
-      idle = {
-         pictures = path.list_files(dirname .. "idle_??.png"),
-         hotspot = { 40, 59 },
-      },
-   },
-
-   aihints = {
-
-   },
-
-   working_positions = {
-      empire_lumberjack = 1
-   },
-
-   outputs = {
-      "log"
-   },
-
-   programs = {
-      work = {
-         descname = "felling trees",
-         actions = {
-            "sleep=400000", -- Barbarian lumberjack sleeps 25000
-            "callworker=harvest"
-         }
-      },
-   },
-   out_of_resource_notification = {
-      title = "No Trees",
-      heading = "Out of Trees",
-      message = "The lumberjack working at this lumberjack’s house can’t find any trees in his work area. You should consider dismantling or destroying the building or building a forester’s house.",
-      productivity_threshold = 60
-   },
-}

=== modified file 'data/campaigns/emp04.wmf/scripting/tribes/mill1.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/mill1.lua	2018-07-30 16:56:10 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/mill1.lua	2018-08-24 22:48:29 +0000
@@ -3,11 +3,17 @@
 tribes:new_productionsite_type {
    msgctxt = "empire_building",
    name = "empire_mill1",
-   descname = "Mill",
+   descname = pgettext("empire_building", "Mill"),
    helptext_script = dirname .. "helptexts.lua",
    icon = dirname .. "menu.png",
    size = "medium",
+   enhancement = "empire_mill2",
 
+   buildcost = {
+      log = 3,
+      granite = 3,
+      marble = 1
+   },
    return_on_dismantle = {
       log = 1,
       granite = 2,
@@ -27,7 +33,6 @@
    },
 
    aihints = {
-
    },
 
    working_positions = {

=== added file 'data/campaigns/emp04.wmf/scripting/tribes/mill2.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/mill2.lua	1970-01-01 00:00:00 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/mill2.lua	2018-08-24 22:48:29 +0000
@@ -0,0 +1,63 @@
+dirname = "tribes/buildings/productionsites/empire/mill/"
+
+tribes:new_productionsite_type {
+   msgctxt = "empire_building",
+   name = "empire_mill2",
+   -- TRANSLATORS: This is a building name used in lists of buildings
+   descname = pgettext("empire_building", "Mill"),
+   helptext_script = dirname .. "helptexts.lua",
+   icon = dirname .. "menu.png",
+   size = "medium",
+
+   enhancement_cost = {
+      log = 1,
+      granite = 1,
+      marble = 1
+   },
+   return_on_dismantle_on_enhanced = {
+      log = 0,
+      granite = 0,
+      marble = 0
+   },
+
+   animations = {
+      idle = {
+         pictures = path.list_files(dirname .. "idle_??.png"),
+         hotspot = { 41, 87 },
+      },
+      working = {
+         pictures = path.list_files(dirname .. "working_??.png"),
+         hotspot = { 41, 87 },
+         fps = 25
+      },
+   },
+
+   aihints = {
+   },
+
+   working_positions = {
+      empire_miller = 1
+   },
+
+   inputs = {
+      { name = "wheat", amount = 6 }
+   },
+   outputs = {
+      "flour"
+   },
+
+   programs = {
+      work = {
+         -- TRANSLATORS: Completed/Skipped/Did not start grinding wheat because ...
+         descname = _"grinding wheat",
+         actions = {
+            "sleep=5000",
+            "return=skipped unless economy needs flour",
+            "consume=wheat",
+            "playsound=sound/mill mill_turning 240",
+            "animate=working 10000",
+            "produce=flour"
+         }
+      },
+   },
+}

=== modified file 'data/campaigns/emp04.wmf/scripting/tribes/well1.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/well1.lua	2017-12-17 13:25:46 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/well1.lua	2018-08-24 22:48:29 +0000
@@ -3,11 +3,10 @@
 tribes:new_productionsite_type {
    msgctxt = "empire_building",
    name = "empire_well1",
-   descname = "Well",
+   descname = pgettext("empire_building", "Well"),
    helptext_script = dirname .. "helptexts.lua",
    icon = dirname .. "menu.png",
    size = "small",
-   enhancement = "empire_well2",
 
    buildcost = {
       log = 2,
@@ -15,7 +14,8 @@
       marble = 1
    },
    return_on_dismantle = {
-      marble = 1
+      log = 1,
+      marble = 1,
    },
 
    animations = {

=== removed file 'data/campaigns/emp04.wmf/scripting/tribes/well2.lua'
--- data/campaigns/emp04.wmf/scripting/tribes/well2.lua	2017-12-17 13:25:46 +0000
+++ data/campaigns/emp04.wmf/scripting/tribes/well2.lua	1970-01-01 00:00:00 +0000
@@ -1,60 +0,0 @@
-dirname = "tribes/buildings/productionsites/empire/well/"
-
-tribes:new_productionsite_type {
-   msgctxt = "empire_building",
-   name = "empire_well2",
-   descname = "Well",
-   helptext_script = dirname .. "helptexts.lua",
-   icon = dirname .. "menu.png",
-   size = "small",
-
-   enhancement_cost = {
-      log = 2,
-      granite = 1,
-      marble = 1
-   },
-   return_on_dismantle_on_enhanced = {
-      log = 1
-   },
-
-   animations = {
-      idle = {
-         pictures = path.list_files(dirname .. "idle_??.png"),
-         hotspot = { 43, 43 },
-      },
-      working = {
-         pictures = path.list_files(dirname .. "idle_??.png"), -- TODO(GunChleoc): No animation yet.
-         hotspot = { 43, 43 },
-      },
-   },
-
-   aihints = {
-
-   },
-
-   working_positions = {
-      empire_carrier = 1
-   },
-
-   outputs = {
-      "water"
-   },
-
-   programs = {
-      work = {
-         descname = "working",
-         actions = {
-            "sleep=30000",
-            "animate=working 30000",
-            "mine=water 5 100 10 2",
-            "produce=water"
-         }
-      },
-   },
-   out_of_resource_notification = {
-      title = "No Water",
-      heading = "Out of Water",
-      message = "The carrier working at this well can’t find any water in his well.",
-      productivity_threshold = 15
-   },
-}


Follow ups