Merge lp:~sirver/widelands/tutorial_mission into lp:widelands

Proposed by SirVer
Status: Merged
Merged at revision: not available
Proposed branch: lp:~sirver/widelands/tutorial_mission
Merge into: lp:widelands
Diff against target: 2904 lines (+1455/-235)
41 files modified
campaigns/cconfig (+2/-2)
campaigns/emp01.wmf/scripting/texts.lua (+5/-5)
campaigns/emp02.wmf/scripting/texts.lua (+4/-4)
campaigns/t01.wmf/scripting/initial_messages.lua (+1/-1)
campaigns/t01.wmf/scripting/khantrukhs_talking.lua (+1/-1)
campaigns/t01.wmf/scripting/texts.lua (+5/-5)
campaigns/t02.wmf/scripting/mission_thread.lua (+1/-1)
campaigns/t02.wmf/scripting/mission_thread_texts.lua (+2/-2)
campaigns/t03.wmf/scripting/texts.lua (+14/-14)
campaigns/tutorial01.wmf/elemental (+1/-1)
campaigns/tutorial01.wmf/player_names (+6/-0)
campaigns/tutorial01.wmf/player_position (+2/-0)
campaigns/tutorial01.wmf/scripting/init.lua (+527/-73)
campaigns/tutorial01.wmf/scripting/texts.lua (+425/-104)
src/economy/flag.cc (+11/-0)
src/economy/flag.h (+1/-0)
src/economy/road.cc (+18/-0)
src/economy/road.h (+1/-0)
src/logic/building.cc (+26/-0)
src/logic/building.h (+2/-0)
src/logic/immovable.cc (+9/-0)
src/logic/immovable.h (+10/-0)
src/logic/legacy.cc (+17/-0)
src/save_handler.cc (+3/-0)
src/save_handler.h (+5/-1)
src/scripting/lua_game.cc (+46/-8)
src/scripting/lua_map.cc (+83/-2)
src/scripting/lua_map.h (+31/-2)
src/scripting/lua_ui.cc (+63/-0)
src/scripting/lua_ui.h (+4/-0)
src/scripting/scripting.cc (+5/-0)
src/scripting/test/ts.wmf/scripting/test_baseimmovables.lua (+2/-0)
src/scripting/test/ts.wmf/scripting/test_constructionsite.lua (+46/-0)
src/scripting/test/ts.wmf/scripting/test_flag.lua (+7/-1)
src/scripting/test/ts.wmf/scripting/test_immovables.lua (+1/-0)
src/scripting/test/ts.wmf/scripting/test_road.lua (+11/-4)
src/scripting/test/ts.wmf/scripting/test_ui.lua (+16/-0)
src/ui_basic/panel.cc (+32/-0)
src/ui_basic/panel.h (+4/-0)
src/wlapplication.cc (+0/-2)
src/wui/interactive_base.cc (+5/-2)
To merge this branch: bzr merge lp:~sirver/widelands/tutorial_mission
Reviewer Review Type Date Requested Status
Chuck Wilder playtesting, spellchecking Needs Fixing
Review via email: mp+24444@code.launchpad.net

Description of the change

This is not really a merge request, as an earlier version of this tutorial was already merged together with the ui scripting capabilities, so this will also be merged eventually. I want to try out if making a merge request will help in getting feedback for the mission to further improve on it.

Please, play the mission and give me some feedback (especially positive to keep me motivated :P).

@chuck and other native speakers: I am especially looking forward to english language improvement. Feel free to reformulate whatever you seem unfitting, as long as the sense stays around, I am happy with improvements to the grammar and the words.

Changes:
To tutorial:
* made tutorial more robust against bad user input
  - by allowing user input to be completely suppressed
  - by adding a coroutine that rips everything the user builds when he shouldn't build anything.
* typo and grammatical fixes
* added infos about census & statistics
* added a chapter about resources & mining
* added infos about the mini map
* added a chapter about soldiers, training and warfare
* added mission objectives

To code:
* minimal Lua wrappings for constructionsites
* new functions to suppress user input processing in the UI
* new property fields in base immovables that offers the reverse mapping from Field.immovable

To post a comment you must log in.
Revision history for this message
Chuck Wilder (chuckw20) wrote :

spellchecking

I reviewed the campaigns folder and found a number of instances that require spelling, grammatical and/or wording changes.

These I have applied and can be found in the following branch:
        ~chuckw20/widelands/tutorial_mission_edit

review: Needs Fixing (playtesting, spellchecking)
Revision history for this message
SirVer (sirver) wrote :

I didn't get much feedback for the scenario, so I guess this could count as a failed experiment. I merged this now, so I guess feedback will come from players.

Revision history for this message
Kiscsirke (csirkeee) wrote :

I did try it, and played it through, I just didn't have any problems :)

András

