1
0
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:
tobspr 2022-01-13 21:45:09 +01:00
parent abf2fd3d94
commit 3e5716504a
5 changed files with 98 additions and 19 deletions

View File

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

View File

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

View File

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

View File

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

View File

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