Implemented erasing rectangular areas (#1419)

* Added support for erasing rectangular areas

* Apply suggestions from code review

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* Switched sending start coordinate + end coordinate to sending start coordinate + rect selection size for preventing different parented positions, general code improvements

* Rewritten certain code part so the checks pass

* Added unshaded shader to rect erasing

* Tweaked alpha of erasing rectangle for better visualizing

Co-authored-by: Manel Navola <ManelNavola@users.noreply.github.com>
Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
Manel Navola
2021-02-27 05:52:12 +01:00
committed by GitHub
parent bfe6eeddb1
commit e33488ba55
5 changed files with 139 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Robust.Client.ResourceManagement;
@@ -21,6 +21,7 @@ using Robust.Shared.Reflection;
using Robust.Shared.Utility;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
using Robust.Shared.Log;
namespace Robust.Client.Placement
{
@@ -87,7 +88,17 @@ namespace Robust.Client.Placement
public bool Eraser { get; private set; }
/// <summary>
/// The texture we use to show from our placement manager to represent the entity to place
/// Holds the selection rectangle for the eraser
/// </summary>
public Box2? EraserRect { get; set; }
/// <summary>
/// Drawing shader for drawing without being affected by lighting
/// </summary>
private ShaderInstance? _drawingShader { get; set; }
/// <summary>
/// The texture we use to show from our placement manager to represent the entity to place
/// </summary>
public List<IDirectionalTextureProvider>? CurrentTextures { get; set; }
@@ -153,6 +164,8 @@ namespace Robust.Client.Placement
public void Initialize()
{
_drawingShader = _prototypeManager.Index<ShaderPrototype>("unshaded").Instance();
NetworkManager.RegisterNetMessage<MsgPlacement>(MsgPlacement.NAME, HandlePlacementMessage);
_modeDictionary.Clear();
@@ -182,7 +195,17 @@ namespace Robust.Client.Placement
.Bind(EngineKeyFunctions.EditorGridPlace, InputCmdHandler.FromDelegate(
session =>
{
if (IsActive && !Eraser) ActivateGridMode();
if (IsActive)
{
if (Eraser)
{
EraseRectMode();
}
else
{
ActivateGridMode();
}
}
}))
.Bind(EngineKeyFunctions.EditorPlaceObject, new PointerStateInputCmdHandler(
(session, coords, uid) =>
@@ -190,6 +213,13 @@ namespace Robust.Client.Placement
if (!IsActive)
return false;
if (EraserRect.HasValue)
{
HandleRectDeletion(StartPoint, EraserRect.Value);
EraserRect = null;
return true;
}
if (Eraser)
{
if (HandleDeletion(coords))
@@ -308,6 +338,7 @@ namespace Robust.Client.Placement
_placenextframe = false;
IsActive = false;
Eraser = false;
EraserRect = null;
PlacementOffset = Vector2i.Zero;
}
@@ -384,6 +415,15 @@ namespace Robust.Client.Placement
NetworkManager.ClientSendMessage(msg);
}
public void HandleRectDeletion(EntityCoordinates start, Box2 rect)
{
var msg = NetworkManager.CreateNetMessage<MsgPlacement>();
msg.PlaceType = PlacementManagerMessage.RequestRectRemove;
msg.EntityCoordinates = new EntityCoordinates(StartPoint.EntityId, rect.BottomLeft);
msg.RectSize = rect.Size;
NetworkManager.ClientSendMessage(msg);
}
public void ToggleEraser()
{
if (!Eraser && !IsActive)
@@ -459,11 +499,62 @@ namespace Robust.Client.Placement
return true;
}
private bool CurrentEraserMouseCoordinates(out EntityCoordinates coordinates)
{
var ent = PlayerManager.LocalPlayer?.ControlledEntity;
if (ent == null)
{
coordinates = new EntityCoordinates();
return false;
}
else
{
var map = ent.Transform.MapID;
if (map == MapId.Nullspace || !Eraser)
{
coordinates = new EntityCoordinates();
return false;
}
coordinates = EntityCoordinates.FromMap(ent.EntityManager, MapManager,
eyeManager.ScreenToMap(new ScreenCoordinates(_inputManager.MouseScreenPosition)));
return true;
}
}
/// <inheritdoc />
public void FrameUpdate(FrameEventArgs e)
{
if (!CurrentMousePosition(out var mouseScreen))
{
if (EraserRect.HasValue)
{
if (!CurrentEraserMouseCoordinates(out EntityCoordinates end))
return;
float b, l, t, r;
if (StartPoint.X < end.X)
{
l = StartPoint.X;
r = end.X;
}
else
{
l = end.X;
r = StartPoint.X;
}
if (StartPoint.Y < end.Y)
{
b = StartPoint.Y;
t = end.Y;
}
else
{
b = end.Y;
t = StartPoint.Y;
}
EraserRect = new Box2(l, b, r, t);
}
return;
}
CurrentMode!.AlignPlacementMode(mouseScreen);
@@ -501,6 +592,15 @@ namespace Robust.Client.Placement
PlacementType = PlacementTypes.Grid;
}
private void EraseRectMode()
{
if (!CurrentEraserMouseCoordinates(out EntityCoordinates coordinates))
return;
StartPoint = coordinates;
EraserRect = new Box2(coordinates.Position, Vector2.Zero);
}
private bool DeactivateSpecialPlacement()
{
if (PlacementType == PlacementTypes.None)
@@ -513,7 +613,14 @@ namespace Robust.Client.Placement
private void Render(DrawingHandleWorld handle)
{
if (CurrentMode == null || !IsActive)
{
if (EraserRect.HasValue)
{
handle.UseShader(_drawingShader);
handle.DrawRect(EraserRect.Value, new Color(255, 0, 0, 50));
}
return;
}
CurrentMode.Render(handle);

View File

@@ -201,6 +201,7 @@ namespace Robust.Client.UserInterface.CustomControls
private void OnEraseButtonToggled(BaseButton.ButtonToggledEventArgs args)
{
placementManager.ToggleEraser();
OverrideMenu.Disabled = args.Pressed;
}
private void BuildEntityList(string? searchStr = null)
@@ -510,6 +511,7 @@ namespace Robust.Client.UserInterface.CustomControls
}
EraseButton.Pressed = false;
OverrideMenu.Disabled = false;
}
private class DoNotMeasure : Control

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using System.Collections.Generic;
@@ -59,6 +59,9 @@ namespace Robust.Server.Placement
case PlacementManagerMessage.RequestEntRemove:
HandleEntRemoveReq(msg.EntityUid);
break;
case PlacementManagerMessage.RequestRectRemove:
HandleRectRemoveReq(msg);
break;
}
}
@@ -202,6 +205,19 @@ namespace Robust.Server.Placement
_entityManager.DeleteEntity(entity);
}
private void HandleRectRemoveReq(MsgPlacement msg)
{
EntityCoordinates start = msg.EntityCoordinates;
Vector2 rectSize = msg.RectSize;
foreach (IEntity entity in _entityManager.GetEntitiesIntersecting(start.GetMapId(_entityManager),
new Box2(start.Position, start.Position + rectSize)))
{
if (entity.Deleted || entity.HasComponent<IMapGridComponent>() || entity.HasComponent<IActorComponent>())
continue;
entity.Delete();
}
}
/// <summary>
/// Places mob in entity placement mode with given settings.
/// </summary>

View File

@@ -7,6 +7,7 @@
PlacementFailed,
RequestPlacement,
RequestEntRemove,
RequestRectRemove,
}
public enum SessionStatus : byte

View File

@@ -29,6 +29,7 @@ namespace Robust.Shared.Network.Messages
public int Range { get; set; }
public string ObjType { get; set; }
public string AlignOption { get; set; }
public Vector2 RectSize { get; set; }
public override void ReadFromBuffer(NetIncomingMessage buffer)
{
@@ -57,6 +58,10 @@ namespace Robust.Shared.Network.Messages
case PlacementManagerMessage.RequestEntRemove:
EntityUid = new EntityUid(buffer.ReadInt32());
break;
case PlacementManagerMessage.RequestRectRemove:
EntityCoordinates = buffer.ReadEntityCoordinates();
RectSize = buffer.ReadVector2();
break;
}
}
@@ -87,6 +92,10 @@ namespace Robust.Shared.Network.Messages
case PlacementManagerMessage.RequestEntRemove:
buffer.Write((int)EntityUid);
break;
case PlacementManagerMessage.RequestRectRemove:
buffer.Write(EntityCoordinates);
buffer.Write(RectSize);
break;
}
}
}