Merge lp:~stdh/widelands/rewrite_wincondition into lp:widelands

Proposed by Steven De Herdt
Status: Work in progress
Proposed branch: lp:~stdh/widelands/rewrite_wincondition
Merge into: lp:widelands
Diff against target: 537 lines (+265/-200)
6 files modified
doc/sphinx/source/conf.py (+2/-2)
scripting/infrastructure.lua (+1/-1)
scripting/table.lua (+23/-0)
scripting/win_condition_functions.lua (+31/-0)
scripting/win_conditions/03_territorial_lord.lua (+207/-196)
src/scripting/lua_bases.cc (+1/-1)
To merge this branch: bzr merge lp:~stdh/widelands/rewrite_wincondition
Reviewer Review Type Date Requested Status
SirVer Needs Fixing
Review via email: mp+178461@code.launchpad.net

Description of the change

A rewrite of the Territorial Lord win condition, imho clearer with better abstractions. It should also be a bit more straightforward to adapt to a land-ownership-change hook, should that materialize.
I hope the structure of the code is clear as is, otherwise I'd like to add some comments.

Remaining questions, on top of those posed in code comments:
*What does wc_version mean & should I provide compatibility code for old savegames?
*The code to check for defeated players was broken in that it only checks once. I didn't touch it, some other win conditions use the same faulty code and it should be adressed more globally, I feel. Bonus question: should other players be noticed when one of their friends/enemies is defeated?
*I noticed that "not rawequal(wl.Game().players[2],wl.Game().players[2])", while the two are considered equal by the "==" operator. This means a Player cannot be used as a key in a table, which is slightly annoying and should be mentioned in the docs if not outright fixed.
*After I found this out, I used wl.game.Player.name as a key. I hope that's a unique property...
*Code style and formatting OK? A quick search didn't turn up information about any preference in the project.
*I must have forgotten what should come here, maybe later...

And a known bug: it doesn't survive save-load. More specifically, the main loop seems to be restarted so that it loses connection to the last thread it started. In specific conditions it is possible to win twice! I have a script more or less ready to demonstrate that, but it seemed a bit silly to put that in this branch...

To post a comment you must log in.
Revision history for this message
Steven De Herdt (stdh) wrote :

Oh yes, that detail I forgot: copyright. I pasted the GPL2+ boilerplate at the top, but I haven't completed the year range(s).
Also, do I have to officialy claim that the code I contribute is licensed to Widelands, and hence the world, under GPL2+? Or is this the implicit understanding?

Revision history for this message
SirVer (sirver) wrote :

> *What does wc_version mean & should I provide compatibility code for old savegames?
I have no idea why it is there actually, it is nowhere used in the code so you should be able to just kill it.

> *The code to check for defeated players was broken in that it only checks once. I didn't touch it, some other win conditions use the same faulty code and it should be adressed more globally, I feel.
I agree - are you doing this? :)

> Bonus question: should other players be noticed when one of their friends/enemies is defeated?
This is certainly a design question - I do not think it is necessary. The players can chat and communicate this and the messages are more about you.

> *I noticed that "not rawequal(wl.Game().players[2],wl.Game().players[2])", while the two are considered equal by the "==" operator. This means a Player cannot be used as a key in a table, which is slightly annoying and should be mentioned in the docs if not outright fixed.
How can this be fixed though? There is a new Lua table with the same metatable generated for each time you access the player. I have no idea what property they must implement to compare equal.

> *After I found this out, I used wl.game.Player.name as a key. I hope that's a unique property...
We do not explicitly enforce this imho. Player.number is absolutely unique though, you should use this. Note that they are not necessarily monotonic (i.e. player 3 could not be in the game while player 4 is).

> *Code style and formatting OK? A quick search didn't turn up information about any preference in the project.
We have none for Lua right now. This should be fixed though - but I would much rather piggy back on some style guide that a third party owns. Do you have any suggestions?

> I pasted the GPL2+ boilerplate at
> the top, but I haven't completed the year range(s).
Please do so.

> Also, do I have to officialy claim that the code I contribute is licensed to
> Widelands, and hence the world, under GPL2+? Or is this the implicit
> understanding?
I am not a lawyer. We do it rather more often than not often enough, so I would appreciate if you could keep it around.

Would you mind open a bug report for this Lua restart bug you see? It seems rather serious and should be tracked down?

