Module:Attacks
Documentation for this module may be created at Module:Attacks/doc
-- For tables & other outputs generated with attack data, see: Module:Attacks/Tables
local p = {}
local AttackData = mw.loadData('Module:Attacks/data')
local Shared = require('Module:Shared')
p.effectDefinition = {
["Burn"] = {
["type"] = 'DOT',
["subtype"] = 'Burn'
},
["Poison"] = {
["type"] = 'DOT',
["subtype"] = 'Poison'
},
["Slow"] = {
["type"] = 'Modifier',
["modifiers"] = {
["include"] = { 'increasedAttackIntervalPercent' },
["exclude"] = { 'increasedFrostburn' }
}
},
["Bleed"] = {
["type"] = 'DOT',
["subtype"] = 'Bleed'
},
["Frostburn"] = {
["type"] = 'Modifier',
["modifiers"] = {
["include"] = { 'increasedFrostburn', 'increasedAttackIntervalPercent' }
}
},
["Mark of Death"] = {
["type"] = 'Stacking',
["modifiers"] = {
["include"] = { 'decreasedDamageReductionPercent' }
}
},
["Affliction"] = {
["type"] = 'Modifier',
["modifiers"] = {
["include"] = { 'decreasedMaxHitpoints' }
}
},
["Sleep"] = {
["type"] = 'Sleep'
},
["Freeze"] = {
["type"] = 'Stun',
["flavour"] = 'Freeze'
},
["Stun"] = {
["type"] = 'Stun',
["flavour"] = 'Stun'
},
["Regen"] = {
["type"] = 'DOT',
["subtype"] = 'Regen'
}
}
function p.getAttackByID(ID)
return AttackData.Attacks[ID + 1]
end
function p.getAttack(name)
name = string.gsub(name, "%%27", "'")
name = string.gsub(name, "'", "'")
name = string.gsub(name, "'", "'")
for i, attack in ipairs(AttackData.Attacks) do
if name == attack.name then
return attack
end
end
end
function p.getAttacks(checkFunc)
local result = {}
for i, attack in ipairs(AttackData.Attacks) do
if checkFunc(attack) then
table.insert(result, attack)
end
end
return result
end
function p.getAttackEffects(attack)
local attackEffects = {}
for effectName, effectDefn in pairs(p.effectDefinition) do
if p.attackHasEffect(attack, effectDefn) then
table.insert(attackEffects, effectName)
end
end
return attackEffects
end
-- Determines if attack applies the effect defined in effectDefinition
function p.attackHasEffect(attack, effectDefn)
if type(attack) == 'table' and type(effectDefn) == 'table' and type(effectDefn.type) == 'string' then
-- Process pre-hit effects
for i, effect in ipairs(attack.prehitEffects) do
if p.effectMatchesDefn(effect, effectDefn) then
return true
end
end
-- Process on hit effects
for i, effect in ipairs(attack.onhitEffects) do
if p.effectMatchesDefn(effect, effectDefn) then
return true
end
end
end
return false
end
function p.effectMatchesDefn(effect, effectDefn)
if effectDefn.type ~= effect.type then
-- Effect's type doesn't match that of the effect definition
return false
elseif (effectDefn.subtype ~= nil and (effect.subtype == nil or effect.subtype ~= effectDefn.subtype))
or (effectDefn.flavour ~= nil and (effect.flavour == nil or effect.flavour ~= effectDefn.flavour)) then
-- Effect's subtype or flavour doesn't match that of the effect definition
return false
elseif type(effectDefn.modifiers) == 'table' and (effectDefn.modifiers.include ~= nil or effectDefn.modifiers.exclude ~= nil) then
-- Definition contains modifiers which need to be checked
local modsIncl, modsExcl = (effectDefn.modifiers.include or {}), (effectDefn.modifiers.exclude or {})
local modsInclFound = {}
if Shared.tableCount(modsIncl) > 0 and (type(effect.modifiers) ~= 'table' or Shared.tableCount(effect.modifiers) < Shared.tableCount(modsIncl)) then
-- Definition has 1+ included modifiers but effect has fewer modifiers than the definition
return false
end
for modName, modVal in pairs(effect.modifiers) do
if Shared.contains(modsExcl, modName, false) then
-- Effect contains a modifier on the exclusion list
return false
elseif Shared.contains(modsIncl, modName, false) then
-- Flag included modifier as found
modsInclFound[modName] = true
end
end
if Shared.tableCount(modsInclFound) < Shared.tableCount(modsIncl) then
-- Effect doesn't have all of the included modifiers
return false
end
end
return true
end
return p