Module:Attacks/Tables: Difference between revisions

Update for v1.1
(Fix for unknown items)
(Update for v1.1)
Line 3: Line 3:
local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Items = require('Module:Items')
local Monsters = require('Module:Monsters')
local Magic = require('Module:Magic')
local Attacks = require('Module:Attacks')
local Attacks = require('Module:Attacks')


Line 22: Line 21:
includeCat[category] = true
includeCat[category] = true
end
end
    -- Build index so we can tell which to include later
    local includedAttacks = {}
    for i, attack in ipairs(attacks) do
        includedAttacks[attack.id] = true
    end


-- Compile a list of monsters, items, spells, etc. for each included attack
-- Compile a list of monsters, items, spells, etc. for each included attack
for i, spAtt in ipairs(attacks) do
    -- Monsters
-- Monsters
    if includeCat['Monster'] then
if includeCat['Monster'] then
        for i, monster in ipairs(GameData.rawData.monsters) do
for j, monsterID in ipairs(spAtt.monsters) do
            if monster.specialAttacks ~= nil and not Shared.tableIsEmpty(monster.specialAttacks) then
local monster = Monsters.getMonsterByID(monsterID)
                local overrideChance = (monster.overrideSpecialChances ~= nil and not Shared.tableIsEmpty(monster.overrideSpecialChances))
local overrideChance = (monster.overrideSpecialChances ~= nil and Shared.tableCount(monster.overrideSpecialChances) > 0)
                for j, spAttID in ipairs(monster.specialAttacks) do
local attChance = spAtt.defaultChance
                    if includedAttacks[spAttID] then
if overrideChance then
                        local spAtt = GameData.getEntityByID('attacks', spAttID)
local attIdx = nil
                        if spAtt ~= nil then
for k, monsterAttack in ipairs(monster.specialAttacks) do
                            local attChance = (overrideChance and monster.overrideSpecialChances[j]) or spAtt.defaultChance
local attID = (type(monsterAttack) == 'table' and monsterAttack.id) or monsterAttack
                            table.insert(spAttTable, { id = spAttID, source = 'Monster', sourceSort = monster.name, sourceText = Icons.Icon({ monster.name, type = 'monster' }), chance = attChance, descType = 'monster' })
if spAtt.id == attID then
                        end
attIdx = k
                    end
break
                end
end
            end
end
        end
if attIdx ~= nil then
    end
attChance = monster.overrideSpecialChances[attIdx]
end
end


table.insert(spAttTable, { idx = i, source = 'Monster', sourceSort = monster.name, sourceText = Icons.Icon({ monster.name, type = 'monster' }), chance = attChance, descType = 'monster' })
    -- Items/Weapons
end
    if includeCat['Item'] then
end
        for i, item in ipairs(GameData.rawData.items) do
 
            if item.specialAttacks ~= nil and not Shared.tableIsEmpty(item.specialAttacks) then
-- Items/Weapons
                local overrideChance = (item.overrideSpecialChances ~= nil and not Shared.tableIsEmpty(item.overrideSpecialChances))
if includeCat['Item'] then
                for j, spAttID in ipairs(item.specialAttacks) do
for j, itemID in ipairs(spAtt.items) do
                    if includedAttacks[spAttID] then
local item = Items.getItemByID(itemID)
                        local spAtt = GameData.getEntityByID('attacks', spAttID)
if item ~= nil then
                        if spAtt ~= nil then
table.insert(spAttTable, { idx = i, source = 'Weapon', sourceSort = item.name, sourceText = Icons.Icon({ item.name, type = 'item' }), chance = spAtt.defaultChance, descType = 'player' })
                            local attChance = (overrideChance and item.overrideSpecialChances[j]) or spAtt.defaultChance
end
                            table.insert(spAttTable, { id = spAttID, source = 'Weapon', sourceSort = item.name, sourceText = Icons.Icon({ item.name, type = 'item' }), chance = attChance, descType = 'player' })
end
                        end
end
                    end
                end
            end
        end
    end


-- Spells
    -- Spells
if includeCat['Spell'] then
    if includeCat['Spell'] then
