模块:Calcsellprice
Description
This module calculates the sell price(s) for a sellable item. It can return a raw, unformatted number to be used as the data-sort-value in a table, or a number formatted appropriately for the language where it's used, including the letter(s) / character(s) for "gold", as used in the game.
This module performs some tasks that were formerly performed by arrays in Template:Qualityprice. The parameters this module requires are explained in the documentation for Template:Qualityprice.
This module can be copy/pasted into all languages without alteration.
Please report any problems or issues with the module on the discussion page for Template:Qualityprice.
local cache = require "mw.ext.LuaCache"
local KEY_PREFIX = "Module:Calcsellprice"
local EXP_TIME = 172800
--Assumes baseprice is always an integer
--Adds the language-appropriate letters/characters for 'gold'
local p = {}
--Float32
function p.PackFloat32(number)
if number == 0 then
return string.char(0x00, 0x00, 0x00, 0x00)
elseif number ~= number then
return string.char(0xFF, 0xFF, 0xFF, 0xFF)
else
local sign = 0x00
if number < 0 then
sign = 0x80
number = -number
end
local mantissa, exponent = math.frexp(number)
exponent = exponent + 0x7F
if exponent <= 0 then
mantissa = math.ldexp(mantissa, exponent - 1)
exponent = 0
elseif exponent > 0 then
if exponent >= 0xFF then
return string.char(sign + 0x7F, 0x80, 0x00, 0x00)
elseif exponent == 1 then
exponent = 0
else
mantissa = mantissa * 2 - 1
exponent = exponent - 1
end
end
mantissa = math.floor(math.ldexp(mantissa, 23) + 0.5)
return string.char(
sign + math.floor(exponent / 2),
(exponent % 2) * 0x80 + math.floor(mantissa / 0x10000),
math.floor(mantissa / 0x100) % 0x100,
mantissa % 0x100)
end
end
function p.UnpackFloat32(packed)
local b1, b2, b3, b4 = string.byte(packed, 1, 4)
local exponent = (b1 % 0x80) * 0x02 + math.floor(b2 / 0x80)
local mantissa = math.ldexp(((b2 % 0x80) * 0x100 + b3) * 0x100 + b4, -23)
if exponent == 0xFF then
if mantissa > 0 then
return 0 / 0
else
mantissa = math.huge
exponent = 0x7F
end
elseif exponent > 0 then
mantissa = mantissa + 1
else
exponent = exponent + 1
end
if b1 >= 0x80 then
mantissa = -mantissa
end
return math.ldexp(mantissa, exponent - 0x7F)
end
function p.toFloat32(number)
return p.UnpackFloat32(p.PackFloat32(number))
end
function p.AddFloat32(a, b)
local a_f = p.toFloat32(a)
local b_f = p.toFloat32(b)
return p.toFloat32(a_f + b_f)
end
function p.MulFloat32(a, b)
local a_f = p.toFloat32(a)
local b_f = p.toFloat32(b)
return p.toFloat32(a_f * b_f)
end
function p.MulFloat32Args(frame)
local a = tonumber(frame.args.a)
local b = tonumber(frame.args.b)
if a == nil or b == nil then
return 0
end
return p.MulFloat32(a, b)
end
function p.TruncFloat32(number)
return math.floor(p.toFloat32(number))
end
--csp = calculate sell price
function p.csp(frame)
local item = string.lower(frame.args.im)
local baseprice = tonumber(frame.args.bp)
local quality = tonumber(frame.args.q)
local profmult = tonumber(frame.args.pm)
local toFormatOrNotToFormat = string.lower(frame.args.fm)
local cacheKey = KEY_PREFIX .. "|" .. "csp" .. "|" .. (item or "") .. "|" .. (baseprice or "") .. "|" .. (quality or "") .. "|" .. (profmult or "") .. "|" .. (toFormatOrNotToFormat or "")
if (cache.get(cacheKey)) then
local result = cache.get(cacheKey)
return result
end
if ((baseprice == nil) or (baseprice == 0)) then return 0 end
local qualitymult, artisanprice
if (profmult == nil) or (item == "coffee") or (item == "oil") then profmult = 1 end
if (quality == 1) then qualitymult = 1.25
elseif (quality == 2) then qualitymult = 1.5
elseif (quality == 4) then qualitymult = 2
else qualitymult = 1
end
--Calculate some artisan goods prices from base ingredient price
--These are needed for data-sort-values on pages like Flowers, Fruit, Vegetables
if (string.find(item, "wine") ~= nil) then
artisanprice = (baseprice * 3)
elseif (string.find(item, "juice") ~= nil) then
artisanprice = math.floor(baseprice * 2.25)
elseif ((string.find(item, "jelly")) or (string.find(item, "pickles")) ~= nil) then
artisanprice = (50 + (baseprice * 2))
elseif (string.find(item, "dried") ~= nil) then
artisanprice = math.floor((baseprice * 7.5) + 25)
elseif (item == "honey") then
--This is a hack that works only because
--no flower has a base sell price of 100
if (baseprice ~= 100) then
artisanprice = (100 + (baseprice * 2))
else
artisanprice = 100
end
elseif (string.find(item, "aged roe") ~= nil) then
artisanprice = (2 * (30 + math.floor(baseprice / 2)))
elseif (string.find(item, "roe") ~= nil) then
artisanprice = (30 + math.floor(baseprice / 2))
elseif (string.find(item, "smoked") ~= nil) then
artisanprice = (baseprice * 2)
--[[elseif (item == "pale ale") then artisanprice = 300
elseif ((item == "beer") or (item == "mead")) then artisanprice = 200
elseif (item == "green tea") then artisanprice = 100
elseif (item == "caviar") then artisanprice = 500
elseif (item == "cheese") then artisanprice = 230
elseif (item == "goat cheese") then artisanprice = 400
elseif (item == "cloth") then artisanprice = 470
elseif (item == "mayonnaise") then artisanprice = 190
elseif (item == "duck mayonnaise") then artisanprice = 375
elseif (item == "void mayonnaise") then artisanprice = 275
elseif (item == "dinosaur mayonnaise") then artisanprice = 800
elseif (item == "truffle oil") then artisanprice = 1065
]]
else artisanprice = baseprice
end
local sum = math.floor(p.MulFloat32(math.floor(qualitymult * artisanprice),profmult))
if toFormatOrNotToFormat == "false" then
cache.set(cacheKey, sum, EXP_TIME)
return sum
end
local formattedSum = mw.language.getContentLanguage():formatNum(sum)
local ulang = string.upper(mw.language.getContentLanguage():getCode())
if ulang == "ZH" then -- 保留用作参考
cache.set(cacheKey, formattedSum .. "金", EXP_TIME)
return formattedSum .. "金"
else
cache.set(cacheKey, formattedSum, EXP_TIME)
return formattedSum
end
end
return p