Merge lp:~qcumber-some/widelands/bugfix-768854 into lp:widelands

Proposed by Jens Beyer
Status: Merged
Merged at revision: 6204
Proposed branch: lp:~qcumber-some/widelands/bugfix-768854
Merge into: lp:widelands
Diff against target: 375 lines (+102/-54)
7 files modified
scripting/win_condition_texts.lua (+50/-0)
scripting/win_conditions/00_endless_game.lua (+3/-3)
scripting/win_conditions/01_defeat_all.lua (+4/-6)
scripting/win_conditions/02_collectors.lua (+10/-10)
scripting/win_conditions/03_territorial_lord.lua (+15/-15)
scripting/win_conditions/04_wood_gnome.lua (+17/-17)
scripting/win_conditions/05_endless_game_fogless.lua (+3/-3)
To merge this branch: bzr merge lp:~qcumber-some/widelands/bugfix-768854
Reviewer Review Type Date Requested Status
SirVer Needs Fixing
Jens Beyer Needs Resubmitting
Review via email: mp+83341@code.launchpad.net

Description of the change

Bugfix for bug768854

I hope I didn't miss a function. Problem seems to be that lua does not translate from within inner (local) functions if you don't set the textdomain again inside that function.

Please review and consider other lua scripts as well where this may be a problem.

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

I think this solution is dangerous. What it does is changing the textdomain which will persist for all other lua functions called later on. This could mean that some other text is then not translated. I suggest moving all static text out of the inner functions into the global lua namespace so that there are translated only once on loading. This is similar to how it is done in the scenarios (where we often have a text.lua script that contains all the static text).

Could you try that out Jens?

review: Needs Fixing
Revision history for this message
Jens Beyer (qcumber-some) wrote :

> I think this solution is dangerous. What it does is changing the textdomain
> which will persist for all other lua functions called later on. This could
> mean that some other text is then not translated. I suggest moving all static
> text out of the inner functions into the global lua namespace so that there
> are translated only once on loading. This is similar to how it is done in the
> scenarios (where we often have a text.lua script that contains all the static
> text).
>
> Could you try that out Jens?

Fixed as requested. From what I found this works, hope I understood correctly what to do ;-)

Please review again.

Revision history for this message
Jens Beyer (qcumber-some) wrote :

To add, I've pushed the branch again, it does not contain the 'old' commit.

review: Needs Resubmitting
Revision history for this message
SirVer (sirver) wrote :

Looking good from a translator point of views. All strings should now be properly translated when the game starts. However, by skimming over I saw that in some logic formated strings are used, e.g.

if candidateisteam and currentcandidate == game_status_territoral_lord.team:format(p.team)

This will break the game logic when a player saves a game, switches locale and reloads. Even worse: when someone attaches a savegame to a bug we need to load it with the same locale or the logic fails. This needs fixing.

review: Needs Fixing
Revision history for this message
Jens Beyer (qcumber-some) wrote :

> Looking good from a translator point of views. All strings should now be
> properly translated when the game starts. However, by skimming over I saw that
> in some logic formated strings are used, e.g.
>
> if candidateisteam and currentcandidate ==
> game_status_territoral_lord.team:format(p.team)
>
> This will break the game logic when a player saves a game, switches locale and
> reloads. Even worse: when someone attaches a savegame to a bug we need to load
> it with the same locale or the logic fails. This needs fixing.

This also made me sceptical when I encountered that, but I couldn't pinpoint why, so I left it the way it was, because this already had been the way before, hasn't it?

This is the line you mentioned before my fix:

if candidateisteam and currentcandidate == _("Team %i"):format(p.team)

Isn't this the same problem? If so, I'd vote for keeping my changes to fix this bug and create a new bug addressing game logic breakage. I suspect I'm not fit enough in Lua to fix this.

Revision history for this message
SirVer (sirver) wrote :

>> This will break the game logic when a player saves a game, switches locale and
>> reloads. Even worse: when someone attaches a savegame to a bug we need to load
>> it with the same locale or the logic fails. This needs fixing.
>
>This also made me sceptical when I encountered that, but I couldn't pinpoint why, so I left it the way it was, because this already had been the way before, hasn't it?
>
>This is the line you mentioned before my fix:
>
>if candidateisteam and currentcandidate == _("Team %i"):format(p.team)
>
>Isn't this the same problem? If so, I'd vote for keeping my changes to fix this bug and create a new bug addressing game logic breakage. I suspect I'm not fit enough in Lua to fix this.

