Unfuck autobuyers (#654)

Unfuck autobuyers
This commit is contained in:
Andrei Andreev 2019-07-23 17:38:16 +03:00 committed by GitHub
commit dcc120efd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 1383 additions and 1347 deletions

View File

@ -188,7 +188,6 @@
<script type="text/javascript" src="javascripts/core/secret-formula/game-database.js"></script>
<script type="text/javascript" src="javascripts/core/glyph-effects.js"></script>
<script type="text/javascript" src="javascripts/core/player.js"></script>
<script type="text/javascript" src="javascripts/core/autobuyer.js"></script>
<script type="text/javascript" src="javascripts/core/performance-stats.js"></script>
<script type="text/javascript" src="javascripts/core/currency.js"></script>
<script type="text/javascript" src="javascripts/core/game-mechanic.js"></script>
@ -199,6 +198,17 @@
<script type="text/javascript" src="javascripts/core/hotkeys.js"></script>
<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/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>
<script type="text/javascript" src="javascripts/core/autobuyers/big-crunch-autobuyer.js"></script>
<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/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"></script>
@ -352,7 +362,7 @@
<script type="text/javascript" src="javascripts/components/infinity/autobuyers/eternity-autobuyer-box.js"></script>
<script type="text/javascript" src="javascripts/components/infinity/autobuyers/dimboost-autobuyer-box.js"></script>
<script type="text/javascript" src="javascripts/components/infinity/autobuyers/galaxy-autobuyer-box.js"></script>
<script type="text/javascript" src="javascripts/components/infinity/autobuyers/dim-autobuyer-box.js"></script>
<script type="text/javascript" src="javascripts/components/infinity/autobuyers/dimension-autobuyer-box.js"></script>
<script type="text/javascript" src="javascripts/components/infinity/autobuyers/tickspeed-autobuyer-box.js"></script>
<script type="text/javascript" src="javascripts/components/infinity/autobuyers/sacrifice-autobuyer-box.js"></script>
<script type="text/javascript" src="javascripts/components/infinity/autobuyers/big-crunch-autobuyer-box.js"></script>

View File

@ -13,11 +13,7 @@ Vue.component("autobuyer-box", {
},
computed: {
intervalDisplay() {
let seconds = TimeSpan.fromMilliseconds(this.interval).totalSeconds;
if (BreakInfinityUpgrade.autobuyerSpeed.isBought) {
seconds /= 2;
}
return seconds.toFixed(2);
return TimeSpan.fromMilliseconds(this.interval).totalSeconds.toFixed(2);
}
},
methods: {
@ -30,58 +26,52 @@ Vue.component("autobuyer-box", {
}
},
props: {
setup: Object
autobuyer: Object,
name: String,
showInterval: {
type: Boolean,
default: false
}
},
data() {
return {
isUnlocked: false,
isOn: false
isActive: false,
globalToggle: false
};
},
computed: {
autobuyer() {
return this.setup.autobuyer;
},
hasInterval() {
return (this.autobuyer instanceof AutobuyerState);
watch: {
isActive(newValue) {
this.autobuyer.isActive = newValue;
}
},
methods: {
update() {
if (this.setup === undefined) return;
const autobuyer = this.autobuyer;
this.isUnlocked = autobuyer.isUnlocked;
if (!this.isUnlocked) return;
this.isOn = autobuyer.isOn;
this.isActive = autobuyer.isActive;
this.globalToggle = player.options.autobuyersOn;
},
changeActive() {
const newValue = !this.autobuyer.isOn;
this.autobuyer.isOn = newValue;
this.active = newValue;
toggle() {
if (!this.globalToggle) return;
this.isActive = !this.isActive;
}
},
template:
`<div v-if="isUnlocked" class="c-autobuyer-box l-autobuyer-box">
<div>{{setup.name}}</div>
<template v-if="hasInterval">
<slot name="beforeInterval" />
<interval-label :autobuyer="autobuyer"/>
</template>
<slot />
<div class="o-autobuyer-toggle-checkbox" @click="changeActive">
<div class="l-autobuyer-box__header">{{name}}</div>
<slot name="beforeInterval" />
<interval-label v-if="showInterval" :autobuyer="autobuyer"/>
<div class="l-autobuyer-box__content">
<slot />
</div>
<div class="o-autobuyer-toggle-checkbox l-autobuyer-box__footer" @click="toggle">
<span class="o-autobuyer-toggle-checkbox__label">Is active:</span>
<input :checked="isOn" type="checkbox"/>
<input
:checked="isActive && globalToggle"
:disabled="!globalToggle"
type="checkbox"
/>
</div>
</div>`
});
class AutobuyerBoxSetup {
/**
* @param {string} name
* @param {AutobuyerState|Autobuyer.eternity|Autobuyer.reality} autobuyer
*/
constructor(name, autobuyer) {
this.name = name;
this.autobuyer = autobuyer;
}
}

View File

@ -2,57 +2,49 @@
Vue.component("autobuyer-input", {
props: {
setup: Object
autobuyer: Object,
property: String,
type: String
},
data() {
return {
isValid: true,
actualValue: undefined,
isFocused: false,
displayValue: "0"
};
},
computed: {
type() {
return this.setup.type;
},
classObject() {
return {
"o-autobuyer-input": true,
"o-autobuyer-input--invalid": !this.isValid,
};
},
inputType() {
return this.type === AutobuyerInputType.INT ? "number" : "text";
return this.type === "int" ? "number" : "text";
},
typeFunctions() {
const functions = AutobuyerInputFunctions[this.type];
if (functions === undefined) {
throw crash("Unknown autobuyer input type");
}
return functions;
},
validityClass() {
return this.isValid ? undefined : "o-autobuyer-input--invalid";
}
},
methods: {
update() {
if (this.isFocused) return;
this.fetchActualValue();
this.updateActualValue();
},
fetchActualValue() {
const actualValue = this.getValue();
if (!this.areEqual(this.actualValue, actualValue)) {
this.actualValue = actualValue;
this.displayValue = this.formatActualValue();
}
updateActualValue() {
const actualValue = this.autobuyer[this.property];
if (this.areEqual(this.actualValue, actualValue)) return;
this.actualValue = this.typeFunctions.copyValue(actualValue);
this.updateDisplayValue();
},
areEqual(value, other) {
if (other === undefined || value === undefined) return false;
switch (this.type) {
case AutobuyerInputType.DECIMAL: return Decimal.eq(value, other);
case AutobuyerInputType.FLOAT:
case AutobuyerInputType.INT: return value === other;
}
throw "Unknown input type";
return this.typeFunctions.areEqual(value, other);
},
getValue() {
return this.setup.getValue();
},
setValue(value) {
this.setup.setValue(value);
this.displayValue = this.formatActualValue();
updateDisplayValue() {
this.displayValue = this.typeFunctions.formatValue(this.actualValue);
},
handleInput(event) {
const input = event.target.value;
@ -61,7 +53,9 @@ Vue.component("autobuyer-input", {
this.isValid = false;
return;
}
this.isValid = this.validate(input);
const parsedValue = this.typeFunctions.tryParse(input);
this.isValid = parsedValue !== undefined;
this.actualValue = this.typeFunctions.copyValue(parsedValue);
},
handleFocus() {
this.isFocused = true;
@ -71,86 +65,57 @@ Vue.component("autobuyer-input", {
SecretAchievement(28).unlock();
}
if (this.isValid) {
this.setValue(this.actualValue);
this.autobuyer[this.property] = this.typeFunctions.copyValue(this.actualValue);
} else {
this.fetchActualValue();
this.updateActualValue();
}
this.updateDisplayValue();
this.isValid = true;
this.isFocused = false;
},
formatActualValue() {
return this.formatValue(this.getValue());
},
validate(input) {
switch (this.type) {
case AutobuyerInputType.DECIMAL: return this.validateDecimal(input);
case AutobuyerInputType.FLOAT: return this.validateFloat(input);
case AutobuyerInputType.INT: return this.validateInt(input);
}
throw "Unknown input type";
},
validateDecimal(input) {
try {
const decimal = Decimal.fromString(input);
if (isNaN(decimal.mantissa) || isNaN(decimal.exponent)) return false;
this.actualValue = decimal;
} catch (e) {
return false;
}
return true;
},
validateFloat(input) {
const float = parseFloat(input);
if (isNaN(float)) return false;
this.actualValue = float;
return true;
},
validateInt(input) {
const int = parseInt(input, 10);
if (isNaN(int) || !Number.isInteger(int)) return false;
this.actualValue = int;
return true;
},
formatValue(value) {
switch (this.type) {
case AutobuyerInputType.DECIMAL: return shortenAutobuyerInput(value);
case AutobuyerInputType.FLOAT:
case AutobuyerInputType.INT: return value.toString();
}
throw "Unknown input type";
}
},
template:
`<input
:value="displayValue"
:class="classObject"
:class="validityClass"
:type="inputType"
class="o-autobuyer-input"
@blur="handleBlur"
@focus="handleFocus"
@input="handleInput"
/>`
});
class AutobuyerInputSetup {
/**
* @param {AutobuyerInputType} type
* @param {Function} getValue
* @param {Function} setValue
*/
constructor(type, getValue, setValue) {
this.type = type;
if (type === AutobuyerInputType.DECIMAL) {
this.getValue = () => new Decimal(getValue());
this.setValue = value => setValue(new Decimal(value));
} else {
this.getValue = getValue;
this.setValue = setValue;
const AutobuyerInputFunctions = {
decimal: {
areEqual: (value, other) => Decimal.eq(value, other),
formatValue: value => Notation.scientific.format(value, 2, 0),
copyValue: value => new Decimal(value),
tryParse: input => {
try {
const decimal = Decimal.fromString(input.replace(",", ""));
return isNaN(decimal.mantissa) || isNaN(decimal.exponent) ? undefined : decimal;
} catch (e) {
return undefined;
}
}
},
float: {
areEqual: (value, other) => value === other,
formatValue: value => value.toString(),
copyValue: value => value,
tryParse: input => {
const float = parseFloat(input);
return isNaN(float) ? undefined : float;
}
},
int: {
areEqual: (value, other) => value === other,
formatValue: value => value.toString(),
copyValue: value => value,
tryParse: input => {
const int = parseInt(input, 10);
return isNaN(int) || !Number.isInteger(int) ? undefined : int;
}
}
}
const AutobuyerInputType = {
DECIMAL: 1,
FLOAT: 2,
INT: 3,
};

View File

@ -3,32 +3,21 @@
Vue.component("autobuyer-toggles", {
data() {
return {
options: player.options,
hasAdditionalCrunchModes: false,
autoCrunchMode: AutoCrunchMode.AMOUNT,
hasAdditionalEternityModes: false,
autoEternityMode: AutoEternityMode.AMOUNT,
autobuyersOn: false,
bulkOn: false,
isAutoRealityUnlocked: false,
autoRealityMode: AutoRealityMode.RM,
};
},
watch: {
autobuyersOn(newValue) {
player.options.autobuyersOn = newValue;
},
bulkOn(newValue) {
player.options.bulkOn = newValue;
}
},
computed: {
autoCrunchModeDisplay() {
switch (this.autoCrunchMode) {
case AutoCrunchMode.AMOUNT: return "amount";
case AutoCrunchMode.TIME: return "time";
case AutoCrunchMode.RELATIVE: return "X times last crunch";
}
throw "Unknown auto crunch mode";
},
autoEternityModeDisplay() {
switch (this.autoEternityMode) {
case AutoEternityMode.AMOUNT: return "amount";
case AutoEternityMode.TIME: return "time";
case AutoEternityMode.RELATIVE: return "X times last eternity";
}
throw "Unknown auto eternity mode";
},
autoRealityModeDisplay() {
switch (this.autoRealityMode) {
case AutoRealityMode.RM: return "reality machines";
@ -41,40 +30,30 @@ Vue.component("autobuyer-toggles", {
},
methods: {
update() {
this.hasAdditionalCrunchModes = Autobuyer.infinity.hasAdditionalModes;
this.autoCrunchMode = Autobuyer.infinity.mode;
this.hasAdditionalEternityModes = Autobuyer.eternity.hasAdditionalModes;
this.autoEternityMode = Autobuyer.eternity.mode;
this.autobuyersOn = player.options.autobuyersOn;
this.bulkOn = player.options.bulkOn;
this.isAutoRealityUnlocked = Autobuyer.reality.isUnlocked;
this.autoRealityMode = Autobuyer.reality.mode;
}
},
template:
`<div class="l-autobuyer-toggles">
<primary-button
class="o-primary-btn--autobuyer-toggle"
onclick="toggleAutobuyers()"
>Enable/disable autobuyers</primary-button>
<primary-button-on-off-custom
v-model="options.bulkOn"
v-model="autobuyersOn"
on="Disable autobuyers"
off="Enable autobuyers"
class="o-primary-btn--autobuyer-toggle"
/>
<primary-button-on-off-custom
v-model="bulkOn"
on="Disable bulk buy"
off="Enable bulk buy"
class="o-primary-btn--autobuyer-toggle"
/>
<primary-button
v-if="hasAdditionalCrunchModes"
class="o-primary-btn--autobuyer-toggle"
onclick="Autobuyer.infinity.toggleMode();"
>Auto crunch mode: {{autoCrunchModeDisplay}}</primary-button>
<primary-button
v-if="hasAdditionalEternityModes"
class="o-primary-btn--autobuyer-toggle"
onclick="Autobuyer.eternity.toggleMode();"
>Auto eternity mode: {{autoEternityModeDisplay}}</primary-button>
<primary-button
v-if="isAutoRealityUnlocked"
class="o-primary-btn--autobuyer-toggle"
onclick="Autobuyer.reality.toggleMode();"
>Auto reality mode: {{autoRealityModeDisplay}}</primary-button>
</div>`
});
});

View File

@ -15,13 +15,13 @@ Vue.component("autobuyers-tab", {
<big-crunch-autobuyer-box />
</div>
<div class="l-autobuyer-grid__row">
<dim-autobuyer-box v-for="tier in 3" :key="tier" :tier="tier"/>
<dimension-autobuyer-box v-for="column in 3" :key="column" :tier="column"/>
</div>
<div class="l-autobuyer-grid__row">
<dim-autobuyer-box v-for="tier in 3" :key="tier + 3" :tier="tier + 3"/>
<dimension-autobuyer-box v-for="column in 3" :key="column + 3" :tier="column + 3"/>
</div>
<div class="l-autobuyer-grid__row">
<dim-autobuyer-box v-for="tier in 2" :key="tier + 6" :tier="tier + 6"/>
<dimension-autobuyer-box v-for="column in 2" :key="column + 6" :tier="column + 6"/>
<tickspeed-autobuyer-box />
</div>
<div class="l-autobuyer-grid__row">
@ -29,4 +29,4 @@ Vue.component("autobuyers-tab", {
</div>
</div>
</div>`
});
});

View File

@ -4,45 +4,77 @@ Vue.component("big-crunch-autobuyer-box", {
data() {
return {
postBreak: false,
mode: AutoCrunchMode.AMOUNT
mode: AutoCrunchMode.AMOUNT,
hasAdditionalModes: false
};
},
computed: {
autobuyer() {
return Autobuyer.infinity;
},
boxSetup() {
return new AutobuyerBoxSetup("Automatic Big Crunch", this.autobuyer);
},
limitInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.DECIMAL,
() => this.autobuyer.limit,
value => this.autobuyer.limit = value
);
},
modeDisplay() {
switch (this.mode) {
case AutoCrunchMode.AMOUNT: return "Amount of IP to wait until reset";
case AutoCrunchMode.TIME: return "Seconds between crunches";
case AutoCrunchMode.RELATIVE: return "X times last crunch";
}
throw "Unknown auto eternity mode";
}
autobuyer: () => Autobuyer.bigCrunch,
modes: () => [
AutoCrunchMode.AMOUNT,
AutoCrunchMode.TIME,
AutoCrunchMode.X_LAST
]
},
methods: {
update() {
this.postBreak = player.break;
this.mode = this.autobuyer.mode;
this.hasAdditionalModes = this.autobuyer.hasAdditionalModes;
},
modeProps(mode) {
switch (mode) {
case AutoCrunchMode.AMOUNT: return {
title: "Big Crunch at X IP",
input: {
property: "amount",
type: "decimal"
},
};
case AutoCrunchMode.TIME: return {
title: "Seconds between Crunches",
input: {
property: "time",
type: "float"
},
};
case AutoCrunchMode.X_LAST: return {
title: "X times last Crunch",
input: {
property: "xLast",
type: "decimal"
},
};
}
throw crash("Unknown auto crunch mode");
},
changeMode(event) {
const mode = parseInt(event.target.value, 10);
this.autobuyer.mode = mode;
this.mode = mode;
}
},
template:
`<autobuyer-box :setup="boxSetup">
`<autobuyer-box :autobuyer="autobuyer" :showInterval="!postBreak" name="Automatic Big Crunch">
<autobuyer-interval-button slot="beforeInterval" :autobuyer="autobuyer" />
<div v-if="postBreak">
<span>{{modeDisplay}}</span>
<autobuyer-input :setup="limitInputSetup" />
<select
v-if="hasAdditionalModes"
class="c-autobuyer-box__mode-select l-autobuyer-box__mode-select"
@change="changeMode"
>
<option
v-for="optionMode in modes"
:value="optionMode"
:selected="mode === optionMode"
>{{modeProps(optionMode).title}}</option>
</select>
<span v-else>{{modeProps(mode).title}}:</span>
<autobuyer-input
:autobuyer="autobuyer"
:key="mode"
v-bind="modeProps(mode).input"
/>
</div>
<br>
</autobuyer-box>`
});
});

View File

@ -8,36 +8,7 @@ Vue.component("dimboost-autobuyer-box", {
};
},
computed: {
autobuyer() {
return Autobuyer.dimboost;
},
boxSetup() {
return new AutobuyerBoxSetup("Automatic DimBoosts", this.autobuyer);
},
limitInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.INT,
() => this.autobuyer.maxDimBoosts,
value => this.autobuyer.maxDimBoosts = value
);
},
galaxiesInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.INT,
() => this.autobuyer.galaxies,
value => this.autobuyer.galaxies = value
);
},
bulkBuyModeDisplay() {
return this.isBuyMaxUnlocked ? "Buy max DimBoosts every X seconds" : "Bulk DimBoost Amount";
},
bulkInputSetup() {
return new AutobuyerInputSetup(
this.isBuyMaxUnlocked ? AutobuyerInputType.FLOAT : AutobuyerInputType.INT,
() => this.autobuyer.bulk,
value => this.autobuyer.bulk = value
);
},
autobuyer: () => Autobuyer.dimboost
},
methods: {
update() {
@ -47,16 +18,41 @@ Vue.component("dimboost-autobuyer-box", {
}
},
template:
`<autobuyer-box :setup="boxSetup">
<autobuyer-interval-button slot="beforeInterval" :autobuyer="autobuyer" />
<span class="c-autobuyer-box__small-text">Max DimBoosts:</span>
<autobuyer-input :setup="limitInputSetup" />
<span class="c-autobuyer-box__small-text">Galaxies required to always DimBoost:</span>
<autobuyer-input :setup="galaxiesInputSetup" />
<template v-if="isBulkBuyUnlocked">
<span class="c-autobuyer-box__small-text">{{bulkBuyModeDisplay}}:</span>
<autobuyer-input :setup="bulkInputSetup" />
`<autobuyer-box :autobuyer="autobuyer" :showInterval="!isBuyMaxUnlocked" name="Automatic DimBoosts">
<div v-if="isBuyMaxUnlocked">
<span>Buy max every X seconds:</span>
<autobuyer-input
:autobuyer="autobuyer"
type="float"
property="buyMaxInterval"
/>
</div>
<template v-else>
<autobuyer-interval-button slot="beforeInterval" :autobuyer="autobuyer" />
<div>
<span class="c-autobuyer-box__small-text">Limit DimBoosts to:</span>
<autobuyer-input
:autobuyer="autobuyer"
type="int"
property="maxDimBoosts"
/>
</div>
<div>
<span class="c-autobuyer-box__small-text">Galaxies required to always DimBoost:</span>
<autobuyer-input
:autobuyer="autobuyer"
type="int"
property="galaxies"
/>
</div>
<div>
<span v-if="isBulkBuyUnlocked" class="c-autobuyer-box__small-text">Bulk DimBoost Amount:</span>
<autobuyer-input
:autobuyer="autobuyer"
type="int"
property="bulk"
/>
</div>
</template>
<br>
</autobuyer-box>`
});
});

View File

@ -1,6 +1,6 @@
"use strict";
Vue.component("dim-autobuyer-box", {
Vue.component("dimension-autobuyer-box", {
components: {
"bulk-button": {
props: {
@ -26,7 +26,6 @@ Vue.component("dim-autobuyer-box", {
methods: {
update() {
const autobuyer = this.autobuyer;
if (!autobuyer.isUnlocked) return;
this.hasMaxedInterval = autobuyer.hasMaxedInterval;
this.hasMaxedBulk = autobuyer.hasMaxedBulk;
this.bulk = autobuyer.bulk;
@ -60,11 +59,10 @@ Vue.component("dim-autobuyer-box", {
},
computed: {
autobuyer() {
return Autobuyer.dim(this.tier);
return Autobuyer.dimension(this.tier);
},
boxSetup() {
const name = DISPLAY_NAMES[this.tier];
return new AutobuyerBoxSetup(`${name} Dimension Autobuyer`, this.autobuyer);
name() {
return `${DISPLAY_NAMES[this.tier]} Dimension Autobuyer`;
},
modeDisplay() {
switch (this.mode) {
@ -76,7 +74,6 @@ Vue.component("dim-autobuyer-box", {
},
methods: {
update() {
if (!this.autobuyer.isUnlocked) return;
this.mode = this.autobuyer.mode;
},
toggleMode() {
@ -85,13 +82,13 @@ Vue.component("dim-autobuyer-box", {
}
},
template:
`<autobuyer-box :setup="boxSetup">
`<autobuyer-box :autobuyer="autobuyer" :name="name" showInterval>
<template slot="beforeInterval">
<bulk-button :autobuyer="autobuyer" />
<autobuyer-interval-button :autobuyer="autobuyer" />
<button class="o-autobuyer-btn" @click="toggleMode">{{modeDisplay}}</button>
</template>
<autobuyer-priority-selector :autobuyer="autobuyer"/>
<br>
<div class="l-autobuyer-box__fill" />
<autobuyer-priority-selector :autobuyer="autobuyer" class="l-autobuyer-box__priority-selector" />
</autobuyer-box>`
});
});

View File

@ -3,40 +3,75 @@
Vue.component("eternity-autobuyer-box", {
data() {
return {
mode: AutoEternityMode.AMOUNT
mode: AutoEternityMode.AMOUNT,
hasAdditionalModes: false
};
},
computed: {
boxSetup() {
return new AutobuyerBoxSetup("Automatic Eternity", Autobuyer.eternity);
},
limitInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.DECIMAL,
() => Autobuyer.eternity.limit,
value => Autobuyer.eternity.limit = value
);
},
modeDisplay() {
switch (this.mode) {
case AutoEternityMode.AMOUNT: return "Amount of EP to wait until reset";
case AutoEternityMode.TIME: return "Seconds between eternities";
case AutoEternityMode.RELATIVE: return "X times last eternity";
}
throw "Unknown auto eternity mode";
}
autobuyer: () => Autobuyer.eternity,
modes: () => [
AutoEternityMode.AMOUNT,
AutoEternityMode.TIME,
AutoEternityMode.X_LAST
]
},
methods: {
update() {
this.mode = Autobuyer.eternity.mode;
this.mode = this.autobuyer.mode;
this.hasAdditionalModes = this.autobuyer.hasAdditionalModes;
},
modeProps(mode) {
switch (mode) {
case AutoEternityMode.AMOUNT: return {
title: "Eternity at X EP",
input: {
property: "amount",
type: "decimal"
},
};
case AutoEternityMode.TIME: return {
title: "Seconds between eternities",
input: {
property: "time",
type: "float"
},
};
case AutoEternityMode.X_LAST: return {
title: "X times last eternity",
input: {
property: "xLast",
type: "decimal"
},
};
}
throw crash("Unknown auto eternity mode");
},
changeMode(event) {
const mode = parseInt(event.target.value, 10);
this.autobuyer.mode = mode;
this.mode = mode;
}
},
template:
`<autobuyer-box :setup="boxSetup">
`<autobuyer-box :autobuyer="autobuyer" name="Automatic Eternity">
<div>
<span>{{modeDisplay}}:</span>
<autobuyer-input :setup="limitInputSetup" />
<select
v-if="hasAdditionalModes"
class="c-autobuyer-box__mode-select l-autobuyer-box__mode-select"
@change="changeMode"
>
<option
v-for="optionMode in modes"
:value="optionMode"
:selected="mode === optionMode"
>{{modeProps(optionMode).title}}</option>
</select>
<span v-else>{{modeProps(mode).title}}:</span>
<autobuyer-input
:autobuyer="autobuyer"
:key="mode"
v-bind="modeProps(mode).input"
/>
</div>
<br>
</autobuyer-box>`
});
});

View File

@ -3,47 +3,54 @@
Vue.component("galaxy-autobuyer-box", {
data() {
return {
isBuyMaxUnlocked: false
limitGalaxies: false,
isBuyMaxUnlocked: false,
buyMax: false
};
},
watch: {
limitGalaxies(newValue) {
this.autobuyer.limitGalaxies = newValue;
},
buyMax(newValue) {
this.autobuyer.buyMax = newValue;
}
},
computed: {
autobuyer() {
return Autobuyer.galaxy;
},
boxSetup() {
return new AutobuyerBoxSetup("Automatic Galaxies", this.autobuyer);
},
limitInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.INT,
() => this.autobuyer.limit,
value => this.autobuyer.limit = value
);
},
buyMaxIntervalInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.FLOAT,
() => this.autobuyer.buyMaxInterval,
value => this.autobuyer.buyMaxInterval = value
);
},
autobuyer: () => Autobuyer.galaxy
},
methods: {
update() {
this.isBuyMaxUnlocked = this.autobuyer.isBuyMaxUnlocked;
this.limitGalaxies = this.autobuyer.limitGalaxies;
this.buyMax = this.autobuyer.buyMax;
}
},
template:
`<autobuyer-box :setup="boxSetup">
`<autobuyer-box :autobuyer="autobuyer" :showInterval="!buyMax" name="Automatic Galaxies">
<autobuyer-interval-button slot="beforeInterval" :autobuyer="autobuyer" />
<span>Max Galaxies:</span>
<autobuyer-input :setup="limitInputSetup" />
<template v-if="isBuyMaxUnlocked">
<br>
<span>Buy max every X seconds:</span>
<autobuyer-input :setup="buyMaxIntervalInputSetup" />
<span class="c-autobuyer-box__small-text">(0 to buy singles on default interval)</span>
</template>
<br>
<div>
<div class="o-autobuyer-toggle-checkbox" @click="limitGalaxies = !limitGalaxies">
<input type="checkbox" :checked="limitGalaxies"/>
<span>Limit galaxies to:</span>
</div>
<autobuyer-input
:autobuyer="autobuyer"
type="int"
property="maxGalaxies"
/>
</div>
<div v-if="isBuyMaxUnlocked">
<div class="o-autobuyer-toggle-checkbox" @click="buyMax = !buyMax">
<input type="checkbox" :checked="buyMax"/>
<span>Buy max</span>
</div>
<span>Activates every x seconds:</span>
<autobuyer-input
:autobuyer="autobuyer"
type="float"
property="buyMaxInterval"
/>
</div>
</autobuyer-box>`
});
});

View File

@ -2,35 +2,25 @@
Vue.component("reality-autobuyer-box", {
computed: {
boxSetup() {
return new AutobuyerBoxSetup("Automatic Reality", Autobuyer.reality);
},
targetRMInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.DECIMAL,
() => Autobuyer.reality.rm,
value => Autobuyer.reality.rm = value
);
},
targetGlyphInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.INT,
() => Autobuyer.reality.glyph,
value => Autobuyer.reality.glyph = value
);
}
autobuyer: () => Autobuyer.reality
},
template:
`<autobuyer-box :setup="boxSetup">
<br>
`<autobuyer-box :autobuyer="autobuyer" name="Automatic Reality">
<div>
<span>Target reality machines:</span>
<autobuyer-input :setup="targetRMInputSetup" />
<autobuyer-input
:autobuyer="autobuyer"
type="decimal"
property="rm"
/>
</div>
<div>
<span>Target glyph level:</span>
<autobuyer-input :setup="targetGlyphInputSetup" />
<autobuyer-input
:autobuyer="autobuyer"
type="int"
property="glyph"
/>
</div>
<br>
</autobuyer-box>`
});
});

View File

@ -2,26 +2,17 @@
Vue.component("sacrifice-autobuyer-box", {
computed: {
autobuyer() {
return Autobuyer.sacrifice;
},
boxSetup() {
return new AutobuyerBoxSetup("Automatic Sacrifice", this.autobuyer);
},
limitInputSetup() {
return new AutobuyerInputSetup(
AutobuyerInputType.FLOAT,
() => this.autobuyer.limit,
value => this.autobuyer.limit = value
);
}
autobuyer: () => Autobuyer.sacrifice
},
template:
`<autobuyer-box :setup="boxSetup">
`<autobuyer-box :autobuyer="autobuyer" name="Automatic Sacrifice">
<div>
<span>Sacrifice when the multiplier is over:</span>
<autobuyer-input :setup="limitInputSetup" />
<span>Sacrifice at X multiplier:</span>
<autobuyer-input
:autobuyer="autobuyer"
type="float"
property="multiplier"
/>
</div>
<br>
</autobuyer-box>`
});
});

View File

@ -7,12 +7,7 @@ Vue.component("tickspeed-autobuyer-box", {
};
},
computed: {
autobuyer() {
return Autobuyer.tickspeed;
},
boxSetup() {
return new AutobuyerBoxSetup("Tickspeed Autobuyer", this.autobuyer);
},
autobuyer: () => Autobuyer.tickspeed,
modeDisplay() {
switch (this.mode) {
case AutobuyerMode.BUY_SINGLE: return "Buys singles";
@ -23,7 +18,6 @@ Vue.component("tickspeed-autobuyer-box", {
},
methods: {
update() {
if (!this.autobuyer.isUnlocked) return;
this.mode = this.autobuyer.mode;
},
toggleMode() {
@ -32,12 +26,12 @@ Vue.component("tickspeed-autobuyer-box", {
}
},
template:
`<autobuyer-box :setup="boxSetup">
`<autobuyer-box :autobuyer="autobuyer" name="Tickspeed Autobuyer" showInterval>
<template slot="beforeInterval">
<autobuyer-interval-button :autobuyer="autobuyer" />
<button class="o-autobuyer-btn" @click="toggleMode">{{modeDisplay}}</button>
</template>
<autobuyer-priority-selector :autobuyer="autobuyer"/>
<br>
<div class="l-autobuyer-box__fill" />
<autobuyer-priority-selector :autobuyer="autobuyer" class="l-autobuyer-box__priority-selector" />
</autobuyer-box>`
});
});

View File

@ -25,7 +25,7 @@ Vue.component("break-infinity-button", {
methods: {
update() {
this.isBroken = player.break;
this.isUnlocked = Autobuyer.infinity.isUnlocked && Autobuyer.infinity.hasMaxedInterval;
this.isUnlocked = Autobuyer.bigCrunch.hasMaxedInterval;
}
},
template:
@ -34,4 +34,4 @@ Vue.component("break-infinity-button", {
:class="classObject"
onclick="breakInfinity()"
>{{isBroken ? "FIX INFINITY" : "BREAK INFINITY"}}</button>`
});
});

View File

@ -34,7 +34,7 @@ Vue.component("break-infinity-tab", {
},
methods: {
update() {
this.isUnlocked = Autobuyer.infinity.isUnlocked && Autobuyer.infinity.hasMaxedInterval;
this.isUnlocked = Autobuyer.bigCrunch.hasMaxedInterval;
},
btnClassObject(column) {
return {
@ -58,4 +58,4 @@ Vue.component("break-infinity-tab", {
</div>
</div>
</div>`
});
});

View File

@ -61,7 +61,7 @@ class AchievementState extends GameMechanicState {
if (this.isUnlocked) return;
player.achievements.add(this.id);
if (this.id === 85 || this.id === 93) {
Autobuyer.infinity.bumpLimit(4);
Autobuyer.bigCrunch.bumpAmount(4);
}
GameUI.notify.success(this.name);
kong.submitAchievements();

View File

@ -1,863 +0,0 @@
"use strict";
const Autobuyer = function Autobuyer(interval) {
this.target = 1;
this.cost = 1;
this.interval = interval;
this.priority = 1;
this.ticks = 0;
this.isOn = false;
this.bulk = 1;
};
Autobuyer.tickTimer = 0;
Autobuyer.intervalTimer = 0;
Autobuyer.lastDimBoost = 0;
Autobuyer.lastGalaxy = 0;
class AutobuyerState {
constructor(getAutobuyer) {
this._getAutobuyer = getAutobuyer;
}
/**
* @returns {Autobuyer|undefined}
*/
get autobuyer() {
// What
const autobuyer = this._getAutobuyer();
return autobuyer % 1 !== 0 ? autobuyer : undefined;
}
/**
* @returns {boolean}
*/
get isUnlocked() {
return this.autobuyer !== undefined;
}
tryUnlock() {
if (!this.isUnlocked && this.challenge.isCompleted) {
this.initialize();
}
}
/**
* @returns {NormalChallengeState|InfinityChallengeState}
*/
get challenge() {
throw "This method should be overridden in inheriting class";
}
initialize() {
throw "This method should be overridden in inheriting class";
}
/**
* @returns {boolean}
*/
get isOn() {
return this.autobuyer.isOn;
}
/**
* @param {boolean} value
*/
set isOn(value) {
this.autobuyer.isOn = value;
}
/**
* @returns {number}
*/
get cost() {
return this.autobuyer.cost;
}
/**
* @param {number} value
*/
set cost(value) {
this.autobuyer.cost = value;
}
/**
* @returns {number}
*/
get ticks() {
return this.autobuyer.ticks;
}
/**
* @param {number} value
*/
set ticks(value) {
this.autobuyer.ticks = value;
}
/**
* @returns {boolean}
*/
canTick() {
if (!this.isUnlocked) return false;
if (this.ticks * 100 < this.interval) {
this.ticks++;
return false;
}
return this.isOn;
}
resetTicks() {
this.ticks = 1;
}
/**
* @returns {number}
*/
get priority() {
return this.autobuyer.priority;
}
/**
* @param {number} value
*/
set priority(value) {
this.autobuyer.priority = value;
}
/**
* @returns {number}
*/
get interval() {
return this.autobuyer.interval;
}
/**
* @param {number} value
*/
set interval(value) {
this.autobuyer.interval = value;
}
/**
* @returns {boolean}
*/
get hasMaxedInterval() {
return this.isUnlocked && this.interval <= 100;
}
/**
* @returns {number}
*/
get bulk() {
return this.autobuyer.bulk;
}
/**
* @param {number} value
*/
set bulk(value) {
this.autobuyer.bulk = value;
}
/**
* @returns {boolean}
*/
get isActive() {
return this.isUnlocked && this.autobuyer.isOn;
}
toggle() {
this.isOn = !this.isOn;
}
upgradeInterval() {
if (this.hasMaxedInterval) return;
if (player.infinityPoints.lt(this.cost)) return;
player.infinityPoints = player.infinityPoints.minus(this.cost);
this.interval = Math.max(this.interval * 0.6, 100);
if (this.interval > 120) {
// if your last purchase wont be very strong, dont double the cost
this.cost *= 2;
}
Autobuyer.checkIntervalAchievements();
GameUI.update();
}
}
class DimensionAutobuyerState extends AutobuyerState {
constructor(tier) {
super(() => player.autobuyers[tier - 1]);
this._tier = tier;
}
initialize() {
const baseIntervals = [
null,
1500,
2000,
2500,
3000,
4000,
5000,
6000,
7500,
];
player.autobuyers[this._tier - 1] = new Autobuyer(baseIntervals[this._tier]);
}
get challenge() {
return NormalChallenge(this._tier);
}
/**
* @returns {boolean}
*/
get hasMaxedBulk() {
return this.isUnlocked && this.bulk >= 1e100;
}
/**
* @returns {AutobuyerMode}
*/
get mode() {
return this.autobuyer.target;
}
/**
* @param {AutobuyerMode} value
*/
set mode(value) {
this.autobuyer.target = value;
}
toggleMode() {
this.mode = this.mode === AutobuyerMode.BUY_SINGLE ? AutobuyerMode.BUY_10 : AutobuyerMode.BUY_SINGLE;
}
tick() {
if (!this.canTick()) return;
const tier = this._tier;
if (!NormalDimension(tier).isAvailable) return;
if (this.mode === AutobuyerMode.BUY_SINGLE) {
buyOneDimension(tier);
}
else {
const bulk = player.options.bulkOn ? this.bulk : 1;
buyManyDimensionAutobuyer(tier, bulk);
}
this.resetTicks();
}
upgradeBulk() {
if (this.hasMaxedBulk) return;
if (player.infinityPoints.lt(this.cost)) return;
player.infinityPoints = player.infinityPoints.minus(this.cost);
this.bulk = Math.min(this.bulk * 2, 1e100);
this.cost = Math.ceil(2.4 * this.cost);
Autobuyer.checkBulkAchievements();
GameUI.update();
}
}
Autobuyer.dim = tier => new DimensionAutobuyerState(tier);
Autobuyer.allDims = Array.dimensionTiers.map(Autobuyer.dim);
class TickspeedAutobuyerState extends AutobuyerState {
constructor() {
super(() => player.autobuyers[8]);
}
initialize() {
player.autobuyers[8] = new Autobuyer(5000);
}
get challenge() {
return NormalChallenge(9);
}
/**
* @returns {AutobuyerMode}
*/
get mode() {
return this.autobuyer.target;
}
/**
* @param {AutobuyerMode} value
*/
set mode(value) {
this.autobuyer.target = value;
}
toggleMode() {
this.mode = this.mode === AutobuyerMode.BUY_SINGLE ? AutobuyerMode.BUY_MAX : AutobuyerMode.BUY_SINGLE;
}
tick() {
if (!this.canTick()) return;
if (this.mode === AutobuyerMode.BUY_SINGLE) {
buyTickSpeed();
}
else {
buyMaxTickSpeed();
}
this.resetTicks();
}
}
Autobuyer.tickspeed = new TickspeedAutobuyerState();
Autobuyer.priorityQueue = function() {
const autobuyers = Array.range(1, 8).map(tier => Autobuyer.dim(tier));
autobuyers.push(Autobuyer.tickspeed);
return autobuyers
.filter(autobuyer => autobuyer.isUnlocked)
.sort((a, b) => a.priority - b.priority);
};
class DimboostAutobuyerState extends AutobuyerState {
constructor() {
super(() => player.autobuyers[9]);
}
initialize() {
player.autobuyers[9] = new Autobuyer(8000);
}
get challenge() {
return NormalChallenge(10);
}
/**
* @returns {number}
*/
get maxDimBoosts() {
return this.priority;
}
/**
* @param {number} value
*/
set maxDimBoosts(value) {
this.priority = value;
}
/**
* @returns {boolean}
*/
get isBulkBuyUnlocked() {
return BreakInfinityUpgrade.bulkDimBoost.isBought || this.isBuyMaxUnlocked;
}
/**
* @returns {boolean}
*/
get isBuyMaxUnlocked() {
return EternityMilestone.autobuyMaxDimboosts.isReached;
}
/**
* @returns {number}
*/
get galaxies() {
return player.overXGalaxies;
}
/**
* @param {number} value
*/
set galaxies(value) {
player.overXGalaxies = value;
}
/**
* @returns {number}
*/
get buyMaxInterval() {
return this.bulk;
}
/**
* @param {number} value
*/
set buyMaxInterval(value) {
this.bulk = value;
}
tick() {
if (Ra.isRunning) return;
if (!this.canTick()) return;
if (this.isBuyMaxUnlocked) {
if (Autobuyer.intervalTimer - Autobuyer.lastDimBoost >= this.buyMaxInterval) {
Autobuyer.lastDimBoost = Autobuyer.intervalTimer;
maxBuyDimBoosts();
}
return;
}
if (this.maxDimBoosts <= player.resets && this.galaxies > player.galaxies) {
return;
}
if (this.isBulkBuyUnlocked && !DimBoost.isShift) {
var bulk = Math.max(this.bulk, 1);
if (!DimBoost.bulkRequirement(bulk).isSatisfied) return;
softReset(bulk);
}
else {
if (!DimBoost.requirement.isSatisfied) return;
softReset(1);
}
this.resetTicks();
}
}
Autobuyer.dimboost = new DimboostAutobuyerState();
class GalaxyAutobuyerState extends AutobuyerState {
constructor() {
super(() => player.autobuyers[10]);
}
initialize() {
player.autobuyers[10] = new Autobuyer(150000);
}
get challenge() {
return NormalChallenge(11);
}
/**
* @returns {number}
*/
get limit() {
return this.priority;
}
/**
* @param {number} value
*/
set limit(value) {
this.priority = value;
}
/**
* @returns {boolean}
*/
get isBuyMaxUnlocked() {
return EternityMilestone.autobuyMaxGalaxies.isReached;
}
/**
* @returns {number}
*/
get buyMaxInterval() {
return this.bulk;
}
/**
* @param {number} value
*/
set buyMaxInterval(value) {
this.bulk = value;
}
tick() {
if (!this.canTick()) return;
if (!Galaxy.requirement.isSatisfied) return;
if (this.limit <= player.galaxies) return;
if (this.isBuyMaxUnlocked && this.buyMaxInterval > 0) {
this.buyMax();
}
else {
this.buySingle();
this.resetTicks();
}
}
buyMax() {
if (Autobuyer.intervalTimer - Autobuyer.lastGalaxy >= this.buyMaxInterval) {
Autobuyer.lastGalaxy = Autobuyer.intervalTimer;
maxBuyGalaxies();
}
}
buySingle() {
galaxyResetBtnClick();
}
}
Autobuyer.galaxy = new GalaxyAutobuyerState();
class SacrificeAutobuyerState extends AutobuyerState {
constructor() {
super(() => player.autoSacrifice);
}
initialize() {
player.autoSacrifice = new Autobuyer(100);
this.limit = new Decimal(5);
}
get challenge() {
return InfinityChallenge(2);
}
/**
* @returns {Decimal}
*/
get limit() {
return this.autobuyer.priority;
}
/**
* @param {Decimal} value
*/
set limit(value) {
this.autobuyer.priority = value;
}
tick() {
if (!this.canTick()) return;
if (!Sacrifice.nextBoost.gte(this.limit)) return;
sacrificeReset(true);
this.resetTicks();
}
}
Autobuyer.sacrifice = new SacrificeAutobuyerState();
class InfinityAutobuyerState extends AutobuyerState {
constructor() {
super(() => player.autobuyers[11]);
}
initialize() {
player.autobuyers[11] = new Autobuyer(300000);
this.limit = new Decimal(1);
}
get challenge() {
return NormalChallenge(12);
}
/**
* @returns {AutoCrunchMode}
*/
get mode() {
return player.autoCrunchMode;
}
/**
* @param {AutoCrunchMode} value
*/
set mode(value) {
player.autoCrunchMode = value;
}
/**
* @returns {boolean}
*/
get hasAdditionalModes() {
return EternityMilestone.bigCrunchModes.isReached;
}
/**
* @returns {Decimal}
*/
get limit() {
return this.autobuyer.priority;
}
/**
* @param {Decimal} value
*/
set limit(value) {
this.autobuyer.priority = value;
}
bumpLimit(mult) {
if (this.isUnlocked && this.mode === AutoCrunchMode.AMOUNT) {
this.limit = this.limit.times(mult);
}
}
toggleMode() {
this.mode = Object.values(AutoCrunchMode).nextSibling(this.mode);
}
tick() {
if (!this.canTick()) return;
if (!player.antimatter.gte(Decimal.MAX_NUMBER)) return;
let proc = !player.break || NormalChallenge.isRunning || InfinityChallenge.isRunning;
if (!proc) {
switch (this.mode) {
case AutoCrunchMode.AMOUNT:
proc = gainedInfinityPoints().gte(this.limit);
break;
case AutoCrunchMode.TIME:
proc = Decimal.gt(Time.thisInfinityRealTime.totalSeconds, this.limit);
break;
case AutoCrunchMode.RELATIVE:
proc = gainedInfinityPoints().gte(player.lastTenRuns[0][1].times(this.limit));
break;
}
}
if (proc) {
bigCrunchResetRequest();
}
this.resetTicks();
}
}
Autobuyer.infinity = new InfinityAutobuyerState();
/**
* @type {AutobuyerState[]}
*/
Autobuyer.unlockables = Autobuyer.allDims
.concat([
Autobuyer.tickspeed,
Autobuyer.dimboost,
Autobuyer.galaxy,
Autobuyer.sacrifice,
Autobuyer.infinity
]);
Autobuyer.tryUnlockAny = function() {
for (const autobuyer of this.unlockables) {
autobuyer.tryUnlock();
}
};
Autobuyer.resetUnlockables = function() {
player.autobuyers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
Autobuyer.tryUnlockAny();
};
Autobuyer.eternity = {
/**
* @returns {boolean}
*/
get isUnlocked() {
return EternityMilestone.autobuyerEternity.isReached;
},
/**
* @returns {boolean}
*/
get hasAdditionalModes() {
return RealityUpgrade(13).isBought;
},
/**
* @returns {boolean}
*/
get isOn() {
return player.eternityBuyer.isOn;
},
/**
* @param {boolean} value
*/
set isOn(value) {
player.eternityBuyer.isOn = value;
},
toggle() {
this.isOn = !this.isOn;
},
/**
* @returns {boolean}
*/
get isActive() {
return this.isUnlocked && this.isOn;
},
/**
* @returns {Decimal}
*/
get limit() {
return player.eternityBuyer.limit;
},
/**
* @param {Decimal} value
*/
set limit(value) {
player.eternityBuyer.limit = value;
},
bumpLimit(mult) {
if (this.isUnlocked && this.mode === AutoEternityMode.AMOUNT) {
this.limit = this.limit.times(mult);
}
},
/**
* @returns {AutoEternityMode}
*/
get mode() {
return player.autoEternityMode;
},
/**
* @param {AutoEternityMode} value
*/
set mode(value) {
player.autoEternityMode = value;
},
toggleMode() {
this.mode = Object.values(AutoEternityMode).nextSibling(this.mode);
},
tick() {
if (!this.isActive) return;
let proc = false;
switch (this.mode) {
case AutoEternityMode.AMOUNT:
proc = EternityChallenge.isRunning || gainedEternityPoints().gte(this.limit);
break;
case AutoEternityMode.TIME:
proc = Decimal.gt(Time.thisEternityRealTime.totalSeconds, this.limit)
break;
case AutoEternityMode.RELATIVE:
proc = gainedEternityPoints().gte(player.lastTenEternities[0][1].times(this.limit));
break;
}
if (proc) eternity(false, true);
}
};
Autobuyer.reality = {
/**
* @returns {boolean}
*/
get isUnlocked() {
return RealityUpgrade(25).isBought;
},
/**
* @returns {boolean}
*/
get isOn() {
return player.realityBuyer.isOn;
},
/**
* @param {boolean} value
*/
set isOn(value) {
player.realityBuyer.isOn = value;
},
toggle() {
this.isOn = !this.isOn;
},
/**
* @returns {boolean}
*/
get isActive() {
return this.isUnlocked && this.isOn;
},
/**
* @returns {Decimal}
*/
get rm() {
return player.realityBuyer.rm;
},
/**
* @param {Decimal} value
*/
set rm(value) {
player.realityBuyer.rm = value;
},
/**
* @returns {number}
*/
get glyph() {
return player.realityBuyer.glyph;
},
/**
* @param {number} value
*/
set glyph(value) {
player.realityBuyer.glyph = value;
},
/**
* @returns {AutoRealityMode}
*/
get mode() {
return player.autoRealityMode;
},
/**
* @param {AutoRealityMode} value
*/
set mode(value) {
player.autoRealityMode = value;
},
toggleMode() {
this.mode = Object.values(AutoRealityMode).nextSibling(this.mode);
},
tick() {
if (!this.isActive || GlyphSelection.active) return;
let proc = false;
const rmProc = gainedRealityMachines().gte(this.rm);
const glyphProc = gainedGlyphLevel().actualLevel >= this.glyph;
switch (this.mode) {
case AutoRealityMode.RM:
proc = rmProc;
break;
case AutoRealityMode.GLYPH:
proc = glyphProc;
break;
case AutoRealityMode.EITHER:
proc = rmProc || glyphProc;
break;
case AutoRealityMode.BOTH:
proc = rmProc && glyphProc;
break;
}
if (proc) autoReality();
}
};
Autobuyer.tick = function() {
PerformanceStats.start("Autobuyers");
Autobuyer.eternity.tick();
Autobuyer.reality.tick();
Autobuyer.infinity.tick();
Autobuyer.galaxy.tick();
Autobuyer.dimboost.tick();
Autobuyer.sacrifice.tick();
for (let autobuyer of Autobuyer.priorityQueue()) {
autobuyer.tick();
}
PerformanceStats.end();
};
Autobuyer.checkIntervalAchievements = function() {
Achievement(52).tryUnlock();
Achievement(53).tryUnlock();
};
Autobuyer.checkBulkAchievements = function() {
Achievement(61).tryUnlock();
SecretAchievement(38).tryUnlock();
};
Autobuyer.convertPropertiesToDecimal = function() {
if (
player.autobuyers[11] % 1 !== 0 &&
player.autobuyers[11].priority !== undefined &&
player.autobuyers[11].priority !== null &&
player.autobuyers[11].priority !== "undefined"
) {
player.autobuyers[11].priority = new Decimal(player.autobuyers[11].priority);
}
}
function toggleAutobuyers() {
const isOn = Autobuyer.dim(1).isOn;
const autobuyers = Autobuyer.allDims
.concat([
Autobuyer.tickspeed,
Autobuyer.dimboost,
Autobuyer.galaxy,
Autobuyer.sacrifice,
Autobuyer.infinity,
Autobuyer.eternity,
Autobuyer.reality
])
.filter(autobuyer => autobuyer.isUnlocked);
for (let autobuyer of autobuyers) {
autobuyer.isOn = !isOn;
}
}

View File

@ -0,0 +1,97 @@
"use strict";
/**
* @abstract
*/
class AutobuyerState {
/**
* @abstract
*/
get data() { throw NotImplementedCrash(); }
/**
* @abstract
*/
get isUnlocked() { throw NotImplementedCrash(); }
get canTick() {
return this.isActive && player.options.autobuyersOn && this.isUnlocked;
}
get isActive() {
return this.data.isActive;
}
set isActive(value) {
this.data.isActive = value;
}
toggle() {
this.isActive = !this.isActive;
}
/**
* @abstract
*/
tick() { throw NotImplementedCrash(); }
// eslint-disable-next-line no-empty-function
reset() { }
}
/**
* @abstract
*/
class IntervaledAutobuyerState extends AutobuyerState {
/**
* @abstract
*/
get baseInterval() { throw NotImplementedCrash(); }
get cost() {
return this.data.cost;
}
get interval() {
const interval = this.data.interval;
return BreakInfinityUpgrade.autobuyerSpeed.isBought ? interval / 2 : interval;
}
get hasMaxedInterval() {
return this.data.interval <= 100;
}
get canTick() {
return super.canTick && this.timeSinceLastTick >= this.interval;
}
get timeSinceLastTick() {
return player.realTimePlayed - this.data.lastTick;
}
tick() {
this.data.lastTick = player.realTimePlayed;
}
upgradeInterval() {
if (this.hasMaxedInterval) return;
if (Currency.infinityPoints.isAffordable(this.cost)) return;
Currency.infinityPoints.subtract(this.cost);
this.data.interval = Math.clampMin(this.data.interval * 0.6, 100);
if (this.data.interval > 120) {
// If your last purchase wont be very strong, dont double the cost
this.data.cost *= 2;
}
Achievement(52).tryUnlock();
Achievement(53).tryUnlock();
GameUI.update();
}
reset() {
if (EternityMilestone.keepAutobuyers.isReached) return;
this.data.interval = this.baseInterval;
this.data.cost = 1;
}
}
const Autobuyer = {};

View File

@ -0,0 +1,70 @@
"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
]);
return {
all,
dimensions,
intervaled: dimensions
.concat([
Autobuyer.tickspeed,
Autobuyer.dimboost,
Autobuyer.galaxy,
Autobuyer.sacrifice,
Autobuyer.bigCrunch
]),
get unlocked() {
return Autobuyers.all.filter(a => a.isUnlocked);
},
toggle() {
player.options.autobuyersOn = !player.options.autobuyersOn;
},
tick() {
PerformanceStats.start("Autobuyers");
const priorityQueue = [Autobuyer.tickspeed]
.concat(dimensions)
.sort((a, b) => a.priority - b.priority);
const autobuyers = [
Autobuyer.reality,
Autobuyer.eternity,
Autobuyer.bigCrunch,
Autobuyer.galaxy,
Autobuyer.dimboost,
Autobuyer.sacrifice
]
.concat(priorityQueue)
.filter(a => a.canTick);
for (const autobuyer of autobuyers) {
autobuyer.tick();
}
PerformanceStats.end();
},
reset() {
for (const autobuyer of Autobuyers.all) {
autobuyer.reset();
}
}
};
}());
EventHub.logic.on(GameEvent.ETERNITY_RESET_AFTER, () => Autobuyers.reset());
EventHub.logic.on(GameEvent.REALITY_RESET_AFTER, () => Autobuyers.reset());

View File

@ -0,0 +1,85 @@
"use strict";
Autobuyer.bigCrunch = new class BigCrunchAutobuyerState extends IntervaledAutobuyerState {
get data() {
return player.auto.bigCrunch;
}
get isUnlocked() {
return NormalChallenge(12).isCompleted;
}
get baseInterval() {
return Player.defaultStart.auto.bigCrunch.interval;
}
get mode() {
return this.data.mode;
}
set mode(value) {
this.data.mode = value;
}
get hasAdditionalModes() {
return EternityMilestone.bigCrunchModes.isReached;
}
get amount() {
return this.data.amount;
}
set amount(value) {
this.data.amount = value;
}
get time() {
return this.data.time;
}
set time(value) {
this.data.time = value;
}
get xLast() {
return this.data.xLast;
}
set xLast(value) {
this.data.xLast = value;
}
bumpAmount(mult) {
if (this.isUnlocked) {
this.amount = this.amount.times(mult);
}
}
tick() {
super.tick();
if (!player.antimatter.gte(Decimal.MAX_NUMBER)) return;
let proc = !player.break || NormalChallenge.isRunning || InfinityChallenge.isRunning;
if (!proc) {
switch (this.mode) {
case AutoCrunchMode.AMOUNT:
proc = gainedInfinityPoints().gte(this.amount);
break;
case AutoCrunchMode.TIME:
proc = Time.thisInfinityRealTime.totalSeconds > this.time;
break;
case AutoCrunchMode.X_LAST:
proc = gainedInfinityPoints().gte(player.lastTenRuns[0][1].times(this.xLast));
break;
}
}
if (proc) {
bigCrunchResetRequest();
}
}
reset() {
super.reset();
if (EternityMilestone.bigCrunchModes.isReached) return;
this.mode = AutoCrunchMode.AMOUNT;
}
}();

View File

@ -0,0 +1,84 @@
"use strict";
Autobuyer.dimboost = new class DimBoostAutobuyerState extends IntervaledAutobuyerState {
get data() {
return player.auto.dimBoost;
}
get isUnlocked() {
return NormalChallenge(10).isCompleted;
}
get baseInterval() {
return Player.defaultStart.auto.dimBoost.interval;
}
get maxDimBoosts() {
return this.data.maxDimBoosts;
}
set maxDimBoosts(value) {
this.data.maxDimBoosts = value;
}
get galaxies() {
return this.data.galaxies;
}
set galaxies(value) {
this.data.galaxies = value;
}
get bulk() {
return this.data.bulk;
}
set bulk(value) {
this.data.bulk = value;
}
get isBulkBuyUnlocked() {
return BreakInfinityUpgrade.bulkDimBoost.isBought;
}
get buyMaxInterval() {
return this.data.buyMaxInterval;
}
set buyMaxInterval(value) {
this.data.buyMaxInterval = value;
}
get isBuyMaxUnlocked() {
return EternityMilestone.autobuyMaxDimboosts.isReached;
}
get interval() {
return this.isBuyMaxUnlocked
? TimeSpan.fromSeconds(this.buyMaxInterval).totalMilliseconds
: super.interval;
}
get canTick() {
return !Ra.isRunning && super.canTick;
}
tick() {
super.tick();
if (this.isBuyMaxUnlocked) {
maxBuyDimBoosts();
return;
}
if (player.resets >= this.maxDimBoosts && player.galaxies < this.galaxies) {
return;
}
if (this.isBulkBuyUnlocked && !DimBoost.isShift) {
const bulk = Math.clampMin(this.bulk, 1);
if (!DimBoost.bulkRequirement(bulk).isSatisfied) return;
softReset(bulk);
return;
}
if (!DimBoost.requirement.isSatisfied) return;
softReset(1);
}
}();

View File

@ -0,0 +1,88 @@
"use strict";
class DimensionAutobuyerState extends IntervaledAutobuyerState {
constructor(tier) {
super();
this._tier = tier;
}
get data() {
return player.auto.dimensions[this._tier - 1];
}
get baseInterval() {
return Player.defaultStart.auto.dimensions[this._tier - 1].interval;
}
get isUnlocked() {
return NormalChallenge(this._tier).isCompleted;
}
get bulk() {
return this.data.bulk;
}
get hasMaxedBulk() {
return this.bulk >= 1e100;
}
get priority() {
return this.data.priority;
}
set priority(value) {
this.data.priority = value;
}
get mode() {
return this.data.mode;
}
set mode(value) {
this.data.mode = value;
}
toggleMode() {
this.mode = [
AutobuyerMode.BUY_SINGLE,
AutobuyerMode.BUY_10
]
.nextSibling(this.mode);
}
tick() {
super.tick();
const tier = this._tier;
if (!NormalDimension(tier).isAvailable) return;
switch (this.mode) {
case AutobuyerMode.BUY_SINGLE:
buyOneDimension(tier);
break;
case AutobuyerMode.BUY_10:
buyManyDimensionAutobuyer(tier, player.options.bulkOn ? this.bulk : 1);
break;
}
}
upgradeBulk() {
if (this.hasMaxedBulk) return;
if (Currency.infinityPoints.isAffordable(this.cost)) return;
Currency.infinityPoints.subtract(this.cost);
this.data.bulk = Math.clampMax(this.bulk * 2, 1e100);
this.data.cost = Math.ceil(2.4 * this.cost);
Achievement(61).tryUnlock();
SecretAchievement(38).tryUnlock();
GameUI.update();
}
reset() {
super.reset();
if (EternityMilestone.keepAutobuyers.isReached) return;
this.data.isUnlocked = false;
this.data.bulk = 1;
}
}
DimensionAutobuyerState.index = Array.range(1, 8).map(tier => new DimensionAutobuyerState(tier));
Autobuyer.dimension = tier => DimensionAutobuyerState.index[tier - 1];

View File

@ -0,0 +1,75 @@
"use strict";
Autobuyer.eternity = new class EternityAutobuyerState extends AutobuyerState {
get data() {
return player.auto.eternity;
}
get isUnlocked() {
return EternityMilestone.autobuyerEternity.isReached;
}
get mode() {
return this.data.mode;
}
set mode(value) {
this.data.mode = value;
}
get amount() {
return this.data.amount;
}
set amount(value) {
this.data.amount = value;
}
get time() {
return this.data.time;
}
set time(value) {
this.data.time = value;
}
get xLast() {
return this.data.xLast;
}
set xLast(value) {
this.data.xLast = value;
}
get hasAdditionalModes() {
return RealityUpgrade(13).isBought;
}
bumpAmount(mult) {
if (this.isUnlocked) {
this.amount = this.amount.times(mult);
}
}
tick() {
let proc = false;
switch (this.mode) {
case AutoEternityMode.AMOUNT:
proc = EternityChallenge.isRunning || gainedEternityPoints().gte(this.amount);
break;
case AutoEternityMode.TIME:
proc = Time.thisEternityRealTime.totalSeconds > this.time;
break;
case AutoEternityMode.X_LAST:
proc = gainedEternityPoints().gte(player.lastTenEternities[0][1].times(this.xLast));
break;
}
if (proc) eternity(false, true);
}
reset() {
if (!RealityUpgrade(10).isBought) {
this.isActive = false;
}
}
}();

View File

@ -0,0 +1,72 @@
"use strict";
Autobuyer.galaxy = new class GalaxyAutobuyerState extends IntervaledAutobuyerState {
get data() {
return player.auto.galaxy;
}
get isUnlocked() {
return NormalChallenge(11).isCompleted;
}
get baseInterval() {
return Player.defaultStart.auto.galaxy.interval;
}
get limitGalaxies() {
return this.data.limitGalaxies;
}
set limitGalaxies(value) {
this.data.limitGalaxies = value;
}
get maxGalaxies() {
return this.data.maxGalaxies;
}
set maxGalaxies(value) {
this.data.maxGalaxies = value;
}
get buyMax() {
return this.data.buyMax;
}
set buyMax(value) {
this.data.buyMax = value;
}
get buyMaxInterval() {
return this.data.buyMaxInterval;
}
set buyMaxInterval(value) {
this.data.buyMaxInterval = value;
}
get isBuyMaxUnlocked() {
return EternityMilestone.autobuyMaxGalaxies.isReached;
}
get isBuyMaxActive() {
return this.isBuyMaxUnlocked && this.buyMax;
}
get interval() {
return this.isBuyMaxActive
? TimeSpan.fromSeconds(this.buyMaxInterval).totalMilliseconds
: super.interval;
}
tick() {
super.tick();
if (!Galaxy.requirement.isSatisfied) return;
if (this.limitGalaxies && player.galaxies >= this.maxGalaxies) return;
if (this.isBuyMaxActive) {
maxBuyGalaxies();
return;
}
galaxyResetBtnClick();
}
}();

View File

@ -0,0 +1,76 @@
"use strict";
Autobuyer.reality = new class RealityAutobuyerState extends AutobuyerState {
get data() {
return player.auto.reality;
}
get isUnlocked() {
return RealityUpgrade(25).isBought;
}
get canTick() {
return super.canTick && !GlyphSelection.active;
}
get mode() {
return this.data.mode;
}
set mode(value) {
this.data.mode = value;
}
get rm() {
return this.data.rm;
}
set rm(value) {
this.data.rm = value;
}
get glyph() {
return this.data.glyph;
}
set glyph(value) {
this.data.glyph = value;
}
toggleMode() {
this.mode = [
AutoRealityMode.RM,
AutoRealityMode.GLYPH,
AutoRealityMode.EITHER,
AutoRealityMode.BOTH
]
.nextSibling(this.mode);
}
bumpAmount(mult) {
if (this.isUnlocked) {
this.rm = this.rm.times(mult);
}
}
tick() {
let proc = false;
const rmProc = gainedRealityMachines().gte(this.rm);
const glyphProc = gainedGlyphLevel().actualLevel >= this.glyph;
switch (this.mode) {
case AutoRealityMode.RM:
proc = rmProc;
break;
case AutoRealityMode.GLYPH:
proc = glyphProc;
break;
case AutoRealityMode.EITHER:
proc = rmProc || glyphProc;
break;
case AutoRealityMode.BOTH:
proc = rmProc && glyphProc;
break;
}
if (proc) autoReality();
}
}();

View File

@ -0,0 +1,24 @@
"use strict";
Autobuyer.sacrifice = new class SacrificeAutobuyerState extends AutobuyerState {
get data() {
return player.auto.sacrifice;
}
get isUnlocked() {
return EternityMilestone.autoIC.isReached || InfinityChallenge(2).isCompleted;
}
get multiplier() {
return this.data.multiplier;
}
set multiplier(value) {
this.data.multiplier = value;
}
tick() {
if (Sacrifice.nextBoost.lt(this.multiplier)) return;
sacrificeReset(true);
}
}();

View File

@ -0,0 +1,57 @@
"use strict";
Autobuyer.tickspeed = new class TickspeedAutobuyerState extends IntervaledAutobuyerState {
get data() {
return player.auto.tickspeed;
}
get isUnlocked() {
return NormalChallenge(9).isCompleted;
}
get baseInterval() {
return Player.defaultStart.auto.tickspeed.interval;
}
get priority() {
return this.data.priority;
}
set priority(value) {
this.data.priority = value;
}
get mode() {
return this.data.mode;
}
set mode(value) {
this.data.mode = value;
}
toggleMode() {
this.mode = [
AutobuyerMode.BUY_SINGLE,
AutobuyerMode.BUY_MAX
]
.nextSibling(this.mode);
}
tick() {
super.tick();
switch (this.mode) {
case AutobuyerMode.BUY_SINGLE:
buyTickSpeed();
break;
case AutobuyerMode.BUY_MAX:
buyMaxTickSpeed();
break;
}
}
reset() {
super.reset();
if (EternityMilestone.keepAutobuyers.isReached) return;
this.data.isUnlocked = false;
}
}();

View File

@ -127,9 +127,9 @@ const AutomatorLexer = (() => {
// eternity will be triggered by something waiting for reality, for example.
createInCategory(PrestigeEvent, "Infinity", /infinity/i, {
extraCategories: [StudyPath],
$autobuyer: Autobuyer.infinity,
$autobuyer: Autobuyer.bigCrunch,
$autobuyerDurationMode: AutoCrunchMode.TIME,
$autobuyerXLastMode: AutoCrunchMode.RELATIVE,
$autobuyerXLastMode: AutoCrunchMode.X_LAST,
$autobuyerCurrencyMode: AutoCrunchMode.AMOUNT,
$prestigeAvailable: () => canCrunch(),
$prestige: () => bigCrunchResetRequest(true),
@ -140,7 +140,7 @@ const AutomatorLexer = (() => {
createInCategory(PrestigeEvent, "Eternity", /eternity/i, {
$autobuyer: Autobuyer.eternity,
$autobuyerDurationMode: AutoEternityMode.TIME,
$autobuyerXLastMode: AutoEternityMode.RELATIVE,
$autobuyerXLastMode: AutoEternityMode.X_LAST,
$autobuyerCurrencyMode: AutoEternityMode.AMOUNT,
$prestigeAvailable: () => canEternity(),
$prestigeLevel: 2,

View File

@ -21,10 +21,7 @@ function handleChallengeCompletion() {
}
const challenge = NormalChallenge.current || InfinityChallenge.current;
if (!challenge) return;
if (!challenge.isCompleted) {
challenge.complete();
Autobuyer.tryUnlockAny();
}
challenge.complete();
challenge.updateChallengeTime();
if (NormalChallenge(9).isRunning) {
kong.submitStats("NormalChallenge 9 time record (ms)", Math.floor(player.thisInfinityTime));
@ -296,7 +293,9 @@ class InfinityIPMultUpgrade extends GameMechanicState {
const costIncrease = this.costIncrease;
const mult = Decimal.pow(2, amount);
player.infMult = player.infMult.times(mult);
Autobuyer.infinity.bumpLimit(mult);
if (!TimeStudy(181).isBought) {
Autobuyer.bigCrunch.bumpAmount(mult);
}
player.infMultCost = this.cost.times(Decimal.pow(costIncrease, amount));
player.infinityPoints = player.infinityPoints.minus(this.cost.dividedBy(costIncrease));
this.adjustToCap();

View File

@ -89,6 +89,7 @@ const Teresa = {
if (player.reality.pp < cost) return false;
player.celestials.teresa.rmMult *= 2;
player.reality.pp -= cost;
Autobuyer.reality.bumpAmount(2);
return true;
},
buyDtBulk() {

View File

@ -19,7 +19,6 @@ function tryUnlockInfinityChallenges() {
++player.postChallUnlocked;
if (player.eternities > 6) {
InfinityChallenge(player.postChallUnlocked).complete();
Autobuyer.tryUnlockAny();
}
}
}
@ -87,7 +86,6 @@ class NormalChallengeState extends GameMechanicState {
complete() {
// eslint-disable-next-line no-bitwise
player.challenge.normal.completedBits |= 1 << this.id;
Autobuyer.tryUnlockAny();
}
get goal() {

View File

@ -1,6 +1,5 @@
"use strict";
const DIMENSION_COUNT = 8;
const DISPLAY_NAMES = [null, "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth"];
const SHORT_DISPLAY_NAMES = [null, "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th"];
@ -11,22 +10,22 @@ const AutobuyerMode = {
};
const AutoCrunchMode = {
AMOUNT: "amount",
TIME: "time",
RELATIVE: "relative"
AMOUNT: 0,
TIME: 1,
X_LAST: 2
};
const AutoEternityMode = {
AMOUNT: "amount",
TIME: "time",
RELATIVE: "relative"
AMOUNT: 0,
TIME: 1,
X_LAST: 2
};
const AutoRealityMode = {
RM: "rm",
GLYPH: "glyph",
EITHER: "either",
BOTH: "both"
RM: 1,
GLYPH: 2,
EITHER: 3,
BOTH: 4
};
// Free tickspeed multiplier with TS171. Shared here because formatting glyph effects depends on it

View File

@ -84,15 +84,8 @@ dev.cancerize = function() {
dev.fixSave = function() {
const save = JSON.stringify(player, GameSaveSerializer.jsonConverter);
const fixed = save.replace(/NaN/gui, "10");
const stillToDo = JSON.parse(fixed);
for (let i = 0; i < stillToDo.autobuyers.length; i++) {
stillToDo.autobuyers[i].isOn = false;
}
console.log(stillToDo);
const saveData = stillToDo;
const saveData = JSON.parse(fixed);
if (!saveData || !GameStorage.verifyPlayerObject(saveData)) {
alert("Could not fix the save..");
return;
@ -410,4 +403,4 @@ dev.kongTest = function() {
page.style.height = "";
page.style.marginTop = "";
}
};
};

View File

@ -141,7 +141,7 @@ function maxBuyDimBoosts(manual) {
return;
}
let availableBoosts = Number.MAX_VALUE;
if (player.overXGalaxies > player.galaxies && !manual) {
if (Autobuyer.dimboost.galaxies > player.galaxies && !manual) {
availableBoosts = Autobuyer.dimboost.maxDimBoosts - player.resets;
}
if (availableBoosts <= 0) return;

View File

@ -24,7 +24,6 @@ function eternity(force, auto, specialConditions = {}) {
player.eternities += Effects.product(RealityUpgrade(3));
}
if (player.eternities < 20 && Autobuyer.dimboost.isUnlocked) Autobuyer.dimboost.buyMaxInterval = 1;
if (EternityChallenge.isRunning) {
const challenge = EternityChallenge.current;
challenge.addCompletion();
@ -49,8 +48,8 @@ function eternity(force, auto, specialConditions = {}) {
initializeChallengeCompletions();
initializeResourcesAfterEternity();
if (player.eternities < 2) {
Autobuyer.resetUnlockables();
if (!EternityMilestone.keepAutobuyers.isReached) {
// Fix infinity because it can only break after big crunch autobuyer interval is maxed
player.break = false;
}
@ -144,9 +143,6 @@ function initializeResourcesAfterEternity() {
player.onlyFirstDimensions = true;
player.noEighthDimensions = true;
player.postChallUnlocked = Achievement(133).isEnabled ? 8 : 0;
if (player.eternities < 7 && !Achievement(133).isEnabled) {
player.autoSacrifice = 1;
}
}
function applyRealityUpgrades() {
@ -285,7 +281,7 @@ class EPMultiplierState extends GameMechanicState {
player.epmultUpgrades = value;
this.cachedCost.invalidate();
this.cachedEffectValue.invalidate();
Autobuyer.eternity.bumpLimit(Decimal.pow(5, diff));
Autobuyer.eternity.bumpAmount(Decimal.pow(5, diff));
}
get effectValue() {

View File

@ -14,7 +14,6 @@ function startEternityChallenge() {
IPminpeak = new Decimal(0);
EPminpeak = new Decimal(0);
resetTimeDimensions();
if (player.eternities < 20) Autobuyer.dimboost.buyMaxInterval = 1;
kong.submitStats("Eternities", player.eternities);
resetTickspeed();
resetAntimatter();

View File

@ -20,10 +20,6 @@ function shortenMultiplier(money) {
return shorten(money, 1, 1);
}
function shortenAutobuyerInput(value) {
return Notation.scientific.format(value, 2, 0);
}
function shorten(value, places, placesUnder1000) {
return Notation.current.format(value, places, placesUnder1000);
}

View File

@ -156,7 +156,7 @@ function galaxyResetBtnClick() {
}
function maxBuyGalaxies(manual) {
const limit = manual ? Number.MAX_VALUE : Autobuyer.galaxy.limit;
const limit = !manual && Autobuyer.galaxy.limitGalaxies ? Autobuyer.galaxy.maxGalaxies : Number.MAX_VALUE;
if (player.galaxies >= limit || !Galaxy.canBeBought) return false;
// Check for ability to buy one galaxy (which is pretty efficient)
const req = Galaxy.requirement;

View File

@ -27,7 +27,7 @@ GameKeyboard.bindRepeatableHotkey("e", () => eternity());
for (let i = 1; i < 9; i++) bindDimensionHotkeys(i);
}());
GameKeyboard.bindHotkey("a", () => toggleAutobuyers());
GameKeyboard.bindHotkey("a", () => Autobuyers.toggle());
GameKeyboard.bindHotkey("b", () => BlackHoles.togglePause());
GameKeyboard.bindHotkey("u", () => automatorOnOff());

View File

@ -84,4 +84,4 @@ const PerformanceStats = {
render(this.stats);
this.container.innerHTML = text;
}
};
};

View File

@ -53,6 +53,74 @@ let player = {
infinity: {
upgradeBits: 0
},
auto: {
dimensions: Array.range(0, 8).map(tier => ({
isUnlocked: false,
cost: 1,
interval: [1500, 2000, 2500, 3000, 4000, 5000, 6000, 7500][tier],
bulk: 1,
mode: AutobuyerMode.BUY_10,
priority: 1,
isActive: false,
lastTick: 0
})),
tickspeed: {
isUnlocked: false,
cost: 1,
interval: 2500,
mode: AutobuyerMode.BUY_SINGLE,
priority: 1,
isActive: false,
lastTick: 0
},
dimBoost: {
cost: 1,
interval: 8000,
maxDimBoosts: 1,
galaxies: 10,
bulk: 1,
buyMaxInterval: 0,
isActive: false,
lastTick: 0
},
galaxy: {
cost: 1,
interval: 75000,
limitGalaxies: true,
maxGalaxies: 1,
buyMax: false,
buyMaxInterval: 0,
isActive: false,
lastTick: 0
},
bigCrunch: {
cost: 1,
interval: 150000,
mode: 0,
amount: new Decimal(1),
time: 1,
xLast: new Decimal(1),
isActive: false,
lastTick: 0
},
sacrifice: {
multiplier: 5,
isActive: false
},
eternity: {
mode: 0,
amount: new Decimal(1),
time: 1,
xLast: new Decimal(1),
isActive: false
},
reality: {
mode: 0,
rm: new Decimal(1),
glyph: 0,
isActive: false
}
},
infinityPoints: new Decimal(0),
infinitied: new Decimal(0),
infinitiedBank: new Decimal(0),
@ -72,7 +140,6 @@ let player = {
// TODO: Not used, remove
interval: null,
lastUpdate: new Date().getTime(),
autobuyers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
tickspeedMultiplier: new Decimal(10),
chall2Pow: 1,
chall3Pow: new Decimal(0.01),
@ -93,7 +160,6 @@ let player = {
lastTenRealities: Array.range(0, 10).map(() => [defaultMaxTime, new Decimal(1), defaultMaxTime, 0]),
infMult: new Decimal(1),
infMultCost: new Decimal(10),
overXGalaxies: 10,
version: 13,
infinityPower: new Decimal(1),
spreadingCancer: 0,
@ -113,7 +179,6 @@ let player = {
totalTickBought: 0,
offlineProd: 0,
offlineProdCost: 1e7,
autoSacrifice: 1,
replicanti: {
amount: new Decimal(0),
unl: false,
@ -141,14 +206,7 @@ let player = {
eternityChalls: {},
etercreq: 0,
infMultBuyer: false,
autoCrunchMode: AutoCrunchMode.AMOUNT,
autoEternityMode: AutoEternityMode.AMOUNT,
autoRealityMode: AutoRealityMode.RM,
respec: false,
eternityBuyer: {
limit: new Decimal(0),
isOn: false
},
eterc8ids: 50,
eterc8repl: 40,
noSacrifices: true,
@ -176,11 +234,6 @@ let player = {
thisReality: 0,
thisRealityRealTime: 0,
bestReality: 999999999999,
realityBuyer: {
rm: new Decimal(0),
glyph: 0,
isOn: false
},
reality: {
realityMachines: new Decimal(0),
glyphs: {
@ -363,6 +416,7 @@ let player = {
retryChallenge: false,
showAllChallenges: false,
bulkOn: true,
autobuyersOn: true,
cloud: true,
hotkeys: true,
theme: "Normal",
@ -470,8 +524,8 @@ function guardFromNaNValues(obj) {
for (let key in obj) {
if (!obj.hasOwnProperty(key)) continue;
//TODO: rework autobuyer saving
if (key === "autobuyers" || key === "autoSacrifice" || key === "automator") continue;
// TODO: rework autobuyer saving
if (key === "automator") continue;
let value = obj[key];
if (isObject(value)) {

View File

@ -281,9 +281,6 @@ function completeReality(force, reset, auto = false) {
player.galaxies = isRUPG10Bought ? 1 : 0;
player.tickDecrease = 0.9;
player.interval = null;
if (!isRUPG10Bought) {
Autobuyer.resetUnlockables();
}
player.partInfinityPoint = 0;
player.partInfinitied = 0;
player.break = isRUPG10Bought ? player.break : false;
@ -316,18 +313,12 @@ function completeReality(force, reset, auto = false) {
player.totalTickGained = 0;
player.offlineProd = isRUPG10Bought ? player.offlineProd : 0;
player.offlineProdCost = isRUPG10Bought ? player.offlineProdCost : 1e7;
if (!isRUPG10Bought) {
player.autoSacrifice = 1;
}
player.eternityChalls = {};
player.reality.lastAutoEC = 0;
player.challenge.eternity.current = 0;
player.challenge.eternity.unlocked = 0;
player.etercreq = 0;
player.infMultBuyer = isRUPG10Bought ? player.infMultBuyer : false;
if (!isRUPG10Bought) {
player.autoCrunchMode = AutoCrunchMode.AMOUNT;
}
player.respec = false;
player.eterc8ids = 50;
player.eterc8repl = 40;
@ -346,9 +337,6 @@ function completeReality(force, reset, auto = false) {
player.timestudy.epcost = new Decimal(1);
player.timestudy.studies = [];
player.celestials.v.additionalStudies = 0;
if (!RealityUpgrade(10).isBought) {
player.eternityBuyer.isOn = false;
}
player.dilation.studies = [];
player.dilation.active = false;
player.dilation.tachyonParticles = new Decimal(0);
@ -389,7 +377,6 @@ function completeReality(force, reset, auto = false) {
if (player.infinitied.gt(0) && !NormalChallenge(1).isCompleted) {
NormalChallenge(1).complete();
}
Autobuyer.tryUnlockAny()
if (player.realities === 4) player.reality.automatorCommands = new Set([12, 24, 25]);
player.reality.upgReqChecks = [true];
InfinityDimensions.resetAmount();

View File

@ -246,15 +246,15 @@ GameDatabase.achievements.normal = [
id: 52,
name: "Age of Automation",
tooltip: "Max any 9 autobuyers.",
checkRequirement: () => Autobuyer.unlockables
.countWhere(a => a.hasMaxedInterval) >= 9
checkRequirement: () => Autobuyer.intervaled
.countWhere(a => a.hasMaxedInterval) === 9
},
{
id: 53,
name: "Definitely not worth it",
tooltip: "Max all the autobuyers.",
checkRequirement: () => Autobuyer.unlockables
.countWhere(a => a.hasMaxedInterval) >= 12
checkRequirement: () => Autobuyer.intervaled
.countWhere(a => !a.hasMaxedInterval) === 0
},
{
id: 54,
@ -306,8 +306,7 @@ GameDatabase.achievements.normal = [
id: 61,
name: "Bulked up",
tooltip: "Get all of your Dimension bulk buyers to 512 or higher.",
checkRequirement: () => Autobuyer.allDims
.countWhere(a => a.isUnlocked && a.bulk >= 512) === DIMENSION_COUNT
checkRequirement: () => Autobuyers.dimensions.countWhere(a => !a.isUnlocked || a.bulk < 512) === 0
},
{
id: 62,

View File

@ -138,8 +138,7 @@ GameDatabase.achievements.secret = [
id: 38,
name: "Professional bodybuilder",
tooltip: "Get all your dimension bulk buyers to 1e100.",
checkRequirement: () => Autobuyer.allDims
.countWhere(a => a.hasMaxedBulk) === DIMENSION_COUNT
checkRequirement: () => Autobuyers.dimensions.countWhere(a => !a.hasMaxedBulk) === 0
},
{
id: 41,

View File

@ -142,8 +142,8 @@ GameStorage.devMigrations = {
player.reality.epmultbuyer = false;
},
player => {
if (!Object.values(AutoRealityMode).includes(player.autoRealityMode)) {
player.autoRealityMode = AutoRealityMode.RM;
if (!["rm", "glyph", "either", "both"].includes(player.autoRealityMode)) {
player.autoRealityMode = "rm";
}
},
GameStorage.migrations.convertAutobuyerMode,
@ -390,7 +390,35 @@ GameStorage.devMigrations = {
}
player.celestials.ra.unlocks = [];
},
GameStorage.migrations.renameMoney
GameStorage.migrations.renameMoney,
player => {
GameStorage.migrations.moveAutobuyers(player);
const old = player.realityBuyer;
const realityAutobuyer = player.auto.reality;
realityAutobuyer.mode = ["rm", "glyph", "either", "both"].indexOf(player.autoRealityMode);
realityAutobuyer.rm = old.rm;
realityAutobuyer.glyph = old.glyph;
realityAutobuyer.isActive = old.isOn;
const eternityAutobuyer = player.auto.eternity;
eternityAutobuyer.mode = ["amount", "time", "relative"].indexOf(player.autoEternityMode);
const condition = new Decimal(old.limit);
switch (player.autoEternityMode) {
case "amount":
eternityAutobuyer.amount = condition;
break;
case "time":
eternityAutobuyer.time = condition.lt(Decimal.MAX_NUMBER) ? condition.toNumber() : eternityAutobuyer.time;
break;
case "relative":
eternityAutobuyer.xLast = condition;
break;
}
delete player.realityBuyer;
delete player.autoRealityMode;
delete player.autoEternityMode;
}
],
patch(player) {

View File

@ -115,6 +115,7 @@ GameStorage.migrations = {
GameStorage.migrations.removeTickspeed(player);
GameStorage.migrations.removePostC3Reward(player);
GameStorage.migrations.renameMoney(player);
GameStorage.migrations.moveAutobuyers(player);
}
},
@ -454,6 +455,114 @@ GameStorage.migrations = {
}
},
moveAutobuyers(player) {
if (
player.autobuyers[11] % 1 !== 0 &&
player.autobuyers[11].priority !== undefined &&
player.autobuyers[11].priority !== null &&
player.autobuyers[11].priority !== "undefined"
) {
player.autobuyers[11].priority = new Decimal(player.autobuyers[11].priority);
}
for (let i = 0; i < 8; i++) {
const old = player.autobuyers[i];
if (old % 1 === 0) continue;
const autobuyer = player.auto.dimensions[i];
autobuyer.cost = old.cost;
autobuyer.interval = old.interval;
autobuyer.bulk = old.bulk;
autobuyer.mode = old.target;
autobuyer.priority = old.priority;
autobuyer.isActive = old.isOn;
autobuyer.lastTick = player.realTimePlayed;
}
if (player.autobuyers[8] % 1 !== 0) {
const old = player.autobuyers[8];
const autobuyer = player.auto.tickspeed;
autobuyer.cost = old.cost;
autobuyer.interval = old.interval;
autobuyer.mode = old.target;
autobuyer.priority = old.priority;
autobuyer.isActive = old.isOn;
autobuyer.lastTick = player.realTimePlayed;
}
if (player.autobuyers[9] % 1 !== 0) {
const old = player.autobuyers[9];
const autobuyer = player.auto.dimBoost;
autobuyer.cost = old.cost;
autobuyer.interval = old.interval;
autobuyer.maxDimBoosts = old.priority;
autobuyer.galaxies = player.overXGalaxies;
autobuyer.bulk = old.bulk;
autobuyer.buyMaxInterval = old.bulk;
autobuyer.isActive = old.isOn;
autobuyer.lastTick = player.realTimePlayed;
}
delete player.overXGalaxies;
if (player.autobuyers[10] % 1 !== 0) {
const old = player.autobuyers[10];
const autobuyer = player.auto.galaxy;
autobuyer.cost = old.cost;
autobuyer.interval = old.interval;
autobuyer.maxGalaxies = old.priority;
autobuyer.buyMaxInterval = old.bulk;
autobuyer.buyMax = old.bulk > 0;
autobuyer.isActive = old.isOn;
autobuyer.lastTick = player.realTimePlayed;
}
if (player.autobuyers[11] % 1 !== 0) {
const old = player.autobuyers[11];
const autobuyer = player.auto.bigCrunch;
autobuyer.cost = old.cost;
autobuyer.interval = old.interval;
autobuyer.mode = ["amount", "time", "relative"].indexOf(player.autoCrunchMode);
const condition = new Decimal(old.priority);
switch (player.autoCrunchMode) {
case "amount":
autobuyer.amount = condition;
break;
case "time":
autobuyer.time = condition.lt(Decimal.MAX_NUMBER) ? condition.toNumber() : autobuyer.time;
break;
case "relative":
autobuyer.xLast = condition;
break;
}
autobuyer.isActive = old.isOn;
autobuyer.lastTick = player.realTimePlayed;
}
delete player.autoCrunchMode;
delete player.autobuyers;
if (player.autoSacrifice % 1 !== 0) {
const old = player.autoSacrifice;
const autobuyer = player.auto.sacrifice;
autobuyer.multiplier = old.priority;
autobuyer.isActive = old.isOn;
}
delete player.autoSacrifice;
if (player.eternityBuyer !== undefined) {
const old = player.eternityBuyer;
const autobuyer = player.auto.eternity;
// Development saves have additional modes
if (player.autoEternityMode === undefined) {
autobuyer.time = Number(old.limit);
}
autobuyer.isActive = old.isOn;
}
delete player.eternityBuyer;
},
prePatch(saveData) {
// Initialize all possibly undefined properties that were not present in
// previous versions and which could be overwritten by deepmerge

View File

@ -136,10 +136,6 @@ const GameStorage = {
}
recalculateAllGlyphs();
Autobuyer.tryUnlockAny();
Autobuyer.checkIntervalAchievements();
Autobuyer.checkBulkAchievements();
Autobuyer.convertPropertiesToDecimal();
checkPerkValidity();
Teresa.checkPPShopValidity();
drawPerkNetwork();

View File

@ -155,7 +155,7 @@ function playerInfinityUpgradesOnEternity() {
}
function breakInfinity() {
if (!Autobuyer.infinity.hasMaxedInterval) return false;
if (!Autobuyer.bigCrunch.hasMaxedInterval) return false;
if (InfinityChallenge.isRunning) return false;
player.break = !player.break;
EventHub.dispatch(player.break ? GameEvent.FIX_INFINITY : GameEvent.BREAK_INFINITY);
@ -467,17 +467,7 @@ function gameLoop(diff, options = {}) {
if (diff < 0) diff = 1;
if (autobuyerOnGameLoop) {
Autobuyer.intervalTimer += diff / 20;
Autobuyer.tickTimer += diff;
let autobuyerInterval = BreakInfinityUpgrade.autobuyerSpeed.isBought ? 50 : 100;
if (Autobuyer.tickTimer >= autobuyerInterval) {
Autobuyer.tickTimer -= autobuyerInterval;
// failsafe
if (Autobuyer.tickTimer > autobuyerInterval) {
Autobuyer.tickTimer = autobuyerInterval;
}
Autobuyer.tick();
}
Autobuyers.tick();
}
// We do these after autobuyers, since it's possible something there might
// change a multiplier.
@ -800,7 +790,7 @@ function gameLoop(diff, options = {}) {
function gameLoopWithAutobuyers(seconds, ticks, real) {
for (let ticksDone = 0; ticksDone < ticks; ticksDone++) {
gameLoop(1000 * seconds)
Autobuyer.tick();
Autobuyers.tick();
if (real)
console.log(ticksDone)
}
@ -839,7 +829,7 @@ function simulateTime(seconds, real, fast) {
// As in gameLoopWithAutobuyers, we run autoBuyerTick after every game tick
// (it doesn't run in gameLoop).
gameLoop(1000 * realTickTime, {blackHoleSpeedup: blackHoleSpeedup});
Autobuyer.tick();
Autobuyers.tick();
}
}

View File

@ -68,7 +68,7 @@ function updateSpoilers() {
if (i === 10 && (player.infinitied.gte(1) || player.eternities >= 1)) {
(displayed === 0) ? displayed = 1 : displayed = 0;
}
if (i === 11 && (player.autobuyers[11].interval>100 || player.eternities >= 1)) {
if (i === 11 && (player.auto.bigCrunch.interval>100 || player.eternities >= 1)) {
(displayed === 0) ? displayed = 1 : displayed = 0;
}
if (i === 12 && (player.infDimensionsUnlocked[0] == true || player.eternities >= 1)) {

View File

@ -4,7 +4,6 @@ function fixSave() {
var fixed = save.replace(/NaN/gi, "10")
var fixed2 = fixed.replace("notyetfixed", "hasbeenfixed")
var stillToDo = JSON.parse(fixed2)
for (var i=0; i<stillToDo.autobuyers.length; i++) stillToDo.autobuyers[i].isOn = false
document.getElementById("fixed").value = btoa(JSON.stringify(stillToDo))
}
}

View File

@ -3761,6 +3761,9 @@ screen and (max-width: 480px) {
.o-autobuyer-input {
border: .01rem solid #c2c2c2;
padding: .3rem;
height: 2.5rem;
width: 20rem;
box-sizing: border-box;
}
.o-autobuyer-input--invalid {
@ -3781,6 +3784,8 @@ screen and (max-width: 480px) {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
user-select: none;
}
.o-autobuyer-toggle-checkbox__label {
@ -3891,7 +3896,7 @@ screen and (max-width: 480px) {
.c-autobuyer-box {
width: 23rem;
height: 15.5rem;
height: 17.5rem;
padding: 1rem;
border: solid .1rem grey;
border-radius: .4rem;
@ -3923,16 +3928,54 @@ screen and (max-width: 480px) {
font-size: .9rem;
}
.c-autobuyer-box__mode-select {
font-family: Typewriter, serif;
font-size: 1.1rem;
color: #4f5957;
text-align: center;
text-align-last: center;
height: 2.5rem;
width: 20rem;
}
.l-autobuyer-box {
display: flex;
flex-direction: column;
align-items: center;
}
.l-autobuyer-box__header {
height: 1.6rem;
}
.l-autobuyer-box__content {
flex: 1 0 auto;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
.l-autobuyer-box__footer {
height: 1.6rem;
}
.l-autobuyer-box__button {
flex-shrink: 0;
}
.l-autobuyer-box__mode-select {
margin-bottom: 0.5rem
}
.l-autobuyer-box__fill {
flex-grow: 1;
}
.l-autobuyer-box__priority-selector {
margin-bottom: 0.5rem;
}
/*#endregion autobuyer-box*/
/*#endregion Autobuyers*/