Module:CreatureStats/sandbox

local p = {}

local function checkFlag(args, flag) return args[flag] and string.lower(args[flag]) == 'yes' end

local Strings = { Attribute = "Attribute", BaseValue = "Base Value", BaseValueNote = "The value of the Attribute at level 1.", LevelIncrease = "Level Increase", TamingBonus = "Taming Bonus", Tamed = "Tamed", TamedNote = "These percentages are based on the value of the Attribute at the moment the creature was tamed.", TamedBaseHealthMultiplier = "The TamedBaseHealthMultiplier (TBHM) is applied right after taming, before the additive bonus is applied.", CannotDrown = "The creature is incapable of drowning.", DamageDisclaimer = "The absolute Base Damage is shown here in addition to the percentage.", ExtraTamedDamageMultiplierNote = "Damage dealt by only the tamed creature is affected by this modifier, " .. "which is not reflected by the percentage value shown in the user interface.", SpeedIncWNote = "Wild creatures do not level up in Movement Speed.", TorpidityIncDNote = "Torpidity increases every level on wild creatures, but cannot be increased once they are tamed.", } local Stats = { { "health",			"Health" }, { "stamina",		"Stamina" }, { "oxygen",			function(creature, args) if creature == 'Tek Stryder' then return 'Tek Stryder#Charge Capacity|Charge Capacity|image=Oxygen.png' elseif checkFlag(args, 'canBeCharged') then return 'Charge Regeneration' end return "Oxygen" end }, { "food",			function(creature, args) if checkFlag(args, 'eatsEnergy') then return 'Energy' end return 'Food' end }, { "weight",			"Weight" }, { "damage",			function(creature, args) if checkFlag(args, 'canBeCharged') then return 'Charge Emission Range' end return 'Melee Damage' end }, { "speed",			function(creature, args) if creature == 'Maewing' then return 'Nursing Effectiveness' end return 'Movement Speed' end }, { "craftingSkill",	function(creature, args) -- Only show this stat on creatures that have it. if args.craftingSkill1 and tonumber(args.craftingSkill1) ~= nil then return 'Crafting Skill' end return nil end }, { "torpor",			"Torpidity" }, } local OfficialStatMultipliers = { health = { incD = 0.20, tameAdd = 0.14 }, damage = { incD = 0.17, tameAdd = 0.14, tameMul = 0.44 }, } local StatComponentConfig = { incW = { showIfNA = true, forceSign = true, hideZero = false }, incD = { showIfNA = true, forceSign = true, hideZero = false }, tameAdd = { showIfNA = true, forceSign = true, hideZero = true }, tameMul = { showIfNA = true, forceSign = true, hideZero = true }, } local MovementSpeedIncWCell = 'class="gray" | ' local TorpidityIncDCell = 'class="gray" | '

local function getStatComponentMult(statId, componentName) local mult = OfficialStatMultipliers[statId] if mult ~= nil then mult = mult[componentName] end return mult and mult or 1 end

local function formatStatChangeValue(statId, componentName, value, asPercent) local showIfNA = StatComponentConfig[componentName].showIfNA local hideZero = StatComponentConfig[componentName].hideZero local alwaysShowSign = StatComponentConfig[componentName].forceSign

if statId == 'torpor' and componentName == 'incD' then -- Torpor does not gain from player-levels. return TorpidityIncDCell elseif statId == 'speed' and componentName == 'incW' then -- Movement Speed does not gain from wild points. return MovementSpeedIncWCell end if not value and hideZero then return '' elseif not value then return '?' elseif value == 'N/A' then if showIfNA then return 'N/A' end return '' end

value = tonumber(value) if hideZero and value == 0 then return '' end local mult = getStatComponentMult(statId, componentName) if value > 0 and mult ~= nil then value = value * mult end

local out = value if asPercent then out = value * 100 .. '%'	end if alwaysShowSign and value >= 0 then out = '+' .. out end return out end

local function makeBlankRow(statId, shouldShowTamed, filler) if statId == 'oxygen' then return table.concat({' || || ', filler, (shouldShowTamed and ' || '..filler..' || || ' or '')}) elseif statId == 'speed' then return table.concat({' || ', filler, '||', MovementSpeedIncWCell, (shouldShowTamed and ' || '..filler..' || || ' or '')}) elseif statId == 'torpor' then return table.concat({' || ', filler, ' || ', filler, (shouldShowTamed and '||'..TorpidityIncDCell..' || || ' or '')}) end return table.concat({' || ', filler, ' || ', filler, (shouldShowTamed and ' || '..filler..' || || ' or '')}) end

local function renderStatRow(statId, name, shouldShowTamed, args) local base = args[statId .. '1']	local incW = args[statId .. 'IncW'] local incD = args[statId .. 'IncD'] local tameAdd = args[statId .. 'TamingBonusAdd'] local tameMul = args[statId .. 'TamingBonusMult'] assert(base == nil or base == '' or base == 'N/A' or tonumber(base) ~= nil) assert(incW == nil or incW == '' or incW == 'N/A' or tonumber(incW) ~= nil) assert(incD == nil or incD == '' or incD == 'N/A' or tonumber(incD) ~= nil) assert(tameAdd == nil or tameAdd == '' or tameAdd == 'N/A' or tonumber(tameAdd) ~= nil) assert(tameMul == nil or tameMul == '' or tameMul == 'N/A' or tonumber(tameMul) ~= nil)

local hasTwoDamageAttacks = statId == 'damage' and tonumber(args.damageAlt1) ~= nil and tonumber(args.damageAlt1) ~= 0

local out = '| '

-- Base value -- Check if unknown or unavailable. if not base or tonumber(base) == nil then return out .. makeBlankRow(statId, shouldShowTamed, '?') elseif base == 'N/A' then return out .. makeBlankRow(statId, shouldShowTamed, 'N/A') end

out = out .. ' || '	-- Melee Damage is shown as a percentage in-game, so show the percent AND first two absolute values. if statId == 'damage' then local bases = tonumber(base) if hasTwoDamageAttacks then bases = bases .. ' / ' .. tonumber(args.damageAlt1) end out = out .. '100% '	-- Normal behaviour: absolute value. else out = out .. tonumber(base) end -- Movement Speed is shown as a percentage in-game. if statId == 'speed' then out = out .. '%'	end

-- Increase per wild level if statId == 'damage' and incW ~= nil then out = out .. '||'..formatStatChangeValue(statId, 'incW', incW, true) .. ' ('..formatStatChangeValue(statId, 'incW', incW*base, false)				 .. (hasTwoDamageAttacks and ' / '..incW*tonumber(args.damageAlt1) or '')				  .. ')' else out = out .. '||'..formatStatChangeValue(statId, 'incW', incW ~= nil and incW*base or nil, false) end

if shouldShowTamed then -- Increase per domesticated level out = out .. '||'..formatStatChangeValue(statId, 'incD', incD, true)

-- Taming bonus: additive -- This should be always shown as a percentage if within a range of (-1, 2). local tameAddPcnt = tameAdd and tonumber(tameAdd) and (tonumber(tameAdd) > -1 and tonumber(tameAdd) < 2) out = out .. '||'..formatStatChangeValue(statId, 'tameAdd', tameAdd, tameAddPcnt) -- Taming bonus: multiplicative (with Taming Effectiveness) out = out .. '||'..formatStatChangeValue(statId, 'tameMul', tameMul, true)

-- Tamed creature damage modifier local etdm = tonumber(args.ExtraTamedDamageMultiplier) if statId == 'damage' and etdm then if tonumber(tameMul) ~= nil and tonumber(tameMul) ~= 0 then out = out .. ', '			end out = out .. ''		end

-- Tamed health base modifier local tbhm = tonumber(args.TamedBaseHealthMultiplier) if statId == 'health' and tbhm then if tonumber(tameMul) ~= nil and tonumber(tameMul) ~= 0 then out = out .. ', '			end out = out .. ''		end end

return out end

function p.main(frame) local args = frame:getParent.args local creature = frame.args[1] local noAutoCategories = frame.args.noAutoCategories == '1'

if not creature then return 'error: first argument to Module:CreatureStats must be a creature name' end

local shouldShowTamed = false for _, stat in ipairs(Stats) do		local stat = stat[1] local incD = args[stat .. 'IncD'] local tameAdd = args[stat .. 'TamingBonusAdd'] local tameMul = args[stat .. 'TamingBonusMult'] if incD ~= 'N/A' then shouldShowTamed = true break end end

local out = { class="wikitable" data-description="Base Stats and Growth"\n' ! rowspan=2 |, Strings.Attribute, ! colspan=, (shouldShowTamed and '2' or '1'), ' | ', Strings.LevelIncrease, ' ', (shouldShowTamed and '!! colspan=2 | ' .. Strings.TamingBonus or ), ! Wild, (shouldShowTamed and	'!!  !! Additive !! Multiplicative' or	),  }

for _, stat in ipairs(Stats) do		local statName = stat[2] if type(statName) == 'function' then statName = stat[2](creature, args) end if statName ~= nil then out[#out+1] = '\n|-\n' .. renderStatRow(stat[1], statName, shouldShowTamed, args) end end

out[#out+1] = '\n|}' return frame:preprocess(table.concat(out)) end

return p