Module:Magic: Difference between revisions

Update for v1.3
m (Fix typo)
(Update for v1.3)
Line 1: Line 1:
local p = {}
local p = {}


local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local SkillData = GameData.skillData
local SkillData = GameData.skillData
local Common = require('Module:Common')
local Common = require('Module:Common')
local Modifiers = require('Module:Modifiers')
local Attacks = require('Module:Attacks')
local Attacks = require('Module:Attacks')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
Line 11: Line 11:


p.spellBooks = {
p.spellBooks = {
{ id = 'standard', dataID = 'standardSpells', name = 'Standard Magic', imgType = 'spell' },
{ id = 'standard', dataID = 'attackSpells', name = 'Standard Magic', imgType = 'spell', bookID = 'melvorD:Standard' },
{ id = 'ancient', dataID = 'ancientSpells', name = 'Ancient Magick', imgType = 'spell' },
{ id = 'ancient', dataID = 'attackSpells', name = 'Ancient Magick', imgType = 'spell', bookID = 'melvorF:Ancient' },
{ id = 'archaic', dataID = 'archaicSpells', name = 'Archaic Magick', imgType = 'spell' },
{ id = 'archaic', dataID = 'attackSpells', name = 'Archaic Magick', imgType = 'spell', bookID = 'melvorTotH:Archaic' },
{ id = 'abyssal' , dataID = 'attackSpells', name = 'Abyssal', imgType = 'spell', bookID = 'melvorItA:Abyssal' },
{ id = 'curse', dataID = 'curseSpells', name = 'Curse', imgType = 'curse' },
{ id = 'curse', dataID = 'curseSpells', name = 'Curse', imgType = 'curse' },
{ id = 'aurora', dataID = 'auroraSpells', name = 'Aurora', imgType = 'aurora' },
{ id = 'aurora', dataID = 'auroraSpells', name = 'Aurora', imgType = 'aurora' },
{ id = 'altMagic', dataID = 'altSpells', name = 'Alt. Magic', imgType = 'spell', dataBySkill = true }
{ id = 'altMagic', dataID = 'altSpells', name = 'Alt. Magic', imgType = 'spell', dataRoot = GameData.getSkillData('melvorD:Magic') }
}
}
p.spellBookIndex = {}
for i, spellBook in ipairs(p.spellBooks) do
p.spellBookIndex[spellBook.id] = i
end


function p.getSpellBookID(sectionName)
function p.getSpellBookID(sectionName)
Line 31: Line 27:
elseif sectionName == 'Archaic' then
elseif sectionName == 'Archaic' then
return 'archaic'
return 'archaic'
elseif sectionName == 'Abyssal' then
return 'abyssal'
elseif sectionName == 'Curse' then
elseif sectionName == 'Curse' then
return 'curse'
return 'curse'
Line 47: Line 45:
local spellBook = GameData.getEntityByID(p.spellBooks, spellBookID)
local spellBook = GameData.getEntityByID(p.spellBooks, spellBookID)
if spellBook ~= nil then
if spellBook ~= nil then
if spellBook.dataBySkill then
local dataRoot = spellBook.dataRoot or GameData.rawData
-- Data is part of the Magic skill object
local spellData = dataRoot[spellBook.dataID]
local magicData = GameData.getSkillData('melvorD:Magic')
if spellBook.bookID == nil then
if magicData ~= nil then
return spellData
return magicData[spellBook.dataID]
end
else
else
-- Data is at the root of GameData
return GameData.getEntities(spellData, function(spell) return spell.spellbook == spellBook.bookID end)
return GameData.rawData[spellBook.dataID]
end
end
end
end
Line 61: Line 56:
end
end


function p.getSpell(name, spellType)
local spellToSpellbookIdx = {}
local spellBookID = p.getSpellBookID(spellType)
for bookIdx, spellBook in ipairs(p.spellBooks) do
name = Shared.fixPagename(name)
local spells = p.getSpellsBySpellBook(spellBook.id)
for _, spell in ipairs(spells) do
spellToSpellbookIdx[spell.id] = bookIdx
end
end


