mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-13 18:21:51 +00:00
Add more examples and allow defining custom item processor operations
This commit is contained in:
parent
2a83853b1c
commit
22b619e8ab
76
mod_examples/add_building_basic.js
Normal file
76
mod_examples/add_building_basic.js
Normal file
File diff suppressed because one or more lines are too long
138
mod_examples/add_building_flipper.js
Normal file
138
mod_examples/add_building_flipper.js
Normal file
File diff suppressed because one or more lines are too long
25
mod_examples/base.js
Normal file
25
mod_examples/base.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* This is the minimal structure of a mod
|
||||||
|
*/
|
||||||
|
registerMod(() => {
|
||||||
|
return class ModImpl extends shapez.Mod {
|
||||||
|
constructor(app, modLoader) {
|
||||||
|
super(
|
||||||
|
app,
|
||||||
|
{
|
||||||
|
website: "https://tobspr.io",
|
||||||
|
author: "tobspr",
|
||||||
|
name: "Mod Example: Base",
|
||||||
|
version: "1",
|
||||||
|
id: "base",
|
||||||
|
description: "The most basic mod",
|
||||||
|
},
|
||||||
|
modLoader
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
// Start the modding here
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
@ -9,6 +9,8 @@ import { GameRoot } from "./root";
|
|||||||
import { enumSubShape, ShapeDefinition } from "./shape_definition";
|
import { enumSubShape, ShapeDefinition } from "./shape_definition";
|
||||||
import { enumHubGoalRewards } from "./tutorial_goals";
|
import { enumHubGoalRewards } from "./tutorial_goals";
|
||||||
|
|
||||||
|
export const MOD_ITEM_PROCESSOR_SPEEDS = {};
|
||||||
|
|
||||||
export class HubGoals extends BasicSerializableObject {
|
export class HubGoals extends BasicSerializableObject {
|
||||||
static getId() {
|
static getId() {
|
||||||
return "HubGoals";
|
return "HubGoals";
|
||||||
@ -556,6 +558,9 @@ export class HubGoals extends BasicSerializableObject {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
if (MOD_ITEM_PROCESSOR_SPEEDS[processorType]) {
|
||||||
|
return MOD_ITEM_PROCESSOR_SPEEDS[processorType](this.root);
|
||||||
|
}
|
||||||
assertAlways(false, "invalid processor type: " + processorType);
|
assertAlways(false, "invalid processor type: " + processorType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,11 @@ export const MODS_ADDITIONAL_SUB_SHAPE_DRAWERS = {};
|
|||||||
* }} ShapeLayerItem
|
* }} ShapeLayerItem
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export const TOP_RIGHT = 0;
|
||||||
|
export const BOTTOM_RIGHT = 1;
|
||||||
|
export const BOTTOM_LEFT = 2;
|
||||||
|
export const TOP_LEFT = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Order is Q1 (tr), Q2(br), Q3(bl), Q4(tl)
|
* Order is Q1 (tr), Q2(br), Q3(bl), Q4(tl)
|
||||||
* @typedef {[ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?]} ShapeLayer
|
* @typedef {[ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?]} ShapeLayer
|
||||||
@ -64,7 +69,7 @@ for (const key in enumSubShapeToShortcode) {
|
|||||||
/**
|
/**
|
||||||
* Converts the given parameters to a valid shape definition
|
* Converts the given parameters to a valid shape definition
|
||||||
* @param {*} layers
|
* @param {*} layers
|
||||||
* @returns {Array<import("./shape_definition").ShapeLayer>}
|
* @returns {Array<ShapeLayer>}
|
||||||
*/
|
*/
|
||||||
export function createSimpleShape(layers) {
|
export function createSimpleShape(layers) {
|
||||||
layers.forEach(layer => {
|
layers.forEach(layer => {
|
||||||
@ -242,7 +247,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
* Internal method to clone the shape definition
|
* Internal method to clone the shape definition
|
||||||
* @returns {Array<ShapeLayer>}
|
* @returns {Array<ShapeLayer>}
|
||||||
*/
|
*/
|
||||||
internalCloneLayers() {
|
getClonedLayers() {
|
||||||
return JSON.parse(JSON.stringify(this.layers));
|
return JSON.parse(JSON.stringify(this.layers));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +465,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
* @returns {ShapeDefinition}
|
* @returns {ShapeDefinition}
|
||||||
*/
|
*/
|
||||||
cloneFilteredByQuadrants(includeQuadrants) {
|
cloneFilteredByQuadrants(includeQuadrants) {
|
||||||
const newLayers = this.internalCloneLayers();
|
const newLayers = this.getClonedLayers();
|
||||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||||
const quadrants = newLayers[layerIndex];
|
const quadrants = newLayers[layerIndex];
|
||||||
let anyContents = false;
|
let anyContents = false;
|
||||||
@ -486,7 +491,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
* @returns {ShapeDefinition}
|
* @returns {ShapeDefinition}
|
||||||
*/
|
*/
|
||||||
cloneRotateCW() {
|
cloneRotateCW() {
|
||||||
const newLayers = this.internalCloneLayers();
|
const newLayers = this.getClonedLayers();
|
||||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||||
const quadrants = newLayers[layerIndex];
|
const quadrants = newLayers[layerIndex];
|
||||||
quadrants.unshift(quadrants[3]);
|
quadrants.unshift(quadrants[3]);
|
||||||
@ -500,7 +505,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
* @returns {ShapeDefinition}
|
* @returns {ShapeDefinition}
|
||||||
*/
|
*/
|
||||||
cloneRotateCCW() {
|
cloneRotateCCW() {
|
||||||
const newLayers = this.internalCloneLayers();
|
const newLayers = this.getClonedLayers();
|
||||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||||
const quadrants = newLayers[layerIndex];
|
const quadrants = newLayers[layerIndex];
|
||||||
quadrants.push(quadrants[0]);
|
quadrants.push(quadrants[0]);
|
||||||
@ -514,7 +519,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
* @returns {ShapeDefinition}
|
* @returns {ShapeDefinition}
|
||||||
*/
|
*/
|
||||||
cloneRotate180() {
|
cloneRotate180() {
|
||||||
const newLayers = this.internalCloneLayers();
|
const newLayers = this.getClonedLayers();
|
||||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||||
const quadrants = newLayers[layerIndex];
|
const quadrants = newLayers[layerIndex];
|
||||||
quadrants.push(quadrants.shift(), quadrants.shift());
|
quadrants.push(quadrants.shift(), quadrants.shift());
|
||||||
@ -572,7 +577,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
// Can't merge at a layer lower than 0
|
// Can't merge at a layer lower than 0
|
||||||
const layerToMergeAt = Math.max(1 - smallestGapBetweenShapes, 0);
|
const layerToMergeAt = Math.max(1 - smallestGapBetweenShapes, 0);
|
||||||
|
|
||||||
const mergedLayers = this.internalCloneLayers();
|
const mergedLayers = this.getClonedLayers();
|
||||||
for (let layer = mergedLayers.length; layer < layerToMergeAt + topShapeLayers.length; ++layer) {
|
for (let layer = mergedLayers.length; layer < layerToMergeAt + topShapeLayers.length; ++layer) {
|
||||||
mergedLayers.push([null, null, null, null]);
|
mergedLayers.push([null, null, null, null]);
|
||||||
}
|
}
|
||||||
@ -598,7 +603,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
* @param {enumColors} color
|
* @param {enumColors} color
|
||||||
*/
|
*/
|
||||||
cloneAndPaintWith(color) {
|
cloneAndPaintWith(color) {
|
||||||
const newLayers = this.internalCloneLayers();
|
const newLayers = this.getClonedLayers();
|
||||||
|
|
||||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||||
const quadrants = newLayers[layerIndex];
|
const quadrants = newLayers[layerIndex];
|
||||||
@ -617,7 +622,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
* @param {[enumColors, enumColors, enumColors, enumColors]} colors
|
* @param {[enumColors, enumColors, enumColors, enumColors]} colors
|
||||||
*/
|
*/
|
||||||
cloneAndPaintWith4Colors(colors) {
|
cloneAndPaintWith4Colors(colors) {
|
||||||
const newLayers = this.internalCloneLayers();
|
const newLayers = this.getClonedLayers();
|
||||||
|
|
||||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||||
const quadrants = newLayers[layerIndex];
|
const quadrants = newLayers[layerIndex];
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import {
|
|||||||
} from "../components/item_processor";
|
} from "../components/item_processor";
|
||||||
import { Entity } from "../entity";
|
import { Entity } from "../entity";
|
||||||
import { GameSystemWithFilter } from "../game_system_with_filter";
|
import { GameSystemWithFilter } from "../game_system_with_filter";
|
||||||
import { BOOL_TRUE_SINGLETON, isTruthyItem } from "../items/boolean_item";
|
import { isTruthyItem } from "../items/boolean_item";
|
||||||
import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
|
import { ColorItem, COLOR_ITEM_SINGLETONS } from "../items/color_item";
|
||||||
import { ShapeItem } from "../items/shape_item";
|
import { ShapeItem } from "../items/shape_item";
|
||||||
|
|
||||||
@ -38,6 +38,11 @@ const MAX_QUEUED_CHARGES = 2;
|
|||||||
* }} ProcessorImplementationPayload
|
* }} ProcessorImplementationPayload
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object<string, (ProcessorImplementationPayload) => void>}
|
||||||
|
*/
|
||||||
|
export const MOD_ITEM_PROCESSOR_HANDLERS = {};
|
||||||
|
|
||||||
export class ItemProcessorSystem extends GameSystemWithFilter {
|
export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
super(root, [ItemProcessorComponent]);
|
super(root, [ItemProcessorComponent]);
|
||||||
@ -61,6 +66,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
|||||||
[enumItemProcessorTypes.hub]: this.process_HUB,
|
[enumItemProcessorTypes.hub]: this.process_HUB,
|
||||||
[enumItemProcessorTypes.reader]: this.process_READER,
|
[enumItemProcessorTypes.reader]: this.process_READER,
|
||||||
[enumItemProcessorTypes.goal]: this.process_GOAL,
|
[enumItemProcessorTypes.goal]: this.process_GOAL,
|
||||||
|
...MOD_ITEM_PROCESSOR_HANDLERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bind all handlers
|
// Bind all handlers
|
||||||
|
|||||||
2
src/js/globals.d.ts
vendored
2
src/js/globals.d.ts
vendored
@ -26,6 +26,8 @@ declare const shapez: any;
|
|||||||
|
|
||||||
declare const ipcRenderer: any;
|
declare const ipcRenderer: any;
|
||||||
|
|
||||||
|
declare const registerMod: any;
|
||||||
|
|
||||||
// Polyfills
|
// Polyfills
|
||||||
declare interface String {
|
declare interface String {
|
||||||
replaceAll(search: string, replacement: string): string;
|
replaceAll(search: string, replacement: string): string;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user