Модуль:PlayerAchievements: различия между версиями
Перейти к навигации
Перейти к поиску
Нет описания правки |
Нет описания правки |
||
| Строка 10: | Строка 10: | ||
local ModuleDataTeams = require('Module:Data/Teams') | local ModuleDataTeams = require('Module:Data/Teams') | ||
local TournamentAwards = require('Module:StatEngine/TournamentAwards') | local TournamentAwards = require('Module:StatEngine/TournamentAwards') | ||
local ModuleMegarating = require('Module:Megarating') | local ModuleMegarating = require('Module:Megarating') | ||
-- ========================================== | -- ========================================== | ||
| Строка 23: | Строка 23: | ||
local ShoeTeams = {} | local ShoeTeams = {} | ||
local AssistTeams = {} | local AssistTeams = {} | ||
local MegaratingRanks = {} -- Прямой кэш рангов мегарейтинга без двойного парсинга БД | |||
local word_map = { | local word_map = { | ||
| Строка 29: | Строка 30: | ||
[9] = "Девятый", [10] = "Десятый", [11] = "Одиннадцатый", [12] = "Двенадцатый" | [9] = "Девятый", [10] = "Десятый", [11] = "Одиннадцатый", [12] = "Двенадцатый" | ||
} | } | ||
-- Порядок тайбрейкера из мегарейтинга | |||
local tie_breaker_order = {1, 9, 8, 24, 18, 10, 2, 3, 19, 11, 12, 13, 7, 4, 23, 16, 22, 17, 6, 5, 15, 14, 21, 20} | |||
local function has_player(aw_data, player) | local function has_player(aw_data, player) | ||
| Строка 42: | Строка 46: | ||
if is_initialized then return end | if is_initialized then return end | ||
-- 1. ТЯЖЁЛАЯ АРТИЛЛЕРИЯ | -- 1. ТЯЖЁЛАЯ АРТИЛЛЕРИЯ (ОДИН ЕДИНСТВЕННЫЙ ЗАПУСК КОМБАЙНА НА ВСЮ СТРАНИЦУ) | ||
GrandStats = CoreEngine.Harvester.run_all_time({ | GrandStats = CoreEngine.Harvester.run_all_time({ | ||
need_players = true, | need_players = true, | ||
| Строка 50: | Строка 54: | ||
}) | }) | ||
-- 2. ТОЧЕЧНЫЙ ПРОХОД (Для стадионов, Клуба 100 | -- 2. ТОЧЕЧНЫЙ ПРОХОД (Для стадионов, Клуба 100, точных наград и рангов мегарейтинга) | ||
CustomStats = { club100 = {}, stadiums = {}, finals = {} } | CustomStats = { club100 = {}, stadiums = {}, finals = {} } | ||
local global_goals = {} | local global_goals = {} | ||
| Строка 86: | Строка 90: | ||
local f = CustomStats.finals[year] | local f = CustomStats.finals[year] | ||
-- | -- Ручной сбор финалов вне эпох (чтобы ассисты считались и в 2006) | ||
f.goals_count = {} | f.goals_count = {} | ||
f.assists_count = {} | f.assists_count = {} | ||
| Строка 152: | Строка 154: | ||
for _, p in ipairs(assists) do | for _, p in ipairs(assists) do | ||
if p.rank <= 4 and not AssistTeams[year][p.player] then AssistTeams[year][p.player] = p.team_code end | if p.rank <= 4 and not AssistTeams[year][p.player] then AssistTeams[year][p.player] = p.team_code end | ||
end | |||
-- ==== ПРЯМАЯ ИНТЕГРАЦИЯ МЕГАРЕЙТИНГА БЕЗ ДВОЙНОГО ПАРСИНГА ==== | |||
if GrandStats.Years[year] then | |||
-- Берём сферы | |||
local spheres = ModuleMegarating.get_spheres_from_db(year_db) | |||
-- Скармливаем УЖЕ СОБРАННЫЙ GrandStats сырому движку мегарейтинга (мгновенная калькуляция без БД) | |||
local final_list = ModuleMegarating.evaluate_raw_stats(year, year_db, GrandStats.Years[year].Players) | |||
if #final_list > 0 then | |||
table.sort(final_list, function(a, b) return ModuleMegarating.compare_players_public(a, b, year, spheres) end) | |||
MegaratingRanks[year] = {} | |||
local current_rank = 1 | |||
for i, p in ipairs(final_list) do | |||
local is_tie = false | |||
if i > 1 then | |||
local prev = final_list[i-1] | |||
if prev.total_points == p.total_points then | |||
local s_a = spheres[prev.name] or 0 | |||
local s_b = spheres[p.name] or 0 | |||
if s_a == s_b then | |||
is_tie = true | |||
-- Точная проверка на равенство по всем тайбрейкерам, как в мегарейтинге | |||
for _, metric_id in ipairs(tie_breaker_order) do | |||
local valid = true | |||
if metric_id >= 10 and metric_id <= 17 and year < Config.eras.plus_minus then valid = false end | |||
if metric_id >= 18 and metric_id <= 23 and year < Config.eras.assists then valid = false end | |||
if valid then | |||
local pts_a = prev.breakdown[metric_id] or 0 | |||
local pts_b = p.breakdown[metric_id] or 0 | |||
if pts_a ~= pts_b then is_tie = false; break end | |||
end | |||
end | |||
end | |||
end | |||
end | |||
if not is_tie then current_rank = i end | |||
MegaratingRanks[year][p.name] = current_rank | |||
end | |||
end | |||
end | end | ||
end | end | ||
| Строка 296: | Строка 341: | ||
local add = {} | local add = {} | ||
local | local latest_year = Config.years[#Config.years] | ||
local | local is_latest_finished = Config.is_latest_finished | ||
local function check_and_add(list, singular, plural, condition_func, sum_counts) | local function check_and_add(list, singular, plural, condition_func, sum_counts) | ||
| Строка 307: | Строка 352: | ||
local str = format_achievement(singular, plural, items, sum_counts) | local str = format_achievement(singular, plural, items, sum_counts) | ||
if str ~= "" then table.insert(list, str) end | if str ~= "" then table.insert(list, str) end | ||
end | |||
-- Вспомогательная функция для Мегарейтинга с учетом завершенности турнира | |||
local function check_mr(y, target_rank) | |||
local is_finished = (y ~= latest_year) or is_latest_finished | |||
if is_finished and MegaratingRanks[y] and MegaratingRanks[y][player] == target_rank then | |||
return {year = y} | |||
end | |||
end | end | ||
| Строка 353: | Строка 406: | ||
-- ================= ДОПОЛНИТЕЛЬНЫЕ ДОСТИЖЕНИЯ ================= | -- ================= ДОПОЛНИТЕЛЬНЫЕ ДОСТИЖЕНИЯ ================= | ||
check_and_add(add, "Лидер [[мегарейтинг]]а", "Лидер [[мегарейтинг]]а", function(y) return check_mr(y, 1) end) | |||
check_and_add(add, "Лидер [[мегарейтинг]]а", "Лидер [[мегарейтинг]]а", function(y) | check_and_add(add, "Второе место в [[мегарейтинг]]е", "Второе место в [[мегарейтинг]]е", function(y) return check_mr(y, 2) end) | ||
check_and_add(add, "Третье место в [[мегарейтинг]]е", "Третье место в [[мегарейтинг]]е", function(y) return check_mr(y, 3) end) | |||
check_and_add(add, "Четвёртое место в [[мегарейтинг]]е", "Четвёртое место в [[мегарейтинг]]е", function(y) return check_mr(y, 4) end) | |||
check_and_add(add, "Второе место в [[мегарейтинг]]е", "Второе место в [[мегарейтинг]]е", function(y) | |||
check_and_add(add, "Третье место в [[мегарейтинг]]е", "Третье место в [[мегарейтинг]]е", function(y) | |||
check_and_add(add, "Четвёртое место в [[мегарейтинг]]е", "Четвёртое место в [[мегарейтинг]]е", function(y) | |||
check_and_add(add, "Обладатель [[Золотой Шар|Серебряного Шара]]", "Обладатель [[Золотой Шар|Серебряного Шара]]", function(y) | check_and_add(add, "Обладатель [[Золотой Шар|Серебряного Шара]]", "Обладатель [[Золотой Шар|Серебряного Шара]]", function(y) | ||
| Строка 415: | Строка 459: | ||
end) | end) | ||
check_and_add(add, "Автор золотого гола ЧТМ", "Автор золотых голов ЧТМ", function(y) | check_and_add(add, "Автор золотого гола ЧТМ", "Автор золотых голов ЧТМ", function(y) | ||
local ys = GrandStats.Years[y] and GrandStats.Years[y].Players[player] | local ys = GrandStats.Years[y] and GrandStats.Years[y].Players[player] | ||
local is_gold, is_shootout = false, false | local is_gold, is_shootout = false, false | ||
if ys and ys.megarating and ys.megarating.final_gold_goals > 0 then is_gold = true end | if ys and ys.megarating and ys.megarating.final_gold_goals > 0 then is_gold = true end | ||
if CustomStats.finals[y] and CustomStats.finals[y].shootout_winner == player then | if CustomStats.finals[y] and CustomStats.finals[y].shootout_winner == player then | ||
| Строка 453: | Строка 495: | ||
end) | end) | ||
local function check_leader(list_arr, title_sing, title_plur, cat) | local function check_leader(list_arr, title_sing, title_plur, cat) | ||
check_and_add(list_arr, title_sing, title_plur, function(y) | check_and_add(list_arr, title_sing, title_plur, function(y) | ||
| Строка 475: | Строка 516: | ||
check_leader(add, "Лидер по [[Коэффициент пропущенных голов|коэффициенту пропущенных голов]]", "Лидер по [[Коэффициент пропущенных голов|коэффициенту пропущенных голов]]", "gaa") | check_leader(add, "Лидер по [[Коэффициент пропущенных голов|коэффициенту пропущенных голов]]", "Лидер по [[Коэффициент пропущенных голов|коэффициенту пропущенных голов]]", "gaa") | ||
local player_teams_best = {} | local player_teams_best = {} | ||
for t, info in pairs(TeamLeaders) do | for t, info in pairs(TeamLeaders) do | ||
| Строка 499: | Строка 539: | ||
end | end | ||
local player_stadiums_best = {} | local player_stadiums_best = {} | ||
for st, info in pairs(StadiumLeaders) do | for st, info in pairs(StadiumLeaders) do | ||
| Строка 520: | Строка 559: | ||
end | end | ||
local output = {} | local output = {} | ||
| Строка 537: | Строка 575: | ||
end | end | ||
function PlayerAchievements.main(frame) | function PlayerAchievements.main(frame) | ||
local player = frame.args[1] or frame.args["игрок"] or "" | local player = frame.args[1] or frame.args["игрок"] or "" | ||
Версия от 04:19, 2 июня 2026
[просмотр] [просмотр кода] [история] [обновить]
Пожалуйста, добавляйте категории на страницу документации.
-- ==========================================
-- Модуль:PlayerAchievements
-- Автоматический генератор достижений игроков ЧТМ
-- ==========================================
local PlayerAchievements = {}
local Config = require('Module:Config')
local CoreEngine = require('Module:StatEngine')
local ModuleDataTeams = require('Module:Data/Teams')
local TournamentAwards = require('Module:StatEngine/TournamentAwards')
local ModuleMegarating = require('Module:Megarating')
-- ==========================================
-- ГЛОБАЛЬНЫЙ КЭШ (Выполняется ровно 1 раз при загрузке страницы!)
-- ==========================================
local is_initialized = false
local GrandStats
local CustomStats = {}
local Leaders = {}
local TeamLeaders = {}
local StadiumLeaders = {}
local ShoeTeams = {}
local AssistTeams = {}
local MegaratingRanks = {} -- Прямой кэш рангов мегарейтинга без двойного парсинга БД
local word_map = {
[1] = "Первый", [2] = "Второй", [3] = "Третий", [4] = "Четвёртый",
[5] = "Пятый", [6] = "Шестой", [7] = "Седьмой", [8] = "Восьмой",
[9] = "Девятый", [10] = "Десятый", [11] = "Одиннадцатый", [12] = "Двенадцатый"
}
-- Порядок тайбрейкера из мегарейтинга
local tie_breaker_order = {1, 9, 8, 24, 18, 10, 2, 3, 19, 11, 12, 13, 7, 4, 23, 16, 22, 17, 6, 5, 15, 14, 21, 20}
local function has_player(aw_data, player)
if type(aw_data) == "table" then
for _, p in ipairs(aw_data) do if p == player then return true end end
elseif type(aw_data) == "string" then
return aw_data == player
end
return false
end
local function initialize_data()
if is_initialized then return end
-- 1. ТЯЖЁЛАЯ АРТИЛЛЕРИЯ (ОДИН ЕДИНСТВЕННЫЙ ЗАПУСК КОМБАЙНА НА ВСЮ СТРАНИЦУ)
GrandStats = CoreEngine.Harvester.run_all_time({
need_players = true,
need_teams = true,
need_combos = true,
keep_years = true
})
-- 2. ТОЧЕЧНЫЙ ПРОХОД (Для стадионов, Клуба 100, точных наград и рангов мегарейтинга)
CustomStats = { club100 = {}, stadiums = {}, finals = {} }
local global_goals = {}
for _, year in ipairs(Config.years) do
local success, year_db = pcall(require, 'Module:Data/' .. year)
if success then
local matches = {}
for id, m in pairs(year_db) do table.insert(matches, {id = id, m = m}) end
table.sort(matches, function(a, b) return (a.m.num_hist or 0) < (b.m.num_hist or 0) end)
CustomStats.finals[year] = {}
for _, item in ipairs(matches) do
local match = item.m
if match.goals then
for _, g in ipairs(match.goals) do
if g.scorer then
local p = g.scorer
global_goals[p] = (global_goals[p] or 0) + 1
if global_goals[p] == 100 then
table.insert(CustomStats.club100, {name = p, year = year})
end
if match.stadium then
CustomStats.stadiums[match.stadium] = CustomStats.stadiums[match.stadium] or {}
CustomStats.stadiums[match.stadium][p] = (CustomStats.stadiums[match.stadium][p] or 0) + 1
end
end
end
end
if match.stage == "Финал" then
local f = CustomStats.finals[year]
-- Ручной сбор финалов вне эпох (чтобы ассисты считались и в 2006)
f.goals_count = {}
f.assists_count = {}
if match.goals then
for _, g in ipairs(match.goals) do
if g.scorer then f.goals_count[g.scorer] = (f.goals_count[g.scorer] or 0) + 1 end
if g.assist then f.assists_count[g.assist] = (f.assists_count[g.assist] or 0) + 1 end
end
end
local function parse_aw(aw_data)
if type(aw_data) == "table" then return aw_data end
if type(aw_data) == "string" then return {aw_data} end
return {}
end
f.superchampions = parse_aw(match.superchampions)
f.golden_sphere = parse_aw(match.golden_sphere)
f.silver_sphere = parse_aw(match.silver_sphere)
f.bronze_sphere = parse_aw(match.bronze_sphere)
f.wooden_sphere = parse_aw(match.wooden_sphere)
f.golden_shoe = parse_aw(match.golden_shoe)
f.silver_shoe = parse_aw(match.silver_shoe)
f.bronze_shoe = parse_aw(match.bronze_shoe)
f.wooden_shoe = parse_aw(match.wooden_shoe)
f.golden_assistant = parse_aw(match.golden_assistant)
f.silver_assistant = parse_aw(match.silver_assistant)
f.bronze_assistant = parse_aw(match.bronze_assistant)
f.wooden_assistant = parse_aw(match.wooden_assistant)
f.elnur_award = parse_aw(match.elnur_award)
f.best_goal = parse_aw(match.best_goal)
f.mvp = match.mvp and match.mvp.player or nil
f.has_shootout = (match.shootout_score1 ~= nil)
f.shootout_winner = nil
if match.shootout and f.has_shootout then
local w_team = match.shootout_score1 > match.shootout_score2 and 1 or 2
local w_score = 0
local max_score = math.max(match.shootout_score1, match.shootout_score2)
for _, shot in ipairs(match.shootout) do
if shot.team == w_team and shot.result == "гол" then
w_score = w_score + 1
if w_score == max_score then
f.shootout_winner = shot.taker
break
end
end
end
end
end
end
local shoes = TournamentAwards.getTournamentAwards(year, year_db, "goals")
ShoeTeams[year] = {}
for _, p in ipairs(shoes) do
if p.rank <= 4 and not ShoeTeams[year][p.player] then ShoeTeams[year][p.player] = p.team_code end
end
local assists = TournamentAwards.getTournamentAwards(year, year_db, "assists")
AssistTeams[year] = {}
for _, p in ipairs(assists) do
if p.rank <= 4 and not AssistTeams[year][p.player] then AssistTeams[year][p.player] = p.team_code end
end
-- ==== ПРЯМАЯ ИНТЕГРАЦИЯ МЕГАРЕЙТИНГА БЕЗ ДВОЙНОГО ПАРСИНГА ====
if GrandStats.Years[year] then
-- Берём сферы
local spheres = ModuleMegarating.get_spheres_from_db(year_db)
-- Скармливаем УЖЕ СОБРАННЫЙ GrandStats сырому движку мегарейтинга (мгновенная калькуляция без БД)
local final_list = ModuleMegarating.evaluate_raw_stats(year, year_db, GrandStats.Years[year].Players)
if #final_list > 0 then
table.sort(final_list, function(a, b) return ModuleMegarating.compare_players_public(a, b, year, spheres) end)
MegaratingRanks[year] = {}
local current_rank = 1
for i, p in ipairs(final_list) do
local is_tie = false
if i > 1 then
local prev = final_list[i-1]
if prev.total_points == p.total_points then
local s_a = spheres[prev.name] or 0
local s_b = spheres[p.name] or 0
if s_a == s_b then
is_tie = true
-- Точная проверка на равенство по всем тайбрейкерам, как в мегарейтинге
for _, metric_id in ipairs(tie_breaker_order) do
local valid = true
if metric_id >= 10 and metric_id <= 17 and year < Config.eras.plus_minus then valid = false end
if metric_id >= 18 and metric_id <= 23 and year < Config.eras.assists then valid = false end
if valid then
local pts_a = prev.breakdown[metric_id] or 0
local pts_b = p.breakdown[metric_id] or 0
if pts_a ~= pts_b then is_tie = false; break end
end
end
end
end
end
if not is_tie then current_rank = i end
MegaratingRanks[year][p.name] = current_rank
end
end
end
end
end
-- 3. ВЫЧИСЛЕНИЕ ЛИДЕРОВ ГОДА
local function evaluate_leader(year, metric_func)
local max_val = -9999
local leaders = {}
for p, p_stats in pairs(GrandStats.Years[year].Players) do
local val = metric_func(p_stats)
if val and val > 0 then
if val > max_val then
max_val = val; leaders = {p}
elseif val == max_val then
table.insert(leaders, p)
end
end
end
return leaders
end
local function evaluate_min_leader(year, metric_func, min_req)
local min_val = 9999
local leaders = {}
for p, p_stats in pairs(GrandStats.Years[year].Players) do
if min_req(p_stats) then
local val = metric_func(p_stats)
if val then
if val < min_val then
min_val = val; leaders = {p}
elseif val == min_val then
table.insert(leaders, p)
end
end
end
end
return leaders
end
for _, year in ipairs(Config.years) do
if GrandStats.Years[year] then
Leaders.goals = Leaders.goals or {}; Leaders.goals[year] = evaluate_leader(year, function(s) return s.goals.total end)
Leaders.assists = Leaders.assists or {}; Leaders.assists[year] = evaluate_leader(year, function(s) return s.assists.total end)
Leaders.matches = Leaders.matches or {}; Leaders.matches[year] = evaluate_leader(year, function(s) return s.matches_total end)
Leaders.mvp = Leaders.mvp or {}; Leaders.mvp[year] = evaluate_leader(year, function(s) return s.mvp.is_mvp end)
Leaders.mvp_goalie = Leaders.mvp_goalie or {}; Leaders.mvp_goalie[year] = evaluate_leader(year, function(s) return s.mvp.is_goalie_mvp end)
Leaders.mega_tricks = Leaders.mega_tricks or {}; Leaders.mega_tricks[year] = evaluate_leader(year, function(s) return (s.goals.hat_trick + s.goals.poker + s.goals.penta + s.goals.hexa) end)
Leaders.head_goals = Leaders.head_goals or {}; Leaders.head_goals[year] = evaluate_leader(year, function(s) return s.goals.head end)
Leaders.pens_saved = Leaders.pens_saved or {}; Leaders.pens_saved[year] = evaluate_leader(year, function(s) return s.penalties.saved_as_goalie end)
Leaders.clearances = Leaders.clearances or {}; Leaders.clearances[year] = evaluate_leader(year, function(s) return s.clearances end)
Leaders.playoff_wins = Leaders.playoff_wins or {}; Leaders.playoff_wins[year] = evaluate_leader(year, function(s) return s.megarating.playoff_wins.r16 + s.megarating.playoff_wins.qf + s.megarating.playoff_wins.sf + (s.megarating.is_champion and 1 or 0) end)
Leaders.plus_minus = Leaders.plus_minus or {}; Leaders.plus_minus[year] = evaluate_leader(year, function(s) return s.plus_minus end)
Leaders.pens_scored = Leaders.pens_scored or {}; Leaders.pens_scored[year] = evaluate_leader(year, function(s) return s.penalties.in_game.g + s.penalties.shootout.g end)
Leaders.avg_goals = Leaders.avg_goals or {}
Leaders.avg_goals[year] = evaluate_leader(year, function(s)
if s.avg.goals_den > 0 then return s.avg.goals_num / s.avg.goals_den else return 0 end
end)
Leaders.gaa = Leaders.gaa or {}
Leaders.gaa[year] = evaluate_min_leader(year,
function(s) return s.weighted_ga / s.matches_goalie end,
function(s) return s.matches_goalie and s.matches_goalie >= 3 end
)
end
end
-- 4. ЛУЧШИЕ БОМБАРДИРЫ КОМАНД И СТАДИОНОВ
for combo, c_data in pairs(GrandStats.PlayerTeam) do
local p = c_data.name
local t = c_data.team
local goals = c_data.goals.total
if goals > 0 then
TeamLeaders[t] = TeamLeaders[t] or {players = {}, goals = 0}
if goals > TeamLeaders[t].goals then
TeamLeaders[t].goals = goals; TeamLeaders[t].players = {p}
elseif goals == TeamLeaders[t].goals then
table.insert(TeamLeaders[t].players, p)
end
end
end
for st, p_list in pairs(CustomStats.stadiums) do
local max = 0
local best = {}
for p, goals in pairs(p_list) do
if goals > max then
max = goals; best = {p}
elseif goals == max then
table.insert(best, p)
end
end
if max > 0 then StadiumLeaders[st] = {players = best, goals = max} end
end
is_initialized = true
end
-- ==========================================
-- УТИЛИТЫ ФОРМАТИРОВАНИЯ СТРОК
-- ==========================================
local function format_achievement(prefix_singular, prefix_plural, items, sum_counts)
if #items == 0 then return "" end
table.sort(items, function(a, b) return a.year < b.year end)
local texts = {}
local total = 0
for _, item in ipairs(items) do
local t = tostring(item.year)
if item.addon and item.addon ~= "" then t = t .. " " .. item.addon end
table.insert(texts, t)
total = total + (item.count or 1)
end
local display_prefix = (#items > 1 or (sum_counts and total > 1)) and prefix_plural or prefix_singular
local count_str = ""
if sum_counts and total > 1 then
count_str = " (" .. total .. ")"
elseif not sum_counts and #items > 1 then
count_str = " (" .. #items .. ")"
end
return "* " .. display_prefix .. count_str .. ": " .. table.concat(texts, ", ") .. "."
end
local function format_list_with_and(list)
if #list == 1 then return list[1] end
if #list == 2 then return list[1] .. " и " .. list[2] end
local last = table.remove(list)
return table.concat(list, ", ") .. " и " .. last
end
-- ==========================================
-- ОСНОВНАЯ ФУНКЦИЯ СБОРКИ ИГРОКА
-- ==========================================
function PlayerAchievements.build_achievements(player)
initialize_data()
if not GrandStats.Players[player] then return "" end
local main = {}
local add = {}
local latest_year = Config.years[#Config.years]
local is_latest_finished = Config.is_latest_finished
local function check_and_add(list, singular, plural, condition_func, sum_counts)
local items = {}
for _, year in ipairs(Config.years) do
local res = condition_func(year)
if res then table.insert(items, res) end
end
local str = format_achievement(singular, plural, items, sum_counts)
if str ~= "" then table.insert(list, str) end
end
-- Вспомогательная функция для Мегарейтинга с учетом завершенности турнира
local function check_mr(y, target_rank)
local is_finished = (y ~= latest_year) or is_latest_finished
if is_finished and MegaratingRanks[y] and MegaratingRanks[y][player] == target_rank then
return {year = y}
end
end
-- ================= ОСНОВНЫЕ ДОСТИЖЕНИЯ =================
check_and_add(main, "[[Список игроков-чемпионов третьего мира|Чемпион третьего мира]]", "[[Список игроков-чемпионов третьего мира|Чемпион третьего мира]]", function(y)
if Config.champions_players[y] and Config.utils.has_value(Config.champions_players[y], player) then return {year = y} end
end)
check_and_add(main, "[[Суперчемпион]]", "[[Суперчемпион]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].superchampions, player) then return {year = y} end
end)
check_and_add(main, "Обладатель [[Золотой Шар|Золотого Шара]]", "Обладатель [[Золотой Шар|Золотого Шара]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].golden_sphere, player) then return {year = y} end
end)
check_and_add(main, "Обладатель [[Золотой Башмак|Золотого Башмака]]", "Обладатель [[Золотой Башмак|Золотого Башмака]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].golden_shoe, player) then
local t = ShoeTeams[y] and ShoeTeams[y][player] or "Неизвестно"
return {year = y, addon = "([[" .. ModuleDataTeams.getName(t) .. "]])"}
end
end)
check_and_add(main, "[[Лучший ассистент]]", "[[Лучший ассистент]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].golden_assistant, player) then
local t = AssistTeams[y] and AssistTeams[y][player] or "Неизвестно"
return {year = y, addon = "([[" .. ModuleDataTeams.getName(t) .. "]])"}
end
end)
check_and_add(main, "[[Приз имени Эльнура|Лучший вратарь турнира]]", "[[Приз имени Эльнура|Лучший вратарь турнира]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].elnur_award, player) then return {year = y} end
end)
local club_index, club_year = 0, 0
for i, p_info in ipairs(CustomStats.club100) do
if p_info.name == player then
club_index = i; club_year = p_info.year; break
end
end
if club_index > 0 then
local w = word_map[club_index] or tostring(club_index) .. "-й"
local suffix = (club_index > 4) and " по счёту участник" or " участник"
table.insert(main, "* " .. w .. suffix .. " [[Клуб 100|Клуба 100]]: " .. club_year .. ".")
end
-- ================= ДОПОЛНИТЕЛЬНЫЕ ДОСТИЖЕНИЯ =================
check_and_add(add, "Лидер [[мегарейтинг]]а", "Лидер [[мегарейтинг]]а", function(y) return check_mr(y, 1) end)
check_and_add(add, "Второе место в [[мегарейтинг]]е", "Второе место в [[мегарейтинг]]е", function(y) return check_mr(y, 2) end)
check_and_add(add, "Третье место в [[мегарейтинг]]е", "Третье место в [[мегарейтинг]]е", function(y) return check_mr(y, 3) end)
check_and_add(add, "Четвёртое место в [[мегарейтинг]]е", "Четвёртое место в [[мегарейтинг]]е", function(y) return check_mr(y, 4) end)
check_and_add(add, "Обладатель [[Золотой Шар|Серебряного Шара]]", "Обладатель [[Золотой Шар|Серебряного Шара]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].silver_sphere, player) then return {year = y} end
end)
check_and_add(add, "Обладатель [[Золотой Шар|Бронзового Шара]]", "Обладатель [[Золотой Шар|Бронзового Шара]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].bronze_sphere, player) then return {year = y} end
end)
check_and_add(add, "Обладатель [[Золотой Шар|Деревянного Шара]]", "Обладатель [[Золотой Шар|Деревянного Шара]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].wooden_sphere, player) then return {year = y} end
end)
check_and_add(add, "Обладатель [[Золотой Башмак|Серебряного Башмака]]", "Обладатель [[Золотой Башмак|Серебряного Башмака]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].silver_shoe, player) then
local t = ShoeTeams[y] and ShoeTeams[y][player] or "Неизвестно"
return {year = y, addon = "([[" .. ModuleDataTeams.getName(t) .. "]])"}
end
end)
check_and_add(add, "Обладатель [[Золотой Башмак|Бронзового Башмака]]", "Обладатель [[Золотой Башмак|Бронзового Башмака]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].bronze_shoe, player) then
local t = ShoeTeams[y] and ShoeTeams[y][player] or "Неизвестно"
return {year = y, addon = "([[" .. ModuleDataTeams.getName(t) .. "]])"}
end
end)
check_and_add(add, "Обладатель [[Золотой Башмак|Деревянного Башмака]]", "Обладатель [[Золотой Башмак|Деревянного Башмака]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].wooden_shoe, player) then
local t = ShoeTeams[y] and ShoeTeams[y][player] or "Неизвестно"
return {year = y, addon = "([[" .. ModuleDataTeams.getName(t) .. "]])"}
end
end)
check_and_add(add, "Второе место в списке [[Лучший ассистент|лучших ассистентов]]", "Второе место в списке [[Лучший ассистент|лучших ассистентов]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].silver_assistant, player) then
local t = AssistTeams[y] and AssistTeams[y][player] or "Неизвестно"
return {year = y, addon = "([[" .. ModuleDataTeams.getName(t) .. "]])"}
end
end)
check_and_add(add, "Третье место в списке [[Лучший ассистент|лучших ассистентов]]", "Третье место в списке [[Лучший ассистент|лучших ассистентов]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].bronze_assistant, player) then
local t = AssistTeams[y] and AssistTeams[y][player] or "Неизвестно"
return {year = y, addon = "([[" .. ModuleDataTeams.getName(t) .. "]])"}
end
end)
check_and_add(add, "Четвёртое место в списке [[Лучший ассистент|лучших ассистентов]]", "Четвёртое место в списке [[Лучший ассистент|лучших ассистентов]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].wooden_assistant, player) then
local t = AssistTeams[y] and AssistTeams[y][player] or "Неизвестно"
return {year = y, addon = "([[" .. ModuleDataTeams.getName(t) .. "]])"}
end
end)
check_and_add(add, "Автор золотого гола ЧТМ", "Автор золотых голов ЧТМ", function(y)
local ys = GrandStats.Years[y] and GrandStats.Years[y].Players[player]
local is_gold, is_shootout = false, false
if ys and ys.megarating and ys.megarating.final_gold_goals > 0 then is_gold = true end
if CustomStats.finals[y] and CustomStats.finals[y].shootout_winner == player then
is_gold = true; is_shootout = true
end
if is_gold then return {year = y, addon = is_shootout and "(в серии пенальти)" or "", count = 1} end
end, false)
check_and_add(add, "Автор гола в финале ЧТМ", "Автор голов в финалах ЧТМ", function(y)
local f = CustomStats.finals[y]
if f and f.goals_count and f.goals_count[player] then
local c = f.goals_count[player]
return {year = y, addon = (c > 1) and ("(" .. c .. ")") or "", count = c}
end
end, true)
check_and_add(add, "Автор голевой передачи в финале ЧТМ", "Автор голевых передач в финалах ЧТМ", function(y)
local f = CustomStats.finals[y]
if f and f.assists_count and f.assists_count[player] then
local c = f.assists_count[player]
return {year = y, addon = (c > 1) and ("(" .. c .. ")") or "", count = c}
end
end, true)
check_and_add(add, "Лучший игрок финала ЧТМ", "Лучший игрок финалов ЧТМ", function(y)
if CustomStats.finals[y] and CustomStats.finals[y].mvp == player then return {year = y} end
end)
check_and_add(add, "Автор [[Лучший гол турнира|лучшего гола турнира]]", "Автор [[Лучший гол турнира|лучшего гола турнира]]", function(y)
if CustomStats.finals[y] and has_player(CustomStats.finals[y].best_goal, player) then return {year = y} end
end)
local function check_leader(list_arr, title_sing, title_plur, cat)
check_and_add(list_arr, title_sing, title_plur, function(y)
if Leaders[cat] and Leaders[cat][y] and Config.utils.has_value(Leaders[cat][y], player) then return {year = y} end
end)
end
check_leader(add, "Лидер по общему числу [[Голы|голов]]", "Лидер по общему числу [[Голы|голов]]", "goals")
check_leader(add, "Лидер по общему числу [[Голевые передачи|голевых передач]]", "Лидер по общему числу [[Голевые передачи|голевых передач]]", "assists")
check_leader(add, "Лидер по количеству признаний [[Игрок матча|игроком матча]]", "Лидер по количеству признаний [[Игрок матча|игроком матча]]", "mvp")
check_leader(add, "Лидер по количеству признаний [[Игрок матча как вратарь|игроком матча в качестве вратаря]]", "Лидер по количеству признаний [[Игрок матча как вратарь|игроком матча в качестве вратаря]]", "mvp_goalie")
check_leader(add, "[[Самый полезный игрок]]", "[[Самый полезный игрок]]", "plus_minus")
check_leader(add, "Лидер по числу [[Победы в плей-офф|побед в плей-офф]]", "Лидер по числу [[Победы в плей-офф|побед в плей-офф]]", "playoff_wins")
check_leader(add, "Лидер по [[Средняя результативность|средней результативности]]", "Лидер по [[Средняя результативность|средней результативности]]", "avg_goals")
check_leader(add, "Лидер по общему числу [[Матчи|сыгранных матчей]]", "Лидер по общему числу [[Матчи|сыгранных матчей]]", "matches")
check_leader(add, "[[Лучший пенальтист]]", "[[Лучший пенальтист]]", "pens_scored")
check_leader(add, "Лидер по общему числу [[Мега-трики|мега-триков]]", "Лидер по общему числу [[Мега-трики|мега-триков]]", "mega_tricks")
check_leader(add, "Лидер по [[Голы головой|голам головой]]", "Лидер по [[Голы головой|голам головой]]", "head_goals")
check_leader(add, "Лидер по [[Выносы из пустых|выносам из пустых]]", "Лидер по [[Выносы из пустых|выносам из пустых]]", "clearances")
check_leader(add, "Лидер по числу [[Отбитые пенальти|отбитых пенальти]]", "Лидер по числу [[Отбитые пенальти|отбитых пенальти]]", "pens_saved")
check_leader(add, "Лидер по [[Коэффициент пропущенных голов|коэффициенту пропущенных голов]]", "Лидер по [[Коэффициент пропущенных голов|коэффициенту пропущенных голов]]", "gaa")
local player_teams_best = {}
for t, info in pairs(TeamLeaders) do
if Config.utils.has_value(info.players, player) then
table.insert(player_teams_best, {team = t, goals = info.goals})
end
end
if #player_teams_best > 0 then
table.sort(player_teams_best, function(a, b) return a.goals > b.goals end)
if #player_teams_best == 1 then
local t_name = ModuleDataTeams.getName(player_teams_best[1].team, 'gen')
local g_word = (player_teams_best[1].goals % 10 == 1 and player_teams_best[1].goals % 100 ~= 11) and "гол" or (player_teams_best[1].goals % 10 >= 2 and player_teams_best[1].goals % 10 <= 4 and (player_teams_best[1].goals % 100 < 10 or player_teams_best[1].goals % 100 >= 20)) and "гола" or "голов"
table.insert(add, "* [[Список голов ЧТМ по сборным|Лучший бомбардир]] в истории сборной [[" .. ModuleDataTeams.getName(player_teams_best[1].team) .. "|" .. t_name .. "]] (" .. player_teams_best[1].goals .. " " .. g_word .. ").")
else
local t_strs = {}
for _, info in ipairs(player_teams_best) do
table.insert(t_strs, "[[" .. ModuleDataTeams.getName(info.team) .. "]] (" .. info.goals .. ")")
end
local w_map = { [2]="двух", [3]="трёх", [4]="четырёх", [5]="пяти", [6]="шести", [7]="семи", [8]="восьми", [9]="девяти", [10]="десяти", [11]="одиннадцати" }
local word = w_map[#player_teams_best] or tostring(#player_teams_best)
table.insert(add, "* [[Список голов ЧТМ по сборным|Лучший бомбардир]] в истории " .. word .. " сборных: " .. table.concat(t_strs, ", ") .. ".")
end
end
local player_stadiums_best = {}
for st, info in pairs(StadiumLeaders) do
if Config.utils.has_value(info.players, player) then
table.insert(player_stadiums_best, {stadium = st, goals = info.goals})
end
end
if #player_stadiums_best > 0 then
table.sort(player_stadiums_best, function(a, b) return a.goals > b.goals end)
local s_strs = {}
for _, info in ipairs(player_stadiums_best) do
local g_word = (info.goals % 10 == 1 and info.goals % 100 ~= 11) and "гол" or (info.goals % 10 >= 2 and info.goals % 10 <= 4 and (info.goals % 100 < 10 or info.goals % 100 >= 20)) and "гола" or "голов"
table.insert(s_strs, "«[[" .. info.stadium .. "]]» (" .. info.goals .. " " .. g_word .. ")")
end
if #player_stadiums_best == 1 then
table.insert(add, "* Лучший бомбардир в истории стадиона " .. s_strs[1] .. ".")
else
table.insert(add, "* Лучший бомбардир в истории стадионов " .. format_list_with_and(s_strs) .. ".")
end
end
local output = {}
if #main > 0 then
table.insert(output, "; Основные:")
for _, item in ipairs(main) do table.insert(output, item) end
end
if #add > 0 then
if #main > 0 then table.insert(output, "") end
table.insert(output, "; Дополнительные:")
for _, item in ipairs(add) do table.insert(output, item) end
end
return table.concat(output, "\n")
end
function PlayerAchievements.main(frame)
local player = frame.args[1] or frame.args["игрок"] or ""
player = mw.text.trim(player)
if player == "" then return "''Не указан игрок''" end
local text = PlayerAchievements.build_achievements(player)
if text == "" then return "''Нет зафиксированных достижений.''" end
return text
end
return PlayerAchievements