for i, spellBook in ipairs(p.spellBooks) do
function p.getSpellBookFromSpell(spell)
if spellBookID == nil or spellBookID == spellBook.id then
local bookIdx = spellToSpellbookIdx[spell.id]
local spells = p.getSpellsBySpellBook(spellBook.id)
if bookIdx ~= nil then
local spell = GameData.getEntityByName(spells, name)
return p.spellBooks[bookIdx]
if spell ~= nil then
return spell
end
end
end
end
end
end


function p.getSpellByID(id, spellType)
function p.getSpell(name, spellType)
local spellBookID = p.getSpellBookID(spellType)
return p.getSpellByProperty(Shared.fixPagename(name), 'name', spellType)
end


if spellType == nil or spellBookID ~= nil then
function p.getSpellByID(spellID, spellType)
for i, spellBook in ipairs(p.spellBooks) do
return p.getSpellByProperty(spellID, 'id', spellType)
if spellType == nil or spellBookID == spellBook.id then
end
if spellBook.dataBySkill then
 
return GameData.getEntityByID(p.getSpellsBySpellBook(spellBook.id), id)
function p.getSpellByProperty(spellProperty, propertyName, spellType)
else
if spellType == nil then
return GameData.getEntityByID(spellBook.dataID, id)
-- Look for spell in all spellbooks
for _, spellBook in ipairs(p.spellBooks) do
local spells = p.getSpellsBySpellBook(spellBook.id)
if spells ~= nil and not Shared.tableIsEmpty(spells) then  
local spell = GameData.getEntityByProperty(spells, propertyName, spellProperty)
if spell ~= nil then
return spell
end
end
end
end
else
local spellBookID = p.getSpellBookID(spellType)
if spellBookID ~= nil then
local spells = p.getSpellsBySpellBook(spellBookID)
if spells ~= nil and not Shared.tableIsEmpty(spells) then
return GameData.getEntityByProperty(spells, propertyName, spellProperty)
end
end
end
end
Line 99: Line 109:
return Shared.printError('No spell named "' .. spellName .. '" exists in the data module')
return Shared.printError('No spell named "' .. spellName .. '" exists in the data module')
end
end
 
return Icons.getExpansionIcon(spell.id)
return Icons.getExpansionIcon(spell.id)
end
function p.getTypeString(spellType)
local spellBookID = p.getSpellBookID(spellType)
if spellBookID ~= nil then
local spellBook = GameData.getEntityByID(p.spellBooks, spellBookID)
if spellBook ~= nil then
return spellBook.name
end
end
end
end


function p._getSpellIconType(spell)
function p._getSpellIconType(spell)
local spellBook = GameData.getEntityByID(p.spellBooks, spell.spellBook)
local spellBook = p.getSpellBookFromSpell(spell)
if spellBook == nil then
if spellBook == nil then
-- Pick a suitable default
-- Pick a suitable default
Line 142: Line 142:
-- All spells have a Magic level requirement
-- All spells have a Magic level requirement
local extraReqs = {
local extraReqs = {
{ ['type'] = 'SkillLevel', ['skillID'] = 'melvorD:Magic', ['level'] = spell.level }
{
['type'] = 'SkillLevel',
['skillID'] = 'melvorD:Magic',
['level'] = spell.level,
['abyssalLevel'] = spell.abyssalLevel
}
}
}
if spell.requiredItemID ~= nil then
if spell.requiredItemID ~= nil then
table.insert(extraReqs, { ['type'] = 'SlayerItem', ['itemID'] = spell.requiredItemID })
table.insert(extraReqs, {
['type'] = 'SlayerItem',
['itemID'] = spell.requiredItemID
})
end
end


