Final Fantasy Wiki
Advertisement
Final Fantasy Wiki

Documentation for this module may be created at Module:FFVII enemy stats/doc

p = {}

local getArgs = require("Dev:Arguments").getArgs

function stat(basestat, aichange, multiply, mod)
    local calc = statcalc(basestat, aichange, multiply, mod)
    return tonumber(calc) and mw.language.getContentLanguage():formatNum(tonumber(calc)) or calc

end

function statcalc(basestat, aichange, multiply, mod)
    local totalstat
    if multiply then
        basestat = math.floor(basestat * multiply)
    end
    if aichange then
        local op = aichange:sub(1,1)
        if op == "+" then
            totalstat = basestat + aichange:sub(2)
        elseif op == "-" then
            totalstat = basestat - aichange:sub(2)
        elseif op == "/" then
            totalstat = basestat / aichange:sub(2)
        elseif op == "*" then
            totalstat = basestat * aichange:sub(2)
        else
            totalstat = aichange
        end
    else
        totalstat = basestat
    end
    if mod and tonumber(totalstat) then
        totalstat = (mod + totalstat) % mod
    end
    return totalstat
end

p.hp = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, false)
end

p["hp bsq"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, 2, false)
end

p.mp = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, false)
end

p.attack = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, 0x100)
end

p["attack bsq"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, 1.25, 0x100)
end

p["magic atk"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, 0x100)
end

p["magic atk bsq"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, 1.25, 0x100)
end

p.defense = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, 2, false)
end

p["magic def"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, 2, false)
end

p.dexterity = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, false)
end

p["defense%"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, false)
end

p["luck"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, false)
end

p["exp"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, false)
end

p["ap"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, false)
end

p["gil"] = function(frame)
    local args = frame.args
    local basestat, aichange = args[1], args[2]
    if aichange == "" then aichange = nil end
    return stat(basestat, aichange, false, false)
end

p.sense = function(frame)
    local args = frame.args
    local immtext, nontext, bsqtext = "Immune", "-", "Immune in Battle Square"
    local basehp, aihp, bsq = args[1], args[2], args[3]~=""
    if aihp == "" then aihp = nil end
    local totalhp = statcalc(basehp, aihp, false, false)+0
    if 30000 <= totalhp then return immtext end
    if bsq then
        local bsqhp = statcalc(basehp, aihp, 2, false)+0
        if bsqhp < 30000 then return nontext end
        return bsqtext
    end
    return nontext
end

