Module:Spell

local TableTools = require('Module:TableTools') local Utils = require('Module:Utils')

local mw = mw local string = string local sprintf = Utils.sprintf local table = table local tsort = Utils.tableSort local removeDuplicates = TableTools.removeDuplicates local shallowClone = TableTools.shallowClone

-- ----- MODULE FUNCTIONS --- -- local p = require("Module:BaseModule"):newModule local module_data = p:getModuleData("Module:Spell/data")

local main_args = { parentFirst = true, wrappers = { "Template:Spell", "Template:SpellDetail", "Template:SpellsInZoneByType", "Template:SpellObtainableFrom" } }

p.manaCost = p:makeInvokeFunc('_manaCost', main_args) p.description = p:makeInvokeFunc('_description', main_args) p.image = p:makeInvokeFunc('_image', main_args) p.school = p:makeInvokeFunc('_school', main_args) p.schoolTable = p:makeInvokeFunc('_schoolTable', main_args) p.spellDetail = p:makeInvokeFunc('_spellDetail', main_args) p.cooldown = p:makeInvokeFunc('_cooldown', main_args) p.allowedWeapons = p:makeInvokeFunc('_allowedWeapons', main_args) p.allowedArmor = p:makeInvokeFunc('_allowedArmor', main_args) p.otherAttributes = p:makeInvokeFunc('_otherAttributes', main_args) p.spellsInZoneByType = p:makeInvokeFunc('_spellsInZoneByType', main_args) p.getListOfAllSpellTypes = p:makeInvokeFunc('_getListOfAllSpellTypes', main_args) p.spellObtainableFrom = p:makeInvokeFunc('_spellObtainableFrom', main_args)

-- ---- INTERNAL FUNCTIONS -- -- local function spellExists(spell_name) return module_data[spell_name] end

local function getSpellField(spell_name, field) if spellExists(spell_name) == nil then return end return module_data[spell_name][field] end

-- -- PAGE FUNCTIONS -- function p._manaCost(args, frame) -- luacheck: ignore return getSpellField(args[1], 'mana_cost') end

function p._description(args, frame) -- luacheck: ignore return getSpellField(args[1], 'description') end

function p._image(args, frame) -- luacheck: ignore return getSpellField(args[1], 'image') or getSpellField('Unknown', 'image') end

function p._school(args, frame) -- luacheck: ignore return getSpellField(args[1], 'school') end

function p._cooldown(args, frame) -- luacheck: ignore return getSpellField(args[1], 'cooldown') end

function p._allowedWeapons(args, frame) -- luacheck: ignore return getSpellField(args[1], 'allowed_weapons') end

function p._allowedArmor(args, frame) -- luacheck: ignore return getSpellField(args[1], 'allowed_armor') end

function p._otherAttributes(args, frame) -- luacheck: ignore return getSpellField(args[1], 'other_attributes') end

--   Build and return a table for the given school with    spells in spellbook order. --

function p._schoolTable(args, frame) -- luacheck: ignore local school_name = args[1] local spells = {}

for k, v in pairs(module_data) do       if v['school'] == school_name then local t = shallowClone(v) t['spell_name'] = k           table.insert(spells, t)        end end

table.sort(spells, function(a, b) return (a.spell_name < b.spell_name) end)

-- Create HTML output local mw_table = mw.html.create('table') mw_table :attr('class', 'wikitable') :attr('style','margin-left: auto; margin-right: auto;') :cssText('width:60%')

for _, v in ipairs(spells) do       mw_table :tag('tr') :tag('td') :attr('colspan','4') :done :done :tag('tr') :tag('td') :attr('colspan','4') :done :done :tag('tr') :tag('td') :attr('colspan', '2') :cssText('text-align:left; padding-left:5px;font-size:150%') :wikitext(sprintf('%s', v['spell_name'])) :done :tag('td') :attr('rowspan','3') :attr('width','300') :cssText('text-align:left; padding-left:5px;font-size:120%') :wikitext(v['other_attributes']) :done :tag('td') :attr('width','150') :cssText('text-align:left; padding-left:5px;font-size:120%') :wikitext(sprintf('Mana Cost: %s', v['mana_cost'])) :done :done :tag('tr') :tag('td') :attr('rowspan', '2') :cssText('padding-top:5px;vertical-align:top') :wikitext(sprintf('', v['image'])) :done :tag('td') :attr('rowspan','2') :cssText('text-align:left; padding-left:5px; font-size:120%') :wikitext(v['description']) :done :tag('td') :cssText('text-align:left; font-size:120%') :wikitext(sprintf('Cooldown: %s', v['cooldown'])) :done :done :tag('tr') :tag('td') :attr('colspan', '2') :cssText('padding-left:5px; font-size:120%') :wikitext(sprintf('School: %s', v['school'])) :done :done :tag('tr') :tag('td') :attr('colspan', '2') :attr('width','50%') :cssText('text-align:left; font-size:120%') :wikitext(sprintf('Allowed Weapons: %s', v['allowed_weapons'])) :done :tag('td') :attr('colspan','2') :attr('width','50%') :cssText('text-align:left; font-size:120%') :wikitext(sprintf('Allowed Armor: %s', v['allowed_armor'])) :done :done end

return tostring(mw_table:allDone) end

-- Spell Detail

function p._spellDetail(args, frame) -- luacheck: ignore local spellName = args[1] local spells = {}

for k, v in pairs(module_data) do       if k == spellName then local t = shallowClone(v) t['spell_name'] = k           table.insert(spells, t)        end end

-- Create HTML output local mw_table = mw.html.create('table') mw_table :attr('class', 'wikitable') :attr('style','margin-left: auto; margin-right: 0px;') :attr('style','float:right; margin-left: 10px;') :cssText('width:60%')

