diff --git a/src/Const/Achievements.ts b/src/Const/Achievements.ts index 2e197909..8c452e95 100644 --- a/src/Const/Achievements.ts +++ b/src/Const/Achievements.ts @@ -224,6 +224,10 @@ const parseCondition = (conds: AchievementCondition | null, data: AchievementTag const value = tags[key as keyof AchievementTags]!; const givenValue = data[key as keyof AchievementTags]!; + if (givenValue === undefined || givenValue === null) { // Just in case + return false; + } + if (key === "total" || key === "value" || key === "delta") { const op = conds.op; diff --git a/src/Entity/Tank/TankBody.ts b/src/Entity/Tank/TankBody.ts index 16209654..284e2ae9 100644 --- a/src/Entity/Tank/TankBody.ts +++ b/src/Entity/Tank/TankBody.ts @@ -37,7 +37,7 @@ import { sendAchievementEvent } from "../../Const/Achievements"; import { DevTank } from "../../Const/DevTankDefinitions"; import { Inputs } from "../AI"; import { ArenaState } from "../../Native/Arena"; -import { AccessLevel, maxPlayerLevel, enableAchievements } from "../../config"; +import { AccessLevel, maxPlayerLevel } from "../../config"; /** * Abstract type of entity which barrels can connect to. @@ -188,7 +188,7 @@ export default class TankBody extends LivingEntity implements BarrelBase { if (client) { if (tank.upgradeMessage) client.notify(tank.upgradeMessage, 0x000000, 10000); - if (enableAchievements && !this.game.arena.disableAchievements) { + if (this.game.enableAchievements) { sendAchievementEvent(client, "classChange", { "class": id }); @@ -208,7 +208,7 @@ export default class TankBody extends LivingEntity implements BarrelBase { client.notify(`You've killed ${entity.nameData.values.name || "an unnamed tank"}`); } - if (enableAchievements && !this.game.arena.disableAchievements) { + if (this.game.enableAchievements) { const victimIsTank = TankBody.isTank(entity); sendAchievementEvent(client, "kill", { diff --git a/src/Game.ts b/src/Game.ts index 646c608a..853a9682 100644 --- a/src/Game.ts +++ b/src/Game.ts @@ -32,6 +32,7 @@ import MothershipArena from "./Gamemodes/Mothership"; import MazeArena from "./Gamemodes/Maze"; import SandboxArena from "./Gamemodes/Sandbox"; import { ClientBound } from "./Const/Enums"; +import { enableAchievements } from "./config"; /** * WriterStream that broadcasts to all of the game's WebSockets. @@ -92,6 +93,8 @@ export default class GameServer { public tick: number; /** The game's arena entity. */ public arena: ArenaEntity; + /** If achievements can be earned on this game. */ + public enableAchievements: boolean = enableAchievements; /** The interval timer of the tick loop. */ private _tickInterval: NodeJS.Timeout; /** The Arena instantiator */ diff --git a/src/Gamemodes/Sandbox.ts b/src/Gamemodes/Sandbox.ts index 772b21dd..6478eb74 100644 --- a/src/Gamemodes/Sandbox.ts +++ b/src/Gamemodes/Sandbox.ts @@ -49,7 +49,7 @@ export default class SandboxArena extends ArenaEntity { this.arenaData.values.flags |= ArenaFlags.canUseCheats; this.state = ArenaState.OPEN; // Sandbox should start instantly, no countdown - this.disableAchievements = true; + this.game.enableAchievements = false; this.setSandboxArenaSize(0); } diff --git a/src/Native/Arena.ts b/src/Native/Arena.ts index 09a24cf2..6e704b4e 100644 --- a/src/Native/Arena.ts +++ b/src/Native/Arena.ts @@ -70,9 +70,6 @@ export default class ArenaEntity extends Entity implements TeamGroupEntity { public state: ArenaState = ArenaState.COUNTDOWN; public shapeScoreRewardMultiplier: number = 1; - - /** If achievements cannot be obtained in this arena */ - public disableAchievements: boolean = false; /** The boss spawner. Set to null in gamemode file to disable boss spawning. */ public bossManager: BossManager | null = new BossManager(this); diff --git a/src/Native/Camera.ts b/src/Native/Camera.ts index ef628469..4c4cee55 100644 --- a/src/Native/Camera.ts +++ b/src/Native/Camera.ts @@ -30,7 +30,7 @@ import { sendAchievementEvent } from "../Const/Achievements"; import { removeFast } from "../util"; import { compileCreation, compileUpdate } from "./UpcreateCompiler"; -import { maxPlayerLevel, enableAchievements } from "../config"; +import { maxPlayerLevel } from "../config"; /** * Represents any entity with a camera field group. @@ -78,7 +78,7 @@ export class CameraEntity extends Entity { this.setFieldFactor(getTankById(this.cameraData.values.tank)?.fieldFactor ?? 1); this.calculateLevelData(); - if (!enableAchievements || this.game.arena.disableAchievements) return; + if (!this.game.enableAchievements) return; const client = this.getClient(); if (!client) return; @@ -107,7 +107,7 @@ export class CameraEntity extends Entity { this.calculateLevelData(); - if (!enableAchievements && !this.game.arena.disableAchievements) return; + if (!this.game.enableAchievements) return; const client = this.getClient(); if (!client) return; @@ -127,7 +127,7 @@ export class CameraEntity extends Entity { this.calculateLevelData(); - if (!enableAchievements || this.game.arena.disableAchievements) return; + if (!this.game.enableAchievements) return; const client = this.getClient(); if (!client) return; @@ -146,7 +146,7 @@ export class CameraEntity extends Entity { if (TankBody.isTank(player)) player.calculateStatData(); - if (!enableAchievements || this.game.arena.disableAchievements) return; + if (!this.game.enableAchievements) return; const client = this.getClient(); if (!client) return; @@ -164,7 +164,7 @@ export class CameraEntity extends Entity { if (TankBody.isTank(player)) player.calculateStatData(); - if (!enableAchievements && !this.game.arena.disableAchievements) return; + if (!this.game.enableAchievements) return; const client = this.getClient(); if (!client) return;