-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(match2): deadlock setup (#4652)
* feat(match2): deadlock setup * from review * shortern down the copy paste * update m2 status * hero icon tweaks * remove side colors
- Loading branch information
Showing
4 changed files
with
396 additions
and
1 deletion.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
components/match2/wikis/deadlock/get_match_group_copy_paste_wiki.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
--- | ||
-- @Liquipedia | ||
-- wiki=deadlock | ||
-- page=Module:GetMatchGroupCopyPaste/wiki | ||
-- | ||
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute | ||
-- | ||
|
||
local Array = require('Module:Array') | ||
local Class = require('Module:Class') | ||
local Logic = require('Module:Logic') | ||
local Lua = require('Module:Lua') | ||
|
||
local BaseCopyPaste = Lua.import('Module:GetMatchGroupCopyPaste/wiki/Base') | ||
|
||
---@class DeadlockMatch2CopyPaste: Match2CopyPasteBase | ||
local WikiCopyPaste = Class.new(BaseCopyPaste) | ||
|
||
local INDENT = WikiCopyPaste.Indent | ||
|
||
function WikiCopyPaste.getMatchCode(bestof, mode, index, opponents, args) | ||
local showScore = Logic.nilOr(Logic.readBoolOrNil, bestof == 0) | ||
|
||
local lines = Array.extend( | ||
'{{Match|bestof=' .. (bestof ~= 0 and bestof or ''), | ||
Array.map(Array.range(1, opponents), function(opponentIndex) | ||
return INDENT .. '|opponent' .. opponentIndex .. '=' .. WikiCopyPaste.getOpponent(mode, showScore) | ||
end), | ||
INDENT .. '|date=|finished=', | ||
INDENT .. '|twitch=|youtube=|vod=', | ||
Array.map(Array.range(1, bestof), WikiCopyPaste._getMapCode), | ||
'}}' | ||
) | ||
|
||
return table.concat(lines, '\n') | ||
end | ||
|
||
---@param mapIndex integer | ||
---@return string | ||
function WikiCopyPaste._getMapCode(mapIndex) | ||
return table.concat(Array.extend( | ||
INDENT .. '|map' .. mapIndex .. '={{Map|length=|winner=|vod=', | ||
INDENT .. INDENT .. '|team1side=|team2side=', | ||
INDENT .. INDENT .. '|t1h1=|t1h2=|t1h3=|t1h4=|t1h5=|t1h6=', | ||
INDENT .. INDENT .. '|t2h1=|t2h2=|t2h3=|t2h4=|t2h5=|t2h6=', | ||
INDENT .. '}}' | ||
), '\n') | ||
end | ||
|
||
return WikiCopyPaste |
181 changes: 181 additions & 0 deletions
181
components/match2/wikis/deadlock/match_group_input_custom.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
--- | ||
-- @Liquipedia | ||
-- wiki=deadlock | ||
-- page=Module:MatchGroup/Input/Custom | ||
-- | ||
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute | ||
-- | ||
|
||
local Array = require('Module:Array') | ||
local FnUtil = require('Module:FnUtil') | ||
local HeroNames = mw.loadData('Module:HeroNames') | ||
local Lua = require('Module:Lua') | ||
local Operator = require('Module:Operator') | ||
local Streams = require('Module:Links/Stream') | ||
local Table = require('Module:Table') | ||
|
||
local MatchGroupInputUtil = Lua.import('Module:MatchGroup/Input/Util') | ||
|
||
local OPPONENT_CONFIG = { | ||
resolveRedirect = true, | ||
pagifyTeamNames = true, | ||
pagifyPlayerNames = true, | ||
maxNumPlayers = 10, | ||
} | ||
|
||
local MatchFunctions = {} | ||
local MapFunctions = {} | ||
|
||
local CustomMatchGroupInput = {} | ||
|
||
---@param match table | ||
---@param options? {isMatchPage: boolean?} | ||
---@return table | ||
function CustomMatchGroupInput.processMatch(match, options) | ||
local finishedInput = match.finished --[[@as string?]] | ||
local winnerInput = match.winner --[[@as string?]] | ||
Table.mergeInto(match, MatchGroupInputUtil.readDate(match.date)) | ||
|
||
local opponents = Array.mapIndexes(function(opponentIndex) | ||
return MatchGroupInputUtil.readOpponent(match, opponentIndex, OPPONENT_CONFIG) | ||
end) | ||
local games = MatchFunctions.extractMaps(match, opponents) | ||
match.bestof = MatchGroupInputUtil.getBestOf(match.bestof, games) | ||
|
||
local autoScoreFunction = MatchGroupInputUtil.canUseAutoScore(match, games) | ||
and MatchFunctions.calculateMatchScore(games) | ||
or nil | ||
|
||
Array.forEach(opponents, function(opponent, opponentIndex) | ||
opponent.score, opponent.status = MatchGroupInputUtil.computeOpponentScore({ | ||
walkover = match.walkover, | ||
winner = match.winner, | ||
opponentIndex = opponentIndex, | ||
score = opponent.score, | ||
}, autoScoreFunction) | ||
end) | ||
|
||
match.finished = MatchGroupInputUtil.matchIsFinished(match, opponents) | ||
|
||
if match.finished then | ||
match.resulttype = MatchGroupInputUtil.getResultType(winnerInput, finishedInput, opponents) | ||
match.walkover = MatchGroupInputUtil.getWalkover(match.resulttype, opponents) | ||
match.winner = MatchGroupInputUtil.getWinner(match.resulttype, winnerInput, opponents) | ||
MatchGroupInputUtil.setPlacement(opponents, match.winner, 1, 2) | ||
elseif MatchGroupInputUtil.isNotPlayed(winnerInput, finishedInput) then | ||
match.resulttype = MatchGroupInputUtil.getResultType(winnerInput, finishedInput, opponents) | ||
match.winner = nil | ||
end | ||
|
||
MatchGroupInputUtil.getCommonTournamentVars(match) | ||
|
||
match.stream = Streams.processStreams(match) | ||
match.extradata = MatchFunctions.getExtraData(match) | ||
|
||
match.games = games | ||
match.opponents = opponents | ||
|
||
return match | ||
end | ||
|
||
---@param match table | ||
---@param opponents table[] | ||
---@return table[] | ||
function MatchFunctions.extractMaps(match, opponents) | ||
local maps = {} | ||
for key, map in Table.iter.pairsByPrefix(match, 'map', {requireIndex = true}) do | ||
local finishedInput = map.finished --[[@as string?]] | ||
local winnerInput = map.winner --[[@as string?]] | ||
|
||
map.map = nil | ||
map.participants = MapFunctions.getParticipants(map, opponents) | ||
map.extradata = MapFunctions.getExtraData(map) | ||
|
||
map.finished = MatchGroupInputUtil.mapIsFinished(map) | ||
local opponentInfo = Array.map(opponents, function(_, opponentIndex) | ||
local score, status = MatchGroupInputUtil.computeOpponentScore({ | ||
walkover = map.walkover, | ||
winner = map.winner, | ||
opponentIndex = opponentIndex, | ||
score = map['score' .. opponentIndex], | ||
}, MapFunctions.calculateMapScore(map.winner, map.finished)) | ||
return {score = score, status = status} | ||
end) | ||
|
||
map.scores = Array.map(opponentInfo, Operator.property('score')) | ||
if map.finished or MatchGroupInputUtil.isNotPlayed(map.winner, finishedInput) then | ||
map.resulttype = MatchGroupInputUtil.getResultType(winnerInput, finishedInput, opponentInfo) | ||
map.walkover = MatchGroupInputUtil.getWalkover(map.resulttype, opponentInfo) | ||
map.winner = MatchGroupInputUtil.getWinner(map.resulttype, winnerInput, opponentInfo) | ||
end | ||
|
||
table.insert(maps, map) | ||
match[key] = nil | ||
end | ||
|
||
return maps | ||
end | ||
|
||
CustomMatchGroupInput.processMap = FnUtil.identity | ||
|
||
---@param maps table[] | ||
---@return fun(opponentIndex: integer): integer | ||
function MatchFunctions.calculateMatchScore(maps) | ||
return function(opponentIndex) | ||
return MatchGroupInputUtil.computeMatchScoreFromMapWinners(maps, opponentIndex) | ||
end | ||
end | ||
|
||
---@param match table | ||
---@return table | ||
function MatchFunctions.getExtraData(match) | ||
return { | ||
comment = match.comment, | ||
} | ||
end | ||
|
||
---@param map table | ||
---@return table | ||
function MapFunctions.getExtraData(map) | ||
local extraData = { | ||
comment = map.comment, | ||
team1side = map.team1side, | ||
team2side = map.team2side, | ||
} | ||
|
||
return extraData | ||
end | ||
|
||
---@param map table | ||
---@param opponents table[] | ||
---@return table | ||
function MapFunctions.getParticipants(map, opponents) | ||
local participants = {} | ||
local getCharacterName = FnUtil.curry(MatchGroupInputUtil.getCharacterName, HeroNames) | ||
|
||
for opponentIndex in ipairs(opponents) do | ||
for _, hero, playerIndex in Table.iter.pairsByPrefix(map, 't' .. opponentIndex .. 'h', {requireIndex = true}) do | ||
participants[opponentIndex .. '_' .. playerIndex] = { | ||
character = getCharacterName(hero), | ||
} | ||
end | ||
end | ||
|
||
return participants | ||
end | ||
|
||
---@param winnerInput string|integer|nil | ||
---@param finished boolean | ||
---@return fun(opponentIndex: integer): integer? | ||
function MapFunctions.calculateMapScore(winnerInput, finished) | ||
local winner = tonumber(winnerInput) | ||
return function(opponentIndex) | ||
-- TODO Better to check if map has started, rather than finished, for a more correct handling | ||
if not winner and not finished then | ||
return | ||
end | ||
return winner == opponentIndex and 1 or 0 | ||
end | ||
end | ||
|
||
return CustomMatchGroupInput |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
--- | ||
-- @Liquipedia | ||
-- wiki=deadlock | ||
-- page=Module:MatchSummary | ||
-- | ||
-- Please see https://github.com/Liquipedia/Lua-Modules to contribute | ||
-- | ||
|
||
local Abbreviation = require('Module:Abbreviation') | ||
local Array = require('Module:Array') | ||
local CharacterIcon = require('Module:CharacterIcon') | ||
local FnUtil = require('Module:FnUtil') | ||
local DateExt = require('Module:Date/Ext') | ||
local Icon = require('Module:Icon') | ||
local Logic = require('Module:Logic') | ||
local Lua = require('Module:Lua') | ||
local Table = require('Module:Table') | ||
|
||
local DisplayHelper = Lua.import('Module:MatchGroup/Display/Helper') | ||
local MatchSummary = Lua.import('Module:MatchSummary/Base') | ||
|
||
local SIZE_HERO = '48x48px' | ||
local ICONS = { | ||
winner = Icon.makeIcon{iconName = 'winner', color = 'forest-green-text', size = 'initial'}, | ||
loss = Icon.makeIcon{iconName = 'loss', color = 'cinnabar-text', size = 'initial'}, | ||
empty = '[[File:NoCheck.png|link=|16px]]', | ||
} | ||
|
||
local CustomMatchSummary = {} | ||
|
||
---@param args table | ||
---@return Html | ||
function CustomMatchSummary.getByMatchId(args) | ||
return MatchSummary.defaultGetByMatchId(CustomMatchSummary, args, {width = '400px', teamStyle = 'bracket'}) | ||
end | ||
|
||
---@param match MatchGroupUtilMatch | ||
---@return MatchSummaryBody | ||
function CustomMatchSummary.createBody(match) | ||
local body = MatchSummary.Body() | ||
|
||
if match.dateIsExact or match.timestamp ~= DateExt.defaultTimestamp then | ||
body:addRow(MatchSummary.Row():addElement( | ||
DisplayHelper.MatchCountdownBlock(match) | ||
)) | ||
end | ||
|
||
Array.forEach(Array.map(match.games, CustomMatchSummary._createGame), FnUtil.curry(body.addRow, body)) | ||
|
||
return body | ||
end | ||
|
||
---@param participants table | ||
---@param opponentIndex integer | ||
---@return table | ||
function CustomMatchSummary._getHeroesForOpponent(participants, opponentIndex) | ||
local characters = {} | ||
for _, participant in Table.iter.pairsByPrefix(participants, opponentIndex .. '_') do | ||
table.insert(characters, participant.character) | ||
end | ||
return characters | ||
end | ||
|
||
---@param game MatchGroupUtilGame | ||
---@param gameIndex integer | ||
---@return MatchSummaryRow | ||
function CustomMatchSummary._createGame(game, gameIndex) | ||
local row = MatchSummary.Row() | ||
local extradata = game.extradata or {} | ||
|
||
row:addClass('brkts-popup-body-game') | ||
:css('font-size', '80%') | ||
:css('padding', '4px') | ||
|
||
local function makeCharacterDisplay(opponentIndex) | ||
return CustomMatchSummary._createCharacterDisplay( | ||
CustomMatchSummary._getHeroesForOpponent(game.participants, opponentIndex), | ||
extradata['team' .. opponentIndex .. 'side'], | ||
opponentIndex == 2 | ||
) | ||
end | ||
|
||
row:addElement(makeCharacterDisplay(1)) | ||
row:addElement(CustomMatchSummary._createCheckMark(game.winner, 1)) | ||
row:addElement(mw.html.create('div') | ||
:addClass('brkts-popup-body-element-vertical-centered') | ||
:wikitext(Abbreviation.make( | ||
Logic.isEmpty(game.length) and ('Game ' .. gameIndex) or game.length, | ||
Logic.isEmpty(game.length) and ('Game ' .. gameIndex .. ' picks') or 'Match Length' | ||
)) | ||
) | ||
row:addElement(CustomMatchSummary._createCheckMark(game.winner, 2)) | ||
row:addElement(makeCharacterDisplay(2)) | ||
|
||
if Logic.isNotEmpty(game.comment) then | ||
row:addElement(MatchSummary.Break():create()) | ||
row:addElement(mw.html.create('div'):css('margin', 'auto'):wikitext(game.comment)) | ||
end | ||
|
||
return row | ||
end | ||
|
||
---@param winner integer|string | ||
---@param opponentIndex integer | ||
---@return Html | ||
function CustomMatchSummary._createCheckMark(winner, opponentIndex) | ||
return mw.html.create('div') | ||
:addClass('brkts-popup-spaced') | ||
:css('line-height', '17px') | ||
:css('margin-left', '1%') | ||
:css('margin-right', '1%') | ||
:wikitext( | ||
winner == opponentIndex and ICONS.winner | ||
or winner == 0 and ICONS.draw | ||
or Logic.isNotEmpty(winner) and ICONS.loss | ||
or ICONS.empty | ||
) | ||
end | ||
|
||
---@param characters {name: string, active: boolean}[]? | ||
---@param side string? | ||
---@param reverse boolean? | ||
---@return Html | ||
function CustomMatchSummary._createCharacterDisplay(characters, side, reverse) | ||
local wrapper = mw.html.create('div') | ||
:addClass('brkts-popup-body-element-thumbs') | ||
:addClass('brkts-popup-body-element-thumbs-' .. (reverse and 'right' or 'left')) | ||
:addClass('brkts-champion-icon') | ||
|
||
local function makeCharacterIcon(character) | ||
return CharacterIcon.Icon{ | ||
character = character, | ||
size = SIZE_HERO, | ||
} | ||
end | ||
|
||
local function characterDisplay(character, showName) | ||
local display = mw.html.create('div') | ||
if not showName then | ||
display:node(makeCharacterIcon(character)) | ||
return display | ||
end | ||
if reverse then | ||
display:wikitext(character):wikitext(' '):wikitext(makeCharacterIcon(character)) | ||
else | ||
display:node(makeCharacterIcon(character)):wikitext(' '):wikitext(character) | ||
end | ||
return display | ||
end | ||
|
||
local characterDisplays = Array.map(characters or {}, function (character) | ||
return characterDisplay(character, #characters == 1) | ||
end) | ||
|
||
if reverse then | ||
characterDisplays = Array.reverse(characterDisplays) | ||
end | ||
|
||
Array.forEach(characterDisplays, FnUtil.curry(wrapper.node, wrapper)) | ||
|
||
return wrapper | ||
end | ||
|
||
return CustomMatchSummary |
Oops, something went wrong.