Welcome to the Umamusume Wiki! If you want to contribute, please read the guidelines.
Module:Game/Banners/Utils
< Module:Game | Banners
Documentation for this module may be created at Module:Game/Banners/Utils/doc
--[[
!! THIS PAGE IS MANAGED BY GITLAB !!
ANY EDITS TO PAGE CONTENT WILL BE OVERWRITTEN
TO MAKE CHANGES, PLEASE SUBMIT A MERGE REQUEST AT https://gitlab.com/umamusume-wiki/lua-modules
]]
local p = {}
function p.getReleaseDates(itemIds, itemType, language)
local Game = require("Module:Game")
local Utils = require("Module:Utils")
-- Language configuration: maps language code to {queryFunction, minTimestamp}
local languageConfig = {
JP = { func = Game.queryMaster, minTimestamp = 1614081600 }, -- Feb 23, 2021
EN = { func = Game.queryMasterEN, minTimestamp = 1750852800 }, -- Jul 25, 2025
-- Add future languages here, e.g.:
-- KR = { func = Game.queryMasterKR, minTimestamp = 1234567890 },
}
local config = languageConfig[language]
if not config then
error(string.format("Unsupported language: %s. Supported languages: %s",
language,
table.concat(Utils.getKeys(languageConfig), ", ")))
end
-- Determine card_type for gacha query and whether to append "01" for characters
local cardType = 1 -- default for playable cards
local queryIds = itemIds
if itemType == "support" then
cardType = 2
elseif itemType == "character" then
cardType = 1
-- For characters, append "01" to get the base card ID (e.g., "1001" -> "100101")
queryIds = {}
for _, charId in ipairs(itemIds) do
table.insert(queryIds, charId .. "01")
end
end
local itemIdsInsert = table.concat(queryIds, ",")
local minTimestamp = config.minTimestamp
local queryFunc = config.func
-- Step 1: Get gacha_available records for the items
local gacha_available = queryFunc {
from = "gacha_available",
where = string.format("gacha_available.card_id IN (%s) AND gacha_available.gacha_id >= 30000 AND gacha_available.gacha_id < 40000 AND gacha_available.card_type = %d", itemIdsInsert, cardType)
}
-- Step 2: Build mapping of card_id to gacha_ids
local gacha_ids = {}
local card_gacha_map = {}
for _, row in ipairs(gacha_available) do
gacha_ids[row.gacha_id] = true
if not card_gacha_map[row.card_id] then
card_gacha_map[row.card_id] = {}
end
table.insert(card_gacha_map[row.card_id], row.gacha_id)
end
-- Step 3: Get gacha_ids as array
local gacha_ids_array = {}
for id, _ in pairs(gacha_ids) do
table.insert(gacha_ids_array, id)
end
-- Step 4: Query gacha_data and find minimum dates
local releaseDates = {}
if #gacha_ids_array > 0 then
local gacha_ids_str = table.concat(gacha_ids_array, ",")
local gacha_data = queryFunc {
from = "gacha_data",
where = string.format("id IN (%s) AND start_date >= %d", gacha_ids_str, minTimestamp),
data = {
id = "id",
start_date = "start_date"
}
}
-- Step 5: Build lookup table for gacha dates
local gacha_dates = {}
for _, row in ipairs(gacha_data) do
gacha_dates[row.id] = row.start_date
end
-- Step 6: Find minimum date for each card
for card_id, gacha_id_list in pairs(card_gacha_map) do
local min_date = nil
for _, gacha_id in ipairs(gacha_id_list) do
local date = gacha_dates[gacha_id]
if date and tonumber(date) >= minTimestamp and (not min_date or tonumber(date) < tonumber(min_date)) then
min_date = date
end
end
if min_date then
-- For characters, map back from card ID to character ID (e.g., "100101" -> "1001")
if itemType == "character" then
local charId = string.sub(card_id, 1, -3) -- Remove last 2 digits
releaseDates[charId] = min_date
else
releaseDates[card_id] = min_date
end
end
end
end
return releaseDates
end
return p