parent
3529a5d77f
commit
0377c6d58f
@ -1,277 +1,281 @@
|
||||
/* typehints:start */
|
||||
import { GameRoot } from "../root";
|
||||
/* typehints:end */
|
||||
|
||||
/* dev:start */
|
||||
import { TrailerMaker } from "./trailer_maker";
|
||||
/* dev:end */
|
||||
|
||||
import { Signal } from "../../core/signal";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { HUDBuildingsToolbar } from "./parts/buildings_toolbar";
|
||||
import { HUDBuildingPlacer } from "./parts/building_placer";
|
||||
import { HUDBlueprintPlacer } from "./parts/blueprint_placer";
|
||||
import { HUDKeybindingOverlay } from "./parts/keybinding_overlay";
|
||||
import { HUDUnlockNotification } from "./parts/unlock_notification";
|
||||
import { HUDGameMenu } from "./parts/game_menu";
|
||||
import { HUDShop } from "./parts/shop";
|
||||
import { IS_MOBILE, globalConfig, IS_DEMO } from "../../core/config";
|
||||
import { HUDMassSelector } from "./parts/mass_selector";
|
||||
import { HUDVignetteOverlay } from "./parts/vignette_overlay";
|
||||
import { HUDStatistics } from "./parts/statistics";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { HUDPinnedShapes } from "./parts/pinned_shapes";
|
||||
import { ShapeDefinition } from "../shape_definition";
|
||||
import { HUDNotifications, enumNotificationType } from "./parts/notifications";
|
||||
import { HUDSettingsMenu } from "./parts/settings_menu";
|
||||
import { HUDDebugInfo } from "./parts/debug_info";
|
||||
import { HUDEntityDebugger } from "./parts/entity_debugger";
|
||||
import { KEYMAPPINGS } from "../key_action_mapper";
|
||||
import { HUDWatermark } from "./parts/watermark";
|
||||
import { HUDModalDialogs } from "./parts/modal_dialogs";
|
||||
import { HUDPartTutorialHints } from "./parts/tutorial_hints";
|
||||
import { HUDWaypoints } from "./parts/waypoints";
|
||||
import { HUDInteractiveTutorial } from "./parts/interactive_tutorial";
|
||||
import { HUDScreenshotExporter } from "./parts/screenshot_exporter";
|
||||
import { HUDColorBlindHelper } from "./parts/color_blind_helper";
|
||||
import { HUDShapeViewer } from "./parts/shape_viewer";
|
||||
import { HUDWiresOverlay } from "./parts/wires_overlay";
|
||||
import { HUDChangesDebugger } from "./parts/debug_changes";
|
||||
import { queryParamOptions } from "../../core/query_parameters";
|
||||
import { HUDSandboxController } from "./parts/sandbox_controller";
|
||||
import { HUDWiresToolbar } from "./parts/wires_toolbar";
|
||||
import { HUDWireInfo } from "./parts/wire_info";
|
||||
import { HUDLeverToggle } from "./parts/lever_toggle";
|
||||
import { HUDLayerPreview } from "./parts/layer_preview";
|
||||
|
||||
export class GameHUD {
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
constructor(root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the hud parts
|
||||
*/
|
||||
initialize() {
|
||||
this.parts = {
|
||||
buildingsToolbar: new HUDBuildingsToolbar(this.root),
|
||||
wiresToolbar: new HUDWiresToolbar(this.root),
|
||||
blueprintPlacer: new HUDBlueprintPlacer(this.root),
|
||||
buildingPlacer: new HUDBuildingPlacer(this.root),
|
||||
unlockNotification: new HUDUnlockNotification(this.root),
|
||||
gameMenu: new HUDGameMenu(this.root),
|
||||
massSelector: new HUDMassSelector(this.root),
|
||||
shop: new HUDShop(this.root),
|
||||
statistics: new HUDStatistics(this.root),
|
||||
waypoints: new HUDWaypoints(this.root),
|
||||
wireInfo: new HUDWireInfo(this.root),
|
||||
leverToggle: new HUDLeverToggle(this.root),
|
||||
|
||||
// Must always exist
|
||||
pinnedShapes: new HUDPinnedShapes(this.root),
|
||||
notifications: new HUDNotifications(this.root),
|
||||
settingsMenu: new HUDSettingsMenu(this.root),
|
||||
// betaOverlay: new HUDBetaOverlay(this.root),
|
||||
debugInfo: new HUDDebugInfo(this.root),
|
||||
dialogs: new HUDModalDialogs(this.root),
|
||||
screenshotExporter: new HUDScreenshotExporter(this.root),
|
||||
shapeViewer: new HUDShapeViewer(this.root),
|
||||
|
||||
wiresOverlay: new HUDWiresOverlay(this.root),
|
||||
layerPreview: new HUDLayerPreview(this.root),
|
||||
|
||||
// Typing hints
|
||||
/* typehints:start */
|
||||
/** @type {HUDChangesDebugger} */
|
||||
changesDebugger: null,
|
||||
/* typehints:end */
|
||||
};
|
||||
|
||||
this.signals = {
|
||||
buildingSelectedForPlacement: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
|
||||
selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
|
||||
shapePinRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
|
||||
shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new Signal()),
|
||||
notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new Signal()),
|
||||
buildingsSelectedForCopy: /** @type {TypedSignal<[Array<number>]>} */ (new Signal()),
|
||||
pasteBlueprintRequested: /** @type {TypedSignal<[]>} */ (new Signal()),
|
||||
viewShapeDetailsRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
|
||||
};
|
||||
|
||||
if (!IS_MOBILE) {
|
||||
this.parts.keybindingOverlay = new HUDKeybindingOverlay(this.root);
|
||||
}
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.enableEntityInspector) {
|
||||
this.parts.entityDebugger = new HUDEntityDebugger(this.root);
|
||||
}
|
||||
|
||||
if (IS_DEMO) {
|
||||
this.parts.watermark = new HUDWatermark(this.root);
|
||||
}
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.renderChanges) {
|
||||
this.parts.changesDebugger = new HUDChangesDebugger(this.root);
|
||||
}
|
||||
|
||||
if (this.root.app.settings.getAllSettings().offerHints) {
|
||||
this.parts.tutorialHints = new HUDPartTutorialHints(this.root);
|
||||
this.parts.interactiveTutorial = new HUDInteractiveTutorial(this.root);
|
||||
}
|
||||
|
||||
if (this.root.app.settings.getAllSettings().vignette) {
|
||||
this.parts.vignetteOverlay = new HUDVignetteOverlay(this.root);
|
||||
}
|
||||
|
||||
if (this.root.app.settings.getAllSettings().enableColorBlindHelper) {
|
||||
this.parts.colorBlindHelper = new HUDColorBlindHelper(this.root);
|
||||
}
|
||||
|
||||
if (queryParamOptions.sandboxMode || G_IS_DEV) {
|
||||
this.parts.sandboxController = new HUDSandboxController(this.root);
|
||||
}
|
||||
|
||||
const frag = document.createDocumentFragment();
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].createElements(frag);
|
||||
}
|
||||
|
||||
document.body.appendChild(frag);
|
||||
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].initialize();
|
||||
}
|
||||
|
||||
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.toggleHud).add(this.toggleUi, this);
|
||||
|
||||
/* dev:start */
|
||||
if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
|
||||
this.trailerMaker = new TrailerMaker(this.root);
|
||||
}
|
||||
/* dev:end*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to close all overlays
|
||||
*/
|
||||
closeAllOverlays() {
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the game logic should be paused
|
||||
*/
|
||||
shouldPauseGame() {
|
||||
for (const key in this.parts) {
|
||||
if (this.parts[key].shouldPauseGame()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the rendering can be paused
|
||||
*/
|
||||
shouldPauseRendering() {
|
||||
for (const key in this.parts) {
|
||||
if (this.parts[key].shouldPauseRendering()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the rendering can be paused
|
||||
*/
|
||||
hasBlockingOverlayOpen() {
|
||||
if (this.root.camera.getIsMapOverlayActive()) {
|
||||
return true;
|
||||
}
|
||||
for (const key in this.parts) {
|
||||
if (this.parts[key].isBlockingOverlay()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the ui
|
||||
*/
|
||||
toggleUi() {
|
||||
document.body.classList.toggle("uiHidden");
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all parts
|
||||
*/
|
||||
update() {
|
||||
if (!this.root.gameInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].update();
|
||||
}
|
||||
|
||||
/* dev:start */
|
||||
if (this.trailerMaker) {
|
||||
this.trailerMaker.update();
|
||||
}
|
||||
/* dev:end*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws all parts
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
const partsOrder = [
|
||||
"massSelector",
|
||||
"buildingPlacer",
|
||||
"blueprintPlacer",
|
||||
"colorBlindHelper",
|
||||
"changesDebugger",
|
||||
];
|
||||
|
||||
for (let i = 0; i < partsOrder.length; ++i) {
|
||||
if (this.parts[partsOrder[i]]) {
|
||||
this.parts[partsOrder[i]].draw(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws all part overlays
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
drawOverlays(parameters) {
|
||||
const partsOrder = ["waypoints", "watermark", "wireInfo"];
|
||||
|
||||
for (let i = 0; i < partsOrder.length; ++i) {
|
||||
if (this.parts[partsOrder[i]]) {
|
||||
this.parts[partsOrder[i]].drawOverlays(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up everything
|
||||
*/
|
||||
cleanup() {
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].cleanup();
|
||||
}
|
||||
|
||||
for (const key in this.signals) {
|
||||
this.signals[key].removeAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* typehints:start */
|
||||
import { GameRoot } from "../root";
|
||||
/* typehints:end */
|
||||
|
||||
/* dev:start */
|
||||
import { TrailerMaker } from "./trailer_maker";
|
||||
/* dev:end */
|
||||
|
||||
import { Signal } from "../../core/signal";
|
||||
import { DrawParameters } from "../../core/draw_parameters";
|
||||
import { HUDBuildingsToolbar } from "./parts/buildings_toolbar";
|
||||
import { HUDBuildingPlacer } from "./parts/building_placer";
|
||||
import { HUDBlueprintPlacer } from "./parts/blueprint_placer";
|
||||
import { HUDKeybindingOverlay } from "./parts/keybinding_overlay";
|
||||
import { HUDUnlockNotification } from "./parts/unlock_notification";
|
||||
import { HUDGameMenu } from "./parts/game_menu";
|
||||
import { HUDShop } from "./parts/shop";
|
||||
import { IS_MOBILE, globalConfig, IS_DEMO } from "../../core/config";
|
||||
import { HUDMassSelector } from "./parts/mass_selector";
|
||||
import { HUDVignetteOverlay } from "./parts/vignette_overlay";
|
||||
import { HUDStatistics } from "./parts/statistics";
|
||||
import { MetaBuilding } from "../meta_building";
|
||||
import { HUDPinnedShapes } from "./parts/pinned_shapes";
|
||||
import { ShapeDefinition } from "../shape_definition";
|
||||
import { HUDNotifications, enumNotificationType } from "./parts/notifications";
|
||||
import { HUDSettingsMenu } from "./parts/settings_menu";
|
||||
import { HUDDebugInfo } from "./parts/debug_info";
|
||||
import { HUDEntityDebugger } from "./parts/entity_debugger";
|
||||
import { KEYMAPPINGS } from "../key_action_mapper";
|
||||
import { HUDWatermark } from "./parts/watermark";
|
||||
import { HUDModalDialogs } from "./parts/modal_dialogs";
|
||||
import { HUDPartTutorialHints } from "./parts/tutorial_hints";
|
||||
import { HUDWaypoints } from "./parts/waypoints";
|
||||
import { HUDInteractiveTutorial } from "./parts/interactive_tutorial";
|
||||
import { HUDScreenshotExporter } from "./parts/screenshot_exporter";
|
||||
import { HUDColorBlindHelper } from "./parts/color_blind_helper";
|
||||
import { HUDShapeViewer } from "./parts/shape_viewer";
|
||||
import { HUDWiresOverlay } from "./parts/wires_overlay";
|
||||
import { HUDChangesDebugger } from "./parts/debug_changes";
|
||||
import { queryParamOptions } from "../../core/query_parameters";
|
||||
import { HUDSandboxController } from "./parts/sandbox_controller";
|
||||
import { HUDWiresToolbar } from "./parts/wires_toolbar";
|
||||
import { HUDWireInfo } from "./parts/wire_info";
|
||||
import { HUDLeverToggle } from "./parts/lever_toggle";
|
||||
import { HUDLayerPreview } from "./parts/layer_preview";
|
||||
import { HUDMinerHighlight } from "./parts/miner_highlight";
|
||||
|
||||
export class GameHUD {
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
*/
|
||||
constructor(root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the hud parts
|
||||
*/
|
||||
initialize() {
|
||||
this.parts = {
|
||||
buildingsToolbar: new HUDBuildingsToolbar(this.root),
|
||||
wiresToolbar: new HUDWiresToolbar(this.root),
|
||||
blueprintPlacer: new HUDBlueprintPlacer(this.root),
|
||||
buildingPlacer: new HUDBuildingPlacer(this.root),
|
||||
unlockNotification: new HUDUnlockNotification(this.root),
|
||||
gameMenu: new HUDGameMenu(this.root),
|
||||
massSelector: new HUDMassSelector(this.root),
|
||||
shop: new HUDShop(this.root),
|
||||
statistics: new HUDStatistics(this.root),
|
||||
waypoints: new HUDWaypoints(this.root),
|
||||
wireInfo: new HUDWireInfo(this.root),
|
||||
leverToggle: new HUDLeverToggle(this.root),
|
||||
|
||||
// Must always exist
|
||||
pinnedShapes: new HUDPinnedShapes(this.root),
|
||||
notifications: new HUDNotifications(this.root),
|
||||
settingsMenu: new HUDSettingsMenu(this.root),
|
||||
// betaOverlay: new HUDBetaOverlay(this.root),
|
||||
debugInfo: new HUDDebugInfo(this.root),
|
||||
dialogs: new HUDModalDialogs(this.root),
|
||||
screenshotExporter: new HUDScreenshotExporter(this.root),
|
||||
shapeViewer: new HUDShapeViewer(this.root),
|
||||
|
||||
wiresOverlay: new HUDWiresOverlay(this.root),
|
||||
layerPreview: new HUDLayerPreview(this.root),
|
||||
|
||||
minerHighlight: new HUDMinerHighlight(this.root),
|
||||
|
||||
// Typing hints
|
||||
/* typehints:start */
|
||||
/** @type {HUDChangesDebugger} */
|
||||
changesDebugger: null,
|
||||
/* typehints:end */
|
||||
};
|
||||
|
||||
this.signals = {
|
||||
buildingSelectedForPlacement: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
|
||||
selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
|
||||
shapePinRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
|
||||
shapeUnpinRequested: /** @type {TypedSignal<[string]>} */ (new Signal()),
|
||||
notification: /** @type {TypedSignal<[string, enumNotificationType]>} */ (new Signal()),
|
||||
buildingsSelectedForCopy: /** @type {TypedSignal<[Array<number>]>} */ (new Signal()),
|
||||
pasteBlueprintRequested: /** @type {TypedSignal<[]>} */ (new Signal()),
|
||||
viewShapeDetailsRequested: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
|
||||
};
|
||||
|
||||
if (!IS_MOBILE) {
|
||||
this.parts.keybindingOverlay = new HUDKeybindingOverlay(this.root);
|
||||
}
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.enableEntityInspector) {
|
||||
this.parts.entityDebugger = new HUDEntityDebugger(this.root);
|
||||
}
|
||||
|
||||
if (IS_DEMO) {
|
||||
this.parts.watermark = new HUDWatermark(this.root);
|
||||
}
|
||||
|
||||
if (G_IS_DEV && globalConfig.debug.renderChanges) {
|
||||
this.parts.changesDebugger = new HUDChangesDebugger(this.root);
|
||||
}
|
||||
|
||||
if (this.root.app.settings.getAllSettings().offerHints) {
|
||||
this.parts.tutorialHints = new HUDPartTutorialHints(this.root);
|
||||
this.parts.interactiveTutorial = new HUDInteractiveTutorial(this.root);
|
||||
}
|
||||
|
||||
if (this.root.app.settings.getAllSettings().vignette) {
|
||||
this.parts.vignetteOverlay = new HUDVignetteOverlay(this.root);
|
||||
}
|
||||
|
||||
if (this.root.app.settings.getAllSettings().enableColorBlindHelper) {
|
||||
this.parts.colorBlindHelper = new HUDColorBlindHelper(this.root);
|
||||
}
|
||||
|
||||
if (queryParamOptions.sandboxMode || G_IS_DEV) {
|
||||
this.parts.sandboxController = new HUDSandboxController(this.root);
|
||||
}
|
||||
|
||||
const frag = document.createDocumentFragment();
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].createElements(frag);
|
||||
}
|
||||
|
||||
document.body.appendChild(frag);
|
||||
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].initialize();
|
||||
}
|
||||
|
||||
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.toggleHud).add(this.toggleUi, this);
|
||||
|
||||
/* dev:start */
|
||||
if (G_IS_DEV && globalConfig.debug.renderForTrailer) {
|
||||
this.trailerMaker = new TrailerMaker(this.root);
|
||||
}
|
||||
/* dev:end*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to close all overlays
|
||||
*/
|
||||
closeAllOverlays() {
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the game logic should be paused
|
||||
*/
|
||||
shouldPauseGame() {
|
||||
for (const key in this.parts) {
|
||||
if (this.parts[key].shouldPauseGame()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the rendering can be paused
|
||||
*/
|
||||
shouldPauseRendering() {
|
||||
for (const key in this.parts) {
|
||||
if (this.parts[key].shouldPauseRendering()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the rendering can be paused
|
||||
*/
|
||||
hasBlockingOverlayOpen() {
|
||||
if (this.root.camera.getIsMapOverlayActive()) {
|
||||
return true;
|
||||
}
|
||||
for (const key in this.parts) {
|
||||
if (this.parts[key].isBlockingOverlay()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the ui
|
||||
*/
|
||||
toggleUi() {
|
||||
document.body.classList.toggle("uiHidden");
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates all parts
|
||||
*/
|
||||
update() {
|
||||
if (!this.root.gameInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].update();
|
||||
}
|
||||
|
||||
/* dev:start */
|
||||
if (this.trailerMaker) {
|
||||
this.trailerMaker.update();
|
||||
}
|
||||
/* dev:end*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws all parts
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
const partsOrder = [
|
||||
"massSelector",
|
||||
"buildingPlacer",
|
||||
"blueprintPlacer",
|
||||
"colorBlindHelper",
|
||||
"changesDebugger",
|
||||
"minerHighlight",
|
||||
];
|
||||
|
||||
for (let i = 0; i < partsOrder.length; ++i) {
|
||||
if (this.parts[partsOrder[i]]) {
|
||||
this.parts[partsOrder[i]].draw(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws all part overlays
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
drawOverlays(parameters) {
|
||||
const partsOrder = ["waypoints", "watermark", "wireInfo"];
|
||||
|
||||
for (let i = 0; i < partsOrder.length; ++i) {
|
||||
if (this.parts[partsOrder[i]]) {
|
||||
this.parts[partsOrder[i]].drawOverlays(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up everything
|
||||
*/
|
||||
cleanup() {
|
||||
for (const key in this.parts) {
|
||||
this.parts[key].cleanup();
|
||||
}
|
||||
|
||||
for (const key in this.signals) {
|
||||
this.signals[key].removeAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,170 @@
|
||||
import { globalConfig } from "../../../core/config";
|
||||
import { formatItemsPerSecond, round2Digits } from "../../../core/utils";
|
||||
import { Vector } from "../../../core/vector";
|
||||
import { T } from "../../../translations";
|
||||
import { Entity } from "../../entity";
|
||||
import { THEME } from "../../theme";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
|
||||
export class HUDMinerHighlight extends BaseHUDPart {
|
||||
initialize() {}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("../../../core/draw_utils").DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
const mousePos = this.root.app.mousePosition;
|
||||
if (!mousePos) {
|
||||
// Mouse pos not ready
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.root.currentLayer !== "regular") {
|
||||
// Not within the regular layer
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.root.camera.getIsMapOverlayActive()) {
|
||||
// Not within the map overlay
|
||||
return;
|
||||
}
|
||||
|
||||
const worldPos = this.root.camera.screenToWorld(mousePos);
|
||||
const hoveredTile = worldPos.toTileSpace();
|
||||
|
||||
const contents = this.root.map.getTileContent(hoveredTile, "regular");
|
||||
if (!contents) {
|
||||
// Empty tile
|
||||
return;
|
||||
}
|
||||
|
||||
const minerComp = contents.components.Miner;
|
||||
if (!minerComp || !minerComp.chainable) {
|
||||
// Not a chainable miner
|
||||
return;
|
||||
}
|
||||
|
||||
parameters.context.fillStyle = THEME.map.connectedMiners.overlay;
|
||||
|
||||
const connectedEntities = this.findConnectedMiners(contents);
|
||||
|
||||
for (let i = 0; i < connectedEntities.length; ++i) {
|
||||
const entity = connectedEntities[i];
|
||||
const staticComp = entity.components.StaticMapEntity;
|
||||
|
||||
parameters.context.beginRoundedRect(
|
||||
staticComp.origin.x * globalConfig.tileSize + 5,
|
||||
staticComp.origin.y * globalConfig.tileSize + 5,
|
||||
globalConfig.tileSize - 10,
|
||||
globalConfig.tileSize - 10,
|
||||
3
|
||||
);
|
||||
parameters.context.fill();
|
||||
}
|
||||
|
||||
const throughput = round2Digits(connectedEntities.length * this.root.hubGoals.getMinerBaseSpeed());
|
||||
|
||||
const maxThroughput = this.root.hubGoals.getBeltBaseSpeed();
|
||||
|
||||
const screenPos = this.root.camera.screenToWorld(mousePos);
|
||||
|
||||
const scale = (1 / this.root.camera.zoomLevel) * this.root.app.getEffectiveUiScale();
|
||||
|
||||
const isCapped = throughput > maxThroughput;
|
||||
|
||||
// Background
|
||||
parameters.context.fillStyle = THEME.map.connectedMiners.background;
|
||||
parameters.context.beginRoundedRect(
|
||||
screenPos.x + 5 * scale,
|
||||
screenPos.y - 3 * scale,
|
||||
(isCapped ? 100 : 65) * scale,
|
||||
(isCapped ? 45 : 30) * scale,
|
||||
2
|
||||
);
|
||||
parameters.context.fill();
|
||||
|
||||
// Throughput
|
||||
parameters.context.fillStyle = THEME.map.connectedMiners.textColor;
|
||||
parameters.context.font = "bold " + scale * 10 + "px GameFont";
|
||||
parameters.context.fillText(
|
||||
formatItemsPerSecond(throughput),
|
||||
screenPos.x + 10 * scale,
|
||||
screenPos.y + 10 * scale
|
||||
);
|
||||
|
||||
// Amount of miners
|
||||
parameters.context.globalAlpha = 0.6;
|
||||
parameters.context.font = "bold " + scale * 8 + "px GameFont";
|
||||
parameters.context.fillText(
|
||||
connectedEntities.length === 1
|
||||
? T.ingame.connectedMiners.one_miner
|
||||
: T.ingame.connectedMiners.n_miners.replace("<amount>", String(connectedEntities.length)),
|
||||
screenPos.x + 10 * scale,
|
||||
screenPos.y + 22 * scale
|
||||
);
|
||||
|
||||
parameters.context.globalAlpha = 1;
|
||||
|
||||
if (isCapped) {
|
||||
parameters.context.fillStyle = THEME.map.connectedMiners.textColorCapped;
|
||||
parameters.context.fillText(
|
||||
T.ingame.connectedMiners.limited_items.replace(
|
||||
"<max_throughput>",
|
||||
formatItemsPerSecond(maxThroughput)
|
||||
),
|
||||
screenPos.x + 10 * scale,
|
||||
screenPos.y + 34 * scale
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all connected miners to the given entity
|
||||
* @param {Entity} entity
|
||||
* @param {Set<number>} seenUids Which entities have already been processed
|
||||
* @returns {Array<Entity>} The connected miners
|
||||
*/
|
||||
findConnectedMiners(entity, seenUids = new Set()) {
|
||||
let results = [];
|
||||
const origin = entity.components.StaticMapEntity.origin;
|
||||
|
||||
if (!seenUids.has(entity.uid)) {
|
||||
seenUids.add(entity.uid);
|
||||
results.push(entity);
|
||||
}
|
||||
|
||||
// Check for the miner which we connect to
|
||||
const connectedMiner = this.root.systemMgr.systems.miner.findChainedMiner(entity);
|
||||
if (connectedMiner && !seenUids.has(connectedMiner.uid)) {
|
||||
results.push(connectedMiner);
|
||||
seenUids.add(connectedMiner.uid);
|
||||
results.push(...this.findConnectedMiners(connectedMiner, seenUids));
|
||||
}
|
||||
|
||||
// Search within a 1x1 grid - this assumes miners are always 1x1
|
||||
for (let dx = -1; dx <= 1; ++dx) {
|
||||
for (let dy = -1; dy <= 1; ++dy) {
|
||||
const contents = this.root.map.getTileContent(
|
||||
new Vector(origin.x + dx, origin.y + dy),
|
||||
"regular"
|
||||
);
|
||||
if (contents) {
|
||||
const minerComp = contents.components.Miner;
|
||||
if (minerComp && minerComp.chainable) {
|
||||
// Found a miner connected to this entity
|
||||
if (!seenUids.has(contents.uid)) {
|
||||
if (this.root.systemMgr.systems.miner.findChainedMiner(contents) === entity) {
|
||||
results.push(contents);
|
||||
seenUids.add(contents.uid);
|
||||
results.push(...this.findConnectedMiners(contents, seenUids));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
Loading…
Reference in new issue