Fractured Online Wiki
No edit summary
No edit summary
Line 568: Line 568:
 
local tags = {}
 
local tags = {}
 
local places_data = mw.loadData('Module:Places/Data')
 
local places_data = mw.loadData('Module:Places/Data')
local res = ""
+
local res = {}
   
 
for k, v in pairs(creature_data["Tags"]) do
 
for k, v in pairs(creature_data["Tags"]) do
Line 578: Line 578:
 
for key, value in pairs(tags) do
 
for key, value in pairs(tags) do
 
if value == k then
 
if value == k then
res = res .. sprintf('* [[%s]]\n', table.remove(tags, key))
+
table.insert(res, sprintf('* [[%s]]\n', table.remove(tags, key)))
 
break
 
break
 
end
 
end
Line 590: Line 590:
 
while i <= #tags do
 
while i <= #tags do
 
if tags[i] == key then
 
if tags[i] == key then
res = res .. sprintf('** [[%s]]', table.remove(tags, i))
+
table.insert(sprintf('** [[%s]]', table.remove(tags, i)))
 
newLine = true
 
newLine = true
 
break
 
break
Line 602: Line 602:
 
if b == y then
 
if b == y then
 
if first then
 
if first then
res = res .. sprintf(': [[%s]]', y)
+
table.insert(res,sprintf(': [[%s]]', y))
 
first = false
 
first = false
 
else
 
else
res = res .. sprintf(', [[%s]]', y)
+
table.insert(res,sprintf(', [[%s]]', y))
 
end
 
end
 
break
 
break
Line 611: Line 611:
 
end
 
end
 
end
 
end
if newLine then res = res .. sprintf('\n') end
+
if newLine then table.insert(res,'\n') end
 
end
 
end
 
end
 
end
   
return res
+
return table.concat(res,'')
 
end
 
end
   

Revision as of 10:10, 16 October 2021

Edit-copy purple Documentation

This module is responsible for the output of creature stats:

  • attributes and modifiers
  • armor and resistances
  • base attacks
  • skills and abilities

Also:

  • list - creatures in zone
  • list - creatures in zone by type
  • list - spells in zone
  • creature locations

It has an accompanying Lua data module at Module:Creature/data. Uses: Module:Spell, Module:Creature/data, Module:Places/Data


local spellImage = require('Module:Spell').image
local TableTools = require('Module:TableTools')
local Utils = require('Module:Utils')

local mw = mw
local sprintf = Utils.sprintf
local tsort = Utils.tableSort

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

local main_args = {
    parentFirst = true,
    wrappers = {
        'Template:Creature',
        'Template:CreaturesInZone',
        'Template:SpellsInZone',
        'Template:CreaturesInZoneByType',
        'Template:CreatureLocations',
        'Template:CreatureHeader'
    }
}

p.all = p:makeInvokeFunc('_all', main_args)
p.attributes_modifiers = p:makeInvokeFunc('_attributes_modifiers', main_args)
p.armor_and_resistances = p:makeInvokeFunc('_armor_and_resistances', main_args)
p.base_attacks = p:makeInvokeFunc('_base_attacks', main_args)
p.skills_abilities = p:makeInvokeFunc('_skills_abilities', main_args)
p.creatures_in_zone = p:makeInvokeFunc('_creatures_in_zone', main_args)
p.creatures_in_zone_by_type = p:makeInvokeFunc('_creatures_in_zone_by_type', main_args)
p.get_list_of_creatures_in_zone = p:makeInvokeFunc('_get_list_of_creatures_in_zone', main_args)
p.getListOfAllCreatureTypes = p:makeInvokeFunc('_getListOfAllCreatureTypes', main_args)
p.spellsInZone = p:makeInvokeFunc('_spellsInZone', main_args)
p.getListOfSpellsInZone = p:makeInvokeFunc('_getListOfSpellsInZone', main_args)
p.creatureLocations = p:makeInvokeFunc('_creatureLocations', main_args)
p.getCreatureHeader = p:makeInvokeFunc('_getCreatureHeader', main_args)


local function writeList(list)
local res = {}
   for _, v in pairs(list) do
      table.insert(res,sprintf('* [[%s]]\n', v))
   end
