Difference between revisions of "Module:Monster"
(Death knight needs disambiguation) |
(Monsters with spell includes damage. Also some refactoring) |
||
| Line 165: | Line 165: | ||
local lich_spells = { | local lich_spells = { | ||
| − | ["Corrosive Bolt"] = | + | ["Corrosive Bolt"] = true, |
| − | ["Lehudib's Crystal Spear"] = | + | ["Lehudib's Crystal Spear"] = true, |
| − | ["Orb of Destruction"] = | + | ["Orb of Destruction"] = true, |
["Summon Greater Demon"] = 50, | ["Summon Greater Demon"] = 50, | ||
["Banishment"] = 33.3, | ["Banishment"] = 33.3, | ||
["Haste"] = 33.3, | ["Haste"] = 33.3, | ||
["Invisibility"] = 33.3, | ["Invisibility"] = 33.3, | ||
| − | ["Agony"] = | + | ["Agony"] = true, |
| − | ["Bolt of Cold"] = | + | ["Bolt of Cold"] = true, |
| − | ["Bolt of Draining"] = | + | ["Bolt of Draining"] = true, |
| − | ["Bolt of Fire"] = | + | ["Bolt of Fire"] = true, |
| − | ["Confuse"] = | + | ["Confuse"] = true, |
| − | ["Fireball"] = | + | ["Fireball"] = true, |
| − | ["Haunt"] = | + | ["Haunt"] = true, |
| − | ["Iron Shot"] = | + | ["Iron Shot"] = true, |
| − | ["Iskenderun's Mystic Blast"] = | + | ["Iskenderun's Mystic Blast"] = true, |
| − | ["Iskenderun's Battlesphere"] = | + | ["Iskenderun's Battlesphere"] = true, |
| − | ["Lee's Rapid Deconstruction"] = | + | ["Lee's Rapid Deconstruction"] = true, |
| − | ["Lightning Bolt"] = | + | ["Lightning Bolt"] = true, |
| − | ["Malign Gateway"] = | + | ["Malign Gateway"] = true, |
| − | ["Paralyse"] = | + | ["Paralyse"] = true, |
| − | ["Petrify"] = | + | ["Petrify"] = true, |
| − | ["Poison Arrow"] = | + | ["Poison Arrow"] = true, |
| − | ["Spellforged Servitor"] = | + | ["Spellforged Servitor"] = true, |
| − | ["Simulacrum"] = | + | ["Simulacrum"] = true, |
| − | ["Sleep"] = | + | ["Sleep"] = true, |
| − | ["Slow"] = | + | ["Slow"] = true, |
| − | ["Summon Horrible Things"] = | + | ["Summon Horrible Things"] = true, |
| − | ["Throw Icicle"] = | + | ["Throw Icicle"] = true, |
} | } | ||
local panlord_spells = { | local panlord_spells = { | ||
| − | ["Fire Storm"] = | + | ["Fire Storm"] = true, |
| − | Glaciate = | + | Glaciate = true, |
| − | ["Lehudib's Crystal Spear"] = | + | ["Lehudib's Crystal Spear"] = true, |
| − | ["Chain Lightning"] = | + | ["Chain Lightning"] = true, |
| − | ["Orb of Destruction"] = | + | ["Orb of Destruction"] = true, |
| − | ["Corrosive Bolt"] = | + | ["Corrosive Bolt"] = true, |
| − | ["Disintegrate"] = | + | ["Disintegrate"] = true, |
| − | ["Bolt of Fire"] = | + | ["Bolt of Fire"] = true, |
| − | ["Bolt of Cold"] = | + | ["Bolt of Cold"] = true, |
| − | ["Iron Shot"] = | + | ["Iron Shot"] = true, |
| − | ["Poison Arrow"] = | + | ["Poison Arrow"] = true, |
| − | ["Bolt of Draining"] = | + | ["Bolt of Draining"] = true, |
| − | ["Quicksilver Bolt"] = | + | ["Quicksilver Bolt"] = true, |
| − | ["Force Lance"] = | + | ["Force Lance"] = true, |
| − | Fireball = | + | Fireball = true, |
| − | ["Bolt of Magma"] = | + | ["Bolt of Magma"] = true, |
| − | ["Lee's Rapid Deconstruction"] = | + | ["Lee's Rapid Deconstruction"] = true, |
| − | ["Lightning Bolt"] = | + | ["Lightning Bolt"] = true, |
| − | Blinkbolt = | + | Blinkbolt = true, |
| − | ["Venom Bolt"] = | + | ["Venom Bolt"] = true, |
| − | Agony = | + | Agony = true, |
| − | Sleep = | + | Sleep = true, |
| − | ["Iskendrun's Mystic Blast"] = | + | ["Iskendrun's Mystic Blast"] = true, |
| − | ["Sticky Flame Range"] = | + | ["Sticky Flame Range"] = true, |
| − | ["Steam Ball"] = | + | ["Steam Ball"] = true, |
| − | ["Throw Icicle"] = | + | ["Throw Icicle"] = true, |
| − | Airstrike = | + | Airstrike = true, |
| − | Smiting = | + | Smiting = true, |
| − | ["Dazzling Spray"] = | + | ["Dazzling Spray"] = true, |
| − | ["Stone Arrow"] = | + | ["Stone Arrow"] = true, |
| − | ["Static Discharge"] = | + | ["Static Discharge"] = true, |
| − | ["Vampiric Draining"] = | + | ["Vampiric Draining"] = true, |
| − | ["Throw Flame"] = | + | ["Throw Flame"] = true, |
| − | ["Throw Frost"] = | + | ["Throw Frost"] = true, |
| − | ["Summon Demon"] = | + | ["Summon Demon"] = true, |
| − | ["Summon Dragon"] = | + | ["Summon Dragon"] = true, |
| − | ["Summon Horrible Things"] = | + | ["Summon Horrible Things"] = true, |
| − | ["Summon Greater Demon"] = | + | ["Summon Greater Demon"] = true, |
| − | Haunt = | + | Haunt = true, |
| − | ["Summon Hydra"] = | + | ["Summon Hydra"] = true, |
| − | ["Malign Gateway"] = | + | ["Malign Gateway"] = true, |
| − | Haste = | + | Haste = true, |
| − | Invisibility = | + | Invisibility = true, |
| − | ["Symbol of Torment"] = | + | ["Symbol of Torment"] = true, |
| − | ["Monstrous Menagerie"] = | + | ["Monstrous Menagerie"] = true, |
| − | Silence = | + | Silence = true, |
| − | ["Shadow Creatures"] = | + | ["Shadow Creatures"] = true, |
| − | ["Summon Vermin"] = | + | ["Summon Vermin"] = true, |
| − | ["Summon Swarm"] = | + | ["Summon Swarm"] = true, |
| − | ["Iskenderun's Battlesphere"] = | + | ["Iskenderun's Battlesphere"] = true, |
| − | ["Fulminant Prism"] = | + | ["Fulminant Prism"] = true, |
| − | ["Summon Ice Beast"] = | + | ["Summon Ice Beast"] = true, |
| − | Swiftness = | + | Swiftness = true, |
| − | Blink = | + | Blink = true, |
| − | ["Summon Butterflies"] = | + | ["Summon Butterflies"] = true, |
| − | Shatter = | + | Shatter = true, |
| − | Banishment = | + | Banishment = true, |
| − | ["Freezing Cloud"] = | + | ["Freezing Cloud"] = true, |
| − | ["Poisonous Cloud"] = | + | ["Poisonous Cloud"] = true, |
| − | ["Mass Confusion"] = | + | ["Mass Confusion"] = true, |
| − | ["Metabolic Englaciation"] = | + | ["Metabolic Englaciation"] = true, |
| − | ["Dispel Undead"] = | + | ["Dispel Undead"] = true, |
| − | Dig = | + | Dig = true, |
| − | Petrify = | + | Petrify = true, |
| − | ["Olgreb's Toxic Radiance"] = | + | ["Olgreb's Toxic Radiance"] = true, |
| − | Paralyse = | + | Paralyse = true, |
| − | Polymorph = | + | Polymorph = true, |
| − | ["Mephitic Cloud"] = | + | ["Mephitic Cloud"] = true, |
| − | Confuse = | + | Confuse = true, |
| − | ["Teleport Other"] = | + | ["Teleport Other"] = true, |
| − | Slow = | + | Slow = true, |
| − | ["Hellfire Burst"] = | + | ["Hellfire Burst"] = true, |
| − | ["Metal Splinters"] = | + | ["Metal Splinters"] = true, |
| − | ["Energy Bolt"] = | + | ["Energy Bolt"] = true, |
| − | ["Orb of Electricity"] = | + | ["Orb of Electricity"] = true, |
| − | ["Hellfire"] = | + | ["Hellfire"] = true, |
["Summon Eyeballs"] = 10, | ["Summon Eyeballs"] = 10, | ||
| − | ["Summon Greater Demon"] = | + | ["Summon Greater Demon"] = true, |
} | } | ||
| Line 286: | Line 286: | ||
end | end | ||
| − | -- returns a | + | -- If a monster may be able to cast the spell, returns a table. Otherwise returns nil. |
| − | + | -- The table contains the following keys: | |
| − | -- | + | -- * chance - the chance that the monster will have the spell. May be missing if the chance is too hard to calculate. |
| − | + | -- * damage - the damage that the spell does when the monster casts it (if any) | |
| − | local function | + | local function monster_spell_data(monster, spell_name) |
| + | local special_table = nil | ||
if monster.Species == "lich" and monster.Name ~= "Boris" then | if monster.Species == "lich" and monster.Name ~= "Boris" then | ||
| − | + | special_table = lich_spells | |
| + | elseif monster.Name == "pandemonium lord" then | ||
| + | special_table = panlord_spells | ||
end | end | ||
| − | if | + | if special_table then |
| − | return | + | local chance = special_table[spell_name] |
| + | if chance then | ||
| + | if type(chance) == "number" then | ||
| + | return {chance = chance} | ||
| + | else | ||
| + | return {} | ||
| + | end | ||
| + | else | ||
| + | return nil | ||
| + | end | ||
end | end | ||
if not monster.Spellsets then | if not monster.Spellsets then | ||
| − | return | + | return nil |
end | end | ||
local has = 0 | local has = 0 | ||
local total = 0 | local total = 0 | ||
| + | local damage = nil | ||
for _, spellset in ipairs(monster.Spellsets) do | for _, spellset in ipairs(monster.Spellsets) do | ||
total = total + 1 | total = total + 1 | ||
| Line 310: | Line 323: | ||
if spell.Spell == spell_name then | if spell.Spell == spell_name then | ||
has = has + 1 | has = has + 1 | ||
| + | if not damage then | ||
| + | damage = spell.Damage | ||
| + | end | ||
break | break | ||
end | end | ||
end | end | ||
end | end | ||
| − | return has * 100 / total | + | if has > 0 then |
| + | return {chance = has * 100 / total, damage = damage} | ||
| + | else | ||
| + | return nil | ||
| + | end | ||
end | end | ||
| Line 348: | Line 368: | ||
wizard = "Wizard (monster)", | wizard = "Wizard (monster)", | ||
} | } | ||
| + | |||
| + | local function monsterlink(frame, data) | ||
| + | local ret = "* " .. frame:expandTemplate{title = "monsterlink", args = {data.monster}} | ||
| + | if data.damage or data.chance and data.chance ~= 100 then | ||
| + | ret = ret .. " (" | ||
| + | if data.damage then | ||
| + | ret = ret .. data.damage .. " damage" | ||
| + | if data.chance and data.chance ~= 100 then | ||
| + | ret = ret .. ", " | ||
| + | end | ||
| + | end | ||
| + | if data.chance and data.chance ~= 100 then | ||
| + | ret = ret .. ("%.1f%% chance"):format(data.chance) | ||
| + | end | ||
| + | ret = ret .. ")" | ||
| + | end | ||
| + | return ret | ||
| + | end | ||
function p.monsters_with_spell(frame) | function p.monsters_with_spell(frame) | ||
| Line 354: | Line 392: | ||
local sometimes = {} | local sometimes = {} | ||
for monster, monsterdata in pairs(data) do | for monster, monsterdata in pairs(data) do | ||
| − | local | + | local data = not is_vault_only(monsterdata) and monster_spell_data(monsterdata, spell_name) |
| − | if | + | if data then |
| − | monster = disambig[monster] or (monster:gsub("^%l", string.upper)) | + | data.monster = disambig[monster] or (monster:gsub("^%l", string.upper)) |
| − | if | + | if data.chance and data.chance == 100 then |
| − | table.insert(always, | + | table.insert(always, data) |
else | else | ||
| − | table.insert(sometimes, | + | table.insert(sometimes, data) |
end | end | ||
end | end | ||
end | end | ||
| − | table.sort(always, string_icmp) | + | table.sort(always, function (m1, m2) return string_icmp(m1.monster, m2.monster) end) |
| − | table.sort(sometimes, function(m1, m2) return string_icmp(m1 | + | table.sort(sometimes, function(m1, m2) return string_icmp(m1.monster, m2.monster) end) |
local ret = {} | local ret = {} | ||
if #always > 0 then | if #always > 0 then | ||
table.insert(ret, "The following enemies cast " .. spell_name .. ":") | table.insert(ret, "The following enemies cast " .. spell_name .. ":") | ||
| − | for _, | + | for _, data in ipairs(always) do |
| − | table.insert(ret, | + | table.insert(ret, monsterlink(frame, data)) |
end | end | ||
end | end | ||
if #sometimes > 0 then | if #sometimes > 0 then | ||
table.insert(ret, "The following enemies may be able to cast " .. spell_name .. ", depending on their spell set:") | table.insert(ret, "The following enemies may be able to cast " .. spell_name .. ", depending on their spell set:") | ||
| − | for _, | + | for _, data in ipairs(sometimes) do |
| − | + | table.insert(ret, monsterlink(frame, data)) | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | table.insert(ret, | ||
end | end | ||
end | end | ||
Revision as of 22:54, 6 January 2016
Documentation for this module may be created at Module:Monster/doc
local p = {}
local data = mw.loadData('Module: Table of monsters')
-- Taken from max_corpse_chunks in mon-util.cc
local max_corpse_chunks = {
Tiny = 1,
Little = 2,
Small = 3,
Medium = 4,
Large = 9,
Big = 10,
Giant = 12,
}
local function name_arg(frame)
local name = frame.args[1]
if not name or name == "" then
name = mw.title.getCurrentTitle().text
end
return name
end
function p.glyph(frame)
local name = name_arg(frame)
local monster = data[name] or data[name:lower()]
if monster then
return frame:expandTemplate{title = monster.Colour, args = {monster.Glyph}}
else
-- probably obsolete monster; fall back to old templates
return frame:expandTemplate{title = "glyph/" .. name}
end
end
function p.monster_info(frame)
local name = name_arg(frame)
local monster = data[name] or data[name:lower()]
if not monster then
return name
end
local args = {}
args.name = monster.Name
args.glyph = frame:expandTemplate{title = monster.Colour, args = {monster.Glyph}}
local flags = {}
for i, v in ipairs(monster.Flags) do
flags[i] = frame:expandTemplate{title = v}
end
args.flags = table.concat(flags, "<br>")
local resistances = {}
for i, v in ipairs(monster.Resistances) do
resistances[i] = frame:expandTemplate{title = v}
end
if #resistances == 0 then
args.resistances = "None"
else
args.resistances = table.concat(resistances, "<br>")
end
local vulnerabilities = {}
for i, v in ipairs(monster.Vulnerabilities) do
vulnerabilities[i] = frame:expandTemplate{title = v}
end
if #vulnerabilities == 0 then
args.vulnerabilities = "None"
else
args.vulnerabilities = table.concat(vulnerabilities, "<br>")
end
if monster.Corpse ~= "No" then
args.max_chunks = max_corpse_chunks[monster.Size] or 0
else
args.max_chunks = 0
end
args.meat = frame:expandTemplate{title = monster.Corpse .. " corpse"}
args.xp = monster.XP
args.holiness = frame:expandTemplate{title = monster.Holiness}
args.magic_resistance = monster.MR
local hp_min = monster.HD*monster["Base HP"] + monster["Fixed HP"]
local hp_max = monster.HD*(monster["Base HP"]+monster["Rand HP"])+monster["Fixed HP"]
if hp_min == hp_max then
args.hp_range = hp_min
else
args.hp_range = ("%d-%d"):format(hp_min, hp_max)
end
args.avg_hp = (hp_min + hp_max)/2
args.armour_class = monster.AC
args.evasion = monster.EV
args.habitat = monster.Habitat
args.speed = monster.Speed
args.size = frame:expandTemplate{title = monster.Size}
local item_use = {}
for i, v in ipairs(monster["Item Use"]) do
item_use[i] = frame:expandTemplate{title = v}
end
args.item_use = table.concat(item_use, "<br>")
for i = 1, 4 do
local attack = monster.Attacks[i]
if attack then
local typ = frame:expandTemplate{title = attack.Type .. " type"}
local flavour = frame:expandTemplate{title = attack.Flavour .. " flavour"}
args["attack" .. i] = ("%d (%s: %s)"):format(attack.Damage, typ, flavour)
else
args["attack" .. i] = ""
end
end
args.hit_dice = monster.HD
args.base_hp = monster["Base HP"]
args.extra_hp = monster["Rand HP"]
args.fixed_hp = monster["Fixed HP"]
args.intelligence = frame:expandTemplate{title = monster.Intelligence .. " intelligence"}
args.genus = monster.Genus
args.species = monster.Species
local infobox = frame:expandTemplate{title = "monster", args = args}
local flavour = monster.Description
if monster.Quote then
flavour = flavour .. "\n----\n" .. monster.Quote:gsub("\n", "<br>")
end
flavour = frame:expandTemplate{title = "flavour", args = {flavour}}
return infobox .. "\n" .. flavour
end
local roman = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"}
function p.monster_spells(frame)
local name = name_arg(frame)
local monster = data[name] or data[name:lower()]
local ret = "==Spells==\n[[Category:Spellcaster]]"
local cleared = false
for i, spells in ipairs(monster.Spellsets) do
ret = ret .. [=[<div style="margin: 1.0em; margin-top:0; margin-right:0; padding: 0px; float: left; border:none;">
{| class="prettytable" style="border:none; margin:0; padding:0; width:16em;"
! colspan="3" style="font-size:larger;" | Spell set ]=] .. roman[i] .. "\n"
for j, spell in ipairs(spells) do
ret = ret .. '|-\n! align="left" | Slot<sup>' .. j .. '</sup>\n| [[' .. spell.Spell .. ']]'
if spell.Damage then
ret = ret .. " (" .. spell.Damage .. ")"
end
ret = ret .. '\n| '
local flags = {}
for i, v in ipairs(spell.Flags) do
flags[i] = frame:expandTemplate{title = v .. " slot flag"}
end
ret = ret .. table.concat(flags, ", ") .. "\n"
end
ret = ret .. "|-\n|}</div>"
cleared = i % 2 == 0
if cleared then
ret = ret .. '<div style="clear:both;"></div>'
end
end
if not cleared then
ret = ret .. '<div style="clear:both;"></div>'
end
return ret
end
local lich_spells = {
["Corrosive Bolt"] = true,
["Lehudib's Crystal Spear"] = true,
["Orb of Destruction"] = true,
["Summon Greater Demon"] = 50,
["Banishment"] = 33.3,
["Haste"] = 33.3,
["Invisibility"] = 33.3,
["Agony"] = true,
["Bolt of Cold"] = true,
["Bolt of Draining"] = true,
["Bolt of Fire"] = true,
["Confuse"] = true,
["Fireball"] = true,
["Haunt"] = true,
["Iron Shot"] = true,
["Iskenderun's Mystic Blast"] = true,
["Iskenderun's Battlesphere"] = true,
["Lee's Rapid Deconstruction"] = true,
["Lightning Bolt"] = true,
["Malign Gateway"] = true,
["Paralyse"] = true,
["Petrify"] = true,
["Poison Arrow"] = true,
["Spellforged Servitor"] = true,
["Simulacrum"] = true,
["Sleep"] = true,
["Slow"] = true,
["Summon Horrible Things"] = true,
["Throw Icicle"] = true,
}
local panlord_spells = {
["Fire Storm"] = true,
Glaciate = true,
["Lehudib's Crystal Spear"] = true,
["Chain Lightning"] = true,
["Orb of Destruction"] = true,
["Corrosive Bolt"] = true,
["Disintegrate"] = true,
["Bolt of Fire"] = true,
["Bolt of Cold"] = true,
["Iron Shot"] = true,
["Poison Arrow"] = true,
["Bolt of Draining"] = true,
["Quicksilver Bolt"] = true,
["Force Lance"] = true,
Fireball = true,
["Bolt of Magma"] = true,
["Lee's Rapid Deconstruction"] = true,
["Lightning Bolt"] = true,
Blinkbolt = true,
["Venom Bolt"] = true,
Agony = true,
Sleep = true,
["Iskendrun's Mystic Blast"] = true,
["Sticky Flame Range"] = true,
["Steam Ball"] = true,
["Throw Icicle"] = true,
Airstrike = true,
Smiting = true,
["Dazzling Spray"] = true,
["Stone Arrow"] = true,
["Static Discharge"] = true,
["Vampiric Draining"] = true,
["Throw Flame"] = true,
["Throw Frost"] = true,
["Summon Demon"] = true,
["Summon Dragon"] = true,
["Summon Horrible Things"] = true,
["Summon Greater Demon"] = true,
Haunt = true,
["Summon Hydra"] = true,
["Malign Gateway"] = true,
Haste = true,
Invisibility = true,
["Symbol of Torment"] = true,
["Monstrous Menagerie"] = true,
Silence = true,
["Shadow Creatures"] = true,
["Summon Vermin"] = true,
["Summon Swarm"] = true,
["Iskenderun's Battlesphere"] = true,
["Fulminant Prism"] = true,
["Summon Ice Beast"] = true,
Swiftness = true,
Blink = true,
["Summon Butterflies"] = true,
Shatter = true,
Banishment = true,
["Freezing Cloud"] = true,
["Poisonous Cloud"] = true,
["Mass Confusion"] = true,
["Metabolic Englaciation"] = true,
["Dispel Undead"] = true,
Dig = true,
Petrify = true,
["Olgreb's Toxic Radiance"] = true,
Paralyse = true,
Polymorph = true,
["Mephitic Cloud"] = true,
Confuse = true,
["Teleport Other"] = true,
Slow = true,
["Hellfire Burst"] = true,
["Metal Splinters"] = true,
["Energy Bolt"] = true,
["Orb of Electricity"] = true,
["Hellfire"] = true,
["Summon Eyeballs"] = 10,
["Summon Greater Demon"] = true,
}
local function is_vault_only(monster)
for _, flag in ipairs(monster.Flags) do
if flag == "Vault flag" then
return true
end
end
return false
end
-- If a monster may be able to cast the spell, returns a table. Otherwise returns nil.
-- The table contains the following keys:
-- * chance - the chance that the monster will have the spell. May be missing if the chance is too hard to calculate.
-- * damage - the damage that the spell does when the monster casts it (if any)
local function monster_spell_data(monster, spell_name)
local special_table = nil
if monster.Species == "lich" and monster.Name ~= "Boris" then
special_table = lich_spells
elseif monster.Name == "pandemonium lord" then
special_table = panlord_spells
end
if special_table then
local chance = special_table[spell_name]
if chance then
if type(chance) == "number" then
return {chance = chance}
else
return {}
end
else
return nil
end
end
if not monster.Spellsets then
return nil
end
local has = 0
local total = 0
local damage = nil
for _, spellset in ipairs(monster.Spellsets) do
total = total + 1
for _, spell in ipairs(spellset) do
if spell.Spell == spell_name then
has = has + 1
if not damage then
damage = spell.Damage
end
break
end
end
end
if has > 0 then
return {chance = has * 100 / total, damage = damage}
else
return nil
end
end
local function string_icmp(s1, s2)
return s1:lower() < s2:lower()
end
local disambig = {
centaur = "Centaur (monster)",
["death knight"] = "Death knight (monster)",
["deep dwarf"] = "Deep dwarf (monster)",
demigod = "Demigod (monster)",
demonspawn = "Demonspawn (monster)",
draconian = "Draconian (monster)",
felid = "Felid (monster)",
formicid = "Formicid (monster)",
gargoyle = "Gargoyle (monster)",
ghoul = "Ghoul (monster)",
halfling = "Halfling (monster)",
human = "Human (monster)",
kobold = "Kobold (monster)",
merfolk = "Merfolk (monster)",
minotaur = "Minotaur (monster)",
mummy = "Mummy (monster)",
naga = "Naga (monster)",
necromancer = "Necromancer (monster)",
octopode = "Octopode (monster)",
ogre = "Ogre (monster)",
spriggan = "Spriggan (monster)",
troll = "Troll (monster)",
tengu = "Tengu (monster)",
vampire = "Vampire (monster)",
wizard = "Wizard (monster)",
}
local function monsterlink(frame, data)
local ret = "* " .. frame:expandTemplate{title = "monsterlink", args = {data.monster}}
if data.damage or data.chance and data.chance ~= 100 then
ret = ret .. " ("
if data.damage then
ret = ret .. data.damage .. " damage"
if data.chance and data.chance ~= 100 then
ret = ret .. ", "
end
end
if data.chance and data.chance ~= 100 then
ret = ret .. ("%.1f%% chance"):format(data.chance)
end
ret = ret .. ")"
end
return ret
end
function p.monsters_with_spell(frame)
local spell_name = name_arg(frame)
local always = {}
local sometimes = {}
for monster, monsterdata in pairs(data) do
local data = not is_vault_only(monsterdata) and monster_spell_data(monsterdata, spell_name)
if data then
data.monster = disambig[monster] or (monster:gsub("^%l", string.upper))
if data.chance and data.chance == 100 then
table.insert(always, data)
else
table.insert(sometimes, data)
end
end
end
table.sort(always, function (m1, m2) return string_icmp(m1.monster, m2.monster) end)
table.sort(sometimes, function(m1, m2) return string_icmp(m1.monster, m2.monster) end)
local ret = {}
if #always > 0 then
table.insert(ret, "The following enemies cast " .. spell_name .. ":")
for _, data in ipairs(always) do
table.insert(ret, monsterlink(frame, data))
end
end
if #sometimes > 0 then
table.insert(ret, "The following enemies may be able to cast " .. spell_name .. ", depending on their spell set:")
for _, data in ipairs(sometimes) do
table.insert(ret, monsterlink(frame, data))
end
end
return table.concat(ret, "\n")
end
return p