Convert all autobuyers into AutobuyerState class

Check #1591 for more information
This commit is contained in:
Waiting Idly 2021-02-01 17:46:04 -08:00
parent 1040e0af5a
commit a4a3ab9682
49 changed files with 555 additions and 440 deletions

View File

@ -116,7 +116,7 @@
<script type="text/javascript" src="javascripts/core/galaxy.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/dimension-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/antimatter-dimension-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/tickspeed-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/dimboost-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/galaxy-autobuyer.js"></script>
@ -124,8 +124,19 @@
<script type="text/javascript" src="javascripts/core/autobuyers/sacrifice-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/eternity-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/reality-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/infinity-dimension-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/time-dimension-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/time-theorem-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/black-hole-power-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/reality-upgrade-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/replicanti-upgrade-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/dilation-upgrade-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/prestige-currency-multiplier-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/replicanti-galaxy-autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyers/autobuyers.js"></script>
<script type="text/javascript" src="javascripts/core/storage/serializer.js"></script>
<script type="text/javascript" src="javascripts/core/storage/storage.js"></script>
<script type="text/javascript" src="javascripts/core/storage/migrations.js?1"></script>

View File

@ -27,7 +27,7 @@ Vue.component("infinity-dim-row", {
},
watch: {
isAutobuyerOn(newValue) {
player.auto.infinityDims.active[this.tier - 1] = newValue;
Autobuyer.infinityDimension(this.tier).isActive = newValue;
}
},
computed: {
@ -66,13 +66,14 @@ Vue.component("infinity-dim-row", {
update() {
const tier = this.tier;
const dimension = InfinityDimension(tier);
const autobuyer = Autobuyer.infinityDimension(tier);
this.isUnlocked = dimension.isUnlocked;
this.multiplier.copyFrom(dimension.multiplier);
this.baseAmount = dimension.baseAmount;
this.purchases = dimension.purchases;
this.amount.copyFrom(dimension.amount);
this.rateOfChange.copyFrom(dimension.rateOfChange);
this.isAutobuyerUnlocked = dimension.isAutobuyerUnlocked;
this.isAutobuyerUnlocked = autobuyer.isUnlocked;
this.cost.copyFrom(dimension.cost);
this.isAvailableForPurchase = dimension.isAvailableForPurchase;
if (!this.isUnlocked) {
@ -84,7 +85,7 @@ Vue.component("infinity-dim-row", {
this.hardcap = dimension.purchaseCap;
}
this.isEC8Running = EternityChallenge(8).isRunning;
this.isAutobuyerOn = player.auto.infinityDims.active[this.tier - 1];
this.isAutobuyerOn = autobuyer.isActive;
this.requirementReached = dimension.requirementReached;
this.eternityReached = PlayerProgress.eternityUnlocked();
this.showCostTitle = this.cost.exponent < 1000000;

View File

@ -38,7 +38,7 @@ Vue.component("infinity-dim-tab", {
this.EC8PurchasesLeft = player.eterc8ids;
}
this.isEnslavedRunning = Enslaved.isRunning;
this.isAnyAutobuyerUnlocked = InfinityDimension(1).isAutobuyerUnlocked;
this.isAnyAutobuyerUnlocked = Autobuyer.infinityDimension(1).isUnlocked;
this.nextDimCapIncrease = Enslaved.nextDimCapIncrease;
this.tesseractCost.copyFrom(Enslaved.tesseractCost);
this.totalDimCap = InfinityDimensions.totalDimCap;

View File

@ -37,7 +37,7 @@ Vue.component("time-dim-row", {
},
watch: {
isAutobuyerOn(newValue) {
player.auto.timeDims.active[this.tier - 1] = newValue;
Autobuyer.timeDimension(this.tier).isActive = newValue;
}
},
methods: {
@ -53,7 +53,7 @@ Vue.component("time-dim-row", {
}
this.cost.copyFrom(dimension.cost);
this.isAffordable = dimension.isAffordable;
this.isAutobuyerOn = player.auto.timeDims.active[tier - 1];
this.isAutobuyerOn = Autobuyer.timeDimension(this.tier).isActive;
this.realityUnlocked = PlayerProgress.realityUnlocked();
},
buyTimeDimension() {

View File

@ -19,7 +19,7 @@ Vue.component("dilation-upgrade", {
},
watch: {
isAutobuyerOn(newValue) {
this.upgrade.isAutobuyerOn = newValue;
Autobuyer.dilationUpgrade(this.upgrade.id).isActive = newValue;
}
},
computed: {
@ -36,23 +36,25 @@ Vue.component("dilation-upgrade", {
},
methods: {
update() {
const upgrade = this.upgrade;
if (this.isRebuyable) {
this.isAffordable = this.upgrade.isAffordable;
this.isCapped = this.upgrade.isCapped;
} else {
this.isBought = this.upgrade.isBought;
if (!this.isBought) {
this.isAffordable = this.upgrade.isAffordable;
}
this.isAffordable = upgrade.isAffordable;
this.isCapped = upgrade.isCapped;
const autobuyer = Autobuyer.dilationUpgrade(upgrade.id);
this.isAutoUnlocked = autobuyer.isUnlocked;
this.isAutobuyerOn = autobuyer.isActive;
return;
}
this.isBought = upgrade.isBought;
if (!this.isBought) {
this.isAffordable = upgrade.isAffordable;
}
this.isAutoUnlocked = Perk.autobuyerDilation.isBought;
this.isAutobuyerOn = this.upgrade.isAutobuyerOn;
}
},
template:
`<div class="l-spoon-btn-group">
<button :class="classObject" @click="upgrade.purchase()">
<description-display
<description-display
:config="upgrade.config"
:length="70"
name="o-dilation-upgrade__description"
@ -72,4 +74,4 @@ Vue.component("dilation-upgrade", {
class="l--spoon-btn-group__little-spoon o-primary-btn--dilation-upgrade-toggle"
/>
</div>`
});
});

View File

@ -3,7 +3,7 @@
Vue.component("ep-multiplier-button", {
data() {
return {
isAutobuyerOn: false,
isAutobuyerActive: false,
isAutoUnlocked: false,
isAffordable: false,
multiplier: new Decimal(0),
@ -11,14 +11,17 @@ Vue.component("ep-multiplier-button", {
};
},
watch: {
isAutobuyerOn(newValue) {
this.upgrade.autobuyer.isOn = newValue;
isAutobuyerActive(newValue) {
Autobuyer.epMult.isActive = newValue;
}
},
computed: {
upgrade() {
return EternityUpgrade.epMult;
},
autobuyer() {
return Autobuyer.epMult;
},
classObject() {
return {
"o-eternity-upgrade": true,
@ -30,9 +33,8 @@ Vue.component("ep-multiplier-button", {
methods: {
update() {
const upgrade = this.upgrade;
const autobuyer = upgrade.autobuyer;
this.isAutoUnlocked = autobuyer.isUnlocked;
this.isAutobuyerOn = autobuyer.isOn;
this.isAutoUnlocked = this.autobuyer.isUnlocked;
this.isAutobuyerActive = this.autobuyer.isActive;
this.multiplier.copyFrom(upgrade.effectValue);
this.cost.copyFrom(upgrade.cost);
this.isAffordable = upgrade.isAffordable;
@ -53,7 +55,7 @@ Vue.component("ep-multiplier-button", {
>Max Eternity Point mult</primary-button>
<primary-button-on-off
v-if="isAutoUnlocked"
v-model="isAutobuyerOn"
v-model="isAutobuyerActive"
text="Autobuy EP mult"
class="l--spoon-btn-group__little-spoon o-primary-btn--small-spoon"
/>

View File

@ -52,7 +52,7 @@ Vue.component("dimension-autobuyer-box", {
<span>Cost: {{format(cost, 2, 0)}} IP</span>
</template>
</button>
<button
<button
v-else-if="hasMaxedInterval && !bulkUnlimited"
class="o-autobuyer-btn l-autobuyer-box__button">
Complete the challenge to upgrade bulk
@ -69,7 +69,7 @@ Vue.component("dimension-autobuyer-box", {
},
computed: {
autobuyer() {
return Autobuyer.dimension(this.tier);
return Autobuyer.antimatterDimension(this.tier);
},
name() {
return `${AntimatterDimension(this.tier).displayName} Dimension Autobuyer`;

View File

@ -5,7 +5,7 @@ Vue.component("replicanti-galaxy-button", {
return {
isAvailable: false,
isAutoUnlocked: false,
isAutoOn: false,
isAutoActive: false,
isAutoEnabled: false,
isDivideUnlocked: false,
boughtGalaxies: 0,
@ -25,27 +25,28 @@ Vue.component("replicanti-galaxy-button", {
return `Currently: ${galaxyCount}`;
},
autobuyer() {
return Replicanti.galaxies.autobuyer;
return Autobuyer.replicantiGalaxy;
},
autobuyerOnTextDisplay() {
return this.isAutoEnabled ? "Auto Galaxy ON" : "Auto Galaxy ON (disabled)";
autobuyerTextDisplay() {
const auto = this.isAutoActive;
const disabled = !this.isAutoEnabled;
return `Auto Galaxy ${auto ? "ON" : "OFF"}${disabled ? " (disabled)" : ""}`;
},
autobuyerOffTextDisplay() {
return this.isAutoEnabled ? "Auto Galaxy OFF" : "Auto Galaxy OFF (disabled)";
}
},
methods: {
update() {
this.isAvailable = Replicanti.galaxies.canBuyMore;
this.boughtGalaxies = Replicanti.galaxies.bought;
this.extraGalaxies = Replicanti.galaxies.extra;
const rg = Replicanti.galaxies;
this.isAvailable = rg.canBuyMore;
this.boughtGalaxies = rg.bought;
this.extraGalaxies = rg.extra;
this.isDivideUnlocked = Achievement(126).isUnlocked;
this.isAutoUnlocked = this.autobuyer.isUnlocked;
this.isAutoOn = this.autobuyer.isOn;
this.isAutoEnabled = this.autobuyer.isEnabled;
const auto = Autobuyer.replicantiGalaxy;
this.isAutoUnlocked = auto.isUnlocked;
this.isAutoActive = auto.isActive;
this.isAutoEnabled = auto.isEnabled;
},
handleAutoToggle(value) {
this.autobuyer.isOn = value;
Autobuyer.replicantiGalaxy.isActive = value;
this.update();
}
},
@ -62,9 +63,9 @@ Vue.component("replicanti-galaxy-button", {
</primary-button>
<primary-button-on-off-custom
v-if="isAutoUnlocked"
:value="isAutoOn"
:on="autobuyerOnTextDisplay"
:off="autobuyerOffTextDisplay"
:value="isAutoActive"
:on="autobuyerTextDisplay"
:off="autobuyerTextDisplay"
class="l--spoon-btn-group__little-spoon o-primary-btn--replicanti-galaxy-toggle"
@input="handleAutoToggle"
/>

View File

@ -17,7 +17,7 @@ Vue.component("replicanti-upgrade-button", {
},
watch: {
isAutobuyerOn(newValue) {
this.upgrade.isAutobuyerOn = newValue;
Autobuyer.replicantiUpgrade(this.upgrade.id).isActive = newValue;
}
},
computed: {
@ -35,8 +35,9 @@ Vue.component("replicanti-upgrade-button", {
if (!this.isCapped) {
this.costDescription = setup.formatCost(upgrade.cost);
}
this.isAutoUnlocked = upgrade.isAutobuyerUnlocked;
this.isAutobuyerOn = upgrade.isAutobuyerOn;
const autobuyer = Autobuyer.replicantiUpgrade(upgrade.id);
this.isAutoUnlocked = autobuyer.isUnlocked;
this.isAutobuyerOn = autobuyer.isActive;
this.isEC8Running = EternityChallenge(8).isRunning;
}
},

View File

@ -3,14 +3,14 @@
Vue.component("ip-multiplier-button", {
data() {
return {
isAutobuyerOn: false,
isAutobuyerActive: false,
isAutoUnlocked: false,
isCapped: false
};
},
watch: {
isAutobuyerOn(newValue) {
player.auto.ipMultBuyer = newValue;
isAutobuyerActive(newValue) {
Autobuyer.ipMult.isActive = newValue;
}
},
computed: {
@ -20,12 +20,12 @@ Vue.component("ip-multiplier-button", {
},
methods: {
update() {
this.isAutoUnlocked = EternityMilestone.autobuyerIPMult.isReached;
this.isAutobuyerOn = player.auto.ipMultBuyer;
this.isAutoUnlocked = Autobuyer.ipMult.isUnlocked;
this.isAutobuyerActive = Autobuyer.ipMult.isActive;
this.isCapped = this.upgrade.isCapped;
},
buyMaxIPMult() {
InfinityUpgrade.ipMult.autobuyerTick();
InfinityUpgrade.ipMult.buyMax();
}
},
template:
@ -45,7 +45,7 @@ Vue.component("ip-multiplier-button", {
>Max Infinity Point mult</primary-button>
<primary-button-on-off
v-if="isAutoUnlocked"
v-model="isAutobuyerOn"
v-model="isAutobuyerActive"
text="Autobuy IP mult"
class="l--spoon-btn-group__little-spoon o-primary-btn--small-spoon"
/>

View File

@ -26,7 +26,7 @@ Vue.component("new-inf-dimension-row", {
},
watch: {
isAutobuyerOn(newValue) {
player.auto.infinityDims.active[this.tier - 1] = newValue;
Autobuyer.infinityDimension(this.tier).isActive = newValue;
}
},
computed: {
@ -67,7 +67,7 @@ Vue.component("new-inf-dimension-row", {
this.purchases = dimension.purchases;
this.amount.copyFrom(dimension.amount);
this.rateOfChange.copyFrom(dimension.rateOfChange);
this.isAutobuyerUnlocked = dimension.isAutobuyerUnlocked;
this.isAutobuyerUnlocked = Autobuyer.infinityDimension(tier).isUnlocked;
this.cost.copyFrom(dimension.cost);
this.isAvailableForPurchase = dimension.isAvailableForPurchase;
if (!this.isUnlocked) {
@ -79,7 +79,7 @@ Vue.component("new-inf-dimension-row", {
this.hardcap = dimension.purchaseCap;
}
this.isEC8Running = EternityChallenge(8).isRunning;
this.isAutobuyerOn = player.auto.infinityDims.active[this.tier - 1];
this.isAutobuyerOn = Autobuyer.infinityDimension(tier).isActive;
this.requirementReached = dimension.requirementReached;
this.eternityReached = PlayerProgress.eternityUnlocked();
},

View File

@ -46,7 +46,7 @@ Vue.component("new-inf-dimensions-tab", {
this.EC8PurchasesLeft = player.eterc8ids;
}
this.isEnslavedRunning = Enslaved.isRunning;
this.isAnyAutobuyerUnlocked = InfinityDimension(1).isAutobuyerUnlocked;
this.isAnyAutobuyerUnlocked = Autobuyer.infinityDimension(1).isUnlocked;
this.nextDimCapIncrease = Enslaved.nextDimCapIncrease;
this.tesseractCost.copyFrom(Enslaved.tesseractCost);
this.totalDimCap = InfinityDimensions.totalDimCap;

View File

@ -37,7 +37,7 @@ Vue.component("new-time-dimension-row", {
},
watch: {
isAutobuyerOn(newValue) {
player.auto.timeDims.active[this.tier - 1] = newValue;
Autobuyer.timeDimension(this.tier).isActive = newValue;
}
},
methods: {
@ -53,7 +53,7 @@ Vue.component("new-time-dimension-row", {
}
this.cost.copyFrom(dimension.cost);
this.isAffordable = dimension.isAffordable;
this.isAutobuyerOn = player.auto.timeDims.active[tier - 1];
this.isAutobuyerOn = Autobuyer.timeDimension(this.tier).isActive;
this.realityUnlocked = PlayerProgress.realityUnlocked();
},
buyTimeDimension() {

View File

@ -35,15 +35,16 @@ Vue.component("black-hole-upgrade-button", {
},
watch: {
isAutobuyerOn(newValue) {
this.config.upgrade.isAutobuyerOn = newValue;
Autobuyer.blackHolePower(this.config.upgrade.id).isActive = newValue;
}
},
methods: {
update() {
this.isAffordable = this.config.upgrade.isAffordable && this.config.upgrade.value !== 0;
this.isCapped = this.config.upgrade.value === 0;
this.isAutoUnlocked = this.config.upgrade.hasAutobuyer && Ra.has(RA_UNLOCKS.AUTO_BLACK_HOLE_POWER);
this.isAutobuyerOn = this.config.upgrade.hasAutobuyer && this.config.upgrade.isAutobuyerOn;
this.isAffordable = this.config.upgrade.isAffordable && !this.isCapped;
const hasAutobuyer = this.config.upgrade.hasAutobuyer;
this.isAutoUnlocked = hasAutobuyer && Ra.has(RA_UNLOCKS.AUTO_BLACK_HOLE_POWER);
this.isAutobuyerOn = hasAutobuyer && Autobuyer.blackHolePower(this.config.upgrade.id).isActive;
}
},
template: `

View File

@ -35,7 +35,7 @@ Vue.component("reality-upgrade-button", {
},
watch: {
isAutobuyerOn(newValue) {
this.upgrade.isAutobuyerOn = newValue;
Autobuyer.realityUpgrades(this.upgrade.id).isActive = newValue;
}
},
methods: {
@ -47,7 +47,7 @@ Vue.component("reality-upgrade-button", {
this.isBought = !upgrade.isRebuyable && upgrade.isBought;
this.isPossible = upgrade.isPossible;
this.isAutoUnlocked = Ra.has(RA_UNLOCKS.AUTO_REALITY_UPGRADES);
this.isAutobuyerOn = upgrade.isAutobuyerOn;
if (this.isRebuyable) this.isAutobuyerOn = Autobuyer.realityUpgrades(upgrade.id).isActive;
}
},
template: `

View File

@ -9,7 +9,7 @@ Vue.component("tt-shop", {
shopMinimized: false,
minimizeAvailable: false,
hasTTAutobuyer: false,
ttAutobuyerOn: false,
isAutobuyerOn: false,
budget: {
am: new Decimal(0),
ip: new Decimal(0),
@ -25,6 +25,11 @@ Vue.component("tt-shop", {
showTTGen: false
};
},
watch: {
isAutobuyerOn(newValue) {
Autobuyer.timeTheorem.isActive = newValue;
}
},
computed: {
minimized() {
return this.minimizeAvailable && this.shopMinimized;
@ -60,9 +65,6 @@ Vue.component("tt-shop", {
saveLoadText() {
return this.$viewModel.shiftDown ? "save:" : "load:";
},
autobuyerText() {
return this.ttAutobuyerOn ? "ON" : "OFF";
}
},
methods: {
minimize() {
@ -96,7 +98,7 @@ Vue.component("tt-shop", {
this.shopMinimized = player.timestudy.shopMinimized;
this.minimizeAvailable = DilationUpgrade.ttGenerator.isBought || Perk.autobuyerTT1.isBought;
this.hasTTAutobuyer = Perk.autobuyerTT1.isBought;
this.ttAutobuyerOn = player.auto.timeTheorems.active;
this.isAutobuyerOn = Autobuyer.timeTheorem.isActive;
const budget = this.budget;
budget.am.copyFrom(Currency.antimatter);
budget.ip.copyFrom(player.infinityPoints);
@ -109,9 +111,6 @@ Vue.component("tt-shop", {
this.STamount = V.availableST;
this.showTTGen = this.theoremGeneration.gt(0) && !ui.view.shiftDown;
},
toggleTTAutobuyer() {
player.auto.timeTheorems = !player.auto.timeTheorems;
}
},
template: `
<div id="TTbuttons">
@ -149,13 +148,12 @@ Vue.component("tt-shop", {
@click="buyMaxTheorems">
Buy max
</button>
<button v-if="!minimized && hasTTAutobuyer"
class="o-tt-autobuyer-button
c-tt-buy-button
c-tt-buy-button--unlocked"
@click="toggleTTAutobuyer">
Auto: {{autobuyerText}}
</button>
<primary-button-on-off
v-if="!minimized && hasTTAutobuyer"
v-model="isAutobuyerOn"
class="o-tt-autobuyer-button c-tt-buy-button c-tt-buy-button--unlocked"
text="Auto:"
/>
</div>
</div>
</div>

View File

@ -1,6 +1,6 @@
"use strict";
class DimensionAutobuyerState extends IntervaledAutobuyerState {
class AntimatterDimensionAutobuyerState extends UpgradeableAutobuyerState {
constructor(tier) {
super();
this._tier = tier;
@ -11,7 +11,7 @@ class DimensionAutobuyerState extends IntervaledAutobuyerState {
}
get baseInterval() {
return Player.defaultStart.auto.dimensions[this._tier - 1].interval;
return Player.defaultStart.auto.antimatterDims[this._tier - 1].interval;
}
get isUnlocked() {
@ -104,6 +104,6 @@ class DimensionAutobuyerState extends IntervaledAutobuyerState {
}
}
DimensionAutobuyerState.index = Array.range(1, 8).map(tier => new DimensionAutobuyerState(tier));
AntimatterDimensionAutobuyerState.index = Array.range(1, 8).map(tier => new AntimatterDimensionAutobuyerState(tier));
Autobuyer.dimension = tier => DimensionAutobuyerState.index[tier - 1];
Autobuyer.antimatterDimension = tier => AntimatterDimensionAutobuyerState.index[tier - 1];

View File

@ -42,7 +42,7 @@ class AutobuyerState {
/**
* @abstract
*/
class IntervaledAutobuyerState extends AutobuyerState {
class UpgradeableAutobuyerState extends AutobuyerState {
/**
* @abstract
*/
@ -101,4 +101,34 @@ class IntervaledAutobuyerState extends AutobuyerState {
}
}
/**
* @abstract
*/
class IntervaledAutobuyerState extends AutobuyerState {
get interval() {
return this.data.interval;
}
get canTick() {
return super.canTick && this.timeSinceLastTick >= this.interval;
}
get timeSinceLastTick() {
return player.records.realTimePlayed - this.data.lastTick;
}
tick() {
const realTimePlayed = player.records.realTimePlayed;
const interval = this.interval;
// Don't allow more than one interval worth of time to accumulate (at most one autobuyer tick)
this.data.lastTick = Math.max(
Math.min(this.data.lastTick + interval, realTimePlayed),
realTimePlayed - interval);
}
// eslint-disable-next-line no-empty-function
reset() { }
}
const Autobuyer = {};

View File

@ -1,22 +1,39 @@
"use strict";
const Autobuyers = (function() {
const dimensions = DimensionAutobuyerState.index;
const all = dimensions
.concat([
Autobuyer.tickspeed,
Autobuyer.dimboost,
Autobuyer.galaxy,
Autobuyer.bigCrunch,
Autobuyer.sacrifice,
Autobuyer.eternity,
Autobuyer.reality,
]);
const antimatterDims = AntimatterDimensionAutobuyerState.index;
const infinityDims = InfinityDimensionAutobuyerState.index;
const timeDims = TimeDimensionAutobuyerState.index;
const dimensions = antimatterDims.concat(infinityDims, timeDims);
const prestige = [
Autobuyer.bigCrunch,
Autobuyer.eternity,
Autobuyer.reality,
];
const single = [
Autobuyer.tickspeed,
Autobuyer.sacrifice,
Autobuyer.dimboost,
Autobuyer.galaxy,
Autobuyer.replicantiGalaxy,
Autobuyer.timeTheorem,
Autobuyer.ipMult,
Autobuyer.epMult,
];
const other = BlackHolePowerAutobuyerState.index.concat(
RealityUpgradeAutobuyerState.index,
ReplicantiUpgradeAutobuyerState.index,
DilationUpgradeAutobuyerState.index
);
const all = dimensions.concat(prestige, single, other);
return {
all,
dimensions,
upgradeable: dimensions.concat([Autobuyer.tickspeed]),
prestige,
single,
other,
upgradeable: antimatterDims.concat([Autobuyer.tickspeed]),
get unlocked() {
return Autobuyers.all.filter(a => a.isUnlocked || a.isBought);
@ -30,17 +47,11 @@ const Autobuyers = (function() {
PerformanceStats.start("Autobuyers");
const priorityQueue = [Autobuyer.tickspeed]
.concat(dimensions)
.concat(antimatterDims)
.sort((a, b) => a.priority - b.priority);
const autobuyers = [
Autobuyer.reality,
Autobuyer.bigCrunch,
Autobuyer.eternity,
Autobuyer.galaxy,
Autobuyer.dimboost,
Autobuyer.sacrifice
]
const autobuyers = prestige
.concat(single, other, infinityDims, timeDims)
.concat(priorityQueue)
.filter(a => a.canTick);

View File

@ -1,6 +1,6 @@
"use strict";
Autobuyer.bigCrunch = new class BigCrunchAutobuyerState extends IntervaledAutobuyerState {
Autobuyer.bigCrunch = new class BigCrunchAutobuyerState extends UpgradeableAutobuyerState {
get data() {
return player.auto.bigCrunch;
}

View File

@ -0,0 +1,25 @@
"use strict";
class BlackHolePowerAutobuyerState extends AutobuyerState {
constructor(blackHole) {
super();
this._blackHole = blackHole;
}
get data() {
return player.auto.blackHolePower[this._blackHole - 1];
}
get isUnlocked() {
return Ra.has(RA_UNLOCKS.AUTO_BLACK_HOLE_POWER);
}
tick() {
const blackHole = this._blackHole;
BlackHole(blackHole).powerUpgrade.purchase();
}
}
BlackHolePowerAutobuyerState.index = Array.range(1, 2).map(blackHole => new BlackHolePowerAutobuyerState(blackHole));
Autobuyer.blackHolePower = blackHole => BlackHolePowerAutobuyerState.index[blackHole - 1];

View File

@ -0,0 +1,30 @@
"use strict";
class DilationUpgradeAutobuyerState extends IntervaledAutobuyerState {
constructor(upgrade) {
super();
this._upgrade = upgrade;
this._upgradeName = ["dtGain", "galaxyThreshold", "tachyonGain"][this._upgrade - 1];
}
get data() {
return player.auto.dilationUpgrades[this._upgrade - 1];
}
get interval() {
return 1000 * Perk.autobuyerFasterDilation.effectOrDefault(1) / PerkShopUpgrade.autoSpeed.effectOrDefault(1);
}
get isUnlocked() {
return Perk.autobuyerDilation.isEffectActive;
}
tick() {
const upgradeName = this._upgradeName;
DilationUpgrade[upgradeName].purchase(true);
}
}
DilationUpgradeAutobuyerState.index = Array.range(1, 3).map(upgrade => new DilationUpgradeAutobuyerState(upgrade));
Autobuyer.dilationUpgrade = upgrade => DilationUpgradeAutobuyerState.index[upgrade - 1];

View File

@ -1,6 +1,6 @@
"use strict";
Autobuyer.dimboost = new class DimBoostAutobuyerState extends IntervaledAutobuyerState {
Autobuyer.dimboost = new class DimBoostAutobuyerState extends UpgradeableAutobuyerState {
get data() {
return player.auto.dimBoost;
}

View File

@ -1,6 +1,6 @@
"use strict";
Autobuyer.galaxy = new class GalaxyAutobuyerState extends IntervaledAutobuyerState {
Autobuyer.galaxy = new class GalaxyAutobuyerState extends UpgradeableAutobuyerState {
get data() {
return player.auto.galaxy;
}

View File

@ -0,0 +1,32 @@
"use strict";
class InfinityDimensionAutobuyerState extends IntervaledAutobuyerState {
constructor(tier) {
super();
this._tier = tier;
}
get data() {
return player.auto.infinityDims[this._tier - 1];
}
get interval() {
return 1000 * Perk.autobuyerFasterID.effectOrDefault(1) / PerkShopUpgrade.autoSpeed.effectOrDefault(1);
}
get isUnlocked() {
return EternityMilestone.autobuyerID(this._tier).isReached;
}
tick() {
const tier = this._tier;
if (!InfinityDimension(tier).isAvailableForPurchase) return;
super.tick();
buyManyInfinityDimension(tier);
buyMaxInfDims(tier);
}
}
InfinityDimensionAutobuyerState.index = Array.range(1, 8).map(tier => new InfinityDimensionAutobuyerState(tier));
Autobuyer.infinityDimension = tier => InfinityDimensionAutobuyerState.index[tier - 1];

View File

@ -0,0 +1,29 @@
"use strict";
Autobuyer.ipMult = new class IPMultAutobuyerState extends AutobuyerState {
get data() {
return player.auto.ipMultBuyer;
}
get isUnlocked() {
return EternityMilestone.autobuyerIPMult.isReached;
}
tick() {
InfinityUpgrade.ipMult.buyMax();
}
}();
Autobuyer.epMult = new class EPMultAutobuyerState extends AutobuyerState {
get data() {
return player.auto.epMultBuyer;
}
get isUnlocked() {
return RealityUpgrade(13).isBought;
}
tick() {
EternityUpgrade.epMult.buyMax();
}
}();

View File

@ -0,0 +1,25 @@
"use strict";
class RealityUpgradeAutobuyerState extends AutobuyerState {
constructor(upgrade) {
super();
this._upgrade = upgrade;
}
get data() {
return player.auto.realityUpgrades[this._upgrade - 1];
}
get isUnlocked() {
return Ra.has(RA_UNLOCKS.AUTO_REALITY_UPGRADES);
}
tick() {
const upgrade = this._upgrade;
RealityUpgrade(upgrade).purchase();
}
}
RealityUpgradeAutobuyerState.index = Array.range(1, 5).map(upgrade => new RealityUpgradeAutobuyerState(upgrade));
Autobuyer.realityUpgrades = upgrade => RealityUpgradeAutobuyerState.index[upgrade - 1];

View File

@ -0,0 +1,20 @@
"use strict";
Autobuyer.replicantiGalaxy = new class ReplicantiGalaxyAutobuyerState extends IntervaledAutobuyerState {
get data() {
return player.auto.replicantiGalaxies;
}
get isUnlocked() {
return EternityMilestone.autobuyerReplicantiGalaxy.isReached;
}
get isEnabled() {
return Achievement(138).isUnlocked || !TimeStudy(131).isBought;
}
tick() {
if (!this.isEnabled) return;
replicantiGalaxy();
}
}();

View File

@ -0,0 +1,31 @@
"use strict";
class ReplicantiUpgradeAutobuyerState extends IntervaledAutobuyerState {
constructor(upgrade) {
super();
this._upgrade = upgrade;
this._upgradeName = ["chance", "interval", "galaxies"][this._upgrade - 1];
}
get data() {
return player.auto.replicantiUpgrades[this._upgrade - 1];
}
get interval() {
return 1000 * Perk.autobuyerFasterReplicanti.effectOrDefault(1) / PerkShopUpgrade.autoSpeed.effectOrDefault(1);
}
get isUnlocked() {
return ReplicantiUpgrade[this._upgradeName].autobuyerMilestone.isReached;
}
tick() {
const upgradeName = this._upgradeName;
if (EternityChallenge(8).isRunning) return;
ReplicantiUpgrade[upgradeName].autobuyerTick();
}
}
ReplicantiUpgradeAutobuyerState.index = Array.range(1, 3).map(upgrade => new ReplicantiUpgradeAutobuyerState(upgrade));
Autobuyer.replicantiUpgrade = upgrade => ReplicantiUpgradeAutobuyerState.index[upgrade - 1];

View File

@ -1,6 +1,6 @@
"use strict";
Autobuyer.tickspeed = new class TickspeedAutobuyerState extends IntervaledAutobuyerState {
Autobuyer.tickspeed = new class TickspeedAutobuyerState extends UpgradeableAutobuyerState {
get data() {
return player.auto.tickspeed;
}

View File

@ -0,0 +1,35 @@
"use strict";
class TimeDimensionAutobuyerState extends IntervaledAutobuyerState {
constructor(tier) {
super();
this._tier = tier;
}
get data() {
return player.auto.timeDims[this._tier - 1];
}
get interval() {
return 1000 / PerkShopUpgrade.autoSpeed.effectOrDefault(1);
}
get isUnlocked() {
return RealityUpgrade(13).isBought;
}
tick() {
const tier = this._tier;
if (!TimeDimension(tier).isAvailableForPurchase) return;
super.tick();
if (player.eternityPoints.gte(1e10)) {
buyMaxTimeDimension(tier);
} else {
buySingleTimeDimension(tier);
}
}
}
TimeDimensionAutobuyerState.index = Array.range(1, 8).map(tier => new TimeDimensionAutobuyerState(tier));
Autobuyer.timeDimension = tier => TimeDimensionAutobuyerState.index[tier - 1];

View File

@ -0,0 +1,26 @@
"use strict";
Autobuyer.timeTheorem = new class TimeTheoremAutobuyerState extends IntervaledAutobuyerState {
get data() {
return player.auto.timeTheorems;
}
get interval() {
const period = Effects.min(
Number.POSITIVE_INFINITY,
Perk.autobuyerTT1,
Perk.autobuyerTT2,
Perk.autobuyerTT3,
Perk.autobuyerTT4
);
return TimeSpan.fromSeconds(period).totalMilliseconds / PerkShopUpgrade.autoSpeed.effectOrDefault(1);
}
get isUnlocked() {
return Perk.autobuyerTT1.isBought;
}
tick() {
TimeTheorems.buyMax(true);
}
}();

View File

@ -111,25 +111,11 @@ function bigCrunchReplicanti() {
// I don't think this Math.clampMax is technically needed, but if we add another source
// of keeping Replicanti Galaxies then it might be.
player.replicanti.galaxies = Math.clampMax(remainingGalaxies, currentReplicantiGalaxies);
autoBuyReplicantiUpgrades();
}
function bigCrunchCheckUnlocks() {
if (EternityChallenge(4).tryFail()) return;
if (EternityMilestone.autobuyerID(1).isReached &&
!EternityChallenge(8).isRunning &&
!EternityChallenge(2).isRunning &&
!EternityChallenge(10).isRunning) {
for (let i = 1; i <= player.eternities.sub(10).clampMax(8).toNumber(); i++) {
if (player.auto.infinityDims.active[i - 1]) {
buyMaxInfDims(i);
buyManyInfinityDimension(i);
}
}
}
if (Effarig.isRunning && !EffarigUnlock.infinity.isUnlocked) {
EffarigUnlock.infinity.unlock();
beginProcessReality(getRealityProps(true));
@ -356,7 +342,7 @@ class InfinityIPMultUpgrade extends GameMechanicState {
}
}
autobuyerTick() {
buyMax() {
if (!this.canBeBought) return;
if (!this.hasIncreasedCost) {
// The purchase at 1e3000000 is considered post-softcap because that purchase increases the cost by 1e10x.

View File

@ -30,25 +30,6 @@ class BlackHoleUpgradeState {
return player.reality.realityMachines.gte(this.cost);
}
get autobuyerId() {
return this.id - 1;
}
get isAutobuyerOn() {
if (this.hasAutobuyer) {
return player.auto.blackHoleUpgrades.active[this.autobuyerId];
}
throw new Error("Trying to get status of the autobuyer of a black hole upgrade without an autobuyer.");
}
set isAutobuyerOn(value) {
if (this.hasAutobuyer) {
player.auto.blackHoleUpgrades.active[this.autobuyerId] = value;
} else {
throw new Error("Trying to set status of the autobuyer of a black hole upgrade without an autobuyer.");
}
}
purchase() {
if (!this.isAffordable || this.value === 0) return;
player.reality.realityMachines = player.reality.realityMachines.minus(this.cost);

View File

@ -433,7 +433,7 @@ dev.testReplicantiCode = function(singleId, useDebugger = false) {
],
[
function() {
player.auto.replicantiGalaxies.active = true;
player.auto.replicantiGalaxies.isActive = true;
}
],
[

View File

@ -49,11 +49,8 @@ const DIL_UPG_NAMES = [
"ndMultDT", "ipMultDT", "timeStudySplit", "dilationPenalty", "ttGenerator"
];
function buyDilationUpgrade(id, bulk, extraFactor) {
function buyDilationUpgrade(id, bulk) {
const upgrade = DilationUpgrade[DIL_UPG_NAMES[id]];
// Upgrades 1-3 are rebuyable, and can be automatically bought in bulk with a perk shop upgrade
// If a tick is really long (perhaps due to the player going offline), they can be automatically bought
// several times in one tick, which is what the extraFactor variable is used for.
if (id > 3) {
if (player.dilation.dilatedTime.lt(upgrade.cost)) return false;
if (player.dilation.upgrades.has(id)) return false;
@ -66,7 +63,7 @@ function buyDilationUpgrade(id, bulk, extraFactor) {
let buying = Decimal.affordGeometricSeries(player.dilation.dilatedTime,
upgrade.config.initialCost, upgrade.config.increment, upgAmount).toNumber();
buying = Math.clampMax(buying, Effects.max(1, PerkShopUpgrade.bulkDilation) * extraFactor);
buying = Math.clampMax(buying, Effects.max(1, PerkShopUpgrade.bulkDilation));
buying = Math.clampMax(buying, upgrade.config.purchaseCap - upgAmount);
if (!bulk) {
buying = Math.clampMax(buying, 1);
@ -204,24 +201,12 @@ class RebuyableDilationUpgradeState extends RebuyableMechanicState {
player.dilation.rebuyables[this.id] = value;
}
get autobuyerId() {
return this.config.id - 1;
}
get isAutobuyerOn() {
return player.auto.dilation.active[this.autobuyerId];
}
set isAutobuyerOn(value) {
player.auto.dilation.active[this.autobuyerId] = value;
}
get isCapped() {
return this.config.reachedCapFn();
}
purchase(bulk, extraFactor = 1) {
buyDilationUpgrade(this.config.id, bulk, extraFactor);
purchase(bulk) {
buyDilationUpgrade(this.config.id, bulk);
}
}

View File

@ -75,9 +75,9 @@ function buyMaxInfinityDimensions() {
}
function toggleAllInfDims() {
const areEnabled = player.auto.infinityDims.active[0];
const areEnabled = Autobuyer.infinityDimension(1).isActive;
for (let i = 1; i < 9; i++) {
player.auto.infinityDims.active[i - 1] = !areEnabled;
Autobuyer.infinityDimension(i).isActive = !areEnabled;
}
}
@ -133,10 +133,6 @@ class InfinityDimensionState extends DimensionState {
return player.records.thisEternity.maxAM.gte(this.requirement);
}
get isAutobuyerUnlocked() {
return player.eternities.gte(10 + this.tier);
}
get isAvailableForPurchase() {
return this.isAffordable && (player.eterc8ids > 0 || !EternityChallenge(8).isRunning);
}
@ -262,7 +258,7 @@ class InfinityDimensionState extends DimensionState {
this.isUnlocked = true;
EventHub.dispatch(GAME_EVENT.INFINITY_DIMENSION_UNLOCKED, this.tier);
if (player.auto.infinityDims.active[this.tier - 1] && !manual &&
if (Autobuyer.infinityDimension(this.tier).isActive && !manual &&
!EternityChallenge(2).isRunning && !EternityChallenge(8).isRunning && !EternityChallenge(10).isRunning) {
buyMaxInfDims(this.tier);
}

View File

@ -26,9 +26,9 @@ function fullResetTimeDimensions() {
}
function toggleAllTimeDims() {
const areEnabled = player.auto.timeDims.active[0];
const areEnabled = Autobuyer.timeDimension(1).isActive;
for (let i = 1; i < 9; i++) {
player.auto.timeDims.active[i - 1] = !areEnabled;
Autobuyer.timeDimension(i).isActive = !areEnabled;
}
}
@ -54,12 +54,12 @@ function maxAllTimeDimensions(checkAutobuyers = false) {
// (reduces overhead at higher EP)
if (player.eternityPoints.gte(1e10)) {
for (let i = 8; i > 0; i--) {
if (!checkAutobuyers || player.auto.timeDims.active[i - 1]) buyMaxTimeDimension(i);
if (!checkAutobuyers || Autobuyer.timeDimension(i).isActive) buyMaxTimeDimension(i);
}
} else {
// Low EP behavior: Try to buy the highest affordable new dimension, then loop buying the cheapest possible
for (let i = 4; i > 0 && TimeDimension(i).bought === 0; i--) {
if (!checkAutobuyers || player.auto.timeDims.active[i - 1]) buySingleTimeDimension(i);
if (!checkAutobuyers || Autobuyer.timeDimension(i).isActive) buySingleTimeDimension(i);
}
// Should never take more than like 50 iterations; explicit infinite loops make me nervous
@ -67,7 +67,7 @@ function maxAllTimeDimensions(checkAutobuyers = false) {
let cheapestDim = 0;
let cheapestCost = 1e10;
for (let i = 1; i <= 4; i++) {
if (TimeDimension(i).cost.lte(cheapestCost) && (!checkAutobuyers || player.auto.timeDims.active[i - 1])) {
if (TimeDimension(i).cost.lte(cheapestCost) && (!checkAutobuyers || Autobuyer.timeDimension(i).isActive)) {
cheapestDim = i;
cheapestCost = TimeDimension(i).cost;
}
@ -147,6 +147,10 @@ class TimeDimensionState extends DimensionState {
return this._tier < 5 || TimeStudy.timeDimension(this._tier).isBought;
}
get isAvailableForPurchase() {
return this.isAffordable && this.isUnlocked;
}
get isAffordable() {
return player.eternityPoints.gte(this.cost);
}

View File

@ -190,16 +190,7 @@ function initializeResourcesAfterEternity() {
player.achievementChecks.noReplicantiGalaxies = true;
}
function applyRealityUpgradesAfterEternity(buySingleTD = false) {
if (RealityUpgrade(13).isBought) {
if (player.auto.epMultBuyer) EternityUpgrade.epMult.buyMax();
for (let i = 1; i < 9; i++) {
if (player.auto.timeDims.active[i - 1]) {
if (buySingleTD) buySingleTimeDimension(i);
else buyMaxTimeDimension(i);
}
}
}
function applyRealityUpgradesAfterEternity() {
if (player.eternityUpgrades.size < 3 && Perk.autounlockEU1.isBought) {
for (const id of [1, 2, 3]) player.eternityUpgrades.add(id);
}
@ -278,17 +269,6 @@ class EternityUpgradeState extends SetPurchasableMechanicState {
class EPMultiplierState extends GameMechanicState {
constructor() {
super({});
this.autobuyer = {
get isUnlocked() {
return RealityUpgrade(13).isBought;
},
get isOn() {
return player.auto.epMultBuyer;
},
set isOn(value) {
player.auto.epMultBuyer = value;
}
};
this.cachedCost = new Lazy(() => this.costAfterCount(player.epmultUpgrades));
this.cachedEffectValue = new Lazy(() => Decimal.pow(5, player.epmultUpgrades));
}

View File

@ -65,10 +65,10 @@ GameKeyboard.bindHotkey("alt+s", () => toggleAutobuyer(12));
GameKeyboard.bindHotkey("alt+e", () => toggleAutobuyer(13));
GameKeyboard.bindHotkey("alt+y", () => toggleAutobuyer(14));
GameKeyboard.bindHotkey("alt+r", () => {
const buyer = Replicanti.galaxies.autobuyer;
const buyer = Autobuyer.replicantiGalaxy;
if (buyer.isUnlocked) {
buyer.toggle();
GameUI.notify.info(`Replicanti Galaxy autobuyer ${(buyer.isOn) ? "enabled" : "disabled"}`);
GameUI.notify.info(`Replicanti Galaxy autobuyer ${(buyer.isActive) ? "enabled" : "disabled"}`);
}
return false;
});

View File

@ -50,6 +50,27 @@ let player = {
upgradeBits: 0
},
auto: {
// TODO: REMOVE COMMENTS
// Desired order of Autobuyer appearance.
// Reality
// ^Eternity
// ^Infinity (Big Crunch)
// Antimatter Galaxies
// Dimension Boosts
// ^Tickspeed Upgrades
// ^Sacrifice
// ^Antimatter Dimensions
// +Infinty Dimensions
// +Time Dimensions
// +Replicanti Upgrades (Percentage, Interval, Max Galaxies)
// +Replicanti Galaxies
// +Dilation Upgrades (DT gain, TG mult, TP gain)
// +Black Hole Power Upgrades
// +Rebuyable Reality Upgrades
// +IP Mult, EP Mult
//
// ^ = To change
// + = To add
bulkOn: true,
autobuyersOn: true,
disableContinuum: false,
@ -124,38 +145,37 @@ let player = {
lastTick: 0,
isBought: false
})),
infinityDims: {
active: [false, false, false, false, false, false, false, false],
timer: 0,
},
timeDims: {
active: [false, false, false, false, false, false, false, false],
timer: 0,
},
infinityDims: Array.range(0, 8).map(() => ({
isActive: false,
lastTick: 0,
})),
timeDims: Array.range(0, 8).map(() => ({
isActive: false,
lastTick: 0,
})),
replicantiGalaxies: {
active: false,
timer: 0,
},
replicantiUpgrades: {
active: [false, false, false],
timer: 0,
isActive: false,
},
replicantiUpgrades: Array.range(0, 3).map(() => ({
isActive: false,
lastTick: 0,
})),
timeTheorems: {
active: false,
timer: 0,
isActive: false,
lastTick: 0,
},
dilation: {
active: [false, false, false],
timer: 0,
},
blackHoleUpgrades: {
active: [false, false]
},
realityUpgrades: {
active: [false, false, false, false, false],
},
ipMultBuyer: false,
epMultBuyer: false,
dilationUpgrades: Array.range(0, 3).map(() => ({
isActive: false,
lastTick: 0,
})),
blackHolePower: Array.range(0, 2).map(() => ({
isActive: false,
})),
realityUpgrades: Array.range(0, 5).map(() => ({
isActive: false,
})),
ipMultBuyer: { isActive: false, },
epMultBuyer: { isActive: false, },
},
infinityPoints: new Decimal(0),
infinitied: new Decimal(0),

View File

@ -364,10 +364,8 @@ function finishProcessReality(realityProps) {
player.infMultCost = new Decimal(10);
player.infinityRebuyables = [0, 0, 0];
player.infinityPower = new Decimal(1);
player.auto.infinityDims.active = Array.repeat(false, 8);
player.timeShards = new Decimal(0);
Replicanti.reset(true);
player.auto.replicantiUpgrades.active = Array.repeat(false, 3);
player.eternityPoints = Player.startingEP;
@ -385,7 +383,6 @@ function finishProcessReality(realityProps) {
player.challenge.eternity.current = 0;
player.challenge.eternity.unlocked = 0;
player.etercreq = 0;
player.auto.ipMultBuyer = false;
player.respec = false;
player.eterc8ids = 50;
player.eterc8repl = 40;
@ -459,7 +456,7 @@ function finishProcessReality(realityProps) {
EventHub.dispatch(GAME_EVENT.REALITY_RESET_AFTER);
// This immediately gives eternity upgrades instead of after the first eternity
if (RealityUpgrades.allBought) applyRealityUpgradesAfterEternity(celestialRunState.enslaved);
if (RealityUpgrades.allBought) applyRealityUpgradesAfterEternity();
if (!isReset) Ra.applyAlchemyReactions();
@ -496,7 +493,6 @@ function applyRUPG10() {
bulk: 1e10,
mode: AUTOBUYER_MODE.BUY_10,
priority: 1,
isActive: true,
lastTick: player.records.realTimePlayed
}));
for (const autobuyer of Autobuyers.all) {
@ -517,13 +513,9 @@ function applyRUPG10() {
player.galaxies = Math.max(1, player.galaxies);
player.break = true;
player.infinityRebuyables = [8, 7, 10];
player.auto.infinityDims.active = Array.repeat(true, 8);
player.auto.ipMultBuyer = true;
player.eternities = player.eternities.plus(100);
player.replicanti.amount = player.replicanti.amount.clampMin(1);
Replicanti.unlock(true);
player.auto.replicantiGalaxies.active = true;
player.auto.replicantiUpgrades.active = Array.repeat(true, 3);
GameCache.tickSpeedMultDecrease.invalidate();
GameCache.dimensionMultDecrease.invalidate();
}

View File

@ -20,7 +20,7 @@ function addReplicantiGalaxies(newGalaxies) {
function replicantiGalaxy() {
if (!Replicanti.galaxies.canBuyMore) return;
player.auto.replicantiGalaxies.timer = 0;
player.replicanti.timer = 0;
let galaxyGain = 1;
if (Achievement(126).isUnlocked) {
// Attempt to buy bulk if RG divides by e308 instead of resetting
@ -72,7 +72,7 @@ function fastReplicantiBelow308(log10GainFactor, isAutobuyerActive) {
}
function replicantiGalaxyAutoToggle(forcestate) {
player.auto.replicantiGalaxies.active = !player.auto.replicantiGalaxies.active || forcestate === true;
player.auto.replicantiGalaxies.isActive = !player.auto.replicantiGalaxies.isActive || forcestate === true;
}
// When the amount is exactly the cap, there are two cases: the player can go
@ -159,14 +159,14 @@ function replicantiLoop(diff) {
Decimal.exp(remainingGain.div(LOG10_E).times(postScale).plus(1).ln() / postScale +
player.replicanti.amount.clampMin(1).ln());
}
player.auto.replicantiGalaxies.timer = 0;
} else if (interval.lte(player.auto.replicantiGalaxies.timer)) {
player.replicanti.timer = 0;
} else if (interval.lte(player.replicanti.timer)) {
const reproduced = binomialDistribution(player.replicanti.amount, player.replicanti.chance);
player.replicanti.amount = player.replicanti.amount.plus(reproduced);
if (!isUncapped) player.replicanti.amount = Decimal.min(replicantiCap(), player.replicanti.amount);
player.auto.replicantiGalaxies.timer += diff - interval.toNumber();
player.replicanti.timer += diff - interval.toNumber();
} else {
player.auto.replicantiGalaxies.timer += diff;
player.replicanti.timer += diff;
}
if (areRGsBeingBought && player.replicanti.amount.gte(Decimal.NUMBER_MAX_VALUE)) {
@ -184,15 +184,10 @@ function replicantiMult() {
.pow(getAdjustedGlyphEffect("replicationpow"));
}
function autoBuyReplicantiUpgrades() {
if (EternityChallenge(8).isRunning) return;
ReplicantiUpgrade.chance.autobuyerTick();
ReplicantiUpgrade.interval.autobuyerTick();
ReplicantiUpgrade.galaxies.autobuyerTick();
}
/** @abstract */
class ReplicantiUpgradeState {
/** @abstract */
get id() { throw new NotImplementedError(); }
/** @abstract */
get value() { throw new NotImplementedError(); }
@ -219,13 +214,6 @@ class ReplicantiUpgradeState {
/** @abstract */
get autobuyerMilestone() { throw new NotImplementedError(); }
/** @abstract */
get autobuyerId() { throw new NotImplementedError(); }
get isAutobuyerUnlocked() { return this.autobuyerMilestone.isReached; }
get isAutobuyerOn() { return player.auto.replicantiUpgrades.active[this.autobuyerId]; }
set isAutobuyerOn(value) { player.auto.replicantiUpgrades.active[this.autobuyerId] = value; }
get canBeBought() {
return !this.isCapped && player.infinityPoints.gte(this.cost) && player.eterc8repl !== 0;
@ -241,7 +229,6 @@ class ReplicantiUpgradeState {
}
autobuyerTick() {
if (!this.isAutobuyerUnlocked || !this.isAutobuyerOn) return;
while (this.canBeBought) {
this.purchase();
}
@ -250,6 +237,8 @@ class ReplicantiUpgradeState {
const ReplicantiUpgrade = {
chance: new class ReplicantiChanceUpgrade extends ReplicantiUpgradeState {
get id() { return 1; }
get value() { return player.replicanti.chance; }
set value(value) { player.replicanti.chance = value; }
@ -277,10 +266,7 @@ const ReplicantiUpgrade = {
return EternityMilestone.autobuyerReplicantiChance;
}
get autobuyerId() { return 0; }
autobuyerTick() {
if (!this.isAutobuyerUnlocked || !this.isAutobuyerOn) return;
// Fixed price increase of 1e15; so total cost for N upgrades is:
// cost + cost * 1e15 + cost * 1e30 + ... + cost * 1e15^(N-1) == cost * (1e15^N - 1) / (1e15 - 1)
// N = log(IP * (1e15 - 1) / cost + 1) / log(1e15)
@ -299,6 +285,8 @@ const ReplicantiUpgrade = {
}
}(),
interval: new class ReplicantiIntervalUpgrade extends ReplicantiUpgradeState {
get id() { return 2; }
get value() { return player.replicanti.interval; }
set value(value) { player.replicanti.interval = value; }
@ -325,13 +313,13 @@ const ReplicantiUpgrade = {
return EternityMilestone.autobuyerReplicantiInterval;
}
get autobuyerId() { return 1; }
applyModifiers(value) {
return getReplicantiInterval(undefined, value);
}
}(),
galaxies: new class ReplicantiGalaxiesUpgrade extends ReplicantiUpgradeState {
get id() { return 3; }
get value() { return player.replicanti.boughtGalaxyCap; }
set value(value) { player.replicanti.boughtGalaxyCap = value; }
@ -370,15 +358,12 @@ const ReplicantiUpgrade = {
return EternityMilestone.autobuyerReplicantiMaxGalaxies;
}
get autobuyerId() { return 2; }
get extra() {
return Effects.max(0, TimeStudy(131));
}
autobuyerTick() {
// This isn't a hot enough autobuyer to worry about doing an actual inverse.
if (!this.isAutobuyerUnlocked || !this.isAutobuyerOn) return;
const bulk = bulkBuyBinarySearch(player.infinityPoints, {
costFunction: x => this.baseCostAfterCount(x).dividedByEffectOf(TimeStudy(233)),
firstCost: this.cost,
@ -422,7 +407,7 @@ const Replicanti = {
reset(force = false) {
player.replicanti.unl = force ? false : EternityMilestone.unlockReplicanti.isReached;
player.replicanti.amount = player.replicanti.unl ? new Decimal(1) : new Decimal(0);
player.auto.replicantiGalaxies.timer = 0;
player.replicanti.timer = 0;
player.replicanti.chance = 0.01;
player.replicanti.chanceCost = new Decimal(1e150);
player.replicanti.interval = 1000;
@ -430,9 +415,9 @@ const Replicanti = {
player.replicanti.boughtGalaxyCap = 0;
player.replicanti.galaxies = 0;
player.replicanti.galCost = new Decimal(1e170);
if (force ||
(EternityMilestone.autobuyerReplicantiGalaxy.isReached && player.auto.replicantiGalaxies.active === undefined)) {
player.auto.replicantiGalaxies.active = false;
if (player.auto.replicantiGalaxies.isActive === undefined &&
EternityMilestone.autobuyerReplicantiGalaxy.isReached) {
player.auto.replicantiGalaxies.isActive = false;
}
},
unlock(freeUnlock = false) {
@ -440,7 +425,7 @@ const Replicanti = {
if (freeUnlock || player.infinityPoints.gte(1e140)) {
if (!freeUnlock) player.infinityPoints = player.infinityPoints.minus(1e140);
player.replicanti.unl = true;
player.auto.replicantiGalaxies.timer = 0;
player.replicanti.timer = 0;
player.replicanti.amount = new Decimal(1);
}
},
@ -472,28 +457,8 @@ const Replicanti = {
return this.bought < this.max;
},
get areBeingBought() {
return this.autobuyer.isActive || this.isPlayerHoldingR;
const buyer = Autobuyer.replicantiGalaxy;
return (buyer.isActive && buyer.isEnabled) || this.isPlayerHoldingR;
},
autobuyer: {
get isUnlocked() {
return EternityMilestone.autobuyerReplicantiGalaxy.isReached;
},
get isOn() {
return player.auto.replicantiGalaxies.active;
},
set isOn(value) {
player.auto.replicantiGalaxies.active = value;
},
toggle() {
if (!this.isUnlocked) return;
this.isOn = !this.isOn;
},
get isEnabled() {
return !TimeStudy(131).isBought || Achievement(138).isUnlocked;
},
get isActive() {
return this.isOn && this.isEnabled;
}
}
},
};

View File

@ -1440,18 +1440,6 @@ class RebuyableRealityUpgradeState extends RebuyableMechanicState {
set boughtAmount(value) {
player.reality.rebuyables[this.id] = value;
}
get autobuyerId() {
return this.id - 1;
}
get isAutobuyerOn() {
return player.auto.realityUpgrades.active[this.autobuyerId];
}
set isAutobuyerOn(value) {
player.auto.realityUpgrades.active[this.autobuyerId] = value;
}
}
RealityUpgradeState.index = mapGameData(

View File

@ -909,24 +909,34 @@ GameStorage.devMigrations = {
delete player.auto.disableContinuum;
},
player => {
for (let i = 0; i < 8; i++) {
player.auto.infinityDims[i].isActive = player.infDimBuyers[i];
player.auto.infinityDims[i].lastTick = player.auto.infDimTimer;
}
for (let i = 0; i < 8; i++) {
player.auto.timeDims[i].isActive = player.reality.tdbuyers[i];
player.auto.timeDims[i].lastTick = player.auto.timeDimTimer;
}
for (let i = 0; i < 3; i++) {
player.auto.replicantiUpgrades[i].isActive = player.replicanti.auto[i];
player.auto.replicantiUpgrades[i].lastTick = player.auto.repUpgradeTimer;
}
for (let i = 0; i < 3; i++) {
player.auto.dilationUpgrades[i].isActive = player.dilation.auto[i];
player.auto.dilationUpgrades[i].lastTick = player.auto.dilUpgradeTimer;
}
for (let i = 0; i < 2; i++) {
player.auto.blackHolePower[i].isActive = player.blackHole[i].autoPower;
}
for (let i = 0; i < 5; i++) {
player.auto.realityUpgrades[i].isActive = player.reality.rebuyablesAuto[i];
}
player.auto.antimatterDims = player.auto.dimensions;
player.auto.infinityDims.active = player.infDimBuyers;
player.auto.infinityDims.timer = player.auto.infDimTimer;
player.auto.timeDims.active = player.reality.tdbuyers;
player.auto.timeDims.timer = player.auto.timeDimTimer;
player.auto.replicantiGalaxies.active = player.replicanti.galaxybuyer;
player.auto.replicantiGalaxies.timer = player.replicanti.timer;
player.auto.replicantiUpgrades.active = player.replicanti.auto;
player.auto.replicantiUpgrades.timer = player.auto.repUpgradeTimer;
player.auto.timeTheorems.active = player.ttbuyer;
player.auto.timeTheorems.timer = player.auto.ttTimer;
player.auto.dilation.active = player.dilation.auto;
player.auto.dilation.timer = player.auto.dilUpgradeTimer;
player.auto.blackHoleUpgrades.active[0] = player.blackHole[0].autoPower;
player.auto.blackHoleUpgrades.active[1] = player.blackHole[1].autoPower;
player.auto.realityUpgrades.active = player.reality.rebuyablesAuto;
player.auto.ipMultBuyer = player.infMultBuyer;
player.auto.epMultBuyer = player.reality.epmultbuyer;
player.auto.replicantiGalaxies.isActive = player.replicanti.galaxybuyer;
player.auto.ipMultBuyer.isActive = player.infMultBuyer;
player.auto.epMultBuyer.isActive = player.reality.epmultbuyer;
player.auto.timeTheorems.isActive = player.ttbuyer;
player.auto.timeTheorems.lastTick = player.auto.ttTimer;
delete player.auto.dimensions;
delete player.infDimBuyers;
@ -934,7 +944,6 @@ GameStorage.devMigrations = {
delete player.reality.tdbuyers;
delete player.auto.timeDimTimer;
delete player.replicanti.galaxybuyer;
delete player.replicanti.timer;
delete player.replicanti.auto;
delete player.auto.repUpgradeTimer;
delete player.ttbuyer;

View File

@ -545,7 +545,7 @@ GameStorage.migrations = {
for (let i = 0; i < 8; i++) {
const old = player.autobuyers[i];
if (old % 1 === 0) continue;
const autobuyer = player.auto.dimensions[i];
const autobuyer = player.auto.antimatterDims[i];
autobuyer.cost = old.cost;
autobuyer.interval = old.interval;
autobuyer.bulk = old.bulk;
@ -798,20 +798,18 @@ GameStorage.migrations = {
},
consolidateAuto(player) {
player.auto.antimatterDims = player.auto.dimensions;
player.auto.infinityDims.active = player.infDimBuyers;
player.auto.infinityDims.timer = player.auto.infDimTimer;
player.auto.replicantiGalaxies.active = player.replicanti.galaxybuyer;
player.auto.replicantiGalaxies.timer = player.replicanti.timer;
for (let i = 0; i < 8; i++) {
player.auto.infinityDims[i].isActive = player.infDimBuyers[i];
player.auto.infinityDims[i].lastTick = player.auto.infDimTimer;
}
player.auto.replicantiGalaxies.isActive = player.replicanti.galaxybuyer;
player.auto.replicantiUpgrades.active = player.replicanti.auto;
player.auto.replicantiUpgrades.timer = player.auto.repUpgradeTimer;
player.auto.ipMultBuyer = player.infMultBuyer;
player.auto.ipMultBuyer.isActive = player.infMultBuyer;
delete player.auto.dimensions;
delete player.infDimBuyers;
delete player.auto.infDimTimer;
delete player.replicanti.galaxybuyer;
delete player.replicanti.timer;
delete player.replicanti.auto;
delete player.auto.repUpgradeTimer;
delete player.infMultBuyer;

View File

@ -23,11 +23,9 @@ const TimeTheorems = {
},
checkForBuying(auto) {
if (player.realities === 0 && TimeDimension(1).bought < 1) {
if (!auto) Modal.message.show("You need to buy at least 1 Time Dimension before you can purchase Time Theorems.");
return false;
}
return true;
if (PlayerProgress.realityUnlocked() || TimeDimension(1).bought) return true;
if (!auto) Modal.message.show("You need to buy at least 1 Time Dimension before you can purchase Time Theorems.");
return false;
},
buyWithAntimatter(auto = false) {
@ -97,23 +95,6 @@ const TimeTheorems = {
Math.round(player.timestudy.epcost.log2());
},
autoBuyMaxTheorems(realDiff) {
if (!player.auto.timeTheorems.active) return;
player.auto.timeTheorems.timer += realDiff;
const period = Effects.min(
Number.POSITIVE_INFINITY,
Perk.autobuyerTT1,
Perk.autobuyerTT2,
Perk.autobuyerTT3,
Perk.autobuyerTT4
);
const milliseconds = TimeSpan.fromSeconds(period).totalMilliseconds;
if (player.auto.timeTheorems.timer > milliseconds) {
TimeTheorems.buyMax(true);
player.auto.timeTheorems.timer = Math.min(player.auto.timeTheorems.timer - milliseconds, milliseconds);
}
},
calculateTimeStudiesCost() {
let totalCost = TimeStudy.boughtNormalTS()
.map(ts => ts.cost)

View File

@ -374,6 +374,8 @@ function getGameSpeedupForDisplay() {
// "diff" is in ms. It is only unspecified when it's being called normally and not due to simulating time, in which
// case it uses the gap between now and the last time the function was called. This is on average equal to the update
// rate.
// TODO: Clean this up, remove the disable line
// eslint-disable-next-line complexity
function gameLoop(diff, options = {}) {
PerformanceStats.start("Frame Time");
PerformanceStats.start("Game Update");
@ -419,8 +421,8 @@ function gameLoop(diff, options = {}) {
diff = Enslaved.nextTickDiff;
}
slowerAutobuyers(realDiff);
Autobuyers.tick();
Tutorial.tutorialLoop();
if (Achievement(165).isUnlocked && player.celestials.effarig.autoAdjustGlyphWeights) {
autoAdjustGlyphWeights();
@ -561,12 +563,6 @@ function gameLoop(diff, options = {}) {
replicantiLoop(diff);
if (player.auto.ipMultBuyer) {
InfinityUpgrade.ipMult.autobuyerTick();
}
if (player.auto.epMultBuyer) EternityUpgrade.epMult.buyMax();
const currentEPmin = gainedEternityPoints().dividedBy(Time.thisEternityRealTime.totalMinutes);
if (currentEPmin.gt(player.records.thisEternity.bestEPmin) && Player.canEternity)
player.records.thisEternity.bestEPmin = currentEPmin;
@ -820,89 +816,12 @@ function simulateTime(seconds, real, fast) {
}
}
function autoBuyDilationUpgrades(extraFactor) {
if (Perk.autobuyerDilation.isBought) {
const upgrades = [DilationUpgrade.dtGain, DilationUpgrade.galaxyThreshold, DilationUpgrade.tachyonGain].filter(
upgrade => upgrade.isAutobuyerOn);
for (const upgrade of upgrades) {
upgrade.purchase(true, extraFactor);
}
}
}
function autoBuyInfDims() {
if (EternityMilestone.autobuyerID(1).isReached && !EternityChallenge(8).isRunning) {
for (let i = 1; i <= player.eternities.sub(10).clampMax(8).toNumber(); i++) {
if (player.auto.infinityDims.active[i - 1]) {
buyMaxInfDims(i);
buyManyInfinityDimension(i);
}
}
}
}
function autoBuyExtraTimeDims() {
if (TimeDimension(8).bought === 0 && Perk.autounlockTD.isBought) {
for (let dim = 5; dim <= 8; ++dim) TimeStudy.timeDimension(dim).purchase();
}
}
function slowerAutobuyers(realDiff) {
const ampDiff = realDiff * PerkShopUpgrade.autoSpeed.effectOrDefault(1);
player.auto.infinityDims.timer += ampDiff;
const infDimPeriod = 1000 * Perk.autobuyerFasterID.effectOrDefault(1);
if (player.auto.infinityDims.timer >= infDimPeriod) {
// Note: we need to reset to a low number here, because we don't want a pile of these accumulating during offline
// time and then releasing normally.
player.auto.infinityDims.timer = Math.min(player.auto.infinityDims.timer - infDimPeriod, infDimPeriod);
autoBuyInfDims();
}
player.auto.timeDims.timer += ampDiff;
const timeDimPeriod = 1000;
if (player.auto.timeDims.timer >= timeDimPeriod) {
player.auto.timeDims.timer = Math.min(player.auto.timeDims.timer - timeDimPeriod, timeDimPeriod);
if (RealityUpgrade(13).isBought) {
maxAllTimeDimensions(true);
}
}
player.auto.replicantiUpgrades.timer += ampDiff;
const repUpgradePeriod = 1000 * Perk.autobuyerFasterReplicanti.effectOrDefault(1);
if (player.auto.replicantiUpgrades.timer >= repUpgradePeriod) {
player.auto.replicantiUpgrades.timer = Math.min(player.auto.replicantiUpgrades.timer - repUpgradePeriod,
repUpgradePeriod);
autoBuyReplicantiUpgrades();
}
player.auto.dilation.timer += ampDiff;
const dilUpgradePeriod = 1000 * Perk.autobuyerFasterDilation.effectOrDefault(1);
if (player.auto.dilation.timer >= dilUpgradePeriod) {
// Because the dilation upgrade autobuyers naturally buy singles, it helps to
// be able to trigger them multiple times in one long-enough tick, which is
// what we do here. (This is why this code looks a bit different from that for
// the other autobuyers, which buy max.)
autoBuyDilationUpgrades(Math.floor(player.auto.dilation.timer / dilUpgradePeriod));
player.auto.dilation.timer %= dilUpgradePeriod;
}
TimeTheorems.autoBuyMaxTheorems(ampDiff);
Tutorial.tutorialLoop();
if (Ra.has(RA_UNLOCKS.AUTO_BLACK_HOLE_POWER)) {
for (let i = 1; i <= 2; i++) {
if (BlackHole(i).powerUpgrade.isAutobuyerOn) {
BlackHole(i).powerUpgrade.purchase();
}
}
}
if (Ra.has(RA_UNLOCKS.AUTO_REALITY_UPGRADES)) {
for (let i = 1; i <= 5; i++) {
if (RealityUpgrade(i).isAutobuyerOn) {
RealityUpgrade(i).purchase();
}
}
}
}
window.onload = function() {
GameUI.initialized = true;
ui.view.initialized = true;

View File

@ -305,7 +305,7 @@ button:focus {
.o-tt-autobuyer-button {
height: 2.5rem;
font-size: 1rem;
font-size: 1rem !important;
margin: 0.3rem;
flex-grow: 0;
flex-shrink: 0;