From 3cc745e252ee84f69b7f2b1d279eb34558712943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20P=C3=B6schl?= Date: Tue, 30 Jul 2024 22:21:19 +0200 Subject: [PATCH 1/4] :sparkles: Move map editing and map list to separate pages --- .../controller/ConfigRestController.kt | 18 +- .../roborush/controller/GameRestController.kt | 2 +- .../roborush/controller/restmodels/MapDtos.kt | 6 +- .../poeschl/roborush/gamelogic/GameHandler.kt | 13 +- .../roborush/gamelogic/GameHandlerTest.kt | 31 ---- frontend/src/assets/main.scss | 1 + .../src/components/MapCanvasComponent.vue | 41 +++-- frontend/src/components/MapEditModal.vue | 87 ---------- .../src/components/MapEditorAttributesBox.vue | 122 +++++++++++++ frontend/src/components/MapListEntry.vue | 37 ++-- frontend/src/components/NavBar.vue | 8 +- frontend/src/main.ts | 9 +- frontend/src/router/main.ts | 12 ++ frontend/src/stores/ConfigStore.ts | 5 +- frontend/src/views/GameConfigView.vue | 16 -- frontend/src/views/MapConfigView.vue | 33 ++++ frontend/src/views/MapEditorView.vue | 160 ++++++++++++++++++ 17 files changed, 402 insertions(+), 199 deletions(-) delete mode 100644 frontend/src/components/MapEditModal.vue create mode 100644 frontend/src/components/MapEditorAttributesBox.vue create mode 100644 frontend/src/views/MapConfigView.vue create mode 100644 frontend/src/views/MapEditorView.vue diff --git a/backend/src/main/kotlin/xyz/poeschl/roborush/controller/ConfigRestController.kt b/backend/src/main/kotlin/xyz/poeschl/roborush/controller/ConfigRestController.kt index 20292dc9..7203c8c4 100644 --- a/backend/src/main/kotlin/xyz/poeschl/roborush/controller/ConfigRestController.kt +++ b/backend/src/main/kotlin/xyz/poeschl/roborush/controller/ConfigRestController.kt @@ -7,10 +7,7 @@ import org.springframework.http.MediaType import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.* import org.springframework.web.multipart.MultipartFile -import xyz.poeschl.roborush.controller.restmodels.MapActiveDto -import xyz.poeschl.roborush.controller.restmodels.MapAttributeSaveDto -import xyz.poeschl.roborush.controller.restmodels.MapGenerationResult -import xyz.poeschl.roborush.controller.restmodels.TextConfigDto +import xyz.poeschl.roborush.controller.restmodels.* import xyz.poeschl.roborush.exceptions.InvalidConfigKeyException import xyz.poeschl.roborush.exceptions.InvalidHeightMapException import xyz.poeschl.roborush.exceptions.MapNotFound @@ -18,7 +15,6 @@ import xyz.poeschl.roborush.models.settings.ClientSettings import xyz.poeschl.roborush.models.settings.SaveSettingDto import xyz.poeschl.roborush.models.settings.Setting import xyz.poeschl.roborush.models.settings.SettingKey -import xyz.poeschl.roborush.repositories.Map import xyz.poeschl.roborush.security.repository.User import xyz.poeschl.roborush.service.ConfigService import xyz.poeschl.roborush.service.MapService @@ -71,18 +67,18 @@ class ConfigRestController(private val configService: ConfigService, private val @SecurityRequirement(name = "Bearer Authentication") @PreAuthorize("hasRole('${User.ROLE_ADMIN}')") @GetMapping("/map", produces = [MediaType.APPLICATION_JSON_VALUE]) - fun getMaps(): List { - return mapService.getAllMaps() + fun getMaps(): List { + return mapService.getAllMaps().map { PlaygroundMap(it) } } @SecurityRequirement(name = "Bearer Authentication") @PreAuthorize("hasRole('${User.ROLE_ADMIN}')") @PostMapping("/map/{id}/active", consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE]) - fun setMapActive(@PathVariable id: Long, @RequestBody activeDto: MapActiveDto): Map { + fun setMapActive(@PathVariable id: Long, @RequestBody activeDto: MapActiveDto): PlaygroundMap { val map = mapService.getMap(id) if (map != null) { - return mapService.setMapActive(map, activeDto.active) + return PlaygroundMap(mapService.setMapActive(map, activeDto.active)) } else { throw MapNotFound("No matching map found for setting active") } @@ -91,11 +87,11 @@ class ConfigRestController(private val configService: ConfigService, private val @SecurityRequirement(name = "Bearer Authentication") @PreAuthorize("hasRole('${User.ROLE_ADMIN}')") @PostMapping("/map/{id}", consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE]) - fun setMapAttributes(@PathVariable id: Long, @RequestBody attributes: MapAttributeSaveDto): Map { + fun setMapAttributes(@PathVariable id: Long, @RequestBody attributes: MapAttributeSaveDto): PlaygroundMap { val map = mapService.getMap(id) if (map != null) { - return mapService.setMapAttributes(map, attributes) + return PlaygroundMap(mapService.setMapAttributes(map, attributes)) } else { throw MapNotFound("No matching map found for given id.") } diff --git a/backend/src/main/kotlin/xyz/poeschl/roborush/controller/GameRestController.kt b/backend/src/main/kotlin/xyz/poeschl/roborush/controller/GameRestController.kt index eb1b0846..eca063bb 100644 --- a/backend/src/main/kotlin/xyz/poeschl/roborush/controller/GameRestController.kt +++ b/backend/src/main/kotlin/xyz/poeschl/roborush/controller/GameRestController.kt @@ -18,7 +18,7 @@ class GameRestController(private val gameHandler: GameHandler) { @GetMapping("/map", produces = [MediaType.APPLICATION_JSON_VALUE]) fun getMap(): PlaygroundMap { - return gameHandler.getCurrentPlaygroundMap() + return PlaygroundMap(gameHandler.getCurrentMap()) } @Operation( diff --git a/backend/src/main/kotlin/xyz/poeschl/roborush/controller/restmodels/MapDtos.kt b/backend/src/main/kotlin/xyz/poeschl/roborush/controller/restmodels/MapDtos.kt index ef742a9c..0c6c2300 100644 --- a/backend/src/main/kotlin/xyz/poeschl/roborush/controller/restmodels/MapDtos.kt +++ b/backend/src/main/kotlin/xyz/poeschl/roborush/controller/restmodels/MapDtos.kt @@ -25,7 +25,7 @@ data class PlaygroundMap( val maxHeight: Int ) { - constructor(map: Map, minHeight: Int, maxHeight: Int) : this( + constructor(map: Map) : this( map.id!!, map.mapName, map.size, @@ -35,7 +35,7 @@ data class PlaygroundMap( map.solarChargeRate, map.active, map.mapData, - minHeight, - maxHeight + minHeight = map.mapData.minOf { it.height }, + maxHeight = map.mapData.maxOf { it.height } ) } diff --git a/backend/src/main/kotlin/xyz/poeschl/roborush/gamelogic/GameHandler.kt b/backend/src/main/kotlin/xyz/poeschl/roborush/gamelogic/GameHandler.kt index 48bd0fce..84a61e7b 100644 --- a/backend/src/main/kotlin/xyz/poeschl/roborush/gamelogic/GameHandler.kt +++ b/backend/src/main/kotlin/xyz/poeschl/roborush/gamelogic/GameHandler.kt @@ -5,7 +5,6 @@ import org.springframework.cache.annotation.CacheEvict import org.springframework.cache.annotation.Cacheable import xyz.poeschl.roborush.configuration.GameLogic import xyz.poeschl.roborush.controller.WebsocketController -import xyz.poeschl.roborush.controller.restmodels.PlaygroundMap import xyz.poeschl.roborush.exceptions.PositionNotAllowedException import xyz.poeschl.roborush.exceptions.PositionOutOfMapException import xyz.poeschl.roborush.gamelogic.actions.RobotAction @@ -46,16 +45,6 @@ class GameHandler( return mapHandler.getMapWithPositions(getGlobalKnownPositions()) } - @Cacheable("playgroundMap") - fun getCurrentPlaygroundMap(): PlaygroundMap { - val fullMap = mapHandler.getCurrentFullMap() - - val minHeight = fullMap.mapData.minOf { it.height } - val maxHeight = fullMap.mapData.maxOf { it.height } - - return PlaygroundMap(getCurrentMap(), minHeight, maxHeight) - } - fun getTileAtPosition(position: Position): Tile { return mapHandler.getTileAtPosition(position) } @@ -129,7 +118,7 @@ class GameHandler( } } - @CacheEvict(cacheNames = ["knownMap", "playgroundMap"], allEntries = true) + @CacheEvict(cacheNames = ["knownMap"], allEntries = true) fun executeAllRobotActions() { robotHandler.executeRobotActions(this) setGameTurn(currentTurn + 1) diff --git a/backend/src/test/kotlin/xyz/poeschl/roborush/gamelogic/GameHandlerTest.kt b/backend/src/test/kotlin/xyz/poeschl/roborush/gamelogic/GameHandlerTest.kt index ed465439..352384af 100644 --- a/backend/src/test/kotlin/xyz/poeschl/roborush/gamelogic/GameHandlerTest.kt +++ b/backend/src/test/kotlin/xyz/poeschl/roborush/gamelogic/GameHandlerTest.kt @@ -68,37 +68,6 @@ class GameHandlerTest { assertThat(result.mapData).containsAll(tiles) } - @Test - fun getCurrentPlaygroundMap() { - // WHEN - val tiles = listOf(a(`$Tile`().withHeight(10)), a(`$Tile`().withHeight(50)), a(`$Tile`().withHeight(20))) - val positions = tiles.map { it.position }.toSet() - val map = a(`$Map`().withId(2)) - tiles.forEach { map.addTile(it) } - val activeRobot1 = a(`$ActiveRobot`().withKnownPositions(positions)) - val activeRobot2 = a(`$ActiveRobot`().withKnownPositions(positions)) - - every { robotHandler.getAllActiveRobots() } returns setOf(activeRobot1, activeRobot2) - every { mapHandler.getCurrentFullMap() } returns map - every { mapHandler.getMapWithPositions(positions) } returns map - every { configService.getBooleanSetting(SettingKey.TARGET_POSITION_IN_GAMEINFO) } returns a(`$BooleanSetting`().withValue(false)) - - // THEN - val result = gameHandler.getCurrentPlaygroundMap() - - // VERIFY - assertThat(result.id).isEqualTo(map.id) - assertThat(result.mapName).isEqualTo(map.mapName) - assertThat(result.possibleStartPositions).isEqualTo(map.possibleStartPositions) - assertThat(result.targetPosition).isEqualTo(map.targetPosition) - assertThat(result.active).isEqualTo(map.active) - assertThat(result.maxRobotFuel).isEqualTo(map.maxRobotFuel) - assertThat(result.solarChargeRate).isEqualTo(map.solarChargeRate) - assertThat(result.mapData).containsAll(tiles) - assertThat(result.minHeight).isEqualTo(10) - assertThat(result.maxHeight).isEqualTo(50) - } - @Test fun isPositionValidForMove() { // WHEN diff --git a/frontend/src/assets/main.scss b/frontend/src/assets/main.scss index df68e277..b934cb06 100644 --- a/frontend/src/assets/main.scss +++ b/frontend/src/assets/main.scss @@ -41,6 +41,7 @@ @forward "bulma/sass/components/card"; @forward "bulma/sass/components/modal"; @forward "bulma/sass/components/navbar"; +@forward "bulma/sass/components/tabs"; @forward "bulma/sass/elements/button"; @forward "bulma/sass/elements/content"; @forward "bulma/sass/elements/delete"; diff --git a/frontend/src/components/MapCanvasComponent.vue b/frontend/src/components/MapCanvasComponent.vue index 1c3e11b8..9a929ca0 100644 --- a/frontend/src/components/MapCanvasComponent.vue +++ b/frontend/src/components/MapCanvasComponent.vue @@ -24,6 +24,7 @@ const cellSize = 16; const cellBorder = 1; const specialTileBorderWidth = 4; const fullTileSize = cellSize + 2 * cellBorder; +const smallCanvasThresholdInPixel = 160; const mapBorderColor = new Color(0, 0, 0); const mapColor = new Color(10, 60, 1); @@ -74,6 +75,7 @@ const heightMap = computed(() => { const currentPath = ref({ points: [] }); const mapTileMinHeight = ref(0); const mapTileMaxHeight = ref(255); +const smallCanvas = ref(false); const emits = defineEmits<{ (e: "pathUpdate", path: Path): void; @@ -176,6 +178,10 @@ const updateCanvasData = () => { mapTileMinHeight.value = props.map.minHeight; mapTileMaxHeight.value = props.map.maxHeight; + + if (container.value && container.value.offsetWidth < smallCanvasThresholdInPixel) { + smallCanvas.value = true; + } } }; @@ -235,21 +241,31 @@ const drawRobots = () => { }; const drawTile = (drawContext: CanvasRenderingContext2D, color: Color) => { - drawContext.fillStyle = mapBorderColor.toHex(); - drawContext.fillRect(0, 0, fullTileSize, fullTileSize); - drawContext.fillStyle = color.toHex(); - drawContext.fillRect(cellBorder, cellBorder, cellSize, cellSize); + if (smallCanvas.value) { + drawContext.fillStyle = color.toHex(); + drawContext.fillRect(0, 0, fullTileSize, fullTileSize); + } else { + drawContext.fillStyle = mapBorderColor.toHex(); + drawContext.fillRect(0, 0, fullTileSize, fullTileSize); + drawContext.fillStyle = color.toHex(); + drawContext.fillRect(cellBorder, cellBorder, cellSize, cellSize); + } }; const drawTileBorder = (drawContext: CanvasRenderingContext2D, color: Color) => { - drawContext.lineWidth = specialTileBorderWidth; - drawContext.strokeStyle = color.toHex(); - drawContext.strokeRect( - cellBorder + specialTileBorderWidth / 2, - cellBorder + specialTileBorderWidth / 2, - cellSize - specialTileBorderWidth, - cellSize - specialTileBorderWidth, - ); + if (smallCanvas.value) { + drawContext.fillStyle = color.toHex(); + drawContext.fillRect(0, 0, fullTileSize, fullTileSize); + } else { + drawContext.lineWidth = specialTileBorderWidth; + drawContext.strokeStyle = color.toHex(); + drawContext.strokeRect( + cellBorder + specialTileBorderWidth / 2, + cellBorder + specialTileBorderWidth / 2, + cellSize - specialTileBorderWidth, + cellSize - specialTileBorderWidth, + ); + } }; const drawRobot = (drawContext: CanvasRenderingContext2D, color: Color) => { @@ -366,7 +382,6 @@ const pixelOriginOfPosition = (position: Position): PixelPosition => { .map-container { position: relative; - min-width: 200px; width: auto; height: auto; diff --git a/frontend/src/components/MapEditModal.vue b/frontend/src/components/MapEditModal.vue deleted file mode 100644 index d18fabc7..00000000 --- a/frontend/src/components/MapEditModal.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - - - diff --git a/frontend/src/components/MapEditorAttributesBox.vue b/frontend/src/components/MapEditorAttributesBox.vue new file mode 100644 index 00000000..712016bf --- /dev/null +++ b/frontend/src/components/MapEditorAttributesBox.vue @@ -0,0 +1,122 @@ + + + + + diff --git a/frontend/src/components/MapListEntry.vue b/frontend/src/components/MapListEntry.vue index 997e5ed0..6050a27c 100644 --- a/frontend/src/components/MapListEntry.vue +++ b/frontend/src/components/MapListEntry.vue @@ -2,7 +2,7 @@
- +
Name
@@ -41,11 +37,11 @@
- +
- - diff --git a/frontend/src/components/NavBar.vue b/frontend/src/components/NavBar.vue index 973d8c20..86238af1 100644 --- a/frontend/src/components/NavBar.vue +++ b/frontend/src/components/NavBar.vue @@ -40,11 +40,17 @@ API docs + +
+ +
+ Maps +
- Game Configuration + Administration
-
-
Map Editor
-
- During the preparing phase of every game one of the active maps is chosen randomly and the fuel value becomes the robots max fuel -
-
-
- -
-
-
- -
-
-
-
+ + diff --git a/frontend/src/views/MapEditorView.vue b/frontend/src/views/MapEditorView.vue new file mode 100644 index 00000000..f41eb363 --- /dev/null +++ b/frontend/src/views/MapEditorView.vue @@ -0,0 +1,160 @@ + + + + + From 4236c9fb819579e8fa5bd30dff34bcfc599050c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20P=C3=B6schl?= Date: Sat, 3 Aug 2024 14:46:10 +0200 Subject: [PATCH 2/4] :bug: Fix map loading on map editor --- frontend/src/stores/ConfigStore.ts | 4 +- frontend/src/views/MapEditorView.vue | 57 ++++++++++++++++++---------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/frontend/src/stores/ConfigStore.ts b/frontend/src/stores/ConfigStore.ts index e30a989e..85303c9c 100644 --- a/frontend/src/stores/ConfigStore.ts +++ b/frontend/src/stores/ConfigStore.ts @@ -24,8 +24,8 @@ export const useConfigStore = defineStore("configStore", () => { }); }; - const updateMaps = () => { - configService.getAvailableMaps().then((response) => { + const updateMaps = (): Promise => { + return configService.getAvailableMaps().then((response) => { availableMaps.value.maps = response; }); }; diff --git a/frontend/src/views/MapEditorView.vue b/frontend/src/views/MapEditorView.vue index f41eb363..9b975daf 100644 --- a/frontend/src/views/MapEditorView.vue +++ b/frontend/src/views/MapEditorView.vue @@ -1,5 +1,8 @@ @@ -56,7 +59,7 @@ const route = useRoute(); const router = useRouter(); const configStore = useConfigStore(); -enum EditorTabs { +enum EditorTab { ATTRIBUTES = "ATTRIBUTES", LOCATIONS = "LOCATIONS", EXPORT = "EXPORT", @@ -64,7 +67,8 @@ enum EditorTabs { const mapId = ref(); const map = ref(); -const activeTab = ref(EditorTabs.ATTRIBUTES); +const mapLoading = computed(() => map.value == undefined); +const activeTab = ref(EditorTab.ATTRIBUTES); const pathDrawEnabled = ref(false); const drawnPath = ref({ points: [] }); const displayPath = ref({ points: [] }); @@ -81,11 +85,12 @@ onMounted(() => { if (inputId.length > 0) { log.info(`Load map with id ${inputId}`); mapId.value = parseInt(inputId as string); - updateMapFromStore(); - - if (map.value == undefined) { - router.push({ path: "/config/maps" }); - } + updateMapFromStore().then(() => { + // If no map is found after data load + if (map.value == undefined) { + router.push({ path: "/config/maps" }); + } + }); } else { router.push({ path: "/config/maps" }); } @@ -101,8 +106,18 @@ onUnmounted(() => { routingWorker.terminate(); }); -const updateMapFromStore = () => { - map.value = configStore.availableMaps.maps.find((map) => map.id === mapId.value); +const updateMapFromStore = (): Promise => { + if (configStore.availableMaps.maps.length > 0) { + return new Promise((resolve) => { + map.value = configStore.availableMaps.maps.find((map) => map.id === mapId.value); + resolve(); + }); + } else { + // Load map data + return configStore.updateMaps().then(() => { + updateMapFromStore(); + }); + } }; const mapWidth = computed(() => { @@ -115,6 +130,10 @@ const mapWidth = computed(() => { } }); +const switchToTab = (tab: EditorTab) => { + activeTab.value = tab; +}; + const calculatePath = (ignoreHeights: boolean = false) => { if (map.value != undefined) { routingActive.value = true; From 75c131bb79cea0223b439cf27136499ba83fdff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20P=C3=B6schl?= Date: Sun, 4 Aug 2024 10:31:08 +0200 Subject: [PATCH 3/4] :recycle: Add also the fuel measurement to new map editor page --- .../src/components/MapCanvasComponent.vue | 8 +- .../src/components/MapEditorMeasureBox.vue | 149 +++++++++++++++ frontend/src/components/MapPreviewModal.vue | 172 ------------------ frontend/src/views/MapEditorView.vue | 71 ++------ 4 files changed, 169 insertions(+), 231 deletions(-) create mode 100644 frontend/src/components/MapEditorMeasureBox.vue delete mode 100644 frontend/src/components/MapPreviewModal.vue diff --git a/frontend/src/components/MapCanvasComponent.vue b/frontend/src/components/MapCanvasComponent.vue index 9a929ca0..c28863e2 100644 --- a/frontend/src/components/MapCanvasComponent.vue +++ b/frontend/src/components/MapCanvasComponent.vue @@ -92,11 +92,9 @@ onMounted(() => { watch( () => props.drawablePath, (newValue) => { - if (newValue) { - currentPath.value.points = []; - emits("pathUpdate", currentPath.value); - redraw(); - } + currentPath.value.points = []; + emits("pathUpdate", currentPath.value); + redraw(); }, ); watch(() => props.map, redraw); diff --git a/frontend/src/components/MapEditorMeasureBox.vue b/frontend/src/components/MapEditorMeasureBox.vue new file mode 100644 index 00000000..acd6b995 --- /dev/null +++ b/frontend/src/components/MapEditorMeasureBox.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/frontend/src/components/MapPreviewModal.vue b/frontend/src/components/MapPreviewModal.vue deleted file mode 100644 index 5ef3e263..00000000 --- a/frontend/src/components/MapPreviewModal.vue +++ /dev/null @@ -1,172 +0,0 @@ - - - - - diff --git a/frontend/src/views/MapEditorView.vue b/frontend/src/views/MapEditorView.vue index 9b975daf..c67b71e4 100644 --- a/frontend/src/views/MapEditorView.vue +++ b/frontend/src/views/MapEditorView.vue @@ -39,8 +39,17 @@ -
LOCATIONS
-
EXPORT
+
+
LOCATIONS
+ +
+
EXPORT
@@ -52,8 +61,8 @@ import MapCanvasComponent from "@/components/MapCanvasComponent.vue"; import type { Path, PlaygroundMap } from "@/models/Map"; import log from "loglevel"; import { useConfigStore } from "@/stores/ConfigStore"; -import type { PathFindingWorkerInput } from "@/workers/PathFindingWorker"; import MapEditorAttributesBox from "@/components/MapEditorAttributesBox.vue"; +import MapEditorMeasureBox from "@/components/MapEditorMeasureBox.vue"; const route = useRoute(); const router = useRouter(); @@ -72,12 +81,6 @@ const activeTab = ref(EditorTab.ATTRIBUTES); const pathDrawEnabled = ref(false); const drawnPath = ref({ points: [] }); const displayPath = ref({ points: [] }); -const routingActionEnabled = computed(() => drawnPath.value.points.length > 1); -const routingActive = ref(false); -const minimalTurns = computed(() => displayPath.value.points.length); -const requiredFuel = computed(() => determineCostOfPath(displayPath.value)); - -const routingWorker = new Worker(new URL("../workers/PathFindingWorker.ts", import.meta.url), { type: "module" }); onMounted(() => { const inputId = route.params.mapId; @@ -94,16 +97,6 @@ onMounted(() => { } else { router.push({ path: "/config/maps" }); } - - routingWorker.onmessage = (message) => { - log.info("Retrieved path from worker"); - displayPath.value = JSON.parse(message.data); - routingActive.value = false; - }; -}); - -onUnmounted(() => { - routingWorker.terminate(); }); const updateMapFromStore = (): Promise => { @@ -132,43 +125,13 @@ const mapWidth = computed(() => { const switchToTab = (tab: EditorTab) => { activeTab.value = tab; + resetMapMeasureDrawing(); }; -const calculatePath = (ignoreHeights: boolean = false) => { - if (map.value != undefined) { - routingActive.value = true; - // Convert data to json, since couldn't get the object ot work - routingWorker.postMessage( - JSON.stringify({ - mapSize: map.value.size, - heightMap: map.value.mapData, - inputPath: drawnPath.value, - ignoreHeights: ignoreHeights, - } as PathFindingWorkerInput), - ); - } -}; - -const determineCostOfPath = (path: Path) => { - let costSum = 0; - if (map.value != undefined) { - for (let index = 0; index < path.points.length - 1; index++) { - const first = path.points[index]; - const second = path.points[index + 1]; - - const firstHeight = map.value.mapData.find((it) => it.position.x === first.x && it.position.y === first.y)!.height; - const secondHeight = map.value.mapData.find((it) => it.position.x === second.x && it.position.y === second.y)!.height; - - const heightDiff = secondHeight - firstHeight; - if (heightDiff < 0) { - // If the difference is negative aka "down the hill" there is only static cost. (1 is used for static cost) - costSum += 1; - } else { - costSum += 1 + heightDiff; - } - } - } - return costSum; +const resetMapMeasureDrawing = () => { + displayPath.value.points = []; + drawnPath.value.points = []; + pathDrawEnabled.value = false; }; From 0ebccb8593b2519b686d531cd4b67159a9a9b5de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20P=C3=B6schl?= Date: Sun, 4 Aug 2024 10:38:23 +0200 Subject: [PATCH 4/4] :lipstick: Better UI for measurements --- frontend/src/components/MapEditorMeasureBox.vue | 8 +++++--- frontend/src/views/MapEditorView.vue | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/MapEditorMeasureBox.vue b/frontend/src/components/MapEditorMeasureBox.vue index acd6b995..ff804add 100644 --- a/frontend/src/components/MapEditorMeasureBox.vue +++ b/frontend/src/components/MapEditorMeasureBox.vue @@ -1,9 +1,9 @@