1-- =======================================================================
2--                       Wood Gnome win condition
3-- =======================================================================
4
5include "scripting/coroutine.lua" -- for sleep
6include "scripting/table.lua"
7include "scripting/win_conditions/win_condition_functions.lua"
8
9set_textdomain("win_conditions")
10
11include "scripting/win_conditions/win_condition_texts.lua"
12
13local wc_name = "Wood Gnome"
14-- This needs to be exactly like wc_name, but localized, because wc_name
15-- will be used as the key to fetch the translation in C++
16local wc_descname = _("Wood Gnome")
17local wc_version = 2
18local wc_desc = _(
19[[As wood gnome you like big forests, so your task is to have more trees on ]] ..
20[[your territory than any other player. The game will end after 4 hours of ]] ..
21[[playing. The one with the most trees at that point will win the game.]])
22local wc_trees_owned = _"Trees owned"
23
24return {
25   name = wc_name,
26   description = wc_desc,
27   peaceful_mode_allowed = true,
28   init = function()
29      -- Calculate valuable fields
30      wl.Game().map:count_terrestrial_fields()
31   end,
32   func = function()
33   local plrs = wl.Game().players
34   local game = wl.Game()
35
36   -- set the maximum game time of 4 hours
37   local max_time = 4 * 60
38
39   -- set the objective with the game type for all players
40   broadcast_objective("win_condition", wc_descname, wc_desc)
41
42   -- The function to calculate the current points.
43   local _last_time_calculated = -100000
44   local playerpoints = {}
45   local function _calc_points()
46
47      if _last_time_calculated > game.time - 5000 then
48         return
49      end
50
51      playerpoints = count_owned_valuable_fields_for_all_players(plrs, "tree")
52      _last_time_calculated = game.time
53   end
54
55   local function _send_state(remaining_time, plrs, show_popup)
56      _calc_points()
57      local msg = format_remaining_time(remaining_time) .. vspace(8) .. game_status.body
58
59      for idx,plr in ipairs(plrs) do
60         local trees = (ngettext ("%i tree", "%i trees", playerpoints[plr.number]))
61               :format(playerpoints[plr.number])
62         -- TRANSLATORS: %1$s = player name, %2$s = x tree(s)
63         msg = msg .. p(_"%1$s has %2$s at the moment."):bformat(plr.name,trees)
64      end
65
66      broadcast(plrs, game_status.title, msg, {popup = show_popup})
67   end
68
69   local function _game_over(plrs)
70      _calc_points()
71      local points = {}
72      for idx,plr in ipairs(plrs) do
73         points[#points + 1] = { plr, playerpoints[plr.number] }
74      end
75      table.sort(points, function(a,b) return a[2] < b[2] end)
76
77      local msg = vspace(8) .. game_status.body
78      for idx,plr in ipairs(plrs) do
79         msg = msg .. vspace(8)
80         local trees = (ngettext ("%i tree", "%i trees", playerpoints[plr.number])):format(playerpoints[plr.number])
81         -- TRANSLATORS: %1$s = player name, %2$s = x tree(s)
82         msg = msg ..  p(_"%1$s had %2$s."):bformat(plr.name,trees)
83      end
84      msg = msg .. vspace(8)
85      local trees = (ngettext ("%i tree", "%i trees", playerpoints[points[#points][1].number]))
86            :format(playerpoints[points[#points][1].number])
87      -- TRANSLATORS: %1$s = player name, %2$s = x tree(s)
88      msg = msg ..  h3(_"The winner is %1$s with %2$s."):bformat(points[#points][1].name, trees)
89
90      local privmsg = ""
91      for i=1,#points-1 do
92         privmsg = lost_game_over.body
93         privmsg = privmsg .. msg
94         points[i][1]:send_message(lost_game_over.title, privmsg)
95         wl.game.report_result(points[i][1], 0, make_extra_data(points[i][1], wc_descname, wc_version, {score=points[i][2]}))
96      end
97      privmsg = won_game_over.body
98      privmsg = privmsg .. msg
99      points[#points][1]:send_message(won_game_over.title, privmsg)
100      wl.game.report_result(points[#points][1], 1,
101         make_extra_data(points[#points][1], wc_descname, wc_version, {score=points[#points][2]}))
102   end
103
104   -- Install statistics hook
105   hooks.custom_statistic = {
106      name = wc_trees_owned,
107      pic = "images/wui/stats/genstats_trees.png",
108      calculator = function(p)
109         _calc_points(p)
110         return playerpoints[p.number] or 0
111      end,
112   }
113
114   -- Start a new coroutine that triggers status notifications.
115   run(function()
116      local remaining_time = max_time
117      while game.time <= ((max_time - 5) * 60 * 1000) and count_factions(plrs) > 1 do
118         remaining_time, show_popup = notification_remaining_time(max_time, remaining_time)
119         _send_state(remaining_time, plrs, show_popup)
120      end
121   end)
122
123   -- main loop checks for defeated players
124   while game.time < (max_time * 60 * 1000) and count_factions(plrs) > 1 do
125      sleep(1000)
126      check_player_defeated(plrs, lost_game.title, lost_game.body, wc_descname, wc_version)
127   end
128
129   -- Game has ended
130   _game_over(plrs)
131
132end
133}
134