Now for the review:
- array_ind_max -- please do not use abbreviations.
- +local wc_version = 3 --stdh: increased by one, right? -- I much rather see it removed. Could you try that?
- can walkable fields be swimmable? -- I do not think so.
- can swimmable fields have immovables? -- I do not think so either, but I am unsure with the portdock.
- --stdh: is this f sometimes nil? -- No, the functions throws an error if you give an invalid coordinate.
- --stdh: points are awarded for player land, disregarding teams. -- I think so.
- --stdh: TODO: fix 'cause only runs once -- What do you mean by this? there should be an ifinite loop in the function. and this coroutine should be saved and run again after load.
- --stdh: why is that important/pertinent? I do not think it is important at all, just so it is in the same ballpark from sampling time.

Otherwise this looks pretty good to me. Thanks for working on this.

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

>I have no idea why it is there actually, it is nowhere used in the code so you should be able to just kill it.

In the end game screen, some value of the string returned by win conditions are parsed. It may be useful to keep this wc_name and versions around.

>should other players be noticed when one of their friends/enemies is defeated?

It is also related to end game screen. The game will be notified as soon as a player loose, we might send a message or log it in the chat from there. So I dont think anything should be done in the scripts.

Revision history for this message
cghislai (charlyghislain) wrote :

Also, you could report some results when declaring a player defeated/victorious.
For instance, to pass land owned in addition, use

make_extra_data(wv, wc_name, wc_version, {land_owned=value})

where land_owned is any string you want. It would be nice to comment it in the header along with wc_name or so
-- ver 4: land_owned key to report land owned as percentages

so that we can update the game end screen accordingly.

6697. By Steven De Herdt

Adress some review comments, add pictures to Sphinx docs (second try).

6698. By Steven De Herdt

Merge trunk. With game end screen!

Revision history for this message
SirVer (sirver) wrote :

Steven, I set this to work in progress again as it seems you are still actively improving it. If you feel it is ready for another review, just ping us here and set to ready for merge again.

Unmerged revisions

6698. By Steven De Herdt

Merge trunk. With game end screen!

6697. By Steven De Herdt

Adress some review comments, add pictures to Sphinx docs (second try).

6696. By Steven De Herdt

