mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-06-13 13:04:03 +00:00
Fixed some static declarations
This commit is contained in:
parent
ca5218561f
commit
dd23eb741d
@ -49,6 +49,19 @@ 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());
|
||||
@ -396,18 +409,3 @@ export class Application {
|
||||
this.checkResize(true);
|
||||
}
|
||||
}
|
||||
|
||||
Application.trackClicks = undefined;
|
||||
|
||||
Application.getMainContentHTML = undefined;
|
||||
|
||||
Application.states = {
|
||||
PreloadState,
|
||||
MobileWarningState,
|
||||
MainMenuState,
|
||||
InGameState,
|
||||
SettingsState,
|
||||
KeybindingsState,
|
||||
AboutState,
|
||||
ChangelogState,
|
||||
};
|
||||
|
@ -503,125 +503,126 @@ export class HubGoals extends BasicSerializableObject {
|
||||
|
||||
return 1 / globalConfig.beltSpeedItemsPerSecond;
|
||||
}
|
||||
}
|
||||
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]
|
||||
);
|
||||
},
|
||||
};
|
||||
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]
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -359,163 +359,163 @@ export class MapChunk {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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.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.<enumSubShape, number>} weights
|
||||
* @returns {enumSubShape}
|
||||
*/
|
||||
var internalGenerateRandomSubShape = (rng, weights) => {
|
||||
// @ts-ignore
|
||||
const sum = Object.values(weights).reduce((a, b) => a + b, 0);
|
||||
},
|
||||
(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;
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
accumulated += weight;
|
||||
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.<enumSubShape, number>} weights
|
||||
* @returns {enumSubShape}
|
||||
*/
|
||||
var internalGenerateRandomSubShape = (rng, weights) => {
|
||||
// @ts-ignore
|
||||
const sum = Object.values(weights).reduce((a, b) => a + b, 0);
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
let weights = {};
|
||||
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;
|
||||
|
||||
// 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)),
|
||||
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)
|
||||
);
|
||||
};
|
||||
|
||||
if (distanceToOriginInChunks < 7) {
|
||||
// Initial chunks can not spawn the good stuff
|
||||
weights[enumSubShape.star] = 0;
|
||||
weights[enumSubShape.windmill] = 0;
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
},
|
||||
];
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -568,51 +568,56 @@ 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();
|
||||
},
|
||||
};
|
||||
|
@ -70,38 +70,38 @@ 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;
|
||||
|
@ -364,59 +364,61 @@ export class ItemEjectorSystem extends GameSystemWithFilter {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
},
|
||||
|
||||
// Its an item processor ..
|
||||
if (comp.tryTakeItem(item, slotIndex)) {
|
||||
return true;
|
||||
}
|
||||
// Item processor 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;
|
||||
}
|
||||
|
||||
UndergroundBelt: (comp, item, receiver, slotIndex, itemEjector) => {
|
||||
// Its an underground belt. yay.
|
||||
if (comp.tryAcceptExternalItem(item, itemEjector.root.hubGoals.getUndergroundBeltBaseSpeed())) {
|
||||
return true;
|
||||
}
|
||||
// Its an item processor ..
|
||||
if (comp.tryTakeItem(item, slotIndex)) {
|
||||
return true;
|
||||
}
|
||||
// Item processor can have nothing else
|
||||
return false;
|
||||
},
|
||||
|
||||
// Underground belt 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;
|
||||
}
|
||||
|
||||
Storage: (comp, item, receiver, slotIndex, itemEjector) => {
|
||||
// It's a storage
|
||||
if (comp.canAcceptItem(item)) {
|
||||
comp.takeItem(item);
|
||||
return true;
|
||||
}
|
||||
// Underground belt can have nothing else
|
||||
return false;
|
||||
},
|
||||
|
||||
// Storage can't have anything else
|
||||
return false;
|
||||
},
|
||||
Storage: (comp, item, receiver, slotIndex, itemEjector) => {
|
||||
// It's a storage
|
||||
if (comp.canAcceptItem(item)) {
|
||||
comp.takeItem(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
},
|
||||
};
|
||||
// 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;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -497,77 +497,83 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
this.root.hubGoals.handleDefinitionDelivered(item.definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemProcessorSystem.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;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
ItemProcessorSystem.canProcess = {
|
||||
[enumItemProcessorRequirements.painterQuad]: (entity, processorComp) => {
|
||||
const pinsComp = entity.components.WiredPins;
|
||||
|
||||
/** @type {Object.<number, { item: BaseItem, sourceSlot: number }>} */
|
||||
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;
|
||||
static checkRequirements = {
|
||||
[enumItemProcessorRequirements.painterQuad]: (
|
||||
entity,
|
||||
item,
|
||||
slotIndex,
|
||||
itemProcessorComp,
|
||||
pinsComp
|
||||
) => {
|
||||
if (slotIndex === 0) {
|
||||
// Always accept the shape
|
||||
return true;
|
||||
}
|
||||
|
||||
slotStatus.push(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;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
// All slots are disabled
|
||||
if (!slotStatus.includes(true)) {
|
||||
return false;
|
||||
}
|
||||
static canProcess = {
|
||||
[enumItemProcessorRequirements.painterQuad]: (entity, processorComp) => {
|
||||
const pinsComp = entity.components.WiredPins;
|
||||
|
||||
// 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;
|
||||
/** @type {Object.<number, { item: BaseItem, sourceSlot: number }>} */
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
return true;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -144,10 +144,10 @@ export class ItemProcessorOverlaysSystem extends GameSystem {
|
||||
|
||||
parameters.context.globalAlpha = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ItemProcessorOverlaysSystem.processorOverlayStatic = {
|
||||
[enumItemProcessorRequirements.painterQuad]: function (parameters, chunk, entity, processorComp) {
|
||||
this.drawConnectedSlotRequirement(parameters, entity, { drawIfFalse: true });
|
||||
},
|
||||
};
|
||||
static processorOverlayStatic = {
|
||||
[enumItemProcessorRequirements.painterQuad]: function (parameters, chunk, entity, processorComp) {
|
||||
this.drawConnectedSlotRequirement(parameters, entity, { drawIfFalse: true });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -760,6 +760,6 @@ export class WireSystem extends GameSystemWithFilter {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WireSystem.getForwardedTile = (tunnelComp, staticComp, offset) => staticComp.origin.add(offset);
|
||||
static getForwardedTile = (tunnelComp, staticComp, offset) => staticComp.origin.add(offset);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user