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 { enumHubGoalRewards } from "./tutorial_goals";
|
||||
|
||||
export const MOD_ITEM_PROCESSOR_SPEEDS = {};
|
||||
|
||||
export class HubGoals extends BasicSerializableObject {
|
||||
static getId() {
|
||||
return "HubGoals";
|
||||
@ -556,6 +558,9 @@ export class HubGoals extends BasicSerializableObject {
|
||||
);
|
||||
}
|
||||
default:
|
||||
if (MOD_ITEM_PROCESSOR_SPEEDS[processorType]) {
|
||||
return MOD_ITEM_PROCESSOR_SPEEDS[processorType](this.root);
|
||||
}
|
||||
assertAlways(false, "invalid processor type: " + processorType);
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,11 @@ export const MODS_ADDITIONAL_SUB_SHAPE_DRAWERS = {};
|
||||
* }} 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)
|
||||
* @typedef {[ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?, ShapeLayerItem?]} ShapeLayer
|
||||
@ -64,7 +69,7 @@ for (const key in enumSubShapeToShortcode) {
|
||||
/**
|
||||
* Converts the given parameters to a valid shape definition
|
||||
* @param {*} layers
|
||||
* @returns {Array<import("./shape_definition").ShapeLayer>}
|
||||
* @returns {Array<ShapeLayer>}
|
||||
*/
|
||||
export function createSimpleShape(layers) {
|
||||
layers.forEach(layer => {
|
||||
@ -242,7 +247,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
* Internal method to clone the shape definition
|
||||
* @returns {Array<ShapeLayer>}
|
||||
*/
|
||||
internalCloneLayers() {
|
||||
getClonedLayers() {
|
||||
return JSON.parse(JSON.stringify(this.layers));
|
||||
}
|
||||
|
||||
@ -460,7 +465,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
* @returns {ShapeDefinition}
|
||||
*/
|
||||
cloneFilteredByQuadrants(includeQuadrants) {
|
||||
const newLayers = this.internalCloneLayers();
|
||||
const newLayers = this.getClonedLayers();
|
||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||
const quadrants = newLayers[layerIndex];
|
||||
let anyContents = false;
|
||||
@ -486,7 +491,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
* @returns {ShapeDefinition}
|
||||
*/
|
||||
cloneRotateCW() {
|
||||
const newLayers = this.internalCloneLayers();
|
||||
const newLayers = this.getClonedLayers();
|
||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||
const quadrants = newLayers[layerIndex];
|
||||
quadrants.unshift(quadrants[3]);
|
||||
@ -500,7 +505,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
* @returns {ShapeDefinition}
|
||||
*/
|
||||
cloneRotateCCW() {
|
||||
const newLayers = this.internalCloneLayers();
|
||||
const newLayers = this.getClonedLayers();
|
||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||
const quadrants = newLayers[layerIndex];
|
||||
quadrants.push(quadrants[0]);
|
||||
@ -514,7 +519,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
* @returns {ShapeDefinition}
|
||||
*/
|
||||
cloneRotate180() {
|
||||
const newLayers = this.internalCloneLayers();
|
||||
const newLayers = this.getClonedLayers();
|
||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||
const quadrants = newLayers[layerIndex];
|
||||
quadrants.push(quadrants.shift(), quadrants.shift());
|
||||
@ -572,7 +577,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
// Can't merge at a layer lower than 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) {
|
||||
mergedLayers.push([null, null, null, null]);
|
||||
}
|
||||
@ -598,7 +603,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
* @param {enumColors} color
|
||||
*/
|
||||
cloneAndPaintWith(color) {
|
||||
const newLayers = this.internalCloneLayers();
|
||||
const newLayers = this.getClonedLayers();
|
||||
|
||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||
const quadrants = newLayers[layerIndex];
|
||||
@ -617,7 +622,7 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
* @param {[enumColors, enumColors, enumColors, enumColors]} colors
|
||||
*/
|
||||
cloneAndPaintWith4Colors(colors) {
|
||||
const newLayers = this.internalCloneLayers();
|
||||
const newLayers = this.getClonedLayers();
|
||||
|
||||
for (let layerIndex = 0; layerIndex < newLayers.length; ++layerIndex) {
|
||||
const quadrants = newLayers[layerIndex];
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
} from "../components/item_processor";
|
||||
import { Entity } from "../entity";
|
||||
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 { ShapeItem } from "../items/shape_item";
|
||||
|
||||
@ -38,6 +38,11 @@ const MAX_QUEUED_CHARGES = 2;
|
||||
* }} ProcessorImplementationPayload
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {Object<string, (ProcessorImplementationPayload) => void>}
|
||||
*/
|
||||
export const MOD_ITEM_PROCESSOR_HANDLERS = {};
|
||||
|
||||
export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
constructor(root) {
|
||||
super(root, [ItemProcessorComponent]);
|
||||
@ -61,6 +66,7 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
[enumItemProcessorTypes.hub]: this.process_HUB,
|
||||
[enumItemProcessorTypes.reader]: this.process_READER,
|
||||
[enumItemProcessorTypes.goal]: this.process_GOAL,
|
||||
...MOD_ITEM_PROCESSOR_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 registerMod: any;
|
||||
|
||||
// Polyfills
|
||||
declare interface String {
|
||||
replaceAll(search: string, replacement: string): string;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user