1+ use std:: marker:: PhantomData ;
2+
13use crate :: tilemap:: { TileData , TileStorage , Tilemap } ;
2- use bevy_ecs:: { entity:: Entity , error :: HandleError , hierarchy:: ChildOf , system:: { Command , Commands } , world:: World } ;
3- use bevy_math:: { IVec2 , UVec2 , Vec2 , Vec3 } ;
4+ use bevy_ecs:: { entity:: Entity , hierarchy:: ChildOf , system:: { Command , Commands } , world:: World } ;
5+ use bevy_math:: { IVec2 , Vec2 , Vec3 } ;
46use bevy_transform:: components:: Transform ;
57
68pub trait CommandsTilemapExt {
79 fn set_tile < T : TileData > (
810 & mut self ,
9- tilemap : Entity ,
11+ tilemap_id : Entity ,
1012 tile_position : IVec2 ,
1113 maybe_tile : Option < T > ,
1214 ) ;
1315
14- fn remove_tile ( & mut self , tilemap : Entity , tile_position : IVec2 ) ;
16+ fn remove_tile < T : TileData > ( & mut self , tilemap_id : Entity , tile_position : IVec2 ) ;
1517}
1618
1719impl CommandsTilemapExt for Commands < ' _ , ' _ > {
@@ -24,8 +26,8 @@ impl CommandsTilemapExt for Commands<'_, '_> {
2426 self . queue ( move |world : & mut World | { SetTile { tilemap_id, tile_position, maybe_tile } . apply ( world) ; } ) ;
2527 }
2628
27- fn remove_tile ( & mut self , tilemap : Entity , tile_position : IVec2 ) {
28- todo ! ( )
29+ fn remove_tile < T : TileData > ( & mut self , tilemap_id : Entity , tile_position : IVec2 ) {
30+ self . queue ( move | world : & mut World | { RemoveTile :: < T > { tilemap_id , tile_position , _t : PhantomData :: default ( ) } . apply ( world ) ; } ) ;
2931 }
3032}
3133
@@ -59,7 +61,7 @@ impl<T: TileData> Command<SetTileResult<T>> for SetTile<T> {
5961 } ;
6062
6163 let chunk_position = tilemap. tile_chunk_position ( self . tile_position ) ;
62- let tile_position = tilemap. tile_chunk_local_position ( self . tile_position ) ;
64+ let tile_relative_position = tilemap. tile_relative_position ( self . tile_position ) ;
6365
6466 if let Some ( tile_storage_id) = tilemap. chunks . get ( & chunk_position) . cloned ( ) {
6567 let replaced_tile = tilemap_entity. world_scope ( move |w| {
@@ -77,15 +79,15 @@ impl<T: TileData> Command<SetTileResult<T>> for SetTile<T> {
7779 return None ;
7880 } ;
7981
80- tile_storage. set ( tile_position , self . maybe_tile )
82+ tile_storage. set ( tile_relative_position , self . maybe_tile )
8183 } ) ;
8284 SetTileResult { chunk_id : Some ( tile_storage_id) , replaced_tile }
8385 } else {
8486 let chunk_size = tilemap. chunk_size ;
8587 let tile_size = tilemap. tile_display_size ;
8688 let tile_storage_id = tilemap_entity. world_scope ( move |w| {
8789 let mut tile_storage = TileStorage :: < T > :: new ( chunk_size) ;
88- tile_storage. set ( tile_position , self . maybe_tile ) ;
90+ tile_storage. set ( tile_relative_position , self . maybe_tile ) ;
8991 let translation = Vec2 :: new ( chunk_size. x as f32 , chunk_size. y as f32 ) * Vec2 :: new ( tile_size. x as f32 , tile_size. y as f32 ) * Vec2 :: new ( chunk_position. x as f32 , chunk_position. y as f32 ) ;
9092 let translation = Vec3 :: new ( translation. x , translation. y , 0.0 ) ;
9193 let transform = Transform :: from_translation ( translation) ;
@@ -99,4 +101,50 @@ impl<T: TileData> Command<SetTileResult<T>> for SetTile<T> {
99101 SetTileResult { chunk_id : Some ( tile_storage_id) , replaced_tile : None }
100102 }
101103 }
104+ }
105+
106+ pub struct RemoveTile < T : TileData > {
107+ pub tilemap_id : Entity ,
108+ pub tile_position : IVec2 ,
109+ pub _t : PhantomData < T >
110+ }
111+
112+ impl < T : TileData > Command < Option < T > > for RemoveTile < T > {
113+ fn apply ( self , world : & mut World ) -> Option < T > {
114+ let Ok ( mut tilemap_entity) = world. get_entity_mut ( self . tilemap_id ) else {
115+ tracing:: warn!( "Could not find Tilemap Entity {:?}" , self . tilemap_id) ;
116+ return Default :: default ( ) ;
117+ } ;
118+
119+ let Some ( tilemap) = tilemap_entity. get :: < Tilemap > ( ) else {
120+ tracing:: warn!( "Could not find Tilemap on Entity {:?}" , self . tilemap_id) ;
121+ return Default :: default ( ) ;
122+ } ;
123+
124+ let chunk_position = tilemap. tile_chunk_position ( self . tile_position ) ;
125+ let tile_relative_position = tilemap. tile_relative_position ( self . tile_position ) ;
126+
127+ if let Some ( tile_storage_id) = tilemap. chunks . get ( & chunk_position) . cloned ( ) {
128+ tilemap_entity. world_scope ( move |w| {
129+ let Ok ( mut tilestorage_entity) = w. get_entity_mut ( tile_storage_id) else {
130+ tracing:: warn!( "Could not find TileStorage Entity {:?}" , tile_storage_id) ;
131+ return None ;
132+ } ;
133+
134+ let Some ( mut tile_storage) = tilestorage_entity. get_mut :: < TileStorage < T > > ( )
135+ else {
136+ tracing:: warn!(
137+ "Could not find TileStorage on Entity {:?}" ,
138+ tile_storage_id
139+ ) ;
140+ return None ;
141+ } ;
142+
143+ tile_storage. remove ( tile_relative_position)
144+ } )
145+ }
146+ else {
147+ None
148+ }
149+ }
102150}
0 commit comments