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

View File

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

View File

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

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