mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-06-13 13:04:03 +00:00
[WIP] Implement painting, cutting, rotating achievements (to log only)
This commit is contained in:
parent
261c7a4070
commit
85999f3f8b
@ -8,49 +8,29 @@ import { createLogger } from "../core/logging";
|
||||
const logger = createLogger("achievement_manager");
|
||||
|
||||
export class AchievementManager {
|
||||
static getId() {
|
||||
return "AchievementManager";
|
||||
}
|
||||
|
||||
constructor(root) {
|
||||
this.root = root;
|
||||
this.achievements = null;
|
||||
this.achievements = this.root.app.achievements;
|
||||
|
||||
if (!this.root.app.achievements.hasAchievements()) {
|
||||
logger.debug("Bypassing achievement set up");
|
||||
// Set adhoc checks to reference a noop, ignore signals.
|
||||
return;
|
||||
}
|
||||
|
||||
this.init();
|
||||
this.load()
|
||||
}
|
||||
|
||||
init () {
|
||||
return this.root.app.achievements.load()
|
||||
load () {
|
||||
return this.achievements.load()
|
||||
.then(() => {
|
||||
this.achievements = this.root.app.achievements.getAchievements();
|
||||
if (!this.achievements.hasAchievements()) {
|
||||
logger.log("Achievements disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
return this.setChecks();
|
||||
logger.log("There are", this.achievements.count, "achievements");
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error("Achievements failed to load", err);
|
||||
})
|
||||
}
|
||||
|
||||
setChecks () {
|
||||
logger.debug("loaded", this.achievements);
|
||||
|
||||
// set checks on achievements
|
||||
|
||||
//this.root.signals.itemProduced.add(this.onItemProduced, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {BaseItem} item
|
||||
*/
|
||||
onItemProduced(item) {
|
||||
logger.debug(item);
|
||||
}
|
||||
|
||||
// Have one check function per achievement
|
||||
isPainted () {
|
||||
return
|
||||
unlock (key) {
|
||||
this.achievements.unlock(key);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +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";
|
||||
|
||||
const logger = createLogger("shape_definition_manager");
|
||||
|
||||
@ -96,6 +97,8 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
|
||||
const rightSide = definition.cloneFilteredByQuadrants([2, 3]);
|
||||
const leftSide = definition.cloneFilteredByQuadrants([0, 1]);
|
||||
|
||||
this.root.achievementMgr.unlock(ACHIEVEMENTS.cutting);
|
||||
|
||||
return /** @type {[ShapeDefinition, ShapeDefinition]} */ (this.operationCache[key] = [
|
||||
this.registerOrReturnHandle(rightSide),
|
||||
this.registerOrReturnHandle(leftSide),
|
||||
@ -137,6 +140,8 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
|
||||
|
||||
const rotated = definition.cloneRotateCW();
|
||||
|
||||
this.root.achievementMgr.unlock(ACHIEVEMENTS.rotating);
|
||||
|
||||
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(
|
||||
rotated
|
||||
));
|
||||
@ -203,9 +208,14 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
|
||||
*/
|
||||
shapeActionPaintWith(definition, color) {
|
||||
const key = "paint/" + definition.getHash() + "/" + color;
|
||||
logger.debug("shapePainted", definition, color);
|
||||
if (this.operationCache[key]) {
|
||||
logger.debug("shapePaintedCache", definition, color);
|
||||
return /** @type {ShapeDefinition} */ (this.operationCache[key]);
|
||||
}
|
||||
|
||||
this.root.achievementMgr.unlock(ACHIEVEMENTS.painting);
|
||||
|
||||
const colorized = definition.cloneAndPaintWith(color);
|
||||
return /** @type {ShapeDefinition} */ (this.operationCache[key] = this.registerOrReturnHandle(
|
||||
colorized
|
||||
|
@ -2,6 +2,14 @@
|
||||
import { Application } from "../application";
|
||||
/* typehints:end */
|
||||
|
||||
export const ACHIEVEMENTS = {
|
||||
painting: "painting",
|
||||
cutting: "cutting",
|
||||
rotating: "rotating",
|
||||
stacking: "stacking",
|
||||
blueprints: "blueprints",
|
||||
}
|
||||
|
||||
export class AchievementsInterface {
|
||||
constructor(app) {
|
||||
/** @type {Application} */
|
||||
@ -9,7 +17,30 @@ export class AchievementsInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the list of achievements
|
||||
* Load achievements into an initial state, bypassing unlocked and/or
|
||||
* irrelevant achievements where possible.
|
||||
*
|
||||
* @params key
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
load() {
|
||||
abstract;
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to unlock an achievement
|
||||
* @params [key] - A property within the ACHIEVEMENTS enum or empty if
|
||||
* bypassing.
|
||||
* @returns {(undefined|Promise)}
|
||||
*/
|
||||
unlock(key) {
|
||||
abstract;
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the list of achievements.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
initialize() {
|
||||
|
@ -1,76 +1,87 @@
|
||||
import { AchievementsInterface } from "../achievements";
|
||||
import { ACHIEVEMENTS, AchievementsInterface } from "../achievements";
|
||||
import { globalConfig } from "../../core/config";
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { newEmptyMap } from "../../core/utils";
|
||||
//import { T } from "../../translations";
|
||||
|
||||
const logger = createLogger("achievements/default");
|
||||
const logger = createLogger("achievements/steam");
|
||||
|
||||
// Include API id per key
|
||||
export const ACHIEVEMENTS = {
|
||||
painting: "painting"
|
||||
const IDS = {
|
||||
painting: "<id>",
|
||||
cutting: "<id>",
|
||||
rotating: "<id>",
|
||||
stacking: "<id>",
|
||||
blueprints: "<id>"
|
||||
}
|
||||
|
||||
export class Achievements extends AchievementsInterface {
|
||||
initialize() {
|
||||
this.authTicket = null;
|
||||
this.achievementNames = null;
|
||||
this.achievements = null;
|
||||
this.connected = false;
|
||||
this.connectPromise = Promise.resolve();
|
||||
this.map = new Map();
|
||||
this.type = "Steam";
|
||||
this.count = 0;
|
||||
|
||||
if (globalConfig.debug.testAchievements) {
|
||||
return Promise.resolve();
|
||||
logger.log("Initializing", this.type, "achievements");
|
||||
|
||||
for (let key in ACHIEVEMENTS) {
|
||||
this.map[key] = new Map();
|
||||
this.map[key].id = IDS[key];
|
||||
this.map[key].key = key;
|
||||
this.map[key].unlocked = false;
|
||||
this.map[key].relevant = true;
|
||||
this.count++;
|
||||
}
|
||||
|
||||
// Check for resolve in AchievementManager via load() to not block game state
|
||||
// transition
|
||||
this.connectPromise = this.fetchAuthTicket()
|
||||
.then(() => this.fetchAchievementNames());
|
||||
this.logOnly = globalConfig.debug.testAchievements;
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
fetchAuthTicket () {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
fetchAchievementNames () {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
load () {
|
||||
this.achievements = newEmptyMap();
|
||||
// TODO: inspect safe file and update achievements
|
||||
// Consider removing load since there's no async behavior anticipated
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
for (let key in ACHIEVEMENTS) {
|
||||
this.achievements[key] = newEmptyMap();
|
||||
this.achievements[key].unlocked = false;
|
||||
this.achievements[key].invalid = false;
|
||||
/**
|
||||
* @param {string} key
|
||||
*/
|
||||
unlock (key) {
|
||||
let achievement = this.map[key];
|
||||
|
||||
if (!achievement) {
|
||||
logger.error("Achievement does not exist:", key);
|
||||
return;
|
||||
}
|
||||
|
||||
return this.connectPromise
|
||||
if (!achievement.relevant) {
|
||||
logger.debug("Achievement unlocked/irrelevant:", key);
|
||||
return;
|
||||
}
|
||||
|
||||
achievement.activate = achievement.activate || this.activate(achievement)
|
||||
.then(() => {
|
||||
// factor in game state, save data, then Steam data (if accessible) as
|
||||
// source of truth.
|
||||
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 {string} key
|
||||
*/
|
||||
fetchAchievement (key) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
activate (achievement) {
|
||||
if (this.logOnly) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
*/
|
||||
unlockAchievement (key) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
//TODO: Implement greenworks activate
|
||||
|
||||
getAchievements() {
|
||||
return this.achievements;
|
||||
return resolve();
|
||||
});
|
||||
}
|
||||
|
||||
hasAchievements() {
|
||||
|
@ -5,7 +5,14 @@ export class NoAchievements extends AchievementsInterface {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
load() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
hasAchievements() {
|
||||
return false;
|
||||
}
|
||||
|
||||
unlock() {
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user