Module:Area: Difference between revisions
>OmegaK2 (Moved ID from title to infobox) |
>Illviljan (Removed id texts from connecting areas, the id now links to the data . Fixed connecting areas randomly not linking. Fixed categories. Added intro text and spawn weight table.) |
||
Line 76: | Line 76: | ||
}, | }, | ||
tooltips = { | tooltips = { | ||
-- boolean tooltips | -- boolean tooltips. Use singular form here, categories makes these plural. | ||
is_map_area = 'Map area', | is_map_area = 'Map area', | ||
is_unique_map_area = 'Unique Map area', | is_unique_map_area = 'Unique Map area', | ||
Line 126: | Line 126: | ||
end | end | ||
end | end | ||
function factory.display_value(k, args) | function factory.display_value(k, args) | ||
Line 146: | Line 145: | ||
function util.display.single_area(tpl_args, frame, area_id) | function util.display.single_area(tpl_args, frame, area_id) | ||
if tpl_args.areas[area_id] then | if tpl_args.areas[area_id] then | ||
if tpl_args.areas[area_id]['Has main page'] ~= '' then | if tpl_args.areas[area_id]['Has main page'] ~= '' then | ||
return string.format('[[%s|%s]]', tpl_args.areas[area_id]['Has main page'], tpl_args.areas[area_id]['Has name']) | |||
else | else | ||
return string.format('%s ([[%s|%s]])', tpl_args.areas[area_id]['Has name'], tpl_args.areas[area_id][1], area_id) | |||
end | end | ||
else | else | ||
return area_id | return area_id | ||
Line 377: | Line 374: | ||
func = function(tpl_args, frame) | func = function(tpl_args, frame) | ||
local query_ids = {} | local query_ids = {} | ||
for _, arg in ipairs({'parent_area_id', 'connection_ids', 'vaal_area_ids'}) do | |||
if type(tpl_args[arg]) == 'table' then | |||
for _, tbl_id in ipairs(tpl_args[arg]) do | |||
for _, arg in ipairs({'connection_ids', 'vaal_area_ids'}) do | query_ids[tbl_id] = {} | ||
for _, | end | ||
query_ids[ | elseif tpl_args[arg] then | ||
query_ids[tpl_args[arg]] = {} | |||
end | end | ||
end | end | ||
local | local query_ids_trimmed = {} | ||
for k, _ in pairs(query_ids) do | for k, _ in pairs(query_ids) do | ||
if type(k) ~= 'number' then | if type(k) ~= 'number' then | ||
query_ids_trimmed[#query_ids_trimmed+1] = k | |||
end | end | ||
end | end | ||
if # | if #query_ids_trimmed == 0 then | ||
tpl_args.areas = {} | tpl_args.areas = {} | ||
else | else | ||
Line 400: | Line 397: | ||
frame=frame, | frame=frame, | ||
property='Is area id', | property='Is area id', | ||
id_array= | id_array=query_ids_trimmed, | ||
query={ | query={ | ||
'?Is area id', | '?Is area id', | ||
Line 472: | Line 469: | ||
}, | }, | ||
header = i18n.headers.id, | header = i18n.headers.id, | ||
func = | func = function(tpl_args, frame) | ||
return string.format('[[%s|%s]]', mw.title.getCurrentTitle().fullText, tpl_args.id) | |||
end, | |||
}, | }, | ||
{ | { | ||
Line 586: | Line 585: | ||
local d = {} | local d = {} | ||
function d.intro_text(tpl_args, frame) | |||
local out = {} | |||
if mw.ustring.find(tpl_args['id'], '_') then | |||
out[#out+1] = frame:expandTemplate{ title = 'Incorrect title', args = { title=tpl_args['id'] } } | |||
end | |||
if tpl_args['id'] then | |||
out[#out+1] = string.format("'''%s''' is the internal id for the '''%s''' area. ", tpl_args['id'], tpl_args['name']) | |||
else | |||
out[#out+1] = string.format("'''%s''' is the internal id of an unnamed area. ", tpl_args['id'], tpl_args['name']) | |||
end | |||
local connected_areas = {} | |||
for _, arg in ipairs({'connection_ids', 'vaal_area_ids'}) do | |||
for _, id in pairs(tpl_args[arg]) do | |||
connected_areas[#connected_areas+1] = string.format('<li>[[%s|%s]] (%s)</li>', tpl_args.areas[id][1], id, tpl_args.areas[id]['Has name']) | |||
end | |||
end | |||
if #connected_areas > 0 then | |||
out[#out+1] = string.format('It is connected to the following areas:<ul>%s</ul>', table.concat(connected_areas)) | |||
end | |||
return table.concat(out) | |||
end | |||
function d._check_args(tpl_args, frame, data) | function d._check_args(tpl_args, frame, data) | ||
Line 670: | Line 694: | ||
return f_infocard(infocard_args) | return f_infocard(infocard_args) | ||
end | |||
function d.subobject_box(tpl_args, frame) | |||
local container = mw.html.create('div') | |||
container | |||
:attr('class', 'modbox floatright') | |||
-- spawn weight table | |||
tbl = container:tag('table') | |||
tbl | |||
:attr('class', 'wikitable sortable') | |||
-- :attr('style', 'style="width: 100%;"') | |||
:tag('tr') | |||
:tag('th') | |||
:attr('colspan', 3) | |||
:wikitext('Spawn Weights') | |||
:done() | |||
:done() | |||
:tag('tr') | |||
:tag('th') | |||
:wikitext('[[Property:Is tag number|#]]') | |||
:done() | |||
:tag('th') | |||
:wikitext('[[Property:Has tag|Tag]]') | |||
:done() | |||
:tag('th') | |||
:wikitext('[[Property:Has spawn weight|Weight]]') | |||
:done() | |||
:done() | |||
:done() | |||
local i = 0 | |||
local value = nil | |||
repeat | |||
i = i + 1 | |||
value = { | |||
tag = tpl_args[string.format('spawn_weight%s_tag', i)], | |||
value = tpl_args[string.format('spawn_weight%s_value', i)], | |||
} | |||
if value.tag then | |||
tbl | |||
:tag('tr') | |||
:tag('td') | |||
:wikitext(i) | |||
:done() | |||
:tag('td') | |||
:wikitext(value.tag) | |||
:done() | |||
:tag('td') | |||
:wikitext(value.value) | |||
:done() | |||
:done() | |||
:done() | |||
end | |||
until value.tag == nil | |||
return tostring(container) | |||
end | end | ||
Line 679: | Line 761: | ||
function p.area(frame) | function p.area(frame) | ||
-- = p.area{id = '1_1_1', name = 'The Twilight Strand', act = 1, level = 1, tags = 'no_tempests, area_with_water', loading_screen = 'Act1', connection_ids = '1_1_town',parent_area_id = '1_1_town', boss_monster_ids = 'Metadata/Monsters/ZombieBoss/ZombieBossHillockNormal', flavour_text = 'Hope was drowned here.', main_page = 'The Twilight Strand (Act 1)'} | |||
-- = p.area{id = '1_4_2', name = 'The Dried Lake', act = '4', level = '34', area_type_tags = 'shore', tags = 'act_boss_area', loading_screen = 'Act4', connection_ids = '1_4_town', parent_area_id = '1_4_town', boss_monster_ids = 'Metadata/Monsters/Voll/VollBoss, Metadata/Monsters/SkeletonSoldier/SkeletonSoldierRangedBoss', vaal_area_spawn_chance = '18', vaal_area_ids = '1_SideArea4_2, 1_SideArea4_4', strongbox_spawn_chance = '30', strongbox_max = '2', strongbox_rarity_weight = '50, 50, 50, 1', flavour_text = 'Bones of betrayal, ashes of purity.', main_page = 'The Dried Lake'} | |||
local tpl_args = getArgs(frame, { | local tpl_args = getArgs(frame, { | ||
parentFirst = true | parentFirst = true | ||
Line 690: | Line 775: | ||
tpl_args._properties = {} | tpl_args._properties = {} | ||
-- | -- Handle release_version and removal_version | ||
m_util.args.version(tpl_args, {frame=frame, set_properties=true}) | m_util.args.version(tpl_args, {frame=frame, set_properties=true}) | ||
-- | -- Parse args | ||
for _, k in ipairs(argument_order) do | for _, k in ipairs(argument_order) do | ||
local data = argument_map[k] | local data = argument_map[k] | ||
Line 712: | Line 797: | ||
end | end | ||
-- | -- Parse spawn weights | ||
m_util.args.weight_list(tpl_args, { | m_util.args.weight_list(tpl_args, { | ||
frame=frame, | frame=frame, | ||
Line 718: | Line 803: | ||
}) | }) | ||
-- Category handling for main page | -- Category handling for main page only by adding the categories in a property: | ||
local cats = {} | -- Do notice the plural form. | ||
local | -- -- Areas, Act X areas/Map areas, Unique map areas | ||
local cats = { | |||
'Category:Areas', | |||
} | |||
local cats_ini_len = #cats | |||
for _, key in ipairs(display.area_type) do | for _, key in ipairs(display.area_type) do | ||
if tpl_args[key] == true then | if tpl_args[key] == true then | ||
cats[#cats+1] = string.format('Category:%ss', i18n.tooltips[key]) | |||
end | end | ||
end | end | ||
if | if #cats == cats_ini_len then | ||
cats[#cats+1] = 'Act ' | cats[#cats+1] = string.format('Category:Act %s areas', tpl_args.act) | ||
end | end | ||
tpl_args._properties['Has main page categories'] = | |||
tpl_args._properties['Has main page categories'] = cats | |||
-- | -- Category handling for the local data page: | ||
local | local page_cats = { | ||
'Area data', | |||
} | |||
-- Display only on main pages: | |||
local out = {} | |||
out[#out+1] = d.area_box(tpl_args, frame) | |||
-- Property to store what's output to main pages: | |||
tpl_args._properties['Has infobox HTML'] = out | tpl_args._properties['Has infobox HTML'] = out | ||
-- | -- Set all semantic properties: | ||
m_util.smw.set(frame, tpl_args._properties) | m_util.smw.set(frame, tpl_args._properties) | ||
-- Display only on data page: | |||
out[#out+1] = d.subobject_box(tpl_args, frame) | |||
out[#out+1] = d.intro_text(tpl_args, frame) | |||
-- | -- Output of function | ||
return m_util.misc.add_category(page_cats) | return table.concat(out) .. m_util.misc.add_category(page_cats) | ||
end | end | ||
function p.query_area_info(frame) | function p.query_area_info(frame) | ||
-- p.query_area_info{conditions = '[[Is area id::test]]', cats='yes'} | |||
local tpl_args = getArgs(frame, { | local tpl_args = getArgs(frame, { | ||
parentFirst = true | parentFirst = true | ||
Line 771: | Line 868: | ||
if row['Has main page categories'] ~= '' then | if row['Has main page categories'] ~= '' then | ||
for _, cat in ipairs(m_util.string.split(row['Has main page categories'], '<MANY>')) do | for _, cat in ipairs(m_util.string.split(row['Has main page categories'], '<MANY>')) do | ||
cats[ | cats[#cats+1] = cat | ||
end | end | ||
end | end | ||
end | end | ||
if tpl_args.cats then | if tpl_args.cats then | ||
return table.concat(out) .. m_util.misc.add_category(cats) | |||
return table.concat( | |||
else | else | ||
return table.concat(out) | return table.concat(out) |
Revision as of 08:12, 17 September 2017

This module is used on 4000+ pages.
To avoid major disruption and server load, do not make unnecessary edits to this module. Test changes to this module first using its /sandbox and /testcases subpages or your user space. All of the changes can then be applied to this module in a single edit.
Consider discussing changes on the talk page or on Discord before implementing them.
The item module provides functionality for various area-related templates.
Overview
This module is responsible for creating area boxes, other area-related tasks. In the process a lot of the input data is verified and also added as semantic property to pages; as such, any templates deriving from this module should not be used on user pages other then for temporary testing purposes.
This template is also backed by an export script in PyPoE (pypoe_exporter wiki area ...
) which can be used to export item data from the game files which then can be used on the wiki. Use the export when possible.
Implemented templates
Core templates
- {{Area}}
- {{Query area infoboxes}}
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
-- SMW powered area module
-- ----------------------------------------------------------------------------
-- TODO
-- ----------------------------------------------------------------------------
-- invalid tags -> utl?
-- spawn_weight* values
-- spawnchacne values
--
-- i18n for properties
-- ----------------------------------------------------------------------------
-- Imports
-- ----------------------------------------------------------------------------
local m_util = require('Module:Util')
local getArgs = require('Module:Arguments').getArgs
local m_game = require('Module:Game')
local f_infocard = require('Module:Infocard')._main
-- ----------------------------------------------------------------------------
-- Localization
-- ----------------------------------------------------------------------------
-- Strings
local i18n = {
images = {
waypoint_no = '[[File:No waypoint area icon.png|link=|No Waypoint]]',
waypoint_yes = '[[File:Waypoint area icon.png|link=|No Waypoint]]',
waypoint_town = '[[File:Town area icon.png|link=|Town Hub]]',
loading_screen = '[[File:%s loading screen.png]]',
loading_screen_infobox = '[[File:%s loading screen.png|250px]]',
screenshot = '[[File:%s area screenshot.%s]]',
screenshot_infobox = '[[File:%s area screenshot.%s|250px]]',
},
args = {
main_page = 'main_page',
id = 'id',
name = 'name',
act = 'act',
area_level = 'level',
level_restriction_max = 'level_restriction_max',
area_type_tags = 'area_type_tags',
tags = 'tags',
loading_screen = 'loading_screen',
connection_ids = 'connection_ids',
parent_area_id = 'parent_area_id',
modifier_ids = 'modifier_ids',
boss_monster_ids = 'boss_monster_ids',
monster_ids = 'monster_ids',
entry_text = 'entry_text',
entry_npc = 'entry_npc',
flavour_text = 'flavour_text',
screenshot_ext = 'screenshot_ext',
vaal_area_spawn_chance = 'vaal_area_spawn_chance',
vaal_area_ids = 'vaal_area_ids',
strongbox_spawn_chance = 'strongbox_spawn_chance',
strongbox_max_count = 'strongbox_max',
strongbox_rarity_weight = 'strongbox_rarity_weight',
is_map_area = 'is_map_area',
is_unique_map_area = 'is_unique_map_area',
is_town_area = 'is_town_area',
is_hideout_area = 'is_hideout_area',
is_vaal_area = 'is_vaal_area',
is_master_daily_area = 'is_master_daily_area',
is_labyrinth_area = 'is_labyrinth_area',
is_labyrinth_airlock_area = 'is_labyrinth_airlock_area',
is_labyrinth_boss_area = 'is_labyrinth_boss_area',
has_waypoint = 'has_waypoint',
},
errors = {
invalid_tag = '%s is not a valid tag',
main_page_is_invalid = 'main_page argument got "%s" which is not a valid wiki page',
main_page_does_not_exist = 'main_page argument requires the specified page "%s" to exist in the main wiki namespace',
},
tooltips = {
-- boolean tooltips. Use singular form here, categories makes these plural.
is_map_area = 'Map area',
is_unique_map_area = 'Unique Map area',
is_town_area = 'Town area',
is_hideout_area = 'Hideout area',
is_vaal_area = 'Vaal area',
is_master_daily_area = 'Master daily spawn area',
is_labyrinth_area = 'Labyrinth area',
is_labyrinth_airlock_area = 'Labyrinth airlock area',
is_labyrinth_boss_area = 'Labyrinth boss area',
area = 'area',
--
entry_message = '%s: %s',
},
headers = {
id = 'Id',
act = 'Act',
area_level = 'Area level',
level_restriction_max = m_util.html.abbr('Max level', 'Characters above this level can not enter this zone.'),
area_type_tags = 'Area type tags',
tags = 'Tags',
parent_area = m_util.html.abbr('Parent Town', 'Portals will lead to the parent town'),
connections = 'Connections',
-- monsters
-- boss monsters
vaal_areas = 'Vaal Areas',
},
}
-- ----------------------------------------------------------------------------
-- Constats
-- ----------------------------------------------------------------------------
local c = {}
-- TODO: test
c.max_area_query = 8
-- ----------------------------------------------------------------------------
-- Utility & helper functions
-- ----------------------------------------------------------------------------
local factory = {}
function factory.arg_list(k, args)
return function (tpl_args, frame)
if tpl_args[k] ~= nil then
tpl_args[k] = m_util.string.split(tpl_args[k], ', ')
end
end
end
function factory.display_value(k, args)
return function(tpl_args, frame)
return tpl_args[k]
end
end
local util = {}
util.display = {}
function util.display.multiple_areas(tpl_args, frame, area_ids)
local out = {}
for _, area_id in ipairs(area_ids) do
out[#out+1] = util.display.single_area(tpl_args, frame, area_id)
end
return table.concat(out, '<br>')
end
function util.display.single_area(tpl_args, frame, area_id)
if tpl_args.areas[area_id] then
if tpl_args.areas[area_id]['Has main page'] ~= '' then
return string.format('[[%s|%s]]', tpl_args.areas[area_id]['Has main page'], tpl_args.areas[area_id]['Has name'])
else
return string.format('%s ([[%s|%s]])', tpl_args.areas[area_id]['Has name'], tpl_args.areas[area_id][1], area_id)
end
else
return area_id
end
end
-- ----------------------------------------------------------------------------
-- Argument & display mapping
-- ----------------------------------------------------------------------------
local argument_map = {
--
-- User supplied arguments
--
main_page = {
property = 'Has main page',
func = function(tpl_args, frame)
local page = tpl_args.main_page
if page ~= nil then
page = mw.title.new(tpl_args.main_page)
if page == nil then
error(string.format(i18n.errors.main_page_is_invalid, tpl_args.main_page))
elseif not page.exists then
error(string.format(i18n.errors.main_page_does_not_exist, tpl_args.main_page))
else
-- dont need the title object anymore
--tpl_args.main_page = page
end
end
end
},
--
-- Can be populated by PyPoE
--
id = {
property = 'Is area id',
func = nil,
},
name = {
property = 'Has name',
func = nil,
},
act = {
property = 'Has act',
func = m_util.cast.factory.number(i18n.args.act, {key_out='act'}),
},
area_level = {
property = 'Has area level',
func = m_util.cast.factory.number(i18n.args.area_level, {key_out='area_level'}),
},
level_restriction_max = {
property = 'Has maximum level restriction',
func = m_util.cast.factory.number(i18n.args.level_restriction_max, {key_out='level_restriction_max'}),
default = 100,
},
area_type_tags = {
property = 'Has area type tags',
func = m_util.cast.factory.assoc_table(i18n.args.area_type_tags, {
tbl = m_game.constants.tags,
errmsg = i18n.errors.invalid_tag,
key_out = 'area_type_tags',
}),
},
tags = {
property = 'Has tags',
func = m_util.cast.factory.assoc_table(i18n.args.tags, {
tbl = m_game.constants.tags,
errmsg = i18n.errors.invalid_tag,
key_out = 'tags',
}),
},
loading_screen = {
property = 'Has loading screen image',
func = function (tpl_args, frame)
local loading_id = tpl_args[i18n.args.loading_screen]
if loading_id ~= nil then
tpl_args.loading_screen = string.format(i18n.images.loading_screen, loading_id)
tpl_args.loading_screen_infobox = string.format(i18n.images.loading_screen_infobox, loading_id)
end
end,
},
connection_ids = {
property = 'Has area connection ids',
func = factory.arg_list(i18n.args.connection_ids, {key_out='connection_ids'}),
default = {},
},
parent_area_id = {
property = 'Has parent area id',
},
modifier_ids = {
property = 'Has mod ids',
func = factory.arg_list(i18n.args.modifier_ids, {key_out='modifier_ids'}),
default = {},
},
monster_ids = {
property = 'Has monster ids',
func = factory.arg_list(i18n.args.monster_ids, {key_out='monster_ids'}),
default = {},
},
boss_monster_ids = {
property = 'Has boss monster ids',
func = factory.arg_list(i18n.args.boss_monster_ids, {key_out='boss_monster_ids'}),
default = {},
},
entry_text = {
property = 'Has entry text message',
},
entry_npc = {
property = 'Has entry npc',
},
flavour_text = {
property = 'Has flavour text',
},
screenshot_ext = {
property = nil,
func = nil,
default = 'jpg',
},
screenshot = {
property = 'Has screenshot',
func = function(tpl_args, frame)
if tpl_args.name ~= nil then
tpl_args.screenshot = string.format(i18n.images.screenshot, tpl_args.name, tpl_args.screenshot_ext)
tpl_args.screenshot_infobox = string.format(i18n.images.screenshot_infobox, tpl_args.name, tpl_args.screenshot_ext)
end
end,
},
--
-- Spawn chances
--
vaal_area_ids = {
property = 'Has vaal area ids',
func = factory.arg_list(i18n.args.vaal_area_ids, {key_out='vaal_area_ids'}),
default = {},
},
vaal_area_spawn_chance = {
property = 'Has vaal area spawn chance',
func = m_util.cast.factory.number(i18n.args.vaal_area_spawn_chance, {key_out='vaal_area_spawn_chance'}),
default = 0,
},
strongbox_spawn_chance = {
property = 'Has strongbox spawn chance',
func = m_util.cast.factory.number(i18n.args.strongbox_spawn_chance, {key_out='strongbox_spawn_chance'}),
default = 0,
},
strongbox_max_count = {
property = 'Has maximum number of strongboxes',
func = m_util.cast.factory.number(i18n.args.strongbox_max_count, {key_out='strongbox_max_count'}),
default = 0,
},
strongbox_rarity_weight = {
property = nil,
func = function (tpl_args, frame)
local weights = m_util.string.split(tpl_args[i18n.args.strongbox_rarity_weight] or '', ', ')
tpl_args.strongbox_rarity_weight = {}
for index, data in ipairs(m_game.constants.item.rarity) do
local value = tonumber(weights[index]) or 0
tpl_args.strongbox_rarity_weight[data.long_lower] = value
tpl_args._properties[string.format('Has %s rarity strongbox weight', data.long_lower)] = value
end
end,
},
--
-- Area flags
--
is_map_area = {
property = 'Is map area',
func = m_util.cast.factory.boolean(i18n.args.is_map_area, {key_out='is_map_area'}),
default = false,
},
is_unique_map_area = {
property = 'Is unique map area',
func = m_util.cast.factory.boolean(i18n.args.is_unique_map_area, {key_out='is_unique_map_area'}),
default = false,
},
is_town_area = {
property = 'Is town area',
func = m_util.cast.factory.boolean(i18n.args.is_town_area, {key_out='is_town_area'}),
default = false,
},
is_hideout_area = {
property = 'Is hideout area',
func = m_util.cast.factory.boolean(i18n.args.is_hideout_area, {key_out='is_hideout_area'}),
default = false,
},
is_vaal_area = {
property = 'Is vaal area',
func = m_util.cast.factory.boolean(i18n.args.is_vaal_area, {key_out='is_vaal_area'}),
default = false,
},
is_master_daily_area = {
property = 'Is master daily area',
func = m_util.cast.factory.boolean(i18n.args.is_master_daily_area, {key_out='is_master_daily_area'}),
default = false,
},
is_labyrinth_area = {
property = 'Is labyrinth area',
func = m_util.cast.factory.boolean(i18n.args.is_labyrinth_area, {key_out='is_labyrinth_area'}),
default = false,
},
is_labyrinth_airlock_area = {
property = 'Is labyrinth airlock area',
func = m_util.cast.factory.boolean(i18n.args.is_labyrinth_airlock_area, {key_out='is_labyrinth_airlock_area'}),
default = false,
},
is_labyrinth_boss_area = {
property = 'Is labyrinth boss area',
func = m_util.cast.factory.boolean(i18n.args.is_labyrinth_boss_area, {key_out='is_labyrinth_boss_area'}),
default = false,
},
has_waypoint = {
property = 'Has waypoint',
func = m_util.cast.factory.boolean(i18n.args.has_waypoint, {key_out='has_waypoint'}),
default = false,
},
--
-- Not argument to the template, but still parsing arguments
--
areas = {
property = nil,
func = function(tpl_args, frame)
local query_ids = {}
for _, arg in ipairs({'parent_area_id', 'connection_ids', 'vaal_area_ids'}) do
if type(tpl_args[arg]) == 'table' then
for _, tbl_id in ipairs(tpl_args[arg]) do
query_ids[tbl_id] = {}
end
elseif tpl_args[arg] then
query_ids[tpl_args[arg]] = {}
end
end
local query_ids_trimmed = {}
for k, _ in pairs(query_ids) do
if type(k) ~= 'number' then
query_ids_trimmed[#query_ids_trimmed+1] = k
end
end
if #query_ids_trimmed == 0 then
tpl_args.areas = {}
else
tpl_args.areas = m_util.smw.array_query{
frame=frame,
property='Is area id',
id_array=query_ids_trimmed,
query={
'?Is area id',
'?Has name',
'?Has main page',
},
}
end
-- TODO: Error/Warning for missing areas?
end,
},
}
local argument_order = {
'main_page',
'id',
'name',
'act',
'area_level',
'level_restriction_max',
'area_type_tags',
'tags',
'loading_screen',
'connection_ids',
'parent_area_id',
'modifier_ids',
'boss_monster_ids',
'monster_ids',
'entry_text',
'entry_npc',
'flavour_text',
'screenshot_ext',
'screenshot',
'vaal_area_spawn_chance',
'vaal_area_ids',
'strongbox_spawn_chance',
'strongbox_max_count',
'strongbox_rarity_weight',
'is_map_area',
'is_unique_map_area',
'is_town_area',
'is_hideout_area',
'is_vaal_area',
'is_master_daily_area',
'is_labyrinth_area',
'is_labyrinth_airlock_area',
'is_labyrinth_boss_area',
'has_waypoint',
-- Non argument, but passed to the script
'areas',
}
local display = {}
display.area_type = {
'is_map_area',
'is_unique_map_area',
'is_town_area',
'is_hideout_area',
'is_vaal_area',
'is_master_daily_area',
'is_labyrinth_area',
'is_labyrinth_airlock_area',
'is_labyrinth_boss_area',
}
display.table_map = {
{
args = {
id = {
},
},
header = i18n.headers.id,
func = function(tpl_args, frame)
return string.format('[[%s|%s]]', mw.title.getCurrentTitle().fullText, tpl_args.id)
end,
},
{
args = {
act = {
},
},
header = i18n.headers.act,
func = factory.display_value('act'),
},
{
args = {
area_level = {
},
},
header = i18n.headers.area_level,
func = factory.display_value('area_level'),
},
{
args = {
level_restriction_max = {
hide = 100,
},
},
header = i18n.headers.level_restriction_max,
func = factory.display_value('level_restriction_max'),
},
{
args = {
area_type_tags = {
},
},
header = i18n.headers.area_type_tags,
func = function(tpl_args, frame)
return table.concat(tpl_args.area_type_tags, ', ')
end,
},
{
args = {
tags = {
},
},
header = i18n.headers.tags,
func = function(tpl_args, frame)
return table.concat(tpl_args.tags, ', ')
end,
},
{
args = {
entry_text = {},
entry_npc = {},
},
header = i18n.headers.entry_messsage,
func = function(tpl_args, frame)
return string.format(i18n.tooltips.entry_message, tpl_args.entry_npc, tpl_args.entry_text)
end,
},
{
args = {
parent_area_ids = {},
},
header = i18n.headers.parent_area,
func = function(tpl_args, frame)
return util.display.single_area(tpl_args, frame, tpl_args.parent_area)
end,
},
{
args = {
connection_ids = {},
},
header = i18n.headers.connections,
func = function(tpl_args, frame)
return util.display.multiple_areas(tpl_args, frame, tpl_args.connection_ids)
end,
},
{
args = {
vaal_area_ids = {},
},
header = i18n.headers.vaal_areas,
func = function(tpl_args, frame)
return util.display.multiple_areas(tpl_args, frame, tpl_args.vaal_area_ids)
end,
},
}
display.list_map = {
{
args = {
flavour_text = {},
},
func = function(tpl_args, frame)
return m_util.html.poe_color('flavour', tpl_args.flavour_text)
end,
},
{
args = {
loading_screen_infobox = {},
},
func = factory.display_value('loading_screen_infobox'),
},
{
args = {
screenshot_infobox = {},
},
func = factory.display_value('screenshot_infobox'),
},
}
-- ----------------------------------------------------------------------------
-- display functions
-- ----------------------------------------------------------------------------
local d = {}
function d.intro_text(tpl_args, frame)
local out = {}
if mw.ustring.find(tpl_args['id'], '_') then
out[#out+1] = frame:expandTemplate{ title = 'Incorrect title', args = { title=tpl_args['id'] } }
end
if tpl_args['id'] then
out[#out+1] = string.format("'''%s''' is the internal id for the '''%s''' area. ", tpl_args['id'], tpl_args['name'])
else
out[#out+1] = string.format("'''%s''' is the internal id of an unnamed area. ", tpl_args['id'], tpl_args['name'])
end
local connected_areas = {}
for _, arg in ipairs({'connection_ids', 'vaal_area_ids'}) do
for _, id in pairs(tpl_args[arg]) do
connected_areas[#connected_areas+1] = string.format('<li>[[%s|%s]] (%s)</li>', tpl_args.areas[id][1], id, tpl_args.areas[id]['Has name'])
end
end
if #connected_areas > 0 then
out[#out+1] = string.format('It is connected to the following areas:<ul>%s</ul>', table.concat(connected_areas))
end
return table.concat(out)
end
function d._check_args(tpl_args, frame, data)
local continue = true
if data.args ~= nil then
for key, key_data in pairs(data.args) do
if tpl_args[key] == nil or (type(tpl_args[key]) == 'table' and #tpl_args[key] == 0) then
continue = false
break
elseif type(key_data.hide) == 'table' then
local br = false
for _, value in ipairs(key_data.hide) do
if tpl_args[key] == value then
br = true
break
end
end
if br then
continue = false
break
end
elseif key_data.hide ~= nil and tpl_args[key] == key_data.hide then
continue = false
break
end
end
end
return continue
end
function d.area_box(tpl_args, frame)
local infocard_args = {}
infocard_args.header = tpl_args.name
-- Subheader
local out = {}
for _, key in ipairs(display.area_type) do
if tpl_args[key] == true then
out[#out+1] = i18n.tooltips[key]
end
end
if #out > 0 then
infocard_args.subheader = table.concat(out, ', ')
else
infocard_args.subheader = i18n.tooltips.area
end
-- Side header
if tpl_args.is_town_area then
infocard_args.headerright = i18n.images.waypoint_town
elseif tpl_args.has_waypoint then
infocard_args.headerright = i18n.images.waypoint_yes
else
infocard_args.headerright = i18n.images.waypoint_no
end
-- Main sections, loop through
local tbl = mw.html.create('table')
for _, data in ipairs(display.table_map) do
if d._check_args(tpl_args, frame, data) then
tbl
:tag('tr')
:tag('th')
:wikitext(data.header or '')
:done()
:tag('td')
:wikitext(data.func(tpl_args, frame) or '')
:done()
:done()
end
end
infocard_args[1] = tostring(tbl)
local i = 2
for _, data in ipairs(display.list_map) do
if d._check_args(tpl_args, frame, data) then
infocard_args[i] = data.func(tpl_args, frame)
i = i + 1
end
end
return f_infocard(infocard_args)
end
function d.subobject_box(tpl_args, frame)
local container = mw.html.create('div')
container
:attr('class', 'modbox floatright')
-- spawn weight table
tbl = container:tag('table')
tbl
:attr('class', 'wikitable sortable')
-- :attr('style', 'style="width: 100%;"')
:tag('tr')
:tag('th')
:attr('colspan', 3)
:wikitext('Spawn Weights')
:done()
:done()
:tag('tr')
:tag('th')
:wikitext('[[Property:Is tag number|#]]')
:done()
:tag('th')
:wikitext('[[Property:Has tag|Tag]]')
:done()
:tag('th')
:wikitext('[[Property:Has spawn weight|Weight]]')
:done()
:done()
:done()
local i = 0
local value = nil
repeat
i = i + 1
value = {
tag = tpl_args[string.format('spawn_weight%s_tag', i)],
value = tpl_args[string.format('spawn_weight%s_value', i)],
}
if value.tag then
tbl
:tag('tr')
:tag('td')
:wikitext(i)
:done()
:tag('td')
:wikitext(value.tag)
:done()
:tag('td')
:wikitext(value.value)
:done()
:done()
:done()
end
until value.tag == nil
return tostring(container)
end
-- ----------------------------------------------------------------------------
-- Page functions
-- ----------------------------------------------------------------------------
local p = {}
function p.area(frame)
-- = p.area{id = '1_1_1', name = 'The Twilight Strand', act = 1, level = 1, tags = 'no_tempests, area_with_water', loading_screen = 'Act1', connection_ids = '1_1_town',parent_area_id = '1_1_town', boss_monster_ids = 'Metadata/Monsters/ZombieBoss/ZombieBossHillockNormal', flavour_text = 'Hope was drowned here.', main_page = 'The Twilight Strand (Act 1)'}
-- = p.area{id = '1_4_2', name = 'The Dried Lake', act = '4', level = '34', area_type_tags = 'shore', tags = 'act_boss_area', loading_screen = 'Act4', connection_ids = '1_4_town', parent_area_id = '1_4_town', boss_monster_ids = 'Metadata/Monsters/Voll/VollBoss, Metadata/Monsters/SkeletonSoldier/SkeletonSoldierRangedBoss', vaal_area_spawn_chance = '18', vaal_area_ids = '1_SideArea4_2, 1_SideArea4_4', strongbox_spawn_chance = '30', strongbox_max = '2', strongbox_rarity_weight = '50, 50, 50, 1', flavour_text = 'Bones of betrayal, ashes of purity.', main_page = 'The Dried Lake'}
local tpl_args = getArgs(frame, {
parentFirst = true
})
frame = m_util.misc.get_frame(frame)
--
-- Shared args
--
tpl_args._properties = {}
-- Handle release_version and removal_version
m_util.args.version(tpl_args, {frame=frame, set_properties=true})
-- Parse args
for _, k in ipairs(argument_order) do
local data = argument_map[k]
if data == nil then
error('Missing data in argument_map: ' .. k)
end
if data.func ~= nil then
data.func(tpl_args, frame)
end
if data.default ~= nil and tpl_args[k] == nil then
tpl_args[k] = data.default
end
if data.property ~= nil and tpl_args[k] ~= nil then
tpl_args._properties[data.property] = tpl_args[k]
end
end
-- Parse spawn weights
m_util.args.weight_list(tpl_args, {
frame=frame,
output_argument='spawn_weights',
})
-- Category handling for main page only by adding the categories in a property:
-- Do notice the plural form.
-- -- Areas, Act X areas/Map areas, Unique map areas
local cats = {
'Category:Areas',
}
local cats_ini_len = #cats
for _, key in ipairs(display.area_type) do
if tpl_args[key] == true then
cats[#cats+1] = string.format('Category:%ss', i18n.tooltips[key])
end
end
if #cats == cats_ini_len then
cats[#cats+1] = string.format('Category:Act %s areas', tpl_args.act)
end
tpl_args._properties['Has main page categories'] = cats
-- Category handling for the local data page:
local page_cats = {
'Area data',
}
-- Display only on main pages:
local out = {}
out[#out+1] = d.area_box(tpl_args, frame)
-- Property to store what's output to main pages:
tpl_args._properties['Has infobox HTML'] = out
-- Set all semantic properties:
m_util.smw.set(frame, tpl_args._properties)
-- Display only on data page:
out[#out+1] = d.subobject_box(tpl_args, frame)
out[#out+1] = d.intro_text(tpl_args, frame)
-- Output of function
return table.concat(out) .. m_util.misc.add_category(page_cats)
end
function p.query_area_info(frame)
-- p.query_area_info{conditions = '[[Is area id::test]]', cats='yes'}
local tpl_args = getArgs(frame, {
parentFirst = true
})
frame = m_util.misc.get_frame(frame)
tpl_args.cats = m_util.cast.boolean(tpl_args.cats)
tpl_args.sort = tpl_args.sort or 'Is area id'
local results = m_util.smw.query({
tpl_args.conditions,
'?Has infobox HTML#',
'?Has main page categories#',
sort=tpl_args.sort,
}, frame)
local out = {}
local cats = {}
for _, row in ipairs(results) do
out[#out+1] = row['Has infobox HTML']
if row['Has main page categories'] ~= '' then
for _, cat in ipairs(m_util.string.split(row['Has main page categories'], '<MANY>')) do
cats[#cats+1] = cat
end
end
end
if tpl_args.cats then
return table.concat(out) .. m_util.misc.add_category(cats)
else
return table.concat(out)
end
end
return p