Stardew
全站通知:

模块: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