From 7ca3bf96641ade1919b30641b30d47d6a47d5dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D1=97=D0=BB=20=D0=93=D1=80=D0=B8?= =?UTF-8?q?=D0=B3=D0=BE=D1=80=27=D1=94=D0=B2?= Date: Tue, 8 Apr 2025 15:39:14 +0300 Subject: [PATCH 1/2] Remove achievement support Suggested by @SkimnerPhi. If needed, mods should provide their own support for achievements. For vanilla this is dead code. --- src/js/application.js | 3 - src/js/core/config.local.template.js | 3 - src/js/core/config.ts | 3 - src/js/game/achievement_proxy.js | 154 ----- src/js/game/blueprint.js | 8 - src/js/game/buildings/trash.js | 22 - src/js/game/core.js | 8 - src/js/game/game_mode.js | 11 +- src/js/game/hud/parts/mass_selector.js | 4 - src/js/game/hud/parts/waypoints.js | 5 - src/js/game/modes/regular.js | 57 +- src/js/game/root.js | 48 +- src/js/game/shape_definition_manager.js | 9 - src/js/game/systems/wire.js | 8 +- src/js/platform/achievement_provider.js | 647 --------------------- src/js/platform/no_achievement_provider.js | 23 - src/js/platform/wrapper.js | 15 +- 17 files changed, 53 insertions(+), 975 deletions(-) delete mode 100644 src/js/game/achievement_proxy.js delete mode 100644 src/js/platform/achievement_provider.js delete mode 100644 src/js/platform/no_achievement_provider.js diff --git a/src/js/application.js b/src/js/application.js index 0985bd15..421f50d2 100644 --- a/src/js/application.js +++ b/src/js/application.js @@ -12,7 +12,6 @@ import { Vector } from "./core/vector"; import { MOD_SIGNALS } from "./mods/mod_signals"; import { MODS } from "./mods/modloader"; import { ClientAPI } from "./platform/api"; -import { NoAchievementProvider } from "./platform/no_achievement_provider"; import { Sound } from "./platform/sound"; import { Storage } from "./platform/storage"; import { PlatformWrapperImplElectron } from "./platform/wrapper"; @@ -30,7 +29,6 @@ import { PuzzleMenuState } from "./states/puzzle_menu"; import { SettingsState } from "./states/settings"; /** - * @typedef {import("./platform/achievement_provider").AchievementProviderInterface} AchievementProviderInterface * @typedef {import("./platform/sound").SoundInterface} SoundInterface */ @@ -74,7 +72,6 @@ export class Application { this.platformWrapper = new PlatformWrapperImplElectron(this); this.sound = new Sound(this); - this.achievementProvider = new NoAchievementProvider(this); // Track if the window is focused (only relevant for browser) this.focused = true; diff --git a/src/js/core/config.local.template.js b/src/js/core/config.local.template.js index 62925b13..7e822bae 100644 --- a/src/js/core/config.local.template.js +++ b/src/js/core/config.local.template.js @@ -59,9 +59,6 @@ export default { // Enables ads in the local build (normally they are deactivated there) // testAds: true, // ----------------------------------------------------------------------------------- - // Allows unlocked achievements to be logged to console in the local build - // testAchievements: true, - // ----------------------------------------------------------------------------------- // Enables use of (some) existing flags within the puzzle mode context // testPuzzleMode: true, // ----------------------------------------------------------------------------------- diff --git a/src/js/core/config.ts b/src/js/core/config.ts index 8b67b9b5..dcff1710 100644 --- a/src/js/core/config.ts +++ b/src/js/core/config.ts @@ -41,9 +41,6 @@ export const globalConfig = { assetsSharpness: 1.5, shapesSharpness: 1.3, - // Achievements - achievementSliceDuration: 10, // Seconds - // Production analytics statisticsGraphDpi: 2.5, statisticsGraphSlices: 100, diff --git a/src/js/game/achievement_proxy.js b/src/js/game/achievement_proxy.js deleted file mode 100644 index 74874289..00000000 --- a/src/js/game/achievement_proxy.js +++ /dev/null @@ -1,154 +0,0 @@ -/* typehints:start */ -import { Entity } from "./entity"; -import { GameRoot } from "./root"; -/* typehints:end */ - -import { globalConfig } from "../core/config"; -import { createLogger } from "../core/logging"; -import { ACHIEVEMENTS } from "../platform/achievement_provider"; -import { getBuildingDataFromCode } from "./building_codes"; - -const logger = createLogger("achievement_proxy"); - -const ROTATOR = "rotator"; -const DEFAULT = "default"; - -export class AchievementProxy { - /** @param {GameRoot} root */ - constructor(root) { - this.root = root; - this.provider = this.root.app.achievementProvider; - this.disabled = true; - - if (G_IS_DEV && globalConfig.debug.testAchievements) { - // still enable the proxy - } else if (!this.provider.hasAchievements()) { - return; - } - - this.sliceTime = 0; - - this.root.signals.postLoadHook.add(this.onLoad, this); - } - - onLoad() { - if (!this.root.gameMode.hasAchievements()) { - logger.log("Disabling achievements because game mode does not have achievements"); - this.disabled = true; - return; - } - - this.provider - .onLoad(this.root) - .then(() => { - this.disabled = false; - logger.log("Recieving achievement signals"); - this.initialize(); - }) - .catch(err => { - this.disabled = true; - logger.error("Ignoring achievement signals", err); - }); - } - - initialize() { - this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.darkMode, null); - - if (this.has(ACHIEVEMENTS.mam)) { - this.root.signals.entityAdded.add(this.onMamFailure, this); - this.root.signals.entityDestroyed.add(this.onMamFailure, this); - this.root.signals.storyGoalCompleted.add(this.onStoryGoalCompleted, this); - } - - if (this.has(ACHIEVEMENTS.noInverseRotator)) { - this.root.signals.entityAdded.add(this.onEntityAdded, this); - } - - this.startSlice(); - } - - startSlice() { - this.sliceTime = this.root.time.now(); - - this.root.signals.bulkAchievementCheck.dispatch( - ACHIEVEMENTS.storeShape, - this.sliceTime, - ACHIEVEMENTS.throughputBp25, - this.sliceTime, - ACHIEVEMENTS.throughputBp50, - this.sliceTime, - ACHIEVEMENTS.throughputLogo25, - this.sliceTime, - ACHIEVEMENTS.throughputLogo50, - this.sliceTime, - ACHIEVEMENTS.throughputRocket10, - this.sliceTime, - ACHIEVEMENTS.throughputRocket20, - this.sliceTime, - ACHIEVEMENTS.play1h, - this.sliceTime, - ACHIEVEMENTS.play10h, - this.sliceTime, - ACHIEVEMENTS.play20h, - this.sliceTime - ); - } - - update() { - if (this.disabled) { - return; - } - - if (this.root.time.now() - this.sliceTime > globalConfig.achievementSliceDuration) { - this.startSlice(); - } - } - - /** - * @param {string} key - * @returns {boolean} - */ - has(key) { - if (!this.provider.collection) { - return false; - } - return this.provider.collection.map.has(key); - } - - /** @param {Entity} entity */ - onEntityAdded(entity) { - if (!entity.components.StaticMapEntity) { - return; - } - - const building = getBuildingDataFromCode(entity.components.StaticMapEntity.code); - - if (building.metaInstance.id !== ROTATOR) { - return; - } - - if (building.variant === DEFAULT) { - return; - } - - this.root.savegame.currentData.stats.usedInverseRotator = true; - this.root.signals.entityAdded.remove(this.onEntityAdded); - } - - /** @param {number} level */ - onStoryGoalCompleted(level) { - if (level > 26) { - this.root.signals.entityAdded.add(this.onMamFailure, this); - this.root.signals.entityDestroyed.add(this.onMamFailure, this); - } - - this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.mam, null); - - // reset on every level - this.root.savegame.currentData.stats.failedMam = false; - } - - onMamFailure() { - this.root.savegame.currentData.stats.failedMam = true; - } -} diff --git a/src/js/game/blueprint.js b/src/js/game/blueprint.js index e195df9f..34e4ed23 100644 --- a/src/js/game/blueprint.js +++ b/src/js/game/blueprint.js @@ -3,7 +3,6 @@ import { DrawParameters } from "../core/draw_parameters"; import { findNiceIntegerValue } from "../core/utils"; import { Vector } from "../core/vector"; import { Entity } from "./entity"; -import { ACHIEVEMENTS } from "../platform/achievement_provider"; import { GameRoot } from "./root"; export class Blueprint { @@ -178,13 +177,6 @@ export class Blueprint { count++; } - root.signals.bulkAchievementCheck.dispatch( - ACHIEVEMENTS.placeBlueprint, - count, - ACHIEVEMENTS.placeBp1000, - count - ); - return count !== 0; }); }); diff --git a/src/js/game/buildings/trash.js b/src/js/game/buildings/trash.js index fcf7f11f..87dbcf09 100644 --- a/src/js/game/buildings/trash.js +++ b/src/js/game/buildings/trash.js @@ -1,6 +1,5 @@ import { generateMatrixRotations } from "../../core/utils"; import { enumDirection, Vector } from "../../core/vector"; -import { ACHIEVEMENTS } from "../../platform/achievement_provider"; import { ItemAcceptorComponent } from "../components/item_acceptor"; import { enumItemProcessorTypes, ItemProcessorComponent } from "../components/item_processor"; import { Entity } from "../entity"; @@ -47,25 +46,6 @@ export class MetaTrashBuilding extends MetaBuilding { return root.hubGoals.isRewardUnlocked(enumHubGoalRewards.reward_cutter_and_trash); } - addAchievementReceiver(entity) { - if (!entity.root) { - return; - } - - const itemProcessor = entity.components.ItemProcessor; - const tryTakeItem = itemProcessor.tryTakeItem.bind(itemProcessor); - - itemProcessor.tryTakeItem = () => { - const taken = tryTakeItem(...arguments); - - if (taken) { - entity.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.trash1000, 1); - } - - return taken; - }; - } - /** * Creates the entity at the given location * @param {Entity} entity @@ -100,7 +80,5 @@ export class MetaTrashBuilding extends MetaBuilding { processorType: enumItemProcessorTypes.trash, }) ); - - this.addAchievementReceiver(entity); } } diff --git a/src/js/game/core.js b/src/js/game/core.js index f6f4e947..0abc6f48 100644 --- a/src/js/game/core.js +++ b/src/js/game/core.js @@ -20,7 +20,6 @@ import { Vector } from "../core/vector"; import { MOD_SIGNALS } from "../mods/mod_signals"; import { Savegame } from "../savegame/savegame"; import { SavegameSerializer } from "../savegame/savegame_serializer"; -import { AchievementProxy } from "./achievement_proxy"; import { AutomaticSave } from "./automatic_save"; import { MetaHubBuilding } from "./buildings/hub"; import { Camera } from "./camera"; @@ -115,7 +114,6 @@ 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); @@ -154,9 +152,6 @@ export class GameCore { // Update analytics root.productionAnalytics.update(); - - // Check achievements - root.achievementProxy.update(); } }); } @@ -290,9 +285,6 @@ export class GameCore { // Update analytics root.productionAnalytics.update(); - - // Check achievements - root.achievementProxy.update(); } // Update automatic save after everything finished diff --git a/src/js/game/game_mode.js b/src/js/game/game_mode.js index 377512bb..a49d94f3 100644 --- a/src/js/game/game_mode.js +++ b/src/js/game/game_mode.js @@ -2,12 +2,12 @@ import { GameRoot } from "./root"; /* typehints:end */ -import { Rectangle } from "../core/rectangle"; import { gGameModeRegistry } from "../core/global_registries"; -import { types, BasicSerializableObject } from "../savegame/serialization"; -import { MetaBuilding } from "./meta_building"; +import { Rectangle } from "../core/rectangle"; +import { BasicSerializableObject } from "../savegame/serialization"; import { MetaItemProducerBuilding } from "./buildings/item_producer"; import { BaseHUDPart } from "./hud/base_hud_part"; +import { MetaBuilding } from "./meta_building"; /** @enum {string} */ export const enumGameModeIds = { @@ -112,11 +112,6 @@ export class GameMode extends BasicSerializableObject { return true; } - /** @returns {boolean} */ - hasAchievements() { - return false; - } - /** @returns {number} */ getMinimumZoom() { return 0.06; diff --git a/src/js/game/hud/parts/mass_selector.js b/src/js/game/hud/parts/mass_selector.js index 520505cb..0a8a3633 100644 --- a/src/js/game/hud/parts/mass_selector.js +++ b/src/js/game/hud/parts/mass_selector.js @@ -4,7 +4,6 @@ import { createLogger } from "../../../core/logging"; import { STOP_PROPAGATION } from "../../../core/signal"; import { formatBigNumberFull } from "../../../core/utils"; import { Vector } from "../../../core/vector"; -import { ACHIEVEMENTS } from "../../../platform/achievement_provider"; import { T } from "../../../translations"; import { Blueprint } from "../../blueprint"; import { enumMouseButton } from "../../camera"; @@ -16,7 +15,6 @@ import { BaseHUDPart } from "../base_hud_part"; /* typehints:start */ // @ts-ignore -import { Component } from "../../component"; /* typehints:end */ const logger = createLogger("hud/mass_selector"); @@ -121,8 +119,6 @@ export class HUDMassSelector extends BaseHUDPart { count++; } } - - this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.destroy1000, count); }); // Clear uids later diff --git a/src/js/game/hud/parts/waypoints.js b/src/js/game/hud/parts/waypoints.js index f21c5e1e..e6a9b848 100644 --- a/src/js/game/hud/parts/waypoints.js +++ b/src/js/game/hud/parts/waypoints.js @@ -15,7 +15,6 @@ import { removeAllChildren, } from "../../../core/utils"; import { Vector } from "../../../core/vector"; -import { ACHIEVEMENTS } from "../../../platform/achievement_provider"; import { T } from "../../../translations"; import { BaseItem } from "../../base_item"; import { MetaHubBuilding } from "../../buildings/hub"; @@ -337,10 +336,6 @@ export class HUDWaypoints extends BaseHUDPart { T.ingame.waypoints.creationSuccessNotification, enumNotificationType.success ); - this.root.signals.achievementCheck.dispatch( - ACHIEVEMENTS.mapMarkers15, - this.waypoints.length - 1 // Disregard HUB - ); // Re-render the list and thus add it this.rerenderWaypointList(); diff --git a/src/js/game/modes/regular.js b/src/js/game/modes/regular.js index d1e5f33a..aafa9fc7 100644 --- a/src/js/game/modes/regular.js +++ b/src/js/game/modes/regular.js @@ -1,39 +1,39 @@ /* typehints:start */ -import { GameRoot } from "../root"; import { MetaBuilding } from "../meta_building"; +import { GameRoot } from "../root"; /* typehints:end */ +import { IS_MOBILE } from "../../core/config"; import { findNiceIntegerValue } from "../../core/utils"; +import { MOD_SIGNALS } from "../../mods/mod_signals"; +import { MetaBlockBuilding } from "../buildings/block"; import { MetaConstantProducerBuilding } from "../buildings/constant_producer"; import { MetaGoalAcceptorBuilding } from "../buildings/goal_acceptor"; +import { MetaItemProducerBuilding } from "../buildings/item_producer"; import { enumGameModeIds, enumGameModeTypes, GameMode } from "../game_mode"; +import { HUDConstantSignalEdit } from "../hud/parts/constant_signal_edit"; +import { HUDGameMenu } from "../hud/parts/game_menu"; +import { HUDInteractiveTutorial } from "../hud/parts/interactive_tutorial"; +import { HUDKeybindingOverlay } from "../hud/parts/keybinding_overlay"; +import { HUDLayerPreview } from "../hud/parts/layer_preview"; +import { HUDLeverToggle } from "../hud/parts/lever_toggle"; +import { HUDMassSelector } from "../hud/parts/mass_selector"; +import { HUDMinerHighlight } from "../hud/parts/miner_highlight"; +import { HUDNotifications } from "../hud/parts/notifications"; +import { HUDPinnedShapes } from "../hud/parts/pinned_shapes"; +import { HUDScreenshotExporter } from "../hud/parts/screenshot_exporter"; +import { HUDShapeViewer } from "../hud/parts/shape_viewer"; +import { HUDShop } from "../hud/parts/shop"; +import { HUDStatistics } from "../hud/parts/statistics"; +import { HUDPartTutorialHints } from "../hud/parts/tutorial_hints"; +import { HUDTutorialVideoOffer } from "../hud/parts/tutorial_video_offer"; +import { HUDUnlockNotification } from "../hud/parts/unlock_notification"; +import { HUDWaypoints } from "../hud/parts/waypoints"; +import { HUDWireInfo } from "../hud/parts/wire_info"; +import { HUDWiresOverlay } from "../hud/parts/wires_overlay"; +import { HUDWiresToolbar } from "../hud/parts/wires_toolbar"; import { ShapeDefinition } from "../shape_definition"; import { enumHubGoalRewards } from "../tutorial_goals"; -import { HUDWiresToolbar } from "../hud/parts/wires_toolbar"; -import { HUDUnlockNotification } from "../hud/parts/unlock_notification"; -import { HUDMassSelector } from "../hud/parts/mass_selector"; -import { HUDShop } from "../hud/parts/shop"; -import { HUDWaypoints } from "../hud/parts/waypoints"; -import { HUDStatistics } from "../hud/parts/statistics"; -import { HUDWireInfo } from "../hud/parts/wire_info"; -import { HUDLeverToggle } from "../hud/parts/lever_toggle"; -import { HUDPinnedShapes } from "../hud/parts/pinned_shapes"; -import { HUDNotifications } from "../hud/parts/notifications"; -import { HUDScreenshotExporter } from "../hud/parts/screenshot_exporter"; -import { HUDWiresOverlay } from "../hud/parts/wires_overlay"; -import { HUDShapeViewer } from "../hud/parts/shape_viewer"; -import { HUDLayerPreview } from "../hud/parts/layer_preview"; -import { HUDTutorialVideoOffer } from "../hud/parts/tutorial_video_offer"; -import { HUDMinerHighlight } from "../hud/parts/miner_highlight"; -import { HUDGameMenu } from "../hud/parts/game_menu"; -import { HUDConstantSignalEdit } from "../hud/parts/constant_signal_edit"; -import { IS_MOBILE } from "../../core/config"; -import { HUDKeybindingOverlay } from "../hud/parts/keybinding_overlay"; -import { HUDPartTutorialHints } from "../hud/parts/tutorial_hints"; -import { HUDInteractiveTutorial } from "../hud/parts/interactive_tutorial"; -import { MetaBlockBuilding } from "../buildings/block"; -import { MetaItemProducerBuilding } from "../buildings/item_producer"; -import { MOD_SIGNALS } from "../../mods/mod_signals"; import { finalGameShape, REGULAR_MODE_LEVELS } from "./levels"; /** @typedef {{ @@ -390,9 +390,4 @@ export class RegularGameMode extends GameMode { getIsFreeplayAvailable() { return true; } - - /** @returns {boolean} */ - hasAchievements() { - return true; - } } diff --git a/src/js/game/root.js b/src/js/game/root.js index 11874af3..6f751e73 100644 --- a/src/js/game/root.js +++ b/src/js/game/root.js @@ -1,33 +1,32 @@ -import { Signal } from "../core/signal"; -import { RandomNumberGenerator } from "../core/rng"; import { createLogger } from "../core/logging"; +import { RandomNumberGenerator } from "../core/rng"; +import { Signal } from "../core/signal"; // Type hints /* typehints:start */ -import { GameTime } from "./time/game_time"; -import { EntityManager } from "./entity_manager"; -import { GameSystemManager } from "./game_system_manager"; -import { AchievementProxy } from "./achievement_proxy"; -import { GameHUD } from "./hud/hud"; -import { MapView } from "./map_view"; -import { Camera } from "./camera"; +import { Application } from "../application"; +import { BufferMaintainer } from "../core/buffer_maintainer"; +import { Vector } from "../core/vector"; +import { Savegame } from "../savegame/savegame"; import { InGameState } from "../states/ingame"; import { AutomaticSave } from "./automatic_save"; -import { Application } from "../application"; -import { SoundProxy } from "./sound_proxy"; -import { Savegame } from "../savegame/savegame"; -import { GameLogic } from "./logic"; -import { ShapeDefinitionManager } from "./shape_definition_manager"; -import { HubGoals } from "./hub_goals"; -import { BufferMaintainer } from "../core/buffer_maintainer"; -import { ProductionAnalytics } from "./production_analytics"; -import { Entity } from "./entity"; -import { ShapeDefinition } from "./shape_definition"; import { BaseItem } from "./base_item"; +import { Camera } from "./camera"; import { DynamicTickrate } from "./dynamic_tickrate"; -import { KeyActionMapper } from "./key_action_mapper"; -import { Vector } from "../core/vector"; +import { Entity } from "./entity"; +import { EntityManager } from "./entity_manager"; import { GameMode } from "./game_mode"; +import { GameSystemManager } from "./game_system_manager"; +import { HubGoals } from "./hub_goals"; +import { GameHUD } from "./hud/hud"; +import { KeyActionMapper } from "./key_action_mapper"; +import { GameLogic } from "./logic"; +import { MapView } from "./map_view"; +import { ProductionAnalytics } from "./production_analytics"; +import { ShapeDefinition } from "./shape_definition"; +import { ShapeDefinitionManager } from "./shape_definition_manager"; +import { SoundProxy } from "./sound_proxy"; +import { GameTime } from "./time/game_time"; /* typehints:end */ const logger = createLogger("game/root"); @@ -124,9 +123,6 @@ export class GameRoot { /** @type {SoundProxy} */ this.soundProxy = null; - /** @type {AchievementProxy} */ - this.achievementProxy = null; - /** @type {ShapeDefinitionManager} */ this.shapeDefinitionMgr = null; @@ -185,10 +181,6 @@ export class GameRoot { // for freeing space before actually placing. freeEntityAreaBeforeBuild: /** @type {Signal<[Entity]>} */ (new Signal()), - // Called with an achievement key and necessary args to validate it can be unlocked. - achievementCheck: /** @type {Signal<[string, any]>} */ (new Signal()), - bulkAchievementCheck: /** @type {Signal<(string|any)[]>} */ (new Signal()), - // Puzzle mode puzzleComplete: /** @type {Signal<[]>} */ (new Signal()), }; diff --git a/src/js/game/shape_definition_manager.js b/src/js/game/shape_definition_manager.js index f29033a1..30641d98 100644 --- a/src/js/game/shape_definition_manager.js +++ b/src/js/game/shape_definition_manager.js @@ -4,7 +4,6 @@ import { enumColors } from "./colors"; import { ShapeItem } from "./items/shape_item"; import { GameRoot } from "./root"; import { enumSubShape, ShapeDefinition } from "./shape_definition"; -import { ACHIEVEMENTS } from "../platform/achievement_provider"; const logger = createLogger("shape_definition_manager"); @@ -97,8 +96,6 @@ export class ShapeDefinitionManager extends BasicSerializableObject { const rightSide = definition.cloneFilteredByQuadrants([2, 3]); const leftSide = definition.cloneFilteredByQuadrants([0, 1]); - this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.cutShape, null); - return /** @type {[ShapeDefinition, ShapeDefinition]} */ ( this.operationCache[key] = [ this.registerOrReturnHandle(rightSide), @@ -143,8 +140,6 @@ export class ShapeDefinitionManager extends BasicSerializableObject { const rotated = definition.cloneRotateCW(); - this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.rotateShape, null); - return /** @type {ShapeDefinition} */ ( this.operationCache[key] = this.registerOrReturnHandle(rotated) ); @@ -198,8 +193,6 @@ export class ShapeDefinitionManager extends BasicSerializableObject { return /** @type {ShapeDefinition} */ (this.operationCache[key]); } - this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.stackShape, null); - const stacked = lowerDefinition.cloneAndStackWith(upperDefinition); return /** @type {ShapeDefinition} */ ( this.operationCache[key] = this.registerOrReturnHandle(stacked) @@ -218,8 +211,6 @@ export class ShapeDefinitionManager extends BasicSerializableObject { return /** @type {ShapeDefinition} */ (this.operationCache[key]); } - this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.paintShape, null); - const colorized = definition.cloneAndPaintWith(color); return /** @type {ShapeDefinition} */ ( this.operationCache[key] = this.registerOrReturnHandle(colorized) diff --git a/src/js/game/systems/wire.js b/src/js/game/systems/wire.js index 8a81de4c..964a3e03 100644 --- a/src/js/game/systems/wire.js +++ b/src/js/game/systems/wire.js @@ -13,16 +13,14 @@ 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"; +import { arrayWireRotationVariantToType, MetaWireBuilding } from "../buildings/wire"; import { enumWireType, enumWireVariant, WireComponent } from "../components/wire"; -import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { WireTunnelComponent } from "../components/wire_tunnel"; +import { enumPinSlotType, WiredPinsComponent } from "../components/wired_pins"; import { Entity } from "../entity"; import { GameSystem } from "../game_system"; -import { GameSystemWithFilter } from "../game_system_with_filter"; import { isTruthyItem } from "../items/boolean_item"; import { MapChunkView } from "../map_chunk_view"; @@ -699,8 +697,6 @@ export class WireSystem extends GameSystem { return; } - this.root.signals.achievementCheck.dispatch(ACHIEVEMENTS.place5000Wires, entity); - // 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 deleted file mode 100644 index 9827e038..00000000 --- a/src/js/platform/achievement_provider.js +++ /dev/null @@ -1,647 +0,0 @@ -/* typehints:start */ -import { Application } from "../application"; -import { Entity } from "../game/entity"; -import { GameRoot } from "../game/root"; -import { THEMES } from "../game/theme"; -/* typehints:end */ - -import { globalConfig } from "../core/config"; -import { ShapeItem } from "../game/items/shape_item"; -import { enumAnalyticsDataSource } from "../game/production_analytics"; -import { ShapeDefinition } from "../game/shape_definition"; - -export const ACHIEVEMENTS = { - belt500Tiles: "belt500Tiles", - blueprint100k: "blueprint100k", - blueprint1m: "blueprint1m", - completeLvl26: "completeLvl26", - cutShape: "cutShape", - darkMode: "darkMode", - destroy1000: "destroy1000", - irrelevantShape: "irrelevantShape", - level100: "level100", - level50: "level50", - logoBefore18: "logoBefore18", - mam: "mam", - mapMarkers15: "mapMarkers15", - noBeltUpgradesUntilBp: "noBeltUpgradesUntilBp", - noInverseRotator: "noInverseRotator", - oldLevel17: "oldLevel17", - openWires: "openWires", - paintShape: "paintShape", - place5000Wires: "place5000Wires", - placeBlueprint: "placeBlueprint", - placeBp1000: "placeBp1000", - play1h: "play1h", - play10h: "play10h", - play20h: "play20h", - produceLogo: "produceLogo", - produceMsLogo: "produceMsLogo", - produceRocket: "produceRocket", - rotateShape: "rotateShape", - speedrunBp30: "speedrunBp30", - speedrunBp60: "speedrunBp60", - speedrunBp120: "speedrunBp120", - stack4Layers: "stack4Layers", - stackShape: "stackShape", - store100Unique: "store100Unique", - storeShape: "storeShape", - throughputBp25: "throughputBp25", - throughputBp50: "throughputBp50", - throughputLogo25: "throughputLogo25", - throughputLogo50: "throughputLogo50", - throughputRocket10: "throughputRocket10", - throughputRocket20: "throughputRocket20", - trash1000: "trash1000", - unlockWires: "unlockWires", - upgradesTier5: "upgradesTier5", - upgradesTier8: "upgradesTier8", -}; - -/** @type {keyof typeof THEMES} */ -const DARK_MODE = "dark"; - -const HOUR_1 = 3600; // Seconds -const HOUR_10 = HOUR_1 * 10; -const HOUR_20 = HOUR_1 * 20; -const ITEM_SHAPE = ShapeItem.getId(); -const MINUTE_30 = 1800; // Seconds -const MINUTE_60 = MINUTE_30 * 2; -const MINUTE_120 = MINUTE_30 * 4; -const ROTATOR_CCW_CODE = 12; -const ROTATOR_180_CODE = 13; -const SHAPE_BP = "CbCbCbRb:CwCwCwCw"; -const SHAPE_LOGO = "RuCw--Cw:----Ru--"; -const SHAPE_MS_LOGO = "RgRyRbRr"; -const SHAPE_OLD_LEVEL_17 = "WrRgWrRg:CwCrCwCr:SgSgSgSg"; -const SHAPE_ROCKET = "CbCuCbCu:Sr------:--CrSrCr:CwCwCwCw"; - -/** @type {Layer} */ -const WIRE_LAYER = "wires"; - -export class AchievementProviderInterface { - /* typehints:start */ - collection = /** @type {AchievementCollection|undefined} */ (null); - /* typehints:end */ - - /** @param {Application} app */ - constructor(app) { - this.app = app; - } - - /** - * Initializes the achievement provider. - * @returns {Promise} - * @abstract - */ - initialize() { - abstract; - return Promise.reject(); - } - - /** - * Opportunity to do additional initialization work with the GameRoot. - * @param {GameRoot} root - * @returns {Promise} - * @abstract - */ - onLoad(root) { - abstract; - return Promise.reject(); - } - - /** @returns {boolean} */ - hasLoaded() { - abstract; - return false; - } - - /** - * Call to activate an achievement with the provider - * @param {string} key - Maps to an Achievement - * @returns {Promise} - * @abstract - */ - activate(key) { - abstract; - return Promise.reject(); - } - - /** - * Checks if achievements are supported in the current build - * @returns {boolean} - * @abstract - */ - hasAchievements() { - abstract; - return false; - } -} - -export class Achievement { - /** @param {string} key - An ACHIEVEMENTS key */ - constructor(key) { - this.key = key; - this.activate = null; - this.activatePromise = null; - this.receiver = null; - this.signal = null; - } - - init() {} - - isValid() { - return true; - } - - unlock() { - if (!this.activatePromise) { - this.activatePromise = this.activate(this.key); - } - - return this.activatePromise; - } -} - -export class AchievementCollection { - /** - * @param {function} activate - Resolves when provider activation is complete - */ - constructor(activate) { - this.map = new Map(); - this.activate = activate; - - this.add(ACHIEVEMENTS.belt500Tiles, { - isValid: this.isBelt500TilesValid, - signal: "entityAdded", - }); - this.add(ACHIEVEMENTS.blueprint100k, this.createBlueprintOptions(100000)); - this.add(ACHIEVEMENTS.blueprint1m, this.createBlueprintOptions(1000000)); - this.add(ACHIEVEMENTS.completeLvl26, this.createLevelOptions(26)); - this.add(ACHIEVEMENTS.cutShape); - this.add(ACHIEVEMENTS.darkMode, { - isValid: this.isDarkModeValid, - }); - this.add(ACHIEVEMENTS.destroy1000, { - isValid: this.isDestroy1000Valid, - }); - this.add(ACHIEVEMENTS.irrelevantShape, { - isValid: this.isIrrelevantShapeValid, - signal: "shapeDelivered", - }); - this.add(ACHIEVEMENTS.level100, this.createLevelOptions(100)); - this.add(ACHIEVEMENTS.level50, this.createLevelOptions(50)); - this.add(ACHIEVEMENTS.logoBefore18, { - isValid: this.isLogoBefore18Valid, - signal: "itemProduced", - }); - this.add(ACHIEVEMENTS.mam, { - isValid: this.isMamValid, - }); - this.add(ACHIEVEMENTS.mapMarkers15, { - isValid: this.isMapMarkers15Valid, - }); - this.add(ACHIEVEMENTS.noBeltUpgradesUntilBp, { - isValid: this.isNoBeltUpgradesUntilBpValid, - signal: "storyGoalCompleted", - }); - this.add(ACHIEVEMENTS.noInverseRotator, { - init: this.initNoInverseRotator, - isValid: this.isNoInverseRotatorValid, - signal: "storyGoalCompleted", - }); - this.add(ACHIEVEMENTS.oldLevel17, this.createShapeOptions(SHAPE_OLD_LEVEL_17)); - this.add(ACHIEVEMENTS.openWires, { - isValid: this.isOpenWiresValid, - signal: "editModeChanged", - }); - this.add(ACHIEVEMENTS.paintShape); - this.add(ACHIEVEMENTS.place5000Wires, { - isValid: this.isPlace5000WiresValid, - }); - this.add(ACHIEVEMENTS.placeBlueprint, { - isValid: this.isPlaceBlueprintValid, - }); - this.add(ACHIEVEMENTS.placeBp1000, { - isValid: this.isPlaceBp1000Valid, - }); - this.add(ACHIEVEMENTS.play1h, this.createTimeOptions(HOUR_1)); - this.add(ACHIEVEMENTS.play10h, this.createTimeOptions(HOUR_10)); - this.add(ACHIEVEMENTS.play20h, this.createTimeOptions(HOUR_20)); - this.add(ACHIEVEMENTS.produceLogo, this.createShapeOptions(SHAPE_LOGO)); - this.add(ACHIEVEMENTS.produceRocket, this.createShapeOptions(SHAPE_ROCKET)); - this.add(ACHIEVEMENTS.produceMsLogo, this.createShapeOptions(SHAPE_MS_LOGO)); - this.add(ACHIEVEMENTS.rotateShape); - this.add(ACHIEVEMENTS.speedrunBp30, this.createSpeedOptions(12, MINUTE_30)); - this.add(ACHIEVEMENTS.speedrunBp60, this.createSpeedOptions(12, MINUTE_60)); - this.add(ACHIEVEMENTS.speedrunBp120, this.createSpeedOptions(12, MINUTE_120)); - this.add(ACHIEVEMENTS.stack4Layers, { - isValid: this.isStack4LayersValid, - signal: "itemProduced", - }); - this.add(ACHIEVEMENTS.stackShape); - this.add(ACHIEVEMENTS.store100Unique, { - init: this.initStore100Unique, - isValid: this.isStore100UniqueValid, - signal: "shapeDelivered", - }); - this.add(ACHIEVEMENTS.storeShape, { - init: this.initStoreShape, - isValid: this.isStoreShapeValid, - }); - this.add(ACHIEVEMENTS.throughputBp25, this.createRateOptions(SHAPE_BP, 25)); - this.add(ACHIEVEMENTS.throughputBp50, this.createRateOptions(SHAPE_BP, 50)); - this.add(ACHIEVEMENTS.throughputLogo25, this.createRateOptions(SHAPE_LOGO, 25)); - this.add(ACHIEVEMENTS.throughputLogo50, this.createRateOptions(SHAPE_LOGO, 50)); - this.add(ACHIEVEMENTS.throughputRocket10, this.createRateOptions(SHAPE_ROCKET, 10)); - this.add(ACHIEVEMENTS.throughputRocket20, this.createRateOptions(SHAPE_ROCKET, 20)); - this.add(ACHIEVEMENTS.trash1000, { - init: this.initTrash1000, - isValid: this.isTrash1000Valid, - }); - this.add(ACHIEVEMENTS.unlockWires, this.createLevelOptions(20)); - this.add(ACHIEVEMENTS.upgradesTier5, this.createUpgradeOptions(5)); - this.add(ACHIEVEMENTS.upgradesTier8, this.createUpgradeOptions(8)); - } - - /** @param {GameRoot} root */ - initialize(root) { - this.root = root; - this.root.signals.achievementCheck.add(this.unlock, this); - this.root.signals.bulkAchievementCheck.add(this.bulkUnlock, this); - - for (let [key, achievement] of this.map.entries()) { - if (achievement.signal) { - achievement.receiver = this.unlock.bind(this, key); - this.root.signals[achievement.signal].add(achievement.receiver); - } - - if (achievement.init) { - achievement.init(); - } - } - - if (!this.hasDefaultReceivers()) { - this.root.signals.achievementCheck.remove(this.unlock); - this.root.signals.bulkAchievementCheck.remove(this.bulkUnlock); - } - } - - /** - * @param {string} key - Maps to an Achievement - * @param {object} [options] - * @param {function} [options.init] - * @param {function} [options.isValid] - * @param {string} [options.signal] - */ - add(key, options = {}) { - if (G_IS_DEV) { - assert(ACHIEVEMENTS[key], "Achievement key not found: ", key); - } - - const achievement = new Achievement(key); - - achievement.activate = this.activate; - - if (options.init) { - achievement.init = options.init.bind(this, achievement); - } - - if (options.isValid) { - achievement.isValid = options.isValid.bind(this); - } - - if (options.signal) { - achievement.signal = options.signal; - } - - this.map.set(key, achievement); - } - - bulkUnlock() { - for (let i = 0; i < arguments.length; i += 2) { - this.unlock(arguments[i], arguments[i + 1]); - } - } - - /** - * @param {string} key - Maps to an Achievement - * @param {any} data - Data received from signal dispatches for validation - */ - unlock(key, data) { - if (!this.map.has(key)) { - return; - } - - const achievement = this.map.get(key); - - if (!achievement.isValid(data)) { - return; - } - - achievement - .unlock() - .then(() => { - this.onActivate(null, key); - }) - .catch(err => { - this.onActivate(err, key); - }); - } - - /** - * Cleans up after achievement activation attempt with the provider. Could - * utilize err to retry some number of times if needed. - * @param {?Error} err - Error is null if activation was successful - * @param {string} key - Maps to an Achievement - */ - onActivate(err, key) { - this.remove(key); - - if (!this.hasDefaultReceivers()) { - this.root.signals.achievementCheck.remove(this.unlock); - } - } - - /** @param {string} key - Maps to an Achievement */ - remove(key) { - const achievement = this.map.get(key); - if (achievement) { - if (achievement.receiver) { - this.root.signals[achievement.signal].remove(achievement.receiver); - } - - this.map.delete(key); - } - } - - /** - * Check if the collection-level achievementCheck receivers are still - * necessary. - */ - hasDefaultReceivers() { - if (!this.map.size) { - return false; - } - - for (let achievement of this.map.values()) { - if (!achievement.signal) { - return true; - } - } - - return false; - } - - /* - * Remaining methods exist to extend Achievement instances within the - * collection. - */ - - hasAllUpgradesAtLeastAtTier(tier) { - const upgrades = this.root.gameMode.getUpgrades(); - - for (let upgradeId in upgrades) { - if (this.root.hubGoals.getUpgradeLevel(upgradeId) < tier - 1) { - return false; - } - } - - return true; - } - - /** - * @param {ShapeItem} item - * @param {string} shape - * @returns {boolean} - */ - isShape(item, shape) { - return item.getItemType() === ITEM_SHAPE && item.definition.getHash() === shape; - } - - createBlueprintOptions(count) { - return { - init: ({ key }) => this.unlock(key, ShapeDefinition.fromShortKey(SHAPE_BP)), - isValid: definition => - definition.cachedHash === SHAPE_BP && - this.root.hubGoals.getShapesStoredByKey(SHAPE_BP) >= count, - signal: "shapeDelivered", - }; - } - - createLevelOptions(level) { - return { - init: ({ key }) => this.unlock(key, this.root.hubGoals.level), - isValid: currentLevel => currentLevel > level, - signal: "storyGoalCompleted", - }; - } - - createRateOptions(shape, rate) { - return { - isValid: () => { - return ( - this.root.productionAnalytics.getCurrentShapeRateRaw( - enumAnalyticsDataSource.delivered, - this.root.shapeDefinitionMgr.getShapeFromShortKey(shape) - ) / - globalConfig.analyticsSliceDurationSeconds >= - rate - ); - }, - }; - } - - createShapeOptions(shape) { - return { - isValid: item => this.isShape(item, shape), - signal: "itemProduced", - }; - } - - createSpeedOptions(level, time) { - return { - isValid: currentLevel => currentLevel >= level && this.root.time.now() < time, - signal: "storyGoalCompleted", - }; - } - - createTimeOptions(duration) { - return { - isValid: () => this.root.time.now() >= duration, - }; - } - - createUpgradeOptions(tier) { - return { - init: ({ key }) => this.unlock(key, null), - isValid: () => this.hasAllUpgradesAtLeastAtTier(tier), - signal: "upgradePurchased", - }; - } - - /** @param {Entity} entity @returns {boolean} */ - isBelt500TilesValid(entity) { - return entity.components.Belt && entity.components.Belt.assignedPath.totalLength >= 500; - } - - /** @returns {boolean} */ - isDarkModeValid() { - return this.root.app.settings.currentData.settings.theme === DARK_MODE; - } - - /** @param {number} count @returns {boolean} */ - isDestroy1000Valid(count) { - return count >= 1000; - } - - /** @param {ShapeDefinition} definition @returns {boolean} */ - isIrrelevantShapeValid(definition) { - const levels = this.root.gameMode.getLevelDefinitions(); - for (let i = 0; i < levels.length; i++) { - if (definition.cachedHash === levels[i].shape) { - return false; - } - } - - const upgrades = this.root.gameMode.getUpgrades(); - for (let upgradeId in upgrades) { - for (const tier in upgrades[upgradeId]) { - const requiredShapes = upgrades[upgradeId][tier].required; - for (let i = 0; i < requiredShapes.length; i++) { - if (definition.cachedHash === requiredShapes[i].shape) { - return false; - } - } - } - } - - return true; - } - - /** @param {ShapeItem} item @returns {boolean} */ - isLogoBefore18Valid(item) { - return this.root.hubGoals.level < 18 && this.isShape(item, SHAPE_LOGO); - } - - /** @returns {boolean} */ - isMamValid() { - return this.root.hubGoals.level > 27 && !this.root.savegame.currentData.stats.failedMam; - } - - /** @param {number} count @returns {boolean} */ - isMapMarkers15Valid(count) { - return count >= 15; - } - - /** - * @param {number} level - * @returns {boolean} - */ - isNoBeltUpgradesUntilBpValid(level) { - return level >= 12 && this.root.hubGoals.upgradeLevels.belt === 0; - } - - initNoInverseRotator() { - if (this.root.savegame.currentData.stats.usedInverseRotator === true) { - return; - } - - const entities = this.root.entityMgr.componentToEntity.StaticMapEntity; - - let usedInverseRotator = false; - for (var i = 0; i < entities.length; i++) { - const entity = entities[i].components.StaticMapEntity; - - if (entity.code === ROTATOR_CCW_CODE || entity.code === ROTATOR_180_CODE) { - usedInverseRotator = true; - break; - } - } - - this.root.savegame.currentData.stats.usedInverseRotator = usedInverseRotator; - } - - /** @param {number} level @returns {boolean} */ - isNoInverseRotatorValid(level) { - return level >= 14 && !this.root.savegame.currentData.stats.usedInverseRotator; - } - - /** @param {string} currentLayer @returns {boolean} */ - isOpenWiresValid(currentLayer) { - return currentLayer === WIRE_LAYER; - } - - /** @param {Entity} entity @returns {boolean} */ - isPlace5000WiresValid(entity) { - return ( - entity.components.Wire && - entity.registered && - entity.root.entityMgr.componentToEntity.Wire.length >= 5000 - ); - } - - /** @param {number} count @returns {boolean} */ - isPlaceBlueprintValid(count) { - return count != 0; - } - - /** @param {number} count @returns {boolean} */ - isPlaceBp1000Valid(count) { - return count >= 1000; - } - - /** @param {ShapeItem} item @returns {boolean} */ - isStack4LayersValid(item) { - return item.getItemType() === ITEM_SHAPE && item.definition.layers.length === 4; - } - - /** @param {Achievement} achievement */ - initStore100Unique({ key }) { - this.unlock(key, null); - } - - /** @returns {boolean} */ - isStore100UniqueValid() { - return Object.keys(this.root.hubGoals.storedShapes).length >= 100; - } - - /** @param {Achievement} achievement */ - initStoreShape({ key }) { - this.unlock(key, null); - } - - /** @returns {boolean} */ - isStoreShapeValid() { - const entities = this.root.systemMgr.systems.storage.allEntities; - - if (entities.length === 0) { - return false; - } - - for (var i = 0; i < entities.length; i++) { - if (entities[i].components.Storage.storedCount > 0) { - return true; - } - } - - return false; - } - - /** @param {Achievement} achievement */ - initTrash1000({ key }) { - if (Number(this.root.savegame.currentData.stats.trashedCount)) { - this.unlock(key, 0); - return; - } - - this.root.savegame.currentData.stats.trashedCount = 0; - } - - /** @param {number} count @returns {boolean} */ - isTrash1000Valid(count) { - this.root.savegame.currentData.stats.trashedCount += count; - - return this.root.savegame.currentData.stats.trashedCount >= 1000; - } -} diff --git a/src/js/platform/no_achievement_provider.js b/src/js/platform/no_achievement_provider.js deleted file mode 100644 index 66a83874..00000000 --- a/src/js/platform/no_achievement_provider.js +++ /dev/null @@ -1,23 +0,0 @@ -import { AchievementProviderInterface } from "./achievement_provider"; - -export class NoAchievementProvider extends AchievementProviderInterface { - hasAchievements() { - return false; - } - - hasLoaded() { - return false; - } - - initialize() { - return Promise.resolve(); - } - - onLoad() { - return Promise.reject(new Error("No achievements to load")); - } - - activate() { - return Promise.resolve(); - } -} diff --git a/src/js/platform/wrapper.js b/src/js/platform/wrapper.js index 2facbde0..460d41e9 100644 --- a/src/js/platform/wrapper.js +++ b/src/js/platform/wrapper.js @@ -5,7 +5,6 @@ import { Application } from "../application"; import { IS_MOBILE } from "../core/config"; import { createLogger } from "../core/logging"; import { clamp } from "../core/utils"; -import { NoAchievementProvider } from "./no_achievement_provider"; const logger = createLogger("electron-wrapper"); @@ -16,10 +15,8 @@ export class PlatformWrapperImplElectron { } initialize() { - return this.initializeAchievementProvider().then(() => { - document.documentElement.classList.add("p-" + this.getId()); - return Promise.resolve(); - }); + document.documentElement.classList.add("p-" + this.getId()); + return Promise.resolve(); } getId() { @@ -61,14 +58,6 @@ export class PlatformWrapperImplElectron { window.location.reload(); } - initializeAchievementProvider() { - return this.app.achievementProvider.initialize().catch(err => { - logger.error("Failed to initialize achievement provider, disabling:", err); - - this.app.achievementProvider = new NoAchievementProvider(this.app); - }); - } - /** * Returns the UI scale, called on every resize * @returns {number} */ From 519128a70aecabd1753cb7dc660b6213c0085356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D1=97=D0=BB=20=D0=93=D1=80=D0=B8?= =?UTF-8?q?=D0=B3=D0=BE=D1=80=27=D1=94=D0=B2?= Date: Tue, 8 Apr 2025 16:59:40 +0300 Subject: [PATCH 2/2] Remove savegame stats (achievements data) No longer used as achievements are gone. Also, avoid copying the old savegame dump object. This is possible thanks to this change. --- src/js/savegame/savegame.js | 15 +-------------- src/js/savegame/savegame_typedefs.js | 7 ------- src/js/savegame/schemas/1008.js | 11 +---------- 3 files changed, 2 insertions(+), 31 deletions(-) diff --git a/src/js/savegame/savegame.js b/src/js/savegame/savegame.js index 2502cb46..d93c5997 100644 --- a/src/js/savegame/savegame.js +++ b/src/js/savegame/savegame.js @@ -24,7 +24,6 @@ const logger = createLogger("savegame"); * @typedef {import("../game/root").GameRoot} GameRoot * @typedef {import("./savegame_typedefs").SavegameData} SavegameData * @typedef {import("./savegame_typedefs").SavegameMetadata} SavegameMetadata - * @typedef {import("./savegame_typedefs").SavegameStats} SavegameStats * @typedef {import("./savegame_typedefs").SerializedGame} SerializedGame */ @@ -99,11 +98,6 @@ export class Savegame extends ReadWriteProxy { return { version: this.getCurrentVersion(), dump: null, - stats: { - failedMam: false, - trashedCount: 0, - usedInverseRotator: false, - }, lastUpdate: Date.now(), mods: MODS.getModsListForSavegame(), }; @@ -196,13 +190,6 @@ export class Savegame extends ReadWriteProxy { isSaveable() { return true; } - /** - * Returns the statistics of the savegame - * @returns {SavegameStats} - */ - getStatistics() { - return this.currentData.stats; - } /** * Returns the *real* last update of the savegame, not the one of the metadata @@ -273,7 +260,7 @@ export class Savegame extends ReadWriteProxy { return false; } - const shadowData = Object.assign({}, this.currentData); + const shadowData = {}; shadowData.dump = dump; shadowData.lastUpdate = new Date().getTime(); shadowData.version = this.getCurrentVersion(); diff --git a/src/js/savegame/savegame_typedefs.js b/src/js/savegame/savegame_typedefs.js index 1a887e74..710ac68c 100644 --- a/src/js/savegame/savegame_typedefs.js +++ b/src/js/savegame/savegame_typedefs.js @@ -10,12 +10,6 @@ * }[]} SavegameStoredMods * * @typedef {{ - * failedMam: boolean, - * trashedCount: number, - * usedInverseRotator: boolean - * }} SavegameStats - * - * @typedef {{ * camera: any, * time: any, * entityMgr: any, @@ -32,7 +26,6 @@ * @typedef {{ * version: number, * dump: SerializedGame, - * stats: SavegameStats, * lastUpdate: number, * mods: SavegameStoredMods * }} SavegameData diff --git a/src/js/savegame/schemas/1008.js b/src/js/savegame/schemas/1008.js index 43c67ff4..227aa7b9 100644 --- a/src/js/savegame/schemas/1008.js +++ b/src/js/savegame/schemas/1008.js @@ -17,16 +17,7 @@ export class SavegameInterface_V1008 extends SavegameInterface_V1007 { * @param {import("../savegame_typedefs.js").SavegameData} data */ static migrate1007to1008(data) { + // Note: no-op since achievement removal logger.log("Migrating 1007 to 1008"); - const dump = data.dump; - if (!dump) { - return true; - } - - Object.assign(data.stats, { - failedMam: true, - trashedCount: 0, - usedInverseRotator: true, - }); } }