From c941ec2ba6b86c6f8bade211f6a597aa742edce6 Mon Sep 17 00:00:00 2001 From: Russell Stringer Date: Tue, 11 Jan 2022 12:42:20 -0500 Subject: [PATCH 1/2] only check cheevo conditional if player is missing it --- src/Achievements/Achievements.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Achievements/Achievements.ts b/src/Achievements/Achievements.ts index e8febf6ce..dd5d6ece4 100644 --- a/src/Achievements/Achievements.ts +++ b/src/Achievements/Achievements.ts @@ -759,13 +759,13 @@ export const achievements: IMap = { // { ID: "FLIGHT.EXE", Condition: () => Player.getHomeComputer().programs.includes(Programs.Flight.name) }, export function calculateAchievements(): void { - const availableAchievements = Object.values(achievements) - .filter((a) => a.Condition()) - .map((a) => a.ID); const playerAchievements = Player.achievements.map((a) => a.ID); - const newAchievements = availableAchievements.filter((a) => !playerAchievements.includes(a)); - for (const id of newAchievements) { + const missingAchievements = Object.values(achievements) + .filter((a) => !playerAchievements.includes(a.ID) && a.Condition()) + .map((a) => a.ID); + + for (const id of missingAchievements) { Player.giveAchievement(id); } From f59a1459652eca45d9d0608e665d1bc1571691c6 Mon Sep 17 00:00:00 2001 From: Russell Stringer Date: Tue, 11 Jan 2022 13:41:08 -0500 Subject: [PATCH 2/2] Hacknet server achievements grant associated hacknet node achieve fixes #1905 Added a new property to the Achievement interface to contain a list of additional achievements that should be granted when an achievement's conditional passes. Right now this is only used to unlock the 4 hacknet node achieves when the corresponding hacknet server achievement is awarded. This branch also changes the calculateAchievements function so it only runs the conditionals for achievements the player doesn't have, instead of checking all of them and then filtering out the unowned. --- src/Achievements/Achievements.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Achievements/Achievements.ts b/src/Achievements/Achievements.ts index dd5d6ece4..1693806d4 100644 --- a/src/Achievements/Achievements.ts +++ b/src/Achievements/Achievements.ts @@ -34,6 +34,7 @@ export interface Achievement { Secret?: boolean; Condition: () => boolean; Visible?: () => boolean; + AdditionalUnlock?: string[]; // IDs of achievements that should be awarded when awarding this one } export interface PlayerAchievement { @@ -510,12 +511,14 @@ export const achievements: IMap = { Icon: "HASHNET", Visible: () => hasAccessToSF(Player, 9), Condition: () => hasHacknetServers(Player) && Player.hacknetNodes.length > 0, + AdditionalUnlock: [achievementData.FIRST_HACKNET_NODE.ID], }, ALL_HACKNET_SERVER: { ...achievementData["ALL_HACKNET_SERVER"], Icon: "HASHNETALL", Visible: () => hasAccessToSF(Player, 9), Condition: () => hasHacknetServers(Player) && Player.hacknetNodes.length === HacknetServerConstants.MaxServers, + AdditionalUnlock: [achievementData["30_HACKNET_NODE"].ID], }, MAX_HACKNET_SERVER: { ...achievementData["MAX_HACKNET_SERVER"], @@ -537,12 +540,14 @@ export const achievements: IMap = { } return false; }, + AdditionalUnlock: [achievementData.MAX_HACKNET_NODE.ID], }, HACKNET_SERVER_1B: { ...achievementData["HACKNET_SERVER_1B"], Icon: "HASHNETMONEY", Visible: () => hasAccessToSF(Player, 9), Condition: () => hasHacknetServers(Player) && Player.moneySourceB.hacknet >= 1e9, + AdditionalUnlock: [achievementData.HACKNET_NODE_10M.ID], }, MAX_CACHE: { ...achievementData["MAX_CACHE"], @@ -763,7 +768,8 @@ export function calculateAchievements(): void { const missingAchievements = Object.values(achievements) .filter((a) => !playerAchievements.includes(a.ID) && a.Condition()) - .map((a) => a.ID); + // callback returns array of achievement id and id of any in the additional list, flatmap means we have only a 1D array + .flatMap((a) => [a.ID, ...(a.AdditionalUnlock || [])]); for (const id of missingAchievements) { Player.giveAchievement(id);