p.steal = function(frame)
 	local args = getArgs(frame)
    local data = {
        { args[1], tonumber(args[2]) or 0 },
        { args[3], tonumber(args[4]) or 0 },
        { args[5], tonumber(args[6]) or 0 },
        { args[7], tonumber(args[8]) or 0 }
    }
    
    local outtext = {}
    
    local increment = 0
    for i=1, 4 do
        if data[i][1] then
            increment = increment + 1
            outtext[#outtext+1] = "Slot " .. increment .. ": " .. data[i][1] .. " [" .. data[i][2] .. "]"
        end
    end

    if #outtext == 0 then return "Nothing" end
    return table.concat(outtext, '<div style="clear:both"></div>')
end

p.stealratetable = function(frame)
 	local args = getArgs(frame)
    local data = {
        level = args.level,
        { item = args["1 item"], rate = tonumber(args["1 rate"]) or 63 },
        { item = args["2 item"], rate = tonumber(args["2 rate"]) or 63 },
        { item = args["3 item"], rate = tonumber(args["3 rate"]) or 63 },
        { item = args["4 item"], rate = tonumber(args["4 rate"]) or 63 },
    }
    
    
    local tbl = mw.html.create("table")
        :addClass("article-table")
        :addClass("FFVII")
    
    local headerrow = tbl:tag("tr")
        :addClass("a")
        :tag("th")
            :wikitext("Player level")
            :done()


    local steals = {}

    for item=1, 4 do
        if data[item].item then
            steals[#steals+1] = item
            headerrow:tag("th")
                :wikitext("Slot " .. #steals .. ":<br/>" .. data[item].item)
        end
    end
    
    local sneakglovelevel = data.level + 60
    local maxlv = sneakglovelevel > 99 and 100 or 99

    local ratefmtcache = {}
    local levelrates = {}
    
    for level=1, maxlv do
        local ratefmtcache = ratefmtcache
        levelrates[level] = {}
        
        local iterate = 0
        local sparerate = 1
        local compounddenom = 1
        
        local levelindex = level

        if level == 100 then
            level = data.level + 60--this works because of how Lua for loops work
        --    leveldisplay = "Sneak Glove"
        --elseif sneakglovelevel == level then
        --    leveldisplay = leveldisplay .. " (Sneak Glove minimum)"
        end

        for iterate=1, #steals do
            local item = steals[iterate]

            local lvdifference = level - data.level + 40
            local lvfactor = math.floor(512 * lvdifference / 100)
            local itemchance = data[item].rate
            local chance = math.floor(itemchance * lvfactor / 255)
            if chance > 63 then chance = 63 end
            if chance < 0 then chance = 0 end

            local rate = chance + 1
            levelrates[levelindex][iterate] = rate

            compounddenom = compounddenom * 64
            
            local ratefmt
            if ratefmtcache[rate] then
                ratefmt, sparerate = ratefmtcache[rate].ratefmt, ratefmtcache[rate].sparerate
            else
                local newsparerate = sparerate*64
                local thiscompoundrate = sparerate*rate
    
                local ratepc = math.floor((10000/compounddenom)*thiscompoundrate)/100
                if thiscompoundrate ~= 0 and ratepc == 0 then
                    ratepc = "<0.01"
                end
    
                if iterate == 1 then
                    ratefmt = '<abbr title="' .. rate .. '/64' .. '">' .. ratepc .. '%</abbr>'
                else
                    ratefmt = '<abbr title="' .. rate .. '/64 (compound: ' .. thiscompoundrate .. '/' .. compounddenom .. ')' .. '">' .. ratepc .. '%</abbr>'
                end
    
                sparerate = newsparerate - thiscompoundrate
                
                ratefmtcache[rate] = { ratefmt = ratefmt, sparerate = sparerate}
            end
            ratefmtcache = ratefmtcache[rate]
        end
    end

    if #steals == 1 then
        local currentrate = levelrates[1][1]
        local firstlevel = 1
        for level=1, maxlv do
            if level >= 99 or levelrates[level+1][1] ~= currentrate then
                local levelnotation = firstlevel
                if level == 100 then
                    levelnotation = "Sneak Glove"
                elseif firstlevel ~= level then
                    levelnotation = levelnotation .. " - " .. level
                end
                local tr = tbl:tag("tr")
                    :tag("th")
                        :addClass("b")
                        :wikitext(levelnotation)
                    :tag("td")
                        :wikitext(ratefmtcache[currentrate].ratefmt)
                    :done()

                if levelrates[level+1] then
                    currentrate = levelrates[level+1][1]
                    firstlevel = level+1
                end
            end
        end
    else

        local collapsibletr = {
            [1] = true,
            [10] = true,
            [20] = true,
            [30] = true,
            [40] = true,
            [50] = true,
            [60] = true,
            [70] = true,
            [80] = true,
            [90] = true,
            [99] = true,
            [100] = true,
            [sneakglovelevel] = true
        }
    
        for level=1, maxlv do
            local iterate = 0
    
            local collapsiblestate = ""
            if collapsibletr[level] then
                if collapsibletr[level+1] or level==maxlv then
                    collapsiblestate = "uncollapsible"
                else
                    collapsiblestate = "collapsibletr collapsed"
                end
            end
    
            local leveldisplay = level
            local levelindex = level
    
            if level == 100 then
                level = data.level + 60--this works because of how lua for loops work
                leveldisplay = "Sneak Glove"
            --elseif sneakglovelevel == level then
            --    leveldisplay = leveldisplay .. " (Sneak Glove minimum)"
            end
    
            local tr = tbl:tag("tr")
                :addClass(collapsiblestate)
                :tag("th")
                    :addClass("b")
                    :wikitext(leveldisplay)
                    :done()

            local ratefmtcache = ratefmtcache
            for iterate=1, #steals do
                local rate = levelrates[levelindex][iterate]
                ratefmtcache = ratefmtcache[rate]
                tr:tag("td")
                    :wikitext(ratefmtcache.ratefmt)
            end

        end
    end

    return "Sneak Glove minimum LV: " .. sneakglovelevel .. tostring(tbl)
end

p.drop = function(frame)
 	local args = getArgs(frame)
    local data = {
        { args[1], tonumber(args[2]) or 0 },
        { args[3], tonumber(args[4]) or 0 },
        { args[5], tonumber(args[6]) or 0 },
        { args[7], tonumber(args[8]) or 0 }
    }
    
    local outtext = {}
    
    local iterate = 0
    local sparerate = 1
    local compounddenom = 1

    for i=1, 4 do
        if data[i][1] then
            iterate = iterate + 1--in case e.g. drop 3 is used but drop 2 isn't

            local rate = data[i][2] + 1

            compounddenom = compounddenom * 64
            
            local newsparerate = sparerate*64
            local thiscompoundrate = sparerate*rate

            ratepc = math.floor((10000/compounddenom)*thiscompoundrate)/100

            local ratefmt
            if iterate == 1 then
                ratefmt = '<abbr title="' .. rate .. '/64' .. '">' .. ratepc .. '%</abbr>'
            else
                ratefmt = '<abbr title="' .. rate .. '/64 (compound: ' .. thiscompoundrate .. '/' .. compounddenom .. ')' .. '">' .. ratepc .. '%</abbr>'
            end

            sparerate = newsparerate - thiscompoundrate

            outtext[#outtext+1] = data[i][1] .. " (" .. ratefmt .. ")"
        end
    end

    if #outtext == 0 then return "Nothing" end
    return table.concat(outtext, '<div style="clear:both"></div>')
end

p.manipulate = function(frame)
 	local args = getArgs(frame)
    local data = {
        args[1], args[2], args[3]
    }
    
    if #data == 0 then return "No abilities" end
    
    return table.concat(data, "<br/>")

end

return p
Advertisement