Merge lp:~widelands-dev/widelands/fh1 into lp:widelands

Proposed by cghislai
Status: Work in progress
Proposed branch: lp:~widelands-dev/widelands/fh1
Merge into: lp:widelands
Diff against target: 20941 lines (+6147/-5758)
228 files modified
CMakeLists.txt (+1/-0)
campaigns/atl01.wmf/scripting/init.lua (+3/-3)
campaigns/atl01.wmf/scripting/texts.lua (+49/-52)
campaigns/bar01.wmf/scripting/texts.lua (+70/-81)
campaigns/bar02.wmf/scripting/texts.lua (+33/-36)
campaigns/emp01.wmf/scripting/texts.lua (+28/-29)
campaigns/emp02.wmf/scripting/texts.lua (+33/-33)
campaigns/tutorial01_basic_control.wmf/scripting/texts.lua (+124/-206)
campaigns/tutorial02_warfare.wmf/scripting/texts.lua (+49/-77)
campaigns/tutorial03_seafaring.wmf/scripting/texts.lua (+43/-72)
campaigns/tutorial04_economy.wmf/scripting/texts.lua (+110/-181)
cmake/Modules/FindICU.cmake (+315/-0)
cmake/WlFunctions.cmake (+6/-0)
doc/sphinx/source/wlrichtext.rst (+4/-6)
i18n/fonts.lua (+17/-10)
i18n/fonts/FaKacstBook/README (+0/-5)
i18n/fonts/amiri/OFL-FAQ.txt (+369/-0)
i18n/fonts/amiri/OFL.txt (+87/-0)
i18n/fonts/amiri/README.txt (+8/-0)
maps/MP Scenarios/Island Hopping.wmf/scripting/first_island.lua (+4/-4)
maps/MP Scenarios/Island Hopping.wmf/scripting/multiplayer_init.lua (+1/-1)
maps/MP Scenarios/Island Hopping.wmf/scripting/texts.lua (+32/-53)
maps/MP Scenarios/Smugglers.wmf/scripting/texts.lua (+1/-0)
maps/Plateau.wmf/scripting/texts.lua (+10/-14)
scripting/format_scenario.lua (+14/-70)
scripting/formatting.lua (+198/-61)
scripting/win_condition_functions.lua (+1/-0)
scripting/win_conditions/collectors.lua (+9/-18)
scripting/win_conditions/defeat_all.lua (+2/-1)
scripting/win_conditions/endless_game.lua (+2/-1)
scripting/win_conditions/endless_game_fogless.lua (+2/-1)
scripting/win_conditions/territorial_lord.lua (+4/-3)
scripting/win_conditions/territorial_time.lua (+3/-2)
scripting/win_conditions/wood_gnome.lua (+6/-5)
src/base/i18n.cc (+2/-1)
src/base/i18n.h (+1/-0)
src/editor/CMakeLists.txt (+1/-0)
src/editor/tools/editor_info_tool.cc (+130/-112)
src/editor/ui_menus/categorized_item_selection_menu.h (+1/-1)
src/editor/ui_menus/editor_main_menu_load_map.cc (+17/-15)
src/editor/ui_menus/editor_main_menu_map_options.cc (+4/-4)
src/editor/ui_menus/editor_main_menu_random_map.cc (+2/-5)
src/editor/ui_menus/editor_main_menu_save_map.cc (+19/-16)
src/editor/ui_menus/editor_main_menu_save_map_make_directory.cc (+1/-2)
src/editor/ui_menus/editor_player_menu.cc (+5/-3)
src/editor/ui_menus/editor_tool_change_height_options_menu.cc (+4/-6)
src/editor/ui_menus/editor_tool_change_resources_options_menu.cc (+24/-26)
src/editor/ui_menus/editor_tool_noise_height_options_menu.cc (+3/-6)
src/editor/ui_menus/editor_tool_set_terrain_options_menu.h (+0/-1)
src/editor/ui_menus/editor_toolsize_menu.cc (+6/-2)
src/editor/ui_menus/editor_toolsize_menu.h (+1/-1)
src/graphic/CMakeLists.txt (+6/-12)
src/graphic/align.cc (+1/-0)
src/graphic/font.cc (+0/-1)
src/graphic/font.h (+0/-1)
src/graphic/font_handler.cc (+0/-275)
src/graphic/font_handler.h (+0/-76)
src/graphic/font_handler1.cc (+91/-28)
src/graphic/font_handler1.h (+25/-2)
src/graphic/format.cc (+210/-140)
src/graphic/format.h (+62/-54)
src/graphic/graphic.cc (+2/-7)
src/graphic/richtext.cc (+0/-497)
src/graphic/richtext.h (+0/-62)
src/graphic/text/CMakeLists.txt (+4/-0)
src/graphic/text/font_set.cc (+6/-0)
src/graphic/text/font_set.h (+2/-0)
src/graphic/text/layout_info.cc (+257/-0)
src/graphic/text/layout_info.h (+174/-0)
src/graphic/text/rt_parse.cc (+72/-41)
src/graphic/text/rt_parse.h (+8/-10)
src/graphic/text/rt_render.cc (+871/-213)
src/graphic/text/rt_render.h (+18/-1)
src/graphic/text/test/data/b1206712/input01.txt (+1/-1)
src/graphic/text/test/data/br/input00.txt (+0/-13)
src/graphic/text/test/data/br/width (+0/-1)
src/graphic/text/test/data/bullet_point/input00.txt (+8/-8)
src/graphic/text/test/data/div_autowidth_floatleftimg/input00.txt (+2/-2)
src/graphic/text/test/data/div_background_img/input00.txt (+2/-2)
src/graphic/text/test/data/div_fixedwidth_floatbothsides/input00.txt (+4/-4)
src/graphic/text/test/data/div_fixedwidth_floatleft/input00.txt (+2/-2)
src/graphic/text/test/data/div_fixedwidth_floatleftimg/input00.txt (+2/-2)
src/graphic/text/test/data/div_fixedwidth_floatright/input00.txt (+2/-2)
src/graphic/text/test/data/div_margin_bgclr/input00.txt (+4/-4)
src/graphic/text/test/data/div_margin_bgimg/input00.txt (+4/-4)
src/graphic/text/test/data/div_nonfloating_valign/input00.txt (+2/-2)
src/graphic/text/test/data/div_padding/input00.txt (+2/-2)
src/graphic/text/test/data/font_shadow/input00.txt (+1/-1)
src/graphic/text/test/data/hspace_dynamic_img/input00.txt (+3/-5)
src/graphic/text/test/data/hspace_dynamic_text/input00.txt (+3/-5)
src/graphic/text/test/data/table_like/input00.txt (+16/-14)
src/graphic/text_constants.h (+0/-51)
src/graphic/text_parser.cc (+0/-310)
src/graphic/text_parser.h (+0/-157)
src/graphic/wordwrap.cc (+0/-293)
src/graphic/wordwrap.h (+0/-80)
src/io/dedicated_log.cc (+4/-3)
src/logic/building.cc (+20/-16)
src/logic/constructionsite.cc (+2/-2)
src/logic/editor_game_base.cc (+1/-4)
src/logic/expedition_bootstrap.cc (+4/-1)
src/logic/immovable.cc (+6/-4)
src/logic/instances.h (+1/-1)
src/logic/productionsite.cc (+10/-10)
src/logic/ship.cc (+4/-4)
src/logic/worker.cc (+3/-5)
src/map_io/map_buildingdata_packet.cc (+0/-1)
src/network/internet_gaming.cc (+3/-4)
src/network/nethost.cc (+56/-56)
src/scripting/lua_game.cc (+14/-3)
src/scripting/lua_globals.cc (+1/-1)
src/ui_basic/button.cc (+51/-22)
src/ui_basic/button.h (+14/-10)
src/ui_basic/editbox.cc (+41/-27)
src/ui_basic/editbox.h (+1/-2)
src/ui_basic/helpwindow.cc (+31/-56)
src/ui_basic/helpwindow.h (+7/-7)
src/ui_basic/icongrid.cc (+0/-3)
src/ui_basic/icongrid.h (+0/-1)
src/ui_basic/listselect.cc (+119/-71)
src/ui_basic/listselect.h (+22/-11)
src/ui_basic/messagebox.cc (+43/-60)
src/ui_basic/messagebox.h (+2/-1)
src/ui_basic/multilineeditbox.cc (+582/-311)
src/ui_basic/multilineeditbox.h (+25/-12)
src/ui_basic/multilinetextarea.cc (+153/-126)
src/ui_basic/multilinetextarea.h (+35/-43)
src/ui_basic/panel.cc (+10/-16)
src/ui_basic/panel.h (+0/-1)
src/ui_basic/progressbar.cc (+11/-8)
src/ui_basic/progresswindow.cc (+7/-9)
src/ui_basic/scrollbar.cc (+6/-1)
src/ui_basic/scrollbar.h (+2/-0)
src/ui_basic/slider.cc (+11/-10)
src/ui_basic/spinbox.cc (+15/-40)
src/ui_basic/spinbox.h (+3/-4)
src/ui_basic/table.cc (+89/-37)
src/ui_basic/table.h (+25/-8)
src/ui_basic/textarea.cc (+100/-99)
src/ui_basic/textarea.h (+15/-20)
src/ui_basic/window.cc (+1/-1)
src/ui_fsmenu/base.cc (+1/-11)
src/ui_fsmenu/base.h (+1/-10)
src/ui_fsmenu/campaign_select.cc (+28/-35)
src/ui_fsmenu/editor.cc.THIS (+73/-0)
src/ui_fsmenu/fileview.cc (+6/-14)
src/ui_fsmenu/fileview.h (+8/-5)
src/ui_fsmenu/internet_lobby.cc (+15/-22)
src/ui_fsmenu/internet_lobby.h (+1/-3)
src/ui_fsmenu/intro.cc (+2/-3)
src/ui_fsmenu/launch_mpg.cc (+40/-52)
src/ui_fsmenu/launch_mpg.h (+2/-2)
src/ui_fsmenu/launch_spg.cc (+18/-30)
src/ui_fsmenu/load_map_or_game.cc (+2/-2)
src/ui_fsmenu/loadgame.cc (+31/-30)
src/ui_fsmenu/main.cc (+21/-20)
src/ui_fsmenu/mapselect.cc (+19/-20)
src/ui_fsmenu/multiplayer.cc (+5/-7)
src/ui_fsmenu/netsetup_lan.cc (+9/-14)
src/ui_fsmenu/options.cc (+57/-47)
src/ui_fsmenu/options.h (+4/-1)
src/ui_fsmenu/singleplayer.cc (+6/-8)
src/ui_fsmenu/suggested_teams_box.cc (+2/-3)
src/wlapplication.cc (+1/-7)
src/wui/actionconfirm.cc (+5/-5)
src/wui/attack_box.cc (+7/-11)
src/wui/attack_box.h (+1/-3)
src/wui/building_statistics_menu.cc (+22/-29)
src/wui/buildingwindow.cc (+14/-6)
src/wui/chat_msg_layout.cc (+1/-105)
src/wui/chat_msg_layout.h (+0/-3)
src/wui/chatoverlay.cc (+11/-4)
src/wui/encyclopedia_window.cc (+5/-3)
src/wui/fieldaction.cc (+6/-3)
src/wui/game_debug_ui.cc (+6/-6)
src/wui/game_main_menu_save_game.cc (+8/-9)
src/wui/game_message_menu.cc (+14/-14)
src/wui/game_objectives_menu.cc (+9/-5)
src/wui/game_options_menu.cc (+1/-2)
src/wui/game_options_sound_menu.cc (+1/-0)
src/wui/game_summary.cc (+7/-5)
src/wui/game_tips.cc (+1/-1)
src/wui/gamechatpanel.cc (+14/-9)
src/wui/interactive_base.cc (+11/-13)
src/wui/interactive_gamebase.cc (+8/-10)
src/wui/interactive_player.cc (+1/-1)
src/wui/login_box.cc (+13/-11)
src/wui/multiplayersetupgroup.cc (+35/-38)
src/wui/multiplayersetupgroup.h (+1/-4)
src/wui/playerdescrgroup.cc (+0/-2)
src/wui/plot_area.cc (+1/-1)
src/wui/soldiercapacitycontrol.cc (+7/-2)
src/wui/soldierlist.cc (+23/-16)
src/wui/story_message_box.cc (+1/-2)
src/wui/transport_ui.cc (+1/-1)
src/wui/waresdisplay.cc (+12/-14)
tribes/atlanteans/dungeon/help.lua (+1/-1)
tribes/atlanteans/headquarters/help.lua (+1/-1)
tribes/atlanteans/labyrinth/help.lua (+3/-3)
tribes/atlanteans/resi_granite1/conf (+0/-10)
tribes/atlanteans/resi_granite2/conf (+0/-10)
tribes/barbarians/axfactory/help.lua (+1/-1)
tribes/barbarians/battlearena/help.lua (+1/-1)
tribes/barbarians/coalmine/help.lua (+3/-2)
tribes/barbarians/deep_coalmine/help.lua (+3/-2)
tribes/barbarians/deep_goldmine/help.lua (+8/-1)
tribes/barbarians/deeper_coalmine/help.lua (+3/-2)
tribes/barbarians/deeper_goldmine/help.lua (+8/-1)
tribes/barbarians/gamekeepers_hut/help.lua (+4/-2)
tribes/barbarians/goldmine/help.lua (+8/-1)
tribes/barbarians/granitemine/help.lua (+2/-2)
tribes/barbarians/headquarters/help.lua (+1/-1)
tribes/barbarians/headquarters_interim/help.lua (+1/-1)
tribes/barbarians/hunters_hut/help.lua (+10/-1)
tribes/barbarians/trainingcamp/help.lua (+2/-2)
tribes/barbarians/warmill/help.lua (+1/-1)
tribes/barbarians/well/help.lua (+8/-1)
tribes/empire/arena/help.lua (+1/-1)
tribes/empire/colosseum/help.lua (+1/-1)
tribes/empire/headquarters/help.lua (+1/-1)
tribes/empire/headquarters_shipwreck/help.lua (+1/-1)
tribes/empire/trainingcamp/help.lua (+2/-2)
tribes/scripting/format_help.lua (+84/-75)
txts/AUTHORS.lua (+11/-6)
txts/LICENSE.lua (+5/-22)
txts/README.lua (+81/-140)
txts/editor_readme.lua (+14/-33)
utils/test/test_lua-xgettext.py (+2/-2)
To merge this branch: bzr merge lp:~widelands-dev/widelands/fh1
Reviewer Review Type Date Requested Status
GunChleoc Needs Resubmitting
SirVer Needs Fixing
Review via email: mp+177228@code.launchpad.net

Description of the change

I implemented the functions from fh in fh1. I removed the old fonthandler and replaced all references.
I tested a bunch of ui elements, the readmes/developped/licenses, the caret position. Everything seems ok.

I'm not sure if this should be merged already, or if all ui elements should be rewritten around the new font renderer.

To post a comment you must log in.
Revision history for this message
SirVer (sirver) wrote :

This is a really good start. I think the deprecated methods should vanish. I think this should be done before merging.

Of course the old <rt> renderer should be killed as well and the new one used in all places instead. We should not need to deal with rich text in code anymore, all formatting should be done in the new renderer. For this the new one needs to learn to render raw text and caret's as well.

Also, the Font:: methods that are now used should somehow be incorporated into the new rich text renderer - I am not too sure how this can be done. Maybe by rendering a simple string and returning its size.

review: Needs Fixing
Revision history for this message
cghislai (charlyghislain) wrote :

Currently I use that method, rendering a test string to know the font height.

I'm coming to the multiline edit box, and I was thinking, should the wordwarpper be kept around? It is currently only used in the multiline textarea and the multiline edit box. For the multiline textarea, i think the wrapping done by the renderer will be sufficient. Now for editbox, in which caret must be rendered, that will be an issue. The multiline textarea is only used in one place in the map editor.

According to me, it would be nice to allow rendering of the caret further down in the new renderer and get rid of this wordwrap class. I was thinking of a caret tag, but it will interfere with surface caching. I'm just asking if you think it is a viable solution, and if you have some guess of where to implement that.

Revision history for this message
SirVer (sirver) wrote :

> Currently I use that method, rendering a test string to know the font height.

As mentioned, I think with the caching this approach is fine.

> I'm coming to the multiline edit box, and I was thinking, should the
> wordwarpper be kept around?
No, I think it should definitively be killed. The one in the richtext render should be strictly superior to what we have in wordwrap.

> It is currently only used in the multiline
> textarea and the multiline edit box. For the multiline textarea, i think the
> wrapping done by the renderer will be sufficient. Now for editbox, in which
> caret must be rendered, that will be an issue. The multiline textarea is only
> used in one place in the map editor.

This is the hardest thing to change imho. I am not really sure how to proceed either - I was thinking about a <caret> tag too. It might not be a problem - a human types at most 4-5 chars per second, we should be able to rerender the text this often. And the cache will just overflow with useless cached images, but eventually clear out. So I'd try this approach first.

> According to me, it would be nice to allow rendering of the caret further down
> in the new renderer and get rid of this wordwrap class. I was thinking of a
> caret tag, but it will interfere with surface caching. I'm just asking if you
> think it is a viable solution, and if you have some guess of where to
> implement that.

Okay, so I think I commented on this before reading this paragraph. As mentioned, I find this a difficult design decision and I am not sure if the tag is viable, but I have no clear path forward that is not using a tag, so I suggest trying that.

Again, thanks for working on this Charly!

Revision history for this message
cghislai (charlyghislain) wrote :

I tried a caret tag renderer. It works fine except it seems there is a 1-pixel space inserted between two text nodes, even if the caret has zero-size. So I'm not quite sure it is the best option.
I still have other options to try, like removing the tag and continuing parsing the text while remembering somehow position of the caret, but it feels dirty.

Also, as I was trying to port the multiline editbox, I realized that if we want to support the direction keys, home end & co, we should definitely add some way to get information about the wrapping. I was thinking of a pointer to a wrapinginfo object that could be passed all the way down to the layouting node, which would fill it with data. We could put coords of every text node in there, including the caret placeholder, so that rendering can be done on top afterwards. Its still just an idea, if you have another one please share!

Revision history for this message
SirVer (sirver) wrote :

I do not care about the 1 pixel thingy. But you are right, cursor movements should not be handled by the text renderer. So the solution might really be to pass the layout boxes up again - then the <cursor> node might not be needed. I kinda like this solution, though I also feel that the separation of concerns is no longer true then - but so what?

Revision history for this message
cghislai (charlyghislain) wrote :

After a few tries, I finally found a way to get the layout info in a not-so-dirty way.
So all basic widgets are ported now, with some fixes still needed: non-rendered whitespace makes the caret behaviour quite strange, and except of cropping when text doesnt fit width, a line break should be introduced.

I will then start to start cleaning everything. So now comes the question - should I use the font specified in the game option everywhere? I think it makes sense. Especially since, as for now, all widgets use the same font in all places - no special font in ui_fsmenu is used anymore.

Revision history for this message
Nasenbaer (nasenbaer) wrote :

> should I use the font specified in the game option everywhere? I think it makes sense. Especially since, as for now, all widgets use the same font in all places - no special font in ui_fsmenu is used anymore.

That would be a good thing, yes. I would However keep special font where explicitly defined (e.g. Widelands.ttf used for "Widelands")

Maybe it would be good to add a <rt text-style=sans / serif> in the long term and make sans and serif selectable? - than we could get rid of almost all explicite font definitions (but maybe Widelands.ttf) as the font renderer would set the appropriate font connected to sans resp. serif - but well I am getting off topic sorry - this should go to a bug report / wishlist item

Revision history for this message
cghislai (charlyghislain) wrote :

> Maybe it would be good to add a <rt text-style=sans / serif> in the long term and make sans and serif selectable?
Yes, why not. However, as I understood from reading some bug reports, custom font support were implemented so that users using exotic locales could find a font that render text correctly. It might not be easy to switch serif/sans in those cases, except if we allow custom serif and custom sans font.

I see TTF handle bold/italic styles, so I wonder why it is handled in the code by using different fonts. This is not going to work if using the custom fonts. The bold faces processed by SDL_TTF do not look that bad imo.

If no objection, I am going to store the font filename in all case in the options, keeping the UI_FONT_NAME constant only to get the default value, and let TTF handle all the styles. The derived fonts in /fonts will be removed.

Revision history for this message
Nasenbaer (nasenbaer) wrote :

Seems that this is a matter of taste - I completely (like 100%) agree with you, however as far as I remember, SirVer does not (e.g. take a look at #1 of https://bugs.launchpad.net/widelands/+bug/1184185 )

For me it seems much better to have a simple option, and everything is working based upon that setting but working way than to to

concerning:
> However, as I understood from reading some bug reports, custom font support were implemented so that users using exotic locales could find a font that render text correctly. It might not be easy to switch serif/sans in those cases, except if we allow custom serif and custom sans font.

I see no problem here - if I write a text and decide to make it "more beautiful" by using a mixture of sans and serif, this decission is of course based upon Latin characters. So if e.g. someone reading the translated text in arabic and sets both styles - serif and sans - to the same TTF font, there is no problem with it (to be more specific: it isn't even a problem if someone is doing this in the untranslated version). Of course this sounds like "more clutter options", but we can still add it to the advanced options menu, as the font selection is at the moment + (and that's the major PLUS for me) We would be simply able to use serif and sans styles without having to worry about which ttf will actually be used. -> and after all that system will be much easier to maintain if for some reason the default font will be changed or removed at some point.

Revision history for this message
Nasenbaer (nasenbaer) wrote :

> For me it seems much better to have a simple option, and everything is working based upon that setting but working way than to to

seems I stopped there in the middle of a thought, but I guess everything below explains my further thoughts pretty much ;) - it's just that the whole system gets better maintainable when we use the italic/bold/underline functions of SDL_TTF and therefore don't have to take care about the fonts - e.g. one problem is that none of the ttfs is complete in matter of the available glyphs, but even worth the "completenes" differes between the different styles - "normal" is most complete, "italic" less, etc...

Revision history for this message
SirVer (sirver) wrote :

I am very pressed on time and have not read through all the comments yet. I have some strong opinions on some of those though, and I will comment as soon as I find 30 minutes to read through all of it. Just FYI :).

Revision history for this message
SirVer (sirver) wrote :

> I see TTF handle bold/italic styles, so I wonder why it is handled in the code by using different fonts. This is not going to work if using the custom fonts. The bold faces processed by SDL_TTF do not look that bad imo.

What SDL_TTF is when rendering bold is to render the same text twice with an offset of a pixel - this looks good often enough, but not always. With some fonts it gets completely unreadable. The same for italic: it renders each character at an angle. It is a fragile system that we do not control. When you use bold/italic in your text processor, it will only work if there is a bold/italic ttf installed on your system - and imho that is a good thing. Reverting back to SDL_TTF rendering is a step backwards imho.

Frankly, letting the user choose a font is not a good idea. First: we have no control what characters are supported in the fonts the user chooses which sets us up for incompatibilities which we cannot fix ourselves. Second: Widelands does not deal well with different font sizes in different places, this can be fixed, but it is much easier if we commit ourselves to a fixed number of fonts that we will support and ship with Widelands.

This leads me to the following suggestion: Why not link language codes to fonts and ship them with Widelands? We then have complete control over how Widelands looks and renders, which chars it supports and we can get rid of this option. I could see that we then also change the <font> tag to only allow style changes as you are suggesting and not change the font that is used for rendering.

Just to manage expectations: I am in vacations for the next two weeks. I might have access to email, but I will not check them regularly, so you will not hear from me much till beginning of September.

Revision history for this message
SirVer (sirver) wrote :

Btw, i also looked at richtext_test branch and I think it should be merged. You made it more general than I ever did, even if it does not completely work for you, it is better than what was there before. We can fix the tests when we want to add new features to the renderer.

Revision history for this message
cghislai (charlyghislain) wrote :

I agree with the solution of linking fonts to locales. Things will be simplier. We could therefore remove the face attribute of the font tag, and indeed introduce new ones such as condensed, sherif and so on.

Apart for that point, the c++ code is almost completely using the new renderer correctly now. The biggest piece of work remaining is for all the extra texts, still using the old tag syntax - even when it's through the lua wrapper. It is a lot of work to rewrite all texts.
I think we could start by improving the lua interface to make it more abstract. Currently, several attributes are passed in, and they are not allowed by the new syntax.

I think the rewrite of the README should wait for this to happen.

Revision history for this message
SirVer (sirver) wrote :

sounds good. do you think we should rush this before b18 or wait till after b18? It seems like rushing is dangerous but could be beneficial. Your call anyways - I think I will not be able to help a lot.

About rewriting the texts: All scenario texts should not need a rewrite, they do not use the rich text syntax explicitly. Only the ingame texts need rewrites, that is not too much to do imho.

Revision history for this message
cghislai (charlyghislain) wrote :

No rush - I won"t have much time neither before release. And while not using the rich text syntax explicitly, i have the feeling the scenario texts will need to be reworked as well because the lua formatting interface does not abstract completely the old renderer.

Revision history for this message
Nasenbaer (nasenbaer) wrote :

Just a comment, an important though:

This branch is linked to be the fix for two high rated bugs, which should definitely be fixed for build18. Therefore I guess a soon merge (if nothing speaks against it) would be a good idea. If you decide to not merge before build18 feature freeze, we should still try to adapt the fixes for said bugs to current trunk, so the bugs can be fixed there as well.

Revision history for this message
cghislai (charlyghislain) wrote :

This is what i get after merging trunk.
I made a test ui you can launch with ./widelands --testui

There are still some layout issues I need to fix.

Revision history for this message
cghislai (charlyghislain) wrote :

Concerning the widgets, there are 2 minor issues left : Consecutive line breaks and RTL auto-wrapping.
Other than that, all use new font renderer and (multiline) editboxes work great.
Sirver, I will try to check the changes in your branch.

Revision history for this message
SirVer (sirver) wrote :

That's a lot of code. I need to make a chunk of time to review this.

My branch is about removing the legacy richtext renderer and using the new one everywhere (i.e. especially in scenario texts).

Revision history for this message
cghislai (charlyghislain) wrote :

I will try to tidy the patch.

As we should first converge the API in graphics/ and text_layout.h, maybe you should have a look there in the first place. From what I see, your text_layout looks more appealing. I think we should merge yours into this one and update text_layout and text_area.

This patch is big, but changes to all ui elements was required. I would also like to unify all signals/getters/setters of basic elements

There are still some important changes that needs to be done here, with respect to the previous comments. That is linking font to locale, (re)introducing bold/italic and serif/condensed styles attributes and removing face attribute.

My branch is about removing the legacy richtext renderer and using the new one everywhere (especially in editboxes), so we should find some common grounds :). In particular, I introduced LayoutInfo to expose text nodes position and updated the rt_renderer to allow keeping extra spaces.

Revision history for this message
SirVer (sirver) wrote :

The aim should be to get this (and my branch) merged into trunk ASAP and then branch again to tackle the remaining issues. Smaller branches are much easier to work with anyways.

I try to look into this in more detail on the weekend.

Revision history for this message
cghislai (charlyghislain) wrote :

I merged your branch and updated textarea, editbox and multilineeditbox, with various fixes.

Revision history for this message
SirVer (sirver) wrote :

I started looking into this now - the testui crashes on game close. and there are a lot of fixmes in the code that I do not understand and that could use a comment. I converted them into NOCOM. I also merged trunk.

I will be on vacation starting tuesday in a week for ~3 weeks. Just fyi :)

Revision history for this message
cghislai (charlyghislain) wrote :

Sirver, can you take a look at text_layout.h? I defined it as a read-only interface, along with an implementation that allows adding nodes info. I am not sure how/where to define that implementation. It is only used in the fonthandler(which downcast and reset it) and rt_render.

Also, I removed custom font attributes, and linked font and horizontal align to the locale used. I also set an option to scale fonts to screen resolution.

- Is that font scale option needed? All text areas will have to specify their height in order to get correctly aligned if fonts are not scaled at higher resolution
- Concerning MultilineTextarea, in your branch you expected richtext, while here simple text is allowed and formatted as_ui_font, is that ok?

Happy vacation :)

Revision history for this message
GunChleoc (gunchleoc) wrote :

RTL support is coming :)

This means a new dependency though, which is the ICU library. It comes with all kinds of i18n bells and whistles that I will play some more with for Build 20. For now, it would be good if our packaging wizards could double-check that the new library will work for everybody.

I will be gone from my development machine again, so if anybody else would like to play with this branch, be my guest. I especially need help with the text input boxes (editbox, multilineeditbox), which don't work at all at the moment.

Also, text flowing around images is broken (c.f. Campaign dialogs), and for some elements either the text height is reported wrongly or the valign is off - I don't know which yet (You can see this in the full screen menus, e.g. Load Game).

I'm setting this to "resubmit" only to greedily grab everyone's attention. This isn't ready for review by a long shot ;)

review: Needs Resubmitting
Revision history for this message
Tino (tino79) wrote :

It does compile and work on win32, small fix only needed atm for a release build:
format.cc, function get_halign() does only contain an assert, a return statement is missing.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks, I will look into this when I get back home :)

Revision history for this message
kaputtnik (franku) wrote :

Seems to me that this branch is some kind incompatible with trunk... i get 186 conflicts when i try to merge trunk.

So what is the state here? Should we unlink the bugs?

I have removed the links to "fix commited" bugs.

Revision history for this message
GunChleoc (gunchleoc) wrote :

To keep merging this branch is very high maintenance, and at this point only I know the code well enough to do it without jumping off a bridge ;)

