Module:BTD6 stats: Difference between revisions
mNo edit summary |
Pymonkibot (talk | contribs) m Text replacement - "[[Bloons TD 6 v" to "[[Update history:Bloons TD 6/Version " |
||
| (16 intermediate revisions by 2 users not shown) | |||
| Line 25: | Line 25: | ||
-- local functions to improve performance | -- local functions to improve performance | ||
local tconcat = table.concat | local tconcat = table.concat | ||
local sformat = string.format | local sformat = string.format | ||
| Line 43: | Line 42: | ||
local amount = 0 | local amount = 0 | ||
if effect[ | if v == "Knockback" and effect.lifespan then headingLower[#headingLower+1] = "Lifespan" amount = amount + 1 end | ||
if amount > 0 then | if amount > 0 then | ||
headingUpper[#headingUpper+1] = v | |||
upperColspans[#upperColspans+1] = amount | |||
end | end | ||
end | end | ||
| Line 57: | Line 56: | ||
local amount = 0 | local amount = 0 | ||
if projectile["maxPierce"]<1 and projectile["pierce"]<99999 then | if projectile["maxPierce"]<1 and projectile["pierce"]<99999 then headingLower[#headingLower+1] = "Pierce" amount = amount + 1 end | ||
if projectile["damage"]~=nil and projectile["damage"]>0 then | if projectile["damage"]~=nil and projectile["damage"]>0 then headingLower[#headingLower+1] = "Damage" amount = amount + 1 end | ||
if projectile["damageModifierForStunned"]~=nil then | if projectile["damageModifierForStunned"]~=nil then headingLower[#headingLower+1] = "Damage to stunned" amount = amount + 1 end | ||
if amount > 0 then | if amount > 0 then | ||
headingUpper[#headingUpper+1] = v | |||
upperColspans[#upperColspans+1] = amount | |||
end | end | ||
end | end | ||
| Line 73: | Line 72: | ||
local amount = 0 | local amount = 0 | ||
if attack | if attack.rate and attack.rate < 9999 and not attack.rateMin then headingLower[#headingLower+1] = "Cooldown" amount = amount + 1 end | ||
if attack | if attack.initialDamage and attack.initialDamage > 0 then headingLower[#headingLower+1] = "Scratch damage" amount = amount + 1 end | ||
if attack[" | if attack.grapplingDamage and attack.grapplingDamage > 0 then headingLower[#headingLower+1] = "Grappling damage" amount = amount + 1 end | ||
if attack.thrashingProjectileRate then headingLower[#headingLower+1] = "Thrash cooldown" amount = amount + 1 end | |||
if amount > 0 then | |||
headingUpper[#headingUpper+1] = v | |||
upperColspans[#upperColspans+1] = amount | |||
end | |||
-- projectiles | |||
if attack.projectiles then headingProjectiles(attack.projectiles) end | |||
end | |||
end | |||
local headingAbilities = function(abils) | |||
for i, v in ipairs(abils["_order"]) do | |||
local abil = abils[v] | |||
local amount = 0 | |||
if abil.cooldown then headingLower[#headingLower+1] = "Cooldown" amount = amount + 1 end | |||
if amount > 0 then | if amount > 0 then | ||
headingUpper[#headingUpper+1] = v | |||
upperColspans[#upperColspans+1] = amount | |||
end | end | ||
-- projectiles | -- projectiles | ||
if | if abil.projectiles then headingProjectiles(abil.projectiles) end | ||
end | end | ||
end | end | ||
| Line 118: | Line 135: | ||
-- insert headings | -- insert headings | ||
if data | if data.speedRangeGyrfalcon > 0 then | ||
headingLower[#headingLower+1] = "Flight speed" | |||
headingUpper[#headingUpper+1]= "Beast" | |||
upperColspans[#upperColspans+1] = 1 | |||
end | end | ||
if data.attacks then headingAttacks(data.attacks) end | |||
if data.abilities then headingAbilities(data.abilities) end | |||
ret[#ret+1] = "!rowspan=2|Power!!rowspan=2|Scale" | ret[#ret+1] = "!rowspan=2|Power!!rowspan=2|Scale" | ||
| Line 131: | Line 149: | ||
end | end | ||
ret[#ret+1] = "|-\n!" .. table.concat(headingLower, "!!") | ret[#ret+1] = "|-\n!" .. table.concat(headingLower, "!!") | ||
-- -- -- -- -- -- -- | |||
-- CALCULATE STATS | |||
-- -- -- -- -- -- -- | |||
-- current scale | |||
local scale | |||
-- attack cooldown | |||
local insertRate = function(amt) | |||
ret[#ret+1] = sformat("| %.4gs", amt - (data.cooldownScaleRange*scale)) | |||
end | |||
-- thrash cooldown | |||
local insertThrashRate = function(amt, thrashRate) | |||
ret[#ret+1] = sformat("| %.4gs", (1 - data.cooldownScaleRange*scale/amt) * thrashRate) | |||
end | |||
-- ability cooldown | |||
local insertAbilityCooldown = function(amt, mainAttackRate) | |||
ret[#ret+1] = sformat("|%.4gs", amt * (1 - (data.cooldownScaleRange*scale/(mainAttackRate - (data.cooldownScaleRange*scale))))) | |||
end | |||
-- damage | |||
local insertDamage = function(amt) | |||
ret[#ret+1] = sformat("|%i", amt + mfloor(data.damageRange*scale)) | |||
end | |||
-- dino stun damage | |||
local insertStunDamage = function(amt) | |||
ret[#ret+1] = sformat("|%i", amt + mfloor(data.damageRange*scale/data.stunBonusDivideMicroraptor)) | |||
end | |||
-- pierce | |||
local insertPierce = function(amt) | |||
ret[#ret+1] = sformat("|%i", amt + mfloor(data.pierceRange*scale)) | |||
end | |||
-- thrash knockback duration | |||
local insertKnockback = function(amt) | |||
ret[#ret+1] = sformat("|%.4gs", amt + (data.thrashKnockbackLifetimeRange*scale)) | |||
end | |||
-- bird flight speed | |||
local insertGyrfalconSpeed = function() | |||
ret[#ret+1] = sformat("|%.4g units/s", data.speed + (data.speedRangeGyrfalcon*scale)) | |||
end | |||
local parseEffects = function(effects) | |||
for i, v in ipairs(effects["_order"]) do | |||
local effect = effects[v] | |||
if v == "Knockback" and effect.duration then insertKnockback(effect.lifespan) end | |||
end | |||
end | |||
local parseProjectiles = function(projectiles) | |||
for i, v in ipairs(projectiles["_order"]) do | |||
local projectile = projectiles[v] | |||
if projectile.maxPierce < 1 and projectile.pierce < 99999 then insertPierce(projectile.pierce) end | |||
if projectile.damage and projectile.damage > 0 then insertDamage(projectile.damage) end | |||
if projectile.damageModifierForStunned then insertStunDamage(projectile.damageModifierForStunned) end | |||
if projectile.effects then parseEffects(projectile.effects) end | |||
end | |||
end | |||
local parseAttacks = function(attacks) | |||
for i, v in ipairs(attacks["_order"]) do | |||
local attack = attacks[v] | |||
if attack.rate and attack.rate < 9999 and not attack.rateMin then insertRate(attack.rate) end | |||
if attack.initialDamage and attack.initialDamage > 0 then insertDamage(attack.initialDamage) end | |||
if attack.grapplingDamage and attack.grapplingDamage > 0 then insertDamage(attack.initialDamage) end | |||
if attack.thrashingProjectileRate then insertThrashRate(attack.rate, attack.thrashingProjectileRate) end | |||
-- projectiles | |||
if attack.projectiles then parseProjectiles(attack.projectiles) end | |||
end | |||
end | |||
local parseAbilities = function(abils) | |||
for i, v in ipairs(abils["_order"]) do | |||
local abil = abils[v] | |||
local attackRate = data.attacks["Attack"].rate | |||
-- rate | |||
insertAbilityCooldown(abil.cooldown, attackRate) | |||
if abil.projectiles ~= nil then parseProjectiles(abil.projectiles) end | |||
end | |||
end | |||
for i = minPower[tiers], maxPower[tiers] do | for i = minPower[tiers], maxPower[tiers] do | ||
scale = ((i - minPower[tiers]) / (maxPower[tiers] - minPower[tiers])) | |||
ret[#ret+1] = sformat("|-\n!%i\n|% | ret[#ret+1] = sformat("|-\n!%i\n|%.4g%%", i, scale*100) | ||
-- calculations | |||
if data.speedRangeGyrfalcon > 0 then insertGyrfalconSpeed() end | |||
if data.attacks then parseAttacks(data.attacks) end | |||
if data.abilities then parseAbilities(data.abilities) end | |||
end | end | ||
| Line 265: | Line 382: | ||
-- attack cooldowns and ability cooldowns | -- attack cooldowns and ability cooldowns | ||
local insert_rate = function(amt) | local insert_rate = function(amt) | ||
tinsert(ret, sformat("|% | tinsert(ret, sformat("|%.4gs", amt / (1 + (0.01 * msqrt((d-1)*50))))) | ||
end | end | ||
-- damage | -- damage | ||
local insert_damage = function(amt) | local insert_damage = function(amt) | ||
if d == 100 then tinsert(ret, sformat("|% | if d == 100 then tinsert(ret, sformat("|%.4g", amt * 2 + 10)) | ||
else tinsert(ret, sformat("|% | else tinsert(ret, sformat("|%.4g", amt * (1 + (d-1) * 0.01) + mfloor((d-1)/10))) end | ||
end | end | ||
-- pierce | -- pierce | ||
local insert_pierce = function(amt) | local insert_pierce = function(amt) | ||
if d == 100 then tinsert(ret, sformat("|% | if d == 100 then tinsert(ret, sformat("|%.4g", amt * 2 + 10)) | ||
else tinsert(ret, sformat("|% | else tinsert(ret, sformat("|%.4g", mfloor(amt * (1 + (d-1) * 0.01)) + (d-1)/10)) end | ||
end | end | ||
-- damage modifiers | -- damage modifiers | ||
local insert_damage_mod = function(amt) | local insert_damage_mod = function(amt) | ||
if d == 100 then tinsert(ret, sformat("| +% | if d == 100 then tinsert(ret, sformat("| +%.4g", amt * 2 + 10)) | ||
else tinsert(ret, sformat("| +% | else tinsert(ret, sformat("| +%.4g", amt * (1 + (d-1) * 0.01))) end | ||
end | end | ||
| Line 654: | Line 771: | ||
local out = parse_tower_base(frame, data, "<h3>%s</h3>", true) | local out = parse_tower_base(frame, data, "<h3>%s</h3>", true) | ||
return string.format("<div class='hatnote'>This data was last updated for: [[Bloons TD 6 | return string.format("<div class='hatnote'>This data was last updated for: [[Update history:Bloons TD 6/Version %s|version %s]]</div>", data["_last_updated"], data["_last_updated"]) .. out | ||
end | end | ||
| Line 689: | Line 806: | ||
} | } | ||
tinsert(ret, sformat("<div class='hatnote'>This data was last updated for: [[Bloons TD 6 | tinsert(ret, sformat("<div class='hatnote'>This data was last updated for: [[Update history:Bloons TD 6/Version %s|version %s]]</div>", data["_last_updated"], data["_last_updated"])) | ||
for i, v in ipairs(upgrade_crosspaths[frame.args[2]]) do | for i, v in ipairs(upgrade_crosspaths[frame.args[2]]) do | ||
my_data = {} | |||
local result = parse_tower(frame, base_data, my_data, "<h3>%s</h3>", false) | local result = parse_tower(frame, base_data, my_data, "<h3>%s</h3>", false) | ||
| Line 759: | Line 877: | ||
function p.last_updated(frame) | function p.last_updated(frame) | ||
local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1])) | local data = mw.loadJsonData(string.format("Module:BTD6 stats/%s/new", frame.args[1])) | ||
return string.format("<div class='hatnote'>This data was last updated for: [[Bloons TD 6 | return string.format("<div class='hatnote'>This data was last updated for: [[Update history:Bloons TD 6/Version %s|version %s]]</div>", data["_last_updated"], data["_last_updated"]) | ||
end | end | ||
return p | return p | ||