Documentation for this module may be created at Module:Match/Dota/doc
local getArgs = require('Module:Arguments').getArgs
local cargo = mw.ext.cargo
local html = require('Module:MatchHTML')
local DotaMatch = {}
local heroesData = mw.loadData('Module:Data/Dota/Heroes')
local VariablesLua = mw.ext.VariablesLua
-- add picks/bans to hover
function DotaMatch.main(map, hover, i)
local mapHeader = mw.html.create('div'):wikitext('Map ' .. i .. ' '):attr('style', 'font-size: 0.9rem;')
-- VODs etc
if map.yt then
mapHeader:wikitext('[[File:Youtube.png|20x20px|https://www.youtube.com/watch?v=' .. map.yt .. ']]')
end
if map.id then
mapHeader:wikitext('[[File:Dotabuff.png|20x20px|https://www.dotabuff.com/matches/' .. map.id .. ']]')
mapHeader:wikitext('[[File:Datdota.png|20x20px|https://www.datdota.com/matches/' .. map.id .. ']]')
mapHeader:wikitext('[[File:Stratz.png|20x20px|https://stratz.com/matches/' .. map.id .. ']]')
end
hover:node(mapHeader)
local dire = map.dire or 'unknown'
local picks = mw.html.create('div'):addClass('details-game')
local p1picks = mw.html.create('div'):addClass(dire == '1' and 'details-picks dire' or 'details-picks radiant')
local p2picks = mw.html.create('div'):addClass(dire == '2' and 'details-picks dire' or 'details-picks radiant')
local iconSize = '28px'
-- Loop through first teams picks
if map.p1picks then
local p1picksSplit = mw.text.split(map.p1picks, ',')
for j = 1, #p1picksSplit do
local hero = getHero(mw.text.trim(p1picksSplit[j]))
--p1picks:wikitext('[[File:' .. w .. '-icon.png|20px]]')
p1picks:node(mw.html.create('div'):wikitext('[[File:' .. hero .. '.png|' .. iconSize .. '|' .. hero .. ']]'))
end
end
-- create the duration/winner part
local duration = mw.html.create('div'):addClass('details-duration')
:node(mw.html.create('div'):wikitext(map.winner == '1' and 'W' or ''))
:node(mw.html.create('div'):node(mw.html.create('abbr'):attr('title', 'Map duration'):wikitext(map.duration)))
:node(mw.html.create('div'):wikitext(map.winner == '2' and 'W' or ''))
-- Loop through second teams picks
if map.p2picks then
local p2picksSplit = mw.text.split(map.p2picks, ',')
for j = 1, #p2picksSplit do
local hero = getHero(mw.text.trim(p2picksSplit[j]))
--p1picks:wikitext('[[File:' .. w .. '-icon.png|20px]]')
p2picks:node(mw.html.create('div'):wikitext('[[File:' .. hero .. '.png|' .. iconSize .. '|' .. hero .. ']]'))
end
end
hover:node(picks:node(p1picks):node(duration):node(p2picks))
local bans = mw.html.create('div'):addClass('details-game')
local p1bans = mw.html.create('div'):addClass('details-picks'):addClass( dire == '1' and 'details-picks dire' or 'details-picks radiant')
local p2bans = mw.html.create('div'):addClass('details-picks'):addClass( dire == '2' and 'details-picks dire' or 'details-picks radiant')
-- Loop through first teams bans
if map.p1bans then
local p1bansSplit = mw.text.split(map.p1bans, ',')
for j = 1, #p1bansSplit do
local hero = getHero(mw.text.trim(p1bansSplit[j]))
--p1picks:wikitext('[[File:' .. w .. '-icon.png|20px]]')
p1bans:node(mw.html.create('div'):wikitext('[[File:' .. hero .. '.png|' .. iconSize .. '|' .. hero .. ']]'))
end
end
-- Loop through second teams bans
if map.p2bans then
local p2bansSplit = mw.text.split(map.p2bans, ',')
for j = 1, #p2bansSplit do
local hero = getHero(mw.text.trim(p2bansSplit[j]))
--p1picks:wikitext('[[File:' .. w .. '-icon.png|20px]]')
p2bans:node(mw.html.create('div'):wikitext('[[File:' .. hero .. '.png|' .. iconSize .. '|' .. hero .. ']]'))
end
end
hover:node(bans:node(mw.html.create('div'):addClass('w-100'):wikitext('Bans')):node(mw.html.create('div'):addClass('w-100'):node(p1bans):node(p2bans)))
return ''
end
function DotaMatch.picksBans(maps, p1_api, p2_api, hover, results, frame)
if #maps > 0 then
for i = 1, #maps do
local map = maps[i]
if map.id and map.winner and not map.p1picks and not map.p1bans then
local tables = 'Maps_Dota'
local fields = 'winner, p1picks, p2picks, p1bans, p2bans, dire, fp, p1kills, p2kills, duration'
local whereStr = 'api_id="' .. map.id .. '" AND winner IS NOT NULL'
local cargoArgs = {
where = whereStr
}
local results = cargo.query(tables, fields, cargoArgs)
if #results == 0 then
local mapData = mw.ext.externaldata.getWebData({
url = 'https://api.opendota.com/api/matches/' .. map.id,
format = 'CSV with header',
})
if mapData then
local json = mw.text.jsonDecode(mapData.__text)
local pickBans = json.picks_bans
map.p1picks = ''
map.p2picks = ''
map.p1bans = ''
map.p2bans = ''
local fp = nil
for j = 1, #pickBans do
local selection = pickBans[j]
if j == 1 then fp = selection.team end
if selection.is_pick then
map['p' .. selection.team + 1 .. 'picks'] = map['p' .. selection.team + 1 .. 'picks'] .. getHero(selection.hero_id) .. ','
else
map['p' .. selection.team + 1 .. 'bans'] = map['p' .. selection.team + 1 .. 'bans'] .. getHero(selection.hero_id) .. ','
end
end
map.p1picks = removeEndComma(map.p1picks)
map.p2picks = removeEndComma(map.p2picks)
map.p1bans = removeEndComma(map.p1bans)
map.p2bans = removeEndComma(map.p2bans)
-- Check if dire team had api_id entered
local dire_id = json.dire_team_id
local dire = dire_id == tonumber(p1_api) and 1 or dire_id == tonumber(p2_api) and 2 or nil
-- If dire team doesn't have api_id entered, then check if maybe radiant does
if dire == nil then
local radiant_id = json.radiant_team_id
local radiant = radiant_id == tonumber(p1_api) and 1 or radiant_id == tonumber(p2_api) and 2 or nil
if radiant then dire = radiant == 1 and 2 or 1 end
end
-- set winner
-- if json.radiant_win then
-- map.winner = dire == 1 and 2 or 1
-- else
-- map.winner = dire == 1 and 1 or 2
-- end
if not map.dire and dire then
map.dire = dire
end
if not map.fp and fp ~= nil then
if fp == 0 then
map.fp = dire == 1 and 2 or 1
else
map.fp = dire
end
end
local radiantKills = json.radiant_score
local direKills = json.dire_score
if not map.p1kills then
map.p1kills = dire == 1 and direKills or radiantKills
end
if not map.p2kills then
map.p2kills = dire == 2 and direKills or radiantKills
end
local duration = json.duration
local seconds = duration % 60
local minutes = (duration - seconds) / 60
if seconds < 10 then seconds = "0" .. tostring(seconds) end
map.duration = minutes .. ':' .. seconds
end
else
map.p1picks = results[1].p1picks
map.p2picks = results[1].p2picks
map.p1bans = results[1].p1bans
map.p2bans = results[1].p2bans
map.dire = results[1].dire
map.fp = results[1].fp
map.p1kills = results[1].p1kills
map.p2kills = results[1].p2kills
map.duration = results[1].duration
end
else
-- Go through normal picks and bans and turn them into proper hero names
if map.p1picks then map.p1picks = listToNames(map, map.p1picks, "p1picks") end
if map.p2picks then map.p2picks = listToNames(map, map.p2picks, "p2picks") end
if map.p1bans then map.p1bans = listToNames(map, map.p1bans, "p1bans") end
if map.p2bans then map.p2bans = listToNames(map, map.p2bans, "p2bans") end
end
frame:callParserFunction{name = '#cargo_store:', args = {_table = 'Maps_Dota', map=i, api_id = map.id, matchID = results[1]._ID, duration = map.duration, p1picks = map.p1picks, p2picks = map.p2picks, p1bans = map.p1bans, p2bans = map.p2bans, dire = map.dire, fp = map.fp, winner = map.winner, p1kills = map.p1kills, p2kills = map.p2kills, yt = map.yt, vod = map.vod}}
DotaMatch.main(map, hover, i, results)
end
end
return map
end
function listToNames(map, list, var)
local split = mw.text.split(list, ',')
map[var] = ''
for i = 1, #split do
map[var] = map[var] .. getHero(mw.text.trim(split[i])) .. ','
map[var] = removeEndComma(map[var])
end
end
function getHero(idOrName)
if type(idOrName) == "string" then idOrName = string.lower(idOrName) end
for _, hero in ipairs(heroesData) do
if hero.id == idOrName then
return hero.localized_name
else
for _, name in ipairs(hero.names) do
if name == idOrName then
return hero.localized_name
end
end
end
end
return "Hero not found " .. idOrName
end
function removeEndComma(inputString)
-- Use the string.match function to check if the string ends with a comma
if inputString:match(",$") then
-- If it does, use string.sub to remove the last character (the comma)
return inputString:sub(1, -2)
else
-- If not, return the input string as it is
return inputString
end
end
return DotaMatch