Let's retarget the bugs.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-01-31 14:24:59 +0000
3+++ CMakeLists.txt 2015-08-01 06:21:02 +0000
4@@ -50,6 +50,7 @@
5 find_package(SDL2_net REQUIRED)
6 find_package(SDL2_ttf REQUIRED)
7 find_package(ZLIB REQUIRED)
8+find_package(ICU REQUIRED)
9 if(OPTION_USE_GLBINDING)
10 find_package(glbinding REQUIRED)
11 else()
12
13=== modified file 'campaigns/atl01.wmf/scripting/init.lua'
14--- campaigns/atl01.wmf/scripting/init.lua 2014-10-03 08:58:44 +0000
15+++ campaigns/atl01.wmf/scripting/init.lua 2015-08-01 06:21:02 +0000
16@@ -69,9 +69,9 @@
17
18 function send_building_lost_message(f)
19 send_message(p1, _"Building lost!",
20- rt("image=".. f.immovable.descr.representative_image,
21- p(_"We lost a building to the ocean!")
22- ), { field = f, popup = false }
23+ rt(p(img(f.immovable.descr.representative_image) ..
24+ _"We lost a building to the ocean!")),
25+ { field = f, popup = false }
26 )
27 end
28
29
30=== modified file 'campaigns/atl01.wmf/scripting/texts.lua'
31--- campaigns/atl01.wmf/scripting/texts.lua 2015-07-26 10:45:53 +0000
32+++ campaigns/atl01.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
33@@ -32,11 +32,11 @@
34 title = _"Ensure the supply of building wares",
35 number = 6,
36 body = objective_text(_"Supply Building Wares", _
37-[[Supply basic building material for your economy:]] .. paragraphdivider() ..
38- listitem_bullet(_[[Build a quarry]]) ..
39- listitem_bullet(_[[Build two woodcutter’s houses]]) ..
40- listitem_bullet(_[[Build two forester’s houses]]) ..
41- listitem_bullet(_[[Build a sawmill]])
42+[[Supply basic building material for your economy:]] ..
43+ li(_[[Build a quarry]]) ..
44+ li(_[[Build two woodcutter’s houses]]) ..
45+ li(_[[Build two forester’s houses]]) ..
46+ li(_[[Build a sawmill]])
47 ),
48 }
49
50@@ -45,8 +45,8 @@
51 title = _"Expand your territory and explore",
52 number = 1,
53 body = objective_text(_"Expand and Explore",
54- _([[The island is huge and as long as we are not sure that we are alone here, we cannot relax. Explore and conquer it, this is the only way to protect us from threats on the island and from Atlantis.]]) .. paragraphdivider() ..
55- listitem_bullet(_[[Build military sites to expand your territory]])
56+ _([[The island is huge and as long as we are not sure that we are alone here, we cannot relax. Explore and conquer it, this is the only way to protect us from threats on the island and from Atlantis.]]) ..
57+ li(_[[Build military sites to expand your territory]])
58 ),
59 }
60
61@@ -55,16 +55,16 @@
62 title = _"Establish a solid food production",
63 number = 10,
64 body = objective_text(_"Food Production",
65- _[[Food is very important for mines and military training areas. Establish a well working food environment by building at least one farm, one blackroot farm and a mill. The two kinds of flour together with water from a well will be baked into bread in a bakery, so build a bakery and a well, too.]] .. paragraphdivider() ..
66- _[[The other two important food wares are smoked fish and smoked meat. Raw meat is delivered from a hunter. A fisher gets the fish out of the sea while a fish breeder makes sure that a school of fish does not go extinct by breeding more. Make sure that there are always fish left, otherwise the fish breeder won’t be able to breed new ones. The smoking happens in a smokery, you will need at least two of those.]] .. paragraphdivider() ..
67- listitem_bullet(_[[Build a farm and a blackroot farm]]) ..
68- listitem_bullet(_[[Build a mill to make cornflour and blackroot flour]]) ..
69- listitem_bullet(_[[Build a well]]) ..
70- listitem_bullet(_[[Build a bakery to bake bread from cornflour, blackroot flour and water]]) ..
71- listitem_bullet(_[[Build a hunter’s house to get raw meat]]) ..
72- listitem_bullet(_[[Build a fisher’s house close to water to get raw fish]]) ..
73- listitem_bullet(_[[Build a fish breeder’s house close to the fisher to make sure the fish do not die out]]) ..
74- listitem_bullet(_[[Build two smokeries to smoke raw meat and fish]])
75+ _[[Food is very important for mines and military training areas. Establish a well working food environment by building at least one farm, one blackroot farm and a mill. The two kinds of flour together with water from a well will be baked into bread in a bakery, so build a bakery and a well, too.]] ..
76+ p(_[[The other two important food wares are smoked fish and smoked meat. Raw meat is delivered from a hunter. A fisher gets the fish out of the sea while a fish breeder makes sure that a school of fish does not go extinct by breeding more. Make sure that there are always fish left, otherwise the fish breeder won’t be able to breed new ones. The smoking happens in a smokery, you will need at least two of those.]]) ..
77+ li(_[[Build a farm and a blackroot farm]]) ..
78+ li(_[[Build a mill to make cornflour and blackroot flour]]) ..
79+ li(_[[Build a well]]) ..
80+ li(_[[Build a bakery to bake bread from cornflour, blackroot flour and water]]) ..
81+ li(_[[Build a hunter’s house to get raw meat]]) ..
82+ li(_[[Build a fisher’s house close to water to get raw fish]]) ..
83+ li(_[[Build a fish breeder’s house close to the fisher to make sure the fish do not die out]]) ..
84+ li(_[[Build two smokeries to smoke raw meat and fish]])
85 )
86 }
87
88@@ -73,10 +73,10 @@
89 title = _"Build a spider farm and a weaving mill",
90 number = 3,
91 body = objective_text(_"Spidercloth Production",
92- _[[The weavers produce spidercloth and tabards in the weaving mill. Spidercloth is needed for the construction of some buildings and clothing, while tabards are the uniforms of soldiers. The weaving mill needs gold yarn and spideryarn as raw material. Spideryarn is produced by the spider farm, while gold yarn is produced by the gold spinning mill out of gold.]] .. paragraphdivider() ..
93- listitem_bullet(_[[Build a weaving mill]]) ..
94- listitem_bullet(_[[Build a spider farm]]) ..
95- listitem_bullet(_[[Build a gold spinning mill]])
96+ _[[The weavers produce spidercloth and tabards in the weaving mill. Spidercloth is needed for the construction of some buildings and clothing, while tabards are the uniforms of soldiers. The weaving mill needs gold yarn and spideryarn as raw material. Spideryarn is produced by the spider farm, while gold yarn is produced by the gold spinning mill out of gold.]] ..
97+ li(_[[Build a weaving mill]]) ..
98+ li(_[[Build a spider farm]]) ..
99+ li(_[[Build a gold spinning mill]])
100 )
101 }
102
103@@ -85,12 +85,12 @@
104 title = _"Build industry and mines",
105 number = 5,
106 body = objective_text(_"Industry and Mines",
107- _[[Iron ore, gold ore and coal are mined in the respective mines. The crystal mine will dig for quartz and diamonds – all of them are precious materials and very rarely found. It will produce a lot of stone while searching for them.]] .. paragraphdivider() ..
108- listitem_bullet(_[[The ores have to be smelted at a smelting works before they can be used. The refined materials are then used in the weapon smithy, the armor smithy and the toolsmithy.]]) .. paragraphdivider() ..
109- listitem_bullet(_[[Build a mine of each type. Make sure to send geologists to the mountain first.]]) ..
110- listitem_bullet(_[[Build a smelting works]]) ..
111- listitem_bullet(_[[Build an armor smithy and a weapon smithy]]) ..
112- listitem_bullet(_[[Build a toolsmithy]])
113+ _[[Iron ore, gold ore and coal are mined in the respective mines. The crystal mine will dig for quartz and diamonds – all of them are precious materials and very rarely found. It will produce a lot of stone while searching for them.]] ..
114+ li(_[[The ores have to be smelted at a smelting works before they can be used. The refined materials are then used in the weapon smithy, the armor smithy and the toolsmithy.]]) ..
115+ li(_[[Build a mine of each type. Make sure to send geologists to the mountain first.]]) ..
116+ li(_[[Build a smelting works]]) ..
117+ li(_[[Build an armor smithy and a weapon smithy]]) ..
118+ li(_[[Build a toolsmithy]])
119 )
120 }
121
122@@ -99,8 +99,8 @@
123 title = _"Build training sites for soldiers",
124 number = 2,
125 body = objective_text(_"Soldier Training Sites",
126- _[[Like all other tribes, the Atlanteans are also able to train soldiers: the dungeon trains attack – the major attribute of the Atlanteans – and the labyrinth trains evasion, health and defense. The items produced by the industry are used to train better soldiers in the two training sites.]] .. paragraphdivider() ..
127- listitem_bullet(_[[Build a dungeon and a labyrinth]])
128+ _[[Like all other tribes, the Atlanteans are also able to train soldiers: the dungeon trains attack – the major attribute of the Atlanteans – and the labyrinth trains evasion, health and defense. The items produced by the industry are used to train better soldiers in the two training sites.]] ..
129+ li(_[[Build a dungeon and a labyrinth]])
130 )
131 }
132
133@@ -109,9 +109,9 @@
134 title = _"Build a warehouse and a horse farm",
135 number = 2,
136 body = objective_text(_"Warehouse and Horse Farm",
137- _[[As your road network gets longer and more complicated, you should employ horses to help out your carriers. Horses are bred at horse farms using water and corn. A warehouse will also help to ensure that your transportation system does not collapse.]] .. paragraphdivider() ..
138- listitem_bullet(_[[Build a warehouse]]) ..
139- listitem_bullet(_[[Build a horse farm]])
140+ _[[As your road network gets longer and more complicated, you should employ horses to help out your carriers. Horses are bred at horse farms using water and corn. A warehouse will also help to ensure that your transportation system does not collapse.]] ..
141+ li(_[[Build a warehouse]]) ..
142+ li(_[[Build a horse farm]])
143 )
144 }
145
146@@ -120,8 +120,8 @@
147 title = _"Build 3 ships to escape from the island",
148 number = 1,
149 body = objective_text(_"Escape From the Island",
150- _[[There is a lake at the top of the island. Build three ships in these waters and you might be able to rescue your people before the island is swallowed completely by the ocean.]] .. paragraphdivider() ..
151- listitem_bullet(_[[Build a shipyard close to the lake to start building ships]])
152+ _[[There is a lake at the top of the island. Build three ships in these waters and you might be able to rescue your people before the island is swallowed completely by the ocean.]] ..
153+ li(_[[Build a shipyard close to the lake to start building ships]])
154 )
155 }
156
157@@ -133,29 +133,26 @@
158 initial_messages = {
159 {
160 title = _"Proud to the Death",
161- body = rt(
162+ body =
163 h1(_"Favored by the God") ..
164 p(_([[On the hidden and lost island of Atlantis, a proud tribe settled since the world was very young. Ruled by the bloodline of King Ajanthul – the first human to be empowered by the sea god Lutas to breathe above sea level – and the wise clerics, who provided the link to Lutas – they prospered and became civilized.]])) ..
165 p(_([[This story is taking place during the reign of King Askandor, the 43rd successor of King Ajanthul. He had been a good king, ruling Atlantis with wisdom and foresight. But with age, he became afraid of dying and so he began looking for a cure for death even though most clerics warned him against it. Some said that endless life was only for the gods and that to seek for it was forbidden.]]))
166- )
167 },
168 {
169 title = _"Disgraced Before the God",
170- body = rt(
171+ body =
172 h1(_"The God’s Punishment") ..
173 p(_([[But all seemed well. Only the horses seemed to feel something was wrong. During the nights, they went crazy and were full of fear. It was not long before the horse breeder Xydra figured out what was wrong with them: the sea level in front of their stable was rising with ever increasing speed.]])) ..
174 p(_([[The clerics retreated into meditation and the reason for the rising water was soon to be found: the god Lutas had lost faith in the Atlanteans because of the boldness of their king. He decided to withdraw the rights that were granted to King Ajanthul and his children. And so, he called them back below the sea again.]]))
175- )
176 },
177 {
178 title = _"Uproar and Confusion",
179- body = rt(
180+ body =
181 h1(_"Emerging Chaos...") ..
182 p(_([[Guilt-ridden, the king committed suicide. Without a monarch, the people turned to the clerics, but they had no substantial help to offer. Most accepted their fate while others tried to change the god’s mind by offering animals in his temple. But to no avail...]])) ..
183 p(_([[Jundlina, the late king’s daughter and the highest priestess of the god was the most determined cleric. As countless offerings didn’t change the situation, she convinced herself that to soothe the god, an offer of great personal value was needed. So she offered him her most beloved: her husband, the father of her only child.]])) ..
184 p(_([[But not even this changed the mind of the god. The water kept on rising. Nearly driven insane by guilt, pain and anger, Jundlina became a heretic: Secretly, she gathered people of the common folk who were not in line with the decision of the clerics to accept the god’s will. Together with them, she set the temple on fire and stole a ship to flee from the god’s influence over Atlantis. This small group started praying to Satul, the fire god and the worst enemy of Lutas.]])) ..
185 p(_([[Leaving the dying Atlantis and their past behind, they started on a quest to find a place sheltered by the fire and protected from the sea.]]))
186- )
187 },
188 } -- end of initial messages.
189
190@@ -164,9 +161,9 @@
191 title = _"The Princess’ Memoir",
192 body = jundlina(_"Jundlina Writes Down Her Memories",
193 _([[We left Atlantis and sailed east. We entered the forbidden sea on the sixth day without noticing any pursuers from Atlantis and without Lutas having smashed our ship. Now, we are out of his reach. One day later, we sighted an island which seems to have one of these fire spitting mountains on it. I deemed this a sign from the fire god and we landed on its shore.]])
194- .. paragraphdivider() ..
195+ .. close_p() .. open_p() ..
196 _([[We spent the last week building two watchtowers on the mountains close to our landing area; and, of course, a hall for us all. We have very talented constructors in our group – still, the buildings do not match the art we had on Atlantis. I hope they will withstand the next rain. At least, the towers will warn us if a ship from Atlantis follows us and if the island is inhabited, we will see attackers a long time before they arrive.]])
197- .. paragraphdivider() ..
198+ .. close_p() .. open_p() ..
199 _([[We have established ourselves on this island. The next step is now to make it a home. I reckon we need to establish a sustainable economy and to explore our surroundings. I called for specialists and will follow their advice.]]))
200 },
201 {
202@@ -208,9 +205,9 @@
203 title = _"Colionder is in Thought",
204 body = colionder(
205 _([[Ahh, but I think this is impossible to change. The preparing and eating of food is something deeply ingrained in us Atlanteans – it is a ceremony that we just need for our well-being. So I guess we cannot take this away from the individuals completely.]])
206- .. paragraphdivider() ..
207+ .. close_p() .. open_p() ..
208 _([[But we might find a compromise in between: for me, making bread is a troublesome task. Grinding the blackroot and corn to flour and then baking the bread is tedious and boring; I feel a more industrial approach would be helpful here. I for one would love to just have fresh bread delivered to my house every day.]])
209- .. paragraphdivider() ..
210+ .. close_p() .. open_p() ..
211 _([[Oooh and even more important: the smoking of fish and meat to cleanse them and improve their taste is terrible. My house is full of smoke and stinks for weeks afterwards. Don’t you think that this could be done in a special building where the side effects do not matter? I think those two things would be accepted by the people and would reduce the cooking time without taking away the ritual.]]))
212 },
213 {
214@@ -234,7 +231,7 @@
215 title = _"A Man Comes to Jundlina",
216 body = opol(
217 _([[May Satul warm you, Jundlina. My name is Opol, and I am the highest weaver of the guild abandoning Atlantis and Lutas with you. I come with sad news indeed: we have no more spidercloth. Not a single piece is to be found in our warehouses. Could you not help the weavers’ guild by arranging the building of a weaving mill and a spider farm? The spiders deliver the finest silk and we will produce the finest spidercloth from it.]])
218- .. paragraphdivider() ..
219+ .. close_p() .. open_p() ..
220 _([[We offer to also produce the tabards for young soldiers and the golden tabards for officers for you in exchange. You will need them for sure as soon as you want to recruit new soldiers.]]))
221 },
222 {
223@@ -305,7 +302,7 @@
224 title = _"Jundlina Considers the Economy",
225 body = jundlina(_"Jundlina",
226 _([[People are complaining about crowded streets and slow transportation. We need to help out our carriers on the roads. I have decided to build a horse farm so that the horses can help with the heavy wares.]])
227- .. paragraphdivider() ..
228+ .. close_p() .. open_p() ..
229 _([[Another way to take load from our roads is to build warehouses. We have claimed the mountain now, it seems a good idea to have a warehouse on the plateau to avoid having to transport everything up and down the slopes.]]))
230 .. new_objectives(obj_horsefarm_and_warehouse)
231 }
232@@ -321,9 +318,9 @@
233 title = _"A Dangerous Discovery",
234 body = jundlina(_"Jundlina is in Thought",
235 _([[We found an old building, destroyed and burned by flames. I am very worried about this discovery. The building is not of any kind I’ve ever seen. It is certainly not designed by any Atlantean architect I’ve ever heard about. The building is crude, the assemblage is sloppy. But the materials are very enduring: the wood used for it seemed to have been burned in a strange way before it was used as building material – it is hard as stone.]])
236- .. paragraphdivider() ..
237+ .. close_p() .. open_p() ..
238 _([[The implications frighten me. Are there others on this island? Where are they then? They work with fire, are they praying to Satul too? Are they friends or foe? And why is the building burned down? Has this island seen war? Is a war being waged on it right now?]])
239- .. paragraphdivider() ..
240+ .. close_p() .. open_p() ..
241 _([[We must improve our military capabilities. If there are foes on the island, we have to be prepared when we meet them. We should also enforce the fortification of our borders.]]))
242 }
243 }
244@@ -386,7 +383,7 @@
245 title = _"Jundlina Replies",
246 body = jundlina(_"Jundlina",
247 _([[Your red hair is a signal from the fire god. I will trust you and support your plan. Our survival lies in your hands now, Ostur.]])
248- .. paragraphdivider() ..
249+ .. close_p() .. open_p() ..
250 _([[Swift now, we need a house for Ostur next to the lake, and we need planks, logs and spidercloth for the construction there. Forget about everything else, we need those wares on top of the mountain before our warehouses are all swallowed by the sea.]]))
251 .. new_objectives(obj_build_ships)
252 }
253@@ -397,9 +394,9 @@
254 title = _"Jundlina is Relieved",
255 body = jundlina(_"Jundlina",
256 _([[Praise Satul! Ostur, the young ship builder did it. We have three ships – never have I seen sturdier ones – with enough room to carry all of us and some wares too. And this rescue came just in time: Lutas is about to swallow the rest of this island, the water rises faster by the hour. But we can make our escape now and start over in some country farther away...]])
257- .. paragraphdivider() ..
258+ .. close_p() .. open_p() ..
259 _([[I expect a long journey, but we will find the land of Satul in the end. This is what I promised my people. And myself.]]))
260- .. rt("<p font-size=10> <br></p>" .. h1(_ "Congratulations") ..
261- p(_[[You have won this mission. Continue with the next one or keep playing for as long as you like.]]))
262+ .. objective_text(_ "Congratulations",
263+ _[[You have won this mission. Continue with the next one or keep playing for as long as you like.]])
264 }
265 }
266
267=== modified file 'campaigns/bar01.wmf/scripting/texts.lua'
268--- campaigns/bar01.wmf/scripting/texts.lua 2015-07-26 11:05:38 +0000
269+++ campaigns/bar01.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
270@@ -23,9 +23,8 @@
271 title = _"Build two ranger’s huts",
272 number = 1,
273 body = objective_text(_"Build two ranger’s huts",
274- listitem_bullet(_"Build a ranger’s hut next to each lumberjack’s hut.") ..
275- listitem_arrow(_"Naturally, trees only grow at a slow rate. To make sure you have enough logs, you have to build rangers.")
276- )
277+ li(_"Build a ranger’s hut next to each lumberjack’s hut.") ..
278+ li_arrow(_"Naturally, trees only grow at a slow rate. To make sure you have enough logs, you have to build rangers."))
279 }
280
281 obj_claim_northeastern_rocks = {
282@@ -33,8 +32,8 @@
283 title = _"Expand north-east and build a quarry",
284 number = 1,
285 body = objective_text(_"Expand north-east to the rocks",
286- listitem_bullet(_"Build military buildings (like sentries or barriers) to expand your territory.") ..
287- listitem_bullet(_"Get to the rocks north-east from you and build a quarry there."))
288+ li(_"Build military buildings (like sentries or barriers) to expand your territory.") ..
289+ li(_"Get to the rocks north-east from you and build a quarry there."))
290 }
291
292 obj_build_mines = {
293@@ -42,21 +41,19 @@
294 title = _"Start building mines on the mountain",
295 number = 2,
296 body = objective_text(_"Build coal and iron ore mines",
297- listitem_bullet(_"Build a coal mine and an iron ore mine.") ..
298- listitem_arrow(_"To do so, place a flag up on the mountain’s flank to the east (on mountain terrain though, not mountain meadow). When you click on the new flag, you can send geologists there. Because the flag is on a mountain, the geologists will search for ores; otherwise, they would search for water. Then build a mine for both kinds of resources that he will find, choosing the appropriate mine to be built:") ..
299- "</rt>" ..
300- rt("image=tribes/barbarians/resi_coal1/resi_00.png", p(_"a bit of coal")) ..
301- rt("image=tribes/barbarians/resi_coal2/resi_00.png", p(_"a lot of coal")) ..
302- rt("image=tribes/barbarians/resi_iron1/resi_00.png", p(_"a bit of iron")) ..
303- rt("image=tribes/barbarians/resi_iron2/resi_00.png", p(_"a lot of iron")) ..
304- rt("image=tribes/barbarians/resi_gold1/resi_00.png", p(_"a bit of gold")) ..
305- rt("image=tribes/barbarians/resi_gold2/resi_00.png", p(_"a lot of gold")) ..
306- rt("image=tribes/barbarians/resi_granite1/resi_00.png", p(_"a bit of granite")) ..
307- rt("image=tribes/barbarians/resi_granite2/resi_00.png", p(_"a lot of granite")) ..
308- rt("image=tribes/barbarians/resi_water1/resi_00.png", p(_"water")) ..
309- rt("image=tribes/barbarians/resi_none/resi_00.png", p(_"nothing was found here")) ..
310- "<rt>" ..
311- p(_[[Mines can only be built on mountain terrain. Suitable places for mines are displayed as orange mine symbols.]]))
312+ li(_"Build a coal mine and an iron ore mine.") ..
313+ li_arrow(_"To do so, place a flag up on the mountain’s flank to the east (on mountain terrain though, not mountain meadow). When you click on the new flag, you can send geologists there. Because the flag is on a mountain, the geologists will search for ores; otherwise, they would search for water. Then build a mine for both kinds of resources that he will find, choosing the appropriate mine to be built:") ..
314+ p(img("tribes/barbarians/resi_coal1/resi_00.png") .. _"a bit of coal") ..
315+ p(img("tribes/barbarians/resi_coal2/resi_00.png") .. _"a lot of coal") ..
316+ p(img("tribes/barbarians/resi_iron1/resi_00.png") .. _"a bit of iron") ..
317+ p(img("tribes/barbarians/resi_iron2/resi_00.png") .. _"a lot of iron") ..
318+ p(img("tribes/barbarians/resi_gold1/resi_00.png") .. _"a bit of gold") ..
319+ p(img("tribes/barbarians/resi_gold2/resi_00.png") .. _"a lot of gold") ..
320+ p(img("tribes/barbarians/resi_granite1/resi_00.png") .. _"a bit of granite") ..
321+ p(img("tribes/barbarians/resi_granite2/resi_00.png") .. _"a lot of granite") ..
322+ p(img("tribes/barbarians/resi_water1/resi_00.png") .. _"water") ..
323+ p(img("tribes/barbarians/resi_none/resi_00.png") .. _"nothing was found here") ..
324+ p(_[[Mines can only be built on mountain terrain. Suitable places for mines are displayed as orange mine symbols.]]))
325 }
326
327 obj_basic_food = {
328@@ -64,9 +61,9 @@
329 title = _"Provide your miners with food",
330 number = 3,
331 body = objective_text(_"Build a hunter, a gamekeeper and a tavern",
332- listitem_bullet(_"In order to work, your miners need food.") ..
333- listitem_arrow(_"A hunter can hunt down animals, while a gamekeeper prevents them from becoming extinct. The meat is then processed in a tavern into lunches for your miners.") .. " " ..
334- _([[This is only the first example of a ware which has to be refined before being used in a secondary building – others will follow.]]))
335+ li(_"In order to work, your miners need food.") ..
336+ li_arrow(_"A hunter can hunt down animals, while a gamekeeper prevents them from becoming extinct. The meat is then processed in a tavern into lunches for your miners.") ..
337+ p(_([[This is only the first example of a ware which has to be refined before being used in a secondary building – others will follow.]])))
338 }
339
340 obj_begin_farming = {
341@@ -90,11 +87,11 @@
342 title = _"Enhance buildings and build a micro brewery",
343 number = 3,
344 body = objective_text(_[[Enhance a mine and the tavern, and build a micro brewery.]],
345- listitem_bullet(_"Enhance the coal mine or the iron mine to a deep mine, and enhance the tavern to an inn.") ..
346- listitem_bullet(_"Also build a micro brewery.") ..
347- listitem_arrow(_"A normal mine can only dig up about one third of all the resources that lie beneath it; then it must be enhanced to a deep mine in order to keep it working properly. To enhance a building, choose it and then click the appropriate button in the appearing window.") ..
348- listitem_arrow(_"Workers gain experience by successful work. With enough experience, they become more advanced workers, who are necessary to operate the enhanced buildings. Do not enhance a building before you have enough advanced workers to operate the advanced building!") ..
349- listitem_arrow(_"Such buildings usually have greater demands than the basic kind of that building – for instance, deep mines need snacks instead of rations. You will have to enhance your tavern to an inn in order to produce snacks out of pitta bread AND a second kind of food (meat or fish) AND beer.") ..
350+ li(_"Enhance the coal mine or the iron mine to a deep mine, and enhance the tavern to an inn.") ..
351+ li(_"Also build a micro brewery.") ..
352+ li_arrow(_"A normal mine can only dig up about one third of all the resources that lie beneath it; then it must be enhanced to a deep mine in order to keep it working properly. To enhance a building, choose it and then click the appropriate button in the appearing window.") ..
353+ li_arrow(_"Workers gain experience by successful work. With enough experience, they become more advanced workers, who are necessary to operate the enhanced buildings. Do not enhance a building before you have enough advanced workers to operate the advanced building!") ..
354+ li_arrow(_"Such buildings usually have greater demands than the basic kind of that building – for instance, deep mines need snacks instead of rations. You will have to enhance your tavern to an inn in order to produce snacks out of pitta bread AND a second kind of food (meat or fish) AND beer.") ..
355 _"You may of course enhance all mines to deep mines instantly given you have the workers – bigger mines work a bit faster, smaller mines need cheaper food. It’s up to you which strategy you prefer.")
356 }
357
358@@ -103,26 +100,21 @@
359 title = _"Build a wood hardener",
360 number = 1,
361 body = objective_text(_"Build a wood hardener",
362- _([[Bigger and better buildings – including all military ones – require better building materials. They cannot be built out of simple logs – the wood has to be refined to blackwood by a wood hardener first. Always remember to build a wood hardener before you run out of blackwood, as without it you cannot expand.]])
363- .. paragraphdivider() ..
364- listitem_bullet(_"Build a wood hardener"))
365+ _([[Bigger and better buildings – including all military ones – require better building materials. They cannot be built out of simple logs – the wood has to be refined to blackwood by a wood hardener first. Always remember to build a wood hardener before you run out of blackwood, as without it you cannot expand.]]) ..
366+ li(_"Build a wood hardener"))
367 }
368
369 obj_better_material_2 = {
370 name = "mission grout",
371 title = _"Build a lime kiln and coal economy",
372 number = 3,
373- body = objective_text(_"Build a lime kiln fed by a well, and by a charcoal kiln or by a coal mine",
374- _([[Better buildings may also require other improved materials besides blackwood. One of these is grout, which is produced out of raw stone, water and coal by a lime-burner.]])
375- .. paragraphdivider() ..
376- _([[You can obtain water by building a well upon a water source, which your geologists can discover when you send them to any flag that is not on a mountain.]])
377- ..paragraphdivider() ..
378- "</p></rt>" ..
379- rt("image=pics/menu_geologist.png", p(_"In order to call a geologist to search for water, click on a flag in the area that you want him to search and then on the button labeled ‘Send geologist to explore site’.")
380- .. paragraphdivider() ..
381- _([[Coal can be obtained by building a charcoal kiln or a coal mine. Burning charcoal out of logs is slow. You should only build a charcoal kiln when no coal is available.]])
382- .. paragraphdivider() ..
383- listitem_bullet(_"Build a lime kiln and a well. Additionally, build either a charcoal kiln or a coal mine for coal supply.")))
384+ body =
385+ objective_text(_"Build a lime kiln fed by a well, and by a charcoal kiln or by a coal mine",
386+ _([[Better buildings may also require other improved materials besides blackwood. One of these is grout, which is produced out of raw stone, water and coal by a lime-burner.]]) ..
387+ p(_([[You can obtain water by building a well upon a water source, which your geologists can discover when you send them to any flag that is not on a mountain.]])) ..
388+ p(img("pics/menu_geologist.png") .. _"In order to call a geologist to search for water, click on a flag in the area that you want him to search and then on the button labeled ‘Send geologist to explore site’.") ..
389+ p(_([[Coal can be obtained by building a charcoal kiln or a coal mine. Burning charcoal out of logs is slow. You should only build a charcoal kiln when no coal is available.]])) ..
390+ li(_"Build a lime kiln and a well. Additionally, build either a charcoal kiln or a coal mine for coal supply."))
391 }
392
393 obj_better_material_3 = {
394@@ -130,9 +122,8 @@
395 title = _"Build a reed yard",
396 number = 1,
397 body = objective_text(_"Build a reed yard",
398- _([[The third material necessary for improved buildings is thatch reed, used to cover roofs. Thatch reed is planted by a gardener around his building, the reed yard.]])
399- .. paragraphdivider() ..
400- listitem_bullet(_"Build a reed yard"))
401+ _([[The third material necessary for improved buildings is thatch reed, used to cover roofs. Thatch reed is planted by a gardener around his building, the reed yard.]]) ..
402+ li(_"Build a reed yard"))
403 }
404
405 obj_build_cattlefarm = {
406@@ -140,11 +131,9 @@
407 title = _"Build a cattle farm",
408 number = 1,
409 body = objective_text(_"Build a cattle farm",
410- _([[When roads are under heavy load for a long time, one carrier is usually not enough to transport goods swiftly. Traffic jams are the consequence. Such roads therefore employ a second carrier: an ox that helps to carry the wares. This doubles the transport capacity.]])
411- .. paragraphdivider() ..
412- _([[Oxen are bred in cattle farms out of wheat and water.]])
413- .. paragraphdivider() ..
414- listitem_bullet(_"Build a cattle farm"))
415+ _([[When roads are under heavy load for a long time, one carrier is usually not enough to transport goods swiftly. Traffic jams are the consequence. Such roads therefore employ a second carrier: an ox that helps to carry the wares. This doubles the transport capacity.]]) ..
416+ p(_([[Oxen are bred in cattle farms out of wheat and water.]])) ..
417+ li(_"Build a cattle farm"))
418 }
419
420
421@@ -156,7 +145,7 @@
422 title = _"The Story Begins",
423 body = thron(_"Thron sighs…",
424 _[[It’s been months, and we are still hiding where the forests are old and dark.]]
425- .. paragraphdivider() ..
426+ .. close_p() .. open_p() ..
427 _[[My warriors hunt at day and lie awake at night – listening to the sounds of the cruel slaughter echoing from afar amongst the ancient trees.]]
428 )
429 }
430@@ -166,7 +155,7 @@
431 title = _"The Story Begins",
432 body = thron(
433 _[[We can see the raging flames that swallow Al’thunran from here, miles away.]]
434- .. paragraphdivider() ..
435+ .. close_p() .. open_p() ..
436 _[[The red lights flash in the darkness and dance to the rhythm of the war drums that haunt me even in my nightmares.]]),
437 field = al_thunran,
438 position = "topleft",
439@@ -178,7 +167,7 @@
440 title = _"The Story Begins",
441 body = thron(
442 _[[My father’s bones rest peacefully in the ground on which he once ended the senseless spilling of blood that had arisen amongst us. It pains me that his peace only endured for one generation.]]
443- .. paragraphdivider() ..
444+ .. close_p() .. open_p() ..
445 _[[Boldreth, my loyal companion and friend is a source of peace and comfort to me in these dark times. He keeps my spirits high and those of my warriors awake, preventing greed or despair from destroying the bonds between us as well.]]),
446 field = grave,
447 position = "topleft"
448@@ -196,7 +185,7 @@
449 title = _"The Story Begins",
450 body = thron(_"Thron is shaking his head…",
451 _([[Yet the war goes on. More and more of our brothers and sisters flee the brutal war raging in the capital beneath the trees.]])
452- .. paragraphdivider() ..
453+ .. close_p() .. open_p() ..
454 _([[The stories they tell about the deeds of our kin are sad to hear. I’ve spent nights lying awake, restless, more tired than I ever believed one could be. Yet whenever I close my eyes, I see the fortress my father built consumed by flames. The Throne Among the Trees, the symbol of unity and peace among our kin, became the wedge that drives us apart.]])),
455 field = sf -- scroll back when showing this and the next few message boxes
456 }
457@@ -206,7 +195,7 @@
458 title = _"The Story Begins",
459 body = thron(
460 _([[Today my hunters brought men, women and little children before me who had hidden out in the forests, trying to escape the war, hate and revenge that rage among the tribes fighting each other like in olden times, when we were no more but wild beasts driven and controlled by instincts. None of my brothers will ever gain and hold control over the wooden throne, none of the tribes will be strong enough to subdue the other. There will be no end to this slaughter, unless… is this it? As father told me?]])
461- .. paragraphdivider() ..
462+ .. close_p() .. open_p() ..
463 _([[To rise against whoever threatens our very existence, even though it may be one of your own blood or mind?]]))
464 }
465
466@@ -215,7 +204,7 @@
467 title = _"The Story Begins",
468 body = thron(
469 _([[Boldreth seems more and more torn as the days go by. The spirits of my fellows sink as the cold season approaches, and we are still living in no more than huts and barracks. I never intended to stay out here in the wilderness for so long – but I never thought my brothers would engage in this senseless battle for so long either.]])
470- .. paragraphdivider() ..
471+ .. close_p() .. open_p() ..
472 _([[Perhaps it’s time to make ourselves feel a little more at ease here. Perhaps it’s time to give those who still live and think united a new home, replacing what is now lost to us? Until we can return to the place we once called our home…]]))
473 }
474
475@@ -224,7 +213,7 @@
476 title = _"Somebody Comes up to You",
477 body = khantrukh(_"An old man says…",
478 _[[Hail, chieftain. I am Khantrukh and have seen many winters pass. Please allow me to aid you with my counsel through these darkened days.]]
479- .. paragraphdivider() ..
480+ .. close_p() .. open_p() ..
481 _[[Only the gods know for how long we have to remain hidden here. The warriors hope we may march back gloriously any day now, but I strongly doubt that will happen soon. And the days are short and cold…]])
482 }
483
484@@ -233,9 +222,9 @@
485 title = _"The Advisor",
486 body = khantrukh(_"Khantrukh notes…",
487 _[[I see you have already built a quarry and two lumberjack’s huts. That is a good beginning if we want to stay here longer.]]
488- .. paragraphdivider() ..
489+ .. close_p() .. open_p() ..
490 _[[But never forget – these forests are our heritage, entrusted upon us by our ancestors. We must always respect and care for them. What we take, we must give back again.]]
491- .. paragraphdivider() ..
492+ .. close_p() .. open_p() ..
493 _[[So, in order to replace the trees we chop down, we should build some ranger’s huts, preferably close to the lumberjack’s huts.]])
494 .. new_objectives(obj_build_rangers)
495 }
496@@ -245,7 +234,7 @@
497 title = _"In the Night",
498 body = thron(_"Thron says…",
499 _[[During another sleepless night, I went up to the hill and gazed towards the north. The fires are still burning, satisfying their hunger upon my father’s legacy.]]
500- .. paragraphdivider() ..
501+ .. close_p() .. open_p() ..
502 _[[They are a constant reminder of why we have to hide here… and why we must return in the end!]]),
503 field = al_thunran,
504 position = "topleft",
505@@ -257,7 +246,7 @@
506 title = _"At the Tomb",
507 body = thron(_"Thron says…",
508 _[[Once again, I went up to my father’s tomb, in a sacred grove at the foot of the great spire of Kal’mavrath. I just stood there and felt neither the hours pass nor the cold rain pouring down from the darkened sky…]]
509- .. paragraphdivider() ..
510+ .. close_p() .. open_p() ..
511 _[[Somehow, it felt like a farewell. For the first time, I wondered what the future might hold for me…]]),
512 field = grave,
513 position = "topleft",
514@@ -269,7 +258,7 @@
515 title = _"The Other Day",
516 body = thron(_"Thron says thoughtfully…",
517 _[[Some time ago, Boldreth came to me. His advice was to move to a place closer to home – to strike at the first sign of my brothers’ forces wavering.]]
518- .. paragraphdivider() ..
519+ .. close_p() .. open_p() ..
520 _[[But when I look over the forests I can still see black smoke rising to the sky. I know – it is too early yet, and what he hopes for will not happen any time soon. He might still be right, but I fear the bloodshed that returning too fast would cause on both sides…]])
521 }
522
523@@ -278,7 +267,7 @@
524 title = _"The Oath",
525 body = thron(_"Thron looks furious…",
526 _[[Today, my warriors picked up an old man, wandering sick and wounded through the dark forest. We listened in horror as he told us of the atrocities taking place in Al’thunran.]]
527- .. paragraphdivider() ..
528+ .. close_p() .. open_p() ..
529 _[[I hereby renew my oath – I will stop this madness at any cost!]])
530 }
531
532@@ -321,7 +310,7 @@
533 title = _"Your Loyal Companion",
534 body = boldreth(_"Boldreth exclaims…",
535 _([[Just look at that! In the east is the great mountain of Kal’mavrath! I wonder what treasures nature might have hidden beneath its majestic flanks!]])
536- .. paragraphdivider() ..
537+ .. close_p() .. open_p() ..
538 _([[Let’s expand to the east. There’s a chance for the elderly to become useful once in a while! Let us send out some of those who understand the stone’s tongue to unravel the mountain’s secrets!]]))
539 .. new_objectives(obj_build_mines)
540 }
541@@ -330,7 +319,7 @@
542 title = _"Your Loyal Companion",
543 body = boldreth(_"Boldreth laughs…",
544 _([[By Chat’Karuth’s beard, this is amazing! Just imagine what we can use this coal and iron ore for!]])
545- .. paragraphdivider() ..
546+ .. close_p() .. open_p() ..
547 _([[It might even be enough to…]]))
548 }
549
550@@ -345,7 +334,7 @@
551 title = _"Your Loyal Companion",
552 body = boldreth(_"Boldreth nods…",
553 _([[I have to hand it to you: you are right here, old man.]])
554- .. paragraphdivider() ..
555+ .. close_p() .. open_p() ..
556 _([[There seem to be quite a lot of animals in the forests here – we might just hunt down more of them. And, of course, the people would cheer a new tavern – hey, we might call it ‘Thron’s Pride’ or so if you want!]]))
557 .. new_objectives(obj_basic_food)
558 }
559@@ -354,7 +343,7 @@
560 title = _"The Advisor",
561 body = khantrukh(_"The elder jumps into the air…",
562 _([[Wisdom commands to seek variety.]])
563- .. paragraphdivider() ..
564+ .. close_p() .. open_p() ..
565 _([[North of the great mountain is a large plain – why don’t we use the space Mother Nature gave us and build a farm? I sure would enjoy a freshly baked pitta bread for a change…]]))
566 .. new_objectives(obj_begin_farming)
567 }
568@@ -363,7 +352,7 @@
569 title = _"Your Loyal Companion",
570 body = boldreth(_"Boldreth cheers up…",
571 _([[Our hunters are out in the forests, Thron.]])
572- .. paragraphdivider() ..
573+ .. close_p() .. open_p() ..
574 _([[I promise you, before the sun sets today you will have a magnificent meal fit for the chieftain of all clans!]]))
575 }
576
577@@ -377,7 +366,7 @@
578 title = _"A Beautiful Morning",
579 body = thron(_"Thron recognizes…",
580 _([[A tavern opened for our people yesterday. While I am hardly in the mood for celebration, I noticed how much this tiny bit of home means to my people. Their songs filled the air until deep in the night, and they were in higher spirits still the day after.]])
581- .. paragraphdivider() ..
582+ .. close_p() .. open_p() ..
583 _([[Maybe we actually are slowly creating a place here which we can… call home.]]))
584 }
585
586@@ -392,7 +381,7 @@
587 title = _"The Advisor",
588 body = khantrukh(_"Khantrukh speaks…",
589 _([[Our miners are digging up less and less by the day! We have to go deeper, closer to the mountain’s core, if we want more of its treasures!]])
590- .. paragraphdivider() ..
591+ .. close_p() .. open_p() ..
592 _([[Of course, it is dark and cold in such depths and only a few venture voluntarily into these places. We should reward this bravery with greater rations for them. And a pint of beer or two will keep their spirits high.]]))
593 .. new_objectives(obj_enhance_buildings)
594 }
595@@ -401,7 +390,7 @@
596 title = _"Your Loyal Companion",
597 body = boldreth(_"Boldreth seems concerned…",
598 _([[As I just discovered, we are running short on blackwood! We cannot put our warriors into some crumbling huts, and even less so in times as dangerous as ours!]])
599- .. paragraphdivider() ..
600+ .. close_p() .. open_p() ..
601 _([[We need a wood hardener, and we need one now!]]))
602 .. new_objectives(obj_better_material_1)
603 }
604@@ -410,7 +399,7 @@
605 title = _"Your Loyal Companion",
606 body = boldreth(_"Boldreth smiles…",
607 _([[Well, old friend, this should ensure that our fortifications do not break down with our foes’ first battle cry! Now we can expand safely!]])
608- .. paragraphdivider() ..
609+ .. close_p() .. open_p() ..
610 _([[Still, it would not hurt to accumulate some grout for our further campaign; thus we could, in times of need, build a fortress such as the world has never seen before!]]))
611 .. new_objectives(obj_better_material_2)
612 }
613@@ -419,7 +408,7 @@
614 title = _"The Advisor",
615 body = khantrukh(_"Khantrukh steps in…",
616 _([[Chieftain, this is a disgrace! It is well that we can produce grout for mighty fortifications and great buildings now – only this does not prevent our roofs from becoming leaky! Maybe the young ones like spending their nights in the rain, but I just can’t find any sleep with these raindrops dripping on my face!]])
617- .. paragraphdivider() ..
618+ .. close_p() .. open_p() ..
619 _([[Now this is a problem we should do something about!]]))
620 .. new_objectives(obj_better_material_3)
621 }
622@@ -434,7 +423,7 @@
623 title = _"We Need Oxen!",
624 body = khantrukh(_"Khantrukh speaks…",
625 _([[As our realm is getting bigger and bigger, the traffic on the roads is overwhelming. Our poor carriers are no longer able to transport the goods as fast as we need them to. I suggest we give them some support by breeding oxen.]])
626- .. paragraphdivider() ..
627+ .. close_p() .. open_p() ..
628 _([[They are amazing animals: The ox is as swift as a human being while being much stronger and very frugal: all we need is wheat and water to breed them and they will do their work on the roads loyally and reliably.]]))
629 .. new_objectives(obj_build_cattlefarm)
630 }
631@@ -443,9 +432,9 @@
632 title = _"Mission Complete",
633 body = thron(_"Thron speaks…",
634 _([[The other day Boldreth asked me to accompany him to the new inn. It would cheer me up, he said.]])
635- .. paragraphdivider() ..
636+ .. close_p() .. open_p() ..
637 _([[When I looked around, I saw faithful faces, trusting that I could guide them through these dark days. Yet before I could speak any words of gratitude or encouragement, one of my warriors ran into the inn. He had been far out in the forest for the past days and I could see how weary he was.]])
638- .. paragraphdivider() ..
639+ .. close_p() .. open_p() ..
640 _([[The news he brought changed everything…]]))
641 .. objective_text(_"Victory",
642 _[[You have completed this mission. You may continue playing if you wish, otherwise move on to the next mission.]])
643@@ -455,7 +444,7 @@
644 title = _"One Full Moon Night",
645 body = thron(_"Thron speaks…",
646 _([[One night, when the moon shone brightly, I climbed to the peak of Kal’mavrath.]])
647- .. paragraphdivider() ..
648+ .. close_p() .. open_p() ..
649 _([[When I gazed at the horizon, I still saw crimson lights flicker in the distance. It is incredible with how much passion my brethren fight this war. I fear the moment I will see Al’thunran again – will there be anything but ashes and wasted ruins left of our once beautiful capital when we get there?]]))
650 }
651
652@@ -463,9 +452,9 @@
653 title = _"Another Cold Day",
654 body = thron(_"Thron looks worried…",
655 _([[The winter is upon us. Many of us are suffering from the cold, yet we must endure. The day we may return cannot be far anymore – it must not be far anymore.]])
656- .. paragraphdivider() ..
657+ .. close_p() .. open_p() ..
658 _([[I prayed that it might get warmer again, as I prayed that the war would finally come to an end.]])
659- .. paragraphdivider() ..
660+ .. close_p() .. open_p() ..
661 _([[So far, it seems that neither prayer was fulfilled.]]))
662 }
663
664@@ -473,9 +462,9 @@
665 title = _"A friendly village has joined us!",
666 body = thron(_"Thron speaks…",
667 _([[We have found a village with friendly and productive people, impressed by our wealth, technology and strength.]])
668- .. paragraphdivider() ..
669+ .. close_p() .. open_p() ..
670 _([[They have lived simply, yet blithely, from hunting and farming. They have not been involved in any conflict so far, and are not ready for fighting.]])
671- .. paragraphdivider() ..
672+ .. close_p() .. open_p() ..
673 _([[But they fear that the war around Al’thunran will set an end to this life. Therefore, they have decided to join us, hoping that we can help each other.]])
674 )
675 }
676
677=== modified file 'campaigns/bar02.wmf/scripting/texts.lua'
678--- campaigns/bar02.wmf/scripting/texts.lua 2014-10-30 11:37:38 +0000
679+++ campaigns/bar02.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
680@@ -21,13 +21,12 @@
681 title = _"Build up a small food economy",
682 number = 5,
683 body = objective_text(_"Build up a small food economy",
684- _"Build up a basic food economy to provide your people with food."
685- .. paragraphdivider() ..
686- listitem_bullet(_"Build a fisher’s hut") ..
687- listitem_bullet(_"Build a hunter’s hut") ..
688- listitem_bullet(_"Build a well") ..
689- listitem_bullet(_"Build a farm") ..
690- listitem_bullet(_"Build a bakery"))
691+ _"Build up a basic food economy to provide your people with food." ..
692+ li(_"Build a fisher’s hut") ..
693+ li(_"Build a hunter’s hut") ..
694+ li(_"Build a well") ..
695+ li(_"Build a farm") ..
696+ li(_"Build a bakery"))
697 }
698
699 obj_build_cattlefarm = {
700@@ -35,9 +34,8 @@
701 title = _"Build a cattle farm",
702 number = 1,
703 body = objective_text(_"Remember to build a cattle farm",
704- _"As your roads grow longer and your economy bigger, you should make good use of your oxen to help transport wares more quickly."
705- .. paragraphdivider () ..
706- listitem_bullet(_"Remember to build a cattle farm")
707+ _"As your roads grow longer and your economy bigger, you should make good use of your oxen to help transport wares more quickly." ..
708+ li(_"Remember to build a cattle farm")
709 ),
710 }
711
712@@ -46,7 +44,7 @@
713 title = _"Build a donjon",
714 number = 1,
715 body = objective_text(_"Build a donjon",
716- listitem_bullet(_"Build a donjon at the north-east border of your territory to get greater visual range and to protect your people from sudden attacks by enemies."))
717+ li(_"Build a donjon at the north-east border of your territory to get greater visual range and to protect your people from sudden attacks by enemies."))
718 }
719
720 obj_explore_further = {
721@@ -54,7 +52,7 @@
722 title = _"Explore further",
723 number = 1,
724 body = objective_text(_"Explore further",
725- listitem_bullet(_"Build more military buildings to explore the area around the headquarters and to ensure the safety of your people."))
726+ li(_"Build more military buildings to explore the area around the headquarters and to ensure the safety of your people."))
727 }
728
729 obj_build_mining_economy = {
730@@ -62,7 +60,7 @@
731 title = _"Build a mining infrastructure",
732 number = 6,
733 body = objective_text(_"Build a mining infrastructure",
734- listitem_bullet(_"Expand your territory to the mountains, send geologists to search for ore and coal and build a mining economy with mines, taverns, smelting works and metal workshop."))
735+ li(_"Expand your territory to the mountains, send geologists to search for ore and coal and build a mining economy with mines, taverns, smelting works and metal workshop."))
736 }
737
738 obj_build_a_fortress = {
739@@ -70,7 +68,7 @@
740 title = _"Build a fortress",
741 number = 1,
742 body = objective_text(_"Build a fortress",
743- listitem_bullet(_"Build a fortress to the east of the mountains."))
744+ li(_"Build a fortress to the east of the mountains."))
745 }
746
747 obj_build_training_infrastructure = {
748@@ -78,9 +76,9 @@
749 title = _"Build a training infrastructure",
750 number = 4,
751 body = objective_text(_"Build a training infrastructure",
752- listitem_bullet(_"Build a battle arena and a training camp to the west of the mountains.") ..
753- listitem_bullet(_"Enhance your metal workshop to an axfactory in order to produce weapons, and build up a second metal workshop to ensure the production of tools. When the blacksmith reaches his next level (master blacksmith), you can even enhance the axfactory to a war mill, which will produce additional weapons.") ..
754- listitem_bullet(_"Build a helm smithy to the west of the mountains to provide your soldiers with better armor."))
755+ li(_"Build a battle arena and a training camp to the west of the mountains.") ..
756+ li(_"Enhance your metal workshop to an axfactory in order to produce weapons, and build up a second metal workshop to ensure the production of tools. When the blacksmith reaches his next level (master blacksmith), you can even enhance the axfactory to a war mill, which will produce additional weapons.") ..
757+ li(_"Build a helm smithy to the west of the mountains to provide your soldiers with better armor."))
758 }
759
760
761@@ -89,8 +87,8 @@
762 title = _"Build a warehouse",
763 number = 1,
764 body = objective_text(_"Build a warehouse",
765- listitem_bullet(_"Build a warehouse to the west of the mountains.") ..
766- listitem_arrow(_"Warehouses are similar to your headquarters, with the only difference that they aren’t defended by soldiers. It is often wise to build a warehouse when your territory is growing and the paths to your headquarters get longer and longer."))
767+ li(_"Build a warehouse to the west of the mountains.") ..
768+ li_arrow(_"Warehouses are similar to your headquarters, with the only difference that they aren’t defended by soldiers. It is often wise to build a warehouse when your territory is growing and the paths to your headquarters get longer and longer."))
769 }
770
771 obj_build_trainingssites = {
772@@ -98,10 +96,9 @@
773 title = _"Build training sites",
774 number = 2,
775 body = objective_text(_"Build training sites",
776- listitem_bullet(_"Build a battle arena and a training camp to the west of the mountains.") ..
777- listitem_arrow(_"Training sites like a training camp or a battle arena are used for training soldiers in their different attributes. These attributes are important in fights and the better a soldier is, the higher is the chance to win a fight."
778- .. "<br>" ..
779- _"The attributes are: health, attack, defense and evade."))
780+ li(_"Build a battle arena and a training camp to the west of the mountains.") ..
781+ li_arrow(_"Training sites like a training camp or a battle arena are used for training soldiers in their different attributes. These attributes are important in fights and the better a soldier is, the higher is the chance to win a fight." ..
782+ p(_"The attributes are: health, attack, defense and evade.")))
783 }
784
785 obj_build_weapon_productions = {
786@@ -109,7 +106,7 @@
787 title = _"Build weapons production",
788 number = 3,
789 body = objective_text(_"Build weapons production",
790- listitem_bullet(_"Enhance your metal workshop to an axfactory in order to produce weapons, and build up a second metal workshop to ensure the production of tools. When the blacksmith reaches his next level (master blacksmith), you can even enhance the axfactory to a war mill, which will produce additional weapons."))
791+ li(_"Enhance your metal workshop to an axfactory in order to produce weapons, and build up a second metal workshop to ensure the production of tools. When the blacksmith reaches his next level (master blacksmith), you can even enhance the axfactory to a war mill, which will produce additional weapons."))
792 }
793
794 obj_build_a_helmsmithy = {
795@@ -117,7 +114,7 @@
796 title=_"Build a helm smithy",
797 number = 1,
798 body = objective_text(_"Build a helm smithy",
799- listitem_bullet(_"Build a helm smithy to the west of the mountains to provide your soldiers with better armor."))
800+ li(_"Build a helm smithy to the west of the mountains to provide your soldiers with better armor."))
801 }
802
803 obj_destroy_kalitaths_army = {
804@@ -125,8 +122,8 @@
805 title = _"Destroy Kalitath’s army",
806 number = 2,
807 body = objective_text(_"Destroy Kalitath’s army",
808- listitem_bullet(_"Destroy Kalitath’s army and expand your territory to the east.") ..
809- listitem_arrow(_"To attack an enemy, you must click on the door of an adversary’s military building. A menu will pop up allowing you to select the number of soldiers that should attack. When you are ready with setting the number, click on the cross (‘Start Attack’)."))
810+ li(_"Destroy Kalitath’s army and expand your territory to the east.") ..
811+ li_arrow(_"To attack an enemy, you must click on the door of an adversary’s military building. A menu will pop up allowing you to select the number of soldiers that should attack. When you are ready with setting the number, click on the cross (‘Start Attack’)."))
812 }
813
814 obj_military_assault_on_althunran = {
815@@ -134,7 +131,7 @@
816 title = _"Military assault on Al’thunran",
817 number = 1,
818 body = objective_text(_"Military assault on Al’thunran",
819- listitem_bullet(_"Destroy all forces of Thron’s two brothers to liberate the throne-circle."))
820+ li(_"Destroy all forces of Thron’s two brothers to liberate the throne-circle."))
821 }
822
823 -- =======================================================================
824@@ -145,7 +142,7 @@
825 title=_"Close to Home",
826 body =thron(_"Thron looks worried…",
827 _([[These last days, we came closer to our capital. Many people have already joined us on our march and set their hopes on me. However, I fear that we are not strong enough to take up the battle against my brothers.]])
828- .. paragraphdivider() ..
829+ .. close_p() .. open_p() ..
830 _([[For now, we are resting at the borders of the old forest and preparing for the coming days.]]))
831 }
832
833@@ -198,9 +195,9 @@
834 title = _"Renegade Fortification",
835 body = thron(_"Thron says:",
836 _([[The traitor left his armies dying where they lay when he saw that he would not keep my forces back. Kalitath disappeared in the confusion of the war, but I don’t care now. Shall he flee and be forgotten for all times as a tribal leader that would not bow before the wooden throne, that is mine to take now.]])
837- .. paragraphdivider() ..
838+ .. close_p() .. open_p() ..
839 _([[Furthermore, his flight brought us a great benefit: all year, Kalitath was so busy fighting that he did not even care to store enough food for all his men. Now that he has fled, their hunger has caused some of his younger followers to desert. This group holds a strong fortification on the main ring.]])
840- .. paragraphdivider() ..
841+ .. close_p() .. open_p() ..
842 _([[But there is more news: My scouts have reported that the two raging tribes of my brothers are in chaos and have barely noticed the new danger that is about to strike them. However, they would not care if they noticed I guess, blinded by rage and hate, there is no sense left in them at all I believe.]]))
843 }
844
845@@ -239,7 +236,7 @@
846 title = _"Further Exploration",
847 body = boldreth(_"Boldreth says:",
848 _([[The first fortification Thron ordered has just been completed. At the moment, he seeks to bring trust and belief to those who live inside the walls of our new habitat that we named ‘Ondun’, which means ‘those who wait’ in the old tongue. But Thron is not yet satisfied – and I fully understand his fears: the forests are deep, and the frontier to Al’thunran is near. I am sure that there are a thousand greater dangers out there than the unknown tracks.]])
849- .. paragraphdivider() ..
850+ .. close_p() .. open_p() ..
851 _([[To overlook more of the area around our hall, we should explore further and set up more guards and scouts to observe the frontier and keep an eye on the raging wars on our doorstep. THEN we will be prepared once trouble seeks to capture our woods.]]))
852 .. new_objectives(obj_explore_further)
853 }
854@@ -279,7 +276,7 @@
855 title = _"Enhanced Economy and Training",
856 body = boldreth(_"Boldreth says:",
857 _([[Our mining economy seems to work fine, that is already good news! Anyway, there are still a lot of men and women waiting in our hall to get a task, so they can help our soldiers to prepare for the war to come.]])
858- .. paragraphdivider() ..
859+ .. close_p() .. open_p() ..
860 _([[Our geologists found a lot more deposits of iron ore, coal and even gold. We should enhance our current mines as soon as our miners are more experienced. We should build up some more mines, a bigger food infrastructure to always supply our men with sufficient food and a further processing economy. But that’s still not everything – most of our soldiers are quite young and neither have a good weapon nor are they well trained. We should build up training sites to prepare them for their future tasks.]]))
861 .. new_objectives(obj_build_training_infrastructure)
862 }
863@@ -289,7 +286,7 @@
864 title=_"Another Cold Day",
865 body= thron(_"Thron looks worried…",
866 _([[My brothers and their soldiers are dead and left fire and destruction behind. In none of all the ruins could I find any man or woman of the normal folk, and so I just may hope that they fled from this cruel battleground and started a better life somewhere else.]])
867- .. paragraphdivider() ..
868+ .. close_p() .. open_p() ..
869 _([[Nothing is left of that beauty I remember, only ruins remain of the old capital. I am sorrowful but also relieved. I never hoped to see Al’thunran’s old beauty again – it was only a few months ago that I wondered whether I would ever be able to set my feet there again. Now the old town is back in my hands, and I will not hesitate to rebuild it with all the strength my people have. I can’t wait to see it again in its old beauty.]]))
870 .. objective_text(_"Victory",
871 _([[You have completed the last mission of the Barbarian tutorial campaign. You may continue playing if you wish, otherwise move on to the next campaign.]]))
872@@ -300,9 +297,9 @@
873 title = _"Military Assault",
874 body = thron(_"Thron says:",
875 _([[So be it, the generals are out and about arranging my troops, and Boldreth himself will lead the first strike. I will ride by his side, to free Al’thunran of this war and return peace to our capital.]])
876- .. paragraphdivider() ..
877+ .. close_p() .. open_p() ..
878 _([[When the young sun rises above the trees tomorrow morning, I will order the assault. By dusk, I will celebrate my victory in the wooden halls of the warlord and sacrifice a newborn lamb in the honor of my father, whose eyes are set upon me today.]])
879- .. paragraphdivider() ..
880+ .. close_p() .. open_p() ..
881 _([[So be it!]]))
882 .. new_objectives(obj_military_assault_on_althunran),
883 }
884
885=== modified file 'campaigns/emp01.wmf/scripting/texts.lua'
886--- campaigns/emp01.wmf/scripting/texts.lua 2015-07-25 08:07:44 +0000
887+++ campaigns/emp01.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
888@@ -28,7 +28,7 @@
889 title=_"Build a barracks",
890 number = 1,
891 body = objective_text(_"Barracks",
892- listitem_bullet(_[[Build a barracks at the red house symbol on the east side of the forests, to the right of your provisional headquarters.]])
893+ li(_[[Build a barracks at the red house symbol on the east side of the forests, to the right of your provisional headquarters.]])
894 ),
895 }
896
897@@ -37,7 +37,7 @@
898 title=_"Build a lumberjack’s house",
899 number = 1,
900 body = objective_text(_"Lumberjack’s House",
901- listitem_bullet(_[[Build a lumberjack’s house at the red house symbol, south of your provisional headquarters.]])
902+ li(_[[Build a lumberjack’s house at the red house symbol, south of your provisional headquarters.]])
903 ),
904 }
905
906@@ -46,7 +46,7 @@
907 title=_"Build 2 lumberjack’s houses and a sawmill",
908 number = 3,
909 body = objective_text(_"Two Lumberjack’s Houses and a Sawmill",
910- listitem_bullet(_[[Build two more lumberjack’s houses and a sawmill as soon as there is enough space for them.]])
911+ li(_[[Build two more lumberjack’s houses and a sawmill as soon as there is enough space for them.]])
912 ),
913 }
914
915@@ -55,7 +55,7 @@
916 title=_"Build a forester’s house",
917 number = 1,
918 body = objective_text(_"Forester’s House",
919- listitem_bullet(_[[Build a forester’s house to preserve the wood resources of this island.]])
920+ li(_[[Build a forester’s house to preserve the wood resources of this island.]])
921 ),
922 }
923
924@@ -64,13 +64,12 @@
925 title=_"Build a quarry",
926 number = 5,
927 body = objective_text(_"Quarry",
928- listitem_bullet(_[[Build a quarry in the south to cut some stones and marble out of the rocks.]]) ..
929- listitem_arrow(_[[These might be used for future buildings.]])
930+ li(_[[Build a quarry in the south to cut some stones and marble out of the rocks.]]) ..
931+ li_arrow(_[[These might be used for future buildings.]])
932 ),
933 }
934
935
936-
937 -- ==================
938 -- Texts to the user
939 -- ==================
940@@ -78,13 +77,13 @@
941 title =_ "A Dark Night",
942 body=lutius(_"Diary of Lutius",
943 _([[What has become of our Empire? I really ask this question – why did my king forbid me from fighting against that monstrous Barbarian tribe, who first acted as a peaceful friend and then attacked my army in the darkest night?]])
944- .. paragraphdivider() ..
945+ .. close_p() .. open_p() ..
946 _([[With an army of 150 men, I was assigned to patrol on our northern frontier, which lies near the Galdin Mountains in a great, beautiful and ancient forest. Soon, we met a Barbarian tribe, which at first was friendly. A few of my men even traded with them and their children came to us, to admire our clean and tidy uniforms and weapons.]])
947- .. paragraphdivider() ..
948+ .. close_p() .. open_p() ..
949 _([[But during our fifth night in that region, they attacked us with no reason. I lost dozens of good men, and found myself imprisoned and brought to their chieftain. He spat at me, mocked me and told me to leave this land forever. He did not want new land and did not want our land, but he told me that THIS forest was their land – and it would stay theirs until the spirits took the last man of his folk!]])
950- .. paragraphdivider() ..
951+ .. close_p() .. open_p() ..
952 _([[Three weeks later, I returned to Fremil to speak with our king. He was furious at the Barbarians, yet forbade any attack on these tribes. He believed that our army was too weak to survive in a war against the Barbarians.]])
953- .. paragraphdivider() ..
954+ .. close_p() .. open_p() ..
955 _([[Still, I saw no way that I could erase my shame without fighting against these Barbarians. So, I left Fremil by boat to find a new world and a new life for myself, somewhere in the south. Now I am sailing on the perl-gulf with my family, some of my friends and a few of my best warriors.]])),
956 w=500,
957 posy=1,
958@@ -94,7 +93,7 @@
959 title=_"The Rough Sea",
960 body= lutius(_"Diary of Lutius",
961 _([[It seems as if sailing on the perl-gulf was one of our biggest mistakes. Nature was against us and drove us into a dark, wild storm. I really don’t know how many hours have passed since the waves rose higher than our boat, but still it would be suicide to go outside.]])
962- .. paragraphdivider() ..
963+ .. close_p() .. open_p() ..
964 _([[Our ship is badly damaged and is taking in more and more water. We can thank the Gods if we survive this black night with our lives.]])),
965 w=400,
966 posy=1,
967@@ -104,9 +103,9 @@
968 title=_"Survivor",
969 body= lutius(_"Diary of Lutius",
970 _([[Finally, the Gods were with us!]])
971- .. paragraphdivider() ..
972+ .. close_p() .. open_p() ..
973 _([[We landed on an unknown coast and found peaceful rest under the palm trees growing at the shore. But that is about as good as it gets. The truth is: when I woke up this morning, I saw nothing but sand around us.]])
974- .. paragraphdivider() ..
975+ .. close_p() .. open_p() ..
976 _([[It really seems as if we have landed under the only palm trees existing in this far-away sandy desert. I fear we won’t find the help we need to get our ship repaired in good time.]])),
977 w=400,
978 posy=1,
979@@ -116,9 +115,9 @@
980 title=_"A Foreboding",
981 body= saledus(_"Saledus looks around nervously…",
982 _([[Sire, I fear we are not safe in this foreign land. Who knows what terrible creatures live beyond this forest, in that mighty desert? What if these creatures enter the woods and await the time to attack us?]])
983- .. paragraphdivider() ..
984+ .. close_p() .. open_p() ..
985 _([[Well, perhaps my fear is misguided, but it can’t be wrong to keep watch in the forests – so that we can be sure to see any potential enemies before they can see us.]])
986- .. paragraphdivider() ..
987+ .. close_p() .. open_p() ..
988 _([[You really should build a barracks in the eastern portion of the forest. Then one of my men can keep watch in the darkness and keep us safe from these creatures.]]))
989 .. new_objectives(obj_build_barracks),
990 w=400,
991@@ -129,7 +128,7 @@
992 title=_"Safe For Now",
993 body= saledus(_"Saledus speaks with a sigh of relief…",
994 _([[Sire, I saw that the construction of the barracks was completed, so I have assigned one of my best soldiers to it to keep watch on the desert.]])
995- .. paragraphdivider() ..
996+ .. close_p() .. open_p() ..
997 _([[This is a good step forward. Now we can feel a bit safer and can look forward to repairing our ship.]])),
998 w=400,
999 }
1000@@ -138,9 +137,9 @@
1001 title=_"Young Amalea",
1002 body= amalea(_"Amalea smiles…",
1003 _([[Greetings, Lutius! I just met Saledus outside.]])
1004- .. paragraphdivider() ..
1005+ .. close_p() .. open_p() ..
1006 _([[He told me about the barracks. Well, I don’t think we need more barracks – instead, we might concentrate on other things now.]])
1007- .. paragraphdivider() ..
1008+ .. close_p() .. open_p() ..
1009 _([[It is absolutely clear that we need wood to repair our ship. So, I walked through the forest yesterday to look for a nice place for a lumberjack’s house and found one right south of our provisional headquarters.]]))
1010 .. new_objectives(obj_build_lumberjack),
1011 w=400,
1012@@ -150,7 +149,7 @@
1013 title=_"Young Amalea",
1014 body= amalea(_"Amalea recommends…",
1015 _([[I got the message that our first lumberjack has started his work today. Perhaps it would be a good idea to wait until he cleans enough space for constructing two more lumberjack’s houses, so that we can harvest the logs faster.]])
1016- .. paragraphdivider() ..
1017+ .. close_p() .. open_p() ..
1018 _([[But unfortunately the logs are useless for repairing our ship – we need refined lumber, like every ship and every bigger building needs, too. So we should build a sawmill – as soon as we have enough space for this.]]))
1019 .. new_objectives(obj_build_sawmill_and_lumberjacks),
1020 w=400,
1021@@ -160,13 +159,13 @@
1022 title=_"Young Amalea",
1023 body= amalea(_"Amalea comes in…",
1024 _([[I’ve got two important things to talk about… First the good news:]])
1025- .. paragraphdivider() ..
1026+ .. close_p() .. open_p() ..
1027 _([[I noticed that the construction of the sawmill is complete, so we can begin to refine the logs that the lumberjacks are harvesting into lumber.]])
1028- .. paragraphdivider() ..
1029+ .. close_p() .. open_p() ..
1030 _([[But the bad news is that our lumberjacks harvest at an incredible speed. There are almost no trees left on this island.]])
1031- .. paragraphdivider() ..
1032+ .. close_p() .. open_p() ..
1033 _([[These trees provide shelter from the sandstorms that sweep in from the desert, and shade on the hot days, and they are the home of many gentle animals. We shouldn’t leave this island a complete desert.]])
1034- .. paragraphdivider() ..
1035+ .. close_p() .. open_p() ..
1036 _([[Lutius, please find someone who will take care of planting new trees.]]))
1037 .. new_objectives(obj_build_forester),
1038 w=400,
1039@@ -176,7 +175,7 @@
1040 title=_"Thinking About the Future",
1041 body= saledus(_"Saledus notes…",
1042 _([[Sire, I just thought about the rocks standing on the south shore of this land. Perhaps we could cut out some useful hard stones and beautiful marble.]])
1043- .. paragraphdivider() ..
1044+ .. close_p() .. open_p() ..
1045 _([[The repair of our ship will take a few weeks, anyway, and the resources we harvest now might be the base of strong and big buildings in another land.]]))
1046 .. new_objectives(obj_build_quarry),
1047 w=400,
1048@@ -184,9 +183,9 @@
1049
1050 saledus_4 = {
1051 title=_"A Step Forward",
1052- body= saledus(_"Saledus looks excited…",
1053+ body= saledus(_"Saledus looks promising…",
1054 _([[Sire, today we got a lot closer to our first castle. The quarry to the south began its work today and will soon provide us with stones and beautiful marble.]])
1055- .. paragraphdivider() ..
1056+ .. close_p() .. open_p() ..
1057 _([[Now we truly can look forward to settling down on another island.]])),
1058 w=400,
1059 }
1060@@ -195,9 +194,9 @@
1061 title=_"Mission Complete",
1062 body= lutius(_"Diary of Lutius",
1063 _([[Today I got the message that our ship is completely repaired. At the moment, my people are loading everything onto our newly repaired ship, hoping it will serve us better than last time.]])
1064- .. paragraphdivider() ..
1065+ .. close_p() .. open_p() ..
1066 _([[Tonight will be our last night on this island. Tomorrow morning we will leave, searching for a new place for our exile.]])
1067- .. paragraphdivider() ..
1068+ .. close_p() .. open_p() ..
1069 _([[I still wonder if we will ever see Fremil again.]]))
1070 .. objective_text(_"Victory",
1071 _[[You have completed this mission. You may continue playing if you wish, otherwise move on to the next mission.]]),
1072
1073=== modified file 'campaigns/emp02.wmf/scripting/texts.lua'
1074--- campaigns/emp02.wmf/scripting/texts.lua 2015-07-25 18:16:31 +0000
1075+++ campaigns/emp02.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
1076@@ -28,7 +28,7 @@
1077 title =_"Build up a wood economy",
1078 number = 5,
1079 body = objective_text(_"Wood Economy",
1080- listitem_bullet(_[[Build three lumberjack’s houses, a forester’s house and a sawmill.]])
1081+ li(_[[Build three lumberjack’s houses, a forester’s house and a sawmill.]])
1082 ),
1083 }
1084
1085@@ -37,7 +37,7 @@
1086 title =_"Build a quarry",
1087 number = 1,
1088 body = objective_text(_"Quarry",
1089- listitem_bullet(_[[Build a quarry to the south of your headquarters.]])
1090+ li(_[[Build a quarry to the south of your headquarters.]])
1091 ),
1092 }
1093
1094@@ -46,7 +46,7 @@
1095 title =_"Protect your colony",
1096 number = 1,
1097 body = objective_text(_"Protect Your Colony",
1098- listitem_bullet(_[[Build some barracks and sentries around the colony.]])
1099+ li(_[[Build some barracks and sentries around the colony.]])
1100 ),
1101 }
1102
1103@@ -55,7 +55,7 @@
1104 title =_"Start mining marble",
1105 number = 1,
1106 body = objective_text(_"Marble",
1107- listitem_bullet(_[[Expand to the east, to start mining marble from the mountain.]])
1108+ li(_[[Expand to the east, to start mining marble from the mountain.]])
1109 ),
1110 }
1111
1112@@ -64,7 +64,7 @@
1113 title =_"Build a stonemason and mining infrastructure",
1114 number = 7,
1115 body = objective_text(_"Stonemason and Mining Infrastructure",
1116- listitem_bullet(_[[Build a stonemason and then a complete mining and production infrastructure (coal mine and / or charcoal kiln, iron ore mine, toolsmithy, weapon smithy, armor smithy and smelting works).]])
1117+ li(_[[Build a stonemason and then a complete mining and production infrastructure (coal mine and / or charcoal kiln, iron ore mine, toolsmithy, weapon smithy, armor smithy and smelting works).]])
1118 ),
1119 }
1120
1121@@ -73,10 +73,10 @@
1122 title =_"Provide your miners with food",
1123 number = 1,
1124 body = objective_text(_"Food For Your Miners",
1125- listitem_bullet(_[[To produce some sustaining food for our miners, we could build up a tavern. To supply them with some good and strong drinks, we could build up a brewery and a winery.]]) ..
1126- listitem_bullet(_[[Of course this means we will need more resources for preparing this food – like fish, meat or bread. To provide these foodstuffs, you would have to build a fisher’s house, a farm, a mill and a bakery.]]) ..
1127- listitem_bullet(_[[Maybe you will also need a hunter’s house, a piggery, a vineyard and some wells.]]) ..
1128- listitem_arrow(_[[It’s up to you what you want to build. But remember – coal and iron ore mines need beer, marble and gold mines need wine and all mines need at least rations, which are produced out of bread OR meat OR fish.]])
1129+ li(_[[To produce some sustaining food for our miners, we could build up a tavern. To supply them with some good and strong drinks, we could build up a brewery and a winery.]]) ..
1130+ li(_[[Of course this means we will need more resources for preparing this food – like fish, meat or bread. To provide these foodstuffs, you would have to build a fisher’s house, a farm, a mill and a bakery.]]) ..
1131+ li(_[[Maybe you will also need a hunter’s house, a piggery, a vineyard and some wells.]]) ..
1132+ li_arrow(_[[It’s up to you what you want to build. But remember – coal and iron ore mines need beer, marble and gold mines need wine and all mines need at least rations, which are produced out of bread OR meat OR fish.]])
1133 ),
1134 }
1135
1136@@ -85,8 +85,8 @@
1137 title =_"Protect your eastern frontier",
1138 number = 1,
1139 body = objective_text(_"Protect Your Eastern Frontier",
1140- listitem_bullet(_[[Build up stronger military buildings, such as an outpost, a barrier or a tower, on the eastern frontier.]]) ..
1141- listitem_arrow(_[[To watch deep inside the enemy territory, build a tower.]])
1142+ li(_[[Build up stronger military buildings, such as an outpost, a barrier or a tower, on the eastern frontier.]]) ..
1143+ li_arrow(_[[To watch deep inside the enemy territory, build a tower.]])
1144 ),
1145 }
1146
1147@@ -95,8 +95,8 @@
1148 title =_"Destroy the Barbarian tribe",
1149 number = 2,
1150 body = objective_text(_"Destroy the Barbarian Tribe",
1151- listitem_bullet(_[[As soon as you have enough soldiers, attack and completely destroy the Barbarian buildings.]]) ..
1152- listitem_bullet(_[[Finally, build up a fortress on the peninsula (near where the Barbarian headquarters stood before), to avoid new settlements of other tribes in that region.]])
1153+ li(_[[As soon as you have enough soldiers, attack and completely destroy the Barbarian buildings.]]) ..
1154+ li(_[[Finally, build up a fortress on the peninsula (near where the Barbarian headquarters stood before), to avoid new settlements of other tribes in that region.]])
1155 ),
1156 }
1157
1158@@ -108,7 +108,7 @@
1159 posy= 1,
1160 body = lutius(_"Diary of Lutius",
1161 _([[Finally! This island appears to have been made for us, it is a gift from the Gods to my people and myself. Until now, we have only seen a small part of this island, but this part alone is already bringing sunlight to my mind. I feel as if we have found a priceless treasure, a land like paradise.]])
1162- .. paragraphdivider() ..
1163+ .. close_p() .. open_p() ..
1164 _([[On this island, we will start our new life. We will build up an outpost for our exile, which perhaps will become a new, beautiful home for every one of us.]])),
1165 }
1166
1167@@ -117,9 +117,9 @@
1168 posy = 1,
1169 body= lutius(_"Diary of Lutius",
1170 _([[As Saledus and I walked through these wonderful forests in the north, we felt that our future had just begun. This land is so peaceful, good and beautiful, I could stay here until the end of my life.]])
1171- .. paragraphdivider() ..
1172+ .. close_p() .. open_p() ..
1173 _([[But until that day, many years may pass! For now, we must concentrate on the present, and build a few lumberjack’s houses and a sawmill to produce some basic building materials.]])
1174- .. paragraphdivider() ..
1175+ .. close_p() .. open_p() ..
1176 _([[But we mustn’t forget to preserve this natural bounty. These forests should last forever, so we really have to build a forester’s house too.]]))
1177 .. new_objectives(obj_build_woodeconomy)
1178 }
1179@@ -129,7 +129,7 @@
1180 posy = 1,
1181 body= lutius(_"Diary of Lutius",
1182 _([[Later, I walked down to the rocks in the south and looked for a place where we could build a quarry to get some hard stone for our larger buildings.]])
1183- .. paragraphdivider() ..
1184+ .. close_p() .. open_p() ..
1185 _([[Again, I felt like I was in paradise when I noticed that some marble-like stones were among the rocks. It seems that we will soon be able to build strong, luxurious buildings, like those we were accustomed to in Fremil.]]))
1186 .. new_objectives(obj_build_quarry)
1187 }
1188@@ -153,9 +153,9 @@
1189 posy = 1,
1190 body= saledus(_"Saledus looks unhappy",
1191 _([[Sire, I don’t want to start a panic, but I found something which gives me a sinking feeling in my stomach and spreads waves of fear in my heart. As I walked down to the southern shore, I found the remains of another ship. I don’t know whether these parts are all that is left of that ship. In any case, these parts do not seem to be old.]])
1192- .. paragraphdivider() ..
1193+ .. close_p() .. open_p() ..
1194 _([[Perhaps the people aboard that ship were caught in the same storm which brought us to Malac’ Mor – and were brought to this island.]])
1195- .. paragraphdivider() ..
1196+ .. close_p() .. open_p() ..
1197 _([[I beg you to be cautious and to build some barracks or sentries around our colony.]]))
1198 .. new_objectives(obj_build_military_buildings)
1199 }
1200@@ -164,9 +164,9 @@
1201 title =_ "Marble on the Mountain",
1202 body= saledus(_"Saledus smiles",
1203 _([[Sire, I’ve got good news for you: As I walked to the east, I found a larger mountain. I am not absolutely sure – a geologist should check if I am right – but I believe we could mine marble from some places on the mountain.]])
1204- .. paragraphdivider() ..
1205+ .. close_p() .. open_p() ..
1206 _([[It would be a good source for bolstering our supply of quality marble, beyond the meager quantities available from the quarry. Perhaps you were right when you said that this island was like paradise.]])
1207- .. paragraphdivider() ..
1208+ .. close_p() .. open_p() ..
1209 _([[Please, expand to that mountain and start mining marble.]]))
1210 .. new_objectives(obj_build_marblemine)
1211 }
1212@@ -175,9 +175,9 @@
1213 title =_ "Further Mountains",
1214 body= saledus(_"Saledus is excited",
1215 _([[By the Gods, this is an unbelievable stroke of fortune! There are two more mountains, and it seems that one has a large quantity of coal and the other of iron ore. I advise you to immediately build iron ore and coal mines (or at least charcoal kilns), smelting works, toolsmithies, armor and weapon smithies.]])
1216- .. paragraphdivider() ..
1217+ .. close_p() .. open_p() ..
1218 _([[However: for all these bigger buildings, we need better and more elegant building materials. So you have to build a stonemason, who will cut columns from marble.]])
1219- .. paragraphdivider() ..
1220+ .. close_p() .. open_p() ..
1221 _([[After everything, we can now begin to live like we did in Fremil.]]))
1222 .. new_objectives(obj_build_mining_infrastructure)
1223 }
1224@@ -186,9 +186,9 @@
1225 title =_ "Food for the Miners",
1226 body= amalea(_"Amalea enters…",
1227 _([[Lutius, don’t you think you forgot something important?]])
1228- .. paragraphdivider() ..
1229+ .. close_p() .. open_p() ..
1230 _([[It’s nice, and of course a good idea, to build up mines, which will give us a more comfortable life, but the people working in the mines are unhappy with the current situation. They have to do hard work and have no time for making their own food.]])
1231- .. paragraphdivider() ..
1232+ .. close_p() .. open_p() ..
1233 _([[What do you think about helping them out? I can’t tell you what we need exactly… but here are my recommendations:]]))
1234 .. new_objectives(obj_build_food_infrastructure)
1235 }
1236@@ -197,7 +197,7 @@
1237 title =_ "Our New Tavern",
1238 body= amalea(_"Amalea smiles",
1239 _([[I just visited our new tavern ‘At the palms’. The beer they serve is really tasty. You really should have a drink there, too.]])
1240- .. paragraphdivider() ..
1241+ .. close_p() .. open_p() ..
1242 _([[It is good to see that we have now got a warmer and more familiar environment on our island. Thank you, Lutius.]]))
1243 }
1244
1245@@ -206,11 +206,11 @@
1246 posy=1,
1247 body= lutius(_"Diary of Lutius",
1248 _([[By the Gods! This is absolutely terrible. It seems as if we stand close to a test – and it seems as if Saledus was right with his fear concerning the shipwreck he found.]])
1249- .. paragraphdivider() ..
1250+ .. close_p() .. open_p() ..
1251 _([[Today, as I walked down to the eastern shore, I got a shock. I caught sight of one of those hated, evil, Barbarian tribes with whom we have had so many problems before.]])
1252- .. paragraphdivider() ..
1253+ .. close_p() .. open_p() ..
1254 _([[At first, I was naive and hoped that they were peaceful, but as soon as one of them saw me, they charged towards me and started attacking me with their throwing spears. Thanks be to the Gods that I was able to flee and hide myself, before retreating back to our colony under cover of darkness.]])
1255- .. paragraphdivider() ..
1256+ .. close_p() .. open_p() ..
1257 _([[Anyway, we must build up stronger military buildings as soon as possible.]]))
1258 .. new_objectives(obj_build_bigger_military_buildings)
1259 }
1260@@ -228,7 +228,7 @@
1261 posy=1,
1262 body= lutius(_"Diary of Lutius",
1263 _([[Today is a proud day. We have fought for our new home and risen victorious.]])
1264- .. paragraphdivider() ..
1265+ .. close_p() .. open_p() ..
1266 _([[There are still a few Barbarians hiding on our island, but I am sure that we will find them soon. Every Barbarian who doesn’t attack us will be put in a boat with the other peaceful ones, and sent back to their country.]]))
1267 .. objective_text(_"Victory",
1268 _[[You have established a working economy, trained new soldiers and driven the Barbarians from the island.]])
1269@@ -238,7 +238,7 @@
1270 title =_ "As Time is Running By",
1271 w=200,
1272 h=150,
1273- body=rt(p(_"7 days later…")),
1274+ body= p(_"7 days later…"),
1275 }
1276
1277 diary_page_11 = {
1278@@ -246,8 +246,8 @@
1279 posy=1,
1280 body= lutius(_"Diary of Lutius",
1281 _([[Today a pigeon landed on our island. It brought a message which fills me with dark thoughts and brings back my fears.]])
1282- .. paragraphdivider() ..
1283+ .. close_p() .. open_p() ..
1284 _([[The message was addressed to me, begging me to come back to Fremil. It says that the Empire is at war with the Barbarians. They were attacked from the north by the tribe that I was forbidden to attack. It is clear to me what I must do…]])
1285- .. paragraphdivider() ..
1286+ .. close_p() .. open_p() ..
1287 _([[You have completed this mission. You may continue playing if you wish, otherwise move on to the next mission.]]))
1288 }
1289
1290=== modified file 'campaigns/tutorial01_basic_control.wmf/scripting/texts.lua'
1291--- campaigns/tutorial01_basic_control.wmf/scripting/texts.lua 2015-07-26 10:48:55 +0000
1292+++ campaigns/tutorial01_basic_control.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
1293@@ -14,22 +14,18 @@
1294 -- =============
1295 scould_player = {
1296 title = _"Nice And Easy Does It All the Time",
1297- body = rt(
1298- p(_[[I am sorry, but will I have to tear this down again. We might need the space here later on. If I am too slow for you, you might want to play a real game and just find everything out for yourself. Otherwise, please bear with me, I am not the youngest and quickest anymore.]]
1299- )
1300- ),
1301+ body =
1302+ p(_[[I am sorry, but will I have to tear this down again. We might need the space here later on. If I am too slow for you, you might want to play a real game and just find everything out for yourself. Otherwise, please bear with me, I am not the youngest and quickest anymore.]]),
1303 h = 300,
1304 show_instantly = true
1305 }
1306
1307 initial_message_01 = {
1308 title = _"Welcome to the Widelands Tutorial!",
1309- body = rt(
1310+ body =
1311 h1(_"Welcome to Widelands!") ..
1312 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.]]) ..
1313- paragraphdivider() ..
1314- listitem_bullet(_[[Dismiss this box by left-clicking on the button below.]])
1315- ),
1316+ li(_[[Dismiss this box by left-clicking on the button below.]]),
1317 h = 300,
1318 w = 400
1319 }
1320@@ -37,31 +33,26 @@
1321 title = _"Diving In",
1322 position = "topright",
1323 field = sf,
1324- body = rt(
1325+ body =
1326 h1(_"Let’s dive right in!") ..
1327 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.]]) ..
1328 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 raw stone. 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.]]) ..
1329 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, either by clicking on the ‘Show Building Spaces’ button at the bottom of the screen, which is the fourth one from the left. Or you can use the SPACE key to toggle it.]]) ..
1330- paragraphdivider() ..
1331- listitem_bullet(_[[Left-click the ‘OK’ button to close this box and then try it.]])
1332- ),
1333+ li(_[[Left-click the ‘OK’ button to close this box and then try it.]]),
1334 obj_name = "enable_buildhelp",
1335 obj_title = _"Enable the showing of building spaces",
1336- obj_body = rt(
1337+ obj_body =
1338 h1(_"Show Building Spaces") ..
1339 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.]]) ..
1340- paragraphdivider() ..
1341- listitem_bullet(_[[Do so now, either by pressing SPACE or by clicking the fourth button from the left at the very bottom of the screen. Right-click on this window and then give it a try.]])
1342- )
1343+ li(_[[Do so now, either by pressing SPACE or by clicking the fourth button from the left at the very bottom of the screen. Right-click on this window and then give it a try.]])
1344 }
1345
1346 lumberjack_message_01 = {
1347 title = _"Lumberjack’s Spot",
1348 position = "topright",
1349 field = first_lumberjack_field,
1350- body = rt(
1351- 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.]])
1352- ),
1353+ body =
1354+ 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.]]),
1355 h = 300,
1356 w = 350
1357 }
1358@@ -69,20 +60,17 @@
1359 lumberjack_message_02 = {
1360 title = _"Building the Lumberjack",
1361 position = "topright",
1362- body = rt(
1363+ body =
1364 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.]]) ..
1365- paragraphdivider() ..
1366- listitem_bullet(_[[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.]])
1367- ),
1368+ 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.]]),
1369 h = 300
1370 }
1371
1372 lumberjack_message_03a = {
1373 title = _"Building a Connecting Road",
1374 position = "topright",
1375- body = rt(
1376- 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.]])
1377- ),
1378+ body =
1379+ 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.]]),
1380 show_instantly = true,
1381 h = 300,
1382 w = 350
1383@@ -91,9 +79,8 @@
1384 lumberjack_message_03b = {
1385 title = _"Building a Connecting Road",
1386 position = "topright",
1387- body = rt(
1388- 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.]])
1389- ),
1390+ body =
1391+ 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.]]),
1392 show_instantly = true,
1393 h = 300,
1394 w = 350
1395@@ -102,9 +89,8 @@
1396 lumberjack_message_04 = {
1397 title = _"Waiting for the Lumberjack to Go Up",
1398 position = "topright",
1399- body = rt(
1400- 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.]])
1401- ),
1402+ body =
1403+ 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.]]),
1404 h = 300,
1405 w = 350
1406 }
1407@@ -112,31 +98,25 @@
1408 lumberjack_message_05 = {
1409 title = _"Placing Another Flag",
1410 position = "topright",
1411- body = rt(
1412+ body =
1413 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.]]) ..
1414- paragraphdivider() ..
1415- listitem_bullet(_[[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]])
1416- ) ..
1417- rt("image=pics/menu_build_flag.png", p(_"build flag symbol.")
1418- ),
1419+ 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]]) ..
1420+ p(img("pics/menu_build_flag.png") .. _"build flag symbol."),
1421 h = 300,
1422 obj_name = "build_flag_on_road_to_lumberjack",
1423 obj_title = _"Build a flag to divide the road to the lumberjack",
1424- obj_body = rt(
1425+ obj_body =
1426 h1(_"Build a Flag on the Road") ..
1427 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.]]) ..
1428- paragraphdivider() ..
1429- listitem_bullet(_[[Build a blue flag now in the middle of the road that connects your headquarters to your lumberjack’s hut.]])
1430- )
1431+ li(_[[Build a blue flag now in the middle of the road that connects your headquarters to your lumberjack’s hut.]])
1432 }
1433
1434 lumberjack_message_06 = {
1435 title = _"Waiting For the Hut to be Finished",
1436 position = "topright",
1437- body = rt(
1438+ body =
1439 p(_[[Well done! Let’s wait till the hut is finished.]]) ..
1440- 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.]])
1441- ),
1442+ 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.]]),
1443 h = 300,
1444 w = 350
1445 }
1446@@ -144,23 +124,21 @@
1447 flag_built = {
1448 title = _"Waiting for the Hut to be Finished",
1449 position = "topright",
1450- body = rt(
1451+ body =
1452 p(_[[I wanted to teach you how to build new flags, but it seems you have already found out on your own. Well done!]]) ..
1453 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.]]) ..
1454 p(_[[Now we only have to wait till the hut is finished.]]) ..
1455- 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.]])
1456- ),
1457+ 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.]]),
1458 h = 350
1459 }
1460
1461 construction_site_window = {
1462 title = _"The Construction Site",
1463- body = rt(
1464+ body =
1465 h1(_"Let's see the progress") ..
1466 p(_[[If you click on the construction site, a window opens. You can see the wares that are still missing grayed out. You can also see the progress of this construction site.]]) ..
1467 -- The player doesn't know about the statistics yet. First things first.
1468- 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!]])
1469- ),
1470+ 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!]]),
1471 h = 300,
1472 w = 350
1473 }
1474@@ -168,42 +146,35 @@
1475 lumberjack_message_07 = {
1476 title = _"Lumberjack is Done",
1477 position = "topright",
1478- body = rt(
1479- 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 raw stone.]])
1480- ),
1481+ body =
1482+ 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 raw stone.]]),
1483 h = 300,
1484 w = 350
1485 }
1486
1487 inform_about_rocks = {
1488 title = _"Some Rocks Were Found",
1489- body = rt(h1(_"Getting a Quarry Up")) ..
1490- rt(
1491+ body =
1492+ h1(_"Getting a Quarry Up") ..
1493 p(_[[Stones 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.]]) ..
1494- paragraphdivider() ..
1495- listitem_arrow(_[[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.]]) ..
1496- listitem_bullet(_[[Click the ‘OK’ button and then move the view using the cursor keys]])
1497- ),
1498+ li_arrow(_[[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.]]) ..
1499+ li(_[[Click the ‘OK’ button and then move the view using the cursor keys]]),
1500 h = 350,
1501 obj_name = "move_view_with_cursor_keys",
1502 obj_title = _"Move your view with the cursor keys",
1503- obj_body = rt(
1504+ obj_body =
1505 h1(_"Moving Your View") ..
1506 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.]]) ..
1507- paragraphdivider() ..
1508- listitem_arrow(_[[The first one is to use the cursor keys on your keyboard.]]) ..
1509- listitem_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.]]) ..
1510- listitem_arrow(_[[The third one is to use the minimap. It is especially useful for traveling big distances.]])
1511- )
1512+ li_arrow(_[[The first one is to use the cursor keys on your keyboard.]]) ..
1513+ 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.]]) ..
1514+ li_arrow(_[[The third one is to use the minimap. It is especially useful for traveling big distances.]])
1515 }
1516
1517 tell_about_right_drag_move = {
1518 title = _"Other Ways to Move the View",
1519- body = rt(
1520+ body =
1521 p(_[[Excellent. Now there is a faster way to move, using the mouse instead:]]) ..
1522- paragraphdivider() ..
1523- listitem_bullet(_[[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.]])
1524- ),
1525+ 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.]]),
1526 h = 300,
1527 w = 350,
1528 obj_name = "move_view_with_mouse",
1529@@ -213,30 +184,23 @@
1530
1531 tell_about_minimap = {
1532 title = _"Use the minimap",
1533- body = rt(
1534- p(_[[Very good. And now about the minimap. You can open it by clicking on the]])
1535- ) ..
1536- rt("image=pics/menu_toggle_minimap.png", p(_[[minimap button at the bottom of the screen or simply by using the keyboard shortcut ‘m’.]])
1537- ) ..
1538- rt(
1539- 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.]]) ..
1540- paragraphdivider() ..
1541- listitem_bullet(_[[Try it out. Open the minimap, click on a few buttons and try moving around. Close it when you have experimented enough.]])
1542- ),
1543+ body =
1544+ p(_[[Very good. And now about the minimap. You can open it by clicking on the]]) ..
1545+ p(img("pics/menu_toggle_minimap.png") .. _[[minimap button at the bottom of the screen or simply by using the keyboard shortcut ‘m’.]]) ..
1546+ 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.]]) ..
1547+ li(_[[Try it out. Open the minimap, click on a few buttons and try moving around. Close it when you have experimented enough.]]),
1548 h = 350,
1549 obj_name = "use_minimap",
1550 obj_title = _"Learn to use the minimap",
1551- obj_body = rt(
1552- paragraphdivider() ..
1553- listitem_bullet(_[[Open the minimap by using the third button from the left on the bottom of your screen or the ‘m’ key.]]) ..
1554- listitem_bullet(_[[Play around a bit with the different overlays (roads, flags, etc.)]]) ..
1555- listitem_bullet(_[[Close the minimap when you are ready to continue by using the same button or ‘m’ again. Of course, a right-click also works.]])
1556- )
1557+ obj_body =
1558+ li(_[[Open the minimap by using the third button from the left on the bottom of your screen or the ‘m’ key.]]) ..
1559+ li(_[[Play around a bit with the different overlays (roads, flags, etc.)]]) ..
1560+ 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.]])
1561 }
1562
1563 congratulate_and_on_to_quarry = {
1564 title = _"Onward to the Quarry",
1565- body = rt(p(_[[Great. Now about that quarry…]])),
1566+ body = p(_[[Great. Now about that quarry…]]),
1567 h = 200,
1568 w = 250
1569 }
1570@@ -245,45 +209,35 @@
1571 field = first_quarry_field,
1572 position = "topright",
1573 title = _"How to Build a Quarry",
1574- body = rt(
1575+ body =
1576 p(_[[Build a quarry next to those rocks here. Remember how I did it earlier?]]) ..
1577 p(_[[Make sure that you are showing the building spaces, then just click on the space were 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.]]) ..
1578- 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:]])
1579- ) ..
1580- rt("image=pics/big.png", p(_[[Everything can be built on the green house symbol.]])) ..
1581- rt("image=pics/medium.png", p(_[[Everything except for big buildings can be built on a yellow house symbol.]])) ..
1582- rt("image=pics/small.png", p(_[[Red building symbols can only hold small buildings and flags.]])) ..
1583- rt("image=pics/set_flag.png", p(_[[And finally, the yellow flag symbol only allows for flags.]])) ..
1584- rt(
1585- p(_[[If you place something on a field, the surrounding fields might have less space for holding buildings, so choose your fields wisely.]]) ..
1586- paragraphdivider() ..
1587- listitem_bullet(_[[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!]])
1588- ),
1589+ 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:]]) ..
1590+ p(img("pics/big.png") .. _[[Everything can be built on the green house symbol.]]) ..
1591+ p(img("pics/medium.png") .. _[[Everything except for big buildings can be built on a yellow house symbol.]]) ..
1592+ p(img("pics/small.png") .. _[[Red building symbols can only hold small buildings and flags.]]) ..
1593+ p(img("pics/set_flag.png") .. _[[And finally, the yellow flag symbol only allows for flags.]]) ..
1594+ p(_[[If you place something on a field, the surrounding fields might have less space for holding buildings, so choose your fields wisely.]]) ..
1595+ 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!]]),
1596 obj_name = "build_a_quarry",
1597 obj_title = _"Build a quarry next to the rocks",
1598- obj_body = rt(
1599+ obj_body =
1600 h1(_"Build a Quarry") ..
1601- paragraphdivider() ..
1602- listitem_bullet(_[[There are some rocks to the west of your headquarters. Build a quarry right next to them.]]) ..
1603- listitem_arrow(_[[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).]]) ..
1604- listitem_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.]])
1605- )
1606+ li(_[[There are some rocks to the west of your headquarters. Build a quarry right next to them.]]) ..
1607+ li_arrow(_[[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).]]) ..
1608+ 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.]])
1609 }
1610
1611 talk_about_roadbuilding_00a = {
1612 position = "topright",
1613 field = wl.Game().map:get_field(9,12),
1614 title = _"Road Building",
1615- body = rt(
1616- 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]])
1617- ) ..
1618- rt("image=pics/menu_build_way.png", p(_[[the road building symbol.]])) ..
1619- rt(
1620- 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]])) ..
1621- rt("image=pics/menu_abort.png", p(_[[the abort symbol.]])) ..
1622- rt(
1623- 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:]])
1624- ),
1625+ body =
1626+ 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]]) ..
1627+ p(img("pics/menu_build_way.png") .. _[[the road building symbol.]]) ..
1628+ 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]]) ..
1629+ p(img("pics/menu_abort.png") .. _[[the abort symbol.]]) ..
1630+ 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:]]),
1631 show_instantly = true
1632 }
1633
1634@@ -291,16 +245,12 @@
1635 position = "topright",
1636 field = road_building_field,
1637 title = _"Road Building",
1638- body = rt(
1639- p(_[[Excellent! To enter road building mode for any flag, left-click on a flag and select]])
1640- ) ..
1641- rt("image=pics/menu_build_way.png", p(_[[the road building symbol.]])) ..
1642- rt(
1643- 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]])) ..
1644- rt("image=pics/menu_abort.png", p(_[[the abort symbol.]])) ..
1645- rt(
1646- 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:]])
1647- ),
1648+ body =
1649+ p(_[[Excellent! To enter road building mode for any flag, left-click on a flag and select]]) ..
1650+ p(img("pics/menu_build_way.png") .. _[[the road building symbol.]]) ..
1651+ 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]]) ..
1652+ p(img("pics/menu_abort.png") .. _[[the abort symbol.]]) ..
1653+ 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:]]),
1654 show_instantly = true
1655 }
1656
1657@@ -308,7 +258,7 @@
1658 position = "topright",
1659 field = road_building_field,
1660 title = _"Road Building",
1661- body = rt(p(_[[Or, you can directly click the flag where the road should end, like so:]])),
1662+ body = p(_[[Or, you can directly click the flag where the road should end, like so:]]),
1663 h = 200,
1664 w = 250
1665 }
1666@@ -316,26 +266,20 @@
1667 talk_about_roadbuilding_02 = {
1668 position = "topright",
1669 title = _"Road Building",
1670- body = rt(
1671- p(_[[One more thing: around the field where your road would end, you can see different markers. They have the following meaning:]])
1672- ) ..
1673- rt("image=pics/roadb_green.png", p(_[[The terrain is flat here. Your carriers will be very swift on this terrain.]])) ..
1674- rt("image=pics/roadb_yellow.png", p(_[[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.]])) ..
1675- rt("image=pics/roadb_red.png", p(_[[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.]])) ..
1676- rt(
1677+ body =
1678+ p(_[[One more thing: around the field where your road would end, you can see different markers. They have the following meaning:]]) ..
1679+ p(img("pics/roadb_green.png") .. _[[The terrain is flat here. Your carriers will be very swift on this terrain.]]) ..
1680+ p(img("pics/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.]]) ..
1681+ p(img("pics/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.]]) ..
1682 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. If you hold Ctrl or Shift+Ctrl while you finish the road, flags are placed automatically.]]) ..
1683- paragraphdivider() ..
1684- listitem_bullet(_[[Now please rebuild the road between your quarry and your headquarters.]])
1685- ),
1686+ li(_[[Now please rebuild the road between your quarry and your headquarters.]]),
1687 h = 450,
1688 obj_name = "build_road_to_quarry",
1689 obj_title = _"Connect the quarry to the headquarters",
1690- obj_body = rt(
1691+ obj_body =
1692 h1(_"Connect Your Construction Site") ..
1693 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.]]) ..
1694- paragraphdivider() ..
1695- listitem_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.]])
1696- )
1697+ 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.]])
1698 }
1699
1700 quarry_not_connected = {
1701@@ -359,35 +303,30 @@
1702 build_second_quarry = {
1703 position = "topright",
1704 title = _"Build a second quarry",
1705- body = rt(
1706+ body =
1707 p(_[[When there are many rocks, you can consider building another quarry. This will make the stone production faster.]]) ..
1708- paragraphdivider() ..
1709- listitem_bullet(_[[Build a second quarry near the rocks and connect it to your road network.]])
1710- ),
1711+ li(_[[Build a second quarry near the rocks and connect it to your road network.]]),
1712 obj_name = "build_the_second_quarry",
1713 obj_title = _"Build another quarry",
1714- obj_body = rt(
1715+ obj_body =
1716 h1(_"Build another quarry") ..
1717 p(_[[Build a second quarry next to the rocks. Do not forget to connect it to another flag.]]) ..
1718- paragraphdivider() ..
1719- listitem_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.]])
1720- ),
1721+ 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.]]),
1722 h = 300,
1723 w = 350
1724 }
1725
1726 census_and_statistics_00 = {
1727 title = _"Census and Statistics",
1728- body = rt(
1729+ body =
1730 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.]]) ..
1731 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.]]) ..
1732 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.]])
1733- )
1734 }
1735
1736 census_and_statistics_01 = {
1737 title = _"Census and Statistics",
1738- body = rt(p(_[[Now we know what’s going on. Let’s wait for the quarries to finish.]])),
1739+ body = p(_[[Now we know what’s going on. Let’s wait for the quarries to finish.]]),
1740 h = 200,
1741 w = 250
1742 }
1743@@ -395,56 +334,45 @@
1744 teaching_about_messages = {
1745 popup = true,
1746 title = _"Introducing Messages",
1747- body = rt(
1748+ body =
1749 h1(_"Messages") ..
1750 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…]]) ..
1751 p(_[[The message window can be toggled by the button on the very 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.]]) ..
1752- 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: You can check them off in your inbox so that they get a tick-symbol in front of them. Then, you can click the]])
1753- ) ..
1754- rt("image=pics/message_archive.png", p(_[[archive message button to move them into your archive.]])) ..
1755- rt(
1756- paragraphdivider() ..
1757- listitem_bullet(_[[Archive all messages that you currently have in your inbox, including this one.]])
1758- ),
1759+ 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: You can check them off in your inbox so that they get a tick-symbol in front of them. Then, you can click the]]) ..
1760+ p(img("pics/message_archive.png") .. _[[archive message button to move them into your archive.]]) ..
1761+ li(_[[Archive all messages that you currently have in your inbox, including this one.]]),
1762 obj_name = "archive_all_messages",
1763 obj_title = _"Archive all messages in your inbox",
1764- obj_body = rt(
1765+ obj_body =
1766 h1(_"Archive Your Inbox Messages") ..
1767 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. ]]) ..
1768- paragraphdivider() ..
1769- listitem_bullet(_[[Archive all your messages in your inbox now.]]) ..
1770- listitem_arrow(_[[To do so, open the message window by pressing ‘n’ or clicking the rightmost button at the very bottom of the screen. Then mark all messages by checking the check box in front of them. Then, click the ‘Archive All’ button.]])
1771- )
1772+ li(_[[Archive all your messages in your inbox now.]]) ..
1773+ li_arrow(_[[To do so, open the message window by pressing ‘n’ or clicking the rightmost button at the very bottom of the screen. Then mark all messages by checking the check box in front of them. Then, click the ‘Archive All’ button.]])
1774 }
1775
1776 closing_msg_window_00 = {
1777 position = "topright",
1778 field = first_quarry_field,
1779 title = _"Closing Windows",
1780- body = rt(
1781+ body =
1782 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.]]) ..
1783- paragraphdivider() ..
1784- listitem_bullet(_[[First, close this window by pressing the button below, then right-click into the messages window to close it.]])
1785- ),
1786+ li(_[[First, close this window by pressing the button below, then right-click into the messages window to close it.]]),
1787 h = 300,
1788 w = 350,
1789 obj_name = "close_message_window",
1790 obj_title = _"Close the messages window",
1791- obj_body = rt(
1792+ obj_body =
1793 h1(_"Close the Messages Window") ..
1794 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.]]) ..
1795- paragraphdivider() ..
1796- listitem_bullet(_[[Close the messages window now by right-clicking into it.]])
1797- )
1798+ li(_[[Close the messages window now by right-clicking into it.]])
1799 }
1800
1801 closing_msg_window_01 = {
1802 position = "topright",
1803 field = first_quarry_field,
1804 title = _"Closing Windows",
1805- body = rt(
1806- 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 working areas the next time they try to do some work.]])
1807- ),
1808+ body =
1809+ 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 working areas the next time they try to do some work.]]),
1810 h = 300,
1811 w = 350
1812 }
1813@@ -452,68 +380,58 @@
1814 destroy_quarries_message = {
1815 position = "topright",
1816 title = _"Messages Arrived!",
1817- body = rt(
1818+ body =
1819 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:]]) ..
1820- paragraphdivider() ..
1821- listitem_bullet(_[[Burning down the quarry: this is the fastest way of clearing the space. While the worker abandons the building, the wares are lost.]]) ..
1822- listitem_bullet(_[[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.]])
1823- ),
1824+ li(_[[Burning down the quarry: this is the fastest way of clearing the space. While the worker abandons the building, the wares are lost.]]) ..
1825+ li(_[[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.]]),
1826 h = 300,
1827 obj_name = "destroy_quarries",
1828 obj_title = "Destroy the two quarries",
1829- obj_body = rt(
1830+ obj_body =
1831 p(_[[Since our quarries are useless now, you can destroy them and reuse the space later on.]]) ..
1832- paragraphdivider() ..
1833- listitem_arrow(_[[There are two different ways of destroying a building: burning down and dismantling. Try them both out on your quarries.]]) ..
1834- listitem_arrow(_[[Burning down the quarry: This is the fastest way of clearing the space. While the worker abandons the building, the wares are lost.]]) ..
1835- listitem_arrow(_[[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.]])
1836- )
1837+ li_arrow(_[[There are two different ways of destroying a building: burning down and dismantling. Try them both out on your quarries.]]) ..
1838+ li_arrow(_[[Burning down the quarry: This is the fastest way of clearing the space. While the worker abandons the building, the wares are lost.]]) ..
1839+ li_arrow(_[[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.]])
1840 }
1841
1842 introduce_expansion = {
1843 title = _"Expanding Your Territory!",
1844- body = rt(
1845+ body =
1846 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.]]) ..
1847 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, donjons, 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.]]) ..
1848 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.]]) ..
1849- paragraphdivider() ..
1850- listitem_bullet(_[[Let’s try it out now: build a military building on your border.]]) ..
1851- listitem_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.]])
1852- ),
1853+ li(_[[Let’s try it out now: build a military building on your border.]]) ..
1854+ 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.]]),
1855 obj_name = "expand_territory",
1856 obj_title = _"Expand your territory",
1857- obj_body = rt(
1858+ obj_body =
1859 h1(_"Make your territory grow") ..
1860 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.]]) ..
1861- paragraphdivider() ..
1862- listitem_bullet(_[[The Barbarians have four different military buildings you can build: the sentry (small), the barrier and the donjon (both medium) and the fortress (big). Just choose the one you like most.]]) ..
1863- listitem_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.]])
1864- )
1865+ li(_[[The Barbarians have four different military buildings you can build: the sentry (small), the barrier and the donjon (both medium) and the fortress (big). Just choose the one you like most.]]) ..
1866+ 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.]])
1867 }
1868
1869
1870 military_building_finished = {
1871 title = _"Military Site Occupied",
1872- body = rt(
1873+ body =
1874 h1(_"Your territory has just grown!") ..
1875 p(_[[Great. Do you see how your territory has grown since your soldiers entered your new military building?]]) ..
1876- p(_[[Every military building has a certain conquer area – the more expensive the building, the more land it conquers.]])
1877- ),
1878+ p(_[[Every military building has a certain conquer area – the more expensive the building, the more land it conquers.]]),
1879 h = 300,
1880 w = 350
1881 }
1882
1883 conclude_tutorial = {
1884 title = _"Conclusion",
1885- body = rt(
1886+ body =
1887 h1(_"Conclusion") ..
1888 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.]]) ..
1889 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.]]) ..
1890- p(_[[To leave this game and return to the main menu, click on the]])
1891- ) ..
1892- rt("image=pics/menu_options_menu.png", p(_[[‘Options’ menu button on the very left at the bottom of the screen. Then click the]])) ..
1893- rt("image=pics/menu_exit_game.png", p(_[[‘Exit Game’ button.]])) ..
1894- rt(p(_[[Thanks for playing this tutorial. Enjoy Widelands and remember to visit us at]])) ..
1895- rt("text-align=center", "<p font-size=24 font-decoration=underline>http://www.widelands.org</p>"),
1896+ p(_[[To leave this game and return to the main menu, click on the]]) ..
1897+ p(img("menu_options_menu.png") .. _[[‘Options’ menu button on the very left at the bottom of the screen. Then click the]]) ..
1898+ p(img("pics/menu_exit_game.png") .. _[[‘Exit Game’ button.]]) ..
1899+ p(_[[Thanks for playing this tutorial. Enjoy Widelands and remember to visit us at]]) ..
1900+ p("halign=center", "<font size=24 underline=1>http://www.widelands.org</font>"),
1901 h = 450
1902 }
1903
1904=== modified file 'campaigns/tutorial02_warfare.wmf/scripting/texts.lua'
1905--- campaigns/tutorial02_warfare.wmf/scripting/texts.lua 2015-07-26 10:35:59 +0000
1906+++ campaigns/tutorial02_warfare.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
1907@@ -15,199 +15,171 @@
1908
1909 introduction = {
1910 title = _"Introduction",
1911- body = rt(
1912+ body =
1913 h1(_"Soldiers, Training and Warfare") ..
1914 p(_[[In this scenario, I’m going to tell you about soldiers, their training and their profession: warfare. Although Widelands is about building up, not burning down, there is an enemy you sometimes have to defeat. Yet warfare is mainly focused on economics, not on military strategies, and its mechanics deserve explanation.]]) ..
1915- p(_[[I’ve set up a small village that contains the most important buildings. You also have enough wares, so you do not have to take care of your weapons production. In a real game, you will not have this luxury.]])
1916- ),
1917+ p(_[[I’ve set up a small village that contains the most important buildings. You also have enough wares, so you do not have to take care of your weapons production. In a real game, you will not have this luxury.]]),
1918 h = 300
1919 }
1920
1921 abilities = {
1922 position = "topright",
1923 title = _"Soldiers’ abilities",
1924- body = rt(
1925+ body =
1926 p(_[[A new soldier is created like a worker: when a military building needs a soldier, a carrier grabs the needed weapons and armor from a warehouse (or your headquarters) and walks up the road to your new building. Basic Barbarian soldiers do not use armor, they only need an ax.]]) ..
1927 p(_[[Take a look at the soldiers that are on their way to our military buildings. They look different from normal workers: they have a health bar over their head that displays their remaining health, and they have four symbols, which symbolize the individual soldier’s current levels in the four different categories: health, attack, defense and evade.]]) ..
1928- p(_[[If a Barbarian soldier is fully trained, he has level 3 health, level 5 attack, level 0 defense and level 2 evade. This is one fearsome warrior then! The individual abilities have the following meaning:]])
1929- ) ..
1930- rt("image=tribes/barbarians/soldier/hp_level0.png", h2(_"Health:"))..
1931- rt(p(_[[The total life of a soldier. A Barbarian soldier starts with 130 health, and he will gain 28 health with each health level.]])) ..
1932- rt("image=tribes/barbarians/soldier/attack_level0.png", h2(_"Attack:")) ..
1933- rt(p(_[[The amount of damage a soldier will inflict on the enemy when an attack is successful. A Barbarian soldier with attack level 0 inflicts ~14 points of health damage when he succeeds in hitting an enemy. For each attack level, he gains 7 damage points.]])) ..
1934- -- The Atlanteans' image, because the Barbarian one has a white background
1935- rt("image=tribes/atlanteans/soldier/defense_level0.png", h2(_"Defense:")) ..
1936- rt(p(_[[The defense is the percentage that is subtracted from the attack value. The Barbarians cannot train in this skill and therefore have always defense level 0, which means that the damage is always reduced by 3%. If an attacker with an attack value of 35 points hits a Barbarian soldier, the Barbarian will lose 35·0.97 = 34 health.]])) ..
1937- rt("image=tribes/barbarians/soldier/evade_level0.png", h2(_"Evade:")) ..
1938- rt(p(_[[Evade is the chance that the soldier is able to dodge an attack. A level 0 Barbarian has a 25% chance to evade an attack, and this increases in steps of 15% for each level.]]))
1939+ p(_[[If a Barbarian soldier is fully trained, he has level 3 health, level 5 attack, level 0 defense and level 2 evade. This is one fearsome warrior then! The individual abilities have the following meaning:]]) ..
1940+ h2(img("tribes/barbarians/soldier/hp_level0.png") .. _"Health:")..
1941+ p(_[[The total life of a soldier. A Barbarian soldier starts with 130 health, and he will gain 28 health with each health level.]]) ..
1942+ h2(img("tribes/barbarians/soldier/attack_level0.png") .. _"Attack:") ..
1943+ p(_[[The amount of damage a soldier will inflict on the enemy when an attack is successful. A Barbarian soldier with attack level 0 inflicts ~14 points of health damage when he succeeds in hitting an enemy. For each attack level, he gains 7 damage points.]]) ..
1944+ -- The Atlanteans' image, because the Barbarian one has a white background
1945+ h2(img("tribes/atlanteans/soldier/defense_level0.png") .. _"Defense:") ..
1946+ p(_[[The defense is the percentage that is subtracted from the attack value. The Barbarians cannot train in this skill and therefore have always defense level 0, which means that the damage is always reduced by 3%. If an attacker with an attack value of 35 points hits a Barbarian soldier, the Barbarian will lose 35·0.97 = 34 health.]]) ..
1947+ h2(img("tribes/barbarians/soldier/evade_level0.png") .. _"Evade:") ..
1948+ p(_[[Evade is the chance that the soldier is able to dodge an attack. A level 0 Barbarian has a 25% chance to evade an attack, and this increases in steps of 15% for each level.]])
1949 }
1950
1951 battlearena1 = {
1952 position = "topright",
1953 title = _"The Battle Arena",
1954- body = rt(
1955+ body =
1956 p(_[[Now I have talked about training and levels. Let me elaborate on that.]]) ..
1957 p(_[[A newly created soldier has no experience and is not very good at fighting. To make him stronger, you can build training sites.]]) ..
1958 p(_[[One of these training sites is the battle arena. It is a big and expensive building, and it trains soldiers in evade. Since soldiers get very hungry during their workout, this building needs a lot of food and strongbeer. In a real game, you should have a good infrastructure before you build it.]]) ..
1959- paragraphdivider() ..
1960- listitem_bullet(_[[To see evade training in action, build a battle arena.]])
1961- ),
1962+ li(_[[To see evade training in action, build a battle arena.]]),
1963 h = 350,
1964 obj_name = "build_battlearena",
1965 obj_title = _"Build a battle arena",
1966- obj_body = rt(
1967- paragraphdivider() ..
1968- listitem_bullet(_[[Build a battle arena. It is a big building.]]) ..
1969- listitem_arrow(_[[Since the construction will take some time, you can change the game speed using PAGE UP and PAGE DOWN.]])
1970- )
1971+ obj_body =
1972+ li(_[[Build a battle arena. It is a big building.]]) ..
1973+ li_arrow(_[[Since the construction will take some time, you can change the game speed using PAGE UP and PAGE DOWN.]])
1974 }
1975
1976 battlearena2 = {
1977 position = "topright",
1978 title = _"The Battle Arena",
1979- body = rt(
1980+ body =
1981 h1(_"The Battle Arena Has Been Constructed") ..
1982 p(_[[Very good. Our battle arena has been finished, and the soldiers are already walking towards it.]]) ..
1983 -- Not perfectly correct (some training steps need either bread or meat), but we do not want to confuse new players
1984 p(_[[The needed wares are also delivered there. For successful training, you need pitta bread and strongbeer, as well as either fish or meat.]] .. " " ..
1985 _[[For more information, you can have a look at the building’s help window, accessible via the question mark in every building’s window.]]) ..
1986- p(_[[To learn how far your soldiers have progressed in their training, you can have a look at their icons. They are modified by red dots:]])
1987- ) ..
1988- rt("image=tribes/barbarians/soldier/evade_level0.png", p(_[[No red dots means that the soldier is not trained, so he has level 0. All your new recruits have this.]])) ..
1989- rt("image=tribes/barbarians/soldier/evade_level1.png", p(_[[With every successful training step, your soldier becomes stronger. This is indicated by a red dot. This soldier is on level 1 in evade training.]])) ..
1990- rt("image=tribes/barbarians/soldier/evade_level2.png", p(_[[When your soldier has reached the highest possible level (in this case level 2), this is indicated by a white background color.]])),
1991+ p(_[[To learn how far your soldiers have progressed in their training, you can have a look at their icons. They are modified by red dots:]]) ..
1992+ p(img("tribes/barbarians/soldier/evade_level0.png") .. _[[No red dots means that the soldier is not trained, so he has level 0. All your new recruits have this.]]) ..
1993+ p(img("tribes/barbarians/soldier/evade_level1.png") .. _[[With every successful training step, your soldier becomes stronger. This is indicated by a red dot. This soldier is on level 1 in evade training.]]) ..
1994+ p(img("tribes/barbarians/soldier/evade_level2.png") .. _[[When your soldier has reached the highest possible level (in this case level 2), this is indicated by a white background color.]]),
1995 h = 450
1996 }
1997
1998 trainingcamp1 = {
1999 position = "topright",
2000 title = _"The Training Camp",
2001- body = rt(
2002+ body =
2003 h1(_"The Training Camp") ..
2004 p(_[[There is a second training site: the training camp. It is a big building too, and to complement the battle arena, it trains attack and health (remember, the Barbarian soldiers cannot be trained in defense).]]) ..
2005- paragraphdivider() ..
2006- listitem_bullet(_[[Build a training camp.]])
2007- ),
2008+ li(_[[Build a training camp.]]),
2009 h = 300,
2010 obj_name = "build_trainingcamp",
2011 obj_title = _"Build a training camp",
2012- obj_body = rt(
2013+ obj_body =
2014 p(_[[The battle arena only trains the soldiers in evade. To get the strongest possible soldier, you also need to build a training camp, which trains them in attack and health.]]) ..
2015- paragraphdivider() ..
2016- listitem_bullet(_[[Build a training camp.]])
2017- )
2018+ li(_[[Build a training camp.]])
2019 }
2020
2021 trainingcamp2 = {
2022 position = "topright",
2023 title = _"The Training Camp",
2024- body = rt(
2025+ body =
2026 p(_[[Great, our training camp has now been finished, too. Now nothing will hinder us from getting the strongest warriors the world has ever seen.]]) ..
2027 p(_[[To train in the training camp, our soldiers need food like in the battle arena, but no strongbeer. Instead, they need different axes for attack training and helmets for health training.]]) ..
2028 p(_[[This equipment is produced in smithies out of coal, iron, and sometimes gold. You will learn more about this in the second scenario of the Barbarian campaign.]]) ..
2029 p(_[[You should also keep in mind that each of the three tribes in Widelands has its own way of training, so the buildings and wares are different. Also, the ability levels cannot be compared: an Imperial soldier with evade level 0 has a 30% chance of evading, while a Barbarian soldier at the same level only has a 25% chance.]])
2030- )
2031 }
2032
2033 heroes_rookies = {
2034 position = "topright",
2035 title = _"Heroes and Rookies",
2036- body = rt(
2037+ body =
2038 h1(_"Heroes and Rookies") ..
2039 p(_[[While our soldiers are training, let me tell you what we can do with them.]]) ..
2040 p(_[[In every military building, you can set the preference for heroes (trained soldiers) or rookies. From time to time, a soldier will walk out of the building and be replaced by a stronger/weaker one automatically.]]) ..
2041 p(_[[The initial setting depends on the type of the building. For the Barbarians, the sentry is the only building that prefers rookies by default. You should change this setting to fit your current needs.]]) ..
2042 p(_[[When you are expanding into no man’s land, you can make your buildings prefer rookies. When you are planning to attack, send heroes into that region. Conquered buildings always prefer heroes.]])
2043- )
2044 }
2045
2046 soldier_capacity = {
2047 position = "topright",
2048 title = _"Soldier capacity",
2049- body = rt(
2050+ body =
2051 h1(_"Adjusting the number of soldiers") ..
2052 p(_[[There is another way how you can control the strength of a military building: by the number of soldiers stationed there. Just click on the arrow buttons to decrease or increase the desired number of soldiers. Every building has a maximum capacity. In case of the barrier, it is five, for example.]]) ..
2053 p(_[[If you wish to send a certain soldier away, you can simply click on it. It will then be replaced by another soldier.]]) ..
2054 p(_[[Let me also describe what the numbers in the statistics string mean. This string can contain up to three numbers, e.g. ‘1 (+5) soldier (+2)’.]]) ..
2055- paragraphdivider() ..
2056- listitem_bullet(_[[The first number describes how many soldiers are currently in this building. In this example, only one soldier is left inside (each military building is always guarded by at least one soldier).]]) ..
2057- listitem_bullet(_[[The second number tells you how many additional soldiers reside in this building, but are currently outside. The five soldiers may be attacking an enemy. They will return when they have been successful.]]) ..
2058- listitem_bullet(_[[The third number indicates the missing soldiers. From the eight soldiers (1 + 5 + 2) you wish to have here, two may have died. They will be replaced by new soldiers from your warehouse, if possible.]])
2059- )
2060+ li(_[[The first number describes how many soldiers are currently in this building. In this example, only one soldier is left inside (each military building is always guarded by at least one soldier).]]) ..
2061+ li(_[[The second number tells you how many additional soldiers reside in this building, but are currently outside. The five soldiers may be attacking an enemy. They will return when they have been successful.]]) ..
2062+ li(_[[The third number indicates the missing soldiers. From the eight soldiers (1 + 5 + 2) you wish to have here, two may have died. They will be replaced by new soldiers from your warehouse, if possible.]])
2063 }
2064
2065 dismantle = {
2066 position = "topright",
2067 title = _"Dismantle your sentry",
2068- body = rt(
2069+ body =
2070 h1(_"Dismantling military buildings") ..
2071 p(_[[You can only reduce the number of soldiers to one. The last soldier of a building will never come out (unless this building is attacked). If you want to have your soldier elsewhere, you will have to dismantle the building (buildings of an alien tribe cannot be dismantled, only be burned down).]]) ..
2072 p(_[[However, destroying a military building is always linked with a risk: the land is still yours, but it is no longer protected. Any enemy that builds his own military sites can take over that land without a fight, causing your buildings to burst into flames. Furthermore, some parts of the land can now be hidden under the fog of war. You should therefore only dismantle military buildings deep inside your territory where you are safe from enemies.]]) ..
2073 p(_[[Have you seen your sentry? Since it cannot contain many soldiers and is next to a stronger barrier, it is rather useless.]]) ..
2074- paragraphdivider() ..
2075 -- TRANSLATORS: 'it' refers to the Barbarian sentry
2076- listitem_bullet(_[[Dismantle it.]])
2077- ) ..
2078- rt(p(_[[You can also use this opportunity to become familiar with the other options: the heroes/rookies preference and the capacity.]])),
2079+ li(_[[Dismantle it.]]) ..
2080+ p(_[[You can also use this opportunity to become familiar with the other options: the heroes/rookies preference and the capacity.]]),
2081 obj_name = "dismantle_sentry",
2082 obj_title = _"Dismantle your north-western sentry",
2083- obj_body = rt(
2084+ obj_body =
2085 p(_[[You can control the number of soldiers stationed at a military site with the arrow buttons. If you want to get even your last soldier out, you will have to destroy it. However, it then will no longer protect your territory, which will make it vulnerable to hostile attacks.]]) ..
2086- paragraphdivider() ..
2087- listitem_bullet(_[[Dismantle your sentry in the north-west, next to the barrier.]])
2088- )
2089+ li(_[[Dismantle your sentry in the north-west, next to the barrier.]])
2090 }
2091
2092 fortress_enhancement = {
2093 position = "topright",
2094 title = _"Enhance Your Fortress",
2095- body = rt(
2096+ body =
2097 h1(_"Enhancing Buildings") ..
2098 p(_[[Well done. Now you know how to draw back your soldiers from the places where you don’t need them. It is time to tell you how to reinforce your front line.]]) ..
2099 p(_[[Your fortress is already quite strong and conquers a lot of space. But there is an even bigger building: the citadel.]]) ..
2100 p(_[[Citadels can’t be built directly. Instead, you’ll have to construct a fortress first and then enhance it to a citadel. To do so, click on the fortress, then choose the ‘Enhance to Citadel’ button.]]) ..
2101 p(_[[Your soldiers will leave the fortress while the construction is going on. This means that your fortress will lose its military influence, as I described above.]]) ..
2102- listitem_bullet(_[[Enhance your fortress to a citadel now.]])
2103- ),
2104+ li(_[[Enhance your fortress to a citadel now.]]),
2105 obj_name = "enhance_fortress",
2106 obj_title = _"Enhance your fortress to a citadel",
2107- obj_body = rt(
2108+ obj_body =
2109 h1(_"Enhance Your Fortress") ..
2110- paragraphdivider() ..
2111- listitem_bullet(_[[Enhance your fortress to a mighty citadel.]]) ..
2112- listitem_arrow(_[[The citadel can house 12 soldiers, and it is the biggest military building the Barbarians can build. It also costs a lot of resources and takes a long time to build. It is most suited to guard strategically important points like constricted points or mountains.]])
2113- )
2114+ li(_[[Enhance your fortress to a mighty citadel.]]) ..
2115+ li_arrow(_[[The citadel can house 12 soldiers, and it is the biggest military building the Barbarians can build. It also costs a lot of resources and takes a long time to build. It is most suited to guard strategically important points like constricted points or mountains.]])
2116 }
2117
2118 attack_enemy = {
2119 position = "topright",
2120 field = wl.Game().map:get_field(29,4), -- show the lost territory
2121 title = _"Defeat your Enemy",
2122- body = rt(
2123+ body =
2124 h1(_"Defeat the Enemy") ..
2125 p(_[[Great work, the citadel is finished. But what’s that? A hostile tribe has settled next to us while the citadel was under construction! Do you see how they took away a part of our land? And our lumberjack has now lost his place of work. This is what I was talking about. Let’s take our land back and defeat the enemy!]]) ..
2126 p(_[[To attack a building, click on its doors, choose the number of soldiers that you wish to send and click on the ‘Attack’ button.]] .. " " .. _[[Your soldiers will come from all nearby military buildings. Likewise, the defenders will come from all nearby military buildings of the enemy and intercept your forces.]]) ..
2127- paragraphdivider() ..
2128- listitem_bullet(_[[Attack and conquer all military buildings of the enemy and destroy their headquarters.]])
2129- ),
2130+ li(_[[Attack and conquer all military buildings of the enemy and destroy their headquarters.]]),
2131 h = 350,
2132 obj_name = "defeated_the_empire",
2133 obj_title = _"Defeat the enemy tribe",
2134- obj_body = rt(
2135+ obj_body =
2136 h1(_"Defeat Your Enemy") ..
2137- paragraphdivider() ..
2138- listitem_bullet(_[[Defeat the nearby enemy.]]) ..
2139- listitem_arrow(_[[To attack a building, click on its doors, choose the number of soldiers that you wish to send and click on the ‘Attack’ button.]])
2140- )
2141+ li(_[[Defeat the nearby enemy.]]) ..
2142+ li_arrow(_[[To attack a building, click on its doors, choose the number of soldiers that you wish to send and click on the ‘Attack’ button.]])
2143 }
2144
2145 conclude_tutorial = {
2146 title = _"Conclusion",
2147- body = rt(
2148+ body =
2149 h1(_"Conclusion") ..
2150 p(_[[Thank you for playing this tutorial. I hope you enjoyed it and you learned how to create and train soldiers, how to control where they go and how to defeat an enemy. Did you see how easily you could overwhelm your enemy? Having trained soldiers is a huge advantage.]]) ..
2151 p(_[[But a war is expensive, and not always the path leading to the goal. When setting up a new game, you can also choose peaceful win conditions. You should definitely try them out, they’re worth it.]]) ..
2152 p(_[[You are now ready to play the campaigns. They will teach you about the different economies of the tribes. You can also play the remaining tutorials, but they are not crucial for succeeding in the campaigns.]])
2153- )
2154 }
2155-
2156
2157=== modified file 'campaigns/tutorial03_seafaring.wmf/scripting/texts.lua'
2158--- campaigns/tutorial03_seafaring.wmf/scripting/texts.lua 2015-05-31 13:45:13 +0000
2159+++ campaigns/tutorial03_seafaring.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
2160@@ -18,11 +18,10 @@
2161 position = "topright",
2162 field = sf,
2163 title = _"Seafaring",
2164- body = rt(
2165+ body =
2166 h1(_"Seafaring Tutorial") ..
2167 p(_[[Welcome back. In this tutorial, you are going to learn the most important things about seafaring, that is ships, ports, and expedition.]]) ..
2168- p(_[[But let me first give you an overview about your territory: here in the south, you have a whole economy with almost everything you need.]])
2169- ),
2170+ p(_[[But let me first give you an overview about your territory: here in the south, you have a whole economy with almost everything you need.]]),
2171 h = 250
2172 }
2173
2174@@ -30,22 +29,20 @@
2175 position = "topright",
2176 field = castle_field,
2177 title = _"The Northern Part",
2178- body = rt(
2179+ body =
2180 p(_[[Here in the northern part, you only have a goldmine and a warehouse. While the miners are supplied well with food, there is no way to transport the gold ore to our smelting works in the southern part.]]) ..
2181 p(_[[We have tried to build a road, but the mountain is too wide and too steep. We therefore have only one possibility: we need to establish a sea lane between these two parts.]]) ..
2182- p(_[[But I don’t want to rush you: you have just arrived here and you would probably like to have a closer look at your camp. I will also take a short break and be back soon.]])
2183- ),
2184+ p(_[[But I don’t want to rush you: you have just arrived here and you would probably like to have a closer look at your camp. I will also take a short break and be back soon.]]),
2185 h = 350
2186 }
2187
2188 tell_about_port = {
2189 position = "topright",
2190 title = _"Ports",
2191- body = rt(
2192+ body =
2193 h1(_"Ports") ..
2194 p(_[[For everything you do on the high seas, you need a port at the shore. Ports are like headquarters: they can store wares, workers and soldiers. The soldiers inside will automatically come out when an enemy attacks the port.]]) ..
2195- p(_[[Additionally, ports offer the possibility of transporting wares via ships. When you click on the port you already have, you will notice two additional tabs: wares and workers in the dock. They are waiting for a ship to transport them to another port. Currently, there are none because we have not yet built a second port. So let’s change this!]])
2196- ),
2197+ p(_[[Additionally, ports offer the possibility of transporting wares via ships. When you click on the port you already have, you will notice two additional tabs: wares and workers in the dock. They are waiting for a ship to transport them to another port. Currently, there are none because we have not yet built a second port. So let’s change this!]]),
2198 h = 350
2199 }
2200
2201@@ -53,82 +50,67 @@
2202 position = "topright",
2203 field = second_port_field,
2204 title = _"Building ports",
2205- body = rt(
2206+ body =
2207 h1(_"How to build a port") ..
2208- p(_[[Ports are big buildings, but they can only be built at special locations: those marked with the]])
2209- ) ..
2210- rt("image=pics/port.png", p(_[[blue port space icon.]])) ..
2211- rt(
2212+ p(_[[Ports are big buildings, but they can only be built at special locations: those marked with the]]) ..
2213+ p(img("pics/port.png") .. _[[blue port space icon.]]) ..
2214 p(_[[Port spaces are set by the map designer, so a map will either contain them or not. They might, however, be hidden under trees or be blocked by surrounding buildings.]]) ..
2215 p(_[[You might already have noticed that you have such an icon next to your castle.]]) ..
2216- paragraphdivider() ..
2217- listitem_bullet(_[[Build a port in the northern part of your camp.]])
2218- ),
2219+ li(_[[Build a port in the northern part of your camp.]]),
2220 obj_name = "build_port",
2221 obj_title = _"Build a port in the northern part of your camp.",
2222- obj_body = rt(
2223+ obj_body =
2224 h1(_"Build a port") ..
2225 p(_[[You always need a port when you want to transport wares with a ship.]]) ..
2226- paragraphdivider() ..
2227- listitem_bullet(_[[Build a port next to your castle, on the blue port space icon.]]) ..
2228- listitem_arrow(_[[Ports are built like normal buildings, but are only available on blue port spaces. Just click on a field with the icon and the building menu automatically offers you to build a port.]]) ..
2229- listitem_arrow(_[[Although ports act as warehouses, you should not build more than necessary: they cost quartz, diamonds and gold, which makes them quite expensive.]])
2230- ),
2231+ li(_[[Build a port next to your castle, on the blue port space icon.]]) ..
2232+ li_arrow(_[[Ports are built like normal buildings, but are only available on blue port spaces. Just click on a field with the icon and the building menu automatically offers you to build a port.]]) ..
2233+ li_arrow(_[[Although ports act as warehouses, you should not build more than necessary: they cost quartz, diamonds and gold, which makes them quite expensive.]]),
2234 }
2235
2236 tell_about_shipyard = {
2237 position = "topright",
2238 title = _"Constructing ships",
2239- body = rt(
2240+ body =
2241 h1(_"Let’s build ships") ..
2242 p(_[[Great. Your port has just been finished. Now we need some ships.]]) ..
2243 p(_[[Ships are constructed in a shipyard by a shipwright. We have to build one somewhere close to the shore.]]) ..
2244- paragraphdivider() ..
2245- listitem_bullet(_[[Build a shipyard close to the coast. It is a medium building.]])
2246- ),
2247+ li(_[[Build a shipyard close to the coast. It is a medium building.]]),
2248 h = 300,
2249 obj_name = "build_shipyard",
2250 obj_title = _"Build a shipyard",
2251- obj_body = rt(
2252+ obj_body =
2253 h1(_"Build a shipyard") ..
2254 p(_[[Ships are produced in a shipyard.]]) ..
2255- paragraphdivider() ..
2256- listitem_bullet(_[[Build a shipyard close to the shore of the southern part of your territory.]]) ..
2257- listitem_arrow(_[[The shipyard is a medium building. Although it can be built everywhere on the map, the shipwright only works when he is close to the water and there are no trees or roads at the shoreline.]])
2258- ),
2259+ li(_[[Build a shipyard close to the shore of the southern part of your territory.]]) ..
2260+ li_arrow(_[[The shipyard is a medium building. Although it can be built everywhere on the map, the shipwright only works when he is close to the water and there are no trees or roads at the shoreline.]]),
2261 }
2262
2263 tell_about_ships = {
2264 position = "topright",
2265 title = _"Constructing ships",
2266- body = rt(
2267+ body =
2268 h1(_"Waiting for the ships") ..
2269 p(_[[Very good. Your shipyard is finished and your shipwright immediately started working. For the construction of ships, he needs logs, planks and spidercloth, which will be transported to the shipyard.]] .. " " ..
2270 _[[The shipwright will take the ware he needs to a free spot at the shoreline and build a ship there. When the first ship is finished, it will launch onto the sea, and the shipwright will construct another one.]]) ..
2271- paragraphdivider() ..
2272- listitem_bullet(_[[We should wait until we have two ships. That should be enough for now.]]) ..
2273- listitem_arrow(_[[You need to stop your shipyard when you have enough ships. Otherwise, your shipwright will consume all your logs and spidercloth, producing dozens of ships.]])
2274- ) ..
2275- rt("image=pics/stop.png",p(_[[This is the icon for stopping production. You will find it in the building window.]])),
2276+ li(_[[We should wait until we have two ships. That should be enough for now.]]) ..
2277+ li_arrow(_[[You need to stop your shipyard when you have enough ships. Otherwise, your shipwright will consume all your logs and spidercloth, producing dozens of ships.]]) ..
2278+ p(img("pics/stop.png") .. _[[This is the icon for stopping production. You will find it in the building window.]]),
2279 obj_name = "wait_for_ships",
2280 obj_title = _"Construct two ships",
2281- obj_body = rt(
2282+ obj_body =
2283 p(_[[Ships are constructed automatically when the shipyard is complete and the needed wares have been delivered.]]) ..
2284- paragraphdivider() ..
2285- listitem_bullet(_[[Wait until the shipwright has constructed two ships.]]) ..
2286- listitem_arrow(_[[Do not forget to stop your shipyard when you have enough ships.]])
2287- )
2288+ li(_[[Wait until the shipwright has constructed two ships.]]) ..
2289+ li_arrow(_[[Do not forget to stop your shipyard when you have enough ships.]])
2290 }
2291
2292 expedition1 = {
2293 position = "topright",
2294 title = _"No Iron",
2295- body = rt(
2296+ body =
2297 h1(_"We lack iron") ..
2298 p(_[[The second ship might not be finished yet, but we have an urgent problem.]]) ..
2299 p(_[[As you surely have already noticed, there is no iron in the mountain in the west. We have plenty of coal and gold ore, but without iron ore, we cannot produce any tools.]]) ..
2300- p(_[[Although it might take long and be expensive and not without dangers – who knows what monsters live in the sea? – I see no other possibility: we will have to undertake an expedition to the unknown seas.]])
2301- ),
2302+ p(_[[Although it might take long and be expensive and not without dangers – who knows what monsters live in the sea? – I see no other possibility: we will have to undertake an expedition to the unknown seas.]]),
2303 h = 300
2304 }
2305
2306@@ -136,58 +118,47 @@
2307 position = "topright",
2308 -- TRANSLATORS: This shall be the beginning of a poem
2309 title = _"A trip by the sea, what fun it can be",
2310- body = rt(
2311+ body =
2312 h1(_"Expeditions") ..
2313- p(_[[During an expedition, you send a ship out to discover new islands and maybe found a colony there.]])
2314- ) ..
2315- rt("image=pics/start_expedition.png",p(_[[Expeditions can be started in every port. Then, all needed wares are transported to that port. The wares are exactly those your tribe needs to build a port (your goal is to build a port far away from home, so this is not surprising), and of course you need a builder, too. When everything is prepared, a ship will come and pick it up.]] .. " " ..
2316+ p(_[[During an expedition, you send a ship out to discover new islands and maybe found a colony there.]]) ..
2317+ p(img("pics/start_expedition.png") .. _[[Expeditions can be started in every port. Then, all needed wares are transported to that port. The wares are exactly those your tribe needs to build a port (your goal is to build a port far away from home, so this is not surprising), and of course you need a builder, too. When everything is prepared, a ship will come and pick it up.]] .. " " ..
2318 _[[You can check out the needed wares in the fifth tab of your port (it will appear when you’ve started an expedition).]]) ..
2319 p(_[[Now try this out. I will tell you later what the next steps are.]]) ..
2320- paragraphdivider() ..
2321- listitem_bullet(_[[Start an expedition in any of your ports.]])
2322- ),
2323+ li(_[[Start an expedition in any of your ports.]]),
2324 obj_name = "start_expedition",
2325 obj_title = _"Start an expedition",
2326- obj_body = rt(
2327- paragraphdivider() ..
2328- listitem_bullet(_[[Start an expedition.]])
2329- ) ..
2330- rt("image=pics/start_expedition.png",p(_[[To do so, click on the ‘Start Expedition’ button in any port. A new tab where you can see the needed wares will appear.]])
2331- )
2332+ obj_body =
2333+ li(_[[Start an expedition.]]) ..
2334+ p(img("pics/start_expedition.png") .. _[[To do so, click on the ‘Start Expedition’ button in any port. A new tab where you can see the needed wares will appear.]])
2335 }
2336
2337 expedition3 = {
2338 position = "topright",
2339 title = _"Off to greener pastures",
2340- body = rt(
2341+ body =
2342 h1(_"Start your expedition") ..
2343 p(_[[Your expedition ship is ready. It is waiting for your orders in front of your port. It isn’t transporting wares anymore. Use its buttons to send your ship in any of the six main directions of the Widelands map. When it has reached a coastline, you can make it travel around the coast, where it will look for suitable places for landing.]] .. " " ..
2344 _[[Once a port space has been found, you can construct a new port with the button in the center of the ship’s control window.]]) ..
2345 p(_[[The wares will then be unloaded, and the ship will take up the task of transporting wares once again. The builder will start his work and build a port.]]) ..
2346- paragraphdivider() ..
2347- listitem_bullet(_[[Search for an island with a mountain, and look for a port space there. Colonize the island.]])
2348- ),
2349+ li(_[[Search for an island with a mountain, and look for a port space there. Colonize the island.]]),
2350 obj_name = "found_settlement",
2351 obj_title = _"Found a settlement",
2352- obj_body = rt(
2353- paragraphdivider() ..
2354- listitem_bullet(_[[Navigate your ship to an island that could contain iron ore.]]) ..
2355- listitem_arrow(_[[When you click on the expedition ship, a window opens where you can control your ship.]]) ..
2356- listitem_bullet(_[[When you have found a suitable port space, build a port there.]])
2357- )
2358+ obj_body =
2359+ li(_[[Navigate your ship to an island that could contain iron ore.]]) ..
2360+ li_arrow(_[[When you click on the expedition ship, a window opens where you can control your ship.]]) ..
2361+ li(_[[When you have found a suitable port space, build a port there.]])
2362 }
2363
2364 conclusion = {
2365 position = "topright",
2366 field = port_on_island,
2367 title = _"Conclusion",
2368- body = rt(
2369+ body =
2370 h1(_"Congratulations") ..
2371 p(_[[You’ve lead the expedition to a successful end and founded a new colony. I’ve sent out some geologists – they already report that they’ve found some iron ore.]]) ..
2372 p(_[[In this scenario, you’ve learned everything about seafaring: how to build ports and ships and how to send out an expedition. Remember that expeditions are sometimes the fastest way to reach essential resources – and sometimes the only one.]]) ..
2373 p(_[[But I want to speak a word of warning. Ports are like headquarters: they can be attacked by a nearby enemy. While your headquarters has soldiers to defend it, your newly built port won’t. You should therefore avoid settling next to an enemy.]]) ..
2374- p(_[[On this map, there is no enemy to fear. As always, you can continue playing and watch how the ships deliver wares to the island when you construct some buildings there. There is also another island where you can build a port.]])
2375- ),
2376+ p(_[[On this map, there is no enemy to fear. As always, you can continue playing and watch how the ships deliver wares to the island when you construct some buildings there. There is also another island where you can build a port.]]),
2377 h = 450
2378 }
2379
2380
2381=== modified file 'campaigns/tutorial04_economy.wmf/scripting/texts.lua'
2382--- campaigns/tutorial04_economy.wmf/scripting/texts.lua 2015-06-10 16:50:57 +0000
2383+++ campaigns/tutorial04_economy.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
2384@@ -16,12 +16,11 @@
2385
2386 intro1 = {
2387 title = _"Your Economy and its Settings",
2388- body = rt(
2389+ body =
2390 h1(_[[Economy]]) ..
2391 p(_[[Welcome back. In this tutorial, I’ll tell you what you can do to check how well your economy works.]]) ..
2392 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.]]) ..
2393- p(_[[This is what I’ll show you in this tutorial: what actions can you take to define those general conditions?]])
2394- ),
2395+ p(_[[This is what I’ll show you in this tutorial: what actions can you take to define those general conditions?]]),
2396 h = 300
2397 }
2398
2399@@ -29,21 +28,19 @@
2400 position = "topright",
2401 field = field_near_border,
2402 title = _"A Peaceful Land",
2403- body = rt(
2404+ body =
2405 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.]]) ..
2406 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.]]) ..
2407- p(_[[You had not been prepared for war, and you have to hurry now to build up an army.]])
2408- ),
2409+ p(_[[You had not been prepared for war, and you have to hurry now to build up an army.]]),
2410 h = 300
2411 }
2412
2413 tavern_burnt_down = {
2414 position = "topright",
2415 title = _"The Tavern is Burning!",
2416- body = rt(
2417+ body =
2418 h1(_[[An accident]]) ..
2419- 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.]])
2420- ),
2421+ 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.]]),
2422 w = 300,
2423 h = 250
2424 }
2425@@ -51,54 +48,43 @@
2426 building_stat = {
2427 position = "topright",
2428 title = _"Building statistics",
2429- body = rt(
2430+ body =
2431 h1(_[[Check out your taverns]]) ..
2432- p(_[[At first, we should find out how many taverns we currently have. Widelands offers you a window where you can easily check this.]])
2433- ) ..
2434- rt("image=pics/menu_toggle_menu.png",p(_[[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.]])) ..
2435- rt("image=pics/menu_building_stats.png",p(_[[Afterwards, choose the ‘Building statistics’.]]) ..
2436- paragraphdivider() ..
2437- listitem_bullet(_[[Open the building statistics window.]]) ..
2438- listitem_arrow(_[[You can also use the hotkey ‘b’.]])
2439- ),
2440+ p(_[[At first, we should find out how many taverns we currently have. Widelands offers you a list where you can easily check this.]]) ..
2441+ p(img("pics/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.]]) ..
2442+ p(img("pics/menu_building_stats.png") .. _[[Afterwards, choose the ‘Building statistics’.]]) ..
2443+ li(_[[Open the building statistics window.]]) ..
2444+ li(_[[You can also use the hotkey ‘b’.]]),
2445 h = 350,
2446 obj_name = "open_building_stat",
2447 obj_title = _"Open the building statistics window.",
2448 obj_body =
2449- rt("image=pics/menu_building_stats.png", p(_[[The building statistics window gives you an overview over the buildings you have.]])) ..
2450- rt(
2451- paragraphdivider() ..
2452+ p(img("pics/menu_building_stats.png") .. _[[The building statistics window gives you an overview over the buildings you have.]]) ..
2453 -- TRANSLATORS: "it" refers to the building statistics window
2454- listitem_bullet(_[[Open it. You can access it from the statistics menu.]]) ..
2455- listitem_arrow(_[[The statistics menu is accessed via the second button at the bottom. It provides several windows that give you information about the game.]])
2456- )
2457+ li(_[[Open it. You can access it from the statistics menu.]]) ..
2458+ 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.]])
2459 }
2460
2461 explain_building_stat = {
2462 title = _"Building Statistics",
2463- body = rt(
2464+ body =
2465 p(_[[This is the building statistics window. It shows you all buildings you can own, sorted by their size.]]) ..
2466 p(_[[Let me now explain what all those numbers mean:]]) ..
2467- paragraphdivider() ..
2468- listitem_bullet(_[[‘2/1’ below the quarry: This means that you have two quarries, plus another one which is under construction.]]) ..
2469- listitem_bullet(_[[‘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.]]) ..
2470- listitem_bullet(_[[‘2/4’ below your sentry: For military buildings, the stationed soldiers are shown instead of a productivity. You want to have four soldiers in your sentries, but only two soldiers are stationed in this kind of building. This leaves two vacant positions — we really need more soldiers.]]) ..
2471- listitem_arrow(_[[In both cases, the color (green - yellow - red) signals you how good the value is.]]) ..
2472- listitem_bullet(_[[If you click on a building, you can scroll through the buildings of the selected type.]]) ..
2473- listitem_bullet(_[[If you don’t have any building of a particular building type, it will be shown greyed out.]])
2474- ) ..
2475- rt(
2476+ li(_[[‘2/1’ below the quarry: This means that you have two quarries, plus another one which is under construction.]]) ..
2477+ 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.]]) ..
2478+ li(_[[‘2/4’ below your sentry: For military buildings, the stationed soldiers are shown instead of a productivity. You want to have four soldiers in your sentries, but only two soldiers are stationed in this kind of building. This leaves two vacant positions — we really need more soldiers.]]) ..
2479+ li_arrow(_[[In both cases, the color (green - yellow - red) signals you how good the value is.]]) ..
2480+ li(_[[If you click on a building, you can scroll through the buildings of the selected type.]]) ..
2481+ li(_[[If you don’t have any building of a particular building type, it will be shown greyed out.]]) ..
2482 h2(_[[Now it’s your turn]]) ..
2483- 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.]])
2484- ),
2485+ 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.]]),
2486 obj_name = "check_taverns",
2487 obj_title = _"Look up your number of taverns in the building statistics window.",
2488- obj_body = rt(
2489- listitem_bullet(_[[Choose the ‘Medium Buildings’ tab in the building statistics window.]]) ..
2490- listitem_bullet(_[[Look up how many taverns you have.]]) ..
2491- listitem_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.]]) ..
2492- listitem_bullet(_[[Close the building statistics window when you are done.]])
2493- )
2494+ obj_body =
2495+ li(_[[Choose the ‘Medium Buildings’ tab in the building statistics window.]]) ..
2496+ li(_[[Look up how many taverns you have.]]) ..
2497+ 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.]]) ..
2498+ li(_[[Close the building statistics window when you are done.]])
2499 }
2500
2501 reopen_building_stat = {
2502@@ -116,9 +102,8 @@
2503 obj_title = _"Open the building statistics window again.",
2504 obj_body = rt(
2505 p(_[[You closed the building statistics window, although you have not yet looked up the number of taverns.]]) ..
2506- paragraphdivider() ..
2507 -- TRANSLATORS: "it" refers to the building statistics window.
2508- listitem_bullet(_[[Please reopen it and choose the second tab (medium buildings).]])
2509+ li(_[[Please reopen it and choose the second tab (medium buildings).]])
2510 ),
2511 h = 250
2512 }
2513@@ -126,63 +111,52 @@
2514 inventory1 = {
2515 position = "topright",
2516 title = _"Stock",
2517- body = rt(
2518+ body =
2519 h1(_[[Check for rations]]) ..
2520- 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.]])
2521- ) ..
2522- rt("image=pics/menu_stock.png",p(_[[Click on the ‘Stock’ button.]])) ..
2523- rt(
2524- paragraphdivider() ..
2525- listitem_arrow(_[[You can also use the hotkey ‘i’ (as in ‘inventory’) to access this window quickly.]])
2526- ),
2527+ 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.]]) ..
2528+ p(img("pics/menu_stock.png") .. _[[Click on the ‘Stock’ button.]]) ..
2529+ li_arrow(_[[You can also use the hotkey ‘i’ (as in ‘inventory’) to access this window quickly.]]),
2530 h = 300,
2531 obj_name = "open_inventory",
2532 obj_title = _"Open your stock window.",
2533- obj_body = rt(
2534+ obj_body =
2535 p(_[[The stock menu window gives you an overview over the wares you currently have.]]) ..
2536- paragraphdivider() ..
2537 -- TRANSLATORS: "it" refers to the stock menu window
2538- listitem_bullet(_[[Open it. You can access it from the statistics menu.]]) ..
2539- listitem_arrow(_[[The statistics menu is accessed via the second button at the bottom. It provides several windows that give you information about the game.]])
2540- )
2541+ li(_[[Open it. You can access it from the statistics menu.]]) ..
2542+ 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.]])
2543 }
2544
2545 inventory2 = {
2546 title = _"Stock",
2547- body = rt(
2548+ body =
2549 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.]]) ..
2550 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.]]) ..
2551 p(_[[The second tab shows you all your workers, again those on roads and in buildings summed up.]]) ..
2552- p(_[[Now have a look at these two tabs. When you click on the]])) ..
2553- rt("image=pics/menu_tab_wares_warehouse.png",p(_[[third tab (‘Wares in warehouses’), I’ll continue.]])
2554- ),
2555+ p(_[[Now have a look at these two tabs. When you click on the]]) ..
2556+ p(img("pics/menu_tab_wares_warehouse.png") .. _[[third tab (‘Wares in warehouses’), I’ll continue.]]),
2557 h = 350,
2558 show_instantly = true,
2559 obj_name = "switch_stock_tab",
2560 obj_title = _"Switch to the third tab in the stock menu window.",
2561- obj_body = rt(
2562+ obj_body =
2563 p(_[[Have a look at the first two tabs in the stock menu window. They show all the wares and workers you have.]]) ..
2564- paragraphdivider() ..
2565- listitem_bullet(_[[When you have seen enough, switch to the third tab.]])
2566- ),
2567+ li(_[[When you have seen enough, switch to the third tab.]]),
2568 }
2569
2570 inventory3 = {
2571 title = _"Stock",
2572- body = rt(
2573+ body =
2574 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.]]) ..
2575 p(_[[The fourth tab shows the same thing for workers.]]) ..
2576- p(_[[The third tab tells you that there are no rations left in your headquarters – that’s not good!]])
2577- ),
2578+ p(_[[The third tab tells you that there are no rations left in your headquarters – that’s not good!]]),
2579 show_instantly = true,
2580 h = 300
2581 }
2582
2583 reopen_stock_menu = {
2584 title = _"You closed the stock window!",
2585- body = rt(
2586- 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?]])
2587- ),
2588+ body =
2589+ 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?]]),
2590 show_instantly = true,
2591 w = 300,
2592 h = 250
2593@@ -191,51 +165,43 @@
2594 reopen_stock_menu_obj = {
2595 obj_name = "open_stock_menu_again",
2596 obj_title = _"Open the stock window again.",
2597- obj_body = rt(
2598+ obj_body =
2599 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.]]) ..
2600- paragraphdivider() ..
2601 -- TRANSLATORS: "it" refers to the stock menu window.
2602- listitem_bullet(_[[Otherwise, please reopen it and choose the third tab.]])
2603- ),
2604+ li(_[[Otherwise, please reopen it and choose the third tab.]]),
2605 h = 250
2606 }
2607
2608 build_taverns = {
2609 position = "topright",
2610 title = _"New taverns",
2611- body = rt(
2612+ body =
2613 h1(_[[We need new taverns]]) ..
2614 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.]]) ..
2615- paragraphdivider() ..
2616- listitem_bullet(_[[Build at least two taverns.]])
2617- ),
2618+ li(_[[Build at least two taverns.]]),
2619 h = 300,
2620 obj_name = "build_taverns",
2621 obj_title = _"Build new taverns.",
2622- obj_body = rt(
2623+ obj_body =
2624 p(_[[To make our mines work, we need rations again – the more, the better.]]) ..
2625- paragraphdivider() ..
2626- listitem_bullet(_[[Build at least two taverns.]])
2627- )
2628+ li(_[[Build at least two taverns.]])
2629 }
2630
2631 ware_encyclopedia = {
2632 title = _"Ware Encyclopedia",
2633- body = rt(
2634+ body =
2635 p(_[[I am not sure if you could follow my remarks. Why do we need rations to get soldiers?]]) ..
2636 p(_[[When you’ve played a lot, you will know such things by heart. But when you’re unsure what this tribe needs for a special ware, you can easily look it up in your tribe’s ware encyclopedia.]]) ..
2637- p(_[[This encyclopedia can be accessed via]])
2638- ) ..
2639- rt("image=pics/menu_help.png",p(_[[the help button at the bottom. For all your tribe’s wares, it shows a short help text, a list of buildings that produces the ware and the needed wares.]]) ..
2640- p(_[[If you want, you can try it out. A soldier needs a wood lance and a helm – from there on out, you can search backwards.]])
2641- ),
2642+ p(_[[This encyclopedia can be accessed via]]) ..
2643+ p(img("pics/menu_help.png") .. _[[the help button at the bottom. For all your tribe’s wares, it shows a short help text, a list of buildings that produces the ware and the needed wares.]]) ..
2644+ p(_[[If you want, you can try it out. A soldier needs a wood lance and a helm – from there on out, you can search backwards.]]),
2645 h = 350
2646 }
2647
2648 building_priority_settings = {
2649 position = "topright",
2650 title = _"Priority Settings",
2651- body = rt(
2652+ body =
2653 h1(_[[Send the wares where they’re needed]]) ..
2654 p(_[[Great. Our taverns have now been built up and are supplying us with rations.]]) ..
2655 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’.]]) ..
2656@@ -243,91 +209,73 @@
2657 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.]])
2658 -- we cannot check whether the user does this, so no objective
2659 -- see bug https://bugs.launchpad.net/widelands/+bug/1380288
2660- )
2661 }
2662
2663 ware_stats1 = {
2664 position = "top",
2665 title = _"Ware Statistics",
2666- body = rt(
2667- p(_[[In the statistics menu, there is also a]])) ..
2668- rt("image=pics/menu_ware_stats.png",p(_[[‘Ware statistics’ button.]])) ..
2669- rt(paragraphdivider() ..
2670+ body =
2671+ p(_[[In the statistics menu, there is also a]]) ..
2672+ p(img("pics/menu_ware_stats.png") .. _[[‘Ware statistics’ button.]]) ..
2673 -- TRANSLATORS: "it" refers to the ware statistics button
2674- listitem_bullet(_[[Click on it.]])
2675- ),
2676+ li(_[[Click on it.]]),
2677 w = 200,
2678 h = 200,
2679 obj_name = "open_ware_stat",
2680 obj_title = _"Open the ware statistics window.",
2681- obj_body = rt(
2682- paragraphdivider() ..
2683- listitem_bullet(_[[Open the ‘Ware statistics’ window, accessed via the statistics menu.]])
2684- )
2685+ obj_body =
2686+ li(_[[Open the ‘Ware statistics’ window, accessed via the statistics menu.]])
2687 }
2688
2689 ware_stats2 = {
2690 title = _"Ware Statistics",
2691- body = rt(
2692+ body =
2693 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.]]) ..
2694- paragraphdivider() ..
2695- listitem_bullet(_[[I’ll continue as soon as you click on the]])) ..
2696- rt("image=pics/menu_tab_wares_econ_health.png",p(_[[third tab (‘Economy Health’).]])
2697- ),
2698+ li(_[[I’ll continue as soon as you click on the]]) ..
2699+ p(img("pics/menu_tab_wares_econ_health.png") .. _[[third tab (‘Economy Health’).]]),
2700 h = 250,
2701 show_instantly = true,
2702 obj_name = "switch_ware_stat_tab_to_third",
2703 obj_title = _"Switch to the third tab in the ware statistics menu window.",
2704- obj_body = rt(
2705+ obj_body =
2706 p(_[[The first two tabs show you the production and consumption of any ware. You can toggle them by simply clicking on them.]]) ..
2707- paragraphdivider() ..
2708- listitem_bullet(_[[When you have seen enough, switch to the third tab.]])
2709- )
2710+ li(_[[When you have seen enough, switch to the third tab.]])
2711 }
2712
2713 ware_stats3 = {
2714 title = _"Ware Statistics",
2715- body = rt(
2716+ body =
2717 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.]]) ..
2718 p(_[[Now try this out. You can also compare it with the two previous tabs.]]) ..
2719- paragraphdivider() ..
2720- listitem_bullet(_[[Click on the last tab when I should continue.]])
2721- ),
2722+ li(_[[Click on the last tab when I should continue.]]),
2723 h = 250,
2724 show_instantly = true,
2725 obj_name = "switch_ware_stat_tab_to_forth",
2726 obj_title = _"Switch to the last tab in the ware statistics menu window.",
2727- obj_body = rt(
2728+ obj_body =
2729 p(_[[The third tab shows you the economy health of the ware. When the value is positive, this means your stock is growing.]]) ..
2730- paragraphdivider() ..
2731- listitem_bullet(_[[When you have seen enough, switch to the fourth tab.]])
2732- )
2733+ li(_[[When you have seen enough, switch to the fourth tab.]])
2734 }
2735
2736 ware_stats4 = {
2737 title = _"Ware Statistics",
2738- body = rt(
2739+ body =
2740 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!]]) ..
2741 p(_[[The last two tabs are good indicators to see whether shortages are about to come. Don’t forget to check them regularly!]]) ..
2742- paragraphdivider() ..
2743- listitem_bullet(_[[Close this window when you’re done.]])
2744- ),
2745+ li(_[[Close this window when you’re done.]]),
2746 h = 250,
2747 show_instantly = true,
2748 obj_name = "close_ware_stats",
2749 obj_title = _"Close the ware statistics window.",
2750- obj_body = rt(
2751+ obj_body =
2752 p(_[[The stock tab shows you how many wares you have. Compare the information from the four tabs to understand the correlation.]]) ..
2753- paragraphdivider() ..
2754- listitem_bullet(_[[When you have finished, close the ware statistics window.]])
2755- ),
2756+ li(_[[When you have finished, close the ware statistics window.]]),
2757 }
2758
2759 reopen_ware_stats1 = {
2760 title = _"You closed the ware statistics window!",
2761- body = rt(
2762- 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?]])
2763- ),
2764+ body =
2765+ 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?]]),
2766 show_instantly = true,
2767 w = 300,
2768 h = 250
2769@@ -336,19 +284,16 @@
2770 reopen_ware_stats1_obj = {
2771 obj_name = "open_ware_stats_menu_again1",
2772 obj_title = _"Open the ware statistics window again.",
2773- obj_body = rt(
2774+ obj_body =
2775 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.]]) ..
2776- paragraphdivider() ..
2777 -- TRANSLATORS: "it" refers to the ware statistics window.
2778- listitem_bullet(_[[Otherwise, please reopen it and choose the third tab.]])
2779- )
2780+ li(_[[Otherwise, please reopen it and choose the third tab.]])
2781 }
2782
2783 reopen_ware_stats2 = {
2784 title = _"You closed the ware statistics window!",
2785- body = rt(
2786- 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?]])
2787- ),
2788+ body =
2789+ 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?]]),
2790 show_instantly = true,
2791 w = 300,
2792 h = 250
2793@@ -357,101 +302,85 @@
2794 reopen_ware_stats2_obj = {
2795 obj_name = "open_ware_stats_menu_again2",
2796 obj_title = _"Open the ware statistics window again.",
2797- obj_body = rt(
2798+ obj_body =
2799 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.]]) ..
2800- paragraphdivider() ..
2801 -- TRANSLATORS: "it" refers to the ware statistics window.
2802- listitem_bullet(_[[Otherwise, please reopen it and choose the fourth tab.]])
2803- )
2804+ li(_[[Otherwise, please reopen it and choose the fourth tab.]])
2805 }
2806
2807 economy_settings1 = {
2808 position = "topright",
2809 title = _"Economy options",
2810- body = rt(
2811+ body =
2812 p(_[[I’ve shown you our stock menu window, where you could see which wares are at the warehouses. You remember?]]) ..
2813- 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’.]])) ..
2814- -- Yup, that's indeed the correct icon
2815- rt("image=pics/genstats_nrwares.png",p(_[[This is the icon.]])) ..
2816- rt(
2817- paragraphdivider() ..
2818- listitem_bullet(_[[Open this window.]])
2819- ),
2820+ 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’.]]) ..
2821+ -- Yup, that's indeed the correct icon
2822+ p(img("pics/genstats_nrwares.png") .. _[[This is the icon.]]) ..
2823+ li(_[[Open this window.]]),
2824 h = 350,
2825 obj_name = "open_economy_settings",
2826 obj_title = _"Open the ‘Configure economy’ window.",
2827- obj_body = rt(
2828- paragraphdivider() ..
2829- listitem_bullet(_[[Open the ‘Configure economy’ window.]]) ..
2830- listitem_arrow(_[[The window can be accessed by clicking on any flag you own.]])
2831- )
2832+ obj_body =
2833+ li(_[[Open the ‘Configure economy’ window.]]) ..
2834+ li_arrow(_[[The window can be accessed by clicking on any flag you own.]])
2835 }
2836
2837 economy_settings2 = {
2838 title = _"Economy options",
2839- body = rt(
2840+ body =
2841 p(_[[This window looks similar to the stock window, but it has additional buttons at the bottom.]]) ..
2842 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.]]) ..
2843 p(_[[Most buildings will only produce something when when the stock level in your warehouses falls below the target quantity, so you should indicate the reserve you want to stockpile.]]) ..
2844 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.]]) ..
2845- 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.]])
2846- ),
2847+ 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.]]),
2848 h = 450
2849 }
2850
2851 economy_settings3 = {
2852 title = _"Economy options",
2853- body = rt(
2854+ body =
2855 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.]]) ..
2856 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.]]) ..
2857 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.]]) ..
2858- paragraphdivider() ..
2859- listitem_bullet(_[[Set the target quantity for marble columns to 20 and wait for your stonemason to produce them.]])
2860- ),
2861+ li(_[[Set the target quantity for marble columns to 20 and wait for your stonemason to produce them.]]),
2862 obj_name = "produce_marble_columns",
2863 obj_title = "Produce 20 marble columns.",
2864- obj_body = rt(
2865+ obj_body =
2866 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.]]) ..
2867- paragraphdivider() ..
2868- listitem_bullet(_[[To be prepared for additional fortifications, you should produce 20 marble columns.]]) ..
2869- listitem_arrow(_[[Your stonemason will not produce marble columns when they are not needed. You have to increase the target quantity.]]) ..
2870- listitem_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.]])
2871- )
2872+ li(_[[To be prepared for additional fortifications, you should produce 20 marble columns.]]) ..
2873+ li_arrow(_[[Your stonemason will not produce marble columns when they are not needed. You have to increase the target quantity.]]) ..
2874+ 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.]])
2875 }
2876
2877 warehouse_preference_settings = {
2878 field = warehouse_field,
2879 position = "topright",
2880 title = _"Warehouse Preferences",
2881- body = rt(
2882+ body =
2883 h1(_[[Bring the marble columns to the front line]]) ..
2884 p(_[[It is great that we are producing marble columns, but it would be great if they were stored where we need them.]]) ..
2885 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.]]) ..
2886 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.]]) ..
2887- paragraphdivider() ..
2888- listitem_bullet(_[[Bring all the marble columns to the warehouse near the front line.]]) ..
2889- listitem_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.]]) ..
2890- listitem_arrow(_[[Then, to move the marble columns out of your headquarters, you will have to click on the remove button there.]])
2891- ),
2892+ li(_[[Bring all the marble columns to the warehouse near the front line.]]) ..
2893+ 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.]]) ..
2894+ li_arrow(_[[Then, to move the marble columns out of your headquarters, you will have to click on the remove button there.]]),
2895 obj_name = "bring_marble_columns_to_front",
2896 obj_title = _"Bring 20 marble columns to the front line.",
2897- obj_body = economy_settings3.obj_body .. rt(
2898+ obj_body = economy_settings3.obj_body ..
2899 p(_[[To decide where your wares get stored, you can use the preference buttons in the warehouses.]]) ..
2900- listitem_bullet(_[[Bring all the marble columns to the warehouse near the front line.]]) ..
2901- listitem_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.]]) ..
2902- listitem_arrow(_[[Then, to move the marble columns out of your headquarters, you will have to click on the remove button there.]])
2903- )
2904+ li(_[[Bring all the marble columns to the warehouse near the front line.]]) ..
2905+ 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.]]) ..
2906+ li_arrow(_[[Then, to move the marble columns out of your headquarters, you will have to click on the remove button there.]])
2907 }
2908
2909 conclusion = {
2910 title = _"Borders Secured",
2911- body = rt(
2912+ body =
2913 h1(_[[We’re safe now]]) ..
2914 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.]]) ..
2915 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!]]) ..
2916 p([[]]) ..
2917- 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:]])
2918- ) ..
2919- rt("text-align=center", "<p font-size=24 font-decoration=underline>http://www.widelands.org</p>")
2920+ 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:]]) ..
2921+ p("halign=center", "<font size=24 underline=1>http://www.widelands.org</font>")
2922 }
2923
2924
2925=== added file 'cmake/Modules/FindICU.cmake'
2926--- cmake/Modules/FindICU.cmake 1970-01-01 00:00:00 +0000
2927+++ cmake/Modules/FindICU.cmake 2015-08-01 06:21:02 +0000
2928@@ -0,0 +1,315 @@
2929+# Downloaded from https://github.com/julp/FindICU.cmake
2930+#
2931+# This module can find the International Components for Unicode (ICU) Library
2932+#
2933+# Requirements:
2934+# - CMake >= 2.8.3 (for new version of find_package_handle_standard_args)
2935+#
2936+# The following variables will be defined for your use:
2937+# - ICU_FOUND : were all of your specified components found (include dependencies)?
2938+# - ICU_INCLUDE_DIRS : ICU include directory
2939+# - ICU_LIBRARIES : ICU libraries
2940+# - ICU_VERSION : complete version of ICU (x.y.z)
2941+# - ICU_MAJOR_VERSION : major version of ICU
2942+# - ICU_MINOR_VERSION : minor version of ICU
2943+# - ICU_PATCH_VERSION : patch version of ICU
2944+# - ICU_<COMPONENT>_FOUND : were <COMPONENT> found? (FALSE for non specified component if it is not a dependency)
2945+#
2946+# For windows or non standard installation, define ICU_ROOT variable to point to the root installation of ICU. Two ways:
2947+# - run cmake with -DICU_ROOT=<PATH>
2948+# - define an environment variable with the same name before running cmake
2949+# With cmake-gui, before pressing "Configure":
2950+# 1) Press "Add Entry" button
2951+# 2) Add a new entry defined as:
2952+# - Name: ICU_ROOT
2953+# - Type: choose PATH in the selection list
2954+# - Press "..." button and select the root installation of ICU
2955+#
2956+# Example Usage:
2957+#
2958+# 1. Copy this file in the root of your project source directory
2959+# 2. Then, tell CMake to search this non-standard module in your project directory by adding to your CMakeLists.txt:
2960+# set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
2961+# 3. Finally call find_package() once, here are some examples to pick from
2962+#
2963+# Require ICU 4.4 or later
2964+# find_package(ICU 4.4 REQUIRED)
2965+#
2966+# if(ICU_FOUND)
2967+# include_directories(${ICU_INCLUDE_DIRS})
2968+# add_executable(myapp myapp.c)
2969+# target_link_libraries(myapp ${ICU_LIBRARIES})
2970+# endif(ICU_FOUND)
2971+
2972+#=============================================================================
2973+# Copyright (c) 2011-2013, julp
2974+#
2975+# Distributed under the OSI-approved BSD License
2976+#
2977+# This software is distributed WITHOUT ANY WARRANTY; without even the
2978+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2979+#=============================================================================
2980+
2981+find_package(PkgConfig QUIET)
2982+
2983+########## Private ##########
2984+if(NOT DEFINED ICU_PUBLIC_VAR_NS)
2985+ set(ICU_PUBLIC_VAR_NS "ICU") # Prefix for all ICU relative public variables
2986+endif(NOT DEFINED ICU_PUBLIC_VAR_NS)
2987+if(NOT DEFINED ICU_PRIVATE_VAR_NS)
2988+ set(ICU_PRIVATE_VAR_NS "_${ICU_PUBLIC_VAR_NS}") # Prefix for all ICU relative internal variables
2989+endif(NOT DEFINED ICU_PRIVATE_VAR_NS)
2990+if(NOT DEFINED PC_ICU_PRIVATE_VAR_NS)
2991+ set(PC_ICU_PRIVATE_VAR_NS "_PC${ICU_PRIVATE_VAR_NS}") # Prefix for all pkg-config relative internal variables
2992+endif(NOT DEFINED PC_ICU_PRIVATE_VAR_NS)
2993+
2994+function(icudebug _VARNAME)
2995+ if(${ICU_PUBLIC_VAR_NS}_DEBUG)
2996+ if(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
2997+ message("${ICU_PUBLIC_VAR_NS}_${_VARNAME} = ${${ICU_PUBLIC_VAR_NS}_${_VARNAME}}")
2998+ else(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
2999+ message("${ICU_PUBLIC_VAR_NS}_${_VARNAME} = <UNDEFINED>")
3000+ endif(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
3001+ endif(${ICU_PUBLIC_VAR_NS}_DEBUG)
3002+endfunction(icudebug)
3003+
3004+set(${ICU_PRIVATE_VAR_NS}_ROOT "")
3005+if(DEFINED ENV{ICU_ROOT})
3006+ set(${ICU_PRIVATE_VAR_NS}_ROOT "$ENV{ICU_ROOT}")
3007+endif(DEFINED ENV{ICU_ROOT})
3008+if (DEFINED ICU_ROOT)
3009+ set(${ICU_PRIVATE_VAR_NS}_ROOT "${ICU_ROOT}")
3010+endif(DEFINED ICU_ROOT)
3011+
3012+set(${ICU_PRIVATE_VAR_NS}_BIN_SUFFIXES )
3013+set(${ICU_PRIVATE_VAR_NS}_LIB_SUFFIXES )
3014+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
3015+ list(APPEND ${ICU_PRIVATE_VAR_NS}_BIN_SUFFIXES "bin64")
3016+ list(APPEND ${ICU_PRIVATE_VAR_NS}_LIB_SUFFIXES "lib64")
3017+endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
3018+list(APPEND ${ICU_PRIVATE_VAR_NS}_BIN_SUFFIXES "bin")
3019+list(APPEND ${ICU_PRIVATE_VAR_NS}_LIB_SUFFIXES "lib")
3020+
3021+set(${ICU_PRIVATE_VAR_NS}_COMPONENTS )
3022+# <icu component name> <library name 1> ... <library name N>
3023+macro(icu_declare_component _NAME)
3024+ list(APPEND ${ICU_PRIVATE_VAR_NS}_COMPONENTS ${_NAME})
3025+ set("${ICU_PRIVATE_VAR_NS}_COMPONENTS_${_NAME}" ${ARGN})
3026+endmacro(icu_declare_component)
3027+
3028+icu_declare_component(data icudata)
3029+icu_declare_component(uc icuuc) # Common and Data libraries
3030+icu_declare_component(i18n icui18n icuin) # Internationalization library
3031+icu_declare_component(io icuio ustdio) # Stream and I/O Library
3032+icu_declare_component(le icule) # Layout library
3033+icu_declare_component(lx iculx) # Paragraph Layout library
3034+
3035+########## Public ##########
3036+set(${ICU_PUBLIC_VAR_NS}_FOUND TRUE)
3037+set(${ICU_PUBLIC_VAR_NS}_LIBRARIES )
3038+set(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS )
3039+set(${ICU_PUBLIC_VAR_NS}_C_FLAGS "")
3040+set(${ICU_PUBLIC_VAR_NS}_CXX_FLAGS "")
3041+set(${ICU_PUBLIC_VAR_NS}_CPP_FLAGS "")
3042+set(${ICU_PUBLIC_VAR_NS}_C_SHARED_FLAGS "")
3043+set(${ICU_PUBLIC_VAR_NS}_CXX_SHARED_FLAGS "")
3044+set(${ICU_PUBLIC_VAR_NS}_CPP_SHARED_FLAGS "")
3045+foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PRIVATE_VAR_NS}_COMPONENTS})
3046+ string(TOUPPER "${${ICU_PRIVATE_VAR_NS}_COMPONENT}" ${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT)
3047+ set("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_FOUND" FALSE) # may be done in the icu_declare_component macro
3048+endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
3049+
3050+# Check components
3051+if(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS) # uc required at least
3052+ set(${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS uc)
3053+else(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
3054+ list(APPEND ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS uc)
3055+ list(REMOVE_DUPLICATES ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
3056+ foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
3057+ if(NOT DEFINED ${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT})
3058+ message(FATAL_ERROR "Unknown ICU component: ${${ICU_PRIVATE_VAR_NS}_COMPONENT}")
3059+ endif(NOT DEFINED ${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT})
3060+ endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
3061+endif(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
3062+
3063+# Includes
3064+find_path(
3065+ ${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS
3066+ NAMES unicode/utypes.h utypes.h
3067+ HINTS ${${ICU_PRIVATE_VAR_NS}_ROOT}
3068+ PATH_SUFFIXES "include"
3069+ DOC "Include directories for ICU"
3070+)
3071+
3072+if(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS)
3073+ ########## <part to keep synced with tests/version/CMakeLists.txt> ##########
3074+ if(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/uvernum.h") # ICU >= 4
3075+ file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/uvernum.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
3076+ elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/uversion.h") # ICU [2;4[
3077+ file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/uversion.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
3078+ elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/utypes.h") # ICU [1.4;2[
3079+ file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/utypes.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
3080+ elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/utypes.h") # ICU 1.3
3081+ file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/utypes.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
3082+ else()
3083+ message(FATAL_ERROR "ICU version header not found")
3084+ endif()
3085+
3086+ if(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *ICU_VERSION *\"([0-9]+)\".*") # ICU 1.3
3087+ # [1.3;1.4[ as #define ICU_VERSION "3" (no patch version, ie all 1.3.X versions will be detected as 1.3.0)
3088+ set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "1")
3089+ set(${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${CMAKE_MATCH_1}")
3090+ set(${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "0")
3091+ elseif(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *U_ICU_VERSION_MAJOR_NUM *([0-9]+).*")
3092+ #
3093+ # Since version 4.9.1, ICU release version numbering was totaly changed, see:
3094+ # - http://site.icu-project.org/download/49
3095+ # - http://userguide.icu-project.org/design#TOC-Version-Numbers-in-ICU
3096+ #
3097+ set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "${CMAKE_MATCH_1}")
3098+ string(REGEX REPLACE ".*# *define *U_ICU_VERSION_MINOR_NUM *([0-9]+).*" "\\1" ${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS}")
3099+ string(REGEX REPLACE ".*# *define *U_ICU_VERSION_PATCHLEVEL_NUM *([0-9]+).*" "\\1" ${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "${${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS}")
3100+ elseif(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *U_ICU_VERSION *\"(([0-9]+)(\\.[0-9]+)*)\".*") # ICU [1.4;1.8[
3101+ # [1.4;1.8[ as #define U_ICU_VERSION "1.4.1.2" but it seems that some 1.4.1(?:\.\d)? have releasing error and appears as 1.4.0
3102+ set(${ICU_PRIVATE_VAR_NS}_FULL_VERSION "${CMAKE_MATCH_1}") # copy CMAKE_MATCH_1, no longer valid on the following if
3103+ if(${ICU_PRIVATE_VAR_NS}_FULL_VERSION MATCHES "^([0-9]+)\\.([0-9]+)$")
3104+ set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "${CMAKE_MATCH_1}")
3105+ set(${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${CMAKE_MATCH_2}")
3106+ set(${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "0")
3107+ elseif(${ICU_PRIVATE_VAR_NS}_FULL_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)")
3108+ set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "${CMAKE_MATCH_1}")
3109+ set(${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${CMAKE_MATCH_2}")
3110+ set(${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "${CMAKE_MATCH_3}")
3111+ endif()
3112+ else()
3113+ message(FATAL_ERROR "failed to detect ICU version")
3114+ endif()
3115+ set(${ICU_PUBLIC_VAR_NS}_VERSION "${${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION}.${${ICU_PUBLIC_VAR_NS}_MINOR_VERSION}.${${ICU_PUBLIC_VAR_NS}_PATCH_VERSION}")
3116+ ########## </part to keep synced with tests/version/CMakeLists.txt> ##########
3117+
3118+ # Check dependencies (implies pkg-config)
3119+ if(PKG_CONFIG_FOUND)
3120+ set(${ICU_PRIVATE_VAR_NS}_COMPONENTS_DUP ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
3121+ foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PRIVATE_VAR_NS}_COMPONENTS_DUP})
3122+ pkg_check_modules(PC_ICU_PRIVATE_VAR_NS "icu-${${ICU_PRIVATE_VAR_NS}_COMPONENT}" QUIET)
3123+
3124+ if(${PC_ICU_PRIVATE_VAR_NS}_FOUND)
3125+ foreach(${PC_ICU_PRIVATE_VAR_NS}_LIBRARY ${PC_ICU_LIBRARIES})
3126+ string(REGEX REPLACE "^icu" "" ${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY ${${PC_ICU_PRIVATE_VAR_NS}_LIBRARY})
3127+ list(APPEND ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS ${${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY})
3128+ endforeach(${PC_ICU_PRIVATE_VAR_NS}_LIBRARY)
3129+ endif(${PC_ICU_PRIVATE_VAR_NS}_FOUND)
3130+ endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
3131+ list(REMOVE_DUPLICATES ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
3132+ endif(PKG_CONFIG_FOUND)
3133+
3134+ # Check libraries
3135+ foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
3136+ set(${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES )
3137+ set(${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES )
3138+ foreach(${ICU_PRIVATE_VAR_NS}_BASE_NAME ${${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT}})
3139+ list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}")
3140+ list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}d")
3141+ list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}${ICU_MAJOR_VERSION}${ICU_MINOR_VERSION}")
3142+ list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}${ICU_MAJOR_VERSION}${ICU_MINOR_VERSION}d")
3143+ endforeach(${ICU_PRIVATE_VAR_NS}_BASE_NAME)
3144+
3145+ find_library(
3146+ ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT}
3147+ NAMES ${${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES}
3148+ HINTS ${${ICU_PRIVATE_VAR_NS}_ROOT}
3149+ PATH_SUFFIXES ${_ICU_LIB_SUFFIXES}
3150+ DOC "Release libraries for ICU"
3151+ )
3152+ find_library(
3153+ ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}
3154+ NAMES ${${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES}
3155+ HINTS ${${ICU_PRIVATE_VAR_NS}_ROOT}
3156+ PATH_SUFFIXES ${_ICU_LIB_SUFFIXES}
3157+ DOC "Debug libraries for ICU"
3158+ )
3159+
3160+ string(TOUPPER "${${ICU_PRIVATE_VAR_NS}_COMPONENT}" ${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT)
3161+ if(NOT ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT} AND NOT ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}) # both not found
3162+ set("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_FOUND" FALSE)
3163+ set("${ICU_PUBLIC_VAR_NS}_FOUND" FALSE)
3164+ else(NOT ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT} AND NOT ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}) # one or both found
3165+ set("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_FOUND" TRUE)
3166+ if(NOT ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT}) # release not found => we are in debug
3167+ set(${ICU_PRIVATE_VAR_NS}_LIB_${${ICU_PRIVATE_VAR_NS}_COMPONENT} "${${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}")
3168+ elseif(NOT ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}) # debug not found => we are in release
3169+ set(${ICU_PRIVATE_VAR_NS}_LIB_${${ICU_PRIVATE_VAR_NS}_COMPONENT} "${${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}")
3170+ else() # both found
3171+ set(
3172+ ${ICU_PRIVATE_VAR_NS}_LIB_${${ICU_PRIVATE_VAR_NS}_COMPONENT}
3173+ optimized ${${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}
3174+ debug ${${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}
3175+ )
3176+ endif()
3177+ list(APPEND ${ICU_PUBLIC_VAR_NS}_LIBRARIES ${${ICU_PRIVATE_VAR_NS}_LIB_${${ICU_PRIVATE_VAR_NS}_COMPONENT}})
3178+ endif(NOT ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT} AND NOT ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT})
3179+ endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
3180+
3181+ # Try to find out compiler flags
3182+ find_program(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE icu-config HINTS ${${ICU_PRIVATE_VAR_NS}_ROOT})
3183+ if(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE)
3184+ execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_C_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
3185+ execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cxxflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CXX_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
3186+ execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cppflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CPP_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
3187+
3188+ execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_C_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
3189+ execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cxxflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CXX_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
3190+ execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cppflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CPP_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
3191+ endif(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE)
3192+
3193+ # Check find_package arguments
3194+ include(FindPackageHandleStandardArgs)
3195+ if(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
3196+ find_package_handle_standard_args(
3197+ ${ICU_PUBLIC_VAR_NS}
3198+ REQUIRED_VARS ${ICU_PUBLIC_VAR_NS}_LIBRARIES ${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS
3199+ VERSION_VAR ${ICU_PUBLIC_VAR_NS}_VERSION
3200+ )
3201+ else(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
3202+ find_package_handle_standard_args(${ICU_PUBLIC_VAR_NS} "ICU not found" ${ICU_PUBLIC_VAR_NS}_LIBRARIES ${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS)
3203+ endif(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
3204+else(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS)
3205+ if(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
3206+ message(FATAL_ERROR "Could not find ICU include directory")
3207+ endif(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
3208+endif(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS)
3209+
3210+mark_as_advanced(
3211+ ${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS
3212+ ${ICU_PUBLIC_VAR_NS}_LIBRARIES
3213+)
3214+
3215+# IN (args)
3216+icudebug("FIND_COMPONENTS")
3217+icudebug("FIND_REQUIRED")
3218+icudebug("FIND_QUIETLY")
3219+icudebug("FIND_VERSION")
3220+# OUT
3221+# Found
3222+icudebug("FOUND")
3223+icudebug("UC_FOUND")
3224+icudebug("I18N_FOUND")
3225+icudebug("IO_FOUND")
3226+icudebug("LE_FOUND")
3227+icudebug("LX_FOUND")
3228+icudebug("DATA_FOUND")
3229+# Flags
3230+icudebug("C_FLAGS")
3231+icudebug("CPP_FLAGS")
3232+icudebug("CXX_FLAGS")
3233+icudebug("C_SHARED_FLAGS")
3234+icudebug("CPP_SHARED_FLAGS")
3235+icudebug("CXX_SHARED_FLAGS")
3236+# Linking
3237+icudebug("INCLUDE_DIRS")
3238+icudebug("LIBRARIES")
3239+# Version
3240+icudebug("MAJOR_VERSION")
3241+icudebug("MINOR_VERSION")
3242+icudebug("PATCH_VERSION")
3243+icudebug("VERSION")
3244
3245=== modified file 'cmake/WlFunctions.cmake'
3246--- cmake/WlFunctions.cmake 2014-12-27 09:46:38 +0000
3247+++ cmake/WlFunctions.cmake 2015-08-01 06:21:02 +0000
3248@@ -15,6 +15,7 @@
3249 USES_SDL2_NET
3250 USES_SDL2_TTF
3251 USES_ZLIB
3252+ USES_ICU
3253 )
3254 set(ONE_VALUE_ARG )
3255 set(MULTI_VALUE_ARGS SRCS DEPENDS)
3256@@ -142,6 +143,11 @@
3257 target_link_libraries(${NAME} ${Boost_LIBRARIES})
3258 endif()
3259
3260+ if(ARG_USES_ICU)
3261+ wl_include_system_directories(${NAME} ${ICU_INCLUDE_DIRS})
3262+ target_link_libraries(${NAME} ${ICU_LIBRARIES})
3263+ endif()
3264+
3265 foreach(DEPENDENCY ${ARG_DEPENDS})
3266 target_link_libraries(${NAME} ${DEPENDENCY})
3267 endforeach(DEPENDENCY)
3268
3269=== modified file 'doc/sphinx/source/wlrichtext.rst'
3270--- doc/sphinx/source/wlrichtext.rst 2014-12-20 18:39:44 +0000
3271+++ doc/sphinx/source/wlrichtext.rst 2015-08-01 06:21:02 +0000
3272@@ -1,6 +1,8 @@
3273 The Widelands Rich Text System
3274 ==============================
3275
3276+NOCOM(#gunchleoc): Update this documentation when we're finished.
3277+
3278 All texts that can be displayed to the user can be formatted to be layouted
3279 and nicely formatted. This allows for changing of font sizes, weights, colors
3280 and for the embedding of images. This documents how to format a string to be
3281@@ -24,7 +26,7 @@
3282 Starts or ends a rich text. Must be the first tag to appear in the string.
3283 A full example would be::
3284
3285- <rt image=map:khanktrukh.png><p line-spacing=3 font-size=12>Hello<br>World</p></rt>
3286+ <rt image=map:khanktrukh.png><p line-spacing=3 font-size=12>Hello World</p></rt>
3287
3288 This would instruct widelands to use the image of Khankruth that comes with
3289 the map, left align it. To the right of it there would be two lines of text.
3290@@ -84,11 +86,7 @@
3291 line-spacing
3292 Line spacing in points. Default is 0.
3293
3294-``<br>``
3295-^^^^^^^^
3296
3297-This inserts a line break into the text. The line break character (``\n``) is
3298-ignored inside a rich text.
3299
3300 Real world Lua example
3301 ----------------------
3302@@ -105,7 +103,7 @@
3303 "<p font-weight=bold font-decoration=underline font-style=italic font-size=24>" ..
3304 "YOU so rock dude!" ..
3305 "</p></rt>" ..
3306- "<rt><p>No. I really mean this.<br><br>Seriously.</p></rt>",
3307+ "<rt><p>No. I really mean this. Seriously.</p></rt>",
3308 { popup = true }
3309 )
3310
3311
3312=== modified file 'i18n/fonts.lua'
3313--- i18n/fonts.lua 2015-01-31 07:09:50 +0000
3314+++ i18n/fonts.lua 2015-08-01 06:21:02 +0000
3315@@ -2,23 +2,21 @@
3316 --
3317 -- Define which fontset you wish to use for your language in locales.lua.
3318 --
3319--- The "default" font set covers all possible font styles.
3320---
3321--- Your font might not have all of these available. In this case, it is
3322--- sufficient to define "serif" at the least, a fallback scheme is in place.
3323--- But do define everything your fontset has.
3324---
3325 -- When adding a new fontset, also make sure you have all pertinent license
3326 -- and source information collected in its folder.
3327
3328
3329 return {
3330- -- This is the default set and always needs to be complete.
3331+ -- This is the default set and always needs to be complete. It covers all possible font styles.
3332 default = {
3333+ -- If your language doesn't distinguish between serif and sans serif fonts, please use the serif set.
3334+ -- Your font set should always define "serif".
3335 serif = "DejaVu/DejaVuSerif.ttf",
3336+ -- Add bold and italic variants if your font set has them.
3337 serif_bold = "DejaVu/DejaVuSerif-Bold.ttf",
3338 serif_italic = "DejaVu/DejaVuSerif-Italic.ttf",
3339 serif_bold_italic = "DejaVu/DejaVuSerif-BoldItalic.ttf",
3340+ -- If your font set doesn't have sans or condensed variants, serif will be used instead.
3341 sans = "DejaVu/DejaVuSans.ttf",
3342 sans_bold = "DejaVu/DejaVuSans-Bold.ttf",
3343 sans_italic = "DejaVu/DejaVuSans-Oblique.ttf",
3344@@ -27,12 +25,21 @@
3345 condensed_bold = "DejaVu/DejaVuSansCondensed-Bold.ttf",
3346 condensed_italic = "DejaVu/DejaVuSansCondensed-Oblique.ttf",
3347 condensed_bold_italic = "DejaVu/DejaVuSansCondensed-BoldOblique.ttf",
3348- direction = "ltr"
3349+ -- If the diection isn't defined, your font set will default to "ltr" = left-to-right.
3350+ -- For right-to-left or bidirectional (BiDi) languages, use "rtl".
3351+ direction = "ltr",
3352+ -- size_offset is added to font sizes to make up for fonts that are too small.
3353+ -- Use negative values if the font is too big.
3354+ size_offset = 0
3355 },
3356
3357 arabic = {
3358- serif = "FaKacstBook/FaKacstBook.ttf",
3359- direction = "rtl"
3360+ serif = "amiri/amiri-regular.ttf",
3361+ serif_bold = "amiri/amiri-bold.ttf",
3362+ serif_italic = "amiri/amiri-slanted.ttf",
3363+ serif_bold_italic = "amiri/amiri-boldslanted.ttf",
3364+ direction = "rtl",
3365+ size_offset = 4
3366 },
3367
3368 cjk = {
3369
3370=== removed directory 'i18n/fonts/FaKacstBook'
3371=== removed file 'i18n/fonts/FaKacstBook/FaKacstBook.ttf'
3372Binary files i18n/fonts/FaKacstBook/FaKacstBook.ttf 2014-10-14 12:53:01 +0000 and i18n/fonts/FaKacstBook/FaKacstBook.ttf 1970-01-01 00:00:00 +0000 differ
3373=== removed file 'i18n/fonts/FaKacstBook/README'
3374--- i18n/fonts/FaKacstBook/README 2014-10-14 12:53:01 +0000
3375+++ i18n/fonts/FaKacstBook/README 1970-01-01 00:00:00 +0000
3376@@ -1,5 +0,0 @@
3377-Downloaded from Persianize Free(GPL'ed) Arabic Fonts
3378-
3379-https://launchpad.net/cgaf
3380-
3381-Maintainer: Saeed Rasooli saeed.gnu@gmail.com
3382
3383=== added directory 'i18n/fonts/amiri'
3384=== added file 'i18n/fonts/amiri/OFL-FAQ.txt'
3385--- i18n/fonts/amiri/OFL-FAQ.txt 1970-01-01 00:00:00 +0000
3386+++ i18n/fonts/amiri/OFL-FAQ.txt 2015-08-01 06:21:02 +0000
3387@@ -0,0 +1,369 @@
3388+OFL FAQ - Frequently Asked Questions about the SIL Open Font License (OFL)
3389+Version 1.1-update2 - 23 August 2010
3390+(See http://scripts.sil.org/OFL for updates)
3391+
3392+
3393+CONTENTS OF THIS FAQ
3394+1 USING AND DISTRIBUTING FONTS LICENSED UNDER THE OFL
3395+2 USING OFL FONTS FOR WEB PAGES AND ONLINE WEBFONT SERVICES
3396+3 MODIFYING OFL-LICENSED FONTS
3397+4 LICENSING YOUR ORIGINAL FONTS UNDER THE OFL
3398+5 CHOOSING RESERVED FONT NAMES
3399+6 ABOUT THE FONTLOG
3400+7 MAKING CONTRIBUTIONS TO OFL PROJECTS
3401+8 ABOUT THE LICENSE ITSELF
3402+9 ABOUT SIL INTERNATIONAL
3403+APPENDIX A - FONTLOG EXAMPLE
3404+
3405+
3406+1 USING AND DISTRIBUTING FONTS LICENSED UNDER THE OFL
3407+
3408+1.1 Can I use the fonts for a book or other print publication?
3409+Yes. You can mention the font and author in the book's colophon if you wish, but that is not required.
3410+
3411+1.2 Can the fonts be included with Free/Libre and Open Source Software collections such as GNU/Linux and BSD distributions?
3412+Yes! Fonts licensed under the OFL can be freely included alongside other software under FLOSS (Free/Libre and Open Source Software) licenses. Since fonts are typically aggregated with, not merged into, existing software, there is little need to be concerned about incompatibility with existing software licenses. You may also repackage the fonts and the accompanying components in a .rpm or .deb package and include them in distribution CD/DVDs and online repositories. (Also see section 5.9 about rebuilding from source.)
3413+
3414+1.3 I want to distribute the fonts with my program. Does this mean my program also has to be Free/Libre and Open Source Software?
3415+No. Only the portions based on the Font Software are required to be released under the OFL. The intent of the license is to allow aggregation or bundling with software under restricted licensing as well.
3416+
3417+1.4 Can I sell a software package that includes these fonts?
3418+Yes, you can do this with both the Original Version and a Modified Version of the fonts. Examples of bundling made possible by the OFL would include: word processors, design and publishing applications, training and educational software, games and entertainment software, mobile device applications, etc.
3419+
3420+1.5 Can I include the fonts on a CD of freeware or commercial fonts?
3421+Yes, as long some other font or software is also on the disk, so the OFL font is not sold by itself.
3422+
3423+1.6 Why won't the OFL let me sell the fonts alone?
3424+The intent is to keep people from making money by simply redistributing the fonts. The only people who ought to profit directly from the fonts should be the original authors, and those authors have kindly given up potential direct income to distribute their fonts under the OFL. Please honour and respect their contribution!
3425+
3426+1.7 What about sharing OFL fonts with friends on a CD, DVD or USB stick?
3427+You are very welcome to share open fonts with friends, family and colleagues through removable media. Just remember to include the full font package, including any copyright notices and licensing information as available in OFL.txt. In the case where you sell the font, it has to come bundled with software.
3428+
3429+1.8 Can I host the fonts on a web site for others to use?
3430+Yes, as long as you make the full font package available. In most cases it may be best to point users to the main site that distributes the Original Version so they always get the most recent stable and complete version. See also discussion of webfonts in Section 2.
3431+
3432+1.9 Can I host the fonts on a server for use over our internal network?
3433+Yes. If the fonts are transferred from the server to the client computer by means that allow them to be used even if the computer is no longer attached to the network, the full package (copyright notices, licensing information, etc.) should be included.
3434+
3435+1.10 Does the full OFL license text always need to accompany the font?
3436+The only situation in which an OFL font can be distributed without the text of the OFL (either in a separate file or in font metadata), is when a font is embedded in a document or bundled within a program. In the case of metadata included within a font, it is legally sufficient to include only a link to the text of the OFL on http://scripts.sil.org/OFL, but we strongly recommend against this. Most modern font formats include metadata fields that will accept the full OFL text, and full inclusion increases the likelihood that users will understand and properly apply the license.
3437+
3438+1.11 What do you mean by 'embedding'? How does that differ from other means of distribution?
3439+By 'embedding' we mean inclusion of the font in a document or file in a way that makes extraction (and redistribution) difficult or clearly discouraged. In many cases the names of embedded fonts might also not be obvious to those reading the document, the font data format might be altered, and only a subset of the font - only the glyphs required for the text - might be included. Any other means of delivering a font to another person is considered 'distribution', and needs to be accompanied by any copyright notices and licensing information available in OFL.txt.
3440+
3441+1.12 So can I embed OFL fonts in my document?
3442+Yes, either in full or a subset. The restrictions regarding font modification and redistribution do not apply, as the font is not intended for use outside the document.
3443+
3444+1.13 Does embedding alter the license of the document itself?
3445+No. Referencing or embedding an OFL font in any document does not change the license of the document itself. The requirement for fonts to remain under the OFL does not apply to any document created using the fonts and their derivatives. Similarly, creating any kind of graphic using a font under OFL does not make the resulting artwork subject to the OFL.
3446+
3447+1.14 If OFL fonts are extracted from a document in which they are embedded (such as a PDF file), what can be done with them? Is this a risk to author(s)?
3448+The few utilities that can extract fonts embedded in a PDF will typically output limited amounts of outlines - not a complete font. To create a working font from this method is much more difficult and time consuming than finding the source of the original OFL font. So there is little chance that an OFL font would be extracted and redistributed inappropriately through this method. Even so, copyright laws address any misrepresentation of authorship. All Font Software released under the OFL and marked as such by the author(s) is intended to remain under this license regardless of the distribution method, and cannot be redistributed under any other license. We strongly discourage any font extraction - we recommend directly using the font sources instead - but if you extract font outlines from a document, please be considerate: use your common sense and respect the work of the author(s) and the licensing model.
3449+
3450+1.15 What about distributing fonts with a document? Within a compressed folder structure? Is it distribution, bundling or embedding?
3451+Certain document formats may allow the inclusion of an unmodified font within their file structure which consists of a compressed folder containing the various resources forming the document (such as pictures and thumbnails). Including fonts within such a structure is understood as being different from embedding but rather similar to bundling (or mere aggregation) which the license explicitly allows. In this case the font is conveyed unchanged whereas embedding a font usually transforms it from the original format. The OFL does not allow anyone to extract the font from such a structure to then redistribute it under another license. The explicit permission to redistribute and embed does not cancel the requirement for the Font Software to remain under the license chosen by its author(s).
3452+
3453+1.16 What about ebooks shipping with open fonts?
3454+The requirements differ depending on whether the fonts are linked, embedded or distributed (bundled or aggregated). Some ebook formats use web technologies to do font linking via @font-face, others are designed for font embedding, some use fonts distributed with the document or reading software, and a few rely solely on the fonts already present on the target system. The license requirements depend on the type of inclusion as discussed in 1.15.
3455+
3456+1.17 Can Font Software released under the OFL be subject to URL-based access restrictions methods or DRM (Digital Rights Management) mechanisms?
3457+Yes, but these issues are out-of-scope for the OFL. The license itself neither encourages their use nor prohibits them since such mechanisms are not implemented in the components of the Font Software but through external software. Such restrictions are put in place for many different purposes corresponding to various usage scenarios. One common example is to limit potentially dangerous cross-site scripting attacks. However, in the spirit of libre/open fonts and unrestricted writing systems, we strongly encourage open sharing and reuse of OFL fonts, and the establishment of an environment where such restrictions are unnecessary. Note that whether you wish to use such mechanisms or you prefer not to, you must still abide by the rules set forth by the OFL when using fonts released by their authors under this license. Derivative fonts must be licensed under the OFL, even if they are part of a service for which you charge fees and/or for which access to source code is restricted. You may not sell the fonts on their own - they must be part of a larger software package, bundle or subscription plan. For example, even if the OFL font is distributed in a software package or via an online service using a DRM mechanism, the user would still have the right to extract that font, use, study, modify and redistribute it under the OFL.
3458+
3459+1.18 I've come across a font released under the OFL. How can I easily get more information about the Original Version? How can I know where it stands compared to the Original Version or other Modified Versions?
3460+Consult the copyright statement(s) in the license for ways to contact the original authors. Consult the FONTLOG for information on how the font differs from the Original Version, and get in touch with the various contributors via the information in the acknowledgement section. Please consider using the Original Versions of the fonts whenever possible.
3461+
3462+1.19 What do you mean in condition 4? Can you provide examples of abusive promotion / endorsement / advertisement vs. normal acknowledgement?
3463+The intent is that the goodwill and reputation of the author(s) should not be used in a way that makes it sound like the original author(s) endorse or approve of a specific Modified Version or software bundle. For example, it would not be right to advertise a word processor by naming the author(s) in a listing of software features, or to promote a Modified Version on a web site by saying "designed by ...". However, it would be appropriate to acknowledge the author(s) if your software package has a list of people who deserve thanks. We realize that this can seem to be a grey area, but the standard used to judge an acknowledgement is that if the acknowledgement benefits the author(s) it is allowed, but if it primarily benefits other parties, or could reflect poorly on the author(s), then it is not.
3464+
3465+
3466+2 USING OFL FONTS FOR WEBPAGES AND ONLINE WEBFONT SERVICES
3467+
3468+2.1 Can I make webpages using these fonts?
3469+Yes! Go ahead! Using CSS (Cascading Style Sheets) is recommended. Your three best options:
3470+- referring directly in your stylesheet to open fonts which may be available on the user's system
3471+- providing links to download the full package of the font - either from your own website or from elsewhere - so users can install it themselves
3472+- using @font-face to distribute the font directly to browsers. This is recommended and explicitly allowed by the licensing model because it is distribution. The font file itself is distributed with other components of the webpage. It is not embedded in the webpage but referenced through a web address which will cause the browser to retrieve and use the corresponding font to render the webpage (see 1.11 and 1.15 for details related to embedding fonts into documents). As you take advantage of the @font-face cross-platform standard, be aware that webfonts are often tuned for a web environment and not intended for installation and use outside a browser. The reasons in favour of using webfonts are to allow design of dynamic text elements instead of static graphics, to make it easier for content to be localized and translated, indexed and searched, and all this with cross-platform open standards without depending on restricted extensions or plugins. You should check the CSS cascade (the order in which fonts are being called or delivered to your users) when testing.
3473+
3474+2.2 Can I make and use WOFF (Web Open Font Format) versions of OFL fonts?
3475+Yes, but you need to be careful. A change in font format normally is considered modification, and Reserved Font Names (RFNs) cannot be used. Because of the design of the WOFF format, however, it is possible to create a WOFF version that is not considered modification, and so would not require a name change. You are allowed to create, use and distribute a WOFF version of an OFL font without changing the font name, but only if:
3476+
3477+- the original font data remains unchanged except for WOFF compression, and
3478+- WOFF-specific metadata is either omitted altogether or present and includes, unaltered, the contents of all equivalent metadata in the original font.
3479+
3480+If the original font data or metadata is changed, or the WOFF-specific metadata is incomplete, the font must be considered a Modified Version, the OFL restrictions would apply and the name of the font must be changed: any RFNs cannot be used and copyright notices and licensing information must be included and cannot be deleted or modified. You must come up with a unique name - we recommend one corresponding to your domain or your particular web application. Be aware that only the original author(s) can use RFNs. This is to prevent collisions between a derivative tuned to your audience and the original upstream version and so to reduce confusion.
3481+
3482+Please note that most WOFF conversion tools and online services do not meet the two requirements listed above, and so their output must be considered a Modified Version. So be very careful and check to be sure that the tool or service you're using is compressing unchanged data and completely and accurately reflecting the original font metadata.
3483+
3484+2.3 What about other webfont formats such as EOT/EOTLite/CWT/etc.?
3485+In most cases these formats alter the original font data more than WOFF, and do not completely support appropriate metadata, so their use must be considered modification and RFNs may not be used.
3486+
3487+2.4 Can I make OFL fonts available through webfont online services?
3488+Yes, you are welcome to include OFL fonts in online webfont services as long as you properly meet all the conditions of the license. The origin and open status of the font should be clear among the other fonts you are hosting. Authorship, copyright notices and license information must be sufficiently visible to your users or subscribers so they know where the font comes from and the rights granted by the author(s). Make sure the font file contains the needed copyright notice(s) and licensing information in its metadata. Please double-check the accuracy of every field to prevent contradictory information. Other font formats, including EOT/EOTLite/CWT and superior alternatives like WOFF, already provide fields for this information. Remember that if you modify the font within your library or convert it to another format for any reason the OFL restrictions apply and you need to change the names accordingly. Please respect the author's wishes as expressed in the OFL and do not misrepresent original designers and their work. Don't lump quality open fonts together with dubious freeware or public domain fonts. Consider how you can best work with the original designers and foundries, support their efforts and generate goodwill that will benefit your service. (See 1.17 for details related to URL-based access restrictions methods or DRM mechanisms).
3489+
3490+2.5 Can I make and publish CMS themes or templates that use OFL fonts? Can I include the fonts themselves in the themes or templates? Can I sell the whole package?
3491+Yes, you are very welcome to integrate open fonts into themes and templates for your preferred CMS and make them more widely available. Be aware that you can only sell the fonts and your CMS add-on as part of a software bundle. (See 1.4 for details and examples about selling bundles).
3492+
3493+2.6 Some webfont formats and services provide ways of "optimising" the font for a particular website or web application; is that allowed?
3494+Yes, it is permitted, but remember that these optimised versions are Modified Versions and so must follow OFL requirements like appropriate renaming. Also you need to bear in mind the other important parameters beyond compression, speed and responsiveness: you need to consider the audience of your particular website or web application, as choosing some optimisation parameters may turn out to be less than ideal for them. Subsetting by removing certain glyphs or features may seriously limit functionality of the font in various languages used by your users. It may also introduce degradation of quality in the rendering or specific bugs on the various platforms compared to the original font. In other words, remember that one person's optimised font may be another person's missing feature. Various advanced typographic features are also available through CSS and may provide the desired effects without the need to modify the font.
3495+
3496+
3497+3 MODIFYING OFL-LICENSED FONTS
3498+
3499+3.1 Can I change the fonts? Are there any limitations to what things I can and cannot change?
3500+You are allowed to change anything, as long as such changes do not violate the terms of the license. In other words, you are not allowed to remove the copyright statement(s) from the font, but you could put additional information into it that covers your contribution.
3501+
3502+3.2 I have a font that needs a few extra glyphs - can I take them from an OFL licensed font and copy them into mine?
3503+Yes, but if you distribute that font to others it must be under the OFL, and include the information mentioned in condition 2 of the license.
3504+
3505+3.3 Can I charge people for my additional work? In other words, if I add a bunch of special glyphs and/or OpenType/Graphite code, can I sell the enhanced font?
3506+Not by itself. Derivative fonts must be released under the OFL and cannot be sold by themselves. It is permitted, however, to include them in a larger software package (such as text editors, office suites or operating systems), even if the larger package is sold. In that case, you are strongly encouraged, but not required, to also make that derived font easily and freely available outside of the larger package.
3507+
3508+3.4 Can I pay someone to enhance the fonts for my use and distribution?
3509+Yes. This is a good way to fund the further development of the fonts. Keep in mind, however, that if the font is distributed to others it must be under the OFL. You won't be able to recover your investment by exclusively selling the font, but you will be making a valuable contribution to the community. Please remember how you have benefited from the contributions of others.
3510+
3511+3.5 I need to make substantial revisions to the font to make it work with my program. It will be a lot of work, and a big investment, and I want to be sure that it can only be distributed with my program. Can I restrict its use?
3512+No. If you redistribute a Modified Version of the font it must be under the OFL. You may not restrict it in any way beyond what the OFL permits and requires. This is intended to ensure that all released improvements to the fonts become available to everyone. But you will likely get an edge over competitors by being the first to distribute a bundle with the enhancements. Again, please remember how you have benefited from the contributions of others.
3513+
3514+3.6 Do I have to make any derivative fonts (including extended source files, build scripts, documentation, etc.) publicly available?
3515+No, but please consider sharing your improvements with others. You may find that you receive in return more than what you gave.
3516+
3517+3.7 If a trademark is claimed in the OFL font, does that trademark need to remain in modified fonts?
3518+Yes, any trademark notices must remain in any derivative fonts to respect trademark laws, but you may add any additional trademarks you claim, officially registered or not. For example if an OFL font called "Foo" contains a notice that "Foo is a trademark of Acme", then if you rename the font to "Bar" when creating a Modified Version, the new trademark notice could say "Foo is a trademark of Acme Inc. - Bar is a trademark of Roadrunner Technologies Ltd.". Trademarks work alongside the OFL and are not subject to the terms of the licensing agreement. Please refer to the appropriate trademark laws.
3519+
3520+
3521+4 LICENSING YOUR ORIGINAL FONTS UNDER THE OFL
3522+
3523+4.1 Can I use the SIL OFL for my own fonts?
3524+Yes! We heartily encourage everyone to use the OFL to distribute their own original fonts. It is a carefully constructed license that allows great freedom along with enough artistic integrity protection for the work of the authors as well as clear rules for other contributors and those who redistribute the fonts. The licensing model is used successfully by various organisations, both for-profit and not-for-profit, to release fonts of varying levels of scope and complexity.
3525+
3526+4.2 What do I have to do to apply the OFL to my font?
3527+If you want to release your fonts under the OFL, we recommend you do the following:
3528+
3529+4.2.1 Put your copyright and Reserved Font Names information at the beginning of the main OFL.txt file in place of the dedicated placeholders. Include this file in your release package.
3530+
3531+4.2.2 Put your copyright and the OFL text with Reserved Font Names into your font files (the copyright and license fields). A link to the OFL text on the OFL web site is an acceptable (but not recommended) alternative. Also add this information to any other components (build scripts, glyph databases, documentation, test files, etc). Depending on the format of your fonts and sources, you can use template human-readable headers or machine-readable metadata.
3532+
3533+4.2.3 Write an initial FONTLOG.txt for your font and include it in the release package.
3534+
3535+4.2.4 Include the relevant practical documentation on the license by including the OFL-FAQ.txt in your package.
3536+
3537+4.3 Will you make my font OFL for me?
3538+We won't do the work for you. We can, however, try to answer your questions, unfortunately we do not have the resources to review and check your font packages for correct use of the OFL.
3539+
3540+4.4 Will you distribute my OFL font for me?
3541+No, although if the font is of sufficient quality and general interest we may include a link to it on our partial list of OFL fonts on the OFL web site. You may wish to consider other open font catalogs or hosting services, such as the Unifont Font Guide (http://unifont.org/fontguide), The League of Movable Type (http://theleagueofmovabletype.com), Kernest (http://kernest.com/) or the Open Font Library (http://openfontlibrary.org/), which despite the name has no direct relationship to the OFL or SIL. We do not endorse any particular catalog or hosting service - it is your responsibility to determine if the service is right for you.
3542+
3543+4.5 Why should I use the OFL for my fonts?
3544+- to meet needs for fonts that can be modified to support minority languages
3545+- to provide a legal and clear way for people to respect your work but still use it (and reduce piracy)
3546+- to involve others in your font project
3547+- to enable your fonts to be expanded with new weights and improved writing system/language support
3548+- to allow more technical font developers to add features to your design (such as OpenType and Graphite support)
3549+- to renew the life of an old font lying on your hard drive with no business model
3550+- to allow your font to be included in Libre Software operating systems like Ubuntu
3551+- to give your font world status and wide, unrestricted distribution
3552+- to educate students about quality typeface and font design
3553+- to expand your test base and get more useful feedback
3554+- to extend your reach to new markets when users see your metadata and go to your website
3555+- to get your font more easily into one of the webfont online services
3556+- to attract attention for your commercial fonts
3557+- to make money through webfont services
3558+- to make money by bundling fonts with applications
3559+- to make money adjusting and extending existing open fonts
3560+- to get a better chance that foundations/NGOs/charities/companies who commission fonts will pick you
3561+- to be part of a sharing design and development community
3562+- to give back and contribute to a growing body of font sources
3563+
3564+
3565+5 CHOOSING RESERVED FONT NAMES
3566+
3567+5.1 What are Reserved Font Names?
3568+These are font names, or portions of font names, that the author has chosen to reserve for use only with the Original Version of the font, or for Modified Version(s) created by the original author.
3569+
3570+5.2 Why can't I use the Reserved Font Names in my derivative font names? I'd like people to know where the design came from.
3571+The best way to acknowledge the source of the design is to thank the original authors and any other contributors in the files that are distributed with your revised font (although no acknowledgement is required). The FONTLOG is a natural place to do this. Reserved Font Names ensure that the only fonts that have the original names are the unmodified Original Versions. This allows designers to maintain artistic integrity while allowing collaboration to happen. It eliminates potential confusion and name conflicts. When choosing a name, be creative and avoid names that reuse almost all the same letters in the same order or sound like the original. It will help everyone if Original Versions and Modified Versions can easily be distinguished from one another and from other derivatives. Any substitution and matching mechanism is outside the scope of the license.
3572+
3573+5.3 What do you mean by "primary name as presented to the user"? Are you referring to the font menu name?
3574+Yes, this applies to the font menu name and other mechanisms that specify a font in a document. It would be fine, however, to keep a text reference to the original fonts in the description field, in your modified source file or in documentation provided alongside your derivative as long as no one could be confused that your modified source is the original. But you cannot use the Reserved Font Names in any way to identify the font to the user (unless the Copyright Holder(s) allow(s) it through a separate agreement). Users who install derivatives (Modified Versions) on their systems should not see any of the original Reserved Font Names in their font menus, for example. Again, this is to ensure that users are not confused and do not mistake one font for another and so expect features only another derivative or the Original Version can actually offer.
3575+
3576+5.4 Am I not allowed to use any part of the Reserved Font Names?
3577+You may not use individual words from the Reserved Font Names, but you would be allowed to use parts of words, as long as you do not use any word from the Reserved Font Names entirely. We do not recommend using parts of words because of potential confusion, but it is allowed. For example, if "Foobar" was a Reserved Font Name, you would be allowed to use "Foo" or "bar", although we would not recommend it. Such an unfortunate choice would confuse the users of your fonts as well as make it harder for other designers to contribute.
3578+
3579+5.5 So what should I, as an author, identify as Reserved Font Names?
3580+Original authors are encouraged to name their fonts using clear, distinct names, and only declare the unique parts of the name as Reserved Font Names. For example, the author of a font called "Foobar Sans" would declare "Foobar" as a Reserved Font Name, but not "Sans", as that is a common typographical term, and may be a useful word to use in a derivative font name. Reserved Font Names should also be single words. A font called "Flowing River" should have Reserved Font Names "Flowing" and "River", not "Flowing River". You also need to be very careful about reserving font names which are already linked to trademarks (whether registered or not) which you do not own.
3581+
3582+5.6 Do I, as an author, have to identify any Reserved Font Names?
3583+No, but we strongly encourage you to do so. This is to avoid confusion between your work and Modified Versions.
3584+
3585+5.7 Are any names (such as the main font name) reserved by default?
3586+No. That is a change to the license as of version 1.1. If you want any names to be Reserved Font Names, they must be specified after the copyright statement(s).
3587+
3588+5.8 Is there any situation in which I can use Reserved Font Names for a Modified Version?
3589+The Copyright Holder(s) can give certain trusted parties the right to use any of the Reserved Font Names through separate written agreements. For example, even if "Foobar" is a RFN, you could write up an agreement to give company "XYZ" the right to distribute a modified version with a name that includes "Foobar". This allows for freedom without confusion.
3590+
3591+5.9 Do font rebuilds require a name change? Do I have to change the name of the font when my packaging workflow includes a full rebuild from source?
3592+Yes, all rebuilds which change the font data and the smart code are Modified Versions and the requirements of the OFL apply: you need to respect what the Author(s) have chosen in terms of Reserved Font Names. However if a package (or installer) is simply a wrapper or a compressed structure around the final font - leaving them intact on the inside - then no name change is required. Please get in touch with the author(s) and copyright holder(s) to inquire about the presence of font sources beyond the final font file(s) and the recommended build path. That build path may very well be non-trivial and hard to reproduce accurately by the maintainer. If a full font build path is made available by the upstream author(s) please be aware that any regressions and changes you may introduce when doing a rebuild for packaging purposes is your responsibility as a package maintainer since you are effectively creating a separate branch. You should make it very clear to your users that your rebuilt version is not the canonical one from upstream.
3593+
3594+5.10 Can I add other Reserved Font Names when making a derivative font?
3595+Yes. List your additional Reserved Font Names after your additional copyright statement, as indicated with example placeholders at the top of the OFL.txt file. Be sure you do not remove any exiting RFNs but only add your own.
3596+
3597+
3598+6 ABOUT THE FONTLOG
3599+
3600+6.1 What is this FONTLOG thing exactly?
3601+It has three purposes: 1) to provide basic information on the font to users and other developers, 2) to document changes that have been made to the font or accompanying files, either by the original authors or others, and 3) to provide a place to acknowledge authors and other contributors. Please use it!
3602+
3603+6.2 Is the FONTLOG required?
3604+It is not a requirement of the license, but we strongly recommend you have one.
3605+
3606+6.3 Am I required to update the FONTLOG when making Modified Versions?
3607+No, but users, designers and other developers might get very frustrated with you if you don't. People need to know how derivative fonts differ from the original, and how to take advantage of the changes, or build on them. There are utilities that can help create and maintain a FONTLOG, such as the FONTLOG support in FontForge.
3608+
3609+6.4 What should the FONTLOG look like?
3610+It is typically a separate text file (FONTLOG.txt), but can take other formats. It commonly includes these four sections:
3611+
3612+- brief header describing the FONTLOG itself and name of the font family
3613+- Basic Font Information - description of the font family, purpose and breadth
3614+- ChangeLog - chronological listing of changes
3615+- Acknowledgements - list of authors and contributors with contact information
3616+
3617+It could also include other sections, such as: where to find documentation, how to make contributions, information on contributing organizations, source code details, and a short design guide. See Appendix A for an example FONTLOG.
3618+
3619+
3620+7 MAKING CONTRIBUTIONS TO OFL PROJECTS
3621+
3622+7.1 Can I contribute work to OFL projects?
3623+In many cases, yes. It is common for OFL fonts to be developed by a team of people who welcome contributions from the wider community. Contact the original authors for specific information on how to participate in their projects.
3624+
3625+7.2 Why should I contribute my changes back to the original authors?
3626+It would benefit many people if you contributed back in response to what you've received. Your contributions and improvements to the fonts and other components could be a tremendous help and would encourage others to contribute as well and 'give back'. You will then benefit from other people's contributions as well. Sometimes maintaining your own separate version takes more effort than merging back with the original. Be aware that any contributions, however, must be either your own original creation or work that you own, and you may be asked to affirm that clearly when you contribute.
3627+
3628+7.3 I've made some very nice improvements to the font. Will you consider adopting them and putting them into future Original Versions?
3629+Most authors would be very happy to receive such contributions. Keep in mind that it is unlikely that they would want to incorporate major changes that would require additional work on their end. Any contributions would likely need to be made for all the fonts in a family and match the overall design and style. Authors are encouraged to include a guide to the design with the fonts. It would also help to have contributions submitted as patches or clearly marked changes - the use of smart source revision control systems like subversion, svk, mercurial, git or bzr is a good idea. Please follow the recommendations given by the author(s) in terms of preferred source formats and configuration parameters for sending contributions. If this is not indicated in a FONTLOG or other documentation of the font, consider asking them directly. Examples of useful contributions are bug fixes, additional glyphs, stylistic alternates (and the smart font code to access them) or improved hinting. Keep in mind that some kinds of changes (esp. hinting) may be technically difficult to integrate.
3630+
3631+7.4 How can I financially support the development of OFL fonts?
3632+It is likely that most authors of OFL fonts would accept financial contributions - contact them for instructions on how to do this. Such contributions would support future development. You can also pay for others to enhance the fonts and contribute the results back to the original authors for inclusion in the Original Version.
3633+
3634+
3635+8 ABOUT THE LICENSE ITSELF
3636+
3637+8.1 I see that this is version 1.1 of the license. Will there be later changes?
3638+Version 1.1 is the first minor revision of the OFL. We are confident that version 1.1 will meet most needs, but are open to future improvements. Any revisions would be for future font releases, and previously existing licenses would remain in effect. No retroactive changes are possible, although the Copyright Holder(s) can re-release the font under a revised OFL. All versions will be available on our web site: http://scripts.sil.org/OFL.
3639+
3640+8.2 Does this license restrict the rights of the Copyright Holder(s)?
3641+No. The Copyright Holder(s) still retain(s) all the rights to their creation; they are only releasing a portion of it for use in a specific way. For example, the Copyright Holder(s) may choose to release a 'basic' version of their font under the OFL, but sell a restricted 'enhanced' version. Only the Copyright Holder(s) can do this.
3642+
3643+8.3 Is the OFL a contract or a license?
3644+The OFL is a license and not a contract and so does not require you to sign it to have legal validity. By using, modifying and redistributing components under the OFL you indicate that you accept the license.
3645+
3646+8.4 I really like the terms of the OFL, but want to change it a little. Am I allowed to take ideas and actual wording from the OFL and put them into my own custom license for distributing my fonts?
3647+We strongly recommend against creating your very own unique open licensing model. Using a modified or derivative license will likely cut you off - along with the font(s) under that license - from the community of designers using the OFL, potentially expose you and your users to legal liabilities, and possibly put your work and rights at risk. The OFL went though a community and legal review process that took years of effort, and that review is only applicable to an unmodified OFL. The text of the OFL has been written by SIL (with review and consultation from the community) and is copyright (c) 2005-2010 SIL International. You may re-use the ideas and wording (in part, not in whole) in another non-proprietary license provided that you call your license by another unambiguous name, that you do not use the preamble, that you do not mention SIL and that you clearly present your license as different from the OFL so as not to cause confusion by being too similar to the original. If you feel the OFL does not meet your needs for an open license, please contact us.
3648+
3649+8.5 Can I translate the license and the FAQ into other languages?
3650+SIL certainly recognises the need for people who are not familiar with English to be able to understand the OFL and its use. Making the license very clear and readable has been a key goal for the OFL, but we know that people understand their own language best.
3651+
3652+If you are an experienced translator, you are very welcome to translate the OFL and OFL-FAQ so that designers and users in your language community can understand the license better. But only the original English version of the license has legal value and has been approved by the community. Translations do not count as legal substitutes and should only serve as a way to explain the original license. SIL - as the author and steward of the license for the community at large - does not approve any translation of the OFL as legally valid because even small translation ambiguities could be abused and create problems.
3653+
3654+SIL gives permission to publish unofficial translations into other languages provided that they comply with the following guidelines:
3655+
3656+- Put the following disclaimer in both English and the target language stating clearly that the translation is unofficial:
3657+
3658+"This is an unofficial translation of the SIL Open Font License into <language_name>. It was not published by SIL International, and does not legally state the distribution terms for fonts that use the OFL. A release under the OFL is only valid when using the original English text. However, we recognize that this unofficial translation will help users and designers not familiar with English to better understand and use the OFL. We encourage designers who consider releasing their creation under the OFL to read the OFL-FAQ in their own language if it is available. Please go to http://scripts.sil.org/OFL for the official version of the license and the accompanying OFL-FAQ."
3659+
3660+- Keep your unofficial translation current and update it at our request if needed, for example if there is any ambiguity which could lead to confusion.
3661+
3662+If you start such a unofficial translation effort of the OFL and OFL-FAQ please let us know.
3663+
3664+
3665+9 ABOUT SIL INTERNATIONAL
3666+
3667+9.1 Who is SIL International and what do they do?
3668+SIL serves language communities worldwide, building their capacity for sustainable language development, by means of research, translation, training and materials development. SIL makes its services available to all without regard to religious belief, political ideology, gender, race, or ethnic background. SIL's members and volunteers share a Christian commitment.
3669+
3670+9.2 What does this have to do with font licensing?
3671+The ability to read, write, type and publish in one's own language is one of the most critical needs for millions of people around the world. This requires fonts that are widely available and support lesser-known languages. SIL develops - and encourages others to develop - a complete stack of writing systems implementation components available under open licenses. This open stack includes input methods, smart fonts, smart rendering libraries and smart applications. There has been a need for a common open license that is specifically applicable to fonts and related software (a crucial component of this stack), so SIL developed the SIL Open Font License with the help of the Free/Libre and Open Source Software community.
3672+
3673+9.3 How can I contact SIL?
3674+Our main web site is: http://www.sil.org/
3675+Our site about complex scripts is: http://scripts.sil.org/
3676+Information about this license (and contact information) is at: http://scripts.sil.org/OFL
3677+
3678+
3679+APPENDIX A - FONTLOG EXAMPLE
3680+
3681+Here is an example of the recommended format for a FONTLOG, although other formats are allowed.
3682+
3683+-----
3684+FONTLOG for the GlobalFontFamily fonts
3685+
3686+This file provides detailed information on the GlobalFontFamily Font Software. This information should be distributed along with the GlobalFontFamily fonts and any derivative works.
3687+
3688+Basic Font Information
3689+
3690+GlobalFontFamily is a Unicode typeface family that supports all languages that use the Latin script and its variants, and could be expanded to support other scripts.
3691+
3692+NewWorldFontFamily is based on the GlobalFontFamily and also supports Greek, Hebrew, Cyrillic and Armenian.
3693+
3694+More specifically, this release supports the following Unicode ranges...
3695+This release contains...
3696+Documentation can be found at...
3697+To contribute to the project...
3698+
3699+ChangeLog
3700+
3701+1 August 2008 (Tom Parker) GlobalFontFamily version 1.2.1
3702+- Tweaked the smart font code (Branch merged with trunk version)
3703+- Provided improved build and debugging environment for smart behaviours
3704+
3705+7 February 2007 (Pat Johnson) NewWorldFontFamily Version 1.3
3706+- Added Greek and Cyrillic glyphs
3707+
3708+7 March 2006 (Fred Foobar) NewWorldFontFamily Version 1.2
3709+- Tweaked contextual behaviours
3710+
3711+1 Feb 2005 (Jane Doe) NewWorldFontFamily Version 1.1
3712+- Improved build script performance and verbosity
3713+- Extended the smart code documentation
3714+- Corrected minor typos in the documentation
3715+- Fixed position of combining inverted breve below (U+032F)
3716+- Added OpenType/Graphite smart code for Armenian
3717+- Added Armenian glyphs (U+0531 -> U+0587)
3718+- Released as "NewWorldFontFamily"
3719+
3720+1 Jan 2005 (Joe Smith) GlobalFontFamily Version 1.0
3721+- Initial release
3722+
3723+Acknowledgements
3724+
3725+If you make modifications be sure to add your name (N), email (E), web-address (if you have one) (W) and description (D). This list is in alphabetical order.
3726+
3727+N: Jane Doe
3728+E: jane@university.edu
3729+W: http://art.university.edu/projects/fonts
3730+D: Contributor - Armenian glyphs and code
3731+
3732+N: Fred Foobar
3733+E: fred@foobar.org
3734+W: http://foobar.org
3735+D: Contributor - misc Graphite fixes
3736+
3737+N: Pat Johnson
3738+E: pat@fontstudio.org
3739+W: http://pat.fontstudio.org
3740+D: Designer - Greek & Cyrillic glyphs based on Roman design
3741+
3742+N: Tom Parker
3743+E: tom@company.com
3744+W: http://www.company.com/tom/projects/fonts
3745+D: Engineer - original smart font code
3746+
3747+N: Joe Smith
3748+E: joe@fontstudio.org
3749+W: http://joe.fontstudio.org
3750+D: Designer - original Roman glyphs
3751+
3752+Fontstudio.org is an not-for-profit design group whose purpose is...
3753+Foobar.org is a distributed community of developers...
3754+Company.com is a small business who likes to support community designers...
3755+University.edu is a renowed educational institution with a strong design department...
3756+-----
3757
3758=== added file 'i18n/fonts/amiri/OFL.txt'
3759--- i18n/fonts/amiri/OFL.txt 1970-01-01 00:00:00 +0000
3760+++ i18n/fonts/amiri/OFL.txt 2015-08-01 06:21:02 +0000
3761@@ -0,0 +1,87 @@
3762+Copyright (c) 2010-2013, Khaled Hosny (<khaledhosny@eglug.org>)
3763+
3764+This Font Software is licensed under the SIL Open Font License, Version 1.1.
3765+This license is copied below, and is also available with a FAQ at:
3766+http://scripts.sil.org/OFL
3767+
3768+---------------------------------------------------------------------------
3769+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
3770+---------------------------------------------------------------------------
3771+
3772+PREAMBLE
3773+
3774+The goals of the Open Font License (OFL) are to stimulate worldwide development
3775+of collaborative font projects, to support the font creation efforts of academic
3776+and linguistic communities, and to provide a free and open framework in which
3777+fonts may be shared and improved in partnership with others.
3778+
3779+The OFL allows the licensed fonts to be used, studied, modified and redistributed
3780+freely as long as they are not sold by themselves. The fonts, including any
3781+derivative works, can be bundled, embedded, redistributed and/or sold with any
3782+software provided that any reserved names are not used by derivative works. The
3783+fonts and derivatives, however, cannot be released under any other type of license.
3784+The requirement for fonts to remain under this license does not apply to any
3785+document created using the fonts or their derivatives.
3786+
3787+DEFINITIONS
3788+
3789+"Font Software" refers to the set of files released by the Copyright Holder(s) under
3790+this license and clearly marked as such. This may include source files, build
3791+scripts and documentation.
3792+
3793+"Reserved Font Name" refers to any names specified as such after the copyright
3794+statement(s).
3795+
3796+"Original Version" refers to the collection of Font Software components as
3797+distributed by the Copyright Holder(s).
3798+
3799+"Modified Version" refers to any derivative made by adding to, deleting, or
3800+substituting -- in part or in whole -- any of the components of the Original Version,
3801+by changing formats or by porting the Font Software to a new environment.
3802+
3803+"Author" refers to any designer, engineer, programmer, technical writer or other
3804+person who contributed to the Font Software.
3805+
3806+PERMISSION & CONDITIONS
3807+
3808+Permission is hereby granted, free of charge, to any person obtaining a copy of the
3809+Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell
3810+modified and unmodified copies of the Font Software, subject to the following
3811+conditions:
3812+
3813+1) Neither the Font Software nor any of its individual components, in Original or
3814+Modified Versions, may be sold by itself.
3815+
3816+2) Original or Modified Versions of the Font Software may be bundled, redistributed
3817+and/or sold with any software, provided that each copy contains the above copyright
3818+notice and this license. These can be included either as stand-alone text files,
3819+human-readable headers or in the appropriate machine-readable metadata fields within
3820+text or binary files as long as those fields can be easily viewed by the user.
3821+
3822+3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless
3823+explicit written permission is granted by the corresponding Copyright Holder. This
3824+restriction only applies to the primary font name as presented to the users.
3825+
3826+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall
3827+not be used to promote, endorse or advertise any Modified Version, except to
3828+acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with
3829+their explicit written permission.
3830+
3831+5) The Font Software, modified or unmodified, in part or in whole, must be distributed
3832+entirely under this license, and must not be distributed under any other license. The
3833+requirement for fonts to remain under this license does not apply to any document
3834+created using the Font Software.
3835+
3836+TERMINATION
3837+
3838+This license becomes null and void if any of the above conditions are not met.
3839+
3840+DISCLAIMER
3841+
3842+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
3843+INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
3844+PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER
3845+RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3846+LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
3847+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR
3848+INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
3849
3850=== added file 'i18n/fonts/amiri/README.txt'
3851--- i18n/fonts/amiri/README.txt 1970-01-01 00:00:00 +0000
3852+++ i18n/fonts/amiri/README.txt 2015-08-01 06:21:02 +0000
3853@@ -0,0 +1,8 @@
3854+designer: Khaled Hosny
3855+url: http://amirifont.org
3856+license: OFL
3857+description: Amiri is a classical Arabic typeface in Naskh style for
3858+typesetting books and other running text. Its design is a revival of the
3859+beautiful typeface pioneered in early 20th century by Bulaq Press in Cairo,
3860+also known as Amiria Press, after which the font is named.
3861+
3862
3863=== added file 'i18n/fonts/amiri/amiri-bold.ttf'
3864Binary files i18n/fonts/amiri/amiri-bold.ttf 1970-01-01 00:00:00 +0000 and i18n/fonts/amiri/amiri-bold.ttf 2015-08-01 06:21:02 +0000 differ
3865=== added file 'i18n/fonts/amiri/amiri-boldslanted.ttf'
3866Binary files i18n/fonts/amiri/amiri-boldslanted.ttf 1970-01-01 00:00:00 +0000 and i18n/fonts/amiri/amiri-boldslanted.ttf 2015-08-01 06:21:02 +0000 differ
3867=== added file 'i18n/fonts/amiri/amiri-regular.ttf'
3868Binary files i18n/fonts/amiri/amiri-regular.ttf 1970-01-01 00:00:00 +0000 and i18n/fonts/amiri/amiri-regular.ttf 2015-08-01 06:21:02 +0000 differ
3869=== added file 'i18n/fonts/amiri/amiri-slanted.ttf'
3870Binary files i18n/fonts/amiri/amiri-slanted.ttf 1970-01-01 00:00:00 +0000 and i18n/fonts/amiri/amiri-slanted.ttf 2015-08-01 06:21:02 +0000 differ
3871=== modified file 'maps/MP Scenarios/Island Hopping.wmf/scripting/first_island.lua'
3872--- maps/MP Scenarios/Island Hopping.wmf/scripting/first_island.lua 2014-07-28 11:22:56 +0000
3873+++ maps/MP Scenarios/Island Hopping.wmf/scripting/first_island.lua 2015-08-01 06:21:02 +0000
3874@@ -21,10 +21,10 @@
3875 _nplayers_finished_island[island_idx] = rank
3876
3877 local rewards = _finish_rewards[island_idx][rank]
3878- send_to_all(rt(
3879- p(msgs_finished_island[rank]:bformat(plr.name, island_idx + 1)) ..
3880- p(finished_island_continues:format(format_rewards(rewards)))
3881- ))
3882+ send_to_all(
3883+ msgs_finished_island[rank]:bformat(plr.name, island_idx + 1) ..
3884+ finished_island_continues:format(format_rewards(rewards))
3885+ )
3886
3887 local new_hq = hop_to_next_island(plr, island_idx)
3888 add_wares(new_hq, rewards)
3889
3890=== modified file 'maps/MP Scenarios/Island Hopping.wmf/scripting/multiplayer_init.lua'
3891--- maps/MP Scenarios/Island Hopping.wmf/scripting/multiplayer_init.lua 2014-10-02 11:45:56 +0000
3892+++ maps/MP Scenarios/Island Hopping.wmf/scripting/multiplayer_init.lua 2015-08-01 06:21:02 +0000
3893@@ -104,7 +104,7 @@
3894 function format_rewards(r)
3895 rv = {}
3896 for name,count in pairs(r) do
3897- rv[#rv + 1] = getplural(count, name) .. "<br>\n"
3898+ rv[#rv + 1] = li(getplural(count, name))
3899 end
3900 return table.concat(rv)
3901 end
3902
3903=== modified file 'maps/MP Scenarios/Island Hopping.wmf/scripting/texts.lua'
3904--- maps/MP Scenarios/Island Hopping.wmf/scripting/texts.lua 2015-07-26 10:39:48 +0000
3905+++ maps/MP Scenarios/Island Hopping.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
3906@@ -1,61 +1,40 @@
3907 -- =======================================================================
3908 -- Texts for this scenario
3909 -- =======================================================================
3910-welcome_msg = rt(
3911+-- NOCOM(#gunchleoc): test when editboxes have been fixed.
3912+welcome_msg =
3913 h1(_"Welcome to Island Hopping") ..
3914 h2(_"Rules") ..
3915- p(_(
3916-[[Island Hopping is a traditional tournament in Atlantean culture. ]] ..
3917-[[The rules of the game are simple: you start with a headquarters on an island. ]] ..
3918-[[When you finish a castle at the end of the first island, you are granted a ]] ..
3919-[[second headquarters on a second island, which will contain all wares from your ]] ..
3920-[[first headquarters.]]
3921-)) ..
3922- p(_(
3923-[[If you finish a castle in the target area on the second island, you will get ]] ..
3924-[[a third headquarters on the third island. You must build a castle at ]] ..
3925-[[the center of the third island and hold it for 20 minutes to win the game.]]
3926-)) ..
3927- p(_(
3928-[[Whenever you finish an island, you will get bonus wares, depending on how many players ]] ..
3929-[[have finished the island before you. The earlier you finish, the fewer wares you will get. ]] ..
3930-[[See below for the details.]])) .. p(_(
3931-[[The point is that the first island only provides stones and wood, the second only meadows and resources. The economies you leave behind will continue to work for you, but you will only reap the benefits at the moment you reach a new island.]])
3932-) ..
3933-p(_
3934-[[Finally, be careful not to waste your quartz and diamonds.]]
3935-) ..
3936-h2(_"Finish Rewards") ..
3937-h3(_"First Island") ..
3938-h4(_"1st to finish") .. p(format_rewards(_finish_rewards[1][1])) ..
3939-h4(_"2nd to finish") .. p(format_rewards(_finish_rewards[1][2])) ..
3940-h4(_"3rd to finish") .. p(format_rewards(_finish_rewards[1][3])) ..
3941-h4(_"4th to finish") .. p(format_rewards(_finish_rewards[1][4])) ..
3942-h3(_"Second Island") ..
3943-h4(_"1st to finish") .. p(format_rewards(_finish_rewards[2][1])) ..
3944-h4(_"2nd to finish") .. p(format_rewards(_finish_rewards[2][2])) ..
3945-h4(_"3rd to finish") .. p(format_rewards(_finish_rewards[2][3])) ..
3946-h4(_"4th to finish") .. p(format_rewards(_finish_rewards[2][4]))
3947-)
3948-
3949+ p(_([[Island Hopping is a traditional tournament in Atlantean culture. The rules of the game are simple: you start with a headquarters on an island. When you finish a castle at the end of the first island, you are granted a second headquarters on a second island, which will contain all wares from your first headquarters.]])) ..
3950+ p(_([[If you finish a castle in the target area on the second island, you will get a third headquarters on the third island. You must build a castle at the center of the third island and hold it for 20 minutes to win the game.]])) ..
3951+ p(_([[Whenever you finish an island, you will get bonus wares, depending on how many players have finished the island before you. The earlier you finish, the fewer wares you will get. See below for the details.]])) ..
3952+ p(_([[The point is that the first island only provides stones and wood, the second only meadows and resources. The economies you leave behind will continue to work for you, but you will only reap the benefits at the moment you reach a new island.]])) ..
3953+ p(_[[Finally, be careful not to waste your quartz and diamonds.]]) ..
3954+ h2(_"Finish Rewards") ..
3955+ h3(_"First Island") ..
3956+ h4(_"1st to finish") .. p(format_rewards(_finish_rewards[1][1])) ..
3957+ h4(_"2nd to finish") .. p(format_rewards(_finish_rewards[1][2])) ..
3958+ h4(_"3rd to finish") .. p(format_rewards(_finish_rewards[1][3])) ..
3959+ h4(_"4th to finish") .. p(format_rewards(_finish_rewards[1][4])) ..
3960+ h3(_"Second Island") ..
3961+ h4(_"1st to finish") .. p(format_rewards(_finish_rewards[2][1])) ..
3962+ h4(_"2nd to finish") .. p(format_rewards(_finish_rewards[2][2])) ..
3963+ h4(_"3rd to finish") .. p(format_rewards(_finish_rewards[2][3])) ..
3964+ h4(_"4th to finish") .. p(format_rewards(_finish_rewards[2][4]))
3965
3966 msgs_finished_island = {
3967- _"%1$s was the first to reach Island number %2$i.",
3968- _"%1$s was the second to reach Island number %2$i.",
3969- _"%1$s was the third to reach Island number %2$i.",
3970- _"%1$s was the fourth to reach Island number %2$i."
3971+ p(_"%1$s was the first to reach Island number %2$i."),
3972+ p(_"%1$s was the second to reach Island number %2$i."),
3973+ p(_"%1$s was the third to reach Island number %2$i."),
3974+ p(_"%1$s was the fourth to reach Island number %2$i.")
3975 }
3976-finished_island_continues = _ "The reward for this feat amounts to:" .. "<br>%s"
3977-
3978-player_claims_hill = rt(p(_
3979-[[%s is now King of the Hill and will win the game in 20 minutes, if nobody takes over the hill before then.]]
3980-))
3981-lost_control = rt(p(_
3982-[[%s lost control of the hill.]]
3983-))
3984-had_control_for = rt(p(_[[%1$s has been King of the Hill for %2$s!]]))
3985-player_won = rt(p(_[[%s has won the game. Congratulations!]]))
3986-
3987-
3988-
3989-
3990+
3991+finished_island_continues = p(_"The reward for this feat amounts to:") .. p("%s")
3992+
3993+player_claims_hill = p(_[[%s is now King of the Hill and will win the game in 20 minutes, if nobody takes over the hill before then.]])
3994+
3995+lost_control = p(_[[%s lost control of the hill.]])
3996+
3997+had_control_for = p(_[[%1$s has been King of the Hill for %2$s!]])
3998+
3999+player_won = p(_[[%s has won the game. Congratulations!]])
4000
4001=== modified file 'maps/MP Scenarios/Smugglers.wmf/scripting/texts.lua'
4002--- maps/MP Scenarios/Smugglers.wmf/scripting/texts.lua 2014-10-03 20:16:29 +0000
4003+++ maps/MP Scenarios/Smugglers.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
4004@@ -1,6 +1,7 @@
4005 -- =======================================================================
4006 -- Texts for this scenario
4007 -- =======================================================================
4008+-- NOCOM(#gunchleoc): convert when editboxes have been fixed.
4009 welcome_msg = rt(
4010 h1(_"Smugglers") ..
4011 h2(_"Rules") ..
4012
4013=== modified file 'maps/Plateau.wmf/scripting/texts.lua'
4014--- maps/Plateau.wmf/scripting/texts.lua 2014-11-03 08:38:48 +0000
4015+++ maps/Plateau.wmf/scripting/texts.lua 2015-08-01 06:21:02 +0000
4016@@ -26,7 +26,7 @@
4017 title = _"Capture the Ancient Castle",
4018 number = 1,
4019 body = objective_text(_"Capture the Ancient Castle",
4020- listitem_bullet(_[[Defeat Lanissa and capture the ancient castle.]])
4021+ li(_[[Defeat Lanissa and capture the ancient castle.]])
4022 ),
4023 }
4024
4025@@ -35,7 +35,7 @@
4026 title = _"Defeat Erwyn",
4027 number = 1,
4028 body = objective_text(_"Defeat Erwyn",
4029- listitem_bullet(_[[Defeat Erwyn. He commands the strongest opposing military force left on this island.]])
4030+ li(_[[Defeat Erwyn. He commands the strongest opposing military force left on this island.]])
4031 ),
4032 }
4033 obj_defeat_jomo = {
4034@@ -43,7 +43,7 @@
4035 title = _"Defeat Jomo",
4036 number = 1,
4037 body = objective_text(_"Defeat Jomo",
4038- listitem_bullet(_[[Defeat Jomo. He is taking care of the soldiers’ food supply.]])
4039+ li(_[[Defeat Jomo. He is taking care of the soldiers’ food supply.]])
4040 ),
4041 }
4042
4043@@ -53,11 +53,7 @@
4044
4045 function obj_message(title, text)
4046 return
4047- rt("<p font-size=20 font-weight=bold font-face=serif font-color=3333FF>"
4048- .. title ..
4049- "</p><p font-size=10> <br></p>"
4050- .. p(text)
4051- )
4052+ h1("3333FF", title) .. p(text)
4053 end
4054
4055 briefing_1_the_forbidden_island = {
4056@@ -76,8 +72,8 @@
4057 height = 300,
4058 posy = 1,
4059 body = obj_message(_"An Ancient Castle",
4060- _([[By the Gods! One of our scouts has discovered a mighty castle at the center of the old plateau. The castle must be quite old and seems to have been built in a foreign style. It’s quite obvious that this is not barbarian craft.]]) .. paragraphdivider() ..
4061- _([[Let’s hope that Lanissa – the warlord holding sway over that castle – has not discovered our movements yet. Perhaps we have a chance of conquering that mighty building without a bigger fight! However, it is essential that we capture it. It will be the key to our reign over this island!]]))
4062+ _([[By the Gods! One of our scouts has discovered a mighty castle at the center of the old plateau. The castle must be quite old and seems to have been built in a foreign style. It’s quite obvious that this is not barbarian craft.]]) ..
4063+ p(_([[Let’s hope that Lanissa – the warlord holding sway over that castle – has not discovered our movements yet. Perhaps we have a chance of conquering that mighty building without a bigger fight! However, it is essential that we capture it. It will be the key to our reign over this island!]])))
4064 .. new_objectives(obj_capture_ancient_castle)
4065 }
4066
4067@@ -87,8 +83,8 @@
4068 height = 300,
4069 posy = 1,
4070 body = obj_message(_"Ancient Castle Captured",
4071- _([[Wonderful! Our troops have finally defeated Lanissa and her soldiers. The ancient castle is ours!]]) .. paragraphdivider() ..
4072- _([[It is amazing how far one can see from the highest tower of the castle. We can watch the whole island. So now I wonder why Lanissa did not see us and thus did not prepare. Be that as it may, some things will never come to the light of day. The only important issue at the moment are the opposing troops still left. We have discovered enemy positions held by Erwyn to the north and east of the castle. He is known to be a strong warlord and surely commands the strongest warriors. In the south, we caught sight of some food infrastructures guarded by Jomo – a younger warlord – and we should take care of those infrastructures so we can cut off our enemies’ food supply.]]))
4073+ _([[Wonderful! Our troops have finally defeated Lanissa and her soldiers. The ancient castle is ours!]]) ..
4074+ p(_([[It is amazing how far one can see from the highest tower of the castle. We can watch the whole island. So now I wonder why Lanissa did not see us and thus did not prepare. Be that as it may, some things will never come to the light of day. The only important issue at the moment are the opposing troops still left. We have discovered enemy positions held by Erwyn to the north and east of the castle. He is known to be a strong warlord and surely commands the strongest warriors. In the south, we caught sight of some food infrastructures guarded by Jomo – a younger warlord – and we should take care of those infrastructures so we can cut off our enemies’ food supply.]])))
4075 .. new_objectives(obj_defeat_erwyn) .. new_objectives(obj_defeat_jomo)
4076 }
4077
4078@@ -116,6 +112,6 @@
4079 height = 300,
4080 posy = 1,
4081 body = obj_message(_"Victory!",
4082- _([[Finally! The island is completely ours. Now we just have to defend it better than the warlords did.]]) .. paragraphdivider() ..
4083- _("Congratulations! You have mastered this scenario. You may play on if you like!"))
4084+ _([[Finally! The island is completely ours. Now we just have to defend it better than the warlords did.]]) ..
4085+ p(_("Congratulations! You have mastered this scenario. You may play on if you like!")))
4086 }
4087
4088=== modified file 'scripting/format_scenario.lua'
4089--- scripting/format_scenario.lua 2014-11-28 08:45:02 +0000
4090+++ scripting/format_scenario.lua 2015-08-01 06:21:02 +0000
4091@@ -18,14 +18,14 @@
4092 -- return speech("map:princess.png", "2F9131", title, text)
4093 -- end
4094 --
4095--- :arg img: name of the image to use for this speaker
4096+-- :arg image: name of the image to use for this speaker
4097 -- :arg clr: a valid 6 char hex color to use for the name of this speaker
4098 -- :arg title: Title of this text.
4099 -- :arg text: The text itself. If this is nil, :const:`title` is used as text
4100 -- instead and there will not be any title.
4101 -- :returns: the formatted text.
4102 --
4103-function speech(img, clr, g_title, g_text)
4104+function speech(image, clr, g_title, g_text)
4105 local title, text = g_title, g_text
4106 if not text then
4107 title = nil
4108@@ -37,75 +37,22 @@
4109
4110 local s = ""
4111 if title then
4112- s = rt("<p font-size=20 font-weight=bold font-face=serif " ..
4113- ("font-color=%s>"):format(clr) .. title ..
4114- "</p><p font-size=8> <br></p>"
4115- )
4116+ s = h1(clr, title)
4117 end
4118-
4119- return s .. rt(("image=%s"):format(img), p(text))
4120-end
4121-
4122-
4123--- RST
4124--- .. function:: listitem(symbol, text)
4125---
4126--- Adds the symbol in front of the text to create a list item and adds a paragraphdivider
4127---
4128--- :arg symbol: the item symbol for the list, e.g. "•" or "→"
4129--- :arg text: the text of the list item
4130---
4131--- :returns: symbol .. " " .. text .. paragraphdivider()
4132-function listitem(symbol, text)
4133- return symbol .. " " .. text .. listdivider()
4134-end
4135-
4136--- RST
4137--- .. function:: listitem_bullet(text)
4138+ return s .. p(img(image) .. text)
4139+end
4140+
4141+
4142+-- RST
4143+-- .. function:: li_arrow(text)
4144 --
4145 -- Creates a list item with an arrow
4146 --
4147 -- :arg text: the text of the list item
4148 --
4149--- :returns: listitem("→", text)
4150-function listitem_arrow(text)
4151- return listitem("→", text)
4152-end
4153-
4154--- RST
4155--- .. function:: listitem_bullet(text)
4156---
4157--- Creates a list item with a bullet point
4158---
4159--- :arg text: the text of the list item
4160---
4161--- :returns: listitem("•", text)
4162-function listitem_bullet(text)
4163- return listitem("•", text)
4164-end
4165-
4166-
4167--- RST
4168--- .. function:: listdivider()
4169---
4170--- Closes a paragraph and opens a new paragraph.
4171--- Use this before starting a list when it doesn't create a paragraph.
4172--- If you want more space, before the list, use paragraphdivider().
4173---
4174--- :returns: <br></p><p font-size=4><br></p><p line-spacing=3 font-size=12>
4175-function listdivider()
4176- return ("<br></p><p font-size=4><br></p><p line-spacing=3 font-size=12>")
4177-end
4178-
4179--- RST
4180--- .. function:: paragraphdivider()
4181---
4182--- Closes a paragraph and opens a new paragraph. Use this when you format a string with the speech function
4183--- and need to divide the speech into multiple paragraphs.
4184---
4185--- :returns: <br></p><p font-size=8><br></p><p line-spacing=3 font-size=12>
4186-function paragraphdivider()
4187- return ("<br></p><p font-size=8><br></p><p line-spacing=3 font-size=12>")
4188+-- :returns: li("→", text)
4189+function li_arrow(text)
4190+ return li("→", text)
4191 end
4192
4193
4194@@ -118,7 +65,7 @@
4195 -- objective text.
4196 --
4197 function objective_text(heading, body)
4198- return rt(h2(heading) .. p(body))
4199+ return h2(heading) .. p(body)
4200 end
4201
4202
4203@@ -141,8 +88,5 @@
4204 s = s .. obj.body
4205 sum = sum + obj.number
4206 end
4207- return rt("<p font-size=10> <br></p>" ..
4208- "<p font=serif font-size=18 font-weight=bold font-color=D1D1D1>"
4209- .. ngettext("New Objective", "New Objectives", sum) .. "</p>") .. s
4210+ return h1(ngettext("New Objective", "New Objectives", sum)) .. s
4211 end
4212-
4213
4214=== modified file 'scripting/formatting.lua'
4215--- scripting/formatting.lua 2015-05-11 16:49:40 +0000
4216+++ scripting/formatting.lua 2015-08-01 06:21:02 +0000
4217@@ -1,3 +1,4 @@
4218+-- NOCOM(#gunchleoc): Wrap all tags and document allowed attributes when we're done
4219 -- RST
4220 -- formatting.lua
4221 -- --------------
4222@@ -5,93 +6,229 @@
4223 -- Function to simplify and unique text formatting in scenarios and help files.
4224 -- Most of these functions are simple wrapper functions that make working with
4225 -- widelands rich text formatting system more bearable.
4226+-- Function names generally follow HTML names.
4227
4228 -- RST
4229--- .. function:: rt(text_or_options[, text = nil])
4230---
4231--- Wraps a block of text into Lua rich text: <rt>%s</rt>.
4232---
4233--- :arg text_or_options: either the text of this rich text
4234--- or any options you care to give it (e.g. image=pic.png).
4235--- :type text_or_options: :class:`string`
4236--- :arg text: if text_or_options is given, this will be the text of the
4237--- rich text.
4238+-- .. function:: rt(text_or_attributes[, text = nil])
4239+--
4240+-- Wraps a block of text into Lua rich text.
4241+-- Only call this once for the whole text that gets sent to the backend.
4242+-- There is no general need to wrap an rt tag around your text,
4243+-- because the backend will take care of it.
4244+-- So, only use this function if you wish to add some attributes to the tag.
4245+--
4246+-- Allowed attributes are: NOCOM
4247+--
4248+-- :arg attributes: the attributes for the rt tag.
4249+-- :type attributes: :class:`string`
4250+-- :arg text: the text to be enclosed in rich text tags.
4251+-- :type text: :class:`string`
4252 -- :returns: the wrapped rich text.
4253 --
4254-function rt(text_or_opts, text)
4255- local k = "<rt>"
4256+function rt(text_or_attributes, text)
4257 if text then
4258- k = ("<rt %s>"):format(text_or_opts)
4259- else
4260- text = text_or_opts
4261- end
4262-
4263- return k .. text .. "</rt>"
4264-end
4265-
4266--- RST
4267--- .. function:: h1(s)
4268+ return "<rt " .. text_or_attributes .. ">" .. text .. "</rt>"
4269+ else
4270+ return "<rt>" .. text_or_attributes .. "</rt>"
4271+ end
4272+end
4273+
4274+
4275+-- RST
4276+-- .. function:: img(src, [ref])
4277+--
4278+-- Turns an image src path into an image tag for richtext.
4279+--
4280+-- :arg src: the file path to the image.
4281+-- :type src: :class:`string`
4282+-- :arg ref: NOCOM.
4283+-- :type ref: :class:`string`
4284+-- :returns: the img tag.
4285+--
4286+function img(src, ref)
4287+ if ref then
4288+ return "<img src=" .. src .." ref=" .. ref .. ">"
4289+ else
4290+ return "<img src=" .. src .. ">"
4291+ end
4292+end
4293+
4294+
4295+function title(font_face, text)
4296+ return p_font("align=center", "size=38 face=".. font_face .. " color=2F9131", text)
4297+end
4298+
4299+
4300+-- RST
4301+-- .. function:: h1(text_or_color[, text = nil])
4302 --
4303 -- Returns a paragraph formatted as a big heading with a small gap after it.
4304 -- The mnemonic comes from HTML.
4305 --
4306--- :returns: A paragraph with s formatted as heading.
4307-function h1(s)
4308- return "<p font-size=18 font-weight=bold font-color=D1D1D1>"
4309- .. s .. "<br></p><p font-size=8> <br></p>"
4310+-- :returns: A paragraph with text formatted as heading.
4311+function h1(text_or_color, text)
4312+ if text then
4313+ return p_font("", "size=18 bold=1 color=".. text_or_color .. " face=serif", text)
4314+ else
4315+ return p_font("", "size=18 bold=1 color=D1D1D1 face=serif", text_or_color)
4316+ end
4317 end
4318
4319 -- RST
4320--- .. function:: h2(s)
4321+-- .. function:: h2(text)
4322 --
4323 -- Like :func:`h1` but smaller.
4324 --
4325--- :returns: A paragraph with s formatted as heading.
4326-function h2(s)
4327- return "<p font-size=2> <br></p><p font-size=14 font-weight=bold font-color=D1D1D1>"
4328- .. s .. "<br></p><p font-size=4> <br></p>"
4329+-- :returns: A paragraph with text formatted as heading.
4330+function h2(text)
4331+ return p_font("", "size=2 face=serif", "") .. p_font("", "size=14 bold=1 color=D1D1D1 face=serif", text)
4332 end
4333
4334 -- RST
4335--- .. function:: h3(s)
4336+-- .. function:: h3(text)
4337 --
4338 -- Like :func:`h2` but smaller.
4339 --
4340--- :returns: A paragraph with s formatted as heading.
4341+-- :returns: A paragraph with text formatted as heading.
4342 --
4343-function h3(s)
4344- return "<p font-size=13 font-color=D1D1D1>"
4345- .. s .. "<br></p><p font-size=4> <br></p>"
4346+function h3(text)
4347+ return p_font("", "size=13 italic=1 color=D1D1D1 face=serif", text)
4348 end
4349
4350 -- RST
4351--- .. function:: h4(s)
4352+-- .. function:: h4(text)
4353 --
4354 -- Like :func:`h3` but smaller.
4355 --
4356--- :returns: A paragraph with s formatted as heading.
4357---
4358-function h4(s)
4359- return "<p font-size=12 font-style=italic font-color=D1D1D1>"
4360- .. s .. "<br></p><p font-size=4> <br></p>"
4361-end
4362-
4363--- RST
4364--- .. function:: p(text_or_options[, text = nil])
4365---
4366--- Returns one paragraph with text followed by a small vertical gap. Options
4367--- can be given as first argument similar to :func:`rt`, otherwise the
4368--- default options will be :const:`line-spacing=3 font-size=12`.
4369---
4370--- :returns: The text wrapped in <p>%s</p>
4371-function p(text_or_opts, text)
4372- local opts = "line-spacing=3 font-size=12"
4373- if text then
4374- opts = text_or_opts
4375- else
4376- text = text_or_opts
4377- end
4378-
4379- return ("<p %s>"):format(opts) .. text .. "<br></p>" ..
4380- "<p font-size=8> <br></p>"
4381+-- :returns: A paragraph with text formatted as heading.
4382+--
4383+function h4(text)
4384+ return p_font("", "size=12 italic=1 color=D1D1D1 face=serif", text)
4385+end
4386+
4387+-- RST
4388+-- .. function:: p(text_or_attributes[, text = nil])
4389+--
4390+-- Returns one paragraph with text followed by a small vertical gap. Options
4391+-- can be given as first argument similar to :func:`rt`.
4392+--
4393+-- :returns: The text wrapped in <p>%s</p>
4394+function p(text_or_attributes, text)
4395+ if text then
4396+ return open_p(text_or_attributes) .. text .. close_p()
4397+ else
4398+ return open_p() .. text_or_attributes .. close_p()
4399+ end
4400+end
4401+
4402+
4403+-- RST
4404+-- .. function:: p(text_or_attributes[, text = nil])
4405+--
4406+-- Returns one paragraph with text followed by a small vertical gap. Options
4407+-- can be given as first argument similar to :func:`rt`.
4408+--
4409+-- :returns: The text wrapped in <p>%s</p>
4410+function p_font(p_or_font_or_attributes, text_or_font_attributes, text)
4411+ if text then
4412+ return ("<p %s>"):format(p_or_font_or_attributes) .. "<font " .. text_or_font_attributes .. ">" .. text .. close_p()
4413+ else
4414+ return "<p><font " .. p_or_font_or_attributes .. ">" .. text_or_font_attributes .. close_p()
4415+ end
4416+end
4417+
4418+
4419+-- RST
4420+-- .. function:: open_p([attributes = nil])
4421+--
4422+-- Returns a paragraph open tag and default font size. Options
4423+-- can be given as first argument similar to :func:`rt`.
4424+--
4425+-- :returns: <p> with added attributes and default font
4426+function open_p(attributes)
4427+ if attributes then
4428+ return ("<p %s>"):format(attributes) .. "<font size=12>"
4429+ else
4430+ return "<p><font size=12>"
4431+ end
4432+end
4433+
4434+
4435+-- RST
4436+-- .. function:: close_p(t)
4437+--
4438+-- Closes a paragraph.
4439+--
4440+-- :returns: The closing tags for a paragraph
4441+function close_p(t)
4442+ return "</font></p>"
4443+end
4444+
4445+-- RST
4446+-- .. function:: font(attributes, text = nil)
4447+--
4448+-- NOCOM
4449+function font(attributes, text)
4450+ return ("<font %s>"):format(attributes) .. text .. "</font>"
4451+end
4452+
4453+-- RST
4454+-- .. function:: dl(dt, dd)
4455+--
4456+-- Description list
4457+-- NOCOM
4458+function dl(dt, dd)
4459+ return p(b(dt) .. " " .. dd)
4460+end
4461+
4462+-- RST
4463+-- .. function:: li(text_or_symbol[, text = nil])
4464+--
4465+-- Adds the symbol in front of the text to create a list item and
4466+-- wraps it in a paragraph
4467+--
4468+-- :arg symbol: the item symbol for the list, e.g. "•" or "→"
4469+-- :arg text: the text of the list item
4470+--
4471+-- :returns: // NOCOM update documentation
4472+function li(text_or_symbol, text)
4473+ if text then
4474+ return p(text_or_symbol .. " " .. text)
4475+ else
4476+ return p("• " .. text_or_symbol)
4477+ end
4478+end
4479+
4480+function a(link)
4481+ return font("underline=1", link)
4482+end
4483+
4484+function b(text)
4485+ return font("bold=1", text)
4486+end
4487+
4488+function i(text)
4489+ return font("italic=1", text)
4490+end
4491+
4492+function u(text)
4493+ return font("underline=1", text)
4494+end
4495+
4496+
4497+function div(text_or_attributes, text)
4498+ if text then
4499+ return ("<div %s>"):format(text_or_attributes) .. text .. "</div>"
4500+ else
4501+ return ("<div>") .. text_or_attributes .. "</div>"
4502+ end
4503+end
4504+
4505+
4506+function td(width_or_text, text)
4507+ if text then
4508+ return div("width=" .. width_or_text, text)
4509+ else
4510+ return div(width_or_text)
4511+ end
4512 end
4513
4514=== modified file 'scripting/win_condition_functions.lua'
4515--- scripting/win_condition_functions.lua 2014-10-02 20:45:24 +0000
4516+++ scripting/win_condition_functions.lua 2015-08-01 06:21:02 +0000
4517@@ -1,3 +1,4 @@
4518+include "scripting/formatting.lua"
4519 include "scripting/messages.lua"
4520
4521 -- RST
4522
4523=== modified file 'scripting/win_conditions/collectors.lua'
4524--- scripting/win_conditions/collectors.lua 2015-05-06 07:15:40 +0000
4525+++ scripting/win_conditions/collectors.lua 2015-08-01 06:21:02 +0000
4526@@ -3,8 +3,8 @@
4527 -- =======================================================================
4528
4529 include "scripting/coroutine.lua" -- for sleep
4530+include "scripting/formatting.lua"
4531 include "scripting/messages.lua"
4532-include "scripting/formatting.lua"
4533 include "scripting/table.lua"
4534 include "scripting/win_condition_functions.lua"
4535
4536@@ -25,14 +25,7 @@
4537 func = function()
4538
4539 -- set the objective with the game type for all players
4540- broadcast_objective("win_condition", wc_name, wc_desc)
4541-
4542- -- Simple flowing text. One Paragraph
4543- local function p(s)
4544- return "<p line-spacing=3 font-size=12>" .. s .. "<br></p>" ..
4545- "<p font-size=8> <br></p>"
4546- end
4547-
4548+ broadcast_objective("win_condition", wc_name, p(wc_desc))
4549
4550 -- The list of wares that give points
4551 local point_table = {
4552@@ -97,7 +90,7 @@
4553 )
4554
4555 local points = 0
4556- local descr = { "</p>" .. h2((_"Status for %s"):format(plr.name)) .. "<p line-spacing=3 font-size=12>"}
4557+ local descr = {h2((_"Status for %s"):format(plr.name))}
4558 for idx, ware in ipairs(point_table[plr.tribe_name .. "_order"]) do
4559 local value = point_table[plr.tribe_name][ware]
4560 local count = 0
4561@@ -108,13 +101,12 @@
4562 points = points + lpoints
4563 local warename = wl.Game():get_ware_description(plr.tribe_name, ware).descname
4564 -- TRANSLATORS: For example: 'gold (3 P) x 4 = 12 P", P meaning "Points'
4565- descr[#descr+1] = [[• ]] .. (_" %1$s (%2$i P) x %3$i = %4$i P"):bformat(
4566- warename, value, count, lpoints
4567- ) .. "<br>"
4568+ descr[#descr+1] =
4569+ li((_" %1$s (%2$i P) x %3$i = %4$i P"):bformat(
4570+ warename, value, count, lpoints))
4571 end
4572- descr[#descr+1] = "</p>" .. h3(ngettext("Total: %i point", "Total: %i points", points)):format(points)
4573- .. "<p line-spacing=3 font-size=12>"
4574- return points, p(table.concat(descr, "\n"))
4575+ descr[#descr+1] = h3(ngettext("Total: %i point", "Total: %i points", points)):format(points)
4576+ return points, table.concat(descr, "")
4577 end
4578
4579 local plrs = wl.Game().players
4580@@ -131,7 +123,6 @@
4581 time = (ngettext("%i minute", "%i minutes", m)):format(m)
4582 end
4583 local msg = p(_"The game will end in %s."):format(time)
4584- msg = msg .. "\n\n"
4585
4586 for idx, plr in ipairs(plrs) do
4587 local points, pstat = _calc_points(plr)
4588@@ -140,7 +131,7 @@
4589 end
4590
4591 for idx, plr in ipairs(plrs) do
4592- send_message(plr, game_status.title, "<rt>" .. msg .. "</rt>", {popup = true})
4593+ send_message(plr, game_status.title, msg, {popup = true})
4594 end
4595 end
4596
4597
4598=== modified file 'scripting/win_conditions/defeat_all.lua'
4599--- scripting/win_conditions/defeat_all.lua 2015-01-31 08:39:43 +0000
4600+++ scripting/win_conditions/defeat_all.lua 2015-08-01 06:21:02 +0000
4601@@ -3,6 +3,7 @@
4602 -- =======================================================================
4603
4604 include "scripting/coroutine.lua" -- for sleep
4605+include "scripting/formatting.lua"
4606 include "scripting/win_condition_functions.lua"
4607
4608 set_textdomain("win_conditions")
4609@@ -19,7 +20,7 @@
4610 local plrs = wl.Game().players
4611
4612 -- set the objective with the game type for all players
4613- broadcast_objective("win_condition", wc_name, wc_desc)
4614+ broadcast_objective("win_condition", wc_name, p(wc_desc))
4615
4616 -- Iterate all players, if one is defeated, remove him
4617 -- from the list, send him a defeated message and give him full vision
4618
4619=== modified file 'scripting/win_conditions/endless_game.lua'
4620--- scripting/win_conditions/endless_game.lua 2015-01-31 08:39:43 +0000
4621+++ scripting/win_conditions/endless_game.lua 2015-08-01 06:21:02 +0000
4622@@ -3,6 +3,7 @@
4623 -- =======================================================================
4624
4625 include "scripting/coroutine.lua" -- for sleep
4626+include "scripting/formatting.lua"
4627 include "scripting/win_condition_functions.lua"
4628
4629 set_textdomain("win_conditions")
4630@@ -19,7 +20,7 @@
4631 local plrs = wl.Game().players
4632
4633 -- set the objective with the game type for all players
4634- broadcast_objective("win_condition", wc_name, wc_desc)
4635+ broadcast_objective("win_condition", wc_name, p(wc_desc))
4636
4637 -- Iterate all players, if one is defeated, remove him
4638 -- from the list, send him a defeated message and give him full vision
4639
4640=== modified file 'scripting/win_conditions/endless_game_fogless.lua'
4641--- scripting/win_conditions/endless_game_fogless.lua 2015-01-31 08:39:43 +0000
4642+++ scripting/win_conditions/endless_game_fogless.lua 2015-08-01 06:21:02 +0000
4643@@ -3,6 +3,7 @@
4644 -- =======================================================================
4645
4646 include "scripting/coroutine.lua" -- for sleep
4647+include "scripting/formatting.lua"
4648 include "scripting/win_condition_functions.lua"
4649
4650 set_textdomain("win_conditions")
4651@@ -19,7 +20,7 @@
4652 local plrs = wl.Game().players
4653
4654 -- set the objective with the game type for all players
4655- broadcast_objective("win_condition", wc_name, wc_desc)
4656+ broadcast_objective("win_condition", wc_name, p(wc_desc))
4657
4658 -- reveal the whole map for every player
4659 local game = wl.Game()
4660
4661=== modified file 'scripting/win_conditions/territorial_lord.lua'
4662--- scripting/win_conditions/territorial_lord.lua 2015-01-31 08:39:43 +0000
4663+++ scripting/win_conditions/territorial_lord.lua 2015-08-01 06:21:02 +0000
4664@@ -3,6 +3,7 @@
4665 -- =======================================================================
4666
4667 include "scripting/coroutine.lua" -- for sleep
4668+include "scripting/formatting.lua"
4669 include "scripting/messages.lua"
4670 include "scripting/table.lua"
4671 include "scripting/win_condition_functions.lua"
4672@@ -25,7 +26,7 @@
4673 local plrs = wl.Game().players
4674
4675 -- set the objective with the game type for all players
4676- broadcast_objective("win_condition", wc_name, wc_desc)
4677+ broadcast_objective("win_condition", wc_name, p(wc_desc))
4678
4679 -- Get all valueable fields of the map
4680 local fields = {}
4681@@ -168,9 +169,9 @@
4682 for idx, p in ipairs(plrs) do
4683 if candidateisteam and currentcandidate == p.team
4684 or not candidateisteam and currentcandidate == p.name then
4685- send_message(p, game_status.title, msg2, {popup = true})
4686+ send_message(p, game_status.title, p(msg2), {popup = true})
4687 else
4688- send_message(p, game_status.title, msg1, {popup = true})
4689+ send_message(p, game_status.title, p(msg1), {popup = true})
4690 end
4691 end
4692 end
4693
4694=== modified file 'scripting/win_conditions/territorial_time.lua'
4695--- scripting/win_conditions/territorial_time.lua 2015-01-31 08:39:43 +0000
4696+++ scripting/win_conditions/territorial_time.lua 2015-08-01 06:21:02 +0000
4697@@ -3,6 +3,7 @@
4698 -- =======================================================================
4699
4700 include "scripting/coroutine.lua" -- for sleep
4701+include "scripting/formatting.lua"
4702 include "scripting/messages.lua"
4703 include "scripting/table.lua"
4704 include "scripting/win_condition_functions.lua"
4705@@ -30,7 +31,7 @@
4706 local plrs = wl.Game().players
4707
4708 -- set the objective with the game type for all players
4709- broadcast_objective("win_condition", wc_name, wc_desc)
4710+ broadcast_objective("win_condition", wc_name, p(wc_desc))
4711
4712 -- Get all valueable fields of the map
4713 local fields = {}
4714@@ -232,7 +233,7 @@
4715 msg = msg .. "\n\n"
4716 msg = msg .. game_status.body
4717 msg = msg .. _status(points, "has")
4718- send_message(p, game_status.title, msg, {popup = true})
4719+ send_message(p, game_status.title, p(msg), {popup = true})
4720 end
4721 end
4722
4723
4724=== modified file 'scripting/win_conditions/wood_gnome.lua'
4725--- scripting/win_conditions/wood_gnome.lua 2015-03-21 13:18:02 +0000
4726+++ scripting/win_conditions/wood_gnome.lua 2015-08-01 06:21:02 +0000
4727@@ -1,8 +1,9 @@
4728 -- =======================================================================
4729 -- Wood Gnome win condition
4730 -- =======================================================================
4731-
4732+-- NOCOM(#gunchleoc): fix status
4733 include "scripting/coroutine.lua" -- for sleep
4734+include "scripting/formatting.lua"
4735 include "scripting/table.lua"
4736 include "scripting/win_condition_functions.lua"
4737
4738@@ -24,7 +25,7 @@
4739 local plrs = wl.Game().players
4740
4741 -- set the objective with the game type for all players
4742- broadcast_objective("win_condition", wc_name, wc_desc)
4743+ broadcast_objective("win_condition", wc_name, p(wc_desc))
4744
4745 local remaining_time = 4 * 60 -- 4 hours
4746
4747@@ -91,7 +92,7 @@
4748 msg = msg .. (_"%1$s has %2$s at the moment."):bformat(plr.name,trees)
4749 end
4750
4751- broadcast(plrs, game_status.title, msg)
4752+ broadcast(plrs, game_status.title, p(msg))
4753 end
4754
4755 -- Start a new coroutine that checks for defeated players
4756@@ -149,12 +150,12 @@
4757 for i=1,#points-1 do
4758 privmsg = lost_game_over.title
4759 privmsg = privmsg .. msg
4760- points[i][1]:send_message(lost_game_over.body, privmsg)
4761+ points[i][1]:send_message(lost_game_over.body, p(privmsg))
4762 wl.game.report_result(points[i][1], 0, make_extra_data(points[i][1], wc_name, wc_version, {score=points[i][2]}))
4763 end
4764 privmsg = won_game_over.title
4765 privmsg = privmsg .. msg
4766- points[#points][1]:send_message(won_game_over.body, privmsg)
4767+ points[#points][1]:send_message(won_game_over.body, p(privmsg))
4768 wl.game.report_result(points[#points][1], 1,
4769 make_extra_data(points[#points][1], wc_name, wc_version, {score=points[#points][2]}))
4770 end
4771
4772=== modified file 'src/base/i18n.cc'
4773--- src/base/i18n.cc 2015-01-31 14:28:10 +0000
4774+++ src/base/i18n.cc 2015-08-01 06:21:02 +0000
4775@@ -352,5 +352,6 @@
4776 return result;
4777 }
4778
4779-
4780 }
4781+
4782+
4783
4784=== modified file 'src/base/i18n.h'
4785--- src/base/i18n.h 2015-01-30 23:10:35 +0000
4786+++ src/base/i18n.h 2015-08-01 06:21:02 +0000
4787@@ -27,6 +27,7 @@
4788 #include <libintl.h> // for ngettext.
4789
4790 #include "base/macros.h"
4791+#include "graphic/text/layout_info.h"
4792 #include "config.h"
4793
4794 ///A macro to make i18n more readable and aid in tagging strings for translation
4795
4796=== modified file 'src/editor/CMakeLists.txt'
4797--- src/editor/CMakeLists.txt 2015-01-31 16:03:59 +0000
4798+++ src/editor/CMakeLists.txt 2015-08-01 06:21:02 +0000
4799@@ -89,6 +89,7 @@
4800 base_scoped_timer
4801 graphic
4802 graphic_surface
4803+ graphic_text_layout
4804 io_filesystem
4805 logic
4806 logic_widelands_geometry
4807
4808=== modified file 'src/editor/tools/editor_info_tool.cc'
4809--- src/editor/tools/editor_info_tool.cc 2015-02-24 13:51:38 +0000
4810+++ src/editor/tools/editor_info_tool.cc 2015-08-01 06:21:02 +0000
4811@@ -21,10 +21,13 @@
4812
4813 #include <cstdio>
4814
4815+#include <boost/algorithm/string/join.hpp>
4816 #include <boost/format.hpp>
4817+#include <boost/lexical_cast.hpp>
4818
4819 #include "base/i18n.h"
4820 #include "editor/editorinteractive.h"
4821+#include "graphic/format.h"
4822 #include "logic/map.h"
4823 #include "logic/world/editor_category.h"
4824 #include "logic/world/terrain_description.h"
4825@@ -48,118 +51,133 @@
4826
4827 Widelands::Field & f = map[center.node];
4828
4829- // *** Node info
4830- std::string buf = _("Node:");
4831- buf += "\n";
4832- buf += "• " + (boost::format(_("Coordinates: (%1$i, %2$i)"))
4833- % center.node.x % center.node.y).str() + "\n";
4834-
4835- std::string temp = "";
4836- Widelands::NodeCaps const caps = f.nodecaps();
4837- switch (caps & Widelands::BUILDCAPS_SIZEMASK) {
4838- /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4839- case Widelands::BUILDCAPS_SMALL: temp += _(" small"); break;
4840- /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4841- case Widelands::BUILDCAPS_MEDIUM: temp += _(" medium"); break;
4842- /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4843- case Widelands::BUILDCAPS_BIG: temp += _(" big"); break;
4844- default: break;
4845- };
4846- /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4847- if (caps & Widelands::BUILDCAPS_FLAG) temp += _(" flag");
4848- /** TRANSLATORS: This is part of a list, e.g. Caps: flag mine walk */
4849- if (caps & Widelands::BUILDCAPS_MINE) temp += _(" mine");
4850- /** TRANSLATORS: This is part of a list, e.g. Caps: big flag port walk */
4851- if (caps & Widelands::BUILDCAPS_PORT) temp += _(" port");
4852- /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4853- if (caps & Widelands::MOVECAPS_WALK) temp += _(" walk");
4854- /** TRANSLATORS: This is part of a list, e.g. Caps: swim */
4855- if (caps & Widelands::MOVECAPS_SWIM) temp += _(" swim");
4856-
4857- buf += std::string("• ") + (boost::format(_("Caps:%s")) % temp).str() + "\n";
4858-
4859- if (f.get_owned_by() > 0) {
4860- buf += std::string("• ") +
4861- (boost::format(_("Owned by: Player %u"))
4862- % static_cast<unsigned int>(f.get_owned_by())).str() + "\n";
4863- } else {
4864- buf += std::string("• ") + _("Owned by: —") + "\n";
4865- }
4866-
4867- temp = f.get_immovable() ? _("Has base immovable") : _("No base immovable");
4868- buf += "• " + temp + "\n";
4869-
4870- temp = f.get_first_bob() ? _("Has animals") : _("No animals");
4871- buf += "• " + temp + "\n";
4872-
4873- // *** Terrain info
4874- buf += std::string("\n") + _("Terrain:") + "\n";
4875-
4876- const Widelands::Field & tf = map[center.triangle];
4877- const Widelands::TerrainDescription& ter = world.terrain_descr(
4878- center.triangle.t == Widelands::TCoords<>::D ? tf.terrain_d() : tf.terrain_r());
4879-
4880- buf += "• " + (boost::format(_("Name: %s")) % ter.descname()).str() + "\n";
4881-
4882- Widelands::TerrainDescription::Type terrain_is = ter.get_is();
4883- std::vector<std::string> terrain_is_strings;
4884-
4885- if (terrain_is == Widelands::TerrainDescription::Type::kGreen) {
4886- terrain_is_strings.push_back(_("arable"));
4887- }
4888- if (terrain_is & Widelands::TerrainDescription::Type::kDry) {
4889- terrain_is_strings.push_back(_("treeless"));
4890- }
4891- if (terrain_is & Widelands::TerrainDescription::Type::kWater) {
4892- terrain_is_strings.push_back(_("aquatic"));
4893- }
4894- if (terrain_is & Widelands::TerrainDescription::Type::kDead) {
4895- terrain_is_strings.push_back(_("dead"));
4896- }
4897- if (terrain_is & Widelands::TerrainDescription::Type::kMountain) {
4898- terrain_is_strings.push_back(_("mountainous"));
4899- }
4900- if (terrain_is & Widelands::TerrainDescription::Type::kImpassable) {
4901- terrain_is_strings.push_back(_("impassable"));
4902- }
4903- buf += "• " + (boost::format(_("Category: %s"))
4904- % i18n::localize_list(terrain_is_strings, i18n::ConcatenateWith::AMPERSAND)).str() + "\n";
4905- buf += "• " + (boost::format(_("Editor Category: %s")) % ter.editor_category().descname()).str() + "\n";
4906-
4907- // *** Resources info
4908- buf += std::string("\n") + _("Resources:") + "\n";
4909-
4910- Widelands::ResourceIndex ridx = f.get_resources();
4911- int ramount = f.get_resources_amount();
4912-
4913- if (ramount > 0) {
4914- buf += "• " + (boost::format(
4915- _("Resource name: %s")) % world.get_resource(ridx)->name().c_str()
4916- ).str() + "\n";
4917- buf += "• " + (boost::format(_("Resource amount: %i")) % ramount).str() + "\n";
4918- }
4919- else {
4920- buf += "• " + std::string(_("No resources")) + "\n";
4921- }
4922-
4923- // *** Map info
4924- buf += std::string("\n") + _("Map:") + "\n";
4925- buf += "• " + (boost::format(_("Name: %s")) % map.get_name().c_str()).str() + "\n";
4926- buf += "• " + (boost::format(_("Size: %1$ix%2$i"))
4927- % map.get_width() % map.get_height()).str() + "\n";
4928-
4929- if (map.get_nrplayers() > 0) {
4930- buf += "• " +
4931- (boost::format(_("Players: %d")) % static_cast<int>(map.get_nrplayers())).str() + "\n";
4932- }
4933- else {
4934- buf += "• " + std::string(_("Players: -")) + "\n";
4935- }
4936-
4937- buf += "• " + (boost::format(_("Author: %s")) % map.get_author()).str() + "\n";
4938- buf += "• " + (boost::format(_("Descr: %s")) % map.get_description().c_str()).str() + "\n";
4939-
4940- multiline_textarea->set_text(buf.c_str());
4941+ constexpr int kLeftColumnWidth = 130;
4942+ std::vector<std::string> elements;
4943+ const auto add_title_row = [multiline_textarea, &elements](const std::string& text) {
4944+ elements.push_back(
4945+ RT::div({RT::attribute("width", multiline_textarea->get_effective_width())},
4946+ RT::p(RT::ui_font(
4947+ {RT::attribute("size", 22), RT::attribute("underline", 1)},
4948+ text))));
4949+ };
4950+
4951+ const auto add_row = [multiline_textarea, kLeftColumnWidth, &elements](
4952+ const std::string& left_text, const std::string& right_text) {
4953+ elements.push_back(RT::p(
4954+ RT::div({RT::attribute("width", kLeftColumnWidth)},
4955+ RT::ui_font(left_text)) +
4956+ "<space fill=\".\">" +
4957+ RT::div(
4958+ {
4959+ RT::attribute("width", multiline_textarea->get_effective_width() - kLeftColumnWidth),
4960+ },
4961+ RT::ui_font(right_text))));
4962+ };
4963+ // NOCOM(GunChleoc): This needs a full overhaul
4964+ // NOCOM(#sirver): needs valign, unfortunately it seems buggy when used here.
4965+ // NOCOM(#sirver): support for relative font sizes (in percent). #gunchleoc: done.
4966+
4967+ add_title_row(_("Field:"));
4968+ add_row(_("Coordinates:"),
4969+ /** TRANSLATORS: X, Y coordinates of a field. */
4970+ (boost::format(_("(%1$i, %2$i)")) % center.node.x % center.node.y).str());
4971+
4972+ {
4973+ std::string temp = "";
4974+ Widelands::NodeCaps const caps = f.nodecaps();
4975+ switch (caps & Widelands::BUILDCAPS_SIZEMASK) {
4976+ /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4977+ case Widelands::BUILDCAPS_SMALL: temp += _(" small"); break;
4978+ /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4979+ case Widelands::BUILDCAPS_MEDIUM: temp += _(" medium"); break;
4980+ /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4981+ case Widelands::BUILDCAPS_BIG: temp += _(" big"); break;
4982+ default: break;
4983+ };
4984+ /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4985+ if (caps & Widelands::BUILDCAPS_FLAG) temp += _(" flag");
4986+ /** TRANSLATORS: This is part of a list, e.g. Caps: flag mine walk */
4987+ if (caps & Widelands::BUILDCAPS_MINE) temp += _(" mine");
4988+ /** TRANSLATORS: This is part of a list, e.g. Caps: big flag port walk */
4989+ if (caps & Widelands::BUILDCAPS_PORT) temp += _(" port");
4990+ /** TRANSLATORS: This is part of a list, e.g. Caps: medium flag walk */
4991+ if (caps & Widelands::MOVECAPS_WALK) temp += _(" walk");
4992+ /** TRANSLATORS: This is part of a list, e.g. Caps: swim */
4993+ if (caps & Widelands::MOVECAPS_SWIM) temp += _(" swim");
4994+ add_row(_("Caps:"), temp);
4995+ }
4996+
4997+ add_row(_("Owned by:"),
4998+ f.get_owned_by() ?
4999+ boost::lexical_cast<std::string>(static_cast<int>(f.get_owned_by())) :
5000+ "-");
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: