mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Merge branch 'master' into master
This commit is contained in:
@@ -8,6 +8,7 @@ import { HUDProcessingOverlay } from "./parts/processing_overlay";
|
||||
import { HUDBuildingsToolbar } from "./parts/buildings_toolbar";
|
||||
import { HUDBuildingPlacer } from "./parts/building_placer";
|
||||
import { HUDBetaOverlay } from "./parts/beta_overlay";
|
||||
import { HUDBlueprintPlacer } from "./parts/blueprint_placer";
|
||||
import { HUDKeybindingOverlay } from "./parts/keybinding_overlay";
|
||||
import { HUDUnlockNotification } from "./parts/unlock_notification";
|
||||
import { HUDGameMenu } from "./parts/game_menu";
|
||||
@@ -45,6 +46,7 @@ export class GameHUD {
|
||||
|
||||
buildingsToolbar: new HUDBuildingsToolbar(this.root),
|
||||
buildingPlacer: new HUDBuildingPlacer(this.root),
|
||||
blueprintPlacer: new HUDBlueprintPlacer(this.root),
|
||||
|
||||
unlockNotification: new HUDUnlockNotification(this.root),
|
||||
|
||||
@@ -72,6 +74,7 @@ export class GameHUD {
|
||||
selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
|
||||
shapePinRequested: /** @type {TypedSignal<[ShapeDefinition, number]>} */ (new Signal()),
|
||||
notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new Signal()),
|
||||
buildingsSelectedForCopy: /** @type {TypedSignal<[Array<number>]>} */ (new Signal()),
|
||||
};
|
||||
|
||||
if (!IS_MOBILE) {
|
||||
@@ -185,7 +188,7 @@ export class GameHUD {
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
const partsOrder = ["massSelector", "buildingPlacer"];
|
||||
const partsOrder = ["massSelector", "buildingPlacer", "blueprintPlacer"];
|
||||
|
||||
for (let i = 0; i < partsOrder.length; ++i) {
|
||||
if (this.parts[partsOrder[i]]) {
|
||||
|
||||
176
src/js/game/hud/parts/blueprint.js
Normal file
176
src/js/game/hud/parts/blueprint.js
Normal file
@@ -0,0 +1,176 @@
|
||||
import { GameRoot } from "../../root";
|
||||
import { Vector } from "../../../core/vector";
|
||||
import { Entity } from "../../entity";
|
||||
import { DrawParameters } from "../../../core/draw_parameters";
|
||||
import { StaticMapEntityComponent } from "../../components/static_map_entity";
|
||||
import { createLogger } from "../../../core/logging";
|
||||
import { Loader } from "../../../core/loader";
|
||||
|
||||
const logger = createLogger("blueprint");
|
||||
|
||||
export class Blueprint {
|
||||
/**
|
||||
* @param {Array<Entity>} entities
|
||||
*/
|
||||
constructor(entities) {
|
||||
this.entities = entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
* @param {Array<number>} uids
|
||||
*/
|
||||
static fromUids(root, uids) {
|
||||
const newEntities = [];
|
||||
|
||||
let averagePosition = new Vector();
|
||||
|
||||
// First, create a copy
|
||||
for (let i = 0; i < uids.length; ++i) {
|
||||
const entity = root.entityMgr.findByUid(uids[i]);
|
||||
assert(entity, "Entity for blueprint not found:" + uids[i]);
|
||||
|
||||
const clone = entity.duplicateWithoutContents();
|
||||
newEntities.push(clone);
|
||||
|
||||
const pos = entity.components.StaticMapEntity.getTileSpaceBounds().getCenter();
|
||||
averagePosition.addInplace(pos);
|
||||
}
|
||||
|
||||
averagePosition.divideScalarInplace(uids.length);
|
||||
const blueprintOrigin = averagePosition.floor();
|
||||
for (let i = 0; i < uids.length; ++i) {
|
||||
newEntities[i].components.StaticMapEntity.origin.subInplace(blueprintOrigin);
|
||||
}
|
||||
|
||||
// Now, make sure the origin is 0,0
|
||||
return new Blueprint(newEntities);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters, tile) {
|
||||
parameters.context.globalAlpha = 0.8;
|
||||
for (let i = 0; i < this.entities.length; ++i) {
|
||||
const entity = this.entities[i];
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
if (!staticComp.blueprintSpriteKey) {
|
||||
logger.warn("Blueprint entity without sprite!");
|
||||
return;
|
||||
}
|
||||
const newPos = staticComp.origin.add(tile);
|
||||
|
||||
const rect = staticComp.getTileSpaceBounds();
|
||||
rect.moveBy(tile.x, tile.y);
|
||||
|
||||
let placeable = true;
|
||||
placementCheck: for (let x = rect.x; x < rect.right(); ++x) {
|
||||
for (let y = rect.y; y < rect.bottom(); ++y) {
|
||||
if (parameters.root.map.isTileUsedXY(x, y)) {
|
||||
placeable = false;
|
||||
break placementCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!placeable) {
|
||||
parameters.context.globalAlpha = 0.3;
|
||||
} else {
|
||||
parameters.context.globalAlpha = 1;
|
||||
}
|
||||
|
||||
staticComp.drawSpriteOnFullEntityBounds(
|
||||
parameters,
|
||||
Loader.getSprite(staticComp.blueprintSpriteKey),
|
||||
0,
|
||||
true,
|
||||
newPos
|
||||
);
|
||||
}
|
||||
parameters.context.globalAlpha = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
* @param {Vector} tile
|
||||
*/
|
||||
canPlace(root, tile) {
|
||||
let anyPlaceable = false;
|
||||
|
||||
for (let i = 0; i < this.entities.length; ++i) {
|
||||
let placeable = true;
|
||||
const entity = this.entities[i];
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
const rect = staticComp.getTileSpaceBounds();
|
||||
rect.moveBy(tile.x, tile.y);
|
||||
placementCheck: for (let x = rect.x; x < rect.right(); ++x) {
|
||||
for (let y = rect.y; y < rect.bottom(); ++y) {
|
||||
if (root.map.isTileUsedXY(x, y)) {
|
||||
placeable = false;
|
||||
break placementCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (placeable) {
|
||||
anyPlaceable = true;
|
||||
}
|
||||
}
|
||||
|
||||
return anyPlaceable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
* @param {Vector} tile
|
||||
*/
|
||||
tryPlace(root, tile) {
|
||||
let anyPlaced = false;
|
||||
for (let i = 0; i < this.entities.length; ++i) {
|
||||
let placeable = true;
|
||||
const entity = this.entities[i];
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
const rect = staticComp.getTileSpaceBounds();
|
||||
rect.moveBy(tile.x, tile.y);
|
||||
placementCheck: for (let x = rect.x; x < rect.right(); ++x) {
|
||||
for (let y = rect.y; y < rect.bottom(); ++y) {
|
||||
const contents = root.map.getTileContentXY(x, y);
|
||||
if (contents && !contents.components.ReplaceableMapEntity) {
|
||||
placeable = false;
|
||||
break placementCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (placeable) {
|
||||
for (let x = rect.x; x < rect.right(); ++x) {
|
||||
for (let y = rect.y; y < rect.bottom(); ++y) {
|
||||
const contents = root.map.getTileContentXY(x, y);
|
||||
if (contents) {
|
||||
assert(
|
||||
contents.components.ReplaceableMapEntity,
|
||||
"Can not delete entity for blueprint"
|
||||
);
|
||||
if (!root.logic.tryDeleteBuilding(contents)) {
|
||||
logger.error(
|
||||
"Building has replaceable component but is also unremovable in blueprint"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const clone = entity.duplicateWithoutContents();
|
||||
clone.components.StaticMapEntity.origin.addInplace(tile);
|
||||
|
||||
root.map.placeStaticEntity(clone);
|
||||
root.entityMgr.registerEntity(clone);
|
||||
anyPlaced = true;
|
||||
}
|
||||
}
|
||||
return anyPlaced;
|
||||
}
|
||||
}
|
||||
103
src/js/game/hud/parts/blueprint_placer.js
Normal file
103
src/js/game/hud/parts/blueprint_placer.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { DrawParameters } from "../../../core/draw_parameters";
|
||||
import { STOP_PROPAGATION } from "../../../core/signal";
|
||||
import { TrackedState } from "../../../core/tracked_state";
|
||||
import { Vector } from "../../../core/vector";
|
||||
import { enumMouseButton } from "../../camera";
|
||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { Blueprint } from "./blueprint";
|
||||
|
||||
export class HUDBlueprintPlacer extends BaseHUDPart {
|
||||
createElements(parent) {}
|
||||
|
||||
initialize() {
|
||||
this.root.hud.signals.buildingsSelectedForCopy.add(this.onBuildingsSelected, this);
|
||||
|
||||
/** @type {TypedTrackedState<Blueprint?>} */
|
||||
this.currentBlueprint = new TrackedState(this.onBlueprintChanged, this);
|
||||
|
||||
const keyActionMapper = this.root.keyMapper;
|
||||
keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.abortPlacement, this);
|
||||
keyActionMapper
|
||||
.getBinding(KEYMAPPINGS.placement.abortBuildingPlacement)
|
||||
.add(this.abortPlacement, this);
|
||||
|
||||
this.root.camera.downPreHandler.add(this.onMouseDown, this);
|
||||
this.root.camera.movePreHandler.add(this.onMouseMove, this);
|
||||
|
||||
this.root.hud.signals.selectedPlacementBuildingChanged.add(this.abortPlacement, this);
|
||||
}
|
||||
|
||||
abortPlacement() {
|
||||
if (this.currentBlueprint.get()) {
|
||||
this.currentBlueprint.set(null);
|
||||
|
||||
return STOP_PROPAGATION;
|
||||
}
|
||||
}
|
||||
|
||||
onBlueprintChanged(blueprint) {}
|
||||
|
||||
/**
|
||||
* mouse down pre handler
|
||||
* @param {Vector} pos
|
||||
* @param {enumMouseButton} button
|
||||
*/
|
||||
onMouseDown(pos, button) {
|
||||
if (button === enumMouseButton.right) {
|
||||
this.abortPlacement();
|
||||
return STOP_PROPAGATION;
|
||||
}
|
||||
|
||||
const blueprint = this.currentBlueprint.get();
|
||||
if (!blueprint) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("down");
|
||||
const worldPos = this.root.camera.screenToWorld(pos);
|
||||
const tile = worldPos.toTileSpace();
|
||||
if (blueprint.tryPlace(this.root, tile)) {
|
||||
if (!this.root.app.inputMgr.shiftIsDown) {
|
||||
this.currentBlueprint.set(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMouseMove() {
|
||||
// Prevent movement while blueprint is selected
|
||||
if (this.currentBlueprint.get()) {
|
||||
return STOP_PROPAGATION;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<number>} uids
|
||||
*/
|
||||
onBuildingsSelected(uids) {
|
||||
if (uids.length === 0) {
|
||||
return;
|
||||
}
|
||||
this.currentBlueprint.set(Blueprint.fromUids(this.root, uids));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
const blueprint = this.currentBlueprint.get();
|
||||
if (!blueprint) {
|
||||
return;
|
||||
}
|
||||
const mousePosition = this.root.app.mousePosition;
|
||||
if (!mousePosition) {
|
||||
// Not on screen
|
||||
return;
|
||||
}
|
||||
|
||||
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
||||
const tile = worldPos.toTileSpace();
|
||||
blueprint.draw(parameters, tile);
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,8 @@ export class HUDBuildingPlacer extends BaseHUDPart {
|
||||
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.tryRotate, this);
|
||||
keyActionMapper.getBinding(KEYMAPPINGS.placement.cycleBuildingVariants).add(this.cycleVariants, this);
|
||||
|
||||
this.root.hud.signals.buildingsSelectedForCopy.add(this.abortPlacement, this);
|
||||
|
||||
this.domAttach = new DynamicDomAttach(this.root, this.element, {});
|
||||
|
||||
this.root.camera.downPreHandler.add(this.onMouseDown, this);
|
||||
@@ -255,6 +257,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
|
||||
origin: new Vector(0, 0),
|
||||
rotation: 0,
|
||||
tileSize: metaBuilding.getDimensions(this.currentVariant.get()).copy(),
|
||||
blueprintSpriteKey: "",
|
||||
})
|
||||
);
|
||||
metaBuilding.updateVariants(this.fakeEntity, 0, this.currentVariant.get());
|
||||
|
||||
@@ -5,12 +5,13 @@ import { DrawParameters } from "../../../core/draw_parameters";
|
||||
import { Entity } from "../../entity";
|
||||
import { Loader } from "../../../core/loader";
|
||||
import { globalConfig } from "../../../core/config";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { makeDiv, formatBigNumber, formatBigNumberFull } from "../../../core/utils";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
import { createLogger } from "../../../core/logging";
|
||||
import { enumMouseButton } from "../../camera";
|
||||
import { T } from "../../../translations";
|
||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||
import { THEME } from "../../theme";
|
||||
|
||||
const logger = createLogger("hud/mass_selector");
|
||||
|
||||
@@ -20,13 +21,17 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
.getBinding(KEYMAPPINGS.massSelect.confirmMassDelete)
|
||||
.getKeyCodeString();
|
||||
const abortKeybinding = this.root.keyMapper.getBinding(KEYMAPPINGS.general.back).getKeyCodeString();
|
||||
const copyKeybinding = this.root.keyMapper
|
||||
.getBinding(KEYMAPPINGS.massSelect.massSelectCopy)
|
||||
.getKeyCodeString();
|
||||
|
||||
this.element = makeDiv(
|
||||
parent,
|
||||
"ingame_HUD_MassSelector",
|
||||
[],
|
||||
T.ingame.massDelete.infoText
|
||||
T.ingame.massSelect.infoText
|
||||
.replace("<keyDelete>", removalKeybinding)
|
||||
.replace("<keyCopy>", copyKeybinding)
|
||||
.replace("<keyCancel>", abortKeybinding)
|
||||
);
|
||||
}
|
||||
@@ -36,7 +41,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
|
||||
this.currentSelectionStart = null;
|
||||
this.currentSelectionEnd = null;
|
||||
this.entityUidsMarkedForDeletion = new Set();
|
||||
this.selectedUids = new Set();
|
||||
|
||||
this.root.signals.entityQueuedForDestroy.add(this.onEntityDestroyed, this);
|
||||
|
||||
@@ -48,6 +53,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
this.root.keyMapper
|
||||
.getBinding(KEYMAPPINGS.massSelect.confirmMassDelete)
|
||||
.add(this.confirmDelete, this);
|
||||
this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectCopy).add(this.startCopy, this);
|
||||
|
||||
this.domAttach = new DynamicDomAttach(this.root, this.element);
|
||||
}
|
||||
@@ -57,7 +63,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
onEntityDestroyed(entity) {
|
||||
this.entityUidsMarkedForDeletion.delete(entity.uid);
|
||||
this.selectedUids.delete(entity.uid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,24 +71,50 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
*/
|
||||
onBack() {
|
||||
// Clear entities on escape
|
||||
if (this.entityUidsMarkedForDeletion.size > 0) {
|
||||
this.entityUidsMarkedForDeletion = new Set();
|
||||
if (this.selectedUids.size > 0) {
|
||||
this.selectedUids = new Set();
|
||||
return STOP_PROPAGATION;
|
||||
}
|
||||
}
|
||||
|
||||
confirmDelete() {
|
||||
const entityUids = Array.from(this.entityUidsMarkedForDeletion);
|
||||
if (this.selectedUids.size > 500) {
|
||||
const { ok } = this.root.hud.parts.dialogs.showWarning(
|
||||
T.dialogs.massDeleteConfirm.title,
|
||||
T.dialogs.massDeleteConfirm.desc.replace(
|
||||
"<count>",
|
||||
"" + formatBigNumberFull(this.selectedUids.size)
|
||||
),
|
||||
["cancel:good", "ok:bad"]
|
||||
);
|
||||
ok.add(() => this.doDelete());
|
||||
} else {
|
||||
this.doDelete();
|
||||
}
|
||||
}
|
||||
|
||||
doDelete() {
|
||||
const entityUids = Array.from(this.selectedUids);
|
||||
for (let i = 0; i < entityUids.length; ++i) {
|
||||
const uid = entityUids[i];
|
||||
const entity = this.root.entityMgr.findByUid(uid);
|
||||
if (!this.root.logic.tryDeleteBuilding(entity)) {
|
||||
logger.error("Error in mass delete, could not remove building");
|
||||
this.entityUidsMarkedForDeletion.delete(uid);
|
||||
this.selectedUids.delete(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startCopy() {
|
||||
if (this.selectedUids.size > 0) {
|
||||
this.root.hud.signals.buildingsSelectedForCopy.dispatch(Array.from(this.selectedUids));
|
||||
this.selectedUids = new Set();
|
||||
this.root.soundProxy.playUiClick();
|
||||
} else {
|
||||
this.root.soundProxy.playUiError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mouse down pre handler
|
||||
* @param {Vector} pos
|
||||
@@ -99,7 +131,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
|
||||
if (!this.root.keyMapper.getBinding(KEYMAPPINGS.massSelect.massSelectSelectMultiple).currentlyDown) {
|
||||
// Start new selection
|
||||
this.entityUidsMarkedForDeletion = new Set();
|
||||
this.selectedUids = new Set();
|
||||
}
|
||||
|
||||
this.currentSelectionStart = pos.copy();
|
||||
@@ -132,7 +164,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
for (let y = realTileStart.y; y <= realTileEnd.y; ++y) {
|
||||
const contents = this.root.map.getTileContentXY(x, y);
|
||||
if (contents && this.root.logic.canDeleteBuilding(contents)) {
|
||||
this.entityUidsMarkedForDeletion.add(contents.uid);
|
||||
this.selectedUids.add(contents.uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +175,7 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
}
|
||||
|
||||
update() {
|
||||
this.domAttach.update(this.entityUidsMarkedForDeletion.size > 0);
|
||||
this.domAttach.update(this.selectedUids.size > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,6 +183,8 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
const boundsBorder = 2;
|
||||
|
||||
if (this.currentSelectionStart) {
|
||||
const worldStart = this.root.camera.screenToWorld(this.currentSelectionStart);
|
||||
const worldEnd = this.root.camera.screenToWorld(this.currentSelectionEnd);
|
||||
@@ -165,8 +199,8 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
const realTileEnd = tileStart.max(tileEnd);
|
||||
|
||||
parameters.context.lineWidth = 1;
|
||||
parameters.context.fillStyle = "rgba(255, 127, 127, 0.2)";
|
||||
parameters.context.strokeStyle = "rgba(255, 127, 127, 0.5)";
|
||||
parameters.context.fillStyle = THEME.map.selectionBackground;
|
||||
parameters.context.strokeStyle = THEME.map.selectionOutline;
|
||||
parameters.context.beginPath();
|
||||
parameters.context.rect(
|
||||
realWorldStart.x,
|
||||
@@ -177,34 +211,40 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
parameters.context.fill();
|
||||
parameters.context.stroke();
|
||||
|
||||
parameters.context.fillStyle = THEME.map.selectionOverlay;
|
||||
|
||||
for (let x = realTileStart.x; x <= realTileEnd.x; ++x) {
|
||||
for (let y = realTileStart.y; y <= realTileEnd.y; ++y) {
|
||||
const contents = this.root.map.getTileContentXY(x, y);
|
||||
if (contents && this.root.logic.canDeleteBuilding(contents)) {
|
||||
const staticComp = contents.components.StaticMapEntity;
|
||||
const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace();
|
||||
this.deletionMarker.drawCachedCentered(
|
||||
parameters,
|
||||
center.x,
|
||||
center.y,
|
||||
globalConfig.tileSize * 0.5
|
||||
const bounds = staticComp.getTileSpaceBounds();
|
||||
parameters.context.beginRoundedRect(
|
||||
bounds.x * globalConfig.tileSize + boundsBorder,
|
||||
bounds.y * globalConfig.tileSize + boundsBorder,
|
||||
bounds.w * globalConfig.tileSize - 2 * boundsBorder,
|
||||
bounds.h * globalConfig.tileSize - 2 * boundsBorder,
|
||||
2
|
||||
);
|
||||
parameters.context.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.entityUidsMarkedForDeletion.forEach(uid => {
|
||||
parameters.context.fillStyle = THEME.map.selectionOverlay;
|
||||
this.selectedUids.forEach(uid => {
|
||||
const entity = this.root.entityMgr.findByUid(uid);
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
const center = staticComp.getTileSpaceBounds().getCenter().toWorldSpace();
|
||||
|
||||
this.deletionMarker.drawCachedCentered(
|
||||
parameters,
|
||||
center.x,
|
||||
center.y,
|
||||
globalConfig.tileSize * 0.5
|
||||
const bounds = staticComp.getTileSpaceBounds();
|
||||
parameters.context.beginRoundedRect(
|
||||
bounds.x * globalConfig.tileSize + boundsBorder,
|
||||
bounds.y * globalConfig.tileSize + boundsBorder,
|
||||
bounds.w * globalConfig.tileSize - 2 * boundsBorder,
|
||||
bounds.h * globalConfig.tileSize - 2 * boundsBorder,
|
||||
2
|
||||
);
|
||||
parameters.context.fill();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { KeyActionMapper, KEYMAPPINGS } from "../../key_action_mapper";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
import { T } from "../../../translations";
|
||||
import { globalConfig } from "../../../core/config";
|
||||
|
||||
const tutorialVideos = [1, 2, 3, 4, 5, 6, 7, 9, 10, 11];
|
||||
|
||||
@@ -56,7 +57,7 @@ export class HUDPartTutorialHints extends BaseHUDPart {
|
||||
this.currentShownLevel = new TrackedState(this.updateVideoUrl, this);
|
||||
|
||||
this.root.signals.postLoadHook.add(() => {
|
||||
if (this.root.hubGoals.level === 1) {
|
||||
if (this.root.hubGoals.level === 1 && !(G_IS_DEV && globalConfig.debug.disableTutorialHints)) {
|
||||
this.root.hud.parts.dialogs.showInfo(
|
||||
T.dialogs.hintDescription.title,
|
||||
T.dialogs.hintDescription.desc
|
||||
|
||||
Reference in New Issue
Block a user