1
0
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:
tobspr 2022-01-15 14:57:11 +01:00
parent 2a83853b1c
commit 22b619e8ab
7 changed files with 267 additions and 10 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

25
mod_examples/base.js Normal file
View 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
}
};
});

View File

@ -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);
}

View File

@ -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];

View File

@ -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
View File

@ -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;