From Dark and Darker Wiki
(Fixed weird ordering issues in ability statuses) |
(Variant color coding for Statuses column.) |
||
| Line 40: | Line 40: | ||
---@return string | ---@return string | ||
local function variant_coloring(common, elite, nightmare, unit) | local function variant_coloring(common, elite, nightmare, unit) | ||
unit = unit or "" | unit = unit or "" | ||
if is_suppressed(common, elite, nightmare) then | if is_suppressed(common, elite, nightmare) then | ||
return "<span style='color:"..suppressed_color.."'>"..tostring(common)..unit.."</span>" | |||
end | |||
local wikitext = "" | |||
if common then | |||
wikitext = tostring(common)..unit | |||
end | |||
if elite then | |||
if wikitext ~= "" then wikitext = wikitext.."/" end | |||
wikitext = wikitext.."<span class='colorrarityElite'>"..tostring(elite)..unit.."</span>" | |||
end | |||
if nightmare then | |||
if wikitext ~= "" then wikitext = wikitext.."/" end | |||
wikitext = wikitext.."<span class='colorrarityNightmare'>"..tostring(nightmare)..unit.."</span>" | |||
end | end | ||
return | return wikitext | ||
end | end | ||
| Line 84: | Line 83: | ||
for k, v in pairs(common.damageReductions) do | for k, v in pairs(common.damageReductions) do | ||
if wikitext ~= "" then wikitext = wikitext.."<br>" end | if wikitext ~= "" then wikitext = wikitext.."<br>" end | ||
-- color the key and strip suffixes for brevity | -- color the key and strip suffixes for brevity | ||
| Line 116: | Line 113: | ||
end | end | ||
return wikitext | return wikitext | ||
end | end | ||
| Line 149: | Line 135: | ||
local function statuses(common, elite, nightmare, highest_variant) | |||
local wikitext = "" | |||
local function statuses(common, elite, nightmare) | |||
local | |||
for i,status in ipairs(highest_variant.statuses) do | for i,status in ipairs(highest_variant.statuses) do | ||
if | if wikitext ~= "" then wikitext = wikitext.."<br>" end | ||
wikitext = wikitext.."<span style='color:"..neutral_color.."'>"..status.name..": </span>" | |||
..variant_coloring( | |||
common.statuses and common.statuses[i] and common.statuses[i].text, | |||
elite.statuses and elite.statuses[i] and elite.statuses[i].text, | |||
nightmare.statuses and nightmare.statuses[i] and nightmare.statuses[i].text | |||
).." " | |||
..variant_coloring( | |||
common.statuses and common.statuses[i] and policy_tooltips(common.statuses[i].policies), | |||
elite.statuses and elite.statuses[i] and policy_tooltips(elite.statuses[i].policies), | |||
nightmare.statuses and nightmare.statuses[i] and policy_tooltips(nightmare.statuses[i].policies) | |||
) | |||
end | end | ||
return | return wikitext | ||
end | end | ||
| Line 183: | Line 168: | ||
local impact_string = "" | local impact_string = "" | ||
if is_suppressed(common.impact, elite.impact, nightmare.impact) then | if is_suppressed(common.impact, elite.impact, nightmare.impact) then | ||
impact_string = "<span style='color:"..suppressed_color.."'> ("..tostring(common.impact)..") </span> " | impact_string = "<span style='color:"..suppressed_color.."'>("..tostring(common.impact)..") </span> " | ||
elseif common.impact then | elseif common.impact then | ||
impact_string = " ("..tostring(common.impact)..") " | impact_string = "("..tostring(common.impact)..") " | ||
end | end | ||
-- get values for each variant | -- get values for each variant | ||
return variant_coloring(common.value, elite.value, nightmare.value) | return variant_coloring(common.value, elite.value, nightmare.value) | ||
..impact_string | .." "..impact_string | ||
..variant_coloring(common.text, elite.text, nightmare.text) | ..variant_coloring(common.text, elite.text, nightmare.text) | ||
end | end | ||
| Line 215: | Line 200: | ||
wikitext = wikitext | wikitext = wikitext | ||
..process_effect( | ..process_effect( | ||
common.abilities[name].effects[k], | common.abilities and common.abilities[name] and common.abilities[name].effects[k] or {}, | ||
elite.abilities and elite.abilities[name] and elite.abilities[name].effects[k] or {}, | elite.abilities and elite.abilities[name] and elite.abilities[name].effects[k] or {}, | ||
nightmare.abilities and nightmare.abilities[name] and nightmare.abilities[name].effects[k] or {} | nightmare.abilities and nightmare.abilities[name] and nightmare.abilities[name].effects[k] or {} | ||
| Line 230: | Line 215: | ||
if wikitext ~= "" and k ~= 1 then wikitext = wikitext..", " end | if wikitext ~= "" and k ~= 1 then wikitext = wikitext..", " end | ||
wikitext = wikitext..variant_coloring( | wikitext = wikitext..variant_coloring( | ||
common.abilities[name].status_effects[k], | common.abilities and common.abilities[name] and common.abilities[name].status_effects[k], | ||
elite.abilities and elite.abilities[name] and elite.abilities[name].status_effects[k], | elite.abilities and elite.abilities[name] and elite.abilities[name].status_effects[k], | ||
nightmare.abilities and nightmare.abilities[name] and nightmare.abilities[name].status_effects[k] | nightmare.abilities and nightmare.abilities[name] and nightmare.abilities[name].status_effects[k] | ||
| Line 242: | Line 227: | ||
---@param elite table | ---@param elite table | ||
---@param nightmare table | ---@param nightmare table | ||
---@param highest_variant table | |||
--- @return string | --- @return string | ||
local function abilities(common, elite, nightmare | local function abilities(common, elite, nightmare, highest_variant) | ||
local wikitext = "" | local wikitext = "" | ||
| Line 274: | Line 256: | ||
---@return table | ---@return table elite | ||
---@return table | ---@return table nightmare | ||
---@return table highest_variant | |||
local function get_monster_variants(common) | local function get_monster_variants(common) | ||
local highest_variant = MD.monster.id[common.name] | |||
local elite = MD.monster.localized_name[common.name].Elite | local elite = MD.monster.localized_name[common.name].Elite | ||
local nightmare = MD.monster.localized_name[common.name].Nightmare | local nightmare = MD.monster.localized_name[common.name].Nightmare | ||
return MD.monster.id[elite] or {}, MD.monster.id[nightmare] or {} | if MD.monster.localized_name[common.name].Nightmare then | ||
highest_variant = MD.monster.id[nightmare] | |||
elseif MD.monster.localized_name[common.name].Elite then | |||
highest_variant = MD.monster.id[elite] | |||
end | |||
return MD.monster.id[elite] or {}, MD.monster.id[nightmare] or {}, highest_variant | |||
end | end | ||
| Line 288: | Line 276: | ||
---@return string | ---@return string | ||
local function row(common) | local function row(common) | ||
local elite, nightmare = get_monster_variants(common) | local elite, nightmare, highest_variant = get_monster_variants(common) | ||
-- TODO string concats like this aren't performant, consider table.concat. | -- TODO string concats like this aren't performant, consider table.concat. | ||
| Line 298: | Line 286: | ||
.."</div><div style='margin:auto; height:50%;'>"..variant_coloring(common.ap, elite.ap, nightmare.ap).."</td><td>" | .."</div><div style='margin:auto; height:50%;'>"..variant_coloring(common.ap, elite.ap, nightmare.ap).."</td><td>" | ||
..damage_reductions(common, elite, nightmare).."</td><td>" | ..damage_reductions(common, elite, nightmare).."</td><td>" | ||
..abilities(common, elite, nightmare).."</td><td>" | ..abilities(common, elite, nightmare, highest_variant).."</td><td>" | ||
..statuses(common, elite, nightmare).."</td><td>" | ..statuses(common, elite, nightmare, highest_variant).."</td><td>" | ||
..races(common).."</td><td>" | ..races(common).."</td><td>" | ||
..variant_coloring(common.actionspeed, elite.actionspeed, nightmare.actionspeed,"%").."</td></tr>" | ..variant_coloring(common.actionspeed, elite.actionspeed, nightmare.actionspeed,"%").."</td></tr>" | ||
Revision as of 02:13, 24 February 2026
Overview
Functions for making Monsters table. Data comes from Data:Monster.json.
Functions
draw_monster_table
Create's a table of monsters
Parameters
- 1 - list key of monsters to use
- 2 - is the list key a race?
Bosses
{{#invoke:Monster_Table|draw_table|bosses}}
| Name | Health | Move Speed | Exp AP |
Damage Reductions | Abilities' Damage(Impact Power) + Statuses | Statuses' Effects | Race | Action Speed |
|---|---|---|---|---|---|---|---|---|
| 2515/3315 | 320/360 | 12/15 50 | Physical: -22% Magical: 7.8% Projectile: 30% order: table%/table% Spirit: -100% Dark: -100% | Attack Slash12: 75.6/96.0 (6) Physical Attack Soul Slash Down: 201.6/256.0 (7) Physical Attack Rush Thrust: 107.1/136.0 (7) Physical order: Attack Long Range Vertically: 100.8/128.0 (7) Physical Attack Rush Thrust For Soul Slash: 107.1/136.0 (7) Physical Debuff Move Speed: -70 Move Speed Attack Front Thrust: 81.9/104.0 (6) Physical Attack Soul Slash Up: 201.6/256.0 (7) Physical Attack Soul Shockwave: 138.6/176.0 (7) Physical + Dead Rift Dmg, Dead Rift Move Slow Attack Slash11: 75.6/96.0 (6) Physical Attack Long Range Transverse: 100.8/128.0 (7) Physical Attack Shoulder Charge: 44.1/56.0 (6) Physical Attack Front Slash: 94.5/120.0 (7) Physical | Dead Rift Dmg: 5 Magical Damage [0.3s]Tick interval: 0.3s[AgT]Stacking Type: Aggregates by Target[Rmv]Removable[1x]Maximum Stacks: 1 Dead Rift Move Slow: -30% Move Speed [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1[Rmv]Removable | Undead-Ghost | 0%/10% | |
| 3615/7115 | 500 | 20/25 125 | Air: -200% Physical: -22% order: table%/table% Magical: 36.8% Projectile: 50% Fire: -25% Dark: -25% Ice: 50% | Buff Movespeed: 1000 Move Speed order: Special Leap Attack3 To Center: 83.6/132.0 (7) Physical + Melee Attack Slow Combo Tail Attack2: 68.4/108.0 (7) Physical + Melee Attack Slow Special Pushing: (999) Special Breath Ground: Extreme Cold Dmg, Extreme Cold Slow, Frost Shield To Breath Special Breath Air To Side: 60.8/96.0 (7) Physical, 45.6/72.0 (6) Physical Radius Combo Forward Attack L: 60.8/96.0 (7) Physical + Melee Attack Slow Combo Two Hand Attack: 76.0/120.0 (7) Physical + Melee Attack Slow Combo Leap Attack3: 83.6/132.0 (7) Physical + Melee Attack Slow Combo Breath Ground: 60.8/96.0 (7) Physical, 45.6/72.0 (6) Physical Radius Combo Leap Attack2: 60.8/96.0 (7) Physical, 45.6/72.0 (6) Physical Radius Combo Breath Air: 60.8/96.0 (7) Physical, 45.6/72.0 (6) Physical Radius Buff Movespeed Special: 2500 Move Speed Combo Tail Attack1: 57.0/90.0 (6) Physical + Melee Attack Slow Special Breath Air: Extreme Cold Dmg, Extreme Cold Slow Combo Forward Attack R: 60.8/96.0 (7) Physical + Melee Attack Slow Special Leap Attack1 To Center: 53.2/84.0 (7) Physical Special Summon Elemental: Frost Shield To Elemental Combo Leap Attack1: 53.2/84.0 (7) Physical + Melee Attack Slow | Melee Attack Slow: -15% Action Speed for 11s [AgT]Stacking Type: Aggregates by Target[3x]Maximum Stacks: 3[Rmv]Removable[Exp]Expiration: Removes Single Stack and Refreshes Duration Frost Shield To Elemental: Immune to Damage Extreme Cold Dmg: 50 Physical Damage, 50 Magical Damage over 2s/100 Physical Damage, 100 Magical Damage over 2s [0.2s]Tick interval: 0.2s[AgT]Stacking Type: Aggregates by Target[Rmv]Removable[1x]Maximum Stacks: 1 Extreme Cold Slow: -20% Move Speed, -20% Action Speed for 8s [AgT]Stacking Type: Aggregates by Target[3x]Maximum Stacks: 3[Rmv]Removable[Exp]Expiration: Removes Single Stack and Refreshes Duration Frost Shield To Breath: Immune to Damage | Dragon-Wyvern | 0% | |
| 4115/7115 | 400 | 15/20 50 | Physical: -22% Magical: 36.8% order: table%/table% Spirit: -50% Lightning: 50% | Swim L: 79.8/126.0 (6) Physical Short Dash: 34.2/54.0 (6) Physical Tail Slash High: 72.2/114.0 (5) Physical, 68.4/108.0 (5) Physical + Tail Poison Water Arrow1: 60.8/96.0 (6) Physical Swim R1500: 79.8/126.0 (6) Physical Turning Water Arrow2 L: 60.8/96.0 (6) Physical Rush Falling Rock: 24.0 Physical Lightning Bubble: Lightning Bubble Dmg, Lightning Bubble Dmg Water Arrow2: 49.4/78.0 (6) Physical order: Rush Lightning: 34.2/54.0 Physical Divine Judgment: 114.0/180.0 (6) Physical Turning Water Arrow R: 60.8/96.0 (6) Physical Rush: 64.6/102.0 (4) Physical Move Spawn Location Start: 22.8/36.0 (4) Physical Swim R: 79.8/126.0 (6) Physical Tail Slash Down: 68.4/108.0 (5) Physical, 68.4/108.0 (5) Physical + Tail Poison Dash End: 22.8/36.0 (4) Physical Swim L1500: 79.8/126.0 (6) Physical Pop Out: 45.6/72.0 (6) Physical Lightning Nova: 304.0/480.0 (6) Physical Tail Attack Up: 72.2/114.0 (5) Physical, 72.2/114.0 (5) Physical + Tail Poison Dash: 22.8/36.0 (4) Physical Tail Attack Down: 76.0/120.0 (5) Physical, 76.0/120.0 (5) Physical + Tail Poison Turning Water Arrow2 R: 60.8/96.0 (6) Physical Turning Water Arrow L: 60.8/96.0 (6) Physical | Lightning Bubble Dmg: 7 Magical Damage Tail Poison: 20 Magical Damage over 30s [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1[Ref]Refresh: Resets on Successful Application | Beast-Aquatic | -12%/0% | |
| 2215/3115 | 250/300 | 15 50 | order: table%/table% Physical: [3%]0 Armor Rating and 25% Other Physical Light: -100% Magical: 7.8% Projectile: -25% Fire: 50% Spirit: -100% Ice: 50% | order: Bombing Spawn Fog Missile: 50.4/67.2 (6) Magical Scream Sentence: 10.8/14.4 (6) Magical Fog Rush: 57.6/76.8 (7) Magical Fog Attack2: 79.2/105.6 (7) Magical Hide Attack: 64.8/86.4 (7) Magical Pull: 54.0/72.0 (6) Magical Fog Attack1: 50.4/67.2 (6) Magical | Undead-Ghost | 0% | ||
| 2990/3980/4515 | 250/280/300 | 12/15/18 50 | Earth: -100% Physical: -22% order: table%/table%/table% Magical: 7.8% Projectile: 40% Fire: 50% Evil: 50% Dark: -200% | Attack Ground Combo: 100.0/110.0/120.0 (7) Physical, 70.0/77.0/84.0 (7) Physical Radius + Slow Attack Ground: 100.0/110.0/120.0 (7) Physical, 70.0/77.0/84.0 (7) Physical Radius + Slow Attack Punch Down: 80.0/88.0/96.0 (7) Physical, 17.0/18.7/20.4 (7) Physical Radius + Slow Combo Head Up: 180.0/198.0/216.0 (7) Physical + Slow Attack Spinning Low: 200.0/220.0/240.0 (7) Physical + Slow Combo Right To Left: 110.0/121.0/132.0 (7) Physical + Slow order: Combo Punch Down: 80.0/88.0/96.0 (7) Physical, 17.0/18.7/20.4 (7) Physical Radius + Slow Attack Spinning High: 200.0/220.0/240.0 (7) Physical + Slow Regeneration: Regeneration Debuff Shouting: Slow Add Impact Power: (999) Combo Left To Right: 150.0/165.0/180.0 (7) Physical + Slow Combo Slap: 145.0/159.5/174.0 (7) Physical, 20.0/22.0/24.0 (7) Physical Radius + Slow | Regeneration: 2 Physical Heal per 1s [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1 Slow: -35% Move Speed for 4s [Rmv]Removable | Troll-Humanoid | 0% | |
| 2656/3646 | 200/270 | 15/20 100 | Physical: -22% Magical: 36.8% Projectile: 25% Evil: 50% order: table%/table% Divine: -100% | Curse Of Chilling: Curse Of Chilling Teleport: 20 (5) Magical + Curse Of Chilling Normal Attack: 30 (7) Magical + Curse Of Chilling order: Eating Snare: Eating Earth Quake: 120.0/60.0 (6) Physical/Magical + Curse Of Chilling Scream: -45% (4) True Max Health + Curse Of Chilling Normal Attack Return: Curse Of Chilling Eating Apply And Remove Shield: Eating Shield | Curse Of Chilling: -1.6% Move Speed for 8s [AgT]Stacking Type: Aggregates by Target[30x]Maximum Stacks: 30[Rmv]Removable Eating Shield: 1000 Shield [AgT]Stacking Type: Aggregates by Target Eating: -95% Max Health, Unable to Move over 15s [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1[Rmv]Removable[Ref]Refresh: Resets on Successful Application | Undead-Ghost | 0% | |
| 2115/3015 | 200/250 | 15/20 100 | Physical: -22% Magical: 36.8% Projectile: 25% Evil: 50% order: table%/table% Divine: -25% | order: Getting Soul: Soul Shield Curse Of Gathering Mark: -50% (4) True Max Health, -15% (4) True Max Health, -95% (4) True Max Health, -5% (4) True Max Health, -2% (4) True Max Health + CoG Heal1, CoG Heal2, CoG Heal3, CoG Heal4, CoG Heal5 Close Attack: 70 (5) Magical Normal Attack: 100 (5) Magical Frenzy: Death Swarm, Frenzy Curse Of Isolation Mark: -70% (4) True Max Health, -90% (4) True Max Health, -50% (4) True Max Health, -150% (4) True Max Health, -250% (4) True Max Health + CoI Heal1, CoI Heal2, CoI Heal3, CoI Heal4, CoI Heal5 Strong Attack: 200 (7) Magical | CoG Heal1: 65% Max Health over 20s [Rmv]Removable CoG Heal2: 35% Max Health over 20s [Rmv]Removable CoG Heal3: 10% Max Health over 20s [Rmv]Removable CoG Heal4: 4% Max Health over 20s [Rmv]Removable CoG Heal5: 2% Max Health over 20s [Rmv]Removable CoI Heal1: 35% Max Health over 20s [Rmv]Removable CoI Heal2: 50% Max Health over 20s [Rmv]Removable CoI Heal3: 60% Max Health over 20s [Rmv]Removable CoI Heal4: 100% Max Health over 20s [Rmv]Removable CoI Heal5: 170% Max Health over 20s [Rmv]Removable Soul Shield: 250 Shield [AgT]Stacking Type: Aggregates by Target[Rmv]Removable Death Swarm: 4 True Magical Damage [AgT]Stacking Type: Aggregates by Target[5x]Maximum Stacks: 5[Ref]Refresh: Resets on Successful Application Frenzy: 25 Move Speed, 50% Action Speed [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1 | Undead-Lich | 0% | |
| 4251/6308 | 250/280 | 12/15 50 | order: table%/table% Physical: -22% Evil: 50% Magical: 7.8% Projectile: 30% Fire: 50% Dark: -25% Light: -200% | Run And Swing: 88.0/106.0 (7) Physical Stomp: 193.6/233.2 (7) Physical + Slow order: Combo1: 96.8/116.6 (7) Physical Riot: 158.4/190.8 (7) Physical Combo2: 140.8/169.6 (7) Physical Combo3: 132.0/159.0 (7) Physical + Blinker Sprinkle Soil: 149.6/180.2 (7) Physical + Blinker Petrification: Petrification Spawn Falling Rock: 17.6/21.2 (4) Physical | Blinker: Blinded by dirt for 10s [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1[Rmv]Removable Slow: -50% Move Speed for 8s [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1[Rmv]Removable Petrification: Unable to Move, Unable to Attack for 6s [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1[Rmv]Removable | Cyclops-Humanoid | -20% | |
| 233 | 180 | 0 1 | Earth: -300% Physical: -22% order: table% Magical: -17.2% Projectile: 15% Fire: -250% Evil: 25% Divine: -200% | Back Step: 67.5 (4) Physical order: Throwing Knife: 43.2 (3) Physical Soul Pass: Skeleton Warlord Speed Up Bombing: 108.0 (5) Physical Attack: 43.2 (3) Physical | Skeleton Warlord Speed Up: 4% Move Speed, 1% Action Speed, 2% Physical Resistance, 1% Magical Resistance [AgT]Stacking Type: Aggregates by Target[25x]Maximum Stacks: 25 | Undead-Skeleton | 0% | |
| 2715/3615 | 260/280 | 15/20 50 | Physical: -22% Magical: 7.8% Projectile: 30% Fire: 50% Spirit: -20% order: table%/table% | Slash Low: 88.2/112.0 (7) Physical Attack Fire Sparks In: 100.8/128.0 (7) Physical Ballista Shockwave: 50.4/64.0 (7) Physical Thrust: 88.2/112.0 (7) Physical Upper Slash: 81.9/104.0 (7) Physical Slash High Short: 88.2/112.0 (7) Physical Cannon Fire Long: 100.8/128.0 (7) Physical order: Reflect Melee: 94.5/120.0 (7) Physical Rush Attack: 88.2/112.0 (7) Physical Ballista Falling: 100.8/128.0 (7) Physical Rush End: 88.2/112.0 (7) Physical Attack Fire Sparks Out: 100.8/128.0 (7) Physical Blade Down: 69.3/88.0 (2) Physical Blade Slash Short: 69.3/88.0 (2) Physical Slash R: 81.9/104.0 (7) Physical Blade Slash: 69.3/88.0 (2) Physical Rush Slash High: 88.2/112.0 (7) Physical Upper Slash Cannon: 81.9/104.0 (7) Physical Blade Down Short: 69.3/88.0 (2) Physical Slash High: 88.2/112.0 (7) Physical Attack Down Slash: 81.9/104.0 (7) Physical Blade Vertical Slash: 69.3/88.0 (2) Physical Attack Overhead Slash: 63.0/80.0 (7) Physical, 44.1/56.0 (7) Physical Slash L: 81.9/104.0 (7) Physical Rush Slash Low: 88.2/112.0 (7) Physical Cannon Fire: 100.8/128.0 (7) Physical | Human-Humanoid | 10%/15% | ||
| 7115/9615 | 230/240 | 15/20 50 | order: table%/table% Physical: -22% Lightning: 20% Magical: 7.8% Projectile: 30% Fire: 70% Spirit: -20% Ice: -70% | Melee Face Down Slam Front: 110.5/119.0 (7) Physical, 26.0/28.0 (7) Physical + Lava Burn Dmg Melee Looking Left Swing120: 84.5/91.0 (7) Physical Melee Looking Right Swing60 Phase2: 84.5/91.0 (7) Physical Melee Looking Left Swing120 Phase2: 84.5/91.0 (7) Physical Melee Right Hand Cross Swing Phase2: 104.0/112.0 (7) Physical order: Base Ground Explosion: 52.0/56.0 (7) Physical + Lava Burn Dmg Melee Right Hand Cross Swing: 104.0/112.0 (7) Physical Melee Face Down Slam Back: 110.5/119.0 (7) Physical, 26.0/28.0 (7) Physical + Lava Burn Dmg Action Lava Eruption: 97.5/105.0 (7) Physical + Lava Burn Dmg Melee Looking Right Swing180 Phase2: 84.5/91.0 (7) Physical Melee Looking Right Swing120 Phase2: 84.5/91.0 (7) Physical Melee Two Hands Ground Strike: 110.5/119.0 (7) Physical, 52.0/56.0 (7) Physical + Lava Burn Dmg Melee Right Foot Stomping: 110.5/119.0 (7) Physical, 39.0/42.0 (7) Physical + Lava Burn Dmg Melee Looking Right Swing180: 84.5/91.0 (7) Physical Melee Looking Left Swing180: 84.5/91.0 (7) Physical Melee Looking Left Swing180 Phase2: 84.5/91.0 (7) Physical Melee Face Down Slam Left: 110.5/119.0 (7) Physical, 26.0/28.0 (7) Physical + Lava Burn Dmg Melee Looking Right Swing120: 84.5/91.0 (7) Physical Melee Looking Left Swing60 Phase2: 84.5/91.0 (7) Physical Melee Looking Left Swing60: 84.5/91.0 (7) Physical Melee Looking Right Swing60: 84.5/91.0 (7) Physical Melee Right Hand Forward Swing Phase2: 84.5/91.0 (7) Physical Melee Face Down Slam Right: 110.5/119.0 (7) Physical, 26.0/28.0 (7) Physical + Lava Burn Dmg Melee Right Hand Forward Swing: 84.5/91.0 (7) Physical | Lava Burn Dmg: 15 Magical Damage over 5s [AgT]Stacking Type: Aggregates by Target[1x]Maximum Stacks: 1[Rmv]Removable | Construct-Golem | 0%/10% | |
| 2959/4359 | 250/280 | 15/20 100 | Earth: -100% Physical: -22% Magical: 36.8% Projectile: 25% Evil: 50% order: table%/table% | Throwing Knives: 60.8/91.2 (7) Magical + Paralyze Combo4: 60.8/91.2 (7) Magical Shield: Shield Combo1: 48.0/72.0 (7) Magical Explosion: 384.0 Magical Throwing Knives2: 25.6/38.4 (3) Magical + Paralyze Combo2: 57.6/86.4 (7) Magical order: Attack Block Explosion Dmg: 48.0 Magical Combo5: 60.8/91.2 (7) Magical Combo3: 70.4/105.6 (7) Magical | Paralyze: -15% Move Speed for 15s [AgT]Stacking Type: Aggregates by Target[5x]Maximum Stacks: 5[Rmv]Removable Shield: Immune to Damage [Inf]Duration: Infinite | Undead-Skeleton | 0% | |
| ? | 100 | 0 0 | Projectile: 15% Physical: -22% order: table% Magical: 7.8% | Beam Attack: 6.0 (7) Magical order: | 0% |
Demons
{{#invoke:Monster_Table|draw_table|Demon|true}}
Lua error at line 217: attempt to index field 'status_effects' (a nil value).
local p = {}
local MD = mw.loadJsonData("Data:Monster.json")
local suppressed_color = "#1A91C4"
local neutral_color = "#EEE8"
---Check existence and equality of common and elite and nightmare variants
---@param common any
---@param elite any
---@param nightmare any
---@return boolean
local function is_suppressed(common, elite, nightmare)
if common and common == elite then
if nightmare then
if elite == nightmare then
return true
end
else
return true
end
end
return false
end
---Create css/html wikitext for iconbox
---@param name string
---@return string
local function iconbox(name)
return "<div class='iconbox'><div class='rarity-1 rounded relative'>[[File:"..name..".png|x80px|link="..name.."]]</div><br>[["..name.."|<b class=rarity-1>"..name.."</b>]]</div>"
end
---Create color coded string for common/elite/nightmare variants, if they exist.
---- If more than one variant exists, and they are all the same, color code as suppressed.
---- If only one variant exists, just return that variant with appopriate rarity color coding.
---@param common any
---@param elite any
---@param nightmare any
---@param unit any
---@return string
local function variant_coloring(common, elite, nightmare, unit)
unit = unit or ""
if is_suppressed(common, elite, nightmare) then
return "<span style='color:"..suppressed_color.."'>"..tostring(common)..unit.."</span>"
end
local wikitext = ""
if common then
wikitext = tostring(common)..unit
end
if elite then
if wikitext ~= "" then wikitext = wikitext.."/" end
wikitext = wikitext.."<span class='colorrarityElite'>"..tostring(elite)..unit.."</span>"
end
if nightmare then
if wikitext ~= "" then wikitext = wikitext.."/" end
wikitext = wikitext.."<span class='colorrarityNightmare'>"..tostring(nightmare)..unit.."</span>"
end
return wikitext
end
---Create tooltip wikitext
---@param color string
---@param display_text string
---@param tooltip_text string
---@return string
local function tooltip(color, display_text, tooltip_text)
if color == "" or color == nil then color = " style='color:"..color.."'" end
return "<span class='tooltip'"..color.."><u>["..tostring(display_text).."]</u><span class='tooltiptext-right'>"..tooltip_text.."</span></span>"
end
---Create color coded string of damage reductions
---- Assumes policy text is invariant
---@param common table
---@param elite table
---@param nightmare table
--- @return string
local function damage_reductions(common, elite, nightmare)
local wikitext = ""
for k, v in pairs(common.damageReductions) do
if wikitext ~= "" then wikitext = wikitext.."<br>" end
-- color the key and strip suffixes for brevity
wikitext = wikitext.."<span style='color:"..neutral_color.."'>"..k:gsub(" Damage Reduction",""):gsub(" Magical",""):gsub(" Physical","")..": </span>"
-- Asterisk indicates presence of policy text, which needs a tooltip.
if tostring(v):find("*") then
local color = ""
if is_suppressed(v, elite.damageReductions and elite.damageReductions[k], nightmare.damageReductions and nightmare.damageReductions[k]) then
color = " style='color:"..suppressed_color.."'"
end
wikitext = wikitext
..tooltip(
color,
variant_coloring(
tostring(v):match("^(.*)%*"),
tostring(elite.damageReductions and elite.damageReductions[k]):match("^(.*)%*"),
tostring(nightmare.damageReductions and nightmare.damageReductions[k]):match("^(.*)%*"),"%"
),
tostring(v):match("%*(.*)$")
)
else
wikitext = wikitext
..variant_coloring(
v,
elite.damageReductions and elite.damageReductions[k],
nightmare.damageReductions and nightmare.damageReductions[k],"%"
)
end
end
return wikitext
end
---Convert a string of policy keys into tooltipped wikitext
---@param policies table
---@return string
local function policy_tooltips(policies)
if policies == "" or policies == nil then return "" end
local wikitext = ""
for _,policy in pairs(policies) do
wikitext = wikitext
..tooltip(
"",
MD.policies[policy],
policy
)
end
return wikitext
end
local function statuses(common, elite, nightmare, highest_variant)
local wikitext = ""
for i,status in ipairs(highest_variant.statuses) do
if wikitext ~= "" then wikitext = wikitext.."<br>" end
wikitext = wikitext.."<span style='color:"..neutral_color.."'>"..status.name..": </span>"
..variant_coloring(
common.statuses and common.statuses[i] and common.statuses[i].text,
elite.statuses and elite.statuses[i] and elite.statuses[i].text,
nightmare.statuses and nightmare.statuses[i] and nightmare.statuses[i].text
).." "
..variant_coloring(
common.statuses and common.statuses[i] and policy_tooltips(common.statuses[i].policies),
elite.statuses and elite.statuses[i] and policy_tooltips(elite.statuses[i].policies),
nightmare.statuses and nightmare.statuses[i] and policy_tooltips(nightmare.statuses[i].policies)
)
end
return wikitext
end
---Check for consistency across variants and format string of an ability's effects
---@param common table
---@param elite table
---@param nightmare table
---@return string
local function process_effect(common, elite, nightmare)
-- check for consistency across variants
if next(elite) and (common.impact ~= elite.impact) or (next(nightmare) and (common.impact ~= nightmare.impact)) then
return "<span color='red'>Error: Impact power differs across variants.</span>"
end
local impact_string = ""
if is_suppressed(common.impact, elite.impact, nightmare.impact) then
impact_string = "<span style='color:"..suppressed_color.."'>("..tostring(common.impact)..") </span> "
elseif common.impact then
impact_string = "("..tostring(common.impact)..") "
end
-- get values for each variant
return variant_coloring(common.value, elite.value, nightmare.value)
.." "..impact_string
..variant_coloring(common.text, elite.text, nightmare.text)
end
--- Assumptions
---- If the variants exists, lower variants have a subset of higher variant ability set.
---- An ability, if present, has identical names across variants. Strings associated with an Ability can vary. Order of abilities matters.
---- Important ability values that vary by variant type are followed by the "#" token.
---- Statuses applied by an ability are preceded by the "$" token.
---- Impact Power of an ability is invariant.
--- @param name string
--- @param common table
--- @param elite table
--- @param nightmare table
--- @param highest_variant table
--- @return string
local function process_ability(name, common, elite, nightmare, highest_variant)
local wikitext = ""
if highest_variant.abilities[name].effects then
for k,_ in pairs(highest_variant.abilities[name].effects) do
if wikitext ~= "" then wikitext = wikitext..", " end
wikitext = wikitext
..process_effect(
common.abilities and common.abilities[name] and common.abilities[name].effects[k] or {},
elite.abilities and elite.abilities[name] and elite.abilities[name].effects[k] or {},
nightmare.abilities and nightmare.abilities[name] and nightmare.abilities[name].effects[k] or {}
)
end
end
if not highest_variant.abilities[name].status_effects then
return wikitext
end
if wikitext ~= "" then wikitext = wikitext.." + " end
for k,_ in ipairs(highest_variant.abilities[name].status_effects) do
if wikitext ~= "" and k ~= 1 then wikitext = wikitext..", " end
wikitext = wikitext..variant_coloring(
common.abilities and common.abilities[name] and common.abilities[name].status_effects[k],
elite.abilities and elite.abilities[name] and elite.abilities[name].status_effects[k],
nightmare.abilities and nightmare.abilities[name] and nightmare.abilities[name].status_effects[k]
)
end
return wikitext
end
---Create color coded string of abilities
---@param common table
---@param elite table
---@param nightmare table
---@param highest_variant table
--- @return string
local function abilities(common, elite, nightmare, highest_variant)
local wikitext = ""
for k, v in pairs(highest_variant.abilities) do
if wikitext ~= "" then wikitext = wikitext.."<br>" end
wikitext = wikitext.."<span style='color:"..neutral_color.."'>"..k..": </span>"
..process_ability(k, common, elite, nightmare, highest_variant)
end
return wikitext
end
---Hyphen seperated list of hyperlinked races. Assumes all variants same races.
---@param common table
---@return string
local function races(common)
local wikitext = ""
for k,v in pairs(common.races) do
if wikitext ~= "" then wikitext = wikitext.."-" end
wikitext = wikitext.."[["..k.."]]"
end
return wikitext
end
---@return table elite
---@return table nightmare
---@return table highest_variant
local function get_monster_variants(common)
local highest_variant = MD.monster.id[common.name]
local elite = MD.monster.localized_name[common.name].Elite
local nightmare = MD.monster.localized_name[common.name].Nightmare
if MD.monster.localized_name[common.name].Nightmare then
highest_variant = MD.monster.id[nightmare]
elseif MD.monster.localized_name[common.name].Elite then
highest_variant = MD.monster.id[elite]
end
return MD.monster.id[elite] or {}, MD.monster.id[nightmare] or {}, highest_variant
end
---Create a table row for a monster and its variants
---@param common table
---@return string
local function row(common)
local elite, nightmare, highest_variant = get_monster_variants(common)
-- TODO string concats like this aren't performant, consider table.concat.
return "<tr><td>"
..iconbox(common.name).."</td><td>"
..variant_coloring(common.hp, elite.hp, nightmare.hp).."</td><td>"
..variant_coloring(common.move, elite.move, nightmare.move).."</td><td>"
.."<div style='margin:auto; height:50%;'>"..variant_coloring(common.xp, elite.xp, nightmare.xp) --TODO the div automargin doesn't work as intended. Need to center vertically while splitting the cell in half.
.."</div><div style='margin:auto; height:50%;'>"..variant_coloring(common.ap, elite.ap, nightmare.ap).."</td><td>"
..damage_reductions(common, elite, nightmare).."</td><td>"
..abilities(common, elite, nightmare, highest_variant).."</td><td>"
..statuses(common, elite, nightmare, highest_variant).."</td><td>"
..races(common).."</td><td>"
..variant_coloring(common.actionspeed, elite.actionspeed, nightmare.actionspeed,"%").."</td></tr>"
end
--- @param frame table: frame args
---- frame.args[1] string: {"bosses", "minibosses", "mimics", "normal"} or a race list like {"Demon", "Undead", ...
---- frame.args[2] bool or string: determines if the first key is a race list
--- @return table: ordered list of monster ids
local function get_monster_list(frame)
local key = frame.args[1] ~= nil and frame.args[1] or "all"
local is_race_list = frame.args[2] ~= nil and frame.args[2]
if is_race_list then
return MD.races[key]
else
return MD[key]
end
end
---Create monster table wikitext
---- Test on wiki with: mw.log(p.draw_table({args={"bosses"}})) or mw.log(p.draw_table({args={"Demon","true"}}))
---@param frame table
--- @return string
function p.draw_table(frame)
if not MD then return "<span style='color:red;'>Error: Could not load Monster data in [[Module:Monster Table]]</span>" end
local wikitext = [===[<table cellspacing="0" class="wikitable sortable jquery-tablesorter" style="width:100%;color:#eee; background:transparent; text-align:center; vertical-align:middle;"><tr>
<th style="width:3%">Name</th>
<th style="width:3%">Health</th>
<th style="width:3%">Move Speed</th>
<th style="width:3%">Exp<br>AP</th>
<th style="width:3%">Damage Reductions</th>
<th style="width:17%">Abilities' Damage([[Impact Power]]) + Statuses</th>
<th style="width:22%">[[Statuses]]' Effects</th>
<th style="width:3%">Race</th>
<th style="width:3%">Action Speed</th></tr>]===]
local monster_list = get_monster_list(frame)
for _, monster_key in pairs(monster_list) do
wikitext = wikitext..row(MD.monster.id[monster_key])
end
return wikitext.."</table>"
end
return p