From b891e6dffabbd700d337448bdcf816a0cbb4f50e Mon Sep 17 00:00:00 2001 From: Jochen Jacobs Date: Wed, 20 Sep 2023 20:01:02 +0200 Subject: [PATCH 1/2] calculate spawnpoint and place marker --- src/components/MainMap.vue | 20 +++++++++++++ src/util/SpawnTarget.ts | 60 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/util/SpawnTarget.ts diff --git a/src/components/MainMap.vue b/src/components/MainMap.vue index af442d6..23863b8 100644 --- a/src/components/MainMap.vue +++ b/src/components/MainMap.vue @@ -12,6 +12,7 @@ import { useSettingsStore } from '../stores/useSettingsStore'; import { useLoadedDimensionStore } from '../stores/useLoadedDimensionStore' import { CachedBiomeSource } from '../util/CachedBiomeSource'; import MapButton from './MapButton.vue'; +import { SpawnTarget } from '../util/SpawnTarget'; const searchStore = useSearchStore() const settingsStore = useSettingsStore() @@ -34,6 +35,7 @@ const y = ref(320) var map: L.Map var markers: L.LayerGroup +var spawnMarker: L.Marker var marker_map = new Map() var needs_zoom = ref(false) @@ -64,6 +66,9 @@ onMounted(() => { map.addLayer(layer) + spawnMarker = L.marker({lat: 0, lng: 0}, {}) + updateSpawnMarker() + markers = L.layerGroup().addTo(map) map.addEventListener("mousemove", (evt: L.LeafletMouseEvent) => { @@ -237,12 +242,27 @@ function getMarker(structureId: Identifier, chunk: ChunkPos) { return marker } +function updateSpawnMarker(){ + if (settingsStore.dimension.equals(Identifier.create("overworld"))){ + const crs = map.options.crs! + const spawnTarget = SpawnTarget.fromJson(loadedDimensionStore.loaded_dimension.noise_settings_json?.spawn_target) + const spawn = spawnTarget.getSpawnPoint(loadedDimensionStore.sampler) + const pos = new L.Point(spawn[0], - spawn[1]) + spawnMarker.setLatLng(crs.unproject(pos)) + spawnMarker.addTo(map) + } else { + spawnMarker.removeFrom(map) + } + +} + loadedDimensionStore.$subscribe((mutation, state) => { for (const marker of marker_map.values()){ marker.marker?.remove() } marker_map.clear() updateMarkers() + updateSpawnMarker() const y_limits = loadedDimensionStore.loaded_dimension.y_limits if (y_limits){ diff --git a/src/util/SpawnTarget.ts b/src/util/SpawnTarget.ts new file mode 100644 index 0000000..6009368 --- /dev/null +++ b/src/util/SpawnTarget.ts @@ -0,0 +1,60 @@ +import { Climate, Json } from "deepslate"; + + +export class SpawnTarget{ + + constructor( + private paramPoints: Climate.ParamPoint[] + ){ + + } + + public static fromJson(obj: unknown){ + return new SpawnTarget(Json.readArray(obj, Climate.ParamPoint.fromJson) ?? []) + } + + public getSpawnPoint(climateSampler: Climate.Sampler): [number, number] { + const self = this + var result: [number, number] = [0, 0] + var result_fitness = getFitness(0, 0) + + radialSearch(2048, 512, 0, 0) + radialSearch(512, 32, result[0], result[1]) + + return result + + function getFitness(x: number, z: number){ + const distanceFitness = Math.pow((x * x + z * z) / (2500 * 2500),2); + + const climate = climateSampler.sample(x >> 2, 0, z >> 2) + const surfaceClimate = Climate.target(climate.temperature, climate.humidity, climate.continentalness, climate.erosion, 0, climate.weirdness) + const climateFitness = Math.min(...self.paramPoints.map(p => p.fittness(surfaceClimate))) + + return distanceFitness + climateFitness + } + + function radialSearch(maxRadius: number, radiusStep: number, centerX: number, centerZ: number) { + var angle = 0 + var radius = radiusStep + + while(radius <= maxRadius) { + const x = centerX + Math.floor(Math.sin(angle) * radius) + const z = centerZ + Math.floor(Math.cos(angle) * radius) + const fitness = getFitness(x, z) + if (fitness < result_fitness) { + result = [x, z]; + result_fitness = fitness + } + + angle += radiusStep / radius + if (angle > Math.PI * 2) { + angle = 0 + radius += radiusStep + } + } + } + + + } + +} From df848b2addc0e3f9e8115d1be4e9445667d0e989 Mon Sep 17 00:00:00 2001 From: Jochen Jacobs Date: Thu, 21 Sep 2023 00:10:14 +0200 Subject: [PATCH 2/2] spawn marker icon and tooltip --- locales/en.json | 2 ++ public/images/spawn_icon.png | Bin 0 -> 4406 bytes src/components/MainMap.vue | 18 ++++++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 public/images/spawn_icon.png diff --git a/locales/en.json b/locales/en.json index cc41f3e..218900c 100644 --- a/locales/en.json +++ b/locales/en.json @@ -57,6 +57,8 @@ "map.info.teleport_command_copied": "Teleport Command Copied", "map.error.structures_unsupported": "Some selected structures are unsupported! Sorry.", + "map.tooltip.spawn": "Spawnpoint", + "map.yslider.aria-label": "Y Level", "map.yslider.y-label": "Y: {y}", diff --git a/public/images/spawn_icon.png b/public/images/spawn_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6bd431efda4288f1956f2a459ccc5293f615590b GIT binary patch literal 4406 zcmeHLe{2)i9Y5zsW85aq+CWpYDv|Nk^xymRB6CkV2v0pTSFOI*~qlCgAKIo-Pv)H ztn)}!^&dILJNW*#a@rQ5%#Fw%=z%!y}xT1cJG0p zH|+IRA!hghk){H~q+?(+O|$b%`H1fIENu5cTgT{ap{da5cS8Gtti1=?m03(4v?)^_ zQVjcE*l1{%!Ttbj@{Y_}$Dpl$%*KxgS~~M&ztZdTqqLPGtqcqONt)qFj;BeKrg@g; zDF&iVKbne2XZq@u@D0eaO|Gl+d+X}ZxT=KZ2tbf@Z)f*1&pY3EaQOIJU3XVKbP65a zy^p^zSTq_u=-+19x3=}SgP)wekCi=*Pd->UvSsV8lLxkbx4*BXZwq=8X-l>>YTfrt z^pve1O2kgg|Ui-oA?H>;uJA5kn zN`)u%mB)9ZwKc^c@N~tBgAHBV*}p8_bo-sYr?8&dKDwM+;NO17h0nK6435Qq_N(*z zd&(M+kBIM&Q@|3|v}&%h8F@=hu9Chr>}Y+_mSI*T=74I& zRn!)O;y8{VX@aJ4h`PNIgs94KO;%#4&MAbHq~^phIFC-o7mfRT zIr>;4s{+)6NDFa-vXVqJN=)}iX!Y%oBpc8ddL#lJaX>VJgpyQ6P~Q$>TE%nY(pp4aWf^!0g35oL)t%uvW7gd`f^3>ymLtes_Whr>qV0w+-p0We{f z;-*n~V+l=&i9n}<MW?Ra!j%gIDRT*Zb z5Sbp8P9;IA5bNN?5XIm?knA{1G9f%tpa74$rX1jabr3ty)KK~vO#qC}inuIlEdeegO-f+n~H4M5Ud z9S%&^;YUfDCo|#ebUsCr!yW$%tzRCr8sg!Rd*lRMzrz^H+^8ndmU+rNMr7kEp{Q{w zctOl;AtAH_$%qqjWv0YdA=Uz5^~k2{XDhTq*{S~3Q#bdU9dl;9o&0__9=*kG&6Hw8H*XfqK|aOiYaZ?)bI$ULQO9 z#_xw-J^%Av<39=RdH02#$GWcVbv=7z+m-LRzI`}-=^1O=!PuUcHf-LqUQrYPz^3Nq zNxvf)45|(G)vH%WR#>H)B^9BsJsPNda@k^+%VoFQ%N+|UD=WV~zHlB~$rO5gr5ky! z@FD$;eqP+OE`cC--m5ng@=9+x94ykjzWSo8^UBJqiWl9vcOe`Kd)+kw$FEO!*H})F z=7Jx;RWP*Z=EQf}pD;iCX3qy_&pdpHFM9FKzu$Z6(2c$Wj_#F}Wq<50yztZc!`j`4 z56xGruv1G0)zdrj9>dgBNvZ$Ub(McDRLtMp{SR%&#oFb6xQoAexb|bQt=&S$$ literal 0 HcmV?d00001 diff --git a/src/components/MainMap.vue b/src/components/MainMap.vue index 23863b8..80acf8c 100644 --- a/src/components/MainMap.vue +++ b/src/components/MainMap.vue @@ -13,10 +13,12 @@ import { useLoadedDimensionStore } from '../stores/useLoadedDimensionStore' import { CachedBiomeSource } from '../util/CachedBiomeSource'; import MapButton from './MapButton.vue'; import { SpawnTarget } from '../util/SpawnTarget'; +import { useI18n } from 'vue-i18n'; const searchStore = useSearchStore() const settingsStore = useSettingsStore() const loadedDimensionStore = useLoadedDimensionStore() +const i18n = useI18n() let layer: BiomeLayer @@ -66,7 +68,14 @@ onMounted(() => { map.addLayer(layer) - spawnMarker = L.marker({lat: 0, lng: 0}, {}) + spawnMarker = L.marker({lat: 0, lng: 0}, { + icon: L.icon({ + iconUrl: "images/spawn_icon.png", + iconAnchor: [16, 16], + popupAnchor: [0, -10] + }), + }).bindPopup(L.popup()) + updateSpawnMarker() markers = L.layerGroup().addTo(map) @@ -247,8 +256,9 @@ function updateSpawnMarker(){ const crs = map.options.crs! const spawnTarget = SpawnTarget.fromJson(loadedDimensionStore.loaded_dimension.noise_settings_json?.spawn_target) const spawn = spawnTarget.getSpawnPoint(loadedDimensionStore.sampler) - const pos = new L.Point(spawn[0], - spawn[1]) + const pos = new L.Point(spawn[0] + 7, - spawn[1] - 7) spawnMarker.setLatLng(crs.unproject(pos)) + spawnMarker.setPopupContent(`${i18n.t("map.tooltip.spawn")}
${spawn[0] + 7}, ${spawn[1] + 7}`) spawnMarker.addTo(map) } else { spawnMarker.removeFrom(map) @@ -278,6 +288,10 @@ watch(searchStore.structures, () => { updateMarkers() }) +watch(i18n.locale, () => { + updateSpawnMarker() +}) +