Module:Area
You might want to create a documentation page for this module.
Editors can experiment in this module's sandbox and testcases pages.
Please add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Please add categories to the /doc subpage. 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|250px]]',
},
args = {
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',
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',
},
tooltips = {
-- boolean tooltips
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',
--
act = 'Act: %s',
area_level = 'Area level: %s',
level_restriction_max = m_util.html.abbr('Max level', 'Characters above this level can not enter this zone.') .. ': %s',
area_type_tags = 'Area type tags: %s',
tags = 'Tags: %s',
parent_area = m_util.html.abbr('Parent Town', 'Portals will lead to the parent town') .. ': %s',
connections = 'Connections: %s',
-- monsters
-- boss monsters
entry_message = '%s: %s',
},
}
-- ----------------------------------------------------------------------------
-- Utility & helper functions
-- ----------------------------------------------------------------------------
local factory = {}
function factory.arg_list(k, args)
return function (tpl_args, frame)
tpl_args[k] = m_util.string.split(tpl_args[k] or '', ', ')
end
end
function factory.display_value(k, args)
return function(tpl_args, frame)
return tpl_args[k]
end
end
-- ----------------------------------------------------------------------------
-- Argument & display mapping
-- ----------------------------------------------------------------------------
local argument_map = {
[i18n.args.id] = {
property = 'Is area id',
func = nil,
},
[i18n.args.name] = {
property = 'Has name',
func = nil,
},
[i18n.args.act] = {
property = 'Has act',
func = m_util.cast.factory.number(i18n.args.act),
},
[i18n.args.area_level] = {
property = 'Has area level',
func = m_util.cast.factory.number(i18n.args.area_level),
},
[i18n.args.level_restriction_max] = {
property = 'Has maximum level restriction',
func = m_util.cast.factory.number(i18n.args.level_restriction_max),
default = 100,
},
[i18n.args.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,
}),
},
[i18n.args.tags] = {
property = 'Has tags',
func = m_util.cast.factory.assoc_table(i18n.args.tags, {
tbl = m_game.constants.tags,
errmsg = i18n.errors.invalid_tag,
}),
},
[i18n.args.loading_screen] = {
property = 'Has loading screen image',
func = function (tpl_args, frame)
if tpl_args[i18n.args.loading_screen] ~= nil then
tpl_args[i18n.args.loading_screen] = string.format(i18n.images.loading_screen, tpl_args[i18n.args.loading_screen])
end
end,
},
[i18n.args.connection_ids] = {
property = 'Has area connection ids',
func = factory.arg_list(i18n.args.connection_ids),
},
[i18n.args.parent_area_id] = {
property = 'Has parent area id',
},
[i18n.args.modifier_ids] = {
property = 'Has mod ids',
func = factory.arg_list(i18n.args.modifier_ids),
},
[i18n.args.monster_ids] = {
property = 'Has monster ids',
func = factory.arg_list(i18n.args.monster_ids)
},
[i18n.args.boss_monster_ids] = {
property = 'Has boss monster ids',
func = factory.arg_list(i18n.args.boss_monster_ids)
},
[i18n.args.entry_text] = {
property = 'Has entry text message',
},
[i18n.args.entry_npc] = {
property = 'Has entry npc',
},
--
-- Spawn chances
--
[i18n.args.vaal_area_ids] = {
property = 'Has vaal area ids',
func = factory.arg_list(i18n.args.vaal_area_ids),
},
[i18n.args.vaal_area_spawn_chance] = {
property = 'Has vaal area spawn chance',
func = m_util.cast.factory.number(i18n.args.vaal_area_spawn_chance),
default = 0,
},
[i18n.args.strongbox_spawn_chance] = {
property = 'Has strongbox spawn chance',
func = m_util.cast.factory.number(i18n.args.strongbox_spawn_chance),
default = 0,
},
[i18n.args.strongbox_max_count] = {
property = 'Has maximum number of strongboxes',
func = m_util.cast.factory.number(i18n.args.strongbox_max_count),
default = 0,
},
[i18n.args.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[i18n.args.strongbox_rarity_weight] = {}
for index, data in ipairs(m_game.constants.item.rarity) do
local value = weights[index] or 0
tpl_args[i18n.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
--
[i18n.args.is_map_area] = {
property = 'Is map area',
func = m_util.cast.factory.boolean(i18n.args.is_map_area),
default = false,
},
[i18n.args.is_unique_map_area] = {
property = 'Is unique map area',
func = m_util.cast.factory.boolean(i18n.args.is_unique_map_area),
default = false,
},
[i18n.args.is_town_area] = {
property = 'Is town area',
func = m_util.cast.factory.boolean(i18n.args.is_town_area),
default = false,
},
[i18n.args.is_hideout_area] = {
property = 'Is hideout area',
func = m_util.cast.factory.boolean(i18n.args.is_hideout_area),
default = false,
},
[i18n.args.is_vaal_area] = {
property = 'Is vaal area',
func = m_util.cast.factory.boolean(i18n.args.is_vaal_area),
default = false,
},
[i18n.args.is_master_daily_area] = {
property = 'Is master daily area',
func = m_util.cast.factory.boolean(i18n.args.is_master_daily_area),
default = false,
},
[i18n.args.is_labyrinth_area] = {
property = 'Is labyrinth area',
func = m_util.cast.factory.boolean(i18n.args.is_labyrinth_area),
default = false,
},
[i18n.args.is_labyrinth_airlock_area] = {
property = 'Is labyrinth airlock area',
func = m_util.cast.factory.boolean(i18n.args.is_labyrinth_airlock_area),
default = false,
},
[i18n.args.is_labyrinth_boss_area] = {
property = 'Is labyrinth boss area',
func = m_util.cast.factory.boolean(i18n.args.is_labyrinth_boss_area),
default = false,
},
[i18n.args.has_waypoint] = {
property = 'Has waypoint',
func = m_util.cast.factory.boolean(i18n.args.has_waypoint),
default = false,
},
}
local argument_order = {
'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',
'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',
}
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.map = {
{
args = {
[i18n.args.act] = {
},
},
func = function(tpl_args, frame)
return string.format(i18n.tooltips.act, tpl_args[i18n.args.act])
end,
},
{
args = {
[i18n.args.area_level] = {
},
},
func = function(tpl_args, frame)
return string.format(i18n.tooltips.area_level, tpl_args[i18n.args.area_level])
end,
},
{
args = {
[i18n.args.level_restriction_max] = {
hide = 100,
},
},
func = function(tpl_args, frame)
return string.format(i18n.tooltips.level_restriction_max, tpl_args[i18n.args.level_restriction_max])
end,
},
{
args = {
[i18n.args.area_type_tags] = {
},
},
func = function(tpl_args, frame)
return string.format(i18n.tooltips.area_type_tags, table.concat(tpl_args[i18n.args.area_type_tags], ', '))
end,
},
{
args = {
[i18n.args.tags] = {
},
},
func = function(tpl_args, frame)
return string.format(i18n.tooltips.tags, table.concat(tpl_args[i18n.args.tags], ', '))
end,
},
{
args = {
[i18n.args.entry_text] = {},
[i18n.args.entry_npc] = {},
},
func = function(tpl_args, frame)
return string.format(i18n.tooltips.entry_message, tpl_args[i18n.args.entry_npc], tpl_args[i18n.args.entry_text])
end,
},
{
args = {
[i18n.args.loading_screen] = {},
},
func = function(tpl_args, frame)
return tpl_args.loading_screen
end,
},
}
-- ----------------------------------------------------------------------------
-- display functions
-- ----------------------------------------------------------------------------
local d = {}
function d.area_box(tpl_args, frame)
local infocard_args = {}
-- Top header
if tpl_args[i18n.args.name] ~= nil then
infocard_args.header = string.format('%s (%s)', tpl_args[i18n.args.name], tpl_args[i18n.args.id])
else
infocard_args.header = tpl_args[i18n.args.name]
end
-- Subheader
local out = {}
for _, key in ipairs(display.area_type) do
if tpl_args[i18n.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[i18n.args.is_town_area] then
infocard_args.headerright = i18n.images.waypoint_town
elseif tpl_args[i18n.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 i = 1
for _, data in ipairs(display.map) do
local continue = true
if data.args ~= nil then
for key, key_data in pairs(data.args) do
if tpl_args[key] == nil then
continue = false
break
elseif key_data.hide == nil and 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 tpl_args[key] == key_data.hide then
continue = false
break
end
end
end
if continue then
infocard_args[i] = data.func(tpl_args, frame)
i = i +1
end
end
return f_infocard(infocard_args)
end
-- ----------------------------------------------------------------------------
-- Page functions
-- ----------------------------------------------------------------------------
local p = {}
function p.area(frame)
local tpl_args = getArgs(frame, {
parentFirst = true
})
frame = m_util.misc.get_frame(frame)
--
-- Shared args
--
tpl_args._properties = {}
-- parse args
for _, k in ipairs(argument_order) do
local key = i18n.args[k]
if key == nil then
error('Missing i18n for argument: ' .. k)
end
local data = argument_map[key]
if data == nil then
error('Missing data in argument_map: ' .. key)
end
if data.func ~= nil then
data.func(tpl_args, frame)
end
if data.default ~= nil and tpl_args[key] == nil then
tpl_args[key] = data.default
end
if data.property ~= nil and tpl_args[key] ~= nil then
tpl_args._properties[data.property] = tpl_args[key]
end
end
-- parse spawn weights
m_util.args.weight_list(tpl_args, {
frame=frame,
output_argument='spawn_weights',
})
-- display
local out = d.area_box(tpl_args, frame)
tpl_args._properties['Has infobox HTML'] = out
-- set semantic properties
m_util.smw.set(frame, tpl_args._properties)
-- display
return out
end
return p