mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-13 18:21: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 { enumSubShape } from "./shape_definition";
|
||||
import { Rectangle } from "../core/rectangle";
|
||||
import { MODS_ADDITIONAL_SHAPE_MAP_WEIGHTS } from "../mods/mod_interface";
|
||||
|
||||
const logger = createLogger("map_chunk");
|
||||
|
||||
@ -192,6 +193,10 @@ export class MapChunk {
|
||||
[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) {
|
||||
// Initial chunks can not spawn the good stuff
|
||||
weights[enumSubShape.star] = 0;
|
||||
|
||||
@ -38,6 +38,7 @@ import { HUDSandboxController } from "../hud/parts/sandbox_controller";
|
||||
import { queryParamOptions } from "../../core/query_parameters";
|
||||
import { MetaBlockBuilding } from "../buildings/block";
|
||||
import { MetaItemProducerBuilding } from "../buildings/item_producer";
|
||||
import { MODS } from "../../mods/modloader";
|
||||
|
||||
/** @typedef {{
|
||||
* shape: string,
|
||||
@ -521,6 +522,8 @@ export function generateLevelDefinitions(limitedVersion = false) {
|
||||
});
|
||||
}
|
||||
|
||||
MODS.callHook("modifyLevelDefinitions", levelDefinitions);
|
||||
|
||||
return levelDefinitions;
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import { globalConfig } from "../core/config";
|
||||
import { smoothenDpi } from "../core/dpi_manager";
|
||||
import { DrawParameters } from "../core/draw_parameters";
|
||||
import { Vector } from "../core/vector";
|
||||
import { MODS_ADDITIONAL_SUB_SHAPE_DRAWERS } from "../mods/mod_interface";
|
||||
import { BasicSerializableObject, types } from "../savegame/serialization";
|
||||
import { enumColors, enumColorsToHexCode, enumColorToShortcode, enumShortcodeToColor } from "./colors";
|
||||
import { THEME } from "./theme";
|
||||
@ -366,18 +367,11 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
context.strokeStyle = THEME.items.outline;
|
||||
context.lineWidth = THEME.items.outlineWidth;
|
||||
|
||||
const insetPadding = 0.0;
|
||||
|
||||
switch (subShape) {
|
||||
case enumSubShape.rect: {
|
||||
context.beginPath();
|
||||
const dims = quadrantSize * layerScale;
|
||||
context.rect(
|
||||
insetPadding + -quadrantHalfSize,
|
||||
-insetPadding + quadrantHalfSize - dims,
|
||||
dims,
|
||||
dims
|
||||
);
|
||||
context.rect(-quadrantHalfSize, quadrantHalfSize - dims, dims, dims);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -385,8 +379,8 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
context.beginPath();
|
||||
const dims = quadrantSize * layerScale;
|
||||
|
||||
let originX = insetPadding - quadrantHalfSize;
|
||||
let originY = -insetPadding + quadrantHalfSize - dims;
|
||||
let originX = -quadrantHalfSize;
|
||||
let originY = quadrantHalfSize - dims;
|
||||
|
||||
const moveInwards = dims * 0.4;
|
||||
context.moveTo(originX, originY + moveInwards);
|
||||
@ -401,8 +395,8 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
context.beginPath();
|
||||
const dims = quadrantSize * layerScale;
|
||||
|
||||
let originX = insetPadding - quadrantHalfSize;
|
||||
let originY = -insetPadding + quadrantHalfSize - dims;
|
||||
let originX = -quadrantHalfSize;
|
||||
let originY = quadrantHalfSize - dims;
|
||||
const moveInwards = dims * 0.4;
|
||||
context.moveTo(originX, originY + moveInwards);
|
||||
context.lineTo(originX + dims, originY);
|
||||
@ -414,10 +408,10 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
|
||||
case enumSubShape.circle: {
|
||||
context.beginPath();
|
||||
context.moveTo(insetPadding + -quadrantHalfSize, -insetPadding + quadrantHalfSize);
|
||||
context.moveTo(-quadrantHalfSize, quadrantHalfSize);
|
||||
context.arc(
|
||||
insetPadding + -quadrantHalfSize,
|
||||
-insetPadding + quadrantHalfSize,
|
||||
-quadrantHalfSize,
|
||||
quadrantHalfSize,
|
||||
quadrantSize * layerScale,
|
||||
-Math.PI * 0.5,
|
||||
0
|
||||
@ -427,7 +421,15 @@ export class ShapeDefinition extends BasicSerializableObject {
|
||||
}
|
||||
|
||||
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() {
|
||||
// Add some custom css
|
||||
this.interface.registerCss(`
|
||||
* {
|
||||
color: red !important;
|
||||
}
|
||||
* {
|
||||
color: red !important;
|
||||
}
|
||||
`);
|
||||
|
||||
// Replace a builtin sprite
|
||||
this.interface.registerSprite(
|
||||
"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"
|
||||
);
|
||||
|
||||
// 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 }) {
|
||||
// Modify the theme colors
|
||||
theme.map.background = "#eee";
|
||||
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 { AtlasSprite, SpriteAtlasLink } from "../core/sprites";
|
||||
import { Mod } from "./mod";
|
||||
import { enumShortcodeToSubShape, enumSubShape, enumSubShapeToShortcode } from "../game/shape_definition";
|
||||
|
||||
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 {
|
||||
/**
|
||||
*
|
||||
@ -74,4 +93,24 @@ export class ModInterface {
|
||||
}
|
||||
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