Skip to content

Commit 75c131b

Browse files
committed
♻️ Add also the fuel measurement to new map editor page
1 parent 4236c9f commit 75c131b

File tree

4 files changed

+169
-231
lines changed

4 files changed

+169
-231
lines changed

frontend/src/components/MapCanvasComponent.vue

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,9 @@ onMounted(() => {
9292
watch(
9393
() => props.drawablePath,
9494
(newValue) => {
95-
if (newValue) {
96-
currentPath.value.points = [];
97-
emits("pathUpdate", currentPath.value);
98-
redraw();
99-
}
95+
currentPath.value.points = [];
96+
emits("pathUpdate", currentPath.value);
97+
redraw();
10098
},
10199
);
102100
watch(() => props.map, redraw);
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<template>
2+
<InfoBoxTemplate title="Measure">
3+
<div class="columns is-align-items-center">
4+
<div class="column">
5+
<button
6+
class="button"
7+
:class="{ 'is-primary': pathDrawEnabled }"
8+
@click="$emit('update:pathDrawEnabled', !pathDrawEnabled)"
9+
title="If active click on the map to draw a path from clicked tile to clicked tile."
10+
>
11+
<div class="icon mr-1">
12+
<FontAwesomeIcon icon="fa-solid fa-square-check" v-if="pathDrawEnabled" />
13+
<FontAwesomeIcon icon="fa-regular fa-square" v-else />
14+
</div>
15+
Draw Move Path
16+
</button>
17+
</div>
18+
<div class="column">
19+
<div class="field has-addons">
20+
<div class="control">
21+
<button
22+
class="button"
23+
:class="{ 'is-loading': routingActive, 'is-primary': routingType == RoutingType.SHORTEST }"
24+
:disabled="!routingActionEnabled"
25+
title="Calculates the shortest path between the selected points. (Ignoring the heights)"
26+
@click="calculatePath(RoutingType.SHORTEST)"
27+
>
28+
<div class="icon mr-1">
29+
<FontAwesomeIcon icon="fa-solid fa-route" />
30+
</div>
31+
Shortest
32+
</button>
33+
</div>
34+
<div class="control">
35+
<button
36+
class="button"
37+
:class="{ 'is-loading': routingActive, 'is-primary': routingType == RoutingType.FUEL_EFFICIENT }"
38+
:disabled="!routingActionEnabled"
39+
title="Calculates the path with the minimal fuel requirement between the selected points."
40+
@click="calculatePath(RoutingType.FUEL_EFFICIENT)"
41+
>
42+
<div class="icon mr-1">
43+
<FontAwesomeIcon icon="fa-solid fa-route" />
44+
</div>
45+
Fuel-efficient
46+
</button>
47+
</div>
48+
</div>
49+
</div>
50+
</div>
51+
<div class="columns">
52+
<div class="column is-flex is-flex-direction-column is-align-items-center is-justify-content-center">
53+
<div class="has-text-centered">Required fuel</div>
54+
<div class="subtitle has-text-white">{{ requiredFuel }}</div>
55+
</div>
56+
<div class="column is-flex is-flex-direction-column is-align-items-center is-justify-content-center">
57+
<div class="has-text-centered">Minimal turns</div>
58+
<div class="subtitle has-text-white">{{ minimalTurns }}</div>
59+
</div>
60+
</div>
61+
</InfoBoxTemplate>
62+
</template>
63+
64+
<script setup lang="ts">
65+
import type { Path, PlaygroundMap } from "@/models/Map";
66+
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
67+
import InfoBoxTemplate from "@/components/templates/InfoBoxTemplate.vue";
68+
import log from "loglevel";
69+
import type { PathFindingWorkerInput } from "@/workers/PathFindingWorker";
70+
71+
enum RoutingType {
72+
SHORTEST = "SHORTEST",
73+
FUEL_EFFICIENT = "FUEL_EFFICIENT",
74+
}
75+
76+
const routingActionEnabled = computed<boolean>(() => props.drawnPath.points.length > 1);
77+
const routingActive = ref<boolean>(false);
78+
const routingType = ref<RoutingType>();
79+
const minimalTurns = computed<number>(() => displayPath.value.points.length);
80+
const requiredFuel = computed<number>(() => determineCostOfPath(displayPath.value));
81+
const displayPath = ref<Path>({ points: [] });
82+
83+
const routingWorker = new Worker(new URL("../workers/PathFindingWorker.ts", import.meta.url), { type: "module" });
84+
85+
const props = defineProps<{
86+
map: PlaygroundMap;
87+
drawnPath: Path;
88+
pathDrawEnabled: boolean;
89+
}>();
90+
91+
const emits = defineEmits<{
92+
(e: "update:pathDrawEnabled", value: boolean): void;
93+
(e: "update:displayPath", value: Path): void;
94+
}>();
95+
96+
watch(
97+
() => displayPath.value,
98+
() => emits("update:displayPath", displayPath.value),
99+
);
100+
101+
onMounted(() => {
102+
routingWorker.onmessage = (message) => {
103+
log.info("Retrieved path from worker");
104+
displayPath.value = JSON.parse(message.data);
105+
routingActive.value = false;
106+
};
107+
});
108+
109+
onUnmounted(() => {
110+
routingWorker.terminate();
111+
});
112+
113+
const calculatePath = (newRoutingType: RoutingType) => {
114+
routingActive.value = true;
115+
routingType.value = newRoutingType;
116+
const ignoreHeights = newRoutingType == RoutingType.SHORTEST;
117+
// Convert data to json, since couldn't get the object to work
118+
routingWorker.postMessage(
119+
JSON.stringify({
120+
mapSize: props.map.size,
121+
heightMap: props.map.mapData,
122+
inputPath: props.drawnPath,
123+
ignoreHeights: ignoreHeights,
124+
} as PathFindingWorkerInput),
125+
);
126+
};
127+
128+
const determineCostOfPath = (path: Path) => {
129+
let costSum = 0;
130+
for (let index = 0; index < path.points.length - 1; index++) {
131+
const first = path.points[index];
132+
const second = path.points[index + 1];
133+
134+
const firstHeight = props.map.mapData.find((it) => it.position.x === first.x && it.position.y === first.y)!.height;
135+
const secondHeight = props.map.mapData.find((it) => it.position.x === second.x && it.position.y === second.y)!.height;
136+
137+
const heightDiff = secondHeight - firstHeight;
138+
if (heightDiff < 0) {
139+
// If the difference is negative aka "down the hill" there is only static cost. (1 is used for static cost)
140+
costSum += 1;
141+
} else {
142+
costSum += 1 + heightDiff;
143+
}
144+
}
145+
return costSum;
146+
};
147+
</script>
148+
149+
<style scoped lang="scss"></style>

frontend/src/components/MapPreviewModal.vue

Lines changed: 0 additions & 172 deletions
This file was deleted.

0 commit comments

Comments
 (0)