return table.concat(res,'')
end

--[[------------------------------------------------]]
--[[---------------- PAGE FUNCTIONS ----------------]]
--[[------------------------------------------------]]
function p._all(args, frame) -- luacheck: ignore
    return sprintf(
        "%s<br/>%s<br>%s",
        p.attributes_modifiers(args, frame),
        p.armor_and_resistances(args, frame),
        p.base_attacks(args, frame)
    )
end

----------------------------
-- ATTRIBUTES AND MODIFIERS
----------------------------
function p._attributes_modifiers(args, frame)  -- luacheck: ignore
    local creature_name = args[1]
    local creature_data = module_data[creature_name]
    if not creature_data then return "ERROR: NO SUCH CREATURE" end

    local table_title = "Attributes and Modifiers"
    local table_data = creature_data[table_title]

    -- Create HTML output
    local mw_table1 = mw.html.create('table')
    mw_table1
        :attr('class', 'wikitable')
        :cssText('text-align: center; font-family: Verdana,Arial,Helvetica,sans-serif; width: 480px')
        :tag('caption')
            :wikitext(table_title)
        :done()
        :tag('tr')
            :tag('th')
                :wikitext("[[Strength|STR]]")
            :done()
            :tag('th')
                :wikitext("[[Dexterity|DEX]]")
            :done()
            :tag('th')
                :wikitext("[[Intelligence|INT]]")
            :done()
            :tag('th')
                :wikitext("[[Constitution|CON]]")
            :done()
            :tag('th')
                :wikitext("[[Perception|PER]]")
            :done()
            :tag('th')
                :wikitext("[[Charisma|CHA]]")
            :done()
        :done()
        :tag('tr')
            :tag('td')
                :wikitext(table_data["STR"])
            :done()
            :tag('td')
                :wikitext(table_data["DEX"])
            :done()
            :tag('td')
                :wikitext(table_data["INT"])
            :done()
            :tag('td')
                :wikitext(table_data["CON"])
            :done()
            :tag('td')
                :wikitext(table_data["PER"])
            :done()
            :tag('td')
                :wikitext(table_data["CHA"])
            :done()
        :done()

        local mw_table2 = mw.html.create('table')
        mw_table2
            :attr('class', 'wikitable')
            :cssText('text-align: center; font-family: Verdana,Arial,Helvetica,sans-serif; width: 480px')
            :tag('tr')
                :tag('th')
                    :wikitext('[[Endurance]]')
                :done()
                :tag('th')
                    :wikitext('[[Mana]]')
                :done()
            :done()
            :tag('tr')
                :tag('td')
                    :wikitext(table_data["Endurance"])
                :done()
                :tag('td')
                    :wikitext(table_data["Mana"])
                :done()
            :done()

            local mw_table3 = mw.html.create('table')
            mw_table3
                :attr('class', 'wikitable')
                :cssText('text-align: center; font-family: Verdana,Arial,Helvetica,sans-serif; width: 480px')
                :tag('tr')
                    :tag('th')
                        :wikitext('[[Accuracy]]')
                    :done()
                    :tag('th')
                        :wikitext('[[Fortitude]]')
                    :done()
                    :tag('th')
                        :wikitext('[[Evasion]]')
                    :done()
                    :tag('th')
                        :wikitext('[[Willpower]]')
                    :done()
                :done()
                :tag('tr')
                    :tag('td')
                        :wikitext(table_data["Accuracy"])
                    :done()
                    :tag('td')
                        :wikitext(table_data["Fortitude"])
                    :done()
                    :tag('td')
                        :wikitext(table_data["Evasion"])
                    :done()
                    :tag('td')
                        :wikitext(table_data["Willpower"])
                    :done()
                :done()


    return sprintf('%s%s%s', tostring(mw_table1:allDone()), tostring(mw_table2:allDone()), tostring(mw_table3:allDone()))
end

----------------------------
-- ARMOR AND RESISTANCES
----------------------------
function p._armor_and_resistances(args, frame) -- luacheck: ignore
    local creature_name = args[1]
    local creature_data = module_data[creature_name]
    if not creature_data then return "ERROR: NO SUCH CREATURE" end

    local table_title = "Armor and Resistances"
    local table_data = creature_data[table_title]

    -- Create HTML output
    local mw_table1 = mw.html.create('table')
    mw_table1
        :attr('class', 'wikitable')
        :cssText('text-align: center; font-family: Verdana,Arial,Helvetica,sans-serif; width: 480px')
        :tag('caption')
            :wikitext(table_title)
        :done()
        :tag('tr')
            :tag('th')
                :wikitext('[[Armor|Armor (Slash)]]')
            :done()
            :tag('th')
                :wikitext('[[Armor|Armor (Pierce)]]')
            :done()
            :tag('th')
                :wikitext('[[Armor|Armor (Crush)]]')
            :done()
        :done()
        :tag('tr')
            :tag('td')
                :wikitext(table_data["Armor (Slash)"])
            :done()
            :tag('td')
            :wikitext(table_data["Armor (Pierce)"])
            :done()
            :tag('td')
            :wikitext(table_data["Armor (Crush)"])
            :done()
        :done()

        local mw_table2 = mw.html.create('table')
        mw_table2
            :attr('class', 'wikitable')
            :cssText('text-align: center; font-family: Verdana,Arial,Helvetica,sans-serif; width: 480px')
            :tag('tr')
                :tag('th')
                    :wikitext('[[Resistances#Elemental|Elemental (Fire)]]')
                :done()
                :tag('th')
                    :wikitext('[[Resistances#Elemental|Elemental (Ice)]]')
                :done()
                :tag('th')
                    :wikitext('[[Resistances#Elemental|Elemental (Shock)]]')
                :done()
            :done()
            :tag('tr')
                :tag('td')
                    :wikitext(table_data["Elemental (Fire)"])
                :done()
                :tag('td')
                :wikitext(table_data["Elemental (Ice)"])
                :done()
                :tag('td')
                :wikitext(table_data["Elemental (Shock)"])
                :done()
            :done()

            local mw_table3 = mw.html.create('table')
            mw_table3
                :attr('class', 'wikitable')
                :cssText('text-align: center; font-family: Verdana,Arial,Helvetica,sans-serif; width: 480px')
                :tag('tr')
                    :tag('th')
                        :wikitext('[[Resistances#Magic|Magic]]')
                    :done()
                    :tag('th')
                        :wikitext('[[Resistances#Poison|Poison]]')
                    :done()
                    :tag('th')
                        :wikitext('[[Resistances#Acid|Acid]]')
                    :done()
                :done()
                :tag('tr')
                    :tag('td')
                        :wikitext(table_data["Magic"])
                    :done()
                    :tag('td')
                    :wikitext(table_data["Poison"])
                    :done()
                    :tag('td')
                    :wikitext(table_data["Acid"])
                    :done()
                :done()

        return sprintf('%s%s%s', tostring(mw_table1:allDone()), tostring(mw_table2:allDone()), tostring(mw_table3:allDone()))
end

----------------------------
-- BASE ATTACKS
----------------------------
function p._base_attacks(args, frame) -- luacheck: ignore
    local creature_name = args[1]
    local creature_data = module_data[creature_name]
    if not creature_data then return "ERROR: NO SUCH CREATURE" end

    local table_title = "Base Attacks"
    local table_data = creature_data[table_title]

    if not table_data then return "" end

    -- Create HTML output
    local mw_table1 = mw.html.create('table')
    mw_table1
        :attr('class', 'wikitable')
        :cssText('text-align: left; font-family: Verdana,Arial,Helvetica,sans-serif; width: 480px')
        :tag('caption')
            :wikitext(table_title)
        :done()

    local mw_inner_table
    local c = 0

    for _, v in ipairs(table_data) do
        if c ~= #table_data then
            mw_table1
                :tag('tr')
                    :tag('td')
                        :wikitext('&nbsp;')
                    :done()
                :done()
        else
            c = c + 1
        end

        mw_inner_table = mw.html.create('table')
        mw_inner_table
            :cssText('width: 100%')
            :tag('tr')
                :tag('td')
                    :attr('colspan', '2')
                    :wikitext(v["Name"])
                :done()
            :done()
            :tag('tr')
                :tag('td')
                    :wikitext("Damage")
                :done()
                :tag('td')
                    :wikitext(v["Damage"])
                :done()
            :done()
            :tag('tr')
                :tag('td')
                    :wikitext("Range")
                :done()
                :tag('td')
                    :wikitext(v["Range"])
                :done()
            :done()
            :tag('tr')
                :tag('td')
                    :wikitext("Speed")
                :done()
                :tag('td')
                    :wikitext(v["Speed"])
                :done()
            :done()

        mw_table1
            :tag('tr')
                :tag('td')
                    :wikitext(tostring(mw_inner_table:allDone()))
                :done()
            :done()
    end

    return tostring(mw_table1:allDone())
end

----------------------------
-- SKILLS AND ABILITIES
----------------------------
function p._skills_abilities(args, frame) -- luacheck: ignore
    local creature_name = args[1]
    local creature_data = module_data[creature_name]
    if not creature_data then return "ERROR: NO SUCH CREATURE" end

    local table_title = "Skills and Abilities"
    local table_data = creature_data[table_title]

    if not table_data then return "NONE" end

    local mw_inner_table
    local mw_table1
    local myframe = mw.getCurrentFrame()

    -- Create HTML output
    local html = ""

    for _, v in ipairs(table_data) do
        mw_inner_table = mw.html.create('table')
        mw_inner_table
            :cssText('width: 100%')
            :tag('tr')
                :tag('td')
                    :wikitext('[[Knowledge|KP]]')
                :done()
                :tag('td')
                    :wikitext(v["KP"])
                :done()
            :done()
            :tag('tr')
                :tag('td')
                    :wikitext('Acquired')
                :done()
                :tag('td')
                    :wikitext(v["Acquired"])
                :done()
            :done()

        -- Give ability name as first argument to spellImage()
        myframe.args = {v["Name"]}
        if spellImage(myframe) == nil then return "ERROR: SKILL DATA NOT FOUND!" end

        mw_table1 = mw.html.create('table')
        mw_table1
            :attr('class', 'wikitable')
            :cssText('text-align: left; font-family: Verdana,Arial,Helvetica,sans-serif')
            :tag('tr')
                :tag('th')
                    :attr('colspan', '2')
                    :wikitext(sprintf('[[%s]]', v["Name"]))
                :done()
            :done()
            :tag('tr')
                :tag('td')
                    :cssText('width: 140px')
                    :wikitext(sprintf('[[File: %s|link=%s]]', spellImage(myframe), v["Name"]))
                :done()
                :tag('td')
                    :cssText('vertical-align: top; width: 180px; padding-left:5px')
                    :wikitext(tostring(mw_inner_table:allDone()))
                :done()
            :done()

        html = sprintf("%s%s", html, tostring(mw_table1:allDone()))
     end

     return html
end

----------------------------
-- Creatures In Zone
----------------------------
function p._creatures_in_zone(args, frame) -- luacheck: ignore
   local getList = require('Module:Places').getListOfAllZones
   local check = false

   for _, name in pairs(getList()) do                                               -- Check if zone exists
      if args[1] == name then
         check = true
         break
      end
   end
   
   if check == false then return sprintf('%s', "ERROR: NO SUCH ZONE EXISTS") end

   return sprintf('%s', writeList(tsort(p.get_list_of_creatures_in_zone(args))))

end

----------------------------
-- Creatures In Zone By Type
----------------------------
--
-- idea for possible improvement: Array[1,1] = category1, Array[1,2] = creature1, Array[1,3] = creature2, Array[2,1] = category2, Array[2,2] = creature3,...
-- only one loop for data module would be required, dont forget break, same goes for spellsInZoneByType fnc
--
function p._creatures_in_zone_by_type(args, frame) -- luacheck: ignore
    local res = {}
    local creature_data

   for _, v in pairs(p.getListOfAllCreatureTypes(args)) do
      local list = {}
      local i = 1
      for key, _ in pairs(module_data) do
         creature_data = module_data[key]
         if args[1] == "all" and v == creature_data["Category"] then
            list[i] = key
            i = i + 1
         else
            for _, two in pairs(creature_data["Tags"]) do
               if two == args[1] and v == creature_data["Category"] then
                  list[i] = key
                  i = i + 1
               end
            end
         end
      end
      if #list ~= 0 then
         table.insert(res,sprintf('* [[%s]]\n', v))
         for _, value in pairs(tsort(list)) do
            table.insert(res,sprintf('** [[%s]]\n', value))
         end
      end
   end

    return table.concat(res,'')
end

----------------------------
-- Spells In Zone
----------------------------
function p._spellsInZone(args, frame) -- luacheck: ignore
    return sprintf('%s', writeList(p.getListOfSpellsInZone(args)))
end

----------------------------
-- Get List of Creatures In Zone                                                  -- Fnc which makes list of creatures in zone
----------------------------
function p._get_list_of_creatures_in_zone(args, frame) -- luacheck: ignore
    local list = {}
    local i = 1

    for k, _ in pairs(module_data) do
        local creature_data = module_data[k]
        for _, two in pairs(creature_data["Tags"]) do
            if two == args[1] then
                list[i] = k
                i = i + 1
            end
        end
    end

    return list
end

----------------------------
-- Get List of All Creature Types
--
-- Makes list of all creature types
----------------------------
function p._getListOfAllCreatureTypes(args, frame) -- luacheck: ignore
    local list = {}
    local i = 1
    local creature_data

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

    return tsort(TableTools.removeDuplicates(list))
end

----------------------------
-- Get List of All Spells In Zone
--
-- Makes list of all spells in zone
----------------------------
function p._getListOfSpellsInZone(args, frame) -- luacheck: ignore
    local list = {}
    local i = 1
    local creature_data

    for k, _ in pairs(module_data) do
        creature_data = module_data[k]
        for _, g in pairs(p.get_list_of_creatures_in_zone(args)) do
            if (g == k) and (creature_data["Skills and Abilities"] ~= nil) then
                for _, y in ipairs(creature_data["Skills and Abilities"]) do
                    list[i] = y["Name"]
                    i = i + 1
                end
            end
        end
    end

    return tsort(TableTools.removeDuplicates(list))
end

----------------------------
-- Creature Locations
----------------------------
function p._creatureLocations(args, frame) -- luacheck: ignore
    local creature_data = module_data[args[1]]
    local tags = {}
    local places_data = mw.loadData('Module:Places/Data')
    local res = {}

   for k, v in pairs(creature_data["Tags"]) do
      tags[k] = v
   end

   if #tags == 0 then return res end
   for k, _ in pairs(places_data) do
      for key, value in pairs(tags) do
         if value == k then
            table.insert(res, sprintf('* [[%s]]\n', table.remove(tags, key)))
            break
         end
      end
      if #tags == 0 then return res end
      local continent_data = places_data[k]
      for key, _ in pairs(continent_data) do
         local first = true
         local newLine = false
         local i = 1
         while i <= #tags do
            if tags[i] == key then
               table.insert(sprintf('** [[%s]]', table.remove(tags, i)))
               newLine = true
               break
            else
               i = i + 1
            end
         end
         if #tags == 0 then return sprintf('%s\n', res) end
         for _, y in pairs(continent_data[key]) do
            for _, b in pairs(tags) do
               if b == y then
                  if first then
                     table.insert(res,sprintf(': [[%s]]', y))
                     first = false
                  else
                     table.insert(res,sprintf(', [[%s]]', y))
                  end
                  break
               end
            end
         end
      if newLine then table.insert(res,'\n') end
      end
   end

    return table.concat(res,'')
end

----------------------------
-- Get Creature Header
----------------------------
function p._getCreatureHeader(args, frame) -- luacheck: ignore
    local creature_data = module_data[args[1]]
    local res = ""
    if creature_data["EnvImage"] == nil then res = res .. "ERROR: Env Image needed!" else res = res .. sprintf('[[File:%s|left|300px]]',creature_data["EnvImage"]) end
    if creature_data["Description"] == nil then res = res .. "\n\nERROR: Description needed!" else res = res .. "\n\n" .. creature_data["Description"] end

    return res
end


----------------------------
return p