Módulo:Skill calc
Ir para navegação
Ir para pesquisar
Documentação do módulo
Esta documentação é transcluída de Predefinição:Sem documentação/doc. [editar] [atualizar]
Este módulo não possui nenhuma documentação. Por favor, considere adicionar uma documentação em Módulo:Skill calc/doc. [editar]
Módulo:Skill calc requer
.
--[=[
dependencies
[[Module:Addcommas]]
[[Module:Tables]]
[[Module:Coins]]
[[Module:GETotal]]
[[Module:Number]]
[[Module:Experience]]
[[Module:Silverhawks/data]]
[[Module:Skill_calc/eltGenerator]]
[[Module:Skill_calc/bonusGenerator]]
TODO
Get input on bonus stacking
Making a module to handle bxp jericowrahl 11:25 am MST 11/02/18
Note: Once all existing calculators have been converted, this Module will be cleaned
up to remove any spaghetti code.
To change data in this calculator, navigate to its appropriate page:
e.g. Module:Skill calc/SKILLNAME/data
Follow the guides on that page and try to emulate the items around it.
--]=]
-- <nowiki>
local p = {}
local commas = require('Módulo:Addcommas')._add
local tables = require('Módulo:Tables')
local coins = require('Módulo:Moedas')._amount
local gePrice = require('Módulo:GETotal')._quantity
local numbers = require('Módulo:Number')._round
local level = require('Módulo:Experience').level_at_xp
local xp = require('Módulo:Experience').xp_at_level
local featherExp = require('Módulo:Silverhawks/data')
-- This houses most of the processing power
local eltGenerator = require('Módulo:Skill_calc/eltGenerator')
local bonusGenerator = require('Módulo:Skill_calc/bonusGenerator')
function p.noValue(frame)
local args = frame:getParent().args
local pctExpBoost = 0 -- Account for outfits, avatar, tools, etc
local flatExpBoost = 0 -- Account for flat experience boosts
local currLv, goalLv, currXP, goalXP, remaining
local links,elts
local prayerBoost -- This is needed to account for popular methods
local message, testMessage
if args.testing == "active" then
testMessage = "Esta calculadora está sendo usada para testar novas adições." end
-- These sub-sections have different table elts than their parent skill
local exceptions =
{"Agility-Other", "Divination-Boons", "Divination-Dungeoneering", "Divination-Hall of Memories", "Divination-Hall of Memories (2 tick)", "Divination-Memory-storage bots", "Divination-Other",
"Farming-Curing Animals", "Farming-Raising Animals", "Farming-Manure", "Farming-Testing", "Firemaking-Barbarian", "Firemaking-Char",
"Firemaking-Other", "Firemaking-Incense Sticks (scratch + ashing)", "Prayer-Incense sticks", "Fishing-Dungeoneering", "Flatpacks",
"Forging", "Invention-Manufacturing", "Invention-Manufacturing - Ancient", "Masters", "Milestones", "Mining-Gems", "Multiples", "Rooms", "Runespan - Free",
"Runespan - Members", "Scrolls", "Summoning-Pets", "Summoning-Dungeoneering - Pouches", "Slayer-Assignments", "Tiaras",
"Thieving-Sorceress Garden", "Thieving-Safes", "Woodcutting-Other"}
local exceptionsAgility =
{"Marcos", "Múltiplos", "Outros"}
local exceptionsDiv =
{"Conversion", "Conversion /w Energy", "Divine locations", "Milestones", "Signs and Portents", "Transmutation"}
local exceptionsSlayer =
{"Objetos", "Mestres", "Marcos"}
local exceptionsSmithing =
{"Kethsian", "Masterwork (unfinished)", "Obsidian"}
local bonusExceptions =
{"Urnas", "Dungeon", "Blast furnace"}
-- These skills have no special considerations in Dungeoneering
local basicDungeons =
{"Mineração", "Corte de Lenha"}
-- elite skills
local eliteSkills = {
['Invenção'] = true
}
local isEliteSkill = eliteSkills[args.skill] or false
-- Hold bonuses and boosts
local bonusPct = pctExpBoost
-- Gather all relative experience boosts to find new base experience
if not (args.avatar == nil) and not (args.disp == "Urns") then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
object = "avatar",
pieces = tonumber(args.avatar)
}
end
-- Only elite that gives xp boost is dungeoneering
if not (args.elite == nil) and not (args.disp == "Urnas") and args.skill == "Dungeon" then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
object = "elite",
pieces = tonumber(args.elite)
}
end
-- Some bonuses can not be used on some sub-sections (E.G. Dungeoneering)
if not findItem(bonusExceptions, args.disp) then
if not (args.abyss == nil) and not (args.abyss == 'Não') then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
object = "abismo",
item = args.abyss
}
end
if not (args.extra == nil) and args.abyss == nil then
if not (args.skill == "Divinação" and args.disp == "Harvest") then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
category = args.disp,
object = "extra",
item = args.extra
}
end
end
if not (args.outfit == nil) then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
object = "roupa",
pieces = tonumber(args.outfit)
}
end
if not (args.portable == nil) and (args.portable == "Sim") then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
object = "portável",
pieces = 1
}
end
if not (args.tool == nil) then
flatExpBoost = flatExpBoost +
bonusGenerator
{
skill = args.skill,
object = "ferramenta",
item = args.tool
}
end
--[=[
-- Anachronia spa
if not (args.spa == nil) and args.disp == "Courses" then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
category = args.disp,
object = "spa",
item = args.spa
}
end
--]=]
if not (tonumber(args.custom) == nil) then
if args.abyss == nil or args.abyss == 'Não' then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
category = args.disp,
object = "personalizado",
item = args.custom
}
end
end
if not (args.wild == nil) then
pctExpBoost = pctExpBoost +
bonusGenerator
{
skill = args.skill,
object = "terra selvagem",
item = args.wild
}
end
--[=[
if not (args.age == nil) and args.disp == "Curing Animals" then
pctExpBoost = bonusGenerator
{
skill = args.skill,
category = args.disp,
object = "age",
item = args.age
}
end
--]=]
end
-- Translate goals into experience comparisons
-- Calculate iterations to goal
currLv, currXP, goalLv, goalXP, remaining = remainingExp(args.current, args.goal, args.currToggle, args.goalToggle, isEliteSkill)
-- Try to catch Silverhawk feathers early..
if args.disp == "Penas de falcão de prata" then
local message = silverhawkFeathers(currLv, goalLv, currXP, goalXP, remaining, pctExpBoost)
local msgRet = mw.html.create('div'):css({['font-size'] = "16px", ['font-weight'] = "bold"}):wikitext(message)
return tostring(msgRet)
end
-- Prevent the Wilderness Agility Course with no Demonic Skull bonus from displaying a table (same XP for every level)
--if args.disp == "Wilderness Agility Course" and (args.wild == "No" or args.wild == "Wilderness Sword 2+") then
if (args.testing == "active" and args.disp == "Wilderness Agility Course") then
if (args.wild == "No" or args.wild == "Wilderness Sword 2+") then
local message = wildernessAC(currLv, goalLv, currXP, goalXP, remaining, pctExpBoost)
local msgRet = mw.html.create('div'):css({['font-size'] = "16px", ['font-weight'] = "normal"}):wikitext(message)
return tostring(msgRet)
end
elseif args.disp == "Wilderness Agility Course" then
local message = wildernessAC(currLv, goalLv, currXP, goalXP, remaining, pctExpBoost)
local msgRet = mw.html.create('div'):css({['font-size'] = "16px", ['font-weight'] = "normal"}):wikitext(message)
return tostring(msgRet)
end
-- Hold skill-related data
local dataRet, data
-- Grab Sub-Category Table Data
if args.skill == "Extermínio" and args.disp == "Tarefas" then
dataRet = require('Módulo:Skill calc/Extermínio/Tarefas/data')
data = dataRet(args.disp,args.creature)
elseif args.skill == "Metalurgia" and args.disp == "Equipamento" then
dataRet = require('Módulo:Skill calc/' .. args.skill .. '/data')
data = dataRet(args.equipment)
else
dataRet = require('Módulo:Skill calc/' .. args.skill .. '/data')
data = dataRet(args.disp)
end
table.sort(data, function(a,b) return sortTable(a,b) end )
local ret = mw.html.create('table'):addClass('wikitable sortable sticky-header')
--[=[
-- Find columns from pool
-- Some require specific parameters due to common phrases
--]=]
local eltsRet = require('Module:Skill calc/elts')
elts = eltsRet[args.skill]
-- Filter out exceptions (re-organized to allow skill-specific filters to catch some exceptions early)
if args.skill == "Agilidade" and findItem(exceptionsAgility, args.disp) then elts = eltsRet[args.skill .. "-Básico"]
elseif args.skill == "Construção" and args.disp == "Outro" then elts = eltsRet[args.skill .. "-Outro"]
elseif args.skill == "Divinação" and findItem(exceptionsDiv, args.disp) then elts = eltsRet[args.skill .. "-Lucro"]
elseif args.skill == "Extermínio" and findItem(exceptionsSlayer, args.disp) then elts = eltsRet[args.skill .. "-Básico"]
elseif args.skill == "Metalurgia" and args.disp == "Equipamento" and findItem(exceptionsSmithing, args.equipment)
then elts = eltsRet["Metalurgia-Equipamento"]
elseif findItem(exceptions, args.disp) or findItem(exceptions, args.skill .. '-' .. args.disp) then
elts = eltsRet[args.skill .. "-" .. args.disp]
-- All urns share the same format; special exception
elseif args.disp == "Urnas" then elts = eltsRet[args.disp]
-- Cooking in Daemonheim
elseif args.skill == "Culinária" and args.disp == "Dungeon" then elts = eltsRet["Culinária-Dungeon"]
-- Basic dungeon format
elseif args.disp == "Dungeons" then elts = eltsRet["Dungeons"]
-- Dungeons with materials
elseif string.find(args.disp, "Dungeon - ") then elts = eltsRet["Dungeons-Materiais"]
-- Hunter methods with bait
elseif args.skill == "Caça" and
(args.disp == "Nets and Sprites" or
args.disp == "Deadfall and Pitfall" or
args.disp == "Box Trapping") then elts = eltsRet["Hunter-Bait"]
elseif args.skill == "Caça" and args.disp == "Big Game Hunting" then elts = eltsRet["Hunter-BGH"]
elseif args.testing == "active" and (args.skill == "Caça" and
args.disp == "Box Trapping") then elts = eltsRet["Hunter-Anachronia"]
elseif args.skill == "Pesca" and args.disp == "Deep Sea" then elts = eltsRet["Fishing-Deep Sea"]
end
tables._row(ret:tag('tr'), elts, true)
for _, v in ipairs(data) do
--Leave common calculations outside of the function calls
--Material count
local mcount = 1
if v.mcount then
mcount = v.mcount
end
--Get total cost of materials
local cost = 0
local productCost = 0
if v.material then
if ((v.mtrade ~= 0) or ( (args.disp == "Urns") and not (v.currency) ) ) then
cost = gePrice(v.material, mcount) end
elseif (args.skill == "Prayer" and args.disp ~= 'Incense sticks') then
if not (v.currency) then cost = gePrice({1, v.name}, 1)
else cost = v.value end
elseif args.disp == "Scrolls" then cost = gePrice({1, v.familiarIcon}, 1)
end
if v.trade ~= 0 and not v.currency and
(args.skill ~= "Agilidade" and
args.skill ~= "Construção" and
args.skill ~= "Agricultura" and
args.skill ~= "Dungeon" and
not ( args.skill == "Oração" and args.disp ~= 'Incensos' ) and
args.skill ~= "Invenção" and
args.skill ~= "Extermínio") then
if (args.skill == "Corte de Lenha" or
args.skill == "Mineração" or
args.skill == "Criação de Runas" or
args.skill == "Divinação") and not (v.icon == nil) then
productCost = gePrice({1, v.icon}, 1)
elseif args.skill == "Caça" then
if v.product then productCost = gePrice({1, v.product}, 1) end
else productCost = gePrice({1, v.name}, 1) end
end
-- If a multiplier is set, it is applied to the product's value for profit calculations
if v.multiplier then productCost = productCost * v.multiplier end
-- Check for other currencies
if (v.currency or v.currency2) and not (args.skill == "Oração" and args.disp ~= 'Incensos') then
productCost = v.value
if v.materialCost then cost = v.materialCost end
end
-- Brewing makes two batches
if args.disp == "Brewing" then productCost = productCost * 2 end
--Establish any experience boosts
local abyss = false
if not (args.abyss == nil) and (args.abyss == "Sim" or args.abyss == "Crânio demoníaco") then
abyss = true end
local unitExp = calculateBonus
{
base = v.xp,
currLv = currLv,
boost = pctExpBoost,
boostSw = pctExpBoostSw,
flatBoost = flatExpBoost,
abyss = abyss,
settings = args,
item = v
}
-- Calculate needed iterations
local needed
if not (unitExp == 0 or unitExp == nil) then needed = tonumber(math.ceil(remaining / unitExp))
else needed = 0 end
-- Keep this as the first check to prevent double generation
if (args.testing == "active") then
-- Pass the current elts as a variable for elt generation
generatedElts = eltGenerator.generate_elts(
{
args =
{
v,
args,
unitExp,
needed,
remaining,
cost,
productCost,
elts,
currLv
}
})
-- No Profit, No Loss skills
else
if (args.skill == "Agilidade"
or args.skill == "Roubo"
or args.skill == "Extermínio"
or args.skill == "Invenção") then
elts = eltGenerator.generate_NoProfitNoLoss({args = {v,unitExp,needed,args,remaining,currLv}})
-- No Loss, Profit skills (Gathering)
elseif (args.skill == "Mineração"
or args.skill == "Pesca"
or args.skill == "Corte de Lenha"
or args.skill == "Criação de Runas"
or args.skill == "Divinação"
or args.skill == "Caça") then
elts = eltGenerator.generate_ProfitNoLoss({args = {v,unitExp,needed,cost,args,productCost,remaining,currLv}})
-- No Profit, Loss skills (Survival)
elseif ( (args.skill == "Arte do Fogo" and not string.find(args.disp, 'Incenso') )
or (args.skill == "Oração" and args.disp ~= 'Incensos')
or args.skill == "Construção"
or args.skill == "Magia") then
elts = eltGenerator.generate_NoProfitLoss({args = {v,unitExp,needed,cost,args,productCost,remaining,currLv}})
-- Profit and Loss skills (Artisan)
-- Fletching, Cooking, Farming, Smithing, Herblore, Summoning
else
elts = eltGenerator.generate_ProfitLoss({args = {v,unitExp,needed,cost,args,productCost,remaining,currLv}})
end
end
-- Allow for items with no level requirement
local levelRequired = 1
if args.skill == "Extermínio" and
(args.disp == "Tarefass" or args.disp == "Monstros") then
if v.level2 then levelRequired = v.level2 end
else
if v.level then levelRequired = v.level end
end
levelRequired = math.floor(levelRequired)
local class = 'table-bg-yellow sortbottom'
if levelRequired > goalLv then class = 'table-bg-red sortbottom'
elseif levelRequired <= currLv then class = 'table-bg-green' end
if args.testing == "active" then tables._row(ret:tag('tr'):addClass(class), generatedElts, false)
else tables._row(ret:tag('tr'):addClass(class), elts, false)
end
end
message = displayExp{display=args.disp, skill=args.skill, remaining=remaining,
goalLv=goalLv, goalXP=goalXP, currLv = currLv, currXP = currXP}
if (args.testing == "active") then
local testNotice = mw.html.create('div'):css({['font-size'] = "16px", ['font-weight'] = "bold"}):wikitext(testMessage)
return tostring(testNotice) .. tostring(message) .. tostring(ret)
else
return tostring(message) .. tostring(ret)
end
end
--[=[ displayExp
-- Creates a text string output for the goal calculations
-- Inputs:
-- params Incoming parameters to generate string
-- - display Current set of sub-categorical data
-- - skill Current skill
-- - remaining Experience needed for goal
-- - goalXP Expected experience
-- - goalLv Expected level
-- - currXP Current experience
-- - currLv Current level
-- Returns:
-- msg String created from params
-- - this may be appended with a warning specifically for flatpacks
--]=]
function displayExp(params)
local msg -- Converted from message to avoid conflict
local display = params.display
local skill = params.skill
local remaining = params.remaining
local goalXP = params.goalXP
local goalLv = params.goalLv
local currXP = params.currXP
local currLv = params.currLv
msg = "Para treinar " .. skill .. " de " .. commas(currXP) .. " experiência (nível " .. currLv .. ") para " .. commas(goalXP) .. " experiência (nível " .. goalLv .. "), " .. commas(remaining) .. " experiência é necessária."
if display == "Flatpacks" then
msg = msg .. "<div style='color:red; font-size:0.9em;'>Levels refer to the minimum needed to use the associated workbench if otherwise lower.</div>"
elseif display == "Boons" then
msg = msg .. "<div style='color:red; font-size:0.9em;'>Each boon can only be made once.</div>"
end
local ret = mw.html.create('div'):css({['font-size'] = "1.1em", ['font-weight'] = "bold"}):wikitext(msg)
return tostring(ret)
end
--[=[ remainingExp
-- Finds and returns experiences and levels based on inputs
-- Inputs:
-- curr current value
-- goal goal value
-- curr_intent what the current is (level/experience)
-- goal_intent what the goal is (level/experience)
-- Returns:
-- current level,
-- current experience,
-- goal level,
-- goal experience,
-- experience remaining
--]=]
function remainingExp(curr, goal, curr_intent, goal_intent, isElite)
local goalLevel, currLevel, goalXP, currXP
local elite = nil
if isElite then
elite = '1'
end
if curr_intent == "Level" and tonumber(curr) <= 120 then
currLevel = tonumber(curr)
currXP = xp({args = {curr, elite = elite}})
else
currLevel = level({args = {curr, elite = elite}})
currXP = tonumber(curr)
end
if goal_intent == "Level" and tonumber(goal) <= 120 then
goalLevel = tonumber(goal)
goalXP = xp({args = {goal, elite = elite}})
else
goalLevel = level({args = {goal, elite = elite}})
goalXP = tonumber(goal)
end
-- Prevent negative values
local remaining = math.ceil(goalXP - currXP)
if remaining < 0 then
remaining = 0
end
return currLevel, currXP, goalLevel, goalXP, remaining
end
--[=[ calculateBonus
-- Inputs:
-- source Incoming data
-- - base Base experience for item
-- - boost Percent experience boost, expressed as a decimal percentage
-- - ava Avatar bonus
-- - outfit Outfit bonus
-- - tools Extra bonuses
-- - flatBoost Flat experience boost
-- Returns:
-- Numeric value of new base experience including bonuses
--]=]
function calculateBonus(source)
local total = source.base -- base experience
local currLv = source.currLv
local boost = source.boost -- bonus percentage
local boostSw = source.boostSw -- value not being set?
local flatBoost = source.flatBoost
local abyss = source.abyss
local settings = source.settings -- calculator
local item = source.item -- ../data
local cLv -- holder for current level
if settings.disp == "Wilderness Agility Course" or
(item.page == "Wilderness Agility Course" and settings.disp ~= "Milestones") then
if (settings.disp == "Wilderness Agility Course") then cLv = item.level
else cLv = currLv end
if settings.wild == "Crânio demoníaco" then
total = total + 498.9
if (cLv > 50) then total = (((cLv-21)*boost)*(total)) end
elseif settings.wild == "Both" then
total = ((total*((cLv-21)*boost))+((((cLv-21)*boost)+0.05)*498.9))
--total = ((total*((cLv-21)*boost))+((((cLv-21)*boost)+boostSw)*498.9))
elseif settings.wild == "Wilderness Sword 2+" then
--total = total + (498.9*(1+boostSw))
total = total + (498.9*1.05) -- 1+0.05
else
total = total + 498.9
end
--elseif settings.skill == "Agility" and item.name == "Anachronia Agility Course" then
--total = total * (1 + boost)
elseif item.skill == "Arte do Fogo" and item.bonus ~= nil then
total = total + (item.bonus * (1 + boost))
--elseif settings.skill == "Farming" and settings.disp == "Curing Animals" then
--total = math.floor((total * source.boost)*10)/10
--total = total * source.boost
else
total = total * (1 + source.boost)
end
if not (settings == nil) then
-- Check for additional modifiers. These must be done on an item to item basis
-- to filter out items that may not be affected by certain boosts
local potionSetting, vosSetting, auraSetting, aotSetting, altarSetting
if settings.potion then potionSetting = settings.potion end
if settings.vos then
if settings.vos == "Yes" then vosSetting = "VoiceOfSeren"
else vosSetting = "No" end
end
if settings.aura then auraSetting = settings.aura end
if settings.aot then
if settings.aot == "Yes" then aotSetting = "AvgOverTime"
else aotSetting = "No" end
end
if settings.altar and
item.name ~= "Cleansing crystal" then
altarSetting = settings.altar
else
altarSetting = "None"
end
-- Check for JuJu potion modifier
if potionSetting ~= nil then
total = total *
bonusGenerator
{
skill = settings.skill,
name = item.name,
object = "potion",
item = potionSetting,
setting = vosSetting,
subSetting = aotSetting
}
end
-- Check for VoS modifier
if vosSetting ~= "No" then
total = total *
bonusGenerator
{
skill = settings.skill,
name = item.name,
object = "VoiceOfSeren",
setting = potionSetting,
subSetting = aotSetting
}
end
-- Check for aura modifier
if auraSetting ~= "No" then
total = total *
bonusGenerator
{
skill = settings.skill,
name = item.name,
object = "aura",
item = auraSetting
}
end
-- Check for altar modifier
if altarSetting ~= "None" then
total = total *
bonusGenerator
{
skill = settings.skill,
object = "altar",
item = altarSetting,
setting = settings.disp
}
end
end
-- If the abyss is active, do not add 1
-- Not sure how it all stacks :: NEED INPUT
if source.abyss == true then total = source.base * source.boost end
total = total + source.flatBoost
return numbers(total,1)
end
--[=[ silverhawkFeathers
-- Inputs:
-- currlv Current level
-- goalLv Goal Level
-- currXP Current Experience
-- goalXP Goal Experience
-- remaining Difference from goal
-- pctExpBoost Calculated boost to base exp
-- Returns:
-- String including needed feathers, remaining experience, and current GE cost for feathers
--]=]
function silverhawkFeathers(currLv, goalLv, currXP, goalXP, remaining, pctExpBoost)
local feathers = 0
local featherXP
local desc = ""
local workingXP = currXP
local workingLv = currLv
while workingXP < goalXP do
feathers = feathers + 1
workingLv = level({args = {workingXP}})
featherXP = featherExp[workingLv] + (featherExp[workingLv] * pctExpBoost)
workingXP = workingXP + featherXP
end
return 'Para treinar de ' .. commas(currXP) .. ' experiência (nível ' .. currLv .. ') para ' .. commas(goalXP) .. ' experiência (nível ' .. goalLv .. '), ' .. commas(remaining) .. " experiência é necessária. Requerendo '''" .. commas(feathers) .. " [[Penas de falcão de prata|penas]]''' e, baseando-se no preço atual no Mercado Gelra, irá custar " .. coins(gePrice({feathers,'Penas de falcão de prata'},1)) .. ' moedas.'
end
function wildernessAC(currLv, goalLv, currXP, goalXP, remaining, pctExpBoost)
local nXP = numbers(571.4 * (1 + pctExpBoost), 1)
local lapsToDo = numbers(remaining / nXP)
return "Para treinar de '''" .. commas(currXP) .. " experiência''' (nível " .. currLv .. ") to '''" .. commas(goalXP) .. " experiência''' (nível " .. goalLv .. "), '''" .. commas(remaining) .. " experiência''' é ncessária.<br/>Requerendo '''" .. commas(lapsToDo) .. " voltas''' para ser completado em '''" .. nXP .. " EXP''' por volta."
end
-- Make it easier to find items in a set
-- A little heavy : if someone can find a better way, replace.
function findItem (list, item)
local status = false
for _,v in pairs(list) do
if v == item then
status = true
break
end
end
return status
end
function sortTable(a, b)
local value = false
if a.level and b.level and a.level ~= b.level then
value = a.level < b.level
elseif a.name and b.name and
a.name == b.name and
(a.title or b.title) then
if a.title and not b.title then
value = a.title < b.name
elseif not a.title and b.title then
value = a.name < b.title
else
value = a.title < b.title
end
else
value = a.xp < b.xp
end
return value
end
--[[
Modified version of GETotal.
Will add together the price of a * 4 and b / 4
Can recognize and parse vulgar fractions
All fractions and decimals will be truncated off the final price
Technically unlimited
To use:
variable 'a' = array of {quantity, value, "item name", etc...}
variable 'b' = number of unique items to be included
--]]
function getPrice(a,b)
local values = a or {}
local count = b or 0
local price = 0
local prices = {}
for i=1 , (count*3) , 3 do
local valuex = a[i+1]
local itemx = a[i+2]
if itemx then
local qtyx = a[i] or 1
local qtyret = tonumber(qtyx) or frac(qtyx) or 1
table.insert(prices,math.floor(valuex * qtyret))
end
end
for _, v in ipairs(prices) do
price = price + v
end
return price
end
return p