First version of rewrite Territorial Lord.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/sphinx/source/conf.py'
2--- doc/sphinx/source/conf.py 2012-06-15 20:29:49 +0000
3+++ doc/sphinx/source/conf.py 2013-08-09 15:55:29 +0000
4@@ -110,12 +110,12 @@
5
6 # The name of an image file (relative to this directory) to place at the top
7 # of the sidebar.
8-#html_logo = None
9+html_logo = '../../../pics/wl-ico-128.png'
10
11 # The name of an image file (within the static path) to use as favicon of the
12 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
13 # pixels large.
14-#html_favicon = None
15+html_favicon = '../../../pics/wl-ico-16.png'
16
17 # Add any paths that contain custom static files (such as style sheets) here,
18 # relative to this directory. They are copied after the builtin static files,
19
20=== modified file 'scripting/infrastructure.lua'
21--- scripting/infrastructure.lua 2010-09-22 17:50:53 +0000
22+++ scripting/infrastructure.lua 2013-08-09 15:55:29 +0000
23@@ -64,7 +64,7 @@
24 --
25 -- prefilled_buildings(wl.Game().players[1],
26 -- {"sentry", 57, 9}, -- Sentry completely full with soldiers
27--- {"sentry", 57, 9, soldier={[{0,0,0,0}]=1}}, -- Sentry with one soldier
28+-- {"sentry", 57, 9, soldiers={[{0,0,0,0}]=1}}, -- Sentry with one soldier
29 -- {"bakery", 55, 20, wares = {wheat=6, water=6}}, -- bakery with wares and workers
30 -- {"well", 52, 30}, -- a well with workers
31 -- )
32
33=== modified file 'scripting/table.lua'
34--- scripting/table.lua 2010-09-25 19:34:01 +0000
35+++ scripting/table.lua 2013-08-09 15:55:29 +0000
36@@ -41,3 +41,26 @@
37 return rv
38 end
39
40+-- RST
41+-- .. function:: array_index_of_maximum(a)
42+--
43+-- Finds the index of the greatest value in the given array.
44+--
45+-- :arg a: An array of sortables (numbers, strings, ...) which are
46+-- comparable between themselves.
47+-- :type a: :class:`array`
48+--
49+-- :returns: The index of the greatest value. If this value occurs multiple
50+-- times: the index of the last occurrence.
51+function array_index_of_maximum(a)
52+ max = -math.huge
53+ maxi = 0
54+ for k,v in ipairs(a) do
55+ if v >= max then
56+ max = v
57+ maxi = k
58+ end
59+ end
60+ return maxi
61+end
62+
63
64=== modified file 'scripting/win_condition_functions.lua'
65--- scripting/win_condition_functions.lua 2013-08-07 16:58:48 +0000
66+++ scripting/win_condition_functions.lua 2013-08-09 15:55:29 +0000
67@@ -96,6 +96,37 @@
68 end
69
70 -- RST
71+-- .. function:: get_factions(plrs)
72+--
73+-- Calculates factions so that each given player is in exactly one faction,
74+-- and each faction contains one team, or teamless player.
75+--
76+-- :arg plrs: only these Players (array) are considered
77+-- :returns: an array with all factions in the game, a faction being an
78+-- array of the Players in it
79+function get_factions(plrs)
80+ local factions = {}
81+ for k,v in pairs(plrs) do
82+ if v.team == 0 then
83+ factions[#factions+1] = {v}
84+ else
85+ local gotteam = false --Overbodig?
86+ for fk, fv in pairs(factions) do
87+ if fv[1].team == v.team then
88+ fv[#fv+1] = v
89+ gotteam = true
90+ break
91+ end
92+ end
93+ if not gotteam then
94+ factions[#factions+1] = {v}
95+ end
96+ end
97+ end
98+ return factions
99+end
100+
101+-- RST
102 -- .. function:: broadcast(plrs, header, msg[, options])
103 --
104 -- broadcast a message to all players using
105
106=== modified file 'scripting/win_conditions/03_territorial_lord.lua'
107--- scripting/win_conditions/03_territorial_lord.lua 2013-07-26 15:57:34 +0000
108+++ scripting/win_conditions/03_territorial_lord.lua 2013-08-09 15:55:29 +0000
109@@ -1,208 +1,219 @@
110+-- Copyright (C) 2010, 2012-2013 by the Widelands Development Team
111+--
112+-- This program is free software; you can redistribute it and/or
113+-- modify it under the terms of the GNU General Public License
114+-- as published by the Free Software Foundation; either version 2
115+-- of the License, or (at your option) any later version.
116+--
117+-- This program is distributed in the hope that it will be useful,
118+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
119+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
120+-- GNU General Public License for more details.
121+--
122+-- You should have received a copy of the GNU General Public License
123+-- along with this program; if not, write to the Free Software
124+-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
125+-- 02110-1301, USA.
126+
127 -- =======================================================================
128 -- Territorial Lord Win condition
129 -- =======================================================================
130
131-use("aux", "coroutine") -- for sleep
132+--Assumptions:
133+-- *Land doesn't change, like it does in Atlantean campaign.
134+-- *No falling below the 50% threshold and exceeding it again
135+-- in one sample period.
136+
137+set_textdomain("win_conditions")
138+
139+use("aux", "coroutine")
140 use("aux", "table")
141 use("aux", "win_condition_functions")
142-
143-set_textdomain("win_conditions")
144-
145 use("aux", "win_condition_texts")
146
147-local wc_name = _ "Territorial Lord"
148-local wc_version = 2
149-local wc_desc = _ (
150- "Each player or team tries to obtain more than half of the maps' " ..
151- "area. The winner will be the player or the team that is able to keep " ..
152- "that area for at least 20 minutes."
153-)
154+local wc_name = _("Territorial Lord")
155+local wc_version = 3 --stdh: increased by one, right?
156+local wc_desc = _(
157+[[Each player or team tries to obtain more than half of the maps' area. The
158+winner will be the player or the team that is able to keep that area for at
159+least 20 minutes.]] )
160+
161+-- Get an array of all valueable fields of the map. A field is valuable if it
162+-- is either walkable or has an immovable. The editor disallows placing
163+-- immovables on dead and acid fields.
164+--TODO: not tested for equivalency with old TLord
165+local get_valfields = function()
166+ local valfields = {}
167+ local map = wl.Game().map
168+ for x=0,map.width-1 do
169+ for y=0,map.height-1 do
170+ local f = map:get_field(x,y)
171+ if (f:has_caps("walkable") or f.immovable) then
172+ valfields[#valfields+1] = f
173+ end
174+ end
175+ end
176+ return valfields
177+end
178+
179+-- Returns array with the number of fields each player owns, using
180+-- corresponding keys of 'players'. Only given fields and players
181+-- (both arrays) are considered.
182+local land_per_player = function(fields, players)
183+ local lpp = {}
184+ local plind = {} --player.number:index map
185+ for k, pl in ipairs(players) do
186+ lpp[k] = 0
187+ plind[pl.number] = k
188+ end
189+ for k, field in ipairs(fields) do
190+ local owner = field.owner
191+ if owner then
192+ local onumber = plind[owner.number]
193+ if not onumber then break end
194+ lpp[onumber] = lpp[onumber] + 1
195+ end
196+ end
197+ return lpp
198+end
199+
200+-- Returns array with the number of fields each faction owns, using the same
201+-- keys as the input 'factions'. Only given fields and factions (such as
202+-- returned by get_factions) are considered.
203+local land_per_faction = function(fields, factions)
204+ local lpf = {}
205+ local plfind = {} --player.number:faction_index map
206+ local players = {}
207+ for fack, facv in ipairs(factions) do
208+ lpf[fack] = 0
209+ for plk, plv in ipairs(facv) do
210+ plfind[plv.number] = fack
211+ players[#players+1] = plv
212+ end
213+ end
214+ for plind, pllandsize in ipairs(land_per_player(fields, players)) do
215+ local facind = plfind[players[plind].number]
216+ lpf[facind] = lpf[facind] + pllandsize
217+ end
218+ return lpf
219+end
220+
221+-- Function which performs the countdown from when one faction reaches 50% land
222+-- 'till win. Gives messages at 5 min. interval and upon win. When 20 minutes
223+-- have elapsed, finalizes the game: sets map visible for everyone, sends
224+-- appropriate won/lost messages and report_results to the metaserver.
225+-- Set proceed[1] (call by ref) to false to abort this procedure.
226+local win_countdown = function(factions, candfaci, proceed)
227+ local candstr
228+ if #factions[candfaci] > 1 then
229+ local teamnr = factions[candfaci][2].team
230+ candstr = game_status_territoral_lord.team:format(teamnr)
231+ else
232+ candstr = factions[candfaci][1].name
233+ end
234+ local msg1 = game_status_territoral_lord.other1:format(candstr) .. "\n" ..
235+ game_status_territoral_lord.other2
236+ local msg2 = game_status_territoral_lord.player1 .. "\n" ..
237+ game_status_territoral_lord.player2
238+ for timetogo = 20,5,-5 do --send status messages at 20, 15, 10 and 5 min
239+ if not proceed[1] then return end
240+ for faci, facv in ipairs(factions) do
241+ if faci == candfaci then
242+ for wi, wv in ipairs(facv) do
243+ wv:send_message(game_status.title, msg2:format(timetogo),
244+ {popup = true})
245+ end
246+ else
247+ for li, lv in ipairs(facv) do
248+ lv:send_message(game_status.title, msg1:format(timetogo),
249+ {popup = true})
250+ end
251+ end
252+ end
253+ sleep(5*60*1000) --5 minutes
254+ end
255+ if not proceed[1] then return end
256+ --We have a winner:
257+ local plrs = wl.Game().players
258+ local lpp = land_per_player(get_valfields(), plrs)
259+ local lppn = {} --player.number:land map
260+ for pli, plv in ipairs(plrs) do
261+ lppn[plv.number] = lpp[pli]
262+ end
263+ for faci, facv in ipairs(factions) do
264+ if faci == candfaci then
265+ for wi, wv in ipairs(facv) do
266+ wv.see_all = 1
267+ wv:send_message(won_game_over.title, won_game_over.body)
268+ -- Points are awarded for player land, disregarding teams:
269+ local score = {score = lppn[wv.number]}
270+ local extradata = make_extra_data(wv, wc_name, wc_version, score)
271+ wl.game.report_result(wv, 1, extradata)
272+ end
273+ else
274+ for li, lv in ipairs(facv) do
275+ lv.see_all = 1
276+ lv:send_message(lost_game_over.title, lost_game_over.body)
277+ local score = {score = lppn[lv.number]}
278+ local extradata = make_extra_data(lv, wc_name, wc_version, score)
279+ wl.game.report_result(lv, 0, extradata)
280+ end
281+ end
282+ end
283+ proceed[1] = "won"
284+end
285+
286+-- Initiates win_countdown and returns a 'proceed' handle.
287+local start_win_countdown = function(factions, candfaci)
288+ local proceed = {true}
289+ run(win_countdown, factions, candfaci, proceed)
290+ return proceed
291+end
292+
293+
294+local wc_func = function()
295+ local plrs = wl.Game().players
296+ local factions = get_factions(plrs)
297+ local fields = get_valfields()
298+ local reqnumfields = #fields/2
299+
300+ broadcast(plrs, wc_name, wc_desc)
301+
302+ -- Start a new coroutine that checks for defeated players
303+ --stdh: TODO: fix 'cause only runs once
304+ run(function()
305+ sleep(5000)
306+ check_player_defeated(plrs, lost_game.title, lost_game.body,
307+ wc_name, wc_version)
308+ end)
309+
310+ local candfac = nil --candidate faction
311+ local proceed = {false} --whether to proceed the win_countdown
312+
313+ -- Main loop:
314+ while true do
315+ sleep(15000) --15 seconds == STATISTICS_SAMPLE_TIME / 2
316+ lpf = land_per_faction(fields, factions)
317+ local maxf = array_index_of_maximum(lpf) --faction owning the most land
318+ if lpf[maxf] >= reqnumfields then
319+ if not candfac or maxf ~= candfac then --new candidate
320+ proceed[1] = false
321+ candfac = maxf
322+ proceed = start_win_countdown(factions, maxf)
323+ else --same candidate
324+ if proceed[1] == "won" then --game over
325+ break
326+ end
327+ end
328+ else --no candidate
329+ candfac = nil
330+ proceed[1] = false
331+ end
332+ end
333+end
334+
335 return {
336 name = wc_name,
337 description = wc_desc,
338- func = function()
339-
340- -- Get all valueable fields of the map
341- local fields = {}
342- local map = wl.Game().map
343- for x=0,map.width-1 do
344- for y=0,map.height-1 do
345- local f = map:get_field(x,y)
346- if f then
347- -- add this field to the list as long as it has not movecaps swim
348- if not f:has_caps("swimmable") then
349- if f:has_caps("walkable") then
350- fields[#fields+1] = f
351- else
352- -- editor disallows placement of immovables on dead and acid fields
353- if f.immovable then
354- fields[#fields+1] = f
355- end
356- end
357- end
358- end
359- end
360- end
361-
362- -- these variables will be used once a player or team owns more than half
363- -- of the map's area
364- local currentcandidate = "" -- Name of Team or Player
365- local candidateisteam = false
366- local remaining_time = 10 -- (dummy) -- time in secs, if == 0 -> victory
367-
368- -- Find all valid players
369- local plrs = wl.Game().players
370-
371- -- send a message with the game type to all players
372- broadcast(plrs, wc_name, wc_desc)
373-
374- -- Find all valid teams
375- local teamnumbers = {} -- array with team numbers
376- for idx,p in ipairs(plrs) do
377- local team = p.team
378- if team > 0 then
379- local found = false
380- for idy,t in ipairs(teamnumbers) do
381- if t == team then
382- found = true
383- break
384- end
385- end
386- if not found then
387- teamnumbers[#teamnumbers+1] = team
388- end
389- end
390- end
391-
392- local _landsizes = {}
393- local function _calc_current_landsizes()
394- -- init the landsizes for each player
395- for idx,plr in ipairs(plrs) do
396- _landsizes[plr.number] = 0
397- end
398-
399- for idx,f in ipairs(fields) do
400- -- check if field is owned by a player
401- local o = f.owner
402- if o then
403- local n = o.number
404- _landsizes[n] = _landsizes[n] + 1
405- end
406- end
407- end
408-
409- function _calc_points()
410- local teampoints = {} -- points of teams
411- local maxplayerpoints = 0 -- the highest points of a player without team
412- local maxpointsplayer = 0 -- the player
413- local foundcandidate = false
414-
415- _calc_current_landsizes()
416-
417- for idx, p in ipairs(plrs) do
418- local team = p.team
419- if team == 0 then
420- if maxplayerpoints < _landsizes[p.number] then
421- maxplayerpoints = _landsizes[p.number]
422- maxpointsplayer = p
423- end
424- else
425- if not teampoints[team] then -- init the value
426- teampoints[team] = 0
427- end
428- teampoints[team] = teampoints[team] + _landsizes[p.number]
429- end
430- end
431-
432- if maxplayerpoints > ( #fields / 2 ) then
433- -- player owns more than half of the map's area
434- foundcandidate = true
435- if candidateisteam == false and currentcandidate == maxpointsplayer.name then
436- remaining_time = remaining_time - 30
437- else
438- currentcandidate = maxpointsplayer.name
439- candidateisteam = false
440- remaining_time = 20 * 60 -- 20 minutes
441- end
442- else
443- for idx, t in ipairs(teamnumbers) do
444- if teampoints[t] > ( #fields / 2 ) then
445- -- this team owns more than half of the map's area
446- foundcandidate = true
447- if candidateisteam == true and currentcandidate == t then
448- remaining_time = remaining_time - 30
449- else
450- currentcandidate = t
451- candidateisteam = true
452- remaining_time = 20 * 60 -- 20 minutes
453- end
454- end
455- end
456- end
457- if not foundcandidate then
458- currentcandidate = ""
459- candidateisteam = false
460- remaining_time = 10
461- end
462- end
463-
464- function _send_state()
465- local msg1 = game_status_territoral_lord.other1:format(currentcandidate)
466- if candidateisteam then
467- local teamstr = game_status_territoral_lord.team:format(currentcandidate)
468- msg1 = game_status_territoral_lord.other1:format(teamstr)
469- end
470- msg1 = msg1 .. "\n"
471- msg1 = msg1 .. game_status_territoral_lord.other2:format(remaining_time / 60)
472-
473- local msg2 = game_status_territoral_lord.player1
474- msg2 = msg2 .. "\n"
475- msg2 = msg2 .. game_status_territoral_lord.player2:format(remaining_time / 60)
476-
477- for idx, p in ipairs(plrs) do
478- if candidateisteam and currentcandidate == p.team
479- or not candidateisteam and currentcandidate == p.name then
480- p:send_message(game_status.title, msg2)
481- else
482- p:send_message(game_status.title, msg1)
483- end
484- end
485- end
486-
487- -- Start a new coroutine that checks for defeated players
488- run(function()
489- sleep(5000)
490- check_player_defeated(plrs, lost_game.title, lost_game.body, wc_name, wc_version)
491- end)
492-
493- -- here is the main loop!!!
494- while true do
495- -- Sleep 30 seconds == STATISTICS_SAMPLE_TIME
496- sleep(30000)
497-
498- -- Check if a player or team is a candidate and update variables
499- _calc_points()
500-
501- -- Do this stuff, if the game is over
502- if remaining_time == 0 then
503- for idx, p in ipairs(plrs) do
504- p.see_all = 1
505- if candidateisteam and currentcandidate == p.team
506- or not candidateisteam and currentcandidate == p.name then
507- p:send_message(won_game_over.title, won_game_over.body)
508- wl.game.report_result(p, 1, make_extra_data(p, wc_name, wc_version, {score=_landsizes[p.number]}))
509- else
510- p:send_message(lost_game_over.title, lost_game_over.body)
511- wl.game.report_result(p, 0, make_extra_data(p, wc_name, wc_version, {score=_landsizes[p.number]}))
512- end
513- end
514- break
515- end
516-
517- -- If there is a candidate, check whether we have to send an update
518- if remaining_time % 300 == 0 then -- every 5 minutes (5 * 60 )
519- _send_state()
520- end
521- end
522- end
523+ func = wc_func
524 }
525
526=== modified file 'src/scripting/lua_bases.cc'
527--- src/scripting/lua_bases.cc 2013-08-01 03:20:46 +0000
528+++ src/scripting/lua_bases.cc 2013-08-09 15:55:29 +0000
529@@ -185,7 +185,7 @@
530 /* RST
531 .. attribute:: number
532
533- (RO) The number of this Player.
534+ (RO) The number of the slot this Player is assigned to.
535 */
536 int L_PlayerBase::get_number(lua_State * L) {
537 lua_pushuint32(L, m_pl);

Subscribers

People subscribed via source and target branches

to status/vote changes: