Module:AutoUpdateAgPrices
From MicrasWiki
Jump to navigationJump to search
Documentation for this module may be created at Module:AutoUpdateAgPrices/doc
--------------------------------------------------------- -- Module:DailyPriceTable -- Generates a table of daily-updated product prices, -- with each cell changing automatically once per day. -- -- Features: -- • Seeds randomness each day using localTime.year + localTime.yday -- • No manual intervention required -- • Tier prices derived from the final adjusted price -- • Minor event-based price boost for special days --------------------------------------------------------- local p = {} --------------------------------------------------------- -- 1. getCurrentDate -- Determines today's PSSC date and returns: -- * dateString in "day/month/year [PSSC]" -- * dayOfMonth (1..61 or 1..61 or 1..61) -- * month (1=Atosiel, 2=Thalassiel, 3=Opsitheiel) --------------------------------------------------------- local function getCurrentDate() local startDate = os.time({year = 1999, month = 8, day = 6}) local secondsInDay = 86400 local daysPerYear = 183 local currentDate = os.time() local totalDaysElapsed = math.floor((currentDate - startDate) / secondsInDay) local yearFraction = totalDaysElapsed / daysPerYear local psscYear = math.floor(yearFraction) local dayOfYear = math.floor((yearFraction - psscYear) * daysPerYear) + 1 local month, dayOfMonth if dayOfYear <= 61 then month = 1 dayOfMonth = dayOfYear elseif dayOfYear <= 122 then month = 2 dayOfMonth = dayOfYear - 61 else month = 3 dayOfMonth = dayOfYear - 122 end return string.format("%d/%d/%d [[PSSC]]", dayOfMonth, month, psscYear), dayOfMonth, month end --------------------------------------------------------- -- 2. Product Data --------------------------------------------------------- local products = { {"Rice", "Gladeseed Farmers' Union", 9.00, "tons"}, {"Edible Algae", "Gladeseed Farmers' Union", 21.00, "tons"}, {"Shrimp", "Gladeseed Farmers' Union", 15.00, "tons"}, {"Anterran Spicy Onion", "Gladeseed Farmers' Union", 18.00, "tons"}, {"Queen's Garlic", "Gladeseed Farmers' Union", 27.00, "tons"}, {"Morovian Water Buffalo", "Atterian Cattle Drivers", 6.60, "herds"}, {"Unprocessed Noctic-Rabrev Flower", "Noctic Fleet", 6.00, "bales"}, {"Processed Noctic Rabrev Flower", "Noctic Fleet", 2.50, "crates"}, {"Noctic-Rabrev Flower Concentrate", "Noctic Fleet", 3.00, "barrels"}, {"Unprocessed Noctic-Rabrev Leaf", "Noctic Fleet", 15.00, "bales"}, {"Processed Noctic-Rabrev Leaf", "Noctic Fleet", 5.79, "crates"}, {"Unprocessed Noctic-Rabrev Leaf Concentrate", "Noctic Fleet", 6.00, "barrels"}, {"Processed Noctic-Rabrev Leaf Concentrate", "Noctic Fleet", 3.00, "barrels"}, {"Manwine", "Jogiani Merchants of Manwine", 2.07, "barrels"}, {"Milkwine", "Jogiani Merchants of Manwine", 6.00, "barrels"}, {"Zoe Elm Resin (Unrefined)", "Keepers of the Grove of Zoe Elm", 0.03, "barrels"}, {"Zoe Elm Resin (Refined)", "Keepers of the Grove of Zoe Elm", 0.04, "barrels"}, {"Sea Elm Flavored Mead", "Sea-Elm Southern Meadery", 1.11, "barrels"}, {"Wheat", "Plains of Jogi", 0.30, "tons"}, {"Oats", "Plains of Jogi", 0.23, "tons"}, {"Cereal", "Plains of Jogi", 0.52, "pallets"}, {"Hay", "Plains of Jogi", 0.45, "bales"}, {"Ale of the Night", "Ale of the Night Central Brewery", 2.43, "barrels"}, {"Camels", "Camel Herders of the Jangsong Province", 1.04, "herds"}, {"Camel Meat", "Camel Herders of the Jangsong Province", 34.65, "tons"}, {"Camel Milk", "Camel Herders of the Jangsong Province", 5.20, "barrels"}, {"Camel Hump Water", "Camel Herders of the Jangsong Province", 3.47, "barrels"}, {"Camel Hump Water Tea", "Camel Herders of the Jangsong Province", 0.86, "barrels"}, {"Pearls", "Anterran Imports and Services", 0.79, "sacks"}, {"Abalone", "Anterran Imports and Services", 2.64, "crates"}, {"Opium", "Merchant Guild of the Poppy Goddess", 0.18, "sacks"}, {"Hash", "Merchant Guild of the Poppy Goddess", 0.17, "sacks"}, {"Mead", "Grand Cave Bee Meadery", 0.49, "barrels"}, {"Cinammon", "Cinammon Plains of Roue", 0.45, "tons"}, {"Velvet Worm Meat", "The Velvet Company", 1.04, "tons"}, {"Velvet Worm Eggs", "The Velvet Company", 0.35, "crates"}, {"Silk", "Seamstresses of Rouge", 5.00, "rolls"}, {"Horehound Mead", "Salurian Temple of Sacred Horehound", 0.05, "barrels"}, {"Horehound Beer", "Salurian Temple of Sacred Horehound", 0.07, "barrels"}, {"Sea Cow Beef", "Bulhanu Ranchers' Association", 8.50, "tons"}, {"Atterian Armored Pufferfish", "Suncliff Fisheries", 3.00, "tons"}, {"Morovian Saucer Eyed Giant Eel", "Suncliff Fisheries", 7.50, "tons"}, {"Amina Crab", "Suncliff Fisheries", 6.00, "tons"}, {"Mugwort Oil", "Ministers of Mistress Mugwort", 0.35, "barrels"}, {"Ground Mugwort", "Ministers of Mistress Mugwort", 0.75, "sacks"}, {"Mugwort Tincture", "Ministers of Mistress Mugwort", 0.10, "barrels"}, {"Blood InfusedRed Wine", "Blood Vineyards of the Far North", 0.39, "barrels"}, {"Wisp Rice", "Norsolyrian Wisp Rice Farmers Association", 15.00, "tons"}, {"Giid-Lisea-Eda", "Giid Lisea Ranching Import Company", 0.41, "shipments"}, {"Vaeringheim Turkey Meat", "Bird Keepers of Saluria", 1.07, "tons"}, {"Salurian Swamp Quail Eggs", "Bird Keepers of Saluria", 12.00, "crates"}, {"Giant Fanged Penguin Blubber", "Hunters of the Giant Fanged Penguin", 25.00, "tons"}, {"Giant Fanged Penguin Blubber Oil Extract", "Hunters of the Giant Fanged Penguin", 5.00, "barrels"}, } --------------------------------------------------------- -- 3. Special Date Events --------------------------------------------------------- local events = { ["1,6"] = "Bayram al-Nur (Festival of Light) [Vaeringheim]", ["1,18"] = "Chag Or Hadash (Festival of New Light) [Luminaria]", ["1,30"] = "Symposion Eirinis (Symposium of Harmony) [Serena]", ["1,43"] = "Alev Günü (Day of Flame) [Pyralis]", ["1,48"] = "Day of Abandonment [Vaeringheim]", ["1,55"] = "Tikkun Tzel (Repair of Shadows) [Symphonara]", ["2,6"] = "Panegyris Chrysou (Golden Gathering) [Aurelia]", ["2,17"] = "Constitution Day [Luminaria]", ["2,19"] = "Mehtap Dalgası (Moonlit Tide) [Vaeringheim]", ["2,31"] = "Oneiro Foteino (Dream of Illumination) [Somniumpolis]", ["2,39"] = "Anniversary of victory in the New South Jangsong Campaign [Nexa]", ["2,44"] = "Erev Galgal (Eve of Cycles) [Nexa]", ["2,45"] = "Bassaridia Festival [Somniumpolis]", ["2,48"] = "Anniversary of victory in the Southern Lake Morovia Campaign [Somniumpolis]", ["2,54"] = "Leilat al-Kamar (Night of the Moon) [Lunalis Sancta]", ["2,61"] = "Taşrakah (Reverence of the Stone) [Luminaria]", ["3,6"] = "Chag Tvuah (Festival of Harvest) [Sylvapolis]", ["3,18"] = "Anagenesis Eirmos (Procession of Rebirth) [Acheron]", ["3,28"] = "Panagia Therizis (Holy Day of the Reaper) [Sylvapolis]", ["3,37"] = "Anniversary of victory in the Morovian Frontier Campaign [Acheron]", ["3,43"] = "Karnavali Thysias (Carnival of Celebration) [Erythros]", ["3,53"] = "Sefar Yashar (Straight Path Celebration) [Catonis Atrium]", } --------------------------------------------------------- -- 4. simulatePriceChange -- Randomly modifies the base price daily, -- applying a slight additional boost if -- a special event occurs on that dateKey. --------------------------------------------------------- local function simulatePriceChange(basePrice, dayOfMonth, month) local dateKey = string.format("%d,%d", month, dayOfMonth) local changeFactor = math.random(-20, 20) / 100 local explanation if events[dateKey] then explanation = events[dateKey] .. ": Prices influenced by event dynamics." changeFactor = changeFactor + 0.05 -- small boost for special events else explanation = "General market fluctuations." end local newPrice = math.floor((basePrice * (1 + changeFactor)) * 100) / 100 return newPrice, changeFactor, explanation end --------------------------------------------------------- -- 5. determinePriceLevel -- Example logic: if adjustedPrice < basePrice => "High" -- otherwise => "Low". --------------------------------------------------------- local function determinePriceLevel(basePrice, adjustedPrice) if adjustedPrice < basePrice then return "High" else return "Low" end end --------------------------------------------------------- -- 6. MAIN Table Generation --------------------------------------------------------- function p.generateTable() ------------------------------------------------------- -- Step A: create a daily seed for randomness -- Uses year + yday to ensure each day is unique ------------------------------------------------------- local localTime = os.date("*t") local dailySeed = localTime.year * 1000 + localTime.yday math.randomseed(dailySeed) -- Step B: gather date info local dateString, dayOfMonth, month = getCurrentDate() -- Step C: build table header local wikitable = "{| class=\"wikitable\"\n" .. "! Date (Day/Month/Year [[PSSC]]) !! Product !! Producing Company !! Base Price !! Price Level !! Tier III Price !! Tier II Price !! Tier I Price !! Units !! Explanation\n" -- We’ll track totals so we can compare average base vs. average new. local totalBase, totalNew = 0, 0 local count = 0 -- Step D: process each product with new daily random changes for _, product in ipairs(products) do local name = product[1] local company = product[2] local basePrice= product[3] local unit = product[4] -- 1) Adjust price with daily random change local newPrice, changeFactor, explanation = simulatePriceChange(basePrice, dayOfMonth, month) -- 2) Determine if "High" / "Low" based on basePrice local priceLevel = determinePriceLevel(basePrice, newPrice) -- 3) Tier prices local tierIIIPrice = math.floor((newPrice / 3) * 100) / 100 local tierIIPrice = math.floor((newPrice * 2 / 3) * 100) / 100 local tierIPrice = newPrice -- 4) Accumulate totals for later average totalBase = totalBase + basePrice totalNew = totalNew + newPrice count = count + 1 -- 5) Insert row wikitable = wikitable .. string.format( "|-\n| %s || %s || %s || %.2f || %s || %.2f || %.2f || %.2f || %s || %s\n", dateString, name, company, basePrice, priceLevel, tierIIIPrice, tierIIPrice, tierIPrice, unit, explanation ) end -- Step E: compute average and determine if overall "High" or "Low" local avgBase = totalBase / count local avgNew = totalNew / count -- Reuse the same logic: if adjusted < base => "High" else => "Low" local averagePriceLevel if avgNew < avgBase then averagePriceLevel = "High" else averagePriceLevel = "Low" end -- Step F: add a final row at the bottom wikitable = wikitable .. string.format( "|-\n! colspan=\"10\" | Average adjusted price (%.2f) compared to average base price (%.2f) is **%s**.\n", avgNew, avgBase, averagePriceLevel ) -- Close table wikitable = wikitable .. "|}" return wikitable end return p