Tile Placement Improvements (#808)

* Tile Placement box actually uses the mouse snapgrid, not the players.

* Placement box only snaps to grids if cursor is over grid.
First tile of new grid is centered on cursor, instead of bottom left on cursor.

* Place square now sticks to the edge of a grid.
Cannot place tiles that would touch two grid Bounds.
This commit is contained in:
Acruid
2019-05-11 06:58:28 -07:00
committed by Pieter-Jan Briers
parent 2a9441a6da
commit c4fb96b5e8
16 changed files with 106 additions and 28 deletions

View File

@@ -77,7 +77,8 @@ namespace Robust.Client.Graphics.ClientEye
public ScreenCoordinates WorldToScreen(GridCoordinates point)
{
return new ScreenCoordinates(WorldToScreen(point.Position));
var worldCoords = _mapManager.GetGrid(point.GridID).LocalToWorld(point);
return new ScreenCoordinates(WorldToScreen(worldCoords.Position));
}
public GridCoordinates ScreenToWorld(ScreenCoordinates point)

View File

@@ -15,7 +15,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
var mapGrid = pManager.MapManager.GetGrid(MouseCoords.GridID);
CurrentTile = mapGrid.GetTileRef(MouseCoords);

View File

@@ -54,7 +54,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
snapSize = pManager.MapManager.GetGrid(MouseCoords.GridID).SnapSize; //Find snap size.
GridDistancing = snapSize;

View File

@@ -44,7 +44,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
snapSize = pManager.MapManager.GetGrid(MouseCoords.GridID).SnapSize; //Find snap size.
GridDistancing = snapSize;

View File

@@ -1,4 +1,7 @@
using Robust.Shared.Map;
using System.CodeDom;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
namespace Robust.Client.Placement.Modes
{
@@ -11,18 +14,71 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
const float SearchBoxSize = 1.5f; // size of search box in meters
MouseCoords = ScreenToCursorGrid(mouseScreen);
var mapGrid = pManager.MapManager.GetGrid(MouseCoords.GridID);
if (mapGrid.IsDefaultGrid)
{
// check if we are on an edge of a grid
// create a box around the cursor
DebugTools.Assert(mapGrid.WorldPosition == Vector2.Zero); // assert that LocalPos == WorldPos
var gridSearchBox = Box2.UnitCentered.Scale(SearchBoxSize).Translated(MouseCoords.Position);
// find grids in search box
var gridsInArea = mapGrid.ParentMap.FindGridsIntersecting(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 tileCenterLocal = closest.GridTileToLocal(tileIndices);
var tileCenterWorld = tileCenterLocal.ToWorld(pManager.MapManager).Position;
// move mouse one tile out along normal
var newTilePos = tileCenterWorld + normal * closest.TileSize;
MouseCoords = new GridCoordinates(closest.WorldToLocal(newTilePos), closest.Index);
}
//else free place
}
CurrentTile = mapGrid.GetTileRef(MouseCoords);
float tileSize = mapGrid.TileSize; //convert from ushort to float
GridDistancing = tileSize;
if (pManager.CurrentPermission.IsTile)
{
MouseCoords = new GridCoordinates(CurrentTile.X + tileSize / 2,
CurrentTile.Y + tileSize / 2,
MouseCoords.GridID);
if(!mapGrid.IsDefaultGrid)
{
MouseCoords = new GridCoordinates(CurrentTile.X + tileSize / 2,
CurrentTile.Y + tileSize / 2,
MouseCoords.GridID);
}
// else we don't modify coords
}
else
{

View File

@@ -11,7 +11,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
var mapGrid = pManager.MapManager.GetGrid(MouseCoords.GridID);
CurrentTile = mapGrid.GetTileRef(MouseCoords);

View File

@@ -14,7 +14,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
var mapGrid = pManager.MapManager.GetGrid(MouseCoords.GridID);
CurrentTile = mapGrid.GetTileRef(MouseCoords);

View File

@@ -11,7 +11,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
var mapGrid = pManager.MapManager.GetGrid(MouseCoords.GridID);
CurrentTile = mapGrid.GetTileRef(MouseCoords);

View File

@@ -11,7 +11,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
CurrentTile = pManager.MapManager.GetGrid(MouseCoords.GridID).GetTileRef(MouseCoords);
if (pManager.CurrentPermission.IsTile)

View File

@@ -8,7 +8,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
CurrentTile = pManager.MapManager.GetGrid(MouseCoords.GridID).GetTileRef(MouseCoords);
}

View File

@@ -10,7 +10,7 @@ namespace Robust.Client.Placement.Modes
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
MouseCoords = ScreenToPlayerGrid(mouseScreen);
MouseCoords = ScreenToCursorGrid(mouseScreen);
CurrentTile = pManager.MapManager.GetGrid(MouseCoords.GridID).GetTileRef(MouseCoords);
}

View File

@@ -107,7 +107,8 @@ namespace Robust.Client.Placement
var size = SpriteToDraw.Size;
foreach (var coordinate in locationcollection)
{
var pos = coordinate.Position - (size/(float)EyeManager.PIXELSPERMETER) / 2f;
var worldPos = pManager.MapManager.GetGrid(coordinate.GridID).LocalToWorld(coordinate).Position;
var pos = worldPos - (size/(float)EyeManager.PIXELSPERMETER) / 2f;
var color = IsValidPosition(coordinate) ? ValidPlaceColor : InvalidPlaceColor;
handle.DrawTexture(SpriteToDraw, pos, color);
}
@@ -206,7 +207,8 @@ namespace Robust.Client.Placement
protected Vector2 ScreenToWorld(Vector2 point)
{
return pManager.eyeManager.ScreenToWorld(point).Position;
var gridCoords = pManager.eyeManager.ScreenToWorld(point);
return gridCoords.ToWorld(pManager.MapManager).Position;
}
protected Vector2 WorldToScreen(Vector2 point)
@@ -214,11 +216,9 @@ namespace Robust.Client.Placement
return pManager.eyeManager.WorldToScreen(point);
}
protected GridCoordinates ScreenToPlayerGrid(ScreenCoordinates coords)
protected GridCoordinates ScreenToCursorGrid(ScreenCoordinates coords)
{
var worldPos = ScreenToWorld(coords.Position);
var entityGrid = pManager.PlayerManager.LocalPlayer.ControlledEntity.Transform.GridID;
return new GridCoordinates(worldPos, entityGrid);
return pManager.eyeManager.ScreenToWorld(coords.Position);
}
}
}

