From 757c282e7c6b46ab27da57c921b86e57eabe6110 Mon Sep 17 00:00:00 2001 From: Scott McBee Date: Sun, 17 Sep 2023 15:37:27 -0400 Subject: [PATCH 1/3] Add invis tile option --- src/level.rs | 38 +++++++++++---------- src/resources.rs | 13 ++++++++ src/tile_makers.rs | 83 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 112 insertions(+), 22 deletions(-) diff --git a/src/level.rs b/src/level.rs index 54cfe6db..491e6a0c 100644 --- a/src/level.rs +++ b/src/level.rs @@ -481,6 +481,7 @@ pub fn spawn_level( layer_instance.c_wid, layer_instance.c_hei, layer_instance.grid_size, + ldtk_settings ), layer_instance.opacity, ), @@ -549,24 +550,25 @@ pub fn spawn_level( layer_instance.c_hei as u32, ).expect("int_grid_csv indices should be within the bounds of 0..(layer_width * layer_height)"); - let tile_entity = storage.get(&grid_coords.into()).unwrap(); - - let mut entity_commands = commands.entity(tile_entity); - - let default_ldtk_int_cell: Box = - Box::new(PhantomLdtkIntCell::::new()); - - ldtk_map_get_or_default( - layer_instance.identifier.clone(), - *value, - &default_ldtk_int_cell, - ldtk_int_cell_map, - ) - .evaluate( - &mut entity_commands, - IntGridCell { value: *value }, - layer_instance, - ); + if let Some(tile_entity) = storage.get(&grid_coords.into()) { + let mut entity_commands = commands.entity(tile_entity); + + let default_ldtk_int_cell: Box< + dyn PhantomLdtkIntCellTrait, + > = Box::new(PhantomLdtkIntCell::::new()); + + ldtk_map_get_or_default( + layer_instance.identifier.clone(), + *value, + &default_ldtk_int_cell, + ldtk_int_cell_map, + ) + .evaluate( + &mut entity_commands, + IntGridCell { value: *value }, + layer_instance, + ); + } } } diff --git a/src/resources.rs b/src/resources.rs index 545183e2..9a0ed19e 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -101,6 +101,18 @@ pub enum LevelBackground { Nonexistent, } + +/// Option in [LdtkSettings] that determines if AutoTile layers should have invisible tiles. +/// These might appear if an AutoTile rule can't match to any tile. +#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)] +pub enum AutoTileInvisibleTiles { + /// There will be no tile entity if AutoTile rules can't match a tile. + #[default] + Nonexistent, + /// If AutoTile rules can't match to a tile, an invisible one will be inserted instead. + Active, +} + /// Settings resource for the plugin. /// Check out the documentation for each field type to learn more. #[derive(Copy, Clone, Eq, PartialEq, Debug, Default, Resource)] @@ -109,6 +121,7 @@ pub struct LdtkSettings { pub set_clear_color: SetClearColor, pub int_grid_rendering: IntGridRendering, pub level_background: LevelBackground, + pub auto_tile_invisible_tiles: AutoTileInvisibleTiles, } /// Events fired by the plugin related to level spawning/despawning. diff --git a/src/tile_makers.rs b/src/tile_makers.rs index 6f7ac5d4..f9667044 100644 --- a/src/tile_makers.rs +++ b/src/tile_makers.rs @@ -12,6 +12,7 @@ use crate::{ ldtk::{IntGridValueDefinition, TileInstance}, level::tile_to_grid_coords, utils::*, + AutoTileInvisibleTiles, LdtkSettings, }; use bevy::prelude::*; use bevy_ecs_tilemap::tiles::{ @@ -164,12 +165,19 @@ pub(crate) fn tile_pos_to_int_grid_with_grid_tiles_tile_maker( layer_width_in_tiles: i32, layer_height_in_tiles: i32, layer_grid_size: i32, + ldtk_settings: &LdtkSettings, ) -> impl FnMut(TilePos) -> Option { // Creating the tile makers outside of the returned tile maker so we only do it once. let mut auto_tile_maker = tile_pos_to_tile_maker(grid_tiles, layer_height_in_tiles, layer_grid_size); + + let invis_tile_type = match ldtk_settings.auto_tile_invisible_tiles { + AutoTileInvisibleTiles::Active => tile_pos_to_invisible_tile, + AutoTileInvisibleTiles::Nonexistent => |_| None, + }; + let mut invisible_tile_maker = tile_pos_to_tile_if_int_grid_nonzero_maker( - tile_pos_to_invisible_tile, + invis_tile_type, int_grid_csv, layer_width_in_tiles, layer_height_in_tiles, @@ -348,7 +356,7 @@ mod tests { } #[test] - fn test_tile_pos_to_int_grid_with_grid_tiles_tile_maker() { + fn test_tile_pos_to_int_grid_with_grid_tiles_tile_maker_no_invis() { // Test is designed to have all permutations of tile/intgrid existence: // 1. tile + nonzero intgrid // 2. tile + zero intgrid @@ -372,8 +380,75 @@ mod tests { let int_grid_csv = vec![1, 0, 2, 0]; - let mut tile_maker = - tile_pos_to_int_grid_with_grid_tiles_tile_maker(&grid_tiles, &int_grid_csv, 2, 2, 32); + let settings = LdtkSettings { + auto_tile_invisible_tiles: AutoTileInvisibleTiles::Nonexistent, + ..Default::default() + }; + + let mut tile_maker = tile_pos_to_int_grid_with_grid_tiles_tile_maker( + &grid_tiles, + &int_grid_csv, + 2, + 2, + 32, + &settings, + ); + + assert!(tile_maker(TilePos { x: 0, y: 0 }).is_none()); + + assert!(tile_maker(TilePos { x: 1, y: 0 }).is_none()); + + assert_eq!( + tile_maker(TilePos { x: 0, y: 1 }).unwrap().texture_index.0, + 1 + ); + assert!(tile_maker(TilePos { x: 0, y: 1 }).unwrap().visible.0); + + assert_eq!( + tile_maker(TilePos { x: 1, y: 1 }).unwrap().texture_index.0, + 2 + ); + assert!(tile_maker(TilePos { x: 1, y: 1 }).unwrap().visible.0); + } + + #[test] + fn test_tile_pos_to_int_grid_with_grid_tiles_tile_maker_with_invis() { + // Test is designed to have all permutations of tile/intgrid existence: + // 1. tile + nonzero intgrid + // 2. tile + zero intgrid + // 3. no tile + nonzero intgrid + // 4. no tile + zero intgrid + + let grid_tiles = vec![ + TileInstance { + px: IVec2::new(0, 0), + src: IVec2::new(0, 0), + t: 1, + ..Default::default() + }, + TileInstance { + px: IVec2::new(32, 0), + src: IVec2::new(32, 0), + t: 2, + ..Default::default() + }, + ]; + + let int_grid_csv = vec![1, 0, 2, 0]; + + let settings = LdtkSettings { + auto_tile_invisible_tiles: AutoTileInvisibleTiles::Active, + ..Default::default() + }; + + let mut tile_maker = tile_pos_to_int_grid_with_grid_tiles_tile_maker( + &grid_tiles, + &int_grid_csv, + 2, + 2, + 32, + &settings, + ); assert_eq!( tile_maker(TilePos { x: 0, y: 0 }).unwrap().texture_index.0, From 8ad1562437305a564f3d366342ce8b015bf6762c Mon Sep 17 00:00:00 2001 From: Scott McBee Date: Sun, 17 Sep 2023 17:18:52 -0400 Subject: [PATCH 2/3] cleanup --- src/resources/mod.rs | 12 ++++++------ src/tile_makers.rs | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 4a2c14e0..5944f0f3 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -68,14 +68,14 @@ pub enum LevelBackground { } -/// Option in [LdtkSettings] that determines if AutoTile layers should have invisible tiles. -/// These might appear if an AutoTile rule can't match to any tile. +/// Option in [LdtkSettings] that determines if Auto-layer layers should have invisible tiles. +/// These might appear if an Auto-layer rule can't match to any tile. #[derive(Copy, Clone, Eq, PartialEq, Debug, Default)] -pub enum AutoTileInvisibleTiles { - /// There will be no tile entity if AutoTile rules can't match a tile. +pub enum AutoLayerInvisibleTiles { + /// There will be no tile entity if Auto-layer rules can't match a tile. #[default] Nonexistent, - /// If AutoTile rules can't match to a tile, an invisible one will be inserted instead. + /// If Auto-layer rules can't match to a tile, an invisible one will be inserted instead. Active, } @@ -87,5 +87,5 @@ pub struct LdtkSettings { pub set_clear_color: SetClearColor, pub int_grid_rendering: IntGridRendering, pub level_background: LevelBackground, - pub auto_tile_invisible_tiles: AutoTileInvisibleTiles, + pub auto_layer_invisible_tiles: AutoLayerInvisibleTiles, } diff --git a/src/tile_makers.rs b/src/tile_makers.rs index f9667044..5a79036f 100644 --- a/src/tile_makers.rs +++ b/src/tile_makers.rs @@ -12,7 +12,7 @@ use crate::{ ldtk::{IntGridValueDefinition, TileInstance}, level::tile_to_grid_coords, utils::*, - AutoTileInvisibleTiles, LdtkSettings, + AutoLayerInvisibleTiles, LdtkSettings, }; use bevy::prelude::*; use bevy_ecs_tilemap::tiles::{ @@ -155,7 +155,7 @@ pub(crate) fn tile_pos_to_tile_if_int_grid_nonzero_maker( /// Creates a tile maker that returns one of the following: /// 1. Returns a tile that matches the tileset visual of the ldtk layer, if it exists -/// 2. Returns an invisible tile, if the corresponding intgrid position is nonzero, +/// 2. Returns an invisible tile, if the corresponding intgrid position is nonzero and "auto_layer_invisible_tiles" in [LdtkSettings] is set to [AutoLayerInvisibleTiles::Active], /// 3. Returns none /// /// Used for spawning IntGrid layers with AutoTile functionality. @@ -171,9 +171,9 @@ pub(crate) fn tile_pos_to_int_grid_with_grid_tiles_tile_maker( let mut auto_tile_maker = tile_pos_to_tile_maker(grid_tiles, layer_height_in_tiles, layer_grid_size); - let invis_tile_type = match ldtk_settings.auto_tile_invisible_tiles { - AutoTileInvisibleTiles::Active => tile_pos_to_invisible_tile, - AutoTileInvisibleTiles::Nonexistent => |_| None, + let invis_tile_type = match ldtk_settings.auto_layer_invisible_tiles { + AutoLayerInvisibleTiles::Active => tile_pos_to_invisible_tile, + AutoLayerInvisibleTiles::Nonexistent => |_| None, }; let mut invisible_tile_maker = tile_pos_to_tile_if_int_grid_nonzero_maker( @@ -381,7 +381,7 @@ mod tests { let int_grid_csv = vec![1, 0, 2, 0]; let settings = LdtkSettings { - auto_tile_invisible_tiles: AutoTileInvisibleTiles::Nonexistent, + auto_layer_invisible_tiles: AutoLayerInvisibleTiles::Nonexistent, ..Default::default() }; @@ -437,7 +437,7 @@ mod tests { let int_grid_csv = vec![1, 0, 2, 0]; let settings = LdtkSettings { - auto_tile_invisible_tiles: AutoTileInvisibleTiles::Active, + auto_layer_invisible_tiles: AutoLayerInvisibleTiles::Active, ..Default::default() }; From 2692bbae18054cef82174e33854f03ef0f33bfb3 Mon Sep 17 00:00:00 2001 From: Scott McBee Date: Mon, 18 Sep 2023 20:33:26 -0400 Subject: [PATCH 3/3] don't add invis tiles on sublayers > 0 --- src/level.rs | 2 +- src/resources/mod.rs | 13 --------- src/tile_makers.rs | 68 +++++++++++--------------------------------- 3 files changed, 18 insertions(+), 65 deletions(-) diff --git a/src/level.rs b/src/level.rs index 266b7243..9355a7cd 100644 --- a/src/level.rs +++ b/src/level.rs @@ -481,7 +481,7 @@ pub fn spawn_level( layer_instance.c_wid, layer_instance.c_hei, layer_instance.grid_size, - ldtk_settings + i, ), layer_instance.opacity, ), diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 5944f0f3..db7e701c 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -67,18 +67,6 @@ pub enum LevelBackground { Nonexistent, } - -/// Option in [LdtkSettings] that determines if Auto-layer layers should have invisible tiles. -/// These might appear if an Auto-layer rule can't match to any tile. -#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)] -pub enum AutoLayerInvisibleTiles { - /// There will be no tile entity if Auto-layer rules can't match a tile. - #[default] - Nonexistent, - /// If Auto-layer rules can't match to a tile, an invisible one will be inserted instead. - Active, -} - /// Settings resource for the plugin. /// Check out the documentation for each field type to learn more. #[derive(Copy, Clone, Eq, PartialEq, Debug, Default, Resource)] @@ -87,5 +75,4 @@ pub struct LdtkSettings { pub set_clear_color: SetClearColor, pub int_grid_rendering: IntGridRendering, pub level_background: LevelBackground, - pub auto_layer_invisible_tiles: AutoLayerInvisibleTiles, } diff --git a/src/tile_makers.rs b/src/tile_makers.rs index 5a79036f..65a64164 100644 --- a/src/tile_makers.rs +++ b/src/tile_makers.rs @@ -12,7 +12,6 @@ use crate::{ ldtk::{IntGridValueDefinition, TileInstance}, level::tile_to_grid_coords, utils::*, - AutoLayerInvisibleTiles, LdtkSettings, }; use bevy::prelude::*; use bevy_ecs_tilemap::tiles::{ @@ -155,7 +154,7 @@ pub(crate) fn tile_pos_to_tile_if_int_grid_nonzero_maker( /// Creates a tile maker that returns one of the following: /// 1. Returns a tile that matches the tileset visual of the ldtk layer, if it exists -/// 2. Returns an invisible tile, if the corresponding intgrid position is nonzero and "auto_layer_invisible_tiles" in [LdtkSettings] is set to [AutoLayerInvisibleTiles::Active], +/// 2. Returns an invisible tile, if the corresponding intgrid position is nonzero and the sublayer index is 0, /// 3. Returns none /// /// Used for spawning IntGrid layers with AutoTile functionality. @@ -165,15 +164,16 @@ pub(crate) fn tile_pos_to_int_grid_with_grid_tiles_tile_maker( layer_width_in_tiles: i32, layer_height_in_tiles: i32, layer_grid_size: i32, - ldtk_settings: &LdtkSettings, + sublayer_index: usize, ) -> impl FnMut(TilePos) -> Option { // Creating the tile makers outside of the returned tile maker so we only do it once. let mut auto_tile_maker = tile_pos_to_tile_maker(grid_tiles, layer_height_in_tiles, layer_grid_size); - let invis_tile_type = match ldtk_settings.auto_layer_invisible_tiles { - AutoLayerInvisibleTiles::Active => tile_pos_to_invisible_tile, - AutoLayerInvisibleTiles::Nonexistent => |_| None, + let invis_tile_type = if sublayer_index == 0 { + tile_pos_to_invisible_tile + } else { + |_| None }; let mut invisible_tile_maker = tile_pos_to_tile_if_int_grid_nonzero_maker( @@ -356,7 +356,7 @@ mod tests { } #[test] - fn test_tile_pos_to_int_grid_with_grid_tiles_tile_maker_no_invis() { + fn test_tile_pos_to_int_grid_with_grid_tiles_tile_maker() { // Test is designed to have all permutations of tile/intgrid existence: // 1. tile + nonzero intgrid // 2. tile + zero intgrid @@ -380,21 +380,21 @@ mod tests { let int_grid_csv = vec![1, 0, 2, 0]; - let settings = LdtkSettings { - auto_layer_invisible_tiles: AutoLayerInvisibleTiles::Nonexistent, - ..Default::default() - }; - + // Test when sublayer index is 0. Invisibile tiles should be created let mut tile_maker = tile_pos_to_int_grid_with_grid_tiles_tile_maker( &grid_tiles, &int_grid_csv, 2, 2, 32, - &settings, + 0, ); - assert!(tile_maker(TilePos { x: 0, y: 0 }).is_none()); + assert_eq!( + tile_maker(TilePos { x: 0, y: 0 }).unwrap().texture_index.0, + 0 + ); + assert!(!tile_maker(TilePos { x: 0, y: 0 }).unwrap().visible.0); assert!(tile_maker(TilePos { x: 1, y: 0 }).is_none()); @@ -409,52 +409,18 @@ mod tests { 2 ); assert!(tile_maker(TilePos { x: 1, y: 1 }).unwrap().visible.0); - } - - #[test] - fn test_tile_pos_to_int_grid_with_grid_tiles_tile_maker_with_invis() { - // Test is designed to have all permutations of tile/intgrid existence: - // 1. tile + nonzero intgrid - // 2. tile + zero intgrid - // 3. no tile + nonzero intgrid - // 4. no tile + zero intgrid - - let grid_tiles = vec![ - TileInstance { - px: IVec2::new(0, 0), - src: IVec2::new(0, 0), - t: 1, - ..Default::default() - }, - TileInstance { - px: IVec2::new(32, 0), - src: IVec2::new(32, 0), - t: 2, - ..Default::default() - }, - ]; - - let int_grid_csv = vec![1, 0, 2, 0]; - - let settings = LdtkSettings { - auto_layer_invisible_tiles: AutoLayerInvisibleTiles::Active, - ..Default::default() - }; + // Test when sublayer index isn't 0. There should be no invisible tiles let mut tile_maker = tile_pos_to_int_grid_with_grid_tiles_tile_maker( &grid_tiles, &int_grid_csv, 2, 2, 32, - &settings, + 1, ); - assert_eq!( - tile_maker(TilePos { x: 0, y: 0 }).unwrap().texture_index.0, - 0 - ); - assert!(!tile_maker(TilePos { x: 0, y: 0 }).unwrap().visible.0); + assert!(tile_maker(TilePos { x: 0, y: 0 }).is_none()); assert!(tile_maker(TilePos { x: 1, y: 0 }).is_none());