public override void AlignPlacementMode(ScreenCoordinates mouseScreen) { MouseCoords = ScreenToCursorGrid(mouseScreen); CurrentTile = GetTileRef(MouseCoords); if (pManager.CurrentPermission !.IsTile) { return; } if (!RangeCheck(MouseCoords)) { return; } var mapId = MouseCoords.GetMapId(pManager.EntityManager); var snapToEntities = EntitySystem.Get <EntityLookupSystem>().GetEntitiesInRange(MouseCoords, SnapToRange) .Where(entity => pManager.EntityManager.GetComponent <MetaDataComponent>(entity).EntityPrototype == pManager.CurrentPrototype && pManager.EntityManager.GetComponent <TransformComponent>(entity).MapID == mapId) .OrderBy(entity => (pManager.EntityManager.GetComponent <TransformComponent>(entity).WorldPosition - MouseCoords.ToMapPos(pManager.EntityManager)).LengthSquared) .ToList(); if (snapToEntities.Count == 0) { return; } var closestEntity = snapToEntities[0]; var closestTransform = pManager.EntityManager.GetComponent <TransformComponent>(closestEntity); if (!pManager.EntityManager.TryGetComponent <ISpriteComponent?>(closestEntity, out var component) || component.BaseRSI == null) { return; } var closestBounds = component.BaseRSI.Size; var closestRect = Box2.FromDimensions( closestTransform.WorldPosition.X - closestBounds.X / 2f, closestTransform.WorldPosition.Y - closestBounds.Y / 2f, closestBounds.X, closestBounds.Y); var sides = new[] { new Vector2(closestRect.Left + closestRect.Width / 2f, closestRect.Top - closestBounds.Y / 2f), new Vector2(closestRect.Left + closestRect.Width / 2f, closestRect.Bottom + closestBounds.Y / 2f), new Vector2(closestRect.Left - closestBounds.X / 2f, closestRect.Top + closestRect.Height / 2f), new Vector2(closestRect.Right + closestBounds.X / 2f, closestRect.Top + closestRect.Height / 2f) }; var closestSide = (from Vector2 side in sides orderby(side - MouseCoords.Position).LengthSquared select side).First(); MouseCoords = new EntityCoordinates(MouseCoords.EntityId, MouseCoords.Position); }
public override void AlignPlacementMode(ScreenCoordinates mouseScreen) { const float SearchBoxSize = 1.5f; // size of search box in meters MouseCoords = ScreenToCursorGrid(mouseScreen); var gridId = MouseCoords.GetGridId(pManager.EntityManager); IMapGrid?mapGrid = null; if (!gridId.IsValid() || !pManager.MapManager.TryGetGrid(gridId, out mapGrid)) { // create a box around the cursor var gridSearchBox = Box2.UnitCentered.Scale(SearchBoxSize).Translated(MouseCoords.Position); // find grids in search box var gridsInArea = pManager.MapManager.FindGridsIntersecting(MouseCoords.GetMapId(pManager.EntityManager), gridSearchBox); // find closest grid intersecting our search box. IMapGrid?closest = null; var distance = float.PositiveInfinity; var intersect = new Box2(); foreach (var grid in gridsInArea) { // figure out closest intersect var gridIntersect = gridSearchBox.Intersect(grid.WorldBounds); var gridDist = (gridIntersect.Center - MouseCoords.Position).LengthSquared; if (gridDist >= distance) { continue; } distance = gridDist; closest = grid; intersect = gridIntersect; } if (closest != null) // stick to existing grid { // round to nearest cardinal dir var normal = new Angle(MouseCoords.Position - intersect.Center).GetCardinalDir().ToVec(); // round coords to center of tile var tileIndices = closest.WorldToTile(intersect.Center); var tileCenterWorld = closest.GridTileToWorldPos(tileIndices); // move mouse one tile out along normal var newTilePos = tileCenterWorld + normal * closest.TileSize; MouseCoords = new EntityCoordinates(closest.GridEntityId, closest.WorldToLocal(newTilePos)); mapGrid = closest; } //else free place } if (mapGrid == null) { return; } CurrentTile = mapGrid.GetTileRef(MouseCoords); float tileSize = mapGrid.TileSize; //convert from ushort to float GridDistancing = tileSize; if (pManager.CurrentPermission !.IsTile) { MouseCoords = new EntityCoordinates(MouseCoords.EntityId, (CurrentTile.X + tileSize / 2, CurrentTile.Y + tileSize / 2)); }