Add unlocking methods for glyph cosmetics

This commit is contained in:
SpectralFlame 2022-11-17 14:33:50 -06:00 committed by cyip92
parent 83a9da6574
commit ad5e0b133e
5 changed files with 87 additions and 20 deletions

View File

@ -54,6 +54,10 @@ const secretImports = [
"857876556a230da15fe1bb6f410ca8dbc9274de47c1a847c2281a7103dd2c274", "857876556a230da15fe1bb6f410ca8dbc9274de47c1a847c2281a7103dd2c274",
"be88e62eb68758cd7381104977c0d3d5d81e19c72a848f0d79d1963c1e39221f", "be88e62eb68758cd7381104977c0d3d5d81e19c72a848f0d79d1963c1e39221f",
"c784c9c0a82b5f3c13884842fa6e6a8f5aed994ef401e6476c30b1adfe439b22", "c784c9c0a82b5f3c13884842fa6e6a8f5aed994ef401e6476c30b1adfe439b22",
"f3a71114261b4af6517a53f89bf0c6b56bb81b6f0e931d0e0d71249eb196628c",
"ea8003b832d73a30ebbe9e889c583989e1e6985c74ccbc149f5b7c183975ea97",
"8c8f5a86418e6c166d595f487e6a3ebd372dc5686960a2b5a4ab85aa7bd8a3cf",
"5869b9b82c6f076495facc820bdb27335d6b48272e9f5044844bba6bce6870fb",
]; ];
function secretImportIndex(data) { function secretImportIndex(data) {
@ -67,23 +71,39 @@ export function isSecretImport(data) {
export function tryImportSecret(data) { export function tryImportSecret(data) {
const index = secretImportIndex(data); const index = secretImportIndex(data);
if (index === 0) {
FullScreenAnimationHandler.display("a-barrel-roll", 5); switch (index) {
SecretAchievement(15).unlock(); case 0:
return true; FullScreenAnimationHandler.display("a-barrel-roll", 5);
SecretAchievement(15).unlock();
return true;
case 1:
SecretAchievement(14).unlock();
return true;
case 2:
SecretAchievement(37).unlock();
return true;
case 3:
if (player.records.fullGameCompletions > 0 || DEV) Speedrun.unlock();
else GameUI.notify.error("Complete the game at least once first!", 15000);
return true;
case 4:
if (!Themes.available().map(t => t.name).includes("S11")) return true;
if (GlyphAppearanceHandler.unlockSet("blob")) return true;
if (GlyphAppearanceHandler.unlockSet("blob2")) return true;
// This is a :blobsad:
GameUI.notify.error(`No more blobs \uE015`, 5000);
return true;
case 5:
GlyphAppearanceHandler.unlockSet("currency");
return true;
case 6:
GlyphAppearanceHandler.unlockSet("chess");
return true;
case 7:
GlyphAppearanceHandler.unlockSet("planet");
return true;
default:
return false;
} }
if (index === 1) {
SecretAchievement(14).unlock();
return true;
}
if (index === 2) {
SecretAchievement(37).unlock();
return true;
}
if (index === 3) {
if (player.records.fullGameCompletions > 0 || DEV) Speedrun.unlock();
else GameUI.notify.error("Complete the game at least once first!", 15000);
return true;
}
return false;
} }

View File

@ -166,5 +166,32 @@ export const GlyphAppearanceHandler = {
return `rgb(${r[i] * (1 - f) + r[i + 1] * f}, return `rgb(${r[i] * (1 - f) + r[i + 1] * f},
${g[i] * (1 - f) + g[i + 1] * f}, ${g[i] * (1 - f) + g[i + 1] * f},
${b[i] * (1 - f) + b[i + 1] * f})`; ${b[i] * (1 - f) + b[i + 1] * f})`;
},
get unlockedSets() {
return player.reality.glyphs.cosmetics.availableSets;
},
get lockedSets() {
return Object.keys(GameDatabase.reality.glyphCosmeticSets)
.filter(set => !player.reality.glyphs.cosmetics.availableSets.includes(set));
},
// Attempts to unlock a specific given set, or a random one if none is given
unlockSet(name) {
const lockedSets = this.lockedSets;
let unlocked;
if (name && lockedSets.includes(name)) {
unlocked = name;
} else if (!name && lockedSets.length > 0) {
// If the player wants to refresh-scum this then we let them (there's probably already going to be an infinite
// lootbox cycle mechanic anyway)
unlocked = lockedSets[Math.floor(Math.random() * lockedSets.length)];
} else {
return false;
}
player.reality.glyphs.cosmetics.availableSets.push(unlocked);
const entry = GameDatabase.reality.glyphCosmeticSets[unlocked];
GameUI.notify.info(`You have unlocked the "${entry.name}" Set for Glyph cosmetics!`, 10000);
return true;
} }
}; };

View File

@ -17,6 +17,8 @@ export const NG = {
const automatorConstants = JSON.stringify(player.reality.automator.constants); const automatorConstants = JSON.stringify(player.reality.automator.constants);
const automatorScripts = JSON.stringify(player.reality.automator.scripts); const automatorScripts = JSON.stringify(player.reality.automator.scripts);
const fullCompletions = player.records.fullGameCompletions; const fullCompletions = player.records.fullGameCompletions;
GlyphAppearanceHandler.unlockSet();
const cosmeticSets = JSON.stringify(player.reality.glyphs.cosmetics.availableSets);
Modal.hideAll(); Modal.hideAll();
Quote.clearAll(); Quote.clearAll();
GameStorage.hardReset(); GameStorage.hardReset();
@ -28,6 +30,7 @@ export const NG = {
player.records.fullGameCompletions = fullCompletions + 1; player.records.fullGameCompletions = fullCompletions + 1;
ui.view.newUI = player.options.newUI; ui.view.newUI = player.options.newUI;
ui.view.news = player.options.news.enabled; ui.view.news = player.options.news.enabled;
player.reality.glyphs.cosmetics.availableSets = JSON.parse(cosmeticSets);
Themes.find(Theme.currentName()).set(); Themes.find(Theme.currentName()).set();
Notations.all.find(n => n.name === player.options.notation).setAsCurrent(); Notations.all.find(n => n.name === player.options.notation).setAsCurrent();
ADNotations.Settings.exponentCommas.show = player.options.commas; ADNotations.Settings.exponentCommas.show = player.options.commas;

View File

@ -21,9 +21,12 @@ export const Speedrun = {
}, },
// Hard-resets the current save and puts it in a state ready to be "unpaused" once resources start being generated // Hard-resets the current save and puts it in a state ready to be "unpaused" once resources start being generated
prepareSave(name) { prepareSave(name) {
// Carry full completion count and cosmetic saves into speedrun mode as well
const fullCompletions = player.records.fullGameCompletions; const fullCompletions = player.records.fullGameCompletions;
const cosmeticSets = JSON.stringify(player.reality.glyphs.cosmetics.availableSets);
GameStorage.hardReset(); GameStorage.hardReset();
player.records.fullGameCompletions = fullCompletions; player.records.fullGameCompletions = fullCompletions;
player.reality.glyphs.cosmetics.availableSets = JSON.parse(cosmeticSets);
player.speedrun.isUnlocked = true; player.speedrun.isUnlocked = true;
player.speedrun.isActive = true; player.speedrun.isActive = true;

View File

@ -11,7 +11,8 @@ export default {
style() { style() {
return { return {
opacity: this.opacity, opacity: this.opacity,
visibility: this.visible ? "visible" : "hidden" visibility: this.visible ? "visible" : "hidden",
hasMoreCosmetics: false,
}; };
} }
}, },
@ -19,6 +20,7 @@ export default {
update() { update() {
this.visible = GameEnd.endState > END_STATE_MARKERS.SHOW_NEW_GAME && !GameEnd.removeAdditionalEnd; this.visible = GameEnd.endState > END_STATE_MARKERS.SHOW_NEW_GAME && !GameEnd.removeAdditionalEnd;
this.opacity = (GameEnd.endState - END_STATE_MARKERS.SHOW_NEW_GAME) * 2; this.opacity = (GameEnd.endState - END_STATE_MARKERS.SHOW_NEW_GAME) * 2;
this.hasMoreCosmetics = GlyphAppearanceHandler.lockedSets.length > 0;
}, },
startNewGame() { startNewGame() {
NG.startNewGame(); NG.startNewGame();
@ -33,7 +35,7 @@ export default {
:style="style" :style="style"
> >
<h2> <h2>
Reset the entire game, but keep Automator Scripts, Secret Themes, Secret Achievements, and Options Reset the entire game, but keep Automator Scripts, Secret Themes, Secret Achievements, and Options.
</h2> </h2>
<h3>You can use the button in the top-right to view the game as it is right now.</h3> <h3>You can use the button in the top-right to view the game as it is right now.</h3>
<div class="c-new-game-button-container"> <div class="c-new-game-button-container">
@ -44,6 +46,18 @@ export default {
Start over? Start over?
</button> </button>
</div> </div>
<br>
<h3 v-if="hasMoreCosmetics">
Upon restarting the game, you will also unlock a random new cosmetic set for your Glyphs. These are freely
modifiable once you reach Reality again, but are purely visual and offer no gameplay bonuses.
</h3>
<h3 v-else>
You have unlocked all Glyph cosmetic sets!
</h3>
<br>
<h3>
You can also import "speedrun" to start the game again with additional tracking for speedrunning purposes.
</h3>
</div> </div>
</template> </template>