欢迎来到气球塔防6 BWIKI!
除特殊说明外,本站内容采用CC BY-NC-SA 4.0协议。
欢迎各位到留言板留言或者加入QQ群:950568164

全站通知:

模块:Rounds

来自气球塔防6WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:Rounds/doc创建

-- 界面的灵感来源:http://topper64.co.uk/nk/btd6/rounds/regular
-- 但代码不是,yeah
local p = {}

local incomeSets = mw.text.jsonDecode(mw.title.new("Module:Rounds/IncomeSets.json"):getContent())
local roundSet = ""
local isSuper = function(round)
	if string.find(roundSet, "Rogue", 1, true) then
		return round > 30
	end
	return round > 80
end

local getIncomeSet = function(set)
	if set == "AcceleratedRoundSet" then
		return incomeSets["Accelerated"]
	elseif string.find(set, "Rogue", 1, true) then
		return incomeSets["Rogue"]
	elseif set == "EnduranceRoundSet" then
		return incomeSets["Endurance"]
	else
		return incomeSets["Default"]
	end
end

local mround = function(num, idp)
    local mult = 10 ^ (idp or 0)
    return math.floor(num * mult + 0.5) / mult
end

local bloons = {
    -- {总金钱, 外壳血量, {{子气球,子气球数}, ...}}
    -- 红气球的子气球为nil
    Red = {1, 1, nil},
    Blue = {2, 1, {{"Red", 1}}},
    Green = {3, 1, {{"Blue", 1}}},
    Yellow = {4, 1, {{"Green", 1}}},
    Pink = {5, 1, {{"Yellow", 1}}},
    Black = {11, 1, {{"Pink", 2}}},
    White = {11, 1, {{"Pink", 2}}},
    Purple = {11, 1, {{"Pink", 2}}},
    Zebra = {23, 1, {{"Black", 1}, {"White", 1}}},
    Lead = {23, 1, {{"Black", 2}}},
    Rainbow = {47, 1, {{"Zebra", 2}}},
    Ceramic = {95, 10, {{"Rainbow", 2}}},
    Moab = {381, 200, {{"Ceramic", 4}}},
    Bfb = {1525, 700, {{"Moab", 4}}},
    Zomg = {6101, 4000, {{"Bfb", 4}}},
    Ddt = {381, 400, {{"Ceramic", 4}}},
    Bad = {13346, 20000, {{"Ddt", 3}, {"Zomg", 2}}}
}

local bloonsSuper = {
    -- {总金钱, 外壳血量, {{子气球,子气球数}, ...}}
    -- 红气球的子气球为nil
    Red = {1, 1, nil},
    Blue = {2, 1, {{"Red", 1}}},
    Green = {3, 1, {{"Blue", 1}}},
    Yellow = {4, 1, {{"Green", 1}}},
    Pink = {5, 1, {{"Yellow", 1}}},
    Black = {6, 1, {{"Pink", 1}}},
    White = {6, 1, {{"Pink", 1}}},
    Purple = {6, 1, {{"Pink", 1}}},
    Zebra = {7, 1, {{"Black", 1}}},
    Lead = {7, 1, {{"Black", 1}}},
    Rainbow = {8, 1, {{"Zebra", 1}}},
    Ceramic = {95, 60, {{"Rainbow", 1}}},
    Moab = {381, 200, {{"Ceramic", 4}}},
    Bfb = {1525, 700, {{"Moab", 4}}},
    Zomg = {6101, 4000, {{"Bfb", 4}}},
    Ddt = {381, 400, {{"Ceramic", 4}}},
    Bad = {13346, 20000, {{"Ddt", 3}, {"Zomg", 2}}}
}

local canFortified = function(bloon)
    return string.find("LeadCeramicMoabBfbZomgDdtBad", bloon) ~= nil
end

local isBlimp = function(bloon)
    return string.find("MoabBfbZomgDdtBad", bloon) ~= nil
end

local getEndOfRoundCash = function(round)
    return 100 + round
end

local getCashPerPop = function(round)
    local set = getIncomeSet(roundSet)
    for i, threshold in ipairs(set["thresholds"]) do
        if round <= threshold[1] then
            return threshold[2]
        end
    end
    return set["final"]
end

local getBloonBaseName = function(bloon)
    local base = string.gsub(string.gsub(string.gsub(bloon, "Fortified", ""), "Regrow", ""), "Camo", "")
    local isFortified = string.find(bloon, "Fortified") ~= nil
    return base, isFortified
end

local getBloonBaseAndFileName = function(bloon)
    local base = getBloonBaseName(bloon)
    local file = bloon
    if isBlimp(base) then
        file = string.gsub(bloon, "Camo", "") .. "Icon" -- ddt需要去掉camo
    end
    return base, file
end

