From 9597f3e89c0d5760ed7ded6710354a9f3eada688 Mon Sep 17 00:00:00 2001 From: Greg Considine Date: Mon, 1 Mar 2021 18:07:21 -0500 Subject: [PATCH] Add more achievements, refactor achievement code --- src/js/application.js | 10 +- src/js/game/achievement_manager.js | 28 ---- src/js/game/achievement_proxy.js | 29 ++++ src/js/game/blueprint.js | 2 +- src/js/game/core.js | 4 +- src/js/game/hub_goals.js | 7 + src/js/game/root.js | 6 +- src/js/game/shape_definition_manager.js | 5 +- src/js/game/systems/item_ejector.js | 6 + src/js/game/systems/wire.js | 7 + src/js/platform/achievement_provider.js | 138 ++++++++++++++++++ src/js/platform/achievements.js | 58 -------- .../browser/no_achievement_provider.js | 14 ++ src/js/platform/browser/no_achievements.js | 14 -- src/js/platform/browser/wrapper.js | 4 +- .../electron/steam_achievement_provider.js | 118 +++++++++++++++ .../platform/electron/steam_achievements.js | 132 ----------------- src/js/platform/electron/wrapper.js | 4 +- 18 files changed, 338 insertions(+), 248 deletions(-) delete mode 100644 src/js/game/achievement_manager.js create mode 100644 src/js/game/achievement_proxy.js create mode 100644 src/js/platform/achievement_provider.js delete mode 100644 src/js/platform/achievements.js create mode 100644 src/js/platform/browser/no_achievement_provider.js delete mode 100644 src/js/platform/browser/no_achievements.js create mode 100644 src/js/platform/electron/steam_achievement_provider.js delete mode 100644 src/js/platform/electron/steam_achievements.js diff --git a/src/js/application.js b/src/js/application.js index 80719111..2c632ef9 100644 --- a/src/js/application.js +++ b/src/js/application.js @@ -12,7 +12,7 @@ import { getPlatformName, waitNextFrame } from "./core/utils"; import { Vector } from "./core/vector"; import { AdProviderInterface } from "./platform/ad_provider"; import { NoAdProvider } from "./platform/ad_providers/no_ad_provider"; -import { NoAchievements } from "./platform/browser/no_achievements"; +import { NoAchievementProvider } from "./platform/browser/no_achievement_provider"; import { AnalyticsInterface } from "./platform/analytics"; import { GoogleAnalyticsImpl } from "./platform/browser/google_analytics"; import { SoundImplBrowser } from "./platform/browser/sound"; @@ -33,7 +33,7 @@ import { ShapezGameAnalytics } from "./platform/browser/game_analytics"; import { RestrictionManager } from "./core/restriction_manager"; /** - * @typedef {import("./platform/achievements").AchievementsInterface} AchievementsInterface + * @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface * @typedef {import("./platform/game_analytics").GameAnalyticsInterface} GameAnalyticsInterface * @typedef {import("./platform/sound").SoundInterface} SoundInterface * @typedef {import("./platform/storage").StorageInterface} StorageInterface @@ -87,8 +87,8 @@ export class Application { /** @type {PlatformWrapperInterface} */ this.platformWrapper = null; - /** @type {AchievementsInterface} */ - this.achievements = null; + /** @type {AchievementProviderInterface} */ + this.achievementProvider = null; /** @type {AdProviderInterface} */ this.adProvider = null; @@ -142,7 +142,7 @@ export class Application { this.sound = new SoundImplBrowser(this); this.analytics = new GoogleAnalyticsImpl(this); this.gameAnalytics = new ShapezGameAnalytics(this); - this.achievements = new NoAchievements(this); + this.achievementProvider = new NoAchievementProvider(this); } /** diff --git a/src/js/game/achievement_manager.js b/src/js/game/achievement_manager.js deleted file mode 100644 index 3218db7f..00000000 --- a/src/js/game/achievement_manager.js +++ /dev/null @@ -1,28 +0,0 @@ -/* typehints:start */ -import { GameRoot } from "./root"; -/* typehints:end */ - -import { globalConfig } from "../core/config"; -import { createLogger } from "../core/logging"; - -const logger = createLogger("achievement_manager"); - -export class AchievementManager { - constructor(root) { - this.root = root; - this.achievements = this.root.app.achievements; - - if (!this.achievements.hasAchievements()) { - logger.log("Achievements disabled"); - return; - } - - logger.log("There are", this.achievements.count, "achievements"); - - this.root.signals.achievementUnlocked.add(this.unlock, this); - } - - unlock (key) { - this.achievements.unlock(key); - } -} diff --git a/src/js/game/achievement_proxy.js b/src/js/game/achievement_proxy.js new file mode 100644 index 00000000..8e8dd802 --- /dev/null +++ b/src/js/game/achievement_proxy.js @@ -0,0 +1,29 @@ +/* typehints:start */ +import { GameRoot } from "./root"; +/* typehints:end */ + +import { createLogger } from "../core/logging"; + +const logger = createLogger("achievement_proxy"); + +export class AchievementProxy { + /** @param {GameRoot} root */ + constructor(root) { + this.root = root; + this.provider = this.root.app.achievementProvider; + + if (!this.provider.hasAchievements()) { + return; + } + + this.provider.initialize() + .then(() => { + this.root.signals.achievementUnlocked.add(this.provider.unlock, this.provider); + + logger.log("Listening for unlocked achievements"); + }) + .catch(err => { + logger.error("Ignoring achievement signals", err); + }) + } +} diff --git a/src/js/game/blueprint.js b/src/js/game/blueprint.js index 66f56623..3968a059 100644 --- a/src/js/game/blueprint.js +++ b/src/js/game/blueprint.js @@ -3,7 +3,7 @@ import { DrawParameters } from "../core/draw_parameters"; import { findNiceIntegerValue } from "../core/utils"; import { Vector } from "../core/vector"; import { Entity } from "./entity"; -import { ACHIEVEMENTS } from "../platform/achievements"; +import { ACHIEVEMENTS } from "../platform/achievement_provider"; import { GameRoot } from "./root"; export class Blueprint { diff --git a/src/js/game/core.js b/src/js/game/core.js index 03fa93d1..4de529bc 100644 --- a/src/js/game/core.js +++ b/src/js/game/core.js @@ -35,7 +35,7 @@ import { RegularGameMode } from "./modes/regular"; import { ProductionAnalytics } from "./production_analytics"; import { GameRoot } from "./root"; import { ShapeDefinitionManager } from "./shape_definition_manager"; -import { AchievementManager } from "./achievement_manager"; +import { AchievementProxy } from "./achievement_proxy"; import { SoundProxy } from "./sound_proxy"; import { GameTime } from "./time/game_time"; @@ -112,6 +112,7 @@ export class GameCore { root.logic = new GameLogic(root); root.hud = new GameHUD(root); root.time = new GameTime(root); + root.achievementProxy = new AchievementProxy(root); root.automaticSave = new AutomaticSave(root); root.soundProxy = new SoundProxy(root); @@ -119,7 +120,6 @@ export class GameCore { root.entityMgr = new EntityManager(root); root.systemMgr = new GameSystemManager(root); root.shapeDefinitionMgr = new ShapeDefinitionManager(root); - root.achievementMgr = new AchievementManager(root); root.hubGoals = new HubGoals(root); root.productionAnalytics = new ProductionAnalytics(root); root.buffers = new BufferMaintainer(root); diff --git a/src/js/game/hub_goals.js b/src/js/game/hub_goals.js index 9a945128..0c4cd9b5 100644 --- a/src/js/game/hub_goals.js +++ b/src/js/game/hub_goals.js @@ -1,6 +1,7 @@ import { globalConfig } from "../core/config"; import { RandomNumberGenerator } from "../core/rng"; import { clamp } from "../core/utils"; +import { ACHIEVEMENTS } from "../platform/achievement_provider"; import { BasicSerializableObject, types } from "../savegame/serialization"; import { enumColors } from "./colors"; import { enumItemProcessorTypes } from "./components/item_processor"; @@ -260,6 +261,12 @@ export class HubGoals extends BasicSerializableObject { this.computeNextGoal(); this.root.signals.storyGoalCompleted.dispatch(this.level - 1, reward); + + if (this.level - 1 === 20) { + this.root.signals.achievementUnlocked.dispatch(ACHIEVEMENTS.wires); + } else if (this.level - 1 === 26) { + this.root.signals.achievementUnlocked.dispatch(ACHIEVEMENTS.freedom); + } } /** diff --git a/src/js/game/root.js b/src/js/game/root.js index d0acdc17..d0659d79 100644 --- a/src/js/game/root.js +++ b/src/js/game/root.js @@ -8,7 +8,7 @@ import { createLogger } from "../core/logging"; import { GameTime } from "./time/game_time"; import { EntityManager } from "./entity_manager"; import { GameSystemManager } from "./game_system_manager"; -import { AchievementManager } from "./achievement_manager"; +import { AchievementProxy } from "./achievement_proxy"; import { GameHUD } from "./hud/hud"; import { MapView } from "./map_view"; import { Camera } from "./camera"; @@ -120,8 +120,8 @@ export class GameRoot { /** @type {SoundProxy} */ this.soundProxy = null; - /** @type {AchievementManager} */ - this.achievementMgr = null; + /** @type {AchievementProxy} */ + this.achievementProxy = null; /** @type {ShapeDefinitionManager} */ this.shapeDefinitionMgr = null; diff --git a/src/js/game/shape_definition_manager.js b/src/js/game/shape_definition_manager.js index 22438ce3..428f33fd 100644 --- a/src/js/game/shape_definition_manager.js +++ b/src/js/game/shape_definition_manager.js @@ -4,7 +4,7 @@ import { enumColors } from "./colors"; import { ShapeItem } from "./items/shape_item"; import { GameRoot } from "./root"; import { enumSubShape, ShapeDefinition } from "./shape_definition"; -import { ACHIEVEMENTS } from "../platform/achievements"; +import { ACHIEVEMENTS } from "../platform/achievement_provider"; const logger = createLogger("shape_definition_manager"); @@ -251,6 +251,9 @@ export class ShapeDefinitionManager extends BasicSerializableObject { return this.shapeKeyToDefinition[id]; } this.shapeKeyToDefinition[id] = definition; + + this.root.signals.achievementUnlocked.dispatch(ACHIEVEMENTS.theLogo, definition); + // logger.log("Registered shape with key (2)", id); return definition; } diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index a4484795..ebb3a16e 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -4,6 +4,7 @@ import { createLogger } from "../../core/logging"; import { Rectangle } from "../../core/rectangle"; import { StaleAreaDetector } from "../../core/stale_area_detector"; import { enumDirection, enumDirectionToVector } from "../../core/vector"; +import { ACHIEVEMENTS } from "../../platform/achievement_provider"; import { BaseItem } from "../base_item"; import { BeltComponent } from "../components/belt"; import { ItemAcceptorComponent } from "../components/item_acceptor"; @@ -274,6 +275,11 @@ export class ItemEjectorSystem extends GameSystemWithFilter { // It's a storage if (storageComp.canAcceptItem(item)) { storageComp.takeItem(item); + + if (storageComp.storedCount === 1) { + this.root.signals.achievementUnlocked.dispatch(ACHIEVEMENTS.storage); + } + return true; } diff --git a/src/js/game/systems/wire.js b/src/js/game/systems/wire.js index 4d0e6de4..25431efb 100644 --- a/src/js/game/systems/wire.js +++ b/src/js/game/systems/wire.js @@ -13,6 +13,7 @@ import { enumInvertedDirections, Vector, } from "../../core/vector"; +import { ACHIEVEMENTS } from "../../platform/achievement_provider"; import { BaseItem } from "../base_item"; import { arrayWireRotationVariantToType, MetaWireBuilding } from "../buildings/wire"; import { getCodeFromBuildingData } from "../building_codes"; @@ -697,6 +698,12 @@ export class WireSystem extends GameSystemWithFilter { return; } + if (entity.components.Wire && entity.registered && + this.root.entityMgr.componentToEntity.Wire.length === 100) { + + this.root.signals.achievementUnlocked.dispatch(ACHIEVEMENTS.networked); + } + // Invalidate affected area const originalRect = staticComp.getTileSpaceBounds(); const affectedArea = originalRect.expandedInAllDirections(1); diff --git a/src/js/platform/achievement_provider.js b/src/js/platform/achievement_provider.js new file mode 100644 index 00000000..85f57304 --- /dev/null +++ b/src/js/platform/achievement_provider.js @@ -0,0 +1,138 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + +export const ACHIEVEMENTS = { + painting: "painting", + cutting: "cutting", + rotating: "rotating", + stacking: "stacking", + blueprints: "blueprints", + wires: "wires", + storage: "storage", + freedom: "freedom", + networked: "networked", + theLogo: "theLogo", +}; + +export class AchievementProviderInterface { + /** @param {Application} app */ + constructor(app) { + this.app = app; + } + + /** + * Initializes the achievement provider. + * @returns {Promise} + */ + initialize() { + abstract; + return Promise.reject(); + } + + /** + * Call to unlock an achievement + * @param {string} [key] - A property within the ACHIEVEMENTS enum or empty if + * bypassing. + * @returns {void} + */ + unlock(key) { + abstract; + } + + /** + * Checks if achievements are supported in the current build + * @returns {boolean} + */ + hasAchievements() { + abstract; + return false; + } +} + +export class Achievement { + /** + * @param {string} key - An ACHIEVEMENTS key + */ + constructor (key) { + this.key = key; + this.unlock = null; + this.isValid = null; + } +} + +export class AchievementCollection { + /** + * @param {string[]} keys - An array of ACHIEVEMENTS keys + * @param {function} [activate] - Resolves when provider activation is complete + */ + constructor (keys, activate) { + this.map = new Map(); + this.activate = activate ? activate : () => Promise.resolve(); + + for (var i = 0; i < keys.length; i++) { + assert(ACHIEVEMENTS[keys[i]], "Achievement does not exist: " + keys[i]); + + const achievement = new Achievement(keys[i]); + this.setValidation(achievement); + this.map.set(keys[i], achievement); + } + } + + /** + * @param {string} key - Maps to an Achievement + * @returns {boolean} + */ + has(key) { + return this.map.has(key); + } + + /** + * @param {string} key - Maps to an Achievement + * @param {*} [details] - Additional information as needed to validate + * @returns {boolean} + */ + isValid(key, details) { + return this.map.get(key).isValid(details); + } + + /** + * @param {string} key - Maps to an Achievement + * @returns {Promise} + */ + unlock(key) { + const achievement = this.map.get(key); + + return achievement.unlock = achievement.unlock || this.activate(achievement) + .then(() => { + this.map.delete(key); + }) + .catch(err => { + achievement.unlock = null; + + throw err; + }) + } + + /** + * @param {Achievement} achievement - Achievement receiving a validation function + */ + setValidation(achievement) { + switch (achievement.key) { + case ACHIEVEMENTS.theLogo: + achievement.isValid = this.isTheLogoValid; + break; + default: + achievement.isValid = () => true; + break; + } + } + + /** + * @param {string} shortKey - The shape's shortKey to check + * @returns {boolean} + */ + isTheLogoValid(shortKey) { + return shortKey === "RuCw--Cw:----Ru--"; + } +} diff --git a/src/js/platform/achievements.js b/src/js/platform/achievements.js deleted file mode 100644 index 32c3ae06..00000000 --- a/src/js/platform/achievements.js +++ /dev/null @@ -1,58 +0,0 @@ -/* typehints:start */ -import { Application } from "../application"; -/* typehints:end */ - -export const ACHIEVEMENTS = { - painting: "painting", - cutting: "cutting", - rotating: "rotating", - stacking: "stacking", - blueprints: "blueprints", -} - -export class AchievementsInterface { - /** @param {Application} app */ - constructor(app) { - this.app = app; - } - - /** - * Load achievements into an initial state, bypassing unlocked and/or - * irrelevant achievements where possible. - * - * @params key - * @returns {Promise} - */ - load() { - abstract; - return Promise.reject(); - } - - /** - * Call to unlock an achievement - * @params {string} [key] - A property within the ACHIEVEMENTS enum or empty if - * bypassing. - * @returns {void} - */ - unlock(key) { - abstract; - } - - /** - * Initializes the list of achievements. - * @returns {Promise} - */ - initialize() { - abstract; - return Promise.reject(); - } - - /** - * Checks if achievements are supported in the current build - * @returns {boolean} - */ - hasAchievements() { - abstract; - return false; - } -} diff --git a/src/js/platform/browser/no_achievement_provider.js b/src/js/platform/browser/no_achievement_provider.js new file mode 100644 index 00000000..f519f924 --- /dev/null +++ b/src/js/platform/browser/no_achievement_provider.js @@ -0,0 +1,14 @@ +import { AchievementProviderInterface } from "../achievement_provider"; + +export class NoAchievementProvider extends AchievementProviderInterface { + hasAchievements() { + return false; + } + + initialize() { + return Promise.resolve(); + } + + unlock() { + } +} diff --git a/src/js/platform/browser/no_achievements.js b/src/js/platform/browser/no_achievements.js deleted file mode 100644 index 65075212..00000000 --- a/src/js/platform/browser/no_achievements.js +++ /dev/null @@ -1,14 +0,0 @@ -import { AchievementsInterface } from "../achievements"; - -export class NoAchievements extends AchievementsInterface { - load() { - return Promise.resolve(); - } - - hasAchievements() { - return false; - } - - unlock() { - } -} diff --git a/src/js/platform/browser/wrapper.js b/src/js/platform/browser/wrapper.js index 02488ebe..5011d32b 100644 --- a/src/js/platform/browser/wrapper.js +++ b/src/js/platform/browser/wrapper.js @@ -4,7 +4,7 @@ import { queryParamOptions } from "../../core/query_parameters"; import { clamp } from "../../core/utils"; import { GamedistributionAdProvider } from "../ad_providers/gamedistribution"; import { NoAdProvider } from "../ad_providers/no_ad_provider"; -import { SteamAchievements } from "../electron/steam_achievements"; +import { SteamAchievementProvider } from "../electron/steam_achievement_provider"; import { PlatformWrapperInterface } from "../wrapper"; import { StorageImplBrowser } from "./storage"; import { StorageImplBrowserIndexedDB } from "./storage_indexed_db"; @@ -72,7 +72,7 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface { if (G_IS_DEV && globalConfig.debug.testAchievements) { logger.log("Testing achievements"); - this.app.achievements = new SteamAchievements(this.app); + this.app.achievementProvider = new SteamAchievementProvider(this.app); } return this.detectStorageImplementation() diff --git a/src/js/platform/electron/steam_achievement_provider.js b/src/js/platform/electron/steam_achievement_provider.js new file mode 100644 index 00000000..19121681 --- /dev/null +++ b/src/js/platform/electron/steam_achievement_provider.js @@ -0,0 +1,118 @@ +/* typehints:start */ +import { Application } from "../../application"; +import { Achievement } from "../achievement_provider"; +/* typehints:end */ + +import { createLogger } from "../../core/logging"; +import { getIPCRenderer } from "../../core/utils"; +import { + ACHIEVEMENTS, + AchievementCollection, + AchievementProviderInterface +} from "../achievement_provider"; + +const logger = createLogger("achievements/steam"); + +const ACHIEVEMENT_IDS = { + [ACHIEVEMENTS.painting]: "", + [ACHIEVEMENTS.cutting]: "achievement_01", // Test ID + [ACHIEVEMENTS.rotating]: "", + [ACHIEVEMENTS.stacking]: "", + [ACHIEVEMENTS.blueprints]: "", + [ACHIEVEMENTS.wires]: "", + [ACHIEVEMENTS.storage]: "", + [ACHIEVEMENTS.freedom]: "", + [ACHIEVEMENTS.networked]: "", + [ACHIEVEMENTS.theLogo]: "" +}; + +export class SteamAchievementProvider extends AchievementProviderInterface { + /** @param {Application} app */ + constructor(app) { + super(app); + + this.initialized = false; + this.collection = new AchievementCollection( + Object.keys(ACHIEVEMENT_IDS), + this.activate.bind(this) + ); + + logger.log("Steam achievement collection created"); + } + + initialize () { + if (!G_IS_STANDALONE) { + logger.warn("Steam listener isn't active. Achievements won't sync."); + return Promise.resolve(); + } + + this.ipc = getIPCRenderer(); + + return this.ipc.invoke("steam:is-initialized") + .then(initialized => { + if (!initialized) { + logger.warn("Steam failed to intialize. Achievements won't sync."); + return; + } + + this.initialized = true; + + logger.log("Steam achievement provider initialized"); + }) + .catch(err => { + logger.error("Steam achievement provider error", err); + throw err; + }) + } + + /** + * @param {string} key - Maps to an Achievement + * @param {*} [details] - Additional information as needed to validate + */ + unlock (key, details) { + if (!this.collection.has(key)) { + console.log("Achievement already unlocked", key); + return; + } + + if (!this.collection.isValid(key, details)) { + console.log("Achievement is invalid", key); + return; + } + + this.collection.unlock(key) + .then(() => { + logger.log("Achievement unlocked:", key); + }) + .catch(err => { + logger.error("Failed to unlock achievement", err); + }) + } + + /** + * @param {string} key - Maps to an API ID for the achievement + * @returns {string} + */ + getApiId (key) { + return ACHIEVEMENT_IDS[key]; + } + + /** + * @param {Achievement} achievement + * @returns {Promise} + */ + activate (achievement) { + if (!this.initialized) { + return Promise.resolve(); + } + + return this.ipc.invoke("steam:activate-achievement", this.getApiId(achievement.key)) + } + + /** + * @returns {boolean} + */ + hasAchievements() { + return true; + } +} diff --git a/src/js/platform/electron/steam_achievements.js b/src/js/platform/electron/steam_achievements.js deleted file mode 100644 index 1137e243..00000000 --- a/src/js/platform/electron/steam_achievements.js +++ /dev/null @@ -1,132 +0,0 @@ -import { globalConfig } from "../../core/config"; -import { createLogger } from "../../core/logging"; -import { getIPCRenderer } from "../../core/utils"; -import { ACHIEVEMENTS, AchievementsInterface } from "../achievements"; - -const logger = createLogger("achievements/steam"); - -const IDS = { - painting: "", - cutting: "achievement_01", // Test ID - rotating: "", - stacking: "", - blueprints: "", - wires: "", -} - -/** @typedef {object} SteamAchievement - * @property {string} id - * @property {string} key - * @property {boolean} unlocked - * @property {boolean} relevant - * @property {?Promise} activate - */ - -/** @typedef {Map} SteamAchievementMap */ - -export class SteamAchievements extends AchievementsInterface { - constructor(app) { - super(app); - - /** @type {SteamAchievementMap} */ - this.map = new Map(); - this.type = "Steam"; - this.count = 0; - this.steamInitialized = false; - - - logger.log("Initializing", this.type, "achievements"); - - for (let key in ACHIEVEMENTS) { - this.map.set(key, { - id: IDS[key], - key: key, - unlocked: false, - relevant: true, - activate: null - }); - - this.count++; - } - - this.load() - } - - load () { - // TODO: inspect save file and update achievements - - if (!G_IS_STANDALONE) { - logger.warn("Steam listener isn't active. Achievements won't sync."); - return Promise.resolve(); - } - - this.ipc = getIPCRenderer(); - - return this.ipc.invoke("steam:is-initialized") - .then(initialized => { - if (!initialized) { - logger.warn("Steam failed to intialize. Achievements won't sync."); - return; - } - - logger.log("Steam listener is active"); - - this.steamInitialized = true; - - return this.ipc.invoke("steam:get-achievement-names") - .then(result => { - logger.log("steam:get-achievement-names", result); - }); - }) - .catch(err => { - logger.error(err); - }) - } - - /** - * @param {string} key - */ - unlock (key) { - if (!this.map.has(key)) { - logger.warn("Achievement does not exist:", key); - return; - } - - let achievement = this.map.get(key); - - if (!achievement.relevant) { - console.log("Achievement unlocked/irrelevant:", key); - return; - } - - achievement.activate = achievement.activate || this.activate(achievement) - .then(() => { - achievement.unlocked = true; - achievement.relevant = false; - - logger.log("Achievement unlocked:", key); - }) - .catch(err => { - logger.error("Failed to unlock achievement", err); - }) - .finally(() => { - achievement.activate = null; - }) - - } - - /** - * @param {SteamAchievement} achievement - */ - activate (achievement) { - if (!this.steamInitialized) { - return Promise.resolve(); - } - - return this.ipc.invoke("steam:activate-achievement", achievement.id) - } - - hasAchievements() { - return true; - } -} diff --git a/src/js/platform/electron/wrapper.js b/src/js/platform/electron/wrapper.js index 4663e27a..dcc57189 100644 --- a/src/js/platform/electron/wrapper.js +++ b/src/js/platform/electron/wrapper.js @@ -2,7 +2,7 @@ import { PlatformWrapperImplBrowser } from "../browser/wrapper"; import { getIPCRenderer } from "../../core/utils"; import { createLogger } from "../../core/logging"; import { StorageImplElectron } from "./storage"; -import { SteamAchievements } from "./steam_achievements"; +import { SteamAchievementProvider } from "./steam_achievement_provider"; import { PlatformWrapperInterface } from "../wrapper"; const logger = createLogger("electron-wrapper"); @@ -20,7 +20,7 @@ export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser { this.app.ticker.frameEmitted.add(this.steamOverlayFixRedrawCanvas, this); this.app.storage = new StorageImplElectron(this); - this.app.achievements = new SteamAchievements(this.app); + this.app.achievementProvider = new SteamAchievementProvider(this.app); return PlatformWrapperInterface.prototype.initialize.call(this); }