using System; using System.Collections; using System.Collections.Generic; namespace MonoGame.Extended.Tilemaps { /// /// A collection of tilesets used by a tilemap. /// public class TilemapTilesetCollection : IReadOnlyList { private readonly List _tilesets = new(); /// /// Gets the tileset at the specified index. /// /// The zero-based index of the tileset to get. /// The tileset at the specified index. public TilemapTileset this[int index] { get { return _tilesets[index]; } } /// /// Gets the number of tilesets in the collection. /// public int Count { get { return _tilesets.Count; } } /// /// Adds a tileset to the collection. /// /// The tileset to add. /// /// This method is not thread-safe. If multiple threads are accessing the collection, /// external synchronization is required. /// public void Add(TilemapTileset tileset) { if (tileset == null) throw new ArgumentNullException(nameof(tileset)); _tilesets.Add(tileset); } /// /// Removes a tileset from the collection. /// /// The tileset to remove. /// if the tileset was removed; otherwise, . /// /// This is an O(n) operation. This method is not thread-safe. /// public bool Remove(TilemapTileset tileset) { return _tilesets.Remove(tileset); } /// /// Removes all tilesets from the collection. /// /// /// Warning: This operation cannot be undone and will remove all tileset references. /// This method is not thread-safe. /// public void Clear() { _tilesets.Clear(); } /// /// Gets the tileset that contains the specified global tile ID. /// /// The global tile ID. /// The tileset containing the tile, or if not found. public TilemapTileset GetTilesetForGid(int globalTileId) { // Tilesets are ordered by FirstGlobalId // Find the tileset where: globalTileId >= FirstGlobalId // and globalTileId < next tileset's FirstGlobalId TilemapTileset result = null; for (int i = 0; i < _tilesets.Count; i++) { var tileset = _tilesets[i]; // Check if this tile ID belongs to this tileset if (globalTileId >= tileset.FirstGlobalId) { // Check if this GID is within the tileset's range int localId = globalTileId - tileset.FirstGlobalId; if(localId < tileset.TileCount) { result = tileset; break; } } } return result; } /// /// Gets the local tile ID within a tileset from a global tile ID. /// /// The global tile ID. /// When this method returns, contains the tileset that owns the tile. /// The local tile ID within the tileset. /// No tileset contains the specified global tile ID. public int GetLocalId(int globalTileId, out TilemapTileset tileset) { var foundTileset = GetTilesetForGid(globalTileId); if (foundTileset == null) { throw new InvalidOperationException($"No tileset found for global tile ID {globalTileId}."); } tileset = foundTileset; return globalTileId - foundTileset.FirstGlobalId; } public IEnumerator GetEnumerator() { return _tilesets.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }