Module:ItemData: Difference between revisionsGive feedback
Added CooldownReductionOnChargedAbilities |
Added bonusbasehealth for colossus |
||
| (25 intermediate revisions by 4 users not shown) | |||
| Line 8: | Line 8: | ||
AbilityLifestealPercentHero = true, | AbilityLifestealPercentHero = true, | ||
AbilityLifestealPercentHeroPassive = true, | AbilityLifestealPercentHeroPassive = true, | ||
ActivatedFireRate = true, | |||
ActiveBonusFireRate = true, | |||
ActiveBonusLifesteal = true, | |||
ActiveReloadPercent = true, | ActiveReloadPercent = true, | ||
AirBonusDamageGiven = true, | |||
AirBonusDamageTaken = true, | |||
AirControlPercent = true, | AirControlPercent = true, | ||
AirMoveIncreasePercent = true, | AirMoveIncreasePercent = true, | ||
| Line 20: | Line 25: | ||
BonusAbilityDurationPercent = true, | BonusAbilityDurationPercent = true, | ||
BonusAttackRangePercent = true, | BonusAttackRangePercent = true, | ||
BonusBaseHealth = true, | |||
BonusBulletSpeedPercent = true, | BonusBulletSpeedPercent = true, | ||
BonusClipSizePercent = true, | BonusClipSizePercent = true, | ||
| Line 28: | Line 34: | ||
BonusSoulsPct = true, | BonusSoulsPct = true, | ||
BonusZoomPercent = true, | BonusZoomPercent = true, | ||
BuffBulletResist = true, | |||
BuffMeleeDamageBoost = true, | BuffMeleeDamageBoost = true, | ||
BuffTechResist = true, | |||
BulletArmorReduction = true, | BulletArmorReduction = true, | ||
BulletDamageReflectedPct = true, | BulletDamageReflectedPct = true, | ||
| Line 34: | Line 42: | ||
BulletProcDeflectionPercent = true, | BulletProcDeflectionPercent = true, | ||
BulletResist = true, | BulletResist = true, | ||
BulletResistBelowThreshold = true, | |||
BulletResistPerStack = true, | BulletResistPerStack = true, | ||
BulletResistReduction = true, | BulletResistReduction = true, | ||
CloseRangeBonusWeaponPower = true, | |||
CooldownBetweenChargeReduction = true, | CooldownBetweenChargeReduction = true, | ||
CooldownReduction = true, | CooldownReduction = true, | ||
CooldownReductionOnChargedAbilities = true, | CooldownReductionOnChargedAbilities = true, | ||
CooldownReductionOnHitPct = true, | |||
CooldownReductionPctOnNonHeroes = true, | CooldownReductionPctOnNonHeroes = true, | ||
CritDamagePercent = true, | CritDamagePercent = true, | ||
| Line 51: | Line 62: | ||
FireRateBonus = true, | FireRateBonus = true, | ||
FireRateSlow = true, | FireRateSlow = true, | ||
FireRateWhileSliding = true, | |||
GravityScale = true, | |||
GroundDashReductionPercent = true, | GroundDashReductionPercent = true, | ||
HealAmpCastPercent = true, | HealAmpCastPercent = true, | ||
| Line 59: | Line 72: | ||
HealPercentAmount = true, | HealPercentAmount = true, | ||
HealPercentPerHeadshot = true, | HealPercentPerHeadshot = true, | ||
HealthPctDamage = true, | |||
ItemCooldownReduction = true, | ItemCooldownReduction = true, | ||
ImbueAbilityLifesteal = true, | |||
ImbuedCooldownReduction = true, | |||
LifestealHealPercent = true, | LifestealHealPercent = true, | ||
LightMeleeAmmo = true, | |||
LongRangeBonusWeaponPower = true, | LongRangeBonusWeaponPower = true, | ||
MagicIncreasePerStack = true, | MagicIncreasePerStack = true, | ||
MagicResistReduction = true, | MagicResistReduction = true, | ||
MaxArmorStacks = true, | |||
MaxHealthDamage = true, | MaxHealthDamage = true, | ||
MaxHealthLossPercent = true, | MaxHealthLossPercent = true, | ||
MaxHealthPercentAsDPS = true, | MaxHealthPercentAsDPS = true, | ||
MaxHPDamage = true, | |||
MaxSlowPercent = true, | MaxSlowPercent = true, | ||
MeleeDistanceScale = true, | MeleeDistanceScale = true, | ||
MeleeResistPercent = true, | MeleeResistPercent = true, | ||
ModelScaleGrowthTooltip = true, | |||
MoveWhileShootingSpeedPenaltyReductionPercent = true, | MoveWhileShootingSpeedPenaltyReductionPercent = true, | ||
MoveWhileZoomedSpeedPenaltyReductionPercent = true, | MoveWhileZoomedSpeedPenaltyReductionPercent = true, | ||
| Line 85: | Line 105: | ||
ReduceFootstepSound = true, | ReduceFootstepSound = true, | ||
ReloadSpeedMultipler = true, | ReloadSpeedMultipler = true, | ||
ResistStealAmount = true, | |||
RespawnTime = true, | |||
RicochetDamagePercent = true, | RicochetDamagePercent = true, | ||
SelfModifier = true, | SelfModifier = true, | ||
| Line 109: | Line 131: | ||
WeaponPowerPerStack = true, | WeaponPowerPerStack = true, | ||
} | } | ||
-- Mappings from placeholder tokens (used in descriptions) to the actual | |||
-- flat property keys in Data:ItemData.json | |||
local PROPERTY_KEY_OVERRIDES = { | |||
["ArcaneSurgeWindow"] = "AbilityDuration", | |||
-- Add any other mismatches here as they appear | |||
} | |||
local function strip_suffix(value) | |||
if type(value) == "number" then | |||
return tostring(value) | |||
end | |||
if type(value) ~= "string" then | |||
return tostring(value) | |||
end | |||
return value:match("[-%d%.]+") or value | |||
end | |||
---------------------------------------- Utility functions | ---------------------------------------- Utility functions | ||
| Line 244: | Line 284: | ||
--check Data:ItemData.json for properties | --check Data:ItemData.json for properties | ||
p.get_prop = function(frame) | p.get_prop = function(frame) | ||
local item_name = frame.args[1] | |||
local property = frame.args[2] | |||
local raw = frame.args.raw == 'true' | |||
local item = get_json_item(item_name) | |||
if(item == nil) then return "<span style=\"color:red;\">Item Not Found.</span>" end | |||
-- Look up property directly; if missing, try the override table | |||
local prop_value = item[property] | |||
if prop_value == nil and PROPERTY_KEY_OVERRIDES[property] then | |||
prop_value = item[ PROPERTY_KEY_OVERRIDES[property] ] | |||
end | |||
if (prop_value == nil) then return nil end | |||
local display_value | local display_value | ||
| Line 259: | Line 304: | ||
if prop_value["Value"] ~= nil and prop_value["Scale"] ~= nil and prop_value["Scale"]["Value"] ~= nil and prop_value["Scale"]["Type"] ~= nil then | if prop_value["Value"] ~= nil and prop_value["Scale"] ~= nil and prop_value["Scale"]["Value"] ~= nil and prop_value["Scale"]["Type"] ~= nil then | ||
-- This is a structured attribute with scaling data | -- This is a structured attribute with scaling data | ||
display_value = tostring(prop_value["Value"]) | display_value = raw and strip_suffix(prop_value["Value"]) or tostring(prop_value["Value"]) | ||
local scale_val = tonumber(prop_value["Scale"]["Value"]) | if not raw then | ||
local scale_val = tonumber(prop_value["Scale"]["Value"]) | |||
if scale_val ~= 0 then | |||
local scale_type = prop_value["Scale"]["Type"] | |||
local rounded_scale_val = util_module.round_to_sig_fig(scale_val, 2) | |||
local template_title | |||
if scale_type == "power_increase" then | |||
template_title = "Template:Boon" | |||
else | |||
template_title = "Template:Ss" | |||
end | |||
local template_args = { [1] = rounded_scale_val } | |||
-- Add a space before the scaling template for proper separation | |||
scaling_str = " " .. mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args } | |||
end | end | ||
end | end | ||
else | else | ||
| Line 281: | Line 327: | ||
local tableValues = {} | local tableValues = {} | ||
for _, v in pairs(prop_value) do | for _, v in pairs(prop_value) do | ||
table.insert(tableValues, tostring(v)) | table.insert(tableValues, raw and strip_suffix(v) or tostring(v)) | ||
end | end | ||
return table.concat(tableValues, ", ") | return table.concat(tableValues, ", ") | ||
| Line 287: | Line 333: | ||
else | else | ||
-- This is a simple, non-table property | -- This is a simple, non-table property | ||
display_value = tostring(prop_value) | display_value = raw and strip_suffix(prop_value) or tostring(prop_value) | ||
end | |||
if raw then | |||
return display_value | |||
end | end | ||
-- Assemble the final string, adding the '%' sign if necessary | -- Assemble the final string, adding the '%' sign if necessary | ||
if percentage_properties[property] == true then | if percentage_properties[property] == true then | ||
| Line 297: | Line 347: | ||
end | end | ||
end | end | ||
p.get_component_name = function(frame) | p.get_component_name = function(frame) | ||
local item_name = frame.args[1] | local item_name = frame.args[1] | ||
local slot_arg = frame.args[2] | |||
local item = get_json_item(item_name) | local item = get_json_item(item_name) | ||
if(item == nil) then return "<span style=\"color:red;\">Item Not Found.</span>" end | if(item == nil) then return "<span style=\"color:red;\">Item Not Found.</span>" end | ||
| Line 307: | Line 360: | ||
if(components == nil) then return nil end | if(components == nil) then return nil end | ||
local component_key = components[ | local slot = tonumber(slot_arg) or 1 | ||
local component_key = components[slot] | |||
if (component_key == nil) then return nil end | |||
local component = data[component_key] | |||
local component = data[component_key] | local component = data[component_key] | ||
if (component == nil) then return nil end | if (component == nil or component["IsDisabled"] == true) then return nil end | ||
return component['Name'] | return component['Name'] | ||
| Line 315: | Line 372: | ||
-- {{Items count}} access point | -- {{Items count}} access point | ||
function p.get_headcount() | function p.get_headcount(frame) | ||
local item_type = frame.args[1] | |||
local iter = 0 | local iter = 0 | ||
local tbl = get_similar_items("IsDisabled") | local tbl = get_similar_items("IsDisabled") | ||
for _, v in ipairs(tbl) do | for _, v in ipairs(tbl) do | ||
if (v["IsDisabled"] == false and v["Name"] ~= nil) then | if item_type == "Standard" then | ||
-- return only regular items | |||
if (v["IsDisabled"] == false and v["Slot"] ~= nil and v["StreetBrawl"] == false and v["Name"] ~= nil) then | |||
iter = iter + 1 | |||
end | |||
elseif item_type == "Street Brawl" then | |||
-- return only street brawl items | |||
if (v["IsDisabled"] == false and v["Slot"] ~= nil and v["StreetBrawl"] == true and v["Name"] ~= nil) then | |||
iter = iter + 1 | iter = iter + 1 | ||
end | |||
end | |||
end | end | ||
return iter | return iter | ||
| Line 349: | Line 416: | ||
end | end | ||
-- {{#invoke:ItemData|get_property_upgrade|ITEM_NAME|PROPERTY}} -- | |||
p.get_property_upgrade = function(frame) | |||
local item_name = frame.args[1] | |||
local property = frame.args[2] | |||
local raw = frame.args.raw == 'true' | |||
local item = get_json_item(item_name) | |||
if item == nil then | |||
return "<span style=\"color:red;\">Item Not Found.</span>" | |||
end | |||
local upgrades = item["PropertyUpgrades"] | |||
if upgrades == nil then return nil end | |||
local value = upgrades[property] | |||
if value == nil then return nil end | |||
local result = raw and strip_suffix(value) or tostring(value) | |||
if raw then | |||
return result | |||
end | |||
-- Append % if this property is percentage-based | |||
if percentage_properties[property] == true then | |||
return result .. "%" | |||
else | |||
return result | |||
end | |||
end | |||
-- Helping function for [[Module:Enhanced]] | |||
function p.get_prop_meta(item_name, property) | |||
local item = get_json_item(item_name) | |||
if not item then return nil end | |||
local raw = item[property] | |||
if raw == nil then return nil end | |||
local meta = { | |||
unit = nil, -- "%", "m", "s" or nil | |||
scale = nil -- { type = "Ss"/"Boon", value = number } or nil | |||
} | |||
if percentage_properties[property] then | |||
meta.unit = "%" | |||
end | |||
if type(raw) == "table" | |||
and raw.Scale | |||
and raw.Scale.Value | |||
and raw.Scale.Type | |||
then | |||
local scale_val = tonumber(raw.Scale.Value) | |||
if scale_val and scale_val ~= 0 then | |||
meta.scale = { | |||
type = raw.Scale.Type == "power_increase" and "Boon" or "Ss", | |||
value = util_module.round_to_sig_fig(scale_val, 2) | |||
} | |||
end | |||
end | |||
return meta | |||
end | |||
-- Builds Into functions | |||
-- Helper: accepts item key or display name, returns the key used in data table | |||
local function get_codename_from_input(input) | |||
if data[input] then return input end | |||
for k, v in pairs(data) do | |||
if v["Name"] == input and (v["IsDisabled"] == false or v["IsDisabled"] == nil) then | |||
return k | |||
end | |||
end | |||
for k, v in pairs(data) do | |||
if v["Name"] == input then return k end | |||
end | |||
return nil | |||
end | |||
-- Core logic: returns table of keys that have this item in their Components | |||
local function get_component_of(item_input) | |||
local target_key = get_codename_from_input(item_input) | |||
if not target_key then return {} end | |||
local parents = {} | |||
for key, item in pairs(data) do | |||
if item.IsDisabled ~= true and item.Components and type(item.Components) == "table" then | |||
for _, comp in ipairs(item.Components) do | |||
if comp == target_key then | |||
table.insert(parents, key) | |||
break | |||
end | |||
end | |||
end | |||
end | |||
table.sort(parents) | |||
return parents | |||
end | |||
-- Template: {{#invoke:ItemData|get_builds_into_count|ITEM_NAME}} | |||
p.get_builds_into_count = function(frame) | |||
local item = frame.args[1] | |||
return #get_component_of(item) | |||
end | |||
-- Template: {{#invoke:ItemData|get_builds_into_name|ITEM_NAME|INDEX}} | |||
p.get_builds_into_name = function(frame) | |||
local item = frame.args[1] | |||
local idx = tonumber(frame.args[2]) or 1 | |||
local parents = get_component_of(item) | |||
local key = parents[idx] | |||
return key and data[key] and data[key]["Name"] or "" | |||
end | |||
-- Template: {{#invoke:ItemData|get_builds_into|ITEM_NAME}} | |||
-- Returns fully rendered ItemIcon templates | |||
p.get_builds_into = function(frame) | |||
local item = frame.args[1] | |||
local parents = get_component_of(item) | |||
if #parents == 0 then return "" end | |||
local and_word = frame:preprocess("{{#invoke:Dictionary|translate|And}}") | |||
and_word = mw.ustring.lower(and_word) | |||
local parts = {} | |||
for _, key in ipairs(parents) do | |||
local name = data[key] and data[key]["Name"] or key | |||
local icon = mw.getCurrentFrame():expandTemplate{ title = "ItemIcon", args = { name } } | |||
table.insert(parts, icon) | |||
end | |||
if #parts == 1 then return parts[1] end | |||
if #parts == 2 then | |||
return parts[1] .. " " .. and_word .. " " .. parts[2] | |||
end | |||
local last = table.remove(parts) | |||
return table.concat(parts, ", ") .. ", " .. and_word .. " " .. last | |||
end | |||
return p | return p | ||