mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
125 lines
6.0 KiB
C#
125 lines
6.0 KiB
C#
using SFML.Graphics;
|
|
using SFML.System;
|
|
using SS14.Client.GameObjects;
|
|
using SS14.Client.Graphics;
|
|
using SS14.Client.Interfaces.GOC;
|
|
using SS14.Client.Interfaces.Map;
|
|
using SS14.Shared.GameObjects;
|
|
using SS14.Shared.GO;
|
|
using SS14.Shared.IoC;
|
|
using SS14.Shared.Maths;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using EntityManager = SS14.Client.GameObjects.EntityManager;
|
|
|
|
namespace SS14.Client.Placement.Modes
|
|
{
|
|
public class AlignSimilar : PlacementMode
|
|
{
|
|
private const uint snapToRange = 50;
|
|
|
|
public AlignSimilar(PlacementManager pMan)
|
|
: base(pMan)
|
|
{
|
|
}
|
|
|
|
public override bool Update(Vector2i mouseS, IMapManager currentMap)
|
|
{
|
|
if (currentMap == null) return false;
|
|
|
|
spriteToDraw = GetDirectionalSprite(pManager.CurrentBaseSpriteKey);
|
|
var spriteBounds = spriteToDraw.GetLocalBounds();
|
|
|
|
mouseScreen = mouseS;
|
|
mouseWorld = CluwneLib.ScreenToWorld(mouseScreen);
|
|
|
|
var spriteSize = CluwneLib.PixelToTile(new Vector2f(spriteBounds.Width, spriteBounds.Height)); // TODO: Doublecheck this. Use SizeF?
|
|
var spriteRectWorld = new FloatRect(mouseWorld.X - (spriteSize.X / 2f),
|
|
mouseWorld.Y - (spriteSize.Y / 2f),
|
|
spriteSize.X, spriteSize.Y);
|
|
|
|
if (pManager.CurrentPermission.IsTile)
|
|
return false;
|
|
|
|
currentTile = currentMap.GetTileRef(mouseWorld);
|
|
|
|
//Align to similar if nearby found else free
|
|
if (currentTile.Tile.TileDef.IsWall)
|
|
return false; //HANDLE CURSOR OUTSIDE MAP
|
|
|
|
var rangeSquared = pManager.CurrentPermission.Range * pManager.CurrentPermission.Range;
|
|
if (rangeSquared > 0)
|
|
if (
|
|
(pManager.PlayerManager.ControlledEntity.GetComponent<TransformComponent>(ComponentFamily.Transform)
|
|
.Position - mouseWorld).LengthSquared() > rangeSquared) return false;
|
|
|
|
Entity[] nearbyEntities =
|
|
((EntityManager) IoCManager.Resolve<IEntityManagerContainer>().EntityManager).GetEntitiesInRange(
|
|
mouseWorld, snapToRange);
|
|
|
|
IOrderedEnumerable<Entity> snapToEntities = from Entity entity in nearbyEntities
|
|
where entity.Template == pManager.CurrentTemplate
|
|
orderby
|
|
(entity.GetComponent<TransformComponent>(
|
|
ComponentFamily.Transform).Position - mouseWorld).LengthSquared()
|
|
ascending
|
|
select entity;
|
|
|
|
if (snapToEntities.Any())
|
|
{
|
|
Entity closestEntity = snapToEntities.First();
|
|
ComponentReplyMessage reply = closestEntity.SendMessage(this, ComponentFamily.Renderable,
|
|
ComponentMessageType.GetSprite);
|
|
|
|
//if(replies.Any(x => x.messageType == SS13_Shared.GO.ComponentMessageType.CurrentSprite))
|
|
//{
|
|
// Sprite closestSprite = (Sprite)replies.Find(x => x.messageType == SS13_Shared.GO.ComponentMessageType.CurrentSprite).paramsList[0]; //This is safer but slower.
|
|
|
|
if (reply.MessageType == ComponentMessageType.CurrentSprite)
|
|
{
|
|
var closestSprite = (Sprite) reply.ParamsList[0]; //This is faster but kinda unsafe.
|
|
var closestBounds = closestSprite.GetLocalBounds();
|
|
|
|
var closestRect =
|
|
new FloatRect(
|
|
closestEntity.GetComponent<TransformComponent>(ComponentFamily.Transform).Position.X - closestBounds.Width / 2f,
|
|
closestEntity.GetComponent<TransformComponent>(ComponentFamily.Transform).Position.Y - closestBounds.Height / 2f,
|
|
closestBounds.Width, closestBounds.Height);
|
|
|
|
var sides = new List<Vector2f>
|
|
{
|
|
new Vector2f(closestRect.Left + (closestRect.Width / 2f), closestRect.Top - closestBounds.Height / 2f),
|
|
new Vector2f(closestRect.Left + (closestRect.Width / 2f), closestRect.Bottom() + closestBounds.Height / 2f),
|
|
new Vector2f(closestRect.Left - closestBounds.Width / 2f, closestRect.Top + (closestRect.Height / 2f)),
|
|
new Vector2f(closestRect.Right() + closestBounds.Width / 2f, closestRect.Top + (closestRect.Height / 2f))
|
|
};
|
|
|
|
Vector2f closestSide =
|
|
(from Vector2f side in sides orderby (side - mouseWorld).LengthSquared() ascending select side).First();
|
|
|
|
mouseWorld = closestSide;
|
|
mouseScreen = CluwneLib.WorldToScreen(mouseWorld).Round();
|
|
}
|
|
}
|
|
|
|
spriteRectWorld = new FloatRect(mouseWorld.X - (spriteBounds.Width/2f), mouseWorld.Y - (spriteBounds.Height/2f),
|
|
spriteBounds.Width, spriteBounds.Height);
|
|
if (pManager.CollisionManager.IsColliding(spriteRectWorld)) return false;
|
|
return true;
|
|
}
|
|
|
|
public override void Render()
|
|
{
|
|
if (spriteToDraw != null)
|
|
{
|
|
var spriteBounds = spriteToDraw.GetLocalBounds();
|
|
spriteToDraw.Color = pManager.ValidPosition ? new Color(0, 128, 0, 255) : new Color(128, 0, 0, 255);
|
|
spriteToDraw.Position = new Vector2f(mouseScreen.X - (spriteBounds.Width/2f),
|
|
mouseScreen.Y - (spriteBounds.Height/2f));
|
|
//Centering the sprite on the cursor.
|
|
spriteToDraw.Draw();
|
|
spriteToDraw.Color = Color.White;
|
|
}
|
|
}
|
|
}
|
|
} |