diff --git a/src/js/application.js b/src/js/application.js index 1f6e2e3d..744a140a 100644 --- a/src/js/application.js +++ b/src/js/application.js @@ -51,19 +51,6 @@ if (typeof document.hidden !== "undefined") { } export class Application { - static trackClicks = undefined; - static getMainContentHTML = undefined; - static states = { - PreloadState, - MobileWarningState, - MainMenuState, - InGameState, - SettingsState, - KeybindingsState, - AboutState, - ChangelogState, - }; - constructor() { assert(!GLOBAL_APP, "Tried to construct application twice"); logger.log("Creating application, platform =", getPlatformName()); @@ -415,3 +402,16 @@ export class Application { this.checkResize(true); } } + +Application.trackClicks = undefined; +Application.getMainContentHTML = undefined; +Application.states = { + PreloadState, + MobileWarningState, + MainMenuState, + InGameState, + SettingsState, + KeybindingsState, + AboutState, + ChangelogState, +}; diff --git a/src/js/core/read_write_proxy.js b/src/js/core/read_write_proxy.js index e1a7e295..c9a3c9a7 100644 --- a/src/js/core/read_write_proxy.js +++ b/src/js/core/read_write_proxy.js @@ -318,7 +318,7 @@ export class ReadWriteProxy { if (!data) { return ExplainedResult.bad("Data is empty"); } - if (!savegameInterfaces[data.version]) { + if (!savegameInterfaces[data.version] && data.version !== this.getCurrentVersion()) { return ExplainedResult.bad( `Data has invalid version: ${data.version} (expected ${this.getCurrentVersion()})` ); diff --git a/src/js/game/hub_goals.js b/src/js/game/hub_goals.js index 29f3adb5..749c332e 100644 --- a/src/js/game/hub_goals.js +++ b/src/js/game/hub_goals.js @@ -503,126 +503,126 @@ export class HubGoals extends BasicSerializableObject { return 1 / globalConfig.beltSpeedItemsPerSecond; } - - static getProcessorBaseSpeed = { - trash: processorType => 1e30, - hub: processorType => 1e30, - balancer: function (processorType) { - return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2; - }, - reader: function (processorType) { - return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt; - }, - mixer: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.painting * - globalConfig.buildingSpeeds[processorType] - ); - }, - painter: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.painting * - globalConfig.buildingSpeeds[processorType] - ); - }, - painterDouble: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.painting * - globalConfig.buildingSpeeds[processorType] - ); - }, - painterQuad: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.painting * - globalConfig.buildingSpeeds[processorType] - ); - }, - - cutter: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.processors * - globalConfig.buildingSpeeds[processorType] - ); - }, - cutterQuad: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.processors * - globalConfig.buildingSpeeds[processorType] - ); - }, - rotater: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.processors * - globalConfig.buildingSpeeds[processorType] - ); - }, - rotaterCCW: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.processors * - globalConfig.buildingSpeeds[processorType] - ); - }, - rotater180: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.processors * - globalConfig.buildingSpeeds[processorType] - ); - }, - stacker: function (processorType) { - assert( - globalConfig.buildingSpeeds[processorType], - "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType - ); - return ( - globalConfig.beltSpeedItemsPerSecond * - this.upgradeImprovements.processors * - globalConfig.buildingSpeeds[processorType] - ); - }, - }; } + +HubGoals.getProcessorBaseSpeed = { + trash: processorType => 1e30, + hub: processorType => 1e30, + balancer: function (processorType) { + return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt * 2; + }, + reader: function (processorType) { + return globalConfig.beltSpeedItemsPerSecond * this.upgradeImprovements.belt; + }, + mixer: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.painting * + globalConfig.buildingSpeeds[processorType] + ); + }, + painter: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.painting * + globalConfig.buildingSpeeds[processorType] + ); + }, + painterDouble: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.painting * + globalConfig.buildingSpeeds[processorType] + ); + }, + painterQuad: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.painting * + globalConfig.buildingSpeeds[processorType] + ); + }, + + cutter: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.processors * + globalConfig.buildingSpeeds[processorType] + ); + }, + cutterQuad: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.processors * + globalConfig.buildingSpeeds[processorType] + ); + }, + rotater: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.processors * + globalConfig.buildingSpeeds[processorType] + ); + }, + rotaterCCW: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.processors * + globalConfig.buildingSpeeds[processorType] + ); + }, + rotater180: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.processors * + globalConfig.buildingSpeeds[processorType] + ); + }, + stacker: function (processorType) { + assert( + globalConfig.buildingSpeeds[processorType], + "Processor type has no speed set in globalConfig.buildingSpeeds:()=> " + processorType + ); + return ( + globalConfig.beltSpeedItemsPerSecond * + this.upgradeImprovements.processors * + globalConfig.buildingSpeeds[processorType] + ); + }, +}; diff --git a/src/js/game/map_chunk.js b/src/js/game/map_chunk.js index b0e00053..3d80c7b9 100644 --- a/src/js/game/map_chunk.js +++ b/src/js/game/map_chunk.js @@ -359,163 +359,162 @@ export class MapChunk { } } } - - static predefined = [ - (self, rng) => { - if (self.x === 0 && self.y === 0) { - self.internalGeneratePatch(rng, 2, ColorItem.ITEM_SINGLETONS[enumColors.red], 7, 7); - return true; - } - }, - (self, rng) => { - if (self.x === 0 && self.y === 0) { - self.internalGeneratePatch(rng, 2, ColorItem.ITEM_SINGLETONS[enumColors.red], 7, 7); - return true; - } - }, - (self, rng) => { - if (self.x === -1 && self.y === 0) { - const item = self.root.shapeDefinitionMgr.getShapeItemFromShortKey("CuCuCuCu"); - self.internalGeneratePatch(rng, 2, item, globalConfig.mapChunkSize - 9, 7); - return true; - } - }, - (self, rng) => { - if (self.x === 0 && self.y === -1) { - const item = self.root.shapeDefinitionMgr.getShapeItemFromShortKey("RuRuRuRu"); - self.internalGeneratePatch(rng, 2, item, 5, globalConfig.mapChunkSize - 7); - return true; - } - }, - (self, rng) => { - if (self.x === -1 && self.y === -1) { - self.internalGeneratePatch(rng, 2, ColorItem.ITEM_SINGLETONS[enumColors.green]); - return true; - } - }, - (self, rng) => { - if (self.x === 5 && self.y === -2) { - const item = self.root.shapeDefinitionMgr.getShapeItemFromShortKey("SuSuSuSu"); - self.internalGeneratePatch(rng, 2, item, 5, globalConfig.mapChunkSize - 7); - return true; - } - }, - ]; - - static lowerLayers = [ - (self, rng, distanceToOriginInChunks) => { - // Determine how likely it is that there is a color patch - const colorPatchChance = 0.9 - clamp(distanceToOriginInChunks / 25, 0, 1) * 0.5; - - if (rng.next() < colorPatchChance / 4) { - const colorPatchSize = Math.max(2, Math.round(1 + clamp(distanceToOriginInChunks / 8, 0, 4))); - // First, determine available colors - let availableColors = [enumColors.red, enumColors.green]; - if (distanceToOriginInChunks > 2) { - availableColors.push(enumColors.blue); - } - self.internalGeneratePatch( - rng, - colorPatchSize, - ColorItem.ITEM_SINGLETONS[rng.choice(availableColors)] - ); - } - }, - (self, rng, distanceToOriginInChunks) => { - /** - * Chooses a random shape with the given weights - * @param {RandomNumberGenerator} rng - * @param {Object.} weights - * @returns {enumSubShape} - */ - var internalGenerateRandomSubShape = (rng, weights) => { - // @ts-ignore - const sum = Object.values(weights).reduce((a, b) => a + b, 0); - - const chosenNumber = rng.nextIntRange(0, sum - 1); - let accumulated = 0; - for (const key in weights) { - const weight = weights[key]; - if (accumulated + weight > chosenNumber) { - return key; - } - accumulated += weight; - } - - logger.error("Failed to find matching shape in chunk generation"); - return enumSubShape.circle; - }; - /** - * Generates a shape patch - * @param {RandomNumberGenerator} rng - * @param {number} shapePatchSize - * @param {number} distanceToOriginInChunks - */ - var internalGenerateShapePatch = (rng, shapePatchSize, distanceToOriginInChunks) => { - /** @type {[enumSubShape, enumSubShape, enumSubShape, enumSubShape]} */ - let subShapes = null; - - let weights = {}; - - // Later there is a mix of everything - weights = { - [enumSubShape.rect]: 100, - [enumSubShape.circle]: Math.round(50 + clamp(distanceToOriginInChunks * 2, 0, 50)), - [enumSubShape.star]: Math.round(20 + clamp(distanceToOriginInChunks, 0, 30)), - [enumSubShape.windmill]: Math.round(6 + clamp(distanceToOriginInChunks / 2, 0, 20)), - }; - - if (distanceToOriginInChunks < 7) { - // Initial chunks can not spawn the good stuff - weights[enumSubShape.star] = 0; - weights[enumSubShape.windmill] = 0; - } - - if (distanceToOriginInChunks < 10) { - // Initial chunk patches always have the same shape - const subShape = internalGenerateRandomSubShape(rng, weights); - subShapes = [subShape, subShape, subShape, subShape]; - } else if (distanceToOriginInChunks < 15) { - // Later patches can also have mixed ones - const subShapeA = internalGenerateRandomSubShape(rng, weights); - const subShapeB = internalGenerateRandomSubShape(rng, weights); - subShapes = [subShapeA, subShapeA, subShapeB, subShapeB]; - } else { - // Finally there is a mix of everything - subShapes = [ - internalGenerateRandomSubShape(rng, weights), - internalGenerateRandomSubShape(rng, weights), - internalGenerateRandomSubShape(rng, weights), - internalGenerateRandomSubShape(rng, weights), - ]; - } - - // Makes sure windmills never spawn as whole - let windmillCount = 0; - for (let i = 0; i < subShapes.length; ++i) { - if (subShapes[i] === enumSubShape.windmill) { - ++windmillCount; - } - } - if (windmillCount > 1) { - subShapes[0] = enumSubShape.rect; - subShapes[1] = enumSubShape.rect; - } - - const definition = self.root.shapeDefinitionMgr.getDefinitionFromSimpleShapes(subShapes); - self.internalGeneratePatch( - rng, - shapePatchSize, - self.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition) - ); - }; - - // Determine how likely it is that there is a shape patch - const shapePatchChance = 0.9 - clamp(distanceToOriginInChunks / 25, 0, 1) * 0.5; - if (rng.next() < shapePatchChance / 4) { - const shapePatchSize = Math.max(2, Math.round(1 + clamp(distanceToOriginInChunks / 8, 0, 4))); - internalGenerateShapePatch(rng, shapePatchSize, distanceToOriginInChunks); - } - }, - ]; } +MapChunk.predefined = [ + (self, rng) => { + if (self.x === 0 && self.y === 0) { + self.internalGeneratePatch(rng, 2, ColorItem.ITEM_SINGLETONS[enumColors.red], 7, 7); + return true; + } + }, + (self, rng) => { + if (self.x === 0 && self.y === 0) { + self.internalGeneratePatch(rng, 2, ColorItem.ITEM_SINGLETONS[enumColors.red], 7, 7); + return true; + } + }, + (self, rng) => { + if (self.x === -1 && self.y === 0) { + const item = self.root.shapeDefinitionMgr.getShapeItemFromShortKey("CuCuCuCu"); + self.internalGeneratePatch(rng, 2, item, globalConfig.mapChunkSize - 9, 7); + return true; + } + }, + (self, rng) => { + if (self.x === 0 && self.y === -1) { + const item = self.root.shapeDefinitionMgr.getShapeItemFromShortKey("RuRuRuRu"); + self.internalGeneratePatch(rng, 2, item, 5, globalConfig.mapChunkSize - 7); + return true; + } + }, + (self, rng) => { + if (self.x === -1 && self.y === -1) { + self.internalGeneratePatch(rng, 2, ColorItem.ITEM_SINGLETONS[enumColors.green]); + return true; + } + }, + (self, rng) => { + if (self.x === 5 && self.y === -2) { + const item = self.root.shapeDefinitionMgr.getShapeItemFromShortKey("SuSuSuSu"); + self.internalGeneratePatch(rng, 2, item, 5, globalConfig.mapChunkSize - 7); + return true; + } + }, +]; + +MapChunk.lowerLayers = [ + (self, rng, distanceToOriginInChunks) => { + // Determine how likely it is that there is a color patch + const colorPatchChance = 0.9 - clamp(distanceToOriginInChunks / 25, 0, 1) * 0.5; + + if (rng.next() < colorPatchChance / 4) { + const colorPatchSize = Math.max(2, Math.round(1 + clamp(distanceToOriginInChunks / 8, 0, 4))); + // First, determine available colors + let availableColors = [enumColors.red, enumColors.green]; + if (distanceToOriginInChunks > 2) { + availableColors.push(enumColors.blue); + } + self.internalGeneratePatch( + rng, + colorPatchSize, + ColorItem.ITEM_SINGLETONS[rng.choice(availableColors)] + ); + } + }, + (self, rng, distanceToOriginInChunks) => { + /** + * Chooses a random shape with the given weights + * @param {RandomNumberGenerator} rng + * @param {Object.} weights + * @returns {enumSubShape} + */ + var internalGenerateRandomSubShape = (rng, weights) => { + // @ts-ignore + const sum = Object.values(weights).reduce((a, b) => a + b, 0); + + const chosenNumber = rng.nextIntRange(0, sum - 1); + let accumulated = 0; + for (const key in weights) { + const weight = weights[key]; + if (accumulated + weight > chosenNumber) { + return key; + } + accumulated += weight; + } + + logger.error("Failed to find matching shape in chunk generation"); + return enumSubShape.circle; + }; + /** + * Generates a shape patch + * @param {RandomNumberGenerator} rng + * @param {number} shapePatchSize + * @param {number} distanceToOriginInChunks + */ + var internalGenerateShapePatch = (rng, shapePatchSize, distanceToOriginInChunks) => { + /** @type {[enumSubShape, enumSubShape, enumSubShape, enumSubShape]} */ + let subShapes = null; + + let weights = {}; + + // Later there is a mix of everything + weights = { + [enumSubShape.rect]: 100, + [enumSubShape.circle]: Math.round(50 + clamp(distanceToOriginInChunks * 2, 0, 50)), + [enumSubShape.star]: Math.round(20 + clamp(distanceToOriginInChunks, 0, 30)), + [enumSubShape.windmill]: Math.round(6 + clamp(distanceToOriginInChunks / 2, 0, 20)), + }; + + if (distanceToOriginInChunks < 7) { + // Initial chunks can not spawn the good stuff + weights[enumSubShape.star] = 0; + weights[enumSubShape.windmill] = 0; + } + + if (distanceToOriginInChunks < 10) { + // Initial chunk patches always have the same shape + const subShape = internalGenerateRandomSubShape(rng, weights); + subShapes = [subShape, subShape, subShape, subShape]; + } else if (distanceToOriginInChunks < 15) { + // Later patches can also have mixed ones + const subShapeA = internalGenerateRandomSubShape(rng, weights); + const subShapeB = internalGenerateRandomSubShape(rng, weights); + subShapes = [subShapeA, subShapeA, subShapeB, subShapeB]; + } else { + // Finally there is a mix of everything + subShapes = [ + internalGenerateRandomSubShape(rng, weights), + internalGenerateRandomSubShape(rng, weights), + internalGenerateRandomSubShape(rng, weights), + internalGenerateRandomSubShape(rng, weights), + ]; + } + + // Makes sure windmills never spawn as whole + let windmillCount = 0; + for (let i = 0; i < subShapes.length; ++i) { + if (subShapes[i] === enumSubShape.windmill) { + ++windmillCount; + } + } + if (windmillCount > 1) { + subShapes[0] = enumSubShape.rect; + subShapes[1] = enumSubShape.rect; + } + + const definition = self.root.shapeDefinitionMgr.getDefinitionFromSimpleShapes(subShapes); + self.internalGeneratePatch( + rng, + shapePatchSize, + self.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition) + ); + }; + + // Determine how likely it is that there is a shape patch + const shapePatchChance = 0.9 - clamp(distanceToOriginInChunks / 25, 0, 1) * 0.5; + if (rng.next() < shapePatchChance / 4) { + const shapePatchSize = Math.max(2, Math.round(1 + clamp(distanceToOriginInChunks / 8, 0, 4))); + internalGenerateShapePatch(rng, shapePatchSize, distanceToOriginInChunks); + } + }, +]; diff --git a/src/js/game/shape_definition.js b/src/js/game/shape_definition.js index 9d39bb6b..9417e97b 100644 --- a/src/js/game/shape_definition.js +++ b/src/js/game/shape_definition.js @@ -568,56 +568,50 @@ export class ShapeDefinition extends BasicSerializableObject { } return new ShapeDefinition({ layers: newLayers }); } - - static renderQuad = { - [enumSubShape.rect]: (context, quadrantSize, quadrantHalfSize, layerScale, insetPadding) => { - context.beginPath(); - const dims = quadrantSize * layerScale; - context.rect( - insetPadding + -quadrantHalfSize, - -insetPadding + quadrantHalfSize - dims, - dims, - dims - ); - }, - [enumSubShape.star]: (context, quadrantSize, quadrantHalfSize, layerScale, insetPadding) => { - context.beginPath(); - const dims = quadrantSize * layerScale; - - let originX = insetPadding - quadrantHalfSize; - let originY = -insetPadding + quadrantHalfSize - dims; - - const moveInwards = dims * 0.4; - context.moveTo(originX, originY + moveInwards); - context.lineTo(originX + dims, originY); - context.lineTo(originX + dims - moveInwards, originY + dims); - context.lineTo(originX, originY + dims); - context.closePath(); - }, - [enumSubShape.windmill]: (context, quadrantSize, quadrantHalfSize, layerScale, insetPadding) => { - context.beginPath(); - const dims = quadrantSize * layerScale; - - let originX = insetPadding - quadrantHalfSize; - let originY = -insetPadding + quadrantHalfSize - dims; - const moveInwards = dims * 0.4; - context.moveTo(originX, originY + moveInwards); - context.lineTo(originX + dims, originY); - context.lineTo(originX + dims, originY + dims); - context.lineTo(originX, originY + dims); - context.closePath(); - }, - [enumSubShape.circle]: (context, quadrantSize, quadrantHalfSize, layerScale, insetPadding) => { - context.beginPath(); - context.moveTo(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize); - context.arc( - insetPadding + -quadrantHalfSize, - -insetPadding + quadrantHalfSize, - quadrantSize * layerScale, - -Math.PI * 0.5, - 0 - ); - context.closePath(); - }, - }; } +ShapeDefinition.renderQuad = { + [enumSubShape.rect]: (context, quadrantSize, quadrantHalfSize, layerScale, insetPadding) => { + context.beginPath(); + const dims = quadrantSize * layerScale; + context.rect(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize - dims, dims, dims); + }, + [enumSubShape.star]: (context, quadrantSize, quadrantHalfSize, layerScale, insetPadding) => { + context.beginPath(); + const dims = quadrantSize * layerScale; + + let originX = insetPadding - quadrantHalfSize; + let originY = -insetPadding + quadrantHalfSize - dims; + + const moveInwards = dims * 0.4; + context.moveTo(originX, originY + moveInwards); + context.lineTo(originX + dims, originY); + context.lineTo(originX + dims - moveInwards, originY + dims); + context.lineTo(originX, originY + dims); + context.closePath(); + }, + [enumSubShape.windmill]: (context, quadrantSize, quadrantHalfSize, layerScale, insetPadding) => { + context.beginPath(); + const dims = quadrantSize * layerScale; + + let originX = insetPadding - quadrantHalfSize; + let originY = -insetPadding + quadrantHalfSize - dims; + const moveInwards = dims * 0.4; + context.moveTo(originX, originY + moveInwards); + context.lineTo(originX + dims, originY); + context.lineTo(originX + dims, originY + dims); + context.lineTo(originX, originY + dims); + context.closePath(); + }, + [enumSubShape.circle]: (context, quadrantSize, quadrantHalfSize, layerScale, insetPadding) => { + context.beginPath(); + context.moveTo(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize); + context.arc( + insetPadding + -quadrantHalfSize, + -insetPadding + quadrantHalfSize, + quadrantSize * layerScale, + -Math.PI * 0.5, + 0 + ); + context.closePath(); + }, +}; diff --git a/src/js/game/systems/display.js b/src/js/game/systems/display.js index 35c4212d..1dd1e974 100644 --- a/src/js/game/systems/display.js +++ b/src/js/game/systems/display.js @@ -70,38 +70,37 @@ export class DisplaySystem extends GameSystemWithFilter { } } } - - static displaySprites = []; - - static displayItemType = { - boolean: value => (isTrueItem(value) ? ColorItem.ITEM_SINGLETONS[enumColors.white] : null), - - color: value => - /**@type {ColorItem} */ - (value).color === enumColors.uncolored ? null : /**@type {ColorItem} */ (value), - - shape: value => value, - }; - - static displayItem = { - color: (parameters, value, origin, globalConfig) => - DisplaySystem.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered( - parameters, - (origin.x + 0.5) * globalConfig.tileSize, - (origin.y + 0.5) * globalConfig.tileSize, - globalConfig.tileSize - ), - - shape: (parameters, value, origin, globalConfig) => - value.drawItemCenteredClipped( - (origin.x + 0.5) * globalConfig.tileSize, - (origin.y + 0.5) * globalConfig.tileSize, - parameters, - DisplaySystem.shapeRadius(), - DisplaySystem.shapeBackground() - ), - }; - - static shapeRadius = () => 30; - static shapeBackground = () => true; } + +DisplaySystem.displaySprites = []; +DisplaySystem.displayItemType = { + boolean: value => (isTrueItem(value) ? ColorItem.ITEM_SINGLETONS[enumColors.white] : null), + + color: value => + /**@type {ColorItem} */ + (value).color === enumColors.uncolored ? null : /**@type {ColorItem} */ (value), + + shape: value => value, +}; + +DisplaySystem.displayItem = { + color: (parameters, value, origin, globalConfig) => + DisplaySystem.displaySprites[/** @type {ColorItem} */ (value).color].drawCachedCentered( + parameters, + (origin.x + 0.5) * globalConfig.tileSize, + (origin.y + 0.5) * globalConfig.tileSize, + globalConfig.tileSize + ), + + shape: (parameters, value, origin, globalConfig) => + value.drawItemCenteredClipped( + (origin.x + 0.5) * globalConfig.tileSize, + (origin.y + 0.5) * globalConfig.tileSize, + parameters, + DisplaySystem.shapeRadius(), + DisplaySystem.shapeBackground() + ), +}; + +DisplaySystem.shapeRadius = () => 30; +DisplaySystem.shapeBackground = () => true; diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index dd6d8da8..0a4ea6a8 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -365,61 +365,59 @@ export class ItemEjectorSystem extends GameSystemWithFilter { } } } - - static tryPassOverItemComponents = { - Belt: (comp, item, receiver, slotIndex, itemEjector) => { - const path = comp.assignedPath; - assert(path, "belt has no path"); - if (path.tryAcceptItem(item)) { - return true; - } - // Belt can have nothing else - return false; - }, - - ItemProcessor: (comp, item, receiver, slotIndex, itemEjector) => { - // Check for potential filters - if ( - !itemEjector.root.systemMgr.systems.itemProcessor.checkRequirements(receiver, item, slotIndex) - ) { - return false; - } - - // Its an item processor .. - if (comp.tryTakeItem(item, slotIndex)) { - return true; - } - // Item processor can have nothing else - return false; - }, - - UndergroundBelt: (comp, item, receiver, slotIndex, itemEjector) => { - // Its an underground belt. yay. - if (comp.tryAcceptExternalItem(item, itemEjector.root.hubGoals.getUndergroundBeltBaseSpeed())) { - return true; - } - - // Underground belt can have nothing else - return false; - }, - - Storage: (comp, item, receiver, slotIndex, itemEjector) => { - // It's a storage - if (comp.canAcceptItem(item)) { - comp.takeItem(item); - return true; - } - - // Storage can't have anything else - return false; - }, - - Filter: (comp, item, receiver, slotIndex, itemEjector) => { - // It's a filter! Unfortunately the filter has to know a lot about it's - // surrounding state and components, so it can't be within the component itself. - if (itemEjector.root.systemMgr.systems.filter.tryAcceptItem(receiver, slotIndex, item)) { - return true; - } - }, - }; } + +ItemEjectorSystem.tryPassOverItemComponents = { + Belt: (comp, item, receiver, slotIndex, itemEjector) => { + const path = comp.assignedPath; + assert(path, "belt has no path"); + if (path.tryAcceptItem(item)) { + return true; + } + // Belt can have nothing else + return false; + }, + + ItemProcessor: (comp, item, receiver, slotIndex, itemEjector) => { + // Check for potential filters + if (!itemEjector.root.systemMgr.systems.itemProcessor.checkRequirements(receiver, item, slotIndex)) { + return false; + } + + // Its an item processor .. + if (comp.tryTakeItem(item, slotIndex)) { + return true; + } + // Item processor can have nothing else + return false; + }, + + UndergroundBelt: (comp, item, receiver, slotIndex, itemEjector) => { + // Its an underground belt. yay. + if (comp.tryAcceptExternalItem(item, itemEjector.root.hubGoals.getUndergroundBeltBaseSpeed())) { + return true; + } + + // Underground belt can have nothing else + return false; + }, + + Storage: (comp, item, receiver, slotIndex, itemEjector) => { + // It's a storage + if (comp.canAcceptItem(item)) { + comp.takeItem(item); + return true; + } + + // Storage can't have anything else + return false; + }, + + Filter: (comp, item, receiver, slotIndex, itemEjector) => { + // It's a filter! Unfortunately the filter has to know a lot about it's + // surrounding state and components, so it can't be within the component itself. + if (itemEjector.root.systemMgr.systems.filter.tryAcceptItem(receiver, slotIndex, item)) { + return true; + } + }, +}; diff --git a/src/js/game/systems/item_processor.js b/src/js/game/systems/item_processor.js index 5db68930..685e103b 100644 --- a/src/js/game/systems/item_processor.js +++ b/src/js/game/systems/item_processor.js @@ -497,83 +497,77 @@ export class ItemProcessorSystem extends GameSystemWithFilter { this.root.hubGoals.handleDefinitionDelivered(item.definition); } } +} - static checkRequirements = { - [enumItemProcessorRequirements.painterQuad]: ( - entity, - item, - slotIndex, - itemProcessorComp, - pinsComp - ) => { - if (slotIndex === 0) { - // Always accept the shape - return true; - } - - // Check the network value at the given slot - const network = pinsComp.slots[slotIndex - 1].linkedNetwork; - const slotIsEnabled = network && network.hasValue() && isTruthyItem(network.currentValue); - if (!slotIsEnabled) { - return false; - } +ItemProcessorSystem.checkRequirements = { + [enumItemProcessorRequirements.painterQuad]: (entity, item, slotIndex, itemProcessorComp, pinsComp) => { + if (slotIndex === 0) { + // Always accept the shape return true; - }, - }; + } - static canProcess = { - [enumItemProcessorRequirements.painterQuad]: (entity, processorComp) => { - const pinsComp = entity.components.WiredPins; + // Check the network value at the given slot + const network = pinsComp.slots[slotIndex - 1].linkedNetwork; + const slotIsEnabled = network && network.hasValue() && isTruthyItem(network.currentValue); + if (!slotIsEnabled) { + return false; + } + return true; + }, +}; - /** @type {Object.} */ - const itemsBySlot = {}; - for (let i = 0; i < processorComp.inputSlots.length; ++i) { - itemsBySlot[processorComp.inputSlots[i].sourceSlot] = processorComp.inputSlots[i]; +ItemProcessorSystem.canProcess = { + [enumItemProcessorRequirements.painterQuad]: (entity, processorComp) => { + const pinsComp = entity.components.WiredPins; + + /** @type {Object.} */ + const itemsBySlot = {}; + for (let i = 0; i < processorComp.inputSlots.length; ++i) { + itemsBySlot[processorComp.inputSlots[i].sourceSlot] = processorComp.inputSlots[i]; + } + + // First slot is the shape, so if it's not there we can't do anything + if (!itemsBySlot[0]) { + return false; + } + + const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item); + const slotStatus = []; + + // Check which slots are enabled + for (let i = 0; i < 4; ++i) { + // Extract the network value on the Nth pin + const network = pinsComp.slots[i].linkedNetwork; + const networkValue = network && network.hasValue() ? network.currentValue : null; + + // If there is no "1" on that slot, don't paint there + if (!isTruthyItem(networkValue)) { + slotStatus.push(false); + continue; } - // First slot is the shape, so if it's not there we can't do anything - if (!itemsBySlot[0]) { - return false; - } + slotStatus.push(true); + } - const shapeItem = /** @type {ShapeItem} */ (itemsBySlot[0].item); - const slotStatus = []; + // All slots are disabled + if (!slotStatus.includes(true)) { + return false; + } - // Check which slots are enabled - for (let i = 0; i < 4; ++i) { - // Extract the network value on the Nth pin - const network = pinsComp.slots[i].linkedNetwork; - const networkValue = network && network.hasValue() ? network.currentValue : null; - - // If there is no "1" on that slot, don't paint there - if (!isTruthyItem(networkValue)) { - slotStatus.push(false); - continue; - } - - slotStatus.push(true); - } - - // All slots are disabled - if (!slotStatus.includes(true)) { - return false; - } - - // Check if all colors of the enabled slots are there - for (let i = 0; i < slotStatus.length; ++i) { - if (slotStatus[i] && !itemsBySlot[1 + i]) { - // A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant, - // it is not possible to paint, but if there is nothing we can ignore it - for (let j = 0; j < 4; ++j) { - const layer = shapeItem.definition.layers[j]; - if (layer && layer[i]) { - return false; - } + // Check if all colors of the enabled slots are there + for (let i = 0; i < slotStatus.length; ++i) { + if (slotStatus[i] && !itemsBySlot[1 + i]) { + // A slot which is enabled wasn't enabled. Make sure if there is anything on the quadrant, + // it is not possible to paint, but if there is nothing we can ignore it + for (let j = 0; j < 4; ++j) { + const layer = shapeItem.definition.layers[j]; + if (layer && layer[i]) { + return false; } } } + } - return true; - }, - }; -} + return true; + }, +}; diff --git a/src/js/game/systems/item_processor_overlays.js b/src/js/game/systems/item_processor_overlays.js index 697b06ac..ffdf0e47 100644 --- a/src/js/game/systems/item_processor_overlays.js +++ b/src/js/game/systems/item_processor_overlays.js @@ -144,10 +144,10 @@ export class ItemProcessorOverlaysSystem extends GameSystem { parameters.context.globalAlpha = 1; } - - static processorOverlayStatic = { - [enumItemProcessorRequirements.painterQuad]: function (parameters, chunk, entity, processorComp) { - this.drawConnectedSlotRequirement(parameters, entity, { drawIfFalse: true }); - }, - }; } + +ItemProcessorOverlaysSystem.processorOverlayStatic = { + [enumItemProcessorRequirements.painterQuad]: function (parameters, chunk, entity, processorComp) { + this.drawConnectedSlotRequirement(parameters, entity, { drawIfFalse: true }); + }, +}; diff --git a/src/js/game/systems/wire.js b/src/js/game/systems/wire.js index a1a09c6f..9f84a035 100644 --- a/src/js/game/systems/wire.js +++ b/src/js/game/systems/wire.js @@ -763,6 +763,6 @@ export class WireSystem extends GameSystemWithFilter { } } } - - static getForwardedTile = (tunnelComp, staticComp, offset) => staticComp.origin.add(offset); } + +WireSystem.getForwardedTile = (tunnelComp, staticComp, offset) => staticComp.origin.add(offset); diff --git a/src/js/main.js b/src/js/main.js index 07190e68..940591d2 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -80,77 +80,23 @@ window.onload = async () => { logSection("Boot Process", "#f9a825"); - // var modpack = { - // mods: [{ - // url: "http://localhost:3006/mod", - // id: "a18121cf-fc7c-4f23-906d-b7ab0512bbc8", - // config: {}, - // settings: { - // hasMakeModButton: { - // value: true, - // }, - // // enum: { - // // value: "new test", - // // }, - // // range: { - // // value: 10, - // // }, - // }, - // }, - // // { - // // url: "http://localhost:3010/mod", - // // id: "cbae38a0-7ac5-4a0a-9985-da3110b1a6e8", - // // config: {}, - // // settings: { - // // hasHubPlacement: { value: true }, - // // }, - // // }, - // // { - // // url: "http://localhost:3011/mod", - // // id: "cba4229f-851b-4f01-807f-2a0c86c3aed7", - // // config: {}, - // // settings: {}, - // // }, - // // { - // // url: "http://localhost:3012/mod", - // // id: "b6eaf06b-a0f7-48ac-b219-4e97fd275beb", - // // config: {}, - // // settings: {}, - // // }, - // // { - // // url: "http://localhost:3013/mod", - // // id: "ca2fb74a-3827-4805-b5fe-8a23bf913c65", - // // config: {}, - // // settings: {}, - // // }, - // // { - // // url: "http://localhost:3014/mod", - // // id: "3ae3751d-6dfb-4504-92dc-99a38a3d8c06", - // // config: {}, - // // settings: {}, - // // }, - // ], - // }; let user = undefined; let instance = undefined; let modFolderContents = []; if (G_IS_STANDALONE) { - const dirResult = await getIPCRenderer().invoke("fs-job", { + modFolderContents = getIPCRenderer().sendSync("fs-sync-job", { folder: "mods", type: "readDir", filename: "", - }); - if (dirResult.success) modFolderContents = dirResult.data; - + }).data; if (modFolderContents.includes("modpack.json")) { - const instanceResult = await getIPCRenderer().invoke("fs-job", { + instance = getIPCRenderer().sendSync("fs-sync-job", { folder: "mods", type: "read", filename: "modpack.json", }); - if (instanceResult.success) instance = JSON.parse(instanceResult.data); } - } else { + } else if (!G_IS_DEV) { user = JSON.parse(localStorage.getItem("user")); instance = JSON.parse(localStorage.getItem("instance")); // instance = { @@ -175,7 +121,7 @@ window.onload = async () => { if (mod.split(".").pop() !== "js") continue; modMgr.addMod(mod, true); } - } else await modMgr.addModPackMods(); + } else if (modMgr.modPack) await modMgr.addModPackMods(); modMgr.loadMods(); initDrawUtils();