for j, spellID in ipairs(spAtt.spells) do
        local spellCats = { 'ancientSpells', 'archaicSpells' }
local spell = Magic.getSpellByID(spellID[1], spellID[2])
        for i, spellCat in ipairs(spellCats) do
table.insert(spAttTable, { idx = i, source = 'Spell', sourceSort = spell.name, sourceText = Icons.Icon({ spell.name, type = 'spell' }), chance = spAtt.defaultChance, descType = 'player' })
            for j, spell in ipairs(GameData.rawData[spellCat]) do
end
                if spell.specialAttack ~= nil and includedAttacks[spell.specialAttack] then
end
                    local spAtt = GameData.getEntityByID('attacks', spell.specialAttack)
end
                    if spAtt ~= nil then
                        table.insert(spAttTable, {id = spAtt.id, source = 'Spell', sourceSort = spell.name, sourceText = Icons.Icon({ spell.name, type = 'spell' }), chance = spAtt.defaultChance, descType = 'player' })
                    end
                end
            end
        end
    end


-- Summoning familiars. Any effects inflicted by combat familiars aren't actually special
-- Summoning familiars. Any effects inflicted by combat familiars aren't actually special
-- attacks, therefore the handling here is a bit different and outside of the above attack loop
-- attacks, therefore the handling here is a bit different
if includeCat['Familiar'] then
if includeCat['Familiar'] then
local famIdx = Shared.tableCount(attacks) + 1
local famIdx = Shared.tableCount(attacks) + 1
local familiars = Items.getItems(function(item)
local familiars = Items.getItems(
if item.type == 'Familiar' and Items._getItemStat(item, 'summoningMaxhit') ~= nil and item.modifiers ~= nil then
            function(item)
local famAttack = { prehitEffects = {}, onhitEffects = { { type = 'Modifier', subtype = 'Familiar', modifiers = item.modifiers } } }
                if item.type == 'Familiar' and item.modifiers ~= nil and Items._getItemStat(item, 'summoningMaxhit') ~= nil then
if effectDefn == nil then
                    local famAttack = { prehitEffects = {}, onhitEffects = { { type = 'Modifier', subtype = 'Familiar', modifiers = item.modifiers } } }
return Shared.tableCount(Attacks.getAttackEffects(famAttack)) > 0
                    if effectDefn == nil then
else
                        return Shared.tableIsEmpty(Attacks.getAttackEffects(famAttack))
return Attacks.attackHasEffect(famAttack, effectDefn)
                    else
end
                        return Attacks.attackHasEffect(famAttack, effectDefn)
end
                    end
return false
                end
end)
                return false
for j, familiar in ipairs(familiars) do
            end)
for i, familiar in ipairs(familiars) do
-- For chance, assume the first modifier we come across has the chance, which is pretty lazy
-- For chance, assume the first modifier we come across has the chance, which is pretty lazy
local famChance, famDesc = 0, ''
local famChance, famDesc = 0, ''
Line 98: Line 111:
end
end


table.insert(spAttTable, { idx = famIdx, source = 'Familiar', sourceSort = familiar.name, sourceText = Icons.Icon({ familiar.name, type = 'item' }), chance = famChance or 0, descType = 'player' })
table.insert(spAttTable, { id = familiar.id, source = 'Familiar', sourceSort = familiar.name, sourceText = Icons.Icon({ familiar.name, type = 'item' }), chance = famChance or 0, descType = 'player' })
-- Slap a dummy entry into the attacks table for this familiar
-- Slap a dummy entry into the attacks table for this familiar
attacks[famIdx] = { name = familiar.name .. ' (Familiar)', description = { player = famDesc } }
attacks[famIdx] = { id = familiar.id, name = familiar.name .. ' (Familiar)', description = { player = famDesc } }
famIdx = famIdx + 1
famIdx = famIdx + 1
end
end
Line 106: Line 119:


