Path of Exile Wiki

Please consider helping keep the wiki up to date. Check the to-do list of updates needed for version 3.14.0.

Game data exports will becoming later as the technical changes in addition to regular changes take some more time.

READ MORE

Path of Exile Wiki
No edit summary
No edit summary
 
(7 intermediate revisions by the same user not shown)
Line 9: Line 9:
 
local m_cargo = require('Module:Cargo')
 
local m_cargo = require('Module:Cargo')
   
  +
-- Should we use the sandbox version of our submodules?
local core = require('Module:Item2/core')
 
  +
local use_sandbox = m_util.misc.maybe_sandbox('Item2')
  +
 
local core = use_sandbox and require('Module:Item2/core/sandbox') or require('Module:Item2/core')
   
 
local c = {}
 
local c = {}
Line 77: Line 80:
 
end
 
end
 
end
 
end
+
-- Weapons also get DPS fields
 
if dcl_args._table == 'weapons' then
 
if dcl_args._table == 'weapons' then
for _, dps_data in ipairs(core.dps_map) do
+
for _, dps_data in pairs(core.dps_map) do
 
for _, range_fields in ipairs(c.range_fields) do
 
for _, range_fields in ipairs(c.range_fields) do
 
-- since there is no parent, the default is float
 
-- since there is no parent, the default is float
Line 94: Line 97:
   
 
-- ----------------------------------------------------------------------------
 
-- ----------------------------------------------------------------------------
-- Cargo tables
+
-- Cargo table schema
 
-- ----------------------------------------------------------------------------
 
-- ----------------------------------------------------------------------------
   
c.cargo_tables = {}
+
c.schema = {}
   
c.cargo_tables.items = {
+
c.schema.items = {
 
table = 'items',
 
table = 'items',
 
fields = {
 
fields = {
Line 159: Line 162:
 
}
 
}
   
c.cargo_tables.item_sell_prices = {
+
c.schema.item_sell_prices = {
 
table = 'item_sell_prices',
 
table = 'item_sell_prices',
 
fields = {
 
fields = {
Line 173: Line 176:
 
}
 
}
   
c.cargo_tables.item_purchase_costs = {
+
c.schema.item_purchase_costs = {
 
table = 'item_purchase_costs',
 
table = 'item_purchase_costs',
 
fields = {
 
fields = {
Line 191: Line 194:
 
}
 
}
   
c.cargo_tables.item_mods = {
+
c.schema.item_mods = {
 
table = 'item_mods',
 
table = 'item_mods',
 
fields = {
 
fields = {
Line 213: Line 216:
 
}
 
}
   
c.cargo_tables.item_stats = {
+
c.schema.item_stats = {
 
table = 'item_stats',
 
table = 'item_stats',
 
fields = {
 
fields = {
Line 244: Line 247:
   
 
-- There probably will be a table named "buffs" in the future, so "item_buffs" is the best solution here
 
-- There probably will be a table named "buffs" in the future, so "item_buffs" is the best solution here
c.cargo_tables.item_buffs = {
+
c.schema.item_buffs = {
 
table = 'item_buffs',
 
table = 'item_buffs',
 
fields = {
 
fields = {
Line 254: Line 257:
 
}
 
}
   
c.cargo_tables.amulets = {
+
c.schema.amulets = {
 
table = 'amulets',
 
table = 'amulets',
 
fields = {
 
fields = {
Line 262: Line 265:
 
}
 
}
   
c.cargo_tables.flasks = {
+
c.schema.flasks = {
 
table = 'flasks',
 
table = 'flasks',
 
fields = {
 
fields = {
Line 275: Line 278:
 
}
 
}
   
c.cargo_tables.weapons = {
+
c.schema.weapons = {
 
table = 'weapons',
 
table = 'weapons',
 
fields = {
 
fields = {
Line 303: Line 306:
 
}
 
}
   
c.cargo_tables.armours = {
+
c.schema.armours = {
 
table = 'armours',
 
table = 'armours',
 
fields = {
 
fields = {
Line 309: Line 312:
 
energy_shield = core.map.energy_shield,
 
energy_shield = core.map.energy_shield,
 
evasion = core.map.evasion,
 
evasion = core.map.evasion,
  +
ward = core.map.ward,
 
movement_speed = core.map.movement_speed,
 
movement_speed = core.map.movement_speed,
 
},
 
},
 
}
 
}
   
c.cargo_tables.shields = {
+
c.schema.shields = {
 
table = 'shields',
 
table = 'shields',
 
fields = {
 
fields = {
Line 320: Line 324:
 
}
 
}
   
c.cargo_tables.skill_gems = {
+
c.schema.skill_gems = {
 
table = 'skill_gems',
 
table = 'skill_gems',
 
fields = {
 
fields = {
Line 335: Line 339:
 
}
 
}
   
c.cargo_tables.maps = {
+
c.schema.maps = {
 
table = 'maps',
 
table = 'maps',
 
fields = {
 
fields = {
Line 351: Line 355:
 
}
 
}
   
c.cargo_tables.atlas_maps = {
+
c.schema.atlas_maps = {
 
table = 'atlas_maps',
 
table = 'atlas_maps',
 
fields = {
 
fields = {
Line 376: Line 380:
 
}
 
}
   
c.cargo_tables.atlas_connections = {
+
c.schema.atlas_connections = {
 
table = 'atlas_connections',
 
table = 'atlas_connections',
 
fields = {
 
fields = {
Line 410: Line 414:
 
}
 
}
   
c.cargo_tables.stackables = {
+
c.schema.stackables = {
 
table = 'stackables',
 
table = 'stackables',
 
fields = {
 
fields = {
 
stack_size = core.map.stack_size,
 
stack_size = core.map.stack_size,
 
stack_size_currency_tab = core.map.stack_size_currency_tab,
 
stack_size_currency_tab = core.map.stack_size_currency_tab,
  +
},
  +
}
  +
  +
c.schema.cosmetic_items = {
  +
table = 'cosmetic_items',
  +
fields = {
 
cosmetic_type = core.map.cosmetic_type,
 
cosmetic_type = core.map.cosmetic_type,
 
},
 
},
 
}
 
}
   
c.cargo_tables.essences = {
+
c.schema.essences = {
 
table = 'essences',
 
table = 'essences',
 
fields = {
 
fields = {
Line 429: Line 439:
 
}
 
}
   
c.cargo_tables.blight_items = {
+
c.schema.blight_items = {
 
table = 'blight_items',
 
table = 'blight_items',
 
fields = {
 
fields = {
Line 436: Line 446:
 
}
 
}
   
c.cargo_tables.hideout_doodads = {
+
c.schema.hideout_doodads = {
 
table = 'hideout_doodads',
 
table = 'hideout_doodads',
 
fields = {
 
fields = {
Line 447: Line 457:
 
}
 
}
   
c.cargo_tables.prophecies = {
+
c.schema.prophecies = {
 
table = 'prophecies',
 
table = 'prophecies',
 
fields = {
 
fields = {
Line 458: Line 468:
 
}
 
}
   
c.cargo_tables.divination_cards = {
+
c.schema.divination_cards = {
 
table = 'divination_cards',
 
table = 'divination_cards',
 
fields = {
 
fields = {
Line 465: Line 475:
 
}
 
}
   
c.cargo_tables.jewels = {
+
c.schema.jewels = {
 
table = 'jewels',
 
table = 'jewels',
 
fields = {
 
fields = {
Line 473: Line 483:
 
}
 
}
   
c.cargo_tables.incubators = {
+
c.schema.incubators = {
 
table = 'incubators',
 
table = 'incubators',
 
fields = {
 
fields = {
Line 480: Line 490:
 
}
 
}
   
c.cargo_tables.harvest_seeds = {
+
c.schema.harvest_seeds = {
 
table = 'harvest_seeds',
 
table = 'harvest_seeds',
 
fields = {
 
fields = {
Line 497: Line 507:
 
}
 
}
   
c.cargo_tables.harvest_plant_boosters = {
+
c.schema.harvest_plant_boosters = {
 
table = 'harvest_plant_boosters',
 
table = 'harvest_plant_boosters',
 
fields = {
 
fields = {
Line 507: Line 517:
 
}
 
}
   
c.cargo_tables.heist_equipment = {
+
c.schema.heist_equipment = {
 
table = 'heist_equipment',
 
table = 'heist_equipment',
 
fields = {
 
fields = {
Line 515: Line 525:
 
}
 
}
   
c.cargo_tables.upgraded_from_sets = {
+
c.schema.upgraded_from_sets = {
 
table = 'upgraded_from_sets',
 
table = 'upgraded_from_sets',
 
fields = {
 
fields = {
Line 533: Line 543:
 
}
 
}
   
c.cargo_tables.upgraded_from_groups = {
+
c.schema.upgraded_from_groups = {
 
table = 'upgraded_from_groups',
 
table = 'upgraded_from_groups',
 
fields = {
 
fields = {
Line 567: Line 577:
 
}
 
}
   
c.cargo_tables.quest_rewards = {
+
c.schema.quest_rewards = {
 
table = 'quest_rewards',
 
table = 'quest_rewards',
 
fields = {
 
fields = {
Line 610: Line 620:
 
}
 
}
   
c.cargo_tables.vendor_rewards = {
+
c.schema.vendor_rewards = {
 
table = 'vendor_rewards',
 
table = 'vendor_rewards',
 
fields = {
 
fields = {
Line 646: Line 656:
 
local p = {}
 
local p = {}
   
p.table_items = h.declare_factory(c.cargo_tables.items)
+
p.table_items = h.declare_factory(c.schema.items)
p.table_item_sell_prices = h.declare_factory(c.cargo_tables.item_sell_prices)
+
p.table_item_sell_prices = h.declare_factory(c.schema.item_sell_prices)
p.table_item_purchase_costs = h.declare_factory(c.cargo_tables.item_purchase_costs)
+
p.table_item_purchase_costs = h.declare_factory(c.schema.item_purchase_costs)
p.table_item_mods = h.declare_factory(c.cargo_tables.item_mods)
+
p.table_item_mods = h.declare_factory(c.schema.item_mods)
p.table_item_stats = h.declare_factory(c.cargo_tables.item_stats)
+
p.table_item_stats = h.declare_factory(c.schema.item_stats)
p.table_item_buffs = h.declare_factory(c.cargo_tables.item_buffs)
+
p.table_item_buffs = h.declare_factory(c.schema.item_buffs)
p.table_amulets = h.declare_factory(c.cargo_tables.amulets)
+
p.table_amulets = h.declare_factory(c.schema.amulets)
p.table_flasks = h.declare_factory(c.cargo_tables.flasks)
+
p.table_flasks = h.declare_factory(c.schema.flasks)
p.table_weapons = h.declare_factory(c.cargo_tables.weapons)
+
p.table_weapons = h.declare_factory(c.schema.weapons)
p.table_armours = h.declare_factory(c.cargo_tables.armours)
+
p.table_armours = h.declare_factory(c.schema.armours)
p.table_shields = h.declare_factory(c.cargo_tables.shields)
+
p.table_shields = h.declare_factory(c.schema.shields)
p.table_skill_gems = h.declare_factory(c.cargo_tables.skill_gems)
+
p.table_skill_gems = h.declare_factory(c.schema.skill_gems)
p.table_maps = h.declare_factory(c.cargo_tables.maps)
+
p.table_maps = h.declare_factory(c.schema.maps)
p.table_atlas_maps = h.declare_factory(c.cargo_tables.atlas_maps)
+
p.table_atlas_maps = h.declare_factory(c.schema.atlas_maps)
p.table_atlas_connections = h.declare_factory(c.cargo_tables.atlas_connections)
+
p.table_atlas_connections = h.declare_factory(c.schema.atlas_connections)
p.table_stackables = h.declare_factory(c.cargo_tables.stackables)
+
p.table_stackables = h.declare_factory(c.schema.stackables)
p.table_essences = h.declare_factory(c.cargo_tables.essences)
+
p.table_cosmetic_items = h.declare_factory(c.schema.cosmetic_items)
p.table_blight_items = h.declare_factory(c.cargo_tables.blight_items)
+
p.table_essences = h.declare_factory(c.schema.essences)
p.table_hideout_doodads = h.declare_factory(c.cargo_tables.hideout_doodads)
+
p.table_blight_items = h.declare_factory(c.schema.blight_items)
p.table_prophecies = h.declare_factory(c.cargo_tables.prophecies)
+
p.table_hideout_doodads = h.declare_factory(c.schema.hideout_doodads)
p.table_divination_cards = h.declare_factory(c.cargo_tables.divination_cards)
+
p.table_prophecies = h.declare_factory(c.schema.prophecies)
p.table_jewels = h.declare_factory(c.cargo_tables.jewels)
+
p.table_divination_cards = h.declare_factory(c.schema.divination_cards)
p.table_incubators = h.declare_factory(c.cargo_tables.incubators)
+
p.table_jewels = h.declare_factory(c.schema.jewels)
p.table_harvest_seeds = h.declare_factory(c.cargo_tables.harvest_seeds)
+
p.table_incubators = h.declare_factory(c.schema.incubators)
p.table_harvest_plant_boosters = h.declare_factory(c.cargo_tables.harvest_plant_boosters)
+
p.table_harvest_seeds = h.declare_factory(c.schema.harvest_seeds)
p.table_heist_equipment = h.declare_factory(c.cargo_tables.heist_equipment)
+
p.table_harvest_plant_boosters = h.declare_factory(c.schema.harvest_plant_boosters)
p.table_upgraded_from_sets = h.declare_factory(c.cargo_tables.upgraded_from_sets)
+
p.table_heist_equipment = h.declare_factory(c.schema.heist_equipment)
p.table_upgraded_from_groups = h.declare_factory(c.cargo_tables.upgraded_from_groups)
+
p.table_upgraded_from_sets = h.declare_factory(c.schema.upgraded_from_sets)
p.table_quest_rewards = h.declare_factory(c.cargo_tables.quest_rewards)
+
p.table_upgraded_from_groups = h.declare_factory(c.schema.upgraded_from_groups)
p.table_vendor_rewards = h.declare_factory(c.cargo_tables.vendor_rewards)
+
p.table_quest_rewards = h.declare_factory(c.schema.quest_rewards)
  +
p.table_vendor_rewards = h.declare_factory(c.schema.vendor_rewards)
   
function p.build_cargo_data(tpl_args, frame)
+
function p.append_schema(tpl_args, frame, tables)
  +
--[[
for _, table_name in ipairs(core.item_classes[tpl_args.class_id].tables) do
 
  +
This function adds specified table names to core.map. The range fields for
-- Need to clone the table here because we'll be changing the table as we run though
 
  +
those tables are also appended to core.map.
-- TODO: Optimize this?
 
  +
--]]
for k, _ in pairs(mw.clone(c.cargo_tables[table_name].fields)) do
 
 
for _, table_name in ipairs(tables) do
field_data = c.cargo_tables[table_name].fields[k]
 
  +
local field_keys = m_util.table.keys(c.schema[table_name].fields)
  +
for _, k in ipairs(field_keys) do
 
local field_data = c.schema[table_name].fields[k]
 
field_data.table = table_name
 
field_data.table = table_name
 
for _, stat_data in pairs(core.stat_map) do
 
for _, stat_data in pairs(core.stat_map) do
Line 688: Line 702:
 
for _, range_field in ipairs(c.range_fields) do
 
for _, range_field in ipairs(c.range_fields) do
 
local field_name = stat_data.field .. range_field.field
 
local field_name = stat_data.field .. range_field.field
 
 
local data = {
 
local data = {
no_copy = true,
+
inherit = true,
 
table = table_name,
 
table = table_name,
 
field = field_name,
 
field = field_name,
Line 697: Line 710:
 
type = range_field.type or field_data.type,
 
type = range_field.type or field_data.type,
 
}
 
}
  +
-- c.schema[table_name].fields[field_name] = data -- We're not using the schema again, so there's no need to update the schema with the added fields
 
c.cargo_tables[table_name].fields[field_name] = data
 
 
core.map[field_name] = data
 
core.map[field_name] = data
 
end
 
end
Line 705: Line 717:
 
end
 
end
 
if table_name == 'weapons' then
 
if table_name == 'weapons' then
for _, dps_data in ipairs(core.dps_map) do
+
for _, dps_data in pairs(core.dps_map) do
 
for _, range_field in ipairs(c.range_fields) do
 
for _, range_field in ipairs(c.range_fields) do
 
local field_name = dps_data.field .. range_field.field
 
local field_name = dps_data.field .. range_field.field
 
 
local data = {
 
local data = {
no_copy = true,
+
inherit = true,
 
table = table_name,
 
table = table_name,
 
field = field_name,
 
field = field_name,
Line 716: Line 727:
 
type = range_field.type or 'Float',
 
type = range_field.type or 'Float',
 
}
 
}
+
-- c.schema[table_name].fields[field_name] = data
c.cargo_tables[table_name].fields[field_name] = data
 
 
core.map[field_name] = data
 
core.map[field_name] = data
 
end
 
end
Line 732: Line 742:
 
function p.debug_print_tables(frame)
 
function p.debug_print_tables(frame)
 
frame = m_util.misc.get_frame(frame)
 
frame = m_util.misc.get_frame(frame)
for key, data in pairs(c.cargo_tables) do
+
for key, data in pairs(c.schema) do
 
mw.logObject(data.table)
 
mw.logObject(data.table)
 
end
 
end
Line 739: Line 749:
 
function p.debug_attach_test(frame)
 
function p.debug_attach_test(frame)
 
frame = m_util.misc.get_frame(frame)
 
frame = m_util.misc.get_frame(frame)
for key, data in pairs(c.cargo_tables) do
+
for key, data in pairs(c.schema) do
 
m_cargo.attach(frame, {_table=data.table})
 
m_cargo.attach(frame, {_table=data.table})
 
end
 
end

Latest revision as of 01:06, 16 July 2021

Template info icon Module documentation[view] [edit] [history] [purge]

This submodule exports functions for item table declaration. It also contains functions for use in Module:Item2 related to cargo tables.

-------------------------------------------------------------------------------
-- 
-- Cargo table declaration for Module:Item2
-- 
-------------------------------------------------------------------------------

local getArgs = require('Module:Arguments').getArgs
local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')

-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Item2')

local core = use_sandbox and require('Module:Item2/core/sandbox') or require('Module:Item2/core')

local c = {}

c.range_fields = {
    {
        field = '_range_minimum',
        type = nil,
    },
    {
        field = '_range_maximum',
        type = nil,
    },
    {
        field = '_range_average',
        type = nil,
    },
        {
        field = '_range_text',
        type = 'Text',
    },
    {
        field = '_range_colour',
        type = 'String',
    },
    {
        field = '_html',
        type = 'Text',
    },
}

-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------

local h = {}

function h.declare_factory(data)
    -- Returns a function that can be called by templates to declare cargo tables
    --
    --  data: data table
    --   table: name of cargo table
    --   fields: associative table with:
    --    field: name of the field to declare
    --    type: type of the field
    return function(frame)
        local tpl_args = getArgs(frame, {
            parentFirst = true
        })
        frame = m_util.misc.get_frame(frame)
        
        local dcl_args = {}
        dcl_args._table = data.table
        for key, field_data in pairs(data.fields) do
            if field_data.field then
                dcl_args[field_data.field] = field_data.type
                for _, stat_data in pairs(core.stat_map) do
                    if stat_data.field == key then
                        for _, range_fields in ipairs(c.range_fields) do
                            -- if the type is nil, use the parent type
                            -- so this is set integer/float values correctly
                            dcl_args[stat_data.field .. range_fields.field] = range_fields.type or field_data.type
                        end
                        break
                    end
                end
            end
        end
        -- Weapons also get DPS fields
        if dcl_args._table == 'weapons' then
            for _, dps_data in pairs(core.dps_map) do
                for _, range_fields in ipairs(c.range_fields) do
                    -- since there is no parent, the default is float
                    dcl_args[dps_data.field .. range_fields.field] = range_fields.type or 'Float'
                end
            end
        end
        if tpl_args.debug then
            mw.logObject(dcl_args)
        end
        return m_cargo.declare(frame, dcl_args)
    end
end

-- ----------------------------------------------------------------------------
-- Cargo table schema
-- ----------------------------------------------------------------------------

c.schema = {}

c.schema.items = {
    table = 'items',
    fields = {
        html = core.map.html,
        html_extra = core.map.html_extra,
        implicit_stat_text = core.map.implicit_stat_text,
        explicit_stat_text = core.map.explicit_stat_text,
        stat_text = core.map.stat_text,
        class = core.map.class,
        class_id = core.map.class_id,
        rarity = core.map.rarity,
        rarity_id = core.map.rarity_id,
        name = core.map.name,
        size_x = core.map.size_x,
        size_y = core.map.size_y,
        drop_enabled = core.map.drop_enabled,
        drop_level = core.map.drop_level,
        drop_level_maximum = core.map.drop_level_maximum,
        drop_leagues = core.map.drop_leagues,
        drop_areas = core.map.drop_areas,
        drop_areas_html = core.map.drop_areas_html,
        drop_monsters = core.map.drop_monsters,
        drop_text = core.map.drop_text,
        -- sightly different because of strange DB issues
        drop_rarity_ids = core.map.drop_rarities_ids,
        required_level = core.map.required_level,
        required_level_final = core.map.required_level_final,
        required_dexterity = core.map.required_dexterity,
        required_strength = core.map.required_strength,
        required_intelligence = core.map.required_intelligence,
        inventory_icon = core.map.inventory_icon,
        alternate_art_inventory_icons = core.map.alternate_art_inventory_icons,
        buff_icon = core.map.buff_icon,
        cannot_be_traded_or_modified = core.map.cannot_be_traded_or_modified,
        help_text = core.map.help_text,
        flavour_text = core.map.flavour_text,
        flavour_text_id = core.map.flavour_text_id,
        tags = core.map.tags,
        metadata_id = core.map.metadata_id,
        influences = core.map.influences,
        is_fractured = core.map.is_fractured,
        is_synthesised = core.map.is_synthesised,
        is_veiled = core.map.is_veiled,
        is_replica = core.map.is_replica,
        is_corrupted = core.map.is_corrupted,
        is_relic = core.map.is_relic,
        is_fated = core.map.is_fated,
        is_drop_restricted = core.map.is_drop_restricted,
        quality = core.map.quality,
        base_item = core.map.base_item,
        base_item_id = core.map.base_item_id,
        base_item_page = core.map.base_item_page,
        frame_type = core.map.frame_type,
        name_list = core.map.name_list,
        description = core.map.description,
        release_version = core.map.release_version,
        removal_version = core.map.removal_version,
    },
}

c.schema.item_sell_prices = {
    table = 'item_sell_prices',
    fields = {
        amount = {
            field = 'amount',
            type = 'Integer',
        },
        name = {
            field = 'name',
            type = 'String',
        },
    },
}

c.schema.item_purchase_costs = {
    table = 'item_purchase_costs',
    fields = {
        amount = {
            field = 'amount',
            type = 'Integer',
        },
        name = {
            field = 'name',
            type = 'String',
        },
        rarity = {
            field = 'rarity',
            type = 'String',
        },
    },
}

c.schema.item_mods = {
    table = 'item_mods',
    fields = {
        id = {
            field = 'id',
            type = 'String',
        },
        stat_text = {
            field = 'text',
            type = 'Text',
        },
        is_implicit = {
            field = 'is_implicit',
            type = 'Boolean',
        },
        is_random = {
            field = 'is_random',
            type = 'Boolean',
        },
    },
}

c.schema.item_stats = {
    table = 'item_stats',
    fields = {
        id = {
            field = 'id',
            type = 'String',
        },
        min = {
            field = 'min',
            type = 'Integer',
        },
        max = {
            field = 'max',
            type = 'Integer',
        },
        avg = {
            field = 'avg',
            type = 'Integer',
        },
        is_implicit = {
            field = 'is_implicit',
            type = 'Boolean',
        },
        is_random = {
            field = 'is_random',
            type = 'Boolean',
        },
    },
}

-- There probably will be a table named "buffs" in the future, so "item_buffs" is the best solution here
c.schema.item_buffs = {
    table = 'item_buffs',
    fields = {
        id = core.map.buff_id,
        buff_values = core.map.buff_values,
        stat_text = core.map.buff_stat_text,
        icon = core.map.buff_icon,
    },
}

c.schema.amulets = {
    table = 'amulets',
    fields = {
        is_talisman = core.map.is_talisman,
        talisman_tier = core.map.talisman_tier,
    },
}

c.schema.flasks = {
    table = 'flasks',
    fields = {
        -- All flasks
        duration = core.map.flask_duration,
        charges_max = core.map.charges_max,
        charges_per_use = core.map.charges_per_use,
        -- Life/Mana/Hybrid flasks
        life = core.map.flask_life,
        mana = core.map.flask_mana,
    },
}

c.schema.weapons = {
    table = 'weapons',
    fields = {
        critical_strike_chance = core.map.critical_strike_chance,
        attack_speed = core.map.attack_speed,
        weapon_range = core.map.weapon_range,
        physical_damage_min = core.map.physical_damage_min,
        physical_damage_max = core.map.physical_damage_max,
        physical_damage_html = core.map.physical_damage_html,
        fire_damage_html = core.map.fire_damage_html,
        cold_damage_html = core.map.cold_damage_html,
        lightning_damage_html = core.map.lightning_damage_html,
        chaos_damage_html = core.map.chaos_damage_html,
        damage_avg = core.map.damage_avg,
        damage_html = core.map.damage_html,
        
        -- Values added via stat population
        fire_damage_min = core.map.fire_damage_min,
        fire_damage_max = core.map.fire_damage_max,
        cold_damage_min = core.map.cold_damage_min,
        cold_damage_max = core.map.cold_damage_max,
        lightning_damage_min = core.map.lightning_damage_min,
        lightning_damage_max = core.map.lightning_damage_max,
        chaos_damage_min = core.map.chaos_damage_min,
        chaos_damage_max = core.map.chaos_damage_max,
    },
}

c.schema.armours = {
    table = 'armours',
    fields = {
        armour = core.map.armour,
        energy_shield = core.map.energy_shield,
        evasion = core.map.evasion,
        ward = core.map.ward,
        movement_speed = core.map.movement_speed,
    },
}

c.schema.shields = {
    table = 'shields',
    fields = {
        block = core.map.block,
    }
}

c.schema.skill_gems = {
    table = 'skill_gems',
    fields = {
        gem_description = core.map.gem_description,
        dexterity_percent = core.map.dexterity_percent,
        strength_percent = core.map.strength_percent,
        intelligence_percent = core.map.intelligence_percent,
        primary_attribute = core.map.primary_attribute,
        gem_tags = core.map.gem_tags,
        -- Support Skill Gems
        support_gem_letter = core.map.support_gem_letter,
        support_gem_letter_html = core.map.support_gem_letter_html,
    },
}

c.schema.maps = {
    table = 'maps',
    fields = {
        tier = core.map.map_tier,
        guild_character = core.map.map_guild_character,
        unique_guild_character = core.map.unique_map_guild_character,
        area_id = core.map.map_area_id,
        unique_area_id = core.map.unique_map_area_id,
        series = core.map.map_series,
        
        -- REMOVE?
        area_level = core.map.map_area_level,
        unique_area_level = core.map.unique_map_area_level,
    },
}

c.schema.atlas_maps = {
    table = 'atlas_maps',
    fields = {
        x = core.map.atlas_x,
        y = core.map.atlas_y,
        region_id = core.map.atlas_region_id,
        region_minimum = core.map.atlas_region_minimum,
        x0 = core.map.atlas_x0,
        x1 = core.map.atlas_x1,
        x2 = core.map.atlas_x2,
        x3 = core.map.atlas_x3,
        x4 = core.map.atlas_x4,
        y0 = core.map.atlas_y0,
        y1 = core.map.atlas_y1,
        y2 = core.map.atlas_y2,
        y3 = core.map.atlas_y3,
        y4 = core.map.atlas_y4,
        map_tier0 = core.map.atlas_map_tier0,
        map_tier1 = core.map.atlas_map_tier1,
        map_tier2 = core.map.atlas_map_tier2,
        map_tier3 = core.map.atlas_map_tier3,
        map_tier4 = core.map.atlas_map_tier4,
    },
}

c.schema.atlas_connections = {
    table = 'atlas_connections',
    fields = {
        map1 = {
            field = 'map1',
            type = 'String',
        },
        map2 = {
            field = 'map2',
            type = 'String',
        },
        region0 = {
            field = 'region0',
            type = 'Boolean',
        },
        region1 = {
            field = 'region1',
            type = 'Boolean',
        },
        region2 = {
            field = 'region2',
            type = 'Boolean',
        },
        region3 = {
            field = 'region3',
            type = 'Boolean',
        },
        region4 = {
            field = 'region4',
            type = 'Boolean',
        },
    },
}

c.schema.stackables = {
    table = 'stackables',
    fields = {
        stack_size = core.map.stack_size,
        stack_size_currency_tab = core.map.stack_size_currency_tab,
    },
}

c.schema.cosmetic_items = {
    table = 'cosmetic_items',
    fields = {
        cosmetic_type = core.map.cosmetic_type,
    },
}

c.schema.essences = {
    table = 'essences',
    fields = {
        level_restriction = core.map.essence_level_restriction,
        level = core.map.essence_level,
        type = core.map.essence_type,
        category  = core.map.essence_category,
    },
}

c.schema.blight_items = {
    table = 'blight_items',
    fields = {
        tier = core.map.blight_item_tier,
    },
}

c.schema.hideout_doodads = {
    table = 'hideout_doodads',
    fields = {
        is_master_doodad = core.map.is_master_doodad,
        master = core.map.master,
        master_level_requirement = core.map.master_level_requirement,
        master_favour_cost = core.map.master_favour_cost,
        variation_count = core.map.variation_count,
    },
}

c.schema.prophecies = {
    table = 'prophecies',
    fields = {
        prophecy_id = core.map.prophecy_id,
        prediction_text = core.map.prediction_text,
        seal_cost = core.map.seal_cost,
        objective = core.map.prophecy_objective,
        reward = core.map.prophecy_reward,
    },
}

c.schema.divination_cards = {
    table = 'divination_cards',
    fields = {
        card_art = core.map.card_art,
    },
}

c.schema.jewels = {
    table = 'jewels',
    fields = {
        item_limit = core.map.item_limit,
        radius_html = core.map.jewel_radius_html,
    },
}

c.schema.incubators = {
    table = 'incubators',
    fields = {
        effect = core.map.incubator_effect,
    },
}

c.schema.harvest_seeds = {
    table = 'harvest_seeds', 
    fields = {
        effect = core.map.seed_effect,
        type_id = core.map.seed_type_id,
        type = core.map.seed_type,
        tier = core.map.seed_tier,
        growth_cycles = core.map.seed_growth_cycles,
        required_nearby_seed_tier = core.map.seed_required_nearby_seed_tier,
        required_nearby_seed_amount = core.map.seed_required_nearby_seed_amount,
        consumed_wild_lifeforce_percentage = core.map.seed_consumed_wild_lifeforce_percentage,
        consumed_vivid_lifeforce_percentage = core.map.seed_consumed_vivid_lifeforce_percentage,
        consumed_primal_lifeforce_percentage = core.map.seed_consumed_primal_lifeforce_percentage,
        granted_craft_option_ids = core.map.seed_granted_craft_option_ids,
    },
}

c.schema.harvest_plant_boosters = {
    table = 'harvest_plant_boosters',
    fields = {
        radius = core.map.plant_booster_radius,
        lifeforce = core.map.plant_booster_lifeforce,
        additional_crafting_options = core.map.plant_booster_additional_crafting_options,
        extra_chances = core.map.plant_booster_extra_chances,
    },
}

c.schema.heist_equipment = {
    table = 'heist_equipment',
    fields = {
        required_job_id = core.map.heist_required_job_id,
        required_job_level = core.map.heist_required_job_level,
    },
}

c.schema.upgraded_from_sets = {
    table = 'upgraded_from_sets',
    fields = {
        set_id = {
            field = 'set_id',
            type = 'Integer',
        },
        text = {
            field = 'text',
            type = 'Text',
        },
        automatic = {
            field = 'automatic',
            type = 'Boolean',
        },
    }
}

c.schema.upgraded_from_groups = {
    table = 'upgraded_from_groups',
    fields = {
        group_id = {
            field = 'group_id',
            type = 'Integer',
        },
        set_id = {
            field = 'set_id',
            type = 'Integer',
        },
        item_id = {
            field = 'item_id',
            type = 'String',
        },
        item_name = {
            field = 'item_name',
            type = 'String',
        },
        item_page = {
            field = 'item_page',
            type = 'Page',
        },
        integer = {
            field = 'amount',
            type = 'Integer',
        },
        notes = {
            field = 'notes',
            type = 'Text',
        },
    }
}

c.schema.quest_rewards = {
    table = 'quest_rewards',
    fields = {
        quest = {
            field = 'quest',
            type = 'String',
        },
        quest_id = {
            field = 'quest_id',
            type = 'String',
        },
        -- still needed?
        act = {
            field = 'act',
            type = 'Integer',
        },
        classes = {
            field = 'classes',
            type = 'List (,) of String',
        },
        class_ids = {
            field = 'class_ids',
            type = 'List (,) of String',
        },
        sockets = {
            field = 'sockets',
            type = 'Integer',
        },
        item_level = {
            field = 'item_level',
            type = 'Integer',
        },
        rarity = {
            field = 'rarity',
            type = 'String',
        },
        notes = {
            field = 'notes',
            type = 'Text',
        },
    },
}

c.schema.vendor_rewards = {
    table = 'vendor_rewards',
    fields = {
        quest = {
            field = 'quest',
            type = 'String',
        },
        quest_id = {
            field = 'quest_id',
            type = 'String',
        },
        act = {
            field = 'act',
            type = 'Integer',
        },
        npc = {
            field = 'npc',
            type = 'String',
        },
        classes = {
            field = 'classes',
            type = 'List (,) of String',
        },
        class_ids = {
            field = 'class_ids',
            type = 'List (,) of String',
        },
    }
}

-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------

local p = {}

p.table_items = h.declare_factory(c.schema.items)
p.table_item_sell_prices = h.declare_factory(c.schema.item_sell_prices)
p.table_item_purchase_costs = h.declare_factory(c.schema.item_purchase_costs)
p.table_item_mods = h.declare_factory(c.schema.item_mods)
p.table_item_stats = h.declare_factory(c.schema.item_stats)
p.table_item_buffs = h.declare_factory(c.schema.item_buffs)
p.table_amulets = h.declare_factory(c.schema.amulets)
p.table_flasks = h.declare_factory(c.schema.flasks)
p.table_weapons = h.declare_factory(c.schema.weapons)
p.table_armours = h.declare_factory(c.schema.armours)
p.table_shields = h.declare_factory(c.schema.shields)
p.table_skill_gems = h.declare_factory(c.schema.skill_gems)
p.table_maps = h.declare_factory(c.schema.maps)
p.table_atlas_maps = h.declare_factory(c.schema.atlas_maps)
p.table_atlas_connections = h.declare_factory(c.schema.atlas_connections)
p.table_stackables = h.declare_factory(c.schema.stackables)
p.table_cosmetic_items = h.declare_factory(c.schema.cosmetic_items)
p.table_essences = h.declare_factory(c.schema.essences)
p.table_blight_items = h.declare_factory(c.schema.blight_items)
p.table_hideout_doodads = h.declare_factory(c.schema.hideout_doodads)
p.table_prophecies = h.declare_factory(c.schema.prophecies)
p.table_divination_cards = h.declare_factory(c.schema.divination_cards)
p.table_jewels = h.declare_factory(c.schema.jewels)
p.table_incubators = h.declare_factory(c.schema.incubators)
p.table_harvest_seeds = h.declare_factory(c.schema.harvest_seeds)
p.table_harvest_plant_boosters = h.declare_factory(c.schema.harvest_plant_boosters)
p.table_heist_equipment = h.declare_factory(c.schema.heist_equipment)
p.table_upgraded_from_sets = h.declare_factory(c.schema.upgraded_from_sets)
p.table_upgraded_from_groups = h.declare_factory(c.schema.upgraded_from_groups)
p.table_quest_rewards = h.declare_factory(c.schema.quest_rewards)
p.table_vendor_rewards = h.declare_factory(c.schema.vendor_rewards)

function p.append_schema(tpl_args, frame, tables)
    --[[
    This function adds specified table names to core.map. The range fields for 
    those tables are also appended to core.map.
    --]]
    for _, table_name in ipairs(tables) do
        local field_keys = m_util.table.keys(c.schema[table_name].fields)
        for _, k in ipairs(field_keys) do
            local field_data = c.schema[table_name].fields[k]
            field_data.table = table_name
            for _, stat_data in pairs(core.stat_map) do
                if stat_data.field == k then
                    for _, range_field in ipairs(c.range_fields) do
                        local field_name = stat_data.field .. range_field.field
                        local data = {
                            inherit = true,
                            table = table_name,
                            field = field_name,
                            -- if the type is nil, use the parent type
                            -- this is set integer/float values correctly
                            type = range_field.type or field_data.type,
                        }
                        -- c.schema[table_name].fields[field_name] = data -- We're not using the schema again, so there's no need to update the schema with the added fields
                        core.map[field_name] = data
                    end
                    break
                end
            end
            if table_name == 'weapons' then
                for _, dps_data in pairs(core.dps_map) do
                    for _, range_field in ipairs(c.range_fields) do
                        local field_name = dps_data.field .. range_field.field
                        local data = {
                            inherit = true,
                            table = table_name,
                            field = field_name,
                            -- dps values are floating points
                            type = range_field.type or 'Float',
                        }
                        -- c.schema[table_name].fields[field_name] = data
                        core.map[field_name] = data
                    end
                end
            end
        end
    end
end

--
-- Debug
--

function p.debug_print_tables(frame)
    frame = m_util.misc.get_frame(frame)
    for key, data in pairs(c.schema) do
        mw.logObject(data.table)
    end
end

function p.debug_attach_test(frame)
    frame = m_util.misc.get_frame(frame)
    for key, data in pairs(c.schema) do
        m_cargo.attach(frame, {_table=data.table})
    end
end

return p