mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-14 02:31:51 +00:00
Initial support for adding new buildings
This commit is contained in:
parent
8777e4c6ea
commit
01b9bf561c
@ -1,6 +1,7 @@
|
|||||||
import { globalConfig } from "../../core/config";
|
import { globalConfig } from "../../core/config";
|
||||||
import { DrawParameters } from "../../core/draw_parameters";
|
import { DrawParameters } from "../../core/draw_parameters";
|
||||||
import { Signal } from "../../core/signal";
|
import { Signal } from "../../core/signal";
|
||||||
|
import { MODS } from "../../mods/modloader";
|
||||||
import { KEYMAPPINGS } from "../key_action_mapper";
|
import { KEYMAPPINGS } from "../key_action_mapper";
|
||||||
import { MetaBuilding } from "../meta_building";
|
import { MetaBuilding } from "../meta_building";
|
||||||
import { GameRoot } from "../root";
|
import { GameRoot } from "../root";
|
||||||
@ -91,6 +92,7 @@ export class GameHUD {
|
|||||||
|
|
||||||
const frag = document.createDocumentFragment();
|
const frag = document.createDocumentFragment();
|
||||||
for (const key in this.parts) {
|
for (const key in this.parts) {
|
||||||
|
MODS.signals.hudElementInitialized.dispatch(this.parts[key]);
|
||||||
this.parts[key].createElements(frag);
|
this.parts[key].createElements(frag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +100,7 @@ export class GameHUD {
|
|||||||
|
|
||||||
for (const key in this.parts) {
|
for (const key in this.parts) {
|
||||||
this.parts[key].initialize();
|
this.parts[key].initialize();
|
||||||
|
MODS.signals.hudElementFinalized.dispatch(this.parts[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.toggleHud).add(this.toggleUi, this);
|
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.toggleHud).add(this.toggleUi, this);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { gMetaBuildingRegistry } from "../../../core/global_registries";
|
import { gMetaBuildingRegistry } from "../../../core/global_registries";
|
||||||
|
import { globalWarn } from "../../../core/logging";
|
||||||
import { STOP_PROPAGATION } from "../../../core/signal";
|
import { STOP_PROPAGATION } from "../../../core/signal";
|
||||||
import { makeDiv, safeModulo } from "../../../core/utils";
|
import { makeDiv, safeModulo } from "../../../core/utils";
|
||||||
import { MetaBlockBuilding } from "../../buildings/block";
|
import { MetaBlockBuilding } from "../../buildings/block";
|
||||||
@ -101,7 +102,12 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
rawBinding = KEYMAPPINGS.buildings[metaBuilding.getId()];
|
rawBinding = KEYMAPPINGS.buildings[metaBuilding.getId()];
|
||||||
}
|
}
|
||||||
|
|
||||||
const binding = actionMapper.getBinding(rawBinding);
|
if (rawBinding) {
|
||||||
|
const binding = actionMapper.getBinding(rawBinding);
|
||||||
|
binding.add(() => this.selectBuildingForPlacement(metaBuilding));
|
||||||
|
} else {
|
||||||
|
globalWarn("Building has no keybinding:", metaBuilding.getId());
|
||||||
|
}
|
||||||
|
|
||||||
const itemContainer = makeDiv(
|
const itemContainer = makeDiv(
|
||||||
this.primaryBuildings.includes(allBuildings[i]) ? rowPrimary : rowSecondary,
|
this.primaryBuildings.includes(allBuildings[i]) ? rowPrimary : rowSecondary,
|
||||||
@ -110,7 +116,6 @@ export class HUDBaseToolbar extends BaseHUDPart {
|
|||||||
);
|
);
|
||||||
itemContainer.setAttribute("data-icon", "building_icons/" + metaBuilding.getId() + ".png");
|
itemContainer.setAttribute("data-icon", "building_icons/" + metaBuilding.getId() + ".png");
|
||||||
itemContainer.setAttribute("data-id", metaBuilding.getId());
|
itemContainer.setAttribute("data-id", metaBuilding.getId());
|
||||||
binding.add(() => this.selectBuildingForPlacement(metaBuilding));
|
|
||||||
|
|
||||||
const icon = makeDiv(itemContainer, null, ["icon"]);
|
const icon = makeDiv(itemContainer, null, ["icon"]);
|
||||||
|
|
||||||
|
|||||||
@ -126,12 +126,15 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
rawBinding = KEYMAPPINGS.buildings[metaBuilding.getId()];
|
rawBinding = KEYMAPPINGS.buildings[metaBuilding.getId()];
|
||||||
}
|
}
|
||||||
|
|
||||||
const binding = this.root.keyMapper.getBinding(rawBinding);
|
if (rawBinding) {
|
||||||
|
const binding = this.root.keyMapper.getBinding(rawBinding);
|
||||||
this.buildingInfoElements.hotkey.innerHTML = T.ingame.buildingPlacement.hotkeyLabel.replace(
|
this.buildingInfoElements.hotkey.innerHTML = T.ingame.buildingPlacement.hotkeyLabel.replace(
|
||||||
"<key>",
|
"<key>",
|
||||||
"<code class='keybinding'>" + binding.getKeyCodeString() + "</code>"
|
"<code class='keybinding'>" + binding.getKeyCodeString() + "</code>"
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
this.buildingInfoElements.hotkey.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
this.buildingInfoElements.tutorialImage.setAttribute(
|
this.buildingInfoElements.tutorialImage.setAttribute(
|
||||||
"data-icon",
|
"data-icon",
|
||||||
|
|||||||
@ -205,18 +205,15 @@ export function initMetaBuildingRegistry() {
|
|||||||
const id = metaBuilding.getId();
|
const id = metaBuilding.getId();
|
||||||
if (!["hub"].includes(id)) {
|
if (!["hub"].includes(id)) {
|
||||||
if (!KEYMAPPINGS.buildings[id]) {
|
if (!KEYMAPPINGS.buildings[id]) {
|
||||||
assertAlways(
|
console.error(
|
||||||
false,
|
|
||||||
"Building " + id + " has no keybinding assigned! Add it to key_action_mapper.js"
|
"Building " + id + " has no keybinding assigned! Add it to key_action_mapper.js"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!T.buildings[id]) {
|
if (!T.buildings[id]) {
|
||||||
assertAlways(false, "Translation for building " + id + " missing!");
|
console.error("Translation for building " + id + " missing!");
|
||||||
}
|
} else if (!T.buildings[id].default) {
|
||||||
|
console.error("Translation for building " + id + " missing (default variant)!");
|
||||||
if (!T.buildings[id].default) {
|
|
||||||
assertAlways(false, "Translation for building " + id + " missing (default variant)!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1,14 +1,17 @@
|
|||||||
/* typehints:start */
|
/* typehints:start */
|
||||||
import { Application } from "../application";
|
|
||||||
import { ModLoader } from "./modloader";
|
import { ModLoader } from "./modloader";
|
||||||
|
import { MetaBuilding } from "../game/meta_building";
|
||||||
/* typehints:end */
|
/* typehints:end */
|
||||||
|
|
||||||
|
import { defaultBuildingVariant } from "../game/meta_building";
|
||||||
import { createLogger } from "../core/logging";
|
import { createLogger } from "../core/logging";
|
||||||
import { AtlasSprite, SpriteAtlasLink } from "../core/sprites";
|
import { AtlasSprite, SpriteAtlasLink } from "../core/sprites";
|
||||||
import { enumShortcodeToSubShape, enumSubShape, enumSubShapeToShortcode } from "../game/shape_definition";
|
import { enumShortcodeToSubShape, enumSubShape, enumSubShapeToShortcode } from "../game/shape_definition";
|
||||||
import { Loader } from "../core/loader";
|
import { Loader } from "../core/loader";
|
||||||
import { LANGUAGES } from "../languages";
|
import { LANGUAGES } from "../languages";
|
||||||
import { matchDataRecursive, T } from "../translations";
|
import { matchDataRecursive, T } from "../translations";
|
||||||
|
import { registerBuildingVariant } from "../game/building_codes";
|
||||||
|
import { gMetaBuildingRegistry } from "../core/global_registries";
|
||||||
|
|
||||||
const LOG = createLogger("mod-interface");
|
const LOG = createLogger("mod-interface");
|
||||||
|
|
||||||
@ -113,4 +116,77 @@ export class ModInterface {
|
|||||||
matchDataRecursive(T, translations, true);
|
matchDataRecursive(T, translations, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} param0
|
||||||
|
* @param {typeof MetaBuilding} param0.metaClass
|
||||||
|
* @param {string=} param0.buildingIconBase64
|
||||||
|
* @param {({
|
||||||
|
* variant?: string;
|
||||||
|
* rotationVariant?: number;
|
||||||
|
* name: string;
|
||||||
|
* description: string;
|
||||||
|
* blueprintImageBase64?: string;
|
||||||
|
* regularImageBase64?: string;
|
||||||
|
* tutorialImageBase64?: string;
|
||||||
|
* }[])} param0.variantsAndRotations
|
||||||
|
*/
|
||||||
|
registerNewBuilding({ metaClass, variantsAndRotations, buildingIconBase64 }) {
|
||||||
|
const id = new /** @type {new () => MetaBuilding} */ (metaClass)().getId();
|
||||||
|
if (gMetaBuildingRegistry.hasId(id)) {
|
||||||
|
throw new Error("Tried to register building twice: " + id);
|
||||||
|
}
|
||||||
|
gMetaBuildingRegistry.register(metaClass);
|
||||||
|
|
||||||
|
T.buildings[id] = {};
|
||||||
|
variantsAndRotations.forEach(payload => {
|
||||||
|
const actualVariant = payload.variant || defaultBuildingVariant;
|
||||||
|
registerBuildingVariant(id, metaClass, actualVariant, payload.rotationVariant || 0);
|
||||||
|
T.buildings[id][actualVariant] = {
|
||||||
|
name: payload.name,
|
||||||
|
description: payload.description,
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildingIdentifier =
|
||||||
|
id + (actualVariant === defaultBuildingVariant ? "" : "-" + actualVariant);
|
||||||
|
if (payload.regularImageBase64) {
|
||||||
|
this.registerSprite(
|
||||||
|
"sprites/buildings/" + buildingIdentifier + ".png",
|
||||||
|
payload.regularImageBase64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (payload.blueprintImageBase64) {
|
||||||
|
this.registerSprite(
|
||||||
|
"sprites/blueprints/" + buildingIdentifier + ".png",
|
||||||
|
payload.blueprintImageBase64
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (payload.tutorialImageBase64) {
|
||||||
|
this.setBuildingTutorialImage(id, actualVariant, payload.tutorialImageBase64);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (buildingIconBase64) {
|
||||||
|
this.setBuildingToolbarIcon(id, buildingIconBase64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setBuildingToolbarIcon(buildingId, iconBase64) {
|
||||||
|
this.registerCss(`
|
||||||
|
[data-icon="building_icons/${buildingId}.png"] .icon {
|
||||||
|
background-image: url('${iconBase64}') !important;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
setBuildingTutorialImage(buildingId, variant, imageBase64) {
|
||||||
|
const buildingIdentifier = buildingId + (variant === defaultBuildingVariant ? "" : "-" + variant);
|
||||||
|
|
||||||
|
this.registerCss(`
|
||||||
|
[data-icon="building_tutorials/${buildingIdentifier}.png"] {
|
||||||
|
background-image: url('${imageBase64}') !important;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { Signal } from "../core/signal";
|
|||||||
import { DemoMod } from "./demo_mod";
|
import { DemoMod } from "./demo_mod";
|
||||||
import { Mod } from "./mod";
|
import { Mod } from "./mod";
|
||||||
import { ModInterface } from "./mod_interface";
|
import { ModInterface } from "./mod_interface";
|
||||||
|
import { BaseHUDPart } from "../game/hud/base_hud_part";
|
||||||
|
|
||||||
const LOG = createLogger("mods");
|
const LOG = createLogger("mods");
|
||||||
|
|
||||||
@ -25,6 +26,9 @@ export class ModLoader {
|
|||||||
injectSprites: new Signal(),
|
injectSprites: new Signal(),
|
||||||
preprocessTheme: /** @type {TypedSignal<[Object]>} */ (new Signal()),
|
preprocessTheme: /** @type {TypedSignal<[Object]>} */ (new Signal()),
|
||||||
modifyLevelDefinitions: /** @type {TypedSignal<[Array[Object]]>} */ (new Signal()),
|
modifyLevelDefinitions: /** @type {TypedSignal<[Array[Object]]>} */ (new Signal()),
|
||||||
|
|
||||||
|
hudElementInitialized: /** @type {TypedSignal<[BaseHUDPart]>} */ (new Signal()),
|
||||||
|
hudElementFinalized: /** @type {TypedSignal<[BaseHUDPart]>} */ (new Signal()),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.registerMod(DemoMod);
|
this.registerMod(DemoMod);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user