<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://deadlock.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sur</id>
	<title>The Deadlock Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://deadlock.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sur"/>
	<link rel="alternate" type="text/html" href="https://deadlock.wiki/Special:Contributions/Sur"/>
	<updated>2026-09-15T02:35:35Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://deadlock.wiki/User:Sur/March_6,_2026?diff=62210</id>
		<title>User:Sur/March 6, 2026</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/March_6,_2026?diff=62210"/>
		<updated>2026-03-10T06:08:27Z</updated>

		<summary type="html">&lt;p&gt;Sur: Created page with &amp;quot;{{Update layout | prev_update = {{Update link|February|17|2026}} | month = March | day = 6 | year = 2026 | next_update ={{Update link|March|7|2026}} | source = https://store.steampowered.com/news/app/1422450/view/519740319207522795 | source_title = Gameplay Update - 03-06-2026 | notes = === General === * Can now jump during slide * Dash jump grants a very brief period with increased air control (30% for 0.25s) * Shrine is now easier to kill for the first one and harder f...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Update layout&lt;br /&gt;
| prev_update = {{Update link|February|17|2026}}&lt;br /&gt;
| month = March&lt;br /&gt;
| day = 6&lt;br /&gt;
| year = 2026&lt;br /&gt;
| next_update ={{Update link|March|7|2026}}&lt;br /&gt;
| source = https://store.steampowered.com/news/app/1422450/view/519740319207522795&lt;br /&gt;
| source_title = Gameplay Update - 03-06-2026&lt;br /&gt;
| notes = === General ===&lt;br /&gt;
* Can now jump during slide&lt;br /&gt;
* Dash jump grants a very brief period with increased air control (30% for 0.25s)&lt;br /&gt;
* Shrine is now easier to kill for the first one and harder for the second. HP from 8100 to 5000/10000 (HP updates after the first one dies, like Walkers)&lt;br /&gt;
* Shrines attack no longer hits heroes under the shrine&lt;br /&gt;
* Super troopers bonus DPS increased from +40% to +60% (the upgraded troopers when Shrine dies)&lt;br /&gt;
* Middle Lane troopers now gets upgraded when either of the shrines die, rather than only when both die&lt;br /&gt;
* Killing a pair of base guardians now spawns a zipline boosted trooper wave to reinforce your push&lt;br /&gt;
* Medic Troopers DPS grows by 3% per minute&lt;br /&gt;
* Troopers now gain 7 HP regen when out of combat&lt;br /&gt;
* Trooper wave interval increased from every 25s to every 20s starting at 35 minutes&lt;br /&gt;
* Guardians bounty increased from 1000 to 1500&lt;br /&gt;
* Walkers bounty increased from 3500 to 4000&lt;br /&gt;
* Walkers Health rescaled from 6800/9350/11900 to 6000/9000/12000&lt;br /&gt;
* Walkers armor decay rescaled from &amp;quot;+75% -&amp;gt; -50%&amp;quot; to &amp;quot;+65% -&amp;gt; -65%&amp;quot;, from over 20min to over 18min&lt;br /&gt;
* Base Guardians bounty from 750 to 1000&lt;br /&gt;
* Shrines bounty increased from 0 to 2000&lt;br /&gt;
* Mid Boss base bounty increased from 2000 to 3000&lt;br /&gt;
* Mid Boss base HP increased from 11900 to 13000&lt;br /&gt;
* Mid Boss global announcement health threshold reduced from 70% to 50%&lt;br /&gt;
* Mid Boss now has 35% Debuff Resistance&lt;br /&gt;
* Rejuv drop duration reduced from 7s to 6s&lt;br /&gt;
* Rejuv duration no longer refreshes when hitting a crystal later&lt;br /&gt;
* Minimap now indicates if the Urn is a favored, neutral or unfavored&lt;br /&gt;
* Added a neutral camp (2 Normal, 3 Weak) at Hidden King Park Walker&lt;br /&gt;
* Added a neutral camp (2 Normal, 3 Weak) at Archmother York Walker&lt;br /&gt;
* Added &amp;quot;0 Way&amp;quot; veils underneath the Shrine platforms in each base&lt;br /&gt;
* Moved the mid lane bridge above the Hidden King Base entrance more to the middle of the two edges&lt;br /&gt;
* Subsequent CC reduction increased from 8%/24% to 10/30% (window from 7s to 8s)&lt;br /&gt;
* Move speed diminishing ramp now occurs around 11m rather than 10m&lt;br /&gt;
* Fixed melee abilities not using conditional damage based on enemy state (close quarters, point blank, opening rounds)&lt;br /&gt;
* Street Brawl: Removed item slot limit (don&#039;t need to sell items in the final round sometimes)&lt;br /&gt;
&lt;br /&gt;
=== Items ===&lt;br /&gt;
* Added new T1 Spirit Item: {{ItemIcon|Golden Goose Egg}}&lt;br /&gt;
* {{ItemIcon|Extended Magazine}}: Weapon Damage increased from +6% to +8%&lt;br /&gt;
* {{ItemIcon|High-Velocity Rounds}}: No longer grants +5% Fire Rate&lt;br /&gt;
* {{ItemIcon|High-Velocity Rounds}}: Now grants +8% Weapon Damage&lt;br /&gt;
* {{ItemIcon|High-Velocity Rounds}}: Bullet Velocity increased from +50% to +60% (these changes affect upgrades)&lt;br /&gt;
* {{ItemIcon|Long Range}}: Fall-off Range increased from +4% to +8%&lt;br /&gt;
* {{ItemIcon|Active Reload}}: You can now reload while already full when carrying this item&lt;br /&gt;
* {{ItemIcon|Opening Rounds}}: Spirit Power increased from +8 to +10&lt;br /&gt;
* {{ItemIcon|Opening Rounds}}: Weapon Damage increased from +40% to +45%&lt;br /&gt;
* {{ItemIcon|Swift Striker}}: Fire Rate increased from 18% to 20%&lt;br /&gt;
* {{ItemIcon|Mystic Shot}}: Damage spirit scaling increased from 0.8 to 1.0&lt;br /&gt;
* {{ItemIcon|Split Shot}}: Cooldown reduced from 32s to 24s&lt;br /&gt;
* {{ItemIcon|Split Shot}}: Now supports custom count and angles per hero&lt;br /&gt;
* {{ItemIcon|Split Shot}}: Enabled for {{HeroIcon|Celeste}} (3 at 70 degrees)&lt;br /&gt;
* {{ItemIcon|Stalker|l1=Backstabber}}: Renamed to Stalker&lt;br /&gt;
* {{ItemIcon|Stalker}}: No longer procs based on angles of attack, but instead based on doing bullet or melee damage within 8m of a hero target&lt;br /&gt;
* {{ItemIcon|Stalker}}: No longer has a proximity requirement for the overtime bonuses (beyond the 8m proc proximity)&lt;br /&gt;
* {{ItemIcon|Melee Charge}}: Heavy Melee Bonus damage now works with heavy melee abilities&lt;br /&gt;
* {{ItemIcon|Spirit Shredder Bullets}}: Spirit Lifesteal increased from 8% to 12%&lt;br /&gt;
* {{ItemIcon|Weakening Headshot}}: Bonus health increased from +50 to +60&lt;br /&gt;
* {{ItemIcon|Ballistic Enchantment}}: Weapon damage per stack increased from 18% to 20%&lt;br /&gt;
* {{ItemIcon|Ballistic Enchantment}}: Range reduced from 30% to 25%&lt;br /&gt;
* {{ItemIcon|Ballistic Enchantment}}: Non-hero weapon damage increased from 4% to 5%&lt;br /&gt;
* {{ItemIcon|Hunter&#039;s Aura}}: Solo hero multiplier reduced from 3x to 2x&lt;br /&gt;
* {{ItemIcon|Hunter&#039;s Aura}}: Bullet Resist Reduction increased from -8% to -10%&lt;br /&gt;
* {{ItemIcon|Hunter&#039;s Aura}}: Fire Rate Reduction increased from -11% to -14%&lt;br /&gt;
* {{ItemIcon|Weighted Shots}}: Now builds from {{ItemIcon|Slowing Bullets}}. Has {{ItemIcon|Slowing Bullets}} passive&lt;br /&gt;
* {{ItemIcon|Weighted Shots}}: No longer grants +16% Spirit Resist&lt;br /&gt;
* {{ItemIcon|Weighted Shots}}: Now grants -0.5m Move Speed&lt;br /&gt;
* {{ItemIcon|Weighted Shots}}: No longer grants -30% Bullet Velocity&lt;br /&gt;
* {{ItemIcon|Weighted Shots}}: Debuff Resist increased from 16% to 18%&lt;br /&gt;
* {{ItemIcon|Weighted Shots}}: Weapon Damage increased from 35% to 40%&lt;br /&gt;
* {{ItemIcon|Weighted Shots}}: Stamina Reduction reduced from -20% to -14%&lt;br /&gt;
* {{ItemIcon|Express Shot}}: Ammo consumed changed from -30% to 2 Ammo&lt;br /&gt;
* {{ItemIcon|Blood Tribute}}: No longer has healing reduction&lt;br /&gt;
* {{ItemIcon|Blood Tribute}}: Self damage increased from 40 to 50&lt;br /&gt;
* {{ItemIcon|Spirit Rend}}: Cooldown reduced from 2.2s to 2s&lt;br /&gt;
* {{ItemIcon|Spirit Rend}}: Spirit Lifesteal increased from 8% to 12%&lt;br /&gt;
* {{ItemIcon|Crushing Fists}}: Heavy Melee Bonus damage now works with heavy melee abilities&lt;br /&gt;
* {{ItemIcon|Frenzy}}: Base Fire Rate increased from 8% to 10%&lt;br /&gt;
* {{ItemIcon|Frenzy}}: Base Spirit Resist increased from 10% to 15%&lt;br /&gt;
* {{ItemIcon|Frenzy}}: Conditional Fire Rate reduced from 28% to 25%&lt;br /&gt;
* {{ItemIcon|Frenzy}}: Conditional Spirit Resist reduced from 30% to 20%&lt;br /&gt;
* {{ItemIcon|Spiritual Overflow}}: Spirit Power increased from 30 to 40&lt;br /&gt;
* {{ItemIcon|Spiritual Overflow}}: Now grants +20% Duration instead of +12% CD Reduction&lt;br /&gt;
* {{ItemIcon|Extra Health}}: Increased from 185 to 210&lt;br /&gt;
* {{ItemIcon|Enduring Speed}}: Fixed slow resistance interaction with dash slows&lt;br /&gt;
* {{ItemIcon|Restorative Locket}}: Range increased from 30m to 35m&lt;br /&gt;
* {{ItemIcon|Restorative Locket}}: Max stamina regen increased from 3 to 4&lt;br /&gt;
* {{ItemIcon|Restorative Locket}}: Now always restores at least 1 stamina&lt;br /&gt;
* {{ItemIcon|Return Fire}}: Returning damage now always hits the target&#039;s body (some amount would naturally miss before, and some would be headshots)&lt;br /&gt;
* {{ItemIcon|Return Fire}}: Bullet Damage Returned reduced from 60% to 50%&lt;br /&gt;
* {{ItemIcon|Weapon Shielding}}: Damage threshold increased from 150 to 250&lt;br /&gt;
* {{ItemIcon|Weapon Shielding}}: Cooldown reduced from 45s to 35s&lt;br /&gt;
* {{ItemIcon|Bullet Resilience}}: Low Health threshold increased from 40% to 50%&lt;br /&gt;
* {{ItemIcon|Bullet Resilience}}: Low Health resistance reduced from 22% to 15%&lt;br /&gt;
* {{ItemIcon|Spirit Resilience}}: Low Health threshold increased from 40% to 50%&lt;br /&gt;
* {{ItemIcon|Spirit Resilience}}: Low Health resistance reduced from 22% to 15%&lt;br /&gt;
* {{ItemIcon|Lifestrike}}: Heal on melee hit reduced from 160 to 100 + 1.5/boon&lt;br /&gt;
* {{ItemIcon|Lifestrike}}: Heal on melee hit percentage reduced from 50% to 30% + 0.5%/boon&lt;br /&gt;
* {{ItemIcon|Majestic Leap}}: Barrier increased from 140 to 200&lt;br /&gt;
* {{ItemIcon|Trophy Collector}}: Souls per minute increased from 22 to 25&lt;br /&gt;
* {{ItemIcon|Dispel Magic}}: Cooldown reduced from 50s to 40s&lt;br /&gt;
* {{ItemIcon|Fortitude}}: Time to regen reduced from 13s to 10s&lt;br /&gt;
* {{ItemIcon|Spellbreaker}}: High instant damage reduction reduced from -75% to -65%&lt;br /&gt;
* {{ItemIcon|Diviner&#039;s Kevlar}}: Cooldown reduced from 64s to 40s&lt;br /&gt;
* {{ItemIcon|Inhibitor}}: Damage Penalty reduced from -35% to -30%&lt;br /&gt;
* {{ItemIcon|Inhibitor}}: Weapon Damage bonus increased from +22% to +25%&lt;br /&gt;
* {{ItemIcon|Cheat Death}}: No longer reduces movement speed by -2m during the death immunity phase&lt;br /&gt;
* {{ItemIcon|Colossus}}: Active now grants you an additional +30% Melee Damage&lt;br /&gt;
* {{ItemIcon|Siphon Bullets}}: Now steals 2.5% of enemy max HP per bullet instead of a fixed amount&lt;br /&gt;
* {{ItemIcon|Mystic Regeneration}}: Health bonus increased from +40 to +50&lt;br /&gt;
* {{ItemIcon|Mystic Regeneration}}: Duration increased from 5s to 6s&lt;br /&gt;
* {{ItemIcon|Rusted Barrel}}: Cooldown reduced from 20s to 16s&lt;br /&gt;
* {{ItemIcon|Arcane Surge}}: Spirit Power increased from +15 to +20&lt;br /&gt;
* {{ItemIcon|Slowing Hex}}: Now sets the gravity of an enemy to a fixed +20% (heavier) regardless of their own base values&lt;br /&gt;
* {{ItemIcon|Slowing Hex}}: Projectile speed increased from 53m/s to 80m/s&lt;br /&gt;
* {{ItemIcon|Slowing Hex}}: Cooldown reduced from 30s to 27s&lt;br /&gt;
* {{ItemIcon|Suppressor}}: Debuff duration increased from 4s to 5s&lt;br /&gt;
* {{ItemIcon|Spirit Sap}}: Spirit Power loss increased from -24 to -30&lt;br /&gt;
* {{ItemIcon|Spirit Sap}}: Cooldown reduced from 32s to 18s&lt;br /&gt;
* {{ItemIcon|Decay}}: Healing Reduction increased from -45% to -50%&lt;br /&gt;
* {{ItemIcon|Silence Wave}}: Damage spirit scaling increased from 0.6 to 1.0&lt;br /&gt;
* {{ItemIcon|Silence Wave}}: Cooldown reduced from 35s to 30s&lt;br /&gt;
* {{ItemIcon|Knockdown}}: Gravity increased from +50% to +100% when the stun hits the target (causes airborne targets to fall faster)&lt;br /&gt;
* {{ItemIcon|Radiant Regeneration}}: Health bonus increased from +65 to +90&lt;br /&gt;
* {{ItemIcon|Radiant Regeneration}}: Duration increased from 5s to 6s&lt;br /&gt;
* {{ItemIcon|Radiant Regeneration}}: Healing on Ability Cast boon scaling increased from 1.5 to 2.0&lt;br /&gt;
* {{ItemIcon|Tankbuster}}: Current Health Bonus Damage increased from 7.5% to 8%&lt;br /&gt;
* {{ItemIcon|Torment Pulse}}: Damage spirit scaling reduced from 0.28 to 0.25&lt;br /&gt;
* {{ItemIcon|Torment Pulse}}: No longer hits sleeping enemies to avoid waking them up&lt;br /&gt;
* {{ItemIcon|Disarming Hex}}: Cooldown reduced from 20s to 16s&lt;br /&gt;
* {{ItemIcon|Magic Carpet}}: Duration increased from 8s to 12s&lt;br /&gt;
* {{ItemIcon|Magic Carpet}}: Bonus health increased from 75 to 125&lt;br /&gt;
* {{ItemIcon|Ethereal Shift}}: Cooldown reduced from 45s to 35s&lt;br /&gt;
* {{ItemIcon|Cursed Relic}}: Damage penalty increased from -8% to -10%&lt;br /&gt;
* {{ItemIcon|Vortex Web}}: Now has a unit target option where it will vacuum enemies around that target&lt;br /&gt;
&lt;br /&gt;
=== Heroes ===&lt;br /&gt;
* {{HeroIcon|Abrams}}: Bullet damage reduced from 3.86+0.13/boon to 3.6+0.1/boon&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} DPS reduced from 29 to 22&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} range reduced from 10m to 7.5m&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} is now circular rather than just in front of him&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} range no longer increases with Spirit Power&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} visual range FX fixed to show larger than default radius values&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} Lifesteal against heroes increased from 66% to 80%&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} Lifesteal against non-heroes increased from 33% to 40%&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} DPS spirit scaling increased from 0.5 to 0.6&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} T1 increased from -19s to -20s&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} T3 now also increases radius by +3.5m&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Siphon Life}} T3 DPS reduced from 20 to 18&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Shoulder Charge}} damage reduced from 37 to 30&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Shoulder Charge}} wall stun duration reduced from 0.6s to 0.3s&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Shoulder Charge|l1=Should Charge}}{{sic}} spirit scaling reduced from 1.9 to 1.4&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Shoulder Charge}} T1 changed from &amp;quot;+2.2 Weapon Damage for 8s&amp;quot; to &amp;quot;+40% Slow for 3s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Shoulder Charge}} T2 wall stun duration increased from 0.45s to 0.8s&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Shoulder Charge}} T3 cooldown increased from -18s to -20s&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Shoulder Charge}} T3 now also grants +1.5 Weapon Damage for 6s&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Infernal Resilience}} T2 increased from +150 Health to +200&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Infernal Resilience}} T3 now also grants +20% Debuff Resistance&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Seismic Impact}} is a little faster to target the location when rising&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Seismic Impact}} damage increase from 75 to 100&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Seismic Impact}} now allows you to use items during it&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Seismic Impact}} radius reduced from 10.5m to 9m&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Seismic Impact}} T2 changed from &amp;quot;Per Hero Hit: +100 HP and +14% Fire Rate&amp;quot; to &amp;quot;+0.6s Stun Duration&amp;quot;&lt;br /&gt;
* {{HeroIcon|Abrams}}: {{AbilityIcon|Seismic Impact}} T3 now also increases radius by 6m&lt;br /&gt;
* {{HeroIcon|Apollo}}: Fixed {{AbilityIcon|Riposte}} not leaving the ground when started on the ground&lt;br /&gt;
* {{HeroIcon|Apollo}}: {{AbilityIcon|Riposte}} no longer triggers from trooper or neutral damage&lt;br /&gt;
* {{HeroIcon|Apollo}}: {{AbilityIcon|Flawless Advance}} T2 no longer increases {{HeroIcon|Apollo}}&#039;s lunge speed&lt;br /&gt;
* {{HeroIcon|Apollo}}: {{AbilityIcon|Flawless Advance}} now gets interrupted by stun and sleep&lt;br /&gt;
* {{HeroIcon|Apollo}}: {{AbilityIcon|Itani Lo Sahn}} base damage reduced from 225 to 190 and spirit scaling increased from 1.6 to 2.3&lt;br /&gt;
* {{HeroIcon|Apollo}}: {{AbilityIcon|Itani Lo Sahn}}&#039;s hit width no longer scales with radius increases&lt;br /&gt;
* {{HeroIcon|Bebop}}: Hook can now be canceled&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Bashdown}} radius reduced from 4.5m to 4m&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Bashdown}} T2 changed from &amp;quot;+1.3m Radius&amp;quot; to &amp;quot;+1 Charge and +2m Radius&amp;quot;&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Bashdown}} T3 now also reduces charge time by 2s&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Rising Ram}} damage reduced from 55 to 40&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Rising Ram}} damage spirit scaling increased from 1.7 to 1.9&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Rising Ram}} cooldown reduced by 50% on impact&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Rising Ram}} charge duration reduced from 0.51s to 0.3s&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Rising Ram}} T1 changed from &amp;quot;On Impact: -50% Cooldown&amp;quot; to &amp;quot;On Impact: +25% Weapon Damage for 5s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Rising Ram}} T2 changed from &amp;quot;On Impact: +35% Weapon Damage for 5s&amp;quot; to &amp;quot;+0.3s Charge Duration&amp;quot;&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Rising Ram}} T3 increased from 6.5% Max Health to 8%&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Blasted}} spirit scaling reduced from 0.8 to 0.6&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Blasted}} active duration no longer slows down the decay when doing bullet damage (melee still extends it though)&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Blasted}} passive no longer reduces enemy fire rate by -14%&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Blasted}} tooltip simplified&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Blasted}} T3 now also increases spirit scaling by +0.6&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Chain Gang}} radius reduced from 13m to 12m&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Chain Gang}} no longer grants +15% Spirit and Bullet Resist&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Chain Gang}} cooldown increased from 125s to 150s&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Chain Gang}} T1 changed from &amp;quot;-25s Cooldown&amp;quot; to &amp;quot;+40% Spirit and Bullet Resist&amp;quot;&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Chain Gang}} T2 changed from &amp;quot;+15% Spirit and Bullet Resist&amp;quot; to &amp;quot;-50s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Chain Gang}} T3 changed from 2s Unstoppable to +1.3s Unstoppable for each hero pulled in&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Chain Gang}} T3 no longer grants +90 damage&lt;br /&gt;
* {{HeroIcon|Billy}}: {{AbilityIcon|Chain Gang}} T3 now also increases the radius by +5m&lt;br /&gt;
* {{HeroIcon|Calico}}: Bullets no longer have gravity&lt;br /&gt;
* {{HeroIcon|Calico}}: Now fires an additional pellet right down the center (DPS is the same). The center pellet is now considered the primary pellet for headshots.&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Gloom Bombs}} changed so the first grenade always lands in the middle&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Gloom Bombs}} projectile sticky radius increased from 10 to 15&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Gloom Bombs}} cast delay reduced from 0.15s to 0.1s&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Gloom Bombs}} T2 changed from +16.2 damage to +75 bonus damage vs barriers&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Leaping Slash}} improved targeting of dash to end early if near enemy heroes&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Leaping Slash}} can now dash vertically, even while on the ground&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Leaping Slash}} T2 changed from +40 damage to +300 souls on hero kill&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Leaping Slash}} T3 changed from -50% CDR on hit to -50% CDR and +60 damage&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Leaping Slash}} radius reduced from 4.5m to 4m&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} can no longer manipulate movement if meleeing while midair&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} now uses healthbar modifier style for duration&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} fixed camera not being centered around {{AbilityIcon|Ava}}&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} melee attack delay reduced from 0.4s to 0.0s&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} melee attack cooldown increased from 0.75 to 0.85&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} melee attack now goes the way you are looking&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} now starts at a minimum speed, and increases to maximum speed over time, resetting on taking damage&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} now gradually recovers speed over time after taking damage, rather than being slowed for the entire duration&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} cooldown reduced from 45s to 30s&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} duration reduced from 16s to 15s&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} T1 duration increased from +14s to 15s&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} T2 changed from +45% Speed to +45% Speed and +15 Health Regen&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Ava}} T3 changed from -20s Cooldown and +35 Health Regen to a growing damage amp the longer you are transformed, up to 20% for 6s&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Return to Shadows|l1=Return To Shadows}} now allows for some vertical flight movement during channel&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Return to Shadows|l1=Return To Shadows}} now has new channel bar&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Return to Shadows}} T2 reduced from 67.5 Damage to 65&lt;br /&gt;
* {{HeroIcon|Calico}}: {{AbilityIcon|Return to Shadows}} T3 no longer grants +18% Damage Amp for 6s, but grants 350 healing instead&lt;br /&gt;
* {{HeroIcon|Celeste}}: Gravity reduced from -20% to -28% (less gravity)&lt;br /&gt;
* {{HeroIcon|Celeste}}: Air Control/Acceleration reduced from +50/18% to +38/12% (less air control and acceleration)&lt;br /&gt;
* {{HeroIcon|Celeste}}: {{AbilityIcon|Shining Wonder}} bounce range reduced from 17m to 15m&lt;br /&gt;
* {{HeroIcon|Celeste}}: {{AbilityIcon|Shining Wonder}} linger duration reduced from 4.5s to 3.25s&lt;br /&gt;
* {{HeroIcon|Doorman}}: Gun now pierces through targets at 50% reduced damage&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} time between charges increased from 4s to 6s&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} no longer has Impact Damage (was 40 with 1.0 scaling)&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} explosion damage increased from 55 to 85&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} explosion damage spirit scaling reduced from 1.7 to 1.4&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} T1 increased from +2m to +2.5m&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} T2 no longer has Impact Damage&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} T2 Explosion Damage increased from 40 to 75&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} T2 now increases spirit scaling by +0.6&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Call Bell}} T3 changed from &amp;quot;Impact causes half radius explosions&amp;quot; to &amp;quot;+1 Charge and +22s Lifetime. Causes the radius to continuously apply it&#039;s slow&amp;quot;&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Doorway}} now has a timer icon above the ability&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Doorway}} T1 duration increased from +10s to +15s&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Doorway}} T2 barrier duration increased from 8s to 12s&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Doorway}} T3 doorway distance now also scales with Spirit Power (0.25)&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Luggage Cart}} is now 20% larger (20% wider hitbox as well)&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Luggage Cart}} T1 changed from &amp;quot;-8s Cooldown&amp;quot; to &amp;quot;+60 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Luggage Cart}} T2 increased from +15m Cast Range to +20m&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Luggage Cart}} T3 changed from &amp;quot;+45 Cart Damage and 117 Wall Damage and 1.2s Wall Stun&amp;quot; to &amp;quot;+1.5s Wall Stun and -15s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Doorman}}: Fixed issues where the cart would hit a target coming out of the hotel before they were supposed to be allowed to be hit, causing the cart to not properly drag the target&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} cast range increased from 6m to 7m&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} no longer goes on cooldown if the target dies during the cast&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} fixed enemies not always landing in the correct spot on return &lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} now supports instant cast settings&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} returning guest now has a 100% time slow that decays to 0% over 1s&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} cost of stay damage reduced from 150 to 75&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} failure to check-out damage reduced from 250 to 125&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} T1 changed from &amp;quot;+2m Cast Range&amp;quot; to &amp;quot;-1 Stamina and -25s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} T2 changed from &amp;quot;Unstoppable while channeling&amp;quot; to &amp;quot;+1.5s Stun On Failure To Checkout and 150 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Doorman}}: {{AbilityIcon|Hotel Guest}} T3 changed from &amp;quot;-50s Cooldown&amp;quot; to &amp;quot;Unstoppable while Hotel is occupied. 10s Cooldown on Failure to Check Out&amp;quot;&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Rend}} damage range reduced from 18m to 16m&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Rend}} cooldown increased from 13s to 16s&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Rend}} damage spirit scaling increased from 1.4 to 1.8&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Rend}} &amp;quot;bonus&amp;quot; damage is now the melee range at close range (so you only do melee damage at close range and spirit is the default)&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Rend}} T1 bonus damage increased from +32 to +40&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Rend}} T3 changed from &amp;quot;Gain 45% Bullet Lifesteal against affected enemies for 4s&amp;quot; to &amp;quot;Close range attack now silences enemies for 2.3s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Stalker&#039;s Mark}} duration reduced from 6s to 5s&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Stalker&#039;s Mark}} T1 changed from &amp;quot;+1% Bleed&amp;quot; to &amp;quot;-8% Bullet Resist&amp;quot;&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Stalker&#039;s Mark}} T2 changed from &amp;quot;+22% Fire Rate for 6s after ambush&amp;quot; to &amp;quot;+3s Duration and -8s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Stalker&#039;s Mark}} T3 changed from &amp;quot;Enables 2 Charges and +2s Duration&amp;quot; to &amp;quot;+2% Bleed and -40% Healing&amp;quot;&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Bloodscent}} now grants {{HeroIcon|Drifter}} the same amount of permanent bonus weapon damage when an isolated hero dies nearby, whether {{HeroIcon|Drifter}} gets the assist or the kill&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Bloodscent}} permanent bonus weapon damage gained per isolated hero death reduced from 4% to 3%&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Bloodscent}} T2 changed from &amp;quot;Isolated kill reduces cooldowns by 15s and restores 3 stamina&amp;quot; to &amp;quot;Isolated death restores 18% Missing Health and restores 2 stamina&amp;quot;&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Eternal Night}} now makes the targets be considered as isolated&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Eternal Night}} Sprint reduced from +3m to +2m&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Eternal Night}} no longer has 7 spirit damage proc&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Eternal Night}} cooldown increased from 120s to 125s&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Eternal Night}} duration reduced from 7s to 6.5s&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Eternal Night}} T1 changed from &amp;quot;+6.3 Spirit Damage Proc&amp;quot; to &amp;quot;+10m Sprint&amp;quot; (kicks in immediately)&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Eternal Night}} T2 changed from &amp;quot;-30s Cooldown and +3m/s Sprint&amp;quot; to &amp;quot;-45s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Drifter}}: {{AbilityIcon|Eternal Night}} T3 increased from &amp;quot;+2s Duration and +1 Max Target&amp;quot; to &amp;quot;+2.5s Duration and +1 Max Target&amp;quot;&lt;br /&gt;
* {{HeroIcon|Dynamo}}: Bullet damage increased from 12.2+0.44 to 12.6+0.5&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Kinetic Pulse}} cooldown increased from 22s to 26s&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Kinetic Pulse}} damage increased from 90 to 115&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Kinetic Pulse}} range reduced from 20m to 16m&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Kinetic Pulse}} range no longer increases with spirit scaling&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Kinetic Pulse}} spirit scaling increased from 1.7 to 2.1&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Kinetic Pulse}} T1 changed from &amp;quot;35% Move Slow and -30% Fire Rate&amp;quot; to &amp;quot;+1 Charge&amp;quot;&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Kinetic Pulse}} T2 changed from &amp;quot;+30% Bullet Damage for 8s&amp;quot; to &amp;quot;Reduces enemy Bullet Resistance by -18% and Move Speed by -30% for 4s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Kinetic Pulse}} T3 changed from &amp;quot;+104 Damage and +1 Charge&amp;quot; to &amp;quot;+135 Damage and +16m Cast Range&amp;quot;&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Quantum Entanglement}} no longer grants +26% Fire Rate&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Quantum Entanglement}} no longer reloads ammo&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Quantum Entanglement}} base ability now restores 1 stamina&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Quantum Entanglement}} ally distance increased from 10m to 13m&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Quantum Entanglement}} range increased from 9m to 10m&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Quantum Entanglement}} T1 increased from +4m Range to +6m&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Quantum Entanglement}} T2 changed from &amp;quot;+22% Fire Rate&amp;quot; to &amp;quot;-6s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Quantum Entanglement}} T3 changed from &amp;quot;-5s Cooldown and +120% Ammo&amp;quot; to &amp;quot;Dispells non-ult debuffs for you and your allies&amp;quot;&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Rejuvenating Aurora}} cooldown increased from 45s to 48s&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Rejuvenating Aurora}} now has a 1s linger on allies&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Rejuvenating Aurora}} now lets you jump while using it&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Rejuvenating Aurora}} T1 changed from &amp;quot;+4 Move Speed for 8s after full channel&amp;quot; to &amp;quot;Aura provides +4 Move Speed during channel&amp;quot;&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Rejuvenating Aurora}} T2 cooldown from -14s to -20s&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Rejuvenating Aurora}} T2 now also increases duration by 1s&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Singularity}} no longer does 1.5% Max Health DPS&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Singularity}} DPS increased from 40 to 75&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Singularity}} DPS spirit scaling increased from 0.19 to 0.28&lt;br /&gt;
* {{HeroIcon|Dynamo}}: {{AbilityIcon|Singularity}} T3 increased from 4% Max Health DPS to 5.5%&lt;br /&gt;
* {{HeroIcon|Graves}}: {{AbilityIcon|Grasping Hands}} is now set up to work through proper alternate cast methods and be more responsive&lt;br /&gt;
* {{HeroIcon|Graves}}: {{AbilityIcon|Grasping Hands}} Immobilize duration reduced from 1.5s to 1.25s&lt;br /&gt;
* {{HeroIcon|Graves}}: {{AbilityIcon|Grasping Hands}} cooldown reduced from 38s to 34s&lt;br /&gt;
* {{HeroIcon|Graves}}: {{AbilityIcon|Grasping Hands}} T2 changed from &amp;quot;+0.75s Immobilize Duration&amp;quot; to &amp;quot;+90 Damage and +10m Wall Length&amp;quot;&lt;br /&gt;
* {{HeroIcon|Graves}}: {{AbilityIcon|Grasping Hands}} T3 changed from &amp;quot;+15m Wall Length and -10s Cooldown&amp;quot; to &amp;quot;+1s Immobilize Duration and -12s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Haze}}: Spirit per boon reduced from 1.1 to 0.5&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Sleep Dagger}} Sleep move speed reduced from 2m/s to 1.5m/s&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Sleep Dagger}} Wake Up delay no longer increases with spirit scaling&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Sleep Dagger}} cooldown increased from 26s to 30s&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Sleep Dagger}} Sleep duration reduced from 3s to 2.75s&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Sleep Dagger}} T1 changed from &amp;quot;Removes 1 Stamina&amp;quot; to &amp;quot;-8% Bullet Resist Reduction for 6s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Sleep Dagger}} T2 changed from &amp;quot;-12s Cooldown and -60% Stamina for 6s&amp;quot; to &amp;quot;-15s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Sleep Dagger}} T3 changed from &amp;quot;-12% Bullet Resist and -35% Fire Rate for 6s on wakeup&amp;quot; to &amp;quot;+0.75s Sleep Duration. -50% Move and Dash Slow for 2.5s on wakeup&amp;quot;&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Smoke Bomb}} cooldown increased from 30s to 33s&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Smoke Bomb}} duration spirit scaling reduced from 0.18 to 0.08&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Smoke Bomb}} no longer has base +2m Invis Sprint Speed&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Smoke Bomb}} T1 increased from +5m Invis Sprint Speed to +7m&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Smoke Bomb}} T2 changed from &amp;quot;+10% Bullet Lifesteal&amp;quot; to &amp;quot;Enables 2 Ability Charges&amp;quot;&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Smoke Bomb}} T3 changed from &amp;quot;Enable 2 Charges and Grants +0.5s of Invincibility&amp;quot; to &amp;quot;Dispels non-ult debuffs and grants 30% Lifesteal for 5s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Smoke Bomb}} T3 now also grants +1 Charge&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Fixation}} reduced from +0.2 Weapon Damage per stack to +0.18&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Fixation}} T1 spirit scaling increased from 0.37 to 0.8&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Fixation}} T1 reduced from +50 Spirit Damage to +40&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Fixation}} T3 increased from +0.12 Weapon Damage to +0.14&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Bullet Dance}} Fire Rate bonus reduced from 30% to 20%&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Bullet Dance}} base ability now has 60% Evasion&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Bullet Dance}} duration spirit scaling increased from 0.06 to 0.08&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Bullet Dance}} Bonus Bullet Damage reduced from 10 to 7&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Bullet Dance}} T1 increased from +4 Bullet Damage to +7&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Bullet Dance}} T2 now also increases Fire Rate by +10%&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Bullet Dance}} T3 no longer adds 60% Bullet Evasion&lt;br /&gt;
* {{HeroIcon|Haze}}: {{AbilityIcon|Bullet Dance}} T3 now also fires at an additional target&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Napalm}} damage reduced from 46 to 40&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Napalm}} damage spirit scaling increased from 0.3 to 0.6&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Napalm}} amplified damage taken reduced from 20% to 16%&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Napalm}} T2 lifesteal increased from 10% to 15%&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Flame Dash}} DPS spirit scaling increased from 0.8 to 1.0&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Flame Dash}} T1 changed from &amp;quot;-25% Fire Rate&amp;quot; to &amp;quot;-12s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Flame Dash}} T2 DPS reduced from +27 to +20&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Flame Dash}} T2 DPS now also increases trail duration by 1s&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Flame Dash}} T3 no longer reduces cooldown by 15s&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Flame Dash}} T3 now also grants +1 Charge&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Flame Dash}} T3 time between charges reduced from 20s to 14s&lt;br /&gt;
* {{HeroIcon|Infernus}}: Melee can now buildup afterburn (20% for light melee, 35% for heavy)&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Afterburn}} T1 changed from &amp;quot;-20% Spirit Damage&amp;quot; to &amp;quot;+14 DPS&amp;quot;&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Afterburn}} T2 changed from +1s Burn Duration to -35% Spirit Damage&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Afterburn}} T3 changed from &amp;quot;+23 DPS&amp;quot; to &amp;quot;+3s Max Burn Duration&amp;quot; (Base duration is the same, but can buildup after igniting to grow to max burn duration, abilities only refresh up to the base)&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Concussive Combustion}} cast now causes camera to move back a bit&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Concussive Combustion}} delay increased from 3s to 3.25s&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Concussive Combustion}} radius reduced from 13m to 12m&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Concussive Combustion}} cooldown increased from 140s to 165s&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Concussive Combustion}} damage reduced from 150 to 125&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Concussive Combustion}} T1 changed from &amp;quot;-35s Cooldown&amp;quot; to &amp;quot;+100 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Concussive Combustion}} T2 changed from &amp;quot;+0.5s Stun and +3m Radius&amp;quot; to &amp;quot;-65s Cooldown and +65% Explosion Heal&amp;quot;&lt;br /&gt;
* {{HeroIcon|Infernus}}: {{AbilityIcon|Concussive Combustion}} T3 changed from &amp;quot;+94 Damage and Heal for 70% damage&amp;quot; to &amp;quot;+0.75s Stun and +10m Radius&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: Now has -10% Gravity&lt;br /&gt;
* {{HeroIcon|Ivy}}: Bullet damage reduced from 4.59+0.12/boon to 4.45+0.06/boon&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Entangling Thorns|l1=Kudzu Bomb}} renamed to Entangling Thorns&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Entangling Thorns}} Recharge Time reduced from 8s to 5s&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Entangling Thorns}} spirit scaling reduced from 0.65 to 0.55&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Entangling Thorns}} T2 changed from &amp;quot;+2s Duration&amp;quot; to &amp;quot;+2m Radius and increases spirit scaling by +0.5&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Entangling Thorns}} T3 changed from &amp;quot;+36 DPS and +2m Radius&amp;quot; to &amp;quot;Entangles enemies that remain in it for 2s. Lasts 1.6s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Kudzu Connection|l1=Watcher&#039;s Covenant}} renamed to Kudzu Connection&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Kudzu Connection}} Fire Rate spirit scaling reduced from 0.25 to 0.18&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Kudzu Connection}} Bullet Lifesteal spirit scaling reduced from 0.19 to 0.15&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Kudzu Connection}} T1 changed from &amp;quot;+8% Fire Rate&amp;quot; to &amp;quot;+2m Move Speed bonus&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Kudzu Connection}} T2 changed from &amp;quot;+2m Move Speed Bonus&amp;quot; to &amp;quot;+8% Fire Rate and +8% Bullet Lifesteal&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Kudzu Connection}} T3 changed from &amp;quot;+1 Tether Count&amp;quot; to &amp;quot;Ability is now always active&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Stone Form}} cooldown increased from 37s to 40s&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Stone Form}} damage spirit scaling reduced from 1.5 to 0.8&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Stone Form}} T1 changed from &amp;quot;-19s cooldown&amp;quot; to &amp;quot;+7% Max Health Heal&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Stone Form}} T2 changed from &amp;quot;+68 Damage and +0.5s Stun&amp;quot; to &amp;quot;-25s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Stone Form}} T3 changed from &amp;quot;+13% Max Health Heal&amp;quot; to &amp;quot;+1s Stun and Increased Spirit Scaling (2.0)&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} cast time removed. Instead, if you take damage the ability will be unable to be used for 3.5s&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} spirit damage scaling reduced from 2.3 to 1.0&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} Cooldown reduced from 100s to 65s&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} duration increased from 16s to 21s&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} base/max speed increased from 11/18m to 10/22m&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} bomb radius increased from 14m to 20m&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} buff duration reduced from 12s to 8s&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} ally cast range increased from 14m to 18m&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} now grants you and your ally +20% Outgoing Damage after dropping&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} bomb no longer has a fast explode expanding behavior&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} bomb no longer causes a knockup&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} bomb no longer slows on explode by default&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} bomb no longer provides barrier by default&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} T1 changed from &amp;quot;-20% Bullet Resist on enemies hit for 8s&amp;quot; to &amp;quot;Grants you and ally 300 Barrier (+1.0 Spirit Scaling)&amp;quot; Lasts 12s.&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} T2 changed from &amp;quot;+200 Barrier and +5m Explode Radius&amp;quot; to &amp;quot;Explode applies 50% Slow for 3s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Ivy}}: {{AbilityIcon|Air Drop}} T3 now also increases damage scaling by +1.5 and barrier scaling by +1.0&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} now impacts on {{AbilityIcon|Ice Path}}&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} radius reduced from 6.5m to 6m&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} cooldown increased from 20s to 30s&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} now comes with 2 charges&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} now heals in the base ability (60 + 0.9 Spirit Scaling)&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} no longer has -40% Stamina regen reduction&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} T1 changed from &amp;quot;+1 Charge&amp;quot; to &amp;quot;Increases damage and heal by +30&amp;quot;&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} T2 changed from &amp;quot;Provides healing 80+1.5&amp;quot; to &amp;quot;Freezes stamina regen and -10s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frost Grenade}} T3 changed from &amp;quot;+144 Damage and -30% Stamina Regen&amp;quot; to &amp;quot;Increases damage and heal spirit scaling by 1.0 and Radius by +2m&amp;quot;&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Ice Path}} is now cancelled on Ability Button Press instead of Space&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Ice Path}} cooldown increased from 46s to 50s&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Ice Path}} incline/decline speed increased&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Ice Path}} T1 changed from &amp;quot;+4 Sprint&amp;quot; to &amp;quot;+2 Move Speed and +35% Bullet Resistance on {{AbilityIcon|Ice Path}}&amp;quot;&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Ice Path}} T2 increased from -17s Cooldown to -20s&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Ice Path}} T3 now grants you +35% Spirit Power while on {{AbilityIcon|Ice Path}}&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} visual clarity on VFX improved&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} now lets you cast {{AbilityIcon|Frost Grenade}} and items while using it&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} Max Fire Rate Reduction reduced from -35% to -20%&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} Max Slow reduced from -40% to -20%&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} spirit scaling reduced from 0.8 to 0.5&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} cooldown increased from 25s to 28s&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} T1 changed from &amp;quot;-7s Cooldown&amp;quot; to &amp;quot;Increases Move Slow and Fire Rate Reduction by -25%&amp;quot;&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} T2 changed from &amp;quot;+33 DPS&amp;quot; to &amp;quot;+20 DPS and +0.6 Spirit Scaling&amp;quot;&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Arctic Beam}} T3 now also reduces cooldown by 13s&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frozen Shelter}} can now be canceled first without canceling Ice Beam&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frozen Shelter}} is now 8m unit target, creates the dome around the center of both heroes. Can be self casted to create it around yourself.&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frozen Shelter}} duration reduced from 5.25s to 5s&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frozen Shelter}} T1 changed from &amp;quot;-35% Enemy Fire Rate&amp;quot; to &amp;quot;-25s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frozen Shelter}} T2 increased from +1s to +1.5s&lt;br /&gt;
* {{HeroIcon|Kelvin}}: {{AbilityIcon|Frozen Shelter}} T3 now also dispels non-ult debuffs on cast (affects you and allies)&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Essence Bomb}} self damage changed from 30 + 1.8 scaling to 30% of the damage (base is 90 + 1.2 scaling)&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Essence Bomb}} radius reduced from 9m to 7m&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Essence Bomb}} cooldown reduced from 14.5s to 14s&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Essence Bomb}} T1 increased from -4s to -5s&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Essence Bomb}} T2 also increases radius by +2m&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Life Drain}} cooldown increased from 30s to 34s&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Life Drain}} break range reduced from 30m to 28m&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Life Drain}} T1 DPS increased from +16.2 to +18&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Life Drain}} T2 duration increased from +2s to +2.5s&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Life Drain}} T3 charges increased from +1 to +2&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Life Drain}} T3 now also increases spirit scaling by +0.3&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Soul Exchange}} cast time reduced from 0.2s to 0.1s&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Soul Exchange}} post cast hold time reduced from 0.7s to 0.2s&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Soul Exchange}} T1 cooldown increased from -35s to -60s&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Soul Exchange}} T2 changed from &amp;quot;On Cast: +35% Fire Rate for 8s&amp;quot; to &amp;quot;Silences enemies within 25m for 3s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Lady Geist}}: {{AbilityIcon|Soul Exchange}} T3 changed from &amp;quot;Silences enemies within 25m for 3s&amp;quot; to &amp;quot;On Cast: +60 Spirit Power, +40% Fire Rate and +50% Spirit Resistance for 8s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Lash}}: Increased Sparkles&lt;br /&gt;
* {{HeroIcon|Lash}}: Fixed {{AbilityIcon|Ground Strike}} against players brought down from mid air not doing damage&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Grapple}} T2 weapon damage increased from +6 to +7&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Grapple}} T3 changed from &amp;quot;+20% Fire Rate&amp;quot; to &amp;quot;+60% Air Control and +1 Stamina on Usage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Flog}} cooldown increased from 24s to 26s&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Flog}} Attack Angle no longer increases with Spirit Power&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Flog}} heal vs heroes reduced from 60% to 50%&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Flog}} T2 increased from -12s Cooldown to -16s&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Flog}} T2 now also reduces Fire Rate by 30%&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Flog}} T3 no longer reduces Fire Rate&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Flog}} T3 damage reduced from +86 to +80&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Flog}} T3 now also increases Attack Angle by 40 and Heal by +20%&lt;br /&gt;
* {{HeroIcon|Lash}}: Fixed {{AbilityIcon|Death Slam}} camera sometimes being obstructed&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Death Slam}} throw distance no longer scales with Spirit Power (was 0.3)&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Death Slam}} cooldown increased from 145s to 150s&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Death Slam}} T1 throw distance increased from +8m to +12m&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Death Slam}} T2 cooldown increased from -25s to -40s&lt;br /&gt;
* {{HeroIcon|Lash}}: {{AbilityIcon|Death Slam}} T3 now also increases cast range by +10m&lt;br /&gt;
* {{HeroIcon|McGinnis}}: Stamina speed bucket 3 to 2&lt;br /&gt;
* {{HeroIcon|McGinnis}}: Bullet damage reduced from 6.72 + 0.2/boon to 6.0 + 0.16/boon&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret}} duration increased from 24s to 35s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret}} base health and health growth reduced by 40%&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret|l1=Mini Turrets}} initial fading resist start value increased from 60% to 80%&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret|l1=Mini Turrets}} now have 35% melee resist&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret}} tracking, angle and projectile speeds significantly improved&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret}} on the minimap now flash/turn red when they are attacking&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret}} T1 changed from &amp;quot;Turrets apply 25% slow&amp;quot; to &amp;quot;+10m Attack Range and +10 DPS&amp;quot;&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret}} T2 changed from &amp;quot;+10m Attack Range and + 10% Fire Rate&amp;quot; to &amp;quot;+2 Charges&amp;quot;&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Mini Turret}} T3 changed from &amp;quot;+38 Turret DPS and +14s Turret Lifetime&amp;quot; to &amp;quot;+30% Turret Fire Rate and +12s Turret Lifetime&amp;quot;&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} duration no longer scales with spirit power&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} radius no longer scales with spirit power&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} regen now scales with spirit power (+0.3)&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} cooldown increased from 48s to 50s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} no longer provides +15% Stamina Recovery&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} T1 changed from &amp;quot;+30% Fire Rate&amp;quot; to &amp;quot;+40% Spirit Resistance&amp;quot;&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} T2 increased from -17s Cooldown to -20s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} T2 now also increases Stamina Recovery by +100%&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} T3 regen reduced from 2.5% Max HP to 2%&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} T3 now also increases radius by 3m&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Medicinal Specter}} T3 now also increases duration by 1s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Spectral Wall}} that is midcast will now fire when you are interrupted, rather than continue to expand outward&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Spectral Wall}} segments can now be destroyed with 2 heavy melee hits (destroys an individual segment)&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Spectral Wall}} min range reduced from 6m to 5m&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Spectral Wall}} applies it&#039;s slow to enemies it passes through while being summoned&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Spectral Wall}} T1 no longer drains 1 stamina&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Spectral Wall}} T1 Damage Amp increased from 15% to 20%&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Spectral Wall}} T2 also increases wall duration by +2s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Spectral Wall}} T3 changed from &amp;quot;0.75s Stun on Impact&amp;quot; to &amp;quot;Creates 2 Turrets for 8s and increases slow by 30%&amp;quot; (creates them on the side facing you spread along the wall)&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} duration reduced from 13s to 8s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} minimum range reduced from 9m to 8.5m&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T1 tooltip updated to clarify that it also reduces dash distance&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T1 move slow reduced from 40% to 30%&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T1 dash slow increased from 20% to 30%&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T1 slow duration reduced from 2s to 1.5s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T2 cooldown reduction increased from -45s to -55s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T2 now also increases duration by 6s&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T3 damage increased from +21 to +25&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T3 spirit scaling from +0.2 to +0.25&lt;br /&gt;
* {{HeroIcon|McGinnis}}: {{AbilityIcon|Heavy Barrage}} T3 now also increases explosion radius by 2m&lt;br /&gt;
* {{HeroIcon|Mina}}: Stamina cooldown increased from 3.9s to 4.2s&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Rake}} cooldown increased from 10s to 16s&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Rake}} hero hit missing health as damage increased from 3% to 5%&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Rake}} heal per kill reduced from 30 to 25&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Rake}} heal per kill spirit scaling reduced from 0.43 to 0.3&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Rake}} T1 changed from &amp;quot;+20 Heal Per Kill&amp;quot; to &amp;quot;+60 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Rake}} T2 changed from &amp;quot;+54 Damage and +1.0 Heal Per Kill spirit scaling&amp;quot; to &amp;quot;+30 Heal Per Kill and -8s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Rake}} T3 now also provides +1.2 Heal Per Kill spirit scaling&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Sanguine Retreat}} cast range reduced 10m to 9m&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Sanguine Retreat}} recast window increased from 3s to 3.5s&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Sanguine Retreat}} T1 changed from &amp;quot;+3m Cast Range&amp;quot; to &amp;quot;+20% Fire Rate and 8 Bullets&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Sanguine Retreat}} T2 changed from &amp;quot;+25% Fire Rate and 8 Bullets&amp;quot; to &amp;quot;-10s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Sanguine Retreat}} T3 changed from &amp;quot;-12s Cooldown&amp;quot; to &amp;quot;+1 Recast&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Love Bites}} Cooldown increased from 8s to 10s&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Love Bites}} damage reduced from 6 to 4&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Love Bites}} damage spirit scaling increased from 0.06 to 0.09&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Love Bites}} bonus damage reduced from 55 to 45&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Love Bites}} bonus damage spirit scaling increased from 1.6 to 1.85&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Love Bites}} T1 changed from &amp;quot;On Proc: +4 m/s Move Speed for 3s&amp;quot; to &amp;quot;On Proc: 30% Slow for 3s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Love Bites}} T2 Damage/Bonus reduced from 3.6/50 to 3/45&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Love Bites}} T3 changed from &amp;quot;On Proc: -1 Stamina and 30% slow for 3s&amp;quot; to &amp;quot;-4s Cooldown and On Proc +25% Fire Rate for 5s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Nox Nostra}} cooldown increased from 115s to 130s&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Nox Nostra}} damage reduced from 6 to 5.6&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Nox Nostra}} T1 increased from +1.8 to +2.2&lt;br /&gt;
* {{HeroIcon|Mina}}: {{AbilityIcon|Nox Nostra}} T2 cooldown increased from -40s to -55s&lt;br /&gt;
* {{HeroIcon|Mirage}}: Bullet damage reduced from 15.2+0.5 to 14.8+0.3&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} no longer have a limited duration to launch each one. Functions as a normal charged ability.&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} collision and model size increased a bit&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} base charges reduced from 4 to 2&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} spirit scaling reduced from 1.0 to 0.8&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} now immediately steal the health from the target&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} Max Health steal increased from 45 to 70&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} changed from -8% Bullet Resist to +10% Damage Amp on that target from any damage you deal&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} cooldown increased from 40s to 45s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} T1 changed from &amp;quot;-15s Cooldown&amp;quot; to &amp;quot;+50 Max Health Steal&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} T2 changed from &amp;quot;-8% Bullet Resist&amp;quot; to &amp;quot;+2 Charges&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} T3 changed from &amp;quot;+63 Max Health Steal&amp;quot; to &amp;quot;+10% Damage Amp and +1.2 Spirit Scaling&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Fire Scarabs}} no longer has a reduced effect against non-heroes&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil|l1=Tornado}} renamed to Dust Devil&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil}} lift duration reduced from 1.0s to 0.4s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil}} spirit scaling reduced from 0.7 to 0.3&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil}} now slows affected enemies by 30% for 3s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil}} bullet evasion duration increased from 3.5s to 4s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil}} bullet evasion increased from 25% to 30%&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil}} T1 changed from &amp;quot;+0.4s Lift Duration&amp;quot; to &amp;quot;+60 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil}} T2 changed from &amp;quot;-14s Cooldown&amp;quot; to &amp;quot;-8s Cooldown and +30% Evasion&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Dust Devil}} T3 changed from &amp;quot;+20% Bullet&amp;quot; to &amp;quot;Can Recast within 5s. Increases spirit scaling by 1.0&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Djinn&#039;s Mark}} cooldown increased from 2.6s to 3s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Djinn&#039;s Mark}} multiplier duration increased from 4.5s to 5s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Djinn&#039;s Mark}} reveal duration increased from 3s to 6s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Djinn&#039;s Mark}} tooltip rewritten to be based on a &amp;quot;per stack&amp;quot; basis. A stack increases the damage by 200%. (this is just a tooltip change)&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Djinn&#039;s Mark}} T1 changed from &amp;quot;60% slow for 0.5s on 2x stack&amp;quot; to &amp;quot;Fading 60% slow for 0.5s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Djinn&#039;s Mark}} T2 increased from +8.1 Damage to +20&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Djinn&#039;s Mark}} T3 cooldown increased from -0.75s to -1s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Djinn&#039;s Mark}} T3 now also stuns for 0.5s at max stacks&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Traveler}} cooldown reduced from 155s to 145s&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Traveler}} can now be cast while on the zipline&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Traveler}} no longer channels. It now has a 3s delay before teleporting. Taking damage interrupts the ability and puts it on cooldown for 6s.&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Traveler}} now targets a location on the minimap rather than units. Places you at the ground level of that location.&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Traveler}} no longer grants +2m Move Speed and +26% Fire Rate&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Traveler}} T1 changed from &amp;quot;+2m Move Speed and -35s Cooldown&amp;quot; to &amp;quot;3m Move Speed for 12s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Traveler}} T2 changed from &amp;quot;Grants {{AbilityIcon|Traveler}} Buffs to Ally&amp;quot; to &amp;quot;400 Barrier for 12s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mirage}}: {{AbilityIcon|Traveler}} T3 &amp;quot;Unstoppable for 3s&amp;quot; to &amp;quot;-80s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Scorn}} damage reduced from 56 to 50&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Scorn}} radius reduced from 10m to 9m&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Scorn}} spirit scaling increased from 0.42 to 0.75&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Scorn}} T1 changed from &amp;quot;-3.75s Cooldown&amp;quot; to &amp;quot;+35 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Scorn}} T2 changed from &amp;quot;+21 Damage&amp;quot; to &amp;quot;-5s Cooldown and +1m Radius&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Burrow}} now lets you enter the tunnels &lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Burrow}} cooldown increased from 37s to 40s&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Burrow}} T1 changed from &amp;quot;+3s Duration&amp;quot; to &amp;quot;+50 Spin DPS&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Burrow}} T2 changed from &amp;quot;+68 Spin DPS and +2 Radius&amp;quot; to &amp;quot;+2 Spin Radius and +4s {{AbilityIcon|Burrow}} Time&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Burrow}} T3 increased from +2 m/s Move Speed to +4&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Burrow}} T3 increased from -19s Cooldown to -20s&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Sand Blast}} cooldown reduced from 42s to 40s&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Sand Blast}} duration reduced from 3s to 2.5s&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Sand Blast}} range reduced from 35m to 25m&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Sand Blast}} T1 changed from &amp;quot;+1s&amp;quot; to &amp;quot;+50 Damage and +5m Range&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Sand Blast}} T2 changed from &amp;quot;-23s Cooldown&amp;quot; to &amp;quot;Slows targets Move Speed and Dash Distance by -25%&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Sand Blast}} T3 changed from &amp;quot;Slows targets Move Speed and Dash Distance by -40%&amp;quot; to &amp;quot;+1s Duration and -20s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Combo}} cooldown increased from 90s to 150s&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Combo}} DPS increased from 35 to 60&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Combo}} T1 changed &amp;quot;+30% Bullet Resist During {{AbilityIcon|Combo}}&amp;quot; to &amp;quot;+100% Lifesteal&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Combo}} T2 changed from &amp;quot;+0.7s Duration&amp;quot; to &amp;quot;+60 DPS and +50% Bullet Resist&amp;quot;&lt;br /&gt;
* {{HeroIcon|Mo &amp;amp; Krill}}: {{AbilityIcon|Combo}} T3 changed from &amp;quot;+32 DPS and 80% Lifesteal&amp;quot; to &amp;quot;+0.7s Duration and -60s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Bookwyrm|l1=Conjure Dragon}} renamed to Bookwyrm&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Bookwyrm}} fixed initial location not starting where you click it&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Bookwyrm}} cooldown increased from 30s to 33s&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Bookwyrm}} T1 changed from &amp;quot;-5s Cooldown&amp;quot; to &amp;quot;+2s Trail Duration and +1m Width&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Bookwyrm}} T2 changed from &amp;quot;+2s Trail Duration&amp;quot; to &amp;quot;-8s Cooldown and +10m Travel Range&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Bookwyrm}} T3 Damage/DPS rescaled from 104/27 to 100/30&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Bookwyrm}} T3 now also grants +1 Charge&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Plot Armor|l1=Defend and Fight!}} renamed to Plot Armor&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Plot Armor}} barrier spirit scaling reduced from 1.6 to 1.3&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Plot Armor}} T3 now also increases spirit scaling (+0.3)&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Captivating Read}} height area no longer increases with range bonuses&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Captivating Read}} cooldown increased from 25s to 30s&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Captivating Read}} immobilize duration reduced from 1.25s to 1s&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Captivating Read}} T1 cooldown increased from -6s to -11s&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Captivating Read}} T2 immobilize duration increased from 0.75s to 1s&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Captivating Read}} T3 now also increases radius by 1m&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Rallying Charge}} T2 now also reduces cooldown by 30s&lt;br /&gt;
* {{HeroIcon|Paige}}: {{AbilityIcon|Rallying Charge}} T3 now also increases Max Amp from +100% to +150%&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} radius reduced from 6m to 5.5m&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} radius increases by +1m per Pulse&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} Amp Per Stack reduced from 6% to 4%&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} cooldown increased from 28s to 32s&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} spirit scaling reduced from 0.6 to 0.4&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} changed from -30% Move Speed for 2s to -20% Time Slow for 0.2s&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} T1 changed from +0.8s Duration to -12s Cooldown&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} T2 changed from &amp;quot;-8s Cooldown&amp;quot; to &amp;quot;+20 Pulse Damage and +0.5 Spirit Scaling&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Pulse Grenade}} T3 changed from &amp;quot;+36 Pulse Damage and +0.8m Radius per Pulse&amp;quot; to &amp;quot;+4% Damage Amp Per Stack and +1.6s Duration&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Time Wall}} duration reduced from 6s to 5.5&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Time Wall}} no longer damages enemies going through it&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Time Wall}} now increases allied bullet speeds going through it by 100%&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Time Wall}} now increases adds +30% Weapon Damage to allied bullet damage (affects Carbine)&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Time Wall}} T1 increased from +2m Width to +3m&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Time Wall}} T2 changed from &amp;quot;+9% Max Health Damage&amp;quot; to &amp;quot;+2.5s Duration and +30% Weapon Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Time Wall}} T3 changed from silencing enemies to Allowing Charges and Granting +1 Charge (4s Charge Time)&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Kinetic Carbine}} cooldown increased from 27s to 30s&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Kinetic Carbine}} speed spirit scaling increased from 0.09 to 0.13&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Kinetic Carbine}} base damage scale increased from 100% to 125%&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Kinetic Carbine}} T2 changed from &amp;quot;-8s Cooldown and +2s Charge Hold&amp;quot; to &amp;quot;-12s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Kinetic Carbine}} T3 now also increases charge hold by 2s&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Paradoxical Swap}} cooldown increased from 75s to 95s&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Paradoxical Swap}} no longer has 80% Spirit Lifesteal&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Paradoxical Swap}} damage changed from 115 (0.6 spirit scaling) to 10% Current Health&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Paradoxical Swap}} T1 changed from &amp;quot;-15s Cooldown&amp;quot; to &amp;quot;+200 Barrier (1.5 Spirit Scaling)&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Paradoxical Swap}} T2 changed from &amp;quot;+81 Damage&amp;quot; to &amp;quot;+13m Cast Range and -35s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Paradox}}: {{AbilityIcon|Paradoxical Swap}} T3 changed from &amp;quot;+15m Cast Range&amp;quot; to &amp;quot;Swaps additional enemies in 7m radius and +10% Current Health Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Barrage}} projectile speed increased by 15%&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Barrage}} now lets you use stamina during the ability&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Barrage}} now lets you use {{AbilityIcon|Flying Cloak}} during the ability&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Barrage}} T1 increased from +12.6 Damage Per Projectile to +16&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Barrage}} T2 cooldown increased from -14s to -16s&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Barrage}} T3 increased from +2m Radius to +3m&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Flying Cloak}} cooldown reduced from 32s to 26s&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Flying Cloak}} damage reduced from 70 to 60&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Flying Cloak}} duration increased from 3.4s to 3.8s (travels slower, same total distance)&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Flying Cloak}} T1 changed from &amp;quot;-14s Cooldown&amp;quot; to &amp;quot;+70 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Flying Cloak}} T2 changed from &amp;quot;+76 Damage&amp;quot; to &amp;quot;+5 Weapon Damage upon cast for 8s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Flying Cloak}} T3 changed from &amp;quot;+7 Weapon Damage after teleporting for 10s&amp;quot; to &amp;quot;+1.6s Travel Time and -14s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Enchanter&#039;s Satchel}} spirit scaling increased from 0.61 to 0.9&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Enchanter&#039;s Satchel}} T3 now also reduces movement speed by 40%&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Enchanter&#039;s Satchel}} T3 Fire Rate slow increased from 35% to 40%&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Enchanter&#039;s Satchel}} T3 Escape duration increased from +0.5s to +1.5s&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Enchanter&#039;s Satchel}} T3 now also increases radius by 4m&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} no longer applies 12% Current Health Damage&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} DPS increased from 28 to 32&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} spirit scaling increased from 0.17 to 0.2&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} cooldown increased from 140s to 150s&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} T1 increased from -25s Cooldown to -40s Cooldown&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} T2 no longer reduces healing by 40%&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} T2 now also increases radius by 4m&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} T3 no longer increases radius by 6m&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} T3 now prevents all healing on targets&lt;br /&gt;
* {{HeroIcon|Pocket}}: {{AbilityIcon|Affliction}} T3 increases spirit scaling by +0.1&lt;br /&gt;
* {{HeroIcon|Rem}}: {{AbilityIcon|Lil Helpers}} trooper base healing changed from 10/s to 8/s. The delay between heals has been reduced so the frequency of healing is more constant. (overall reduction)&lt;br /&gt;
* {{HeroIcon|Rem}}: {{AbilityIcon|Lil Helpers}} trooper healing spirit scaling increased from 0.125 to 0.14&lt;br /&gt;
* {{HeroIcon|Rem}}: {{AbilityIcon|Naptime}} sleep move speed reduced from 2m/s to 1.5m/s&lt;br /&gt;
* {{HeroIcon|Rem}}: {{AbilityIcon|Naptime}} sleep duration decreased from 4.25s to 4s&lt;br /&gt;
* {{HeroIcon|Rem}}: {{AbilityIcon|Naptime}} radius decreased from 20m to 17.0m&lt;br /&gt;
* {{HeroIcon|Rem}}: {{AbilityIcon|Naptime}} T2 changed from &amp;quot;unstoppable and -35% Damage resist while channeling&amp;quot; to &amp;quot;+0.5s Sleep Duration and +3m Radius&amp;quot;&lt;br /&gt;
* {{HeroIcon|Rem}}: {{AbilityIcon|Naptime}} T3 now also grants +50% damage resist while channeling&lt;br /&gt;
* {{HeroIcon|Seven}}: Move Speed no longer scales with spirit power&lt;br /&gt;
* {{HeroIcon|Seven}}: Sprint speed increased from 0.6m to 1.8m&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Lightning Ball}} slows down less vs non-heroes (previously was 2m/s for all, now 3.5m/s for non-heroes)&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Lightning Ball}} fixed now doing damage if another ball was already hitting a target&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Lightning Ball}} T2 now also increases lifetime by 1s&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Static Charge}} damage reduced from 38 to 35&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Static Charge}} cast range reduced from 16m to 15m&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Static Charge}} cast range no longer increases with spirit power&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Static Charge}} T1 increased from -19s Cooldown to -20s&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Static Charge}} T2 now also increases cast range by +5m&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Static Charge}} T3 now also increases damage by +160&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Power Surge}} duration no longer scales with spirit power&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Power Surge}} cooldown increased from 48s to 50s&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Power Surge}} max jumps increased from 3 to 4&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Power Surge}} T1 increased from -15s to -18s&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Power Surge}} T2 changed from &amp;quot;-10% Spirit Resist for 6s&amp;quot; to &amp;quot;+3m Move Speed, +8 Damage and increased Spirit Scaling (+0.23)&amp;quot;&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Power Surge}} T3 changed from &amp;quot;+11 Shock Damage, scaling and +3 max jumps&amp;quot; to &amp;quot;-15% Spirit Resist for 8s and +12s Duration&amp;quot;&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Storm Cloud}} allows movement in the base ability (1.5m)&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Storm Cloud}} bullet resistance reduced from 20% to 0%&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Storm Cloud}} T1 bullet resist increased from 35% to 55%&lt;br /&gt;
* {{HeroIcon|Seven}}: {{AbilityIcon|Storm Cloud}} T3 increases move speed by +3m (was +3.8m before)&lt;br /&gt;
* {{HeroIcon|Shiv}}: Stamina reduced from 3 to 2&lt;br /&gt;
* {{HeroIcon|Shiv}}: Stamina movement speed reduced from 6.7 to 6.5&lt;br /&gt;
* {{HeroIcon|Shiv}}: Bullet damage growth increased from 0.154 to 0.165&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Serrated Knives}} no longer has impact damage&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Serrated Knives}} Bleed DPS per knife increased from 4 to 10&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Serrated Knives}} Bleed DPS spirit scaling increased from 0.13 to 0.15&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Serrated Knives}} T1 changed from &amp;quot;+1 Charge&amp;quot; to &amp;quot;+2s Duration&amp;quot;&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Serrated Knives}} T2 changed from &amp;quot;+2s Duration&amp;quot; to &amp;quot;+2 Charges&amp;quot;&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Serrated Knives}} T3 no longer has +30 Impact Damage&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Serrated Knives}} T3 DPS increased from +5.5 to +12&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Serrated Knives}} T3 increases spirit scaling by +0.10&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Slice and Dice}} cooldown increased from 15s to 16s&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Slice and Dice}} Impact damage reduced from 75 to 60&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Slice and Dice}} reduces Spirit Resistance by 6% for 16s. Multiple instances stack.&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Slice and Dice}} T1 increased from -3s Cooldown to -6s Cooldown&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Slice and Dice}} T2 changed from &amp;quot;+50 Impact Damage&amp;quot; to &amp;quot;-8% Spirit Resistance and +2m Dash Range&amp;quot;&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Slice and Dice}} T3 now also grants +50 Impact Damage&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Killing Blow}} is no longer unit targeted, you jump in the direction forward with some small control&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Killing Blow}} Damage Amp reduced from 15% to 14%&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Killing Blow}} T2 changed from &amp;quot;+5% Enemy Health Threshold and +6% Damage Amp&amp;quot; to &amp;quot;+8% Damage Amp&amp;quot; &lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Killing Blow}} T3 now grants you 20s to recast the ultimate, rather than removing the cooldown&lt;br /&gt;
* {{HeroIcon|Shiv}}: {{AbilityIcon|Killing Blow}} T3 now also increases enemy health threshold by +5%&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Mauling Leap}} damage scaling reduced from 1.9 to 1.5&lt;br /&gt;
* {{HeroIcon|Silver}}: Fixed {{AbilityIcon|Tail Whack}} being considered a movement ability&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Tail Whack}} disarm duration reduced from 2.5s to 2s&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Tail Whack}} slow duration increased from 1.5s to 2s&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Tail Whack}} T3 changed from &amp;quot;+1s Disarm Duration&amp;quot; to &amp;quot;1.5s Debuff Duration&amp;quot;&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Lycan Curse}} cooldown increased from 35s to 50s&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Lycan Curse}} base health bonus reduced from 100 to 75&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Lycan Curse}} no longer grants +14% Bullet and Spirit Resistance&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Lycan Curse}} no longer grants +2m Move Speed&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Lycan Curse}} T1 resist increased from +14% to +15%&lt;br /&gt;
* {{HeroIcon|Silver}}: {{AbilityIcon|Lycan Curse}} T2 bonus health increased from 125 to 150&lt;br /&gt;
* {{HeroIcon|Victor}}: Bullet damage increased from 12.3 to 12.5&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Pain Battery}} now starts charged&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Pain Battery}} range increased from 20m to 28m&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Pain Battery}} reduced randomness on the projectile paths&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Pain Battery}} bolt count from 5 to 7&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Pain Battery}} T2 increased from +36 to +50&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Pain Battery}} T3 now also increases spirit scaling by +0.6&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Jumpstart}} cooldown increased from 23s to 30s&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Jumpstart}} Move Speed reduced from 4m to 3m&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Jumpstart}} spirit scaling reduced from 1.8 to 1.2&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Jumpstart}} T1 increased from +1.5m to +3m Move Speed&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Jumpstart}} T2 now also reduces cooldown by -8s&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Jumpstart}} T3 now also provides +1 Charge&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Jumpstart}} T3 no longer reduces cooldown&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Jumpstart}} T3 now also increases spirit scaling by 0.8&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} time to max DPS reduced from 10s to 6s&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} radius increased from 7.7m to 10m&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} toggle cooldown reduced from 2.5s to 2s&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} Min DPS reduced from 16 to 12&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} Min DPS spirit scaling reduced from 0.18 to 0.135&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} Max DPS reduced from 70 to 54&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} Max DPS spirit scaling reduced from 0.9 to 0.67&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} T2 Min/Max DPS reduced from 8/36 to 6/26&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} Text Progress bar indicates time to Max DPS&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Aura of Suffering}} T3 reduced from +13% Damage to +15%&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Shocking Reanimation}} radius reduced from 13m to 12m&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Shocking Reanimation}} rebirth health reduced from 60% to 50%&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Shocking Reanimation}} T1 changed from &amp;quot;+3m Radius and +90 Damage&amp;quot; to &amp;quot;While on Cooldown: +15% Fire Rate and +6 Spirit Damage Per Bullet (0.06 scaling)&amp;quot;&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Shocking Reanimation}} T2 rebirth health increased from 40% to 50%&lt;br /&gt;
* {{HeroIcon|Victor}}: {{AbilityIcon|Shocking Reanimation}} T3 changed from &amp;quot;While on Cooldown: +18% Fire Rate and +9 Spirit Damage Per Bullet (0.06 scaling)&amp;quot; to &amp;quot;+6m Radius, +1s Stun and -50s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Vindicta}}: Fire Rate no longer scales with Spirit Power&lt;br /&gt;
* {{HeroIcon|Vindicta}}: Bullet damage now scales with spirit power (0.022)&lt;br /&gt;
* {{HeroIcon|Vindicta|l1=Vindcita}}{{sic}}: Ammo reduced from 22 to 19&lt;br /&gt;
* {{HeroIcon|Vindicta}}: Bullet Velocity increased from 557 to 660&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Stake}} damage reduced from 55 to 40&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Stake}} damage spirit scaling increased from 0.37 to 0.5&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Stake}} projectile speed increased from 20m/s to 25m/s&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Stake}} T1 changed from &amp;quot;-35% Fire Rate&amp;quot; to &amp;quot;+65 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Stake}} T3 Tether Duration increased from +0.5s to +0.75s&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Stake}} T3 capture radius increased from +1m to +2m&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} now allows you to use melee&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} now allows parry to be used&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} now grants you +50% Item Cast Range&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} spirit damage scaling reduced from 0.22 to 0.18&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} duration reduced from 15s to 13s&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} T2 duration increased from +8s to +10s&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} T3 Spirit Damage Per Bullet reduced from 12.6 to 10&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} T3 now increases spirit scaling by 0.1&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Flight}} T3 now also refreshes duration on hero kill&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Crow Familiar}} now releases a swarm of crows in a cone forward, hitting all enemies along the path&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Crow Familiar}} debuff duration no longer scales with spirit power&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Crow Familiar}} debuff duration increased from 4s to 5s&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Crow Familiar}} bleed damage reduced from 2.7% to 2.2%&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Crow Familiar}} damage increased from 37 to 40&lt;br /&gt;
* {{HeroIcon|Vindicta|l1=Vindcita}}{{sic}}: {{AbilityIcon|Crow Familiar}} cooldown increased from 28s to 32s&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Crow Familiar}} T1 changed from &amp;quot;Ricochet up to 2 times&amp;quot; to &amp;quot;Reduces healing by -35%&amp;quot;&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Crow Familiar}} T2 now also increase bleed damage by +0.5%&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Crow Familiar}} T3 now also increases debuff duration by 2s&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Assassinate}} while scoped no longer un-scopes when using items&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Assassinate}} now has a 4s buffer on impact for bonus credit&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Assassinate}} while scoped now plays a sound for you when the it is fully charged&lt;br /&gt;
* {{HeroIcon|Vindicta}}: {{AbilityIcon|Assassinate}} weapon damage bonus increased from 5% to 6%&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} bounces once by default&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} cooldown reduced from 30s to 26&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} spirit scaling reduced from 1.77 to 0.8&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} ground effect now increases slide distance by 60% for you and your allies&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} multiple hit damage value reduced from 50% to 50/38/26%&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} T1 radius increased from +1m to +2m&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} T2 cooldown increased from -12s to -14s&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} T3 spirit scaling increased from +0.4 to +1.3&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Splatter}} T3 still adds 2 bounces&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|The Cube}} now has a very brief period where allies cannot cancel to prevent accidental cancels&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|The Cube}} healing spirit scaling increased from 0.14 to 0.3&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|The Cube}} T3 increased from -21s Cooldown to -25s&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Puddle Punch}} now grants +30% Air Control when affecting yourself or allies&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Puddle Punch}} Charge Time increased from 1.5s to 1.7s&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Puddle Punch}} Slow increased from 15% to 20%&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Puddle Punch}} now acts as if its close range with respect to item procs (like {{ItemIcon|Point Blank}})&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Puddle Punch}} radius reduced from 4.5m to 4m&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Puddle Punch}} T2 changed from &amp;quot;+27 Damage and -15% Move Slow&amp;quot; to &amp;quot;+1.5m Radius and +30 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} no longer can carry Urn&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} turn rate improved a bit&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} can now use abilities and items (rather than being locked behind T3)&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} cooldown increased from 115s to 130s&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} duration increased from 9s to 10s&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} Bullet and Spirit resist reduced from 60% to 35%&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} T1 changed from &amp;quot;+5s Duration&amp;quot; to &amp;quot;-30s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} T2 reduced from +72 Damage to +70&lt;br /&gt;
* {{HeroIcon|Viscous}}: {{AbilityIcon|Goo Ball}} T3 changed from &amp;quot;Can now use abilities and items&amp;quot; to &amp;quot;+6s duration and +0.3s Stun Duration&amp;quot;&lt;br /&gt;
* {{HeroIcon|Warden}}: Bullet growth per boon reduced from 0.44 to 0.38&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Alchemical Flask}} Weapon Damage reduction reduced from -30% to -25%&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Alchemical Flask}} T2 damage increased from +36 to +40&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Alchemical Flask}} T2 now also increases Weapon Damage Reduction by -20%&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Alchemical Flask}} T2 no longer increases radius by 1m&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Alchemical Flask}} T3 cooldown increased from -6.5s to -7s&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Alchemical Flask}} T3 now also increases radius by 2m&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Willpower}} duration reduced from 7s to 5s&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Willpower}} cooldown reduced from 42s to 40&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Willpower}} barrier now scales with spirit power in the base ability (+0.5)&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Willpower}} T2 cooldown from -19s to -22s&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Willpower}} T2 now also increases duration by +2s&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Willpower}} T3 changed from &amp;quot;+150 Barrier Health and improved scaling (3.7)&amp;quot; to &amp;quot;+40% Debuff Resistance and improved scaling (2.5)&amp;quot;&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Binding Word}} cast range reduced from 20m to 15m&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Binding Word}} cooldown decreased from 37s to 34s&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Binding Word}} T1 changed from &amp;quot;+1s Immobilize Duration&amp;quot; to &amp;quot;+20% Bullet Damage to Trapped heroes for 5s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Binding Word}} T2 changed from &amp;quot;-19s Cooldown&amp;quot; to &amp;quot;+0.75s Duration and +12m Cast Range&amp;quot;&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Binding Word}} T2 now increases trap duration by 0.75s&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Binding Word}} T3 changed from &amp;quot;+20% Bullet Damage&amp;quot; to &amp;quot;-18s Cooldown and Silences enemies until they escape or are trapped&amp;quot;&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Last Stand}} Channeling bullet and spirit resist increased from 30% to 60%&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Last Stand}} radius reduced from 13m to 12m&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Last Stand}} T1 increased from +3m Radius to +4m&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Last Stand}} T3 no longer grants +50% Bullet and Spirit Resist&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Last Stand}} T3 duration increased from +2.5s to +3s&lt;br /&gt;
* {{HeroIcon|Warden}}: {{AbilityIcon|Last Stand}} T3 now also grants you Unstoppable while channeling&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} cards now have specific suites with special bonuses.&lt;br /&gt;
** Card Types:&lt;br /&gt;
*** Spades: +70% Damage&lt;br /&gt;
*** Diamond: Cuts enemy resistances by -8% for 5s. Does not stack.&lt;br /&gt;
*** Hearts: Heals you for 75 HP (1.25 spirit scaling, half heal no non-heroes)&lt;br /&gt;
*** Clubs: 30% Slow for 3s&lt;br /&gt;
*** Joker: Has all of the above effects and bounces to an additional enemy within 20m. (Has 1/9th chance)&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} base charge count increased from 1 to 2&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} base damage reduced from 60 to 45&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} spirit scaling reduced from 1.0 to 0.55&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} buildup now takes 20% longer&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} cooldown reduced from 0.75s to 0.5s&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} post cast time reduced from 0.2s to 0.1&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} now highlights the card that will be throw next.&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} now has unique sounds for each card suite that is summoned.&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} T1 increased from &amp;quot;+1 Charges&amp;quot; to &amp;quot;+2 Charges&amp;quot;&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} T2 changed from &amp;quot;+35 Damage&amp;quot; to &amp;quot;+40 Damage and increased spirit scaling (+0.4)&amp;quot;&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Card Trick}} T2 changed from &amp;quot;+50% Card Summon Rate and 30% slow for 1s&amp;quot; to &amp;quot;Improves Card Suites and increased joker chances&amp;quot; (new totals are Spades: 2.5x, Diamond: -13%, Heal: 150/2.0, Clubs: 50%, Joker: 1/5th chance)&lt;br /&gt;
* {{HeroIcon|Wraith}}: Fixed {{AbilityIcon|Project Mind}} interaction with stuns&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Full Auto}} no longer affects allies (previously gave half fire rate to allies)&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Full Auto}} duration no longer scales with Spirit Power&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Full Auto}} cooldown reduced from 48s to 45s&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Full Auto}} base ability now deals +2 Spirit Damage Per Bullet (0.03 Spirit Scaling)&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Full Auto}} T1 increased from -14s Cooldown to -20s&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Full Auto}} T2 changed from &amp;quot;2.52 Spirit Damage per Bullet&amp;quot; to &amp;quot;+10% Fire Rate and +3s Duration&amp;quot;&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Full Auto}} T3 changed from &amp;quot;+15% Bullet and Spirit Lifesteal and increased spirit scaling&amp;quot; to &amp;quot;Unlimited Ammo and increased spirit scaling (+0.06)&amp;quot;&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Telekinesis}} cooldown increased from 110s to 120s&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Telekinesis}} cast range reduced from 20m to 14m&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Telekinesis}} cast time increased from 0.1s to 0.3s&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Telekinesis}} no longer has a projectile, it now instantly lifts the target for 0.75s and gives you a location target on the ground. After the 0.75s is over, it&#039;ll throw the hero towards that location up to 15m away. The target will take 100 Damage, 40% move slow and prevent stamina/movement-item and ability usage for 3s.&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Telekinesis}} T1 changed from &amp;quot;-25s Cooldown&amp;quot; to &amp;quot;+100 Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Telekinesis}} T2 changed from &amp;quot;+0.75s Silence and Disarm Duration&amp;quot; to &amp;quot;-50s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Wraith}}: {{AbilityIcon|Telekinesis}} T3 changed from &amp;quot;Bounces to nearby target&amp;quot; to &amp;quot;+1.5s Debuff duration and +6m Throw and Cast Range&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Power Slash}} being held down no longer automatically fires it&lt;br /&gt;
* {{HeroIcon|Yamato}}: You can now cast Parry directly while channeling {{AbilityIcon|Power Slash}} to fire the {{AbilityIcon|Power Slash}} and parry&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Power Slash}} base ability now has +60% Bullet Resist while channeling&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Power Slash}} cooldown increased from 10.5s to 12s&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Power Slash}} Slash Length reduced from 25m to 22m&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Power Slash}} T1 changed from &amp;quot;+60% Bullet Resist while channeling&amp;quot; to &amp;quot;40% Slow for 3s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Power Slash}} T2 changed from &amp;quot;-2s Cooldown and 40% slow for 3s&amp;quot; to &amp;quot;-4s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Power Slash}} T3 now also grants +8m Range&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Flying Slash|l1=Flying Strike}} renamed to Flying Slash&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Flying Slash}} is now light melee damage rather than spirit&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Flying Slash}} slow increased from -30% to -50%&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Flying Slash}} cooldown increased from 21s to 36s&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Flying Slash}} range increased from 20m to 25m&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Flying Slash}} T1 changed from &amp;quot;25% Slow&amp;quot; to &amp;quot;-18s Cooldown&amp;quot;&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Flying Slash}} T2 changed from &amp;quot;+20m Cast Range&amp;quot; to &amp;quot;+20m Cast Range and gain +40 Spirit for 6s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Flying Slash}} T3 changed from &amp;quot;Can Grapple to ally heroes and +6 Weapon Damage for 10s&amp;quot; to &amp;quot;Can Grapple to ally heroes. Becomes Charged and grants +2 charges (3s between charges).&amp;quot;&lt;br /&gt;
* {{HeroIcon|Yamato}}: Fixed {{AbilityIcon|Flying Slash}} T3 ally cast stopping too soon before reaching the player&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Crimson Slash}} cooldown increased from 15s to 16s&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Crimson Slash}} Fire Rate reduction increased from -18% to -30%&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Crimson Slash}} T1 changed from &amp;quot;-26% Fire Rate&amp;quot; to &amp;quot;On Hit: +30% Melee Damage for 4s&amp;quot;&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Crimson Slash}} T3 increased from -9s Cooldown to -10s&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Crimson Slash}} T3 now also increases spirit scaling (+0.6)&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Shadow Transformation}} cooldown increased from 110s to 130s&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Shadow Transformation}} Bullet and Spirit Resist reduced from 40% to 30%&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Shadow Transformation}} T1 changed from &amp;quot;+14% Fire Rate&amp;quot; to &amp;quot;+5 Weapon Damage&amp;quot;&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Shadow Transformation}} T2 now also reduces cooldown by 25s&lt;br /&gt;
* {{HeroIcon|Yamato}}: {{AbilityIcon|Shadow Transformation}} T3 increased from +20% Bullet and Spirit Resist to +30%&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/Sandbox/Module?diff=62193</id>
		<title>User:Sur/Sandbox/Module</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/Sandbox/Module?diff=62193"/>
		<updated>2026-03-10T05:46:09Z</updated>

		<summary type="html">&lt;p&gt;Sur: Created page with &amp;quot;p = { }&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;p = {&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Data:GenericData.json?diff=25404</id>
		<title>Data:GenericData.json</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Data:GenericData.json?diff=25404"/>
		<updated>2025-05-08T21:03:40Z</updated>

		<summary type="html">&lt;p&gt;Sur: item price per tier manually set to 800,1600,3200,6400&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{&lt;br /&gt;
	&amp;quot;AimSpringStrength&amp;quot;: [&lt;br /&gt;
		0,&lt;br /&gt;
		2,&lt;br /&gt;
		10,&lt;br /&gt;
		300&lt;br /&gt;
	],&lt;br /&gt;
	&amp;quot;CurrencyTypeSounds&amp;quot;: {&lt;br /&gt;
		&amp;quot;AbilityPoints&amp;quot;: {&lt;br /&gt;
			&amp;quot;SourceSounds&amp;quot;: {}&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;Gold&amp;quot;: {&lt;br /&gt;
			&amp;quot;SourceSounds&amp;quot;: {}&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;DamageFlash&amp;quot;: {&lt;br /&gt;
		&amp;quot;FlashType_BulletDamage&amp;quot;: {&lt;br /&gt;
			&amp;quot;Duration&amp;quot;: 0.25,&lt;br /&gt;
			&amp;quot;Coverage&amp;quot;: 0.5,&lt;br /&gt;
			&amp;quot;Hardness&amp;quot;: 0.7,&lt;br /&gt;
			&amp;quot;Brightness&amp;quot;: 1.2,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				255,&lt;br /&gt;
				0,&lt;br /&gt;
				0&lt;br /&gt;
			]&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;FlashType_TechDamage&amp;quot;: {&lt;br /&gt;
			&amp;quot;Duration&amp;quot;: 0.25,&lt;br /&gt;
			&amp;quot;Coverage&amp;quot;: 0.5,&lt;br /&gt;
			&amp;quot;Hardness&amp;quot;: 0.5,&lt;br /&gt;
			&amp;quot;Brightness&amp;quot;: 1.5,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				35,&lt;br /&gt;
				17,&lt;br /&gt;
				236&lt;br /&gt;
			]&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;FlashType_Healing&amp;quot;: {&lt;br /&gt;
			&amp;quot;Duration&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;Coverage&amp;quot;: 0.5,&lt;br /&gt;
			&amp;quot;Hardness&amp;quot;: 0,&lt;br /&gt;
			&amp;quot;Brightness&amp;quot;: 1.2,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				0,&lt;br /&gt;
				195,&lt;br /&gt;
				45&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;BrightnessInLightSensitivityMode&amp;quot;: 0.6&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;FlashType_CritDamage&amp;quot;: {&lt;br /&gt;
			&amp;quot;Duration&amp;quot;: 0.33,&lt;br /&gt;
			&amp;quot;Coverage&amp;quot;: 0.6,&lt;br /&gt;
			&amp;quot;Hardness&amp;quot;: 0.9,&lt;br /&gt;
			&amp;quot;Brightness&amp;quot;: 1.7,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				255,&lt;br /&gt;
				255,&lt;br /&gt;
				0&lt;br /&gt;
			]&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;FlashType_MeleeActivate&amp;quot;: {&lt;br /&gt;
			&amp;quot;Duration&amp;quot;: 0.275,&lt;br /&gt;
			&amp;quot;Coverage&amp;quot;: 0.5,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				254,&lt;br /&gt;
				101,&lt;br /&gt;
				40&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;Brightness&amp;quot;: 3,&lt;br /&gt;
			&amp;quot;Hardness&amp;quot;: 0&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;DamageIndicatorParamSets&amp;quot;: {&lt;br /&gt;
		&amp;quot;DamageIndicatorSet_Normal&amp;quot;: {},&lt;br /&gt;
		&amp;quot;DamageIndicatorSet_MinionDealt&amp;quot;: {},&lt;br /&gt;
		&amp;quot;DamageIndicatorSet_DOT&amp;quot;: {},&lt;br /&gt;
		&amp;quot;DamageIndicatorSet_TroopersAndNeutrals&amp;quot;: {}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;DamageIndicatorSounds&amp;quot;: {},&lt;br /&gt;
	&amp;quot;DamageReceivedSounds&amp;quot;: {},&lt;br /&gt;
	&amp;quot;DefaultDOF&amp;quot;: {&lt;br /&gt;
		&amp;quot;DofNearBlurry&amp;quot;: 0,&lt;br /&gt;
		&amp;quot;DofNearCrisp&amp;quot;: 0,&lt;br /&gt;
		&amp;quot;DofFarBlurry&amp;quot;: 0,&lt;br /&gt;
		&amp;quot;DofFarCrisp&amp;quot;: 0&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;GlitchSettings&amp;quot;: {&lt;br /&gt;
		&amp;quot;Strength&amp;quot;: 1,&lt;br /&gt;
		&amp;quot;QuantizeType&amp;quot;: 2,&lt;br /&gt;
		&amp;quot;QuantizeScale&amp;quot;: 0.5,&lt;br /&gt;
		&amp;quot;QuantizeStrength&amp;quot;: 0.2,&lt;br /&gt;
		&amp;quot;FrameRate&amp;quot;: 5,&lt;br /&gt;
		&amp;quot;Speed&amp;quot;: 10,&lt;br /&gt;
		&amp;quot;JumpStrength&amp;quot;: 1,&lt;br /&gt;
		&amp;quot;DistortStrength&amp;quot;: 1.25,&lt;br /&gt;
		&amp;quot;WhiteNoiseStrength&amp;quot;: 3,&lt;br /&gt;
		&amp;quot;ScanlineStrength&amp;quot;: 1.5,&lt;br /&gt;
		&amp;quot;BreakupStrength&amp;quot;: 0&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;HealingReceivedSounds&amp;quot;: {},&lt;br /&gt;
	&amp;quot;HeroTestingTargetDummyUpgrades&amp;quot;: [&lt;br /&gt;
		&amp;quot;upgrade_toughness_2&amp;quot;,&lt;br /&gt;
		&amp;quot;upgrade_health_regen_1&amp;quot;,&lt;br /&gt;
		&amp;quot;upgrade_toughness_3&amp;quot;,&lt;br /&gt;
		&amp;quot;upgrade_health_percent_large&amp;quot;,&lt;br /&gt;
		&amp;quot;upgrade_out_of_combat_health_regen&amp;quot;,&lt;br /&gt;
		&amp;quot;upgrade_zipine_mastery&amp;quot;&lt;br /&gt;
	],&lt;br /&gt;
	&amp;quot;IdolParams&amp;quot;: {&lt;br /&gt;
		&amp;quot;LoopingSequenceName&amp;quot;: &amp;quot;golden_idol_idle&amp;quot;,&lt;br /&gt;
		&amp;quot;IdolReturnLocationParticleScale&amp;quot;: 2,&lt;br /&gt;
		&amp;quot;IdolDropHeight&amp;quot;: 1800,&lt;br /&gt;
		&amp;quot;IdolDropDuration&amp;quot;: 12.5&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;ItemPricePerTier&amp;quot;: [&lt;br /&gt;
		0,&lt;br /&gt;
		800,&lt;br /&gt;
		1600,&lt;br /&gt;
		3200,&lt;br /&gt;
		6400&lt;br /&gt;
	],&lt;br /&gt;
	&amp;quot;LaneInfo&amp;quot;: [&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;LaneName&amp;quot;: &amp;quot;Yellow&amp;quot;,&lt;br /&gt;
			&amp;quot;CSSClass&amp;quot;: &amp;quot;yellowLane&amp;quot;,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				249,&lt;br /&gt;
				213,&lt;br /&gt;
				6&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;MinimapColorOverride&amp;quot;: [&lt;br /&gt;
				249,&lt;br /&gt;
				212,&lt;br /&gt;
				5&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;MinimapZiplineColorOverride&amp;quot;: [&lt;br /&gt;
				249,&lt;br /&gt;
				212,&lt;br /&gt;
				5&lt;br /&gt;
			]&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;LaneName&amp;quot;: &amp;quot;Yellow + Orange&amp;quot;,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				0,&lt;br /&gt;
				0,&lt;br /&gt;
				0&lt;br /&gt;
			]&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;LaneName&amp;quot;: &amp;quot;Green&amp;quot;,&lt;br /&gt;
			&amp;quot;CSSClass&amp;quot;: &amp;quot;greenLane&amp;quot;,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				48,&lt;br /&gt;
				151,&lt;br /&gt;
				70&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;MinimapColorOverride&amp;quot;: [&lt;br /&gt;
				47,&lt;br /&gt;
				151,&lt;br /&gt;
				68&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;MinimapZiplineColorOverride&amp;quot;: [&lt;br /&gt;
				47,&lt;br /&gt;
				151,&lt;br /&gt;
				68&lt;br /&gt;
			]&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;LaneName&amp;quot;: &amp;quot;Blue&amp;quot;,&lt;br /&gt;
			&amp;quot;CSSClass&amp;quot;: &amp;quot;blueLane&amp;quot;,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				67,&lt;br /&gt;
				124,&lt;br /&gt;
				220&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;MinimapColorOverride&amp;quot;: [&lt;br /&gt;
				67,&lt;br /&gt;
				125,&lt;br /&gt;
				220&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;MinimapZiplineColorOverride&amp;quot;: [&lt;br /&gt;
				67,&lt;br /&gt;
				125,&lt;br /&gt;
				220&lt;br /&gt;
			]&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;LaneName&amp;quot;: &amp;quot; + Purple&amp;quot;,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				0,&lt;br /&gt;
				0,&lt;br /&gt;
				0&lt;br /&gt;
			]&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;LaneName&amp;quot;: &amp;quot;Purple&amp;quot;,&lt;br /&gt;
			&amp;quot;CSSClass&amp;quot;: &amp;quot;purpleLane&amp;quot;,&lt;br /&gt;
			&amp;quot;Color&amp;quot;: [&lt;br /&gt;
				194,&lt;br /&gt;
				65,&lt;br /&gt;
				168&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;MinimapColorOverride&amp;quot;: [&lt;br /&gt;
				194,&lt;br /&gt;
				65,&lt;br /&gt;
				168&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;MinimapZiplineColorOverride&amp;quot;: [&lt;br /&gt;
				194,&lt;br /&gt;
				64,&lt;br /&gt;
				168&lt;br /&gt;
			]&lt;br /&gt;
		}&lt;br /&gt;
	],&lt;br /&gt;
	&amp;quot;MinimapTeamCombineColor&amp;quot;: [&lt;br /&gt;
		83,&lt;br /&gt;
		51,&lt;br /&gt;
		51&lt;br /&gt;
	],&lt;br /&gt;
	&amp;quot;MinimapTeamRebelsColor&amp;quot;: [&lt;br /&gt;
		58,&lt;br /&gt;
		91,&lt;br /&gt;
		66&lt;br /&gt;
	],&lt;br /&gt;
	&amp;quot;NewPlayerMetrics&amp;quot;: [&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;SkillTierName&amp;quot;: &amp;quot;Bronze&amp;quot;,&lt;br /&gt;
			&amp;quot;NetWorth&amp;quot;: 1000,&lt;br /&gt;
			&amp;quot;DamageTaken&amp;quot;: 6600,&lt;br /&gt;
			&amp;quot;BossDamage&amp;quot;: 300,&lt;br /&gt;
			&amp;quot;PlayerDamage&amp;quot;: 900,&lt;br /&gt;
			&amp;quot;LastHits&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;OrbsSecured&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;OrbsDenied&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;AbilitiesUpgraded&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;ModsPurchased&amp;quot;: 1&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;SkillTierName&amp;quot;: &amp;quot;Silver&amp;quot;,&lt;br /&gt;
			&amp;quot;NetWorth&amp;quot;: 1000,&lt;br /&gt;
			&amp;quot;DamageTaken&amp;quot;: 5800,&lt;br /&gt;
			&amp;quot;BossDamage&amp;quot;: 400,&lt;br /&gt;
			&amp;quot;PlayerDamage&amp;quot;: 1400,&lt;br /&gt;
			&amp;quot;LastHits&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;OrbsSecured&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;OrbsDenied&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;AbilitiesUpgraded&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;ModsPurchased&amp;quot;: 1&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;SkillTierName&amp;quot;: &amp;quot;Gold&amp;quot;,&lt;br /&gt;
			&amp;quot;NetWorth&amp;quot;: 1000,&lt;br /&gt;
			&amp;quot;DamageTaken&amp;quot;: 5000,&lt;br /&gt;
			&amp;quot;BossDamage&amp;quot;: 600,&lt;br /&gt;
			&amp;quot;PlayerDamage&amp;quot;: 1800,&lt;br /&gt;
			&amp;quot;LastHits&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;OrbsSecured&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;OrbsDenied&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;AbilitiesUpgraded&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;ModsPurchased&amp;quot;: 1&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;SkillTierName&amp;quot;: &amp;quot;Platinum&amp;quot;,&lt;br /&gt;
			&amp;quot;NetWorth&amp;quot;: 1000,&lt;br /&gt;
			&amp;quot;DamageTaken&amp;quot;: 4600,&lt;br /&gt;
			&amp;quot;BossDamage&amp;quot;: 700,&lt;br /&gt;
			&amp;quot;PlayerDamage&amp;quot;: 2300,&lt;br /&gt;
			&amp;quot;LastHits&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;OrbsSecured&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;OrbsDenied&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;AbilitiesUpgraded&amp;quot;: 1,&lt;br /&gt;
			&amp;quot;ModsPurchased&amp;quot;: 1&lt;br /&gt;
		}&lt;br /&gt;
	],&lt;br /&gt;
	&amp;quot;NoLaneZip&amp;quot;: {&lt;br /&gt;
		&amp;quot;LaneName&amp;quot;: &amp;quot;NoLane&amp;quot;,&lt;br /&gt;
		&amp;quot;CSSClass&amp;quot;: &amp;quot;noLane&amp;quot;,&lt;br /&gt;
		&amp;quot;Color&amp;quot;: [&lt;br /&gt;
			0,&lt;br /&gt;
			0,&lt;br /&gt;
			0&lt;br /&gt;
		]&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;ObjectiveParams&amp;quot;: {&lt;br /&gt;
		&amp;quot;GoldPerOrb&amp;quot;: 40,&lt;br /&gt;
		&amp;quot;Tier1GoldKill&amp;quot;: 175,&lt;br /&gt;
		&amp;quot;Tier1GoldOrbs&amp;quot;: 100,&lt;br /&gt;
		&amp;quot;Tier2GoldKill&amp;quot;: 500,&lt;br /&gt;
		&amp;quot;Tier2GoldOrbs&amp;quot;: 250,&lt;br /&gt;
		&amp;quot;BaseGuardiansGoldKill&amp;quot;: 85,&lt;br /&gt;
		&amp;quot;BaseGuardiansGoldOrbs&amp;quot;: 40,&lt;br /&gt;
		&amp;quot;ShrinesGoldKill&amp;quot;: 0,&lt;br /&gt;
		&amp;quot;ShrinesGoldOrbs&amp;quot;: 0,&lt;br /&gt;
		&amp;quot;PatronPhase1GoldKill&amp;quot;: 0,&lt;br /&gt;
		&amp;quot;PatronPhase1GoldOrbs&amp;quot;: 0&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;RejuvParams&amp;quot;: {&lt;br /&gt;
		&amp;quot;RejuvinatorExpirationWarningTiming&amp;quot;: 30,&lt;br /&gt;
		&amp;quot;RejuvinatorBuffDuration&amp;quot;: 180,&lt;br /&gt;
		&amp;quot;RejuvinatorDropHeight&amp;quot;: 752,&lt;br /&gt;
		&amp;quot;RejuvinatorDropDuration&amp;quot;: 9,&lt;br /&gt;
		&amp;quot;TrooperHealthMult&amp;quot;: [&lt;br /&gt;
			1.5,&lt;br /&gt;
			1.7,&lt;br /&gt;
			1.9&lt;br /&gt;
		],&lt;br /&gt;
		&amp;quot;PlayerRespawnMult&amp;quot;: [&lt;br /&gt;
			0.6,&lt;br /&gt;
			0.5,&lt;br /&gt;
			0.4&lt;br /&gt;
		]&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;ResourceTypes&amp;quot;: {&lt;br /&gt;
		&amp;quot;ResourceType_Rage&amp;quot;: {&lt;br /&gt;
			&amp;quot;HUDSnippetName&amp;quot;: &amp;quot;rage&amp;quot;,&lt;br /&gt;
			&amp;quot;CantCastOutOfResourceToken&amp;quot;: &amp;quot;#CITADEL_ABILITY_INVALID_NOT_RAGE&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;StatTypeImages&amp;quot;: {&lt;br /&gt;
		&amp;quot;BaseHealthRegen&amp;quot;: &amp;quot;file://{images}/upgrades/mods_armor/health_regen.psd&amp;quot;,&lt;br /&gt;
		&amp;quot;BulletArmorDamageReduction&amp;quot;: &amp;quot;file://{images}/upgrades/mods_armor/bullet_armor.psd&amp;quot;,&lt;br /&gt;
		&amp;quot;TechArmorDamageReduction&amp;quot;: &amp;quot;file://{images}/upgrades/mods_armor/tech_armor.psd&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;TargetingSpringStrength&amp;quot;: [&lt;br /&gt;
		0,&lt;br /&gt;
		2,&lt;br /&gt;
		10,&lt;br /&gt;
		30&lt;br /&gt;
	],&lt;br /&gt;
	&amp;quot;TeleporterParams&amp;quot;: {},&lt;br /&gt;
	&amp;quot;UISounds&amp;quot;: {},&lt;br /&gt;
	&amp;quot;generic_data_type&amp;quot;: &amp;quot;CitadelGenericData_t&amp;quot;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:Abilities/utils?diff=25030</id>
		<title>Module:Abilities/utils</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:Abilities/utils?diff=25030"/>
		<updated>2025-04-30T19:09:29Z</updated>

		<summary type="html">&lt;p&gt;Sur: couldnt get working; removed get_value&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local commonutils = require &amp;quot;Module:Utilities&amp;quot;&lt;br /&gt;
local lang = require&amp;quot;Module:Lang&amp;quot;&lt;br /&gt;
local dictionary_module = require(&amp;quot;Module:Dictionary&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local data = mw.loadJsonData(&amp;quot;Data:AbilityCards.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- returns the table of a specific item&#039;&lt;br /&gt;
function p.get_ability_card_data(hero_key, ability_num)&lt;br /&gt;
	if(hero_key == nil) then return nil end&lt;br /&gt;
	return data[hero_key][tonumber(ability_num)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_hero_key(hero_name)&lt;br /&gt;
	for i, hero in pairs(data) do&lt;br /&gt;
		if hero[&amp;quot;Name&amp;quot;] == hero_name then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Add prefix and postfix labels to a value. Eg. &amp;quot;32&amp;quot; -&amp;gt; &amp;quot;32s&amp;quot;&lt;br /&gt;
function p.format_value_with_prepost(key, value, frame, exclude_plus)&lt;br /&gt;
	if (value == nil) then return nil end&lt;br /&gt;
		&lt;br /&gt;
	local prefix = lang.get_string(string.format(&amp;quot;%s_prefix&amp;quot;,key))&lt;br /&gt;
	local postfix = lang.get_string(string.format(&amp;quot;%s_postfix&amp;quot;,key))&lt;br /&gt;
	&lt;br /&gt;
	-- Default pre/post fix to empty string, as they may not exist&lt;br /&gt;
	if (prefix == nil) then prefix = &#039;&#039; end&lt;br /&gt;
	if (postfix == nil) then postfix = &#039;&#039; end&lt;br /&gt;
	&lt;br /&gt;
	-- If string ends with &#039;m&#039;, then set the postfix to &#039;m&#039; and remove it&lt;br /&gt;
	if commonutils.string_endswith(tostring(value), &#039;m&#039;) then&lt;br /&gt;
		value = tonumber(value:sub(1, -2))	&lt;br /&gt;
		postfix = &#039;m&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If string ends with &#039;s&#039;, then set the postfix to &#039;s&#039; and remove it&lt;br /&gt;
	if commonutils.string_endswith(tostring(value), &#039;s&#039;) then&lt;br /&gt;
		value = tonumber(value:sub(1, -2))	&lt;br /&gt;
		postfix = &#039;s&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (prefix == &#039;{s:sign}&#039;) then&lt;br /&gt;
		if value &amp;lt; 0 then &lt;br /&gt;
			prefix = &#039;-&#039;&lt;br /&gt;
		else&lt;br /&gt;
			prefix = &#039;+&#039;&lt;br /&gt;
		end&lt;br /&gt;
	-- if no prefix on positive value, add a &#039;+&#039;&lt;br /&gt;
	else&lt;br /&gt;
		if value &amp;gt; 0 then&lt;br /&gt;
			prefix = &#039;+&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- some use cases don&#039;t require the &#039;+&#039; symbol prefix&lt;br /&gt;
	if exclude_plus == true and prefix == &#039;+&#039; then&lt;br /&gt;
		prefix = &#039;&#039;	&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	value_and_uom = frame:expandTemplate{&lt;br /&gt;
		title = &#039;Template:ValueAndUom&#039;,&lt;br /&gt;
		args = {&lt;br /&gt;
			prefix..value, &lt;br /&gt;
			postfix,&lt;br /&gt;
			uom_style = &#039;font-size: 12px;&#039;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return value_and_uom&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_notes_source_page_name(ability_key) &lt;br /&gt;
	local ability_name_en = data[&amp;quot;Name&amp;quot;]&lt;br /&gt;
	local ability_name_localized = lang.get_string(ability_key)&lt;br /&gt;
	local notes_str_localized = dictionary_module.translate(&#039;Notes&#039;, nil, &#039;&#039;)&lt;br /&gt;
	&lt;br /&gt;
	--Determine notes link&lt;br /&gt;
	local notes_source_page&lt;br /&gt;
	local notes_untranslated_msg = &#039;&#039;&lt;br /&gt;
	-- if either &amp;quot;Notes&amp;quot; string or ability_name is not able to be localized,&lt;br /&gt;
	-- use an english link instead, as transcluded content relies on it&lt;br /&gt;
	if (ability_name_localized == &#039;&#039;) or (notes_str_localized == &#039;&#039;) then&lt;br /&gt;
		notes_source_page = ability_name_en .. &#039;/&#039; .. dictionary_module.translate(&#039;Notes&#039;, &#039;en&#039;, &#039;&#039;)&lt;br /&gt;
		if notes_str_localized==&#039;&#039; then&lt;br /&gt;
			notes_untranslated_msg = &#039;&amp;lt;br&amp;gt;&#039; .. dictionary_module.translate(&#039;NotesNeedsTranslation&#039;) .. &#039; [[Template:Translate]]&#039; .. &amp;quot;&amp;lt;br&amp;gt;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		notes_source_page = ability_name_localized .. &#039;/&#039; .. notes_str_localized&lt;br /&gt;
	end&lt;br /&gt;
	notes_source_page = &amp;quot;User:Sur/&amp;quot; .. notes_source_page --temp&lt;br /&gt;
	&lt;br /&gt;
	return notes_source_page&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:Abilities/utils?diff=25027</id>
		<title>Module:Abilities/utils</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:Abilities/utils?diff=25027"/>
		<updated>2025-04-30T19:02:55Z</updated>

		<summary type="html">&lt;p&gt;Sur: get_value() adjusted to search number keys first as a string key and then as an integer index&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local commonutils = require &amp;quot;Module:Utilities&amp;quot;&lt;br /&gt;
local lang = require&amp;quot;Module:Lang&amp;quot;&lt;br /&gt;
local dictionary_module = require(&amp;quot;Module:Dictionary&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local data = mw.loadJsonData(&amp;quot;Data:AbilityCards.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- returns the table of a specific item&#039;&lt;br /&gt;
function p.get_ability_card_data(hero_key, ability_num)&lt;br /&gt;
	if(hero_key == nil) then return nil end&lt;br /&gt;
	return data[hero_key][tonumber(ability_num)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_hero_key(hero_name)&lt;br /&gt;
	for i, hero in pairs(data) do&lt;br /&gt;
		if hero[&amp;quot;Name&amp;quot;] == hero_name then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Add prefix and postfix labels to a value. Eg. &amp;quot;32&amp;quot; -&amp;gt; &amp;quot;32s&amp;quot;&lt;br /&gt;
function p.format_value_with_prepost(key, value, frame, exclude_plus)&lt;br /&gt;
	if (value == nil) then return nil end&lt;br /&gt;
		&lt;br /&gt;
	local prefix = lang.get_string(string.format(&amp;quot;%s_prefix&amp;quot;,key))&lt;br /&gt;
	local postfix = lang.get_string(string.format(&amp;quot;%s_postfix&amp;quot;,key))&lt;br /&gt;
	&lt;br /&gt;
	-- Default pre/post fix to empty string, as they may not exist&lt;br /&gt;
	if (prefix == nil) then prefix = &#039;&#039; end&lt;br /&gt;
	if (postfix == nil) then postfix = &#039;&#039; end&lt;br /&gt;
	&lt;br /&gt;
	-- If string ends with &#039;m&#039;, then set the postfix to &#039;m&#039; and remove it&lt;br /&gt;
	if commonutils.string_endswith(tostring(value), &#039;m&#039;) then&lt;br /&gt;
		value = tonumber(value:sub(1, -2))	&lt;br /&gt;
		postfix = &#039;m&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If string ends with &#039;s&#039;, then set the postfix to &#039;s&#039; and remove it&lt;br /&gt;
	if commonutils.string_endswith(tostring(value), &#039;s&#039;) then&lt;br /&gt;
		value = tonumber(value:sub(1, -2))	&lt;br /&gt;
		postfix = &#039;s&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (prefix == &#039;{s:sign}&#039;) then&lt;br /&gt;
		if value &amp;lt; 0 then &lt;br /&gt;
			prefix = &#039;-&#039;&lt;br /&gt;
		else&lt;br /&gt;
			prefix = &#039;+&#039;&lt;br /&gt;
		end&lt;br /&gt;
	-- if no prefix on positive value, add a &#039;+&#039;&lt;br /&gt;
	else&lt;br /&gt;
		if value &amp;gt; 0 then&lt;br /&gt;
			prefix = &#039;+&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- some use cases don&#039;t require the &#039;+&#039; symbol prefix&lt;br /&gt;
	if exclude_plus == true and prefix == &#039;+&#039; then&lt;br /&gt;
		prefix = &#039;&#039;	&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	value_and_uom = frame:expandTemplate{&lt;br /&gt;
		title = &#039;Template:ValueAndUom&#039;,&lt;br /&gt;
		args = {&lt;br /&gt;
			prefix..value, &lt;br /&gt;
			postfix,&lt;br /&gt;
			uom_style = &#039;font-size: 12px;&#039;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return value_and_uom&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_notes_source_page_name(ability_key) &lt;br /&gt;
	local ability_name_en = data[&amp;quot;Name&amp;quot;]&lt;br /&gt;
	local ability_name_localized = lang.get_string(ability_key)&lt;br /&gt;
	local notes_str_localized = dictionary_module.translate(&#039;Notes&#039;, nil, &#039;&#039;)&lt;br /&gt;
	&lt;br /&gt;
	--Determine notes link&lt;br /&gt;
	local notes_source_page&lt;br /&gt;
	local notes_untranslated_msg = &#039;&#039;&lt;br /&gt;
	-- if either &amp;quot;Notes&amp;quot; string or ability_name is not able to be localized,&lt;br /&gt;
	-- use an english link instead, as transcluded content relies on it&lt;br /&gt;
	if (ability_name_localized == &#039;&#039;) or (notes_str_localized == &#039;&#039;) then&lt;br /&gt;
		notes_source_page = ability_name_en .. &#039;/&#039; .. dictionary_module.translate(&#039;Notes&#039;, &#039;en&#039;, &#039;&#039;)&lt;br /&gt;
		if notes_str_localized==&#039;&#039; then&lt;br /&gt;
			notes_untranslated_msg = &#039;&amp;lt;br&amp;gt;&#039; .. dictionary_module.translate(&#039;NotesNeedsTranslation&#039;) .. &#039; [[Template:Translate]]&#039; .. &amp;quot;&amp;lt;br&amp;gt;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		notes_source_page = ability_name_localized .. &#039;/&#039; .. notes_str_localized&lt;br /&gt;
	end&lt;br /&gt;
	notes_source_page = &amp;quot;User:Sur/&amp;quot; .. notes_source_page --temp&lt;br /&gt;
	&lt;br /&gt;
	return notes_source_page&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Generic function to traverse the table&lt;br /&gt;
-- A parameter can be passed that is numerical, like 2; and the function will&lt;br /&gt;
-- first try to access the key &amp;quot;2&amp;quot;, otherwise it will look for the value at index=2 (3rd value)&lt;br /&gt;
function p.get_value(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local value = item_data&lt;br /&gt;
&lt;br /&gt;
	for i = 1, #args do&lt;br /&gt;
		local key = args[i]&lt;br /&gt;
&lt;br /&gt;
		-- First try string key&lt;br /&gt;
		if type(value) == &amp;quot;table&amp;quot; and value[key] ~= nil then&lt;br /&gt;
			value = value[key]&lt;br /&gt;
&lt;br /&gt;
		-- Then try numeric key if string didn&#039;t work&lt;br /&gt;
		elseif type(value) == &amp;quot;table&amp;quot; then&lt;br /&gt;
			local num_key = tonumber(key)&lt;br /&gt;
			if num_key and value[num_key] ~= nil then&lt;br /&gt;
				value = value[num_key]&lt;br /&gt;
			else&lt;br /&gt;
				return &amp;quot;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			return &amp;quot;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Return final value, convert to string if not nil&lt;br /&gt;
	if value == nil then&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		return tostring(value)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:Abilities/utils?diff=25025</id>
		<title>Module:Abilities/utils</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:Abilities/utils?diff=25025"/>
		<updated>2025-04-30T18:57:06Z</updated>

		<summary type="html">&lt;p&gt;Sur: testing a generic table accessor function&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local commonutils = require &amp;quot;Module:Utilities&amp;quot;&lt;br /&gt;
local lang = require&amp;quot;Module:Lang&amp;quot;&lt;br /&gt;
local dictionary_module = require(&amp;quot;Module:Dictionary&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local data = mw.loadJsonData(&amp;quot;Data:AbilityCards.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- returns the table of a specific item&#039;&lt;br /&gt;
function p.get_ability_card_data(hero_key, ability_num)&lt;br /&gt;
	if(hero_key == nil) then return nil end&lt;br /&gt;
	return data[hero_key][tonumber(ability_num)]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_hero_key(hero_name)&lt;br /&gt;
	for i, hero in pairs(data) do&lt;br /&gt;
		if hero[&amp;quot;Name&amp;quot;] == hero_name then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Add prefix and postfix labels to a value. Eg. &amp;quot;32&amp;quot; -&amp;gt; &amp;quot;32s&amp;quot;&lt;br /&gt;
function p.format_value_with_prepost(key, value, frame, exclude_plus)&lt;br /&gt;
	if (value == nil) then return nil end&lt;br /&gt;
		&lt;br /&gt;
	local prefix = lang.get_string(string.format(&amp;quot;%s_prefix&amp;quot;,key))&lt;br /&gt;
	local postfix = lang.get_string(string.format(&amp;quot;%s_postfix&amp;quot;,key))&lt;br /&gt;
	&lt;br /&gt;
	-- Default pre/post fix to empty string, as they may not exist&lt;br /&gt;
	if (prefix == nil) then prefix = &#039;&#039; end&lt;br /&gt;
	if (postfix == nil) then postfix = &#039;&#039; end&lt;br /&gt;
	&lt;br /&gt;
	-- If string ends with &#039;m&#039;, then set the postfix to &#039;m&#039; and remove it&lt;br /&gt;
	if commonutils.string_endswith(tostring(value), &#039;m&#039;) then&lt;br /&gt;
		value = tonumber(value:sub(1, -2))	&lt;br /&gt;
		postfix = &#039;m&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If string ends with &#039;s&#039;, then set the postfix to &#039;s&#039; and remove it&lt;br /&gt;
	if commonutils.string_endswith(tostring(value), &#039;s&#039;) then&lt;br /&gt;
		value = tonumber(value:sub(1, -2))	&lt;br /&gt;
		postfix = &#039;s&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (prefix == &#039;{s:sign}&#039;) then&lt;br /&gt;
		if value &amp;lt; 0 then &lt;br /&gt;
			prefix = &#039;-&#039;&lt;br /&gt;
		else&lt;br /&gt;
			prefix = &#039;+&#039;&lt;br /&gt;
		end&lt;br /&gt;
	-- if no prefix on positive value, add a &#039;+&#039;&lt;br /&gt;
	else&lt;br /&gt;
		if value &amp;gt; 0 then&lt;br /&gt;
			prefix = &#039;+&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- some use cases don&#039;t require the &#039;+&#039; symbol prefix&lt;br /&gt;
	if exclude_plus == true and prefix == &#039;+&#039; then&lt;br /&gt;
		prefix = &#039;&#039;	&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	value_and_uom = frame:expandTemplate{&lt;br /&gt;
		title = &#039;Template:ValueAndUom&#039;,&lt;br /&gt;
		args = {&lt;br /&gt;
			prefix..value, &lt;br /&gt;
			postfix,&lt;br /&gt;
			uom_style = &#039;font-size: 12px;&#039;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return value_and_uom&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_notes_source_page_name(ability_key) &lt;br /&gt;
	local ability_name_en = data[&amp;quot;Name&amp;quot;]&lt;br /&gt;
	local ability_name_localized = lang.get_string(ability_key)&lt;br /&gt;
	local notes_str_localized = dictionary_module.translate(&#039;Notes&#039;, nil, &#039;&#039;)&lt;br /&gt;
	&lt;br /&gt;
	--Determine notes link&lt;br /&gt;
	local notes_source_page&lt;br /&gt;
	local notes_untranslated_msg = &#039;&#039;&lt;br /&gt;
	-- if either &amp;quot;Notes&amp;quot; string or ability_name is not able to be localized,&lt;br /&gt;
	-- use an english link instead, as transcluded content relies on it&lt;br /&gt;
	if (ability_name_localized == &#039;&#039;) or (notes_str_localized == &#039;&#039;) then&lt;br /&gt;
		notes_source_page = ability_name_en .. &#039;/&#039; .. dictionary_module.translate(&#039;Notes&#039;, &#039;en&#039;, &#039;&#039;)&lt;br /&gt;
		if notes_str_localized==&#039;&#039; then&lt;br /&gt;
			notes_untranslated_msg = &#039;&amp;lt;br&amp;gt;&#039; .. dictionary_module.translate(&#039;NotesNeedsTranslation&#039;) .. &#039; [[Template:Translate]]&#039; .. &amp;quot;&amp;lt;br&amp;gt;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		notes_source_page = ability_name_localized .. &#039;/&#039; .. notes_str_localized&lt;br /&gt;
	end&lt;br /&gt;
	notes_source_page = &amp;quot;User:Sur/&amp;quot; .. notes_source_page --temp&lt;br /&gt;
	&lt;br /&gt;
	return notes_source_page&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Generic function to traverse the table&lt;br /&gt;
function p.get_value(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local value = data&lt;br /&gt;
&lt;br /&gt;
	for i = 1, #args do&lt;br /&gt;
		local key = args[i]&lt;br /&gt;
		-- Try converting numeric keys&lt;br /&gt;
		local num_key = tonumber(key)&lt;br /&gt;
		if num_key and value[num_key] ~= nil then&lt;br /&gt;
			key = num_key&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if type(value) == &amp;quot;table&amp;quot; then&lt;br /&gt;
			value = value[key]&lt;br /&gt;
		else&lt;br /&gt;
			return &amp;quot;Error: Attempted to index non-table at key &#039;&amp;quot; .. tostring(key) .. &amp;quot;&#039;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if value == nil then&lt;br /&gt;
			return &amp;quot;Error: Invalid key path at &#039;&amp;quot; .. tostring(key) .. &amp;quot;&#039;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:Utilities/doc?diff=23865</id>
		<title>Module:Utilities/doc</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:Utilities/doc?diff=23865"/>
		<updated>2025-04-04T17:01:06Z</updated>

		<summary type="html">&lt;p&gt;Sur: remove_trailing_colon example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Overview==&lt;br /&gt;
Utility functions that serve any miscellaneous purpose&lt;br /&gt;
&lt;br /&gt;
==Functions==&lt;br /&gt;
&lt;br /&gt;
==get_slot_color==&lt;br /&gt;
Retrieve&#039;s the color of a certain slot/category in any color format (default hex), formerly known in english as Weapon, Vitality, and Spirit, though their unlocalized names are Weapon, Armor, and Tech. Utilized by [[Template:Color]]&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
* &#039;&#039;&#039;slot&#039;&#039;&#039; - slot key, options are Weapon, Armor, and Tech&lt;br /&gt;
* &#039;&#039;&#039;color_format&#039;&#039;&#039; - color format - Defaults to hex. Valid options are hex, rgb, hsl, cmyk&lt;br /&gt;
* &#039;&#039;&#039;no_wrap&#039;&#039;&#039; - (OPTIONAL) - Defaults to false. Set to true to remove prefixes and postfixes of &#039;#&#039; from hex, or &#039;rgb()&#039;, &#039;hsl()&#039;, and &#039;cmyk()&#039; from the other formats. May be useful for altering the values dynamically&lt;br /&gt;
* &#039;&#039;&#039;debug_mode&#039;&#039;&#039; - (OPTIONAL) - Defaults to false. Used mostly for documentation purposes&lt;br /&gt;
&lt;br /&gt;
===Examples===&lt;br /&gt;
See examples at [[Template:Color]]&lt;br /&gt;
&lt;br /&gt;
==remove_trailing_colon==&lt;br /&gt;
Remove&#039;s the &amp;quot;:&amp;quot; character from the end of a string&lt;br /&gt;
&lt;br /&gt;
===Examples===&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:Utilities|remove_trailing_colon|A Fate&#039;s Tale:}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{#invoke:Utilities|remove_trailing_colon|A Fate&#039;s Tale:}}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:Utilities?diff=23864</id>
		<title>Module:Utilities</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:Utilities?diff=23864"/>
		<updated>2025-04-04T16:59:20Z</updated>

		<summary type="html">&lt;p&gt;Sur: remove_trailing_colon() initial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {};&lt;br /&gt;
	&lt;br /&gt;
	-- &amp;quot;Default %hero_name% Build&amp;quot; --&amp;gt; &amp;quot;Default  Build&amp;quot;, or &amp;quot;Default Build&amp;quot; with -1 or +1 for spaces&lt;br /&gt;
	function p.remove_var(input, spaces)&lt;br /&gt;
		-- spaces = &lt;br /&gt;
		-- -1: also remove prefixed character&lt;br /&gt;
		-- 0 or nil: no character&lt;br /&gt;
		-- 1: postfixed character&lt;br /&gt;
		-- Remove text between % and % including the %&lt;br /&gt;
	    local result = input:gsub(&amp;quot;%%.-%%&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
	    &lt;br /&gt;
	    -- If spaces == -1, remove the character before the removed section&lt;br /&gt;
	    if spaces ~= nil and spaces == -1 then&lt;br /&gt;
	        result = result:gsub(&amp;quot;%s+%s*&amp;quot;, &amp;quot;&amp;quot;, 1) -- Removes the preceding space or character&lt;br /&gt;
	    -- If spaces == 1, remove the character after the removed section&lt;br /&gt;
	    elseif spaces ~= nil and spaces == 1 then&lt;br /&gt;
	        result = result:gsub(&amp;quot;%s+&amp;quot;, &amp;quot;&amp;quot;, 1) -- Removes the postfixed space&lt;br /&gt;
	    end&lt;br /&gt;
	    &lt;br /&gt;
	    -- Trim any extra whitespace&lt;br /&gt;
	    result = result:gsub(&amp;quot;^%s*(.-)%s*$&amp;quot;, &amp;quot;%1&amp;quot;)&lt;br /&gt;
	    &lt;br /&gt;
	    return result&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--round_to_significant_figures(12345.6789, 3)  -- Output: 12300&lt;br /&gt;
	--round_to_significant_figures(0.0012345, 2)   -- Output: 0.0012&lt;br /&gt;
	--round_to_significant_figures(-98765, 4)      -- Output: -98760&lt;br /&gt;
	function p.round_to_sig_fig(num, n)&lt;br /&gt;
	    if num == 0 then&lt;br /&gt;
	        return 0&lt;br /&gt;
	    end&lt;br /&gt;
	&lt;br /&gt;
	    -- Calculate the order of magnitude (log10 returns the logarithm base 10)&lt;br /&gt;
	    local order_of_magnitude = math.floor(math.log10(math.abs(num)))&lt;br /&gt;
	    &lt;br /&gt;
	    -- Scale the number to move the significant digits into the integer part&lt;br /&gt;
	    local scale = math.pow(10, n - 1 - order_of_magnitude)&lt;br /&gt;
	    &lt;br /&gt;
	    -- Round the scaled number and then scale it back&lt;br /&gt;
	    local rounded_num = math.floor(num * scale + 0.5) / scale&lt;br /&gt;
	    &lt;br /&gt;
	    return rounded_num&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- If the image exists exists, return it back enclosed in brackets, else return a blank string&lt;br /&gt;
	function p.get_image_file(image_file_name, px, link)&lt;br /&gt;
		if (px == nil) then px = 15 end --default&lt;br /&gt;
		if (link == nil) then link = &amp;quot;&amp;quot; end --default&lt;br /&gt;
		&lt;br /&gt;
		image_file = mw.title.new(image_file_name)&lt;br /&gt;
		if image_file and image_file.exists then&lt;br /&gt;
		    image_file_name = &amp;quot;[[&amp;quot; .. image_file_name .. &amp;quot;|&amp;quot; .. px .. &amp;quot;px|link=&amp;quot; .. link .. &amp;quot;]]&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
		    image_file_name = &#039;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		return image_file_name&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	function p.string_endswith(str, ending)&lt;br /&gt;
	    return ending == &amp;quot;&amp;quot; or str:sub(-#ending) == ending&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Add a space before each capital letter that is not the first character&lt;br /&gt;
	-- i.e. BulletVelocity &amp;gt; Bullet Velocity&lt;br /&gt;
	-- when a string doesn&#039;t have localization, it can outputted as add_space_before_cap(unlocalized_key)&lt;br /&gt;
	function p.add_space_before_cap(str)&lt;br /&gt;
	    local result = str:gsub(&amp;quot;(%l)(%u)&amp;quot;, &amp;quot;%1 %2&amp;quot;)&lt;br /&gt;
	    return result:gsub(&amp;quot;(%u)(%u%l)&amp;quot;, &amp;quot; %1%2&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--Much room for expansion here, currently just replaces spaces with underscores essentially&lt;br /&gt;
	--so that it can be used in a url directly&lt;br /&gt;
	p.url_encode = function(str)&lt;br /&gt;
		if type(str) == &#039;table&#039; and str.args then&lt;br /&gt;
			frame = str&lt;br /&gt;
			str = frame.args[1]&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if (str == nil) then return &amp;quot;First parameter must be a string&amp;quot; end&lt;br /&gt;
		if (str == &#039;&#039;) then return &#039;&#039; end&lt;br /&gt;
		-- Just replaces spaces with %20&lt;br /&gt;
		local result = string.gsub(str, &amp;quot; &amp;quot;, &amp;quot;%%20&amp;quot;)&lt;br /&gt;
		return result --must assign as local result first to grab just first returned result&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--Creates a deepCopy of a table&lt;br /&gt;
	function p.deep_copy(orig)&lt;br /&gt;
    local orig_type = type(orig)&lt;br /&gt;
    local copy&lt;br /&gt;
    if orig_type == &amp;quot;table&amp;quot; then&lt;br /&gt;
        copy = {}&lt;br /&gt;
        for key, value in pairs(orig) do&lt;br /&gt;
            copy[p.deep_copy(key)] = p.deep_copy(value)&lt;br /&gt;
        end&lt;br /&gt;
        setmetatable(copy, p.deep_copy(getmetatable(orig)))&lt;br /&gt;
    else  -- For non-table types, simply return the original value&lt;br /&gt;
        copy = orig&lt;br /&gt;
    end&lt;br /&gt;
    return copy&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Hash for color values&lt;br /&gt;
local slot_colors = {&lt;br /&gt;
	[&amp;quot;Weapon&amp;quot;] = {&lt;br /&gt;
		hex = &amp;quot;c97a03&amp;quot;,&lt;br /&gt;
		rgb = &amp;quot;201,122,3&amp;quot;,&lt;br /&gt;
		hsl = &amp;quot;35,97%,40%&amp;quot;,&lt;br /&gt;
		cmyk = &amp;quot;0%,39%,98%,21%&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;Armor&amp;quot;] = {&lt;br /&gt;
		hex = &amp;quot;659818&amp;quot;,&lt;br /&gt;
		rgb = &amp;quot;101,152,24&amp;quot;,&lt;br /&gt;
		hsl = &amp;quot;82,73%,34%&amp;quot;,&lt;br /&gt;
		cmyk = &amp;quot;34%,0%,84%,40%&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;Tech&amp;quot;] = {&lt;br /&gt;
		hex = &amp;quot;c288f0&amp;quot;, -- purple&lt;br /&gt;
		rgb = &amp;quot;194,136,240&amp;quot;,&lt;br /&gt;
		hsl = &amp;quot;276,79%,74%&amp;quot;,&lt;br /&gt;
		cmyk = &amp;quot;19%,43%,0%,6%&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Hash for format configuration&lt;br /&gt;
local color_formats = {&lt;br /&gt;
	hex = {&lt;br /&gt;
		prefix = &amp;quot;#&amp;quot;,&lt;br /&gt;
		postfix = &amp;quot;&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	rgb = {&lt;br /&gt;
		prefix = &amp;quot;rgb(&amp;quot;,&lt;br /&gt;
		postfix = &amp;quot;)&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	hsl = {&lt;br /&gt;
		prefix = &amp;quot;hsl(&amp;quot;,&lt;br /&gt;
		postfix = &amp;quot;)&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
	cmyk = {&lt;br /&gt;
		prefix = &amp;quot;cmyk(&amp;quot;,&lt;br /&gt;
		postfix = &amp;quot;)&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
function p.get_slot_color(slot, color_format, no_wrap, debug_mode)&lt;br /&gt;
	if type(slot) == &#039;table&#039; and slot.args then&lt;br /&gt;
		frame = slot&lt;br /&gt;
		slot = frame.args[1]&lt;br /&gt;
		color_format = frame.args[2]&lt;br /&gt;
		no_wrap = frame.args[&amp;quot;no_wrap&amp;quot;]&lt;br /&gt;
		debug_mode = frame.args[&amp;quot;debug_mode&amp;quot;]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Validate arguments&lt;br /&gt;
	if slot == nil or slot == &amp;quot;&amp;quot; then return &amp;quot;&#039;slot&#039; parameter must be provided&amp;quot; end&lt;br /&gt;
	if color_format == nil or color_format == &amp;quot;&amp;quot; then color_format = &amp;quot;hex&amp;quot; end&lt;br /&gt;
	if no_wrap == nil or no_wrap == &#039;false&#039; or no_wrap == &amp;quot;&amp;quot; then no_wrap = false else no_wrap = true end&lt;br /&gt;
	if debug_mode == nil or debug_mode == &#039;false&#039; or debug_mode == &amp;quot;&amp;quot; then debug_mode = false end&lt;br /&gt;
	&lt;br /&gt;
	local slot_data = slot_colors[slot]&lt;br /&gt;
	if slot_data == nil then return &amp;quot;slot &#039;&amp;quot; .. slot .. &amp;quot;&#039; was not in slots_data map&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	--Retrieve the color&lt;br /&gt;
	local color = slot_data[color_format]&lt;br /&gt;
	if color == nil then&lt;br /&gt;
		return &amp;quot;color_format &#039;&amp;quot; .. color_format .. &amp;quot;&#039; is not in slots_data map&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Add prefix and postfix wrapping&lt;br /&gt;
	if not no_wrap then&lt;br /&gt;
		-- Retrieve prefix and postfix&lt;br /&gt;
		prefix = color_formats[color_format][&#039;prefix&#039;]&lt;br /&gt;
		postfix = color_formats[color_format][&#039;postfix&#039;]&lt;br /&gt;
		-- Add to color&lt;br /&gt;
		color = prefix .. color .. postfix&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Return result&lt;br /&gt;
	if debug_mode then&lt;br /&gt;
		return &amp;quot; &amp;quot; .. color&lt;br /&gt;
	end&lt;br /&gt;
	return color&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.remove_trailing_colon(frame)&lt;br /&gt;
    local str = frame.args[1] or &amp;quot;&amp;quot;&lt;br /&gt;
    -- Remove trailing colon&lt;br /&gt;
    return (str:gsub(&amp;quot;:$&amp;quot;, &amp;quot;&amp;quot;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Fates_Tale?diff=23764</id>
		<title>Template:Fates Tale</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Fates_Tale?diff=23764"/>
		<updated>2025-04-02T04:26:49Z</updated>

		<summary type="html">&lt;p&gt;Sur: comment out newline between code and documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;lt;div style=margin-top:10px;&amp;gt;{{Quotation|&#039;&#039;&#039;A FATE&#039;S TALE&#039;&#039;&#039;|{{#invoke:Lang|get_string|hero_{{{1}}}_lore}}}}&amp;lt;/div&amp;gt;&amp;lt;/includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
--&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:ItemType?diff=22447</id>
		<title>Template:ItemType</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:ItemType?diff=22447"/>
		<updated>2025-02-28T00:36:10Z</updated>

		<summary type="html">&lt;p&gt;Sur: span fixed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{#switch: {{{1}}}&lt;br /&gt;
|Weapon = &amp;lt;span style=&amp;quot;position:relative; bottom:2px; white-space:nowrap;&amp;quot;&amp;gt;[[File:Weapon Icon.png|{{{size|25px}}}|link={{#invoke:Dictionary|translate|Weapon Item|lang_code_override=en}}]]&amp;lt;/span&amp;gt; [[Weapon Item|{{#invoke:Dictionary|translate|Weapon Item}}]]{{{2|}}}&lt;br /&gt;
|Armor = &amp;lt;span style=&amp;quot;position:relative; bottom:2px; white-space:nowrap;&amp;quot;&amp;gt;[[File:Vitality Icon.png|{{{size|25px}}}|link={{#invoke:Dictionary|translate|Armor Item|lang_code_override=en}}]]&amp;lt;/span&amp;gt; [[Vitality Item|{{#invoke:Dictionary|translate|Armor Item}}]]{{{2|}}}&lt;br /&gt;
|Tech = &amp;lt;span style=&amp;quot;position:relative; bottom:2px; white-space:nowrap;&amp;quot;&amp;gt;[[File:Spirit icon.png|{{{size|25px}}}|link={{#invoke:Dictionary|translate|Tech Item|lang_code_override=en}}]]&amp;lt;/span&amp;gt; [[Spirit Item|{{#invoke:Dictionary|translate|Tech Item}}]]{{{2|}}}&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
[[Category:Icon templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:HeroData?diff=22138</id>
		<title>Module:HeroData</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:HeroData?diff=22138"/>
		<updated>2025-02-22T04:03:01Z</updated>

		<summary type="html">&lt;p&gt;Sur: use {{PI}} instead of {{Ls}} for level scaling&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {};&lt;br /&gt;
local heroes_data = mw.loadJsonData(&amp;quot;Data:HeroData.json&amp;quot;)&lt;br /&gt;
local attributes_data = mw.loadJsonData(&amp;quot;Data:AttributeData.json&amp;quot;)&lt;br /&gt;
local attribute_orders = mw.loadJsonData(&amp;quot;Data:StatInfoboxOrder.json&amp;quot;)&lt;br /&gt;
local util_module = require(&#039;Module:Utilities&#039;)&lt;br /&gt;
local lang_module = require(&#039;Module:Lang&#039;)&lt;br /&gt;
local dictionary_module = require(&#039;Module:Dictionary&#039;)&lt;br /&gt;
local attribute_module = require(&#039;Module:AttributeData&#039;)&lt;br /&gt;
&lt;br /&gt;
-- returns the table of a specific item, used by external modules&lt;br /&gt;
function p.get_json_item(name)&lt;br /&gt;
	for i,v in pairs(heroes_data) do&lt;br /&gt;
		if (v[&amp;quot;Name&amp;quot;] == name) then&lt;br /&gt;
			return v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns an array of item tables that have the same properties&lt;br /&gt;
-- @function   get_similar_items&lt;br /&gt;
-- @param      {string}&lt;br /&gt;
-- @return     {array of tables}&lt;br /&gt;
local function get_similar_items(property)&lt;br /&gt;
	local similarItems = {}&lt;br /&gt;
	for _, v in pairs(heroes_data) do&lt;br /&gt;
		if (v[property] ~= nil) then&lt;br /&gt;
			table.insert(similarItems, v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return similarItems&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- returns the key of the specified hero&#039;s english name&lt;br /&gt;
function p.get_hero_key(name)&lt;br /&gt;
	for i,v in pairs(heroes_data) do&lt;br /&gt;
		if (v[&amp;quot;Name&amp;quot;] == name) then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|get_hero_var|HERO_NAME|STAT_NAME|sig_figs_or_localize}}--&lt;br /&gt;
--sig_figs optional for rounding floats&lt;br /&gt;
p.get_hero_var = function(frame)&lt;br /&gt;
	local hero_name = frame.args[1]&lt;br /&gt;
	local hero_stat_key = frame.args[2]&lt;br /&gt;
	local sig_figs_or_localize = frame.args[3]&lt;br /&gt;
	&lt;br /&gt;
	local hero = heroes_data[hero_name] --check if hero key is passed instead&lt;br /&gt;
	if(hero == nil) then hero = p.get_json_item(hero_name) end --check if hero name is passed&lt;br /&gt;
	if(hero == nil) then return &amp;quot;Hero Not Found&amp;quot; end --both invalid, error&lt;br /&gt;
	&lt;br /&gt;
	local var_value = hero[hero_stat_key]&lt;br /&gt;
	if(var_value == nil) then return 0 end&lt;br /&gt;
	&lt;br /&gt;
	--round&lt;br /&gt;
	if (sig_figs_or_localize ~= nil and tonumber(sig_figs_or_localize) ~= nil) then&lt;br /&gt;
		var_value = util_module.round_to_sig_fig(var_value, sig_figs_or_localize)&lt;br /&gt;
		if (var_value == nil) then return &amp;quot;get_hero_var() error with rounding&amp;quot; end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--localize&lt;br /&gt;
	if (sig_figs_or_localize == &amp;quot;true&amp;quot;) then&lt;br /&gt;
		return lang_module.get_string(var_value)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return var_value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|get_list_elem|HERO_NAME|VAR|NUMBER|LOCALIZE}}&lt;br /&gt;
p.get_list_elem = function(frame)&lt;br /&gt;
	local hero_name = frame.args[1]&lt;br /&gt;
	local var = frame.args[2]&lt;br /&gt;
	local number_str = frame.args[3]&lt;br /&gt;
	local number_int = tonumber(number_str)&lt;br /&gt;
	local localize = frame.args[4]&lt;br /&gt;
	local hero = heroes_data[hero_name] --check if hero key is passed instead&lt;br /&gt;
	if(hero == nil) then hero = p.get_json_item(hero_name) end --check if hero name is passed&lt;br /&gt;
	if(hero == nil) then return &amp;quot;Hero Not Found&amp;quot; end --both invalid, error&lt;br /&gt;
	if (hero == nil) then return &amp;quot;Hero &amp;quot; .. hero_name .. &amp;quot; not found&amp;quot; end&lt;br /&gt;
	local list = hero[var]&lt;br /&gt;
	if (list == nil) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	local element = list[number_int]&lt;br /&gt;
	if (element == nil) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	if localize==&amp;quot;true&amp;quot; then &lt;br /&gt;
		element = lang_module.get_string(element)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return element&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.get_ability_key = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	local bound_slot_number = frame.args[2]&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	if (hero_data == nil) then return &amp;quot;Hero key &amp;quot;..hero_key.. &amp;quot; not found&amp;quot; end&lt;br /&gt;
	local bound_abilities_data = hero_data[&amp;quot;BoundAbilities&amp;quot;]&lt;br /&gt;
	if (bound_abilities_data == nil) then return &amp;quot;Hero key &amp;quot; .. hero_key.. &amp;quot; has no BoundAbilities&amp;quot; end&lt;br /&gt;
	return bound_abilities_data[tonumber(bound_slot_number)][&amp;quot;Key&amp;quot;]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.write_role_playstyle_quote = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	if (hero_data == nil) then return hero_key..&amp;quot; not found&amp;quot; end&lt;br /&gt;
	local role_key = hero_data[&amp;quot;Role&amp;quot;]&lt;br /&gt;
	local role_localized = lang_module.get_string(role_key, nil, &#039;en&#039;)&lt;br /&gt;
	local playstyle_key = hero_data[&amp;quot;Playstyle&amp;quot;]&lt;br /&gt;
	local playstyle_localized = lang_module.get_string(playstyle_key, nil, &#039;en&#039;)&lt;br /&gt;
	&lt;br /&gt;
	local str = &amp;quot;&amp;lt;b&amp;gt;&amp;quot; .. role_localized .. &#039;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; .. playstyle_localized&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	template_args[1] = &amp;quot;&amp;quot;&lt;br /&gt;
	template_args[2] = str&lt;br /&gt;
	return frame:expandTemplate{title = &#039;Quotation&#039;, args = template_args}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.write_default_items = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1] --unlocalized&lt;br /&gt;
	if (hero_key == nil) then return &amp;quot;No hero key provided&amp;quot; end&lt;br /&gt;
	local str = &amp;quot;&amp;quot;&lt;br /&gt;
	local hero = heroes_data[hero_key]&lt;br /&gt;
	if (hero == nil) then return &amp;quot;Hero not found, must be unlocalized&amp;quot; end&lt;br /&gt;
	local template_title = &#039;PageRef&#039;&lt;br /&gt;
	for i, item_key in ipairs(hero[&amp;quot;RecommendedItems&amp;quot;]) do&lt;br /&gt;
		template_args = {}&lt;br /&gt;
		template_args[1] = lang_module.get_string(item_key, &#039;en&#039;)&lt;br /&gt;
		template_args[&#039;alt_name&#039;] = localize(item_key, item_key)&lt;br /&gt;
		local expanded_template = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
		str = str .. &amp;quot;* &amp;quot; .. expanded_template .. &amp;quot;\n&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return str&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
--If the hero scales with the stat, it returns {{Ss|value}} or {{Ls|value}}, else blank string&lt;br /&gt;
--{{#invoke:HeroData|get_hero_scalar|HERO_NAME|SCALING_TYPE|STAT_NAME}}--&lt;br /&gt;
p.get_hero_scalar = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	local scaling_type = frame.args[2]&lt;br /&gt;
	local hero_stat_key = frame.args[3]&lt;br /&gt;
	&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	if(hero_data == nil) then return &amp;quot;Hero &amp;quot; .. hero_key .. &amp;quot; not found.&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	local scaling_data = hero_data[scaling_type .. &amp;quot;Scaling&amp;quot;]&lt;br /&gt;
	if scaling_data == nil then return scaling_type .. &amp;quot;Scaling data not found for hero&amp;quot; .. hero_key end&lt;br /&gt;
	&lt;br /&gt;
	local scaling_value = scaling_data[hero_stat_key]&lt;br /&gt;
	if scaling_value == nil then return scaling_type .. &amp;quot;Scaling data does not have key &amp;quot; .. hero_stat_key .. &amp;quot; for hero &amp;quot; .. hero_key end&lt;br /&gt;
	&lt;br /&gt;
	local scaling_str = p.write_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
	if (scaling_str ~= &amp;quot;&amp;quot;) then scaling_str = &amp;quot; &amp;quot; .. scaling_str end&lt;br /&gt;
	return scaling_str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Retrieve scaling string of a hero&#039;s given stat, if it has scaling, else return blank&lt;br /&gt;
-- Scaling string meaning the expanded template {{Ss|scalar}} or {{Ls|scalar}}&lt;br /&gt;
function p.write_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
	local scaling_abbrevs = {Spirit = &amp;quot;Ss&amp;quot;, Level = &amp;quot;PI&amp;quot;}&lt;br /&gt;
	&lt;br /&gt;
	-- Return blank if it doesnt scale&lt;br /&gt;
	if (scaling_value == 0) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	-- Round it&lt;br /&gt;
	scaling_value = util_module.round_to_sig_fig(scaling_value, 3)&lt;br /&gt;
	&lt;br /&gt;
	--The hero has a scaling value with this stat&lt;br /&gt;
	local template_title = &amp;quot;Template:&amp;quot; .. scaling_abbrevs[scaling_type] --scaling type&#039;s abbreviation&lt;br /&gt;
	&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	template_args[&amp;quot;1&amp;quot;] = scaling_value --store in 1st arg for {{{1}}} to grab it from {{SS}} or {{LS}} template&lt;br /&gt;
	&lt;br /&gt;
	local template_call = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
	return template_call&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Retrieve scaling value and type of a hero&#039;s given stat, if it has scaling, else return 0&lt;br /&gt;
function p.get_hero_scaling_data(hero_data, hero_stat_key)&lt;br /&gt;
	local scaling_type_full&lt;br /&gt;
	local scaling_data&lt;br /&gt;
	local scaling_value&lt;br /&gt;
	local scaling_types = {&amp;quot;Spirit&amp;quot;, &amp;quot;Level&amp;quot;}&lt;br /&gt;
	local scaling_data_returned = {}&lt;br /&gt;
	&lt;br /&gt;
	for index, scaling_type in ipairs(scaling_types) do&lt;br /&gt;
		scaling_type_full = scaling_type .. &amp;quot;Scaling&amp;quot;&lt;br /&gt;
		scaling_data = hero_data[scaling_type_full]&lt;br /&gt;
		&lt;br /&gt;
		--If the scaling data exists&lt;br /&gt;
		if (scaling_data ~= nil) then &lt;br /&gt;
			scaling_value = scaling_data[hero_stat_key]&lt;br /&gt;
			&lt;br /&gt;
			--If the stat scales&lt;br /&gt;
			if (scaling_value ~= nil) then&lt;br /&gt;
				scaling_data_returned[scaling_value] = scaling_type&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return scaling_data_returned&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--HERO_NAME in english&lt;br /&gt;
--{{#invoke:HeroData|write_infobox|HERO_NAME}}--&lt;br /&gt;
p.write_infobox = function(frame)&lt;br /&gt;
	-- Get hero data&lt;br /&gt;
    hero_key = frame.args[1]&lt;br /&gt;
    hero_data = heroes_data[hero_key]&lt;br /&gt;
    if(hero_data == nil) then return &amp;quot;Hero &amp;quot; .. hero_key .. &amp;quot; Not Found&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local infobox_attributes = {&lt;br /&gt;
        Weapon = {&#039;DPS&#039;,&#039;ClipSize&#039;,&#039;RoundsPerSecond&#039;,&#039;ReloadTime&#039;},&lt;br /&gt;
        Vitality = {&#039;MaxHealth&#039;,&#039;BulletResist&#039;,&#039;TechResist&#039;,&#039;MaxMoveSpeed&#039;}&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    -- Declarations and initializations&lt;br /&gt;
    local category_data = attribute_module.get_category_data()&lt;br /&gt;
    local stats&lt;br /&gt;
    local stat_data&lt;br /&gt;
    local stat_value&lt;br /&gt;
    local stat_text&lt;br /&gt;
    local label&lt;br /&gt;
    local postfix&lt;br /&gt;
    local should_display&lt;br /&gt;
    local image_file_name&lt;br /&gt;
    local image_file&lt;br /&gt;
    local icon_and_value_str&lt;br /&gt;
    local template_args = {}&lt;br /&gt;
    local stat_values = {Weapon = &amp;quot;&amp;quot;, Vitality = &amp;quot;&amp;quot;}&lt;br /&gt;
    &lt;br /&gt;
    -- Add the main parameters&lt;br /&gt;
    template_args[&amp;quot;name_english&amp;quot;] = lang_module.get_string(hero_key, &#039;en&#039;)&lt;br /&gt;
    template_args[&amp;quot;name_localized&amp;quot;] = localize(hero_key, hero_key)&lt;br /&gt;
    &lt;br /&gt;
    -- Iterate attribute categories&lt;br /&gt;
    for category, stats in pairs(infobox_attributes) do&lt;br /&gt;
		-- Iterate stats&lt;br /&gt;
		for _, stat_name in ipairs(stats) do&lt;br /&gt;
			-- Confirm its in attribute data and retrieve it&lt;br /&gt;
			attribute_data = attributes_data[category]&lt;br /&gt;
			if (attribute_data == nil) then return &amp;quot;Category &amp;quot; .. category .. &amp;quot; in infobox_attributes is not in Data:AttributeData&amp;quot; end&lt;br /&gt;
			stat_data = attribute_data[stat_name]&lt;br /&gt;
			if (stat_data == nil) then return &amp;quot;Attribute &amp;quot; .. stat_name .. &amp;quot; in infobox_attributes is not in Data:AttributeData&amp;quot; end&lt;br /&gt;
			&lt;br /&gt;
			-- gets the stat&#039;s value&lt;br /&gt;
			stat_value = hero_data[stat_name]&lt;br /&gt;
			if (stat_value == nil) then&lt;br /&gt;
				stat_value = 0 --default to 0 if not present&lt;br /&gt;
			end&lt;br /&gt;
				&lt;br /&gt;
			--Round value to 3 significant figures&lt;br /&gt;
			stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
			&lt;br /&gt;
			-- get label and postfix&lt;br /&gt;
			label = localize(stat_data[&amp;quot;label&amp;quot;], stat_name)&lt;br /&gt;
			postfix = stat_data[&amp;quot;postfix&amp;quot;]&lt;br /&gt;
			if (postfix == nil) then &lt;br /&gt;
				postfix = &amp;quot;&amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				-- light grey for postfixes&lt;br /&gt;
				postfix = lang_module.get_string(postfix)&lt;br /&gt;
				if (postfix == nil) then&lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				postfix = &#039;&amp;lt;span style=&amp;quot;color: #666666;&amp;quot;&amp;gt;&#039; .. postfix .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
			-- if a language is missing the postfix, use no postfix&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			-- Check if icon file exists, and if not, don&#039;t use any image&lt;br /&gt;
			image_file_name = &#039;File:AttributeIcon&#039; .. stat_name .. &#039;.png&#039;&lt;br /&gt;
			image_file = util_module.get_image_file(image_file_name, 15, stat_name)&lt;br /&gt;
			&lt;br /&gt;
			-- Create the template&#039;d icon&lt;br /&gt;
			local icon_color = attribute_module.get_attr_icon_color(stat_name)&lt;br /&gt;
			icon_template_title = mw.title.new(&amp;quot;Template:Icon/&amp;quot; .. icon_color)&lt;br /&gt;
			icon_template_args = {}&lt;br /&gt;
			icon_template_args[1] = image_file&lt;br /&gt;
			icon_template_args[2] = stat_value .. postfix&lt;br /&gt;
			icon_and_value_str = mw.getCurrentFrame():expandTemplate{ title = icon_template_title, args = icon_template_args }&lt;br /&gt;
			&lt;br /&gt;
			label =  &#039;,&amp;lt;span style=&amp;quot;color: #999999; background-color: #2F2F2F; display: inline-flex; width: 100%; height: 100%; justify-content: center; align-items: center;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
			&lt;br /&gt;
			-- First add localized stat name for left column&lt;br /&gt;
			stat_values[category] = stat_values[category] .. label&lt;br /&gt;
			&lt;br /&gt;
			-- Then add icon and stat value for right column&lt;br /&gt;
			stat_values[category] = stat_values[category] .. &#039;,&#039; .. icon_and_value_str&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Add the stat values in the category to i.e weapon_values and vitality_values parameters&lt;br /&gt;
		template_args[string.lower(category) .. &amp;quot;_values&amp;quot;] = stat_values[category]&lt;br /&gt;
	end&lt;br /&gt;
    &lt;br /&gt;
    -- Use expandTemplate to evaluate the Infobox_hero template&lt;br /&gt;
    local template_title = mw.title.new(&amp;quot;User:Sur&amp;quot;)&lt;br /&gt;
    local expanded_template = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
    &lt;br /&gt;
    return expanded_template&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|write_stat_infoboxes|HERO_KEY}}&lt;br /&gt;
--Creates {{Infobox_stat}}&#039;s&#039; for the 3 categories Weapon, Vitality, Spirit&lt;br /&gt;
p.write_stat_infoboxes = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	if(hero_key == nil) then return &amp;quot;Hero parameter missing&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	-- Use expandTemplate to evaluate the Infobox_hero template&lt;br /&gt;
    local template_title = mw.title.new(&amp;quot;Template:Infobox_stat&amp;quot;) --name of the template&lt;br /&gt;
    local template_calls = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-direction: column;&amp;quot;&amp;gt;&#039; --all template calls concatenated&lt;br /&gt;
    local template_call --current template call&lt;br /&gt;
	local template_args = {} --current template arguments&lt;br /&gt;
	local cell_values --current cell values&lt;br /&gt;
	local cell_value --current cell value&lt;br /&gt;
	local label --current stat&#039;s label&lt;br /&gt;
	local postfix --current stat&#039;s postfix&lt;br /&gt;
	local stat_value --current stat&#039;s numerical value in the hero data&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	local stats --stats of the current category&lt;br /&gt;
	local image_file_name --name of the image_file to check&lt;br /&gt;
	local image_file --mw returned image file&lt;br /&gt;
	local extra_blank_cell --add a blank cell after certain stats&lt;br /&gt;
	local stats_to_add_blank_after = {CritDamageReceivedScale = true}&lt;br /&gt;
	if (hero_data == nil) then return &amp;quot;Hero Not Found&amp;quot; end&lt;br /&gt;
	local category_data = attribute_module.get_category_data()&lt;br /&gt;
	local should_display&lt;br /&gt;
	&lt;br /&gt;
	for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
		if (category ~= &amp;quot;Spirit&amp;quot;) then --hide Spirit section for now&lt;br /&gt;
			stats = attributes_data[category]&lt;br /&gt;
			local category_values = category_data[category]&lt;br /&gt;
			template_args[&amp;quot;box_name&amp;quot;] = category_values.unlocalized_name&lt;br /&gt;
			template_args[&amp;quot;box_rgb&amp;quot;] = category_values.rgb&lt;br /&gt;
			template_args[&amp;quot;num_cols&amp;quot;] = 2&lt;br /&gt;
			cell_values = &amp;quot;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Determine cell values&lt;br /&gt;
			for _, stat_name in ipairs(attribute_orders[category][&amp;quot;attribute_order&amp;quot;]) do&lt;br /&gt;
				local stat_data = stats[stat_name]&lt;br /&gt;
				if stat_data == nil then return &amp;quot;Stat &amp;quot; .. stat_name .. &amp;quot; from StatInfoboxOrder has no data in AttributeData&amp;quot; end&lt;br /&gt;
				&lt;br /&gt;
				-- gets the stat&#039;s value if it has that stat, default to 0 if not&lt;br /&gt;
				stat_value = hero_data[stat_name]&lt;br /&gt;
				if (stat_value == nil) then&lt;br /&gt;
					stat_value = 0 --default to 0 if not present&lt;br /&gt;
				end&lt;br /&gt;
					&lt;br /&gt;
				--Round value to 3 significant figures&lt;br /&gt;
				stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
				&lt;br /&gt;
				-- get label and postfix&lt;br /&gt;
				label = localize(stat_data[&amp;quot;label&amp;quot;], stat_name)&lt;br /&gt;
				postfix = stat_data[&amp;quot;postfix&amp;quot;]&lt;br /&gt;
				if (postfix == nil) then &lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				else&lt;br /&gt;
					-- light grey for postfixes&lt;br /&gt;
					postfix = &#039;&amp;lt;span style=&amp;quot;color: #666666;&amp;quot;&amp;gt;&#039; .. lang_module.get_string(postfix) .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				-- if a language is missing the postfix, use no postfix&lt;br /&gt;
				if (postfix == nil) then&lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- Check if icon file exists, and if not, don&#039;t use any image&lt;br /&gt;
				image_file_name = &#039;File:AttributeIcon&#039; .. stat_name .. &#039;.png&#039;&lt;br /&gt;
				-- 15px and link to stat name (page name might not match perfectly yet)&lt;br /&gt;
				image_file = util_module.get_image_file(image_file_name, 15, stat_name)&lt;br /&gt;
				&lt;br /&gt;
				-- Create the template&#039;d icon&lt;br /&gt;
				local icon_color = attribute_module.get_attr_icon_color(stat_name)&lt;br /&gt;
				if (icon_color == &amp;quot;Brown&amp;quot;) then&lt;br /&gt;
					image_file = &#039;&amp;lt;span style=&amp;quot;position: relative; bottom: 2px; filter: invert(42%) sepia(10%) saturate(2912%) hue-rotate(351deg) brightness(90%) contrast(87%);&amp;quot;&amp;gt;&#039; .. image_file .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				end&lt;br /&gt;
				-- use white instead of grey if grey is returned&lt;br /&gt;
				&lt;br /&gt;
				-- Add an empty cell following some stats to align them correctly as seen in game&lt;br /&gt;
				if (stats_to_add_blank_after[stat_name]) then&lt;br /&gt;
					extra_blank_cell = &amp;quot; ,&amp;quot; --prefixed space is needed&lt;br /&gt;
				else&lt;br /&gt;
					extra_blank_cell = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- slightly lighter color for stat name&lt;br /&gt;
				label = &#039;&amp;lt;span style=&amp;quot;color: #3d3d3d;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				&lt;br /&gt;
				-- Add the scaling str if it scales&lt;br /&gt;
				local scaling_data = p.get_hero_scaling_data(hero_data, stat_name)&lt;br /&gt;
				local scaling_strs = &amp;quot;&amp;quot;&lt;br /&gt;
				if (scaling_data ~= nil) then&lt;br /&gt;
					for scaling_value, scaling_type in pairs(scaling_data) do&lt;br /&gt;
						local scaling_str = p.write_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
						if (scaling_str ~= &amp;quot;&amp;quot;) then scaling_str = &amp;quot; &amp;quot; .. scaling_str end&lt;br /&gt;
						scaling_strs = scaling_strs .. scaling_str&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- Set cell value as &amp;quot;Icon StatvaluePostfix Statname Scaling,&amp;quot;&lt;br /&gt;
				-- If icon file already exists, set it to #REDIRECT to the duplicate file page&lt;br /&gt;
				cell_value = image_file .. &amp;quot; &amp;quot; .. stat_value  .. postfix .. &amp;quot; &amp;quot; .. label  .. scaling_strs .. &amp;quot;,&amp;quot; .. extra_blank_cell&lt;br /&gt;
				&lt;br /&gt;
				cell_values = cell_values .. cell_value --add value to values list&lt;br /&gt;
			end&lt;br /&gt;
			template_args[&amp;quot;cell_values&amp;quot;] = cell_values&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			-- Write current call&lt;br /&gt;
			template_call = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
		&lt;br /&gt;
			-- Add call to the set of calls&lt;br /&gt;
			template_calls = template_calls .. &amp;quot;\n&amp;quot; .. template_call&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return template_calls .. &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--writes the massive hero comparison table for a specific PI and SP&lt;br /&gt;
-- scaling icons are shown only if PI and SP are both 0 or both not provided&lt;br /&gt;
--{{#invoke:HeroData|write_hero_comparison_table|POWER_INCREASES|SPIRIT_POWER}}&lt;br /&gt;
p.write_hero_comparison_table = function(frame)&lt;br /&gt;
	-- process inputs&lt;br /&gt;
	local power_increases = frame.args[1]&lt;br /&gt;
	if (power_increases == nil) then power_increases = 0 end&lt;br /&gt;
	local spirit_power = frame.args[2]&lt;br /&gt;
	if (spirit_power == nil) then spirit_power = 0 end&lt;br /&gt;
	&lt;br /&gt;
	-- Show scaling icons if power/increases/spirit power are 0/not specified&lt;br /&gt;
	local display_scaling_icons = false&lt;br /&gt;
	if (power_increases == 0 and spirit_power == 0) then&lt;br /&gt;
		display_scaling_icons = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Initializations and declarations&lt;br /&gt;
	local row_str = &amp;quot;&amp;quot;&lt;br /&gt;
	local body_str = &amp;quot;&amp;quot;&lt;br /&gt;
	local in_development&lt;br /&gt;
	local is_disabled&lt;br /&gt;
	local template_title = &amp;quot;&amp;quot;&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	local hero_icon&lt;br /&gt;
	local hero_td_style&lt;br /&gt;
	local scalar_str&lt;br /&gt;
	&lt;br /&gt;
	-- Add hero comp stats to &lt;br /&gt;
	local stats_to_include = {&lt;br /&gt;
		Weapon = {&lt;br /&gt;
			&amp;quot;DPS&amp;quot;,&lt;br /&gt;
            &amp;quot;SustainedDPS&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;RoundsPerSecond&amp;quot;,&lt;br /&gt;
            &amp;quot;FireRate&amp;quot;,&lt;br /&gt;
            &amp;quot;ClipSize&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadTime&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadDelay&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletsPerShot&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletsPerBurst&amp;quot;,&lt;br /&gt;
            &amp;quot;BurstInterShotInterval&amp;quot;,&lt;br /&gt;
            &amp;quot;LightMeleeDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;HeavyMeleeDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadSingle&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletGravityScale&amp;quot;,&lt;br /&gt;
            &amp;quot;FalloffStartRange&amp;quot;,&lt;br /&gt;
            &amp;quot;FalloffEndRange&amp;quot;,&lt;br /&gt;
            &amp;quot;BonusAttackRange&amp;quot;,&lt;br /&gt;
            &amp;quot;RoundsPerSecondAtMaxSpin&amp;quot;,&lt;br /&gt;
            &amp;quot;SpinAcceleration&amp;quot;,&lt;br /&gt;
            &amp;quot;SpinDeceleration&amp;quot;&lt;br /&gt;
		},&lt;br /&gt;
		Vitality = {&lt;br /&gt;
			&amp;quot;MaxHealth&amp;quot;,&lt;br /&gt;
            &amp;quot;BaseHealthRegen&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletResist&amp;quot;,&lt;br /&gt;
            &amp;quot;TechResist&amp;quot;,&lt;br /&gt;
            &amp;quot;CritDamageReceivedScale&amp;quot;,&lt;br /&gt;
            &amp;quot;MaxMoveSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;SprintSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;StaminaCooldown&amp;quot;,&lt;br /&gt;
            &amp;quot;Stamina&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	-- Iterate heroes&lt;br /&gt;
	for hero_key, hero_data in pairs(heroes_data) do&lt;br /&gt;
		-- Ensure they are not in development and they are an active hero&lt;br /&gt;
		in_development = hero_data[&amp;quot;InDevelopment&amp;quot;]&lt;br /&gt;
		is_disabled = hero_data[&amp;quot;IsDisabled&amp;quot;]&lt;br /&gt;
		if (not is_disabled) then &lt;br /&gt;
			&lt;br /&gt;
			--Add the row&#039;s stats&lt;br /&gt;
			row_str = &amp;quot;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Retrieve hero&#039;s localized name&lt;br /&gt;
			hero_name = localize(hero_key, hero_key)&lt;br /&gt;
			&lt;br /&gt;
			-- Retrieve hero&#039;s english name, used for hero icon&lt;br /&gt;
			hero_name_en = hero_data[&amp;quot;Name&amp;quot;]&lt;br /&gt;
			&lt;br /&gt;
			-- Expand hero icon&lt;br /&gt;
			template_title = &amp;quot;Template:HeroIcon&amp;quot;&lt;br /&gt;
			template_args[1] = hero_name_en&lt;br /&gt;
			template_args[2] = hero_name&lt;br /&gt;
			hero_icon = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
			&lt;br /&gt;
			-- First column in each row is hero name&lt;br /&gt;
			row_str = row_str .. &amp;quot;&amp;lt;td&amp;gt;&amp;quot; .. hero_icon .. &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Consecutive columns are then stats&lt;br /&gt;
			-- Iterate categories&lt;br /&gt;
			for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
				category_attrs = attributes_data[category]&lt;br /&gt;
				&lt;br /&gt;
				-- Iterate attributes within the category&lt;br /&gt;
				if (stats_to_include[category] ~= nil) then&lt;br /&gt;
					&lt;br /&gt;
					for _, attr_key in ipairs(stats_to_include[category]) do&lt;br /&gt;
						&lt;br /&gt;
						--Retrieve the stats value from hero data&lt;br /&gt;
						stat_value = hero_data[attr_key]&lt;br /&gt;
						if (stat_value == nil) then stat_value = 0 end&lt;br /&gt;
						&lt;br /&gt;
						-- Retrieve scaling val and str if it scales&lt;br /&gt;
						local scaling_data = p.get_hero_scaling_data(hero_data, attr_key)&lt;br /&gt;
						local scaling_strs = &amp;quot;&amp;quot;&lt;br /&gt;
						if (scaling_data ~= nil) then&lt;br /&gt;
							for scaling_value, scaling_type in pairs(scaling_data) do&lt;br /&gt;
								local scaling_str = p.write_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
								if (scaling_str ~= &amp;quot;&amp;quot;) then scaling_str = &amp;quot; &amp;quot; .. scaling_str end&lt;br /&gt;
								if (scaling_str ~= nil) then&lt;br /&gt;
									scaling_strs = scaling_strs .. scaling_str &lt;br /&gt;
								end&lt;br /&gt;
								-- Scale the stat value&lt;br /&gt;
								if (scaling_type == &amp;quot;Spirit&amp;quot;) then&lt;br /&gt;
									stat_value = stat_value + (spirit_power * scaling_value)&lt;br /&gt;
								elseif (scaling_type == &amp;quot;Level&amp;quot;) then&lt;br /&gt;
									if attr_key == &#039;TechResist&#039; or attr_key == &#039;BulletResist&#039; then&lt;br /&gt;
										-- each PI for resists is multiplicative&lt;br /&gt;
										stat_value = (stat_value/100 + 1 - (1-scaling_value/100)^power_increases)*100&lt;br /&gt;
									else&lt;br /&gt;
										stat_value = stat_value + (power_increases * scaling_value)&lt;br /&gt;
									end&lt;br /&gt;
								end&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
						if (not display_scaling_icons) then scaling_strs = &amp;quot;&amp;quot; end&lt;br /&gt;
						&lt;br /&gt;
						&lt;br /&gt;
						&lt;br /&gt;
						-- Convert from boolean to string, or round it&lt;br /&gt;
						if (type(stat_value)) == &#039;boolean&#039; then&lt;br /&gt;
							stat_value = tostring(stat_value)&lt;br /&gt;
						else&lt;br /&gt;
							stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
						end&lt;br /&gt;
						&lt;br /&gt;
						-- Add it to the row&lt;br /&gt;
						row_str = row_str .. &amp;quot;&amp;lt;td&amp;gt;&amp;quot; .. stat_value .. scaling_strs .. &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			-- Add row to the body&lt;br /&gt;
			row_str = &amp;quot;&amp;lt;tr&amp;gt;&amp;quot; .. row_str .. &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;&lt;br /&gt;
			body_str = body_str .. row_str &lt;br /&gt;
			&lt;br /&gt;
			first_hero = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	-- First header is Hero&lt;br /&gt;
	local headers_str = &amp;quot;&amp;lt;th&amp;gt;&amp;quot; .. &amp;quot;Hero&amp;quot; .. &amp;quot;&amp;lt;/th&amp;gt;&amp;quot;&lt;br /&gt;
	local header_style = &amp;quot;&amp;quot;&lt;br /&gt;
	local category_data = attribute_module.get_category_data()&lt;br /&gt;
	local postfix&lt;br /&gt;
	-- Used for keys that are not localized by Valve&lt;br /&gt;
	local postfix_key_map = {&lt;br /&gt;
		[&amp;quot;ReloadDelay&amp;quot;] = &amp;quot;StatDesc_ReloadTime_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;BulletsPerShot&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BulletsPerBurst&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BurstInterShotInterval&amp;quot;] = &amp;quot;StatDesc_ReloadTime_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;ReloadSingle&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BonusAttackRange&amp;quot;] = &amp;quot;StatDesc_WeaponRangeFalloffMax_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;SustainedDPS&amp;quot;] = &amp;quot;DPS_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;RoundsPerSecondAtMaxSpin&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;SpinAcceleration&amp;quot;] = &amp;quot;BonusFireRate_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;SpinDeceleration&amp;quot;] = &amp;quot;BonusFireRate_postfix&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
	-- Iterate stats again for displaying headers with their respective color&lt;br /&gt;
	for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
		category_attrs = attributes_data[category]&lt;br /&gt;
		category_rgb = category_data[category][&amp;quot;rgb&amp;quot;]&lt;br /&gt;
		&lt;br /&gt;
		-- Iterate attributes within the category&lt;br /&gt;
		if (stats_to_include[category] ~= nil) then &lt;br /&gt;
			for _, attr_key in ipairs(stats_to_include[category]) do&lt;br /&gt;
				attr_data = category_attrs[attr_key]&lt;br /&gt;
				&lt;br /&gt;
				if (attr_data ~= nil) then&lt;br /&gt;
					-- Localize, fallback to attr_key with proper spaces&lt;br /&gt;
					attr_localized = lang_module.get_string(attr_data[&amp;quot;label&amp;quot;])&lt;br /&gt;
					if (attr_localized == nil or attr_localized == &amp;quot;&amp;quot;) then attr_localized = util_module.add_space_before_cap(attr_key) end&lt;br /&gt;
				&lt;br /&gt;
					-- Get postfix&lt;br /&gt;
					postfix = lang_module.get_string(attr_data[&amp;quot;postfix&amp;quot;])&lt;br /&gt;
					if (postfix == nil or postfix == &amp;quot;&amp;quot;) then &lt;br /&gt;
						postfix = &amp;quot;&amp;quot; &lt;br /&gt;
					else&lt;br /&gt;
						postfix = &amp;quot; (&amp;quot; .. postfix .. &amp;quot;)&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				else -- If not in attributes data, use dictionary translate and postfix&lt;br /&gt;
					attr_localized = dictionary_module.translate(attr_key)&lt;br /&gt;
					postfix = lang_module.get_string(postfix_key_map[attr_key])&lt;br /&gt;
					if postfix == nil then &lt;br /&gt;
						return &amp;quot;attr_key &amp;quot; .. attr_key .. &amp;quot; must be added to postfix_key_map&amp;quot; &lt;br /&gt;
					end&lt;br /&gt;
					if postfix ~= &amp;quot;&amp;quot; then&lt;br /&gt;
						postfix = &amp;quot; (&amp;quot; .. postfix .. &amp;quot;)&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				header_style = &#039; style=&amp;quot;background-color: &#039; .. &amp;quot;rgb(&amp;quot; .. category_rgb .. &#039;) ;&amp;quot;&#039;&lt;br /&gt;
				&lt;br /&gt;
				headers_str = headers_str .. &amp;quot;&amp;lt;th&amp;quot; .. header_style .. &amp;quot;&amp;gt;&amp;quot; .. attr_localized .. postfix .. &amp;quot;&amp;lt;/th&amp;gt;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	headers_str = &amp;quot;&amp;lt;tr&amp;gt;&amp;quot; .. headers_str .. &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local table_str = &#039;&amp;lt;table class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;table-layout: auto; width: 100%;&amp;quot;&amp;gt;&#039; .. headers_str .. body_str .. &amp;quot;&amp;lt;/table&amp;gt;&amp;quot;&lt;br /&gt;
	local output_str = &#039;&amp;lt;div style=&amp;quot;overflow-x: auto; width: 100%;&amp;quot;&amp;gt;&#039; .. table_str .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return output_str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function localize(key, fallback)&lt;br /&gt;
	local result = lang_module.get_string(key)&lt;br /&gt;
	if (result == &amp;quot;&amp;quot;) or (result == nil) then&lt;br /&gt;
		result = util_module.add_space_before_cap(fallback) .. mw.getCurrentFrame():expandTemplate{title=&amp;quot;MissingValveTranslationTooltip&amp;quot;}&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:HeroData/doc?diff=22133</id>
		<title>Module:HeroData/doc</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:HeroData/doc?diff=22133"/>
		<updated>2025-02-22T02:21:39Z</updated>

		<summary type="html">&lt;p&gt;Sur: get_hero_scalar() reordered&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Documentation|contents=&lt;br /&gt;
Also see:&lt;br /&gt;
* [[Module:HeroData/nav]] - For nav box purposes&lt;br /&gt;
* [[Module:HeroData/release]] - For determining the release status of a hero&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This module provides functions to create hero infoboxes, statboxes, or retrieve hero information using the data uploaded to [[Data:HeroData.json]].&lt;br /&gt;
&lt;br /&gt;
Both will automatically be translated depending on the language selected. If called on&lt;br /&gt;
* &#039;&#039;&#039;[[Page]] - translates to english&lt;br /&gt;
* &#039;&#039;&#039;[[Page/en]] - translates to english&lt;br /&gt;
* &#039;&#039;&#039;[[Page/es]] - translates to spanish&lt;br /&gt;
See [[Template:Lang]] for more&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
&lt;br /&gt;
=== get_hero_var ===&lt;br /&gt;
Retrieve a hero variable&#039;s value, such as Abram&#039;s MaxHealth&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;hero_name&#039;&#039;&#039; - Name of the hero in english, or key of the hero. Preferred and recommended to use hero key, as its much more efficient. Search for the key in [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;hero_var&#039;&#039;&#039; - Key of the hero&#039;s variable, see [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;sig_figs_or_localize&#039;&#039;&#039; - OPTIONAL, # of sig figs to round to if retrieving a float, or &amp;quot;true&amp;quot; if its a string that should be localized. See Localizable values section.&lt;br /&gt;
&lt;br /&gt;
Note: Recommended to use hero key where possible, i.e. hero_atlas as its O(1) time complexity instead of hero name (Abrams) which is O(N).&lt;br /&gt;
&lt;br /&gt;
====Examples====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
Using hero name in english&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|MaxHealth}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|MaxHealth}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using hero key&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|hero_atlas|MaxHealth}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|hero_atlas|MaxHealth}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|FalloffStartRange}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|FalloffStartRange}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Round to 2 sig figs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|FalloffStartRange|2}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|FalloffStartRange|2}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|WeaponName}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|WeaponName}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Localize&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|WeaponName|true}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|WeaponName|true}}&lt;br /&gt;
&lt;br /&gt;
====Notes====&lt;br /&gt;
Only usable on variables that are integers, strings, or floats (meaning not dictionaries/hashes or arrays/lists).&lt;br /&gt;
&lt;br /&gt;
If using sig_figs parameter, ensure the value is a float.&lt;br /&gt;
&lt;br /&gt;
If using localize parameter, ensure the value is a string. See [[Data:HeroData.json]], you will notice that hero_astro&#039;s &amp;quot;Lore&amp;quot; variable has the value &amp;quot;hero_astro_lore&amp;quot;. This key is then sent to [[Module:Lang]] which checks for it in [[Data:Lang_en.json]] (or a different language).&lt;br /&gt;
&lt;br /&gt;
=== get_list_elem ===&lt;br /&gt;
Retrieve a specified element from a list&lt;br /&gt;
&lt;br /&gt;
==== Parameters ====&lt;br /&gt;
* &#039;&#039;&#039;hero_name&#039;&#039;&#039; - Name of the hero in english, or hero key. Preferred and recommended to use hero key, as its much more efficient. Search for the key in [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;hero_var&#039;&#039;&#039; - Key of the hero&#039;s variable, see [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;number&#039;&#039;&#039; - Index to retrieve from the list. 1 for 1st element, 2 for 2nd element, etc.&lt;br /&gt;
* &#039;&#039;&#039;localize&#039;&#039;&#039; - OPTIONAL - &amp;quot;true&amp;quot; if its a string that should be localized. See Localizable values section.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
Using hero name in english&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_list_elem|Abrams|WeaponTypes|2}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_list_elem|Abrams|WeaponTypes|2}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using hero key&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_list_elem|hero_atlas|WeaponTypes|2}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_list_elem|hero_atlas|WeaponTypes|2}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_list_elem|Abrams|WeaponTypes|2|true}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_list_elem|Abrams|WeaponTypes|2|true}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_hero_scalar ===&lt;br /&gt;
Retrieve a hero variable&#039;s scalar value that is inside either &amp;quot;Spirit Scaling&amp;quot; or &amp;quot;Level Scaling&amp;quot;, such as Abram&#039;s BulletDamage (scaling).&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;hero_key&#039;&#039;&#039; - Key of the hero. Search for the key of a given hero in [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;scaling_type&#039;&#039;&#039; - &amp;quot;Spirit&amp;quot; or &amp;quot;Level&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;hero_var&#039;&#039;&#039; - Key of the hero&#039;s variable that is inside either &amp;quot;Spirit Scaling&amp;quot; or &amp;quot;Level Scaling&amp;quot;, see [[Data:HeroData.json]]&lt;br /&gt;
&lt;br /&gt;
====Examples====&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_scalar|hero_atlas|Level|BulletDamage}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_scalar|hero_atlas|Level|BulletDamage}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== write_infobox ===&lt;br /&gt;
Writes a [[Template:Infobox_hero]] template call for a given hero&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;hero_name&#039;&#039;&#039; – Name of the hero, in english&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|write_infobox|HERO_NAME}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which outputs&lt;br /&gt;
{{#invoke:HeroData|write_infobox|Abrams}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== write_stat_infoboxes ===&lt;br /&gt;
Writes all 3 [[Template:Infobox_stat]] template calls (Weapon, Vitality, Spirit) for a given hero&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;hero_name&#039;&#039;&#039; – Name of the hero, in english&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|write_stat_infoboxes|HERO_NAME}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which outputs&lt;br /&gt;
{{#invoke:HeroData|write_stat_infoboxes|Abrams}}&lt;br /&gt;
&lt;br /&gt;
=== write_hero_comparison_table ===&lt;br /&gt;
Writes the [[Hero Comparison]] table for a specific Level and Spirit Power&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;level&#039;&#039;&#039; - Number of [[Level]]s / Power Increases&lt;br /&gt;
* &#039;&#039;&#039;spirit_power&#039;&#039;&#039; - Amount of Spirit power&lt;br /&gt;
&lt;br /&gt;
Both parameters are optional, as if both are 0 or not provided, the outputted table will be at base and will also include the level/SS scaling in each cell along with the base value, rather than the scaled value.&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|write_hero_comparison_table|LEVEL|SPIRITPOWER}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which outputs&lt;br /&gt;
{{#invoke:HeroData|write_hero_comparison_table|11|200}}&lt;br /&gt;
&lt;br /&gt;
== Localizable values ==&lt;br /&gt;
Localizable values as of writing this:&lt;br /&gt;
* Lore&lt;br /&gt;
* Playstyle&lt;br /&gt;
* Role&lt;br /&gt;
* WeaponDescription&lt;br /&gt;
* WeaponName&lt;br /&gt;
* elements in WeaponTypes&lt;br /&gt;
* elements in RecommendedItems&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:HeroData?diff=22132</id>
		<title>Module:HeroData</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:HeroData?diff=22132"/>
		<updated>2025-02-22T02:20:50Z</updated>

		<summary type="html">&lt;p&gt;Sur: get_scaling related funcs renamed for clarity; get_hero_scalar finished&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {};&lt;br /&gt;
local heroes_data = mw.loadJsonData(&amp;quot;Data:HeroData.json&amp;quot;)&lt;br /&gt;
local attributes_data = mw.loadJsonData(&amp;quot;Data:AttributeData.json&amp;quot;)&lt;br /&gt;
local attribute_orders = mw.loadJsonData(&amp;quot;Data:StatInfoboxOrder.json&amp;quot;)&lt;br /&gt;
local util_module = require(&#039;Module:Utilities&#039;)&lt;br /&gt;
local lang_module = require(&#039;Module:Lang&#039;)&lt;br /&gt;
local dictionary_module = require(&#039;Module:Dictionary&#039;)&lt;br /&gt;
local attribute_module = require(&#039;Module:AttributeData&#039;)&lt;br /&gt;
&lt;br /&gt;
-- returns the table of a specific item, used by external modules&lt;br /&gt;
function p.get_json_item(name)&lt;br /&gt;
	for i,v in pairs(heroes_data) do&lt;br /&gt;
		if (v[&amp;quot;Name&amp;quot;] == name) then&lt;br /&gt;
			return v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns an array of item tables that have the same properties&lt;br /&gt;
-- @function   get_similar_items&lt;br /&gt;
-- @param      {string}&lt;br /&gt;
-- @return     {array of tables}&lt;br /&gt;
local function get_similar_items(property)&lt;br /&gt;
	local similarItems = {}&lt;br /&gt;
	for _, v in pairs(heroes_data) do&lt;br /&gt;
		if (v[property] ~= nil) then&lt;br /&gt;
			table.insert(similarItems, v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return similarItems&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- returns the key of the specified hero&#039;s english name&lt;br /&gt;
function p.get_hero_key(name)&lt;br /&gt;
	for i,v in pairs(heroes_data) do&lt;br /&gt;
		if (v[&amp;quot;Name&amp;quot;] == name) then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|get_hero_var|HERO_NAME|STAT_NAME|sig_figs_or_localize}}--&lt;br /&gt;
--sig_figs optional for rounding floats&lt;br /&gt;
p.get_hero_var = function(frame)&lt;br /&gt;
	local hero_name = frame.args[1]&lt;br /&gt;
	local hero_stat_key = frame.args[2]&lt;br /&gt;
	local sig_figs_or_localize = frame.args[3]&lt;br /&gt;
	&lt;br /&gt;
	local hero = heroes_data[hero_name] --check if hero key is passed instead&lt;br /&gt;
	if(hero == nil) then hero = p.get_json_item(hero_name) end --check if hero name is passed&lt;br /&gt;
	if(hero == nil) then return &amp;quot;Hero Not Found&amp;quot; end --both invalid, error&lt;br /&gt;
	&lt;br /&gt;
	local var_value = hero[hero_stat_key]&lt;br /&gt;
	if(var_value == nil) then return 0 end&lt;br /&gt;
	&lt;br /&gt;
	--round&lt;br /&gt;
	if (sig_figs_or_localize ~= nil and tonumber(sig_figs_or_localize) ~= nil) then&lt;br /&gt;
		var_value = util_module.round_to_sig_fig(var_value, sig_figs_or_localize)&lt;br /&gt;
		if (var_value == nil) then return &amp;quot;get_hero_var() error with rounding&amp;quot; end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--localize&lt;br /&gt;
	if (sig_figs_or_localize == &amp;quot;true&amp;quot;) then&lt;br /&gt;
		return lang_module.get_string(var_value)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return var_value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|get_list_elem|HERO_NAME|VAR|NUMBER|LOCALIZE}}&lt;br /&gt;
p.get_list_elem = function(frame)&lt;br /&gt;
	local hero_name = frame.args[1]&lt;br /&gt;
	local var = frame.args[2]&lt;br /&gt;
	local number_str = frame.args[3]&lt;br /&gt;
	local number_int = tonumber(number_str)&lt;br /&gt;
	local localize = frame.args[4]&lt;br /&gt;
	local hero = heroes_data[hero_name] --check if hero key is passed instead&lt;br /&gt;
	if(hero == nil) then hero = p.get_json_item(hero_name) end --check if hero name is passed&lt;br /&gt;
	if(hero == nil) then return &amp;quot;Hero Not Found&amp;quot; end --both invalid, error&lt;br /&gt;
	if (hero == nil) then return &amp;quot;Hero &amp;quot; .. hero_name .. &amp;quot; not found&amp;quot; end&lt;br /&gt;
	local list = hero[var]&lt;br /&gt;
	if (list == nil) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	local element = list[number_int]&lt;br /&gt;
	if (element == nil) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	if localize==&amp;quot;true&amp;quot; then &lt;br /&gt;
		element = lang_module.get_string(element)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return element&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.get_ability_key = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	local bound_slot_number = frame.args[2]&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	if (hero_data == nil) then return &amp;quot;Hero key &amp;quot;..hero_key.. &amp;quot; not found&amp;quot; end&lt;br /&gt;
	local bound_abilities_data = hero_data[&amp;quot;BoundAbilities&amp;quot;]&lt;br /&gt;
	if (bound_abilities_data == nil) then return &amp;quot;Hero key &amp;quot; .. hero_key.. &amp;quot; has no BoundAbilities&amp;quot; end&lt;br /&gt;
	return bound_abilities_data[tonumber(bound_slot_number)][&amp;quot;Key&amp;quot;]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.write_role_playstyle_quote = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	if (hero_data == nil) then return hero_key..&amp;quot; not found&amp;quot; end&lt;br /&gt;
	local role_key = hero_data[&amp;quot;Role&amp;quot;]&lt;br /&gt;
	local role_localized = lang_module.get_string(role_key, nil, &#039;en&#039;)&lt;br /&gt;
	local playstyle_key = hero_data[&amp;quot;Playstyle&amp;quot;]&lt;br /&gt;
	local playstyle_localized = lang_module.get_string(playstyle_key, nil, &#039;en&#039;)&lt;br /&gt;
	&lt;br /&gt;
	local str = &amp;quot;&amp;lt;b&amp;gt;&amp;quot; .. role_localized .. &#039;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; .. playstyle_localized&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	template_args[1] = &amp;quot;&amp;quot;&lt;br /&gt;
	template_args[2] = str&lt;br /&gt;
	return frame:expandTemplate{title = &#039;Quotation&#039;, args = template_args}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.write_default_items = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1] --unlocalized&lt;br /&gt;
	if (hero_key == nil) then return &amp;quot;No hero key provided&amp;quot; end&lt;br /&gt;
	local str = &amp;quot;&amp;quot;&lt;br /&gt;
	local hero = heroes_data[hero_key]&lt;br /&gt;
	if (hero == nil) then return &amp;quot;Hero not found, must be unlocalized&amp;quot; end&lt;br /&gt;
	local template_title = &#039;PageRef&#039;&lt;br /&gt;
	for i, item_key in ipairs(hero[&amp;quot;RecommendedItems&amp;quot;]) do&lt;br /&gt;
		template_args = {}&lt;br /&gt;
		template_args[1] = lang_module.get_string(item_key, &#039;en&#039;)&lt;br /&gt;
		template_args[&#039;alt_name&#039;] = localize(item_key, item_key)&lt;br /&gt;
		local expanded_template = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
		str = str .. &amp;quot;* &amp;quot; .. expanded_template .. &amp;quot;\n&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return str&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
--If the hero scales with the stat, it returns {{Ss|value}} or {{Ls|value}}, else blank string&lt;br /&gt;
--{{#invoke:HeroData|get_hero_scalar|HERO_NAME|SCALING_TYPE|STAT_NAME}}--&lt;br /&gt;
p.get_hero_scalar = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	local scaling_type = frame.args[2]&lt;br /&gt;
	local hero_stat_key = frame.args[3]&lt;br /&gt;
	&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	if(hero_data == nil) then return &amp;quot;Hero &amp;quot; .. hero_key .. &amp;quot; not found.&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	local scaling_data = hero_data[scaling_type .. &amp;quot;Scaling&amp;quot;]&lt;br /&gt;
	if scaling_data == nil then return scaling_type .. &amp;quot;Scaling data not found for hero&amp;quot; .. hero_key end&lt;br /&gt;
	&lt;br /&gt;
	local scaling_value = scaling_data[hero_stat_key]&lt;br /&gt;
	if scaling_value == nil then return scaling_type .. &amp;quot;Scaling data does not have key &amp;quot; .. hero_stat_key .. &amp;quot; for hero &amp;quot; .. hero_key end&lt;br /&gt;
	&lt;br /&gt;
	local scaling_str = p.write_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
	if (scaling_str ~= &amp;quot;&amp;quot;) then scaling_str = &amp;quot; &amp;quot; .. scaling_str end&lt;br /&gt;
	return scaling_str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Retrieve scaling string of a hero&#039;s given stat, if it has scaling, else return blank&lt;br /&gt;
-- Scaling string meaning the expanded template {{Ss|scalar}} or {{Ls|scalar}}&lt;br /&gt;
function p.write_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
	local scaling_abbrevs = {Spirit = &amp;quot;Ss&amp;quot;, Level = &amp;quot;Ls&amp;quot;}&lt;br /&gt;
	&lt;br /&gt;
	-- Return blank if it doesnt scale&lt;br /&gt;
	if (scaling_value == 0) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	-- Round it&lt;br /&gt;
	scaling_value = util_module.round_to_sig_fig(scaling_value, 3)&lt;br /&gt;
	&lt;br /&gt;
	--The hero has a scaling value with this stat&lt;br /&gt;
	local template_title = &amp;quot;Template:&amp;quot; .. scaling_abbrevs[scaling_type] --scaling type&#039;s abbreviation&lt;br /&gt;
	&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	template_args[&amp;quot;1&amp;quot;] = scaling_value --store in 1st arg for {{{1}}} to grab it from {{SS}} or {{LS}} template&lt;br /&gt;
	&lt;br /&gt;
	local template_call = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
	return template_call&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Retrieve scaling value and type of a hero&#039;s given stat, if it has scaling, else return 0&lt;br /&gt;
function p.get_hero_scaling_data(hero_data, hero_stat_key)&lt;br /&gt;
	local scaling_type_full&lt;br /&gt;
	local scaling_data&lt;br /&gt;
	local scaling_value&lt;br /&gt;
	local scaling_types = {&amp;quot;Spirit&amp;quot;, &amp;quot;Level&amp;quot;}&lt;br /&gt;
	local scaling_data_returned = {}&lt;br /&gt;
	&lt;br /&gt;
	for index, scaling_type in ipairs(scaling_types) do&lt;br /&gt;
		scaling_type_full = scaling_type .. &amp;quot;Scaling&amp;quot;&lt;br /&gt;
		scaling_data = hero_data[scaling_type_full]&lt;br /&gt;
		&lt;br /&gt;
		--If the scaling data exists&lt;br /&gt;
		if (scaling_data ~= nil) then &lt;br /&gt;
			scaling_value = scaling_data[hero_stat_key]&lt;br /&gt;
			&lt;br /&gt;
			--If the stat scales&lt;br /&gt;
			if (scaling_value ~= nil) then&lt;br /&gt;
				scaling_data_returned[scaling_value] = scaling_type&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return scaling_data_returned&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--HERO_NAME in english&lt;br /&gt;
--{{#invoke:HeroData|write_infobox|HERO_NAME}}--&lt;br /&gt;
p.write_infobox = function(frame)&lt;br /&gt;
	-- Get hero data&lt;br /&gt;
    hero_key = frame.args[1]&lt;br /&gt;
    hero_data = heroes_data[hero_key]&lt;br /&gt;
    if(hero_data == nil) then return &amp;quot;Hero &amp;quot; .. hero_key .. &amp;quot; Not Found&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local infobox_attributes = {&lt;br /&gt;
        Weapon = {&#039;DPS&#039;,&#039;ClipSize&#039;,&#039;RoundsPerSecond&#039;,&#039;ReloadTime&#039;},&lt;br /&gt;
        Vitality = {&#039;MaxHealth&#039;,&#039;BulletResist&#039;,&#039;TechResist&#039;,&#039;MaxMoveSpeed&#039;}&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    -- Declarations and initializations&lt;br /&gt;
    local category_data = attribute_module.get_category_data()&lt;br /&gt;
    local stats&lt;br /&gt;
    local stat_data&lt;br /&gt;
    local stat_value&lt;br /&gt;
    local stat_text&lt;br /&gt;
    local label&lt;br /&gt;
    local postfix&lt;br /&gt;
    local should_display&lt;br /&gt;
    local image_file_name&lt;br /&gt;
    local image_file&lt;br /&gt;
    local icon_and_value_str&lt;br /&gt;
    local template_args = {}&lt;br /&gt;
    local stat_values = {Weapon = &amp;quot;&amp;quot;, Vitality = &amp;quot;&amp;quot;}&lt;br /&gt;
    &lt;br /&gt;
    -- Add the main parameters&lt;br /&gt;
    template_args[&amp;quot;name_english&amp;quot;] = lang_module.get_string(hero_key, &#039;en&#039;)&lt;br /&gt;
    template_args[&amp;quot;name_localized&amp;quot;] = localize(hero_key, hero_key)&lt;br /&gt;
    &lt;br /&gt;
    -- Iterate attribute categories&lt;br /&gt;
    for category, stats in pairs(infobox_attributes) do&lt;br /&gt;
		-- Iterate stats&lt;br /&gt;
		for _, stat_name in ipairs(stats) do&lt;br /&gt;
			-- Confirm its in attribute data and retrieve it&lt;br /&gt;
			attribute_data = attributes_data[category]&lt;br /&gt;
			if (attribute_data == nil) then return &amp;quot;Category &amp;quot; .. category .. &amp;quot; in infobox_attributes is not in Data:AttributeData&amp;quot; end&lt;br /&gt;
			stat_data = attribute_data[stat_name]&lt;br /&gt;
			if (stat_data == nil) then return &amp;quot;Attribute &amp;quot; .. stat_name .. &amp;quot; in infobox_attributes is not in Data:AttributeData&amp;quot; end&lt;br /&gt;
			&lt;br /&gt;
			-- gets the stat&#039;s value&lt;br /&gt;
			stat_value = hero_data[stat_name]&lt;br /&gt;
			if (stat_value == nil) then&lt;br /&gt;
				stat_value = 0 --default to 0 if not present&lt;br /&gt;
			end&lt;br /&gt;
				&lt;br /&gt;
			--Round value to 3 significant figures&lt;br /&gt;
			stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
			&lt;br /&gt;
			-- get label and postfix&lt;br /&gt;
			label = localize(stat_data[&amp;quot;label&amp;quot;], stat_name)&lt;br /&gt;
			postfix = stat_data[&amp;quot;postfix&amp;quot;]&lt;br /&gt;
			if (postfix == nil) then &lt;br /&gt;
				postfix = &amp;quot;&amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				-- light grey for postfixes&lt;br /&gt;
				postfix = lang_module.get_string(postfix)&lt;br /&gt;
				if (postfix == nil) then&lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				postfix = &#039;&amp;lt;span style=&amp;quot;color: #666666;&amp;quot;&amp;gt;&#039; .. postfix .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
			-- if a language is missing the postfix, use no postfix&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			-- Check if icon file exists, and if not, don&#039;t use any image&lt;br /&gt;
			image_file_name = &#039;File:AttributeIcon&#039; .. stat_name .. &#039;.png&#039;&lt;br /&gt;
			image_file = util_module.get_image_file(image_file_name, 15, stat_name)&lt;br /&gt;
			&lt;br /&gt;
			-- Create the template&#039;d icon&lt;br /&gt;
			local icon_color = attribute_module.get_attr_icon_color(stat_name)&lt;br /&gt;
			icon_template_title = mw.title.new(&amp;quot;Template:Icon/&amp;quot; .. icon_color)&lt;br /&gt;
			icon_template_args = {}&lt;br /&gt;
			icon_template_args[1] = image_file&lt;br /&gt;
			icon_template_args[2] = stat_value .. postfix&lt;br /&gt;
			icon_and_value_str = mw.getCurrentFrame():expandTemplate{ title = icon_template_title, args = icon_template_args }&lt;br /&gt;
			&lt;br /&gt;
			label =  &#039;,&amp;lt;span style=&amp;quot;color: #999999; background-color: #2F2F2F; display: inline-flex; width: 100%; height: 100%; justify-content: center; align-items: center;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
			&lt;br /&gt;
			-- First add localized stat name for left column&lt;br /&gt;
			stat_values[category] = stat_values[category] .. label&lt;br /&gt;
			&lt;br /&gt;
			-- Then add icon and stat value for right column&lt;br /&gt;
			stat_values[category] = stat_values[category] .. &#039;,&#039; .. icon_and_value_str&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Add the stat values in the category to i.e weapon_values and vitality_values parameters&lt;br /&gt;
		template_args[string.lower(category) .. &amp;quot;_values&amp;quot;] = stat_values[category]&lt;br /&gt;
	end&lt;br /&gt;
    &lt;br /&gt;
    -- Use expandTemplate to evaluate the Infobox_hero template&lt;br /&gt;
    local template_title = mw.title.new(&amp;quot;User:Sur&amp;quot;)&lt;br /&gt;
    local expanded_template = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
    &lt;br /&gt;
    return expanded_template&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|write_stat_infoboxes|HERO_KEY}}&lt;br /&gt;
--Creates {{Infobox_stat}}&#039;s&#039; for the 3 categories Weapon, Vitality, Spirit&lt;br /&gt;
p.write_stat_infoboxes = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	if(hero_key == nil) then return &amp;quot;Hero parameter missing&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	-- Use expandTemplate to evaluate the Infobox_hero template&lt;br /&gt;
    local template_title = mw.title.new(&amp;quot;Template:Infobox_stat&amp;quot;) --name of the template&lt;br /&gt;
    local template_calls = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-direction: column;&amp;quot;&amp;gt;&#039; --all template calls concatenated&lt;br /&gt;
    local template_call --current template call&lt;br /&gt;
	local template_args = {} --current template arguments&lt;br /&gt;
	local cell_values --current cell values&lt;br /&gt;
	local cell_value --current cell value&lt;br /&gt;
	local label --current stat&#039;s label&lt;br /&gt;
	local postfix --current stat&#039;s postfix&lt;br /&gt;
	local stat_value --current stat&#039;s numerical value in the hero data&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	local stats --stats of the current category&lt;br /&gt;
	local image_file_name --name of the image_file to check&lt;br /&gt;
	local image_file --mw returned image file&lt;br /&gt;
	local extra_blank_cell --add a blank cell after certain stats&lt;br /&gt;
	local stats_to_add_blank_after = {CritDamageReceivedScale = true}&lt;br /&gt;
	if (hero_data == nil) then return &amp;quot;Hero Not Found&amp;quot; end&lt;br /&gt;
	local category_data = attribute_module.get_category_data()&lt;br /&gt;
	local should_display&lt;br /&gt;
	&lt;br /&gt;
	for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
		if (category ~= &amp;quot;Spirit&amp;quot;) then --hide Spirit section for now&lt;br /&gt;
			stats = attributes_data[category]&lt;br /&gt;
			local category_values = category_data[category]&lt;br /&gt;
			template_args[&amp;quot;box_name&amp;quot;] = category_values.unlocalized_name&lt;br /&gt;
			template_args[&amp;quot;box_rgb&amp;quot;] = category_values.rgb&lt;br /&gt;
			template_args[&amp;quot;num_cols&amp;quot;] = 2&lt;br /&gt;
			cell_values = &amp;quot;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Determine cell values&lt;br /&gt;
			for _, stat_name in ipairs(attribute_orders[category][&amp;quot;attribute_order&amp;quot;]) do&lt;br /&gt;
				local stat_data = stats[stat_name]&lt;br /&gt;
				if stat_data == nil then return &amp;quot;Stat &amp;quot; .. stat_name .. &amp;quot; from StatInfoboxOrder has no data in AttributeData&amp;quot; end&lt;br /&gt;
				&lt;br /&gt;
				-- gets the stat&#039;s value if it has that stat, default to 0 if not&lt;br /&gt;
				stat_value = hero_data[stat_name]&lt;br /&gt;
				if (stat_value == nil) then&lt;br /&gt;
					stat_value = 0 --default to 0 if not present&lt;br /&gt;
				end&lt;br /&gt;
					&lt;br /&gt;
				--Round value to 3 significant figures&lt;br /&gt;
				stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
				&lt;br /&gt;
				-- get label and postfix&lt;br /&gt;
				label = localize(stat_data[&amp;quot;label&amp;quot;], stat_name)&lt;br /&gt;
				postfix = stat_data[&amp;quot;postfix&amp;quot;]&lt;br /&gt;
				if (postfix == nil) then &lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				else&lt;br /&gt;
					-- light grey for postfixes&lt;br /&gt;
					postfix = &#039;&amp;lt;span style=&amp;quot;color: #666666;&amp;quot;&amp;gt;&#039; .. lang_module.get_string(postfix) .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				-- if a language is missing the postfix, use no postfix&lt;br /&gt;
				if (postfix == nil) then&lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- Check if icon file exists, and if not, don&#039;t use any image&lt;br /&gt;
				image_file_name = &#039;File:AttributeIcon&#039; .. stat_name .. &#039;.png&#039;&lt;br /&gt;
				-- 15px and link to stat name (page name might not match perfectly yet)&lt;br /&gt;
				image_file = util_module.get_image_file(image_file_name, 15, stat_name)&lt;br /&gt;
				&lt;br /&gt;
				-- Create the template&#039;d icon&lt;br /&gt;
				local icon_color = attribute_module.get_attr_icon_color(stat_name)&lt;br /&gt;
				if (icon_color == &amp;quot;Brown&amp;quot;) then&lt;br /&gt;
					image_file = &#039;&amp;lt;span style=&amp;quot;position: relative; bottom: 2px; filter: invert(42%) sepia(10%) saturate(2912%) hue-rotate(351deg) brightness(90%) contrast(87%);&amp;quot;&amp;gt;&#039; .. image_file .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				end&lt;br /&gt;
				-- use white instead of grey if grey is returned&lt;br /&gt;
				&lt;br /&gt;
				-- Add an empty cell following some stats to align them correctly as seen in game&lt;br /&gt;
				if (stats_to_add_blank_after[stat_name]) then&lt;br /&gt;
					extra_blank_cell = &amp;quot; ,&amp;quot; --prefixed space is needed&lt;br /&gt;
				else&lt;br /&gt;
					extra_blank_cell = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- slightly lighter color for stat name&lt;br /&gt;
				label = &#039;&amp;lt;span style=&amp;quot;color: #3d3d3d;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				&lt;br /&gt;
				-- Add the scaling str if it scales&lt;br /&gt;
				local scaling_data = p.get_hero_scaling_data(hero_data, stat_name)&lt;br /&gt;
				local scaling_strs = &amp;quot;&amp;quot;&lt;br /&gt;
				if (scaling_data ~= nil) then&lt;br /&gt;
					for scaling_value, scaling_type in pairs(scaling_data) do&lt;br /&gt;
						local scaling_str = p.write_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
						if (scaling_str ~= &amp;quot;&amp;quot;) then scaling_str = &amp;quot; &amp;quot; .. scaling_str end&lt;br /&gt;
						scaling_strs = scaling_strs .. scaling_str&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- Set cell value as &amp;quot;Icon StatvaluePostfix Statname Scaling,&amp;quot;&lt;br /&gt;
				-- If icon file already exists, set it to #REDIRECT to the duplicate file page&lt;br /&gt;
				cell_value = image_file .. &amp;quot; &amp;quot; .. stat_value  .. postfix .. &amp;quot; &amp;quot; .. label  .. scaling_strs .. &amp;quot;,&amp;quot; .. extra_blank_cell&lt;br /&gt;
				&lt;br /&gt;
				cell_values = cell_values .. cell_value --add value to values list&lt;br /&gt;
			end&lt;br /&gt;
			template_args[&amp;quot;cell_values&amp;quot;] = cell_values&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			-- Write current call&lt;br /&gt;
			template_call = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
		&lt;br /&gt;
			-- Add call to the set of calls&lt;br /&gt;
			template_calls = template_calls .. &amp;quot;\n&amp;quot; .. template_call&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return template_calls .. &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--writes the massive hero comparison table for a specific PI and SP&lt;br /&gt;
-- scaling icons are shown only if PI and SP are both 0 or both not provided&lt;br /&gt;
--{{#invoke:HeroData|write_hero_comparison_table|POWER_INCREASES|SPIRIT_POWER}}&lt;br /&gt;
p.write_hero_comparison_table = function(frame)&lt;br /&gt;
	-- process inputs&lt;br /&gt;
	local power_increases = frame.args[1]&lt;br /&gt;
	if (power_increases == nil) then power_increases = 0 end&lt;br /&gt;
	local spirit_power = frame.args[2]&lt;br /&gt;
	if (spirit_power == nil) then spirit_power = 0 end&lt;br /&gt;
	&lt;br /&gt;
	-- Show scaling icons if power/increases/spirit power are 0/not specified&lt;br /&gt;
	local display_scaling_icons = false&lt;br /&gt;
	if (power_increases == 0 and spirit_power == 0) then&lt;br /&gt;
		display_scaling_icons = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Initializations and declarations&lt;br /&gt;
	local row_str = &amp;quot;&amp;quot;&lt;br /&gt;
	local body_str = &amp;quot;&amp;quot;&lt;br /&gt;
	local in_development&lt;br /&gt;
	local is_disabled&lt;br /&gt;
	local template_title = &amp;quot;&amp;quot;&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	local hero_icon&lt;br /&gt;
	local hero_td_style&lt;br /&gt;
	local scalar_str&lt;br /&gt;
	&lt;br /&gt;
	-- Add hero comp stats to &lt;br /&gt;
	local stats_to_include = {&lt;br /&gt;
		Weapon = {&lt;br /&gt;
			&amp;quot;DPS&amp;quot;,&lt;br /&gt;
            &amp;quot;SustainedDPS&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;RoundsPerSecond&amp;quot;,&lt;br /&gt;
            &amp;quot;FireRate&amp;quot;,&lt;br /&gt;
            &amp;quot;ClipSize&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadTime&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadDelay&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletsPerShot&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletsPerBurst&amp;quot;,&lt;br /&gt;
            &amp;quot;BurstInterShotInterval&amp;quot;,&lt;br /&gt;
            &amp;quot;LightMeleeDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;HeavyMeleeDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadSingle&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletGravityScale&amp;quot;,&lt;br /&gt;
            &amp;quot;FalloffStartRange&amp;quot;,&lt;br /&gt;
            &amp;quot;FalloffEndRange&amp;quot;,&lt;br /&gt;
            &amp;quot;BonusAttackRange&amp;quot;,&lt;br /&gt;
            &amp;quot;RoundsPerSecondAtMaxSpin&amp;quot;,&lt;br /&gt;
            &amp;quot;SpinAcceleration&amp;quot;,&lt;br /&gt;
            &amp;quot;SpinDeceleration&amp;quot;&lt;br /&gt;
		},&lt;br /&gt;
		Vitality = {&lt;br /&gt;
			&amp;quot;MaxHealth&amp;quot;,&lt;br /&gt;
            &amp;quot;BaseHealthRegen&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletResist&amp;quot;,&lt;br /&gt;
            &amp;quot;TechResist&amp;quot;,&lt;br /&gt;
            &amp;quot;CritDamageReceivedScale&amp;quot;,&lt;br /&gt;
            &amp;quot;MaxMoveSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;SprintSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;StaminaCooldown&amp;quot;,&lt;br /&gt;
            &amp;quot;Stamina&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	-- Iterate heroes&lt;br /&gt;
	for hero_key, hero_data in pairs(heroes_data) do&lt;br /&gt;
		-- Ensure they are not in development and they are an active hero&lt;br /&gt;
		in_development = hero_data[&amp;quot;InDevelopment&amp;quot;]&lt;br /&gt;
		is_disabled = hero_data[&amp;quot;IsDisabled&amp;quot;]&lt;br /&gt;
		if (not is_disabled) then &lt;br /&gt;
			&lt;br /&gt;
			--Add the row&#039;s stats&lt;br /&gt;
			row_str = &amp;quot;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Retrieve hero&#039;s localized name&lt;br /&gt;
			hero_name = localize(hero_key, hero_key)&lt;br /&gt;
			&lt;br /&gt;
			-- Retrieve hero&#039;s english name, used for hero icon&lt;br /&gt;
			hero_name_en = hero_data[&amp;quot;Name&amp;quot;]&lt;br /&gt;
			&lt;br /&gt;
			-- Expand hero icon&lt;br /&gt;
			template_title = &amp;quot;Template:HeroIcon&amp;quot;&lt;br /&gt;
			template_args[1] = hero_name_en&lt;br /&gt;
			template_args[2] = hero_name&lt;br /&gt;
			hero_icon = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
			&lt;br /&gt;
			-- First column in each row is hero name&lt;br /&gt;
			row_str = row_str .. &amp;quot;&amp;lt;td&amp;gt;&amp;quot; .. hero_icon .. &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Consecutive columns are then stats&lt;br /&gt;
			-- Iterate categories&lt;br /&gt;
			for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
				category_attrs = attributes_data[category]&lt;br /&gt;
				&lt;br /&gt;
				-- Iterate attributes within the category&lt;br /&gt;
				if (stats_to_include[category] ~= nil) then&lt;br /&gt;
					&lt;br /&gt;
					for _, attr_key in ipairs(stats_to_include[category]) do&lt;br /&gt;
						&lt;br /&gt;
						--Retrieve the stats value from hero data&lt;br /&gt;
						stat_value = hero_data[attr_key]&lt;br /&gt;
						if (stat_value == nil) then stat_value = 0 end&lt;br /&gt;
						&lt;br /&gt;
						-- Retrieve scaling val and str if it scales&lt;br /&gt;
						local scaling_data = p.get_hero_scaling_data(hero_data, attr_key)&lt;br /&gt;
						local scaling_strs = &amp;quot;&amp;quot;&lt;br /&gt;
						if (scaling_data ~= nil) then&lt;br /&gt;
							for scaling_value, scaling_type in pairs(scaling_data) do&lt;br /&gt;
								local scaling_str = p.write_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
								if (scaling_str ~= &amp;quot;&amp;quot;) then scaling_str = &amp;quot; &amp;quot; .. scaling_str end&lt;br /&gt;
								if (scaling_str ~= nil) then&lt;br /&gt;
									scaling_strs = scaling_strs .. scaling_str &lt;br /&gt;
								end&lt;br /&gt;
								-- Scale the stat value&lt;br /&gt;
								if (scaling_type == &amp;quot;Spirit&amp;quot;) then&lt;br /&gt;
									stat_value = stat_value + (spirit_power * scaling_value)&lt;br /&gt;
								elseif (scaling_type == &amp;quot;Level&amp;quot;) then&lt;br /&gt;
									if attr_key == &#039;TechResist&#039; or attr_key == &#039;BulletResist&#039; then&lt;br /&gt;
										-- each PI for resists is multiplicative&lt;br /&gt;
										stat_value = (stat_value/100 + 1 - (1-scaling_value/100)^power_increases)*100&lt;br /&gt;
									else&lt;br /&gt;
										stat_value = stat_value + (power_increases * scaling_value)&lt;br /&gt;
									end&lt;br /&gt;
								end&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
						if (not display_scaling_icons) then scaling_strs = &amp;quot;&amp;quot; end&lt;br /&gt;
						&lt;br /&gt;
						&lt;br /&gt;
						&lt;br /&gt;
						-- Convert from boolean to string, or round it&lt;br /&gt;
						if (type(stat_value)) == &#039;boolean&#039; then&lt;br /&gt;
							stat_value = tostring(stat_value)&lt;br /&gt;
						else&lt;br /&gt;
							stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
						end&lt;br /&gt;
						&lt;br /&gt;
						-- Add it to the row&lt;br /&gt;
						row_str = row_str .. &amp;quot;&amp;lt;td&amp;gt;&amp;quot; .. stat_value .. scaling_strs .. &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			-- Add row to the body&lt;br /&gt;
			row_str = &amp;quot;&amp;lt;tr&amp;gt;&amp;quot; .. row_str .. &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;&lt;br /&gt;
			body_str = body_str .. row_str &lt;br /&gt;
			&lt;br /&gt;
			first_hero = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	-- First header is Hero&lt;br /&gt;
	local headers_str = &amp;quot;&amp;lt;th&amp;gt;&amp;quot; .. &amp;quot;Hero&amp;quot; .. &amp;quot;&amp;lt;/th&amp;gt;&amp;quot;&lt;br /&gt;
	local header_style = &amp;quot;&amp;quot;&lt;br /&gt;
	local category_data = attribute_module.get_category_data()&lt;br /&gt;
	local postfix&lt;br /&gt;
	-- Used for keys that are not localized by Valve&lt;br /&gt;
	local postfix_key_map = {&lt;br /&gt;
		[&amp;quot;ReloadDelay&amp;quot;] = &amp;quot;StatDesc_ReloadTime_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;BulletsPerShot&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BulletsPerBurst&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BurstInterShotInterval&amp;quot;] = &amp;quot;StatDesc_ReloadTime_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;ReloadSingle&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BonusAttackRange&amp;quot;] = &amp;quot;StatDesc_WeaponRangeFalloffMax_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;SustainedDPS&amp;quot;] = &amp;quot;DPS_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;RoundsPerSecondAtMaxSpin&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;SpinAcceleration&amp;quot;] = &amp;quot;BonusFireRate_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;SpinDeceleration&amp;quot;] = &amp;quot;BonusFireRate_postfix&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
	-- Iterate stats again for displaying headers with their respective color&lt;br /&gt;
	for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
		category_attrs = attributes_data[category]&lt;br /&gt;
		category_rgb = category_data[category][&amp;quot;rgb&amp;quot;]&lt;br /&gt;
		&lt;br /&gt;
		-- Iterate attributes within the category&lt;br /&gt;
		if (stats_to_include[category] ~= nil) then &lt;br /&gt;
			for _, attr_key in ipairs(stats_to_include[category]) do&lt;br /&gt;
				attr_data = category_attrs[attr_key]&lt;br /&gt;
				&lt;br /&gt;
				if (attr_data ~= nil) then&lt;br /&gt;
					-- Localize, fallback to attr_key with proper spaces&lt;br /&gt;
					attr_localized = lang_module.get_string(attr_data[&amp;quot;label&amp;quot;])&lt;br /&gt;
					if (attr_localized == nil or attr_localized == &amp;quot;&amp;quot;) then attr_localized = util_module.add_space_before_cap(attr_key) end&lt;br /&gt;
				&lt;br /&gt;
					-- Get postfix&lt;br /&gt;
					postfix = lang_module.get_string(attr_data[&amp;quot;postfix&amp;quot;])&lt;br /&gt;
					if (postfix == nil or postfix == &amp;quot;&amp;quot;) then &lt;br /&gt;
						postfix = &amp;quot;&amp;quot; &lt;br /&gt;
					else&lt;br /&gt;
						postfix = &amp;quot; (&amp;quot; .. postfix .. &amp;quot;)&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				else -- If not in attributes data, use dictionary translate and postfix&lt;br /&gt;
					attr_localized = dictionary_module.translate(attr_key)&lt;br /&gt;
					postfix = lang_module.get_string(postfix_key_map[attr_key])&lt;br /&gt;
					if postfix == nil then &lt;br /&gt;
						return &amp;quot;attr_key &amp;quot; .. attr_key .. &amp;quot; must be added to postfix_key_map&amp;quot; &lt;br /&gt;
					end&lt;br /&gt;
					if postfix ~= &amp;quot;&amp;quot; then&lt;br /&gt;
						postfix = &amp;quot; (&amp;quot; .. postfix .. &amp;quot;)&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				header_style = &#039; style=&amp;quot;background-color: &#039; .. &amp;quot;rgb(&amp;quot; .. category_rgb .. &#039;) ;&amp;quot;&#039;&lt;br /&gt;
				&lt;br /&gt;
				headers_str = headers_str .. &amp;quot;&amp;lt;th&amp;quot; .. header_style .. &amp;quot;&amp;gt;&amp;quot; .. attr_localized .. postfix .. &amp;quot;&amp;lt;/th&amp;gt;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	headers_str = &amp;quot;&amp;lt;tr&amp;gt;&amp;quot; .. headers_str .. &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local table_str = &#039;&amp;lt;table class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;table-layout: auto; width: 100%;&amp;quot;&amp;gt;&#039; .. headers_str .. body_str .. &amp;quot;&amp;lt;/table&amp;gt;&amp;quot;&lt;br /&gt;
	local output_str = &#039;&amp;lt;div style=&amp;quot;overflow-x: auto; width: 100%;&amp;quot;&amp;gt;&#039; .. table_str .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return output_str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function localize(key, fallback)&lt;br /&gt;
	local result = lang_module.get_string(key)&lt;br /&gt;
	if (result == &amp;quot;&amp;quot;) or (result == nil) then&lt;br /&gt;
		result = util_module.add_space_before_cap(fallback) .. mw.getCurrentFrame():expandTemplate{title=&amp;quot;MissingValveTranslationTooltip&amp;quot;}&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:HeroData/doc?diff=22131</id>
		<title>Module:HeroData/doc</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:HeroData/doc?diff=22131"/>
		<updated>2025-02-22T02:01:53Z</updated>

		<summary type="html">&lt;p&gt;Sur: get_hero_scalar() example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Documentation|contents=&lt;br /&gt;
Also see:&lt;br /&gt;
* [[Module:HeroData/nav]] - For nav box purposes&lt;br /&gt;
* [[Module:HeroData/release]] - For determining the release status of a hero&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This module provides functions to create hero infoboxes, statboxes, or retrieve hero information using the data uploaded to [[Data:HeroData.json]].&lt;br /&gt;
&lt;br /&gt;
Both will automatically be translated depending on the language selected. If called on&lt;br /&gt;
* &#039;&#039;&#039;[[Page]] - translates to english&lt;br /&gt;
* &#039;&#039;&#039;[[Page/en]] - translates to english&lt;br /&gt;
* &#039;&#039;&#039;[[Page/es]] - translates to spanish&lt;br /&gt;
See [[Template:Lang]] for more&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
&lt;br /&gt;
=== get_hero_var ===&lt;br /&gt;
Retrieve a hero variable&#039;s value, such as Abram&#039;s MaxHealth&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;hero_name&#039;&#039;&#039; - Name of the hero in english, or key of the hero. Preferred and recommended to use hero key, as its much more efficient. Search for the key in [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;hero_var&#039;&#039;&#039; - Key of the hero&#039;s variable, see [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;sig_figs_or_localize&#039;&#039;&#039; - OPTIONAL, # of sig figs to round to if retrieving a float, or &amp;quot;true&amp;quot; if its a string that should be localized. See Localizable values section.&lt;br /&gt;
&lt;br /&gt;
Note: Recommended to use hero key where possible, i.e. hero_atlas as its O(1) time complexity instead of hero name (Abrams) which is O(N).&lt;br /&gt;
&lt;br /&gt;
====Examples====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
Using hero name in english&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|MaxHealth}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|MaxHealth}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using hero key&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|hero_atlas|MaxHealth}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|hero_atlas|MaxHealth}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|FalloffStartRange}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|FalloffStartRange}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Round to 2 sig figs&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|FalloffStartRange|2}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|FalloffStartRange|2}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|WeaponName}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|WeaponName}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Localize&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_var|Abrams|WeaponName|true}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_var|Abrams|WeaponName|true}}&lt;br /&gt;
&lt;br /&gt;
====Notes====&lt;br /&gt;
Only usable on variables that are integers, strings, or floats (meaning not dictionaries/hashes or arrays/lists).&lt;br /&gt;
&lt;br /&gt;
If using sig_figs parameter, ensure the value is a float.&lt;br /&gt;
&lt;br /&gt;
If using localize parameter, ensure the value is a string. See [[Data:HeroData.json]], you will notice that hero_astro&#039;s &amp;quot;Lore&amp;quot; variable has the value &amp;quot;hero_astro_lore&amp;quot;. This key is then sent to [[Module:Lang]] which checks for it in [[Data:Lang_en.json]] (or a different language).&lt;br /&gt;
&lt;br /&gt;
=== get_list_elem ===&lt;br /&gt;
Retrieve a specified element from a list&lt;br /&gt;
&lt;br /&gt;
==== Parameters ====&lt;br /&gt;
* &#039;&#039;&#039;hero_name&#039;&#039;&#039; - Name of the hero in english, or hero key. Preferred and recommended to use hero key, as its much more efficient. Search for the key in [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;hero_var&#039;&#039;&#039; - Key of the hero&#039;s variable, see [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;number&#039;&#039;&#039; - Index to retrieve from the list. 1 for 1st element, 2 for 2nd element, etc.&lt;br /&gt;
* &#039;&#039;&#039;localize&#039;&#039;&#039; - OPTIONAL - &amp;quot;true&amp;quot; if its a string that should be localized. See Localizable values section.&lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
Using hero name in english&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_list_elem|Abrams|WeaponTypes|2}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_list_elem|Abrams|WeaponTypes|2}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Using hero key&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_list_elem|hero_atlas|WeaponTypes|2}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_list_elem|hero_atlas|WeaponTypes|2}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_list_elem|Abrams|WeaponTypes|2|true}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_list_elem|Abrams|WeaponTypes|2|true}}&lt;br /&gt;
&lt;br /&gt;
=== write_infobox ===&lt;br /&gt;
Writes a [[Template:Infobox_hero]] template call for a given hero&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;hero_name&#039;&#039;&#039; – Name of the hero, in english&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|write_infobox|HERO_NAME}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which outputs&lt;br /&gt;
{{#invoke:HeroData|write_infobox|Abrams}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== get_hero_scalar ===&lt;br /&gt;
Retrieve a hero variable&#039;s scalar value that is inside either &amp;quot;Spirit Scaling&amp;quot; or &amp;quot;Level Scaling&amp;quot;, such as Abram&#039;s BulletDamage (scaling).&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;hero_key&#039;&#039;&#039; - Key of the hero. Search for the key of a given hero in [[Data:HeroData.json]]&lt;br /&gt;
* &#039;&#039;&#039;scaling_type&#039;&#039;&#039; - &amp;quot;Spirit&amp;quot; or &amp;quot;Level&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;hero_var&#039;&#039;&#039; - Key of the hero&#039;s variable that is inside either &amp;quot;Spirit Scaling&amp;quot; or &amp;quot;Level Scaling&amp;quot;, see [[Data:HeroData.json]]&lt;br /&gt;
&lt;br /&gt;
====Examples====&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|get_hero_scalar|hero_atlas|Level|BulletDamage}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|get_hero_scalar|hero_atlas|Level|BulletDamage}}&lt;br /&gt;
&lt;br /&gt;
=== write_stat_infoboxes ===&lt;br /&gt;
Writes all 3 [[Template:Infobox_stat]] template calls (Weapon, Vitality, Spirit) for a given hero&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;hero_name&#039;&#039;&#039; – Name of the hero, in english&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|write_stat_infoboxes|HERO_NAME}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which outputs&lt;br /&gt;
{{#invoke:HeroData|write_stat_infoboxes|Abrams}}&lt;br /&gt;
&lt;br /&gt;
=== write_hero_comparison_table ===&lt;br /&gt;
Writes the [[Hero Comparison]] table for a specific Level and Spirit Power&lt;br /&gt;
&lt;br /&gt;
====Parameters====&lt;br /&gt;
* &#039;&#039;&#039;level&#039;&#039;&#039; - Number of [[Level]]s / Power Increases&lt;br /&gt;
* &#039;&#039;&#039;spirit_power&#039;&#039;&#039; - Amount of Spirit power&lt;br /&gt;
&lt;br /&gt;
Both parameters are optional, as if both are 0 or not provided, the outputted table will be at base and will also include the level/SS scaling in each cell along with the base value, rather than the scaled value.&lt;br /&gt;
&lt;br /&gt;
====Example====&lt;br /&gt;
From wikitext:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;{{#invoke:HeroData|write_hero_comparison_table|LEVEL|SPIRITPOWER}}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which outputs&lt;br /&gt;
{{#invoke:HeroData|write_hero_comparison_table|11|200}}&lt;br /&gt;
&lt;br /&gt;
== Localizable values ==&lt;br /&gt;
Localizable values as of writing this:&lt;br /&gt;
* Lore&lt;br /&gt;
* Playstyle&lt;br /&gt;
* Role&lt;br /&gt;
* WeaponDescription&lt;br /&gt;
* WeaponName&lt;br /&gt;
* elements in WeaponTypes&lt;br /&gt;
* elements in RecommendedItems&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/Sandbox?diff=22017</id>
		<title>User:Sur/Sandbox</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/Sandbox?diff=22017"/>
		<updated>2025-02-19T16:45:40Z</updated>

		<summary type="html">&lt;p&gt;Sur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{#dateformat:05-30-2024}}&lt;br /&gt;
{{#dateformat:05/30/2024}}&lt;br /&gt;
&lt;br /&gt;
{{#dateformat:30-05-2024}}&lt;br /&gt;
{{#dateformat:30/05/2024}}&lt;br /&gt;
&lt;br /&gt;
{{#invoke:HeroData|get_hero_scalar_str_invoke|Abrams|BulletDamage}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Normal&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Siphon Life.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inverted&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;filter: invert(1);&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Siphon Life.png]]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/DefaultBuild?diff=21579</id>
		<title>User:Sur/DefaultBuild</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/DefaultBuild?diff=21579"/>
		<updated>2025-02-07T22:01:50Z</updated>

		<summary type="html">&lt;p&gt;Sur: example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=-1}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuildDesc}}&lt;br /&gt;
{{#invoke:HeroData|write_default_items|hero_atlas}}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/Sandbox?diff=21544</id>
		<title>User:Sur/Sandbox</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/Sandbox?diff=21544"/>
		<updated>2025-02-07T03:31:40Z</updated>

		<summary type="html">&lt;p&gt;Sur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{#dateformat:05-30-2024}}&lt;br /&gt;
{{#dateformat:05/30/2024}}&lt;br /&gt;
&lt;br /&gt;
{{#dateformat:30-05-2024}}&lt;br /&gt;
{{#dateformat:30/05/2024}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Normal&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Siphon Life.png]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inverted&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;filter: invert(1);&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Siphon Life.png]]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/MetaExample?diff=21341</id>
		<title>User:Sur/MetaExample</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/MetaExample?diff=21341"/>
		<updated>2025-01-31T18:13:03Z</updated>

		<summary type="html">&lt;p&gt;Sur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;secret&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
My cool page&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/MetaExample?diff=21340</id>
		<title>User:Sur/MetaExample</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/MetaExample?diff=21340"/>
		<updated>2025-01-31T18:09:41Z</updated>

		<summary type="html">&lt;p&gt;Sur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta property=“og:title” content=“secret text”&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
My cool page&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/MetaExample?diff=21339</id>
		<title>User:Sur/MetaExample</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/MetaExample?diff=21339"/>
		<updated>2025-01-31T18:09:09Z</updated>

		<summary type="html">&lt;p&gt;Sur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta content=“secret text”&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
My cool page&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/MetaExample?diff=21338</id>
		<title>User:Sur/MetaExample</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/MetaExample?diff=21338"/>
		<updated>2025-01-31T18:08:27Z</updated>

		<summary type="html">&lt;p&gt;Sur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;meta content=“secret text”&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My cool page&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/MetaExample?diff=21337</id>
		<title>User:Sur/MetaExample</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/MetaExample?diff=21337"/>
		<updated>2025-01-31T18:07:43Z</updated>

		<summary type="html">&lt;p&gt;Sur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;meta&amp;gt;secret text&amp;lt;/meta&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My cool page&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/MetaExample?diff=21336</id>
		<title>User:Sur/MetaExample</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/MetaExample?diff=21336"/>
		<updated>2025-01-31T18:04:40Z</updated>

		<summary type="html">&lt;p&gt;Sur: Created page with &amp;quot;&amp;lt;metadata&amp;gt;secret text&amp;lt;/metadata&amp;gt;  My cool page&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;metadata&amp;gt;secret text&amp;lt;/metadata&amp;gt;&lt;br /&gt;
&lt;br /&gt;
My cool page&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:ItemData?diff=21195</id>
		<title>Module:ItemData</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:ItemData?diff=21195"/>
		<updated>2025-01-29T05:12:53Z</updated>

		<summary type="html">&lt;p&gt;Sur: Disabled renamed to IsDisabled in backend for consistency&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {};&lt;br /&gt;
local data = mw.loadJsonData(&amp;quot;Data:ItemData.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
---------------------------------------- Utility functions&lt;br /&gt;
&lt;br /&gt;
-- Returns the table of a specific item&lt;br /&gt;
-- @function   get_json_item&lt;br /&gt;
-- @param      {string}&lt;br /&gt;
-- @return     {table}&lt;br /&gt;
local function get_json_item(name)&lt;br /&gt;
	for _, v in pairs(data) do&lt;br /&gt;
		if (v[&amp;quot;Name&amp;quot;] == name and not v[&amp;quot;IsDisabled&amp;quot;]) then&lt;br /&gt;
			return v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns an array of item tables that have the same properties&lt;br /&gt;
-- @function   get_similar_items&lt;br /&gt;
-- @param      {string}&lt;br /&gt;
-- @return     {array of tables}&lt;br /&gt;
local function get_similar_items(property)&lt;br /&gt;
	local similarItems = {}&lt;br /&gt;
	for _, v in pairs(data) do&lt;br /&gt;
		if (v[property] ~= nil) then&lt;br /&gt;
			table.insert(similarItems, v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return similarItems&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Adds commas delimiter to the thousands place&lt;br /&gt;
local lang = mw.language.getContentLanguage()&lt;br /&gt;
local function Format(amount)&lt;br /&gt;
    local formatted = amount&lt;br /&gt;
    if(type(formatted) ~= &amp;quot;number&amp;quot;) then return &amp;quot;&amp;lt;span style=\&amp;quot;color:red;\&amp;quot;&amp;gt;Cannot format non-number value.&amp;lt;/span&amp;gt;&amp;quot; end&lt;br /&gt;
    return lang:formatNum(tonumber(formatted))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Get cost of an item &lt;br /&gt;
-- @function   get_cost&lt;br /&gt;
-- @param      {string}&lt;br /&gt;
-- @return     {number}&lt;br /&gt;
local function get_cost(item_name)&lt;br /&gt;
	local item = get_json_item(item_name)&lt;br /&gt;
	if(item == nil) then return &amp;quot;&amp;lt;span style=\&amp;quot;color:red;\&amp;quot;&amp;gt;Item Not Found.&amp;lt;/span&amp;gt;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	local cost = 0&lt;br /&gt;
	local cur_item = item&lt;br /&gt;
	repeat&lt;br /&gt;
		cost = cost + cur_item[&amp;quot;Cost&amp;quot;]&lt;br /&gt;
		if(cur_item[&amp;quot;Components&amp;quot;] == nil) then&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
		cur_item = data[cur_item[&amp;quot;Components&amp;quot;][1]]&lt;br /&gt;
	until cur_item == nil&lt;br /&gt;
&lt;br /&gt;
	return cost&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--- Get type/slot/category of an item &lt;br /&gt;
-- @function   get_type&lt;br /&gt;
-- @param      {string}&lt;br /&gt;
-- @return     {string}&lt;br /&gt;
local function get_type(item_name)&lt;br /&gt;
	local item = get_json_item(item_name)&lt;br /&gt;
	if(item == nil) then return &amp;quot;&amp;lt;span style=\&amp;quot;color:red;\&amp;quot;&amp;gt;Item Not Found.&amp;lt;/span&amp;gt;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	if (item[&amp;quot;Slot&amp;quot;] == &amp;quot;Weapon&amp;quot;) then&lt;br /&gt;
		return &amp;quot;Weapon&amp;quot;&lt;br /&gt;
	elseif (item[&amp;quot;Slot&amp;quot;] == &amp;quot;Armor&amp;quot;) then&lt;br /&gt;
		return &amp;quot;Vitality&amp;quot;&lt;br /&gt;
	elseif (item[&amp;quot;Slot&amp;quot;] == &amp;quot;Tech&amp;quot;) then&lt;br /&gt;
		return &amp;quot;Spirit&amp;quot;&lt;br /&gt;
	else &lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---------------------------------------- Invocable functions&lt;br /&gt;
&lt;br /&gt;
--- {{#invoke:ItemData|get_cost|ITEM_NAME}} access point&lt;br /&gt;
p.get_cost = function(frame)&lt;br /&gt;
	local item_name = frame.args[1]&lt;br /&gt;
	return Format(get_cost(item_name))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Module access point&lt;br /&gt;
function p._get_cost(a)&lt;br /&gt;
	a = tostring(a) or &#039;0&#039;&lt;br /&gt;
	return get_cost(a)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- {{#invoke:ItemData|get_type|ITEM_NAME}} access point&lt;br /&gt;
p.get_type = function(frame)&lt;br /&gt;
	local item_name = frame.args[1]&lt;br /&gt;
	return get_type(item_name)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Module access point&lt;br /&gt;
function p._get_type(a)&lt;br /&gt;
	a = tostring(a) or &amp;quot;&amp;quot;&lt;br /&gt;
	return get_type(a)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:ItemData|is_active|ITEM_NAME}}--&lt;br /&gt;
p.is_active = function(frame)&lt;br /&gt;
	local item_name = frame.args[1]&lt;br /&gt;
	local item = get_json_item(item_name)&lt;br /&gt;
	if(item == nil) then return &amp;quot;&amp;lt;span style=\&amp;quot;color:red;\&amp;quot;&amp;gt;Item Not Found.&amp;lt;/span&amp;gt;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	if (item[&amp;quot;Activation&amp;quot;] == &amp;quot;Passive&amp;quot;) then&lt;br /&gt;
		return	false&lt;br /&gt;
	else &lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:ItemData|get_prop|ITEM_NAME|PROPERTY}}--&lt;br /&gt;
--check Data:ItemData.json for properties&lt;br /&gt;
p.get_prop = function(frame)&lt;br /&gt;
	local tableValues = {}&lt;br /&gt;
	local item_name = frame.args[1]&lt;br /&gt;
	local property = frame.args[2]&lt;br /&gt;
	local item = get_json_item(item_name)&lt;br /&gt;
	if(item == nil) then return &amp;quot;&amp;lt;span style=\&amp;quot;color:red;\&amp;quot;&amp;gt;Item Not Found.&amp;lt;/span&amp;gt;&amp;quot; end&lt;br /&gt;
	if(type(item[property]) == &amp;quot;table&amp;quot;) then&lt;br /&gt;
		for i,v in pairs(item[property]) do&lt;br /&gt;
			local tableValues = table.insert(tableValues, v)&lt;br /&gt;
		end&lt;br /&gt;
		return table.concat(tableValues, &amp;quot;, &amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	return item[property]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
p.get_component_name = function(frame)&lt;br /&gt;
	local item_name = frame.args[1]&lt;br /&gt;
	local item = get_json_item(item_name)&lt;br /&gt;
	if(item == nil) then return &amp;quot;&amp;lt;span style=\&amp;quot;color:red;\&amp;quot;&amp;gt;Item Not Found.&amp;lt;/span&amp;gt;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	local components = item[&#039;Components&#039;]&lt;br /&gt;
	--return empty string if no component found&lt;br /&gt;
	if(components == nil) then return nil end&lt;br /&gt;
	&lt;br /&gt;
	local component_key = components[1]&lt;br /&gt;
	local component = data[component_key]&lt;br /&gt;
	if (component == nil) then return nil end&lt;br /&gt;
	&lt;br /&gt;
	return component[&#039;Name&#039;]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- {{Items count}} access point&lt;br /&gt;
function p.get_headcount()&lt;br /&gt;
	local iter = 0&lt;br /&gt;
	local tbl = get_similar_items(&amp;quot;IsDisabled&amp;quot;)&lt;br /&gt;
	for _, v in ipairs(tbl) do&lt;br /&gt;
		if (v[&amp;quot;IsDisabled&amp;quot;] == false and v[&amp;quot;Name&amp;quot;] ~= nil) then&lt;br /&gt;
			iter = iter + 1	&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return iter&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Hero_Navbox?diff=20732</id>
		<title>Template:Hero Navbox</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Hero_Navbox?diff=20732"/>
		<updated>2025-01-23T13:57:56Z</updated>

		<summary type="html">&lt;p&gt;Sur: Fix herolabs not defaulting to no slash&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;display:block;border-radius: 8px;text-align: center; background-image: linear-gradient(#c1a671, #d0bb95); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero{{#if:{{{lang_code|}}}|/{{{lang_code}}}|}}|&amp;lt;span style=&amp;quot;color:#FFF5E8; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3);&amp;quot;&amp;gt;{{#invoke:lang|get_string|menu_heroes}}&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=false&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
|lang_code={{{lang_code|en}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;border-radius: 8px;text-align: center; background-image: linear-gradient(#ce9b54, #674915); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero Labs{{#if:{{{lang_code|}}}|/{{{lang_code}}}|}}|&amp;lt;span style=&amp;quot;color:#FFF0D6; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center;&amp;quot;&amp;gt;{{#invoke:lang|get_string|MyRosterHeroLabsHero}}&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: 0 auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=true&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
|lang_code={{{lang_code|en}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Hero_Navbox?diff=20730</id>
		<title>Template:Hero Navbox</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Hero_Navbox?diff=20730"/>
		<updated>2025-01-23T03:31:16Z</updated>

		<summary type="html">&lt;p&gt;Sur: fixing placement of /&amp;lt;lang_code&amp;gt; in title code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;display:block;border-radius: 8px;text-align: center; background-image: linear-gradient(#c1a671, #d0bb95); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero{{#if:{{{lang_code|}}}|/{{{lang_code}}}|}}|&amp;lt;span style=&amp;quot;color:#FFF5E8; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3);&amp;quot;&amp;gt;{{#invoke:lang|get_string|menu_heroes}}&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=false&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
|lang_code={{{lang_code|en}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;border-radius: 8px;text-align: center; background-image: linear-gradient(#ce9b54, #674915); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero Labs{{#if:{{{lang_code|}}}|/{{{lang_code}}}|}}|&amp;lt;span style=&amp;quot;color:#FFF0D6; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center;&amp;quot;&amp;gt;{{#invoke:lang|get_string|MyRosterHeroLabsHero}}&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: 0 auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=true&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
|lang_code={{{lang_code|}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Hero_Navbox?diff=20729</id>
		<title>Template:Hero Navbox</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Hero_Navbox?diff=20729"/>
		<updated>2025-01-23T03:28:51Z</updated>

		<summary type="html">&lt;p&gt;Sur: attempting localizing titles&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;display:block;border-radius: 8px;text-align: center; background-image: linear-gradient(#c1a671, #d0bb95); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero|&amp;lt;span style=&amp;quot;color:#FFF5E8; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3);&amp;quot;&amp;gt;{{#invoke:lang|get_string|menu_heroes}}{{#if:{{{lang_code|}}}|/{{{lang_code}}}|}}&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=false&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
|lang_code={{{lang_code|en}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;border-radius: 8px;text-align: center; background-image: linear-gradient(#ce9b54, #674915); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero Labs|&amp;lt;span style=&amp;quot;color:#FFF0D6; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center;&amp;quot;&amp;gt;{{#invoke:lang|get_string|MyRosterHeroLabsHero}}{{#if:{{{lang_code|}}}|/{{{lang_code}}}|}}&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: 0 auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=true&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
|lang_code={{{lang_code|}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Hero_card2?diff=20721</id>
		<title>Template:Hero card2</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Hero_card2?diff=20721"/>
		<updated>2025-01-22T23:35:34Z</updated>

		<summary type="html">&lt;p&gt;Sur: using link and subpage param in all spots where link is used&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;lt;div class=&amp;quot;HeroCard2&amp;quot; style=&amp;quot;display:inline-block; border-radius: 8px; overflow:hidden; position: relative; background-image: {{#ifeq: {{{herolabs|false}}} | true | linear-gradient(#ce9b54, #674915)| linear-gradient(#A69885, #72695A) }}; max-width: {{{card_size|132}}}px; width: 30%; height: auto; box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5); transition: 0.1s transform ease-in-out;&amp;quot;&amp;gt;&amp;lt;span&amp;gt;[[File:{{{Image|{{{link|{{{name|Abrams}}}}}}}}} card.png|{{{card_size|132}}}px|link={{{link|{{{name|Abrams}}}}}}{{{subpage|}}}]]&amp;lt;/span&amp;gt;&amp;lt;p style=&amp;quot;display: {{#ifeq: {{{herolabs|false}}} | true | block| none }}; position: absolute; bottom: 35px; left: 50%; transform: translateX(-50%); text-align: center; width: fit-content; font-size: {{{herolabs_text_size|6}}}px; margin: 0; pointer-events: none; border-radius: 2px; background-color: #d36c16ee; padding: 1px 4px 0px 4px; font-family: Tahoma, sans-serif; color: white; font-weight: bold; max-height: 15px;&amp;quot;&amp;gt;{{#invoke:Lang|get_string|MyRosterHeroLabsHero|fallback_str=en}}&amp;lt;/p&amp;gt;&amp;lt;p style=&amp;quot;position: absolute; bottom: 0px; text-align: center; width: 100%; font-weight: bold; font-family: &#039;Forevs Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; color: #FFEFD7; text-shadow: 0px 0px 8px rgba(0, 0, 0, 0.5), 0px 0px 8px rgba(0, 0, 0, 0.5), 0px 0px 8px rgba(0, 0, 0, 0.5); font-size: min(5vw, {{{text_size|{{{text-size|24}}}}}}px); letter-spacing: 0.5px; margin: 0; text-transform: uppercase; text-overflow: ellipsis; pointer-events: none;&amp;quot;&amp;gt;{{{name|Abrams}}}&amp;lt;/p&amp;gt;&amp;lt;div style=&amp;quot;display: {{#ifeq: {{{recommended|false}}} | true | inline| none }}; top:0; right:0; position: absolute;&amp;quot;&amp;gt;&amp;lt;div position: relative;&amp;gt;[[File:Recommended icon backer.png| {{{sticker_size|56}}}px |link={{{link|{{{name|Abrams}}}}}}{{{subpage|}}}]]&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div style=&amp;quot;display: {{#ifeq: {{{herolabs|false}}} | true | inline| none }}; top:0; right:0; position: absolute;&amp;quot;&amp;gt;&amp;lt;div position: relative;&amp;gt;[[File:Herolabs_icon_backer.png | {{{sticker_size|56}}}px |link={{{link|{{{name|Abrams}}}}}}{{{subpage|}}}]]&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:HeroData/nav?diff=20720</id>
		<title>Module:HeroData/nav</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:HeroData/nav?diff=20720"/>
		<updated>2025-01-22T23:33:41Z</updated>

		<summary type="html">&lt;p&gt;Sur: send subpage to subpage parameter instead of appending to link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local heroes_data = mw.loadJsonData(&amp;quot;Data:HeroData.json&amp;quot;)&lt;br /&gt;
local hero_release_module = require(&#039;Module:HeroData/release&#039;)&lt;br /&gt;
local lang_module = require(&#039;Module:Lang&#039;)&lt;br /&gt;
&lt;br /&gt;
-- for [[Template:Deadlock_Wiki/Heroes]] on home page, i.e. [[Template:Hero card2]]&lt;br /&gt;
function p.get_hero_nav_cards(frame)&lt;br /&gt;
	local in_herolabs = frame.args[&#039;in_herolabs&#039;] --true or false&lt;br /&gt;
	local text_size = frame.args[&#039;text_size&#039;]&lt;br /&gt;
	local card_size = frame.args[&#039;card_size&#039;]&lt;br /&gt;
	local sticker_size = frame.args[&#039;sticker_size&#039;]&lt;br /&gt;
	local herolabs_text_size = frame.args[&#039;herolabs_text_size&#039;]&lt;br /&gt;
	local debug_mode = frame.args[&#039;debug_mode&#039;]&lt;br /&gt;
	local lang_code = frame.args[&#039;lang_code&#039;]&lt;br /&gt;
	&lt;br /&gt;
	-- Turn debug_mode from string to bool, default to false&lt;br /&gt;
	if debug_mode == nil then&lt;br /&gt;
		debug_mode = false&lt;br /&gt;
	elseif debug_mode == &#039;true&#039; then&lt;br /&gt;
		 debug_mode = true&lt;br /&gt;
	elseif debug_mode == &#039;false&#039; then&lt;br /&gt;
		debug_mode = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if in_herolabs ~= &#039;true&#039; and in_herolabs ~= &#039;false&#039; then&lt;br /&gt;
		return &#039;in_herolabs must be either true or false&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local subpage = &#039;&#039;&lt;br /&gt;
	if lang_code ~= nil and lang_code ~= &#039;en&#039; then subpage = &#039;/&#039; .. lang_code end&lt;br /&gt;
	&lt;br /&gt;
	--Iterate heroes&lt;br /&gt;
	local heroes = {}&lt;br /&gt;
	for hero_key, hero_data in pairs(heroes_data) do&lt;br /&gt;
		if hero_data[&amp;quot;Name&amp;quot;] ~= nil then&lt;br /&gt;
			-- if herolabs is requested, only needs to have herolabs=true&lt;br /&gt;
			-- otherwise, needs to be not disabled, in development, nd herolabs is nil or false&lt;br /&gt;
			local this_hero_status = hero_release_module.get_hero_release_status(hero_key)&lt;br /&gt;
			&lt;br /&gt;
			if this_in_herolabs == nil then this_in_herolabs = false end&lt;br /&gt;
			&lt;br /&gt;
			if ((in_herolabs == &#039;true&#039; and this_hero_status == &#039;HeroLabs&#039;) or&lt;br /&gt;
				(in_herolabs == &#039;false&#039; and this_hero_status == &#039;Released&#039;)) then&lt;br /&gt;
				&lt;br /&gt;
				local is_recommended = hero_data[&#039;IsRecommended&#039;]&lt;br /&gt;
				if is_recommended == nil then&lt;br /&gt;
					is_recommended = false&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				local sub_page_str = &#039;&#039;&lt;br /&gt;
				&lt;br /&gt;
				&lt;br /&gt;
				local hero_str = &#039;|name=&#039; .. lang_module.get_string(hero_key, nil, &#039;en&#039;) .. &#039;|link=&#039; .. lang_module.get_string(hero_key, &#039;en&#039;) .. &#039;|subpage=&#039; .. subpage .. &#039;|recommended=&#039; .. tostring(is_recommended)&lt;br /&gt;
				&lt;br /&gt;
				table.insert(heroes, hero_str)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	--Order list alphabetically&lt;br /&gt;
	table.sort(heroes) --O(nlogn)&lt;br /&gt;
	&lt;br /&gt;
	--Add each item to output&lt;br /&gt;
	local ret = &#039;&#039;&lt;br /&gt;
	for index, hero_name in ipairs(heroes) do&lt;br /&gt;
		ret = ret .. &#039;{{Hero card2&#039; .. hero_name&lt;br /&gt;
		ret = ret .. &#039;|text_size=&#039; .. text_size&lt;br /&gt;
		ret = ret .. &#039;|herolabs=&#039; .. in_herolabs&lt;br /&gt;
		ret = ret .. &#039;|card_size=&#039; .. card_size&lt;br /&gt;
		ret = ret .. &#039;|sticker_size=&#039; .. sticker_size&lt;br /&gt;
		ret = ret .. &#039;|herolabs_text_size=&#039; .. herolabs_text_size&lt;br /&gt;
		ret = ret .. &#039;}} &#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--Remove the last space&lt;br /&gt;
	ret = string.sub(ret, 1, -(string.len(&#039; &#039;))-1)&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	if debug_mode then&lt;br /&gt;
		return ret&lt;br /&gt;
	else -- evaluate wikitext if not in debug mode&lt;br /&gt;
		return frame:preprocess(ret)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Hero_Navbox?diff=20719</id>
		<title>Template:Hero Navbox</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Hero_Navbox?diff=20719"/>
		<updated>2025-01-22T23:30:32Z</updated>

		<summary type="html">&lt;p&gt;Sur: forward lang_code parameter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;display:block;border-radius: 8px;text-align: center; background-image: linear-gradient(#c1a671, #d0bb95); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero|&amp;lt;span style=&amp;quot;color:#FFF5E8; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3);&amp;quot;&amp;gt;Heroes&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=false&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
|lang_code={{{lang_code|en}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;border-radius: 8px;text-align: center; background-image: linear-gradient(#ce9b54, #674915); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero Labs|&amp;lt;span style=&amp;quot;color:#FFF0D6; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center;&amp;quot;&amp;gt;Hero Labs&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: 0 auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=true&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
|lang_code={{{lang_code|en}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:HeroData/nav?diff=20718</id>
		<title>Module:HeroData/nav</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:HeroData/nav?diff=20718"/>
		<updated>2025-01-22T23:29:03Z</updated>

		<summary type="html">&lt;p&gt;Sur: get_hero_nav_cards() lang_code param added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local heroes_data = mw.loadJsonData(&amp;quot;Data:HeroData.json&amp;quot;)&lt;br /&gt;
local hero_release_module = require(&#039;Module:HeroData/release&#039;)&lt;br /&gt;
local lang_module = require(&#039;Module:Lang&#039;)&lt;br /&gt;
&lt;br /&gt;
-- for [[Template:Deadlock_Wiki/Heroes]] on home page, i.e. [[Template:Hero card2]]&lt;br /&gt;
function p.get_hero_nav_cards(frame)&lt;br /&gt;
	local in_herolabs = frame.args[&#039;in_herolabs&#039;] --true or false&lt;br /&gt;
	local text_size = frame.args[&#039;text_size&#039;]&lt;br /&gt;
	local card_size = frame.args[&#039;card_size&#039;]&lt;br /&gt;
	local sticker_size = frame.args[&#039;sticker_size&#039;]&lt;br /&gt;
	local herolabs_text_size = frame.args[&#039;herolabs_text_size&#039;]&lt;br /&gt;
	local debug_mode = frame.args[&#039;debug_mode&#039;]&lt;br /&gt;
	local lang_code = frame.args[&#039;lang_code&#039;]&lt;br /&gt;
	&lt;br /&gt;
	-- Turn debug_mode from string to bool, default to false&lt;br /&gt;
	if debug_mode == nil then&lt;br /&gt;
		debug_mode = false&lt;br /&gt;
	elseif debug_mode == &#039;true&#039; then&lt;br /&gt;
		 debug_mode = true&lt;br /&gt;
	elseif debug_mode == &#039;false&#039; then&lt;br /&gt;
		debug_mode = false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if in_herolabs ~= &#039;true&#039; and in_herolabs ~= &#039;false&#039; then&lt;br /&gt;
		return &#039;in_herolabs must be either true or false&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local subpage = &#039;&#039;&lt;br /&gt;
	if lang_code ~= nil and lang_code ~= &#039;en&#039; then subpage = &#039;/&#039; .. lang_code end&lt;br /&gt;
	&lt;br /&gt;
	--Iterate heroes&lt;br /&gt;
	local heroes = {}&lt;br /&gt;
	for hero_key, hero_data in pairs(heroes_data) do&lt;br /&gt;
		if hero_data[&amp;quot;Name&amp;quot;] ~= nil then&lt;br /&gt;
			-- if herolabs is requested, only needs to have herolabs=true&lt;br /&gt;
			-- otherwise, needs to be not disabled, in development, nd herolabs is nil or false&lt;br /&gt;
			local this_hero_status = hero_release_module.get_hero_release_status(hero_key)&lt;br /&gt;
			&lt;br /&gt;
			if this_in_herolabs == nil then this_in_herolabs = false end&lt;br /&gt;
			&lt;br /&gt;
			if ((in_herolabs == &#039;true&#039; and this_hero_status == &#039;HeroLabs&#039;) or&lt;br /&gt;
				(in_herolabs == &#039;false&#039; and this_hero_status == &#039;Released&#039;)) then&lt;br /&gt;
				&lt;br /&gt;
				local is_recommended = hero_data[&#039;IsRecommended&#039;]&lt;br /&gt;
				if is_recommended == nil then&lt;br /&gt;
					is_recommended = false&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				local sub_page_str = &#039;&#039;&lt;br /&gt;
				&lt;br /&gt;
				&lt;br /&gt;
				local hero_str = &#039;|name=&#039; .. lang_module.get_string(hero_key, nil, &#039;en&#039;) .. &#039;|link=&#039; .. lang_module.get_string(hero_key, &#039;en&#039;) .. subpage .. &#039;|recommended=&#039; .. tostring(is_recommended)&lt;br /&gt;
				&lt;br /&gt;
				table.insert(heroes, hero_str)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	--Order list alphabetically&lt;br /&gt;
	table.sort(heroes) --O(nlogn)&lt;br /&gt;
	&lt;br /&gt;
	--Add each item to output&lt;br /&gt;
	local ret = &#039;&#039;&lt;br /&gt;
	for index, hero_name in ipairs(heroes) do&lt;br /&gt;
		ret = ret .. &#039;{{Hero card2&#039; .. hero_name&lt;br /&gt;
		ret = ret .. &#039;|text_size=&#039; .. text_size&lt;br /&gt;
		ret = ret .. &#039;|herolabs=&#039; .. in_herolabs&lt;br /&gt;
		ret = ret .. &#039;|card_size=&#039; .. card_size&lt;br /&gt;
		ret = ret .. &#039;|sticker_size=&#039; .. sticker_size&lt;br /&gt;
		ret = ret .. &#039;|herolabs_text_size=&#039; .. herolabs_text_size&lt;br /&gt;
		ret = ret .. &#039;}} &#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--Remove the last space&lt;br /&gt;
	ret = string.sub(ret, 1, -(string.len(&#039; &#039;))-1)&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	if debug_mode then&lt;br /&gt;
		return ret&lt;br /&gt;
	else -- evaluate wikitext if not in debug mode&lt;br /&gt;
		return frame:preprocess(ret)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Weapon_Damage?diff=20679</id>
		<title>Weapon Damage</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Weapon_Damage?diff=20679"/>
		<updated>2025-01-22T15:38:28Z</updated>

		<summary type="html">&lt;p&gt;Sur: /* Increased Bullet Damage */ typo; ammount&amp;gt;amount&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ev:youtube|xGTD-bBA57M|360|right|description=Video explaining Weapon Damage|frame}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weapon Damage&#039;&#039;&#039; is a stat that increases [[Bullet Damage]], Light [[Melee Damage]], and Heavy Melee Damage.&lt;br /&gt;
&lt;br /&gt;
== Weapon Damage Formula ==&lt;br /&gt;
The formula for calculating weapon damage is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Final Weapon Damage = (BaseBulletDmg*WeaponDmg%*DmgBonus%+FlatWeaponDmg)*DmgFalloff*(BulletResist% - BulletResistReduction%)*IncreasedBulletDmg%*CritMultiplier&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Base Bullet Damage ==&lt;br /&gt;
The Amount of damage your Hero will do while having no items. This is different for each hero and it increases based on your level. All heroes gain levels at the same soul milestones. &lt;br /&gt;
&lt;br /&gt;
The formula for Base Bullet Damage is: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;BaseBulletDamage = \sum_{k=1}^{15}(p_i)&amp;lt;/math&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
  p_i &amp;amp;= \text{The damage acquired through each power increase} \\&lt;br /&gt;
  15 &amp;amp;= \text{Number of total power increases} \\&lt;br /&gt;
  i &amp;amp;= \text{the index of the power increase}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
[[Grey Talon]] is an exception to the rule, additionally increasing his Base Bullet Damage based on his [[Spirit Power]] acquired through [[items]].&lt;br /&gt;
&lt;br /&gt;
== Weapon Damage ==&lt;br /&gt;
The percentage of damage acquired through items and golden statues&lt;br /&gt;
&lt;br /&gt;
The formula for weapon damage is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x_f = x_i * (1 + \sum_{i=1}^n \text{Shop Bonus} + \sum_{i=1}^n \text{Golden Statues})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--this is missing damage dropoff and bullet resist calc--&amp;gt;where:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
  x_f &amp;amp;= \text{final weapon damage,} \\&lt;br /&gt;
  x_i &amp;amp;= \text{initial weapon damage,} \\&lt;br /&gt;
  Shop Bonus &amp;amp;= \text{Increase based on the tier,} \\&lt;br /&gt;
  Golden Statues &amp;amp;= \text{Golden Statue value}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Golden Statue]]s can provide a permanent increase: +&amp;lt;b&amp;gt;3&amp;lt;/b&amp;gt;% before 10 minutes, +&amp;lt;b&amp;gt;4&amp;lt;/b&amp;gt;% before 30 minutes and +&amp;lt;b&amp;gt;7&amp;lt;/b&amp;gt;% after 30 minutes.&lt;br /&gt;
&lt;br /&gt;
All [[Weapon|weapon items]] provide Weapon Damage based on their Tier.&lt;br /&gt;
&lt;br /&gt;
Tier 1 items provide +6%, Tier 2 items provide +10%, Tier 3 items provide +14%, and Tier 4 items provide +18%. The following items grant increased weapon damage:{{Item stat table|Weapon Damage}}&lt;br /&gt;
&lt;br /&gt;
* {{ItemIcon|Headshot Booster}} deals +40 bonus Weapon Damage with headshots.&lt;br /&gt;
* {{ItemIcon|Monster Rounds}} increases Weapon Damage against NPCs by +35%.&lt;br /&gt;
* {{ItemIcon|Berserker}} increases Weapon Damage by +5% per [[stack]] for sustaining damage, where 100 receiving damage equals one stack, maxing at ten stacks.&lt;br /&gt;
* {{ItemIcon|Headhunter}} additionally deals +140 bonus Weapon Damage with headshots.&lt;br /&gt;
* {{ItemIcon|Intensifying Magazine}} additionally increases Weapon Damage to a maximum of 60% after continuously firing for three seconds.&lt;br /&gt;
* {{ItemIcon|Pristine Emblem}} additionally increases Weapon Damage by +25% against enemies above 50% health.&lt;br /&gt;
* {{ItemIcon|Alchemical Fire}} causes enemies to receive +50% Weapon Damage from the player&#039;s team.&lt;br /&gt;
* {{ItemIcon|Glass Cannon}} additionally increases Weapon Damage by +10% per stack for each hero kill, maxing at seven stacks&lt;br /&gt;
&lt;br /&gt;
== Flat Weapon Damage ==&lt;br /&gt;
An extra amount of damage obtained through the use of second abilities on particular [[heroes]].&lt;br /&gt;
&lt;br /&gt;
Flat Weapon Damage is not affected by Weapon Damage, it&#039;s an additive damage source and it&#039;s not multiplied with the total multiplication that comes from Base Bullet Damage, Weapon Damage and Damage Bonus, but added in top of it.&lt;br /&gt;
&lt;br /&gt;
However, it is later multiplied by Damage Falloff, Bullet Resist, Bullet Damage and Crit Multipliers&lt;br /&gt;
&lt;br /&gt;
Some sources of Flat Weapon Damage are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Hero&lt;br /&gt;
!Ability&lt;br /&gt;
!{{Ap|0}}&lt;br /&gt;
!{{Ap|1}}&lt;br /&gt;
!{{Ap|2}}&lt;br /&gt;
!{{Ap|5}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Abrams=true}}&lt;br /&gt;
|{{AbilityIcon|Shoulder Charge}}&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|{{Plink|+5.5|pic=Damage|size=18}} Weapon Damage for &#039;&#039;&#039;8s&#039;&#039;&#039; after colliding with an enemy&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Grey Talon=true}}&lt;br /&gt;
|{{AbilityIcon|Rain of Arrows}}&lt;br /&gt;
|{{Plink|+4|pic=Damage|size=18}}Weapon Damage&lt;br /&gt;
|&lt;br /&gt;
|While airborne, {{Plink|+5|pic=Damage|size=18}} Weapon Damage and weapon damage applies &#039;&#039;&#039;40%&#039;&#039;&#039; movement slow for 1.5s&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Lash=true}}&lt;br /&gt;
|{{AbilityIcon|Grapple}}&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;+20m&#039;&#039;&#039; Cast Range and gain {{Plink|+6|pic=Damage|size=18}} Weapon Damage for 10s (Able to stack)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Pocket=true}}&lt;br /&gt;
|{{AbilityIcon|Flying Cloak}}&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;{{Plink|+7|pic=Damage|size=18}} Weapon Damage&#039;&#039;&#039; for 10s after teleporting with Flying Cloak.&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Yamato=true}}&lt;br /&gt;
|{{AbilityIcon|Flying Strike}}&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Can Grapple to ally &#039;&#039;&#039;Heroes&#039;&#039;&#039; and &#039;&#039;&#039;{{Plink|+6|pic=Damage|size=18}}&#039;&#039;&#039; Weapon Damage for &#039;&#039;&#039;10s&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Damage Falloff ==&lt;br /&gt;
The amount of weapon damage reduction a hero experiences in relation to their distance from a target entity. The greater the distance between the attacker and their target, the less weapon damage they are able to do.&lt;br /&gt;
&lt;br /&gt;
All heroes have a Falloff Range, comprised of two distances that mark the start and end, in which their weapon damage is linearly reduced.&lt;br /&gt;
&lt;br /&gt;
Damage Falloff makes Weapon Damage drop from 100% (&amp;lt;math&amp;gt;Distance &amp;lt; FalloffRangeStart&amp;lt;/math&amp;gt;) to 10% (&amp;lt;math&amp;gt;Distance &amp;gt; FalloffRangeEnd&amp;lt;/math&amp;gt;) for all heroes, the only difference between heroes being their respective Weapon Falloff Ranges.&lt;br /&gt;
&lt;br /&gt;
When aiming at an enemy hero, the percentage of inflicted Weapon Damage can be approximated by the player through a dot located at the left side of the enemies health bar that gradually turns from yellow to red.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;Dot colors and their approximate Weapon Damage percentage ranges.&amp;lt;ref name=&amp;quot;Weapon Damage Explained by Yapistism&amp;quot;&amp;gt;[https://youtu.be/xGTD-bBA57M &amp;quot;Weapon Damage Explained&amp;quot; by Yapistism] 7:21&amp;lt;/ref&amp;gt;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Dot Color !! Damage Percentage&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color:#fe6160&amp;quot;&amp;gt;&#039;&#039;&#039;Red&#039;&#039;&#039;&amp;lt;/span&amp;gt;||10% - 20%&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color:#feab44&amp;quot;&amp;gt;&#039;&#039;&#039;Orange&#039;&#039;&#039;&amp;lt;/span&amp;gt;||20% - 35%&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color:#f9f926&amp;quot;&amp;gt;&#039;&#039;&#039;Yellow&#039;&#039;&#039;&amp;lt;/span&amp;gt;||35% - 75%&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color:#6f6f6f&amp;quot;&amp;gt;&#039;&#039;&#039;Transparent&#039;&#039;&#039;&amp;lt;/span&amp;gt;||75% - 100%&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Falloff Range can be increased by buying [[Sharpshooter]], a Tier 3 [[Weapon Item]].&lt;br /&gt;
&lt;br /&gt;
Bebop is able to increase his Falloff Range by upgrading his first skill:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+&lt;br /&gt;
!Hero&lt;br /&gt;
!Ability&lt;br /&gt;
!{{Ap|0}}&lt;br /&gt;
!{{Ap|1}}&lt;br /&gt;
!{{Ap|2}}&lt;br /&gt;
!{{Ap|5}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Bebop=true}}&lt;br /&gt;
|{{AbilityIcon|Exploding Uppercut}}&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|On Uppercut enemy Hero, gain &#039;&#039;&#039;fast spin-up time, 2x range, and +60% weapon damage&#039;&#039;&#039; for 12s&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
However, Exploding Uppercut bonus Falloff Range can&#039;t be stacked with [[Sharpshooter]].&lt;br /&gt;
&lt;br /&gt;
Damage Falloff affects all types of damage listed so far, these being:&lt;br /&gt;
&lt;br /&gt;
* {{Plink|Base Bullet Damage|pic=Bullet damage|size=18}}&lt;br /&gt;
* Weapon Damage&lt;br /&gt;
* Damage Bonus&lt;br /&gt;
* {{Plink|Flat Weapon Damage|pic=Damage|size=18}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Damage Falloff does not affect the Weapon Damage done by {{HeroIcon|Holliday}}s third ability {{AbilityIcon|Crackshot}}.&lt;br /&gt;
== Bullet Resist - Bullet Resist Reduction ==&lt;br /&gt;
&lt;br /&gt;
=== Bullet Resist ===&lt;br /&gt;
Bullet Resist is a reduction of the damage taken by a hero. The formula for Damage Resist is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;BulletResist = 1 - \prod_{i=1}^n (1-p_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
  p_i &amp;amp;= \text{each instance of Bullet Resist} \\&lt;br /&gt;
  1 &amp;amp;= \text{Damage recieved from a gun} \\&lt;br /&gt;
  n &amp;amp;= \text{Number of total Bullet Resist sources} \\&lt;br /&gt;
  i &amp;amp;= \text{the index of the item that is giving Bullet Resist}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Explanation of the formula: =====&lt;br /&gt;
Each instance of Bullet Resist is deducted from 100% of the damage received from a gun. This calculation is then repeated for each instance of Bullet Resist the hero has on. Once all these deductions have been calculated, the results are multiplied. The result of this multiplication is then deducted from 100% of the damage given initially. The result of this process is the Bullet Resist.&lt;br /&gt;
&lt;br /&gt;
=== Bullet Resist Reduction ===&lt;br /&gt;
Bullet Resist Reduction is a reduction inflicted upon an enemy. The formula for Damage Resist Reduction is similar to the Bullet Resist one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;BulletResistReduction = 1 - \prod_{i=1}^n (1-p_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
  p_i &amp;amp;= \text{each instance of Bullet Resist Reduction} \\&lt;br /&gt;
  1 &amp;amp;= \text{Damage recieved from a gun} \\&lt;br /&gt;
  n &amp;amp;= \text{Number of total Bullet Resist Reduction sources} \\&lt;br /&gt;
  i &amp;amp;= \text{the index of the item that is giving Bullet Resist Reduction}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Explanation of the formula: =====&lt;br /&gt;
Each instance of Bullet Resist reduction is deducted from 100% of the damage received from a gun. This calculation is then repeated for each instance of Bullet Resist Reduction the hero has on. Once all these deductions have been calculated, the results are multiplied. The result of this multiplication is then deducted from 100% of the damage given initially. The result of this process is the Bullet Resist Reduction.&lt;br /&gt;
&lt;br /&gt;
=== Result ===&lt;br /&gt;
To calculate the final Bullet Resist you have to calculate the difference between Bullet Resist and Bullet Resist Reduction&lt;br /&gt;
&lt;br /&gt;
== Increased Bullet Damage ==&lt;br /&gt;
A personal [[debuff]] you inflict on enemies. It multiplies the amount of damage they take from you but not your allies.&lt;br /&gt;
&lt;br /&gt;
Increased Bullet damage is not the same thing as Weapon Damage. as Increased Bullet Damage takes into account your {{Plink|Flat Weapon Damage|pic=Damage|size=18}}.&lt;br /&gt;
&lt;br /&gt;
There are only four known instances of Increased Bullet Damage, all coming from heroe&#039;s abilities:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Hero&lt;br /&gt;
!Ability&lt;br /&gt;
!{{Ap|0}}&lt;br /&gt;
!{{Ap|1}}&lt;br /&gt;
!{{Ap|2}}&lt;br /&gt;
!{{Ap|5}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Bebop=true}}&lt;br /&gt;
|{{AbilityIcon|Hook}}&lt;br /&gt;
|&lt;br /&gt;
|Bebop deals &#039;&#039;&#039;30% more weapon damage&#039;&#039;&#039; against hooked enemies for 10s&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Dynamo=true}}&lt;br /&gt;
|{{AbilityIcon|Kinetic Pulse}}&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Dynamo deals &#039;&#039;&#039;30% more Weapon Damage&#039;&#039;&#039; to hit enemies for &#039;&#039;&#039;8s&#039;&#039;&#039;&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Grey Talon=true}}&lt;br /&gt;
|{{AbilityIcon|Spirit Snare}}&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Grey Talon deals &#039;&#039;&#039;+30%&#039;&#039;&#039; more Bullet Damage to enemies hit by Spirit Snare for &#039;&#039;&#039;10s&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Warden=true}}&lt;br /&gt;
|{{AbilityIcon|Binding Word}}&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|Warden deals &#039;&#039;&#039;+20% more Bullet Damage&#039;&#039;&#039; to trapped Heroes for &#039;&#039;&#039;6s&#039;&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Crit Multiplier ==&lt;br /&gt;
&lt;br /&gt;
=== Formula ===&lt;br /&gt;
&amp;lt;math&amp;gt;CritMultiplier = Headshot*CritBonusScale*CritResist&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Headshots ===&lt;br /&gt;
Aiming for the head will deal increased damage. [[Troopers]], [[Guardians]], and [[Heroes]] have a weakpoint hitbox that receives approximately double base bullet damage when hit by a weapon.&lt;br /&gt;
&lt;br /&gt;
Several items have effects that proc on headshots, such as {{ItemIcon|Headshot Booster}}, {{ItemIcon|Headhunter}}, and {{ItemIcon|Crippling Headshot}}.&lt;br /&gt;
&lt;br /&gt;
=== Crit Bonus Scale ===&lt;br /&gt;
&lt;br /&gt;
=== Crit Resist ===&lt;br /&gt;
{{HeroIcon|Seven}} receives reduced incoming headshot damage, as do {{HeroIcon|Mo &amp;amp; Krill}}, who have a separate hitbox for each of Mo and Krill&#039;s heads.&lt;br /&gt;
&lt;br /&gt;
== Spreadshots ==&lt;br /&gt;
Spreadshots are a property of certain weapons that allow them to shoot multiple bullets at once, such as shotguns and shurikens.&lt;br /&gt;
&lt;br /&gt;
In these particular cases, all the previous instances of damage apply to every single bullet.&lt;br /&gt;
&lt;br /&gt;
There are currently 6 weapons capable of doing Spreadshots in game&lt;br /&gt;
{|&lt;br /&gt;
!Hero&lt;br /&gt;
!Weapon&lt;br /&gt;
!Bullets per shot&lt;br /&gt;
!Pattern&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Abrams=true}}&lt;br /&gt;
|{{WeaponCard|key=hero_atlas}}&lt;br /&gt;
|9&lt;br /&gt;
|Semi-Fixed&lt;br /&gt;
|-&lt;br /&gt;
|Calico&lt;br /&gt;
|{{WeaponCard|key=hero_nano|ph=true}}&lt;br /&gt;
|8&lt;br /&gt;
|Fixed&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Mo &amp;amp; Krill=true}}&lt;br /&gt;
|{{WeaponCard|key=hero_krill}}&lt;br /&gt;
|4&lt;br /&gt;
|Semi-Fixed&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Shiv=true}}&lt;br /&gt;
|{{WeaponCard|key=hero_shiv}}&lt;br /&gt;
|6 (Fire)&lt;br /&gt;
12 (Alt-Fire)&lt;br /&gt;
|Random&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Yamato=true}}&lt;br /&gt;
|{{WeaponCard|key=hero_yamato}}&lt;br /&gt;
|5&lt;br /&gt;
|Semi-Fixed&lt;br /&gt;
|-&lt;br /&gt;
|{{Hero Icon List|Pocket=true}}&lt;br /&gt;
|{{WeaponCard|key=hero_synth}}&lt;br /&gt;
|7&lt;br /&gt;
|Fixed&lt;br /&gt;
|}&lt;br /&gt;
{{Stat navbox}}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:HeroIcon/doc?diff=20651</id>
		<title>Template:HeroIcon/doc</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:HeroIcon/doc?diff=20651"/>
		<updated>2025-01-22T00:56:34Z</updated>

		<summary type="html">&lt;p&gt;Sur: example for subpage parameter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Usage ==&lt;br /&gt;
This icon link template is used to add a small headshot of the hero with a link. &lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:50%&amp;quot;&amp;gt;&lt;br /&gt;
{{HeroIcon|Lash}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{HeroIcon|Lash}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:50%&amp;quot;&amp;gt;&lt;br /&gt;
{{HeroIcon|Lash|Jacob}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{HeroIcon|Lash|Jacob}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;width:50%&amp;quot;&amp;gt;&lt;br /&gt;
{{HeroIcon|Abrams|Абрамс|subpage=/ru}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{HeroIcon|Abrams|Абрамс|subpage=/ru}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;templatedata&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;params&amp;quot;: {&lt;br /&gt;
		&amp;quot;2&amp;quot;: {&lt;br /&gt;
			&amp;quot;description&amp;quot;: &amp;quot;Set the alternative text to display.&amp;quot;,&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;icon&amp;quot;: {&lt;br /&gt;
			&amp;quot;aliases&amp;quot;: [&lt;br /&gt;
				&amp;quot;1&amp;quot;&lt;br /&gt;
			],&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
			&amp;quot;description&amp;quot;: &amp;quot;Set the image file name.&amp;quot;,&lt;br /&gt;
			&amp;quot;required&amp;quot;: true&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;size&amp;quot;: {&lt;br /&gt;
			&amp;quot;type&amp;quot;: &amp;quot;number&amp;quot;,&lt;br /&gt;
			&amp;quot;description&amp;quot;: &amp;quot;Set the size of the icon in px.&amp;quot;,&lt;br /&gt;
			&amp;quot;example&amp;quot;: &amp;quot;20, 24, 32&amp;quot;,&lt;br /&gt;
			&amp;quot;default&amp;quot;: &amp;quot;25&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;format&amp;quot;: &amp;quot;inline&amp;quot;,&lt;br /&gt;
	&amp;quot;paramOrder&amp;quot;: [&lt;br /&gt;
		&amp;quot;icon&amp;quot;,&lt;br /&gt;
		&amp;quot;2&amp;quot;,&lt;br /&gt;
		&amp;quot;size&amp;quot;&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/templatedata&amp;gt;&amp;lt;noinclude&amp;gt;[[Category:Template documentation]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:HeroIcon?diff=20650</id>
		<title>Template:HeroIcon</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:HeroIcon?diff=20650"/>
		<updated>2025-01-22T00:53:55Z</updated>

		<summary type="html">&lt;p&gt;Sur: subpage parameter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;lt;span style=&amp;quot;position: relative; bottom: 2px;&amp;quot;&amp;gt;[[File:{{{icon|{{{1|}}}}}} MM.png|alt=|link={{{3|{{{1|}}}}}}{{{subpage|}}}|{{{size|25px}}}]]&amp;lt;/span&amp;gt; [[{{{3|{{{1|}}}}}}{{{subpage|}}}|{{{2|{{{1|}}}}}}]]&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&lt;br /&gt;
[[Category:Icon templates]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Hero_Navbox/doc?diff=20231</id>
		<title>Template:Hero Navbox/doc</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Hero_Navbox/doc?diff=20231"/>
		<updated>2025-01-17T21:20:16Z</updated>

		<summary type="html">&lt;p&gt;Sur: example updated to use 16px instead of 20px which is what home page currently uses&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Usage ==&lt;br /&gt;
This navbox template displays [[Heroes]], and should be added at the end of the page.&lt;br /&gt;
&lt;br /&gt;
It appears at the bottom of individual hero pages like [[Abrams]] and on the home page.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
Default parameters for a smaller navbox:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{Hero Navbox}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Hero Navbox}}&lt;br /&gt;
&lt;br /&gt;
Specific parameters for a bigger navbox:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{{Hero Navbox|text_size=16|card_size=132|sticker_size=56|herolabs_text_size=8}}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Hero Navbox|text_size=16|card_size=132|sticker_size=56|herolabs_text_size=8}}&lt;br /&gt;
&amp;lt;templatedata&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;params&amp;quot;: {&lt;br /&gt;
		&amp;quot;text_size&amp;quot;: {},&lt;br /&gt;
		&amp;quot;card_size&amp;quot;: {},&lt;br /&gt;
		&amp;quot;sticker_size&amp;quot;: {},&lt;br /&gt;
		&amp;quot;herolabs_text_size&amp;quot;: {}&lt;br /&gt;
	},&lt;br /&gt;
	&amp;quot;description&amp;quot;: &amp;quot; &amp;quot;,&lt;br /&gt;
	&amp;quot;format&amp;quot;: &amp;quot;block&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/templatedata&amp;gt;&lt;br /&gt;
&amp;lt;includeonly&amp;gt;[[Category:Navigation templates]]&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;[[Category:Template documentation]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Hero_Navbox?diff=20229</id>
		<title>Template:Hero Navbox</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Hero_Navbox?diff=20229"/>
		<updated>2025-01-17T21:19:08Z</updated>

		<summary type="html">&lt;p&gt;Sur: default text size 11px to 10px&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
|style=&amp;quot;display:block;border-radius: 8px;text-align: center; background-image: linear-gradient(#c1a671, #d0bb95); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero|&amp;lt;span style=&amp;quot;color:#FFF5E8; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3);&amp;quot;&amp;gt;Heroes&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=false&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|style=&amp;quot;display:inline;border: 2px solid transparent;margin-top:10px;margin-bottom:10px;background-color:transparent;margin: auto;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;border-radius: 8px;text-align: center; background-image: linear-gradient(#ce9b54, #674915); font-family: &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-size:22px;&amp;quot;| [[Hero Labs|&amp;lt;span style=&amp;quot;color:#FFF0D6; font-family: &#039;Retail Demo&#039;, &#039;PT Serif&#039;,&#039;Palatino&#039;,&#039;Georgia&#039;,serif; font-weight:bold; text-shadow: 1px 1px rgba(0, 0, 0, 0.3); display: flex; justify-content: center; align-items: center;&amp;quot;&amp;gt;Hero Labs&amp;lt;/span&amp;gt;]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; gap: 3px; align-items: center; justify-content: center; margin: 0 auto;&amp;quot;&amp;gt;&lt;br /&gt;
{{#invoke:HeroData/nav|get_hero_nav_cards&lt;br /&gt;
|in_herolabs=true&lt;br /&gt;
|text_size={{{text_size|10}}}&lt;br /&gt;
|card_size={{{card_size|88}}}&lt;br /&gt;
|sticker_size={{{sticker_size|30}}}&lt;br /&gt;
|herolabs_text_size={{{herolabs_text_size|6}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:Deadlock_Wiki/Heroes?diff=20225</id>
		<title>Template:Deadlock Wiki/Heroes</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:Deadlock_Wiki/Heroes?diff=20225"/>
		<updated>2025-01-17T21:16:51Z</updated>

		<summary type="html">&lt;p&gt;Sur: text size 20px to 16px&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Hero Navbox|text_size=16|card_size=132|sticker_size=56|herolabs_text_size=8}}&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:ItemData/nav?diff=20216</id>
		<title>Module:ItemData/nav</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:ItemData/nav?diff=20216"/>
		<updated>2025-01-17T21:12:33Z</updated>

		<summary type="html">&lt;p&gt;Sur: checks for IsDisabled instead of Disabled as it was renamed on GH&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local items_data = mw.loadJsonData(&amp;quot;Data:ItemData.json&amp;quot;)&lt;br /&gt;
local lang_module = require(&#039;Module:Lang&#039;)&lt;br /&gt;
local generic_module = require(&#039;Module:GenericData&#039;)&lt;br /&gt;
local util_module = require(&#039;Module:Utilities&#039;)&lt;br /&gt;
&lt;br /&gt;
--With debug_mode on, it outputs unprocessed wikitext&lt;br /&gt;
--With debug_mode off/unspecified, it processes the wikitext&lt;br /&gt;
local function process_debug_mode(wikitext, debug_mode)&lt;br /&gt;
	if debug_mode == &#039;true&#039; then&lt;br /&gt;
		return wikitext&lt;br /&gt;
	elseif debug_mode == &#039;false&#039; or debug_mode == nil then&lt;br /&gt;
		return mw.getCurrentFrame():preprocess(wikitext)&lt;br /&gt;
	else&lt;br /&gt;
		return &amp;quot;debug_mode must be &#039;true&#039; or &#039;false&#039;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--Writes list of items of a certain slot within the min and max soul bounds&lt;br /&gt;
-- Each item is wrapped and separated. For example of wrapping/separator, see&lt;br /&gt;
-- get_item_nav_bulletpoints. &#039;sep&#039; should not be combined with &#039;right_wrap&#039;, &lt;br /&gt;
-- as the trailing separator should also be removed from the string&lt;br /&gt;
local function write_wrapped_item_list(slot, min_souls, max_souls, left_wrap, right_wrap, sep)&lt;br /&gt;
	if slot ~= &#039;Weapon&#039; and slot ~= &#039;Armor&#039; and slot ~= &#039;Tech&#039; then&lt;br /&gt;
		return &#039;slot must be Weapon, Armor (Vitality), or Tech (Spirit)&#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local min_souls = tonumber(min_souls)&lt;br /&gt;
	local max_souls = tonumber(max_souls)&lt;br /&gt;
	if min_souls == nil or max_souls == nil then return &#039;Min/Max souls must be numerical&#039; end&lt;br /&gt;
	&lt;br /&gt;
	--Retrieve all items that fit the bounds&lt;br /&gt;
	local items = {}&lt;br /&gt;
	for item_key, item_data in pairs(items_data) do&lt;br /&gt;
		--future proofing; Disabled will be renamed to IsDisabled soon&lt;br /&gt;
		local this_cost = tonumber(item_data[&amp;quot;Cost&amp;quot;])&lt;br /&gt;
		local this_slot = item_data[&amp;quot;Slot&amp;quot;]&lt;br /&gt;
		if item_data[&amp;quot;Name&amp;quot;] ~= nil and item_data[&amp;quot;IsDisabled&amp;quot;] == false and this_cost ~= nil and this_slot ~= nil then&lt;br /&gt;
			if slot == this_slot and this_cost&amp;gt;=min_souls and this_cost&amp;lt;max_souls then&lt;br /&gt;
				table.insert(items, lang_module.get_string(item_key))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--Order list alphabetically&lt;br /&gt;
	table.sort(items) --O(nlogn)&lt;br /&gt;
	&lt;br /&gt;
	--Add each item to output&lt;br /&gt;
	-- Each item is surrounded by left and right wrap, and separated by sep&lt;br /&gt;
	local ret = &#039;&#039;&lt;br /&gt;
	for index, item_name in ipairs(items) do&lt;br /&gt;
		ret = ret .. left_wrap .. item_name .. right_wrap .. sep&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--Remove the last separator thats trailing after the last item&lt;br /&gt;
	ret = string.sub(ret, 1, -(string.len(sep))-1)&lt;br /&gt;
	&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- for [[Template:Item Navbox]]&lt;br /&gt;
function p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode)&lt;br /&gt;
	-- If called internally (direct Lua call), args will be passed directly.&lt;br /&gt;
    -- If called from wikitext, `slot` will be the `frame` object, and we get args from `frame.args`.&lt;br /&gt;
&lt;br /&gt;
    -- Handle the case where it&#039;s called via #invoke (i.e., from wikitext)&lt;br /&gt;
    if type(slot) == &amp;quot;table&amp;quot; and slot.args then&lt;br /&gt;
        local frame = slot&lt;br /&gt;
        slot = frame.args[1]&lt;br /&gt;
        min_souls = frame.args[2]&lt;br /&gt;
        max_souls = frame.args[3]&lt;br /&gt;
        debug_mode = frame.args[&amp;quot;debug_mode&amp;quot;]&lt;br /&gt;
    end&lt;br /&gt;
	&lt;br /&gt;
	local left_wrap = &#039;{{ItemIcon|&#039;&lt;br /&gt;
	local right_wrap = &#039;}}&#039;&lt;br /&gt;
	local sep = &#039; &amp;amp;bull; &#039;&lt;br /&gt;
	&lt;br /&gt;
	local item_list = write_wrapped_item_list(slot, min_souls, max_souls, left_wrap, right_wrap, sep)&lt;br /&gt;
	&lt;br /&gt;
	return process_debug_mode(item_list, debug_mode)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- for [[Template:Infobox ShopItems]]&lt;br /&gt;
function p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode)&lt;br /&gt;
	-- If called internally (direct Lua call), args will be passed directly.&lt;br /&gt;
    -- If called from wikitext, `slot` will be the `frame` object, and we get args from `frame.args`.&lt;br /&gt;
&lt;br /&gt;
    -- Handle the case where it&#039;s called via #invoke (i.e., from wikitext)&lt;br /&gt;
    if type(slot) == &amp;quot;table&amp;quot; and slot.args then&lt;br /&gt;
        local frame = slot&lt;br /&gt;
        slot = frame.args[1]&lt;br /&gt;
        min_souls = frame.args[2]&lt;br /&gt;
        max_souls = frame.args[3]&lt;br /&gt;
        debug_mode = frame.args[&amp;quot;debug_mode&amp;quot;]&lt;br /&gt;
    end&lt;br /&gt;
	&lt;br /&gt;
	local left_wrap = &#039;{{ItemBox|item_name=&#039;&lt;br /&gt;
	local right_wrap = &#039;}}&#039;&lt;br /&gt;
	local sep = &#039; &#039;&lt;br /&gt;
	&lt;br /&gt;
	local item_list = write_wrapped_item_list(slot, min_souls, max_souls, left_wrap, right_wrap, sep)&lt;br /&gt;
	&lt;br /&gt;
	return process_debug_mode(item_list, debug_mode)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.write_item_slot_subgroup(frame)&lt;br /&gt;
	local slot = frame.args[1]&lt;br /&gt;
	local type = frame.args[2]&lt;br /&gt;
	local debug_mode = frame.args[&#039;debug_mode&#039;]&lt;br /&gt;
	if slot == nil then return &amp;quot;&#039;slot&#039; parameter is required&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	-- Define base args&lt;br /&gt;
	local template_title = &amp;quot;Navbox subgroup&amp;quot;&lt;br /&gt;
	local template_args = {&lt;br /&gt;
		[&amp;quot;groupstyle&amp;quot;] = &amp;quot;background-color:&amp;quot; .. util_module.get_slot_color(slot) .. &amp;quot;;width:10%;min-width:70px;border-radius: 8px 0 0 8px&amp;quot;,&lt;br /&gt;
		[&amp;quot;grouppadding&amp;quot;] = &amp;quot;5px&amp;quot;,&lt;br /&gt;
		[&amp;quot;listpadding&amp;quot;] = &amp;quot;0 0.25rem&amp;quot;,&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	local soul_style = &amp;quot;font-size: 12px; text-shadow: 1px 1px rgba(0, 0, 0, 0.3);&amp;quot;&lt;br /&gt;
	local prices = generic_module.get_item_price_per_tier()&lt;br /&gt;
	for i, souls in ipairs(prices) do&lt;br /&gt;
		--Determine lower bound for soul&lt;br /&gt;
		min_souls = souls&lt;br /&gt;
		&lt;br /&gt;
		--Skip 0 to i1 as no items cost less than 500&lt;br /&gt;
		if min_souls ~= 0 then &lt;br /&gt;
			&lt;br /&gt;
			-- Determine upper bound&lt;br /&gt;
			max_souls = prices[i+1]&lt;br /&gt;
			if max_souls == nil then &lt;br /&gt;
				max_souls = min_souls * 10 --essentially have no upper bound&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			--Create the subgroup&lt;br /&gt;
			template_args[&amp;quot;group&amp;quot; .. (i-1)] = frame:expandTemplate{title=&amp;quot;Souls&amp;quot;, args={[1] = min_souls, [&amp;quot;Shadow&amp;quot;] = soul_style}}&lt;br /&gt;
			local list&lt;br /&gt;
			if type==&#039;get_item_nav_cards&#039; then&lt;br /&gt;
				list = p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode)&lt;br /&gt;
			elseif type==&#039;get_item_nav_bulletpoints&#039; then&lt;br /&gt;
				list = p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode)&lt;br /&gt;
			else&lt;br /&gt;
				return &amp;quot;&#039;type&#039; should be get_item_nav_cards or get_item_nav_bulletpoints&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
			template_args[&amp;quot;list&amp;quot; .. (i-1)] =  list&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return frame:expandTemplate{title=template_title, args=template_args}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/THE_MAGNIFICENT_SINCLAIR?diff=20208</id>
		<title>THE MAGNIFICENT SINCLAIR</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/THE_MAGNIFICENT_SINCLAIR?diff=20208"/>
		<updated>2025-01-17T21:06:34Z</updated>

		<summary type="html">&lt;p&gt;Sur: magician changed to THE MAGNIFICENT SINCLAIR in ability template calls&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Infobox hero&lt;br /&gt;
| key = hero_magician&lt;br /&gt;
| weapon_name = The Prestige&lt;br /&gt;
| card = Magician card.png&lt;br /&gt;
| no_bullet_resist = true&lt;br /&gt;
| release_date = January 17, 2025&lt;br /&gt;
| no_spirit_resist = false&lt;br /&gt;
| no_sprint = true&lt;br /&gt;
| no_voice_actor = true&lt;br /&gt;
| max_health = {{#invoke:HeroData|get_hero_var|{{#var:hero_key_or_en}}|MaxHealth|3}}{{PI|31}}&lt;br /&gt;
| bullet_damage = {{#invoke:HeroData|get_hero_var|{{#var:hero_key_or_en}}|BulletDamage|3}}{{PI|0.60}}&lt;br /&gt;
| light_melee = {{#invoke:HeroData|get_hero_var|{{#var:hero_key_or_en}}|LightMeleeDamage|3}}{{PI|2.7}}&lt;br /&gt;
| heavy_melee = {{#invoke:HeroData|get_hero_var|{{#var:hero_key_or_en}}|HeavyMeleeDamage|3}}&lt;br /&gt;
| spirit_resist = 0{{PI|?}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;THE MAGNIFICENT SINCLAIR&#039;&#039;&#039; is a hero in &#039;&#039;[[DeadLock]]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
THE MAGNIFICENT SINCLAIR was added to Hero Labs on [[Update:October 24, 2024|October 24, 2024]], and officially released in [[Update:January 17, 2025|January 17, 2025]].&lt;br /&gt;
&lt;br /&gt;
== Abilities ==&lt;br /&gt;
&amp;lt;tabber&amp;gt;&lt;br /&gt;
|-|(1) Vexing Bolt=&lt;br /&gt;
{{Ability card v2&lt;br /&gt;
| hero_name=THE MAGNIFICENT SINCLAIR&lt;br /&gt;
| ability_num=1&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
|-|(2) Spectral Assistant=&lt;br /&gt;
{{Ability card v2&lt;br /&gt;
| hero_name=THE MAGNIFICENT SINCLAIR&lt;br /&gt;
| ability_num=2&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
|-|(3) Rabbit Hex=&lt;br /&gt;
{{Ability card v2&lt;br /&gt;
| hero_name=THE MAGNIFICENT SINCLAIR&lt;br /&gt;
| ability_num=3&lt;br /&gt;
| notes=&lt;br /&gt;
* This ability also prevents the usage of movement abilities on hit for 6s.&lt;br /&gt;
}}&lt;br /&gt;
|-|(4) Grand Finale!=&lt;br /&gt;
{{Ability card v2&lt;br /&gt;
| hero_name=THE MAGNIFICENT SINCLAIR&lt;br /&gt;
| ability_num=4&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/tabber&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weapon ==&lt;br /&gt;
{{WeaponCard|Magician|ph=true}}&lt;br /&gt;
&lt;br /&gt;
== Update History ==&lt;br /&gt;
{{Main|Magician/Update history|l1=Update history}}&lt;br /&gt;
{{Update history}}&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
{{Quotation|&#039;&#039;&#039;A FATE&#039;S TALE&#039;&#039;&#039;|Henry&#039;s parents told him he was too young and impulsive to mess with real magic, and so they gave him a deck of cards to play with. He took to sleight of hand naturally and soon was dazzling his classmates with fantastic feats of illusions that were done without mystic artifacts or incantation.&lt;br /&gt;
&lt;br /&gt;
When he was in high school he met Savannah, and their mutual love of stage magic sparked a whirlwind romance. Soon they fell in love and created an act together. Obviously they were meant to be, and so at prom, Henry proposed to Savannah and they married soon after graduation.&lt;br /&gt;
&lt;br /&gt;
Unsurprisingly both sets of parents were not thrilled at this prospect, but Henry and Savannah knew they were soulmates. And so they cemented their love for one another by having a blood mystic bind their souls for eternity.&lt;br /&gt;
&lt;br /&gt;
When an on-stage accident claimed both their lives, no one was sure who to blame. Henry claims Savannah was out of position. Savannah says Henry didn&#039;t wait for his queue. But one things for sure, since their souls are tied to each other neither one of them have been able to move on. Now a bickering pair of ghosts, Henry and Savannah need to work together if they want to have any chance of undoing their eternal union.}}&lt;br /&gt;
&lt;br /&gt;
=== Lore ===&lt;br /&gt;
The Magnificent Sinclair has two different voices, as Henry and Savannah. The character is initially controlled by Henry, then changes to Savannah once Henry dies in-game, and changes back to Henry when Savannah dies. The character who isn&#039;t controlling the Magician plays the Spectral Assistant.&lt;br /&gt;
&lt;br /&gt;
The Magnificent Sinclair&#039;s stage names are &#039;&#039;Henry the Magnificent&#039;&#039; and &#039;&#039;The Spectacular Savannah.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Gallery ==&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Magician card.png|Portrait&lt;br /&gt;
File:The Magnificent Sinclair.png|Minimap icon&lt;br /&gt;
File:Magician Render.png|In-game render&lt;br /&gt;
File:Magician Reference Sheet.png|Model sheet&lt;br /&gt;
File:Magician Weapon.png|Weapon - The Prestige&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Trivia ==&lt;br /&gt;
&lt;br /&gt;
* The Magnificent Sinclair was originally named &#039;&#039;&#039;Magician&#039;&#039;&#039;.&lt;br /&gt;
* His weapon&#039;s name is a reference to Christopher Nolan&#039;s movie [[wikipedia:The_Prestige_(film)|&#039;&#039;The Prestige&#039;&#039;]], whose plot also involved a magician&#039;s assistant killed by a stage accident.&lt;br /&gt;
* The Magnificent Sinclair&#039;s weapon was originally called &#039;&#039;&#039;[[wikipedia:Sleight_of_hand|Legerdemain]]&#039;&#039;&#039;.&lt;br /&gt;
* The Magnificent Sinclair&#039;s current design is based on one of the scrapped designs for [[Wraith]]. It is also used in a [[Metal Skin]] advert.&lt;br /&gt;
* The Magnificent Sinclair&#039;s gun model and animations are reused from [[Seven]].&lt;br /&gt;
* The Magnificent Sinclair&#039;s lead developer is [[Hopoo]],&amp;lt;ref&amp;gt;2024-10-28 - Hopoo; Deadlock Discord - &amp;quot;&#039;&#039;yes I was lead on viper (and magician), it’s why neither was in the hero list previously&amp;quot;&#039;&#039;&amp;lt;/ref&amp;gt; best known as the co-creator of the &#039;&#039;[[wikipedia:Risk_of_Rain_2|Risk of Rain]]&#039;&#039; series.&lt;br /&gt;
* Both Henry and Savannah believe they are &amp;quot;the responsible one.&amp;quot;&amp;lt;ref&amp;gt;{{VoiceLineCite|name=Magician|file=Magician henry respawn 07.mp3|context=(as Henry)|transcription=It&#039;s ok, I&#039;m the responsible one.}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{VoiceLineCite|name=Magician|file=Magician savannah respawn 07.mp3|context=(as Savannah)|transcription=It&#039;s ok, I&#039;m the responsible one.}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
* There are two references in the [https://steamcommunity.com/games/1422450/announcements/detail/786541361952194833 update blog] where his name is instead written as &#039;&#039;&#039;The Magnificent Sinclair&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[The Magnificent Sinclair/Quotes]]&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
{{Hero Navbox}}&lt;br /&gt;
[[Category:Heroes]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Magician?diff=20205</id>
		<title>Magician</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Magician?diff=20205"/>
		<updated>2025-01-17T21:05:58Z</updated>

		<summary type="html">&lt;p&gt;Sur: double redirection&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[THE MAGNIFICENT SINCLAIR]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:HeroData?diff=18432</id>
		<title>Module:HeroData</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:HeroData?diff=18432"/>
		<updated>2025-01-01T04:01:33Z</updated>

		<summary type="html">&lt;p&gt;Sur: fix outdated use of PageRef for write_default_items()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {};&lt;br /&gt;
local heroes_data = mw.loadJsonData(&amp;quot;Data:HeroData.json&amp;quot;)&lt;br /&gt;
local attributes_data = mw.loadJsonData(&amp;quot;Data:AttributeData.json&amp;quot;)&lt;br /&gt;
local attribute_orders = mw.loadJsonData(&amp;quot;Data:StatInfoboxOrder.json&amp;quot;)&lt;br /&gt;
local util_module = require(&#039;Module:Utilities&#039;)&lt;br /&gt;
local lang_module = require(&#039;Module:Lang&#039;)&lt;br /&gt;
local dictionary_module = require(&#039;Module:Dictionary&#039;)&lt;br /&gt;
local attribute_module = require(&#039;Module:AttributeData&#039;)&lt;br /&gt;
&lt;br /&gt;
-- returns the table of a specific item, used by external modules&lt;br /&gt;
function p.get_json_item(name)&lt;br /&gt;
	for i,v in pairs(heroes_data) do&lt;br /&gt;
		if (v[&amp;quot;Name&amp;quot;] == name) then&lt;br /&gt;
			return v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns an array of item tables that have the same properties&lt;br /&gt;
-- @function   get_similar_items&lt;br /&gt;
-- @param      {string}&lt;br /&gt;
-- @return     {array of tables}&lt;br /&gt;
local function get_similar_items(property)&lt;br /&gt;
	local similarItems = {}&lt;br /&gt;
	for _, v in pairs(heroes_data) do&lt;br /&gt;
		if (v[property] ~= nil) then&lt;br /&gt;
			table.insert(similarItems, v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return similarItems&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- returns the key of the specified hero&#039;s english name&lt;br /&gt;
function p.get_hero_key(name)&lt;br /&gt;
	for i,v in pairs(heroes_data) do&lt;br /&gt;
		if (v[&amp;quot;Name&amp;quot;] == name) then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|get_hero_var|HERO_NAME|STAT_NAME|sig_figs_or_localize}}--&lt;br /&gt;
--sig_figs optional for rounding floats&lt;br /&gt;
p.get_hero_var = function(frame)&lt;br /&gt;
	local hero_name = frame.args[1]&lt;br /&gt;
	local hero_stat_key = frame.args[2]&lt;br /&gt;
	local sig_figs_or_localize = frame.args[3]&lt;br /&gt;
	&lt;br /&gt;
	local hero = heroes_data[hero_name] --check if hero key is passed instead&lt;br /&gt;
	if(hero == nil) then hero = p.get_json_item(hero_name) end --check if hero name is passed&lt;br /&gt;
	if(hero == nil) then return &amp;quot;Hero Not Found&amp;quot; end --both invalid, error&lt;br /&gt;
	&lt;br /&gt;
	local var_value = hero[hero_stat_key]&lt;br /&gt;
	if(var_value == nil) then return 0 end&lt;br /&gt;
	&lt;br /&gt;
	--round&lt;br /&gt;
	if (sig_figs_or_localize ~= nil and tonumber(sig_figs_or_localize) ~= nil) then&lt;br /&gt;
		var_value = util_module.round_to_sig_fig(var_value, sig_figs_or_localize)&lt;br /&gt;
		if (var_value == nil) then return &amp;quot;get_hero_var() error with rounding&amp;quot; end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--localize&lt;br /&gt;
	if (sig_figs_or_localize == &amp;quot;true&amp;quot;) then&lt;br /&gt;
		return lang_module.get_string(var_value)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return var_value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|get_list_elem|HERO_NAME|VAR|NUMBER|LOCALIZE}}&lt;br /&gt;
p.get_list_elem = function(frame)&lt;br /&gt;
	local hero_name = frame.args[1]&lt;br /&gt;
	local var = frame.args[2]&lt;br /&gt;
	local number_str = frame.args[3]&lt;br /&gt;
	local number_int = tonumber(number_str)&lt;br /&gt;
	local localize = frame.args[4]&lt;br /&gt;
	local hero = heroes_data[hero_name] --check if hero key is passed instead&lt;br /&gt;
	if(hero == nil) then hero = p.get_json_item(hero_name) end --check if hero name is passed&lt;br /&gt;
	if(hero == nil) then return &amp;quot;Hero Not Found&amp;quot; end --both invalid, error&lt;br /&gt;
	if (hero == nil) then return &amp;quot;Hero &amp;quot; .. hero_name .. &amp;quot; not found&amp;quot; end&lt;br /&gt;
	local list = hero[var]&lt;br /&gt;
	if (list == nil) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	local element = list[number_int]&lt;br /&gt;
	if (element == nil) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	if localize==&amp;quot;true&amp;quot; then &lt;br /&gt;
		element = lang_module.get_string(element)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return element&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.get_ability_key = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	local bound_slot_number = frame.args[2]&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	if (hero_data == nil) then return &amp;quot;Hero key &amp;quot;..hero_key.. &amp;quot; not found&amp;quot; end&lt;br /&gt;
	local bound_abilities_data = hero_data[&amp;quot;BoundAbilities&amp;quot;]&lt;br /&gt;
	if (bound_abilities_data == nil) then return &amp;quot;Hero key &amp;quot; .. hero_key.. &amp;quot; has no BoundAbilities&amp;quot; end&lt;br /&gt;
	return bound_abilities_data[tonumber(bound_slot_number)][&amp;quot;Key&amp;quot;]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.write_role_playstyle_quote = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	if (hero_data == nil) then return hero_key..&amp;quot; not found&amp;quot; end&lt;br /&gt;
	local role_key = hero_data[&amp;quot;Role&amp;quot;]&lt;br /&gt;
	local role_localized = lang_module.get_string(role_key, nil, &#039;en&#039;)&lt;br /&gt;
	local playstyle_key = hero_data[&amp;quot;Playstyle&amp;quot;]&lt;br /&gt;
	local playstyle_localized = lang_module.get_string(playstyle_key, nil, &#039;en&#039;)&lt;br /&gt;
	&lt;br /&gt;
	local str = &amp;quot;&amp;lt;b&amp;gt;&amp;quot; .. role_localized .. &#039;&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&#039; .. playstyle_localized&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	template_args[1] = &amp;quot;&amp;quot;&lt;br /&gt;
	template_args[2] = str&lt;br /&gt;
	return frame:expandTemplate{title = &#039;Quotation&#039;, args = template_args}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.write_default_items = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1] --unlocalized&lt;br /&gt;
	if (hero_key == nil) then return &amp;quot;No hero key provided&amp;quot; end&lt;br /&gt;
	local str = &amp;quot;&amp;quot;&lt;br /&gt;
	local hero = heroes_data[hero_key]&lt;br /&gt;
	if (hero == nil) then return &amp;quot;Hero not found, must be unlocalized&amp;quot; end&lt;br /&gt;
	local template_title = &#039;PageRef&#039;&lt;br /&gt;
	for i, item_key in ipairs(hero[&amp;quot;RecommendedItems&amp;quot;]) do&lt;br /&gt;
		template_args = {}&lt;br /&gt;
		template_args[1] = lang_module.get_string(item_key, &#039;en&#039;)&lt;br /&gt;
		template_args[&#039;alt_name&#039;] = localize(item_key, item_key)&lt;br /&gt;
		local expanded_template = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
		str = str .. &amp;quot;* &amp;quot; .. expanded_template .. &amp;quot;\n&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return str&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
--If the hero scales with the stat, it returns {{Ss|value}} or {{Ls|value}}, else blank string&lt;br /&gt;
--{{#invoke:HeroData|get_hero_scalar_str_invoke|HERO_NAME|STAT_NAME}}--&lt;br /&gt;
p.get_hero_scalar_str_invoke = function(frame)&lt;br /&gt;
	local hero_name = frame.args[1]&lt;br /&gt;
	local hero_stat_key = frame.args[2]&lt;br /&gt;
	local hero_data = p.get_json_item(hero_name)&lt;br /&gt;
	if(hero_data == nil) then return &amp;quot;Hero Not Found&amp;quot; end&lt;br /&gt;
	return p.get_hero_scalar_str(hero_data, hero_stat_key) --surely theres a better way&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Retrieve scaling string of a hero&#039;s given stat, if it has scaling, else return blank&lt;br /&gt;
-- Scaling string meaning the expanded template {{Ss|scalar}} or {{Ls|scalar}}&lt;br /&gt;
function p.get_hero_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
	local scaling_abbrevs = {Spirit = &amp;quot;Ss&amp;quot;, Level = &amp;quot;Ls&amp;quot;}&lt;br /&gt;
	&lt;br /&gt;
	-- Return blank if it doesnt scale&lt;br /&gt;
	if (scaling_value == 0) then return &amp;quot;&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	-- Round it&lt;br /&gt;
	scaling_value = util_module.round_to_sig_fig(scaling_value, 3)&lt;br /&gt;
	&lt;br /&gt;
	--The hero has a scaling value with this stat&lt;br /&gt;
	local template_title = &amp;quot;Template:&amp;quot; .. scaling_abbrevs[scaling_type] --scaling type&#039;s abbreviation&lt;br /&gt;
	&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	template_args[&amp;quot;1&amp;quot;] = scaling_value --store in 1st arg for {{{1}}} to grab it from {{SS}} or {{LS}} template&lt;br /&gt;
	&lt;br /&gt;
	local template_call = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
	return template_call&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Retrieve scaling value and type of a hero&#039;s given stat, if it has scaling, else return 0&lt;br /&gt;
function p.get_hero_scalar(hero_data, hero_stat_key)&lt;br /&gt;
	local scaling_type_full&lt;br /&gt;
	local scaling_data&lt;br /&gt;
	local scaling_value&lt;br /&gt;
	local scaling_types = {&amp;quot;Spirit&amp;quot;, &amp;quot;Level&amp;quot;}&lt;br /&gt;
	local scaling_data_returned = {}&lt;br /&gt;
	&lt;br /&gt;
	for index, scaling_type in ipairs(scaling_types) do&lt;br /&gt;
		scaling_type_full = scaling_type .. &amp;quot;Scaling&amp;quot;&lt;br /&gt;
		scaling_data = hero_data[scaling_type_full]&lt;br /&gt;
		&lt;br /&gt;
		--If the scaling data exists&lt;br /&gt;
		if (scaling_data ~= nil) then &lt;br /&gt;
			scaling_value = scaling_data[hero_stat_key]&lt;br /&gt;
			&lt;br /&gt;
			--If the stat scales&lt;br /&gt;
			if (scaling_value ~= nil) then&lt;br /&gt;
				scaling_data_returned[scaling_value] = scaling_type&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return scaling_data_returned&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--HERO_NAME in english&lt;br /&gt;
--{{#invoke:HeroData|write_infobox|HERO_NAME}}--&lt;br /&gt;
p.write_infobox = function(frame)&lt;br /&gt;
	-- Get hero data&lt;br /&gt;
    hero_key = frame.args[1]&lt;br /&gt;
    hero_data = heroes_data[hero_key]&lt;br /&gt;
    if(hero_data == nil) then return &amp;quot;Hero &amp;quot; .. hero_key .. &amp;quot; Not Found&amp;quot; end&lt;br /&gt;
    &lt;br /&gt;
    local infobox_attributes = {&lt;br /&gt;
        Weapon = {&#039;DPS&#039;,&#039;ClipSize&#039;,&#039;RoundsPerSecond&#039;,&#039;ReloadTime&#039;},&lt;br /&gt;
        Vitality = {&#039;MaxHealth&#039;,&#039;BulletResist&#039;,&#039;TechResist&#039;,&#039;MaxMoveSpeed&#039;}&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    -- Declarations and initializations&lt;br /&gt;
    local category_data = attribute_module.get_category_data()&lt;br /&gt;
    local stats&lt;br /&gt;
    local stat_data&lt;br /&gt;
    local stat_value&lt;br /&gt;
    local stat_text&lt;br /&gt;
    local label&lt;br /&gt;
    local postfix&lt;br /&gt;
    local should_display&lt;br /&gt;
    local image_file_name&lt;br /&gt;
    local image_file&lt;br /&gt;
    local icon_and_value_str&lt;br /&gt;
    local template_args = {}&lt;br /&gt;
    local stat_values = {Weapon = &amp;quot;&amp;quot;, Vitality = &amp;quot;&amp;quot;}&lt;br /&gt;
    &lt;br /&gt;
    -- Add the main parameters&lt;br /&gt;
    template_args[&amp;quot;name_english&amp;quot;] = lang_module.get_string(hero_key, &#039;en&#039;)&lt;br /&gt;
    template_args[&amp;quot;name_localized&amp;quot;] = localize(hero_key, hero_key)&lt;br /&gt;
    &lt;br /&gt;
    -- Iterate attribute categories&lt;br /&gt;
    for category, stats in pairs(infobox_attributes) do&lt;br /&gt;
		-- Iterate stats&lt;br /&gt;
		for _, stat_name in ipairs(stats) do&lt;br /&gt;
			-- Confirm its in attribute data and retrieve it&lt;br /&gt;
			attribute_data = attributes_data[category]&lt;br /&gt;
			if (attribute_data == nil) then return &amp;quot;Category &amp;quot; .. category .. &amp;quot; in infobox_attributes is not in Data:AttributeData&amp;quot; end&lt;br /&gt;
			stat_data = attribute_data[stat_name]&lt;br /&gt;
			if (stat_data == nil) then return &amp;quot;Attribute &amp;quot; .. stat_name .. &amp;quot; in infobox_attributes is not in Data:AttributeData&amp;quot; end&lt;br /&gt;
			&lt;br /&gt;
			-- gets the stat&#039;s value&lt;br /&gt;
			stat_value = hero_data[stat_name]&lt;br /&gt;
			if (stat_value == nil) then&lt;br /&gt;
				stat_value = 0 --default to 0 if not present&lt;br /&gt;
			end&lt;br /&gt;
				&lt;br /&gt;
			--Round value to 3 significant figures&lt;br /&gt;
			stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
			&lt;br /&gt;
			-- get label and postfix&lt;br /&gt;
			label = localize(stat_data[&amp;quot;label&amp;quot;], stat_name)&lt;br /&gt;
			postfix = stat_data[&amp;quot;postfix&amp;quot;]&lt;br /&gt;
			if (postfix == nil) then &lt;br /&gt;
				postfix = &amp;quot;&amp;quot;&lt;br /&gt;
			else&lt;br /&gt;
				-- light grey for postfixes&lt;br /&gt;
				postfix = lang_module.get_string(postfix)&lt;br /&gt;
				if (postfix == nil) then&lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				postfix = &#039;&amp;lt;span style=&amp;quot;color: #666666;&amp;quot;&amp;gt;&#039; .. postfix .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
			-- if a language is missing the postfix, use no postfix&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			-- Check if icon file exists, and if not, don&#039;t use any image&lt;br /&gt;
			image_file_name = &#039;File:AttributeIcon&#039; .. stat_name .. &#039;.png&#039;&lt;br /&gt;
			image_file = util_module.get_image_file(image_file_name, 15, stat_name)&lt;br /&gt;
			&lt;br /&gt;
			-- Create the template&#039;d icon&lt;br /&gt;
			local icon_color = attribute_module.get_attr_icon_color(stat_name)&lt;br /&gt;
			icon_template_title = mw.title.new(&amp;quot;Template:Icon/&amp;quot; .. icon_color)&lt;br /&gt;
			icon_template_args = {}&lt;br /&gt;
			icon_template_args[1] = image_file&lt;br /&gt;
			icon_template_args[2] = stat_value .. postfix&lt;br /&gt;
			icon_and_value_str = mw.getCurrentFrame():expandTemplate{ title = icon_template_title, args = icon_template_args }&lt;br /&gt;
			&lt;br /&gt;
			label =  &#039;,&amp;lt;span style=&amp;quot;color: #999999; background-color: #2F2F2F; display: inline-flex; width: 100%; height: 100%; justify-content: center; align-items: center;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
			&lt;br /&gt;
			-- First add localized stat name for left column&lt;br /&gt;
			stat_values[category] = stat_values[category] .. label&lt;br /&gt;
			&lt;br /&gt;
			-- Then add icon and stat value for right column&lt;br /&gt;
			stat_values[category] = stat_values[category] .. &#039;,&#039; .. icon_and_value_str&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Add the stat values in the category to i.e weapon_values and vitality_values parameters&lt;br /&gt;
		template_args[string.lower(category) .. &amp;quot;_values&amp;quot;] = stat_values[category]&lt;br /&gt;
	end&lt;br /&gt;
    &lt;br /&gt;
    -- Use expandTemplate to evaluate the Infobox_hero template&lt;br /&gt;
    local template_title = mw.title.new(&amp;quot;User:Sur&amp;quot;)&lt;br /&gt;
    local expanded_template = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
    &lt;br /&gt;
    return expanded_template&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--{{#invoke:HeroData|write_stat_infoboxes|HERO_KEY}}&lt;br /&gt;
--Creates {{Infobox_stat}}&#039;s&#039; for the 3 categories Weapon, Vitality, Spirit&lt;br /&gt;
p.write_stat_infoboxes = function(frame)&lt;br /&gt;
	local hero_key = frame.args[1]&lt;br /&gt;
	if(hero_key == nil) then return &amp;quot;Hero parameter missing&amp;quot; end&lt;br /&gt;
	&lt;br /&gt;
	-- Use expandTemplate to evaluate the Infobox_hero template&lt;br /&gt;
    local template_title = mw.title.new(&amp;quot;Template:Infobox_stat&amp;quot;) --name of the template&lt;br /&gt;
    local template_calls = &#039;&amp;lt;div style=&amp;quot;display: flex; flex-direction: column;&amp;quot;&amp;gt;&#039; --all template calls concatenated&lt;br /&gt;
    local template_call --current template call&lt;br /&gt;
	local template_args = {} --current template arguments&lt;br /&gt;
	local cell_values --current cell values&lt;br /&gt;
	local cell_value --current cell value&lt;br /&gt;
	local label --current stat&#039;s label&lt;br /&gt;
	local postfix --current stat&#039;s postfix&lt;br /&gt;
	local stat_value --current stat&#039;s numerical value in the hero data&lt;br /&gt;
	local hero_data = heroes_data[hero_key]&lt;br /&gt;
	local stats --stats of the current category&lt;br /&gt;
	local image_file_name --name of the image_file to check&lt;br /&gt;
	local image_file --mw returned image file&lt;br /&gt;
	local extra_blank_cell --add a blank cell after certain stats&lt;br /&gt;
	local stats_to_add_blank_after = {CritDamageReceivedScale = true}&lt;br /&gt;
	if (hero_data == nil) then return &amp;quot;Hero Not Found&amp;quot; end&lt;br /&gt;
	local category_data = attribute_module.get_category_data()&lt;br /&gt;
	local should_display&lt;br /&gt;
	&lt;br /&gt;
	for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
		if (category ~= &amp;quot;Spirit&amp;quot;) then --hide Spirit section for now&lt;br /&gt;
			stats = attributes_data[category]&lt;br /&gt;
			local category_values = category_data[category]&lt;br /&gt;
			template_args[&amp;quot;box_name&amp;quot;] = category_values.unlocalized_name&lt;br /&gt;
			template_args[&amp;quot;box_rgb&amp;quot;] = category_values.rgb&lt;br /&gt;
			template_args[&amp;quot;num_cols&amp;quot;] = 2&lt;br /&gt;
			cell_values = &amp;quot;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Determine cell values&lt;br /&gt;
			for _, stat_name in ipairs(attribute_orders[category][&amp;quot;attribute_order&amp;quot;]) do&lt;br /&gt;
				local stat_data = stats[stat_name]&lt;br /&gt;
				if stat_data == nil then return &amp;quot;Stat &amp;quot; .. stat_name .. &amp;quot; from StatInfoboxOrder has no data in AttributeData&amp;quot; end&lt;br /&gt;
				&lt;br /&gt;
				-- gets the stat&#039;s value if it has that stat, default to 0 if not&lt;br /&gt;
				stat_value = hero_data[stat_name]&lt;br /&gt;
				if (stat_value == nil) then&lt;br /&gt;
					stat_value = 0 --default to 0 if not present&lt;br /&gt;
				end&lt;br /&gt;
					&lt;br /&gt;
				--Round value to 3 significant figures&lt;br /&gt;
				stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
				&lt;br /&gt;
				-- get label and postfix&lt;br /&gt;
				label = localize(stat_data[&amp;quot;label&amp;quot;], stat_name)&lt;br /&gt;
				postfix = stat_data[&amp;quot;postfix&amp;quot;]&lt;br /&gt;
				if (postfix == nil) then &lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				else&lt;br /&gt;
					-- light grey for postfixes&lt;br /&gt;
					postfix = &#039;&amp;lt;span style=&amp;quot;color: #666666;&amp;quot;&amp;gt;&#039; .. lang_module.get_string(postfix) .. &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				-- if a language is missing the postfix, use no postfix&lt;br /&gt;
				if (postfix == nil) then&lt;br /&gt;
					postfix = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- Check if icon file exists, and if not, don&#039;t use any image&lt;br /&gt;
				image_file_name = &#039;File:AttributeIcon&#039; .. stat_name .. &#039;.png&#039;&lt;br /&gt;
				-- 15px and link to stat name (page name might not match perfectly yet)&lt;br /&gt;
				image_file = util_module.get_image_file(image_file_name, 15, stat_name)&lt;br /&gt;
				&lt;br /&gt;
				-- Create the template&#039;d icon&lt;br /&gt;
				local icon_color = attribute_module.get_attr_icon_color(stat_name)&lt;br /&gt;
				if (icon_color == &amp;quot;Brown&amp;quot;) then&lt;br /&gt;
					image_file = &#039;&amp;lt;span style=&amp;quot;position: relative; bottom: 2px; filter: invert(42%) sepia(10%) saturate(2912%) hue-rotate(351deg) brightness(90%) contrast(87%);&amp;quot;&amp;gt;&#039; .. image_file .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				end&lt;br /&gt;
				-- use white instead of grey if grey is returned&lt;br /&gt;
				&lt;br /&gt;
				-- Add an empty cell following some stats to align them correctly as seen in game&lt;br /&gt;
				if (stats_to_add_blank_after[stat_name]) then&lt;br /&gt;
					extra_blank_cell = &amp;quot; ,&amp;quot; --prefixed space is needed&lt;br /&gt;
				else&lt;br /&gt;
					extra_blank_cell = &amp;quot;&amp;quot;&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- slightly lighter color for stat name&lt;br /&gt;
				label = &#039;&amp;lt;span style=&amp;quot;color: #3d3d3d;&amp;quot;&amp;gt;&#039; .. label .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
				&lt;br /&gt;
				-- Add the scaling str if it scales&lt;br /&gt;
				local scaling_data = p.get_hero_scalar(hero_data, stat_name)&lt;br /&gt;
				local scaling_strs = &amp;quot;&amp;quot;&lt;br /&gt;
				if (scaling_data ~= nil) then&lt;br /&gt;
					for scaling_value, scaling_type in pairs(scaling_data) do&lt;br /&gt;
						local scaling_str = p.get_hero_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
						if (scaling_str ~= &amp;quot;&amp;quot;) then scaling_str = &amp;quot; &amp;quot; .. scaling_str end&lt;br /&gt;
						scaling_strs = scaling_strs .. scaling_str&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				-- Set cell value as &amp;quot;Icon StatvaluePostfix Statname Scaling,&amp;quot;&lt;br /&gt;
				-- If icon file already exists, set it to #REDIRECT to the duplicate file page&lt;br /&gt;
				cell_value = image_file .. &amp;quot; &amp;quot; .. stat_value  .. postfix .. &amp;quot; &amp;quot; .. label  .. scaling_strs .. &amp;quot;,&amp;quot; .. extra_blank_cell&lt;br /&gt;
				&lt;br /&gt;
				cell_values = cell_values .. cell_value --add value to values list&lt;br /&gt;
			end&lt;br /&gt;
			template_args[&amp;quot;cell_values&amp;quot;] = cell_values&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			-- Write current call&lt;br /&gt;
			template_call = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
		&lt;br /&gt;
			-- Add call to the set of calls&lt;br /&gt;
			template_calls = template_calls .. &amp;quot;\n&amp;quot; .. template_call&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return template_calls .. &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--writes the massive hero comparison table for a specific PI and SP&lt;br /&gt;
-- scaling icons are shown only if PI and SP are both 0 or both not provided&lt;br /&gt;
--{{#invoke:HeroData|write_hero_comparison_table|POWER_INCREASES|SPIRIT_POWER}}&lt;br /&gt;
p.write_hero_comparison_table = function(frame)&lt;br /&gt;
	-- process inputs&lt;br /&gt;
	local power_increases = frame.args[1]&lt;br /&gt;
	if (power_increases == nil) then power_increases = 0 end&lt;br /&gt;
	local spirit_power = frame.args[2]&lt;br /&gt;
	if (spirit_power == nil) then spirit_power = 0 end&lt;br /&gt;
	&lt;br /&gt;
	-- Show scaling icons if power/increases/spirit power are 0/not specified&lt;br /&gt;
	local display_scaling_icons = false&lt;br /&gt;
	if (power_increases == 0 and spirit_power == 0) then&lt;br /&gt;
		display_scaling_icons = true&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Initializations and declarations&lt;br /&gt;
	local row_str = &amp;quot;&amp;quot;&lt;br /&gt;
	local body_str = &amp;quot;&amp;quot;&lt;br /&gt;
	local in_development&lt;br /&gt;
	local is_disabled&lt;br /&gt;
	local template_title = &amp;quot;&amp;quot;&lt;br /&gt;
	local template_args = {}&lt;br /&gt;
	local hero_icon&lt;br /&gt;
	local hero_td_style&lt;br /&gt;
	local scalar_str&lt;br /&gt;
	&lt;br /&gt;
	-- Add hero comp stats to &lt;br /&gt;
	local stats_to_include = {&lt;br /&gt;
		Weapon = {&lt;br /&gt;
			&amp;quot;DPS&amp;quot;,&lt;br /&gt;
            &amp;quot;SustainedDPS&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;RoundsPerSecond&amp;quot;,&lt;br /&gt;
            &amp;quot;FireRate&amp;quot;,&lt;br /&gt;
            &amp;quot;ClipSize&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadTime&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadDelay&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletsPerShot&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletsPerBurst&amp;quot;,&lt;br /&gt;
            &amp;quot;BurstInterShotInterval&amp;quot;,&lt;br /&gt;
            &amp;quot;LightMeleeDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;HeavyMeleeDamage&amp;quot;,&lt;br /&gt;
            &amp;quot;ReloadSingle&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletGravityScale&amp;quot;,&lt;br /&gt;
            &amp;quot;FalloffStartRange&amp;quot;,&lt;br /&gt;
            &amp;quot;FalloffEndRange&amp;quot;,&lt;br /&gt;
            &amp;quot;BonusAttackRange&amp;quot;,&lt;br /&gt;
            &amp;quot;RoundsPerSecondAtMaxSpin&amp;quot;,&lt;br /&gt;
            &amp;quot;SpinAcceleration&amp;quot;,&lt;br /&gt;
            &amp;quot;SpinDeceleration&amp;quot;&lt;br /&gt;
		},&lt;br /&gt;
		Vitality = {&lt;br /&gt;
			&amp;quot;MaxHealth&amp;quot;,&lt;br /&gt;
            &amp;quot;BaseHealthRegen&amp;quot;,&lt;br /&gt;
            &amp;quot;BulletResist&amp;quot;,&lt;br /&gt;
            &amp;quot;TechResist&amp;quot;,&lt;br /&gt;
            &amp;quot;CritDamageReceivedScale&amp;quot;,&lt;br /&gt;
            &amp;quot;MaxMoveSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;SprintSpeed&amp;quot;,&lt;br /&gt;
            &amp;quot;StaminaCooldown&amp;quot;,&lt;br /&gt;
            &amp;quot;Stamina&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	-- Iterate heroes&lt;br /&gt;
	for hero_key, hero_data in pairs(heroes_data) do&lt;br /&gt;
		-- Ensure they are not in development and they are an active hero&lt;br /&gt;
		in_development = hero_data[&amp;quot;InDevelopment&amp;quot;]&lt;br /&gt;
		is_disabled = hero_data[&amp;quot;IsDisabled&amp;quot;]&lt;br /&gt;
		if ((not in_development) and (not is_disabled)) then &lt;br /&gt;
			&lt;br /&gt;
			--Add the row&#039;s stats&lt;br /&gt;
			row_str = &amp;quot;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Retrieve hero&#039;s localized name&lt;br /&gt;
			hero_name = localize(hero_key, hero_key)&lt;br /&gt;
			&lt;br /&gt;
			-- Retrieve hero&#039;s english name, used for hero icon&lt;br /&gt;
			hero_name_en = hero_data[&amp;quot;Name&amp;quot;]&lt;br /&gt;
			&lt;br /&gt;
			-- Expand hero icon&lt;br /&gt;
			template_title = &amp;quot;Template:HeroIcon&amp;quot;&lt;br /&gt;
			template_args[1] = hero_name_en&lt;br /&gt;
			template_args[2] = hero_name&lt;br /&gt;
			hero_icon = mw.getCurrentFrame():expandTemplate{ title = template_title, args = template_args }&lt;br /&gt;
			&lt;br /&gt;
			-- First column in each row is hero name&lt;br /&gt;
			row_str = row_str .. &amp;quot;&amp;lt;td&amp;gt;&amp;quot; .. hero_icon .. &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;br /&gt;
			&lt;br /&gt;
			-- Consecutive columns are then stats&lt;br /&gt;
			-- Iterate categories&lt;br /&gt;
			for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
				category_attrs = attributes_data[category]&lt;br /&gt;
				&lt;br /&gt;
				-- Iterate attributes within the category&lt;br /&gt;
				if (stats_to_include[category] ~= nil) then&lt;br /&gt;
					&lt;br /&gt;
					for _, attr_key in ipairs(stats_to_include[category]) do&lt;br /&gt;
						&lt;br /&gt;
						--Retrieve the stats value from hero data&lt;br /&gt;
						stat_value = hero_data[attr_key]&lt;br /&gt;
						if (stat_value == nil) then stat_value = 0 end&lt;br /&gt;
						&lt;br /&gt;
						-- Retrieve scaling val and str if it scales&lt;br /&gt;
						local scaling_data = p.get_hero_scalar(hero_data, attr_key)&lt;br /&gt;
						local scaling_strs = &amp;quot;&amp;quot;&lt;br /&gt;
						if (scaling_data ~= nil) then&lt;br /&gt;
							for scaling_value, scaling_type in pairs(scaling_data) do&lt;br /&gt;
								local scaling_str = p.get_hero_scalar_str(scaling_value, scaling_type)&lt;br /&gt;
								if (scaling_str ~= &amp;quot;&amp;quot;) then scaling_str = &amp;quot; &amp;quot; .. scaling_str end&lt;br /&gt;
								if (scaling_str ~= nil) then&lt;br /&gt;
									scaling_strs = scaling_strs .. scaling_str &lt;br /&gt;
								end&lt;br /&gt;
								-- Scale the stat value&lt;br /&gt;
								if (scaling_type == &amp;quot;Spirit&amp;quot;) then&lt;br /&gt;
									stat_value = stat_value + (spirit_power * scaling_value)&lt;br /&gt;
								elseif (scaling_type == &amp;quot;Level&amp;quot;) then&lt;br /&gt;
									if attr_key == &#039;TechResist&#039; or attr_key == &#039;BulletResist&#039; then&lt;br /&gt;
										-- each PI for resists is multiplicative&lt;br /&gt;
										stat_value = (stat_value/100 + 1 - (1-scaling_value/100)^power_increases)*100&lt;br /&gt;
									else&lt;br /&gt;
										stat_value = stat_value + (power_increases * scaling_value)&lt;br /&gt;
									end&lt;br /&gt;
								end&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
						if (not display_scaling_icons) then scaling_strs = &amp;quot;&amp;quot; end&lt;br /&gt;
						&lt;br /&gt;
						&lt;br /&gt;
						&lt;br /&gt;
						-- Convert from boolean to string, or round it&lt;br /&gt;
						if (type(stat_value)) == &#039;boolean&#039; then&lt;br /&gt;
							stat_value = tostring(stat_value)&lt;br /&gt;
						else&lt;br /&gt;
							stat_value = util_module.round_to_sig_fig(stat_value, 3)&lt;br /&gt;
						end&lt;br /&gt;
						&lt;br /&gt;
						-- Add it to the row&lt;br /&gt;
						row_str = row_str .. &amp;quot;&amp;lt;td&amp;gt;&amp;quot; .. stat_value .. scaling_strs .. &amp;quot;&amp;lt;/td&amp;gt;&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			-- Add row to the body&lt;br /&gt;
			row_str = &amp;quot;&amp;lt;tr&amp;gt;&amp;quot; .. row_str .. &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;&lt;br /&gt;
			body_str = body_str .. row_str &lt;br /&gt;
			&lt;br /&gt;
			first_hero = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	-- First header is Hero&lt;br /&gt;
	local headers_str = &amp;quot;&amp;lt;th&amp;gt;&amp;quot; .. &amp;quot;Hero&amp;quot; .. &amp;quot;&amp;lt;/th&amp;gt;&amp;quot;&lt;br /&gt;
	local header_style = &amp;quot;&amp;quot;&lt;br /&gt;
	local category_data = attribute_module.get_category_data()&lt;br /&gt;
	local postfix&lt;br /&gt;
	-- Used for keys that are not localized by Valve&lt;br /&gt;
	local postfix_key_map = {&lt;br /&gt;
		[&amp;quot;ReloadDelay&amp;quot;] = &amp;quot;StatDesc_ReloadTime_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;BulletsPerShot&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BulletsPerBurst&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BurstInterShotInterval&amp;quot;] = &amp;quot;StatDesc_ReloadTime_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;ReloadSingle&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;BonusAttackRange&amp;quot;] = &amp;quot;StatDesc_WeaponRangeFalloffMax_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;SustainedDPS&amp;quot;] = &amp;quot;DPS_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;RoundsPerSecondAtMaxSpin&amp;quot;] = &amp;quot;&amp;quot;,&lt;br /&gt;
		[&amp;quot;SpinAcceleration&amp;quot;] = &amp;quot;BonusFireRate_postfix&amp;quot;,&lt;br /&gt;
		[&amp;quot;SpinDeceleration&amp;quot;] = &amp;quot;BonusFireRate_postfix&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
	-- Iterate stats again for displaying headers with their respective color&lt;br /&gt;
	for _, category in ipairs(attribute_orders[&amp;quot;category_order&amp;quot;]) do&lt;br /&gt;
		category_attrs = attributes_data[category]&lt;br /&gt;
		category_rgb = category_data[category][&amp;quot;rgb&amp;quot;]&lt;br /&gt;
		&lt;br /&gt;
		-- Iterate attributes within the category&lt;br /&gt;
		if (stats_to_include[category] ~= nil) then &lt;br /&gt;
			for _, attr_key in ipairs(stats_to_include[category]) do&lt;br /&gt;
				attr_data = category_attrs[attr_key]&lt;br /&gt;
				&lt;br /&gt;
				if (attr_data ~= nil) then&lt;br /&gt;
					-- Localize, fallback to attr_key with proper spaces&lt;br /&gt;
					attr_localized = lang_module.get_string(attr_data[&amp;quot;label&amp;quot;])&lt;br /&gt;
					if (attr_localized == nil or attr_localized == &amp;quot;&amp;quot;) then attr_localized = util_module.add_space_before_cap(attr_key) end&lt;br /&gt;
				&lt;br /&gt;
					-- Get postfix&lt;br /&gt;
					postfix = lang_module.get_string(attr_data[&amp;quot;postfix&amp;quot;])&lt;br /&gt;
					if (postfix == nil or postfix == &amp;quot;&amp;quot;) then &lt;br /&gt;
						postfix = &amp;quot;&amp;quot; &lt;br /&gt;
					else&lt;br /&gt;
						postfix = &amp;quot; (&amp;quot; .. postfix .. &amp;quot;)&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				else -- If not in attributes data, use dictionary translate and postfix&lt;br /&gt;
					attr_localized = dictionary_module.translate(attr_key)&lt;br /&gt;
					postfix = lang_module.get_string(postfix_key_map[attr_key])&lt;br /&gt;
					if postfix == nil then &lt;br /&gt;
						return &amp;quot;attr_key &amp;quot; .. attr_key .. &amp;quot; must be added to postfix_key_map&amp;quot; &lt;br /&gt;
					end&lt;br /&gt;
					if postfix ~= &amp;quot;&amp;quot; then&lt;br /&gt;
						postfix = &amp;quot; (&amp;quot; .. postfix .. &amp;quot;)&amp;quot;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				&lt;br /&gt;
				header_style = &#039; style=&amp;quot;background-color: &#039; .. &amp;quot;rgb(&amp;quot; .. category_rgb .. &#039;) ;&amp;quot;&#039;&lt;br /&gt;
				&lt;br /&gt;
				headers_str = headers_str .. &amp;quot;&amp;lt;th&amp;quot; .. header_style .. &amp;quot;&amp;gt;&amp;quot; .. attr_localized .. postfix .. &amp;quot;&amp;lt;/th&amp;gt;&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	headers_str = &amp;quot;&amp;lt;tr&amp;gt;&amp;quot; .. headers_str .. &amp;quot;&amp;lt;/tr&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local table_str = &#039;&amp;lt;table class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;table-layout: auto; width: 100%;&amp;quot;&amp;gt;&#039; .. headers_str .. body_str .. &amp;quot;&amp;lt;/table&amp;gt;&amp;quot;&lt;br /&gt;
	local output_str = &#039;&amp;lt;div style=&amp;quot;overflow-x: auto; width: 100%;&amp;quot;&amp;gt;&#039; .. table_str .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	return output_str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function localize(key, fallback)&lt;br /&gt;
	local result = lang_module.get_string(key)&lt;br /&gt;
	if (result == &amp;quot;&amp;quot;) or (result == nil) then&lt;br /&gt;
		result = util_module.add_space_before_cap(fallback) .. mw.getCurrentFrame():expandTemplate{title=&amp;quot;MissingValveTranslationTooltip&amp;quot;}&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/Abrams/es?diff=18431</id>
		<title>User:Sur/Abrams/es</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/Abrams/es?diff=18431"/>
		<updated>2025-01-01T03:59:18Z</updated>

		<summary type="html">&lt;p&gt;Sur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#vardefine:unlocalized|hero_atlas}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#vardefine:localized|{{#invoke:Lang|get_string|{{#var:unlocalized}}}}}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|guide_the_map_welcome_header|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_infobox|{{#var:unlocalized}}}}&lt;br /&gt;
{{#invoke:HeroData|write_role_playstyle_quote|{{#var:unlocalized}}}}&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Abrams&#039;&#039;&#039; is hard-boiled, hard-hitting bruiser of a character that focuses on engaging groups of enemies and relying on his fortitude and life drain to stay in the fight. With a powerful area stun and a devastating shoulder charge, Abrams can isolate fragile targets from the rest of the team and set-up his more damaging allies to finish them off. &lt;br /&gt;
&lt;br /&gt;
A capable and well-known detective of New York, Abrams solved crimes ranging from kidnappings to ritual murders. One day, a mysterious Tome was left on his desk with a note of &amp;quot;Don&#039;t let them have it&amp;quot; scrolled in Onyx blood; followed by car bombings and break-ins to his office. Now, Abrams is trying to figure out just what the hell is going on. &lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|item_info_abilities|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:AbilityData/hero|write_hero_abilities|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Stats}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_stat_infoboxes|{{#var:unlocalized}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelCategoryWeapon|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{WeaponCard|key={{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=-1}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuildDesc}}&lt;br /&gt;
{{#invoke:HeroData|write_default_items|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Update history}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Main|User:Sur/{{#var:localized}}/Update history|l1={{#invoke:Dictionary|translate|Update history}}}}&lt;br /&gt;
{{#invoke:Changelog|write_changelog_by_tag|{{#var:localized}}|3}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelHeroDetails_Background|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Quotation|&#039;&#039;&#039;{{#invoke:Lang|get_string|Citadel_HeroPage_FatesTale}}&#039;&#039;&#039;|{{#invoke:HeroData|get_hero_var|{{#var:unlocalized}}|Lore|true}}}}&lt;br /&gt;
=== Lore ===&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Lore - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
Abrams is [[Ixia|Ixian]].&amp;lt;ref name=&amp;quot;:0&amp;quot;&amp;gt;[https://www.youtube.com/watch?v=yM6oQ2FiYxk Grey Talon and Abrams conversation] - Talon: &#039;&#039;&amp;quot;You remind me of my stepdaughter.&amp;quot;&#039;&#039; Abrams: &#039;&#039;&amp;quot;Son married an Ixian?&amp;quot;&#039;&#039; Talon: &#039;&#039;&amp;quot;Yeah.&amp;quot;&#039;&#039;&amp;lt;/ref&amp;gt; However, unlike [[Infernus]], he does not demonstrate control over fire.&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Lore - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Character interactions ==&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Character interactions - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
* In one of the endings of [[The Binding of Oathkeeper|&#039;&#039;The Binding of Oathkeeper&#039;&#039;]], Abrams moves to [[Lady Geist|Lady Geist&#039;s]] apartment.&lt;br /&gt;
* Grey Talon says his &amp;quot;stepdaughter&amp;quot; is [[Ixia|Ixian]], like Abrams.&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt; However, it seems that the intended term was &amp;quot;daughter-in-law&amp;quot;, as evidenced by Talon&#039;s background and Abrams&#039; response.&lt;br /&gt;
* Abrams is surprised that [[Infernus]] has never visited Ixia.&amp;lt;ref&amp;gt;[https://www.youtube.com/watch?v=cg9-nS_iCVk Infernus and Abrams conversation] - Abrams: &#039;&#039;&amp;quot;So when&#039;s the last time you went to Ixia?&amp;quot;&#039;&#039; Infernus: &#039;&#039;&amp;quot;Never.&amp;quot;&#039;&#039; Abrams: &#039;&#039;&amp;quot;You gotta be kidding me!&amp;quot;&#039;&#039; Infernus: &#039;&#039;&amp;quot;New York born and raised, baby.&amp;quot;&#039;&#039;&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Character interactions - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Gallery==&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Gallery - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Abrams card.png|Portrait&lt;br /&gt;
File:Abrams MM.png|Minimap icon&lt;br /&gt;
File:Abrams Render.png|In-game render&lt;br /&gt;
File:Abrams Winter.png|Winter skin&lt;br /&gt;
File:Abrams menu.jpg|Main menu animation&lt;br /&gt;
File:Abrams Reference Sheet.png|Model sheet&lt;br /&gt;
File:Learn to play menu.png|Abrams with [[Ivy]] and a [[Trooper]] in the &amp;quot;Learn to play&amp;quot; menu art&lt;br /&gt;
File:Abrams new model.png|Work-in-progress new model&lt;br /&gt;
File:Abrams visual novel.png|Visual novel art&lt;br /&gt;
File:Abrams visual novel shirt.png|Visual novel art - without coat&lt;br /&gt;
File:Abrams Weapon.png|Weapon - Cold Case&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Gallery - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Trivia}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Trivia - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
* Abrams during &#039;&#039;Deadlock&#039;&#039; Pre-Alpha (&#039;&#039;[[Neon Prime]]&#039;&#039;) was named &#039;&#039;&#039;Atlas&#039;&#039;&#039;.&lt;br /&gt;
* Abrams is voiced by [[wikipedia:Samoa Joe|Samoa Joe]], a professional wrestler.&amp;lt;ref&amp;gt;[https://twitter.com/SamoaJoe/status/1837127627015958604 Samoa Joe on Twitter]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** Haze may call Abrams a &amp;quot;juggernaut&amp;quot;.&amp;lt;ref&amp;gt;{{VoiceLineCite|name=Haze|file=haze_enemy_atlas_unkillable_02.mp3|transcription=This man&#039;s a juggernaut!}}&amp;lt;/ref&amp;gt; Samoa Joe voiced the character &#039;&#039;&#039;Juggernaut&#039;&#039;&#039; in &#039;&#039;Dota Underlords&#039;&#039;.&lt;br /&gt;
* Abrams&#039; Tome contains a ripped page matching [[Oathkeeper|Oathkeeper&#039;s]] sign.&amp;lt;ref&amp;gt;[[The Binding of Oathkeeper|&#039;&#039;The Binding of Oathkeeper&#039;&#039;]] - [https://youtu.be/nn_C9nQ_Ri0?si=5PrfULMqVKUf-8tQ&amp;amp;t=894 Chapter 4B]&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Abrams&#039; Tome in game currently uses the textures from TF2&#039;s [https://wiki.teamfortress.com/wiki/Bombinomicon_(character) Bombinomicon.]&lt;br /&gt;
* In [[The Binding of Oathkeeper|&#039;&#039;The Binding of Oathkeeper&#039;&#039;]] artwork, Abrams has spikes on his back.&lt;br /&gt;
* Abrams was the only hero who had unique animations in the [[shop]] menu screen. These animations have been removed.&lt;br /&gt;
* Abrams was made slightly taller in an unlisted patch change around November 2024. Because of this, the top of his head is cut off in the shop menu and in the player profile screen.&lt;br /&gt;
* Abrams had a new work-in-progress model added to the game files in the [[Update:December 6, 2024|2024-12-06 Update]], and later removed. This model had more finished textures and a remodeled head with complete facial rigging, as well as an added tail. His badge was removed, indicating that he is not a police detective.&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Trivia - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;hidden&amp;quot;&amp;gt;{{Hero Navbox}}&amp;lt;/div&amp;gt;&amp;lt;!--viewed by desktop only--&amp;gt; &lt;br /&gt;
[[Category:Heroes]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Deadbot/blueprints/Hero?diff=18386</id>
		<title>User:Deadbot/blueprints/Hero</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Deadbot/blueprints/Hero?diff=18386"/>
		<updated>2025-01-01T00:00:59Z</updated>

		<summary type="html">&lt;p&gt;Sur: Sur changed the content model of the page User:DeadBot/blueprints/Hero from &amp;quot;wikitext&amp;quot; to &amp;quot;plain text&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#vardefine:unlocalized|&amp;lt;key&amp;gt;}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#vardefine:localized|{{#invoke:Lang|get_string|{{#var:unlocalized}}}}}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|guide_the_map_welcome_header|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_infobox|{{#var:unlocalized}}}}&lt;br /&gt;
{{#invoke:HeroData|write_role_playstyle_quote|{{#var:unlocalized}}}}&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|item_info_abilities|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:AbilityData/hero|write_hero_abilities|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Stats}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_stat_infoboxes|{{#var:unlocalized}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelCategoryWeapon|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{WeaponCard|key={{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=-1}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuildDesc}}&lt;br /&gt;
{{#invoke:HeroData|write_default_items|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Update history}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Main|User:Sur/{{#var:localized}}/Update history|l1={{#invoke:Dictionary|translate|Update history}}}}&lt;br /&gt;
{{#invoke:Changelog|write_changelog_by_tag|{{#var:localized}}|3}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelHeroDetails_Background|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Quotation|&#039;&#039;&#039;{{#invoke:Lang|get_string|Citadel_HeroPage_FatesTale}}&#039;&#039;&#039;|{{#invoke:HeroData|get_hero_var|{{#var:unlocalized}}|Lore|true}}}}&lt;br /&gt;
=== Lore ===&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Lore - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
Lore&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Lore - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Character interactions ==&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Character interactions - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
* Character interaction&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Character interactions - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Gallery==&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Gallery - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
Gallery&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Gallery - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Trivia}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Trivia - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
* Trivia&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Trivia - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;hidden&amp;quot;&amp;gt;{{Hero Navbox}}&amp;lt;/div&amp;gt;&amp;lt;!--viewed by desktop only--&amp;gt; &lt;br /&gt;
[[Category:Heroes]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Deadbot/blueprints/Hero?diff=18385</id>
		<title>User:Deadbot/blueprints/Hero</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Deadbot/blueprints/Hero?diff=18385"/>
		<updated>2025-01-01T00:00:39Z</updated>

		<summary type="html">&lt;p&gt;Sur: initial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#vardefine:unlocalized|&amp;lt;key&amp;gt;}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#vardefine:localized|{{#invoke:Lang|get_string|{{#var:unlocalized}}}}}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|guide_the_map_welcome_header|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_infobox|{{#var:unlocalized}}}}&lt;br /&gt;
{{#invoke:HeroData|write_role_playstyle_quote|{{#var:unlocalized}}}}&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|item_info_abilities|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:AbilityData/hero|write_hero_abilities|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Stats}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_stat_infoboxes|{{#var:unlocalized}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelCategoryWeapon|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{WeaponCard|key={{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=-1}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuildDesc}}&lt;br /&gt;
{{#invoke:HeroData|write_default_items|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Update history}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Main|User:Sur/{{#var:localized}}/Update history|l1={{#invoke:Dictionary|translate|Update history}}}}&lt;br /&gt;
{{#invoke:Changelog|write_changelog_by_tag|{{#var:localized}}|3}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelHeroDetails_Background|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Quotation|&#039;&#039;&#039;{{#invoke:Lang|get_string|Citadel_HeroPage_FatesTale}}&#039;&#039;&#039;|{{#invoke:HeroData|get_hero_var|{{#var:unlocalized}}|Lore|true}}}}&lt;br /&gt;
=== Lore ===&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Lore - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
Lore&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Lore - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Character interactions ==&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Character interactions - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
* Character interaction&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Character interactions - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Gallery==&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Gallery - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
Gallery&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Gallery - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Trivia}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Trivia - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
* Trivia&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Trivia - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;hidden&amp;quot;&amp;gt;{{Hero Navbox}}&amp;lt;/div&amp;gt;&amp;lt;!--viewed by desktop only--&amp;gt; &lt;br /&gt;
[[Category:Heroes]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/Abrams?diff=18384</id>
		<title>User:Sur/Abrams</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/Abrams?diff=18384"/>
		<updated>2024-12-31T23:57:56Z</updated>

		<summary type="html">&lt;p&gt;Sur: use all the new hero sections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#vardefine:unlocalized|hero_atlas}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#vardefine:localized|{{#invoke:Lang|get_string|{{#var:unlocalized}}}}}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|guide_the_map_welcome_header|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_infobox|{{#var:unlocalized}}}}&lt;br /&gt;
{{#invoke:HeroData|write_role_playstyle_quote|{{#var:unlocalized}}}}&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Abrams&#039;&#039;&#039; is hard-boiled, hard-hitting bruiser of a character that focuses on engaging groups of enemies and relying on his fortitude and life drain to stay in the fight. With a powerful area stun and a devastating shoulder charge, Abrams can isolate fragile targets from the rest of the team and set-up his more damaging allies to finish them off. &lt;br /&gt;
&lt;br /&gt;
A capable and well-known detective of New York, Abrams solved crimes ranging from kidnappings to ritual murders. One day, a mysterious Tome was left on his desk with a note of &amp;quot;Don&#039;t let them have it&amp;quot; scrolled in Onyx blood; followed by car bombings and break-ins to his office. Now, Abrams is trying to figure out just what the hell is going on. &lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|item_info_abilities|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:AbilityData/hero|write_hero_abilities|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Stats}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_stat_infoboxes|{{#var:unlocalized}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelCategoryWeapon|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{WeaponCard|key={{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=-1}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuildDesc}}&lt;br /&gt;
{{#invoke:HeroData|write_default_items|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Update history}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Main|User:Sur/{{#var:localized}}/Update history|l1={{#invoke:Dictionary|translate|Update history}}}}&lt;br /&gt;
{{#invoke:Changelog|write_changelog_by_tag|{{#var:localized}}|3}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelHeroDetails_Background|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Quotation|&#039;&#039;&#039;{{#invoke:Lang|get_string|Citadel_HeroPage_FatesTale}}&#039;&#039;&#039;|{{#invoke:HeroData|get_hero_var|{{#var:unlocalized}}|Lore|true}}}}&lt;br /&gt;
=== Lore ===&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Lore - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
Abrams is [[Ixia|Ixian]].&amp;lt;ref name=&amp;quot;:0&amp;quot;&amp;gt;[https://www.youtube.com/watch?v=yM6oQ2FiYxk Grey Talon and Abrams conversation] - Talon: &#039;&#039;&amp;quot;You remind me of my stepdaughter.&amp;quot;&#039;&#039; Abrams: &#039;&#039;&amp;quot;Son married an Ixian?&amp;quot;&#039;&#039; Talon: &#039;&#039;&amp;quot;Yeah.&amp;quot;&#039;&#039;&amp;lt;/ref&amp;gt; However, unlike [[Infernus]], he does not demonstrate control over fire.&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Lore - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Character interactions ==&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Character interactions - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
* In one of the endings of [[The Binding of Oathkeeper|&#039;&#039;The Binding of Oathkeeper&#039;&#039;]], Abrams moves to [[Lady Geist|Lady Geist&#039;s]] apartment.&lt;br /&gt;
* Grey Talon says his &amp;quot;stepdaughter&amp;quot; is [[Ixia|Ixian]], like Abrams.&amp;lt;ref name=&amp;quot;:0&amp;quot; /&amp;gt; However, it seems that the intended term was &amp;quot;daughter-in-law&amp;quot;, as evidenced by Talon&#039;s background and Abrams&#039; response.&lt;br /&gt;
* Abrams is surprised that [[Infernus]] has never visited Ixia.&amp;lt;ref&amp;gt;[https://www.youtube.com/watch?v=cg9-nS_iCVk Infernus and Abrams conversation] - Abrams: &#039;&#039;&amp;quot;So when&#039;s the last time you went to Ixia?&amp;quot;&#039;&#039; Infernus: &#039;&#039;&amp;quot;Never.&amp;quot;&#039;&#039; Abrams: &#039;&#039;&amp;quot;You gotta be kidding me!&amp;quot;&#039;&#039; Infernus: &#039;&#039;&amp;quot;New York born and raised, baby.&amp;quot;&#039;&#039;&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Character interactions - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Gallery==&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Gallery - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
File:Abrams card.png|Portrait&lt;br /&gt;
File:Abrams MM.png|Minimap icon&lt;br /&gt;
File:Abrams Render.png|In-game render&lt;br /&gt;
File:Abrams Winter.png|Winter skin&lt;br /&gt;
File:Abrams menu.jpg|Main menu animation&lt;br /&gt;
File:Abrams Reference Sheet.png|Model sheet&lt;br /&gt;
File:Learn to play menu.png|Abrams with [[Ivy]] and a [[Trooper]] in the &amp;quot;Learn to play&amp;quot; menu art&lt;br /&gt;
File:Abrams new model.png|Work-in-progress new model&lt;br /&gt;
File:Abrams visual novel.png|Visual novel art&lt;br /&gt;
File:Abrams visual novel shirt.png|Visual novel art - without coat&lt;br /&gt;
File:Abrams Weapon.png|Weapon - Cold Case&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Gallery - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Trivia}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Trivia - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
* Abrams during &#039;&#039;Deadlock&#039;&#039; Pre-Alpha (&#039;&#039;[[Neon Prime]]&#039;&#039;) was named &#039;&#039;&#039;Atlas&#039;&#039;&#039;.&lt;br /&gt;
* Abrams is voiced by [[wikipedia:Samoa Joe|Samoa Joe]], a professional wrestler.&amp;lt;ref&amp;gt;[https://twitter.com/SamoaJoe/status/1837127627015958604 Samoa Joe on Twitter]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** Haze may call Abrams a &amp;quot;juggernaut&amp;quot;.&amp;lt;ref&amp;gt;{{VoiceLineCite|name=Haze|file=haze_enemy_atlas_unkillable_02.mp3|transcription=This man&#039;s a juggernaut!}}&amp;lt;/ref&amp;gt; Samoa Joe voiced the character &#039;&#039;&#039;Juggernaut&#039;&#039;&#039; in &#039;&#039;Dota Underlords&#039;&#039;.&lt;br /&gt;
* Abrams&#039; Tome contains a ripped page matching [[Oathkeeper|Oathkeeper&#039;s]] sign.&amp;lt;ref&amp;gt;[[The Binding of Oathkeeper|&#039;&#039;The Binding of Oathkeeper&#039;&#039;]] - [https://youtu.be/nn_C9nQ_Ri0?si=5PrfULMqVKUf-8tQ&amp;amp;t=894 Chapter 4B]&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Abrams&#039; Tome in game currently uses the textures from TF2&#039;s [https://wiki.teamfortress.com/wiki/Bombinomicon_(character) Bombinomicon.]&lt;br /&gt;
* In [[The Binding of Oathkeeper|&#039;&#039;The Binding of Oathkeeper&#039;&#039;]] artwork, Abrams has spikes on his back.&lt;br /&gt;
* Abrams was the only hero who had unique animations in the [[shop]] menu screen. These animations have been removed.&lt;br /&gt;
* Abrams was made slightly taller in an unlisted patch change around November 2024. Because of this, the top of his head is cut off in the shop menu and in the player profile screen.&lt;br /&gt;
* Abrams had a new work-in-progress model added to the game files in the [[Update:December 6, 2024|2024-12-06 Update]], and later removed. This model had more finished textures and a remodeled head with complete facial rigging, as well as an added tail. His badge was removed, indicating that he is not a police detective.&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Trivia - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;hidden&amp;quot;&amp;gt;{{Hero Navbox}}&amp;lt;/div&amp;gt;&amp;lt;!--viewed by desktop only--&amp;gt; &lt;br /&gt;
[[Category:Heroes]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Deadbot/blueprints?diff=18137</id>
		<title>User:Deadbot/blueprints</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Deadbot/blueprints?diff=18137"/>
		<updated>2024-12-29T19:35:10Z</updated>

		<summary type="html">&lt;p&gt;Sur: remove hero comparison&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All pages that utilize DeadBot have a blueprint, all of which are listed below:&lt;br /&gt;
* [[User:DeadBot/blueprints/Ability|/Ability]] i.e. [[Siphon Life]]&lt;br /&gt;
** [[User:DeadBot/blueprints/Ability/Notes|/Ability/Notes]] i.e. [[Siphon Life/Notes]]&lt;br /&gt;
* [[User:DeadBot/blueprints/Hero|/Hero]] i.e. [[Abrams]]&lt;br /&gt;
* [[User:DeadBot/blueprints/Item|/Item]] i.e. [[Basic Magazine]]&lt;br /&gt;
* [[User:DeadBot/blueprints/Tag/Update history|/Tag/Update history]] i.e. [[Abrams/Update history]], [[Basic Magazine/Update history]], [[Items/Update history]], see all Tags at [[Changelogs]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Deadbot/blueprints/Ability/Notes?diff=18131</id>
		<title>User:Deadbot/blueprints/Ability/Notes</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Deadbot/blueprints/Ability/Notes?diff=18131"/>
		<updated>2024-12-29T17:08:40Z</updated>

		<summary type="html">&lt;p&gt;Sur: another section/tag format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--EditFreely-Section:Notes - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&amp;lt;!--Each note should be prefixed with &amp;quot;*&amp;quot; to make it a bullet point, use multiple &amp;quot;**&amp;quot; to indent a layer--&amp;gt;&lt;br /&gt;
* Note 1&lt;br /&gt;
** Note 2&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Notes - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/Abrams?diff=18130</id>
		<title>User:Sur/Abrams</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/Abrams?diff=18130"/>
		<updated>2024-12-29T17:07:35Z</updated>

		<summary type="html">&lt;p&gt;Sur: i like this tag format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#vardefine:unlocalized|hero_atlas}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#vardefine:localized|{{#invoke:Lang|get_string|{{#var:unlocalized}}}}}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|guide_the_map_welcome_header|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_infobox|{{#var:unlocalized}}}}&lt;br /&gt;
&#039;&#039;&#039;Abrams&#039;&#039;&#039; is hard-boiled, hard-hitting bruiser of a character that focuses on engaging groups of enemies and relying on his fortitude and life drain to stay in the fight. With a powerful area stun and a devastating shoulder charge, Abrams can isolate fragile targets from the rest of the team and set-up his more damaging allies to finish them off. &lt;br /&gt;
&lt;br /&gt;
A capable and well-known detective of New York, Abrams solved crimes ranging from kidnappings to ritual murders. One day, a mysterious Tome was left on his desk with a note of &amp;quot;Don&#039;t let them have it&amp;quot; scrolled in Onyx blood; followed by car bombings and break-ins to his office. Now, Abrams is trying to figure out just what the hell is going on. &lt;br /&gt;
&amp;lt;!--[[User:DeadBot/Tags]]:Introduction End--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{#invoke:HeroData|write_role_playstyle_quote|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|item_info_abilities|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:AbilityData/hero|write_hero_abilities|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Stats}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_stat_infoboxes|{{#var:unlocalized}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelCategoryWeapon|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{WeaponCard|key={{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelHeroDetails_Background|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Quotation|&#039;&#039;&#039;{{#invoke:Lang|get_string|Citadel_HeroPage_FatesTale}}&#039;&#039;&#039;|{{#invoke:HeroData|get_hero_var|{{#var:unlocalized}}|Lore|true}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=-1}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuildDesc}}&lt;br /&gt;
{{#invoke:HeroData|write_default_items|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Update history}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Main|User:Sur/{{#var:localized}}/Update history|l1={{#invoke:Dictionary|translate|Update history}}}}&lt;br /&gt;
{{#invoke:Changelog|write_changelog_by_tag|{{#var:localized}}|3}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Trivia}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!--[[User:DeadBot/Tags]]:Trivia Start--&amp;gt;&lt;br /&gt;
* Abrams during &#039;&#039;Deadlock&#039;&#039; Pre-Alpha (&#039;&#039;Neon Prime&#039;&#039;) was named &#039;&#039;&#039;Atlas&#039;&#039;&#039;.&lt;br /&gt;
* Abrams is voiced by [[wikipedia:Samoa Joe|Samoa Joe]], a professional wrestler.&amp;lt;ref&amp;gt;[https://twitter.com/SamoaJoe/status/1837127627015958604 Samoa Joe on Twitter]&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Abrams&#039; Tome contains a ripped page matching [[Oathkeeper|Oathkeeper&#039;s]] sign.&amp;lt;ref&amp;gt;[https://youtu.be/nn_C9nQ_Ri0?si=5PrfULMqVKUf-8tQ&amp;amp;t=894 Lady Geist Full Novel] @ 14:54&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Abrams&#039; Tome in game currently uses the textures from TF2&#039;s [https://wiki.teamfortress.com/wiki/Bombinomicon_(character) Bombinomicon]&lt;br /&gt;
&amp;lt;!--[[User:DeadBot/Tags]]:Trivia End--&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;hidden&amp;quot;&amp;gt;{{Hero Navbox}}&amp;lt;/div&amp;gt;&amp;lt;!--viewed by desktop only--&amp;gt; &amp;lt;!--make this navbox dynamic to heroes list--&amp;gt;&lt;br /&gt;
[[Category:Heroes]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Sur/Abrams?diff=18129</id>
		<title>User:Sur/Abrams</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Sur/Abrams?diff=18129"/>
		<updated>2024-12-29T17:04:52Z</updated>

		<summary type="html">&lt;p&gt;Sur: testing another tag format&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#vardefine:unlocalized|hero_atlas}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{#vardefine:localized|{{#invoke:Lang|get_string|{{#var:unlocalized}}}}}}&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|guide_the_map_welcome_header|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!--EditFreely-Section-Start:Introduction - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_infobox|{{#var:unlocalized}}}}&lt;br /&gt;
&#039;&#039;&#039;Abrams&#039;&#039;&#039; is hard-boiled, hard-hitting bruiser of a character that focuses on engaging groups of enemies and relying on his fortitude and life drain to stay in the fight. With a powerful area stun and a devastating shoulder charge, Abrams can isolate fragile targets from the rest of the team and set-up his more damaging allies to finish them off. &lt;br /&gt;
&lt;br /&gt;
A capable and well-known detective of New York, Abrams solved crimes ranging from kidnappings to ritual murders. One day, a mysterious Tome was left on his desk with a note of &amp;quot;Don&#039;t let them have it&amp;quot; scrolled in Onyx blood; followed by car bombings and break-ins to his office. Now, Abrams is trying to figure out just what the hell is going on. &lt;br /&gt;
&amp;lt;!--[[User:DeadBot/Tags]]:Introduction End--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{#invoke:HeroData|write_role_playstyle_quote|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|item_info_abilities|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:AbilityData/hero|write_hero_abilities|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Stats}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:HeroData|write_stat_infoboxes|{{#var:unlocalized}}}}&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelCategoryWeapon|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{WeaponCard|key={{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|CitadelHeroDetails_Background|fallback_str=en}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Quotation|&#039;&#039;&#039;{{#invoke:Lang|get_string|Citadel_HeroPage_FatesTale}}&#039;&#039;&#039;|{{#invoke:HeroData|get_hero_var|{{#var:unlocalized}}|Lore|true}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuild|remove_var_index=-1}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{#invoke:Lang|get_string|Citadel_HeroBuilds_DefaultHeroBuildDesc}}&lt;br /&gt;
{{#invoke:HeroData|write_default_items|{{#var:unlocalized}}}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Update history}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
{{Main|User:Sur/{{#var:localized}}/Update history|l1={{#invoke:Dictionary|translate|Update history}}}}&lt;br /&gt;
{{#invoke:Changelog|write_changelog_by_tag|{{#var:localized}}|3}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;{{#invoke:Dictionary|translate|Trivia}}&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!--[[User:DeadBot/Tags]]:Trivia Start--&amp;gt;&lt;br /&gt;
* Abrams during &#039;&#039;Deadlock&#039;&#039; Pre-Alpha (&#039;&#039;Neon Prime&#039;&#039;) was named &#039;&#039;&#039;Atlas&#039;&#039;&#039;.&lt;br /&gt;
* Abrams is voiced by [[wikipedia:Samoa Joe|Samoa Joe]], a professional wrestler.&amp;lt;ref&amp;gt;[https://twitter.com/SamoaJoe/status/1837127627015958604 Samoa Joe on Twitter]&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Abrams&#039; Tome contains a ripped page matching [[Oathkeeper|Oathkeeper&#039;s]] sign.&amp;lt;ref&amp;gt;[https://youtu.be/nn_C9nQ_Ri0?si=5PrfULMqVKUf-8tQ&amp;amp;t=894 Lady Geist Full Novel] @ 14:54&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Abrams&#039; Tome in game currently uses the textures from TF2&#039;s [https://wiki.teamfortress.com/wiki/Bombinomicon_(character) Bombinomicon]&lt;br /&gt;
&amp;lt;!--[[User:DeadBot/Tags]]:Trivia End--&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;hidden&amp;quot;&amp;gt;{{Hero Navbox}}&amp;lt;/div&amp;gt;&amp;lt;!--viewed by desktop only--&amp;gt; &amp;lt;!--make this navbox dynamic to heroes list--&amp;gt;&lt;br /&gt;
[[Category:Heroes]]&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/User:Deadbot/blueprints/Ability/Notes?diff=18128</id>
		<title>User:Deadbot/blueprints/Ability/Notes</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/User:Deadbot/blueprints/Ability/Notes?diff=18128"/>
		<updated>2024-12-29T17:04:14Z</updated>

		<summary type="html">&lt;p&gt;Sur: testing section formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--EditFreely-Section-Start:Notes - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;br /&gt;
&amp;lt;!--Each note should be prefixed with &amp;quot;*&amp;quot; to make it a bullet point, use multiple &amp;quot;**&amp;quot; to indent a layer--&amp;gt;&lt;br /&gt;
* Note 1&lt;br /&gt;
** Note 2&lt;br /&gt;
&amp;lt;!--EditFreely-Section-End:Notes - Additional info available at [[User:DeadBot/Tags]]--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sur</name></author>
	</entry>
</feed>