Yes that is the very same problem. This should not have slipped by :/.
I agree then, a bug report of its own is the way to go. I will merge
your work soonish (maybe tomorrow).

Revision history for this message
David Allwicher (aber) wrote :

qcumber-some is also member of widelands-dev ;)

Revision history for this message
SirVer (sirver) wrote :

Ooh shit... Jens, I dropped the ball on this and now there are some merge conflicts! Could you look over this branch again and resubmit. I am deeply sorry and I owe you a whisky for that.

Also... have we already opened the bug report for using translated strings in logic or have we not?

review: Needs Fixing
Revision history for this message
Jens Beyer (qcumber-some) wrote :

> Ooh shit... Jens, I dropped the ball on this and now there are some merge
> conflicts! Could you look over this branch again and resubmit. I am deeply
> sorry and I owe you a whisky for that.
>
> Also... have we already opened the bug report for using translated strings in
> logic or have we not?

I did a "manual merge" (read: reimplement) the same directly on trunk. Setting this branch to merged anyway.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'scripting/win_condition_texts.lua'
2--- scripting/win_condition_texts.lua 1970-01-01 00:00:00 +0000
3+++ scripting/win_condition_texts.lua 2012-01-09 00:57:27 +0000
4@@ -0,0 +1,50 @@
5+won_game = {
6+ title = _ "Congratulations!",
7+ body = _ "You have won this game!"
8+}
9+
10+lost_game = {
11+ title = _ "You are defeated!",
12+ body = _ "You have nothing to command left. If you want, you may continue as spectator."
13+}
14+
15+won_game_over = {
16+ title = _ "You won",
17+ body = _"You are the winner!"
18+}
19+
20+lost_game_over = {
21+ title = _ "You lost",
22+ body = _"You've lost this game!"
23+}
24+
25+game_status = {
26+ title = _ "Status",
27+ body = _ "Player overview:"
28+}
29+
30+game_status_woodgnome = {
31+ end_in = _ "The game will end in %i minutes.",
32+ trees = _ "%s has %i trees at the moment.",
33+ overview = _ "Player overview:",
34+ had1 = _ "%s had ",
35+ had2 = _ "%i trees.",
36+ winner1 = _ "The winner is %s ",
37+ winner2 = _ "with %i trees.",
38+ owned = _ "Trees owned"
39+}
40+
41+game_status_collectors = {
42+ title = _ "Status for %s<br>",
43+ total = _ "Total: %i points",
44+ end_in = _ "The game will end in %s.",
45+ points = _ "Points"
46+}
47+
48+game_status_territoral_lord = {
49+ team = _ "Team %i",
50+ other1 = _ "%s owns more than half of the maps area.",
51+ other2 = _ "You still got %i minutes to prevent a victory.",
52+ player1 = _ "You own more than half of the maps area.",
53+ player2 = _ "Keep it for %i more minutes to win the game."
54+}
55\ No newline at end of file
56
57=== modified file 'scripting/win_conditions/00_endless_game.lua'
58--- scripting/win_conditions/00_endless_game.lua 2010-09-12 11:17:13 +0000
59+++ scripting/win_conditions/00_endless_game.lua 2012-01-09 00:57:27 +0000
60@@ -7,6 +7,8 @@
61
62 set_textdomain("win_conditions")
63
64+use("aux", "win_condition_texts")
65+
66 local wc_name = _ "Endless Game"
67 local wc_desc = _"This is an endless game without rules."
68 return {
69@@ -21,9 +23,7 @@
70 -- from the list, send him a defeated message and give him full vision
71 repeat
72 sleep(5000)
73- check_player_defeated(plrs, _ "You are defeated!",
74- _ ("You have nothing to command left. If you want, you may " ..
75- "continue as spectator."))
76+ check_player_defeated(plrs, lost_game.title, lost_game.body)
77 until count_factions(plrs) < 1
78
79 end
80
81=== modified file 'scripting/win_conditions/01_defeat_all.lua'
82--- scripting/win_conditions/01_defeat_all.lua 2010-09-12 11:17:13 +0000
83+++ scripting/win_conditions/01_defeat_all.lua 2012-01-09 00:57:27 +0000
84@@ -7,6 +7,8 @@
85
86 set_textdomain("win_conditions")
87
88+use("aux", "win_condition_texts")
89+
90 local wc_name = _ "Autocrat"
91 local wc_desc = _ "The tribe or team that can defeat all others wins the game!"
92 return {
93@@ -21,15 +23,11 @@
94 -- from the list, send him a defeated message and give him full vision
95 repeat
96 sleep(5000)
97- check_player_defeated(plrs, _ "You are defeated!",
98- _ ("You have nothing to command left. If you want, you may " ..
99- "continue as spectator."))
100+ check_player_defeated(plrs, lost_game.title, lost_game.body)
101 until count_factions(plrs) <= 1
102
103 -- Send congratulations to all remaining players
104- broadcast(plrs,
105- _ "Congratulations!",
106- _ "You have won this game!",
107+ broadcast(plrs, won_game.title, won_game.body,
108 {popup = true}
109 )
110
111
112=== modified file 'scripting/win_conditions/02_collectors.lua'
113--- scripting/win_conditions/02_collectors.lua 2011-11-06 00:06:25 +0000
114+++ scripting/win_conditions/02_collectors.lua 2012-01-09 00:57:27 +0000
115@@ -8,6 +8,8 @@
116
117 set_textdomain("win_conditions")
118
119+use("aux", "win_condition_texts")
120+
121 local wc_name = _ "Collectors"
122 local wc_desc = _ (
123 "You get points for precious wares in your warehouses, the player with " ..
124@@ -87,7 +89,7 @@
125 )
126
127 local points = 0
128- local descr = { _("Status for %s<br>"):format(plr.name) }
129+ local descr = { game_status_collectors.title:format(plr.name) }
130 for idx, ware in ipairs(point_table[plr.tribe_name .. "_order"]) do
131 local value = point_table[plr.tribe_name][ware]
132 local count = 0
133@@ -100,7 +102,7 @@
134 ware, value, count, lpoints
135 )
136 end
137- descr[#descr+1] = _("Total: %i points"):format(points)
138+ descr[#descr+1] = game_status_collectors.total:format(points)
139
140 return points, p(table.concat(descr, "\n"))
141 end
142@@ -115,7 +117,7 @@
143 else
144 time = ("%i minutes"):format(m)
145 end
146- local msg = p(_"The game will end in %s."):format(time)
147+ local msg = p(game_status_collectors.end_in):format(time)
148 msg = msg .. "\n\n"
149
150 for idx, plr in ipairs(plrs) do
151@@ -125,7 +127,7 @@
152 end
153
154 for idx, plr in ipairs(plrs) do
155- plr:send_message(_ "Status", "<rt>" .. msg .. "</rt>")
156+ plr:send_message(game_status.title, "<rt>" .. msg .. "</rt>")
157 end
158 end
159
160@@ -136,15 +138,15 @@
161 end
162 table.sort(points, function(a,b) return a[2] < b[2] end)
163 for i=1,#points-1 do
164- points[i][1]:send_message(_"You lost", _"You've lost this game!")
165+ points[i][1]:send_message(lost_game_over.title, lost_game_over.body)
166 end
167- points[#points][1]:send_message(_"You won!", _"You are the winner!")
168+ points[#points][1]:send_message(won_game_over.title, won_game_over.body)
169 end
170
171 -- Instantiate the hook to calculate points
172 if hooks == nil then hooks = {} end
173 hooks.custom_statistic = {
174- name = _ "Points",
175+ name = game_status_collectors.points,
176 pic = "pics/genstats_points.png",
177 calculator = function(p)
178 local pts = _calc_points(p)
179@@ -176,9 +178,7 @@
180 local runs = 0
181 repeat
182 sleep(5000)
183- check_player_defeated(plrs, _ "You are defeated!",
184- _ ("You have nothing to command left. If you want, you may " ..
185- "continue as spectator."))
186+ check_player_defeated(plrs, lost_game.title, lost_game.body)
187 runs = runs + 1
188 until runs >= 120 -- 120 * 5000ms = 600000 ms = 10 minutes
189 remaining_time = remaining_time - 10
190
191=== modified file 'scripting/win_conditions/03_territorial_lord.lua'
192--- scripting/win_conditions/03_territorial_lord.lua 2010-11-12 14:16:36 +0000
193+++ scripting/win_conditions/03_territorial_lord.lua 2012-01-09 00:57:27 +0000
194@@ -8,6 +8,8 @@
195
196 set_textdomain("win_conditions")
197
198+use("aux", "win_condition_texts")
199+
200 local wc_name = _ "Territorial Lord"
201 local wc_desc = _ (
202 "Each player or team tries to obtain more than half of the maps' " ..
203@@ -126,10 +128,10 @@
204 if teampoints[t] > ( #fields / 2 ) then
205 -- this team owns more than half of the map's area
206 foundcandidate = true
207- if candidateisteam == true and currentcandidate == _("Team %i"):format(t) then
208+ if candidateisteam == true and currentcandidate == game_status_territoral_lord.team:format(t) then
209 remaining_time = remaining_time - 30
210 else
211- currentcandidate = _("Team %i"):format(t)
212+ currentcandidate = game_status_territoral_lord.team:format(t)
213 candidateisteam = true
214 remaining_time = 20 * 60 -- 20 minutes
215 end
216@@ -142,20 +144,20 @@
217 end
218
219 function _send_state()
220- local msg1 = _("%s owns more than half of the maps area."):format(currentcandidate)
221+ local msg1 = game_status_territoral_lord.other1:format(currentcandidate)
222 msg1 = msg1 .. "\n"
223- msg1 = msg1 .. _("You still got %i minutes to prevent a victory."):format(remaining_time / 60)
224+ msg1 = msg1 .. game_status_territoral_lord.other2:format(remaining_time / 60)
225
226- local msg2 = _("You own more than half of the maps area.")
227+ local msg2 = game_status_territoral_lord.player1
228 msg2 = msg2 .. "\n"
229- msg2 = msg2 .. _("Keep it for %i more minutes to win the game."):format(remaining_time / 60)
230+ msg2 = msg2 .. game_status_territoral_lord.player2:format(remaining_time / 60)
231
232 for idx, p in ipairs(plrs) do
233- if candidateisteam and currentcandidate == _("Team %i"):format(p.team)
234+ if candidateisteam and currentcandidate == game_status_territoral_lord.team:format(p.team)
235 or not candidateisteam and currentcandidate == p.name then
236- p:send_message(_ "Status", msg2, {popup = true})
237+ p:send_message(game_status.title, msg2, {popup = true})
238 else
239- p:send_message(_ "Status", msg1, {popup = true})
240+ p:send_message(game_status.title, msg1, {popup = true})
241 end
242 end
243 end
244@@ -163,9 +165,7 @@
245 -- Start a new coroutine that checks for defeated players
246 run(function()
247 sleep(5000)
248- check_player_defeated(plrs, _ "You are defeated!",
249- _ ("You have nothing to command left. If you want, you may " ..
250- "continue as spectator."))
251+ check_player_defeated(plrs, lost_game.title, lost_game.body)
252 end)
253
254 -- here is the main loop!!!
255@@ -180,11 +180,11 @@
256 if remaining_time == 0 then
257 for idx, p in ipairs(plrs) do
258 p.see_all = 1
259- if candidateisteam and currentcandidate == _("Team %i"):format(p.team)
260+ if candidateisteam and currentcandidate == game_status_territoral_lord.team:format(p.team)
261 or not candidateisteam and currentcandidate == p.name then
262- p:send_message(_"You won!", _"You are the winner!", {popup = true})
263+ p:send_message(won_game_over.title, won_game_over.body, {popup = true})
264 else
265- p:send_message(_"You lost", _"You've lost this game!", {popup = true})
266+ p:send_message(lost_game_over.title, lost_game_over.body, {popup = true})
267 end
268 end
269 break
270
271=== modified file 'scripting/win_conditions/04_wood_gnome.lua'
272--- scripting/win_conditions/04_wood_gnome.lua 2011-11-06 00:06:25 +0000
273+++ scripting/win_conditions/04_wood_gnome.lua 2012-01-09 00:57:27 +0000
274@@ -8,6 +8,8 @@
275
276 set_textdomain("win_conditions")
277
278+use("aux", "win_condition_texts")
279+
280 local wc_name = _ "Wood Gnome"
281 local wc_desc = _
282 [[As wood gnome you like big forests, so your task is, to have more trees on
283@@ -76,29 +78,27 @@
284
285 local function _send_state()
286 local playerpoints = _calc_points()
287- local msg = _("The game will end in %i minutes."):format(remaining_time)
288+ local msg = game_status.body:format(remaining_time)
289 msg = msg .. "\n\n"
290- msg = msg .. _ ("Player overview:")
291+ msg = msg .. game_status_woodgnome.end_in:format(remaining_time)
292 for idx,plr in ipairs(plrs) do
293 msg = msg .. "\n"
294- msg = msg .. _ ("%s has %i trees at the moment."):format(plr.name, playerpoints[plr.number])
295+ msg = msg .. game_status_woodgnome.trees:format(plr.name, playerpoints[plr.number])
296 end
297
298- broadcast(plrs, _ "Status", msg)
299+ broadcast(plrs, game_status.title, msg)
300 end
301
302 -- Start a new coroutine that checks for defeated players
303 run(function()
304 sleep(5000)
305- check_player_defeated(plrs, _ "You are defeated!",
306- _ ("You have nothing to command left. If you want, you may " ..
307- "continue as spectator."))
308+ check_player_defeated(plrs, lost_game.title, lost_game.body)
309 end)
310
311 -- Install statistics hook
312 if hooks == nil then hooks = {} end
313 hooks.custom_statistic = {
314- name = _ "Trees owned",
315+ name = game_status_woodgnome.owned,
316 pic = "pics/genstats_trees.png",
317 calculator = function(p)
318 local pts = _calc_points(p)
319@@ -130,23 +130,23 @@
320 table.sort(points, function(a,b) return a[2] < b[2] end)
321
322 local msg = "\n\n"
323- msg = msg .. _ ("Player overview:")
324+ msg = msg .. game_status_woodgnome.overview
325 for idx,plr in ipairs(plrs) do
326 msg = msg .. "\n"
327- msg = msg .. _ ("%s had "):format(plr.name)
328- msg = msg .. _ ("%i trees."):format(playerpoints[plr.number])
329+ msg = msg .. game_status_woodgnome.had1:format(plr.name)
330+ msg = msg .. game_status_woodgnome.had2:format(playerpoints[plr.number])
331 end
332 msg = msg .. "\n\n"
333- msg = msg .. _ ("The winner is %s "):format(points[#points][1].name)
334- msg = msg .. _ ("with %i trees."):format(playerpoints[points[#points][1].number])
335+ msg = msg .. game_status_woodgnome.winner1:format(points[#points][1].name)
336+ msg = msg .. game_status_woodgnome.winner2:format(playerpoints[points[#points][1].number])
337 local privmsg = ""
338 for i=1,#points-1 do
339- privmsg = _ ("You have lost this game!")
340+ privmsg = lost_game_over.body
341 privmsg = privmsg .. msg
342- points[i][1]:send_message(_"You lost!", privmsg, {popup = true})
343+ points[i][1]:send_message(lost_game_over.title, privmsg, {popup = true})
344 end
345- privmsg = _ ("You are the winner of this game!")
346+ privmsg = won_game_over.body
347 privmsg = privmsg .. msg
348- points[#points][1]:send_message(_"You won!", privmsg, {popup = true})
349+ points[#points][1]:send_message(won_game_over.title, privmsg, {popup = true})
350 end
351 }
352
353=== modified file 'scripting/win_conditions/05_endless_game_fogless.lua'
354--- scripting/win_conditions/05_endless_game_fogless.lua 2011-08-21 12:02:42 +0000
355+++ scripting/win_conditions/05_endless_game_fogless.lua 2012-01-09 00:57:27 +0000
356@@ -7,6 +7,8 @@
357
358 set_textdomain("win_conditions")
359
360+use("aux", "win_condition_texts")
361+
362 local wc_name = _ "Endless Game (no fog)"
363 local wc_desc = _"This is an endless game without rules. Fog of war is disabled."
364 return {
365@@ -36,9 +38,7 @@
366 -- from the list, send him a defeated message and give him full vision
367 repeat
368 sleep(5000)
369- check_player_defeated(plrs, _ "You are defeated!",
370- _ ("You have nothing to command left. If you want, you may " ..
371- "continue as spectator."))
372+ check_player_defeated(plrs, lost_game.title, lost_game.body)
373 until count_factions(plrs) < 1
374
375 end

Subscribers

People subscribed via source and target branches

to status/vote changes: