mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-06-13 13:04:03 +00:00
Shapes support (taken from Dimava's MODZ with slight modifications)
This commit is contained in:
parent
ee0770ec0b
commit
6612a58ff5
@ -12,6 +12,7 @@ import { registerBuildingVariant } from "../game/building_codes";
|
||||
import { supportedBuildings } from "../game/hud/parts/buildings_toolbar";
|
||||
import { KEYMAPPINGS, key } from "../game/key_action_mapper";
|
||||
import { T } from "../translations";
|
||||
import { ShapeData, allShapeData, initShapes } from "../game/shapes";
|
||||
import { globalConfig } from "../core/config";
|
||||
|
||||
export { MetaModBuilding } from "./mod_building";
|
||||
@ -28,6 +29,7 @@ export { ModSystem, ModSystemWithFilter } from "./mod_system";
|
||||
* @property {Array<typeof ModItem>=} items
|
||||
* @property {Array<typeof ModProcessor>=} processors
|
||||
* @property {Array<typeof ModSystem | typeof ModSystemWithFilter>=} systems
|
||||
* @property {Array<ShapeData>=} shapes
|
||||
*/
|
||||
|
||||
const logger = createLogger("GeoZ");
|
||||
@ -50,6 +52,9 @@ export const ModItems = [];
|
||||
/** @type {Array<typeof MetaModBuilding>} */
|
||||
export const ModBuildings = [];
|
||||
|
||||
/** @type {Array<ShapeData>} */
|
||||
export const ModShapes = [];
|
||||
|
||||
const GameSystemManager_internalInitSystems_original = GameSystemManager.prototype.internalInitSystems;
|
||||
GameSystemManager.prototype.internalInitSystems = function () {
|
||||
GameSystemManager_internalInitSystems_original.call(this);
|
||||
@ -224,6 +229,14 @@ export async function initMods() {
|
||||
T.buildings[base_id][variant] = translations.variants[variant];
|
||||
}
|
||||
}
|
||||
|
||||
if(mod.shapes) {
|
||||
mod_infos += `${mod.shapes.length} shapes, `;
|
||||
for (const shape of mod.shapes) {
|
||||
ModShapes.push(shape);
|
||||
allShapeData[shape.id] = shape;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.log(mod_infos);
|
||||
|
@ -2,9 +2,10 @@ import { globalConfig } from "../core/config";
|
||||
import { clamp, findNiceIntegerValue, randomChoice, randomInt } from "../core/utils";
|
||||
import { BasicSerializableObject, types } from "../savegame/serialization";
|
||||
import { enumColors } from "./colors";
|
||||
import { allShapeData } from "./shapes";
|
||||
import { enumItemProcessorTypes } from "./components/item_processor";
|
||||
import { GameRoot } from "./root";
|
||||
import { enumSubShape, ShapeDefinition } from "./shape_definition";
|
||||
import { ShapeDefinition, ShapeLayer } from "./shape_definition";
|
||||
import { enumHubGoalRewards, tutorialGoals } from "./tutorial_goals";
|
||||
import { UPGRADES } from "./upgrades";
|
||||
|
||||
@ -324,16 +325,16 @@ export class HubGoals extends BasicSerializableObject {
|
||||
*/
|
||||
createRandomShape() {
|
||||
const layerCount = clamp(this.level / 25, 2, 4);
|
||||
/** @type {Array<import("./shape_definition").ShapeLayer>} */
|
||||
/** @type {Array<ShapeLayer>} */
|
||||
let layers = [];
|
||||
|
||||
const randomColor = () => randomChoice(Object.values(enumColors));
|
||||
const randomShape = () => randomChoice(Object.values(enumSubShape));
|
||||
const randomShape = () => randomChoice(Object.values(allShapeData).map(d => d.id));
|
||||
|
||||
let anyIsMissingTwo = false;
|
||||
|
||||
for (let i = 0; i < layerCount; ++i) {
|
||||
/** @type {import("./shape_definition").ShapeLayer} */
|
||||
/** @type {ShapeLayer} */
|
||||
const layer = [null, null, null, null];
|
||||
|
||||
for (let quad = 0; quad < 4; ++quad) {
|
||||
|
@ -5,10 +5,11 @@ import { clamp, fastArrayDeleteValueIfContained, make2DUndefinedArray } from "..
|
||||
import { Vector } from "../core/vector";
|
||||
import { BaseItem } from "./base_item";
|
||||
import { enumColors } from "./colors";
|
||||
import { allShapeData } from "./shapes";
|
||||
import { Entity } from "./entity";
|
||||
import { COLOR_ITEM_SINGLETONS } from "./items/color_item";
|
||||
import { GameRoot } from "./root";
|
||||
import { enumSubShape } from "./shape_definition";
|
||||
import { enumSubShape } from "./shapes";
|
||||
import { Rectangle } from "../core/rectangle";
|
||||
|
||||
const logger = createLogger("map_chunk");
|
||||
@ -180,56 +181,58 @@ export class MapChunk {
|
||||
*/
|
||||
internalGenerateShapePatch(rng, shapePatchSize, distanceToOriginInChunks) {
|
||||
/** @type {[enumSubShape, enumSubShape, enumSubShape, enumSubShape]} */
|
||||
let subShapes = null;
|
||||
let quads = 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 = this.internalGenerateRandomSubShape(rng, weights);
|
||||
subShapes = [subShape, subShape, subShape, subShape];
|
||||
} else if (distanceToOriginInChunks < 15) {
|
||||
// Later patches can also have mixed ones
|
||||
const subShapeA = this.internalGenerateRandomSubShape(rng, weights);
|
||||
const subShapeB = this.internalGenerateRandomSubShape(rng, weights);
|
||||
subShapes = [subShapeA, subShapeA, subShapeB, subShapeB];
|
||||
} else {
|
||||
// Finally there is a mix of everything
|
||||
subShapes = [
|
||||
this.internalGenerateRandomSubShape(rng, weights),
|
||||
this.internalGenerateRandomSubShape(rng, weights),
|
||||
this.internalGenerateRandomSubShape(rng, weights),
|
||||
this.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;
|
||||
for (let s in allShapeData) {
|
||||
const data = allShapeData[s];
|
||||
if (!data.spawnData || distanceToOriginInChunks < data.spawnData.minDistance) {
|
||||
continue;
|
||||
}
|
||||
const chances = data.spawnData.chances;
|
||||
const chance = Math.round(
|
||||
clamp(
|
||||
chances.min + (distanceToOriginInChunks - data.spawnData.minDistance) * chances.distanceMultiplier,
|
||||
0,
|
||||
chances.max
|
||||
)
|
||||
);
|
||||
if (chance) {
|
||||
weights[data.id] = chance;
|
||||
}
|
||||
}
|
||||
if (windmillCount > 1) {
|
||||
subShapes[0] = enumSubShape.rect;
|
||||
subShapes[1] = enumSubShape.rect;
|
||||
quads = [
|
||||
this.internalGenerateRandomSubShape(rng, weights),
|
||||
this.internalGenerateRandomSubShape(rng, weights),
|
||||
this.internalGenerateRandomSubShape(rng, weights),
|
||||
this.internalGenerateRandomSubShape(rng, weights),
|
||||
];
|
||||
if (distanceToOriginInChunks < 10) {
|
||||
// Initial chunk patches always have the same shape
|
||||
quads = [quads[0], quads[0], quads[0], quads[0]];
|
||||
} else if (distanceToOriginInChunks < 15) {
|
||||
// Later patches can also have mixed ones
|
||||
quads = [quads[0], quads[0], quads[1], quads[1]];
|
||||
} else {
|
||||
// if (quads[0] == quads[2] && quads[0] != quads[3] && quads[0] != quads[1]) {
|
||||
// quads = [quads[0], quads[2], quads[1], quads[3]];
|
||||
// }
|
||||
// if (quads[1] == quads[3] && quads[1] != quads[0] && quads[1] != quads[2]) {
|
||||
// quads = [quads[0], quads[2], quads[1], quads[3]];
|
||||
// }
|
||||
}
|
||||
|
||||
const definition = this.root.shapeDefinitionMgr.getDefinitionFromSimpleShapes(subShapes);
|
||||
if (
|
||||
quads.filter(q => q == quads[0]).length > allShapeData[quads[0]].spawnData.maxQuarters ||
|
||||
quads.filter(q => q == quads[1]).length > allShapeData[quads[1]].spawnData.maxQuarters ||
|
||||
quads.filter(q => q == quads[2]).length > allShapeData[quads[2]].spawnData.maxQuarters
|
||||
) {
|
||||
return this.internalGenerateShapePatch(rng, shapePatchSize, distanceToOriginInChunks);
|
||||
}
|
||||
|
||||
let colors = /** @type {[string, string, string, string]} */ (quads.map(q => allShapeData[q].spawnData.color));
|
||||
|
||||
const definition = this.root.shapeDefinitionMgr.getDefinitionFromSimpleShapesAndColors(quads, colors);
|
||||
this.internalGeneratePatch(
|
||||
rng,
|
||||
shapePatchSize,
|
||||
|
@ -6,6 +6,7 @@ import { Vector } from "../core/vector";
|
||||
import { BasicSerializableObject, types } from "../savegame/serialization";
|
||||
import { enumColors, enumColorsToHexCode, enumColorToShortcode, enumShortcodeToColor } from "./colors";
|
||||
import { THEME } from "./theme";
|
||||
import { allShapeData, ShapeData, enumShortcodeToSubShape, enumSubShapeToShortcode, enumSubShape } from "./shapes";
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
@ -26,28 +27,6 @@ const arrayQuadrantIndexToOffset = [
|
||||
new Vector(-1, -1), // tl
|
||||
];
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumSubShape = {
|
||||
rect: "rect",
|
||||
circle: "circle",
|
||||
star: "star",
|
||||
windmill: "windmill",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumSubShapeToShortcode = {
|
||||
[enumSubShape.rect]: "R",
|
||||
[enumSubShape.circle]: "C",
|
||||
[enumSubShape.star]: "S",
|
||||
[enumSubShape.windmill]: "W",
|
||||
};
|
||||
|
||||
/** @enum {enumSubShape} */
|
||||
export const enumShortcodeToSubShape = {};
|
||||
for (const key in enumSubShapeToShortcode) {
|
||||
enumShortcodeToSubShape[enumSubShapeToShortcode[key]] = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given parameters to a valid shape definition
|
||||
* @param {*} layers
|
||||
@ -85,6 +64,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
return errorCode;
|
||||
}
|
||||
const definition = ShapeDefinition.fromShortKey(data);
|
||||
/** @type {Array<ShapeLayer>} */
|
||||
this.layers = /** @type {Array<ShapeLayer>} */ (definition.layers);
|
||||
}
|
||||
|
||||
@ -336,97 +316,98 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
for (let layerIndex = 0; layerIndex < this.layers.length; ++layerIndex) {
|
||||
const quadrants = this.layers[layerIndex];
|
||||
|
||||
let quads = quadrants
|
||||
.map((e, i) => ({ e, i }))
|
||||
.filter(e => e.e)
|
||||
.map(e => ({ ...e.e, quadrantIndex: e.i }))
|
||||
const layerScale = Math.max(0.1, 0.9 - layerIndex * 0.22);
|
||||
|
||||
for (let quadrantIndex = 0; quadrantIndex < 4; ++quadrantIndex) {
|
||||
if (!quadrants[quadrantIndex]) {
|
||||
for (let quad of quads) {
|
||||
if (!quad) {
|
||||
continue;
|
||||
}
|
||||
const { subShape, color, quadrantIndex } = quad;
|
||||
if (subShape == "-") {
|
||||
continue;
|
||||
}
|
||||
const { subShape, color } = quadrants[quadrantIndex];
|
||||
|
||||
const quadrantPos = arrayQuadrantIndexToOffset[quadrantIndex];
|
||||
|
||||
const centerQuadrantX = quadrantPos.x * quadrantHalfSize;
|
||||
const centerQuadrantY = quadrantPos.y * quadrantHalfSize;
|
||||
|
||||
const rotation = Math.radians(quadrantIndex * 90);
|
||||
|
||||
context.save();
|
||||
context.translate(centerQuadrantX, centerQuadrantY);
|
||||
context.rotate(rotation);
|
||||
|
||||
context.fillStyle = enumColorsToHexCode[color];
|
||||
context.strokeStyle = THEME.items.outline;
|
||||
context.lineWidth = THEME.items.outlineWidth;
|
||||
const lineWidth = THEME.items.outlineWidth * Math.pow(0.8, layerIndex);
|
||||
context.lineWidth = lineWidth;
|
||||
|
||||
const insetPadding = 0.0;
|
||||
|
||||
switch (subShape) {
|
||||
case enumSubShape.rect: {
|
||||
context.beginPath();
|
||||
const dims = quadrantSize * layerScale;
|
||||
context.rect(
|
||||
insetPadding + -quadrantHalfSize,
|
||||
-insetPadding + quadrantHalfSize - dims,
|
||||
dims,
|
||||
dims
|
||||
);
|
||||
|
||||
break;
|
||||
const dims = quadrantSize * layerScale;
|
||||
const innerDims = insetPadding - quadrantHalfSize;
|
||||
|
||||
let began = null;
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
/** @type {import("./shapes").BeginDrawShape} */
|
||||
function begin(args) {
|
||||
context.save();
|
||||
context.translate(innerDims, -innerDims);
|
||||
context.scale(dims, -dims);
|
||||
context.lineWidth = lineWidth / dims / (args.scale || 1);
|
||||
if (args.scale) {
|
||||
context.scale(args.scale, args.scale);
|
||||
}
|
||||
case enumSubShape.star: {
|
||||
if (args.beginPath) {
|
||||
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);
|
||||
}
|
||||
if (args.moveToZero) {
|
||||
context.moveTo(0, 0);
|
||||
}
|
||||
began = args;
|
||||
}
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
function end() {
|
||||
if (!began) {
|
||||
return;
|
||||
}
|
||||
if (began.path) {
|
||||
context.closePath();
|
||||
break;
|
||||
}
|
||||
|
||||
case enumSubShape.windmill: {
|
||||
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();
|
||||
break;
|
||||
}
|
||||
|
||||
case enumSubShape.circle: {
|
||||
context.beginPath();
|
||||
context.moveTo(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize);
|
||||
context.arc(
|
||||
insetPadding + -quadrantHalfSize,
|
||||
-insetPadding + quadrantHalfSize,
|
||||
quadrantSize * layerScale,
|
||||
-Math.PI * 0.5,
|
||||
0
|
||||
);
|
||||
context.closePath();
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
assertAlways(false, "Unkown sub shape: " + subShape);
|
||||
}
|
||||
context.restore();
|
||||
}
|
||||
|
||||
context.fill();
|
||||
context.stroke();
|
||||
/** @type {ShapeData} */
|
||||
let shape = allShapeData[subShape];
|
||||
assertAlways(shape.draw, "shape should be drawable!");
|
||||
if (typeof shape.draw === "string") {
|
||||
let draw = shape.draw;
|
||||
begin({ scale: 1 });
|
||||
let p = new Path2D(draw);
|
||||
context.fill(p);
|
||||
context.stroke(p);
|
||||
end();
|
||||
} else {
|
||||
shape.draw({
|
||||
dims,
|
||||
innerDims,
|
||||
layer: layerIndex,
|
||||
quadrant: quadrantIndex,
|
||||
context,
|
||||
color,
|
||||
begin,
|
||||
});
|
||||
end();
|
||||
context.fill();
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
context.rotate(-rotation);
|
||||
context.translate(-centerQuadrantX, -centerQuadrantY);
|
||||
context.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,8 @@ import { BasicSerializableObject } from "../savegame/serialization";
|
||||
import { enumColors } from "./colors";
|
||||
import { ShapeItem } from "./items/shape_item";
|
||||
import { GameRoot } from "./root";
|
||||
import { enumSubShape, ShapeDefinition } from "./shape_definition";
|
||||
import { ShapeDefinition } from "./shape_definition";
|
||||
import { enumSubShape } from "./shapes";
|
||||
|
||||
const logger = createLogger("shape_definition_manager");
|
||||
|
||||
@ -256,4 +257,18 @@ export class ShapeDefinitionManager extends BasicSerializableObject {
|
||||
|
||||
return this.registerOrReturnHandle(new ShapeDefinition({ layers: [shapeLayer] }));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {[enumSubShape, enumSubShape, enumSubShape, enumSubShape]} subShapes
|
||||
* @param {[string, string, string, string]} colors
|
||||
* @returns {ShapeDefinition}
|
||||
*/
|
||||
getDefinitionFromSimpleShapesAndColors(subShapes, colors) {
|
||||
const shapeLayer = /** @type {import("./shape_definition").ShapeLayer} */ (subShapes.map(
|
||||
(subShape, i) => ({ subShape, color: colors[i] })
|
||||
));
|
||||
|
||||
return this.registerOrReturnHandle(new ShapeDefinition({ layers: [shapeLayer] }));
|
||||
}
|
||||
}
|
||||
|
181
src/js/game/shapes.js
Normal file
181
src/js/game/shapes.js
Normal file
@ -0,0 +1,181 @@
|
||||
/** @enum {string} */
|
||||
export const enumSubShape = {
|
||||
rect: "rect",
|
||||
circle: "circle",
|
||||
star: "star",
|
||||
windmill: "windmill",
|
||||
};
|
||||
|
||||
/** @enum {string} */
|
||||
export const enumSubShapeToShortcode = {
|
||||
[enumSubShape.rect]: "R",
|
||||
[enumSubShape.circle]: "C",
|
||||
[enumSubShape.star]: "S",
|
||||
[enumSubShape.windmill]: "W",
|
||||
};
|
||||
|
||||
/** @enum {enumSubShape} */
|
||||
export const enumShortcodeToSubShape = {};
|
||||
for (const key in enumSubShapeToShortcode) {
|
||||
enumShortcodeToSubShape[enumSubShapeToShortcode[key]] = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback BeginDrawShape
|
||||
* @param {{
|
||||
* scale?: number,
|
||||
* beginPath?: boolean,
|
||||
* moveToZero?: true
|
||||
* }} args
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} DrawShapeParams
|
||||
* @property {number} dims
|
||||
* @property {number} innerDims
|
||||
* @property {number} layer
|
||||
* @property {number} quadrant
|
||||
* @property {CanvasRenderingContext2D} context
|
||||
* @property {string} color
|
||||
* @property {BeginDrawShape} begin
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback DrawShape
|
||||
* @param {DrawShapeParams} args
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SpawnChanceData
|
||||
* @property {number} [min=0]
|
||||
* @property {number} [max=100]
|
||||
* @property {number} [distanceMultiplier=1]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ShapeSpawnData
|
||||
* @property {string} [color="uncolored"]
|
||||
* @property {number} [minDistance=0]
|
||||
* @property {number} [maxQuarters=4]
|
||||
* @property {SpawnChanceData} [chances]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ShapeData
|
||||
* @property {string} id
|
||||
* @property {string} code
|
||||
* @property {DrawShape | string} draw
|
||||
* @property {number} tier
|
||||
* @property {ShapeSpawnData} [spawnData]
|
||||
*/
|
||||
|
||||
/** @type {Object<string, ShapeData>} */
|
||||
export const allShapeData = {
|
||||
rect: {
|
||||
id: "rect",
|
||||
code: "R",
|
||||
draw: "M 0 0 v 1 h 1 v -1 z",
|
||||
tier: 0,
|
||||
spawnData: {
|
||||
color: "uncolored",
|
||||
maxQuarters: 4,
|
||||
minDistance: 0,
|
||||
chances: {
|
||||
min: 100,
|
||||
distanceMultiplier: 0,
|
||||
max: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
circle: {
|
||||
id: "circle",
|
||||
code: "C",
|
||||
draw: "M 0 0 l 1 0 a 1 1 0 0 1 -1 1 z ",
|
||||
tier: 0,
|
||||
spawnData: {
|
||||
color: "uncolored",
|
||||
maxQuarters: 4,
|
||||
minDistance: 0,
|
||||
chances: {
|
||||
min: 50,
|
||||
distanceMultiplier: 15,
|
||||
max: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
star: {
|
||||
id: "star",
|
||||
code: "S",
|
||||
draw: "M 0 0 L 0 0.6 1 1 0.6 0 z",
|
||||
tier: 0.5,
|
||||
spawnData: {
|
||||
color: "uncolored",
|
||||
maxQuarters: 4,
|
||||
minDistance: 5,
|
||||
chances: {
|
||||
min: 20,
|
||||
distanceMultiplier: 10,
|
||||
max: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
windmill: {
|
||||
id: "windmill",
|
||||
code: "W",
|
||||
draw: "M 0 0 L 0 0.6 1 1 1 0 z",
|
||||
tier: 1,
|
||||
spawnData: {
|
||||
color: "uncolored",
|
||||
maxQuarters: 3,
|
||||
minDistance: 7,
|
||||
chances: {
|
||||
min: 20,
|
||||
distanceMultiplier: 5,
|
||||
max: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export function initShapes() {
|
||||
for (let k in enumSubShape) {
|
||||
delete enumSubShape[k];
|
||||
}
|
||||
for (let k in enumSubShapeToShortcode) {
|
||||
delete enumSubShapeToShortcode[k];
|
||||
}
|
||||
for (let k in enumShortcodeToSubShape) {
|
||||
delete enumShortcodeToSubShape[k];
|
||||
}
|
||||
|
||||
for (let s in allShapeData) {
|
||||
let data = allShapeData[s];
|
||||
assert(data.id == s);
|
||||
assert(data.code.toUpperCase() == data.code);
|
||||
assert(data.draw);
|
||||
|
||||
enumSubShape[data.id] = data.id;
|
||||
enumSubShapeToShortcode[data.id] = data.code;
|
||||
enumShortcodeToSubShape[data.code] = data.id;
|
||||
|
||||
if (data.spawnData) {
|
||||
const sdata = data.spawnData;
|
||||
sdata.color = sdata.color || "uncolored";
|
||||
sdata.maxQuarters = sdata.maxQuarters || 4;
|
||||
sdata.minDistance = sdata.minDistance || 0;
|
||||
|
||||
if(sdata.chances) {
|
||||
const chances = sdata.chances;
|
||||
chances.min = chances.min || 0;
|
||||
chances.max = chances.max || 100;
|
||||
chances.distanceMultiplier = chances.distanceMultiplier || 1;
|
||||
} else {
|
||||
sdata.chances = {
|
||||
min: 0,
|
||||
max: 100,
|
||||
distanceMultiplier: 1
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user