Module:Ability progression

-- local p = {} local lib      = require('Module:Feature') local userError   = require('Dev:User error') local col = require('Module:color')

function p.pp(frame) local args; if frame.args[1] then args = frame.args else args = frame:getParent.args end local values="" local values2="" local count=30 local fill=18 local fill1=18 local temp,a,b,c local displayformula=args["formula"] local round1=args["round1"] or 2 local round2=args["round"] or args["round2"] or 2 local key1=args["key1"] or "" local key2=args["key"] or args["key2"] or "" local label1=args["label1"] or args["type"] local label2=args["label2"] local orig=mw.text.split(args[1] or "","%;") local orig1=mw.text.split(args[2] or "","%;") local i=1 local s,occurences=string.gsub(args[1] or "","to","") local s,occurences1=string.gsub(args[1] or "","x","") local s,occurences2=string.gsub(args[2] or "","to","") local s,occurences3=string.gsub(args[2] or "","x","") local to=0 local to1=0 if occurences+occurences1~=0 or occurences2+occurences3~=0 then while orig[i]~=nil and orig[i]~="" do           if (string.find(orig[i],"to")~=nil or string.find(orig[i],"x")~=nil) and string.find(orig[i],"%<")==nil then if string.find(orig[i],"x")==nil then start,finish,times=orig[i]:match"(.*) *to *([^ ]*) *([^ ]*)" if start~=nil and finish~=nil and pcall(expr,start.."*2")~=false and pcall(expr,finish.."*2")~=false then if times~="" and times~=nil then times=tonumber(expr(times)) fill=fill-times else to=1 end else fill=fill-1 end else useformula,times=orig[i]:match"([^ ]*) *([^ ]*)" if useformula~=nil and pcall(expr,string.gsub(useformula,"x","1").."*2")~=false then if times~="" and times~=nil then times=tonumber(expr(times)) fill=fill-times else to=1 end else fill=fill-1 end end else fill=fill-1 end i=i+1 end end i=1 if occurences+occurences1~=0 or occurences2+occurences3~=0 then while orig1[i]~=nil and orig1[i]~="" do           if (string.find(orig1[i],"to")~=nil or string.find(orig1[i],"x")~=nil) and string.find(orig1[i],"%<")==nil then if string.find(orig1[i],"x")==nil then start,finish,times=orig1[i]:match"(.*) *to *([^ ]*) *([^ ]*)" if start~=nil and finish~=nil and pcall(expr,start.."*2")~=false and pcall(expr,finish.."*2")~=false then if times~="" and times~=nil then times=tonumber(expr(times)) fill1=fill1-times else to1=1 end else fill1=fill1-1 end else useformula,times=orig1[i]:match"([^ ]*) *([^ ]*)" if useformula~=nil and pcall(expr,string.gsub(useformula,"x","1").."*2")~=false then if times~="" and times~=nil then times=tonumber(expr(times)) fill1=fill1-times else to1=1 end else fill1=fill1-1 end end else fill1=fill1-1 end i=i+1 end end if 18-fill>18-fill1 then if to==0 then fill1=fill1-fill end else if to1==0 then fill=fill-fill1 end end if fill<0 then fill=0 end if fill1<0 then fill1=0 end i=1 while orig[i]~=nil and orig[i]~="" do       if (string.find(orig[i],"to")~=nil or string.find(orig[i],"x")~=nil) and string.find(orig[i],"%<")==nil then if string.find(orig[i],"x")==nil then start,finish,times=orig[i]:match"(.*) *to *([^ ]*) *([^ ]*)" if start~=nil and finish~=nil and pcall(expr,start.."*2")~=false and pcall(expr,finish.."*2")~=false then start=tonumber(expr(start)) finish=tonumber(expr(finish)) if times=="" or times==nil then times=fill fill=0 else times=tonumber(expr(times)) end x=1 while x<=times do                       count=count-1 if count<0 then return userError("Maximum size exceeded", "LuaError") end if x==1 then formula=start else formula=formula+(finish-start)/(times-1) end if values=="" then values=fd(rounding(formula,round2))..key2 values2=rounding(formula,round2)..key2 else values=values.." / "..fd(rounding(formula,round2))..key2 values2=values2.." / "..rounding(formula,round2)..key2 end x=x+1 end else count=count-1 if count<0 then return userError("Maximum size exceeded", "LuaError") end if values=="" then values=fd(rounding(expr(orig[i]),round2))..key2 values2=rounding(expr(orig[i]),round2)..key2 else values=values.." / "..fd(rounding(expr(orig[i]),round2))..key2 values2=values2.." / "..rounding(expr(orig[i]),round2)..key2 end end else useformula,times=orig[i]:match"([^ ]*) *([^ ]*)" if useformula~=nil and pcall(expr,string.gsub(useformula,"x","1").."*2")~=false then if displayformula==nil and (orig[2]==nil or orig[2]=="") then displayformula=useformula end if times=="" or times==nil then times=fill fill=0 else times=tonumber(expr(times)) end x=1 while x<=times do                       count=count-1 if count<0 then return userError("Maximum size exceeded", "LuaError") end formula=string.gsub(useformula,"x",x) if values=="" then values=fd(rounding(expr(formula),round2))..key2 values2=rounding(expr(formula),round2)..key2 else values=values.." / "..fd(rounding(expr(formula),round2))..key2 values2=values2.." / "..rounding(expr(formula),round2)..key2 end x=x+1 end else count=count-1 if count<0 then return userError("Maximum size exceeded", "LuaError") end if values=="" then values=fd(rounding(expr(orig[i]),round2))..key2 values2=rounding(expr(orig[i]),round2)..key2 else values=values.." / "..fd(rounding(expr(orig[i]),round2))..key2 values2=values2.." / "..rounding(expr(orig[i]),round2)..key2 end end end else count=count-1 if count<0 then return userError("Maximum size exceeded", "LuaError") end if values=="" then values=fd(rounding(expr(orig[i]),round2))..key2 values2=rounding(expr(orig[i]),round2)..key2 else values=values.." / "..fd(rounding(expr(orig[i]),round2))..key2 values2=values2.." / "..rounding(expr(orig[i]),round2)..key2 end end i=i+1 end s="" if args["notooltip"]~="true" then s=s..'<span class="pp-tooltip" style="position:relative; border-bottom:1px dotted; cursor:help; color: '       if args["color"]~=nil then            s=s..col.keyword{string.lower(args["color"])}        else            s=s.."inherit"        end        s=s..';"' if label1~=nil then s=s..' data-label1="'..mw.ustring.gsub(string.gsub(string.gsub(label1,"'"),""), "^.", mw.ustring.upper)..'"' end if label2~=nil then s=s..' data-label2="'..mw.ustring.gsub(label2,"^.", mw.ustring.upper)..'"' end if displayformula~=nil then s=s..' data-displayformula="'..displayformula..'"' end if values~=nil then s=s..' data-values2="'..values2..'"' end if args[2]~=nil then s=s..' data-values1="'..args[2]..'"' end s=s.." >" end s=s..values if args["notooltip"]~="true" then s=s.." " end return s end

function p.pptooltip(frame) local args; if frame.args[1] then args = frame.args else args = frame:getParent.args end local label1=args["label1"] if label1=="" then label1="Level" end local label2=args["label2"] if label2=="" then label2="Value" end local orig1=mw.text.split(args["values1"],"%/") local orig2=mw.text.split(args["values2"],"%/") s="" s=s..' ' return s end

function p.ap(frame) local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end local values="" local count=6 local fill local formula if args["skill"]=="R" then fill=3 else fill=5 end i=1 local temp,a,b,c local round=args["round"] or nil while args[i]~=nil do       if string.find(args[i],"to")~=nil and string.find(args[i],"%<")==nil then start,finish,times=args[i]:match"(.*) *to *([^ ]*) *([^ ]*)" if start~=nil and finish~=nil and pcall(expr,start.."*2")~=false and pcall(expr,finish.."*2")~=false then start=tonumber(expr(start)) finish=tonumber(expr(finish)) if times=="" or times==nil then times=fill fill=0 else times=tonumber(expr(times)) end x=1 while x<=times do                   count=count-1 if count<0 then return userError("Maximum size exceeded", "LuaError") end if x==1 then formula=start else formula=formula+(finish-start)/(times-1) end if values=="" then values=fd(rounding(formula,round)) else values=values.." / "..fd(rounding(formula,round)) end x=x+1 end else count=count-1 if count<0 then return userError("Maximum size exceeded", "LuaError") end if values=="" then values=fd(rounding(args[i],round)) else values=values.." / "..fd(rounding(args[i],round)) end end else count=count-1 if count<0 then return userError("Maximum size exceeded", "LuaError") end if values=="" then values=fd(rounding(args[i],round)) else values=values.." / "..fd(rounding(args[i],round)) end end i=i+1 end return values end

function expr(val) local val=string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(string.gsub(val," ",""),"%/"," / "),"%*"," * "),"%+"," + "),"%-"," - "),"%^"," %^ "),"([^%d%(%)]) %- ","%1-"),"([^%d%(%)]) %+ ","%1+") local i=1 local j=1 local a,b,switcher,switcher2,switcher3,temp while i>0 do       while j>0 do            temp=val if string.find(val,"%)")~=nil then               switchertemp=mw.text.split( val, "%)") temp=last(switchertemp[1],"%(")           end            if string.find(temp," %^ ")~=nil then                a=mw.text.split(temp," %^ ")                b=mw.text.split(a[2]," ")                switcher=last( a[1]," ")                switcher2=b[1]                switcher3=switcher^switcher2                if string.find(switcher2,"%-")~=nil then                     switcher2="%-"..switcher2*(-1)                end                val=string.gsub(val,switcher.." %^ "..switcher2,switcher3)                break            end            if string.find(temp," %/ ")~=nil then                a=mw.text.split(temp," %/ ")                b=mw.text.split(a[2]," ")                switcher=last( a[1]," ")                switcher2=b[1]                switcher3=switcher/switcher2                if string.find(switcher2,"%-")~=nil then                     switcher2="%-"..switcher2*(-1) end val=string.gsub(val,switcher.." %/ "..switcher2,switcher3) break end if string.find(temp," %* ")~=nil then a=mw.text.split( temp," %* ") b=mw.text.split(a[2]," ") switcher=last( a[1]," ") switcher2=b[1] switcher3=switcher*switcher2 if string.find(switcher2,"%-")~=nil then switcher2="%-"..switcher2*(-1) end val=string.gsub(val,switcher.." %* "..switcher2,switcher3) break end if string.find(temp," %- ")~=nil then a=mw.text.split( temp," %- ") b=mw.text.split(a[2]," ") switcher=last( a[1]," ") switcher2=b[1] if switcher=="" then if string.find(switcher2,"%-")~=nil then switcher2="%-"..switcher2*(-1) end val=string.gsub(val," %- "..switcher2,"%-"..switcher2) break else switcher3=switcher-switcher2 if string.find(switcher2,"%-")~=nil then switcher2="%-"..switcher2*(-1) end val=string.gsub(val,switcher.." %- "..switcher2,switcher3) break end end if string.find(temp," %+ ")~=nil then a=mw.text.split( temp," %+ ") b=mw.text.split(a[2]," ") switcher=last( a[1]," ") switcher2=b[1] if switcher=="" then if string.find(switcher2,"%-")~=nil then switcher2="%-"..switcher2*(-1) end val=string.gsub(val," %+ "..switcher2,switcher2) break else switcher3=switcher+switcher2 if string.find(switcher2,"%-")~=nil then switcher2="%-"..switcher2*(-1) end val=string.gsub(val,switcher.." %+ "..switcher2,switcher3) break end end if string.find(val,"%)")~=nil then               if string.find(temp,"%-")~=nil then                     temp="%-"..temp*(-1)                end                val=string.gsub(val,"%("..temp.."%)",temp)                break            else                i=0            end            break        end    end    return temp end

function last(val,sign) local a=mw.text.split(val,sign) local j=1 while j>0 do       if a[j] ~=nil then j=j+1 else break end end return a[j-1] end

function fd(val) if string.find(val,"[0-9]") == nil or string.find(val,"%.") == nil then return val end local a,b,c if string.find(val,"span") ~= nil then a,b,c = val:match"([^.]*).(.*) (.*)" if string.find(val,"span")<=string.find(val,"%.") then return a .. ". " .. b .. " " .. c       else return a .. ". " .. b .. " " .. c       end else a,b,c = val:match"([^.]*).([0-9]*)(.*)" return a .. ". " .. b .. " " .. c   end end

function rounding(val, decimals) local round local val=tostring(val) if decimals==nil or string.find(val,"[0-9]")==nil or string.find(val,"<span")~=nil or string.find(val,"%.")==nil then return val end local a,b,c,d a,b,c,d = val:match"([^0-9]*)([0-9]*).([0-9]*)(.*)" val=tonumber(b.."."..c)   if decimals=="abs" then round=math.abs(val) end if decimals=="floor" then round=math.floor(val) end if decimals=="ceil" then round=math.ceil(val) end if round==nil then local mult = 10^(decimals) round=math.floor(val * mult + 0.5) / mult end return a..round..d end

return p

-- --