Line 224: Line 232:
function p._getSpellTemplateData(spell)
function p._getSpellTemplateData(spell)
local templateData = nil
local templateData = nil
if spell.spellBook == 'altMagic' then
local spellBook = p.getSpellBookFromSpell(spell)
if spellBook.id == 'altMagic' then
if spell.produces ~= nil then
if spell.produces ~= nil then
-- Item produced varies depending on items consumed
-- Item produced varies depending on items consumed
Line 275: Line 284:
if inline == nil then inline = false end
if inline == nil then inline = false end
local connector = inline and '<br/>' or ' and '
local connector = inline and '<br/>' or ' and '
local spellBook = p.getSpellBookFromSpell(spell)
if spell.description ~= nil then
if spell.description ~= nil then
return Shared.applyTemplateData(spell.description, p._getSpellTemplateData(spell))
return Shared.applyTemplateData(spell.description, p._getSpellTemplateData(spell))
Line 280: Line 290:
local resultPart = {}
local resultPart = {}
if spell.modifiers ~= nil then
if spell.modifiers ~= nil then
table.insert(resultPart, Constants.getModifiersText(spell.modifiers, false))
table.insert(resultPart, Modifiers.getModifiersText(spell.modifiers, false, inline))
end
end
if spell.targetModifiers ~= nil then
if spell.targetModifiers ~= nil then
local targetModText = Constants.getModifiersText(spell.targetModifiers, false, inline)
local targetModText = Modifiers.getModifiersText(spell.targetModifiers, false, inline)
if inline then  
if inline then  
table.insert(resultPart, targetModText)
table.insert(resultPart, targetModText)
Line 296: Line 306:
return spAtt.description
return spAtt.description
end
end
elseif spell.spellBook == 'standard' then
elseif spellBook.id == 'standard' then
return 'Combat spell with a max hit of ' .. Shared.formatnum(spell.maxHit * 10)
return 'Combat spell with a max hit of ' .. Shared.formatnum(spell.maxHit * 10)
else
else
Line 315: Line 325:
return p._getSpellRunes(spell)
return p._getSpellRunes(spell)
elseif stat == 'type' then
elseif stat == 'type' then
return p.getTypeString(spell.spellBook)
local spellBook = p.getSpellBookFromSpell(spell)
return spellBook.name
elseif stat == 'spellDamage' then
elseif stat == 'spellDamage' then
if spell.maxHit ~= nil then  
if spell.maxHit ~= nil then  
Line 342: Line 353:
return Shared.printError('No spell named "' .. spellName .. '" exists in the data module')
return Shared.printError('No spell named "' .. spellName .. '" exists in the data module')
end
end
local spellBook = p.getSpellBookFromSpell(spell)


local result = ''
local result = ''


--11/01/22: Added Spell Damage for standard & archaic spells
--11/01/22: Added Spell Damage for standard & archaic spells
if spell.spellBook == 'standard' or spell.spellBook == 'archaic' then
if spellBook.id == 'standard' or spellBook.id == 'archaic' then
result = result.."\r\n|-\r\n|'''Spell Damage:''' "..p._getSpellStat(spell, 'spellDamage')
result = result.."\r\n|-\r\n|'''Spell Damage:''' "..p._getSpellStat(spell, 'spellDamage')
end
end
--8/20/21: Changed to using the new getSpellDescription function
--8/20/21: Changed to using the new getSpellDescription function
result = result.."\r\n|-\r\n|'''Description:'''<br/>"..p._getSpellStat(spell, 'description')
-- TODO: Spell descriptions need fixing, now uses combat effects rather than modifiers
local spellDesc = p._getSpellStat(spell, 'description')
if spellDesc ~= '' then
result = result.."\r\n|-\r\n|'''Description:'''<br/>"..spellDesc
end


return result
return result
Line 356: Line 372:


function p._getSpellCategories(spell)
function p._getSpellCategories(spell)
local spellBook = p.getSpellBookFromSpell(spell)
local result = '[[Category:Spells]]'
local result = '[[Category:Spells]]'
result = result..'[[Category:'..p.getTypeString(spell.spellBook)..']]'
result = result..'[[Category:' .. spellBook.name .. ']]'
return result
return result
end
end
Line 540: Line 557:


table.sort(spellList, function(a, b)
table.sort(spellList, function(a, b)
if a.spellBook ~= b.spellBook then
local bookA, bookB = p.getSpellBookFromSpell(a), p.getSpellBookFromSpell(b)
return p.spellBookIndex[a.spellBook] < p.spellBookIndex[b.spellBook]
if bookA.id ~= bookB.id then
return bookA.id < bookB.id
else
else
return a.level < b.level
return a.level < b.level
Line 561: Line 579:
elseif spellBookID == 'archaic' then
elseif spellBookID == 'archaic' then
return Icons.Icon({'Archaic Magicks', 'Archaic', img='Archaic', type='spellType'})
return Icons.Icon({'Archaic Magicks', 'Archaic', img='Archaic', type='spellType'})
elseif spellBookID == 'abyssal' then
return Icons.Icon({'Abyssal Magicks', 'Abyssal', img='Abyssal', type='spellType'})
elseif spellBookID == 'curse' then
elseif spellBookID == 'curse' then
return Icons.Icon({'Curses', 'Curse', img='Curse', type='spellType'})
return Icons.Icon({'Curses', 'Curse', img='Curse', type='spellType'})
Line 593: Line 613:


function p._getSpellRow(spell, includeTypeColumn, includeItems, includeDamage, includeExperience)
function p._getSpellRow(spell, includeTypeColumn, includeItems, includeDamage, includeExperience)
local spellBookIdx = p.spellBookIndex[spell.spellBook]
local spellBook = p.getSpellBookFromSpell(spell)
local spellBook = p.spellBooks[spellBookIdx]
local rowPart = {'\n|-\n|data-sort-value="' .. spell.name .. '"| '}
local rowPart = {'\n|-\n|data-sort-value="' .. spell.name .. '"| '}
table.insert(rowPart, Icons.Icon({spell.name, type=spellBook.imgType, notext=true, size=50}))
table.insert(rowPart, Icons.Icon({spell.name, type=spellBook.imgType, notext=true, size=50}))
table.insert(rowPart, '|| ' .. Icons.getExpansionIcon(spell.id) .. Icons.Icon({spell.name, type=spellBook.imgType, noicon=true}))
table.insert(rowPart, '|| ' .. Icons.getExpansionIcon(spell.id) .. Icons.Icon({spell.name, type=spellBook.imgType, noicon=true}))
if includeTypeColumn then
if includeTypeColumn then
table.insert(rowPart, '||data-sort-value="' .. spellBookIdx .. '"| ' .. p.getSpellTypeLink(spell.spellBook))
table.insert(rowPart, '||data-sort-value="' .. spellBook.id .. '"| ' .. p.getSpellTypeLink(spellBook.id))
end
end
table.insert(rowPart, '||data-sort-value="' .. spell.level .. '"| ' .. p._getSpellRequirements(spell))
table.insert(rowPart, '||data-sort-value="' .. spell.level .. '"| ' .. p._getSpellRequirements(spell))
Line 644: Line 663:
-- Check to see what columns are required
-- Check to see what columns are required
for i, spell in ipairs(spellList) do
for i, spell in ipairs(spellList) do
local spellBook = p.getSpellBookFromSpell(spell)
if not includeItems and p._getSpellItems(spell) ~= '' then
if not includeItems and p._getSpellItems(spell) ~= '' then
includeItems = true
includeItems = true
end
end
if not includeExperience and spell.spellBook == 'altMagic' then
if not includeExperience and spellBook.id == 'altMagic' then
includeExperience = true
includeExperience = true
end
end
if not includeDamage and (spell.spellBook == 'archaic' or spell.spellBook == 'standard') then
if not includeDamage and (spellBook.id == 'archaic' or spellBook.id == 'standard') then
includeDamage = true
includeDamage = true
end
end