parent
f204189fdb
commit
9a67115ba7
After Width: | Height: | Size: 577 B |
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1dc8775fdf5155097d6e1d60a436f48916af56eec14fb9034e71b32ad3b6f1b0
|
||||
size 358896
|
@ -0,0 +1,18 @@
|
||||
#ingame_HUD_ColorBlindBelowTileHelper {
|
||||
position: absolute;
|
||||
|
||||
@include SuperSmallText;
|
||||
color: #fff;
|
||||
background: $ingameHudBg;
|
||||
@include S(padding, 5px);
|
||||
@include S(top, 20px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
text-transform: uppercase;
|
||||
|
||||
&:not(.visible) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@include DarkThemeInvert;
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
#ingame_HUD_ShapeViewer {
|
||||
.dialogInner {
|
||||
@include S(width, 160px);
|
||||
}
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
|
||||
.seperator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.layer {
|
||||
position: relative;
|
||||
background: #eee;
|
||||
|
||||
@include DarkThemeOverride {
|
||||
background: rgba(0, 10, 20, 0.2);
|
||||
}
|
||||
@include S(width, 150px);
|
||||
@include S(height, 100px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
> canvas {
|
||||
@include S(width, 50px);
|
||||
@include S(height, 50px);
|
||||
}
|
||||
|
||||
.quad {
|
||||
position: absolute;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
$arrowDims: 23px;
|
||||
$spacing: 9px;
|
||||
@include S(padding, 6px);
|
||||
|
||||
.colorLabel {
|
||||
text-transform: uppercase;
|
||||
@include SuperSmallText;
|
||||
@include S(font-size, 9px);
|
||||
}
|
||||
|
||||
.emptyLabel {
|
||||
text-transform: uppercase;
|
||||
@include SuperSmallText;
|
||||
@include S(font-size, 9px);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: " ";
|
||||
background: rgba(0, 10, 20, 0.5);
|
||||
@include S(width, $arrowDims);
|
||||
@include S(height, 1px);
|
||||
position: absolute;
|
||||
transform: rotate(45deg);
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
@include DarkThemeOverride {
|
||||
&::after {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
&.quad-0 {
|
||||
right: 0;
|
||||
top: 0;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-end;
|
||||
|
||||
&::after {
|
||||
@include S(left, $spacing);
|
||||
@include S(bottom, $arrowDims / 2 + $spacing);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
}
|
||||
&.quad-1 {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
|
||||
align-items: flex-end;
|
||||
justify-content: flex-end;
|
||||
|
||||
&::after {
|
||||
@include S(left, $spacing);
|
||||
@include S(top, $arrowDims / 2 + $spacing);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
&.quad-2 {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
align-items: flex-end;
|
||||
justify-content: flex-start;
|
||||
|
||||
&::after {
|
||||
@include S(right, $spacing);
|
||||
@include S(top, $arrowDims / 2 + $spacing);
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
}
|
||||
&.quad-3 {
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
|
||||
&::after {
|
||||
@include S(right, $spacing);
|
||||
@include S(bottom, $arrowDims / 2 + $spacing);
|
||||
transform: rotate(225deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { makeDiv } from "../../../core/utils";
|
||||
import { TrackedState } from "../../../core/tracked_state";
|
||||
import { enumColors } from "../../colors";
|
||||
import { ColorItem } from "../../items/color_item";
|
||||
import { DrawParameters } from "../../../core/draw_parameters";
|
||||
import { THEME } from "../../theme";
|
||||
import { globalConfig } from "../../../core/config";
|
||||
import { T } from "../../../translations";
|
||||
|
||||
export class HUDColorBlindHelper extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.belowTileIndicator = makeDiv(parent, "ingame_HUD_ColorBlindBelowTileHelper", []);
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.trackedColorBelowTile = new TrackedState(this.onColorBelowTileChanged, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the color below the current tile changed
|
||||
* @param {enumColors|null} color
|
||||
*/
|
||||
onColorBelowTileChanged(color) {
|
||||
this.belowTileIndicator.classList.toggle("visible", !!color);
|
||||
if (color) {
|
||||
this.belowTileIndicator.innerText = T.ingame.colors[color];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the color below the current tile
|
||||
* @returns {enumColors}
|
||||
*/
|
||||
computeColorBelowTile() {
|
||||
const mousePosition = this.root.app.mousePosition;
|
||||
if (!mousePosition) {
|
||||
// Not on screen
|
||||
return null;
|
||||
}
|
||||
|
||||
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
||||
const tile = worldPos.toTileSpace();
|
||||
const contents = this.root.map.getTileContent(tile);
|
||||
|
||||
if (contents && !contents.components.Miner) {
|
||||
const beltComp = contents.components.Belt;
|
||||
|
||||
// Check if the belt has a color item
|
||||
if (beltComp) {
|
||||
const firstItem = beltComp.sortedItems[0];
|
||||
if (firstItem && firstItem[1] instanceof ColorItem) {
|
||||
return firstItem[1].color;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we are ejecting an item, if so use that color
|
||||
const ejectorComp = contents.components.ItemEjector;
|
||||
if (ejectorComp) {
|
||||
for (let i = 0; i < ejectorComp.slots.length; ++i) {
|
||||
const slot = ejectorComp.slots[i];
|
||||
if (slot.item && slot.item instanceof ColorItem) {
|
||||
return slot.item.color;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We hovered a lower layer, show the color there
|
||||
const lowerLayer = this.root.map.getLowerLayerContentXY(tile.x, tile.y);
|
||||
if (lowerLayer && lowerLayer instanceof ColorItem) {
|
||||
return lowerLayer.color;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
update() {
|
||||
this.trackedColorBelowTile.set(this.computeColorBelowTile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the currently selected tile
|
||||
* @param {DrawParameters} parameters
|
||||
*/
|
||||
draw(parameters) {
|
||||
const mousePosition = this.root.app.mousePosition;
|
||||
if (!mousePosition) {
|
||||
// Not on screen
|
||||
return null;
|
||||
}
|
||||
|
||||
const below = this.computeColorBelowTile();
|
||||
if (below) {
|
||||
// We have something below our tile
|
||||
const worldPos = this.root.camera.screenToWorld(mousePosition);
|
||||
const tile = worldPos.toTileSpace().toWorldSpace();
|
||||
|
||||
parameters.context.strokeStyle = THEME.map.colorBlindPickerTile;
|
||||
parameters.context.lineWidth = 1;
|
||||
parameters.context.beginPath();
|
||||
parameters.context.rect(tile.x, tile.y, globalConfig.tileSize, globalConfig.tileSize);
|
||||
parameters.context.stroke();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
import { BaseHUDPart } from "../base_hud_part";
|
||||
import { makeDiv, removeAllChildren } from "../../../core/utils";
|
||||
import { T } from "../../../translations";
|
||||
import { defaultBuildingVariant } from "../../meta_building";
|
||||
import { ShapeDefinition } from "../../shape_definition";
|
||||
import { KEYMAPPINGS, KeyActionMapper } from "../../key_action_mapper";
|
||||
import { InputReceiver } from "../../../core/input_receiver";
|
||||
import { DynamicDomAttach } from "../dynamic_dom_attach";
|
||||
|
||||
export class HUDShapeViewer extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.background = makeDiv(parent, "ingame_HUD_ShapeViewer", ["ingameDialog"]);
|
||||
|
||||
// DIALOG Inner / Wrapper
|
||||
this.dialogInner = makeDiv(this.background, null, ["dialogInner"]);
|
||||
this.title = makeDiv(this.dialogInner, null, ["title"], T.ingame.shapeViewer.title);
|
||||
this.closeButton = makeDiv(this.title, null, ["closeButton"]);
|
||||
this.trackClicks(this.closeButton, this.close);
|
||||
this.contentDiv = makeDiv(this.dialogInner, null, ["content"]);
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.root.hud.signals.viewShapeDetailsRequested.add(this.renderForShape, this);
|
||||
|
||||
this.domAttach = new DynamicDomAttach(this.root, this.background, {
|
||||
attachClass: "visible",
|
||||
});
|
||||
|
||||
this.inputReciever = new InputReceiver("shape_viewer");
|
||||
this.keyActionMapper = new KeyActionMapper(this.root, this.inputReciever);
|
||||
|
||||
this.keyActionMapper.getBinding(KEYMAPPINGS.general.back).add(this.close, this);
|
||||
|
||||
this.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the dialog
|
||||
*/
|
||||
close() {
|
||||
this.visible = false;
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureDetached(this.inputReciever);
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the viewer for a given definition
|
||||
* @param {ShapeDefinition} definition
|
||||
*/
|
||||
renderForShape(definition) {
|
||||
this.visible = true;
|
||||
document.body.classList.add("ingameDialogOpen");
|
||||
this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever);
|
||||
|
||||
removeAllChildren(this.contentDiv);
|
||||
|
||||
const layers = definition.layers;
|
||||
for (let i = 0; i < layers.length; ++i) {
|
||||
const layerElem = makeDiv(this.contentDiv, null, ["layer", "layer-" + i]);
|
||||
|
||||
let fakeLayers = [];
|
||||
for (let k = 0; k < i; ++k) {
|
||||
fakeLayers.push([null, null, null, null]);
|
||||
}
|
||||
fakeLayers.push(layers[i]);
|
||||
|
||||
const thisLayerOnly = new ShapeDefinition({ layers: fakeLayers });
|
||||
const thisLayerCanvas = thisLayerOnly.generateAsCanvas(160);
|
||||
layerElem.appendChild(thisLayerCanvas);
|
||||
|
||||
for (let quad = 0; quad < 4; ++quad) {
|
||||
const quadElem = makeDiv(layerElem, null, ["quad", "quad-" + quad]);
|
||||
|
||||
const contents = layers[i][quad];
|
||||
if (contents) {
|
||||
const colorLabelElem = makeDiv(
|
||||
quadElem,
|
||||
null,
|
||||
["colorLabel"],
|
||||
T.ingame.colors[contents.color]
|
||||
);
|
||||
} else {
|
||||
const emptyLabelElem = makeDiv(
|
||||
quadElem,
|
||||
null,
|
||||
["emptyLabel"],
|
||||
T.ingame.shapeViewer.empty
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (i < layers.length - 1) {
|
||||
makeDiv(this.contentDiv, null, ["seperator"], "+");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up everything
|
||||
*/
|
||||
cleanup() {
|
||||
document.body.classList.remove("ingameDialogOpen");
|
||||
}
|
||||
|
||||
update() {
|
||||
this.domAttach.update(this.visible);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue