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