local getBlimpHpMultiplier = function(round)
    if round <= 80 then
        return 1
    end
    if round <= 100 then
        return (round - 30) / 50
    end
    if round <= 124 then
        return (round - 72) / 20
    end
    if round <= 150 then
        return (3 * round - 320) / 20
    end
    if round <= 250 then
        return (7 * round - 920) / 20
    end
    if round <= 300 then
        return (2 * round - 417) / 2
    end
    if round <= 400 then
        return (3 * round - 717) / 2
    end
    if round <= 500 then
        return (5 * round - 1517) / 2
    end
    return (10 * round - 4017) / 2
end

local getBloonRbe
getBloonRbe = function(bloon, round, isFortified)
    if bloon == "Red" then
        return 1
    end -- 红气球直接返回1

    local b = {}
    if isSuper(round) then
        b = bloonsSuper
    else
        b = bloons
    end

    local rbe = b[bloon][2]
    if isBlimp(bloon) then
        rbe = rbe * getBlimpHpMultiplier(round)
    end
    if isFortified then
        if bloon == "Lead" then
            rbe = rbe * 4
        else
            rbe = rbe * 2
        end
    end
    for i, subs in ipairs(b[bloon][3]) do
        rbe = rbe + getBloonRbe(subs[1], round, (isFortified and canFortified(subs[1]))) * subs[2]
    end
    return rbe
end

local getRoundCash = function(round, roundTable)
    local cash = 0
    local b
    if isSuper(round) then
        b = bloonsSuper
    else
        b = bloons
    end
    for i, emission in ipairs(roundTable) do
        local base = getBloonBaseName(emission['bloon'])
        cash = cash + b[base][1] * getCashPerPop(round) * emission['count']
    end
    if roundSet == "EnduranceRoundSet" then
        return cash
    end
    return cash + getEndOfRoundCash(round)
end

local getRoundXp = function(round)
    if round <= 20 then
        return round * 20 + 20
    end
    if round <= 50 then
        return round * 40 - 380
    end
    return round * 90 - 2880
end

local getRoundRbe = function(round, roundTable)
    local rbe = 0
    local b
    if isSuper(round) then
        b = bloonsSuper
    else
        b = bloons
    end
    for i, emission in ipairs(roundTable) do
        local base, isFortified = getBloonBaseName(emission['bloon'])
        rbe = rbe + getBloonRbe(base, round, isFortified) * emission['count']
    end
    return rbe
end

local getRoundLength = function(round, roundTable)
    local endTime = 0
    for i, emission in ipairs(roundTable) do
        if emission['end'] > endTime then
            endTime = emission['end']
        end
    end
    return endTime
end

local roundTableHead = [=[{|style="width:100%;border:2px solid #000;text-align:center"
|-style="background:#EAECF0"
|style="width:8%;border: 2px solid #000"|'''回合'''
|style="width:23%;border: 2px solid #000"|'''金币'''
|style="width:23%;border: 2px solid #000"|'''经验'''
|style="width:23%;border: 2px solid #000"|'''RBE'''
|style="width:23%;border: 2px solid #000"|'''时间/s''']=]

local roundTableStats = [=[
|- class="roundtableline-%d"
| style="border: 1px solid #888" | %s
| style="border: 1px solid #888" | %s
| style="border: 1px solid #888" | %s
| style="border: 1px solid #888" | %s
| style="border: 1px solid #888" | %s]=]

local roundTableBar = [=[|- class="roundtablebloon-%d"
| [[file:%s.png|15px]]x%d
| colspan="4" | <span class="popup"><span style="display:inline-block;width:%f%%;margin-left:%f%%"><div class="bloon-bar bloon-bar-%s"></div></span><span style="display:none;width:auto;" data-size="500"><div style="line-height:20px;font-size:12px">%.4fs-%.4fs</div></span></span>]=]

local roundTableTail = "|}"

-- 方便MediaWiki:RoundCalculator.js读取最后一回合,减少一次web调用,也方便一般用户添加新回合组
local endRoundCap = '<div id="end-round-cap" style="display:none">%d</div>'

function p.rounds(frame)
    roundSet = frame.args[1]
    local rounds = mw.text.jsonDecode(mw.title.new("Module:Rounds/" .. roundSet .. ".json"):getContent())
    local lines = {roundTableHead}
    for i, round in ipairs(rounds) do
        local roundNumber, roundCash, roundXp, roundRbe, roundLength = i, getRoundCash(i, round),
            getRoundXp(i), getRoundRbe(i, round), getRoundLength(i, round)
        table.insert(lines, string.format(roundTableStats, roundNumber, roundNumber, roundCash, roundXp, roundRbe,
            mround(roundLength / 60, 4)))
        for j, emission in ipairs(round) do
            local baseName, fileName = getBloonBaseAndFileName(emission['bloon'])
            table.insert(lines, string.format(roundTableBar, roundNumber, fileName, emission['count'],
                (emission['end'] - emission['start']) / roundLength * 100, emission['start'] / roundLength * 100,
                baseName, mround(emission['start'] / 60, 4), mround(emission['end'] / 60, 4)))
        end
    end
    table.insert(lines, roundTableTail)
    table.insert(lines, string.format(endRoundCap, #rounds))
    return table.concat(lines, '\n')
end

return p

-- p.rounds({ args = { "DefaultRoundSet" } })