diff --git a/lua/wikis/valorant/MatchGroup/Input/Custom.lua b/lua/wikis/valorant/MatchGroup/Input/Custom.lua index d736ac473d8..26a05cf2b52 100644 --- a/lua/wikis/valorant/MatchGroup/Input/Custom.lua +++ b/lua/wikis/valorant/MatchGroup/Input/Custom.lua @@ -12,6 +12,7 @@ local AgentNames = Lua.import('Module:AgentNames') local FnUtil = Lua.import('Module:FnUtil') local Logic = Lua.import('Module:Logic') local Operator = Lua.import('Module:Operator') +local Page = Lua.import('Module:Page') local Table = Lua.import('Module:Table') local MatchGroupInputUtil = Lua.import('Module:MatchGroup/Input/Util') @@ -71,6 +72,11 @@ local VALORANT_REGIONS = {'eu', 'na', 'ap', 'kr', 'latam', 'br', 'pbe1', 'esport ---@field totalKastRounds integer ---@field damageDealt integer +---@class ValorantSkirmishResult +---@field players MGIParsedPlayer[] +---@field scores number[] +---@field winner number + ---@param match table ---@param options table? ---@return table @@ -148,6 +154,51 @@ function MatchFunctions.getExtraData(match, games, opponents) return { mapveto = MatchGroupInputUtil.getMapVeto(match), mvp = MatchGroupInputUtil.readMvp(match, opponents), + skirmish = MatchFunctions.parseSkirmish(match, opponents), + } +end + +---@param match table +---@param opponents MGIParsedOpponent[] +---@return ValorantSkirmishResult? +function MatchFunctions.parseSkirmish(match, opponents) + local skirmishData = match.skirmish + if Logic.isEmpty(skirmishData) then + return + end + + ---@param playerName string? + ---@param opponentIndex integer + ---@return MGIParsedPlayer? + local function lookupPlayer(playerName, opponentIndex) + if Logic.isEmpty(playerName) then + return + end + ---@cast playerName -nil + local link = Page.pageifyLink(playerName) + return Array.find( + opponents[opponentIndex].match2players, + function (match2player) + return match2player.name == link or match2player.displayname == link or match2player.displayname == playerName + end + ) + end + + local player1 = lookupPlayer(skirmishData.t1p1, 1) + local player2 = lookupPlayer(skirmishData.t2p1, 2) + if Logic.isEmpty(player1) or Logic.isEmpty(player2) then + return + end + local scores = Array.mapIndexes(function (index) + return tonumber(skirmishData['score' .. index]) + end) + if #scores ~= 2 then + return + end + return { + players = {player1, player2}, + scores = scores, + winner = tonumber(skirmishData.winner) or (match.finished and (scores[1] > scores[2] and 1 or 2) or nil) } end diff --git a/lua/wikis/valorant/MatchPage.lua b/lua/wikis/valorant/MatchPage.lua index 0d18713eef9..28861d9fbb5 100644 --- a/lua/wikis/valorant/MatchPage.lua +++ b/lua/wikis/valorant/MatchPage.lua @@ -21,6 +21,7 @@ local MatchGroupUtil = Lua.import('Module:MatchGroup/Util/Custom') local Html = Lua.import('Module:Widget/Html') local Carousel = Lua.import('Module:Widget/Basic/Carousel') local Div = Html.Div +local Comment = Lua.import('Module:Widget/Match/Page/Comment') local GeneralCollapsible = Lua.import('Module:Widget/GeneralCollapsible/Default') local IconFa = Lua.import('Module:Widget/Image/Icon/Fontawesome') local IconImage = Lua.import('Module:Widget/Image/Icon/Image') @@ -29,6 +30,7 @@ local PlayerDisplay = Lua.import('Module:Widget/Match/Page/PlayerDisplay') local PlayerStat = Lua.import('Module:Widget/Match/Page/PlayerStat') local PlayerStatContainer = Lua.import('Module:Widget/Match/Page/PlayerStat/Container') local RoundsOverview = Lua.import('Module:Widget/Match/Page/RoundsOverview') +local SkirmishDisplay = Lua.import('Module:Widget/Match/Summary/Skirmish') local Span = Html.Span local StatsList = Lua.import('Module:Widget/Match/Page/StatsList') local WidgetUtil = Lua.import('Module:Widget/Util') @@ -645,4 +647,16 @@ function MatchPage:_renderPlayerPerformance(player) } end +---@return VNode[]? +function MatchPage:addComments() + local skirmishData = self.matchData.extradata.skirmish + if Logic.isEmpty(skirmishData) then + return + end + ---@cast skirmishData ValorantSkirmishResult + return { + Comment{children = SkirmishDisplay(skirmishData)} + } +end + return MatchPage diff --git a/lua/wikis/valorant/MatchSummary.lua b/lua/wikis/valorant/MatchSummary.lua index 3ba3cfb2c96..4eeb1d53624 100644 --- a/lua/wikis/valorant/MatchSummary.lua +++ b/lua/wikis/valorant/MatchSummary.lua @@ -11,10 +11,12 @@ local Array = Lua.import('Module:Array') local Class = Lua.import('Module:Class') local Logic = Lua.import('Module:Logic') local Operator = Lua.import('Module:Operator') +local PlayerDisplay = Lua.import('Module:Player/Display/Custom') local MatchSummary = Lua.import('Module:MatchSummary/Base') local MatchSummaryWidgets = Lua.import('Module:Widget/Match/Summary/All') +local HtmlWidgets = Lua.import('Module:Widget/Html/All') local WidgetUtil = Lua.import('Module:Widget/Util') ---@class ValorantMatchSummary: CustomMatchSummaryInterface @@ -36,18 +38,96 @@ function CustomMatchSummary.createBody(match) return WidgetUtil.collect( MatchSummaryWidgets.GamesContainer{ gridLayout = 'standard', - children = Array.map(match.games, function (game, gameIndex) - if Logic.isEmpty(game.map) then - return - end - return ValorantMatchSummaryGameRow{game = game, gameIndex = gameIndex} - end) + children = WidgetUtil.collect( + Array.map(match.games, function (game, gameIndex) + if Logic.isEmpty(game.map) then + return + end + return ValorantMatchSummaryGameRow{game = game, gameIndex = gameIndex} + end), + CustomMatchSummary._createSkirmishDisplay(match.extradata.skirmish) + ) }, MatchSummaryWidgets.Mvp(match.extradata.mvp), MatchSummaryWidgets.MapVeto(MatchSummary.preProcessMapVeto(match.extradata.mapveto, {game = match.game})) ) end +---@param skirmishData ValorantSkirmishResult +---@return Widget? +function CustomMatchSummary._createSkirmishDisplay(skirmishData) + if Logic.isEmpty(skirmishData) then + return + end + local players = Array.map( + skirmishData.players, + function (player) + ---@type standardPlayer + return { + displayName = player.displayname, + pageName = player.name, + flag = player.flag, + } + end + ) + return HtmlWidgets.Div{ + classes = {'brkts-popup-body-grid-row'}, + children = { + HtmlWidgets.B{ + css = { + ['grid-column'] = '1 / -1', + ['justify-self'] = 'center', + }, + children = 'Skirmish Side Selection Result' + }, + HtmlWidgets.Div{ + classes = {'brkts-popup-body-grid-row-detail'}, + children = { + HtmlWidgets.Span{ + css = { + ['justify-self'] = 'end', + }, + children = PlayerDisplay.InlinePlayer{ + flip = true, + player = players[1], + } + }, + HtmlWidgets.Div{ + css = { + display = 'grid', + ['grid-template-columns'] = '1fr min-content 1fr', + gap = '0.25rem', + ['justify-self'] = 'center', + }, + children = Array.interleave( + Array.map( + skirmishData.scores, + function (score, scoreIndex) + return HtmlWidgets.Span{ + css = skirmishData.winner == scoreIndex and { + ['font-weight'] = 'bold' + } or nil, + children = score, + } + end + ), + HtmlWidgets.Span{children = '–'} + ) + }, + HtmlWidgets.Span{ + css = { + ['justify-self'] = 'start', + }, + children = PlayerDisplay.InlinePlayer{ + player = players[2], + } + }, + } + }, + } + } +end + ---@return string function ValorantMatchSummaryGameRow:createGameOverview() return self:mapDisplay() diff --git a/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua b/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua new file mode 100644 index 00000000000..15535cdbbca --- /dev/null +++ b/lua/wikis/valorant/Widget/Match/Summary/Skirmish.lua @@ -0,0 +1,90 @@ +--- +-- @Liquipedia +-- page=Module:Widget/Match/Summary/Skirmish +-- +-- Please see https://github.com/Liquipedia/Lua-Modules to contribute +-- + +local Lua = require('Module:Lua') + +local Array = Lua.import('Module:Array') +local Logic = Lua.import('Module:Logic') +local PlayerDisplay = Lua.import('Module:Player/Display/Custom') + +local Component = Lua.import('Module:Widget/Component') +local Html = Lua.import('Module:Widget/Html') +local Div = Html.Div + +---@param props ValorantSkirmishResult +---@return VNode? +local function ValorantSkirmishDisplay(props) + if Logic.isEmpty(props) then + return + end + local players = Array.map( + props.players, + function (player) + ---@type standardPlayer + return { + displayName = player.displayname, + pageName = player.name, + flag = player.flag, + } + end + ) + return Div{ + css = { + display = 'grid', + ['grid-template-columns'] = '1fr min-content 1fr', + gap = '0.25rem', + }, + children = { + Html.B{ + css = { + ['grid-column'] = '1 / -1' + }, + children = 'Skirmish Side Selection Result' + }, + Html.Span{ + css = { + ['justify-self'] = 'end', + }, + children = PlayerDisplay.InlinePlayer{ + flip = true, + player = players[1], + } + }, + Div{ + css = { + display = 'grid', + ['grid-template-columns'] = '1fr min-content 1fr', + gap = '0.25rem', + }, + children = Array.interleave( + Array.map( + props.scores, + function (score, scoreIndex) + return Html.Span{ + css = props.winner == scoreIndex and { + ['font-weight'] = 'bold' + } or nil, + children = score, + } + end + ), + Html.Span{children = '–'} + ) + }, + Html.Span{ + css = { + ['justify-self'] = 'start', + }, + children = PlayerDisplay.InlinePlayer{ + player = players[2], + } + }, + } + } +end + +return Component.component(ValorantSkirmishDisplay)