Modul:Coin expr
Zur Navigation springen
Zur Suche springen
Dokumentation Die folgende Dokumentation stammt von der Seite Modul:Coin expr/Dokumentation. (bearbeiten | Versionsgeschichte)
Siehe auch die englische Modulseite: Module:Coin expr. Sie enthält möglicherweise umfassendere oder aktuellere Informationen.
Provides the functionality for {{sell expr}} and {{buy expr}}. Only parameters from the template transclusion are considered (instead of from the call), with the exception of #invoke, which, if set, causes the module to divide all coin values gathered via {{iteminfo}} by 5.
sell
--------------------------------------------------------------------------------
--
-- =============================================================================
--
-- Module:Coin expr
--
-- Calculation of expressions that involve dynamic item values
--
-- =============================================================================
--
-- Code annotations:
-- This module is documented according to LuaCATS (Lua Comment and Type System).
-- LuaCATS comments are prefixed with three dashes (---) and use Markdown syntax.
-- For a full list of annotations, see the following link:
-- https://luals.github.io/wiki/annotations/
--
--------------------------------------------------------------------------------
local trim = mw.text.trim
local iteminfo = require('Module:Iteminfo')
local itemNameData = require('Module:ItemNames').getData
---A cached version of the current frame, the interface to the parser.
local currentFrame
---Holds the arguments from the template call.
---@type table<string, string>
local inputArgs
---Whether the module should compute sell values of items, instead of buy prices.
local isSellExpr = false
---Return a trimmed version of the value of the template parameter with the specified `key`.
---Return `nil` if the parameter is unset.
---@param key string|integer
---@return string?
local function getArg(key)
local value = inputArgs[key]
if not value then
return nil
end
value = trim(value)
return value
end
---Conversion table for the `getBoolArg` function.
---@type table<string, boolean>
local stringToBoolean = {
['y'] = true, ['yes'] = true, ['1'] = true, ['on'] = true, ['true'] = true,
['n'] = false, ['no'] = false, ['0'] = false, ['off'] = false, ['false'] = false,
}
---Convert the value of the template parameter with the specified `key` to a Boolean.
---Return `default` or `nil` if the value is not a recognized Boolean string.
---@param key string|integer
---@param default boolean?
---@return boolean?
local function getBoolArg(key, default)
local value = getArg(key)
if stringToBoolean[value] ~= nil then
return stringToBoolean[value]
end
return default
end
---List of strings about erroneous parameters.
---@type string[]
local argErrors = {}
---Mark a parameter as erroneous and add an error string about it.
---@param argValue string Erroneous value of the parameter
---@param argIndex integer Index of the parameter
local function argError(argValue, argIndex)
argErrors[#argErrors + 1] = 'Parameter ' .. argIndex .. ' is not a valid item name or ID (Value: <code>' .. argValue .. '</code>)! '
end
---Combine all the error strings that were collected previously via `argError()`
---and format them with `{{error}}`.
---@return string
local function errorOutput()
local templateName = (isSellExpr and 'sell' or 'buy') .. ' expr'
local templateLink = currentFrame:expandTemplate{ title = 'tl', args = {templateName} }
local errorStr = 'Error in ' .. templateLink .. ': ' .. table.concat(argErrors)
return currentFrame:expandTemplate{ title = 'error', args = {errorStr} }
end
---Convert the input parameter to an item ID. Recognizes valid item ID strings
---and valid English item names. If the `itemNameOrId` is neither, then return
---`nil`.
---@param itemNameOrId string Input parameter value
---@return number?
local function convertToItemId(itemNameOrId)
-- check: is `itemNameOrId` an item ID string?
if (
-- is it a number?
type(tonumber(itemNameOrId)) == 'number'
-- does it not start with '+' nor '-'?
-- (`tonumber` accepts '+' and '-' at the start of the string, so we
-- need to explicitly exclude that)
and string.byte(itemNameOrId) ~= 43 and string.byte(itemNameOrId) ~= 45
-- is it in the range of valid item IDs?
and iteminfo.info.IDs.isValidWithUnused(tonumber(itemNameOrId)))
then
-- check succeeded
return tonumber(itemNameOrId)
end
-- check: is `itemNameOrId` an English item name string?
local itemId = itemNameData('itemIdFromName', itemNameOrId)
if itemId and itemId ~= '' then
-- check succeeded
return tonumber(itemId) -- itemIdFromName returns the ID as a string
end
-- both checks failed, we don't recognize `itemNameOrId` and cannot convert
-- it to an item ID
return nil
end
---Return the coin value of an item as a string for the expression string.
---@param itemNameOrId string Input parameter value
---@param argIndex integer Parameter index
---@return string coinvalue
local function coinvalueOfItem(itemNameOrId, argIndex)
if itemNameOrId == '' then
return ''
end
local itemid = convertToItemId(itemNameOrId)
if itemid then
local coinvalue = iteminfo.getItemStat(itemid, 'value')
if isSellExpr then
coinvalue = math.floor(coinvalue / 5)
end
return tostring(coinvalue)
end
-- the parameter is not a recognized item ID or English item name, so add an
-- error string about this
argError(itemNameOrId, argIndex)
return ''
end
--------------------------------------------------------------------------------
---Main return object
local p = {}
---@param frame table Interface to the parser (`mw.frame`)
p.go = function(frame)
currentFrame = frame -- global frame cache
inputArgs = currentFrame:getParent().args -- global input args cache
local sellArg = currentFrame.args['sell']
if stringToBoolean[sellArg] ~= nil then
isSellExpr = stringToBoolean[sellArg]
end
local exprStr = ''
-- iterate over all parameters and assemble the expression string
-- (e.g. {'Terra Blade', '+ 5*', 'Torch'} => '200000 + 5* 10')
local argIndex = 0
while true do
argIndex = argIndex + 1
local arg = getArg(argIndex)
if arg == nil then
-- we reached the end of the parameters
break
end
-- the parameters 1, 3, 5, ... are item names or IDs; the parameters
-- 2, 4, 6, ... are expression syntax
if argIndex % 2 == 0 then
-- the current parameter is just expression syntax, so simply append
-- it to the expression
exprStr = exprStr .. arg
else
-- the current parameter is an item name or ID, so append its coin
-- value to the expression
exprStr = exprStr .. coinvalueOfItem(arg, argIndex)
end
end
if #argErrors > 0 then
return errorOutput()
end
-- parse and compute the expression (e.g. '200000 + 5* 10' => '200050')
local resultStr = currentFrame:callParserFunction('#expr', exprStr)
if getBoolArg('raw') then
return resultStr
else
-- format the result with `{{coin}}`
local round = getArg('round') or 999
return currentFrame:expandTemplate{ title = 'coin', args = {resultStr, round=round} }
end
end
return p