On 3 May 2010 11:39, SirVer <email address hidden> wrote:
> I didn't get much feedback for the scenario, so I guess this could count as a failed experiment. I merged this now, so I guess feedback will come from players.
> --
> https://code.launchpad.net/~sirver/widelands/tutorial_mission/+merge/24444
> You are subscribed to branch lp:widelands.
>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'campaigns/cconfig' (properties changed: -x to +x)
2--- campaigns/cconfig 2010-04-21 17:45:21 +0000
3+++ campaigns/cconfig 2010-04-30 14:39:36 +0000
4@@ -24,13 +24,13 @@
5 campname0=_"(Tutorial) Barbarians - The second Empire"
6 campsect0=barbariantut
7 campdiff0=1
8-campdesc0=_"When Chat’Karuth died, he was an old man, father to three strong and ambitious sons and warlord to an army that could match any enemy willing to rise against the ancient forests. Though his glorious reign, Chat’Karuth left his eldest son Thron in the due to succeed him as the tribes warlord – a decision that left his two brothers unsatisfied. The old warlord knew that. As his father told him, Thron left the capital of Al’thunran, the home of the throne among the trees and redrew his forces to the high hills where he buried the corpse of his father and swore to the gods and his spirit, that he’d return to re-established order. While his brothers raged in blind war against Thron and the few forces he left to secure the borders of Al’thunran, the young warlord seeks to reunite his ambitious brothers and force the tribes to march once again under a common banner."
9+campdesc0=_"When Chat’Karuth died, he was an old man, father to three strong and ambitious sons and warlord to an army that could match any enemy willing to rise against the ancient forests. Though at the end of his glorious reign, Chat’Karuth left his eldest son, Thron, to succeed him as the tribe's warlord – a decision that left his two brothers unsatisfied. The old warlord knew that. As his father instructed him, Thron left the capital of Al’thunran, the home of the Throne Among the Trees and withdrew his forces to the high hills where he buried the corpse of his father. There he swore to the gods and his father's spirit that he’d return to re-established order. While his brothers raged in blind war against Thron and the few forces he left to secure the borders of Al’thunran, the young warlord seeks to reunite his ambitious brothers and force the tribes to march once again under a common banner."
10 campvisi0=1
11 # Empire Campaign
12 campname1=_"Empire - The months of exile"
13 campsect1=empiretut
14 campdiff1=2
15-campdesc1=_"Six months ago, Lutius - a young general of the Empire - was send with 150 soldiers to the frontier beyond the northern forests where Barbarian-tribes and official Empire-land are crossing. His task was to defend the Empire-land. At first, everything was calm. He even talked to a few barbarian children and thought about a peaceful life - side by side with this archaic folk. He began to feel safer and his army began to drop their attention off the potential enemy. That was their fault. At one night in march his unprepared army was attacked by 100 barbarian footmen and was completely scattered. Only with his bare life he and a handful of his soldiers survived."
16+campdesc1=_"Six months ago, Lutius - a young general of the Empire - was sent with 150 soldiers to the frontier beyond the northern forests where Barbarian tribes were crossing onto land held by the Empire. His task was to defend the Empire's land. At first, everything was calm. He even talked to a few barbarian children and thought about a peaceful life - side by side with this archaic folk. He began to feel safer and his army began to drop their attention off the potential enemy. That was their undoing. One night in March his unprepared army was attacked by 100 barbarian footmen and was completely scattered. Only with his bare life he and a handful of his soldiers survived."
17 campvisi1=0
18 # Atlantean Campaign
19 campname2=_"Atlanteans - the new rise"
20
21=== modified file 'campaigns/emp01.wmf/scripting/texts.lua' (properties changed: -x to +x)
22--- campaigns/emp01.wmf/scripting/texts.lua 2010-04-18 06:46:20 +0000
23+++ campaigns/emp01.wmf/scripting/texts.lua 2010-04-30 14:39:36 +0000
24@@ -35,7 +35,7 @@
25 body="<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=2F9131>" ..
26 _"Diary of Lutius" ..
27 "</p></rt><rt image=map:Lutius.png><p line-spacing=3 font-size=12><br>" ..
28- _[[ "Finally, the Gods were with us!<br> We landed on an unknown coast and found peaceful rest under the palm trees growing at the strand. But that is about as good as it gets. The truth is:<br> when I woke up this morning, I saw nothing more than sand around us.<br> It really seems as if we 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." ]] ..
29+ _[[ "Finally, the Gods were with us!<br> 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:<br> when I woke up this morning, I saw nothing more than sand around us.<br> It really seems as if we 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." ]] ..
30 "</p></rt>",
31 width=400,
32 height=350,
33@@ -47,7 +47,7 @@
34 body="<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=8F9131>" ..
35 _"Saledus looks around nervously..." ..
36 "</p></rt><rt image=map:Saledus.png><p line-spacing=3 font-size=12><br>" ..
37- _[[ "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?<br> 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.<br> We really should build a barracks in the eastern portion of the forest. Than one of us will keep watch in the darkness and keep us safe from these creatures."<br><br>-- NEW OBJECTIVE --<br> ]] ..
38+ _[[ "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?<br> 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.<br> We really should build a barracks in the eastern portion of the forest. Then one of us can keep watch in the darkness and keep us safe from these creatures."<br><br>-- NEW OBJECTIVE --<br> ]] ..
39 _"* Build a barracks at the red point on the east side of the forests, to the right of your headquarters." ..
40 "</p></rt>",
41 width=400,
42@@ -87,7 +87,7 @@
43 body="<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=AF7511>" ..
44 _"Amalea recommends..." ..
45 "</p></rt><rt image=map:Amalea.png><p line-spacing=3 font-size=12><br>" ..
46- _[[ "Hey Lutius, I got the message that our first lumberjack started his work today. Perhaps it would be a good idea to wait until he cleans enough space for building up two further lumberjack's houses, so that we can faster harvest the trunks.<br> But unfortunately the trunks are useless for repairing our ship - we need refined wood, like every ship and every bigger building needs, too. So we should build up a sawmill - as soon as we have enough space for this."<br><br>-- NEW OBJECTIVE --<br> ]] ..
47+ _[[ "Hey Lutius, I got the message that our first lumberjack started his work today. Perhaps it would be a good idea to wait until he cleans enough space for building up two further lumberjack's houses, so that we can harvest the trunks faster.<br> But unfortunately the trunks are useless for repairing our ship - we need refined lumber, like every ship and every bigger building needs, too. So we should build up a sawmill - as soon as we have enough space for this."<br><br>-- NEW OBJECTIVE --<br> ]] ..
48 _"* Build two more lumberjack's houses and a sawmill as soon as there is enough space for them." ..
49 "</p></rt>",
50 width=400,
51@@ -99,7 +99,7 @@
52 body="<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=AF7511>" ..
53 _"Amalea comes in..." ..
54 "</p></rt><rt image=map:Amalea.png><p line-spacing=3 font-size=12><br>" ..
55- _[[ "Hi Lutius, I've got two important things to talk about... First the good news:<br> I saw that the construction of the sawmill is complete, so we can begin to refine the trunks the lumberjacks are harvesting to wood.<br> But that's just about the only positive thing I know to talk about. The bad news is that our lumberjacks harvest at an unbelievable speed. There are almost no trees left on this island.<br> Lutius, these trees provide shelter from the sandstorms from the desert, shade on the hot days and they are the home of so many gentle animals. We shouldn't leave this island a complete desert.<br> Lutius, I beg you: find someone who takes care about planting new trees."<br><br>-- NEW OBJECTIVE --<br> ]] ..
56+ _[[ "Hi Lutius, I've got two important things to talk about... First the good news:<br> I saw that the construction of the sawmill is complete, so we can begin to refine the trunks that the lumberjacks are harvesting into lumber.<br> But that's just about the only positive thing I know to talk about. The bad news is that our lumberjacks harvest at an unbelievable speed. There are almost no trees left on this island.<br> Lutius, these trees provide shelter from the sandstorms from the desert, shade on the hot days and they are the home of so many gentle animals. We shouldn't leave this island a complete desert.<br> Lutius, I beg you: find someone who takes care about planting new trees."<br><br>-- NEW OBJECTIVE --<br> ]] ..
57 _"* Build a forester's house to preserve the wood resources of this island." ..
58 "</p></rt>",
59 width=400,
60@@ -111,7 +111,7 @@
61 body="<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=8F9131>" ..
62 _"Saledus notes..." ..
63 "</p></rt><rt image=map:Saledus.png><p line-spacing=3 font-size=12><br>" ..
64- _[[ "Hey, my good old friend. I just thought about the rocks standing on the south strand of this land. Perhaps we could cut out some useful hard stones and beautiful marble.<br> 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."<br><br>-- NEW OBJECTIVE --<br> ]] ..
65+ _[[ "Hey, my good old friend. 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.<br> 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."<br><br>-- NEW OBJECTIVE --<br> ]] ..
66 _"* Build a quarry in the south to cut some stones and marble out of the rocks.<br> These might be used for future buildings." ..
67 "</p></rt>",
68 width=400,
69
70=== modified file 'campaigns/emp02.wmf/scripting/texts.lua' (properties changed: -x to +x)
71--- campaigns/emp02.wmf/scripting/texts.lua 2010-03-14 11:16:54 +0000
72+++ campaigns/emp02.wmf/scripting/texts.lua 2010-04-30 14:39:36 +0000
73@@ -66,7 +66,7 @@
74 title =_"Destroy the barbarian tribe",
75 body ="<rt><p>" ..
76 _"* As soon as you have enough soldiers, attack and completely destroy the barbarian buildings.<br>" ..
77-_"* Finally, build up a fortress on the peninsula<br> (near where the barbarian headquarters stood befre), to avoid new settlements of other tribes in that region." ..
78+_"* Finally, build up a fortress on the peninsula<br> (near where the barbarian headquarters stood before), to avoid new settlements of other tribes in that region." ..
79 "</p></rt>",
80 }
81
82@@ -132,7 +132,7 @@
83 body="<rt><p font-size=24 text-align=left font-face=FreeSerif font-weight=bold font-color=2F9131>" ..
84 _"Diary of Lutius" ..
85 "</p></rt><rt image=map:Lutius.png><p line-spacing=3 font-size=12><br>" ..
86-_[[ "Great, today the building of the quarry was completed. Now we get enough stone to construct larger buildings." ]] ..
87+_[[ "Great! Today the building of the quarry was completed. Now we get enough stone to construct larger buildings." ]] ..
88 "</p></rt>",
89 }
90
91@@ -144,7 +144,7 @@
92 body="<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=8F9131>" ..
93 _"Saledus looks unhappy" ..
94 "</p></rt><rt image=map:Saledus.png><p line-spacing=3 font-size=12><br>" ..
95-_[[ "Greetings Lutius, 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 strands I found the remains of another ship. I don't know whether these parts are all that is left of that ship. Inn any case: these parts do not seem to be old.<br> Perhaps the people aboard that ship were caught in the same storm which brought us to Malac' Mor - and were brought to this island.<br> I beg you to be cautious and to build some barracks or sentries around our colony."<br><br>-- NEW OBJECTIVE --<br> ]] ..
96+_[[ "Greetings Lutius, 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.<br> Perhaps the people aboard that ship were caught in the same storm which brought us to Malac' Mor - and were brought to this island.<br> I beg you to be cautious and to build some barracks or sentries around our colony."<br><br>-- NEW OBJECTIVE --<br> ]] ..
97 _"* Build some barracks and sentries around the colony." ..
98 "</p></rt>",
99 }
100@@ -193,7 +193,7 @@
101 body="<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=2F9131>" ..
102 _"Diary of Lutius" ..
103 "</p></rt><rt image=map:Lutius.png><p line-spacing=3 font-size=12><br>" ..
104-_[[ "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.<br> Today, as I walked down to the eastern strands,<br> I got a shock. I caught sight of one of those hated, evil, barbarian tribes with whom we have had so many problems before.<br> 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<br> I was able to flee and hide myself, before retreating back to our colony under cover of darkness.<br> Anyway, we must build up stronger military buildings as soon as possible."<br><br>-- NEW OBJECTIVE --<br> ]] ..
105+_[[ "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.<br> Today, as I walked down to the eastern shore,<br> I got a shock. I caught sight of one of those hated, evil, barbarian tribes with whom we have had so many problems before.<br> 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<br> I was able to flee and hide myself, before retreating back to our colony under cover of darkness.<br> Anyway, we must build up stronger military buildings as soon as possible."<br><br>-- NEW OBJECTIVE --<br> ]] ..
106 _"* Build up stronger military buildings, such as an outpost, a barrier or a tower, on the eastern frontier. To watch deep inside the enemy territory, build a tower." ..
107 "</p></rt>",
108 }
109
110=== modified file 'campaigns/t01.wmf/scripting/initial_messages.lua' (properties changed: -x to +x)
111--- campaigns/t01.wmf/scripting/initial_messages.lua 2010-03-19 09:54:23 +0000
112+++ campaigns/t01.wmf/scripting/initial_messages.lua 2010-04-30 14:39:36 +0000
113@@ -19,7 +19,7 @@
114 show_story_box(title, msg, al_thunran)
115
116 msg = "<rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
117-_[[ "My father's bones rest peacefully in the grounds he cleared from the senseless bloodspilling that has once risen among us.<br> 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, not to let greed or despair destroy the bonds between us as well." ]] ..
118+_[[ "My father's bones rest peacefully in the grounds on which he once ended the senseless bloodspilling that has risen among us. It pains me that his peace only endured for one generation.<br> 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, not to let greed or despair destroy the bonds between us as well." ]] ..
119 "</p></rt>"
120 show_story_box(title, msg, grave)
121
122
123=== modified file 'campaigns/t01.wmf/scripting/khantrukhs_talking.lua' (properties changed: -x to +x)
124--- campaigns/t01.wmf/scripting/khantrukhs_talking.lua 2010-03-13 20:20:27 +0000
125+++ campaigns/t01.wmf/scripting/khantrukhs_talking.lua 2010-04-30 14:39:36 +0000
126@@ -22,7 +22,7 @@
127 end
128
129 function tutorial_thread()
130- show_story_box(_"Somebody comes upon to you", khantrukh_1)
131+ show_story_box(_"Somebody comes up to you", khantrukh_1)
132 show_story_box(_"The advisor", khantrukh_2, nil, 80, 80)
133 o = start_lumberjack_01(p)
134 -- Wait till the hut is build.
135
136=== modified file 'campaigns/t01.wmf/scripting/texts.lua' (properties changed: -x to +x)
137--- campaigns/t01.wmf/scripting/texts.lua 2010-04-18 16:36:26 +0000
138+++ campaigns/t01.wmf/scripting/texts.lua 2010-04-30 14:39:36 +0000
139@@ -8,7 +8,7 @@
140 "<rt><p>" ..
141 _"* Press SPACE to see where you can build.<br> The red house symbols show you where a small building - like a lumberjack's hut - may be built.<br>" ..
142 _"* Build a lumberjack's hut at the red house symbol just right of your headquarters by clicking on it and selecting a lumberjack's hut.<br>" ..
143-_"* Build a road between your headquarters and the construction site of the lumberjack's hut.<br> When you place the lumberjack's hut, a flag is created for it. You need to connect it to another flag by building a road between them.<br> If you click on a flag and select to build a road, little symbols will appear around it to show you in which directions you can build it.<br> The colour of these symbols indicats how steep this part of the road will be. Green is for flat, yellow means steep and red stands for very steep. The steeper the road is, the harder it will be for your people to walk on it (and your wares will be transported more slowly).<br> You can click on any of the symbols to build the first part of the road there. New symbols will appear to show you where the next part of the road can go, and so on. However, you can also click farer away from the flag to build several steps at once. Click on the flag at the headquarters to finish the road." ..
144+_"* Build a road between your headquarters and the construction site of the lumberjack's hut.<br> When you place the lumberjack's hut, a flag is created for it. You need to connect it to another flag by building a road between them.<br> If you click on a flag and select to build a road, little symbols will appear around it to show you in which directions you can build it.<br> The colour of these symbols indicates how steep this part of the road will be. Green is for flat, yellow means steep and red stands for very steep. The steeper the road is, the harder it will be for your people to walk on it (and your wares will be transported more slowly).<br> You can click on any of the symbols to build the first part of the road there. New symbols will appear to show you where the next part of the road can go, and so on. However, you can also click farther away from the flag to build several steps at once. Click on the flag at the headquarters to finish the road." ..
145 "</p></rt>")
146 end
147
148@@ -16,7 +16,7 @@
149 return p:add_objective("lumberjack02",
150 _ "Build another lumberjack's hut",
151 "<rt><p>" ..
152-_"* Place a flag in the middle of the road.<br> There is a flag symbol in the middle of the way you just built. You create a flag there by clicking on the symbol and then choosing the flag button in the menu that opens up. This divides the way the wood is transported into two parts with one carrier each.<br> When much wares are being transported between two points, additional flags in between make them arrive at their destination faster, thus improving your infrastructure.<br>" ..
153+_"* Place a flag in the middle of the road.<br> There is a flag symbol in the middle of the way you just built. You create a flag there by clicking on the symbol and then choosing the flag button in the menu that opens up. This divides the way the wood is transported into two parts with one carrier each.<br> When many wares are being transported between two points, additional flags in between make them arrive at their destination faster, thus improving your infrastructure.<br>" ..
154 _"* Place a lumberjack's hut just south of the flag you just placed on the road. Connect the flag you just raised with the flag of the new lumberjack's hut construction site afterwards.<br> Note that instead of building a road step by step, you may also click directly at its destination to build the entire road at once." ..
155 "</p></rt>")
156 end
157@@ -48,7 +48,7 @@
158 khantrukh_2= "<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=8080FF>" ..
159 _"Khantrukh continues..." ..
160 "</p></rt><rt image=map:khantrukh.png><p line-spacing=3 font-size=12>" ..
161-_[[ "None but the gods know 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 already getting shorter and colder...<br> We should prepare, in case we have to face the winter in these harsh lands. I believe to the east of our campside are a few places where we could raise a lumberjack's hut."<br><br>-- NEW OBJECTIVES --<br> ]] ..
162+_[[ "None but the gods know 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 already getting shorter and colder...<br> We should prepare, in case we have to face the winter in these harsh lands. I believe to the east of our campsite are a few places where we could raise a lumberjack's hut."<br><br>-- NEW OBJECTIVES --<br> ]] ..
163 _"* Press SPACE to see where you can build.<br> The red house symbols show you where a small building - like a lumberjack's hut - may be built.<br>" ..
164 _"* Build a lumberjack's hut at the red house symbol just right of your headquarters by clicking on it and selecting a lumberjack's hut.<br>" ..
165 "</p></rt>"
166@@ -58,14 +58,14 @@
167 _"The elder remarks..." ..
168 "</p></rt><rt image=map:khantrukh.png><p line-spacing=3 font-size=12>" ..
169 _[[ "Obviously, it would be too exhausting for our people to walk all the way to the lumberjack's hut through the wilderness. We will have to build a road between our hall and the lumberjack's hut. It's not a hard guess that the men would appreciate a way as short and plain as possible - the wood will surely be heavy enough, nevertheless."<br><br>-- NEW OBJECTIVE --<br> ]] ..
170-_"* Build a road between your headquarters and the construction site of the lumberjack's hut.<br> When you place the lumberjack's hut, a flag is created for it. You need to connect it to another flag by building a road between them.<br> If you click on a flag and select to build a road, little symbols will appear around it to show you in which directions you can build it.<br> The colour of these symbols indicats how steep this part of the road will be. Green is for flat, yellow means steep and red stands for very steep. The steeper the road is, the harder it will be for your people to walk on it (and your wares will be transported more slowly).<br> You can click on any of the symbols to build the first part of the road there. New symbols will appear to show you where the next part of the road can go, and so on. However, you can also click farer away from the flag to build several steps at once. Click on the flag at the headquarters to finish the road." ..
171+_"* Build a road between your headquarters and the construction site of the lumberjack's hut.<br> When you place the lumberjack's hut, a flag is created for it. You need to connect it to another flag by building a road between them.<br> If you click on a flag and select to build a road, little symbols will appear around it to show you in which directions you can build it.<br> The colour of these symbols indicates how steep this part of the road will be. Green is for flat, yellow means steep and red stands for very steep. The steeper the road is, the harder it will be for your people to walk on it (and your wares will be transported more slowly).<br> You can click on any of the symbols to build the first part of the road there. New symbols will appear to show you where the next part of the road can go, and so on. However, you can also click farer away from the flag to build several steps at once. Click on the flag at the headquarters to finish the road." ..
172 "</p></rt>"
173
174 khantrukh_4 = "<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=8080FF>" ..
175 _"Khantrukh remembers..." ..
176 "</p></rt><rt image=map:khantrukh.png><p line-spacing=3 font-size=12>" ..
177 _[[ "There is an old saying:<br> 'A burden divided is easier to endure.'<br> A crossroads on the way between our headquarters and the lumberjack's hut would ease the work of our carriers."<br><br>-- NEW OBJECTIVE --<br> ]] ..
178-_"* Place a flag in the middle of the road.<br> There is a flag symbol in the middle of the way you just built. You create a flag there by clicking on the symbol and then choosing the flag button in the menu that opens up. This divides the way the wood is transported into two parts with one carrier each.<br> When much wares are being transported between two points, additional flags in between make them arrive at their destination faster, thus improving your infrastructure.<br>" ..
179+_"* Place a flag in the middle of the road.<br> There is a flag symbol in the middle of the way you just built. You create a flag there by clicking on the symbol and then choosing the flag button in the menu that opens up. This divides the way the wood is transported into two parts with one carrier each.<br> When many wares are being transported between two points, additional flags in between make them arrive at their destination faster, thus improving your infrastructure.<br>" ..
180 "</p></rt>"
181
182 khantrukh_5 = "<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=8080FF>" ..
183
184=== modified file 'campaigns/t02.wmf/scripting/mission_thread.lua' (properties changed: -x to +x)
185--- campaigns/t02.wmf/scripting/mission_thread.lua 2010-04-25 13:59:43 +0000
186+++ campaigns/t02.wmf/scripting/mission_thread.lua 2010-04-30 14:39:36 +0000
187@@ -209,7 +209,7 @@
188 This is a village of poor but friendly people who have settled in a safe
189 valley between two glaciers. They hunt and produce timber and grain but they
190 do not have ores or even stones, so they are dependent on the infrequent
191- merchant that may pass by and provide them with whatever they can not
192+ merchant that may pass by and provide them with whatever they cannot
193 produce on their own. Their only protection is a guard hut at each entrance
194 to the valley. Therefore they realize that they may have to join a more
195 powerful society for protection in order to stay alive in this world.
196
197=== modified file 'campaigns/t02.wmf/scripting/mission_thread_texts.lua' (properties changed: -x to +x)
198--- campaigns/t02.wmf/scripting/mission_thread_texts.lua 2010-03-13 22:33:12 +0000
199+++ campaigns/t02.wmf/scripting/mission_thread_texts.lua 2010-04-30 14:39:36 +0000
200@@ -9,7 +9,7 @@
201 "<rt><p font-size=24 font-weight=bold font-face=FreeSerif font-color=2F9131>" ..
202 _"Thron shakes his head..." ..
203 "</p></rt><rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
204-_[[ "The war goes on. More and more of our brothers and sisters flee the brutal war raging in the capital beneath the trees.<br> The stories they tell about the deeds of our kin are sad to hear. I've spent nights lying awake, restless, more tired I ever believed one could be. Yet whenever I close my eyes, I see the fortress my father built consumed by flames. The throne between the trees, the symbol of unity and peace among our kin became the wedge that drives us apart." ]] ..
205+_[[ "The war goes on. More and more of our brothers and sisters flee the brutal war raging in the capital beneath the trees.<br> The stories they tell about the deeds of our kin are sad to hear. I've spent nights lying awake, restless, more tired 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." ]] ..
206 "</p></rt>",
207 }
208
209@@ -18,7 +18,7 @@
210 title =_ "The story continues",
211 body =
212 "<rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
213-_ [[ "Today my hunters brought men, women and little children 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 old times, when we were no more but the 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 slaughtering, unless... is this it? As father told me?<br> Rise against whoever threatens our very existence, may it even be one of your blood or mind?" ]] ..
214+_ [[ "Today my hunters brought men, women and little children 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 old 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 slaughtering, unless... is this it? As father told me?<br> Rise against whoever threatens our very existence, may it even be one of your blood or mind?" ]] ..
215 "</p></rt>",
216 }
217
218
219=== modified file 'campaigns/t03.wmf/scripting/texts.lua' (properties changed: -x to +x)
220--- campaigns/t03.wmf/scripting/texts.lua 2010-04-25 18:33:38 +0000
221+++ campaigns/t03.wmf/scripting/texts.lua 2010-04-30 14:39:36 +0000
222@@ -126,7 +126,7 @@
223 body= "<rt><p line-spacing=3 font-size=12>" ..
224 _"* Destroy Kalitaths army and expand your territory to the east." ..
225 "<br>" ..
226-_"-> To attack an enemy you must click on the door of an advarse 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')" ..
227+_"-> 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')" ..
228 "</p></rt>",
229 }
230
231@@ -148,7 +148,7 @@
232 _"Thron looks worried..." ..
233 "</p></rt><rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
234
235-_[[ "The 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 with my brothers.<br>For now we rest at the borders of the old forest and prepare for the coming days." ]] ..
236+_[[ "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 with my brothers.<br>For now we rest at the borders of the old forest and prepare for the coming days." ]] ..
237 "</p></rt>",
238 }
239
240@@ -186,7 +186,7 @@
241 body= "<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=2F9131>" ..
242 _"Thron speaks confidently." ..
243 "</p></rt><rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
244-_[[ "The frontier line of my forces has expanded to the edge of the forests. We have a long and cold winter and so many miles behind us. The fortification that we erected around Ondun will guarantee us fast supply of man and goods and once Al’thunran is in my hands, the two cities will be linked by a good and defendable infrastructure. Still I hope I will not walk alone on this mission, I hope Kailitat son of Kun will follow my call." ]] ..
245+_[[ "The frontier line of my forces has expanded to the edge of the forests. We have a long and cold winter and so many miles behind us. The fortification that we erected around Ondun will guarantee us a fast supply of men and goods and once Al’thunran is in my hands, the two cities will be linked by a good and defendable infrastructure. Still I hope I will not walk alone on this mission, I hope Kalitath son of Kun will follow my call." ]] ..
246 "</p></rt>",
247 }
248
249@@ -194,7 +194,7 @@
250 posy=1,
251 title=_"The story continues",
252 body= "<rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
253-_[[ "I have sent men to meet Kalitath in this fortress. He has barricaded the former main entrance to the capital and is trying to set up a siege ring around Al’thunran. He will not let anyone enter or leave the city while the ring is intact. Until now, he has not answered any of my messages. But the time I wait won't be lost. I will further upgrade my soldiers and prepare for battle." ]] ..
254+_[[ "I have sent men to meet with Kalitath in his fortress. He has barricaded the former main entrance to the capital and is trying to set up a siege ring around Al’thunran. He will not let anyone enter or leave the city while the ring is intact. Until now, he has not answered any of my messages. But the time I wait won't be lost. I will further upgrade my soldiers and prepare for battle." ]] ..
255 "</p></rt>",
256 }
257
258@@ -203,13 +203,13 @@
259 body= "<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=FF0000>" ..
260 _"Boldreth shouts out!" ..
261 "</p></rt><rt image=map:boldreth.png><p line-spacing=3 font-size=12>" ..
262-_[[ "This BASTARD! Only one man of our frontier patrol came back alive. He carried a message of Kalitath telling us that he will punish every move of our troops with their own blood! We cannot accept this behaviour. From now on there is war between Kalitath and us!" ]] ..
263+_[[ "This BASTARD! Only one man of our frontier patrol came back alive. He carried a message from Kalitath telling us that he will punish every move of our troops with their own blood! We cannot accept this behaviour. From now on there is war between Kalitath and us!" ]] ..
264 "<br><br>" ..
265 _"-- NEW OBJECTIVE --" ..
266 "<br>" ..
267-_"* Destroy Kalitaths army and expand your territory to the east." ..
268+_"* Destroy Kalitath's army and expand your territory to the east." ..
269 "<br>" ..
270-_"-> To attack an enemy you must click on the door of an advarse 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')" ..
271+_"-> 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')" ..
272 "</p></rt>",
273 }
274
275@@ -219,7 +219,7 @@
276 body= "<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=2F9131>" ..
277 _"Thron speaks:" ..
278 "</p></rt><rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
279-_[[ "The traitor has left his armies dying where they lay as he saw that he would not keep my forces back. Kalitath disappeared in the mess of the war, but I don’t care now. Shall he flee and be forgotten for all times as a tribeleader that would not bow before the wooden throne, that is mine to take now. Even more his flight brought us a big benefit: All year Kalitath was to busy fighting so that he did not even care to store enough food for all his men. Now that he fled the hunger brought some of his younger followers to desert. This group helds a strong fortification on the main ring. But there is more news: My scouts 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." ]] ..
280+_[[ "The traitor has left his armies dying where they lay as he saw that he would not keep my forces back. Kalitath disappeared in the mess of the war, but I don’t care now. Shall he flee and be forgotten for all times as a tribeleader that would not bow before the wooden throne, that is mine to take now. Even more his flight brought us a big 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 brought some of his younger followers to desert. This group holds a strong fortification on the main ring. But there is more news: My scouts 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." ]] ..
281 "</p></rt>",
282 }
283
284@@ -229,7 +229,7 @@
285 body= "<rt><p font-size=24 font-weight=bold font-face=FreeSerif font-color=2F9131>" ..
286 _"Boldreth speaks:" ..
287 "</p></rt><rt image=map:boldreth.png><p line-spacing=3 font-size=12>" ..
288-_[[ "This morning I found Thron trouble-minded. He returned from his patrol late last night and sat back against a tree watching over the encampment. The number of quarrels and disputes keeps growing and the winter has us firmly under control. We should put food in our storage to survive the long, cold winter!" ]] ..
289+_[[ "This morning I found Thron trouble-minded. He returned from his patrol late last night and sat back against a tree watching over the encampment. The number of quarrels and disputes keeps growing and the winter has us firmly in its grip. We should put food in our storage to survive the long, cold winter!" ]] ..
290 "</p></rt>",
291 }
292
293@@ -259,7 +259,7 @@
294 posy=1,
295 title=_"Tracks",
296 body= "<rt image=map:boldreth.png><p line-spacing=3 font-size=12>" ..
297- _[[ "Thron told me that he discovered tracks in the snow to the northeast of our settlement. He instructed us to build a Donjon, to have a further visual range on the area around our hall to protect our people from sudden attacks." ]] ..
298+ _[[ "Thron told me that he discovered tracks in the snow to the northeast of our settlement. He instructed us to build a Donjon, to have a greater visual range on the area around our hall to protect our people from sudden attacks." ]] ..
299 "<br><br>" ..
300 _"-- NEW OBJECTIVE --" ..
301 "<br>" ..
302@@ -271,7 +271,7 @@
303 posy=1,
304 title=_"Further explorations",
305 body= "<rt image=map:boldreth.png><p line-spacing=3 font-size=12>" ..
306-_[[ "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 thousand bigger dangers out there than the unknown tracks.<br>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 doorsteps. THEN we will be prepared once trouble seeks to capture our woods." ]] ..
307+_[[ "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.<br>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 doorsteps. THEN we will be prepared once trouble seeks to capture our woods." ]] ..
308 "<br><br>" ..
309 _"-- NEW OBJECTIVE --" ..
310 "<br>" ..
311@@ -295,7 +295,7 @@
312 posy=1,
313 title=_"Mining economy completed",
314 body= "<rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
315-_[[ "I just got informed, that our mining economy started its work. These news brought a smile on my face - even if the hardest part is still waiting to be done, now our smiths will give their best to further ease our lives." ]] ..
316+_[[ "I just got informed, that our mining economy started its work. This news brought a smile to my face - even if the hardest part is still waiting to be done, now our smiths will give their best to further ease our lives." ]] ..
317 "</p></rt>",
318 }
319
320@@ -345,7 +345,7 @@
321 body= "<rt><p font-size=24 font-face=FreeSerif font-weight=bold font-color=2F9131>" ..
322 _"Thron looks worried." ..
323 "</p></rt><rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
324-_[[ "My brothers and their soldiers are dead and left fire and destruction behind. In none of all the ruins I found 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. Nothing is left from that beauty I remember, only ruins remain from the old capital. I am sorrowful but also relieved. I never hoped to ever see Al'thunrans old beauty again - few months ago I even wondered whether I will ever be able to set my feet near to Al'thunran again. Now the old town is back in my hands and I will not hesitate to rebuild it with all forces my people have. I can't wait to see it again in it's old beauty." ]] ..
325+_[[ "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. Nothing is left from that beauty I remember, only ruins remain from the old capital. I am sorrowful but also relieved. I never hoped to ever 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 in Al'thunran 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 it's old beauty." ]] ..
326 "<br><br>" ..
327 _"--------------------- VICTORY! ----------------------" ..
328 "<br><br>" ..
329@@ -357,7 +357,7 @@
330 posy = 1,
331 title=_"Military assault",
332 body= "<rt image=map:chieftain.png><p line-spacing=3 font-size=12>" ..
333-_[[ "So be it, the generals are out to set up my troops and Boldreth himself will lead the first strike. I will ride by his side, to free Al’thunran of this war and bring peace back in our capital. 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 honour of my father whose eyes lie upon me today.<br>So be it!" ]] ..
334+_[[ "So be it, the generals are out to set up my troops and Boldreth himself will lead the first strike. I will ride by his side, to free Al’thunran of this war and bring peace back to our capital. 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 honour of my father whose eyes are set upon me today.<br>So be it!" ]] ..
335 "<br><br>" ..
336 _"-- NEW OBJECTIVE --" ..
337 "<br>" ..
338
339=== modified file 'campaigns/tutorial01.wmf/elemental'
340--- campaigns/tutorial01.wmf/elemental 2010-04-17 11:18:54 +0000
341+++ campaigns/tutorial01.wmf/elemental 2010-04-30 14:39:36 +0000
342@@ -2,7 +2,7 @@
343 packet_version=1
344 map_w=64
345 map_h=64
346-nr_players=1
347+nr_players=2
348 world=greenland
349 name=_"Tutorial01"
350 author="Winterwind, SirVer, Nasenbaer"
351
352=== modified file 'campaigns/tutorial01.wmf/player_names'
353--- campaigns/tutorial01.wmf/player_names 2010-04-13 19:19:45 +0000
354+++ campaigns/tutorial01.wmf/player_names 2010-04-30 14:39:36 +0000
355@@ -4,3 +4,9 @@
356 [player_1]
357 name=Player 1
358 tribe=barbarians
359+
360+[player_2]
361+name=Sparing Partner
362+tribe=empire
363+ai="Defensive"
364+
365
366=== modified file 'campaigns/tutorial01.wmf/player_position'
367--- campaigns/tutorial01.wmf/player_position 2010-04-13 19:19:45 +0000
368+++ campaigns/tutorial01.wmf/player_position 2010-04-30 14:39:36 +0000
369@@ -1,3 +1,5 @@
370 [global]
371 packet_version=2
372 player_1=12 10
373+player_2=50 10
374+
375
376=== modified file 'campaigns/tutorial01.wmf/scripting/init.lua'
377--- campaigns/tutorial01.wmf/scripting/init.lua 2010-04-27 08:20:50 +0000
378+++ campaigns/tutorial01.wmf/scripting/init.lua 2010-04-30 14:39:36 +0000
379@@ -22,18 +22,58 @@
380 -- Constants
381 first_lumberjack_field = wl.map.Field(16,10)
382 first_quarry_field = wl.map.Field(8,12)
383-conquer_field = wl.map.Field(19,15)
384+conquer_field = wl.map.Field(6,18)
385+trainings_ground = wl.map.Field(33,57)
386+
387+-- Global variables
388+registered_player_immovables = {}
389+terminate_bad_boy_sentinel = false
390+illegal_immovable_found = function(i) return false end
391
392 use("map", "texts")
393
394--- TODO: add objectives, there are none currently
395-
396 -- =================
397 -- Helper functions
398 -- =================
399+
400+-- A small helper class to disable/enable autosaving and user interaction
401+UserInputDisabler = {}
402+function UserInputDisabler:new()
403+ local rv = {}
404+ setmetatable(rv, self)
405+ self.__index = self
406+
407+ rv:establish_blocks()
408+
409+ return rv
410+end
411+function UserInputDisabler:establish_blocks()
412+ self._ui_state = wl.ui.get_user_input_allowed()
413+ self._as_state = wl.game.get_allow_autosaving()
414+
415+ wl.ui.set_user_input_allowed(false)
416+ wl.game.set_allow_autosaving(false)
417+end
418+function UserInputDisabler:lift_blocks()
419+ wl.ui.set_user_input_allowed(self._ui_state)
420+ wl.game.set_allow_autosaving(self._as_state)
421+end
422+
423+function _try_add_objective(i)
424+ -- Add an objective that is defined in the table i to the players objectives.
425+ -- Returns the new objective or nil. Does nothing if i does not specify an
426+ -- objective.
427+ local o = nil
428+ if i.obj_name then
429+ o = plr:add_objective(i.obj_name, i.obj_title, i.obj_body)
430+ end
431+ return o
432+end
433 function msg_box(i)
434 wl.game.set_speed(1000)
435
436+ local blocker = UserInputDisabler:new()
437+
438 if i.field then
439 scroll_smoothly_to(i.field.trn.trn.trn.trn)
440
441@@ -50,46 +90,267 @@
442
443 plr:message_box(i.title, i.body, i)
444
445+ blocker:lift_blocks()
446+
447+ local o = _try_add_objective(i)
448+
449 sleep(130)
450+
451+ return o
452 end
453
454 function send_message(i)
455 plr:send_message(i.title, i.body, i)
456
457+ local o = _try_add_objective(i)
458 sleep(130)
459+ return o
460 end
461
462-function click_on_field(f, g_T)
463- sleep(500)
464+function click_on_field(f, g_T, g_sleeptime)
465+ local sleeptime = g_sleeptime or 500
466+
467+ local blocker = UserInputDisabler:new()
468+
469 mouse_smoothly_to(f, g_T)
470- sleep(500)
471+ sleep(sleeptime)
472+
473 wl.ui.MapView():click(f)
474- sleep(500)
475-end
476-
477-function click_on_panel(panel, g_T)
478- sleep(500)
479- mouse_smoothly_to_panel(panel, g_T)
480- sleep(500)
481- if panel.press then panel:press() sleep(250) end
482- if panel.click then panel:click() end
483- sleep(500)
484-end
485-
486--- ======
487--- Logic
488--- ======
489+ sleep(sleeptime)
490+
491+ blocker:lift_blocks()
492+end
493+
494+function click_on_panel(panel, g_T, g_sleeptime)
495+ local sleeptime = g_sleeptime or 500
496+
497+ local blocker = UserInputDisabler:new()
498+
499+ sleep(sleeptime)
500+ if not panel.active then -- If this is a tab and already on, do nothing
501+ mouse_smoothly_to_panel(panel, g_T)
502+ sleep(sleeptime)
503+ if panel.press then panel:press() sleep(250) end
504+ if panel.click then panel:click() end
505+ sleep(sleeptime)
506+ end
507+
508+ blocker:lift_blocks()
509+end
510+
511+function warp_houses(descriptions)
512+ local blocker = UserInputDisabler:new()
513+
514+ for idx, d in ipairs(descriptions) do
515+ local name, x, y = d[1], d[2], d[3]
516+ mouse_smoothly_to(wl.map.Field(x, y))
517+ sleep(300)
518+ prefilled_buildings(plr, d)
519+ sleep(300)
520+ end
521+
522+ blocker:lift_blocks()
523+end
524+
525+function build_road(field, ...)
526+ -- Build a road by clicking the UI. A little faster than before
527+ mouse_smoothly_to(field, 400, 200)
528+
529+ local function _start_road(field)
530+ wl.ui.MapView():click(field)
531+ click_on_panel(
532+ wl.ui.MapView().windows.field_action.buttons.build_road, 100, 200
533+ )
534+ end
535+
536+ _start_road(field)
537+
538+ for idx, d in ipairs{...} do
539+ if field.immovable and field.immovable.player ~= plr then
540+ field.immovable:remove()
541+ end
542+ if d == '|' or d == '.' then
543+ mouse_smoothly_to(field, 400, 200)
544+ wl.ui.MapView():click(field)
545+ if d == '|' then
546+ wl.ui.MapView():click(field)
547+ click_on_panel(
548+ wl.ui.MapView().windows.field_action.buttons.build_flag, 100, 200
549+ )
550+ _start_road(field)
551+ end
552+ else
553+ field = field[d .. 'n']
554+ end
555+ end
556+end
557+
558+function build_eastern_trainings_area()
559+ -- Build some infrastructure as another example
560+ local blocker = UserInputDisabler:new()
561+
562+ warp_houses{
563+ {"fortress", 31, 63, soldiers = {[{3,5,0,2}] = 8 }},
564+ {"warehouse", 33, 57,
565+ soldiers = {
566+ [{0,0,0,0}] = 1,
567+ [{1,0,0,0}] = 1,
568+ [{2,0,0,0}] = 1,
569+ [{3,0,0,0}] = 1,
570+ [{0,1,0,0}] = 1,
571+ [{0,2,0,0}] = 1,
572+ [{0,3,0,0}] = 1,
573+ [{0,4,0,0}] = 1,
574+ [{0,5,0,0}] = 1,
575+ [{0,0,0,1}] = 1,
576+ [{0,0,0,2}] = 1,
577+ [{3,5,0,2}] = 30,
578+ },
579+ workers = {
580+ builder = 1
581+ },
582+ wares = {
583+ trunk = 40,
584+ blackwood = 40,
585+ cloth = 10,
586+ gold = 10,
587+ grout = 30,
588+ raw_stone = 30,
589+ thatchreed = 40,
590+ }
591+ },
592+ {"trainingscamp", 31, 56, soldiers = {} },
593+ {"sentry", 28, 57, soldiers = {[{3,5,0,2}] = 2 }},
594+ {"sentry", 37, 61, soldiers = {[{3,5,0,2}] = 2 }},
595+ }
596+ -- Build the roads
597+ build_road(wl.map.Field(31,57), "bl", "bl", "|", "br", "br", "|",
598+ "r", "r", "|", "tr", "tr", "tl", ".")
599+ build_road(wl.map.Field(29,58), "r", "br", ".")
600+ build_road(wl.map.Field(38,62), "l", "l", "|", "l", "bl",
601+ "|", "tl", "tl", ".")
602+ build_road(wl.map.Field(32, 0), "tr", "tr", "tr", '.')
603+
604+ -- Add wares to the trainingssite so that it does something. Also
605+ -- add buildwares to the warehouse
606+ local ts = wl.map.Field(31,56).immovable
607+ ts:set_wares(ts.valid_wares)
608+
609+ blocker:lift_blocks()
610+end
611+
612+-- Remove all stones in a given environment. This is done
613+-- in a loop for a nice optical effect
614+function remove_all_stones(fields, g_sleeptime)
615+ local sleeptime = g_sleeptime or 150
616+ while #fields > 0 do
617+ local idx = math.random(#fields)
618+ local f = fields[idx]
619+ local remove_field = true
620+
621+ if f.immovable then
622+ local n = f.immovable.name:match("stones(%d*)")
623+ if n then
624+ n = tonumber(n)
625+ f.immovable:remove()
626+ if n > 1 then
627+ remove_field = false
628+ wl.map.create_immovable("stones" .. n-1, f)
629+ end
630+ sleep(sleeptime)
631+ end
632+ end
633+
634+ if remove_field then
635+ table.remove(fields, idx)
636+ end
637+ end
638+end
639+
640+-- ==============
641+-- Sentry Thread
642+-- ==============
643+-- This thread makes sure that the player does not build stuff where he
644+-- is not supposed to. He gets a message box when he tries and what he build
645+-- gets immediately ripped. This thread can be disabled temporarily.
646+function _fmt(f) return ("%i_%i"):format(f.x, f.y) end
647+function register_immovable_as_allowed(i)
648+ for idx, f in ipairs(i.fields) do
649+ registered_player_immovables[_fmt(f)] = true
650+ end
651+
652+ -- buildings and constructionsite have a flag
653+ if i.building_type or i.type == "constructionsite" then
654+ registered_player_immovables[_fmt(i.fields[1].brn)] = true
655+ end
656+end
657+register_immovable_as_allowed(plr.starting_field.immovable)
658+
659+function bad_boy_sentry()
660+ while not terminate_bad_boy_sentinel do
661+ -- Check all fields.
662+ local sent_msg = false
663+ for idx,f in ipairs(plr.starting_field:region(8)) do
664+ if f.immovable and f.immovable.player == plr and
665+ not registered_player_immovables[_fmt(f)] then
666+
667+ -- Give the callback a chance to veto the deletion. Maybe
668+ -- we expect the player to build something at the moment
669+ if not illegal_immovable_found(f.immovable) then
670+ print ("Killing", f.x .. '_' .. f.y)
671+
672+ -- scould the player
673+ if not sent_msg then
674+ msg_box(scould_player)
675+ sent_msg = true
676+ end
677+
678+ -- Remove the object again
679+ f.immovable:remove()
680+ end
681+ end
682+ end
683+ sleep(1000)
684+ end
685+end
686+
687+-- Allows constructionsites for the given buildings, all others are invalid
688+-- as is any other immovable build by the player
689+function allow_constructionsite(i, buildings)
690+ if i.type == "constructionsite" then
691+ if not buildings then return i end
692+ for idx,n in ipairs(buildings) do
693+ if i.building == n then return i end
694+ end
695+ return false
696+ elseif i.type == "flag" then
697+ local tr = i.fields[1].tln.immovable
698+ if tr and tr.type == "constructionsite" then
699+ return allow_constructionsite(tr, buildings)
700+ end
701+ end
702+
703+ return false
704+end
705+
706+-- ================
707+-- Message threads
708+-- ================
709 function starting_infos()
710 sleep(100)
711
712 msg_box(initial_message_01)
713 sleep(500)
714- msg_box(initial_message_02)
715+
716+ local o = msg_box(initial_message_02)
717+
718
719 -- Wait for buildhelp to come on
720 while not wl.ui.MapView().buildhelp do
721 sleep(200)
722 end
723+ o.done = true
724+
725 sleep(500)
726
727 build_lumberjack()
728@@ -98,12 +359,17 @@
729 function build_lumberjack()
730 sleep(100)
731
732+ -- We take control, everything that we build is legal
733+ illegal_immovable_found = function(i) return true end
734+
735 msg_box(lumberjack_message_01)
736
737+ local blocker = UserInputDisabler:new()
738+
739+ scroll_smoothly_to(first_lumberjack_field)
740 mouse_smoothly_to(first_lumberjack_field)
741 sleep(500)
742 msg_box(lumberjack_message_02)
743-
744 sleep(500)
745
746 click_on_field(first_lumberjack_field)
747@@ -117,15 +383,32 @@
748 click_on_field(plr.starting_field.brn)
749
750 msg_box(lumberjack_message_04)
751+
752+ register_immovable_as_allowed(first_lumberjack_field.immovable) -- hut + flag
753+
754+ local f = wl.map.Field(14,11)
755+ register_immovable_as_allowed(f.immovable) -- road + everything on it
756+
757+ illegal_immovable_found = function(i) return false end
758+
759+ blocker:lift_blocks()
760+
761 sleep(15000)
762
763- msg_box(lumberjack_message_05)
764+ local o = msg_box(lumberjack_message_05)
765+
766+ local blocker = UserInputDisabler:new()
767
768 local f = wl.map.Field(14,11)
769+ scroll_smoothly_to(f)
770 mouse_smoothly_to(f)
771-
772+
773+ blocker:lift_blocks()
774+
775 -- Wait for flag
776 while not (f.immovable and f.immovable.type == "flag") do sleep(300) end
777+ o.done = true
778+
779 sleep(300)
780
781 msg_box(lumberjack_message_06)
782@@ -139,7 +422,7 @@
783
784 function learn_to_move()
785 -- Teaching the user how to scroll on the map
786- msg_box(inform_about_stones)
787+ local o = msg_box(inform_about_stones)
788
789 function _wait_for_move()
790 local cx = wl.ui.MapView().viewpoint_x
791@@ -151,11 +434,13 @@
792 end
793
794 _wait_for_move()
795+ o.done = true
796 sleep(3000) -- Give the player a chance to try this some more
797
798- msg_box(tell_about_right_drag_move)
799+ o = msg_box(tell_about_right_drag_move)
800
801 _wait_for_move()
802+ o.done = true
803 sleep(3000) -- Give the player a chance to try this some more
804
805 msg_box(congratulate_and_on_to_quarry)
806@@ -167,25 +452,22 @@
807 sleep(200)
808
809 -- Teaching how to build a quarry and the nits and knacks of road building.
810- msg_box(order_quarry_recap_how_to_build)
811+ local o = msg_box(order_quarry_recap_how_to_build)
812
813+ local cs = nil
814 -- Wait for the constructionsite to come up.
815- -- TODO: this needs to be done better, but a wrapping of the constructionsite
816- -- is needed for this.
817- -- TODO: check that the constructionsite is indeed for the correct building
818- local cs = nil
819- while not cs do
820- for idx,f in ipairs(first_quarry_field:region(6)) do
821- if f.immovable and f.immovable.type == "constructionsite" then
822- cs = f
823- break
824- end
825- end
826- sleep(400)
827+ illegal_immovable_found = function(i)
828+ cs = allow_constructionsite(i, {"quarry"})
829+ return cs
830 end
831
832+ -- Wait for the constructionsite to be placed
833+ while not cs do sleep(300) end
834+ o.done = true
835+ register_immovable_as_allowed(cs)
836+
837 local function _rip_road()
838- for idx,f in ipairs(cs:region(2)) do
839+ for idx,f in ipairs(cs.fields[1].brn:region(2)) do
840 if f.immovable and f.immovable.type == "road" then
841 click_on_field(f)
842 click_on_panel(wl.ui.MapView().windows.
843@@ -196,6 +478,10 @@
844 end
845 end
846
847+ local blocker = UserInputDisabler:new()
848+
849+ illegal_immovable_found = function() return true end
850+
851 msg_box(talk_about_roadbuilding_00)
852 -- Showoff one-by-one roadbuilding
853 click_on_field(wl.map.Field(9,12))
854@@ -203,65 +489,93 @@
855 click_on_field(wl.map.Field(11,12))
856 click_on_field(wl.map.Field(12,12))
857 click_on_field(wl.map.Field(12,11))
858+
859 sleep(3000)
860+
861 _rip_road()
862
863 msg_box(talk_about_roadbuilding_01)
864 -- Showoff direct roadbuilding
865- click_on_field(cs.brn)
866+ click_on_field(cs.fields[1].brn)
867 click_on_panel(wl.ui.MapView().windows.field_action.buttons.build_road, 300)
868 click_on_field(plr.starting_field.brn)
869+
870 sleep(3000)
871+
872 _rip_road()
873
874- msg_box(talk_about_roadbuilding_02)
875-
876- -- TODO: Add information about census and statistics here
877-
878+ blocker:lift_blocks()
879+
880+ local o = msg_box(talk_about_roadbuilding_02)
881+
882+ -- From now on, the player can build whatever he wants
883+ terminate_bad_boy_sentinel = true
884+
885+ -- Wait a while
886+ sleep( 120*1000 )
887+
888+ -- Interludium: talk about census and statistics
889+ census_and_statistics(cs)
890+
891 while #plr:get_buildings("quarry") < 1 do sleep(1400) end
892+ o.done = true
893
894 messages()
895 end
896+
897+function census_and_statistics(cs)
898+ sleep(25000)
899+
900+ local blocker = UserInputDisabler:new()
901+
902+ wl.ui.MapView().census = false
903+ wl.ui.MapView().statistics = false
904+
905+ msg_box(census_and_statistics_00)
906+ -- Pick any empty field
907+ local function _pick_empty_field()
908+ local reg = cs.fields[1]:region(2)
909+ local f
910+ repeat
911+ f = reg[math.random(#reg)]
912+ until not f.immovable
913+ return f
914+ end
915+
916+ click_on_field(_pick_empty_field())
917+ click_on_panel(wl.ui.MapView().windows.field_action.tabs.watch)
918+ click_on_panel(wl.ui.MapView().windows.field_action.buttons.census)
919+ sleep(300)
920+ click_on_field(_pick_empty_field())
921+ click_on_panel(wl.ui.MapView().windows.field_action.tabs.watch)
922+ click_on_panel(wl.ui.MapView().windows.field_action.buttons.statistics)
923+
924+ msg_box(census_and_statistics_01)
925+
926+ blocker:lift_blocks()
927+end
928
929 function messages()
930 -- Teach the player about receiving messages
931 sleep(10)
932
933- send_message(teaching_about_messages)
934+ local o = send_message(teaching_about_messages)
935
936 while #plr.inbox > 0 do sleep(200) end
937-
938- msg_box(closing_msg_window_00)
939+ o.done = true
940+
941+ sleep(500)
942+
943+ local o = msg_box(closing_msg_window_00)
944
945 -- Wait for messages window to close
946 while wl.ui.MapView().windows.messages do sleep(300) end
947+ o.done = true
948
949 msg_box(closing_msg_window_01)
950
951 -- Remove all stones
952- local fields = first_quarry_field:region(6)
953- while #fields > 0 do
954- local idx = math.random(#fields)
955- local f = fields[idx]
956- local remove_field = true
957-
958- if f.immovable then
959- temp, temp, n = f.immovable.name:find("stones(%d*)")
960- if n then
961- n = n + 0 -- trick to convert string to integer
962- f.immovable:remove()
963- if n > 1 then
964- remove_field = false
965- wl.map.create_immovable(("stones%i"):format(n-1), f)
966- sleep(150)
967- end
968- end
969- end
970-
971- if remove_field then
972- table.remove(fields, idx)
973- end
974- end
975+ remove_all_stones(first_quarry_field:region(6))
976
977 -- Wait for message to arrive
978 while #plr.inbox < 1 do sleep(300) end
979@@ -269,16 +583,155 @@
980 sleep(800)
981 msg_box(conclude_messages)
982
983+ sleep(3000)
984 expansion()
985 end
986
987 function expansion()
988 -- Teach about expanding your territory.
989 sleep(10)
990+
991+ -- This is not really needed since the stones are already removed, but if
992+ -- we're debugging and we start with this function it is most useful to have
993+ -- the stones away already
994+ remove_all_stones(first_quarry_field:region(6), 20)
995
996- msg_box(introduce_expansion)
997+ local o = msg_box(introduce_expansion)
998
999 while #conquer_field.owners < 1 do sleep(100) end
1000+ o.done = true
1001+
1002+ mining()
1003+end
1004+
1005+function mining()
1006+ -- Teach about geologist and resources
1007+ sleep(10)
1008+
1009+ msg_box(mining_00)
1010+
1011+ local function _find_good_flag_position()
1012+ fields = conquer_field:region(8)
1013+ while #fields > 0 do
1014+ local idx = math.random(#fields)
1015+ local f = fields[idx]
1016+
1017+ if f.terr:match("berg%d+") and f.terd:match("berg%d+") then
1018+ if pcall(function() plr:place_flag(f) end) then
1019+ f.immovable:remove()
1020+ return f
1021+ end
1022+ end
1023+
1024+ table.remove(fields, idx)
1025+ end
1026+ end
1027+
1028+ local function _find_nearby_flag()
1029+ for i=2,8 do
1030+ for idx, f in ipairs(conquer_field:region(i)) do
1031+ if f.immovable and f.immovable.type == "flag" then
1032+ return f
1033+ end
1034+ end
1035+ end
1036+ end
1037+
1038+ scroll_smoothly_to(conquer_field)
1039+
1040+ local dest = _find_good_flag_position()
1041+ local start = _find_nearby_flag()
1042+
1043+ -- Build a road, call a geologist
1044+ click_on_field(start)
1045+ click_on_panel(wl.ui.MapView().windows.field_action.tabs.roads)
1046+ click_on_panel(wl.ui.MapView().windows.field_action.buttons.build_road)
1047+ click_on_field(dest)
1048+ click_on_field(dest) -- second click
1049+ click_on_panel(wl.ui.MapView().windows.field_action.buttons.build_flag)
1050+ click_on_field(dest)
1051+ click_on_panel(wl.ui.MapView().windows.field_action.buttons.geologist)
1052+
1053+ sleep(6000)
1054+
1055+ msg_box(mining_01)
1056+
1057+ local function _wait_for_some_resi(wanted)
1058+ while 1 do
1059+ local cnt = 0
1060+ for idx, f in ipairs(dest:region(6)) do
1061+ if f.immovable and f.immovable.name:sub(1,4) == "resi" then
1062+ cnt = cnt + 1
1063+ if cnt >= wanted then return end
1064+ end
1065+ end
1066+ sleep(500)
1067+ end
1068+ end
1069+ _wait_for_some_resi(8)
1070+
1071+ scroll_smoothly_to(dest)
1072+
1073+ msg_box(mining_02)
1074+
1075+ training()
1076+end
1077+
1078+function training()
1079+ -- Teach about trainingsites and soldiers
1080+ sleep(300)
1081+
1082+ msg_box(warefare_and_training_00)
1083+
1084+ build_eastern_trainings_area()
1085+ sleep(8000)
1086+
1087+ msg_box(warefare_and_training_01)
1088+
1089+ sleep(5000)
1090+ local citadel_field = wl.map.Field(31, 63)
1091+ scroll_smoothly_to(citadel_field)
1092+
1093+ local o = msg_box(enhance_fortress)
1094+ while not (citadel_field.immovable and
1095+ citadel_field.immovable.name == "citadel") do sleep(800) end
1096+ o.done = true
1097+
1098+ -- Wait for soldiers to move in
1099+ local citadel = citadel_field.immovable
1100+ local break_out = false
1101+ while not break_out do
1102+ for k,v in pairs(citadel:get_soldiers("all")) do
1103+ break_out = true
1104+ break -- Break out if there is at least one soldier here
1105+ end
1106+
1107+ sleep(500)
1108+ end
1109+
1110+ -- Create enemy tribe
1111+ prefilled_buildings(wl.game.Player(2),
1112+ {"barrier", 25, 6},
1113+ {"sentry", 29, 16},
1114+ {"tower", 30, 21},
1115+ {"headquarters", 30, 27,
1116+ workers = {
1117+ carrier = 50,
1118+ },
1119+ soldiers = {
1120+ [{0,0,0,0}] = 15,
1121+ }
1122+ }
1123+ )
1124+
1125+ scroll_smoothly_to(citadel_field)
1126+ local o = msg_box(attack_enemey)
1127+
1128+ local plr2 = wl.game.Player(2)
1129+ while #plr2:get_buildings("headquarters") > 0 or not plr2.defeated do
1130+ sleep(3000)
1131+ end
1132+ o.done = true
1133
1134 conclusion()
1135 end
1136@@ -292,5 +745,6 @@
1137
1138 end
1139
1140+run(bad_boy_sentry)
1141 run(starting_infos)
1142
1143
1144=== modified file 'campaigns/tutorial01.wmf/scripting/texts.lua' (properties changed: -x to +x)
1145--- campaigns/tutorial01.wmf/scripting/texts.lua 2010-04-27 07:47:43 +0000
1146+++ campaigns/tutorial01.wmf/scripting/texts.lua 2010-04-30 14:39:36 +0000
1147@@ -23,6 +23,11 @@
1148 .. s .. "<br></p><p font-size=8> <br></p>"
1149 end
1150
1151+function h2(s)
1152+ return "<p font=FreeSerif font-size=12 font-weight=bold font-color=D1D1D1>"
1153+ .. s .. "<br></p><p font-size=4> <br></p>"
1154+end
1155+
1156 -- Simple flowing text. One Paragraph
1157 function p(s)
1158 return "<p line-spacing=3 font-size=12>" .. s .. "<br></p>" ..
1159@@ -30,15 +35,26 @@
1160 end
1161
1162 -- =============
1163--- Textes below
1164+-- Texts below
1165 -- =============
1166+scould_player = {
1167+ title = _ "Nice and easy does it all the time",
1168+ body = rt(p(_
1169+[[I am sorry, but I have to rip this again. We might need the space here later
1170+on. If I am too slow for you, you might want to play a real game and just find
1171+everything out for yourself. Otherwise, please bear with me, I am not the
1172+youngest and quickest anymore.]]
1173+ )
1174+ )
1175+}
1176+
1177 initial_message_01 = {
1178 title = _ "Welcome to the Widelands tutorial!",
1179 body = rt(
1180 h1(_"Welcome to Widelands!") ..
1181 p(_
1182 [[Widelands is a slow-paced build-up strategy with an emphasis on construction,
1183- not destruction. This tutorial will get you through the basics of the game.]]
1184+not destruction. This tutorial will get you through the basics of the game.]]
1185 ) .. p(_
1186 [[You can dismiss this box by left-clicking on the button below.]]
1187 )
1188@@ -52,23 +68,32 @@
1189 h1(_"Let's dive right in!") ..
1190 p(_
1191 [[There are three different tribes in Widelands: the barbarians, the empire and
1192- the atlanteans. All tribes have a different economy, strength and weaknesses,
1193- but the general gameplay is the same for all. We play the barbarians for now.]]
1194+the atlanteans. All tribes have a different economy, strength and weaknesses,
1195+but the general gameplay is the same for all. We play the barbarians for now.]]
1196 ) .. p(_
1197 [[You usually start the game with one headquarters. This is the big building
1198- with the blue flag in front of it. The headquarters is a ware house that stores
1199- wares, workers and soldiers. Some wares are needed for building houses, others
1200- for making other wares. Obviously, the wares in the headquarters will not last
1201- forever, so you must make sure to reproduce them. The most important wares in
1202- the early game are the basic build wares: trunks and raw stone. Let's make sure
1203- that we do not run out of trunks. For this, we need to build a lumberjack.]]
1204+with the blue flag in front of it. The headquarters is a ware house that stores
1205+wares, workers and soldiers. Some wares are needed for building houses, others
1206+for making other wares. Obviously, the wares in the headquarters will not last
1207+forever, so you must make sure to reproduce them. The most important wares in
1208+the early game are the basic build wares: trunks and raw stone. Let's make sure
1209+that we do not run out of trunks. For this, we need to build a lumberjack.]]
1210 ) .. p(_
1211 [[We need to find a nice place for the lumberjack. To make this easier, we
1212- activate the build help. To do this, either click on the build help button
1213- at the bottom of the screen which is the fourth one from the left. Or you
1214- can use the SPACE key to toggle it.]]
1215+activate the build help. To do this, either click on the build help button
1216+at the bottom of the screen which is the fourth one from the left. Or you
1217+can use the SPACE key to toggle it.]]
1218 )
1219 ),
1220+ obj_name = "enable_buildhelp",
1221+ obj_title = _ "Enable the build help",
1222+ obj_body = rt(h1(_"Enable the build help") ..
1223+ p(
1224+[[It is easier to understand what is allowed to be built on which field when
1225+the build help symbols are enabled. Do so now either by pressing SPACE or by
1226+clicking the fourth button from the left at the very bottom of the screen.]]
1227+ )
1228+ )
1229 }
1230
1231 lumberjack_message_01 = {
1232@@ -77,8 +102,8 @@
1233 field = first_lumberjack_field,
1234 body = rt(p(_
1235 [[There you go. I will explain about all those symbols in a minute. First, let
1236- me show you how to make a lumberjack's hut and how to connect it with a road.
1237- There is a sweet spot for a lumberjack right next to those trees.]]
1238+me show you how to make a lumberjack's hut and how to connect it with a road.
1239+There is a sweet spot for a lumberjack right next to those trees.]]
1240 )
1241 )
1242 }
1243@@ -88,11 +113,11 @@
1244 pos = "topright",
1245 body = rt(p(_
1246 [[First, I'll left-click on the symbol were I want the lumberjack to be built. A
1247- window will appear where I can choose between buildings. Because I clicked a
1248- yellow house symbol - it means that this field can house medium and small
1249- buildings - I am presented with all medium buildings that I can build. I
1250- go on to select the small buildings tab. Then I choose the lumberjack's hut.
1251- Watch me, I'll go really slow: click - select tab - choose building.]]
1252+window will appear where I can choose between buildings. Because I'll click a
1253+yellow house symbol - which means that this field can house medium and small
1254+buildings - I am presented with all medium buildings that I can build. I
1255+go on to select the small buildings tab. Then I choose the lumberjack's hut.
1256+Watch me, I'll go really slow: click - select tab - choose building.]]
1257 )
1258 )
1259 }
1260@@ -102,9 +127,9 @@
1261 pos = "topright",
1262 body = rt(p(_
1263 [[That won't do yet. I still need to connect the lumberjack's hut to the
1264- rest of my road network. After I ordered a construction site, I am
1265- automatically in road building mode, so all I have to do is click on the flag
1266- in front of my headquarters.]]
1267+rest of my road network. After I ordered a construction site, I am
1268+automatically in road building mode, so all I have to do is click on the flag
1269+in front of my headquarters.]]
1270 )
1271 )
1272 }
1273@@ -114,8 +139,8 @@
1274 pos = "topright",
1275 body = rt(p(_
1276 [[Now watch closely as a builder leaves the headquarters and goes to the
1277- construction site. Also a carrier will take position in between the two flags
1278- and carry wares from one flag to the other.]]
1279+construction site. Also a carrier will take position in between the two flags
1280+and carry wares from one flag to the other.]]
1281 )
1282 )
1283 }
1284@@ -125,10 +150,18 @@
1285 pos = "topright",
1286 body = rt(p(_
1287 [[Nice how they work, isn't it? But the poor carrier has a very long way to go.
1288- We can make it easier for him (and more efficient for us) when we place another
1289- flag on the road. You try it this time: click on the yellow flag symbol
1290- in between the two blue flags we just placed and then click on the]]
1291+We can make it easier for him (and more efficient for us) when we place another
1292+flag on the road. You try it this time: click on the yellow flag symbol
1293+in between the two blue flags we just placed and then click on the]]
1294 )) .. rt("image=pics/menu_build_flag.png", p(_ "build flag symbol.")
1295+ ),
1296+ obj_name = "build_flag_on_road_to_lumberjack",
1297+ obj_title = _ "Build a flag to divide the road to the lumberjack",
1298+ obj_body = rt(h1(_"Build a flag on the road") .. p(_
1299+[[The shorter your road segments are, the faster your wares will be transported.
1300+You should therefore make sure that your roads have as many flags as possible.
1301+Build a flag now in the middle of the road that connects your headquarters
1302+to your lumberjack's hut.]])
1303 )
1304 }
1305
1306@@ -137,8 +170,8 @@
1307 pos = "topright",
1308 body = rt(p(_
1309 [[Well done! Let's wait till the hut is finished. If you want things to
1310- go faster, simply use the PAGE UP key on your keyboard to increase the game
1311- speed. You can use PAGE DOWN to make the game slower again.]]
1312+go faster, simply use the PAGE UP key on your keyboard to increase the game
1313+speed. You can use PAGE DOWN to make the game slower again.]]
1314 )
1315 )
1316 }
1317@@ -148,8 +181,8 @@
1318 pos = "topright",
1319 body = rt(p(_
1320 [[Excellent. The lumberjack's hut is done. A lumberjack will now move in and
1321- start chopping down trees, so our trunks income is secured for now. Now on to
1322- the raw stone.]]
1323+start chopping down trees, so our trunks income is secured for now. Now on to
1324+the raw stone.]]
1325 )
1326 )
1327 }
1328@@ -159,13 +192,23 @@
1329 body = rt(h1(_ "Getting a quarry up.")) ..
1330 rt(p(_
1331 [[Stones can be mined in granite mines, but the easier way is to build a quarry
1332- next to some stones laying around. As it happens, there is a pile of them
1333- laying right to the west of your headquarters. I will teach you now how to
1334- move your view over there]]
1335+next to some stones laying around. As it happens, there is a pile of them
1336+laying just to the west of your headquarters. I will teach you now how to
1337+move your view over there.]]
1338 ) .. p(_
1339 [[There are two ways to move your view. The first one is using the cursor keys
1340- on your keyboard. Go ahead and try this out, move the view using the cursor
1341- keys]]
1342+on your keyboard. Go ahead and try this out, move the view using the cursor
1343+keys]]
1344+ )
1345+ ),
1346+ obj_name = "move_view_with_cursor_keys",
1347+ obj_title = _ "Move your view with the cursor keys",
1348+ obj_body = rt(h1(_"Moving your view") .. p(_
1349+[[Moving your view is essential to get a complete overview over your whole
1350+economy. There are two ways to move your view in widelands. The first one is
1351+to use the cursor keys on your keyboard. The second one is the more common and
1352+faster one: press-and-hold the right mouse button anywhere on the map, then move
1353+your mouse around and you'll see the view scroll.]]
1354 )
1355 )
1356 }
1357@@ -174,16 +217,19 @@
1358 title = _ "Other ways to move the view",
1359 body = rt(p(_
1360 [[Excellent. Now there is a faster way to move, using the mouse instead: Simply
1361- right-click-and-hold anywhere on the map, then drag the mouse and instead
1362- of the cursor, the view will be moved. Try it.]]
1363+right-click-and-hold anywhere on the map, then drag the mouse and instead
1364+of the cursor, the view will be moved. Try it.]]
1365 )
1366- )
1367+ ),
1368+ obj_name = "move_view_with_mouse",
1369+ obj_title = _ "Move your view with the mouse",
1370+ obj_body = inform_about_stones.obj_body,
1371 }
1372
1373 congratulate_and_on_to_quarry = {
1374 title = _ "Onward to the quarry",
1375 body = rt(p(_
1376-[[Great. Now about the quarry...]]
1377+[[Great. Now about that quarry...]]
1378 )
1379 )
1380 }
1381@@ -194,17 +240,17 @@
1382 title = _ "How to build a quarry",
1383 body = rt(p(_
1384 [[Build a quarry next to those stones here. Remember how I did it earlier?
1385- Just click the place were you want the building to be, choose it from the
1386- window that appears and it is placed. Maybe it is a good time to explain about
1387- all those build help symbols we activated earlier.]]
1388+Just click the place were you want the building to be, choose it from the
1389+window that appears and it is placed. Maybe it is a good time to explain about
1390+all those build help symbols we activated earlier.]]
1391 ) .. p(_
1392 [[You can build four things on fields in Widelands: Flags, small houses, medium
1393- houses and big houses. But not every field can hold anything. The build help
1394- eases recognition:]]
1395+houses and big houses. But not every field can hold anything. The build help
1396+eases recognition:]]
1397 )) .. rt("image=pics/big.png", p(_
1398-[[Everything can be build on the green house symbol.]]
1399+[[Everything can be built on the green house symbol.]]
1400 )) .. rt("image=pics/medium.png", p(_
1401-[[Everything except for big buildings can be build on a yellow house symbol.]]
1402+[[Everything except for big buildings can be built on a yellow house symbol.]]
1403 )) .. rt("image=pics/small.png", p(_
1404 [[Red building symbols can only hold small buildings and flags.]]
1405 )) .. rt("image=pics/set_flag.png", p(_
1406@@ -214,40 +260,54 @@
1407 space for holding buildings, so choose your fields wisely.]]
1408 )) .. rt(p(_
1409 [[Now go ahead, try it. The quarry is a small building, so if you click on a
1410- medium or big building symbol, you will have to select the small buildings
1411- tab first to find it. Go on, check it out!]]
1412+medium or big building symbol, you will have to select the small buildings
1413+tab first to find it. Go on, check it out!]]
1414+ )
1415+ ),
1416+ obj_name = "build_a_quarry",
1417+ obj_title = _ "Build a quarry next to the stones",
1418+ obj_body = rt(h1(_ "Build a quarry") .. p(_
1419+[[There are some stones to the west of your headquarters. Build a quarry right
1420+next to them. The quarry is a small building like the lumberjack's hut. You
1421+can therefore build it on any field that shows a red, yellow or green house
1422+when the build help is enabled (Press SPACE for that).]]) .. p(_
1423+[[Just click on any house symbol next to the stones, select the small buildings
1424+tab in the window that opens up, then click on the quarry symbol.]]
1425 )
1426 )
1427 }
1428
1429 talk_about_roadbuilding_00 = {
1430 pos = "topright",
1431+ field = wl.map.Field(9,12),
1432 title = _ "Road building",
1433 body = rt(p(_
1434 [[Excellent! Directly after you placed a building, you are in road building
1435- mode. The new road will start at the flag in front of your newly placed
1436- construction site. You can enter road building mode for any flag by
1437- left-clicking on a flag and selecting]]
1438+mode. The new road will start at the flag in front of your newly placed
1439+construction site. You can enter road building mode for any flag by
1440+left-clicking on a flag and selecting]]
1441 )) .. rt("image=pics/menu_build_way.png", p(_
1442 [[the road building symbol.]]
1443 )) .. rt(p(_
1444 [[If you decide you do not want to build a road at this time, you can cancel
1445- road building by clicking on the starting flag of the road and selecting]]
1446+road building by clicking on the starting flag of the road and selecting]]
1447 )) .. rt("image=pics/menu_abort.png", p(_
1448 [[the abort symbol.]]
1449 )) .. rt(p(_
1450-[[Now, you can either make it longer by one field at a time by left-clicking
1451- multiple times on neighbouring fields for perfect control over the route the
1452- road takes like so:]]
1453+[[Now, about this road. Remember: we are already in road building mode since you
1454+just ordered the quarry. You can either make it longer by one field at a time
1455+by left-clicking multiple times on neighbouring fields for perfect control over
1456+the route the road takes like so:]]
1457 ))
1458 }
1459
1460 talk_about_roadbuilding_01 = {
1461 pos = "topright",
1462+ field = wl.map.Field(9,12),
1463 title = _ "Road building",
1464 body = rt(p(_
1465 [[Alternatively, you can directly click the flag where
1466- the road should end like so.]]
1467+the road should end like so.]]
1468 ))
1469 }
1470
1471@@ -256,23 +316,62 @@
1472 title = _ "Road building",
1473 body = rt(p(_
1474 [[One more thing: around the field where your road would end you can see
1475- different markers. They have the following meaning:]]
1476+different markers. They have the following meaning:]]
1477 )) .. rt("image=pics/roadb_green.png", p(_
1478 [[The terrain is flat here. Your carriers will be very swift on this terrain.]]
1479 )) .. rt("image=pics/roadb_yellow.png", p(_
1480 [[There is a small slope to climb to reach this field. This means you're
1481- workers are faster walking downwards than they are walking upwards.]]
1482+workers are faster walking downwards than they are walking upwards.]]
1483 )) .. rt("image=pics/roadb_red.png", p(_
1484 [[The connection between the fields is extremely steep. The speed increase in
1485- one direction is huge while the slowdown in the other is also substantial.]]
1486+one direction is huge while the slowdown in the other is also substantial.]]
1487 )) .. rt(p(_
1488 [[Keep the slopes in mind while placing roads and use them to your advantage.
1489- Also try to keep roads as short as possible and always remember to place as
1490- many flags as you can on road segments to share the load better.]]
1491+Also try to keep roads as short as possible and always remember to place as
1492+many flags as you can on road segments to share the load better.]]
1493 )) .. rt(p(_
1494 [[Now please rebuild the road between your quarry and your headquarters.
1495- We'll wait until the quarry is completed.]]
1496- ))
1497+We'll wait until the quarry is completed.]]
1498+ )),
1499+ obj_name = "build_road_to_quarry",
1500+ obj_title = _ "Connect the quarry to the headquarters",
1501+ obj_body = rt(h1(_"Connect your construction site") .. p(_
1502+[[Connect your quarry construction site to your headquarters with a road. You
1503+are directly in road building mode when you ordered a new site. But now, you
1504+aren't. To build a completely new road just click on the flag in front of your
1505+construction site, click on the build road icon then click on the flag in front
1506+of your headquarters.]]
1507+ )
1508+ )
1509+}
1510+
1511+census_and_statistics_00 = {
1512+ title = _ "Census and statistics",
1513+ body = rt(p(_
1514+[[While we wait, I'll quickly show you another useful feature. All construction
1515+sites look the same and some buildings look alike. It is sometimes hard to tell
1516+them apart. Widelands offers a feature to show label texts over the buildings.
1517+They are called the census and you can toggle them via the 'c' key or via
1518+the button on the watch tab of any field.]]
1519+ ) .. p(_
1520+[[Similar to this are building statistics which are also toggled via a
1521+button on the watch tab of any field. The hotkey for it is 's'. This will
1522+display an information string about the productivity of buildings or the
1523+progress of construction sites.]]
1524+ ) .. p(_
1525+[[Let me quickly enable those two for you. Remember: 'c' and 's' are the keys.
1526+Alternatively you can click on any field without a building on it, select the
1527+watch tab and then click on the corresponding buttons.]]
1528+ )
1529+)
1530+}
1531+
1532+census_and_statistics_01 = {
1533+ title = _ "Census and statistics",
1534+ body = rt(p(_
1535+[[Now we know what's going on. Let's wait for this quarry to finish.]]
1536+ )
1537+)
1538 }
1539
1540 teaching_about_messages = {
1541@@ -281,24 +380,35 @@
1542 body = rt(h1(_"Messages") ..
1543 p(_
1544 [[Hi, it's me again! This time, I sent you a message. Messages are sent to you
1545- by Widelands to inform you about important events: empty mines, attacks on your
1546- tribe, won or lost military buildings, resources found...]]
1547+by Widelands to inform you about important events: empty mines, attacks on your
1548+tribe, won or lost military buildings, resources found...]]
1549 ) .. p(_
1550 [[The message window can be toggled by the button on the very right at the
1551- bottom of the screen. This button also changes appearance if new messages are
1552- available, but there is also a bell sound played whenever you receive a new
1553- message.]]
1554+bottom of the screen. This button also changes appearance if new messages are
1555+available, but there is also a bell sound played whenever you receive a new
1556+message.]]
1557 ) .. p(_
1558 [[Currently, you have two messages. This one which you are currently reading and
1559- the one that informed you that a new headquarters was added to your economy.
1560- Let's learn how to archive messages: You can check them off in your inbox so
1561- that they get a tick-symbol in front of them. Then, you can click the]]
1562+the one that informed you that a new headquarters was added to your economy.
1563+Let's learn how to archive messages: You can check them off in your inbox so
1564+that they get a tick-symbol in front of them. Then, you can click the]]
1565 )) .. rt("image=pics/message_archive.png", p(_
1566 [[archive message button to move them into your archive.]]
1567 )) .. rt(p(_
1568 [[Archive all messages, including this one, that you currently have in your
1569 inbox.]]
1570 )
1571+ ),
1572+ obj_name = "archive_all_messages",
1573+ obj_title = _"Archive all messages in your inbox",
1574+ obj_body = rt(h1(_"Archive our inbox messages") .. p(_
1575+[[The message window is central to fully control your tribe's fortune. But you
1576+get a lot of messages in a real game. To keep your head straight, you should
1577+try to keep the inbox empty. Archive all your messages in the inbox now. To do
1578+so, open the messages window by pressing 'n' or clicking the right most button
1579+at the very bottom of the screen. Then mark all messages by checking the check
1580+box in front of them. Then, click the archive all button]]
1581+ )
1582 )
1583 }
1584
1585@@ -308,9 +418,17 @@
1586 title = _"Closing windows",
1587 body = rt(p(_
1588 [[Excellent. By the way: closing windows in Widelands is as easy as
1589- right-clicking on them. This works with all windows except for story message
1590- windows like this one. Go ahead and try it. Close the messages window,
1591- please.]]
1592+right-clicking on them. This works with all windows except for story message
1593+windows like this one. Go ahead and try it. First, close this window by pressing
1594+the button below, then right click into the messages window to close it.]]
1595+ )
1596+ ),
1597+ obj_name = "close_message_window",
1598+ obj_title = _ "Close the messages window",
1599+ obj_body = rt(h1(_"Close the messages window") .. p(_
1600+[[All windows in widelands can be closed by right clicking into them. Some
1601+windows can also be toggled with the buttons at the very bottom of the screen.
1602+Close the messages window now by right clicking into it.]]
1603 )
1604 )
1605 }
1606@@ -321,9 +439,9 @@
1607 title = _ "Closing windows",
1608 body = rt(p(_
1609 [[Well done! Let's see how messages work in the real game, shall we? For this,
1610- I'll take all stones away from the poor stonemason in the quarry. He will then
1611- send a message that he can't find any in his working area the next time he
1612- tries to do some work.]]
1613+I'll take all stones away from the poor stonemason in the quarry. He will then
1614+send a message that he can't find any in his working area the next time he
1615+tries to do some work.]]
1616 )
1617 )
1618 }
1619@@ -333,8 +451,9 @@
1620 title = _ "Message arrived!",
1621 body = rt(p(_
1622 [[A message has been sent to you. See how the button at the bottom of the
1623- screen has changed appearance? You should now burn this quarry down as it is
1624- no longer of any use and is just blocking space.]]
1625+screen has changed appearance? You should now burn this quarry down as it is
1626+no longer of any use and is just blocking space. To do that, click on the
1627+quarry and select the destroy button.]]
1628 ))
1629 }
1630
1631@@ -342,23 +461,225 @@
1632 title = _ "Expanding your territory!",
1633 body = rt(p(_
1634 [[There is one more thing I'd like to teach you now: Expanding your territory.
1635- The place that we start with around our headquarters is barely enough for a
1636- basic build infrastructure and we do not have access to mountains which we
1637- need to mine minerals and coal. So we have to expand our territory]]
1638+The place that we start with around our headquarters is barely enough for a
1639+basic build infrastructure and we do not have access to mountains which we
1640+need to mine minerals and coal. So we have to expand our territory.]]
1641 ) .. p(_
1642 [[Expanding is as simple as building a military building at the corner of
1643- your territory. The barbarians have a few different military buildings:
1644- sentries, barriers, donjons, strongholds, fortresses and citadels. The bigger
1645- the building, the more expensive it is to build, the more land it conquers
1646- around itself and the more soldiers can be stationed there. The buildings also
1647- vary in their vision range: buildings with a tower see farther than others.]]
1648+your territory. The barbarians have a few different military buildings:
1649+sentries, barriers, donjons, strongholds, fortresses and citadels. The bigger
1650+the building, the more expensive it is to build, the more land it conquers
1651+around itself and the more soldiers can be stationed there. The buildings also
1652+vary in their vision range: buildings with a tower see farther than others.]]
1653 ) .. p(_
1654 [[As soon as a military building is manned, it extends your land. You can then
1655- burn it down again if you need the place. But note that your land is then
1656- vulnerable: any military site from another player can conquer the land. You
1657- therefore need military sites to keep military influence over your land.]]
1658- ) .. p(_
1659-[[Let's try it out now: Build a military building on your eastern border.]]
1660+burn it down again if you need the place. But note that your land is then
1661+vulnerable: any military site from another player can conquer the land. You
1662+therefore need military sites to keep military influence over your land.]]
1663+ ) .. p(_
1664+[[Let's try it out now: Build a few military buildings on your south western
1665+border. We want to capture some of this mountain, so we can search for
1666+resources there. Bigger buildings will conquer more land which can be beneficial
1667+close to mountains because you can't build houses in mountains.]]
1668+ )
1669+ ),
1670+ obj_name = "conquer_mountain",
1671+ obj_title = _ "Conquer an area were we can build mines",
1672+ obj_body = rt(h1(_"Conquer the mountain to the south west") .. p(_
1673+[[For a full-fledged economy, we need coal, iron and gold. These can be found
1674+in mountains. Conquer some area on the mountains to the south-west of your
1675+headquarters by building some military buildings close to your border.]]
1676+ ) .. p(_
1677+[[You can choose from the following military buildings: sentry, stronghold,
1678+donjon, barrier and fortress. The bigger the building, the more expensive it is
1679+to be built. But it will also conquer a bigger region. Sometimes, it is useful
1680+to build a big military building next to a mountain so that you can reach
1681+fields farther up.]]
1682+ )
1683+ )
1684+}
1685+
1686+mining_00 = {
1687+ pos = "topright",
1688+ title = _ "Searching for resources",
1689+ body = rt(p(_
1690+[[Okay, now we own some of the area on this mountain. Mountains are very
1691+important, because they contain resources: coal, iron ore, goldstone and
1692+granite. Each tribe uses the resources differently, but all need mines to get
1693+the resources out of the ground.]]
1694+ ) .. p(_
1695+[[Let's search for resources in this mountain. First, we'll build a road into
1696+the mountains and place a flag. Then, we click on the flag and call a geologist
1697+to it. I'll show you how it's done.]]
1698+ )
1699+)
1700+}
1701+
1702+mining_01 = {
1703+ pos = "topright",
1704+ title = _"Waiting for the geologist",
1705+ body = rt(p(_
1706+[[The geologist will arrive shortly to the flag and start investigating the
1707+area in his surroundings. He will place the following markers for the various
1708+resources:]]
1709+ )) ..
1710+ rt("image=tribes/barbarians/resi_coal1/resi_00.png", p(_ "a bit of coal")) ..
1711+ rt("image=tribes/barbarians/resi_coal2/resi_00.png", p(_ "a lot of coal")) ..
1712+ rt("image=tribes/barbarians/resi_iron1/resi_00.png", p(_ "a bit of iron")) ..
1713+ rt("image=tribes/barbarians/resi_iron2/resi_00.png", p(_ "a lot of iron")) ..
1714+ rt("image=tribes/barbarians/resi_gold1/resi_00.png", p(_ "a bit of gold")) ..
1715+ rt("image=tribes/barbarians/resi_gold2/resi_00.png", p(_ "a lot of gold")) ..
1716+ rt("image=tribes/barbarians/resi_granit1/resi_00.png",
1717+ p(_ "a bit of granite")) ..
1718+ rt("image=tribes/barbarians/resi_granit2/resi_00.png",
1719+ p(_ "a lot of granite")) ..
1720+ rt("image=tribes/barbarians/resi_water1/resi_00.png", p(_ "water")) ..
1721+ rt("image=tribes/barbarians/resi_none/resi_00.png",
1722+ p(_ "nothing was found here"))
1723+ .. rt(p(_
1724+[[Let's wait and see what the geologist finds on the mountain.]]
1725+ )
1726+)
1727+}
1728+
1729+mining_02 = {
1730+ pos = "topright",
1731+ title = _ "Mining conclusion",
1732+ body = rt(p(_
1733+[[So our geologist found a lot of coal on this mountain. You should therefore
1734+build a coal mine here. Building a mine is like building a house. The build
1735+help symbol for where a mine can be built is]]
1736+ )) .. rt("image=pics/mine.png", p(_"this one.")) ..
1737+ rt(p(_
1738+[[Note that a mine needs rations to work. Rations are
1739+produced in taverns and taverns need meat, pitta bread, and fish to produce
1740+them. You will need a lot more infrastructure to get your mines working
1741+well. This infrastructure also varies from tribe to tribe. You'll get them
1742+explained in the introduction campaigns for the three tribes.]]
1743+ )
1744+)
1745+}
1746+
1747+warefare_and_training_00 = {
1748+ title = _ "Warfare and Training",
1749+ body = rt(h1(_ "Soldiers and Warefare") .. p(_
1750+[[On to the last topic now. We are going to talk about soldiers, their training
1751+and their profession: warfare. As mentioned, widelands is about building up,
1752+not burning down: therefore warfare is also more focused on the economics than
1753+the military strategies. Nevertheless, warfare offers one way to challenge
1754+other players and it has some game mechanics that deserve explanation. The
1755+economies of the tribes are explained in their individual tutorial campaigns.
1756+Ok, I am going to create us a little training ground with a training camp and a
1757+warehouse to the north east of here.]]) .. p(_
1758+[[If you want to come back to this eastern part of your realm, just scroll here
1759+via right-button scrolling or open the minimap by clicking on the]]
1760+ )) .. rt("image=pics/menu_toggle_minimap.png", p(_
1761+[[minimap button at the bottom of the screen. Alternatively you could also press
1762+'m' on your keyboard]]
1763+ )) .. (rt(p(_
1764+[[The minimap shows you the complete map in miniature. You can directly jump to
1765+any field by left-clicking on it. You can also toggle buildings, roads, flags
1766+and player indicators on and off inside the map.]]
1767+ ) .. p(_
1768+[[But I digress. Back to soldiers. What was I about to do? Oh yes, I wanted to
1769+build a small training scenario for you. Let's do that now.]]
1770+ )
1771+ )
1772+ )
1773+}
1774+
1775+warefare_and_training_01 = {
1776+ pos = "topright",
1777+ title = _ "Trainings camp and soldier stats",
1778+ body = rt(p(_
1779+[[There we go. Take a look at the soldiers that are on their way into our
1780+trainings camp. They look different than normal workers: they have a health bar
1781+over their head that displays their remaining hitpoints and they have four
1782+symbols which symbolize the individual soldier's current levels in the four
1783+different categories hitpoints, attack, defense and evade.]]
1784+ ) .. p(_
1785+[[A soldier is created as any normal worker: a carrier grabs a tool in a
1786+warehouse as soon as a request for a certain profession is not fulfilled. The
1787+tool to create a barbarian soldier is an axe. The newly created soldier is of
1788+level 0. To make the soldier better in any of the four categories, training is
1789+needed. Training happens in training sites like the trainings camp or the
1790+battle arena: soldiers go there (as our little fellows are currently doing),
1791+consume some wares and advance a level in one category. If a barbarian soldier
1792+is fully trained, he has level 3 hitpoints, level 5 attack, level 0 defense and
1793+level 2 evade. This is one fearsome warrior then! The individual statistics
1794+have the following meaning:]]
1795+ ) .. h2(_"Hitpoints:") .. p(_
1796+[[The total life of a soldier. A barbarian soldier starts with ~130 hitpoints,
1797+with each hitpoint level he gains 28 hitpoints.]]
1798+ ) .. h2(_"Attack:") .. p(_
1799+[[The amount of damage a soldier inflicts upon a successful attack on the
1800+enemy. A barbarian soldier with attack level 0 inflicts ~14 hitpoints damage
1801+when he succeeds to hit an enemy. For each attack level, he gains 7 damage.
1802+]]
1803+ ) .. h2(_"Defense:") .. p(_
1804+[[Defense is the value that is subtracted from the attack value. The barbarians
1805+can not train in this skill and therefore have always defense level 0 which
1806+means that they always get 3 hitpoints subtracted from the damage inflicted. If
1807+an attacker with an attack value of 15 hitpoints hits a barbarian soldier, the
1808+barbarian would lose 15 - 3 = 12 hitpoints. The 3 hitpoints that are subtracted
1809+are because of the defense ability.]]
1810+ ) .. h2(_"Evade:") .. p(_
1811+[[Evade is the chance that the soldier is able to dodge an attack. It is 25% for
1812+a level 0 evade barbarian and increases in steps of 15% for each level.]]
1813+ )
1814+ )
1815+}
1816+
1817+enhance_fortress = {
1818+ pos = "topright",
1819+ title = _ "Enhance this fortress",
1820+ body = rt(h1(_ "Enhancing buildings") .. p(_
1821+[[I will create an enemy for you soon, but let's make sure you are prepared.
1822+This fortress is already quite strong and conquers a lot of space. But there is
1823+an even bigger building: the citadel.]]
1824+ ) .. p(_
1825+[[Citadels can not be built directly. Instead, you have to construct a fortress
1826+first and then enhance it to a citadel. To do so, click on the fortress, then
1827+choose the enhance to citadel button. Your soldiers will leave the citadel
1828+while the construction is going on. This means that your fortress has no
1829+military influence any more. If an enemy builds a military building nearby,
1830+your construction site could burn down. No sweat, that won't happen here.]]
1831+ ) .. p(_
1832+[[Enhance your fortress to a citadel now. Remember that you can speed time up
1833+by using PAGE_UP, building a citadel takes a while.]]
1834+ )
1835+ ),
1836+ obj_name = "enhance_fortress",
1837+ obj_title = _"Enhance your fortress to a citadel",
1838+ obj_body = rt(h1(_ "Enhance your fortress") .. p(_
1839+[[Enhance your fortress to a mighty citadel. The citadel can house 12 soldiers
1840+and is the biggest military building the barbarians can build. It also costs a
1841+lot and takes a long time to build. It is most suited to guard strategically
1842+important points like constricted points or mountains.]]
1843+ )
1844+ )
1845+}
1846+
1847+attack_enemey = {
1848+ pos = "topright",
1849+ title = _ "Defeat your enemy",
1850+ body = rt(h1(_ "Defeat the enemy") .. p(_
1851+[[I created a sparring partner for you: It is an empire tribe close to your
1852+citadel. To attack its buildings, click on the door of your target building,
1853+choose the number of soldiers that you wish to send and click on the attack
1854+button. Your soldiers will come from all nearby military buildings. Likewise,
1855+the defenders will come from all nearby military buildings of the enemy and
1856+intercept your forces.]]
1857+ ) .. p(_
1858+[[Attack and conquer all military buildings of the enemy and destroy its
1859+headquarters.]]
1860+ )
1861+ ),
1862+ obj_name = "defeated_the_empire",
1863+ obj_title = _ "Defeat the enemy tribe",
1864+ obj_body = rt(h1(_"Defeat your enemy") .. p(_
1865+[[Defeat the nearby enemy. To attack a building, click on its doors, choose the
1866+number of attacking soldiers, then send them via the attack button.]]
1867 )
1868 )
1869 }
1870@@ -367,24 +688,24 @@
1871 title = _ "Conclusion",
1872 body = rt(h1(_"Conclusion") ..
1873 p(_
1874-[[This concludes the tutorial. There is some stuff we have not covered: mining,
1875- training of soldiers, enhancing buildings, warfare, the statistics, the
1876- mini-map. We have not even build a single producing building even though
1877- producing wares is the most important thing in Widelands. But you can learn
1878- these while you go through the individual tribe's introduction campaigns. Each
1879- consists of some scenarios introducing the tribes and their economy while
1880- introducing the background story of Widelands.]]
1881+[[This concludes the tutorial. There is some stuff we have not covered here --
1882+we have not even built a single producing building even though producing wares
1883+is the most important thing in Widelands -- but you've learned the ropes. You
1884+can learn about the remaining stuff while you go through the individual tribe's
1885+introduction campaigns. Each consists of some scenarios explaining the tribes
1886+and their economy while introducing the background story of Widelands. Have fun
1887+playing!]]
1888 ) .. p(_
1889 [[You can continue playing this map or you can end this game whenever you like.
1890- To leave this game and return to the main menu click on the]]
1891+To leave this game and return to the main menu click on the]]
1892 )) .. rt("image=pics/menu_options_menu.png", p(_
1893 [[options menu button on the very left at the bottom of the screen.
1894- Then click the]]
1895+Then click the]]
1896 )) .. rt("image=pics/menu_exit_game.png", p(_
1897 [[exit game button.]]
1898 )) .. rt(p(_
1899 [[Thanks for playing this tutorial. Enjoy Widelands and remember
1900- to visit us at]]
1901+to visit us at]]
1902 )) .. rt("text-align=center",
1903 "<p font-size=24 font-decoration=underline>http://www.widelands.org</p>"
1904 )
1905
1906=== modified file 'src/economy/flag.cc'
1907--- src/economy/flag.cc 2010-04-18 13:13:49 +0000
1908+++ src/economy/flag.cc 2010-04-30 14:39:36 +0000
1909@@ -243,6 +243,17 @@
1910 }
1911
1912 /**
1913+ * Return all positions we occupy on the map. For a Flag, this is only one
1914+*/
1915+BaseImmovable::PositionList Flag::get_positions
1916+ (const Editor_Game_Base &) const throw ()
1917+{
1918+ PositionList rv;
1919+ rv.push_back(m_position);
1920+ return rv;
1921+}
1922+
1923+/**
1924 * Return neighbouring flags.
1925 */
1926 void Flag::get_neighbours(RoutingNodeNeighbours & neighbours)
1927
1928=== modified file 'src/economy/flag.h'
1929--- src/economy/flag.h 2010-04-18 12:16:52 +0000
1930+++ src/economy/flag.h 2010-04-30 14:39:36 +0000
1931@@ -74,6 +74,7 @@
1932 virtual Flag & base_flag();
1933
1934 Coords get_position() const {return m_position;}
1935+ virtual PositionList get_positions (const Editor_Game_Base &) const throw ();
1936 void get_neighbours(RoutingNodeNeighbours &);
1937 int32_t get_waitcost() const {return m_item_filled;}
1938
1939
1940=== modified file 'src/economy/road.cc'
1941--- src/economy/road.cc 2010-04-05 21:51:37 +0000
1942+++ src/economy/road.cc 2010-04-30 14:39:36 +0000
1943@@ -122,6 +122,24 @@
1944 return true;
1945 }
1946
1947+BaseImmovable::PositionList Road::get_positions
1948+ (const Editor_Game_Base & egbase) const throw()
1949+{
1950+ Map & map = egbase.map();
1951+ Coords curf = map.get_fcoords(m_path.get_start());
1952+
1953+ PositionList rv;
1954+ const Path::Step_Vector::size_type nr_steps = m_path.get_nsteps();
1955+ for (Path::Step_Vector::size_type steps = 0; steps < nr_steps + 1; ++steps)
1956+ {
1957+ if (steps > 0 && steps < m_path.get_nsteps())
1958+ rv.push_back(curf);
1959+
1960+ if (steps < m_path.get_nsteps())
1961+ map.get_neighbour(curf, m_path[steps], &curf);
1962+ }
1963+ return rv;
1964+}
1965
1966 static std::string const road_name = "road";
1967 std::string const & Road::name() const throw () {return road_name;}
1968
1969=== modified file 'src/economy/road.h'
1970--- src/economy/road.h 2010-03-28 09:39:54 +0000
1971+++ src/economy/road.h 2010-04-30 14:39:36 +0000
1972@@ -78,6 +78,7 @@
1973 char const * type_name() const throw () {return "road";}
1974 virtual int32_t get_size () const throw ();
1975 virtual bool get_passable() const throw ();
1976+ virtual PositionList get_positions(const Editor_Game_Base &) const throw ();
1977 std::string const & name() const throw ();
1978
1979 virtual Flag & base_flag();
1980
1981=== modified file 'src/logic/building.cc'
1982--- src/logic/building.cc 2010-04-01 10:59:34 +0000
1983+++ src/logic/building.cc 2010-04-30 14:39:36 +0000
1984@@ -459,6 +459,32 @@
1985 }
1986
1987
1988+/**
1989+ * Return all positions on the map that we occupy
1990+ */
1991+BaseImmovable::PositionList Building::get_positions
1992+ (const Editor_Game_Base & egbase) const throw ()
1993+{
1994+ PositionList rv;
1995+
1996+ rv.push_back(m_position);
1997+ if (get_size() == BIG) {
1998+ Map & map = egbase.map();
1999+ Coords neighb;
2000+
2001+ map.get_ln(m_position, &neighb);
2002+ rv.push_back(neighb);
2003+
2004+ map.get_tln(m_position, &neighb);
2005+ rv.push_back(neighb);
2006+
2007+ map.get_trn(m_position, &neighb);
2008+ rv.push_back(neighb);
2009+ }
2010+ return rv;
2011+}
2012+
2013+
2014 /*
2015 ===============
2016 Remove the building from the world now, and create a fire in its place if
2017
2018=== modified file 'src/logic/building.h'
2019--- src/logic/building.h 2010-04-03 16:44:44 +0000
2020+++ src/logic/building.h 2010-04-30 14:39:36 +0000
2021@@ -165,7 +165,9 @@
2022
2023 virtual Flag & base_flag();
2024 virtual uint32_t get_playercaps() const throw ();
2025+
2026 virtual Coords get_position() const throw () {return m_position;}
2027+ virtual PositionList get_positions (const Editor_Game_Base &) const throw ();
2028
2029 std::string const & name() const throw ();
2030 const std::string & descname() const throw () {return descr().descname();}
2031
2032=== modified file 'src/logic/immovable.cc'
2033--- src/logic/immovable.cc 2010-04-19 09:39:05 +0000
2034+++ src/logic/immovable.cc 2010-04-30 14:39:36 +0000
2035@@ -348,6 +348,15 @@
2036 return IMMOVABLE;
2037 }
2038
2039+BaseImmovable::PositionList Immovable::get_positions
2040+ (const Editor_Game_Base &) const throw ()
2041+{
2042+ PositionList rv;
2043+
2044+ rv.push_back(m_position);
2045+ return rv;
2046+}
2047+
2048 int32_t Immovable::get_size() const throw ()
2049 {
2050 return descr().get_size();
2051
2052=== modified file 'src/logic/immovable.h'
2053--- src/logic/immovable.h 2010-03-28 13:19:24 +0000
2054+++ src/logic/immovable.h 2010-04-30 14:39:36 +0000
2055@@ -56,6 +56,15 @@
2056
2057 virtual int32_t get_size () const throw () = 0;
2058 virtual bool get_passable() const throw () = 0;
2059+
2060+ typedef std::vector<Coords> PositionList;
2061+ /**
2062+ * Return all coordinates occupied by this Immovable. We gurantee that the
2063+ * list always contains one entry and the first one is the main position
2064+ * if one can be chosen as main.
2065+ */
2066+ virtual PositionList get_positions
2067+ (const Editor_Game_Base &) const throw () = 0;
2068 virtual void draw
2069 (const Editor_Game_Base &, RenderTarget &, const FCoords, const Point)
2070 = 0;
2071@@ -127,6 +136,7 @@
2072 Immovable(const Immovable_Descr &);
2073
2074 Coords get_position() const {return m_position;}
2075+ virtual PositionList get_positions (const Editor_Game_Base &) const throw ();
2076
2077 virtual int32_t get_type () const throw ();
2078 char const * type_name() const throw () {return "immovable";}
2079
2080=== modified file 'src/logic/legacy.cc'
2081--- src/logic/legacy.cc 2010-01-14 18:22:23 +0000
2082+++ src/logic/legacy.cc 2010-04-30 14:39:36 +0000
2083@@ -352,6 +352,15 @@
2084 virtual bool get_passable() const throw () {return true;}
2085 virtual void draw (Editor_Game_Base const &, RenderTarget &, FCoords, Point)
2086 {}
2087+ virtual PositionList get_positions (const Editor_Game_Base &) const throw ()
2088+ {
2089+ // This violates what I had in mind for get_positions, but since this is
2090+ // attic code and get_positions was added long after this code was gone
2091+ // I guess it is save to return an empty list here.
2092+ PositionList rv;
2093+ return rv;
2094+ }
2095+
2096
2097 struct Loader : public BaseImmovable::Loader {
2098 virtual void load(FileRead & fr, uint8_t const version) {
2099@@ -425,6 +434,14 @@
2100 virtual bool get_passable() const throw () {return true;}
2101 virtual void draw (Editor_Game_Base const &, RenderTarget &, FCoords, Point)
2102 {}
2103+ virtual PositionList get_positions (const Editor_Game_Base &) const throw ()
2104+ {
2105+ // This violates what I had in mind for get_positions, but since this is
2106+ // attic code and get_positions was added long after this code was gone
2107+ // I guess it is save to return an empty list here.
2108+ PositionList rv;
2109+ return rv;
2110+ }
2111
2112 struct Loader : public BaseImmovable::Loader {
2113 virtual void load(FileRead & fr, uint8_t const version) {
2114
2115=== modified file 'src/save_handler.cc'
2116--- src/save_handler.cc 2009-09-06 11:57:37 +0000
2117+++ src/save_handler.cc 2010-04-30 14:39:36 +0000
2118@@ -36,6 +36,9 @@
2119 void SaveHandler::think(Widelands::Game & game, int32_t realtime) {
2120 initialize(realtime);
2121
2122+ if (not m_allow_autosaving) // Is autosaving allowed atm?
2123+ return;
2124+
2125 int32_t const autosaveInterval =
2126 g_options.pull_section("global").get_int
2127 ("autosave", DEFAULT_AUTOSAVE_INTERVAL * 60);
2128
2129=== modified file 'src/save_handler.h'
2130--- src/save_handler.h 2009-09-30 17:38:02 +0000
2131+++ src/save_handler.h 2010-04-30 14:39:36 +0000
2132@@ -33,11 +33,13 @@
2133 class SaveHandler {
2134 int32_t m_lastSaveTime;
2135 bool m_initialized;
2136+ bool m_allow_autosaving;
2137
2138 void initialize(int32_t currenttime);
2139
2140+
2141 public:
2142- SaveHandler() : m_initialized(false) {}
2143+ SaveHandler() : m_initialized(false), m_allow_autosaving(true) {}
2144 void think(Widelands::Game &, int32_t currenttime);
2145 std::string create_file_name(std::string dir, std::string filename);
2146 bool save_game
2147@@ -46,6 +48,8 @@
2148 std::string * error = 0);
2149
2150 static std::string get_base_dir() {return "save";}
2151+ void set_allow_autosaving(bool t) {m_allow_autosaving = t;}
2152+ bool get_allow_autosaving() {return m_allow_autosaving;}
2153 };
2154
2155 #endif
2156
2157=== modified file 'src/scripting/lua_game.cc'
2158--- src/scripting/lua_game.cc 2010-04-25 18:47:42 +0000
2159+++ src/scripting/lua_game.cc 2010-04-30 14:39:36 +0000
2160@@ -571,11 +571,14 @@
2161 }
2162 #undef CHECK_ARG
2163
2164+ std::string title = luaL_checkstring(L, 2);
2165+ std::string body = luaL_checkstring(L, 3);
2166+
2167 uint32_t cspeed = game.gameController()->desiredSpeed();
2168 game.gameController()->setDesiredSpeed(0);
2169
2170- std::string title = luaL_checkstring(L, 2);
2171- std::string body = luaL_checkstring(L, 3);
2172+ game.save_handler().set_allow_autosaving(false);
2173+
2174 Story_Message_Box * mb =
2175 new Story_Message_Box
2176 (game.get_ipl(), luaL_checkstring(L, 2), luaL_checkstring(L, 3),
2177@@ -586,9 +589,12 @@
2178
2179 // Manually force the game to reevaluate it's current state,
2180 // especially time information.
2181- game.think();
2182+ game.gameController()->think();
2183
2184 game.gameController()->setDesiredSpeed(cspeed);
2185+
2186+ game.save_handler().set_allow_autosaving(true);
2187+
2188 return 1;
2189 }
2190
2191@@ -1581,11 +1587,11 @@
2192 }
2193
2194 /* RST
2195- .. function:: get_speed(speed)
2196-
2197- Gets the current game speed
2198-
2199- :returns: :const:`nil`
2200+.. function:: get_speed(speed)
2201+
2202+ Gets the current game speed
2203+
2204+ :returns: :const:`nil`
2205 */
2206 // UNTESTED
2207 static int L_get_speed(lua_State * L) {
2208@@ -1593,11 +1599,43 @@
2209 return 1;
2210 }
2211
2212+/* RST
2213+ .. function:: set_allow_autosaving(b)
2214+
2215+ Disable or enable auto-saving. When you show off UI features in a
2216+ tutorial or scenario, you have to disallow auto-saving because UI
2217+ elements can now be saved.
2218+
2219+ :arg b: allow autosaving or disallow it
2220+ :type b: :class:`boolean`
2221+*/
2222+// UNTESTED
2223+static int L_set_allow_autosaving(lua_State * L) {
2224+ get_game(L).save_handler().set_allow_autosaving
2225+ (luaL_checkboolean(L, -1));
2226+ return 0;
2227+}
2228+
2229+/* RST
2230+ .. function:: get_allow_autosaving
2231+
2232+ Returns the current state of autosaving.
2233+
2234+ :returns: :class:`boolean`
2235+*/
2236+// UNTESTED
2237+static int L_get_allow_autosaving(lua_State * L) {
2238+ lua_pushboolean(L, get_game(L).save_handler().get_allow_autosaving());
2239+ return 1;
2240+}
2241+
2242 const static struct luaL_reg wlgame [] = {
2243 {"run_coroutine", &L_run_coroutine},
2244 {"get_time", &L_get_time},
2245 {"get_speed", &L_get_speed},
2246 {"set_speed", &L_set_speed},
2247+ {"set_allow_autosaving", &L_set_allow_autosaving},
2248+ {"get_allow_autosaving", &L_get_allow_autosaving},
2249 {0, 0}
2250 };
2251
2252
2253=== modified file 'src/scripting/lua_map.cc'
2254--- src/scripting/lua_map.cc 2010-04-25 12:56:53 +0000
2255+++ src/scripting/lua_map.cc 2010-04-30 14:39:36 +0000
2256@@ -74,12 +74,14 @@
2257 case Map_Object::BUILDING:
2258 {
2259 const char * type_name = bi->type_name();
2260- if (!strcmp(type_name, "warehouse"))
2261- return CAST_TO_LUA(Warehouse);
2262+ if (!strcmp(type_name, "constructionsite"))
2263+ return CAST_TO_LUA(ConstructionSite);
2264 else if (!strcmp(type_name, "productionsite"))
2265 return CAST_TO_LUA(ProductionSite);
2266 else if (!strcmp(type_name, "militarysite"))
2267 return CAST_TO_LUA(MilitarySite);
2268+ else if (!strcmp(type_name, "warehouse"))
2269+ return CAST_TO_LUA(Warehouse);
2270 else if (!strcmp(type_name, "trainingsite"))
2271 return CAST_TO_LUA(TrainingSite);
2272 else
2273@@ -914,6 +916,7 @@
2274 const PropertyType<L_BaseImmovable> L_BaseImmovable::Properties[] = {
2275 PROP_RO(L_BaseImmovable, size),
2276 PROP_RO(L_BaseImmovable, name),
2277+ PROP_RO(L_BaseImmovable, fields),
2278 {0, 0, 0},
2279 };
2280
2281@@ -964,6 +967,28 @@
2282 return 1;
2283 }
2284
2285+/* RST
2286+ .. attribute:: fields
2287+
2288+ (RO) An :class:`array` of :class:`~wl.map.Field` that is occupied by this
2289+ Immovable. If the immovable occupies more than one field (roads or big
2290+ buildings for example) the first entry in this list will be the main field
2291+*/
2292+int L_BaseImmovable::get_fields(lua_State * L) {
2293+ Editor_Game_Base & egbase = get_egbase(L);
2294+
2295+ BaseImmovable::PositionList pl = get(L, egbase)->get_positions(egbase);
2296+
2297+ lua_createtable(L, pl.size(), 0);
2298+ uint32_t idx = 1;
2299+ container_iterate_const(BaseImmovable::PositionList, pl, f) {
2300+ lua_pushuint32(L, idx++);
2301+ to_lua<L_Field>(L, new L_Field(f->x, f->y));
2302+ lua_rawset(L, -3);
2303+ }
2304+ return 1;
2305+}
2306+
2307 /*
2308 ==========================================================
2309 LUA METHODS
2310@@ -1352,6 +1377,55 @@
2311 ==========================================================
2312 */
2313
2314+/* RST
2315+ConstructionSite
2316+-----------------
2317+
2318+.. class:: ConstructionSite
2319+
2320+ Child of: :class:`Building`
2321+
2322+ A ConstructionSite as it appears in Game. This is only a minimal wrapping at
2323+ the moment
2324+*/
2325+const char L_ConstructionSite::className[] = "ConstructionSite";
2326+const MethodType<L_ConstructionSite> L_ConstructionSite::Methods[] = {
2327+ {0, 0},
2328+};
2329+const PropertyType<L_ConstructionSite> L_ConstructionSite::Properties[] = {
2330+ PROP_RO(L_ConstructionSite, building),
2331+ {0, 0, 0},
2332+};
2333+
2334+/*
2335+ ==========================================================
2336+ PROPERTIES
2337+ ==========================================================
2338+ */
2339+/* RST
2340+ .. attribute:: building
2341+
2342+ (RO) The name of the building that is constructed here
2343+*/
2344+int L_ConstructionSite::get_building(lua_State * L) {
2345+ lua_pushstring(L, get(L, get_game(L))->building().name());
2346+ return 1;
2347+}
2348+
2349+/*
2350+ ==========================================================
2351+ LUA METHODS
2352+ ==========================================================
2353+ */
2354+
2355+/*
2356+ ==========================================================
2357+ C METHODS
2358+ ==========================================================
2359+ */
2360+
2361+
2362+
2363
2364 /* RST
2365 Warehouse
2366@@ -2255,6 +2329,13 @@
2367 add_parent<L_Road, L_MapObject>(L);
2368 lua_pop(L, 1); // Pop the meta table
2369
2370+ register_class<L_ConstructionSite>(L, "map", true);
2371+ add_parent<L_ConstructionSite, L_Building>(L);
2372+ add_parent<L_ConstructionSite, L_PlayerImmovable>(L);
2373+ add_parent<L_ConstructionSite, L_BaseImmovable>(L);
2374+ add_parent<L_ConstructionSite, L_MapObject>(L);
2375+ lua_pop(L, 1); // Pop the meta table
2376+
2377 register_class<L_Warehouse>(L, "map", true);
2378 add_parent<L_Warehouse, L_Building>(L);
2379 add_parent<L_Warehouse, L_PlayerImmovable>(L);
2380
2381=== modified file 'src/scripting/lua_map.h'
2382--- src/scripting/lua_map.h 2010-04-08 13:22:53 +0000
2383+++ src/scripting/lua_map.h 2010-04-30 14:39:36 +0000
2384@@ -26,11 +26,12 @@
2385
2386 #include "economy/flag.h"
2387 #include "economy/road.h"
2388+#include "logic/constructionsite.h"
2389 #include "logic/game.h"
2390-#include "logic/warehouse.h"
2391+#include "logic/militarysite.h"
2392 #include "logic/productionsite.h"
2393-#include "logic/militarysite.h"
2394 #include "logic/trainingsite.h"
2395+#include "logic/warehouse.h"
2396
2397 #include "luna.h"
2398
2399@@ -120,6 +121,7 @@
2400 */
2401 int get_size(lua_State * L);
2402 int get_name(lua_State * L);
2403+ int get_fields(lua_State * L);
2404
2405 /*
2406 * Lua Methods
2407@@ -348,6 +350,33 @@
2408 };
2409
2410
2411+class L_ConstructionSite : public L_Building
2412+{
2413+public:
2414+ LUNA_CLASS_HEAD(L_ConstructionSite);
2415+
2416+ L_ConstructionSite() {}
2417+ L_ConstructionSite(Widelands::ConstructionSite & mo) : L_Building(mo) {
2418+ }
2419+ L_ConstructionSite(lua_State * L) : L_Building(L) {}
2420+ virtual ~L_ConstructionSite() {}
2421+
2422+ /*
2423+ * Properties
2424+ */
2425+ int get_building(lua_State *);
2426+
2427+ /*
2428+ * Lua Methods
2429+ */
2430+
2431+ /*
2432+ * C Methods
2433+ */
2434+ CASTED_GET(ConstructionSite);
2435+};
2436+
2437+
2438 class L_Warehouse : public L_Building,
2439 public L_HasWares, public L_HasWorkers, public L_HasSoldiers
2440 {
2441
2442=== modified file 'src/scripting/lua_ui.cc'
2443--- src/scripting/lua_ui.cc 2010-04-26 15:18:43 +0000
2444+++ src/scripting/lua_ui.cc 2010-04-30 14:39:36 +0000
2445@@ -503,6 +503,8 @@
2446 PROP_RW(L_MapView, viewpoint_x),
2447 PROP_RW(L_MapView, viewpoint_y),
2448 PROP_RW(L_MapView, buildhelp),
2449+ PROP_RW(L_MapView, census),
2450+ PROP_RW(L_MapView, statistics),
2451 {0, 0, 0},
2452 };
2453
2454@@ -559,6 +561,37 @@
2455 return 0;
2456 }
2457
2458+/* RST
2459+ .. attribute:: census
2460+
2461+ (RW) True if the census strings are shown on buildings, false otherwise
2462+*/
2463+int L_MapView::get_census(lua_State * L) {
2464+ lua_pushboolean(L, get()->get_display_flag(Interactive_Base::dfShowCensus));
2465+ return 1;
2466+}
2467+int L_MapView::set_census(lua_State * L) {
2468+ get()->set_display_flag
2469+ (Interactive_Base::dfShowCensus, luaL_checkboolean(L, -1));
2470+ return 0;
2471+}
2472+
2473+/* RST
2474+ .. attribute:: statistics
2475+
2476+ (RW) True if the statistics strings are shown on buildings, false
2477+ otherwise
2478+*/
2479+int L_MapView::get_statistics(lua_State * L) {
2480+ lua_pushboolean(L, get()->get_display_flag
2481+ (Interactive_Base::dfShowStatistics));
2482+ return 1;
2483+}
2484+int L_MapView::set_statistics(lua_State * L) {
2485+ get()->set_display_flag
2486+ (Interactive_Base::dfShowStatistics, luaL_checkboolean(L, -1));
2487+ return 0;
2488+}
2489
2490 /*
2491 * Lua Functions
2492@@ -589,7 +622,37 @@
2493 * ========================================================================
2494 */
2495
2496+/* RST
2497+.. function:: set_user_input_allowed(b)
2498+
2499+ Allow or disallow user input. Be warned, setting this will make that
2500+ mouse movements and keyboard presses are completely ignored. Only
2501+ scripted stuff will still happen.
2502+
2503+ :arg b: :const:`true` or :const:`false`
2504+ :type b: :class:`boolean`
2505+*/
2506+static int L_set_user_input_allowed(lua_State * L) {
2507+ UI::Panel::set_allow_user_input(luaL_checkboolean(L, -1));
2508+ return 0;
2509+}
2510+/* RST
2511+.. method:: get_user_input_allowed
2512+
2513+ Return the current state of this flag.
2514+
2515+ :returns: :const:`true` or :const:`false`
2516+ :rtype: :class:`boolean`
2517+*/
2518+static int L_get_user_input_allowed(lua_State * L) {
2519+ lua_pushboolean(L, UI::Panel::allow_user_input());
2520+ return 1;
2521+}
2522+
2523+
2524 const static struct luaL_reg wlui [] = {
2525+ {"set_user_input_allowed", &L_set_user_input_allowed},
2526+ {"get_user_input_allowed", &L_get_user_input_allowed},
2527 {0, 0}
2528 };
2529
2530
2531=== modified file 'src/scripting/lua_ui.h'
2532--- src/scripting/lua_ui.h 2010-04-26 15:18:43 +0000
2533+++ src/scripting/lua_ui.h 2010-04-30 14:39:36 +0000
2534@@ -188,6 +188,10 @@
2535 int set_viewpoint_y(lua_State *);
2536 int get_buildhelp(lua_State * L);
2537 int set_buildhelp(lua_State * L);
2538+ int get_census(lua_State * L);
2539+ int set_census(lua_State * L);
2540+ int get_statistics(lua_State * L);
2541+ int set_statistics(lua_State * L);
2542
2543 /*
2544 * Lua Methods
2545
2546=== modified file 'src/scripting/scripting.cc'
2547--- src/scripting/scripting.cc 2010-04-25 18:47:42 +0000
2548+++ src/scripting/scripting.cc 2010-04-30 14:39:36 +0000
2549@@ -40,6 +40,11 @@
2550 #endif
2551
2552 // TODO: add wl.editor to documentation
2553+// TODO: position or field should be on the immovable classes.
2554+// Check out what this BaseImmovable <-> Immovable thing is all about.
2555+// TODO: road must offer some access to it's fields for this to work.
2556+// TODO: also big buildings occupy more space: i suggest some occupied fields property
2557+// TODO: and also a field property
2558
2559 /*
2560 ============================================
2561
2562=== modified file 'src/scripting/test/ts.wmf/scripting/test_baseimmovables.lua'
2563--- src/scripting/test/ts.wmf/scripting/test_baseimmovables.lua 2010-04-08 14:04:31 +0000
2564+++ src/scripting/test/ts.wmf/scripting/test_baseimmovables.lua 2010-04-30 14:39:36 +0000
2565@@ -94,6 +94,8 @@
2566 -- -- ==============
2567 -- -- Property tests
2568 -- -- ==============
2569+-- TODO: add tests for immovable.fields
2570+-- TODO: add also tests for big buildings
2571 immovable_property_tests = lunit.TestCase("Immovable sizes")
2572 function immovable_property_tests:setup()
2573 self.none = wl.map.create_immovable("pebble1", wl.map.Field(19, 10))
2574
2575=== added file 'src/scripting/test/ts.wmf/scripting/test_constructionsite.lua'
2576--- src/scripting/test/ts.wmf/scripting/test_constructionsite.lua 1970-01-01 00:00:00 +0000
2577+++ src/scripting/test/ts.wmf/scripting/test_constructionsite.lua 2010-04-30 14:39:36 +0000
2578@@ -0,0 +1,46 @@
2579+-- =========================
2580+-- Constructionsite Functionality
2581+-- =========================
2582+constructionsite_tests = lunit.TestCase("constructionsite tests")
2583+function constructionsite_tests:setup()
2584+ self.f1 = wl.map.Field(8,10)
2585+ self.f2 = wl.map.Field(12,10)
2586+ self.p = wl.game.Player(1)
2587+
2588+ self.p:place_building("lumberjacks_hut", self.f1, true)
2589+ self.p:place_building("fortress", self.f2, true)
2590+
2591+ self.l = self.f1.immovable
2592+ self.f = self.f2.immovable
2593+end
2594+
2595+function constructionsite_tests:test_upcasting_from_immovable_to_building()
2596+ local i = self.f1.immovable
2597+ assert_equal(i, self.l)
2598+ assert_not_equal(nil, i.building)
2599+end
2600+
2601+function constructionsite_tests:teardown()
2602+ pcall(function() self.f1.brn.immovable:remove() end)
2603+ pcall(function() self.f2.brn.immovable:remove() end)
2604+end
2605+
2606+function constructionsite_tests:test_name()
2607+ assert_equal("constructionsite", self.l.name)
2608+ assert_equal("constructionsite", self.f.name)
2609+end
2610+function constructionsite_tests:test_type()
2611+ assert_equal("constructionsite", self.l.type)
2612+ assert_equal("constructionsite", self.f.type)
2613+end
2614+
2615+function constructionsite_tests:test_size()
2616+ assert_equal("small", self.l.size)
2617+ assert_equal("big", self.f.size)
2618+end
2619+
2620+function constructionsite_tests:test_building()
2621+ assert_equal("lumberjacks_hut", self.l.building)
2622+ assert_equal("fortress", self.f.building)
2623+end
2624+
2625
2626=== modified file 'src/scripting/test/ts.wmf/scripting/test_flag.lua'
2627--- src/scripting/test/ts.wmf/scripting/test_flag.lua 2010-03-24 12:08:42 +0000
2628+++ src/scripting/test/ts.wmf/scripting/test_flag.lua 2010-04-30 14:39:36 +0000
2629@@ -9,7 +9,8 @@
2630 flag_tests = lunit.TestCase("flag tests")
2631 function flag_tests:setup()
2632 self.p = wl.game.Player(1)
2633- self.f = self.p:place_flag(wl.map.Field(13,10), 1)
2634+ self.field = wl.map.Field(13,10)
2635+ self.f = self.p:place_flag(self.field, 1)
2636 end
2637 function flag_tests:teardown()
2638 pcall(self.f.remove, self.f)
2639@@ -21,6 +22,11 @@
2640 function flag_tests:test_type()
2641 assert_equal("flag", self.f.type)
2642 end
2643+function flag_tests:test_fields()
2644+ local f = self.f.fields
2645+ assert_equal(1, #f)
2646+ assert_equal(self.field, f[1])
2647+end
2648 function flag_tests:test_no_wares_on_creation()
2649 local rv = self.f:get_wares("all")
2650 cnt = 0
2651
2652=== modified file 'src/scripting/test/ts.wmf/scripting/test_immovables.lua'
2653--- src/scripting/test/ts.wmf/scripting/test_immovables.lua 2010-04-08 14:04:31 +0000
2654+++ src/scripting/test/ts.wmf/scripting/test_immovables.lua 2010-04-30 14:39:36 +0000
2655@@ -9,6 +9,7 @@
2656 include "test_road"
2657
2658 -- Buildings
2659+ include "test_constructionsite"
2660 include "test_warehouse"
2661 include "test_productionsite"
2662 include "test_militarysite"
2663
2664=== modified file 'src/scripting/test/ts.wmf/scripting/test_road.lua'
2665--- src/scripting/test/ts.wmf/scripting/test_road.lua 2010-03-24 12:08:42 +0000
2666+++ src/scripting/test/ts.wmf/scripting/test_road.lua 2010-04-30 14:39:36 +0000
2667@@ -76,8 +76,8 @@
2668
2669 self.start_flag = self.p:place_flag(self.f)
2670
2671- self.r = self.p:place_road(self.start_flag, "r", "r")
2672- self.end_flag = self.f.rn.rn.immovable
2673+ self.r = self.p:place_road(self.start_flag, "r", "r", "br", "br")
2674+ self.end_flag = self.f.rn.rn.brn.brn.immovable
2675 end
2676 function road_tests:teardown()
2677 flags = {self.start_flag, self.end_flag}
2678@@ -87,7 +87,14 @@
2679 end
2680
2681 function road_tests:test_length()
2682- assert_equal(2, self.r.length)
2683+ assert_equal(4, self.r.length)
2684+end
2685+function road_tests:test_field()
2686+ local f = self.r.fields
2687+ assert_equal(#f, 3)
2688+ assert_equal(self.f.rn, f[1])
2689+ assert_equal(self.f.rn.rn, f[2])
2690+ assert_equal(self.f.rn.rn.brn, f[3])
2691 end
2692 function road_tests:test_roadtype()
2693 assert_equal("normal", self.r.road_type)
2694@@ -110,7 +117,7 @@
2695 function road_tests:test_road_upcasting()
2696 i = self.f.rn.immovable
2697 assert_equal(i, self.r)
2698- assert_equal(2, i.length)
2699+ assert_equal(4, i.length)
2700 end
2701
2702 -- ====================
2703
2704=== modified file 'src/scripting/test/ts.wmf/scripting/test_ui.lua'
2705--- src/scripting/test/ts.wmf/scripting/test_ui.lua 2010-04-26 15:18:43 +0000
2706+++ src/scripting/test/ts.wmf/scripting/test_ui.lua 2010-04-30 14:39:36 +0000
2707@@ -161,6 +161,8 @@
2708 mv_tests = lunit.TestCase("MapView tests")
2709 function mv_tests:setup()
2710 self.mv = wl.ui.MapView()
2711+ self.mv.census = false
2712+ self.mv.buildhelp = false
2713 for n,w in pairs(self.mv.windows) do w:close() end
2714 end
2715
2716@@ -169,4 +171,18 @@
2717 assert_not_equal(nil, self.mv.windows.field_action)
2718 end
2719
2720+function mv_tests:test_census()
2721+ self.mv.census = 1
2722+ assert_equal(true, self.mv.census)
2723+ assert_equal(false, self.mv.statistics)
2724+end
2725+
2726+function mv_tests:test_statistics()
2727+ self.mv.statistics = 1
2728+ assert_equal(true, self.mv.statistics)
2729+ assert_equal(false, self.mv.census)
2730+end
2731+
2732+
2733+
2734
2735
2736=== modified file 'src/ui_basic/panel.cc'
2737--- src/ui_basic/panel.cc 2010-04-20 20:50:37 +0000
2738+++ src/ui_basic/panel.cc 2010-04-30 14:39:36 +0000
2739@@ -31,6 +31,11 @@
2740 Panel * Panel::_modal = 0;
2741 Panel * Panel::_g_mousegrab = 0;
2742 Panel * Panel::_g_mousein = 0;
2743+
2744+// The following variable can be set to false. If so, all mouse and keyboard
2745+// events are ignored and not passed on to any widget. This is only useful
2746+// for scripts that want to show off functionality without the user interfering.
2747+bool Panel::_g_allow_user_input = true;
2748 PictureID Panel::s_default_cursor = g_gr->get_no_picture();
2749
2750
2751@@ -824,6 +829,9 @@
2752 */
2753 void Panel::do_mousein(bool const inside)
2754 {
2755+ if (not _g_allow_user_input)
2756+ return;
2757+
2758 if (!inside && _mousein) {
2759 _mousein->do_mousein(false);
2760 _mousein = false;
2761@@ -837,6 +845,9 @@
2762 * Returns whether the event was processed.
2763 */
2764 bool Panel::do_mousepress(const Uint8 btn, int32_t x, int32_t y) {
2765+ if (not _g_allow_user_input)
2766+ return true;
2767+
2768 x -= _lborder;
2769 y -= _tborder;
2770 if (_flags & pf_top_on_click)
2771@@ -851,6 +862,9 @@
2772 return handle_mousepress(btn, x, y);
2773 }
2774 bool Panel::do_mouserelease(const Uint8 btn, int32_t x, int32_t y) {
2775+ if (not _g_allow_user_input)
2776+ return true;
2777+
2778 x -= _lborder;
2779 y -= _tborder;
2780 if (_g_mousegrab != this)
2781@@ -866,6 +880,9 @@
2782 (Uint8 const state,
2783 int32_t x, int32_t y, int32_t const xdiff, int32_t const ydiff)
2784 {
2785+ if (not _g_allow_user_input)
2786+ return true;
2787+
2788 x -= _lborder;
2789 y -= _tborder;
2790 if (_g_mousegrab != this)
2791@@ -886,6 +903,9 @@
2792 */
2793 bool Panel::do_key(bool const down, SDL_keysym const code)
2794 {
2795+ if (not _g_allow_user_input)
2796+ return true;
2797+
2798 if (_focus) {
2799 if (_focus->do_key(down, code))
2800 return true;
2801@@ -950,10 +970,16 @@
2802 * panel.
2803 */
2804 void Panel::ui_mousepress(const Uint8 button, int32_t x, int32_t y) {
2805+ if (not _g_allow_user_input)
2806+ return;
2807+
2808 if (Panel * const p = ui_trackmouse(x, y))
2809 p->do_mousepress(button, x, y);
2810 }
2811 void Panel::ui_mouserelease(const Uint8 button, int32_t x, int32_t y) {
2812+ if (not _g_allow_user_input)
2813+ return;
2814+
2815 if (Panel * const p = ui_trackmouse(x, y))
2816 p->do_mouserelease(button, x, y);
2817 }
2818@@ -966,6 +992,9 @@
2819 (Uint8 const state,
2820 int32_t x, int32_t y, int32_t const xdiff, int32_t const ydiff)
2821 {
2822+ if (not _g_allow_user_input)
2823+ return;
2824+
2825 if (!xdiff && !ydiff)
2826 return;
2827
2828@@ -988,6 +1017,9 @@
2829 */
2830 void Panel::ui_key(bool const down, SDL_keysym const code)
2831 {
2832+ if (not _g_allow_user_input)
2833+ return;
2834+
2835 _modal->do_key(down, code);
2836 }
2837
2838
2839=== modified file 'src/ui_basic/panel.h'
2840--- src/ui_basic/panel.h 2010-04-26 15:06:30 +0000
2841+++ src/ui_basic/panel.h 2010-04-30 14:39:36 +0000
2842@@ -208,6 +208,8 @@
2843 void set_snapparent(bool snapparent);
2844 bool get_snapparent() const {return _flags & pf_snap_parent_size;}
2845
2846+ inline static void set_allow_user_input(bool t) {_g_allow_user_input=t;}
2847+ inline static bool allow_user_input(void) {return _g_allow_user_input;}
2848
2849 protected:
2850 void die();
2851@@ -230,6 +232,7 @@
2852 (const Uint8 state, int32_t x, int32_t y, int32_t xdiff, int32_t ydiff);
2853 bool do_key(bool down, SDL_keysym code);
2854
2855+
2856 Panel * _parent;
2857 Panel * _next, * _prev;
2858 Panel * _fchild, * _lchild; // first, last child
2859@@ -269,6 +272,7 @@
2860 static Panel * _modal;
2861 static Panel * _g_mousegrab;
2862 static Panel * _g_mousein;
2863+ static bool _g_allow_user_input;
2864 static PictureID s_default_cursor;
2865 };
2866
2867
2868=== modified file 'src/wlapplication.cc'
2869--- src/wlapplication.cc 2010-04-24 13:39:38 +0000
2870+++ src/wlapplication.cc 2010-04-30 14:39:36 +0000
2871@@ -622,8 +622,6 @@
2872 break;
2873
2874 case SDL_MOUSEMOTION:
2875- // All the interesting stuff is now in Sys_PollEvent()
2876-
2877 m_mouse_position = Point(ev.motion.x, ev.motion.y);
2878
2879 if ((ev.motion.xrel or ev.motion.yrel) and cb and cb->mouse_move)
2880
2881=== modified file 'src/wui/interactive_base.cc'
2882--- src/wui/interactive_base.cc 2010-04-25 18:47:42 +0000
2883+++ src/wui/interactive_base.cc 2010-04-30 14:39:36 +0000
2884@@ -301,7 +301,7 @@
2885 // If one of the arrow keys is pressed, scroll here
2886 const uint32_t scrollval = 10;
2887
2888- if (keyboard_free()) {
2889+ if (keyboard_free() && Panel::allow_user_input()) {
2890 if (get_key_state(SDLK_UP))
2891 set_rel_viewpoint(Point(0, -scrollval));
2892 if (get_key_state(SDLK_DOWN))
2893@@ -590,7 +590,10 @@
2894 // Build the path as requested
2895 ref_cast<Game, Editor_Game_Base>(egbase()).send_player_build_road
2896 (m_road_build_player, *new Widelands::Path(*m_buildroad));
2897- if (get_key_state(SDLK_LCTRL) || get_key_state(SDLK_RCTRL)) {
2898+ if
2899+ (allow_user_input() and
2900+ (get_key_state(SDLK_LCTRL) or get_key_state(SDLK_RCTRL)))
2901+ {
2902 // place flags
2903 Map const & map = egbase().map();
2904 std::vector<Coords> const & c_vector =

Subscribers

People subscribed via source and target branches

to status/vote changes: