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

Proposed by Toni Förster
Status: Merged
Merged at revision: 8964
Proposed branch: lp:~widelands-dev/widelands/collectors_notification
Merge into: lp:widelands
Diff against target: 349 lines (+148/-113)
3 files modified
data/scripting/win_conditions/collectors.lua (+30/-51)
data/scripting/win_conditions/win_condition_functions.lua (+58/-0)
data/scripting/win_conditions/wood_gnome.lua (+60/-62)
To merge this branch: bzr merge lp:~widelands-dev/widelands/collectors_notification
Reviewer Review Type Date Requested Status
Notabilis diff, testing Approve
Review via email: mp+361334@code.launchpad.net

Commit message

- unified some functions for wood_gnome and collectors
- removed duplicated code and moved it to win_condition_functions
- notify only every hour, 10 minutes in the last 30
- move _game_over function out of the main loop.
- don't show points when game ended by military defeat
- main loop ends when time is over or only one faction is left
- check every second for defeated players

Description of the change

Currently notifications are sent every 10 minutes, which is quite annoying. With this change it only sends them every 30 minutes and during the last 30 minutes every 5. Also, if a faction has been defeated the game ends immediately.

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

Continuous integration builds have changed state:

Travis build 4372. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/473313790.
Appveyor build 4165. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_collectors_notification-4165.

8956. By Toni Förster

- Move _game_over function out of the main loop.
- Don't show points when game ended by by military defeat
- main loop ends when time is over or only one faction is left
- Check every 5 seconds for defeated players

8957. By Toni Förster

remove erroneous whitespace

8958. By Toni Förster

- check for defeated player every second
- status notifications are in a separate coroutine
- only popup when 30 minutes game-time are left

8959. By Toni Förster

add missing closing parenthesis

8960. By Toni Förster

- unified some functions for wood_gnome and collectors
- removed duplicated code and moved it to win_condition_functions
- in territory immovables are also counted

8961. By Toni Förster

mistake: reverted remaining_time=10 in territorial

8962. By Toni Förster

revert changes in territorial_fuctions

Revision history for this message
Notabilis (notabilis27) wrote :

Code is looking good and it seems to work as intended. A few possible improvements are in the diff.

I assume it is intentional that there is no message on game start?
In the commit/merge message of this branch you could add that wood gnome is also affected.

review: Approve (diff, testing)
Revision history for this message
Toni Förster (stonerl) wrote :

I'm going to add more info to the notification_remaining_time() function.

Since I wanted this to be in place for build 20, I'm going to address count_factions() later. I'd like to unify more code, were possible. But this would also involve some changes to strings.

8963. By Toni Förster

added more info to the notification_remaining_time() function

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4390. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/477473643.
Appveyor build 4181. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_collectors_notification-4181.

8964. By Toni Förster

merged trunk

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4398. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/478872308.
Appveyor build 4189. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_collectors_notification-4189.

Revision history for this message
Notabilis (notabilis27) wrote :

Not sure whether you are waiting for me with this. As far as I am concerned, your (new) changes are fine and this can be merged.

Revision history for this message
Toni Förster (stonerl) wrote :

Well then :-)

@bunnybot merge

8965. By Toni Förster

merged trunk

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 4426. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/490531894.
Appveyor build 4214. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_collectors_notification-4214.

Revision history for this message
bunnybot (widelandsofficial) wrote :

Refusing to merge, since Travis is not green. Use @bunnybot merge force for merging anyways.

Travis build 4426. State: failed. Details: https://travis-ci.org/widelands/widelands/builds/490531894.

Revision history for this message
Toni Förster (stonerl) wrote :

Just a Homebrew download issue.

@bunnybot merge force

Revision history for this message
GunChleoc (gunchleoc) wrote :

I have wanted this unified for a long time. Thanks for taking it on!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/scripting/win_conditions/collectors.lua'
2--- data/scripting/win_conditions/collectors.lua 2019-01-26 15:14:57 +0000
3+++ data/scripting/win_conditions/collectors.lua 2019-02-04 21:28:15 +0000
4@@ -28,7 +28,11 @@
5
6 -- set the objective with the game type for all players
7 broadcast_objective("win_condition", wc_descname, wc_desc)
8-
9+
10+ -- set the maximum game time of 4 hours
11+ local max_time = 4 * 60
12+
13+ local game = wl.Game()
14 local plrs = wl.Game().players
15 local teams = {}
16 for idx,plr in ipairs(plrs) do
17@@ -147,33 +151,9 @@
18 return team_points, descr
19 end
20
21-
22 -- Send all players the momentary game state
23- local function _send_state(remaining_time, plrs)
24- local msg = vspace(8)
25- set_textdomain("win_conditions")
26- if remaining_time <= 0 then
27- msg = p(_"The game has ended.") .. vspace(8)
28- else
29- local h = math.floor(remaining_time / 60)
30- local m = remaining_time % 60
31- -- TRANSLATORS: Context: 'The game will end in (2 hours and) 30 minutes.'
32- local time = ""
33- if m > 0 then
34- time = (ngettext("%i minute", "%i minutes", m)):format(m)
35- end
36- if h > 0 then
37- if m > 0 then
38- -- TRANSLATORS: Context: 'The game will end in 2 hours and 30 minutes.'
39- time = (ngettext("%1% hour and %2%", "%1% hours and %2%", h)):bformat(h, time)
40- else
41- -- TRANSLATORS: Context: 'The game will end in 2 hours.'
42- time = (ngettext("%1% hour", "%1% hours", h)):bformat(h)
43- end
44- end
45- -- TRANSLATORS: Context: 'The game will end in 2 hours and 30 minutes.'
46- msg = p(_"The game will end in %s."):format(time) .. vspace(8)
47- end
48+ local function _send_state(remaining_time, plrs, show_popup)
49+ local msg = format_remaining_time(remaining_time) .. vspace(8) .. game_status.body
50
51 -- Points for players without team
52 for idx, plr in ipairs(plrs) do
53@@ -191,7 +171,7 @@
54 msg = msg .. vspace(8) .. message
55 end
56
57- broadcast(plrs, game_status.title, msg, {popup = true})
58+ broadcast(plrs, game_status.title, msg, {popup = show_popup})
59 end
60
61 local function _game_over(plrs)
62@@ -219,10 +199,14 @@
63 lost_or_won = 1
64 player:send_message(won_game_over.title, won_game_over.body)
65 end
66- if (player.team == 0) then
67- wl.game.report_result(player, lost_or_won, make_extra_data(player, wc_descname, wc_version, {score=info[2]}))
68+ if (count_factions(plrs) > 1) then
69+ if (player.team == 0) then
70+ wl.game.report_result(player, lost_or_won, make_extra_data(player, wc_descname, wc_version, {score=info[2]}))
71+ else
72+ wl.game.report_result(player, lost_or_won, make_extra_data(player, wc_descname, wc_version, {score=info[3], team_score=info[2]}))
73+ end
74 else
75- wl.game.report_result(player, lost_or_won, make_extra_data(player, wc_descname, wc_version, {score=info[3], team_score=info[2]}))
76+ wl.game.report_result(player, lost_or_won)
77 end
78 end
79 end
80@@ -237,27 +221,22 @@
81 end,
82 }
83
84- sleep(1000)
85-
86- local remaining_time = 60 * 4
87-
88- -- Endless loop
89- while true do
90- _send_state(remaining_time, plrs)
91-
92- -- Game ended?
93- if remaining_time <= 0 then
94- _game_over(plrs)
95- break
96+ -- Start a new coroutine that triggers status notifications.
97+ run(function()
98+ local remaining_time = max_time
99+ while game.time <= ((max_time - 5) * 60 * 1000) and count_factions(plrs) > 1 do
100+ remaining_time, show_popup = notification_remaining_time(max_time, remaining_time)
101+ _send_state(remaining_time, plrs, show_popup)
102 end
103-
104- local runs = 0
105- repeat
106- sleep(5000)
107- check_player_defeated(plrs, lost_game.title, lost_game.body, wc_descname, wc_version)
108- runs = runs + 1
109- until runs >= 120 -- 120 * 5000ms = 600000 ms = 10 minutes
110- remaining_time = remaining_time - 10
111+ end)
112+
113+ -- main loop checks for defeated players
114+ while game.time < (max_time * 60 * 1000) and count_factions(plrs) > 1 do
115+ sleep(1000)
116+ check_player_defeated(plrs, lost_game.title, lost_game.body, wc_descname, wc_version)
117 end
118+
119+ -- Game has ended
120+ _game_over(plrs)
121 end
122 }
123
124=== modified file 'data/scripting/win_conditions/win_condition_functions.lua'
125--- data/scripting/win_conditions/win_condition_functions.lua 2019-01-27 15:18:27 +0000
126+++ data/scripting/win_conditions/win_condition_functions.lua 2019-02-04 21:28:15 +0000
127@@ -237,3 +237,61 @@
128 table.sort(ranked_players_and_teams, function(a,b) return a["points"] > b["points"] end)
129 return ranked_players_and_teams
130 end
131+
132+-- RST
133+-- .. function:: format_remaining_time(remaining_time)
134+--
135+-- return a message that contains the remaining game time
136+-- to be used when sending status meassages
137+--
138+-- :arg remaining_time: The remaining game time in minutes
139+function format_remaining_time(remaining_time)
140+ local h = 0
141+ local m = 60
142+ local time = ""
143+ set_textdomain("win_conditions")
144+
145+ if (remaining_time ~= 60) then
146+ h = math.floor(remaining_time / 60)
147+ m = remaining_time % 60
148+ end
149+
150+ if ((h > 0) and (m > 0)) then
151+ -- TRANSLATORS: Context: 'The game will end in 2 hours and 30 minutes.'
152+ time = (ngettext("%1% hour and %2% minutes", "%1% hours and %2% minutes", h, m)):bformat(h, m)
153+ elseif m > 0 then
154+ -- TRANSLATORS: Context: 'The game will end in 30 minutes.'
155+ time = (ngettext("%i minute", "%i minutes", m)):format(m)
156+ else
157+ -- TRANSLATORS: Context: 'The game will end in 2 hours.'
158+ time = (ngettext("%1% hour", "%1% hours", h)):bformat(h)
159+ end
160+ -- TRANSLATORS: Context: 'The game will end in (2 hours and) 30 minutes.'
161+ return p(_"The game will end in %s."):format(time)
162+end
163+
164+-- RST
165+-- .. function:: notification_remaining_time(max_time)
166+--
167+-- Calculate the remaining game time for notifications.
168+-- Should only be called within a coroutine, because the routine gets blocked.
169+-- Returns the remaining time and whether the notification should popup.
170+--
171+-- To be used when sending status messages.
172+-- Status messages are to be send every 30 minutes and every 5 during the last 30 minutes,
173+-- the message window pops up ever hour, 30, 20 & 10 minutes before the game ends.
174+--
175+-- :arg max_time: The time maximum game time in minutes
176+function notification_remaining_time(max_time, remaining_time)
177+ local show_popup = false
178+ if (wl.Game().time < ((max_time - 30) * 60 * 1000)) then --
179+ wake_me(wl.Game().time + (30 * 60 * 1000)) -- 30 minutes
180+ remaining_time = remaining_time - 30
181+ if (remaining_time % 60 == 0) or (remaining_time == 30) then show_popup = true end
182+ else
183+ wake_me(wl.Game().time + (300 * 1000)) --5 Minutes
184+ remaining_time = remaining_time - 5
185+ if ((remaining_time ~= 0) and (remaining_time % 10 == 0)) then show_popup = true end
186+ end
187+ return remaining_time, show_popup
188+end
189\ No newline at end of file
190
191=== modified file 'data/scripting/win_conditions/wood_gnome.lua'
192--- data/scripting/win_conditions/wood_gnome.lua 2017-05-12 11:37:17 +0000
193+++ data/scripting/win_conditions/wood_gnome.lua 2019-02-04 21:28:15 +0000
194@@ -25,12 +25,14 @@
195 description = wc_desc,
196 func = function()
197 local plrs = wl.Game().players
198+ local game = wl.Game()
199+
200+ -- set the maximum game time of 4 hours
201+ local max_time = 4 * 60
202
203 -- set the objective with the game type for all players
204 broadcast_objective("win_condition", wc_descname, wc_desc)
205
206- local remaining_time = 4 * 60 -- 4 hours
207-
208 -- Get all valueable fields of the map
209 local fields = {}
210 local map = wl.Game().map
211@@ -86,28 +88,54 @@
212 return _plrpoints
213 end
214
215- local function _send_state()
216- set_textdomain("win_conditions")
217+ local function _send_state(remaining_time, plrs, show_popup)
218 local playerpoints = _calc_points()
219- local msg = p(ngettext("The game will end in %i minute.", "The game will end in %i minutes.", remaining_time))
220- :format(remaining_time)
221- msg = msg .. vspace(8) .. game_status.body
222+ local msg = format_remaining_time(remaining_time) .. vspace(8) .. game_status.body
223+
224 for idx,plr in ipairs(plrs) do
225 local trees = (ngettext ("%i tree", "%i trees", playerpoints[plr.number]))
226 :format(playerpoints[plr.number])
227 -- TRANSLATORS: %1$s = player name, %2$s = x tree(s)
228 msg = msg .. p(_"%1$s has %2$s at the moment."):bformat(plr.name,trees)
229 end
230- broadcast(plrs, game_status.title, msg)
231- end
232-
233- -- Start a new coroutine that checks for defeated players
234- run(function()
235- while remaining_time > 0 do
236- sleep(5000)
237- check_player_defeated(plrs, lost_game.title, lost_game.body, wc_descname, wc_version)
238- end
239- end)
240+
241+ broadcast(plrs, game_status.title, msg, {popup = show_popup})
242+ end
243+
244+ local function _game_over(plrs)
245+ local playerpoints = _calc_points()
246+ local points = {}
247+ for idx,plr in ipairs(plrs) do
248+ points[#points + 1] = { plr, playerpoints[plr.number] }
249+ end
250+ table.sort(points, function(a,b) return a[2] < b[2] end)
251+
252+ local msg = vspace(8) .. game_status.body
253+ for idx,plr in ipairs(plrs) do
254+ msg = msg .. vspace(8)
255+ local trees = (ngettext ("%i tree", "%i trees", playerpoints[plr.number])):format(playerpoints[plr.number])
256+ -- TRANSLATORS: %1$s = player name, %2$s = x tree(s)
257+ msg = msg .. p(_"%1$s had %2$s."):bformat(plr.name,trees)
258+ end
259+ msg = msg .. vspace(8)
260+ local trees = (ngettext ("%i tree", "%i trees", playerpoints[points[#points][1].number]))
261+ :format(playerpoints[points[#points][1].number])
262+ -- TRANSLATORS: %1$s = player name, %2$s = x tree(s)
263+ msg = msg .. h3(_"The winner is %1$s with %2$s."):bformat(points[#points][1].name, trees)
264+
265+ local privmsg = ""
266+ for i=1,#points-1 do
267+ privmsg = lost_game_over.body
268+ privmsg = privmsg .. msg
269+ points[i][1]:send_message(lost_game_over.title, privmsg)
270+ wl.game.report_result(points[i][1], 0, make_extra_data(points[i][1], wc_descname, wc_version, {score=points[i][2]}))
271+ end
272+ privmsg = won_game_over.body
273+ privmsg = privmsg .. msg
274+ points[#points][1]:send_message(won_game_over.title, privmsg)
275+ wl.game.report_result(points[#points][1], 1,
276+ make_extra_data(points[#points][1], wc_descname, wc_version, {score=points[#points][2]}))
277+ end
278
279 -- Install statistics hook
280 hooks.custom_statistic = {
281@@ -119,53 +147,23 @@
282 end,
283 }
284
285- -- main loop
286- while true do
287- sleep(300000) -- 5 Minutes
288- remaining_time = remaining_time - 5
289-
290- -- at the beginning send remaining time message only each 30 minutes
291- -- if only 30 minutes or less are left, send each 5 minutes
292- if (remaining_time < 30 or remaining_time % 30 == 0)
293- and remaining_time > 0 then
294- _send_state()
295+ -- Start a new coroutine that triggers status notifications.
296+ run(function()
297+ local remaining_time = max_time
298+ while game.time <= ((max_time - 5) * 60 * 1000) and count_factions(plrs) > 1 do
299+ remaining_time, show_popup = notification_remaining_time(max_time, remaining_time)
300+ _send_state(remaining_time, plrs, show_popup)
301 end
302-
303- if remaining_time <= 0 then break end
304+ end)
305+
306+ -- main loop checks for defeated players
307+ while game.time < (max_time * 60 * 1000) and count_factions(plrs) > 1 do
308+ sleep(1000)
309+ check_player_defeated(plrs, lost_game.title, lost_game.body, wc_descname, wc_version)
310 end
311-
312+
313 -- Game has ended
314- local playerpoints = _calc_points()
315- local points = {}
316- for idx,plr in ipairs(plrs) do
317- points[#points + 1] = { plr, playerpoints[plr.number] }
318- end
319- table.sort(points, function(a,b) return a[2] < b[2] end)
320-
321- local msg = vspace(8) .. game_status.body
322- for idx,plr in ipairs(plrs) do
323- msg = msg .. vspace(8)
324- local trees = (ngettext ("%i tree", "%i trees", playerpoints[plr.number])):format(playerpoints[plr.number])
325- -- TRANSLATORS: %1$s = player name, %2$s = x tree(s)
326- msg = msg .. p(_"%1$s had %2$s."):bformat(plr.name,trees)
327- end
328- msg = msg .. vspace(8)
329- local trees = (ngettext ("%i tree", "%i trees", playerpoints[points[#points][1].number]))
330- :format(playerpoints[points[#points][1].number])
331- -- TRANSLATORS: %1$s = player name, %2$s = x tree(s)
332- msg = msg .. h3(_"The winner is %1$s with %2$s."):bformat(points[#points][1].name, trees)
333-
334- local privmsg = ""
335- for i=1,#points-1 do
336- privmsg = lost_game_over.body
337- privmsg = privmsg .. msg
338- points[i][1]:send_message(lost_game_over.title, privmsg)
339- wl.game.report_result(points[i][1], 0, make_extra_data(points[i][1], wc_descname, wc_version, {score=points[i][2]}))
340- end
341- privmsg = won_game_over.body
342- privmsg = privmsg .. msg
343- points[#points][1]:send_message(won_game_over.title, privmsg)
344- wl.game.report_result(points[#points][1], 1,
345- make_extra_data(points[#points][1], wc_descname, wc_version, {score=points[#points][2]}))
346+ _game_over(plrs)
347+
348 end
349 }

Subscribers

People subscribed via source and target branches

to status/vote changes: