UNPKG

@kitten-science/kitten-scientists

Version:

Add-on for the wonderful incremental browser game: https://kittensgame.com/web/

615 lines 32.7 kB
import { isNil, mustExist } from "@oliversalzburg/js-utils/data/nil.js"; import { InvalidOperationError } from "@oliversalzburg/js-utils/errors/InvalidOperationError.js"; import { BulkPurchaseHelper } from "./helper/BulkPurchaseHelper.js"; import { BonfireBuildingSetting } from "./settings/BonfireSettings.js"; import { ReligionSettings } from "./settings/ReligionSettings.js"; import { negativeOneToInfinity } from "./tools/Format.js"; import { cl } from "./tools/Log.js"; import { UnicornItems, UnicornItemVariant, } from "./types/index.js"; export class ReligionManager { _host; settings; _bulkManager; _bonfireManager; _workshopManager; constructor(host, bonfireManager, workshopManager, settings = new ReligionSettings()) { this._host = host; this.settings = settings; this._workshopManager = workshopManager; this._bulkManager = new BulkPurchaseHelper(this._host, this._workshopManager); this._bonfireManager = bonfireManager; } async tick(context) { if (!this.settings.enabled) { return; } this._bulkManager.resetPriceCache(); this._autoBuild(context); if (this.settings.sacrificeUnicorns.enabled) { await this._autoSacrificeUnicorns(); } if (this.settings.sacrificeAlicorns.enabled) { await this._autoSacrificeAlicorns(context); } if (this.settings.refineTears.enabled) { this._autoTears(context); } if (this.settings.refineTimeCrystals.enabled) { await this._autoTCs(context); } this._autoTAP(); } _autoBuild(context) { if (this.settings.bestUnicornBuilding.enabled) { this._buildBestUnicornBuilding(context); this._buildNonUnicornBuildings(context); } else { // Create the list of builds, excluding the unicorn pasture. // The unicorn pasture requires a special build path, because it's really // a bonfire building. const builds = Object.fromEntries(Object.entries(this.settings.buildings).filter(([, building]) => building.variant !== UnicornItemVariant.UnicornPasture)); // Build a unicorn pasture if possible. const maxPastures = negativeOneToInfinity(this.settings.buildings.unicornPasture.max); const meta = this._host.game.bld.getBuildingExt("unicornPasture").meta; if (this.settings.buildings.unicornPasture.enabled && meta.val < maxPastures) { this._bonfireManager.autoBuild(context, { unicornPasture: new BonfireBuildingSetting("unicornPasture", this.settings.buildings.unicornPasture.enabled, this.settings.buildings.unicornPasture.trigger, this.settings.buildings.unicornPasture.max), }); } // And then we build all other possible religion buildings. this._buildReligionBuildings(context, builds); } } _buildBestUnicornBuilding(context) { const bestUnicornBuilding = this.getBestUnicornBuilding(); if (this.settings.bestUnicornBuildingCurrent !== bestUnicornBuilding) { this.settings.bestUnicornBuildingCurrent = bestUnicornBuilding; this._host.refreshEntireUserInterface(); } if (this.settings.bestUnicornBuildingCurrent === null) { return; } const sectionTrigger = this.settings.trigger; if (this.settings.bestUnicornBuildingCurrent === "unicornPasture") { const buildRequest = { [this.settings.bestUnicornBuildingCurrent]: this.settings.buildings[this.settings.bestUnicornBuildingCurrent], }; const meta = { [this.settings.bestUnicornBuildingCurrent]: this._host.game.bld.getBuildingExt("unicornPasture").meta, }; const builder = (_build) => { this._bonfireManager.build("unicornPasture", 0, 1); }; context.purchaseOrders.push({ builder, builds: buildRequest, metaData: meta, sectionTrigger, }); return; } const buildImpl = this._getBuild(this.settings.bestUnicornBuildingCurrent, UnicornItemVariant.Ziggurat); let tearsNeeded = 0; const priceTears = mustExist(buildImpl.model.prices).find(subject => subject.name === "tears"); if (!isNil(priceTears)) { tearsNeeded = priceTears.val; } const tearsAvailableForUse = this._workshopManager.getValue("tears") - this._workshopManager.getStock("tears"); if (tearsAvailableForUse < tearsNeeded) { // How many times can we sacrifice unicorns to make tears? const maxSacrifice = Math.floor((this._workshopManager.getValue("unicorns") - this._workshopManager.getStock("unicorns")) / 2500); // How many sacrifices would we need, so we'd end up with enough tears. const needSacrifice = Math.ceil((tearsNeeded - tearsAvailableForUse) / this._host.game.bld.getBuildingExt("ziggurat").meta.on); // Sacrifice some unicorns to get the tears to buy the building. const zigguratCount = this._host.game.bld.get("ziggurat").on; if (needSacrifice < maxSacrifice && 0 < zigguratCount) { const controller = new classes.ui.religion.TransformBtnController(this._host.game, { applyAtGain: (priceCount) => { this._host.game.stats.getStat("unicornsSacrificed").val += priceCount; }, gainedResource: "tears", gainMultiplier: () => { return this._host.game.bld.get("ziggurat").on; }, logfilterID: "unicornSacrifice", logTextID: "religion.sacrificeBtn.sacrifice.msg", overcapMsgID: "religion.sacrificeBtn.sacrifice.msg.overcap", }); const model = controller.fetchModel({ controller, description: "", name: "", prices: [{ name: "unicorns", val: 2500 }], }); controller._transform(model, needSacrifice); // iactivity? // TODO: ☝ Yeah, seems like a good idea. } else { // Not enough unicorns to sacrifice to make enough tears. return; } } // Let the BulkManager figure out if the build can be made. const buildRequest = { [this.settings.bestUnicornBuildingCurrent]: this.settings.buildings[this.settings.bestUnicornBuildingCurrent], }; const builder = (build) => { // We force only building 1 of the best unicorn building, because // afterwards the best unicorn building is likely going to change. this.build(build.id, UnicornItemVariant.Ziggurat, 1); }; context.purchaseOrders.push({ builder, builds: buildRequest, metaData: this.getBuildMetaData(buildRequest), sectionTrigger, }); } _buildNonUnicornBuildings(context) { const alreadyHandled = [...UnicornItems]; const builds = Object.fromEntries(Object.entries(this.settings.buildings).filter(([, building]) => !alreadyHandled.includes(building.building))); this._buildReligionBuildings(context, builds); } _buildReligionBuildings(context, builds) { const metaData = this.getBuildMetaData(builds); const sectionTrigger = this.settings.trigger; const builder = (build) => { this.build(build.id, mustExist(build.variant), build.count); }; context.purchaseOrders.push({ builder, builds, metaData, sectionTrigger }); } /** * Determine the best unicorn-related building to buy next. * This is the building where the cost is in the best proportion to the * unicorn production bonus it generates. * * @see https://github.com/Bioniclegenius/NummonCalc/blob/112f716e2fde9956dfe520021b0400cba7b7113e/NummonCalc.js#L490 * @returns The best unicorn building. */ getBestUnicornBuilding() { const unicornPastureImpl = this._bonfireManager.getBuild("unicornPasture"); const validBuildings = [...UnicornItems].filter(item => item !== "unicornPasture"); // How many unicorns are produced per second. const unicornsPerSecondBase = this._host.game.getEffect("unicornsPerTickBase") * this._host.game.getTicksPerSecondUI(); // Unicorn ratio modifier. For example, through "unicorn selection". const globalRatio = this._host.game.getEffect("unicornsGlobalRatio") + 1; // The unicorn ratio modifier through religion buildings. const religionRatio = this._host.game.getEffect("unicornsRatioReligion") + 1; // The ratio modifier through paragon. const paragonRatio = this._host.game.prestige.getParagonProductionRatio() + 1; // Bonus from collected faith. const faithBonus = this._host.game.religion.getSolarRevolutionRatio() + 1; const currentCycleIndex = this._host.game.calendar.cycle; const currentCycle = this._host.game.calendar.cycles[currentCycleIndex]; // The modifier applied by the current cycle and holding a festival. let cycleBonus = 1; // If the current cycle has an effect on unicorn production during festivals // TODO: Simplify if (currentCycle.festivalEffects.unicorns !== undefined) { // Numeromancy is the metaphysics upgrade that grants bonuses based on cycles. if (this._host.game.prestige.getPerk("numeromancy").researched && this._host.game.calendar.festivalDays) { cycleBonus = currentCycle.festivalEffects.unicorns; } } const unicornsPerSecond = unicornsPerSecondBase * globalRatio * religionRatio * paragonRatio * faithBonus * cycleBonus; // Based on how many ziggurats we have. const zigguratRatio = Math.max(this._host.game.bld.getBuildingExt("ziggurat").meta.on, 1); // How many unicorns do we receive in a unicorn rift? const baseUnicornsPerRift = 500 * (1 + this._host.game.getEffect("unicornsRatioReligion") * 0.1); // How likely are unicorn rifts to happen? The unicornmancy metaphysics upgrade increases this chance. let riftChanceRatio = 1; if (this._host.game.prestige.getPerk("unicornmancy").researched) { riftChanceRatio *= 1.1; } // ? const unicornRiftChange = ((this._host.game.getEffect("riftChance") * riftChanceRatio) / (10000 * 2)) * baseUnicornsPerRift; // We now want to determine how quickly the cost of given building is neutralized // by its effect on production of unicorns. let bestAmortization = Number.POSITIVE_INFINITY; let bestBuilding = null; const unicornsPerTickBase = mustExist(this._host.game.bld.getBuildingExt("unicornPasture").meta.effects?.unicornsPerTickBase); const pastureProduction = unicornsPerTickBase * this._host.game.getTicksPerSecondUI() * globalRatio * religionRatio * paragonRatio * faithBonus * cycleBonus; // If the unicorn pasture amortizes itself in less than infinity ticks, // set it as the default. This is likely to protect against cases where // production of unicorns is 0. const pastureAmortization = mustExist(unicornPastureImpl.model?.prices)[0].val / pastureProduction; if (pastureAmortization < bestAmortization) { bestAmortization = pastureAmortization; bestBuilding = "unicornPasture"; } for (const building of validBuildings) { const buildingImpl = this._getBuild(building, UnicornItemVariant.Ziggurat); if (!buildingImpl.model.metadata.unlocked) { continue; } // Determine a price value for this building. let unicornPrice = 0; for (const price of mustExist(buildingImpl.model.prices)) { // Add the amount of unicorns the building costs (if any). if (price.name === "unicorns") { unicornPrice += price.val; } // Tears result from unicorn sacrifices, so factor that into the price proportionally. if (price.name === "tears") { unicornPrice += (price.val * 2500) / zigguratRatio; } } // Determine the effect the building will have on unicorn production and unicorn rifts. const buildingInfo = mustExist(this._host.game.religion.getZU(building)); let religionBonus = religionRatio; let riftChance = this._host.game.getEffect("riftChance"); for (const effect in buildingInfo.effects) { if (effect === "unicornsRatioReligion") { religionBonus += mustExist(buildingInfo.effects.unicornsRatioReligion); } if (effect === "riftChance") { riftChance += mustExist(buildingInfo.effects.riftChance); } } // The rest should be straight forward. const unicornsPerRift = 500 * ((religionBonus - 1) * 0.1 + 1); let riftBonus = ((riftChance * riftChanceRatio) / (10000 * 2)) * unicornsPerRift; riftBonus -= unicornRiftChange; let buildingProduction = unicornsPerSecondBase * globalRatio * religionBonus * paragonRatio * faithBonus * cycleBonus; buildingProduction -= unicornsPerSecond; buildingProduction += riftBonus; const amortization = unicornPrice / buildingProduction; if (amortization < bestAmortization) { if (0 < riftBonus || (religionRatio < religionBonus && 0 < unicornPrice)) { bestAmortization = amortization; bestBuilding = building; } } } return bestBuilding; } build(name, variant, amount) { let amountConstructed = 0; let label; if (variant === UnicornItemVariant.Cryptotheology) { const itemMetaRaw = game.getUnlockByName(name, "transcendenceUpgrades"); const controller = new classes.ui.TranscendenceBtnController(this._host.game); const model = controller.fetchModel({ controller, id: itemMetaRaw.name }); amountConstructed = this._bulkManager.construct(model, controller, amount); label = itemMetaRaw.label; } else if (variant === UnicornItemVariant.OrderOfTheSun) { const itemMetaRaw = game.getUnlockByName(name, "religion"); const controller = new com.nuclearunicorn.game.ui.ReligionBtnController(this._host.game); const model = controller.fetchModel({ controller, id: itemMetaRaw.name }); amountConstructed = this._bulkManager.construct(model, controller, amount); label = itemMetaRaw.label; } else if (variant === UnicornItemVariant.Ziggurat) { const itemMetaRaw = game.getUnlockByName(name, "zigguratUpgrades"); const controller = new com.nuclearunicorn.game.ui.ZigguratBtnController(this._host.game); const model = controller.fetchModel({ controller, id: itemMetaRaw.name }); amountConstructed = this._bulkManager.construct(model, controller, amount); label = itemMetaRaw.label; } else { throw new InvalidOperationError("unsupported"); } if (amount !== amountConstructed) { console.warn(...cl(`${label} Amount ordered: ${amount} Amount Constructed: ${amountConstructed}`)); // Bail out to not flood the log with garbage. if (amountConstructed === 0) { return; } } if (variant === UnicornItemVariant.OrderOfTheSun) { this._host.engine.storeForSummary(label, amountConstructed, "faith"); if (amountConstructed === 1) { this._host.engine.iactivity("act.sun.discover", [label], "ks-faith"); } else { this._host.engine.iactivity("act.sun.discovers", [label, this._host.renderAbsolute(amountConstructed)], "ks-faith"); } } else { this._host.engine.storeForSummary(label, amountConstructed, "build"); if (amountConstructed === 1) { this._host.engine.iactivity("act.build", [label], "ks-build"); } else { this._host.engine.iactivity("act.builds", [label, this._host.renderAbsolute(amountConstructed)], "ks-build"); } } } getBuildMetaData(builds) { const metaData = {}; for (const build of Object.values(builds)) { const buildInfo = this.getUpgradeMeta(build.building, build.variant); if (buildInfo === null) { continue; } metaData[build.building] = buildInfo; const buildMetaData = mustExist(metaData[build.building]); // If an item is marked as `rHidden`, it wouldn't be build. // TODO: Why not remove it from the `builds` then? if (!this._getBuild(build.building, build.variant)) { buildMetaData.rHidden = true; } else { const model = mustExist(this._getBuild(build.building, build.variant)).model; const panel = build.variant === UnicornItemVariant.Cryptotheology ? this._host.game.science.get("cryptotheology").researched : true; buildMetaData.rHidden = !(model?.visible && model.enabled && panel); } } return metaData; } /** * Retrieve information about an upgrade. * * @param name The name of the upgrade. * @param variant The variant of the upgrade. * @returns The build information for the upgrade. */ getUpgradeMeta(name, variant) { switch (variant) { case UnicornItemVariant.Ziggurat: return this._host.game.religion.getZU(name) ?? null; case UnicornItemVariant.OrderOfTheSun: return this._host.game.religion.getRU(name) ?? null; case UnicornItemVariant.Cryptotheology: return this._host.game.religion.getTU(name) ?? null; } throw new Error(`Unknown build: ${name} (${variant})`); } /** * Find the button that allows purchasing a given upgrade. * * @param name The name of the upgrade. * @param variant The variant of the upgrade. * @returns The button to buy the upgrade, or `null`. */ _getBuild(name, variant) { switch (variant) { case UnicornItemVariant.Ziggurat: { return this._host.game.time.queue.getQueueElementControllerAndModel({ name, type: "zigguratUpgrades", }); } case UnicornItemVariant.OrderOfTheSun: { return this._host.game.time.queue.getQueueElementControllerAndModel({ name, type: "religion", }); } case UnicornItemVariant.Cryptotheology: { return this._host.game.time.queue.getQueueElementControllerAndModel({ name, type: "transcendenceUpgrades", }); } default: throw new Error(`Invalid variant '${variant}'`); } } _transformBtnSacrificeHelper(available, total, controller, model) { const conversionPercentage = available / total; const percentageInverse = 1 / conversionPercentage; const customController = new classes.ui.religion.TransformBtnController(game, controller.controllerOpts); const link = customController._newLink(model, percentageInverse); return new Promise(resolve => { link.handler(new Event("decoy"), resolve); }); } async _autoSacrificeUnicorns() { const unicorns = this._workshopManager.getResource("unicorns"); const available = this._workshopManager.getValueAvailable("unicorns"); if (!isNil(this._host.game.religionTab.sacrificeBtn) && negativeOneToInfinity(this.settings.sacrificeUnicorns.trigger) <= available && negativeOneToInfinity(this.settings.sacrificeUnicorns.trigger) <= unicorns.value) { const controller = this._host.game.religionTab.sacrificeBtn.controller; const model = this._host.game.religionTab.sacrificeBtn.model; if (isNil(model)) { return; } await this._transformBtnSacrificeHelper(available, unicorns.value, controller, model); const availableNow = this._workshopManager.getValueAvailable("unicorns"); const cost = available - availableNow; this._host.engine.iactivity("act.sacrificeUnicorns", [this._host.game.getDisplayValueExt(cost)], "ks-faith"); this._host.engine.storeForSummary(this._host.engine.i18n("$resources.unicorns.title"), cost, "refine"); } } async _autoSacrificeAlicorns(context) { const alicorns = this._workshopManager.getResource("alicorn"); const available = this._workshopManager.getValueAvailable("alicorn"); if (!isNil(this._host.game.religionTab.sacrificeAlicornsBtn) && negativeOneToInfinity(this.settings.sacrificeAlicorns.trigger) <= available && negativeOneToInfinity(this.settings.sacrificeAlicorns.trigger) <= alicorns.value) { this._host.game.religionTab.sacrificeAlicornsBtn.render(); const controller = this._host.game.religionTab.sacrificeAlicornsBtn.controller; const model = this._host.game.religionTab.sacrificeAlicornsBtn.model; if (isNil(model)) { context.requestGameUiRefresh = true; return; } await this._transformBtnSacrificeHelper(available, alicorns.value, controller, model); const availableNow = this._workshopManager.getValueAvailable("alicorn"); const cost = available - availableNow; this._host.engine.iactivity("act.sacrificeAlicorns", [this._host.game.getDisplayValueExt(cost)], "ks-faith"); this._host.engine.storeForSummary(this._host.engine.i18n("$resources.alicorn.title"), cost, "refine"); } } _autoTears(context) { const tears = this._workshopManager.getResource("tears"); const available = this._workshopManager.getValueAvailable("tears"); const sorrow = this._workshopManager.getResource("sorrow"); if (!isNil(this._host.game.religionTab.refineBtn) && negativeOneToInfinity(this.settings.refineTears.trigger) <= available && negativeOneToInfinity(this.settings.refineTears.trigger) <= tears.value && sorrow.value < sorrow.maxValue) { const availableForConversion = available - this.settings.refineTears.trigger; if (availableForConversion < 10000) { return; } const controller = this._host.game.religionTab.refineBtn.controller; const model = this._host.game.religionTab.refineBtn.model; if (isNil(model)) { context.requestGameUiRefresh = true; return; } controller.buyItem(model, new Event("decoy"), availableForConversion); const availableNow = this._workshopManager.getValueAvailable("tears"); const cost = available - availableNow; this._host.engine.iactivity("act.refineTears", [this._host.game.getDisplayValueExt(cost)], "ks-faith"); this._host.engine.storeForSummary(this._host.engine.i18n("$resources.tears.title"), cost, "refine"); } } async _autoTCs(context) { const timeCrystals = this._workshopManager.getResource("timeCrystal"); const available = this._workshopManager.getValueAvailable("timeCrystal"); if (!isNil(this._host.game.religionTab.refineTCBtn) && negativeOneToInfinity(this.settings.refineTimeCrystals.trigger) <= available && negativeOneToInfinity(this.settings.refineTimeCrystals.trigger) <= timeCrystals.value) { const controller = this._host.game.religionTab.refineTCBtn.controller; const model = this._host.game.religionTab.refineTCBtn.model; if (isNil(model)) { context.requestGameUiRefresh = true; return; } await this._transformBtnSacrificeHelper(available, timeCrystals.value, controller, model); const availableNow = this._workshopManager.getValueAvailable("timeCrystal"); const cost = available - availableNow; this._host.engine.iactivity("act.refineTCs", [this._host.game.getDisplayValueExt(cost)], "ks-faith"); this._host.engine.storeForSummary(this._host.engine.i18n("$resources.timeCrystal.title"), cost, "refine"); } } _autoTAP() { const faith = this._workshopManager.getResource("faith"); const faithLevel = faith.value / faith.maxValue; // enough faith, and then TAP (transcend, adore, praise) if (this.settings.transcend.enabled && this.settings.autoPraise.trigger - 0.02 <= faithLevel) { this._autoTranscend(); } // Praise (faith → worship) if (this.settings.autoPraise.trigger <= faithLevel) { // Adore the galaxy (worship → epiphany) if (this.settings.adore.enabled && mustExist(this._host.game.religion.getRU("apocripha")).on) { this._autoAdore(this.settings.adore.trigger); } if (this.settings.autoPraise.enabled) { this._autoPraise(); } } } _autoAdore(trigger) { const faith = this._workshopManager.getResource("faith"); const worship = this._host.game.religion.faith; const epiphany = this._host.game.religion.faithRatio; const transcendenceReached = mustExist(this._host.game.religion.getRU("transcendence")).on; const transcendenceTierCurrent = transcendenceReached ? this._host.game.religion.transcendenceTier : 0; // game version: 1.4.8.1 // solarRevolutionLimit is increased by black obelisks. const maxSolarRevolution = 10 + this._host.game.getEffect("solarRevolutionLimit"); // The absolute value at which to trigger adoring the galaxy. const triggerSolarRevolution = maxSolarRevolution * trigger; // How much epiphany we'll get from converting our worship. const epiphanyIncrease = (worship / 1000000) * transcendenceTierCurrent * transcendenceTierCurrent * 1.01; // How much epiphany we'll have after adoring. const epiphanyAfterAdore = epiphany + epiphanyIncrease; // How much worship we'll have after adoring. const worshipAfterAdore = 0.01 + faith.value * (1 + this._host.game.getUnlimitedDR(epiphanyAfterAdore, 0.1) * 0.1); // How much solar revolution bonus we'll have after adoring. const solarRevolutionAfterAdore = this._host.game.getLimitedDR(this._host.game.getUnlimitedDR(worshipAfterAdore, 1000) / 100, maxSolarRevolution); // After adoring the galaxy, we want a single praise to be able to reach the trigger // level of solar revolution bonus. if (triggerSolarRevolution <= solarRevolutionAfterAdore) { // Perform the actual adoration. this._host.game.religion._resetFaithInternal(1.01); // Log the action. this._host.engine.iactivity("act.adore", [ this._host.game.getDisplayValueExt(worship), this._host.game.getDisplayValueExt(epiphanyIncrease), ], "ks-adore"); this._host.engine.storeForSummary("adore", epiphanyIncrease); } } _autoTranscend() { let epiphany = this._host.game.religion.faithRatio; const transcendenceReached = mustExist(this._host.game.religion.getRU("transcendence")).on; let transcendenceTierCurrent = transcendenceReached ? this._host.game.religion.transcendenceTier : 0; // Transcend if (transcendenceReached) { // How much our adoration ratio increases from transcending. const adoreIncreaseRatio = ((transcendenceTierCurrent + 2) / (transcendenceTierCurrent + 1)) ** 2; // The amount of worship needed to upgrade to the next level. const needNextLevel = this._host.game.religion._getTranscendTotalPrice(transcendenceTierCurrent + 1) - this._host.game.religion._getTranscendTotalPrice(transcendenceTierCurrent); // We want to determine the ideal value for when to transcend. // TODO: How exactly this works isn't understood yet. const x = needNextLevel; const k = adoreIncreaseRatio; const epiphanyRecommend = ((1 - k + Math.sqrt(80 * (k * k - 1) * x + (k - 1) * (k - 1))) * k) / (40 * (k + 1) * (k + 1) * (k - 1)) + x + x / (k * k - 1); if (epiphanyRecommend <= epiphany) { // code copy from kittens game's religion.js: this._host.game.religion.transcend() // this._host.game.religion.transcend() need confirm by player // game version: 1.4.8.1 // ======================================================================================================== // DO TRANSCEND START // ======================================================================================================== this._host.game.religion.faithRatio -= needNextLevel; this._host.game.religion.tcratio += needNextLevel; this._host.game.religion.transcendenceTier += 1; const atheism = mustExist(this._host.game.challenges.getChallenge("atheism")); atheism.calculateEffects?.(atheism, this._host.game); const blackObelisk = mustExist(this._host.game.religion.getTU("blackObelisk")); blackObelisk.calculateEffects?.(blackObelisk, this._host.game); this._host.game.msg(this._host.engine.i18n("$religion.transcend.msg.success", [ this._host.game.religion.transcendenceTier, ])); // ======================================================================================================== // DO TRANSCEND END // ======================================================================================================== epiphany = this._host.game.religion.faithRatio; transcendenceTierCurrent = this._host.game.religion.transcendenceTier; this._host.engine.iactivity("act.transcend", [this._host.game.getDisplayValueExt(needNextLevel), transcendenceTierCurrent], "ks-transcend"); this._host.engine.storeForSummary("transcend", 1); } } } _autoPraise() { const faith = this._workshopManager.getResource("faith"); const apocryphaBonus = this._host.game.religion.getApocryphaBonus(); // Determine how much worship we'll gain and log it. const worshipIncrease = faith.value * (1 + apocryphaBonus); this._host.engine.storeForSummary("praise", worshipIncrease); this._host.engine.iactivity("act.praise", [ this._host.game.getDisplayValueExt(faith.value), this._host.game.getDisplayValueExt(worshipIncrease), ], "ks-praise"); // Now finally praise the sun. this._host.game.religion.praise(); } } //# sourceMappingURL=ReligionManager.js.map