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

View File

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

View File

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