Module:Resource data: Difference between revisions

From Beyond These Stars Official Wiki
Created to serve resource data from cargo and structure for consumption
 
now skips Coffee
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
--[[
Test in Scribunto console with:
=mw.dumpObject(p.get_resource("Power"))
=mw.dumpObject(p.get_all_resources())
=mw.dumpObject(p.get_name_by_id("Potato"))
]]--
local p = {}
local p = {}






--#region Cargo-related type definitions and constants
--#region MARK: Cargo types


--- Cargo row from querying Resources; all values are strings at runtime.
--- Cargo row from querying Resources; all values are strings at runtime.
Line 43: Line 49:
---@field DefinedResourceLists_5 string|nil
---@field DefinedResourceLists_5 string|nil


--#endregion
--#region MARK: Cargo consts


local QUERIES = {
local QUERIES = {
Line 48: Line 59:
     TABLE = "Resources",
     TABLE = "Resources",
     WHERE_NAME = "page_name",
     WHERE_NAME = "page_name",
     ORDER_BY = "sort_order",
    WHERE_ID = "Name",
     ORDER_BY = "page_name",
    FIELDS_NAME_ONLY = {
      "page_name",
    },
     -- Commented out fields are not used in the current implementation.
     -- Commented out fields are not used in the current implementation.
     FIELDS = {
     FIELDS = {
Line 68: Line 83:
       "PeepHappinessAdded",
       "PeepHappinessAdded",
       -- "DontDrop",
       -- "DontDrop",
       -- "ResourceTemperature",
       "ResourceTemperature",
       -- "SummaryType",
       -- "SummaryType",
       "ResourceCategory",
       -- "ResourceCategory",
       -- "Renewable",
       -- "Renewable",
       -- "KnownRecordName",
       -- "KnownRecordName",
Line 92: Line 107:




--#region Cargo queries
--#region MARK: Cargo queries
 
--- Skips unwanted resources from a query result.
---@param results CargoResourceRecord[]
---@return CargoResourceRecord[]
local function skip_unwanted_resources(results)
  local new_results = {}
  for _, record in ipairs(results) do
    if not p.SKIPPED_RESOURCE_NAMES[record.Name] then
      table.insert(new_results, record)
    end
  end
  return new_results
end
 
--- Queries cargo for all resource records.
---@return CargoResourceRecord[]
local function query_all_resources()
  local cargo = mw.ext.cargo
  if not cargo then return {} end
  local result = cargo.query(
    QUERIES.RESOURCES.TABLE,
    table.concat(QUERIES.RESOURCES.FIELDS, ","),
    {
      limit = 150,
      orderBy = QUERIES.RESOURCES.ORDER_BY,
    })
  if not result or #result == 0 then return {} end
  result = skip_unwanted_resources(result)
  return result
end


--- Queries cargo for the resource record with the given name.
--- Queries cargo for the resource record with the given name.
Line 107: Line 152:
     })
     })
   if not result or #result == 0 then return nil end
   if not result or #result == 0 then return nil end
  result = skip_unwanted_resources(result)
  return result[1]
end
--- Queries cargo for the resource page name only with the given id.
---@param resource_id string the id of the resource to fetch
---@return CargoResourceRecord|nil
local function query_resource_name_only(resource_id)
  local cargo = mw.ext.cargo
  if not cargo then return nil end
  local result = cargo.query(
    QUERIES.RESOURCES.TABLE,
    table.concat(QUERIES.RESOURCES.FIELDS_NAME_ONLY, ","),
    {
      where = QUERIES.RESOURCES.WHERE_ID .. '="' .. resource_id .. '"',
    })
  if not result or #result == 0 then return nil end
  result = skip_unwanted_resources(result)
   return result[1]
   return result[1]
end
end
Line 114: Line 177:




--#region Local helper functions
--#region MARK: Local helpers


--- Makes an array out of multiple optional fields from a resource record.
--- Makes an array out of multiple optional fields from a resource record.
Line 132: Line 195:
--- Restructures a resource record from the database into a more usable format.
--- Restructures a resource record from the database into a more usable format.
---@param record CargoResourceRecord the resource record retrieved from the database
---@param record CargoResourceRecord the resource record retrieved from the database
---@return ResourceRecord
---@return Resource
local function restructure_resource_record(record)
local function restructure_resource_record(record)
   local resource = {
   local resource = {
     name = record.page_name,
     name = record.Name,
    category = record.Type,
    produce_type = record.ProduceType,
     display_name = record.DisplayNameTerm_en,
     display_name = record.DisplayNameTerm_en,
     display_name_plural = record.DisplayNamePluralTerm_en,
     display_name_plural = record.DisplayNamePluralTerm_en,
     icon = record.IconAddress,
     icon = record.IconAddress,
    type = record.Type,
    produce_type = record.ProduceType,
     peep_carry_amount = tonumber(record.PeepCarryAmount),
     peep_carry_amount = tonumber(record.PeepCarryAmount),
     known_at_start = record.KnownAtStart,
     known_at_start = record.KnownAtStart,
    peep_temperature_effect = record.ResourceTemperature,
     peep_exhaustion_removed = tonumber(record.PeepExhaustionRemoved),
     peep_exhaustion_removed = tonumber(record.PeepExhaustionRemoved),
     peep_happiness_added = tonumber(record.PeepHappinessAdded),
     peep_happiness_added = tonumber(record.PeepHappinessAdded),
     peep_energy_added = tonumber(record.PeepEnergyAdded),
     peep_energy_added = tonumber(record.PeepEnergyAdded),
     resource_category = record.ResourceCategory,
     resource_list = {},
    defined_resource_lists = {},
   }
   }
   resource.resource_list = restructure_resource_list(record)
   resource.resource_list = restructure_resource_list(record)
Line 155: Line 218:




--#region Public interface
--#region MARK: Public interface


---@class ResourceDataModule
---@class ResourceDataModule
---@field get_all_resources fun(): ResourceRecord[] gets all resources
---@field get_all_resources fun(): Resource[] gets all resources
---@field get_resource fun(resource_name: string): ResourceRecord|nil looks up a resource by name
---@field get_resource fun(resource_name: string): Resource|nil looks up a resource by name
---@field get_name_by_id fun(id: string): string|nil looks up a resource page name by codename


p.MAX_RESOURCE_LISTS = 5
p.MAX_RESOURCE_LISTS = 5
p.POWER_RESOURCE_NAME = "Power"
p.POWER_RESOURCE_NAME = "Power"
p.SKIPPED_RESOURCE_NAMES = {
  ["Astrobaleenium_Ground"] = true,
  ["Crystal_Ground"] = true,
  ["FieldSeed"] = true,
  ["Gold_Ground"] = true,
  ["Honeycomb_Ground"] = true,
  ["Mystery_Ground"] = true,
  ["Peep"] = true,
  ["Shell_Ground"] = true,
  ["Trash_Ground"] = true,
  -- these are listed as "Fake"
  ["Beverage"] = true,
  ["Drink"] = true,
  ["Food"] = true,
  ["Meal"] = true,
  -- these are blank
  ["Coffee"] = true,
}


---@class ResourceRecord
---@class Resource
---@field name string|nil the in-game codename for the resource
---@field name string|nil the in-game codename for the resource
---@field category string|nil the category of the resource
---@field produce_type string|nil the produce type of the resource
---@field display_name string|nil the display name of the resource
---@field display_name string|nil the display name of the resource
---@field display_name_plural string|nil the plural display name of the resource
---@field display_name_plural string|nil the plural display name of the resource
---@field icon string|nil the icon filename for the resource
---@field icon string|nil the icon filename for the resource
---@field type string|nil the type of the resource
---@field peep_carry_amount number|nil how many a peep can carry at once
---@field produce_type string|nil the produce type of the resource
---@field peep_carry_amount number|nil the peep carry amount of the resource
---@field known_at_start boolean|nil whether the resource is known at start
---@field known_at_start boolean|nil whether the resource is known at start
---@field peep_temperature_effect string|nil the temperature effect of the resource
---@field peep_exhaustion_removed number|nil the amount of exhaustion removed per peep per second
---@field peep_exhaustion_removed number|nil the amount of exhaustion removed per peep per second
---@field peep_happiness_added number|nil the amount of happiness added per peep per second
---@field peep_happiness_added number|nil the amount of happiness added per peep per second
---@field peep_energy_added number|nil the amount of energy added per peep per second
---@field peep_energy_added number|nil the amount of energy added per peep per second
---@field resource_category string|nil the category of the resource
---@field resource_list string[]|nil the defined resource lists for the resource
---@field defined_resource_list string[]|nil the defined resource lists for the resource
 
--- Fetches a resource's page name by its id.
---@param id string the id of the resource to fetch
---@return string|nil the page name of the resource
function p.get_name_by_id(id)
  if not id or id == "" then return nil end
  local raw_record = query_resource_name_only(id)
  if not raw_record then return nil end
  return raw_record.page_name or nil
end


--- Fetches a resource record from the database.
--- Fetches a resource record from the database.
---@param resource_name string the in-game name of the resource to fetch
---@param resource_name string the in-game name of the resource to fetch
---@return ResourceRecord|nil
---@return Resource|nil
function p.get_resource(resource_name)
function p.get_resource(resource_name)
  if not resource_name or resource_name == "" then return nil end
   local raw_record = query_resource(resource_name)
   local raw_record = query_resource(resource_name)
   if not raw_record then return nil end
   if not raw_record then return nil end
   local record = restructure_resource_record(raw_record)
   local record = restructure_resource_record(raw_record)
   return record
   return record
end
--- Fetches all resource records from the database.
---@return Resource[]
function p.get_all_resources()
  local raw_records = query_all_resources()
  if not raw_records or #raw_records == 0 then return {} end
  local records = {}
  for _, raw_record in ipairs(raw_records) do
    local record = restructure_resource_record(raw_record)
    table.insert(records, record)
  end
  return records
end
end



Latest revision as of 20:18, 10 October 2026

Documentation for this module may be created at Module:Resource data/doc

--[[
Test in Scribunto console with:
=mw.dumpObject(p.get_resource("Power"))
=mw.dumpObject(p.get_all_resources())
=mw.dumpObject(p.get_name_by_id("Potato"))
]]--
local p = {}



--#region MARK: Cargo types

--- Cargo row from querying Resources; all values are strings at runtime.
---@class CargoResourceRecord
---@field page_name string|nil
---@field guid string|nil
---@field Name string|nil
---@field DisplayNameTerm string|nil
---@field DisplayNameTerm_en string|nil
---@field DisplayNamePluralTerm string|nil
---@field DisplayNamePluralTerm_en string|nil
---@field IconAddress string|nil
---@field ID string|nil
---@field PriorityAdjustment string|nil
---@field Type string|nil
---@field DefinedResourceLists string|nil
---@field ProduceType string|nil
---@field PeepCarryAmount string|nil
---@field KnownAtStart string|nil
---@field ProducedAtStart string|nil
---@field PeepExhaustionRemoved string|nil
---@field PeepHappinessAdded string|nil
---@field DontDrop string|nil
---@field ResourceTemperature string|nil
---@field SummaryType string|nil
---@field ResourceCategory string|nil
---@field Renewable string|nil
---@field KnownRecordName string|nil
---@field ProducedRecordName string|nil
---@field PollutionRatio string|nil
---@field PollutionRange string|nil
---@field PeepEnergyAdded string|nil
---@field TerrainTextureValueIndex string|nil
---@field YarnNodeOnSelect string|nil
---@field DefinedResourceLists_1 string|nil
---@field DefinedResourceLists_2 string|nil
---@field DefinedResourceLists_3 string|nil
---@field DefinedResourceLists_4 string|nil
---@field DefinedResourceLists_5 string|nil

--#endregion



--#region MARK: Cargo consts

local QUERIES = {
  RESOURCES = {
    TABLE = "Resources",
    WHERE_NAME = "page_name",
    WHERE_ID = "Name",
    ORDER_BY = "page_name",
    FIELDS_NAME_ONLY = {
      "page_name",
    },
    -- Commented out fields are not used in the current implementation.
    FIELDS = {
      "page_name",
      "guid",
      "Name",
      "DisplayNameTerm_en",
      "DisplayNamePluralTerm_en",
      "IconAddress",
      -- "ID",
      -- "PriorityAdjustment",
      "Type",
      -- "DefinedResourceLists",
      "ProduceType",
      "PeepCarryAmount",
      "KnownAtStart",
      -- "ProducedAtStart",
      "PeepExhaustionRemoved",
      "PeepHappinessAdded",
      -- "DontDrop",
      "ResourceTemperature",
      -- "SummaryType",
      -- "ResourceCategory",
      -- "Renewable",
      -- "KnownRecordName",
      -- "ProducedRecordName",
      -- "PollutionRatio",
      -- "PollutionRange",
      "PeepEnergyAdded",
      -- "TerrainTextureValueIndex",
      -- "YarnNodeOnSelect",
      "DefinedResourceLists_1",
      "DefinedResourceLists_2",
      "DefinedResourceLists_3",
      "DefinedResourceLists_4",
      "DefinedResourceLists_5",
    }
  }
}

--#endregion



--#region MARK: Cargo queries

--- Skips unwanted resources from a query result.
---@param results CargoResourceRecord[]
---@return CargoResourceRecord[]
local function skip_unwanted_resources(results)
  local new_results = {}
  for _, record in ipairs(results) do
    if not p.SKIPPED_RESOURCE_NAMES[record.Name] then
      table.insert(new_results, record)
    end
  end
  return new_results
end

--- Queries cargo for all resource records.
---@return CargoResourceRecord[]
local function query_all_resources()
  local cargo = mw.ext.cargo
  if not cargo then return {} end
  local result = cargo.query(
    QUERIES.RESOURCES.TABLE,
    table.concat(QUERIES.RESOURCES.FIELDS, ","),
    {
      limit = 150,
      orderBy = QUERIES.RESOURCES.ORDER_BY,
    })
  if not result or #result == 0 then return {} end
  result = skip_unwanted_resources(result)
  return result
end

--- Queries cargo for the resource record with the given name.
---@param resource_name string the name of the resource to fetch
---@return CargoResourceRecord|nil
local function query_resource(resource_name)
  local cargo = mw.ext.cargo
  if not cargo then return nil end
  local result = cargo.query(
    QUERIES.RESOURCES.TABLE,
    table.concat(QUERIES.RESOURCES.FIELDS, ","),
    {
      where = QUERIES.RESOURCES.WHERE_NAME .. '="' .. resource_name .. '"',
    })
  if not result or #result == 0 then return nil end
  result = skip_unwanted_resources(result)
  return result[1]
end

--- Queries cargo for the resource page name only with the given id.
---@param resource_id string the id of the resource to fetch
---@return CargoResourceRecord|nil
local function query_resource_name_only(resource_id)
  local cargo = mw.ext.cargo
  if not cargo then return nil end
  local result = cargo.query(
    QUERIES.RESOURCES.TABLE,
    table.concat(QUERIES.RESOURCES.FIELDS_NAME_ONLY, ","),
    {
      where = QUERIES.RESOURCES.WHERE_ID .. '="' .. resource_id .. '"',
    })
  if not result or #result == 0 then return nil end
  result = skip_unwanted_resources(result)
  return result[1]
end

--#endregion



--#region MARK: Local helpers

--- Makes an array out of multiple optional fields from a resource record.
---@param record CargoResourceRecord
---@return string[]
local function restructure_resource_list(record)
  local resource_list = {}
  for i = 1, p.MAX_RESOURCE_LISTS do
    local item = record[string.format("DefinedResourceLists_%d", i)]
    if item then
      table.insert(resource_list, item)
    end
  end
  return resource_list
end

--- Restructures a resource record from the database into a more usable format.
---@param record CargoResourceRecord the resource record retrieved from the database
---@return Resource
local function restructure_resource_record(record)
  local resource = {
    name = record.Name,
    category = record.Type,
    produce_type = record.ProduceType,
    display_name = record.DisplayNameTerm_en,
    display_name_plural = record.DisplayNamePluralTerm_en,
    icon = record.IconAddress,
    peep_carry_amount = tonumber(record.PeepCarryAmount),
    known_at_start = record.KnownAtStart,
    peep_temperature_effect = record.ResourceTemperature,
    peep_exhaustion_removed = tonumber(record.PeepExhaustionRemoved),
    peep_happiness_added = tonumber(record.PeepHappinessAdded),
    peep_energy_added = tonumber(record.PeepEnergyAdded),
    resource_list = {},
  }
  resource.resource_list = restructure_resource_list(record)
  return resource
end



--#region MARK: Public interface

---@class ResourceDataModule
---@field get_all_resources fun(): Resource[] gets all resources
---@field get_resource fun(resource_name: string): Resource|nil looks up a resource by name
---@field get_name_by_id fun(id: string): string|nil looks up a resource page name by codename

p.MAX_RESOURCE_LISTS = 5
p.POWER_RESOURCE_NAME = "Power"
p.SKIPPED_RESOURCE_NAMES = {
  ["Astrobaleenium_Ground"] = true,
  ["Crystal_Ground"] = true,
  ["FieldSeed"] = true,
  ["Gold_Ground"] = true,
  ["Honeycomb_Ground"] = true,
  ["Mystery_Ground"] = true,
  ["Peep"] = true,
  ["Shell_Ground"] = true,
  ["Trash_Ground"] = true,
  -- these are listed as "Fake"
  ["Beverage"] = true,
  ["Drink"] = true,
  ["Food"] = true,
  ["Meal"] = true,
  -- these are blank
  ["Coffee"] = true,
}

---@class Resource
---@field name string|nil the in-game codename for the resource
---@field category string|nil the category of the resource
---@field produce_type string|nil the produce type of the resource
---@field display_name string|nil the display name of the resource
---@field display_name_plural string|nil the plural display name of the resource
---@field icon string|nil the icon filename for the resource
---@field peep_carry_amount number|nil how many a peep can carry at once
---@field known_at_start boolean|nil whether the resource is known at start
---@field peep_temperature_effect string|nil the temperature effect of the resource
---@field peep_exhaustion_removed number|nil the amount of exhaustion removed per peep per second
---@field peep_happiness_added number|nil the amount of happiness added per peep per second
---@field peep_energy_added number|nil the amount of energy added per peep per second
---@field resource_list string[]|nil the defined resource lists for the resource

--- Fetches a resource's page name by its id.
---@param id string the id of the resource to fetch
---@return string|nil the page name of the resource
function p.get_name_by_id(id)
  if not id or id == "" then return nil end
  local raw_record = query_resource_name_only(id)
  if not raw_record then return nil end
  return raw_record.page_name or nil
end

--- Fetches a resource record from the database.
---@param resource_name string the in-game name of the resource to fetch
---@return Resource|nil
function p.get_resource(resource_name)
  if not resource_name or resource_name == "" then return nil end
  local raw_record = query_resource(resource_name)
  if not raw_record then return nil end
  local record = restructure_resource_record(raw_record)
  return record
end

--- Fetches all resource records from the database.
---@return Resource[]
function p.get_all_resources()
  local raw_records = query_all_resources()
  if not raw_records or #raw_records == 0 then return {} end
  local records = {}
  for _, raw_record in ipairs(raw_records) do
    local record = restructure_resource_record(raw_record)
    table.insert(records, record)
  end
  return records
end

---@cast p ResourceDataModule
return p

--#endregion