mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Added shape tooltip - final version (#1251)
* Added shape tooltip * Shortened and simplified shape tooltip code * added special logic for cutters so they remove overlays of empty outputs, and added clearing overlays on clear items
This commit is contained in:
parent
736fbaed42
commit
4b36426a77
@ -11,6 +11,7 @@ import { typeItemSingleton } from "../item_resolver";
|
||||
* pos: Vector,
|
||||
* direction: enumDirection,
|
||||
* item: BaseItem,
|
||||
* lastItem: BaseItem,
|
||||
* progress: number?,
|
||||
* cachedDestSlot?: import("./item_acceptor").ItemAcceptorLocatedSlot,
|
||||
* cachedBeltPath?: BeltPath,
|
||||
@ -51,6 +52,7 @@ export class ItemEjectorComponent extends Component {
|
||||
clear() {
|
||||
for (const slot of this.slots) {
|
||||
slot.item = null;
|
||||
slot.lastItem = null;
|
||||
slot.progress = 0;
|
||||
}
|
||||
}
|
||||
@ -67,6 +69,7 @@ export class ItemEjectorComponent extends Component {
|
||||
pos: slot.pos,
|
||||
direction: slot.direction,
|
||||
item: null,
|
||||
lastItem: null,
|
||||
progress: 0,
|
||||
cachedDestSlot: null,
|
||||
cachedTargetEntity: null,
|
||||
@ -131,6 +134,7 @@ export class ItemEjectorComponent extends Component {
|
||||
return false;
|
||||
}
|
||||
this.slots[slotIndex].item = item;
|
||||
this.slots[slotIndex].lastItem = item;
|
||||
this.slots[slotIndex].progress = 0;
|
||||
return true;
|
||||
}
|
||||
|
@ -189,6 +189,7 @@ export class GameHUD {
|
||||
"colorBlindHelper",
|
||||
"changesDebugger",
|
||||
"minerHighlight",
|
||||
"shapeTooltip",
|
||||
];
|
||||
|
||||
for (let i = 0; i < partsOrder.length; ++i) {
|
||||
|
90
src/js/game/hud/parts/shape_tooltip.js
Normal file
90
src/js/game/hud/parts/shape_tooltip.js
Normal file
@ -0,0 +1,90 @@
|
||||
import { DrawParameters } from "../../../core/draw_parameters";
|
||||
import { Vector } from "../../../core/vector";
|
||||
import { Entity } from "../../entity";
|
||||
import { KEYMAPPINGS } from "../../key_action_mapper";
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
|
||||
export class HUDShapeTooltip extends BaseHUDPart {
|
||||
createElements(parent) {}
|
||||
|
||||
initialize() {
|
||||
/** @type {Vector} */
|
||||
this.currentTile = new Vector(0, 0);
|
||||
|
||||
/** @type {Entity} */
|
||||
this.currentEntity = null;
|
||||
|
||||
this.isPlacingBuilding = false;
|
||||
|
||||
this.root.signals.entityQueuedForDestroy.add(() => {
|
||||
this.currentEntity = null;
|
||||
}, this);
|
||||
|
||||
this.root.hud.signals.selectedPlacementBuildingChanged.add(metaBuilding => {
|
||||
this.isPlacingBuilding = metaBuilding;
|
||||
}, this);
|
||||
}
|
||||
|
||||
isActive() {
|
||||
const hudParts = this.root.hud.parts;
|
||||
|
||||
// return false if any other placer is active
|
||||
return (
|
||||
this.root.keyMapper.getBinding(KEYMAPPINGS.ingame.showShapeTooltip).pressed &&
|
||||
!this.isPlacingBuilding &&
|
||||
!hudParts.massSelector.currentSelectionStartWorld &&
|
||||
hudParts.massSelector.selectedUids.size < 1 &&
|
||||
!hudParts.blueprintPlacer.currentBlueprint.get()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
if (this.isActive()) {
|
||||
const mousePos = this.root.app.mousePosition;
|
||||
|
||||
if (mousePos) {
|
||||
const tile = this.root.camera.screenToWorld(mousePos.copy()).toTileSpace();
|
||||
if (!tile.equals(this.currentTile)) {
|
||||
this.currentTile = tile;
|
||||
|
||||
const entity = this.root.map.getLayerContentXY(tile.x, tile.y, this.root.currentLayer);
|
||||
|
||||
if (entity && entity.components.ItemProcessor && entity.components.ItemEjector) {
|
||||
this.currentEntity = entity;
|
||||
} else {
|
||||
this.currentEntity = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.currentEntity) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ejectorComp = this.currentEntity.components.ItemEjector;
|
||||
const staticComp = this.currentEntity.components.StaticMapEntity;
|
||||
|
||||
for (let i = 0; i < ejectorComp.slots.length; ++i) {
|
||||
const slot = ejectorComp.slots[i];
|
||||
|
||||
if (!slot.lastItem || slot.lastItem._type != "shape") {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @type {Vector} */
|
||||
let drawPos = null;
|
||||
if (ejectorComp.slots.length == 1) {
|
||||
drawPos = staticComp.getTileSpaceBounds().getCenter().toWorldSpace();
|
||||
} else {
|
||||
drawPos = staticComp.localTileToWorld(slot.pos).toWorldSpaceCenterOfTile();
|
||||
}
|
||||
|
||||
slot.lastItem.drawItemCenteredClipped(drawPos.x, drawPos.y, parameters, 25);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -32,6 +32,8 @@ export const KEYMAPPINGS = {
|
||||
toggleFPSInfo: { keyCode: 115 }, // F4
|
||||
|
||||
switchLayers: { keyCode: key("E") },
|
||||
|
||||
showShapeTooltip: { keyCode: 18 }, // ALT
|
||||
},
|
||||
|
||||
navigation: {
|
||||
|
@ -8,6 +8,7 @@ import { enumGameModeTypes, GameMode } from "../game_mode";
|
||||
import { HUDPuzzleBackToMenu } from "../hud/parts/puzzle_back_to_menu";
|
||||
import { HUDPuzzleDLCLogo } from "../hud/parts/puzzle_dlc_logo";
|
||||
import { HUDMassSelector } from "../hud/parts/mass_selector";
|
||||
import { HUDShapeTooltip } from "../hud/parts/shape_tooltip";
|
||||
|
||||
export class PuzzleGameMode extends GameMode {
|
||||
static getType() {
|
||||
@ -32,6 +33,7 @@ export class PuzzleGameMode extends GameMode {
|
||||
puzzleBackToMenu: HUDPuzzleBackToMenu,
|
||||
puzzleDlcLogo: HUDPuzzleDLCLogo,
|
||||
massSelector: HUDMassSelector,
|
||||
shapeTooltip: HUDShapeTooltip,
|
||||
};
|
||||
|
||||
this.zoneWidth = data.zoneWidth || 8;
|
||||
|
@ -334,14 +334,19 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
|
||||
const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutHalf(inputDefinition);
|
||||
|
||||
const ejectorComp = payload.entity.components.ItemEjector;
|
||||
for (let i = 0; i < cutDefinitions.length; ++i) {
|
||||
const definition = cutDefinitions[i];
|
||||
if (!definition.isEntirelyEmpty()) {
|
||||
payload.outItems.push({
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
|
||||
requiredSlot: i,
|
||||
});
|
||||
|
||||
if (definition.isEntirelyEmpty()) {
|
||||
ejectorComp.slots[i].lastItem = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
payload.outItems.push({
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
|
||||
requiredSlot: i,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,14 +360,19 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
|
||||
|
||||
const cutDefinitions = this.root.shapeDefinitionMgr.shapeActionCutQuad(inputDefinition);
|
||||
|
||||
const ejectorComp = payload.entity.components.ItemEjector;
|
||||
for (let i = 0; i < cutDefinitions.length; ++i) {
|
||||
const definition = cutDefinitions[i];
|
||||
if (!definition.isEntirelyEmpty()) {
|
||||
payload.outItems.push({
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
|
||||
requiredSlot: i,
|
||||
});
|
||||
|
||||
if (definition.isEntirelyEmpty()) {
|
||||
ejectorComp.slots[i].lastItem = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
payload.outItems.push({
|
||||
item: this.root.shapeDefinitionMgr.getShapeItemFromDefinition(definition),
|
||||
requiredSlot: i,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1363,6 +1363,8 @@ keybindings:
|
||||
placeMultiple: Stay in placement mode
|
||||
placeInverse: Invert automatic belt orientation
|
||||
|
||||
showShapeTooltip: Show shape output tooltip
|
||||
|
||||
about:
|
||||
title: About this Game
|
||||
body: >-
|
||||
|
Loading…
Reference in New Issue
Block a user