1include "tribes/scripting/help/format_help.lua"
2include "tribes/scripting/help/global_helptexts.lua"
3
4-- RST
5-- building_help.lua
6-- -----------------
7--
8-- This script returns a formatted entry for the ingame building help.
9-- Pass the internal tribe name and building name to the coroutine to select the
10-- building type.
11
12--  =======================================================
13--  ********** Helper functions for dependencies **********
14--  =======================================================
15
16-- RST
17-- .. function:: dependencies_basic(images[, text = nil])
18--
19--    Creates a dependencies line of any length.
20--
21--    :arg images: images in the correct order from left to right as table (set in {}).
22--    :arg text: comment of the image.
23--    :returns: a row of pictures connected by arrows.
24--
25function dependencies_basic(images, text)
26   if not text then
27      text = ""
28   end
29
30   local imgstring = img(images[1])
31   for k,v in ipairs({table.unpack(images,2)}) do
32      imgstring = imgstring .. img("images/richtext/arrow-right.png") .. img(v)
33   end
34   return p(imgstring .. text)
35end
36
37
38-- RST
39-- .. function:: dependencies_resi(resource, items[, text = nil])
40--
41--    Creates a dependencies line of any length for resources (that don't have menu.png files).
42--
43--    :arg resource: name of the geological resource.
44--    :arg items: ware/building descriptions in the correct order from left to right as table (set in {}).
45--    :arg text: comment of the image.
46--    :returns: a row of pictures connected by arrows.
47--
48function dependencies_resi(tribename, resource, items, text)
49   if not text then
50      text = ""
51   end
52   local tribe_descr = wl.Game():get_tribe_description(tribename)
53   local resi
54   local am = 0
55   for amount,name in pairs(tribe_descr.resource_indicators[resource]) do
56      if amount > am then
57         resi = name
58         am = amount
59      end
60   end
61   local items_with_resource = { wl.Game():get_immovable_description(resi).icon_name }
62   for count, item in pairs(items) do
63      table.insert(items_with_resource, item.icon_name)
64   end
65   return dependencies_basic(items_with_resource, text)
66end
67
68
69--  =======================================================
70--  *************** Dependencies functions ****************
71--  =======================================================
72
73-- RST
74-- .. function:: dependencies_training_food
75--
76--    Creates dependencies lines for food in training sites.
77--
78--    :arg foods: an array of arrays with food items. Outer array has "and" logic and
79--        will appear from back to front, inner arrays have "or" logic
80--    :returns: a list of food descriptions with images
81--
82function dependencies_training_food(foods)
83   local result = ""
84   for countlist, foodlist in pairs(foods) do
85      local food_warenames = {}
86      local food_images = {}
87      for countfood, food in pairs(foodlist) do
88         local ware_description = wl.Game():get_ware_description(food)
89         food_warenames[countfood] = ware_description.descname
90         food_images[countfood] = ware_description.icon_name
91      end
92      local text = localize_list(food_warenames, "or", "tribes_encyclopedia")
93      if (countlist > 1) then
94         text = _"%s and":bformat(text)
95      end
96      local images = img(food_images[1])
97      for k,v in ipairs({table.unpack(food_images,2)}) do
98         images = images .. img(v)
99      end
100      result =
101         div("width=100%",
102            div("width=50%", p(vspace(6) .. text .. space(6))) ..
103            div("width=*", p("align=right", vspace(6) .. images .. vspace(12)))
104         )
105         .. result
106   end
107   if (result ~= "") then
108      result = h3(_"Food:") .. result
109   end
110   return result
111end
112
113
114-- RST
115-- .. function:: dependencies_training_weapons(weapons)
116--
117--    Creates a dependencies line for any number of weapons.
118--
119--    :arg weapons: an array of weapon names
120--    :arg tribename: the name of the tribe for filtering the buildings
121--    :returns: a list weapons images with the producing and receiving building
122--
123function dependencies_training_weapons(weapons, tribename)
124   local result = "";
125   local producers = {};
126   for count, weaponname in pairs(weapons) do
127      local weapon_description = wl.Game():get_ware_description(weaponname)
128      for i, producer in ipairs(weapon_description:producers(tribename)) do
129         if (producers[producer.name] == nil) then
130            producers[producer.name] = {}
131         end
132         producers[producer.name][weaponname] = true;
133      end
134   end
135
136   local building_count = 0;
137   for producer, weaponnames in pairs(producers) do
138      local producer_description = wl.Game():get_building_description(producer)
139      local weaponsstring = ""
140      local weaponslist = { producer_description.icon_name }
141      for weaponname, hasweapon in pairs(weaponnames) do
142         if (hasweapon) then
143            local weapon_description = wl.Game():get_ware_description(weaponname)
144            if (#weaponslist < 2) then
145                  table.insert(weaponslist, weapon_description.icon_name)
146               else
147                  weaponsstring = weaponsstring .. img(weapon_description.icon_name)
148            end
149         end
150      end
151      building_count = building_count + 1;
152      result = result ..
153         dependencies_basic(
154            weaponslist,
155            weaponsstring .. " " .. producer_description.descname
156         )
157   end
158   if (result ~= "") then
159      result = h3(_"Equipment:") .. result
160   end
161   return result
162end
163
164
165--  =======================================================
166--  ************* Main buildinghelp functions *************
167--  =======================================================
168
169
170-- RST
171-- .. function:: building_help_general_string(tribe, building_description)
172--
173--    Creates the string for the general section in building help
174--
175--    :arg tribe: The :class:`LuaTribeDescription` for the tribe that has this building.
176--    :arg building_description: The :class:`LuaBuildingDescription` for the building
177--                               that we are displaying this help for.
178--    :returns: rt of the formatted text
179--
180function building_help_general_string(tribe, building_description)
181   -- TRANSLATORS: Heading for a flavour text in the building help.
182   local result = h2(_"Lore")
183   local lore_text = building_helptext_lore()
184   if type(lore_text) == "table" then
185      result = result .. li_object(building_description.name, lore_text[1])
186      for k,v in ipairs({table.unpack(lore_text, 2)}) do
187         result = result .. p(v)
188      end
189   else
190    result = result ..
191      li_object(building_description.name, lore_text)
192   end
193
194   local lore_author = building_helptext_lore_author()
195
196   if type(lore_author) ~= "table" then
197      lore_author = { building_helptext_lore_author() }
198   end
199   for i, item in ipairs(lore_author) do
200      result = result .. div("width=100%", p_font("align=right", "size=10 italic=1", item .. vspace(3)))
201   end
202
203   result = result .. h2(_"General")
204   result = result .. h3(_"Purpose:")
205
206-- TODO(GunChleoc) "carrier" for headquarters, "ship" for ports, "scout" for scouts_hut, "shipwright" for shipyard?
207-- TODO(GunChleoc) use aihints for gamekeeper, forester?
208   local representative_resource = nil
209   if (building_description.type_name == "productionsite" or
210       building_description.type_name == "trainingsite") then
211      representative_resource = building_description.output_ware_types[1]
212      if(not representative_resource) then
213         representative_resource = building_description.output_worker_types[1]
214      end
215   elseif (building_description.type_name == "militarysite") then
216      representative_resource = wl.Game():get_worker_description(tribe.soldier)
217-- TODO(GunChleoc) need a bob_descr for the ship -> port and shipyard
218-- TODO(GunChleoc) create descr objects for flag, portdock, ...
219   elseif (building_description.is_port or building_description.name == "shipyard") then
220      representative_resource = nil
221   elseif (building_description.type_name == "warehouse") then
222      representative_resource = wl.Game():get_ware_description("log")
223   end
224
225   if(representative_resource) then
226      result = result .. li_image(representative_resource.icon_name, building_helptext_purpose())
227   else
228      result = result .. p(building_helptext_purpose())
229   end
230
231   if (building_helptext_note() ~= "") then
232      result = result .. h3(_"Note:") .. p(building_helptext_note())
233   end
234
235   if(building_description.type_name == "productionsite") then
236      if(building_description.workarea_radius and building_description.workarea_radius > 0) then
237         result = result .. inline_header(_"Work area radius:", building_description.workarea_radius)
238      end
239
240   elseif(building_description.type_name == "warehouse") then
241      result = result .. inline_header(_"Healing:",
242         ngettext("Garrisoned soldiers heal %d health point per second.", "Garrisoned soldiers heal %d health points per second.", building_description.heal_per_second):bformat(building_description.heal_per_second))
243      result = result .. inline_header(_"Conquer range:", building_description.conquers)
244
245   elseif(building_description.type_name == "militarysite") then
246      result = result .. h3(_"Healing:")
247         .. p(ngettext("Garrisoned soldiers heal %d health point per second.", "Garrisoned soldiers heal %d health points per second.", building_description.heal_per_second):bformat(building_description.heal_per_second))
248      result = result .. inline_header(_"Capacity:", building_description.max_number_of_soldiers)
249      result = result .. inline_header(_"Conquer range:", building_description.conquers)
250
251   elseif(building_description.type_name == "trainingsite") then
252      result = result .. inline_header(_"Capacity:", building_description.max_number_of_soldiers)
253   end
254   result = result .. inline_header(_"Vision range:", building_description.vision_range)
255   return result
256end
257
258
259-- RST
260-- .. function:: building_help_dependencies_production(tribe, building_description)
261--
262--    The input and output wares of a productionsite
263--
264--    :arg tribe: The :class:`LuaTribeDescription` for the tribe that has this building.
265--    :arg building_description: The :class:`LuaBuildingDescription` for the building
266--                               that we are displaying this help for.
267--    :returns: an rt string with images describing a chain of ware/building dependencies
268--
269function building_help_dependencies_production(tribe, building_description)
270   local result = ""
271   local hasinput = false
272
273   for i, ware_description in ipairs(building_description.inputs) do
274    hasinput = true
275      for j, producer in ipairs(ware_description:producers(tribe.name)) do
276         result = result .. dependencies(
277            {producer, ware_description},
278            _"%1$s from: %2$s":bformat(ware_description.descname, producer.descname)
279         )
280      end
281   end
282   if (hasinput) then
283      -- TRANSLATORS: Heading in the building help for wares that a building accepts (e.g. wheat for a mill).
284      result =  h3(_"Incoming:") .. result
285   end
286
287   if ((not hasinput) and building_description.output_ware_types[1]) then
288      result = result .. h3(_"Collects:")
289      for i, ware_description in ipairs(building_description.output_ware_types) do
290         result = result ..
291            dependencies({building_description, ware_description}, ware_description.descname)
292      end
293      for i, worker_description in ipairs(building_description.output_worker_types) do
294         result = result ..
295            dependencies({building_description, worker_description}, worker_description.descname)
296      end
297
298   elseif (building_description.is_mine) then
299      -- TRANSLATORS: This is a verb (The miner mines)
300      result = result .. h3(_"Mines:")
301      for i, ware_description in ipairs(building_description.output_ware_types) do
302
303         -- Need to hack this, because resource != produced ware.
304         local resi_name = ware_description.name
305         if(resi_name == "iron_ore") then resi_name = "iron"
306         elseif(resi_name == "granite") then resi_name = "stones"
307         elseif(resi_name == "diamond") then resi_name = "stones"
308         elseif(resi_name == "quartz") then resi_name = "stones"
309         elseif(resi_name == "marble") then resi_name = "stones"
310         elseif(resi_name == "gold_ore") then resi_name = "gold" end
311         result = result .. dependencies_resi(tribe.name,
312            resi_name,
313            {building_description, ware_description},
314            ware_description.descname
315         )
316      end
317
318   else
319      if(building_description.output_ware_types[1] or building_description.output_worker_types[1]) then
320         result = result .. h3(_"Produces:")
321      end
322      for i, ware_description in ipairs(building_description.output_ware_types) do
323         result = result ..
324            dependencies({building_description, ware_description}, ware_description.descname)
325      end
326      for i, worker_description in ipairs(building_description.output_worker_types) do
327         result = result ..
328            dependencies({building_description, worker_description}, worker_description.descname)
329      end
330   end
331
332   local outgoing = ""
333   for i, ware_description in ipairs(building_description.output_ware_types) do
334
335      -- Constructionsite isn't listed with the consumers, so we need a special check
336      if (ware_description:is_construction_material(tribe.name)) then
337         local constructionsite_description =
338            wl.Game():get_building_description("constructionsite")
339         outgoing = outgoing .. dependencies({ware_description, constructionsite_description},
340                                              constructionsite_description.descname)
341      end
342
343      -- Normal buildings
344      for j, consumer in ipairs(ware_description:consumers(tribe.name)) do
345         if (tribe:has_building(consumer.name)) then
346            outgoing = outgoing .. dependencies({ware_description, consumer}, consumer.descname)
347         end
348      end
349
350      -- Soldiers aren't listed with the consumers. Get their buildcost wares and list the warehouses.
351      local soldier = wl.Game():get_worker_description(tribe.soldier)
352      for j, buildcost in ipairs(soldier.buildcost) do
353         if (buildcost == ware) then
354            for k, building in ipairs(tribe.buildings) do
355               if (building.type_name == "warehouse") then
356                  outgoing = outgoing .. dependencies({ware, building, soldier}, soldier.descname)
357               end
358            end
359         end
360      end
361   end
362   if (outgoing ~= "") then result = result .. h3(_"Outgoing:") .. outgoing end
363
364   if (result == "") then result = p(_"None") end
365   return h2(_"Dependencies") .. result
366end
367
368-- RST
369-- .. function:: building_help_dependencies_training(tribe, building_description)
370--
371--    Shows the production dependencies for a training site.
372--
373--    :arg tribe: The :class:`LuaTribeDescription` for the tribe that has this building.
374--    :arg building_description: The :class:`LuaBuildingDescription` for the building
375--                               that we are displaying this help for.
376--    :returns: rt string with training dependencies information.
377--
378function building_help_dependencies_training(tribe, building_description)
379   local result = ""
380   if (building_description.max_health and building_description.min_health) then
381      result = result .. h2(_"Health Training")
382      result = result .. p(_"Trains ‘Health’ from %1% up to %2%":
383            bformat(building_description.min_health, building_description.max_health+1))
384      result = result .. h3(_"Soldiers:")
385      result = result ..
386         dependencies_basic({
387            "tribes/workers/" .. tribe.name .. "/soldier/health_level" .. building_description.min_health .. ".png",
388            building_description.icon_name,
389            "tribes/workers/" .. tribe.name .. "/soldier/health_level" .. (building_description.max_health + 1) ..".png"})
390      result = result .. dependencies_training_food(building_description.food_health)
391      result = result .. dependencies_training_weapons(building_description.weapons_health, tribe.name)
392   end
393   if (building_description.max_attack and building_description.min_attack) then
394      result = result .. h2(_"Attack Training")
395      -- TRANSLATORS: %1$s = Health, Evade, Attack or Defense. %2$s and %3$s are numbers.
396      result = result .. p(_"Trains ‘Attack’ from %1% up to %2%":
397         bformat(building_description.min_attack, building_description.max_attack+1))
398      result = result .. h3(_"Soldiers:") ..
399         dependencies_basic({
400            "tribes/workers/" .. tribe.name .. "/soldier/attack_level" .. building_description.min_attack .. ".png",
401            building_description.icon_name,
402            "tribes/workers/" .. tribe.name .. "/soldier/attack_level" .. (building_description.max_attack + 1) ..".png"})
403      result = result .. dependencies_training_food(building_description.food_attack)
404      result = result .. dependencies_training_weapons(building_description.weapons_attack, tribe.name)
405   end
406   if (building_description.max_defense and building_description.min_defense) then
407      result = result .. h2(_"Defense Training")
408      result = result .. p( _"Trains ‘Defense’ from %1% up to %2%":
409            bformat(building_description.min_defense, building_description.max_defense+1))
410            result = result .. h3(_"Soldiers:")
411      result = result ..
412         dependencies_basic({
413            "tribes/workers/" .. tribe.name .. "/soldier/defense_level" .. building_description.min_defense .. ".png",
414            building_description.icon_name,
415            "tribes/workers/" .. tribe.name .. "/soldier/defense_level" .. (building_description.max_defense + 1) ..".png"})
416      result = result .. dependencies_training_food(building_description.food_defense)
417      result = result .. dependencies_training_weapons(building_description.weapons_defense, tribe.name)
418   end
419   if (building_description.max_evade and building_description.min_evade) then
420      result = result .. h2(_"Evade Training")
421      result = result .. p( _"Trains ‘Evade’ from %1% up to %2%":
422            bformat(building_description.min_evade, building_description.max_evade+1))
423      result = result .. h3(_"Soldiers:")
424      result = result ..
425         dependencies_basic({
426            "tribes/workers/" .. tribe.name .. "/soldier/evade_level" .. building_description.min_evade .. ".png",
427            building_description.icon_name,
428            "tribes/workers/" .. tribe.name .. "/soldier/evade_level" .. (building_description.max_evade + 1) ..".png"})
429      result = result .. dependencies_training_food(building_description.food_evade)
430      result = result .. dependencies_training_weapons(building_description.weapons_evade, tribe.name)
431   end
432   return result
433end
434
435
436-- RST
437--
438-- .. function:: building_help_building_section(building_description)
439--
440--    Formats the "Building" section in the building help: Enhancing info, costs and space required
441--
442--    :arg building_description: The :class:`LuaBuildingDescription` for the building
443--                               that we are displaying this help for.
444--    :returns: an rt string describing the building section
445--
446function building_help_building_section(building_description)
447   -- TRANSLATORS: This is the header for the "Building" section in the building help, containing size info, buildcost etc.
448   local result = h2(_"Building")
449
450   -- Space required
451   if (building_description.is_mine) then
452      result = result .. plot_size_line("mine")
453   elseif (building_description.is_port) then
454      result = result .. plot_size_line("port")
455   else
456      result = result .. plot_size_line(building_description.size)
457   end
458
459   -- Enhanced from
460   if (building_description.buildable or building_description.enhanced) then
461
462      if (building_description.buildable and building_description.enhanced) then
463         result = result .. inline_header(_"Note:",
464            _"This building can either be built directly or obtained by enhancing another building.")
465      end
466
467      if (building_description.buildable) then
468         -- Build cost
469         if (building_description.buildable and building_description.enhanced) then
470            result = result .. h3(_"Direct build cost:")
471         else
472            result = result .. h3(_"Build cost:")
473         end
474         for ware, amount in pairs(building_description.buildcost) do
475            local ware_description = wl.Game():get_ware_description(ware)
476            result = result .. help_ware_amount_line(ware_description, amount)
477         end
478      end
479      local former_building = nil
480      if (building_description.enhanced) then
481         former_building = building_description.enhanced_from
482            if (building_description.buildable) then
483               result = result .. inline_header(_"Or enhanced from:", former_building.descname)
484            else
485               result = result .. inline_header(_"Enhanced from:", former_building.descname)
486            end
487
488         for ware, amount in pairs(building_description.enhancement_cost) do
489            local ware_description = wl.Game():get_ware_description(ware)
490            result = result .. help_ware_amount_line(ware_description, amount)
491         end
492
493         -- Cumulative cost
494         result = result .. h3(_"Cumulative cost:")
495         local warescost = {}
496         for ware, amount in pairs(building_description.enhancement_cost) do
497            if (warescost[ware]) then
498               warescost[ware] = warescost[ware] + amount
499            else
500               warescost[ware] = amount
501            end
502         end
503
504         local former_buildings = {};
505         former_building = building_description
506
507         while former_building.enhanced do
508            former_building = former_building.enhanced_from
509            table.insert(former_buildings, former_building)
510         end
511
512         for index, former in pairs(former_buildings) do
513            former_building = wl.Game():get_building_description(former.name)
514            if (former_building.buildable) then
515               for ware, amount in pairs(former_building.buildcost) do
516                  if (warescost[ware]) then
517                     warescost[ware] = warescost[ware] + amount
518                  else
519                     warescost[ware] = amount
520                  end
521               end
522            elseif (former_building.enhanced) then
523               for ware, amount in pairs(former_building.enhancement_cost) do
524                  if (warescost[ware]) then
525                     warescost[ware] = warescost[ware] + amount
526                  else
527                     warescost[ware] = amount
528                  end
529               end
530            end
531         end
532
533         if (warescost ~= {}) then
534            for ware, amount in pairs(warescost) do
535               local ware_description = wl.Game():get_ware_description(ware)
536               result = result .. help_ware_amount_line(ware_description, amount)
537            end
538         else
539            result = result .. p(_"Unknown")
540         end
541
542         -- Dismantle yields
543         if (building_description.buildable) then
544            result = result .. h3(_"If built directly, dismantle yields:")
545            for ware, amount in pairs(building_description.returned_wares) do
546               local ware_description = wl.Game():get_ware_description(ware)
547               result = result .. help_ware_amount_line(ware_description, amount)
548            end
549            result = result .. h3(_"If enhanced, dismantle yields:")
550         else
551            -- TRANSLATORS: This is a heading for the resources that you will get back when you dismantle a building of this type. What dismantling will give you.
552            result = result .. h3(_"Dismantle yields:")
553         end
554         local warescost = {}
555         for ware, amount in pairs(building_description.returned_wares_enhanced) do
556            if (warescost[ware]) then
557               warescost[ware] = warescost[ware] + amount
558            else
559               warescost[ware] = amount
560            end
561         end
562         for index, former in pairs(former_buildings) do
563            former_building = wl.Game():get_building_description(former.name)
564            if (former_building.buildable) then
565               for ware, amount in pairs(former_building.returned_wares) do
566                  if (warescost[ware]) then
567                     warescost[ware] = warescost[ware] + amount
568                  else
569                     warescost[ware] = amount
570                  end
571               end
572            elseif (former_building.enhanced) then
573               for ware, amount in pairs(former_building.returned_wares_enhanced) do
574                  if (warescost[ware]) then
575                     warescost[ware] = warescost[ware] + amount
576                  else
577                     warescost[ware] = amount
578                  end
579               end
580            end
581         end
582         if (warescost ~= {}) then
583            for ware, amount in pairs(warescost) do
584               local ware_description = wl.Game():get_ware_description(ware)
585               result = result .. help_ware_amount_line(ware_description, amount)
586            end
587         else
588            result = result .. p(_"Unknown")
589         end
590      -- Buildable
591      else
592         -- Dismantle yields
593         result = result .. h3(_"Dismantle yields:")
594         for ware, amount in pairs(building_description.returned_wares) do
595            local ware_description = wl.Game():get_ware_description(ware)
596            result = result .. help_ware_amount_line(ware_description, amount)
597         end
598      end
599
600      -- Can be enhanced to
601      if (building_description.enhancement) then
602         result = result .. inline_header(_"Can be enhanced to:", building_description.enhancement.descname)
603         for ware, amount in pairs(building_description.enhancement.enhancement_cost) do
604            local ware_description = wl.Game():get_ware_description(ware)
605            result = result .. help_ware_amount_line(ware_description, amount)
606         end
607      end
608   end
609   return result
610end
611
612
613
614-- RST
615-- .. function:: building_help_crew_string(tribe, building_description)
616--
617--    Displays the building's workers with an image and the tool they use
618--
619--    :arg tribe: The :class:`LuaTribeDescription` for the tribe
620--                that we are displaying this help for.
621--
622--    :arg building_description: The :class:`LuaBuildingDescription` for the building
623--                               that we are displaying this help for.
624--
625--    :returns: Workers/Crew section of the help file
626--
627function building_help_crew_string(tribe, building_description)
628   local result = ""
629
630   if(building_description.type_name == "productionsite" or building_description.type_name == "trainingsite") then
631
632      result = result .. h2(_"Workers") .. h3(_"Crew required:")
633
634      local worker_description = building_description.working_positions[1]
635      local becomes_description = nil
636      local number_of_workers = 0
637      local toolnames = {}
638
639      for i, worker_description in ipairs(building_description.working_positions) do
640
641         -- Get the tools for the workers.
642         for j, buildcost in ipairs(worker_description.buildcost) do
643            if (buildcost ~= nil and tribe:has_ware(buildcost)) then
644               toolnames[#toolnames + 1] = buildcost
645            end
646         end
647
648         becomes_description = worker_description.becomes
649         number_of_workers = number_of_workers + 1
650
651         if(becomes_description) then
652            result = result .. image_line(worker_description.icon_name, 1,
653               -- TRANSLATORS: %s is a worker name, e.g. "Chief Miner" or "Brewer".
654               p(_"%s or better":bformat(worker_description.descname)))
655         else
656            result = result .. image_line(worker_description.icon_name, 1,
657               p(worker_description.descname))
658         end
659      end
660
661      if (number_of_workers > 0) then
662         local tool_string = help_tool_string(tribe, toolnames, number_of_workers)
663         if (tool_string ~= "") then
664            if (number_of_workers == 1) then
665               -- TRANSLATORS: Tribal Encyclopedia: Heading for which tool 1 worker uses
666               result = result .. h3(_"Worker uses:")
667            else
668               -- TRANSLATORS: Tribal Encyclopedia: Heading for which tool more than 1 worker uses
669               result = result .. h3(_"Workers use:")
670            end
671            result = result .. tool_string
672         end
673      end
674
675      worker_description = building_description.working_positions[1]
676      becomes_description = worker_description.becomes
677
678      if (becomes_description) then
679         result = result .. help_worker_experience(worker_description, becomes_description)
680      end
681   end
682
683   return result
684end
685
686
687-- RST
688-- .. function:: building_help_production_section()
689--
690--    Displays the production/performance section with a headline
691--
692--    :returns: rt for the production section
693--
694function building_help_production_section()
695   if (building_helptext_performance() ~= "") then
696      return h2(_"Production") ..
697        inline_header(_"Performance:", building_helptext_performance())
698   else
699      return ""
700   end
701end
702
703
704-- RST
705-- .. function:: building_help(tribe, building_description)
706--
707--    Main function to create a building help string.
708--
709--    :arg tribe: The :class:`LuaTribeDescription` for the tribe that has this building.
710--    :arg building_description: The :class:`LuaBuildingDescription` for the building
711--                               that we are displaying this help for.
712--    :returns: rt of the formatted text
713--
714function building_help(tribe, building_description)
715   include(building_description.helptext_script)
716
717   if (building_description.type_name == "productionsite") then
718      return building_help_general_string(tribe, building_description) ..
719         building_help_dependencies_production(tribe, building_description) ..
720         building_help_crew_string(tribe, building_description) ..
721         building_help_building_section(building_description) ..
722         building_help_production_section()
723   elseif (building_description.type_name == "militarysite") then
724      return building_help_general_string(tribe, building_description) ..
725         building_help_building_section(building_description)
726   elseif (building_description.type_name == "warehouse") then
727      if (building_description.is_port) then
728         return building_help_general_string(tribe, building_description) ..
729            -- TODO(GunChleoc) expedition costs here?
730            building_help_building_section(building_description) ..
731            building_help_production_section()
732      else
733         return building_help_general_string(tribe, building_description) ..
734            building_help_building_section(building_description)
735      end
736   elseif (building_description.type_name == "trainingsite") then
737      return building_help_general_string(tribe, building_description) ..
738         building_help_dependencies_training(tribe, building_description) ..
739         building_help_crew_string(tribe, building_description) ..
740         building_help_building_section(building_description) ..building_help_production_section()
741   elseif (building_description.type_name == "constructionsite" or
742            building_description.type_name == "dismantlesite") then
743            -- TODO(GunChleoc) Get them a crew string for the builder
744      return building_help_general_string(tribe, building_description)
745   elseif (building_description.type_name == "market") then
746      return building_help_general_string(tribe, building_description)
747   else
748      return ""
749   end
750end
751
752-- The main function call
753return {
754   func = function(tribename, buildingname)
755      set_textdomain("tribes_encyclopedia")
756      local tribe = wl.Game():get_tribe_description(tribename)
757      -- We need to get the building description again, because it will
758      -- give us a cast to the appropriate subclass.
759      local building_description = wl.Game():get_building_description(buildingname)
760      return {
761         title = building_description.descname,
762         text = building_help(tribe, building_description)
763      }
764   end
765}
766