mirror of
https://github.com/IvarK/AntimatterDimensionsSourceCode.git
synced 2024-11-10 06:02:13 +00:00
Refactor notation system
This commit is contained in:
parent
ffb7d56c4d
commit
f5772f7bda
@ -636,7 +636,7 @@
|
||||
<script type="text/javascript" src="javascripts/core/app/player-progress.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/modal.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/themes.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/notations.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/notations.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/options.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/event-hub.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/ui.js"></script>
|
||||
|
@ -53,6 +53,9 @@ Vue.component('normal-dim-row', {
|
||||
buyUntil10: function() {
|
||||
buyManyDimensionsBtnClick(this.tier);
|
||||
},
|
||||
showCostTitle: function(value) {
|
||||
return value.exponent < 1000000;
|
||||
}
|
||||
},
|
||||
template:
|
||||
`<div v-show="isUnlocked" class="c-normal-dim-row">
|
||||
@ -66,12 +69,12 @@ Vue.component('normal-dim-row', {
|
||||
:enabled="isAffordable"
|
||||
class="o-primary-btn--buy-nd o-primary-btn--buy-single-nd c-normal-dim-row__buy-button"
|
||||
@click="buySingle"
|
||||
>Cost: {{shortenCosts(singleCost)}}</primary-button>
|
||||
><span v-if="showCostTitle(singleCost)">Cost: </span>{{shortenCosts(singleCost)}}</primary-button>
|
||||
<primary-button
|
||||
:enabled="isAffordableUntil10"
|
||||
class="o-primary-btn--buy-nd o-primary-btn--buy-10-nd c-normal-dim-row__buy-button"
|
||||
@click="buyUntil10"
|
||||
>Until 10, Cost: {{shortenCosts(until10Cost)}}</primary-button>
|
||||
>Until 10, <span v-if="showCostTitle(until10Cost)">Cost: </span>{{shortenCosts(until10Cost)}}</primary-button>
|
||||
<div
|
||||
v-for="text in floatingText"
|
||||
:key="text.key"
|
||||
|
@ -56,6 +56,9 @@ Vue.component("game-header-tickspeed-row", {
|
||||
if (this.isGameSpeedNormal) return undefined;
|
||||
const displayValue = this.isGameSpeedSlow ? (1 / this.gameSpeedMult).toFixed(0) : this.formattedFastSpeed;
|
||||
return `The game is running ${displayValue}x ${this.isGameSpeedSlow ? "slower." : "faster."}`;
|
||||
},
|
||||
showCostTitle: function() {
|
||||
return this.cost.exponent < 1000000;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -78,7 +81,7 @@ Vue.component("game-header-tickspeed-row", {
|
||||
:enabled="isAffordable"
|
||||
class="o-primary-btn--tickspeed"
|
||||
onclick="buyTickSpeed()"
|
||||
>Cost: {{shortenCosts(cost)}}</primary-button>
|
||||
><span v-if="showCostTitle">Cost: </span>{{shortenCosts(cost)}}</primary-button>
|
||||
<primary-button
|
||||
:enabled="isAffordable"
|
||||
class="o-primary-btn--buy-max"
|
||||
|
@ -55,10 +55,7 @@ Vue.component('modal-import', {
|
||||
},
|
||||
methods: {
|
||||
formatMoney: function(money) {
|
||||
forcePostBreakFormat = true;
|
||||
let formatted = this.shorten(money, 2, 1);
|
||||
forcePostBreakFormat = false;
|
||||
return formatted;
|
||||
return this.shortenPostBreak(money, 2, 1);
|
||||
},
|
||||
importSave: function() {
|
||||
if (!this.inputIsValid) return;
|
||||
|
@ -20,10 +20,7 @@ Vue.component('modal-load-game', {
|
||||
change_save(this.saveId);
|
||||
},
|
||||
formatMoney: function(money) {
|
||||
forcePostBreakFormat = true;
|
||||
let formatted = this.shorten(money, 2, 1);
|
||||
forcePostBreakFormat = false;
|
||||
return formatted;
|
||||
return this.shortenPostBreak(money, 2, 1);
|
||||
},
|
||||
update() {
|
||||
if (this.isSelected) {
|
||||
|
@ -1,34 +0,0 @@
|
||||
var Notation = function Notation(name) {
|
||||
this.name = name;
|
||||
|
||||
this.isCancer = function () {
|
||||
return name === "Cancer";
|
||||
};
|
||||
|
||||
this.isPain = function () {
|
||||
return ["Standard", "Cancer", "Brackets"].includes(name);
|
||||
};
|
||||
};
|
||||
|
||||
Notation.current = function () {
|
||||
return new Notation(player.options.notation);
|
||||
};
|
||||
|
||||
Notation.set = function (name) {
|
||||
if (name === undefined) {
|
||||
name = "Standard";
|
||||
}
|
||||
if (name === "Mixed") {
|
||||
name = "Mixed scientific";
|
||||
}
|
||||
if (name === "Default") {
|
||||
name = "Brackets";
|
||||
}
|
||||
if (name === "Emojis") {
|
||||
name = "Cancer";
|
||||
}
|
||||
player.options.notation = name;
|
||||
if (name === "Cancer") {
|
||||
ui.notify.success("😂😂😂");
|
||||
}
|
||||
};
|
@ -7,21 +7,10 @@ class GameOptions {
|
||||
}
|
||||
|
||||
static changeNotation() {
|
||||
const notations = [
|
||||
"Scientific",
|
||||
"Engineering",
|
||||
"Letters",
|
||||
"Standard",
|
||||
"Cancer",
|
||||
"Mixed scientific",
|
||||
"Mixed engineering",
|
||||
"Logarithm",
|
||||
"Brackets",
|
||||
"Infinity"
|
||||
];
|
||||
const notations = Notation.all.map(n => n.name);
|
||||
const current = player.options.notation;
|
||||
const next = shiftDown ? notations.previousSibling(current) : notations.nextSibling(current);
|
||||
Notation.set(next);
|
||||
Notation.find(next).setCurrent();
|
||||
}
|
||||
|
||||
static toggleNews() {
|
||||
|
@ -20,6 +20,9 @@ Vue.mixin({
|
||||
shorten: function(value, places, placesUnder1000) {
|
||||
return shorten(value, places, placesUnder1000);
|
||||
},
|
||||
shortenPostBreak: function(value, places, placesUnder1000) {
|
||||
return shortenPostBreak(value, places, placesUnder1000);
|
||||
},
|
||||
shortenRateOfChange: function(value) {
|
||||
return shortenRateOfChange(value);
|
||||
},
|
||||
|
@ -32,7 +32,7 @@ dev.spin4d = function() {
|
||||
|
||||
dev.cancerize = function() {
|
||||
Theme.tryUnlock("Cancer");
|
||||
Notation.set("Cancer");
|
||||
Notation.cancer.setCurrent();
|
||||
};
|
||||
|
||||
dev.fixSave = function() {
|
||||
|
@ -1,164 +1,3 @@
|
||||
var FormatList = ['', 'K', 'M', 'B', 'T', 'Qa', 'Qt', 'Sx', 'Sp', 'Oc', 'No', 'Dc', 'UDc', 'DDc', 'TDc', 'QaDc', 'QtDc', 'SxDc', 'SpDc', 'ODc', 'NDc', 'Vg', 'UVg', 'DVg', 'TVg', 'QaVg', 'QtVg', 'SxVg', 'SpVg', 'OVg', 'NVg', 'Tg', 'UTg', 'DTg', 'TTg', 'QaTg', 'QtTg', 'SxTg', 'SpTg', 'OTg', 'NTg', 'Qd', 'UQd', 'DQd', 'TQd', 'QaQd', 'QtQd', 'SxQd', 'SpQd', 'OQd', 'NQd', 'Qi', 'UQi', 'DQi', 'TQi', 'QaQi', 'QtQi', 'SxQi', 'SpQi', 'OQi', 'NQi', 'Se', 'USe', 'DSe', 'TSe', 'QaSe', 'QtSe', 'SxSe', 'SpSe', 'OSe', 'NSe', 'St', 'USt', 'DSt', 'TSt', 'QaSt', 'QtSt', 'SxSt', 'SpSt', 'OSt', 'NSt', 'Og', 'UOg', 'DOg', 'TOg', 'QaOg', 'QtOg', 'SxOg', 'SpOg', 'OOg', 'NOg', 'Nn', 'UNn', 'DNn', 'TNn', 'QaNn', 'QtNn', 'SxNn', 'SpNn', 'ONn', 'NNn', 'Ce',];
|
||||
const commaRegexp = /\B(?=(\d{3})+(?!\d))/g;
|
||||
|
||||
function letter(power,str) {
|
||||
const len = str.length;
|
||||
function lN(n) {
|
||||
let result = 1;
|
||||
for (var j = 0; j < n; ++j) result = len*result+1;
|
||||
return result;
|
||||
}
|
||||
if (power <= 5) return str[0];
|
||||
power = Math.floor(power / 3);
|
||||
let i=0;
|
||||
while (power >= lN(++i));
|
||||
if (i==1) return str[power-1];
|
||||
power -= lN(i-1);
|
||||
let ret = '';
|
||||
while (i>0) ret += str[Math.floor(power/Math.pow(len,--i))%len]
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getAbbreviation(e) {
|
||||
const prefixes = [
|
||||
['', 'U', 'D', 'T', 'Qa', 'Qt', 'Sx', 'Sp', 'O', 'N'],
|
||||
['', 'Dc', 'Vg', 'Tg', 'Qd', 'Qi', 'Se', 'St', 'Og', 'Nn'],
|
||||
['', 'Ce', 'Dn', 'Tc', 'Qe', 'Qu', 'Sc', 'Si', 'Oe', 'Ne']]
|
||||
const prefixes2 = ['', 'MI-', 'MC-', 'NA-', 'PC-', 'FM-']
|
||||
e = Math.floor(e/3)-1;
|
||||
let index2 = 0;
|
||||
let prefix = [prefixes[0][e%10]];
|
||||
while (e >= 10) {
|
||||
e = Math.floor(e/10);
|
||||
prefix.push(prefixes[(++index2)%3][e%10])
|
||||
}
|
||||
index2 = Math.floor(index2/3)
|
||||
while (prefix.length%3 != 0) prefix.push("");
|
||||
let ret = "";
|
||||
while (index2 >= 0) ret += prefix[index2*3] + prefix[index2*3+1] + prefix[index2*3+2] + prefixes2[index2--];
|
||||
if (ret.endsWith("-")) ret = ret.slice(0,ret.length-1)
|
||||
return ret.replace("UM","M").replace("UNA","NA").replace("UPC","PC").replace("UFM","FM")
|
||||
}
|
||||
|
||||
let forcePostBreakFormat = false;
|
||||
|
||||
const inflog10 = Math.log10(Number.MAX_VALUE);
|
||||
const infDecimal = new Decimal(Number.MAX_VALUE);
|
||||
function formatValue(notation, value, places, placesUnder1000) {
|
||||
const decimal = new Decimal(value);
|
||||
|
||||
if (decimal.exponent < 3) {
|
||||
return decimal.toNumber().toFixed(placesUnder1000);
|
||||
}
|
||||
|
||||
const notFinite = typeof value === "number" && !Number.isFinite(value);
|
||||
const isPreBreak = !player.break || Challenge.isRunning();
|
||||
if (notFinite || !forcePostBreakFormat && isPreBreak && decimal.gte(infDecimal)) {
|
||||
return "Infinite";
|
||||
}
|
||||
|
||||
let power = decimal.exponent;
|
||||
let mantissa = decimal.mantissa;
|
||||
// If commas is false, exponent will be formatted with current notation
|
||||
let commas = player.options.commas && power < 1000000000;
|
||||
|
||||
function formatPower(power) {
|
||||
if (power < 100000) return power.toString();
|
||||
if (commas) return formatWithCommas(power);
|
||||
return formatValue(notation, power, 3, 3);
|
||||
}
|
||||
|
||||
function isOverflowing(mantissa, threshold) {
|
||||
const pow10 = Math.pow(10, places);
|
||||
return Math.round(mantissa * pow10) >= threshold * pow10;
|
||||
}
|
||||
|
||||
if (notation === "Scientific" || (notation === "Mixed scientific" && power >= 33)) {
|
||||
if (isOverflowing(mantissa, 10)) {
|
||||
mantissa = 1;
|
||||
power++;
|
||||
}
|
||||
return `${mantissa.toFixed(places)}e${formatPower(power)}`;
|
||||
}
|
||||
|
||||
if (notation === "Infinity") {
|
||||
commas = player.options.commas;
|
||||
const log10 = decimal.log10();
|
||||
const infinities = log10 / inflog10;
|
||||
const infPlaces = infinities < 1000 ? 4 : 3;
|
||||
const formatted = infinities.toFixed(Math.max(infPlaces, places));
|
||||
if (commas) {
|
||||
const parts = formatted.split(".");
|
||||
return `${formatWithCommas(parts[0])}.${parts[1]}∞`;
|
||||
}
|
||||
else {
|
||||
return `${formatted}∞`;
|
||||
}
|
||||
}
|
||||
|
||||
if (notation === "Logarithm") {
|
||||
const log10 = decimal.log10();
|
||||
if (power < 100000) {
|
||||
return "e" + log10.toFixed(Math.max(places, 1));
|
||||
}
|
||||
if (commas) {
|
||||
return "e" + formatWithCommas(log10.toFixed(places));
|
||||
}
|
||||
return "ee" + Math.log10(log10).toFixed(3);
|
||||
}
|
||||
|
||||
if (notation === "Brackets") {
|
||||
let table = [")", "[", "{", "]", "(", "}"];
|
||||
let log6 = Math.LN10 / Math.log(6) * decimal.log10();
|
||||
let wholePartOfLog = Math.floor(log6);
|
||||
let decimalPartOfLog = log6 - wholePartOfLog;
|
||||
//Easier to convert a number between 0-35 to base 6 than messing with fractions and shit
|
||||
let decimalPartTimes36 = Math.floor(decimalPartOfLog * 36);
|
||||
let string = "";
|
||||
while (wholePartOfLog >= 6) {
|
||||
let remainder = wholePartOfLog % 6;
|
||||
wholePartOfLog -= remainder;
|
||||
wholePartOfLog /= 6;
|
||||
string = table[remainder] + string;
|
||||
}
|
||||
string = "e" + table[wholePartOfLog] + string + ".";
|
||||
string += table[Math.floor(decimalPartTimes36 / 6)];
|
||||
string += table[decimalPartTimes36 % 6];
|
||||
return string;
|
||||
}
|
||||
|
||||
// 3-digit mantissa notations below
|
||||
|
||||
const powerOffset = power % 3;
|
||||
mantissa *= Math.pow(10, powerOffset);
|
||||
if (isOverflowing(mantissa, 1000)) {
|
||||
mantissa = 1;
|
||||
power += 3;
|
||||
}
|
||||
function concatResult(powerFormat) {
|
||||
return mantissa.toFixed(places) + powerFormat;
|
||||
}
|
||||
|
||||
if (notation === "Engineering" || (notation === "Mixed engineering" && power >= 33)) {
|
||||
return concatResult("e" + formatPower(power - powerOffset));
|
||||
}
|
||||
|
||||
if (notation === "Standard" || notation === "Mixed scientific" || notation === "Mixed engineering") {
|
||||
const abbreviation = power <= 303 ? FormatList[(power - powerOffset) / 3] : getAbbreviation(power);
|
||||
return concatResult(" " + abbreviation);
|
||||
}
|
||||
|
||||
if (notation === "Letters") {
|
||||
return concatResult(letter(power, 'abcdefghijklmnopqrstuvwxyz'));
|
||||
}
|
||||
|
||||
if (notation === "Cancer") {
|
||||
return concatResult(letter(power, ['😠', '🎂', '🎄', '💀', '🍆', '👪', '🌈', '💯', '🍦', '🎃', '💋', '😂', '🌙', '⛔', '🐙', '💩', '❓', '☢', '🙈', '👍', '☂', '✌', '⚠', '❌', '😋', '⚡']));
|
||||
}
|
||||
|
||||
return "1337 H4CK3R";
|
||||
}
|
||||
|
||||
function shortenRateOfChange(money) {
|
||||
return shorten(money, 2, 2);
|
||||
}
|
||||
@ -183,12 +22,21 @@ function shortenMultiplier(money) {
|
||||
return shorten(money, 1, 1);
|
||||
}
|
||||
|
||||
function shortenAutobuyerInput(money) {
|
||||
return formatValue("Scientific", money, 2, 0);
|
||||
function shortenAutobuyerInput(value) {
|
||||
return Notation.scientific.format(value, 2, 0);
|
||||
}
|
||||
|
||||
function shorten(value, places, placesUnder1000) {
|
||||
return formatValue(Notation.current().name, value, places, placesUnder1000);
|
||||
// TODO: this is needed for Vue reactivity to work
|
||||
const notation = player.options.notation;
|
||||
return Notation.current.format(value, places, placesUnder1000);
|
||||
}
|
||||
|
||||
function shortenPostBreak(value, places, placesUnder1000) {
|
||||
Notation.forcePostBreakFormat = true;
|
||||
const shortened = this.shorten(value, places, placesUnder1000);
|
||||
Notation.forcePostBreakFormat = false;
|
||||
return shortened;
|
||||
}
|
||||
|
||||
function formatX(value, places, placesUnder1000) {
|
||||
@ -212,6 +60,7 @@ function timeDisplayShort(ms) {
|
||||
return TimeSpan.fromMilliseconds(ms).toStringShort();
|
||||
}
|
||||
|
||||
const commaRegexp = /\B(?=(\d{3})+(?!\d))/g;
|
||||
function formatWithCommas(value) {
|
||||
return value.toString().replace(commaRegexp, ",");
|
||||
}
|
@ -84,7 +84,7 @@ function galaxyReset() {
|
||||
player.tickDecrease -= 0.03;
|
||||
player.resets = 0;
|
||||
softReset(0);
|
||||
if (Notation.current().isCancer()) player.spreadingCancer += 1;
|
||||
if (Notation.current === Notation.cancer) player.spreadingCancer += 1;
|
||||
Galaxy.checkAchievements();
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ function maxBuyGalaxies(manual) {
|
||||
if (player.currentEternityChall === "eterc6" || Challenge(8).isRunning || player.currentChallenge === "postc7") return
|
||||
if (Autobuyer.galaxy.limit > player.galaxies || manual) {
|
||||
while (player.eightAmount >= Galaxy.requirement.amount && (Autobuyer.galaxy.limit > player.galaxies || manual)) {
|
||||
if (Notation.current().isCancer()) player.spreadingCancer += 1;
|
||||
if (Notation.current === Notation.cancer) player.spreadingCancer += 1;
|
||||
player.galaxies++;
|
||||
}
|
||||
player.galaxies--;
|
||||
|
@ -203,8 +203,20 @@ function onLoad() {
|
||||
updateWormholeUpgrades()
|
||||
updateAutomatorRows()
|
||||
drawPerkNetwork()
|
||||
Notation.set(player.options.notation);
|
||||
GameCache.invalidate();
|
||||
|
||||
const notation = player.options.notation;
|
||||
if (notation === undefined) {
|
||||
player.options.notation = "Standard";
|
||||
}
|
||||
const notationMigration = {
|
||||
"Mixed": "Mixed scientific",
|
||||
"Default": "Brackets",
|
||||
"Emojis": "Cancer"
|
||||
};
|
||||
if (notationMigration[notation] !== undefined) {
|
||||
player.options.notation = notationMigration[notation];
|
||||
}
|
||||
Notation.find(player.options.notation).setCurrent();
|
||||
|
||||
$(".wormhole-upgrades").hide()
|
||||
if (player.wormhole[0].unlocked) {
|
||||
@ -228,6 +240,8 @@ function onLoad() {
|
||||
if (automatorOn) $("#automatorOn")[0].checked = true
|
||||
automatorIdx = player.reality.automatorCurrentRow;
|
||||
|
||||
GameCache.invalidate();
|
||||
|
||||
let diff = new Date().getTime() - player.lastUpdate
|
||||
if (diff > 1000*1000) {
|
||||
simulateTime(diff/1000)
|
||||
|
407
javascripts/core/notations.js
Normal file
407
javascripts/core/notations.js
Normal file
@ -0,0 +1,407 @@
|
||||
class Notation {
|
||||
constructor(name) {
|
||||
this.name = name;
|
||||
this._infDecimal = new Decimal(Number.MAX_VALUE);
|
||||
}
|
||||
|
||||
get isPainful() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Decimal | number | string | undefined | null} value
|
||||
* @param {number} places
|
||||
* @param {number} placesUnder1000
|
||||
* @return {string}
|
||||
*/
|
||||
format(value, places, placesUnder1000) {
|
||||
const decimal = new Decimal(value);
|
||||
|
||||
if (decimal.exponent < 3) {
|
||||
return decimal.toNumber().toFixed(placesUnder1000);
|
||||
}
|
||||
|
||||
if (typeof value === "number" && !Number.isFinite(value) || this.isInfinite(decimal)) {
|
||||
return "Infinite";
|
||||
}
|
||||
|
||||
return this.formatDecimal(decimal, places);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Decimal} decimal
|
||||
* @protected
|
||||
*/
|
||||
isInfinite(decimal) {
|
||||
const isPreBreak = !player.break || Challenge.isRunning();
|
||||
return !Notation.forcePostBreakFormat && isPreBreak && decimal.gte(this._infDecimal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Decimal} value
|
||||
* @param {number} places
|
||||
* @return {string}
|
||||
* @abstract
|
||||
* @protected
|
||||
*/
|
||||
formatDecimal(value, places) {}
|
||||
|
||||
/**
|
||||
* @param {number} power
|
||||
* @return {string}
|
||||
* @protected
|
||||
*/
|
||||
formatExponent(power) {
|
||||
if (power < 100000) return power.toString();
|
||||
if (Notation.commasOnExponent(power)) return formatWithCommas(power);
|
||||
return this.formatDecimal(power.toDecimal(), 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} power
|
||||
* @return {boolean}
|
||||
* @protected
|
||||
*/
|
||||
static commasOnExponent(power) {
|
||||
return player.options.commas && power < 1000000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes cases like (9.6e3, 0), which results in "10e3" (but we need "1e4" instead)
|
||||
* because toFixed rounds numbers to closest integer
|
||||
* @param {Decimal} value
|
||||
* @param {number} places
|
||||
* @param {number} threshold
|
||||
* @param powerOffset
|
||||
* @return {Decimal}
|
||||
* @protected
|
||||
*/
|
||||
fixMantissaOverflow(value, places, threshold, powerOffset) {
|
||||
const pow10 = Math.pow(10, places);
|
||||
const isOverflowing = Math.round(value.mantissa * pow10) >= threshold * pow10;
|
||||
if (!isOverflowing) return value;
|
||||
return Decimal.fromMantissaExponent_noNormalize(1, value.exponent + powerOffset);
|
||||
}
|
||||
|
||||
setCurrent() {
|
||||
player.options.notation = this.name;
|
||||
Notation.current = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @return {Notation}
|
||||
*/
|
||||
static find(name) {
|
||||
const notation = Notation.all.find(n => n.name === name);
|
||||
return notation === undefined ? Notation.mixedScientific : notation;
|
||||
}
|
||||
}
|
||||
|
||||
Notation.forcePostBreakFormat = false;
|
||||
|
||||
Notation.scientific = new class ScientificNotation extends Notation {
|
||||
formatDecimal(value, places) {
|
||||
const fixedValue = this.fixMantissaOverflow(value, places, 10, 1);
|
||||
const mantissa = fixedValue.mantissa.toFixed(places);
|
||||
const exponent = this.formatExponent(fixedValue.exponent);
|
||||
return `${mantissa}e${exponent}`;
|
||||
}
|
||||
}("Scientific");
|
||||
|
||||
class EngineeringNotation extends Notation {
|
||||
formatDecimal(value, places) {
|
||||
const engineering = this.makeFixedEngineering(value, places);
|
||||
const mantissa = engineering.mantissa.toFixed(places);
|
||||
const exponent = this.formatExponent(engineering.exponent);
|
||||
return `${mantissa}e${exponent}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms 1-digit mantissa decimal into 3-digits mantissa decimal
|
||||
* For example: 1.5e5 => 150e3
|
||||
* Note, that it does so in 3 exponent increments, so 1.5e3 is still 1.5e3
|
||||
* @param {Decimal} value
|
||||
* @returns {Decimal}
|
||||
* @protected
|
||||
*/
|
||||
makeEngineering(value) {
|
||||
const exponentOffset = value.exponent % 3;
|
||||
return Decimal.fromMantissaExponent_noNormalize(
|
||||
value.mantissa * Math.pow(10, exponentOffset),
|
||||
value.exponent - exponentOffset
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Decimal} value
|
||||
* @param {number} places
|
||||
* @protected
|
||||
*/
|
||||
makeFixedEngineering(value, places) {
|
||||
const result = this.makeEngineering(value);
|
||||
return this.fixMantissaOverflow(result, places, 1000, 3);
|
||||
}
|
||||
}
|
||||
|
||||
Notation.engineering = new EngineeringNotation("Engineering");
|
||||
|
||||
Notation.standard = new class StandardNotation extends EngineeringNotation {
|
||||
constructor() {
|
||||
super("Standard");
|
||||
this.abbreviations = [
|
||||
'', 'K', 'M', 'B', 'T', 'Qa', 'Qt', 'Sx', 'Sp', 'Oc', 'No', 'Dc', 'UDc', 'DDc',
|
||||
'TDc', 'QaDc', 'QtDc', 'SxDc', 'SpDc', 'ODc', 'NDc', 'Vg', 'UVg', 'DVg', 'TVg',
|
||||
'QaVg', 'QtVg', 'SxVg', 'SpVg', 'OVg', 'NVg', 'Tg', 'UTg', 'DTg', 'TTg', 'QaTg',
|
||||
'QtTg', 'SxTg', 'SpTg', 'OTg', 'NTg', 'Qd', 'UQd', 'DQd', 'TQd', 'QaQd', 'QtQd',
|
||||
'SxQd', 'SpQd', 'OQd', 'NQd', 'Qi', 'UQi', 'DQi', 'TQi', 'QaQi', 'QtQi', 'SxQi',
|
||||
'SpQi', 'OQi', 'NQi', 'Se', 'USe', 'DSe', 'TSe', 'QaSe', 'QtSe', 'SxSe', 'SpSe',
|
||||
'OSe', 'NSe', 'St', 'USt', 'DSt', 'TSt', 'QaSt', 'QtSt', 'SxSt', 'SpSt', 'OSt',
|
||||
'NSt', 'Og', 'UOg', 'DOg', 'TOg', 'QaOg', 'QtOg', 'SxOg', 'SpOg', 'OOg', 'NOg',
|
||||
'Nn', 'UNn', 'DNn', 'TNn', 'QaNn', 'QtNn', 'SxNn', 'SpNn', 'ONn', 'NNn', 'Ce'
|
||||
];
|
||||
}
|
||||
|
||||
get isPainful() {
|
||||
return true;
|
||||
}
|
||||
|
||||
formatDecimal(value, places) {
|
||||
const engineering = this.makeFixedEngineering(value, places);
|
||||
const mantissa = engineering.mantissa.toFixed(places);
|
||||
const abbreviation = value.exponent <= 303 ?
|
||||
this.abbreviations[engineering.exponent / 3] :
|
||||
StandardNotation.getAbbreviation(value.exponent);
|
||||
return `${mantissa} ${abbreviation}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} e
|
||||
* @return {string}
|
||||
* @private
|
||||
*/
|
||||
static getAbbreviation(e) {
|
||||
const prefixes = [
|
||||
['', 'U', 'D', 'T', 'Qa', 'Qt', 'Sx', 'Sp', 'O', 'N'],
|
||||
['', 'Dc', 'Vg', 'Tg', 'Qd', 'Qi', 'Se', 'St', 'Og', 'Nn'],
|
||||
['', 'Ce', 'Dn', 'Tc', 'Qe', 'Qu', 'Sc', 'Si', 'Oe', 'Ne']];
|
||||
const prefixes2 = ['', 'MI-', 'MC-', 'NA-', 'PC-', 'FM-'];
|
||||
e = Math.floor(e / 3) - 1;
|
||||
let index2 = 0;
|
||||
let prefix = [prefixes[0][e % 10]];
|
||||
while (e >= 10) {
|
||||
e = Math.floor(e / 10);
|
||||
prefix.push(prefixes[(++index2) % 3][e % 10]);
|
||||
}
|
||||
index2 = Math.floor(index2 / 3);
|
||||
while (prefix.length % 3 !== 0) prefix.push("");
|
||||
let ret = "";
|
||||
while (index2 >= 0) ret += prefix[index2 * 3] + prefix[index2 * 3 + 1] + prefix[index2 * 3 + 2] + prefixes2[index2--];
|
||||
if (ret.endsWith("-")) ret = ret.slice(0, ret.length - 1)
|
||||
return ret.replace("UM", "M").replace("UNA", "NA").replace("UPC", "PC").replace("UFM", "FM");
|
||||
}
|
||||
}();
|
||||
|
||||
Notation.mixedScientific = new class MixedScientificNotation extends Notation {
|
||||
formatDecimal(value, places) {
|
||||
const notation = value.exponent >= 33 ? Notation.scientific : Notation.standard;
|
||||
return notation.format(value, places);
|
||||
}
|
||||
}("Mixed scientific");
|
||||
|
||||
Notation.mixedEngineering = new class MixedEngineeringNotation extends Notation {
|
||||
formatDecimal(value, places) {
|
||||
const notation = value.exponent >= 33 ? Notation.engineering : Notation.standard;
|
||||
return notation.format(value, places);
|
||||
}
|
||||
}("Mixed engineering");
|
||||
|
||||
Notation.infinity = new class InfinityNotation extends Notation {
|
||||
constructor() {
|
||||
super("Infinity");
|
||||
this._infLog10 = Math.log10(Number.MAX_VALUE);
|
||||
}
|
||||
|
||||
formatDecimal(value, places) {
|
||||
const log10 = value.log10();
|
||||
const infinities = log10 / this._infLog10;
|
||||
const infPlaces = infinities < 1000 ? 4 : 3;
|
||||
const formatted = infinities.toFixed(Math.max(infPlaces, places));
|
||||
if (player.options.commas) {
|
||||
const parts = formatted.split(".");
|
||||
return `${formatWithCommas(parts[0])}.${parts[1]}∞`;
|
||||
}
|
||||
else {
|
||||
return `${formatted}∞`;
|
||||
}
|
||||
}
|
||||
}("Infinity");
|
||||
|
||||
Notation.logarithm = new class LogarithmNotation extends Notation {
|
||||
formatDecimal(value, places) {
|
||||
const log10 = value.log10();
|
||||
if (value.exponent < 100000) {
|
||||
return "e" + log10.toFixed(Math.max(places, 1));
|
||||
}
|
||||
if (Notation.commasOnExponent(value.exponent)) {
|
||||
return "e" + formatWithCommas(log10.toFixed(places));
|
||||
}
|
||||
return "ee" + Math.log10(log10).toFixed(3);
|
||||
}
|
||||
}("Logarithm");
|
||||
|
||||
Notation.brackets = new class BracketsNotation extends Notation {
|
||||
get isPainful() {
|
||||
return true;
|
||||
}
|
||||
|
||||
formatDecimal(value, places) {
|
||||
let table = [")", "[", "{", "]", "(", "}"];
|
||||
let log6 = Math.LN10 / Math.log(6) * value.log10();
|
||||
let wholePartOfLog = Math.floor(log6);
|
||||
let decimalPartOfLog = log6 - wholePartOfLog;
|
||||
//Easier to convert a number between 0-35 to base 6 than messing with fractions and shit
|
||||
let decimalPartTimes36 = Math.floor(decimalPartOfLog * 36);
|
||||
let string = "";
|
||||
while (wholePartOfLog >= 6) {
|
||||
let remainder = wholePartOfLog % 6;
|
||||
wholePartOfLog -= remainder;
|
||||
wholePartOfLog /= 6;
|
||||
string = table[remainder] + string;
|
||||
}
|
||||
string = "e" + table[wholePartOfLog] + string + ".";
|
||||
string += table[Math.floor(decimalPartTimes36 / 6)];
|
||||
string += table[decimalPartTimes36 % 6];
|
||||
return string;
|
||||
}
|
||||
}("Brackets");
|
||||
|
||||
class LettersNotation extends EngineeringNotation {
|
||||
constructor(name, letters) {
|
||||
super(name);
|
||||
this._letters = letters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
letter(power, str) {
|
||||
const len = str.length;
|
||||
|
||||
function lN(n) {
|
||||
let result = 1;
|
||||
for (let j = 0; j < n; ++j) result = len * result + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (power <= 5) return str[0];
|
||||
power = Math.floor(power / 3);
|
||||
let i = 0;
|
||||
while (power >= lN(++i)) ;
|
||||
if (i === 1) return str[power - 1];
|
||||
power -= lN(i - 1);
|
||||
let ret = '';
|
||||
while (i > 0) ret += str[Math.floor(power / Math.pow(len, --i)) % len];
|
||||
return ret;
|
||||
}
|
||||
|
||||
formatDecimal(value, places) {
|
||||
const engineering = this.makeEngineering(value);
|
||||
const mantissa = engineering.mantissa.toFixed(places);
|
||||
const letters = this.letter(value.exponent, this._letters);
|
||||
return mantissa + letters;
|
||||
}
|
||||
}
|
||||
|
||||
Notation.letters = new LettersNotation("Letters", "abcdefghijklmnopqrstuvwxyz");
|
||||
|
||||
Notation.cancer = new class CancerNotation extends LettersNotation{
|
||||
get isPainful() {
|
||||
return true;
|
||||
}
|
||||
|
||||
setCurrent() {
|
||||
super.setCurrent();
|
||||
ui.notify.success("😂😂😂");
|
||||
}
|
||||
}("Cancer", ['😠', '🎂', '🎄', '💀', '🍆', '👪', '🌈', '💯', '🍦', '🎃', '💋', '😂', '🌙', '⛔', '🐙', '💩', '❓', '☢', '🙈', '👍', '☂', '✌', '⚠', '❌', '😋', '⚡']);
|
||||
|
||||
Notation.roman = new class RomanNotation extends Notation {
|
||||
constructor() {
|
||||
super("Roman");
|
||||
this._decimalValue = [ 1000000, 900000, 500000, 400000, 100000, 90000, 50000, 40000, 10000, 9000, 5000, 4000, 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ];
|
||||
this._romanNumeral = [ "M̄", "C̄M̄", "D̄", "C̄D̄", "C̄", "X̄C̄", "L̄", "X̄L̄", "X̄", "ⅯX̄", "V̄", "ⅯV̄", "Ⅿ", "ⅭⅯ", "Ⅾ", "ⅭⅮ", "Ⅽ", "ⅩⅭ", "Ⅼ", "ⅩⅬ", "Ⅹ", "ⅠⅩ","Ⅴ", "ⅠⅤ", "Ⅰ" ];
|
||||
this._romanFractions = ["", "·", ":", "∴", "∷", "⁙"];
|
||||
this.maximum = 4000000;
|
||||
this._maxLog10 = Math.log10(this.maximum);
|
||||
}
|
||||
|
||||
get isPainful() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to format all values (even below 1000), so override format instead of formatDecimal
|
||||
format(value, places, placesUnder1000) {
|
||||
const decimal = new Decimal(value);
|
||||
|
||||
if (typeof value === "number" && !Number.isFinite(value) || this.isInfinite(decimal)) {
|
||||
return "Infinitus";
|
||||
}
|
||||
|
||||
const decimalValue = this._decimalValue;
|
||||
const romanNumeral = this._romanNumeral;
|
||||
const romanFractions = this._romanFractions;
|
||||
|
||||
function romanize(value) {
|
||||
let roman = String.empty;
|
||||
for (let i = 0; i < decimalValue.length; i++) {
|
||||
while (decimalValue[i] <= value) {
|
||||
roman += romanNumeral[i];
|
||||
value -= decimalValue[i];
|
||||
}
|
||||
}
|
||||
let duodecimal = Math.round(Math.floor(value * 10) * 1.2);
|
||||
if (duodecimal === 0) {
|
||||
return roman === String.empty ? "nulla" : roman;
|
||||
}
|
||||
if (duodecimal > 5) {
|
||||
duodecimal -= 6;
|
||||
roman += "S";
|
||||
}
|
||||
roman += romanFractions[duodecimal];
|
||||
return roman;
|
||||
}
|
||||
|
||||
if (decimal.lt(this.maximum)) {
|
||||
return romanize(decimal.toNumber());
|
||||
}
|
||||
|
||||
const log10 = decimal.log10();
|
||||
const maximums = log10 / this._maxLog10;
|
||||
const current = Math.pow(this.maximum, maximums - Math.floor(maximums));
|
||||
return `${romanize(current)}↑${this.format(maximums)}`;
|
||||
}
|
||||
|
||||
formatDecimal(value, places) {}
|
||||
}("Roman");
|
||||
|
||||
/**
|
||||
* Explicit array declaration instead of Object.values for sorting purposes
|
||||
* (Object.values doesn't guarantee any order)
|
||||
* @type {Notation[]}
|
||||
*/
|
||||
Notation.all = [
|
||||
Notation.scientific,
|
||||
Notation.engineering,
|
||||
Notation.letters,
|
||||
Notation.standard,
|
||||
Notation.cancer,
|
||||
Notation.mixedScientific,
|
||||
Notation.mixedEngineering,
|
||||
Notation.logarithm,
|
||||
Notation.brackets,
|
||||
Notation.infinity,
|
||||
Notation.roman
|
||||
];
|
||||
|
||||
Notation.current = Notation.mixedScientific;
|
@ -329,7 +329,7 @@ function fromValue(value) {
|
||||
let m,k,l;
|
||||
if (value.split(" ")[1].length < 5) {
|
||||
for (l=101;l>0;l--) {
|
||||
if (value.includes(FormatList[l])) {
|
||||
if (value.includes(Notation.standard.abbreviations[l])) {
|
||||
e += l*3
|
||||
console.log("caught!"+l)
|
||||
|
||||
@ -1138,7 +1138,7 @@ function gameLoop(diff, options = {}) {
|
||||
} else {
|
||||
Marathon2 = 0;
|
||||
}
|
||||
if (player.eternities >= 1 && Notation.current().isPain()) {
|
||||
if (player.eternities >= 1 && Notation.current.isPainful) {
|
||||
player.secretUnlocks.painTimer += player.options.updateRate/1000;
|
||||
if (player.secretUnlocks.painTimer >= 600) giveAchievement("Do you enjoy pain?");
|
||||
}
|
||||
|
@ -126,7 +126,7 @@
|
||||
<script type="text/javascript" src="javascripts/core/app/player-progress.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/modal.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/themes.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/notations.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/notations.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/options.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/event-hub.js"></script>
|
||||
<script type="text/javascript" src="javascripts/core/app/ui.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user