View File

@@ -143,15 +143,36 @@ namespace Robust.Server.Placement
if (closest != null) // stick to existing grid
{
var normal = new Angle(position - intersect.Center).GetCardinalDir().ToVec(); // round to nearest cardinal dir
var newTilePos = position + normal * closest.TileSize;
// round to nearest cardinal dir
var normal = new Angle(position - intersect.Center).GetCardinalDir().ToVec();
// round coords to center of tile
var tileIndices = closest.WorldToTile(intersect.Center);
var tileCenterLocal = closest.GridTileToLocal(tileIndices);
var tileCenterWorld = tileCenterLocal.ToWorld(_mapManager).Position;
// move mouse one tile out along normal
var newTilePos = tileCenterWorld + normal * closest.TileSize;
// you can always remove a tile
if(Tile.Empty.TypeId != tileType)
{
var tileBounds = Box2.UnitCentered.Scale(closest.TileSize).Translated(newTilePos);
var collideCount = map.FindGridsIntersecting(tileBounds).Count();
// prevent placing a tile if it overlaps more than one grid
if(collideCount > 1)
return;
}
var pos = closest.WorldToTile(position);
closest.SetTile(pos, new Tile(tileType));
}
else // create a new grid
{
var newGrid = map.CreateGrid();
newGrid.WorldPosition = position;
newGrid.WorldPosition = position + (newGrid.TileSize / 2f); // assume bottom left tile origin
var tilePos = newGrid.WorldToTile(position);
newGrid.SetTile(tilePos, new Tile(tileType));
}

View File

@@ -228,7 +228,7 @@ namespace Robust.Shared.GameObjects.Components.Transform
// Eh.
if (_mapManager.TryGetGrid(GridID, out var grid))
{
return grid.ConvertToWorld(GetLocalPosition());
return grid.LocalToWorld(GetLocalPosition());
}
return GetLocalPosition();
}

View File

@@ -150,8 +150,8 @@ namespace Robust.Shared.Map
/// </summary>
/// <param name="posLocal">The local vector with this grid as origin.</param>
/// <returns>The world-space vector with global origin.</returns>
Vector2 ConvertToWorld(Vector2 posLocal);
Vector2 LocalToWorld(Vector2 posLocal);
/// <summary>
/// Transforms World position into grid tile indices.
/// </summary>

View File

@@ -349,7 +349,7 @@ namespace Robust.Shared.Map
}
/// <inheritdoc />
public Vector2 ConvertToWorld(Vector2 posLocal)
public Vector2 LocalToWorld(Vector2 posLocal)
{
return posLocal + WorldPosition;
}