From 88d85108d50ba25fe38f1b6a25a8ad9c4ce3cf3e Mon Sep 17 00:00:00 2001 From: Aidar Shaikhiev Date: Sun, 28 Jul 2024 20:59:47 +0000 Subject: [PATCH] Fix minimap bug --- CHANGELOG.md | 1 + voxygen/src/hud/minimap.rs | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52e415e0d9..42763ebded 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Limit the minimum vertical scaling value in the world generation UI to 0.1 to prevent an overflow - Wood log and worker/linen clothing pricing. - Charm recipes can now be found in the Potions tab of the crafting menu +- Black minimap when some terrain blocks are deleted. ## [0.16.0] - 2024-03-30 diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index ff5fe45531..29480300c9 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -21,12 +21,13 @@ use common::{ vol::{ReadVol, RectVolSize}, }; use common_net::msg::world_msg::SiteKind; +use common_state::TerrainChanges; use conrod_core::{ color, position, widget::{self, Button, Image, Rectangle, Text}, widget_ids, Color, Colorable, Positionable, Sizeable, Widget, WidgetCommon, }; -use hashbrown::HashMap; +use hashbrown::{HashMap, HashSet}; use image::{DynamicImage, RgbaImage}; use specs::WorldExt; use std::sync::Arc; @@ -45,6 +46,7 @@ struct MinimapColumn { pub struct VoxelMinimap { chunk_minimaps: HashMap, MinimapColumn>, + chunks_to_replace: HashSet>, composited: RgbaImage, image_id: img_ids::Rotations, last_pos: Vec3, @@ -63,6 +65,7 @@ impl VoxelMinimap { ); Self { chunk_minimaps: HashMap::new(), + chunks_to_replace: HashSet::new(), image_id: ui.add_graphic_with_rotations(Graphic::Image( Arc::new(DynamicImage::ImageRgba8(composited.clone())), Some(Rgba::from([0.0, 0.0, 0.0, 0.0])), @@ -162,7 +165,8 @@ impl VoxelMinimap { let delta: Vec2 = (key - cpos).map(i32::abs).as_(); if delta.x < VOXEL_MINIMAP_SIDELENGTH / TerrainChunkSize::RECT_SIZE.x && delta.y < VOXEL_MINIMAP_SIDELENGTH / TerrainChunkSize::RECT_SIZE.y - && !self.chunk_minimaps.contains_key(&key) + && (!self.chunk_minimaps.contains_key(&key) + || self.chunks_to_replace.contains(&key)) { if let Some((_, column)) = self.keyed_jobs.spawn(Some(pool), key, || { let arc_chunk = Arc::clone(chunk); @@ -198,6 +202,7 @@ impl VoxelMinimap { } } }) { + self.chunks_to_replace.remove(&key); self.chunk_minimaps.insert(key, column); new_chunks = true; } @@ -206,13 +211,30 @@ impl VoxelMinimap { new_chunks } + fn add_chunks_to_replace(&mut self, terrain: &TerrainGrid, changes: &TerrainChanges) { + changes + .modified_blocks + .iter() + .filter(|(key, old_block)| { + terrain.get(**key).map_or(false, |new_block| { + new_block.is_terrain() != old_block.is_terrain() + }) + }) + .map(|(key, _)| terrain.pos_key(*key)) + .for_each(|key| { + self.chunks_to_replace.insert(key); + }); + } + fn remove_chunks_far(&mut self, terrain: &TerrainGrid, cpos: Vec2) { - self.chunk_minimaps.retain(|key, _| { + let key_predicate = |key: &Vec2| { let delta: Vec2 = (key - cpos).map(i32::abs).as_(); delta.x < 1 + VOXEL_MINIMAP_SIDELENGTH / TerrainChunkSize::RECT_SIZE.x && delta.y < 1 + VOXEL_MINIMAP_SIDELENGTH / TerrainChunkSize::RECT_SIZE.y && terrain.get_key(*key).is_some() - }); + }; + self.chunks_to_replace.retain(&key_predicate); + self.chunk_minimaps.retain(|key, _| key_predicate(key)); } pub fn maintain(&mut self, client: &Client, ui: &mut Ui) { @@ -229,6 +251,8 @@ impl VoxelMinimap { let pool = client.state().ecs().read_resource::(); let terrain = client.state().terrain(); + let changed_blocks = client.state().terrain_changes(); + self.add_chunks_to_replace(&terrain, &changed_blocks); let new_chunks = self.add_chunks_near(&pool, &terrain, cpos); self.remove_chunks_far(&terrain, cpos);