Merge pull request #2239 from IvarK/lars-credits

credits
This commit is contained in:
Dys 2022-04-25 08:35:25 +08:00 committed by GitHub
commit f7ec26fc0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 732 additions and 252 deletions

View File

@ -0,0 +1,31 @@
export const GameEnd = {
get endState() {
if (this.removeAdditionalEnd) return this.additionalEnd;
return Math.max((Math.log10(player.celestials.pelle.records.totalAntimatter.plus(1).log10() + 1) - 8.7) /
(Math.log10(9e15) - 8.7) + this.additionalEnd, 0);
},
_additionalEnd: 0,
get additionalEnd() {
return (player.isGameEnd || this.removeAdditionalEnd) ? this._additionalEnd : 0;
},
set additionalEnd(x) {
this._additionalEnd = (player.isGameEnd || this.removeAdditionalEnd) ? x : 0;
},
removeAdditionalEnd: false,
gameLoop(diff) {
if (this.removeAdditionalEnd) {
this.additionalEnd -= 0.12;
if (this.additionalEnd < 0) {
this.additionalEnd = 0;
this.removeAdditionalEnd = false;
}
}
if (this.endState >= 1 && ui.$viewModel.modal.progressBar === undefined) {
player.isGameEnd = true;
this.additionalEnd += Math.min(diff / 1000 / 20, 0.1);
}
}
};

View File

@ -55,14 +55,6 @@ export const Pelle = {
return Date.now() % 4000 > 500 ? "Pelle" : Pelle.modalTools.randomCrossWords("Pelle");
},
additionalEnd: 0,
addAdditionalEnd: true,
get endState() {
return Math.max((Math.log10(player.celestials.pelle.records.totalAntimatter.plus(1).log10() + 1) - 8.7) /
(Math.log10(9e15) - 8.7) + this.additionalEnd, 0);
},
get isUnlocked() {
return ImaginaryUpgrade(25).isBought;
},
@ -108,7 +100,6 @@ export const Pelle = {
this.cel.armageddonDuration += diff;
Currency.realityShards.add(this.realityShardGainPerSecond.times(diff).div(1000));
PelleRifts.all.forEach(r => r.fill(diff));
if (this.endState >= 1 && Pelle.addAdditionalEnd) this.additionalEnd += Math.min(diff / 1000 / 20, 0.1);
}
},
@ -144,7 +135,7 @@ export const Pelle = {
get uselessPerks() {
return [10, 12, 13, 14, 15, 16, 17, 30, 40, 41, 42, 43, 44, 45, 46, 51, 53,
60, 61, 62, 80, 81, 82, 83, 100, 105, 106];
60, 61, 62, 80, 81, 82, 83, 100, 105, 106, 201, 202, 203, 204];
},
// Glyph effects are controlled through other means, but are also enumerated here for accessing to improve UX. Note

View File

@ -1,6 +1,6 @@
window.format = function format(value, places, placesUnder1000) {
if (Pelle.isDoomed) {
if ((Pelle.endState - 2.5) / 2 > Math.random()) return "END";
if ((GameEnd.endState - 2.5) / 2 > Math.random()) return "END";
}
return Notations.current.format(value, places, placesUnder1000);
};

View File

@ -34,6 +34,7 @@ export * from "./celestials/pelle/pelle.js";
export * from "./celestials/pelle/strikes.js";
export * from "./celestials/pelle/rifts.js";
export * from "./celestials/pelle/galaxy-generator.js";
export * from "./celestials/pelle/game-end.js";
export * from "./celestials/celestials.js";
export * from "./automator/index.js";

View File

@ -143,7 +143,6 @@ export const shortcuts = [
keys: ["mod", "s"],
type: "bind",
function: () => {
if (Pelle.endState >= 4.5) return false;
GameStorage.save(false, true);
return false;
},

View File

@ -69,7 +69,7 @@ export class GameKeyboard {
GameKeyboard.spins = [];
function executeKey(action) {
if (ui.$viewModel.modal.progressBar !== undefined) {
if (ui.$viewModel.modal.progressBar !== undefined || GameEnd.endState >= 2.5) {
return undefined;
}
return action();

View File

@ -33,12 +33,14 @@ export const NG = {
const secretUnlocks = player.secretUnlocks;
const newGameBackup = JSON.stringify(player.newGame);
const secretAchievements = JSON.stringify(player.secretAchievementBits);
const prevGameEnd = GameEnd.additionalEnd;
GameEnd.removeAdditionalEnd = true;
Modal.hideAll();
GameStorage.hardReset();
player.newGame = JSON.parse(newGameBackup);
player.newGame.current = i;
player.newGame.plusRecord = Math.max(player.newGame.plusRecord, i);
player.newGame.minusRecord = Math.min(player.newGame.minusRecord, i);
Pelle.additionalEnd = 0;
player.options = JSON.parse(backUpOptions);
player.secretUnlocks = secretUnlocks;
player.secretAchievementBits = JSON.parse(secretAchievements);
@ -48,5 +50,7 @@ export const NG = {
Notations.all.find(n => n.name === player.options.notation).setAsCurrent();
ADNotations.Settings.exponentCommas.show = player.options.commas;
GameStorage.save();
player.lastUpdate = Date.now();
GameEnd.additionalEnd = Math.min(prevGameEnd, 14) + 1;
}
};

View File

@ -722,6 +722,7 @@ window.player = {
showBought: false,
}
},
isGameEnd: false,
newGame: {
current: 0,
plusRecord: 0,

View File

@ -1352,7 +1352,7 @@ GameDatabase.achievements.normal = [
id: 188,
name: "The End",
description: "Beat the game.",
checkRequirement: () => Pelle.endState > 1,
checkRequirement: () => GameEnd.endState > 1 && !GameEnd.removeAdditionalEnd,
checkEvent: GAME_EVENT.GAME_TICK_AFTER
},
];

View File

@ -0,0 +1,362 @@
import { GameDatabase } from "./game-database.js";
GameDatabase.credits = {
// Must be placed in the order it is desired they appear in the credits
roles: {
1: "Creator",
2: "Technical Architect",
3: "Lead Developer",
4: "Android Developer",
5: "Library Developer",
6: "Developer",
7: "Lead Design Consultant",
8: "Design Consultant",
9: "Modal Maker, Lady Taker, Pie Baker",
10: "Lurker Tester",
11: "Web Tester",
12: "Android Tester"
},
// Each person must have a name and at least one role (the index of the desired role in roles). They can also have a
// second name, which will appear in parentheses besides their first.
people: [
{
name: "Hevipelle",
name2: "Ivar Kerajärvi",
roles: 1
}, {
name: "Razenpok",
name2: "Andrei Andreev",
roles: 2
}, {
name: "garnet420",
roles: 3
}, {
name: "Omsi",
roles: 3
}, {
name: "SpectralFlame",
name2: "Christopher Yip",
roles: 3
}, {
name: "WaitingIdly",
roles: [3, 6, 8, 11, 12]
}, {
name: "kajfik",
name2: "Jakub Kajfosz",
roles: 4
}, {
name: "Patashu",
roles: [5, 6, 11]
}, {
name: "Dan",
roles: [6, 11]
}, {
name: "earth",
name2: "Jace Royer",
roles: [6, 9, 11, 12]
}, {
name: "Hira",
roles: [6, 11, 12]
}, {
name: "IkerStream",
name2: "Iker de Aguirre",
roles: [6, 11]
}, {
name: "L4R5",
name2: "Lars Wolf",
roles: [6, 11, 12]
}, {
name: "Pichusuperlover",
roles: [6, 8, 11]
}, {
name: "realrapidjazz",
roles: [6, 7]
}, {
name: "Scarlet",
roles: [6, 11, 12]
}, {
name: "slabdrill",
roles: 6
}, {
name: "Acamaeda",
roles: [8, 11]
}, {
name: "Dravitar",
name2: "Alex Henderson",
roles: 10
}, {
name: "Aesis",
roles: 11
}, {
name: "AFYINEE",
name2: "Gabriel HADDAG",
roles: 11
}, {
name: "Alexitato",
roles: 11
}, {
name: "Anno",
roles: 11
}, {
name: "Archa",
name2: "Myresa",
roles: [11, 12]
}, {
name: "ArrowBounce",
name2: "Timothy Su",
roles: 11
}, {
name: "Birb",
name2: "Kelsey Black",
roles: 11
}, {
name: "Boo",
name2: "Jean-Christophe Bourgault",
roles: 11
}, {
name: "CaptainGalaxy",
name2: "Ovidijus Točelis",
roles: 11
}, {
name: "ChaoticHans",
roles: [11, 12]
}, {
name: "cubic frog",
roles: 11
}, {
name: "dankesehr",
roles: 11
}, {
name: "Davixx",
name2: "Davide Fedele",
roles: 11
}, {
name: "Empireus",
roles: 11
}, {
name: "GirixK",
name2: "Nikola Jelinčić",
roles: [11, 12]
}, {
name: "GoldenTritium",
roles: [11, 12]
}, {
name: "Kael",
roles: 11
}, {
name: "Lynn",
roles: 11
}, {
name: "Merp",
roles: 11
}, {
name: "philipebreaker",
name2: "Philipe",
roles: 11
}, {
name: "Phillip Marshall",
roles: 11
}, {
name: "Phoenix",
roles: 11
}, {
name: "Reda Kotob",
roles: 11
}, {
name: "Saturnus",
roles: 11
}, {
name: "SereKabii",
roles: 11
}, {
name: "Sheer",
roles: 11
}, {
name: "sirusi",
name2: "Vinícius Oliveira Martins",
roles: 11
}, {
name: "Spanosa",
name2: "Jared K",
roles: 11
}, {
name: "Sparticle999",
roles: 11
}, {
name: "SpicyCrusader13",
roles: [11, 12]
}, {
name: "Storm",
roles: 11
}, {
name: "SzyszakS",
roles: 11
}, {
name: "Tacitus",
roles: 11
}, {
name: "Typh",
roles: 11
}, {
name: "Vnge",
name2: "Ben Parrish",
roles: [11, 12]
}, {
name: "Xemadus",
name2: "Jonathan Gibson",
roles: 11
}, {
name: "Young Woo Joo",
roles: 11
}, {
name: "Zipi",
roles: 11
}, {
name: "about:blank",
roles: 12
}, {
name: "ÆiOuF",
roles: 12
}, {
name: "Anjinho01",
roles: 12
}, {
name: "Anthios",
roles: 12
}, {
name: "Auti",
name2: "Alice Tolle",
roles: 12
}, {
name: "Buck",
roles: 12
}, {
name: "Barrin84",
roles: 12
}, {
name: "ChizuX",
roles: 12
}, {
name: "Circle",
roles: 12
}, {
name: "Crinkly Weasel",
name2: "Aaryan Sarawgi",
roles: 12
}, {
name: "DarthDie",
name2: "Briar Bowser",
roles: 12
}, {
name: "Epsilon",
name2: "Coolguystorm",
roles: 12
}, {
name: "Firecracker",
roles: 12
}, {
name: "Gaunter",
roles: 12
}, {
name: "HarrisL2",
roles: 12
}, {
name: "Hellbach",
name2: "Asher Günther",
roles: 12
}, {
name: "hen-ben",
name2: "Henry Ellenberg",
roles: 12
}, {
name: "ImpossibleSalsa",
roles: 12
}, {
name: "Johanniklas",
name2: "Jan-Niklas Petersen",
roles: 12
}, {
name: "kaislash",
name2: "Lily",
roles: 12
}, {
name: "Kirku",
name2: "Fabian Makowski",
roles: 12
}, {
name: "Kirin",
name2: "Arthur",
roles: 12
}, {
name: "Mirai",
roles: 12
}, {
name: "Monoma",
name2: "ARoman Ruiz",
roles: 12
}, {
name: "Nani",
roles: 12
}, {
name: "NotBrewst",
name2: "Luc Leblanc",
roles: 12
}, {
name: "opdollar",
name2: "Zane Coole",
roles: 12
}, {
name: "Pavlxiiv",
roles: 12
}, {
name: "Porygon-Z",
roles: 12
}, {
name: "PotatoTIAB",
roles: 12
}, {
name: "Razor",
roles: 12
}, {
name: "Razvan Cercel",
roles: 12
}, {
name: "Rukimix",
roles: 12
}, {
name: "Skunky",
name2: "Lukas",
roles: 12
}, {
name: "Socks",
name2: "Hannah Pocks",
roles: 12
}, {
name: "Taylor Reeves",
roles: 12
}, {
name: "Tim Wong",
roles: 12
}, {
name: "tragedt",
name2: "Ethan Manninen",
roles: 12
}, {
name: "Valentine Clarissa Alanis Star Z",
roles: 12
}, {
name: "vanadium_void",
roles: 12
}, {
name: "X3N0_32",
roles: 12
}, {
name: "ZylaKat",
name2: "Katherine Goforth-Harbin",
roles: 12
}
]
};
GameDatabase.credits.roles.count = Object.keys(GameDatabase.credits.roles).length;

View File

@ -41,3 +41,5 @@ import "./script-templates.js";
import "./speedrun-milestones.js";
import "./h2p.js";
import "./credits.js";

View File

@ -69,6 +69,12 @@ export const GameStorage = {
this.loadPlayerObject(player, overrideLastUpdate);
if (player.speedrun?.isActive) Speedrun.setSegmented(true);
this.save(true);
// This is to fix a very specific exploit: When the game is ending, some tabs get hidden
// The options tab is the first one of those, which makes the player redirect to the Pelle tab
// You can doom your reality even if you haven't unlocked infinity yet if you import while the Pelle tab
// is showing
Tab.options.subtabs[0].show();
GameUI.notify.info("Game imported");
},
@ -133,7 +139,7 @@ export const GameStorage = {
},
save(silent = false, manual = false) {
if (Pelle.endState >= 4.5) return;
if (GameEnd.endState >= 4.5 && !GameEnd.removeAdditionalEnd) return;
if (GlyphSelection.active || ui.$viewModel.modal.progressBar !== undefined) return;
this.lastSaveTime = Date.now();
GameIntervals.save.restart();
@ -172,7 +178,7 @@ export const GameStorage = {
hardReset() {
this.loadPlayerObject(Player.defaultStart);
this.save();
this.save(true);
Tab.dimensions.antimatter.show();
},
@ -216,6 +222,7 @@ export const GameStorage = {
checkPerkValidity();
V.updateTotalRunUnlocks();
Enslaved.boostReality = false;
GameEnd.additionalEnd = 0;
Theme.set(player.options.theme);
Notations.find(player.options.notation).setAsCurrent(true);
ADNotations.Settings.exponentCommas.show = player.options.commas;

View File

@ -13,7 +13,7 @@ class SubtabState {
}
get isPermanentlyHidden() {
return this.config.hideAt <= Pelle.endState;
return this.config.hideAt <= GameEnd.endState;
}
get hidable() {
@ -99,7 +99,7 @@ class TabState {
}
get isPermanentlyHidden() {
return this.config.hideAt <= Pelle.endState;
return this.config.hideAt <= GameEnd.endState;
}
get hidable() {

View File

@ -606,6 +606,7 @@ export function gameLoop(passDiff, options = {}) {
AutomatorBackend.update(realDiff);
Pelle.gameLoop(realDiff);
GalaxyGenerator.loop(realDiff);
GameEnd.gameLoop(realDiff);
if (Tabs.current.isPermanentlyHidden) {
const tab = Tabs.all.reverse().find(t => !t.isPermanentlyHidden && t.id !== 10);

View File

@ -34,6 +34,11 @@ export default {
InfoButton,
TimeTheoremShop
},
data() {
return {
rollCredits: false,
};
},
computed: {
view() {
return this.$viewModel;
@ -52,6 +57,11 @@ export default {
return `stylesheets/theme-${this.view.theme}.css`;
}
},
methods: {
update() {
this.rollCredits = GameEnd.endState >= 2.5;
}
}
};
</script>
@ -95,9 +105,9 @@ export default {
<ModernSidebar v-if="view.newUI" />
<SaveTimer />
<SpeedrunStatus />
<FadeToBlack />
<CreditsContainer />
<NewGame />
<FadeToBlack v-if="rollCredits" />
<CreditsContainer v-if="rollCredits" />
<NewGame v-if="rollCredits" />
</div>
</template>

View File

@ -7,6 +7,11 @@ export default {
required: true,
}
},
data() {
return {
forceDontShowModal: false
};
},
created() {
this.on$(GAME_EVENT.CLOSE_MODAL, this.hide);
},
@ -14,6 +19,10 @@ export default {
document.activeElement.blur();
},
methods: {
update() {
// 2.5 is the cutoff point where the screen starts fading
this.forceDontShowModal = GameEnd.endState > 2.5;
},
hide() {
if (this.modal.hide) this.modal.hide();
else Modal.hide();
@ -25,11 +34,11 @@ export default {
<template>
<component
:is="modal.component"
v-if="modal.isBare"
v-if="modal.isBare && !forceDontShowModal"
:modal-config="modal.props"
/>
<div
v-else
v-else-if="!forceDontShowModal"
class="c-modal l-modal"
>
<component

View File

@ -4,11 +4,11 @@ import ModalWrapperChoice from "@/components/modals/ModalWrapperChoice";
export default {
name: "HardResetModal",
components: {
ModalWrapperChoice,
ModalWrapperChoice
},
data() {
return {
input: "",
input: ""
};
},
computed: {

View File

@ -5,7 +5,6 @@ export default {
name: "AntimatterDimensionProgressBar",
data() {
return {
isVisible: true,
fill: 0,
tooltip: ""
};
@ -23,7 +22,6 @@ export default {
methods: {
// eslint-disable-next-line complexity
update() {
this.isVisible = Pelle.endState < 4.5;
const setProgress = (current, goal, tooltip) => {
this.fill = Math.clampMax(current.pLog10() / Decimal.log10(goal), 1);
this.tooltip = tooltip;
@ -120,7 +118,6 @@ export default {
class="c-progress-bar__fill"
>
<span
v-if="isVisible"
v-tooltip="tooltip"
class="c-progress-bar__percents"
>

View File

@ -51,7 +51,6 @@ export default {
return this.isShown || this.isUnlocked || this.amount.gt(0);
},
boughtTooltip() {
if (this.end) return "";
if (this.isCapped) return `Enslaved prevents the purchase of more than ${format(1)} 8th Antimatter Dimension`;
if (this.isContinuumActive) return "Continuum produces all your Antimatter Dimensions";
return `Purchased ${quantifyInt("time", this.bought)}`;
@ -62,7 +61,6 @@ export default {
},
methods: {
update() {
this.end = Pelle.endState >= 4.5;
const tier = this.tier;
if (tier > DimBoost.maxDimensionsUnlockable) return;
const dimension = AntimatterDimension(tier);

View File

@ -27,9 +27,16 @@ export default {
isSacrificeUnlocked: false,
buy10Mult: new Decimal(0),
currentSacrifice: new Decimal(0),
multiplierText: "",
};
},
computed: {
multiplierText() {
const sacText = this.isSacrificeUnlocked
? ` | Dimensional Sacrifice multiplier: ${formatX(this.currentSacrifice, 2, 2)}`
: "";
return `Buy 10 Dimension purchase multiplier: ${formatX(this.buy10Mult, 2, 1)}${sacText}`;
},
},
methods: {
update() {
this.isInMatterChallenge = Player.isInMatterChallenge;
@ -57,10 +64,6 @@ export default {
this.isSacrificeUnlocked = Sacrifice.isVisible;
this.buy10Mult.copyFrom(AntimatterDimensions.buyTenMultiplier);
this.currentSacrifice.copyFrom(Sacrifice.totalBoost);
this.multiplierText = `Buy 10 Dimension purchase multiplier: ${formatX(this.buy10Mult, 2, 1)}`;
if (this.isSacrificeUnlocked) this.multiplierText +=
` | Dimensional Sacrifice multiplier: ${formatX(this.currentSacrifice, 2, 2)}`;
},
quickReset() {
softReset(-1, true, true);

View File

@ -8,7 +8,6 @@ export default {
},
data() {
return {
end: false,
isSacrificeUnlocked: false,
isSacrificeAffordable: false,
currentSacrifice: new Decimal(0),
@ -18,13 +17,11 @@ export default {
},
computed: {
sacrificeTooltip() {
if (this.end) return "";
return `Boosts 8th Antimatter Dimension by ${formatX(this.sacrificeBoost, 2, 2)}`;
},
},
methods: {
update() {
this.end = Pelle.endState >= 4.5;
const isSacrificeUnlocked = Sacrifice.isVisible;
this.isSacrificeUnlocked = isSacrificeUnlocked;
if (!isSacrificeUnlocked) return;

View File

@ -9,7 +9,6 @@ export default {
},
data() {
return {
end: false,
isUnlocked: false,
isCapped: false,
multiplier: new Decimal(0),
@ -50,7 +49,6 @@ export default {
return this.isShown || this.isUnlocked || this.amount.gt(0);
},
boughtTooltip() {
if (this.end) return "";
if (this.isCapped) return `Enslaved prevents the purchase of more than ${format(1)} 8th Antimatter Dimension`;
if (this.isContinuumActive) return "Continuum produces all your Antimatter Dimensions";
return `Purchased ${quantifyInt("time", this.bought)}`;
@ -61,7 +59,6 @@ export default {
},
methods: {
update() {
this.end = Pelle.endState >= 4.5;
const tier = this.tier;
if (tier > DimBoost.maxDimensionsUnlockable) return;
const dimension = AntimatterDimension(tier);

View File

@ -25,7 +25,6 @@ export default {
buy10Mult: new Decimal(0),
currentSacrifice: new Decimal(0),
sacrificeBoost: new Decimal(0),
multiplierText: "",
disabledCondition: "",
isQuickResetAvailable: false,
hasContinuum: false,
@ -36,6 +35,12 @@ export default {
sacrificeTooltip() {
return `Boosts 8th Antimatter Dimension by ${formatX(this.sacrificeBoost, 2, 2)}`;
},
multiplierText() {
const sacText = this.isSacrificeUnlocked
? ` | Dimensional Sacrifice multiplier: ${formatX(this.currentSacrifice, 2, 2)}`
: "";
return `Buy 10 Dimension purchase multiplier: ${formatX(this.buy10Mult, 2, 1)}${sacText}`;
},
},
methods: {
maxAll() {
@ -74,16 +79,13 @@ export default {
const isSacrificeUnlocked = Sacrifice.isVisible;
this.isSacrificeUnlocked = isSacrificeUnlocked;
this.buy10Mult.copyFrom(AntimatterDimensions.buyTenMultiplier);
if (!isSacrificeUnlocked) return;
this.isSacrificeAffordable = Sacrifice.canSacrifice;
this.currentSacrifice.copyFrom(Sacrifice.totalBoost);
this.buy10Mult.copyFrom(AntimatterDimensions.buyTenMultiplier);
this.sacrificeBoost.copyFrom(Sacrifice.nextBoost);
this.disabledCondition = Sacrifice.disabledCondition;
this.multiplierText = `Buy 10 Dimension purchase multiplier: ${formatX(this.buy10Mult, 2, 1)}`;
if (this.isSacrificeUnlocked) this.multiplierText +=
` | Dimensional Sacrifice multiplier: ${formatX(this.currentSacrifice, 2, 2)}`;
}
}
};

View File

@ -5,10 +5,30 @@ export default {
return {
rolling: false,
scroll: 0,
audio: null,
isDoomed: false
audio: null
};
},
computed: {
people() { return GameDatabase.credits.people; },
roles() { return GameDatabase.credits.roles; },
creditStyles() {
return {
bottom: `${this.scroll}rem`,
display: this.rolling ? "block" : "none"
};
},
celestialDisplays() {
return {
teresa: Teresa.symbol,
effarig: Effarig.symbol,
enslaved: Enslaved.symbol,
v: V.symbol,
ra: Ra.symbol,
laitela: Laitela.symbol,
pelle: Pelle.symbol
};
}
},
watch: {
rolling(newVal, oldVal) {
if (!oldVal && newVal && this.audio === null) {
@ -19,11 +39,14 @@ export default {
},
methods: {
update() {
this.isDoomed = Pelle.isDoomed;
if (!this.isDoomed) return;
this.rolling = Pelle.endState > 4.5;
this.scroll = (Pelle.endState - 4.5) / 2 * 100;
if (this.audio) this.audio.volume = Math.clamp(Pelle.endState - 4.5, 0, 0.3);
this.rolling = GameEnd.endState > 4.5;
this.scroll = (GameEnd.endState - 4.5) * 48;
if (this.audio) this.audio.volume = Math.clamp((GameEnd.endState - 4.5), 0, 0.3);
},
relevantPeople(role) {
return this.people
.filter(x => (typeof x.roles === "number" ? x.roles === role : x.roles.includes(role)))
.sort((a, b) => a.name.localeCompare(b.name));
}
}
};
@ -31,174 +54,202 @@ export default {
<template>
<div
v-if="isDoomed"
class="credits-container"
:style="{
top: `${100 - scroll}vh`,
display: rolling ? 'block' : 'none'
}"
class="c-credits-container"
:style="creditStyles"
>
<h1>Antimatter Dimensions</h1>
<div
v-for="(celSymbol, celIndex) in celestialDisplays"
:key="celIndex + '-end-credit-symbol-disp'"
class="c-credits-cel-symbol"
:class="`c-${celIndex}-credits`"
v-html="celSymbol"
/>
<h1 class="c-credits-header">
Antimatter Dimensions
</h1>
<h2>Created by</h2>
<p>Ivar "Hevipelle" Kerajärvi</p>
<h2>Technical Architect</h2>
<p>Razenpok (Andrei Andreev)</p>
<h2>Head Developer</h2>
<p>SpectralFlame (Christopher Yip)</p>
<p>Omsi</p>
<h2>Developer</h2>
<p>Dan</p>
<p>realrapidjazz</p>
<p>earth</p>
<p>IkerStream</p>
<p>Pichusuperlover</p>
<p>Patashu</p>
<p>L4R5 (Lars Wolf)</p>
<p>Hira</p>
<p>Sparticle999</p>
<h2>Modal Maker, Lady Taker, Pie Baker</h2>
<p>earth</p>
<h2>Android Developer</h2>
<p>kajfik (Jakub Kajfosz)</p>
<h2>Library Developer</h2>
<p>Patashu</p>
<h2>Design Consoltant</h2>
<p>Pichusuperlover</p>
<p>Acamaeda</p>
<h2>Web Tester</h2>
<div class="l-credits--left">
<p>Aesis</p>
<p>Alexitato</p>
<p>Birb (Kelsey Black)</p>
<p>CaptainGalaxy (Ovidijus Točelis)</p>
<p>cubic frog</p>
<p>dankesehr</p>
<p>earth</p>
<p>Hira</p>
<p>Kael</p>
<p>Merp</p>
<p>Phoenix</p>
<p>Phillip Marshall</p>
<p>Reda Kotob</p>
<p>sirusi (Vinícius Oliveira Martins)</p>
<p>SpicyCrusader13</p>
<p>SzyszakS</p>
<p>Typh</p>
<p>Xemadus (Jonathan Gibson)</p>
<p>Zipi</p>
</div>
<div class="l-credits--right">
<p>Acamaeda</p>
<p>AFYINEE (Gabriel HADDAG)</p>
<p>Archa (Myresa)</p>
<p>Boo (Jean-Christophe Bourgault)</p>
<p>ChaoticHans</p>
<p>Dan</p>
<p>Davixx (Davide Fedele)</p>
<p>Empireus</p>
<p>IkerStream (Iker de Aguirre)</p>
<p>Lynn</p>
<p>Patashu</p>
<p>philipebreaker (Philipe)</p>
<p>Pichusuperlover</p>
<p>Saturnus</p>
<p>Spanosa (Jared K)</p>
<p>Storm</p>
<p>Tacitus</p>
<p>Vnge (Ben Parrish)</p>
<p>Young Woo Joo</p>
<div
v-for="role in roles.count"
:key="role"
>
<h2 class="c-credits-section">
{{ pluralize(roles[role], relevantPeople(role).length) }}
</h2>
<div :class="{ 'l-credits--bulk': relevantPeople(role).length > 10}">
<div
v-for="person in relevantPeople(role)"
:key="person.name"
class="c-credit-entry"
>
{{ person.name }}
<span v-if="person.name2">
({{ person.name2 }})
</span>
</div>
</div>
</div>
<h2>Android Tester:</h2>
<div class="l-credits--left">
<p>Archa (Myresa)</p>
<p>ChaoticHans</p>
<p>Vnge (Ben Parrish)</p>
<p>Rukimix</p>
<p>Anjinho01</p>
<p>HarrisL2</p>
<p>hen-ben (Henry Ellenberg)</p>
<p>Gaunter</p>
<p>Socks (Hannah Pocks)</p>
<p>Johanniklas (Jan-Niklas Petersen)</p>
<p>Razor</p>
<p>Barrin84</p>
<p>DarthDie (Briar Bowser)</p>
<p>Monoma (ARoman Ruiz)</p>
<p>Nani</p>
<p>Kirin Nijinski (Arthur)</p>
<p>about:blank</p>
<p>Epsilon (Coolguystorm)</p>
<p>Razvan Cercel</p>
</div>
<div class="l-credits--right">
<p>Hira</p>
<p>Hellbach (Asher Günther)</p>
<p>Buck</p>
<p>Valentine Clarissa Alanis Star Z</p>
<p>Porygon-Z</p>
<p>tragedt (Ethan Manninen)</p>
<p>SpicyCrusader13</p>
<p>Firecracker</p>
<p>opdollar (Zane Coole)</p>
<p>ImpossibleSalsa</p>
<p>kaislash (Lily)</p>
<p>Skunky (Lukas)</p>
<p>ZylaKat (Katherine Goforth-Harbin)</p>
<p>vanadium_void</p>
<p>Circle</p>
<p>PotatoTIAB</p>
<p>Pavlxiiv</p>
<p>Kirku (Fabian Makowski)</p>
<p>Tim Wong</p>
</div>
<br><br><br>
<h1>Thank you so much for playing!</h1>
<br><br><br><br><br><br><br><br><br>
<h1 class="c-credits-header">
Thank you so much for playing!
</h1>
</div>
</template>
<style scoped>
.credits-container {
position: absolute;
left: 0;
height: 100%;
width: 100%;
z-index: 7;
color: rgb(185, 185, 185);
}
.c-credits-container {
position: absolute;
left: 0;
height: 100%;
width: 100%;
z-index: 9;
color: rgb(185, 185, 185);
pointer-events: none;
transform: translateY(100%);
}
h1 {
color: yellow;
}
.c-credits-header {
color: yellow;
}
h2 {
margin-top: 20rem;
margin-bottom: 2rem;
color: white;
text-shadow: 1px 1px 2px turquoise;
}
.c-credits-section {
margin-top: 10rem;
margin-bottom: 2rem;
color: white;
text-shadow: 1px 1px 2px turquoise;
}
.l-credits--left {
width: 50%;
float: left;
}
.l-credits--bulk {
display: grid;
grid-template-columns: repeat(2, 1fr);
position: relative;
width: 76%;
left: 12%;
}
.l-credits--right {
width: 50%;
overflow: hidden;
}
.c-credit-entry {
margin-top: 1rem;
font-size: 1.3rem;
}
p {
margin-top: 1rem;
}
.c-credits-cel-symbol {
position: absolute;
font-size: 14rem;
text-shadow: 0 0 3rem;
transform: translateX(-50%);
height: 14rem;
width: 14rem;
display: flex;
justify-content: center;
align-items: center;
}
.c-teresa-credits {
left: 65%;
top: 130rem;
color: var(--color-teresa--base);
animation: a-teresa-credits 10s ease-in-out infinite;
}
.c-effarig-credits {
left: 80%;
top: 50rem;
color: #f40;
animation: a-effarig-credits 4s ease-in-out infinite;
}
.c-enslaved-credits {
left: 52%;
top: 220rem;
color: var(--color-enslaved-base);
animation: a-enslaved-credits 10s linear infinite;
}
.c-v-credits {
left: 20%;
top: 170rem;
color: var(--color-v--base);
animation: a-v-credits 15s ease-in-out infinite;
}
.c-ra-credits {
left: 44%;
top: 300rem;
color: var(--color-ra-base);
animation: a-ra-credits 10s ease-in-out infinite;
}
.c-laitela-credits {
left: 13%;
top: 90rem;
color: #ffffff;
animation: a-laitela-credits 5s ease-in-out infinite;
}
.c-pelle-credits {
left: 30%;
top: 8rem;
color: var(--color-pelle--base);
animation: a-pelle-credits 5s linear infinite;
}
@keyframes a-teresa-credits {
0% { transform: rotate(61deg); }
10% { transform: rotate(322deg); }
20% { transform: rotate(235deg); }
30% { transform: rotate(222deg); }
40% { transform: rotate(105deg); }
50% { transform: rotate(33deg); }
60% { transform: rotate(103deg); }
70% { transform: rotate(158deg); }
80% { transform: rotate(41deg); }
90% { transform: rotate(73deg); }
100% { transform: rotate(61deg); }
}
@keyframes a-effarig-credits {
0% { opacity: 0.8; text-shadow: 0 0 3rem; }
50% { opacity: 1; text-shadow: 0 0 4rem, 0 0 4rem; }
100% { opacity: 0.8; text-shadow: 0 0 3rem; }
}
@keyframes a-enslaved-credits {
0% { transform: translateX(-50%) rotate(0); }
100% { transform: translateX(-50%) rotate(360deg); }
}
/* We unfortunately have to do it this way, because due to how the benzene unicode symbol works, 0 and 120deg aren't
perfectly the same. */
@keyframes a-v-credits {
0% { transform: translateX(-50%) rotate(0) scale(0.8); }
16.67% { transform: translateX(-50%) rotate(60deg) scale(1.2); }
33.33% { transform: translateX(-50%) rotate(120deg) scale(0.8); }
50% { transform: translateX(-50%) rotate(180deg) scale(1.2); }
66.67% { transform: translateX(-50%) rotate(240deg) scale(0.8); }
83.33% { transform: translateX(-50%) rotate(300deg) scale(1.2); }
100% { transform: translateX(-50%) rotate(360deg) scale(0.8); }
}
@keyframes a-ra-credits {
0% { opacity: 0.1; transform: translateX(-50%) scale(0.2); }
50% { opacity: 0.4; transform: translateX(-50%) scale(0.9); }
100% { opacity: 0.1; transform: translateX(-50%) scale(0.2); }
}
@keyframes a-laitela-credits {
0% { transform: translate(-50%, 30%); }
25% { transform: translate(-50%, -20%); }
50% { transform: translate(-50%, 30%); }
75% { transform: translate(0%, 30%); }
100% { transform: translate(-50%, 30%); }
}
@keyframes a-pelle-credits {
0% { transform: translateX(-50%) rotate3d(0, 1, 0, 0) scaleY(1); }
25% { transform: translateX(-50%) rotate3d(0, 1, 0, 90deg) scaleY(1.3); }
50% { transform: translateX(-50%) rotate3d(0, 1, 0, 180deg) scaleY(1); }
75% { transform: translateX(-50%) rotate3d(0, 1, 0, 270deg) scaleY(1.3); }
100% { transform: translateX(-50%) rotate3d(0, 1, 0, 360deg) scaleY(1); }
}
</style>

View File

@ -8,7 +8,7 @@ export default {
},
methods: {
update() {
this.opacity = (Pelle.endState - 2.5) / 2;
this.opacity = (GameEnd.endState - 2.5) / 2;
}
}
};
@ -17,7 +17,10 @@ export default {
<template>
<div
class="black-overlay"
:style="{ opacity: opacity }"
:style="{
opacity,
pointerEvents: opacity > 1 ? 'auto' : 'none'
}"
/>
</template>
@ -28,8 +31,7 @@ export default {
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
background: black;
z-index: 6;
z-index: 8;
}
</style>

View File

@ -6,7 +6,7 @@ export default {
plusRecord: 0,
minusRecord: 0,
opacity: 0,
visible: false
visible: false,
};
},
computed: {
@ -15,13 +15,19 @@ export default {
.map(x => x - 1 + this.minusRecord)
.filter(Boolean);
},
style() {
return {
opacity: this.opacity,
visibility: this.visible ? "visible" : "hidden"
};
}
},
methods: {
update() {
this.plusRecord = NG.plusRecord;
this.minusRecord = NG.minusRecord;
this.visible = Pelle.endState > 14.9;
this.opacity = (Pelle.endState - 14.9) * 2;
this.visible = GameEnd.endState > 13.75 && !GameEnd.removeAdditionalEnd;
this.opacity = (GameEnd.endState - 13.75) * 2;
},
ngString(i) {
if (!i) return "";
@ -36,44 +42,53 @@ export default {
<template>
<div
class="new-game-container"
:style="{ display: visible ? 'flex' : 'none', opacity }"
class="c-new-game-container"
:style="style"
>
<h1>Wanna start over?</h1>
Highest NG+: {{ plusRecord }}<br>
Highest NG-: {{ minusRecord }}<br>
<button
v-for="i in ngRange"
:key="i"
class="new-game-button"
@click="startNewGame(i)"
>
Start a {{ ngString(i) }}
</button>
<div class="c-new-game-button-container">
<button
v-for="i in ngRange"
:key="i"
class="c-new-game-button"
@click="startNewGame(i)"
>
Start a {{ ngString(i) }}
</button>
</div>
</div>
</template>
<style scoped>
.new-game-container {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
z-index: 7;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.c-new-game-container {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 9;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: black;
box-shadow: 0 0 20px 1px black;
}
button {
margin-top: 1rem;
padding: 1rem;
font-family: Typewriter;
background: grey;
border: black;
border-radius: 5px;
cursor: pointer;
}
.c-new-game-button-container {
display: flex;
align-items: stretch;
flex-direction: column;
}
.c-new-game-button {
margin-top: 1rem;
padding: 1rem;
font-family: Typewriter;
background: grey;
border: black;
border-radius: 0.5rem;
cursor: pointer;
}
</style>

View File

@ -26,7 +26,7 @@ export default {
this.tabName = Pelle.transitionText(
this.tab.name,
Pelle.endTabNames[this.tabPosition],
Math.max(Math.min(Pelle.endState - (this.tab.id) % 4 / 10, 1), 0)
Math.max(Math.min(GameEnd.endState - (this.tab.id) % 4 / 10, 1), 0)
);
} else {
this.tabName = this.tab.name;

View File

@ -40,7 +40,7 @@ export default {
this.tabName = Pelle.transitionText(
this.tab.name,
Pelle.endTabNames[this.tabPosition],
Math.max(Math.min(Pelle.endState - (this.tab.id) % 4 / 10, 1), 0)
Math.max(Math.min(GameEnd.endState - (this.tab.id) % 4 / 10, 1), 0)
);
} else {
this.tabName = this.tab.name;