using Godot; using System; using System.Linq; using System.Threading.Tasks; using Godot.Collections; public partial class TilemapAvoidance : TileMapLayer { [Export] private Array _solidLayers; [Export(PropertyHint.Layers2DPhysics)] public uint ObstaclesCollisionMask { get; private set; } private bool _needsFullCheck = false; public override void _Ready() { //NavigationServer2D.MapSetEdgeConnectionMargin(this.TileSet.GetRid(), 0f); //_ = RefreshNavigationAsync(); } private async Task RefreshNavigationAsync() { await Task.Delay(500); _needsFullCheck = true; this.NotifyRuntimeTileDataUpdate(); } public void Recalculate(Vector2 position) { var mapPos = LocalToMap(this.ToLocal(position)); var tile = GetCellTileData(mapPos); tile.SetNavigationPolygon(0, null); //_UpdateCells([mapPos], false); } public override bool _UseTileDataRuntimeUpdate(Vector2I coords) { // Run this check and return true only if I know the tiles will need to be updated, which means at start. // if (_needsFullCheck) { // var spaceState = GetWorld2D().DirectSpaceState; // var globalCoords = ToGlobal(this.MapToLocal(coords)); // var query = new PhysicsPointQueryParameters2D(); // query.Position = globalCoords; // query.CollisionMask = ObstaclesCollisionMask; // query.CollideWithBodies = true; // query.CollideWithAreas = true; // // var result = spaceState.IntersectPoint(query); // if (result.Count > 0) return true; //_needsFullCheck = false; return _solidLayers.Aggregate(false, (current, layer) => current | layer.GetUsedCellsById(0).Contains(coords)); } else { return false; } } public override void _TileDataRuntimeUpdate(Vector2I coords, TileData tileData) { tileData.SetNavigationPolygon(0, null); } }