Module:OrdersData: Difference between revisions
From Against the Storm Official Wiki
Anteprefix (talk | contribs) No edit summary |
Anteprefix (talk | contribs) Merge from OrdersData2 to implement filtering by settlement difficulty |
||
| (16 intermediate revisions by the same user not shown) | |||
| Line 12: | Line 12: | ||
--region Private member variables | --region Private member variables | ||
local | local ordersData2 | ||
--endregion | --endregion | ||
| Line 32: | Line 32: | ||
OrdersData.DIFFICULTY_MEDIUM_HARD = "medium, hard" | OrdersData.DIFFICULTY_MEDIUM_HARD = "medium, hard" | ||
OrdersData.DIFFICULTY_EASY_MEDIUM_HARD = "easy, medium, hard" | OrdersData.DIFFICULTY_EASY_MEDIUM_HARD = "easy, medium, hard" | ||
OrdersData.SETTLER = "settler" | |||
OrdersData.PIONEER = "pioneer" | |||
OrdersData.VETERAN = "veteran" | |||
OrdersData.VICEROY = "viceroy" | |||
OrdersData.PRESTIGE = "prestige" | |||
--endregion | --endregion | ||
| Line 86: | Line 92: | ||
[OrdersData.DIFFICULTY_EASY_MEDIUM_HARD] = true, | [OrdersData.DIFFICULTY_EASY_MEDIUM_HARD] = true, | ||
[OrdersData.NONE] = true, | [OrdersData.NONE] = true, | ||
} | |||
local SWITCH_SETTLEMENT_CHECK = { | |||
[OrdersData.SETTLER] = true, | |||
[OrdersData.PIONEER] = true, | |||
[OrdersData.VETERAN] = true, | |||
[OrdersData.VICEROY] = true, | |||
[OrdersData.PRESTIGE] = true, | |||
} | } | ||
| Line 97: | Line 111: | ||
["none"] = OrdersData.NONE, | ["none"] = OrdersData.NONE, | ||
} | } | ||
local NORMALIZED_TEXT_SETTLEMENT = { | |||
["settler"] = OrdersData.SETTLER, | |||
["pioneer"] = OrdersData.PIONEER, | |||
["veteran"] = OrdersData.VETERAN, | |||
["viceroy"] = OrdersData.VICEROY, | |||
["prestige"] = OrdersData.PRESTIGE, | |||
["none"] = OrdersData.NONE, | |||
} | |||
local SETTLEMENT_CHECK_ARRAY = { | |||
["settler"] = { | |||
["easy"] = {"i", "ii", "iii", "iv"}, | |||
["medium"] = {}, | |||
["hard"] = {}, | |||
["easy, medium"] = {"i", "ii", "iii", "iv"}, | |||
["medium, hard"] = {}, | |||
["easy, medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
}, | |||
["pioneer"] = { | |||
["easy"] = {"i", "ii", "iii", "iv"}, | |||
["medium"] = {"i", "ii", "iii", "iv"}, | |||
["hard"] = {}, | |||
["easy, medium"] = {"i", "ii", "iii", "iv"}, | |||
["medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
["easy, medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
}, | |||
["veteran"] = { | |||
["easy"] = {"i"}, | |||
["medium"] = {"i", "ii", "iii", "iv"}, | |||
["hard"] = {"iii", "iv"}, | |||
["easy, medium"] = {"i", "ii", "iii", "iv"}, | |||
["medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
["easy, medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
}, | |||
["viceroy"] = { | |||
["easy"] = {}, | |||
["medium"] = {"i", "ii", "iii", "iv"}, | |||
["hard"] = {"i", "ii", "iii"}, | |||
["easy, medium"] = {"i", "ii", "iii", "iv"}, | |||
["medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
["easy, medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
}, | |||
["prestige"] = { | |||
["easy"] = {}, | |||
["medium"] = {}, | |||
["hard"] = {"i", "ii", "iii", "iv"}, | |||
["easy, medium"] = {}, | |||
["medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
["easy, medium, hard"] = {"i", "ii", "iii", "iv"}, | |||
}, | |||
} | |||
local SETTLEMENT_REVERSE_CHECK_ARRAY = { | |||
["i"] = { | |||
["easy"] = {"settler", "pioneer", "veteran"}, | |||
["medium"] = {"pioneer", "veteran", "viceroy"}, | |||
["hard"] = {"viceroy", "prestige"}, | |||
["easy, medium"] = {"settler", "pioneer", "veteran", "viceroy"}, | |||
["medium, hard"] = {"pioneer", "veteran", "viceroy", "prestige"}, | |||
["easy, medium, hard"] = {"settler", "pioneer", "veteran", "viceroy", "prestige"}, | |||
}, | |||
["ii"] = { | |||
["easy"] = {"settler", "pioneer"}, | |||
["medium"] = {"pioneer", "veteran", "viceroy"}, | |||
["hard"] = {"viceroy", "prestige"}, | |||
["easy, medium"] = {"settler", "pioneer", "veteran", "viceroy"}, | |||
["medium, hard"] = {"pioneer", "veteran", "viceroy", "prestige"}, | |||
["easy, medium, hard"] = {"settler", "pioneer", "veteran", "viceroy", "prestige"}, | |||
}, | |||
["iii"] = { | |||
["easy"] = {"settler", "pioneer"}, | |||
["medium"] = {"pioneer", "veteran", "viceroy"}, | |||
["hard"] = {"veteran", "viceroy", "prestige"}, | |||
["easy, medium"] = {"settler", "pioneer", "veteran", "viceroy"}, | |||
["medium, hard"] = {"pioneer", "veteran", "viceroy", "prestige"}, | |||
["easy, medium, hard"] = {"settler", "pioneer", "veteran", "viceroy", "prestige"}, | |||
}, | |||
["iv"] = { | |||
["easy"] = {"settler", "pioneer"}, | |||
["medium"] = {"pioneer", "veteran", "viceroy"}, | |||
["hard"] = {"veteran", "prestige"}, | |||
["easy, medium"] = {"settler", "pioneer", "veteran", "viceroy"}, | |||
["medium, hard"] = {"pioneer", "veteran", "viceroy", "prestige"}, | |||
["easy, medium, hard"] = {"settler", "pioneer", "veteran", "viceroy", "prestige"}, | |||
}, | |||
} | |||
| Line 126: | Line 225: | ||
IS_TIMED_TRUE = "true", | IS_TIMED_TRUE = "true", | ||
IS_TIMED_FALSE = " | IS_TIMED_FALSE = "false", | ||
} | } | ||
| Line 146: | Line 245: | ||
if not ordersData then | if not ordersData then | ||
local newData = JsonUtils.convertJSONToLuaTable(DATA_FILE) | --local newData = JsonUtils.convertJSONToLuaTable(DATA_FILE) | ||
--Promote the ID to be the key of the main data table. | --Promote the ID to be the key of the main data table. | ||
ordersData = {} | ordersData = {} | ||
--for _, order in ipairs(newData) do | |||
--OrdersData[order[SCHEMA.ID]] = order | |||
--end | |||
--OrdersData = mw.loadJsonData("Module:OrdersData/Orders.json") | |||
local newData = mw.loadJsonData("Module:OrdersData/Orders.json") | |||
for _, order in ipairs(newData) do | for _, order in ipairs(newData) do | ||
ordersData[order[SCHEMA.ID]] = order | ordersData[order[SCHEMA.ID]] = order | ||
end | end | ||
end | end | ||
end | end | ||
| Line 195: | Line 300: | ||
return difficultyList | return difficultyList | ||
end | end | ||
end | |||
local function getSettlementsArrayByID(orderID) | |||
local difficulties = OrdersData.getDifficulties(orderID) | |||
local tierRaw = OrdersData.getTiers(orderID) | |||
local tier = OrdersData.normalizeTierText(tierRaw[1]) | |||
local settlementsArray = {} | |||
local isSettlementAlreadyAdded = {} | |||
for i, diff in ipairs(difficulties) do | |||
diff = OrdersData.normalizeDifficultyText(diff) | |||
for sett, diffToMatch in pairs(SETTLEMENT_CHECK_ARRAY) do | |||
local diffArray = diffToMatch[diff] | |||
if diffArray then | |||
for j, tierToMatch in ipairs(diffArray) do | |||
if tierToMatch == tier then | |||
if not isSettlementAlreadyAdded[sett] then | |||
isSettlementAlreadyAdded[sett] = true | |||
table.insert(settlementsArray, sett) | |||
end | |||
end | |||
end | |||
end | |||
end | |||
end | |||
return settlementsArray | |||
end | end | ||
| Line 363: | Line 495: | ||
function OrdersData.getFormattedRequirementsByIDAndRowNum(orderID, rowNum) | function OrdersData.getFormattedRequirementsByIDAndRowNum(orderID, rowNum) | ||
requirements = getRequirementByIDAndRow(orderID, rowNum) | requirements = getRequirementByIDAndRow(orderID, rowNum) | ||
local requirementsAmount = #requirements | --local requirementsAmount = #requirements | ||
local formattedRequirements = "" | local formattedRequirements = "" | ||
for i | for i, _ in ipairs(requirements) do | ||
if i > 1 then | if i > 1 then | ||
formattedRequirements = formattedRequirements .. "<br />" | formattedRequirements = formattedRequirements .. "<br />" | ||
| Line 386: | Line 518: | ||
for i = 1, rewardsAmount do | for i = 1, rewardsAmount do | ||
if i > 1 then | if i > 1 then | ||
formattedRewards = formattedRewards .. " | formattedRewards = formattedRewards .. "<br /><br />" | ||
end | end | ||
local reward = rewards[i][ | for j,k in ipairs(rewards[i]) do | ||
if j > 1 then | |||
formattedRewards = formattedRewards .. " or <br />" | |||
end | |||
local reward = rewards[i][j] | |||
if reward then | |||
if string.find(reward[SCHEMA.REWARD_ID], "Blueprint") then | |||
formattedRewards = formattedRewards .. reward[SCHEMA.REWARD_NAME] .. " Blueprint" | |||
else | |||
formattedRewards = formattedRewards .. reward[SCHEMA.REWARD_DESCRIPTION] | |||
end | |||
end | |||
end | end | ||
end | end | ||
| Line 412: | Line 553: | ||
function OrdersData.getDifficulties(orderID) | function OrdersData.getDifficulties(orderID) | ||
return getDifficultiesArrayByID(orderID) | return getDifficultiesArrayByID(orderID) | ||
end | |||
---@public | |||
-----Gets the valid settlement difficulties of the specified order. | |||
----- | |||
-----@param orderID string | |||
-----@return array the list of valid settlement difficulties | |||
function OrdersData.getSettlements(orderID) | |||
return getSettlementsArrayByID(orderID) | |||
end | end | ||
| Line 462: | Line 612: | ||
--- If the provided tier is nil or not an accepted term (for example misspelled), this will return nil. | --- If the provided tier is nil or not an accepted term (for example misspelled), this will return nil. | ||
--- | --- | ||
---@param | ---@param difficultyString string the descriptive name of the difficulty of an order | ||
---@return string that same | ---@return string that same string, normalized to title case | ||
function OrdersData.normalizeDifficultyText(difficultyString) | function OrdersData.normalizeDifficultyText(difficultyString) | ||
| Line 473: | Line 623: | ||
local difficulty = string.lower(difficultyString) | local difficulty = string.lower(difficultyString) | ||
if not difficulty or not SWITCH_DIFFICULTIES_CHECK[difficulty] then | if not difficulty or not SWITCH_DIFFICULTIES_CHECK[difficulty] then | ||
return nil | return nil | ||
end | end | ||
return NORMALIZED_TEXT_DIFFICULTIES[difficulty] | return NORMALIZED_TEXT_DIFFICULTIES[difficulty] | ||
end | |||
--- Standardizes the display of a string name of one of Orders' settlement difficulty. | |||
--- | |||
--- If the provided tier is nil or not an accepted term (for example misspelled), this will return nil. | |||
--- | |||
---@param settlementString string the descriptive name of the settlement difficulty of an order | |||
---@return string that same string, normalized to title case | |||
function OrdersData.normalizeSettlementDifficultyText(settlementString) | |||
if not settlementString or "" == settlementString then | |||
return nil | |||
end | |||
local settlement = string.lower(settlementString) | |||
if not settlement or not SWITCH_SETTLEMENT_CHECK[settlement] then | |||
return nil | |||
end | |||
return NORMALIZED_TEXT_SETTLEMENT[settlement] | |||
end | end | ||
| Line 541: | Line 710: | ||
local difficulties = OrdersData.getDifficulties(orderID) | local difficulties = OrdersData.getDifficulties(orderID) | ||
for i, diff in ipairs(difficulties) do | for i, diff in ipairs(difficulties) do | ||
OrdersData.normalizeDifficultyText(diff) | if string.find(OrdersData.normalizeDifficultyText(diff), difficultyToMatch) then | ||
--if string. | return true | ||
end | |||
end | |||
return false | |||
end | |||
---isSettlementMatchByID | |||
---@param orderID string the unique identifier of an Order | |||
---@param settlementToMatch string the settlement difficulty to check against | |||
---@return boolean true if the settlement difficulty is valid for the orderID checked | |||
function OrdersData.isSettlementMatchByID(orderID, settlementToMatch) | |||
local settlements = OrdersData.getSettlements(orderID) | |||
for i, sett in ipairs(settlements) do | |||
if OrdersData.normalizeSettlementDifficultyText(sett) == settlementToMatch then | |||
return true | |||
end | |||
end | |||
return false | |||
end | |||
---isSettlementMatchSpecificOrder | |||
---@param orderDifficulty string the difficulty string of an order | |||
---@param orderTier string the tier string of an order | |||
---@param settlementToMatch string the settlement difficulty to check against | |||
---@return boolean true if the settlement difficulty is valid for the difficulty and tier combo checked | |||
function OrdersData.isSettlementMatchSpecificOrder(orderDifficulty, orderTier, settlementToMatch) | |||
local tier = OrdersData.normalizeTierText(orderTier[1]) | |||
local difficulty = OrdersData.normalizeDifficultyText(orderDifficulty) | |||
local settlementArray = SETTLEMENT_REVERSE_CHECK_ARRAY[tier][difficulty] | |||
for i, sett in ipairs(settlementArray) do | |||
if OrdersData.normalizeSettlementDifficultyText(sett) == settlementToMatch then | |||
return true | |||
end | |||
end | end | ||
return false | return false | ||
end | end | ||
---getAllOrdersIDsWhereName | ---getAllOrdersIDsWhereName | ||
--- Loop through all orders and return those whose names contain the | --- Loop through all orders and return those whose names contain the | ||
| Line 568: | Line 769: | ||
if string.lower(order[SCHEMA.NAME]):find(string.lower(searchTerm)) then | if string.lower(order[SCHEMA.NAME]):find(string.lower(searchTerm)) then | ||
table.insert(list, order[SCHEMA.ID]) | |||
end | |||
end | |||
return list | |||
end | |||
---getAllOrdersIDsWhereRequirements | |||
--- Loop through all orders and return those whose requirements contain the | |||
--- specified search term. | |||
--- | |||
---@param searchTerm string terms to search for | |||
---@return table list of orderIDs with a match in their name | |||
function OrdersData.getAllOrdersIDsWhereRequirements(searchTerm) | |||
if not searchTerm then | |||
return {} | |||
end | |||
if not ordersData then | |||
loadData() | |||
end | |||
local list = {} | |||
for _, order in pairs(ordersData) do | |||
local numRows = #getRequirementsArrayByID(order[SCHEMA.ID]) | |||
--local numRows = #requirementsArray | |||
local isMatch = false | |||
for i = 1, numRows do | |||
if not isMatch then | |||
if string.lower(OrdersData.getFormattedRequirementsByIDAndRowNum(order[SCHEMA.ID], i)):find(string.lower(searchTerm)) then | |||
table.insert(list, order[SCHEMA.ID]) | |||
end | |||
end | |||
end | |||
end | |||
return list | |||
end | |||
---getAllOrdersIDsWhereRequirements | |||
--- Loop through all orders and return those whose requirements contain the | |||
--- specified search term. | |||
--- | |||
---@param searchTerm string terms to search for | |||
---@return table list of orderIDs with a match in their name | |||
function OrdersData.getAllOrdersIDsWhereRewards(searchTerm) | |||
if not searchTerm then | |||
return {} | |||
end | |||
if not ordersData then | |||
loadData() | |||
end | |||
local list = {} | |||
for _, order in pairs(ordersData) do | |||
if string.lower(OrdersData.getRewardsFormattedByID(order[SCHEMA.ID])):find(string.lower(searchTerm)) then | |||
table.insert(list, order[SCHEMA.ID]) | table.insert(list, order[SCHEMA.ID]) | ||
end | end | ||
Latest revision as of 01:47, 21 October 2025
Documentation for this module may be created at Module:OrdersData/doc
---@class OrdersData
local OrdersData = {}
--region Dependencies
local JsonUtils = require("Module:JsonUtils")
--endregion
--region Private member variables
local ordersData2
--endregion
--region Public enums
OrdersData.TIER_I = "i"
OrdersData.TIER_II = "ii"
OrdersData.TIER_III = "iii"
OrdersData.TIER_IV = "iv"
OrdersData.NONE = "none"
OrdersData.TRUE = "true"
OrdersData.FALSE = "false"
OrdersData.DIFFICULTY_EASY = "easy"
OrdersData.DIFFICULTY_MEDIUM = "medium"
OrdersData.DIFFICULTY_HARD = "hard"
OrdersData.DIFFICULTY_EASY_MEDIUM = "easy, medium"
OrdersData.DIFFICULTY_MEDIUM_HARD = "medium, hard"
OrdersData.DIFFICULTY_EASY_MEDIUM_HARD = "easy, medium, hard"
OrdersData.SETTLER = "settler"
OrdersData.PIONEER = "pioneer"
OrdersData.VETERAN = "veteran"
OrdersData.VICEROY = "viceroy"
OrdersData.PRESTIGE = "prestige"
--endregion
--region Private constants
local DATA_FILE = "Module:OrdersData/Orders.json"
local SWITCH_TIERS_CHECK = {
[OrdersData.TIER_I] = true,
[OrdersData.TIER_II] = true,
[OrdersData.TIER_III] = true,
[OrdersData.TIER_IV] = true,
[OrdersData.NONE] = true,
}
local NORMALIZED_TEXT_TIERS = {
["i"] = OrdersData.TIER_I,
["ii"] = OrdersData.TIER_II,
["iii"] = OrdersData.TIER_III,
["iv"] = OrdersData.TIER_IV,
["none"] = OrdersData.NONE,
}
local SWITCH_TIMED_CHECK = {
[OrdersData.TRUE] = true,
[OrdersData.FALSE] = true,
[OrdersData.NONE] = true,
}
local NORMALIZED_TEXT_TIMED = {
["true"] = OrdersData.TRUE,
["false"] = OrdersData.FALSE,
["none"] = OrdersData.NONE,
}
local TIERS_SORT_ORDER = {
[OrdersData.TIER_I] = 1,
[OrdersData.TIER_II] = 2,
[OrdersData.TIER_III] = 3,
[OrdersData.TIER_IV] = 4,
}
local SWITCH_DIFFICULTIES_CHECK = {
[OrdersData.DIFFICULTY_EASY] = true,
[OrdersData.DIFFICULTY_MEDIUM] = true,
[OrdersData.DIFFICULTY_HARD] = true,
[OrdersData.DIFFICULTY_EASY_MEDIUM] = true,
[OrdersData.DIFFICULTY_MEDIUM_HARD] = true,
[OrdersData.DIFFICULTY_EASY_MEDIUM_HARD] = true,
[OrdersData.NONE] = true,
}
local SWITCH_SETTLEMENT_CHECK = {
[OrdersData.SETTLER] = true,
[OrdersData.PIONEER] = true,
[OrdersData.VETERAN] = true,
[OrdersData.VICEROY] = true,
[OrdersData.PRESTIGE] = true,
}
local NORMALIZED_TEXT_DIFFICULTIES = {
["easy"] = OrdersData.DIFFICULTY_EASY,
["medium"] = OrdersData.DIFFICULTY_MEDIUM,
["hard"] = OrdersData.DIFFICULTY_HARD,
["easy, medium"] = OrdersData.DIFFICULTY_EASY_MEDIUM,
["medium, hard"] = OrdersData.DIFFICULTY_MEDIUM_HARD,
["easy, medium, hard"] = OrdersData.DIFFICULTY_EASY_MEDIUM_HARD,
["none"] = OrdersData.NONE,
}
local NORMALIZED_TEXT_SETTLEMENT = {
["settler"] = OrdersData.SETTLER,
["pioneer"] = OrdersData.PIONEER,
["veteran"] = OrdersData.VETERAN,
["viceroy"] = OrdersData.VICEROY,
["prestige"] = OrdersData.PRESTIGE,
["none"] = OrdersData.NONE,
}
local SETTLEMENT_CHECK_ARRAY = {
["settler"] = {
["easy"] = {"i", "ii", "iii", "iv"},
["medium"] = {},
["hard"] = {},
["easy, medium"] = {"i", "ii", "iii", "iv"},
["medium, hard"] = {},
["easy, medium, hard"] = {"i", "ii", "iii", "iv"},
},
["pioneer"] = {
["easy"] = {"i", "ii", "iii", "iv"},
["medium"] = {"i", "ii", "iii", "iv"},
["hard"] = {},
["easy, medium"] = {"i", "ii", "iii", "iv"},
["medium, hard"] = {"i", "ii", "iii", "iv"},
["easy, medium, hard"] = {"i", "ii", "iii", "iv"},
},
["veteran"] = {
["easy"] = {"i"},
["medium"] = {"i", "ii", "iii", "iv"},
["hard"] = {"iii", "iv"},
["easy, medium"] = {"i", "ii", "iii", "iv"},
["medium, hard"] = {"i", "ii", "iii", "iv"},
["easy, medium, hard"] = {"i", "ii", "iii", "iv"},
},
["viceroy"] = {
["easy"] = {},
["medium"] = {"i", "ii", "iii", "iv"},
["hard"] = {"i", "ii", "iii"},
["easy, medium"] = {"i", "ii", "iii", "iv"},
["medium, hard"] = {"i", "ii", "iii", "iv"},
["easy, medium, hard"] = {"i", "ii", "iii", "iv"},
},
["prestige"] = {
["easy"] = {},
["medium"] = {},
["hard"] = {"i", "ii", "iii", "iv"},
["easy, medium"] = {},
["medium, hard"] = {"i", "ii", "iii", "iv"},
["easy, medium, hard"] = {"i", "ii", "iii", "iv"},
},
}
local SETTLEMENT_REVERSE_CHECK_ARRAY = {
["i"] = {
["easy"] = {"settler", "pioneer", "veteran"},
["medium"] = {"pioneer", "veteran", "viceroy"},
["hard"] = {"viceroy", "prestige"},
["easy, medium"] = {"settler", "pioneer", "veteran", "viceroy"},
["medium, hard"] = {"pioneer", "veteran", "viceroy", "prestige"},
["easy, medium, hard"] = {"settler", "pioneer", "veteran", "viceroy", "prestige"},
},
["ii"] = {
["easy"] = {"settler", "pioneer"},
["medium"] = {"pioneer", "veteran", "viceroy"},
["hard"] = {"viceroy", "prestige"},
["easy, medium"] = {"settler", "pioneer", "veteran", "viceroy"},
["medium, hard"] = {"pioneer", "veteran", "viceroy", "prestige"},
["easy, medium, hard"] = {"settler", "pioneer", "veteran", "viceroy", "prestige"},
},
["iii"] = {
["easy"] = {"settler", "pioneer"},
["medium"] = {"pioneer", "veteran", "viceroy"},
["hard"] = {"veteran", "viceroy", "prestige"},
["easy, medium"] = {"settler", "pioneer", "veteran", "viceroy"},
["medium, hard"] = {"pioneer", "veteran", "viceroy", "prestige"},
["easy, medium, hard"] = {"settler", "pioneer", "veteran", "viceroy", "prestige"},
},
["iv"] = {
["easy"] = {"settler", "pioneer"},
["medium"] = {"pioneer", "veteran", "viceroy"},
["hard"] = {"veteran", "prestige"},
["easy, medium"] = {"settler", "pioneer", "veteran", "viceroy"},
["medium, hard"] = {"pioneer", "veteran", "viceroy", "prestige"},
["easy, medium, hard"] = {"settler", "pioneer", "veteran", "viceroy", "prestige"},
},
}
local SCHEMA = {
ID = "id",
NAME = "displayName",
TIERS = "tiers",
TIMED_ORDER = "isTimed",
TIME_LIMIT = "timeToFail",
OBJECTIVES = "objectivesSets",
DIFFICULTY = "difficulty",
REQUIREMENTS = "logics",
REQUIREMENT_TYPE = "type",
REQUIREMENT_AMOUNT = "amount",
REQUIREMENT_ICON = "icon",
REQUIREMENT_NAME = "displayName",
REQUIREMENT_DESCRIPTION = "description",
REWARD_1 = "rewards1",
REWARD_2 = "rewards2",
REWARD_3 = "rewards3",
REWARD_ID = "id",
REWARD_NAME = "displayName",
REWARD_DESCRIPTION = "description",
IS_TIMED_TRUE = "true",
IS_TIMED_FALSE = "false",
}
local ERROR_MESSAGE_INVALID_FUNCTION_CALL = "Invalid function call to OrdersData"
--endregion
--region Localization string constants
--endregion
--region Private methods
local function loadData()
if not ordersData then
--local newData = JsonUtils.convertJSONToLuaTable(DATA_FILE)
--Promote the ID to be the key of the main data table.
ordersData = {}
--for _, order in ipairs(newData) do
--OrdersData[order[SCHEMA.ID]] = order
--end
--OrdersData = mw.loadJsonData("Module:OrdersData/Orders.json")
local newData = mw.loadJsonData("Module:OrdersData/Orders.json")
for _, order in ipairs(newData) do
ordersData[order[SCHEMA.ID]] = order
end
end
end
local function getOrderFieldByID(orderID, fieldName)
loadData()
local order = ordersData[orderID]
if not order then
return nil
else
return order[fieldName]
end
end
local function getObjectivesArrayByID(orderID)
loadData()
local objectives = getOrderFieldByID(orderID, SCHEMA.OBJECTIVES)
if not objectives then
return nil
else
return objectives
end
end
local function getDifficultiesArrayByID(orderID)
loadData()
local objectives = getObjectivesArrayByID(orderID)
if not objectives then
return nil
else
local difficultyList = {}
for i, obj in pairs(objectives) do
for j, value in pairs(objectives[i]) do
if j == SCHEMA.DIFFICULTY then
table.insert(difficultyList,value)
end
end
end
return difficultyList
end
end
local function getSettlementsArrayByID(orderID)
local difficulties = OrdersData.getDifficulties(orderID)
local tierRaw = OrdersData.getTiers(orderID)
local tier = OrdersData.normalizeTierText(tierRaw[1])
local settlementsArray = {}
local isSettlementAlreadyAdded = {}
for i, diff in ipairs(difficulties) do
diff = OrdersData.normalizeDifficultyText(diff)
for sett, diffToMatch in pairs(SETTLEMENT_CHECK_ARRAY) do
local diffArray = diffToMatch[diff]
if diffArray then
for j, tierToMatch in ipairs(diffArray) do
if tierToMatch == tier then
if not isSettlementAlreadyAdded[sett] then
isSettlementAlreadyAdded[sett] = true
table.insert(settlementsArray, sett)
end
end
end
end
end
end
return settlementsArray
end
local function getRequirementsArrayByID(orderID)
loadData()
local objectives = getObjectivesArrayByID(orderID)
if not objectives then
return nil
else
local requirementsList = {}
for i, obj in pairs(objectives) do
for j, value in pairs(objectives[i]) do
if j == SCHEMA.REQUIREMENTS then
table.insert(requirementsList,value)
end
end
end
return requirementsList
end
end
local function getRequirementByIDAndRow(orderID, rowNum)
local requirements = getRequirementsArrayByID(orderID)
local requirement = requirements[rowNum]
if not requirement then
return nil
else
return requirement
end
end
local function getSpecificRequirementByIDAndRowAndSubrow(orderID, rowNum, subrow)
local specific = getRequirementByIDAndRow(orderID, rowNum)[subrow]
if not specific then
return nil
else
return specific
end
end
local function getSpecificRequirementFieldByIDAndRowAndSubrowAndField(orderID, rowNum, subrow, field)
local specificField = getSpecificRequirementByIDAndRowAndSubrow(orderID, rowNum, subrow)[field]
if not specificField then
return nil
else
return specificField
end
end
local function makeFormattedRequirementByIDAndRowNumAndSubrow(orderID, rowNum, subrow)
local requirementType = getSpecificRequirementFieldByIDAndRowAndSubrowAndField(orderID, rowNum, subrow, SCHEMA.REQUIREMENT_TYPE)
if not requirementType then
return nil
end
---It's better if the following parts are reworked to not be hardcoded in the future
---For Good Delivery requirements, use the name instead of description
if requirementType == "Good" then
local requirementString = getSpecificRequirementFieldByIDAndRowAndSubrowAndField(orderID, rowNum, subrow, SCHEMA.REQUIREMENT_NAME)
requirementString = requirementString .. ". "
return requirementString
end
---For owning at least X buildings of type Y, use "Own at least [X] [Y](s)."
if requirementType == "BuildingOwning" then
local requirementString = "Own at least "
local requirementAmount = getSpecificRequirementFieldByIDAndRowAndSubrowAndField(orderID, rowNum, subrow, SCHEMA.REQUIREMENT_AMOUNT)
local requirementBuildingName = getSpecificRequirementFieldByIDAndRowAndSubrowAndField(orderID, rowNum, subrow, SCHEMA.REQUIREMENT_NAME)
if tonumber(requirementAmount) > 1 then
requirementString = requirementString .. requirementAmount .. " " .. requirementBuildingName .. "s."
else
requirementString = requirementString .. requirementAmount .. " " .. requirementBuildingName .. ". "
end
return requirementString
end
---For producing at least X goods, use "Produce [X] Goods in any capable building."
if requirementType == "GoodProduced" then
local requirementString = getSpecificRequirementFieldByIDAndRowAndSubrowAndField(orderID, rowNum, subrow, SCHEMA.REQUIREMENT_DESCRIPTION)
local requirementAmount = getSpecificRequirementFieldByIDAndRowAndSubrowAndField(orderID, rowNum, subrow, SCHEMA.REQUIREMENT_AMOUNT)
requirementString = requirementString:sub(1, 7) .. " " .. requirementAmount .. requirementString:sub(8)
return requirementString
end
---In any other case, the description is already properly formatted
return getSpecificRequirementFieldByIDAndRowAndSubrowAndField(orderID, rowNum, subrow, SCHEMA.REQUIREMENT_DESCRIPTION)
end
local function getRewardsByID(orderID)
local reward1 = getOrderFieldByID(orderID, SCHEMA.REWARD_1)
local reward2 = getOrderFieldByID(orderID, SCHEMA.REWARD_2)
local reward3 = getOrderFieldByID(orderID, SCHEMA.REWARD_3)
return {reward1, reward2, reward3}
end
--endregion
--region Public methods
---@public
---Gets an array of all IDs of orders in the data.
---
---@return table an array of IDs
function OrdersData.getAllOrderIDs()
loadData()
local orderIDs = {}
for id, _ in pairs(ordersData) do
table.insert(orderIDs, id)
end
return orderIDs
end
---@public
-----Gets the name of the specified order.
-----
-----@param orderID string
-----@return string the display name
function OrdersData.getNameByID(orderID)
return getOrderFieldByID(orderID, SCHEMA.NAME)
end
---@public
-----Gets the tiers of the specified order.
-----
-----@param orderID string
-----@return array the list of valid tiers
function OrdersData.getTiers(orderID)
return getOrderFieldByID(orderID, SCHEMA.TIERS)
end
---@public
-----Gets the timed status of the specified order.
-----
-----@param orderID string
-----@return boolean the timed status
function OrdersData.getTimed(orderID)
return getOrderFieldByID(orderID, SCHEMA.TIMED_ORDER)
end
---@public
-----Gets the time limit of the specified order.
-----
-----@param orderID string
-----@return number the time limit
function OrdersData.getTimeLimit(orderID)
return getOrderFieldByID(orderID, SCHEMA.TIME_LIMIT)
end
---@public
-----Gets the specified difficulty of the specified order.
-----
-----@param orderID string
-----@param rowNum integer
-----@return difficultyList[rowNum] the difficulty listed in that row
function OrdersData.getDifficultyByIDAndRowNum(orderID, rowNum)
local difficultyList = getDifficultiesArrayByID(orderID)
return difficultyList[rowNum]
end
---@public
-----Gets the specified requirements of the specified order and returns it after formatting it for display.
-----
-----@param orderID string
-----@param rowNum integer
-----@return string the appropriately formatted requirement description
function OrdersData.getFormattedRequirementsByIDAndRowNum(orderID, rowNum)
requirements = getRequirementByIDAndRow(orderID, rowNum)
--local requirementsAmount = #requirements
local formattedRequirements = ""
for i, _ in ipairs(requirements) do
if i > 1 then
formattedRequirements = formattedRequirements .. "<br />"
end
formattedRequirements = formattedRequirements .. makeFormattedRequirementByIDAndRowNumAndSubrow(orderID, rowNum, i)
end
return formattedRequirements
end
---@public
-----Gets the specified rewards of the specified order and returns it after formatting it for display.
-----
-----@param orderID string
-----@return string the appropriately formatted rewards description
function OrdersData.getRewardsFormattedByID(orderID)
local rewards = getRewardsByID(orderID)
local rewardsAmount = #rewards
local formattedRewards = ""
for i = 1, rewardsAmount do
if i > 1 then
formattedRewards = formattedRewards .. "<br /><br />"
end
for j,k in ipairs(rewards[i]) do
if j > 1 then
formattedRewards = formattedRewards .. " or <br />"
end
local reward = rewards[i][j]
if reward then
if string.find(reward[SCHEMA.REWARD_ID], "Blueprint") then
formattedRewards = formattedRewards .. reward[SCHEMA.REWARD_NAME] .. " Blueprint"
else
formattedRewards = formattedRewards .. reward[SCHEMA.REWARD_DESCRIPTION]
end
end
end
end
return formattedRewards
end
---@public
-----Gets the number of unique difficulties for the order.
-----
-----@param orderID string
-----@return difficultyList[rowNum] the difficulty listed in that row
function OrdersData.getNumberOfDifficulties(orderID)
return #getDifficultiesArrayByID(orderID)
end
---@public
-----Gets the valid difficulties of the specified order.
-----
-----@param orderID string
-----@return array the list of valid difficulties
function OrdersData.getDifficulties(orderID)
return getDifficultiesArrayByID(orderID)
end
---@public
-----Gets the valid settlement difficulties of the specified order.
-----
-----@param orderID string
-----@return array the list of valid settlement difficulties
function OrdersData.getSettlements(orderID)
return getSettlementsArrayByID(orderID)
end
--- Standardizes the display of a string name of one of Orders' tier.
---
--- If the provided tier is nil or not an accepted term (for example misspelled), this will return nil.
---
---@param tierString string the descriptive name of the tier of an order
---@return string that same tier, normalized to title case
function OrdersData.normalizeTierText(tierString)
if not tierString or "" == tierString then
return nil
end
local tier = string.lower(tierString)
if not tier or not SWITCH_TIERS_CHECK[tier] then
return nil
end
return NORMALIZED_TEXT_TIERS[tier]
end
--- Standardizes the display of a string name of one of Orders' timed status.
---
--- If the provided tier is nil or not an accepted term (for example misspelled), this will return nil.
---
---@param timedString string the descriptive name of the timed status of an order
---@return string that same timed status, normalized to title case
function OrdersData.normalizeTimedText(timedString)
if not timedString or "" == timedString then
return nil
end
local timed = string.lower(timedString)
if not timed or not SWITCH_TIMED_CHECK[timed] then
return nil
end
return NORMALIZED_TEXT_TIMED[timed]
end
--- Standardizes the display of a string name of one of Orders' difficulty.
---
--- If the provided tier is nil or not an accepted term (for example misspelled), this will return nil.
---
---@param difficultyString string the descriptive name of the difficulty of an order
---@return string that same string, normalized to title case
function OrdersData.normalizeDifficultyText(difficultyString)
if not difficultyString or "" == difficultyString then
return nil
end
local difficulty = string.lower(difficultyString)
if not difficulty or not SWITCH_DIFFICULTIES_CHECK[difficulty] then
return nil
end
return NORMALIZED_TEXT_DIFFICULTIES[difficulty]
end
--- Standardizes the display of a string name of one of Orders' settlement difficulty.
---
--- If the provided tier is nil or not an accepted term (for example misspelled), this will return nil.
---
---@param settlementString string the descriptive name of the settlement difficulty of an order
---@return string that same string, normalized to title case
function OrdersData.normalizeSettlementDifficultyText(settlementString)
if not settlementString or "" == settlementString then
return nil
end
local settlement = string.lower(settlementString)
if not settlement or not SWITCH_SETTLEMENT_CHECK[settlement] then
return nil
end
return NORMALIZED_TEXT_SETTLEMENT[settlement]
end
---isOrderIDValid
---@param orderID string the unique identifier of an Order
---@return boolean true if there is a record with the specified ID
function OrdersData.isOrderIDValid(orderID)
if not orderID or "" == orderID then
return false
else
local record = OrdersData.getNameByID(orderID)
return record ~= nil
end
end
--endregion
---isTierMatchByID
---@param orderID string the unique identifier of an Order
---@param tierToMatch string the tier to check against
---@return boolean true if the tier matches
function OrdersData.isTierMatchByID(orderID, tierToMatch)
local record = OrdersData.getTiers(orderID)
--need to retrieve first entry in record because of nested tables and convert to lowercase
if OrdersData.normalizeTierText(record[1]) == tierToMatch then
return true
else
return false
end
end
---isTimedMatchByID
---@param orderID string the unique identifier of an Order
---@param timedToMatch boolean the timed status to check against
---@return boolean true if the status matches
function OrdersData.isTimedMatchByID(orderID, timedToMatch)
local record = OrdersData.getTimed(orderID)
if record then
if timedToMatch == SCHEMA.IS_TIMED_TRUE then
return true
end
if timedToMatch == SCHEMA.IS_TIMED_FALSE then
return false
end
else
if timedToMatch == SCHEMA.IS_TIMED_TRUE then
return false
end
if timedToMatch == SCHEMA.IS_TIMED_FALSE then
return true
end
end
error(ERROR_MESSAGE_INVALID_FUNCTION_CALL .. ": isTimedMatchByID was called but could not return a boolean.")
end
---isDifficultyMatchByID
---@param orderID string the unique identifier of an Order
---@param difficultyToMatch string the order difficulty to check against
---@return boolean true if the difficulty matches a substring in the array
function OrdersData.isDifficultyMatchByID(orderID, difficultyToMatch)
local difficulties = OrdersData.getDifficulties(orderID)
for i, diff in ipairs(difficulties) do
if string.find(OrdersData.normalizeDifficultyText(diff), difficultyToMatch) then
return true
end
end
return false
end
---isSettlementMatchByID
---@param orderID string the unique identifier of an Order
---@param settlementToMatch string the settlement difficulty to check against
---@return boolean true if the settlement difficulty is valid for the orderID checked
function OrdersData.isSettlementMatchByID(orderID, settlementToMatch)
local settlements = OrdersData.getSettlements(orderID)
for i, sett in ipairs(settlements) do
if OrdersData.normalizeSettlementDifficultyText(sett) == settlementToMatch then
return true
end
end
return false
end
---isSettlementMatchSpecificOrder
---@param orderDifficulty string the difficulty string of an order
---@param orderTier string the tier string of an order
---@param settlementToMatch string the settlement difficulty to check against
---@return boolean true if the settlement difficulty is valid for the difficulty and tier combo checked
function OrdersData.isSettlementMatchSpecificOrder(orderDifficulty, orderTier, settlementToMatch)
local tier = OrdersData.normalizeTierText(orderTier[1])
local difficulty = OrdersData.normalizeDifficultyText(orderDifficulty)
local settlementArray = SETTLEMENT_REVERSE_CHECK_ARRAY[tier][difficulty]
for i, sett in ipairs(settlementArray) do
if OrdersData.normalizeSettlementDifficultyText(sett) == settlementToMatch then
return true
end
end
return false
end
---getAllOrdersIDsWhereName
--- Loop through all orders and return those whose names contain the
--- specified search term.
---
---@param searchTerm string terms to search for
---@return table list of orderIDs with a match in their name
function OrdersData.getAllOrdersIDsWhereName(searchTerm)
if not searchTerm then
return {}
end
if not ordersData then
loadData()
end
local list = {}
for _, order in pairs(ordersData) do
if string.lower(order[SCHEMA.NAME]):find(string.lower(searchTerm)) then
table.insert(list, order[SCHEMA.ID])
end
end
return list
end
---getAllOrdersIDsWhereRequirements
--- Loop through all orders and return those whose requirements contain the
--- specified search term.
---
---@param searchTerm string terms to search for
---@return table list of orderIDs with a match in their name
function OrdersData.getAllOrdersIDsWhereRequirements(searchTerm)
if not searchTerm then
return {}
end
if not ordersData then
loadData()
end
local list = {}
for _, order in pairs(ordersData) do
local numRows = #getRequirementsArrayByID(order[SCHEMA.ID])
--local numRows = #requirementsArray
local isMatch = false
for i = 1, numRows do
if not isMatch then
if string.lower(OrdersData.getFormattedRequirementsByIDAndRowNum(order[SCHEMA.ID], i)):find(string.lower(searchTerm)) then
table.insert(list, order[SCHEMA.ID])
end
end
end
end
return list
end
---getAllOrdersIDsWhereRequirements
--- Loop through all orders and return those whose requirements contain the
--- specified search term.
---
---@param searchTerm string terms to search for
---@return table list of orderIDs with a match in their name
function OrdersData.getAllOrdersIDsWhereRewards(searchTerm)
if not searchTerm then
return {}
end
if not ordersData then
loadData()
end
local list = {}
for _, order in pairs(ordersData) do
if string.lower(OrdersData.getRewardsFormattedByID(order[SCHEMA.ID])):find(string.lower(searchTerm)) then
table.insert(list, order[SCHEMA.ID])
end
end
return list
end
--endregion
return OrdersData


