import { GameConfig } from "./config.js"; /** * @param {number} baseCost * @param {number} growth * @param {number} level * @returns {number} */ export function exponentialCost(baseCost, growth, level) { const exponent = Math.max(0, level - 1); return Math.floor(baseCost * Math.pow(growth, exponent) + 0.5); } /** * @param {number} currentLevel * @returns {number} */ export function getConveyorUpgradeCost(currentLevel) { return exponentialCost( GameConfig.Conveyor.BaseUpgradeCost, GameConfig.Conveyor.UpgradeGrowth, currentLevel ); } /** * @param {number} currentLevel * @returns {number} */ export function getTruckUpgradeCost(currentLevel) { return exponentialCost( GameConfig.Truck.BaseUpgradeCost, GameConfig.Truck.UpgradeGrowth, currentLevel ); } /** * @param {number} currentLevel * @returns {number} */ export function getSchoolUpgradeCost(currentLevel) { return exponentialCost( GameConfig.School.BaseUpgradeCost, GameConfig.School.UpgradeGrowth, currentLevel ); } /** * @param {number} currentLevel * @returns {number} */ export function getWorldMapUpgradeCost(currentLevel) { const cfg = GameConfig.WorldMap && GameConfig.WorldMap.MapUpgrade; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** * Research points required to upgrade world map level (phase 9: agrandissement en unités de recherche). * @param {number} currentLevel * @returns {number} */ export function getWorldMapUpgradeResearchCost(currentLevel) { const cfg = GameConfig.WorldMap && GameConfig.WorldMap.MapUpgrade; if (!cfg || cfg.BaseResearchCost === null || cfg.BaseResearchCost === undefined) return 9999; const growth = cfg.ResearchUpgradeGrowth ?? 1.6; return exponentialCost(cfg.BaseResearchCost, growth, currentLevel); } /** * @param {number} currentLevel * @returns {number} */ export function getPlotUpgradeCost(currentLevel) { return exponentialCost( GameConfig.Plot.BaseUpgradeCost, GameConfig.Plot.UpgradeGrowth, currentLevel ); } /** * @returns {number} */ export function getNurseryBuildCost() { return GameConfig.Nursery?.BuildCost ?? 200; } /** * @param {number} currentLevel * @returns {number} */ export function getNurseryUpgradeCost(currentLevel) { const cfg = GameConfig.Nursery; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** * @returns {number} */ export function getSouvenirShopBuildCost() { return GameConfig.SouvenirShop?.BuildCost ?? 250; } /** * @param {number} currentLevel * @returns {number} */ export function getSouvenirShopUpgradeCost(currentLevel) { const cfg = GameConfig.SouvenirShop; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** * @returns {number} */ export function getResearchBuildCost() { return GameConfig.Research?.BuildCost ?? 300; } /** * @param {number} currentLevel * @returns {number} */ export function getResearchUpgradeCost(currentLevel) { const cfg = GameConfig.Research; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** * @returns {number} */ export function getBilleterieBuildCost() { return GameConfig.Billeterie?.BuildCost ?? 280; } /** * @param {number} currentLevel * @returns {number} */ export function getBilleterieUpgradeCost(currentLevel) { const cfg = GameConfig.Billeterie; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** * @returns {number} */ export function getFoodBuildCost() { return GameConfig.Food?.BuildCost ?? 260; } /** * @param {number} currentLevel * @returns {number} */ export function getFoodUpgradeCost(currentLevel) { const cfg = GameConfig.Food; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** * @returns {number} */ export function getReceptionBuildCost() { return GameConfig.Reception?.BuildCost ?? 240; } /** * @param {number} currentLevel * @returns {number} */ export function getReceptionUpgradeCost(currentLevel) { const cfg = GameConfig.Reception; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** * @returns {number} */ export function getBiomeChangeColorBuildCost() { return GameConfig.BiomeChangeColor?.BuildCost ?? 340; } /** * @param {number} currentLevel * @returns {number} */ export function getBiomeChangeColorUpgradeCost(currentLevel) { const cfg = GameConfig.BiomeChangeColor; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** * @returns {number} */ export function getBiomeChangeTempBuildCost() { return GameConfig.BiomeChangeTemp?.BuildCost ?? 340; } /** * @param {number} currentLevel * @returns {number} */ export function getBiomeChangeTempUpgradeCost(currentLevel) { const cfg = GameConfig.BiomeChangeTemp; if (!cfg) return 9999; return exponentialCost(cfg.BaseUpgradeCost, cfg.UpgradeGrowth, currentLevel); } /** Building kinds that use the same build/upgrade pattern (7 levels). */ export const BUILDING_KINDS = [ "research", "billeterie", "food", "reception", "biomeChangeColor", "biomeChangeTemp", ]; /** * @param {typeof BUILDING_KINDS[number]} kind * @returns {number} */ export function getBuildingBuildCost(kind) { switch (kind) { case "research": return getResearchBuildCost(); case "billeterie": return getBilleterieBuildCost(); case "food": return getFoodBuildCost(); case "reception": return getReceptionBuildCost(); case "biomeChangeColor": return getBiomeChangeColorBuildCost(); case "biomeChangeTemp": return getBiomeChangeTempBuildCost(); default: return 9999; } } /** * @param {typeof BUILDING_KINDS[number]} kind * @param {number} currentLevel * @returns {number} */ export function getBuildingUpgradeCost(kind, currentLevel) { switch (kind) { case "research": return getResearchUpgradeCost(currentLevel); case "billeterie": return getBilleterieUpgradeCost(currentLevel); case "food": return getFoodUpgradeCost(currentLevel); case "reception": return getReceptionUpgradeCost(currentLevel); case "biomeChangeColor": return getBiomeChangeColorUpgradeCost(currentLevel); case "biomeChangeTemp": return getBiomeChangeTempUpgradeCost(currentLevel); default: return 9999; } } /** * @param {typeof BUILDING_KINDS[number]} kind * @returns {number} */ export function getBuildingMaxLevel(kind) { const key = kind.charAt(0).toUpperCase() + kind.slice(1); const cfg = GameConfig[key]; return cfg?.MaxLevel ?? 7; } /** * @param {number} level * @returns {number} */ export function getLevelMultiplier(level) { const current = level ?? 1; return 1 + 0.1 * Math.max(0, current - 1); } /** * @param {number} baseIncomePerSecond * @param {number} level * @param {number} mutationMultiplier * @param {number} sellFactor * @returns {number} */ export function getSellValue(baseIncomePerSecond, level, mutationMultiplier, sellFactor) { const levelMult = getLevelMultiplier(level); return Math.floor(baseIncomePerSecond * mutationMultiplier * levelMult * sellFactor + 0.5); }