-- Nothing to output if there are no row definitions
-- Nothing to output if there are no row definitions
if Shared.tableCount(spAttTable) == 0 then
if Shared.tableIsEmpty(spAttTable) then
return ''
return ''
end
end
Line 113: Line 126:
-- By attack index, description type (monster/player), chance, source, then source name (weapon/item/etc.)
-- By attack index, description type (monster/player), chance, source, then source name (weapon/item/etc.)
table.sort(spAttTable, function (a, b)
table.sort(spAttTable, function (a, b)
local sortKeys = { 'idx', 'descType', 'chance', 'source', 'sourceSort' }
local sortKeys = { 'id', 'descType', 'chance', 'source', 'sourceSort' }
for i, key in ipairs(sortKeys) do
for i, key in ipairs(sortKeys) do
if a[key] ~= b[key] then
if a[key] ~= b[key] then
Line 124: Line 137:
local rowCounts = {}
local rowCounts = {}
for i, rowDefn in ipairs(spAttTable) do
for i, rowDefn in ipairs(spAttTable) do
local idx, dt, chance = rowDefn.idx, rowDefn.descType, rowDefn.chance
local id, dt, chance = rowDefn.id, rowDefn.descType, rowDefn.chance
if rowCounts[idx] == nil then
if rowCounts[id] == nil then
rowCounts[idx] = { rows = 0 }
rowCounts[id] = { rows = 0 }
end
end
if rowCounts[idx][dt] == nil then
if rowCounts[id][dt] == nil then
rowCounts[idx][dt] = { rows = 0 }
rowCounts[id][dt] = { rows = 0 }
end
end
if rowCounts[idx][dt][chance] == nil then
if rowCounts[id][dt][chance] == nil then
rowCounts[idx][dt][chance] = 0
rowCounts[id][dt][chance] = 0
end
end
rowCounts[idx]['rows'] = rowCounts[idx]['rows'] + 1
rowCounts[id]['rows'] = rowCounts[id]['rows'] + 1
rowCounts[idx][dt]['rows'] = rowCounts[idx][dt]['rows'] + 1
rowCounts[id][dt]['rows'] = rowCounts[id][dt]['rows'] + 1
rowCounts[idx][dt][chance] = rowCounts[idx][dt][chance] + 1
rowCounts[id][dt][chance] = rowCounts[id][dt][chance] + 1
end
end


Line 145: Line 158:
table.insert(resultPart, '\r\n!Name!!style="min-width:225px"| ' .. sourceHeaderLabel .. (includeSource and '!!Type' or '') .. '!!Chance!!Effect')
table.insert(resultPart, '\r\n!Name!!style="min-width:225px"| ' .. sourceHeaderLabel .. (includeSource and '!!Type' or '') .. '!!Chance!!Effect')


local firstRow = { idx = true, descType = true, chance = true }
local firstRow = { id = true, descType = true, chance = true }
local prevRowVal = { idx = 0, descType = '', chance = 0 }
local prevRowVal = { id = 0, descType = '', chance = 0 }
local resetOnChange = {
local resetOnChange = {
idx = { 'idx', 'descType', 'chance' },
id = { 'id', 'descType', 'chance' },
descType = { 'descType', 'chance' },
descType = { 'descType', 'chance' },
chance = { 'chance' }
chance = { 'chance' }
Line 154: Line 167:
local rowSuffix = ''
local rowSuffix = ''
for i, spAttRow in ipairs(spAttTable) do
for i, spAttRow in ipairs(spAttTable) do
local spIdx = spAttRow.idx
local spIdx = spAttRow.id
local spAtt = attacks[spIdx]
local spAtt = attacks[spIdx]
-- Determine if it's the first row for any of our groupings
-- Determine if it's the first row for any of our groupings
Line 171: Line 184:


table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|-')
if firstRow.idx then
if firstRow.id then
rowSuffix = (rowCounts[spIdx]['rows'] > 1 and '|rowspan="' .. rowCounts[spIdx]['rows'] .. '"') or ''
rowSuffix = (rowCounts[spIdx]['rows'] > 1 and '|rowspan="' .. rowCounts[spIdx]['rows'] .. '"') or ''
table.insert(resultPart, '\r\n' .. rowSuffix .. '| ' .. spAtt.name)
table.insert(resultPart, '\r\n' .. rowSuffix .. '| ' .. spAtt.name)