1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2025-06-13 13:04:03 +00:00

Allow for compasses for custom waypoints

Waypoints that begin with "!" (or another prefix specified by COMPASS_PREFIX)
will display a compass that functions identically to the hub compass.

Because compasses are remembered by position, two markers in the same position
will share a compass, leading to other small issues.

Camera recentering is also now exact, with a slight change to how it operates.
This commit is contained in:
EmeraldBlock 2020-10-26 12:35:03 -05:00
parent ede9bf2338
commit 5a7489e4ad
3 changed files with 89 additions and 29 deletions

View File

@ -99,21 +99,20 @@
background: none !important;
@include S(padding-left, 0);
canvas {
canvas.compass {
@include S(width, 12px);
@include S(height, 12px);
@include S(margin-right, 1px);
pointer-events: none;
}
}
&.shapeIcon {
canvas {
@include S(width, 15px);
@include S(height, 15px);
pointer-events: none;
// Double invert, to make sure it has the right color
@include DarkThemeInvert();
}
canvas.shapeIcon {
@include S(width, 15px);
@include S(height, 15px);
pointer-events: none;
// Double invert, to make sure it has the right color
@include DarkThemeInvert();
}
}
}

View File

@ -958,9 +958,9 @@ export class Camera extends BasicSerializableObject {
if (!this.currentlyMoving && this.desiredCenter !== null) {
const diff = this.center.direction(this.desiredCenter);
const length = diff.length();
const tolerance = 1 / this.zoomLevel;
if (length > tolerance) {
const movement = diff.multiplyScalar(Math.min(1, dt * 0.008));
if (length > 0) {
const tolerance = 32 / globalConfig.tileSize;
const movement = diff.multiplyScalar(Math.min(1, dt * 0.008 * (1 + tolerance / length)));
this.center.x += movement.x;
this.center.y += movement.y;
} else {

View File

@ -32,6 +32,7 @@ import { enumNotificationType } from "./notifications";
const MAX_LABEL_LENGTH = 70;
const SHAPE_TEXT_LENGTH = 2;
const COMPASS_PREFIX = "!";
export class HUDWaypoints extends BaseHUDPart {
/**
@ -79,6 +80,20 @@ export class HUDWaypoints extends BaseHUDPart {
return "Invalid waypoints data";
}
this.waypoints = data.waypoints;
for (let i = 0; i < this.waypoints.length; ++i) {
const waypoint = this.waypoints[i];
if (waypoint.label && waypoint.label.startsWith(COMPASS_PREFIX)) {
const [canvas, context] = makeOffscreenBuffer(48, 48, {
smooth: true,
reusable: false,
label: "waypoints-compass/" + waypoint.center.x + "/" + waypoint.center.y,
});
canvas.classList.add("compass");
this.compassBuffers["" + waypoint.center.x + "/" + waypoint.center.y] = { canvas, context };
}
}
this.rerenderWaypointList();
}
@ -123,15 +138,16 @@ export class HUDWaypoints extends BaseHUDPart {
* This is interpolated over multiple frames so we have some sort of fade effect
*/
this.currentMarkerOpacity = 1;
this.currentCompassOpacity = 0;
this.currentCompassOpacities = { ["0/0"]: 0 };
// Create buffer which is used to indicate the hub direction
const [canvas, context] = makeOffscreenBuffer(48, 48, {
smooth: true,
reusable: false,
label: "waypoints-compass",
label: "waypoints-compass/0/0",
});
this.compassBuffer = { canvas, context };
canvas.classList.add("compass");
this.compassBuffers = { ["0/0"]: { canvas, context } };
/**
* Stores a cache from a shape short key to its canvas representation
@ -206,8 +222,8 @@ export class HUDWaypoints extends BaseHUDPart {
label: part + "-waypoint-" + i,
});
context.drawImage(canvas, 0, 0);
newCanvas.classList.add("shapeIcon");
element.appendChild(newCanvas);
element.classList.add("shapeIcon");
} else {
element.appendChild(document.createTextNode(part));
}
@ -219,10 +235,12 @@ export class HUDWaypoints extends BaseHUDPart {
this.trackClicks(editButton, () => this.requestSaveMarker({ waypoint }));
}
if (!waypoint.label) {
// This must be the hub label
if (!waypoint.label || waypoint.label.startsWith(COMPASS_PREFIX)) {
// This must be a compass label
element.classList.add("hub");
element.insertBefore(this.compassBuffer.canvas, element.childNodes[0]);
const canvas = this.compassBuffers["" + waypoint.center.x + "/" + waypoint.center.y].canvas;
element.insertBefore(canvas, element.childNodes[0]);
}
this.trackClicks(element, () => this.moveToWaypoint(waypoint), {
@ -329,6 +347,20 @@ export class HUDWaypoints extends BaseHUDPart {
*/
addWaypoint(label, position) {
const parts = this.splitLabel(label);
if (label.startsWith(COMPASS_PREFIX)) {
const bufferKey = "" + position.x + "/" + position.y;
if (!this.compassBuffers[bufferKey]) {
const [canvas, context] = makeOffscreenBuffer(48, 48, {
smooth: true,
reusable: false,
label: "waypoints-compass/" + position.x + "/" + position.y,
});
canvas.classList.add("compass");
this.compassBuffers[bufferKey] = { canvas, context };
}
}
this.waypoints.push({
label,
parts,
@ -357,6 +389,19 @@ export class HUDWaypoints extends BaseHUDPart {
waypoint.label = label;
waypoint.parts = this.splitLabel(waypoint.label);
if (label.startsWith(COMPASS_PREFIX)) {
const bufferKey = "" + waypoint.center.x + "/" + waypoint.center.y;
if (!this.compassBuffers[bufferKey]) {
const [canvas, context] = makeOffscreenBuffer(48, 48, {
smooth: true,
reusable: false,
label: "waypoints-compass/" + waypoint.center.x + "/" + waypoint.center.y,
});
canvas.classList.add("compass");
this.compassBuffers[bufferKey] = { canvas, context };
}
}
this.sortWaypoints();
// Show notification about renamed
@ -579,26 +624,37 @@ export class HUDWaypoints extends BaseHUDPart {
/**
* Rerenders the compass
* @param {Waypoint} waypoint
*/
rerenderWaypointsCompass() {
rerenderWaypointsCompass(waypoint) {
const dims = 48;
const indicatorSize = 30;
const cameraPos = this.root.camera.center;
const relativeCameraPos = new Vector(waypoint.center.x, waypoint.center.y).direction(
this.root.camera.center
);
const context = this.compassBuffer.context;
const bufferKey = "" + waypoint.center.x + "/" + waypoint.center.y;
const context = this.compassBuffers[bufferKey].context;
context.clearRect(0, 0, dims, dims);
const distanceToHub = cameraPos.length();
const distanceToHub = relativeCameraPos.length();
const compassVisible = distanceToHub > (10 * globalConfig.tileSize) / this.root.camera.zoomLevel;
const targetCompassAlpha = compassVisible ? 1 : 0;
// Fade the compas in / out
this.currentCompassOpacity = lerp(this.currentCompassOpacity, targetCompassAlpha, 0.08);
if (this.currentCompassOpacities[bufferKey] === undefined) {
this.currentCompassOpacities[bufferKey] = 0;
}
this.currentCompassOpacities[bufferKey] = lerp(
this.currentCompassOpacities[bufferKey],
targetCompassAlpha,
0.08
);
// Render the compass
if (this.currentCompassOpacity > 0.01) {
context.globalAlpha = this.currentCompassOpacity;
const angle = cameraPos.angle() + Math.radians(45) + Math.PI / 2;
if (this.currentCompassOpacities[bufferKey] > 0.01) {
context.globalAlpha = this.currentCompassOpacities[bufferKey];
const angle = relativeCameraPos.angle() + Math.radians(45) + Math.PI / 2;
context.translate(dims / 2, dims / 2);
context.rotate(angle);
this.directionIndicatorSprite.drawCentered(context, 0, 0, indicatorSize);
@ -608,7 +664,7 @@ export class HUDWaypoints extends BaseHUDPart {
}
// Render the regualr icon
const iconOpacity = 1 - this.currentCompassOpacity;
const iconOpacity = 1 - this.currentCompassOpacities[bufferKey];
if (iconOpacity > 0.01) {
context.globalAlpha = iconOpacity;
this.waypointSprite.drawCentered(context, dims / 2, dims / 2, dims * 0.7);
@ -625,7 +681,12 @@ export class HUDWaypoints extends BaseHUDPart {
const desiredOpacity = this.root.camera.getIsMapOverlayActive() ? 1 : 0;
this.currentMarkerOpacity = lerp(this.currentMarkerOpacity, desiredOpacity, 0.08);
this.rerenderWaypointsCompass();
for (let i = 0; i < this.waypoints.length; ++i) {
const waypoint = this.waypoints[i];
if (!waypoint.label || waypoint.label.startsWith(COMPASS_PREFIX)) {
this.rerenderWaypointsCompass(waypoint);
}
}
// Don't render with low opacity
if (this.currentMarkerOpacity < 0.01) {