mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-14 02:31:51 +00:00
modloader features
This commit is contained in:
parent
abf2fd3d94
commit
3e5716504a
@ -10,6 +10,7 @@ import { COLOR_ITEM_SINGLETONS } from "./items/color_item";
|
|||||||
import { GameRoot } from "./root";
|
import { GameRoot } from "./root";
|
||||||
import { enumSubShape } from "./shape_definition";
|
import { enumSubShape } from "./shape_definition";
|
||||||
import { Rectangle } from "../core/rectangle";
|
import { Rectangle } from "../core/rectangle";
|
||||||
|
import { MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS } from "../mods/mod_interface";
|
||||||
|
|
||||||
const logger = createLogger("map_chunk");
|
const logger = createLogger("map_chunk");
|
||||||
|
|
||||||
@ -192,6 +193,10 @@ export class MapChunk {
|
|||||||
[enumSubShape.windmill]: Math.round(6 + clamp(distanceToOriginInChunks / 2, 0, 20)),
|
[enumSubShape.windmill]: Math.round(6 + clamp(distanceToOriginInChunks / 2, 0, 20)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (const key in MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS) {
|
||||||
|
weights[key] = MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS[key](distanceToOriginInChunks);
|
||||||
|
}
|
||||||
|
|
||||||
if (distanceToOriginInChunks < 7) {
|
if (distanceToOriginInChunks < 7) {
|
||||||
// Initial chunks can not spawn the good stuff
|
// Initial chunks can not spawn the good stuff
|
||||||
weights[enumSubShape.star] = 0;
|
weights[enumSubShape.star] = 0;
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import { HUDSandboxController } from "../hud/parts/sandbox_controller";
|
|||||||
import { queryParamOptions } from "../../core/query_parameters";
|
import { queryParamOptions } from "../../core/query_parameters";
|
||||||
import { MetaBlockBuilding } from "../buildings/block";
|
import { MetaBlockBuilding } from "../buildings/block";
|
||||||
import { MetaItemProducerBuilding } from "../buildings/item_producer";
|
import { MetaItemProducerBuilding } from "../buildings/item_producer";
|
||||||
|
import { MODS } from "../../mods/modloader";
|
||||||
|
|
||||||
/** @typedef {{
|
/** @typedef {{
|
||||||
* shape: string,
|
* shape: string,
|
||||||
@ -521,6 +522,8 @@ export function generateLevelDefinitions(limitedVersion = false) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MODS.callHook("modifyLevelDefinitions", levelDefinitions);
|
||||||
|
|
||||||
return levelDefinitions;
|
return levelDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { globalConfig } from "../core/config";
|
|||||||
import { smoothenDpi } from "../core/dpi_manager";
|
import { smoothenDpi } from "../core/dpi_manager";
|
||||||
import { DrawParameters } from "../core/draw_parameters";
|
import { DrawParameters } from "../core/draw_parameters";
|
||||||
import { Vector } from "../core/vector";
|
import { Vector } from "../core/vector";
|
||||||
|
import { MODS_ADDITIONAL_SUB_SHAPE_DRAWERS } from "../mods/mod_interface";
|
||||||
import { BasicSerializableObject, types } from "../savegame/serialization";
|
import { BasicSerializableObject, types } from "../savegame/serialization";
|
||||||
import { enumColors, enumColorsToHexCode, enumColorToShortcode, enumShortcodeToColor } from "./colors";
|
import { enumColors, enumColorsToHexCode, enumColorToShortcode, enumShortcodeToColor } from "./colors";
|
||||||
import { THEME } from "./theme";
|
import { THEME } from "./theme";
|
||||||
@ -366,18 +367,11 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
context.strokeStyle = THEME.items.outline;
|
context.strokeStyle = THEME.items.outline;
|
||||||
context.lineWidth = THEME.items.outlineWidth;
|
context.lineWidth = THEME.items.outlineWidth;
|
||||||
|
|
||||||
const insetPadding = 0.0;
|
|
||||||
|
|
||||||
switch (subShape) {
|
switch (subShape) {
|
||||||
case enumSubShape.rect: {
|
case enumSubShape.rect: {
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
const dims = quadrantSize * layerScale;
|
const dims = quadrantSize * layerScale;
|
||||||
context.rect(
|
context.rect(-quadrantHalfSize, quadrantHalfSize - dims, dims, dims);
|
||||||
insetPadding + -quadrantHalfSize,
|
|
||||||
-insetPadding + quadrantHalfSize - dims,
|
|
||||||
dims,
|
|
||||||
dims
|
|
||||||
);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -385,8 +379,8 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
context.beginPath();
|
context.beginPath();
|
||||||
const dims = quadrantSize * layerScale;
|
const dims = quadrantSize * layerScale;
|
||||||
|
|
||||||
let originX = insetPadding - quadrantHalfSize;
|
let originX = -quadrantHalfSize;
|
||||||
let originY = -insetPadding + quadrantHalfSize - dims;
|
let originY = quadrantHalfSize - dims;
|
||||||
|
|
||||||
const moveInwards = dims * 0.4;
|
const moveInwards = dims * 0.4;
|
||||||
context.moveTo(originX, originY + moveInwards);
|
context.moveTo(originX, originY + moveInwards);
|
||||||
@ -401,8 +395,8 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
context.beginPath();
|
context.beginPath();
|
||||||
const dims = quadrantSize * layerScale;
|
const dims = quadrantSize * layerScale;
|
||||||
|
|
||||||
let originX = insetPadding - quadrantHalfSize;
|
let originX = -quadrantHalfSize;
|
||||||
let originY = -insetPadding + quadrantHalfSize - dims;
|
let originY = quadrantHalfSize - dims;
|
||||||
const moveInwards = dims * 0.4;
|
const moveInwards = dims * 0.4;
|
||||||
context.moveTo(originX, originY + moveInwards);
|
context.moveTo(originX, originY + moveInwards);
|
||||||
context.lineTo(originX + dims, originY);
|
context.lineTo(originX + dims, originY);
|
||||||
@ -414,10 +408,10 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
|
|
||||||
case enumSubShape.circle: {
|
case enumSubShape.circle: {
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.moveTo(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize);
|
context.moveTo(-quadrantHalfSize, quadrantHalfSize);
|
||||||
context.arc(
|
context.arc(
|
||||||
insetPadding + -quadrantHalfSize,
|
-quadrantHalfSize,
|
||||||
-insetPadding + quadrantHalfSize,
|
quadrantHalfSize,
|
||||||
quadrantSize * layerScale,
|
quadrantSize * layerScale,
|
||||||
-Math.PI * 0.5,
|
-Math.PI * 0.5,
|
||||||
0
|
0
|
||||||
@ -427,7 +421,15 @@ export class ShapeDefinition extends BasicSerializableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
assertAlways(false, "Unkown sub shape: " + subShape);
|
if (MODS_ADDITIONAL_SUB_SHAPE_DRAWERS[subShape]) {
|
||||||
|
MODS_ADDITIONAL_SUB_SHAPE_DRAWERS[subShape]({
|
||||||
|
context,
|
||||||
|
layerScale,
|
||||||
|
quadrantSize,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new Error("Unkown sub shape: " + subShape);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,20 +12,50 @@ export class DemoMod extends Mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hook_init() {
|
hook_init() {
|
||||||
|
// Add some custom css
|
||||||
this.interface.registerCss(`
|
this.interface.registerCss(`
|
||||||
* {
|
* {
|
||||||
color: red !important;
|
color: red !important;
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
// Replace a builtin sprite
|
||||||
this.interface.registerSprite(
|
this.interface.registerSprite(
|
||||||
"sprites/colors/red.png",
|
"sprites/colors/red.png",
|
||||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAB2AAAAdgB+lymcgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAATkSURBVHic7ZpfiFRVHMc/v5m99+6qWYhCYKFGVJpPFYgK4UNQb1GwODO5M2OLUmASItGD6OJDYX8IIqPMdWdmdWZkE6GnnozqJWkxENMyg/75tP31z+7MnZ3760GrZf7fmXuvaPfzMvA7v3PO9/e7555z5pwLISEhISEhISH/U6SXyjo4aFaM+atUndUISwEUSmjkW5XouYH86I9eiJxJDC8Tra4EHhBxrGtW+UWQr43K1bMyMWF323ZXCSglko8JJFF5EljYwvUMytFqVcfmTeQuuuljejC5NBqVzQgx4MEWrpdAjjtIbqAwdsJNH+AyAXYi9TDKGwobXPYzI8J7hil7JZP5s5WjptN3VGzdrcpzwICbTgQ9gbLTLOa+6rxOh9iJ1FZV3gEMN6Jqevspok7SKIx/2qi4Ek+udZDDwD1d9wGziO6y8rl9nUlqg4LY8dQosLkHUXOpCmwxC9mxuUY7ln5WRQ8AUS86UWXUKma3CGgrv0i7hirx1Ot4FzxAVGG0lEhu+8dQiqdfUNGDeBQ8gAjDdiL1Wlu/VoXleHITyLhXompwVHkKQITjdPAwukOHrELucLPSpgnQeHxxGfOcwGJ/hAFw5frvAr86UJiysFdJofBro/KmWS+rudfn4OFa4L4FDyCwpCLmSIvyenRw6+12X/kiMN8vYQFzxZy17pKJA3/VFjQcAWWjNMStEzzAgnK0vKlRQcMEiMoT/uoJHhEeb2SvS4Beey3W+q4oeNbryEhdvHWGUiy9DFgUiKRgWVQ6//Pdtca6BESVJcHoCZ4os3WrWl0CnGj1Vnz6ADg47RNANdJy73xzI9VaS/2kEOW3YMQET6Qa/b3OVmsw+qPnAScQRcHiGH32hVpjXQLk0KHLwDeBSAqWs3LkyKVaY+ONEPKx/3oCRmgYU+M/Q1ot+CrmBiCO5hvZGybALI5PIpzyV1KAKF82OydsfgihvOKboKARaRpL0wSY9684fouMgknz/uUfNStseSRmx4YeUYmcxLfjKt9xJCLrzSOZL5o5tAzMLI5PqvK+97qCQZR3WwUPHTxZq192AKc9UxUcZ43q9EvtnNomQDKZEugQMOOJrCAQpnGcjTIx0VZzR++2VcidBoa4ObbICjJsHR0/04lzx5ObVcgeQ9nTva6AEN1l5TPFjt3dtm/H028qusNtvSAQYb+Zz25r7/kfrpc3o5DZqegHbuv5j2SN+1Zsd1vLdQIE1JqdeR4Ya+scHGPm7NVhGRlxPUd1/YWIgtiJ9B5Ub+i8IMLbRj77Yrtb4Kb1exVQiqW2i/AWwe8WFXjZKmTb3gC3oucEANiJVFKVg/Ty8YQ7KqIybBYzPd9ce5IAgMozqfWOw4fAnV612QiFKRXdOJDPfeJFe54lAK5/2NQXOQa6xst2/0U45dD3tFdfn4HH7+28idxF02IDvqwQesj8Y+E6L4MHj0fAXK7PC/vp/f7/sgg7zXz2gBe6avEtAQAzsfTyiGie7i9bJ1Uk0Z/PfOelrrn4unQNFDM/mLPTG1DZB9TdyrSgCrxq3mat8zN48HkEzMWODa1RiYwBK9u4fh9R2WwUM58HoSuwzYtZHD9pWvIQIrsVpmrLFaYQ2W1asjqo4CHAETAXHRwcKBv9j+JE7gUg4lywKqXPOjnACAkJCQkJCQkJ8Yi/AfA6e2lfA0oPAAAAAElFTkSuQmCC"
|
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAB2AAAAdgB+lymcgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAATkSURBVHic7ZpfiFRVHMc/v5m99+6qWYhCYKFGVJpPFYgK4UNQb1GwODO5M2OLUmASItGD6OJDYX8IIqPMdWdmdWZkE6GnnozqJWkxENMyg/75tP31z+7MnZ3760GrZf7fmXuvaPfzMvA7v3PO9/e7555z5pwLISEhISEhISH/U6SXyjo4aFaM+atUndUISwEUSmjkW5XouYH86I9eiJxJDC8Tra4EHhBxrGtW+UWQr43K1bMyMWF323ZXCSglko8JJFF5EljYwvUMytFqVcfmTeQuuuljejC5NBqVzQgx4MEWrpdAjjtIbqAwdsJNH+AyAXYi9TDKGwobXPYzI8J7hil7JZP5s5WjptN3VGzdrcpzwICbTgQ9gbLTLOa+6rxOh9iJ1FZV3gEMN6Jqevspok7SKIx/2qi4Ek+udZDDwD1d9wGziO6y8rl9nUlqg4LY8dQosLkHUXOpCmwxC9mxuUY7ln5WRQ8AUS86UWXUKma3CGgrv0i7hirx1Ot4FzxAVGG0lEhu+8dQiqdfUNGDeBQ8gAjDdiL1Wlu/VoXleHITyLhXompwVHkKQITjdPAwukOHrELucLPSpgnQeHxxGfOcwGJ/hAFw5frvAr86UJiysFdJofBro/KmWS+rudfn4OFa4L4FDyCwpCLmSIvyenRw6+12X/kiMN8vYQFzxZy17pKJA3/VFjQcAWWjNMStEzzAgnK0vKlRQcMEiMoT/uoJHhEeb2SvS4Beey3W+q4oeNbryEhdvHWGUiy9DFgUiKRgWVQ6//Pdtca6BESVJcHoCZ4os3WrWl0CnGj1Vnz6ADg47RNANdJy73xzI9VaS/2kEOW3YMQET6Qa/b3OVmsw+qPnAScQRcHiGH32hVpjXQLk0KHLwDeBSAqWs3LkyKVaY+ONEPKx/3oCRmgYU+M/Q1ot+CrmBiCO5hvZGybALI5PIpzyV1KAKF82OydsfgihvOKboKARaRpL0wSY9684fouMgknz/uUfNStseSRmx4YeUYmcxLfjKt9xJCLrzSOZL5o5tAzMLI5PqvK+97qCQZR3WwUPHTxZq192AKc9UxUcZ43q9EvtnNomQDKZEugQMOOJrCAQpnGcjTIx0VZzR++2VcidBoa4ObbICjJsHR0/04lzx5ObVcgeQ9nTva6AEN1l5TPFjt3dtm/H028qusNtvSAQYb+Zz25r7/kfrpc3o5DZqegHbuv5j2SN+1Zsd1vLdQIE1JqdeR4Ya+scHGPm7NVhGRlxPUd1/YWIgtiJ9B5Ub+i8IMLbRj77Yrtb4Kb1exVQiqW2i/AWwe8WFXjZKmTb3gC3oucEANiJVFKVg/Ty8YQ7KqIybBYzPd9ce5IAgMozqfWOw4fAnV612QiFKRXdOJDPfeJFe54lAK5/2NQXOQa6xst2/0U45dD3tFdfn4HH7+28idxF02IDvqwQesj8Y+E6L4MHj0fAXK7PC/vp/f7/sgg7zXz2gBe6avEtAQAzsfTyiGie7i9bJ1Uk0Z/PfOelrrn4unQNFDM/mLPTG1DZB9TdyrSgCrxq3mat8zN48HkEzMWODa1RiYwBK9u4fh9R2WwUM58HoSuwzYtZHD9pWvIQIrsVpmrLFaYQ2W1asjqo4CHAETAXHRwcKBv9j+JE7gUg4lywKqXPOjnACAkJCQkJCQkJ8Yi/AfA6e2lfA0oPAAAAAElFTkSuQmCC"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add a new type of sub shape ("Line", short code "L")
|
||||||
|
this.interface.registerSubShapeType({
|
||||||
|
id: "line",
|
||||||
|
shortCode: "L",
|
||||||
|
weightComputation: distanceToOriginInChunks =>
|
||||||
|
Math.round(20 + Math.max(Math.min(distanceToOriginInChunks, 30), 0)),
|
||||||
|
|
||||||
|
shapeDrawer: ({ context, quadrantSize, layerScale }) => {
|
||||||
|
const quadrantHalfSize = quadrantSize / 2;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(-quadrantHalfSize, quadrantHalfSize);
|
||||||
|
context.arc(
|
||||||
|
-quadrantHalfSize,
|
||||||
|
quadrantHalfSize,
|
||||||
|
quadrantSize * layerScale,
|
||||||
|
-Math.PI * 0.25,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
context.closePath();
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hook_preprocessTheme({ id, theme }) {
|
hook_preprocessTheme({ id, theme }) {
|
||||||
|
// Modify the theme colors
|
||||||
theme.map.background = "#eee";
|
theme.map.background = "#eee";
|
||||||
theme.items.outline = "#000";
|
theme.items.outline = "#000";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hook_modifyLevelDefinitions(definitions) {
|
||||||
|
// Modify the goal of the first level
|
||||||
|
definitions[0].shape = "LuCuLuCu";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,9 +6,28 @@ import { ModLoader } from "./modloader";
|
|||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
import { AtlasSprite, SpriteAtlasLink } from "../core/sprites";
|
import { AtlasSprite, SpriteAtlasLink } from "../core/sprites";
|
||||||
import { Mod } from "./mod";
|
import { Mod } from "./mod";
|
||||||
|
import { enumShortcodeToSubShape, enumSubShape, enumSubShapeToShortcode } from "../game/shape_definition";
|
||||||
|
|
||||||
const LOG = createLogger("mod-interface");
|
const LOG = createLogger("mod-interface");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object<string, (distanceToOriginInChunks: number) => number>}
|
||||||
|
*/
|
||||||
|
export const MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* context: CanvasRenderingContext2D,
|
||||||
|
* quadrantSize: number,
|
||||||
|
* layerScale: number,
|
||||||
|
* }} SubShapeDrawOptions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object<string, (options: SubShapeDrawOptions) => void>}
|
||||||
|
*/
|
||||||
|
export const MODS_ADDITIONAL_SUB_SHAPE_DRAWERS = {};
|
||||||
|
|
||||||
export class ModInterface {
|
export class ModInterface {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -74,4 +93,24 @@ export class ModInterface {
|
|||||||
}
|
}
|
||||||
this.modLoader.lazySprites.set(spriteId, sprite);
|
this.modLoader.lazySprites.set(spriteId, sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} param0
|
||||||
|
* @param {string} param0.id
|
||||||
|
* @param {string} param0.shortCode
|
||||||
|
* @param {(distanceToOriginInChunks: number) => number} param0.weightComputation
|
||||||
|
* @param {(options: SubShapeDrawOptions) => void} param0.shapeDrawer
|
||||||
|
*/
|
||||||
|
registerSubShapeType({ id, shortCode, weightComputation, shapeDrawer }) {
|
||||||
|
if (shortCode.length !== 1) {
|
||||||
|
throw new Error("Bad short code: " + shortCode);
|
||||||
|
}
|
||||||
|
enumSubShape[id] = id;
|
||||||
|
enumSubShapeToShortcode[id] = shortCode;
|
||||||
|
enumShortcodeToSubShape[shortCode] = id;
|
||||||
|
|
||||||
|
MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS[id] = weightComputation;
|
||||||
|
MODS_ADDITIONAL_SUB_SHAPE_DRAWERS[id] = shapeDrawer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user