for _, v in ipairs(spells) do       mw_table :tag('tr') :tag('td') :attr('colspan', '2') :cssText('text-align:left; padding-left:5px;font-size:150%') :wikitext(sprintf('%s', v['spell_name'])) :done :tag('td') :attr('rowspan','3') :attr('width','300') :cssText('text-align:left; padding-left:5px;font-size:120%') :wikitext(v['other_attributes']) :done :tag('td') :attr('width','150') :cssText('text-align:left; padding-left:5px;font-size:120%') :wikitext(sprintf('Mana Cost: %s', v['mana_cost'])) :done :done :tag('tr') :tag('td') :attr('rowspan', '2') :cssText('padding-top:5px;vertical-align:top') :wikitext(sprintf('', v['image'])) :done :tag('td') :attr('rowspan','2') :cssText('text-align:left; padding-left:5px; font-size:120%') :wikitext(v['description']) :done :tag('td') :cssText('text-align:left; font-size:120%') :wikitext(sprintf('Cooldown: %s', v['cooldown'])) :done :done :tag('tr') :tag('td') :attr('colspan', '2') :cssText('padding-left:5px; font-size:120%') :wikitext(sprintf('School: %s', v['school'])) :done :done :tag('tr') :tag('td') :attr('colspan', '2') :attr('width','50%') :cssText('text-align:left; font-size:120%') :wikitext(sprintf('Allowed Weapons: %s', v['allowed_weapons'])) :done :tag('td') :attr('colspan','2') :attr('width','50%') :cssText('text-align:left; font-size:120%') :wikitext(sprintf('Allowed Armor: %s', v['allowed_armor'])) :done :done end

return tostring(mw_table:allDone) end

-- Spells In Zone By Type

function p._spellsInZoneByType(args, frame) -- luacheck: ignore local res = "" local getListOfSpellsInZone = require('Module:Creature').getListOfSpellsInZone

for _, v in pairs(p.getListOfAllSpellTypes(args)) do     local list = {} local i = 1 local spell_data for key, _ in pairs(module_data) do        spell_data = module_data[key] if (args[1] == "all") and (v == spell_data["school"]) then list[i] = key i = i + 1 else for _, b in pairs(getListOfSpellsInZone(args)) do              if (b == key) and (v == spell_data["school"]) then list[i] = key i = i + 1 end end end end if #list ~= 0 then res = res .. sprintf('* %s\n', v)        for _, value in pairs(tsort(list)) do            res = res .. sprintf('** %s\n', value) end end end

return res end

-- Get List of All Spell Types                                                -- Fnc which makes list of all spell types

function p._getListOfAllSpellTypes(args, frame) -- luacheck: ignore local list = {} local i = 1 local spell_data

for k, _ in pairs(module_data) do     spell_data = module_data[k] list[i] = spell_data["school"] i = i + 1 end

return tsort(removeDuplicates(list)) end

-- Spell Obtainable From -- -- Fnc list all creatures you can get spell from and show their known location

function p._spellObtainableFrom(args, frame) -- luacheck: ignore local creature_module_data = mw.loadData('Module:Creature/data') local world_data = mw.loadData('Module:Places/Data') local list = {} local WorldRes = "" local ContinentRes = "" local ZonesRes = ""

local function tagsLoop(target, boolean, extra) local res = "" for _, value in pairs(list) do               local creature_data = creature_module_data[value] local tags = creature_data["Tags"] for _, b in pairs(tags) do                   if b == target then res = res .. extra .. sprintf(' %s', target) boolean = true end end if boolean == true then break end end return res end

local function redoList local i = 1 for k, _ in pairs(creature_module_data) do           local creature_data = creature_module_data[k] if creature_data["Skills and Abilities"] ~= nil then for _, value in ipairs(creature_data["Skills and Abilities"]) do               if value["Name"] == args[1] then list[i] = k                   i = i + 1 end end end end end

local function listCreatures(target) local res = "" local first = true local i = 1

while i <= #list do           local creature_data = creature_module_data[list[i]] local tags = creature_data["Tags"] local increment = false local remove = false

for _, b in pairs(tags) do               if b == target then if first == true then res = res .. sprintf(': %s', list[i]) first = false else res = res .. sprintf(', %s', list[i]) end remove = true increment = false break else increment = true end end if remove == true then table.remove(list, i)           end

if increment == true then i = i + 1 end end

if res ~= "" then res = res .. sprintf('\n') end return res end

for k, _ in pairs(world_data) do       redoList table.sort(list) WorldRes = WorldRes .. tagsLoop(k, false, "*")

local continent_data = world_data[k] for cont, _ in pairs(continent_data) do           ContinentRes = ContinentRes .. tagsLoop(cont, false, "**") local zones_data = continent_data[cont]

for _, zoneName in pairs(zones_data)do ZonesRes = ZonesRes .. tagsLoop(zoneName, false, "***") .. listCreatures(zoneName) end if #list ~= 0 then ContinentRes = ContinentRes .. listCreatures(cont) end if ZonesRes ~= "" then if string.sub(ContinentRes, -1) == "\n" then ContinentRes = ContinentRes .. ZonesRes ZonesRes = "" else ContinentRes = ContinentRes .. "\n" .. ZonesRes ZonesRes = "" end end end if #list ~= 0 then WorldRes = WorldRes .. listCreatures(k) end

if ContinentRes ~= "" then if string.sub(WorldRes, -1) == "\n" then WorldRes = WorldRes .. ContinentRes ContinentRes = "" else WorldRes = WorldRes .. "\n" .. ContinentRes ContinentRes = "" end end end

return WorldRes end

return p