1806 lines
74 KiB
C#
1806 lines
74 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using AsyncAwaitBestPractices;
|
|
using Microsoft.AspNetCore.SignalR.Client;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using Microsoft.Xna.Framework.Input;
|
|
using MonoGame.Extended;
|
|
using Myra;
|
|
using Myra.Graphics2D.Brushes;
|
|
using Myra.Graphics2D.TextureAtlases;
|
|
using Myra.Graphics2D.UI;
|
|
using Myra.Utility;
|
|
using Sledgemapper.Shared.Entities;
|
|
using Sledgemapper.UI;
|
|
using TinyMessenger;
|
|
using Thickness = Myra.Graphics2D.Thickness;
|
|
|
|
namespace Sledgemapper
|
|
{
|
|
public class Sledgemapper : Game
|
|
{
|
|
private readonly CommunicationManager _communicationManager;
|
|
private readonly Desktop _desktop;
|
|
private readonly GraphicsDeviceManager _graphics;
|
|
private readonly TinyMessengerHub _messenger;
|
|
private readonly Session _sessionData;
|
|
private readonly State _state;
|
|
private CachedContent _cachedContent;
|
|
private Texture2D _comment;
|
|
private Dictionary<string, SpriteFont> _fonts;
|
|
private bool _isDragging;
|
|
private Label _lblOverlayName;
|
|
private MainWidget _mainWidget;
|
|
private MouseState _oldMouseState;
|
|
private KeyboardState _oldState;
|
|
private Effect _outlineShader;
|
|
private RenderTarget2D _renderTarget;
|
|
private SpriteSheet _rippleSpriteSheet;
|
|
private SpriteBatch _spriteBatch;
|
|
private SpriteSheet _spriteSheet;
|
|
private Texture2D _transparentRedRectangle;
|
|
private Dictionary<string, Texture2D> _wallsContent;
|
|
private Texture2D _whiteRectangle;
|
|
|
|
public Sledgemapper()
|
|
{
|
|
_graphics = new GraphicsDeviceManager(this);
|
|
|
|
_graphics.GraphicsProfile = GraphicsProfile.Reach;
|
|
_graphics.PreferMultiSampling = true;
|
|
|
|
Content.RootDirectory = "Content";
|
|
_desktop = new Desktop();
|
|
|
|
MyraEnvironment.Game = this;
|
|
|
|
|
|
_sessionData = new Session();
|
|
IsFixedTimeStep = true;
|
|
TargetElapsedTime = TimeSpan.FromSeconds(1d / 30d);
|
|
_messenger = new TinyMessengerHub();
|
|
_communicationManager = new CommunicationManager(_sessionData,_messenger);
|
|
_communicationManager.Connection.Reconnected += OnHubReconnected;
|
|
_communicationManager.Connection.Reconnecting += OnHubReconnecting;
|
|
_communicationManager.Connection.Closed += OnHubDisconnected;
|
|
_state = State.Instance;
|
|
}
|
|
|
|
protected override void Draw(GameTime gameTime)
|
|
{
|
|
if (_spriteBatch is null) return;
|
|
var visibleTilesX = GraphicsDevice.Viewport.Width / _state.TileSize + 1;
|
|
var visibleTilesY = GraphicsDevice.Viewport.Height / _state.TileSize + 1;
|
|
|
|
DrawMap();
|
|
ApplyShaderToMap();
|
|
|
|
_spriteBatch.Begin(
|
|
transformMatrix: Matrix.CreateTranslation(_state.ViewportCenter),
|
|
sortMode: SpriteSortMode.Texture, samplerState: SamplerState.PointClamp);
|
|
|
|
DrawTiles();
|
|
|
|
DrawWalls();
|
|
|
|
DrawOverlays();
|
|
|
|
DrawNotes();
|
|
|
|
DrawGrid(visibleTilesX, visibleTilesY);
|
|
|
|
DrawPlayerOffline();
|
|
|
|
DrawPlayers();
|
|
|
|
DrawSelectedWall();
|
|
|
|
DrawSelectedIntersection();
|
|
|
|
DrawLinePreview();
|
|
|
|
DrawRoomPreview();
|
|
|
|
_spriteBatch.End();
|
|
|
|
DrawRipple(gameTime);
|
|
|
|
try
|
|
{
|
|
_desktop?.Render();
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("Desktop render error");
|
|
}
|
|
|
|
base.Draw(gameTime);
|
|
}
|
|
|
|
protected override void Initialize()
|
|
{
|
|
// ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Initialize", Type = "AppLifecycle", Source = _settings.MachineName });
|
|
IsMouseVisible = true;
|
|
Window.AllowUserResizing = true;
|
|
Window.ClientSizeChanged += OnClientSizeChanged;
|
|
base.Initialize();
|
|
}
|
|
|
|
protected override void LoadContent()
|
|
{
|
|
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
|
_cachedContent = CachedContent.Instance;
|
|
|
|
_outlineShader = Content.Load<Effect>("shaders/OutlineShader");
|
|
MyraEnvironment.Game = this;
|
|
ResetRenderTarget();
|
|
// Inform Myra that external text input is available
|
|
// So it stops translating Keys to chars
|
|
_desktop.HasExternalTextInput = true;
|
|
|
|
// Provide that text input
|
|
Window.TextInput += (s, a) =>
|
|
{
|
|
_desktop.OnChar(a.Character);
|
|
|
|
};
|
|
|
|
_mainWidget = new MainWidget(_communicationManager, _messenger, Window);
|
|
_communicationManager.CheckLogin();
|
|
|
|
_wallsContent = Content.LoadContentFolder<Texture2D>("walls");
|
|
|
|
_spriteSheet = new SpriteSheet();
|
|
_spriteSheet.LoadContent(Content, "spriteIndex", "sprites");
|
|
_rippleSpriteSheet = new SpriteSheet();
|
|
_rippleSpriteSheet.LoadContent(Content, "handcursorsIndex", "handcursors");
|
|
|
|
_lblOverlayName = new Label
|
|
{
|
|
Background = new SolidBrush(Color.SlateGray),
|
|
Padding = new Thickness(4)
|
|
};
|
|
|
|
AddItemToToolGrid(_mainWidget.GridWalls, OnWallButtonClicked, _wallsContent);
|
|
AddItemToToolGrid(_mainWidget.GridOverlays, OnOverlayButtonClicked, _spriteSheet);
|
|
|
|
_fonts = Content.LoadContentFolder<SpriteFont>("fonts");
|
|
_cachedContent.Eye = Content.Load<Texture2D>("eye");
|
|
_cachedContent.Location = Content.Load<Texture2D>("location");
|
|
_comment = Content.Load<Texture2D>("comment");
|
|
_mainWidget.BtnToolbarLine.Image = new TextureRegion(Content.Load<Texture2D>("icon_line"));
|
|
_mainWidget.BtnToolbarRoom.Image = new TextureRegion(Content.Load<Texture2D>("icon_room"));
|
|
_mainWidget.BtnToolbarDelete.Image = new TextureRegion(Content.Load<Texture2D>("icon_delete"));
|
|
_mainWidget.TxtOverlaySearch.TextChangedByUser += OnTxtOverlaySearchChange;
|
|
|
|
_desktop.Root = _mainWidget;
|
|
|
|
_transparentRedRectangle = new Texture2D(GraphicsDevice, 1, 1);
|
|
_transparentRedRectangle.SetData(new[] { new Color(Color.Red, 80) });
|
|
|
|
_whiteRectangle = new Texture2D(GraphicsDevice, 1, 1);
|
|
_whiteRectangle.SetData(new[] { Color.White });
|
|
|
|
CenterOnTile(0, 0);
|
|
}
|
|
|
|
protected override void Update(GameTime gameTime)
|
|
{
|
|
var newState = Keyboard.GetState();
|
|
|
|
if (IsActive && GraphicsDevice.Viewport.Bounds.Contains(Mouse.GetState().Position) &&
|
|
!_desktop.IsMouseOverGUI && !_desktop.HasModalWidget)
|
|
{
|
|
var mouseState = Mouse.GetState();
|
|
|
|
var screenPosition = new Point(mouseState.Position.X - (int)_state.ViewportCenter.X,
|
|
mouseState.Position.Y - (int)_state.ViewportCenter.Y);
|
|
|
|
if (!_desktop.ContextMenu?.Visible ?? true)
|
|
{
|
|
_state.HoveredTile.X = screenPosition.X / _state.TileSize;
|
|
_state.HoveredTile.Y = screenPosition.Y / _state.TileSize;
|
|
|
|
|
|
if (screenPosition.X < 0) _state.HoveredTile.X--;
|
|
|
|
if (screenPosition.Y < 0) _state.HoveredTile.Y--;
|
|
}
|
|
|
|
if (_state.InsertMode == InsertMode.Wall) _state.SelectClosestWall(screenPosition);
|
|
|
|
if (_state.InsertMode == InsertMode.Overlay) _state.SelectOverlay(screenPosition);
|
|
|
|
if (_state.InsertMode == InsertMode.NewLine || _state.InsertMode == InsertMode.NewRoom ||
|
|
_state.InsertMode == InsertMode.NewDelete) _state.SelectClosestSnapPoint(screenPosition);
|
|
|
|
if (!newState.IsKeyDown(Keys.LeftControl) && mouseState.LeftButton == ButtonState.Pressed &&
|
|
mouseState.LeftButton == _oldMouseState.LeftButton &&
|
|
!_desktop.IsMouseOverGUI
|
|
)
|
|
{
|
|
_state.ViewportCenter =
|
|
new Vector3(_state.ViewportCenter.X + mouseState.Position.X - _oldMouseState.Position.X,
|
|
_state.ViewportCenter.Y + mouseState.Position.Y - _oldMouseState.Position.Y, 0);
|
|
if (mouseState.Position != _oldMouseState.Position) _isDragging = true;
|
|
}
|
|
|
|
if (mouseState.LeftButton == ButtonState.Released && mouseState.LeftButton != _oldMouseState.LeftButton)
|
|
{
|
|
if (_isDragging)
|
|
{
|
|
_isDragging = false;
|
|
}
|
|
else
|
|
{
|
|
_state.SelectedTile.X = _state.HoveredTile.X;
|
|
_state.SelectedTile.Y = _state.HoveredTile.Y;
|
|
_communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapName,
|
|
State.Instance.MapId, _state.SelectedTile);
|
|
}
|
|
}
|
|
|
|
if (mouseState.RightButton == ButtonState.Released &&
|
|
mouseState.RightButton != _oldMouseState.RightButton)
|
|
{
|
|
_state.SelectedNote.X = _state.HoveredTile.X;
|
|
_state.SelectedNote.Y = _state.HoveredTile.Y;
|
|
|
|
var popup = new VerticalStackPanel
|
|
{ Padding = new Thickness(1), Spacing = 2, Background = new SolidBrush(Color.DarkGray) };
|
|
|
|
if (!_sessionData.Notes.ContainsKey(_state.SelectedNote.ToString()))
|
|
{
|
|
var newNoteButton = new TextButton
|
|
{
|
|
Text = "New Note", Width = 80, Height = 20, Padding = new Thickness(2),
|
|
HorizontalAlignment = HorizontalAlignment.Left
|
|
};
|
|
newNoteButton.Click += OnContextMenuNewNoteClick;
|
|
popup.AddChild(newNoteButton);
|
|
}
|
|
else
|
|
{
|
|
_sessionData.Notes.TryGetValue(_state.SelectedNote.ToString(), out var n);
|
|
_state.SelectedNote = new Note(n);
|
|
var viewNoteButton = new TextButton
|
|
{
|
|
Text = "View Note", Width = 80, Height = 20, Padding = new Thickness(2),
|
|
HorizontalAlignment = HorizontalAlignment.Left
|
|
};
|
|
var deleteNoteButton = new TextButton
|
|
{
|
|
Text = "Delete Note", Width = 80, Height = 20, Padding = new Thickness(2),
|
|
HorizontalAlignment = HorizontalAlignment.Left
|
|
};
|
|
viewNoteButton.Click += OnContextMenuViewNoteClick;
|
|
deleteNoteButton.Click += OnContextMenuDeleteNoteClick;
|
|
|
|
popup.AddChild(viewNoteButton);
|
|
popup.AddChild(deleteNoteButton);
|
|
}
|
|
|
|
var pingButton = new TextButton
|
|
{
|
|
Text = "Ping", Width = 80, Height = 20, Padding = new Thickness(2),
|
|
HorizontalAlignment = HorizontalAlignment.Left
|
|
};
|
|
var location = new Tile { X = _state.HoveredTile.X, Y = _state.HoveredTile.Y };
|
|
pingButton.Click += (s, e) => OnContextMenuPingClick(s, e, location);
|
|
popup.AddChild(pingButton);
|
|
|
|
_desktop.ShowContextMenu(popup, mouseState.Position);
|
|
}
|
|
|
|
if (newState.IsKeyDown(Keys.LeftControl)
|
|
&& mouseState.LeftButton == ButtonState.Released
|
|
&& mouseState.LeftButton != _oldMouseState.LeftButton)
|
|
switch (_state.InsertMode)
|
|
{
|
|
case InsertMode.Tile:
|
|
_state.SelectedTile.X = _state.HoveredTile.X;
|
|
_state.SelectedTile.Y = _state.HoveredTile.Y;
|
|
_communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapName,
|
|
State.Instance.MapId, _state.SelectedTile);
|
|
|
|
_sessionData.NewTile(_state.SelectedTile, _state.CurrentTileId);
|
|
break;
|
|
case InsertMode.Wall:
|
|
_sessionData.NewWall(_state.SelectedWall, _state.CurrentWallId);
|
|
|
|
break;
|
|
case InsertMode.Overlay:
|
|
_sessionData.NewOverlay(_state.SelectedOverlay, _state.CurrentOverlayId);
|
|
break;
|
|
}
|
|
|
|
|
|
if (_state.InsertMode == InsertMode.NewLine && newState.IsKeyDown(Keys.LeftControl)
|
|
&& mouseState.LeftButton == ButtonState.Released
|
|
&& mouseState.LeftButton != _oldMouseState.LeftButton)
|
|
{
|
|
if (_state.LineStart is null)
|
|
{
|
|
_state.LineStart = new SnapPoint
|
|
{
|
|
X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y,
|
|
Index = _state.SelectedSnapPoint.Index
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var line = new Line
|
|
{
|
|
Start = new SnapPoint
|
|
{ X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index },
|
|
End = new SnapPoint
|
|
{
|
|
X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y,
|
|
Index = _state.SelectedSnapPoint.Index
|
|
},
|
|
Width = _state.LineWidth
|
|
};
|
|
_state.LineStart = null;
|
|
_state.LineWidth = 1;
|
|
_sessionData.NewLine(line);
|
|
}
|
|
}
|
|
|
|
if (_state.InsertMode == InsertMode.NewRoom && newState.IsKeyDown(Keys.LeftControl)
|
|
&& mouseState.LeftButton == ButtonState.Released
|
|
&& mouseState.LeftButton != _oldMouseState.LeftButton)
|
|
{
|
|
if (_state.LineStart is null)
|
|
{
|
|
_state.LineStart = new SnapPoint
|
|
{
|
|
X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y,
|
|
Index = _state.SelectedSnapPoint.Index
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var line = new Room
|
|
{
|
|
Start = new SnapPoint
|
|
{ X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index },
|
|
End = new SnapPoint
|
|
{
|
|
X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y,
|
|
Index = _state.SelectedSnapPoint.Index
|
|
}
|
|
};
|
|
_state.LineStart = null;
|
|
_state.LineWidth = 1;
|
|
_sessionData.NewRoom(line);
|
|
}
|
|
}
|
|
|
|
|
|
if (_state.InsertMode == InsertMode.NewDelete && newState.IsKeyDown(Keys.LeftControl)
|
|
&& mouseState.LeftButton == ButtonState.Released
|
|
&& mouseState.LeftButton != _oldMouseState.LeftButton)
|
|
{
|
|
if (_state.LineStart is null)
|
|
{
|
|
_state.LineStart = new SnapPoint
|
|
{
|
|
X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y,
|
|
Index = _state.SelectedSnapPoint.Index
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var line = new Room
|
|
{
|
|
Start = new SnapPoint
|
|
{ X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index },
|
|
End = new SnapPoint
|
|
{
|
|
X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y,
|
|
Index = _state.SelectedSnapPoint.Index
|
|
},
|
|
Delete = true
|
|
};
|
|
_state.LineStart = null;
|
|
_state.LineWidth = 1;
|
|
_sessionData.NewRoom(line);
|
|
}
|
|
}
|
|
|
|
if (_state.InsertMode == InsertMode.NewLine && _state.LineStart != null)
|
|
{
|
|
if (mouseState.ScrollWheelValue > _oldMouseState.ScrollWheelValue)
|
|
_state.LineWidth += .01f;
|
|
else if (mouseState.ScrollWheelValue < _oldMouseState.ScrollWheelValue) _state.LineWidth -= .01f;
|
|
}
|
|
|
|
if (newState.IsKeyDown(Keys.LeftControl) &&
|
|
mouseState.ScrollWheelValue != _oldMouseState.ScrollWheelValue)
|
|
{
|
|
var maxTileSize = 500;
|
|
var center = new Point((Window.ClientBounds.Width + 200) / 2 - _state.TileSize / 2,
|
|
Window.ClientBounds.Height / 2 - _state.TileSize / 2);
|
|
|
|
var tx = (center.X - (int)_state.ViewportCenter.X) / _state.TileSize;
|
|
var ty = (center.Y - (int)_state.ViewportCenter.Y) / _state.TileSize;
|
|
|
|
if (mouseState.ScrollWheelValue > _oldMouseState.ScrollWheelValue)
|
|
_state.TileSize = Math.Min(maxTileSize, _state.TileSize + 10);
|
|
else if (mouseState.ScrollWheelValue < _oldMouseState.ScrollWheelValue)
|
|
_state.TileSize = Math.Max(10, _state.TileSize - 10);
|
|
|
|
CenterOnTile(tx, ty);
|
|
}
|
|
|
|
_oldMouseState = mouseState;
|
|
}
|
|
|
|
|
|
if (newState.IsKeyDown(Keys.Delete))
|
|
switch (_state.InsertMode)
|
|
{
|
|
case InsertMode.Tile:
|
|
case InsertMode.NewRoom:
|
|
case InsertMode.NewLine:
|
|
case InsertMode.NewDelete:
|
|
_state.SelectedTile.X = _state.HoveredTile.X;
|
|
_state.SelectedTile.Y = _state.HoveredTile.Y;
|
|
_sessionData.DeleteTile(_state.SelectedTile);
|
|
break;
|
|
case InsertMode.Wall:
|
|
_sessionData.DeleteWall(_state.SelectedWall);
|
|
break;
|
|
case InsertMode.Overlay:
|
|
_sessionData.DeleteOverlay(_state.SelectedOverlay);
|
|
break;
|
|
}
|
|
|
|
if (_oldState.IsKeyDown(Keys.P) && newState.IsKeyUp(Keys.P))
|
|
_communicationManager.Ping(_state.HoveredTile).SafeFireAndForget();
|
|
|
|
foreach (var key in newState.GetPressedKeys())
|
|
switch (key)
|
|
{
|
|
case Keys.Left:
|
|
if (_oldState.IsKeyUp(Keys.Left) && newState.IsKeyDown(Keys.Left))
|
|
{
|
|
_state.SelectedTile.X--;
|
|
_communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapId,
|
|
_state.SelectedTile);
|
|
}
|
|
|
|
break;
|
|
case Keys.Right:
|
|
if (_oldState.IsKeyUp(Keys.Right) && newState.IsKeyDown(Keys.Right))
|
|
{
|
|
_state.SelectedTile.X++;
|
|
_communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapId,
|
|
_state.SelectedTile);
|
|
}
|
|
|
|
break;
|
|
case Keys.Up:
|
|
if (_oldState.IsKeyUp(Keys.Up) && newState.IsKeyDown(Keys.Up))
|
|
{
|
|
_state.SelectedTile.Y--;
|
|
_communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapId,
|
|
_state.SelectedTile);
|
|
}
|
|
|
|
break;
|
|
case Keys.Down:
|
|
if (_oldState.IsKeyUp(Keys.Down) && newState.IsKeyDown(Keys.Down))
|
|
{
|
|
_state.SelectedTile.Y++;
|
|
_communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapId,
|
|
_state.SelectedTile);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
_oldState = newState;
|
|
|
|
base.Update(gameTime);
|
|
}
|
|
|
|
private void AddItemToToolGrid(Grid grid, EventHandler eventAction, Dictionary<string, Texture2D> tilesFolderContent)
|
|
{
|
|
var indexX = 0;
|
|
var indexY = 0;
|
|
foreach (var item in tilesFolderContent)
|
|
{
|
|
var tileButton = new ImageButton
|
|
{
|
|
Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key,
|
|
Width = 40, Height = 40
|
|
};
|
|
tileButton.Click += eventAction;
|
|
grid.Widgets.Add(tileButton);
|
|
indexY++;
|
|
if (indexY == 4)
|
|
{
|
|
indexY = 0;
|
|
indexX++;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AddItemToToolGrid(Grid grid, EventHandler eventAction, SpriteSheet spriteSheet, string e = "")
|
|
{
|
|
var indexX = 0;
|
|
var indexY = 0;
|
|
grid.Widgets.Clear();
|
|
_mainWidget.ScrOverlay.ResetScroll();
|
|
foreach (var item in spriteSheet.index.Where(t =>
|
|
string.IsNullOrWhiteSpace(e) || t.Key.ToLower().Contains(e.ToLower())))
|
|
{
|
|
var tileButton = new ImageButton
|
|
{
|
|
Image = new TextureRegion(spriteSheet.Texture, item.Value), GridColumn = indexY, GridRow = indexX,
|
|
Id = item.Key, Width = 40, Height = 40
|
|
};
|
|
tileButton.Click += eventAction;
|
|
tileButton.MouseMoved += OnTileButtonTouchEntered;
|
|
tileButton.MouseLeft += OnTileButtonTouchLeft;
|
|
grid.Widgets.Add(tileButton);
|
|
indexY++;
|
|
if (indexY == 4)
|
|
{
|
|
indexY = 0;
|
|
indexX++;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplyShaderToMap()
|
|
{
|
|
var texelSize = new Vector2(_renderTarget.Width, _renderTarget.Height);
|
|
_outlineShader.Parameters["ImageSize"].SetValue(texelSize);
|
|
_outlineShader.Parameters["BorderSize"].SetValue((int)(_state.TileSize / 100f * 10f));
|
|
|
|
_outlineShader.Parameters["R"].SetValue(Settings.Instance.OverlayTintColor.R / 255.0f);
|
|
_outlineShader.Parameters["G"].SetValue(Settings.Instance.OverlayTintColor.G / 255.0f);
|
|
_outlineShader.Parameters["B"].SetValue(Settings.Instance.OverlayTintColor.B / 255.0f);
|
|
|
|
GraphicsDevice.Clear(Settings.Instance.BackgroundColor);
|
|
|
|
_spriteBatch.Begin(
|
|
effect: _outlineShader,
|
|
sortMode: SpriteSortMode.Immediate);
|
|
_spriteBatch.Draw(_renderTarget, Vector2.Zero, null, Color.White);
|
|
_spriteBatch.End();
|
|
}
|
|
|
|
private void CenterOnTile(int x, int y)
|
|
{
|
|
var center = new Point((Window.ClientBounds.Width + 200) / 2 - _state.TileSize / 2,
|
|
Window.ClientBounds.Height / 2 - _state.TileSize / 2);
|
|
var dx = center.X - x * _state.TileSize - _state.ViewportCenter.X;
|
|
var dy = center.Y - y * _state.TileSize - _state.ViewportCenter.Y;
|
|
_state.ViewportCenter = new Vector3(_state.ViewportCenter.X + dx, _state.ViewportCenter.Y + dy,
|
|
_state.ViewportCenter.Z);
|
|
}
|
|
|
|
private void DrawDelete(Room tile)
|
|
{
|
|
var posX = tile.Start.X * _state.TileSize;
|
|
var posY = tile.Start.Y * _state.TileSize;
|
|
|
|
var endposX = tile.End.X * _state.TileSize;
|
|
var endposY = tile.End.Y * _state.TileSize;
|
|
|
|
|
|
var ww = _state.TileSize / Settings.Instance.TileDeleteDivider;
|
|
if (posX == endposX)
|
|
{
|
|
endposX += ww;
|
|
posX -= ww;
|
|
}
|
|
|
|
if (posY == endposY)
|
|
{
|
|
endposY += ww;
|
|
posY -= ww;
|
|
}
|
|
|
|
switch (tile.Start.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
posX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
posY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
posX += _state.TileSize / 2;
|
|
posY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
switch (tile.End.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
endposX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
endposY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
endposX += _state.TileSize / 2;
|
|
endposY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
if (posX != endposX && posY != endposY)
|
|
{
|
|
var r = new Rectangle();
|
|
|
|
if (posX < endposX && posY < endposY)
|
|
{
|
|
r = new Rectangle(posX, posY, endposX - posX, endposY - posY);
|
|
}
|
|
else if (posX > endposX && posY > endposY)
|
|
{
|
|
r = new Rectangle(posX, posY, endposX - posX, endposY - posY);
|
|
}
|
|
else
|
|
{
|
|
if (endposY < posY) r = new Rectangle(posX, endposY, endposX - posX, posY - endposY);
|
|
if (endposX < posX) r = new Rectangle(endposX, posY, posX - endposX, endposY - posY);
|
|
}
|
|
|
|
_spriteBatch.Draw(_whiteRectangle, r, null, Color.Black, 0, Vector2.Zero, SpriteEffects.None, 1);
|
|
}
|
|
}
|
|
|
|
private void DrawGrid(int visibleTilesX, int visibleTilesY)
|
|
{
|
|
for (var i = -1; i < visibleTilesX + 3; i++)
|
|
{
|
|
var posX1 = i * _state.TileSize - _state.ViewportCenter.X;
|
|
var posY1 = -_state.ViewportCenter.Y;
|
|
posX1 -= posX1 % _state.TileSize;
|
|
posY1 -= posY1 % _state.TileSize;
|
|
var posX2 = i * _state.TileSize - _state.ViewportCenter.X;
|
|
var posY2 = GraphicsDevice.Viewport.Height - _state.ViewportCenter.Y;
|
|
posX2 -= posX2 % _state.TileSize;
|
|
posY2 -= posY2 % _state.TileSize;
|
|
|
|
_spriteBatch.DrawLine(
|
|
posX1, posY1,
|
|
posX2,
|
|
posY2+ _state.TileSize,
|
|
Settings.Instance.GridColor);
|
|
}
|
|
|
|
for (var i = -1; i < visibleTilesY + 2; i++)
|
|
{
|
|
var posX1 = -_state.ViewportCenter.X;
|
|
var posY1 = i * _state.TileSize - _state.ViewportCenter.Y;
|
|
posX1 -= posX1 % _state.TileSize;
|
|
posY1 -= posY1 % _state.TileSize;
|
|
var posX2 = GraphicsDevice.Viewport.Width - _state.ViewportCenter.X;
|
|
var posY2 = i * _state.TileSize - _state.ViewportCenter.Y;
|
|
posX2 -= posX2 % _state.TileSize;
|
|
posY2 -= posY2 % _state.TileSize;
|
|
|
|
_spriteBatch.DrawLine(posX1, posY1,
|
|
posX2 + _state.TileSize,
|
|
posY2,
|
|
Settings.Instance.GridColor);
|
|
}
|
|
|
|
|
|
if (_state.ShowCellNumbers && _state.TileSize >= 30)
|
|
{
|
|
var ffont =
|
|
_fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize / 8).Value ??
|
|
_fonts.Last().Value;
|
|
var fscale = 1f;
|
|
|
|
for (var i = -1; i < visibleTilesX + 2; i++)
|
|
for (var j = -1; j < visibleTilesY + 2; j++)
|
|
{
|
|
var screenPosition = new Point(i * _state.TileSize - (int)_state.ViewportCenter.X,
|
|
j * _state.TileSize - (int)_state.ViewportCenter.Y);
|
|
|
|
var x = screenPosition.X / _state.TileSize;
|
|
var y = screenPosition.Y / _state.TileSize;
|
|
|
|
_spriteBatch.DrawString(ffont,
|
|
$"{x}:{y}",
|
|
new Vector2(
|
|
x * _state.TileSize + 2,
|
|
y * _state.TileSize + 2
|
|
),
|
|
Color.Black,
|
|
0,
|
|
Vector2.Zero,
|
|
fscale,
|
|
SpriteEffects.None,
|
|
0);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawLine(Line tile)
|
|
{
|
|
var posX = tile.Start.X * _state.TileSize;
|
|
var posY = tile.Start.Y * _state.TileSize;
|
|
|
|
var endposX = tile.End.X * _state.TileSize;
|
|
var endposY = tile.End.Y * _state.TileSize;
|
|
|
|
switch (tile.Start.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
posX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
posY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
posX += _state.TileSize / 2;
|
|
posY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
switch (tile.End.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
endposX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
endposY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
endposX += _state.TileSize / 2;
|
|
endposY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
var length = (int)Math.Sqrt(Math.Pow(posX - endposX, 2) + Math.Pow(posY - endposY, 2));
|
|
var height = (int)(_state.TileSize * tile.Width);
|
|
if (length > 0)
|
|
{
|
|
var angle = Math.Atan2(posY - endposY, endposX - posX);
|
|
var angleRad = -(float)angle;
|
|
_spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, length, height), null, Color.White,
|
|
angleRad, new Vector2(0, 0), SpriteEffects.None, 1);
|
|
}
|
|
}
|
|
|
|
private void DrawLinePreview()
|
|
{
|
|
if (_state.InsertMode == InsertMode.NewLine && _state.SelectedSnapPoint != null)
|
|
{
|
|
var snapPoint = new Vector2(_state.SelectedSnapPoint.X * _state.TileSize,
|
|
_state.SelectedSnapPoint.Y * _state.TileSize);
|
|
|
|
switch (_state.SelectedSnapPoint.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
snapPoint.X += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
snapPoint.Y += _state.TileSize / 2;
|
|
break;
|
|
case 4:
|
|
snapPoint.Y += _state.TileSize / 2;
|
|
snapPoint.X += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
_spriteBatch.DrawCircle(snapPoint, _state.TileSize / 5f, 100, Color.Red, 2);
|
|
|
|
if (_state.LineStart != null)
|
|
{
|
|
var posX = _state.LineStart.X * _state.TileSize;
|
|
var posY = _state.LineStart.Y * _state.TileSize;
|
|
|
|
var endposX = _state.SelectedSnapPoint.X * _state.TileSize;
|
|
var endposY = _state.SelectedSnapPoint.Y * _state.TileSize;
|
|
|
|
switch (_state.LineStart.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
posX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
posY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
posX += _state.TileSize / 2;
|
|
posY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
switch (_state.SelectedSnapPoint.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
endposX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
endposY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
endposX += _state.TileSize / 2;
|
|
endposY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
var l = Math.Sqrt(Math.Pow(posX - endposX, 2) + Math.Pow(posY - endposY, 2));
|
|
|
|
var angle = Math.Atan2(posY - endposY, endposX - posX);
|
|
var angleRad = -(float)angle;
|
|
if (l > 0)
|
|
_spriteBatch.Draw(_transparentRedRectangle,
|
|
new Rectangle(posX, posY, (int)l, (int)(_state.TileSize * _state.LineWidth)), null,
|
|
Color.White, angleRad, new Vector2(0, 0), SpriteEffects.None, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawMap()
|
|
{
|
|
GraphicsDevice.SetRenderTarget(_renderTarget);
|
|
GraphicsDevice.Clear(Color.Transparent);
|
|
|
|
_spriteBatch.Begin(
|
|
transformMatrix: Matrix.CreateTranslation(_state.ViewportCenter),
|
|
samplerState: SamplerState.PointClamp
|
|
);
|
|
|
|
var items = _sessionData.Lines.Values.Union<BaseMapEntity>(_sessionData.Rooms.Values)
|
|
.OrderBy(t => t.Timestamp).ToArray();
|
|
|
|
for (var i = 0; i < items.Count(); i++)
|
|
{
|
|
var item = items.ElementAt(i);
|
|
if (IsMapElementOffscreen(item)) continue;
|
|
switch (item)
|
|
{
|
|
case Line l:
|
|
DrawLine(l);
|
|
break;
|
|
|
|
case Room room:
|
|
if (room.Delete)
|
|
DrawDelete(room);
|
|
else
|
|
DrawRoom(room);
|
|
break;
|
|
}
|
|
}
|
|
|
|
_spriteBatch.End();
|
|
|
|
GraphicsDevice.SetRenderTarget(null);
|
|
}
|
|
|
|
private void DrawNotes()
|
|
{
|
|
if (_state.TileSize < 30) return;
|
|
|
|
for (var i = 0; i < _sessionData.Notes.Values.Count; i++)
|
|
{
|
|
var note = _sessionData.Notes.Values.ElementAt(i);
|
|
_spriteBatch.Draw(
|
|
_comment,
|
|
new Rectangle(
|
|
note.X * _state.TileSize + _state.TileSize - _state.TileSize / 2 + _state.TileSize / 25,
|
|
note.Y * _state.TileSize + _state.TileSize / 8 + _state.TileSize / 25,
|
|
(int)(_state.TileSize / 2.5), (int)(_state.TileSize / 2.5 / 1.136)
|
|
), Color.Black * .2f
|
|
);
|
|
|
|
_spriteBatch.Draw(
|
|
_comment,
|
|
new Rectangle(
|
|
note.X * _state.TileSize + _state.TileSize - _state.TileSize / 2,
|
|
note.Y * _state.TileSize + _state.TileSize / 8,
|
|
(int)(_state.TileSize / 2.5), (int)(_state.TileSize / 2.5 / 1.136)
|
|
), Settings.Instance.NoteColor
|
|
);
|
|
}
|
|
}
|
|
|
|
private void DrawOverlays()
|
|
{
|
|
for (var i = 0; i < _sessionData.Overlays.Values.Count; i++)
|
|
{
|
|
var tile = _sessionData.Overlays.Values.ElementAt(i);
|
|
var spriteRec = _spriteSheet.SourceRectangle(tile.ID);
|
|
|
|
float posX;
|
|
float posY;
|
|
|
|
if (tile.Intersection)
|
|
{
|
|
posX = tile.X * _state.TileSize;
|
|
posY = tile.Y * _state.TileSize;
|
|
|
|
_spriteBatch.Draw(_spriteSheet.Texture,
|
|
new Vector2(posX + _state.TileSize / 25, posY + _state.TileSize / 25), spriteRec,
|
|
Color.Black * .2f, MathHelper.ToRadians(90 * tile.Rotation),
|
|
new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2),
|
|
((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0);
|
|
_spriteBatch.Draw(_spriteSheet.Texture, new Vector2(posX, posY), spriteRec,
|
|
Settings.Instance.OverlayTintColor, MathHelper.ToRadians(90 * tile.Rotation),
|
|
new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2),
|
|
((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0);
|
|
}
|
|
else
|
|
{
|
|
posX = tile.X * _state.TileSize + _state.TileSize / 2f;
|
|
posY = tile.Y * _state.TileSize + _state.TileSize / 2f;
|
|
}
|
|
|
|
_spriteBatch.Draw(_spriteSheet.Texture,
|
|
new Vector2(posX + _state.TileSize / 25, posY + _state.TileSize / 25), spriteRec, Color.Black * .2f,
|
|
MathHelper.ToRadians(90 * tile.Rotation),
|
|
new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2),
|
|
((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0);
|
|
_spriteBatch.Draw(_spriteSheet.Texture, new Vector2(posX, posY), spriteRec,
|
|
Settings.Instance.OverlayTintColor, MathHelper.ToRadians(90 * tile.Rotation),
|
|
new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2),
|
|
((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0);
|
|
}
|
|
}
|
|
|
|
private void DrawPingPointer(Ping ping, GameTime gameTime)
|
|
{
|
|
var durationMs = 2000f;
|
|
var baseRadius = _state.TileSize / 4f;
|
|
var baseOuterRadius = (float)_state.TileSize;
|
|
var iterations = 3f;
|
|
var validPointer = GetPointerVector(new Point(ping.X, ping.Y), out var points);
|
|
|
|
if (validPointer)
|
|
{
|
|
_spriteBatch.DrawPolygon(Vector2.Zero, points, ping.Player.Color.ToColor(), 4);
|
|
|
|
|
|
for (var j = 0; j < iterations; j++)
|
|
{
|
|
var cycleTime = ((float)gameTime.TotalGameTime.TotalMilliseconds + j * durationMs / iterations) %
|
|
durationMs / durationMs;
|
|
var easing = Easings.Interpolate(cycleTime, Easings.Functions.SineEaseInOut);
|
|
var v2 = new Vector2[points.Length];
|
|
|
|
|
|
var tCenter = new Vector2((points[0].X + points[1].X + points[2].X) / 3f,
|
|
(points[0].Y + points[1].Y + points[2].Y) / 3f);
|
|
|
|
|
|
for (var i1 = 0; i1 < v2.Length; i1++)
|
|
{
|
|
var svx = (points[i1].X - tCenter.X) * (1 + 2 * easing) + tCenter.X;
|
|
var svy = (points[i1].Y - tCenter.Y) * (1 + 2 * easing) + tCenter.Y;
|
|
v2[i1] = new Vector2(svx, svy);
|
|
}
|
|
|
|
_spriteBatch.DrawPolygon(
|
|
Vector2.Zero,
|
|
v2,
|
|
new Color(ping.Player.Color.ToColor(), 1f - easing),
|
|
2 + 2 * (1 - easing));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawPlayerOffline()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_sessionData.SessionName))
|
|
{
|
|
var isoffscreen = IsOffscreen(_state.SelectedTile);
|
|
if (isoffscreen)
|
|
{
|
|
var validPointer = GetPointerVector(new Point(_state.SelectedTile.X, _state.SelectedTile.Y),
|
|
out var points);
|
|
if (validPointer) _spriteBatch.DrawPolygon(Vector2.Zero, points, Color.Red, 2);
|
|
}
|
|
else
|
|
{
|
|
_spriteBatch.DrawRectangle(
|
|
new Rectangle(_state.SelectedTile.X * _state.TileSize - 2,
|
|
_state.SelectedTile.Y * _state.TileSize - 2, _state.TileSize + 3, _state.TileSize + 3),
|
|
Color.Red, 2);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawPlayerPointer(Player player)
|
|
{
|
|
var validPointer = GetPointerVector(new Point(player.Position.X, player.Position.Y), out var points);
|
|
if (validPointer) _spriteBatch.DrawPolygon(Vector2.Zero, points, player.Color.ToColor(), 2);
|
|
}
|
|
|
|
private void DrawPlayers()
|
|
{
|
|
var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize).Value ??
|
|
_fonts.Last().Value;
|
|
var fscale = _state.TileSize / (ffont.LineSpacing * 3f);
|
|
|
|
var playerCells = _sessionData.Players.Select(m => m.Position).Distinct().ToList();
|
|
|
|
foreach (var cell in playerCells.Where(c => !IsOffscreen(c)))
|
|
{
|
|
var playersInCell = _sessionData.Players.Where(m => m.Position == cell).ToList();
|
|
var i = 0;
|
|
foreach (var player in playersInCell)
|
|
|
|
{
|
|
var color = player.Color.ToColor();
|
|
|
|
var rectangle = new Rectangle();
|
|
var stringPosition = new Vector2();
|
|
var measure = ffont.MeasureString(player.Initials);
|
|
var maxSize = Math.Max(measure.X, measure.Y);
|
|
|
|
if (playersInCell.Count == 1)
|
|
{
|
|
fscale = (_state.TileSize - 2) / maxSize;
|
|
rectangle = new Rectangle(
|
|
player.Position.X * _state.TileSize,
|
|
player.Position.Y * _state.TileSize,
|
|
_state.TileSize - 1,
|
|
_state.TileSize - 1);
|
|
stringPosition = new Vector2(
|
|
player.Position.X * _state.TileSize + 1,
|
|
player.Position.Y * _state.TileSize + _state.TileSize - measure.Y * fscale);
|
|
}
|
|
else if (playersInCell.Count == 2)
|
|
{
|
|
fscale = (_state.TileSize / 2 - 2) / maxSize;
|
|
|
|
if (i == 0)
|
|
{
|
|
rectangle = new Rectangle(
|
|
player.Position.X * _state.TileSize,
|
|
player.Position.Y * _state.TileSize,
|
|
_state.TileSize / 2 - 1,
|
|
_state.TileSize - 1);
|
|
stringPosition = new Vector2(
|
|
player.Position.X * _state.TileSize + 1,
|
|
player.Position.Y * _state.TileSize + _state.TileSize - measure.Y * fscale);
|
|
}
|
|
else
|
|
{
|
|
rectangle = new Rectangle(
|
|
player.Position.X * _state.TileSize + _state.TileSize / 2,
|
|
player.Position.Y * _state.TileSize,
|
|
_state.TileSize / 2 - 1,
|
|
_state.TileSize - 1);
|
|
stringPosition = new Vector2(
|
|
player.Position.X * _state.TileSize + _state.TileSize / 2 + 1,
|
|
player.Position.Y * _state.TileSize + _state.TileSize - measure.Y * fscale);
|
|
}
|
|
|
|
i++;
|
|
}
|
|
else if (playersInCell.Count >= 3)
|
|
{
|
|
fscale = (_state.TileSize / 2 - 2) / maxSize;
|
|
switch (i)
|
|
{
|
|
case 0:
|
|
rectangle = new Rectangle(
|
|
player.Position.X * _state.TileSize,
|
|
player.Position.Y * _state.TileSize,
|
|
_state.TileSize / 2 - 1,
|
|
_state.TileSize / 2 - 1);
|
|
stringPosition = new Vector2(
|
|
player.Position.X * _state.TileSize + 1,
|
|
player.Position.Y * _state.TileSize + _state.TileSize / 2 - measure.Y * fscale);
|
|
|
|
break;
|
|
case 1:
|
|
rectangle = new Rectangle(
|
|
player.Position.X * _state.TileSize + _state.TileSize / 2,
|
|
player.Position.Y * _state.TileSize,
|
|
_state.TileSize / 2 - 1,
|
|
_state.TileSize / 2 - 1);
|
|
stringPosition = new Vector2(
|
|
player.Position.X * _state.TileSize + _state.TileSize / 2 + 1,
|
|
player.Position.Y * _state.TileSize + _state.TileSize / 2 - measure.Y * fscale);
|
|
|
|
break;
|
|
case 2:
|
|
rectangle = new Rectangle(
|
|
player.Position.X * _state.TileSize,
|
|
player.Position.Y * _state.TileSize + _state.TileSize / 2,
|
|
_state.TileSize / 2 - 1,
|
|
_state.TileSize / 2 - 1);
|
|
stringPosition = new Vector2(
|
|
player.Position.X * _state.TileSize + 1,
|
|
player.Position.Y * _state.TileSize + _state.TileSize - measure.Y * fscale);
|
|
|
|
break;
|
|
case 3:
|
|
default:
|
|
rectangle = new Rectangle(
|
|
player.Position.X * _state.TileSize + _state.TileSize / 2,
|
|
player.Position.Y * _state.TileSize + _state.TileSize / 2,
|
|
_state.TileSize / 2 - 1,
|
|
_state.TileSize / 2 - 1);
|
|
stringPosition = new Vector2(
|
|
player.Position.X * _state.TileSize + _state.TileSize / 2 + 1,
|
|
player.Position.Y * _state.TileSize + _state.TileSize - measure.Y * fscale);
|
|
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
_spriteBatch.DrawRectangle(rectangle, color, 2);
|
|
_spriteBatch.DrawString(ffont,
|
|
player.Initials,
|
|
stringPosition,
|
|
color,
|
|
0,
|
|
Vector2.Zero,
|
|
fscale,
|
|
SpriteEffects.None,
|
|
0);
|
|
}
|
|
}
|
|
|
|
foreach (var player in _sessionData.Players)
|
|
{
|
|
var isOffscreen = IsOffscreen(player.Position);
|
|
if (isOffscreen) DrawPlayerPointer(player);
|
|
}
|
|
}
|
|
|
|
private void DrawRipple(GameTime gameTime)
|
|
{
|
|
_spriteBatch.Begin(
|
|
blendState: BlendState.NonPremultiplied,
|
|
transformMatrix: Matrix.CreateTranslation(_state.ViewportCenter));
|
|
|
|
var durationMs = 2000;
|
|
var baseRadius = _state.TileSize / 4f;
|
|
var baseOuterRadius = (float)_state.TileSize;
|
|
var iterations = 3f;
|
|
var guids = _sessionData.Pings.Keys.ToArray();
|
|
|
|
foreach (var guid in guids)
|
|
{
|
|
var pingFound = _sessionData.Pings.TryGetValue(guid, out var ping);
|
|
if (!pingFound) continue;
|
|
|
|
if (ping.StartTime == 0) ping.StartTime = gameTime.TotalGameTime.TotalMilliseconds;
|
|
|
|
var x = ping.X * _state.TileSize + _state.TileSize / 2f;
|
|
var y = ping.Y * _state.TileSize + _state.TileSize / 2f;
|
|
|
|
if (IsOffscreen(new Tile { X = ping.X, Y = ping.Y }))
|
|
{
|
|
DrawPingPointer(ping, gameTime);
|
|
}
|
|
else
|
|
{
|
|
_spriteBatch.DrawCircle(
|
|
new Vector2(x, y),
|
|
baseRadius,
|
|
20,
|
|
ping.Player.Color.ToColor(),
|
|
baseRadius);
|
|
|
|
for (var i = 0; i < iterations; i++)
|
|
{
|
|
var cycleTime =
|
|
((float)gameTime.TotalGameTime.TotalMilliseconds + (float)i * durationMs / iterations) %
|
|
durationMs / durationMs;
|
|
var easing = Easings.Interpolate(cycleTime, Easings.Functions.SineEaseInOut);
|
|
_spriteBatch.DrawCircle(
|
|
new Vector2(x, y),
|
|
baseRadius + baseOuterRadius * easing,
|
|
20,
|
|
new Color(ping.Player.Color.ToColor(), 1 - easing),
|
|
2 + 5 * (1 - easing));
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var guid in guids)
|
|
{
|
|
var pingFound = _sessionData.Pings.TryGetValue(guid, out var ping);
|
|
if (!pingFound) continue;
|
|
|
|
if (gameTime.TotalGameTime.TotalMilliseconds - ping.StartTime > Settings.Instance.PingDuration)
|
|
_sessionData.Pings.TryRemove(guid, out var _);
|
|
}
|
|
|
|
|
|
_spriteBatch.End();
|
|
}
|
|
|
|
private void DrawRoom(Room tile)
|
|
{
|
|
var posX = tile.Start.X * _state.TileSize;
|
|
var posY = tile.Start.Y * _state.TileSize;
|
|
|
|
var endposX = tile.End.X * _state.TileSize;
|
|
var endposY = tile.End.Y * _state.TileSize;
|
|
|
|
switch (tile.Start.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
posX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
posY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
posX += _state.TileSize / 2;
|
|
posY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
switch (tile.End.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
endposX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
endposY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
endposX += _state.TileSize / 2;
|
|
endposY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
if (posX != endposX && posY != endposY)
|
|
{
|
|
if (posX < endposX && posY < endposY)
|
|
|
|
{
|
|
_spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null,
|
|
Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
|
|
}
|
|
else if (posX > endposX && posY > endposY)
|
|
{
|
|
_spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null,
|
|
Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
|
|
}
|
|
|
|
else
|
|
{
|
|
if (endposY < posY)
|
|
_spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, endposY, endposX - posX, posY - endposY),
|
|
null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
|
|
|
|
if (endposX < posX)
|
|
_spriteBatch.Draw(_whiteRectangle, new Rectangle(endposX, posY, posX - endposX, endposY - posY),
|
|
null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawRoomPreview()
|
|
{
|
|
if ((_state.InsertMode == InsertMode.NewRoom || _state.InsertMode == InsertMode.NewDelete) &&
|
|
_state.SelectedSnapPoint != null)
|
|
{
|
|
var snapPoint = new Vector2(_state.SelectedSnapPoint.X * _state.TileSize,
|
|
_state.SelectedSnapPoint.Y * _state.TileSize);
|
|
|
|
switch (_state.SelectedSnapPoint.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
snapPoint.X += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
snapPoint.Y += _state.TileSize / 2;
|
|
break;
|
|
case 4:
|
|
snapPoint.Y += _state.TileSize / 2;
|
|
snapPoint.X += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
_spriteBatch.DrawCircle(snapPoint, _state.TileSize / 6f, 50, Color.Red, 2);
|
|
|
|
if (_state.LineStart != null)
|
|
{
|
|
var posX = _state.LineStart.X * _state.TileSize;
|
|
var posY = _state.LineStart.Y * _state.TileSize;
|
|
|
|
var endposX = _state.SelectedSnapPoint.X * _state.TileSize;
|
|
var endposY = _state.SelectedSnapPoint.Y * _state.TileSize;
|
|
if (_state.InsertMode == InsertMode.NewDelete)
|
|
{
|
|
var ww = _state.TileSize / Settings.Instance.TileDeleteDivider;
|
|
if (posX == endposX)
|
|
{
|
|
endposX += ww;
|
|
posX -= ww;
|
|
}
|
|
|
|
if (posY == endposY)
|
|
{
|
|
endposY += ww;
|
|
posY -= ww;
|
|
}
|
|
}
|
|
|
|
switch (_state.LineStart.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
posX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
posY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
posX += _state.TileSize / 2;
|
|
posY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
switch (_state.SelectedSnapPoint.Index)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
endposX += _state.TileSize / 2;
|
|
break;
|
|
case 3:
|
|
endposY += _state.TileSize / 2;
|
|
|
|
break;
|
|
case 4:
|
|
endposX += _state.TileSize / 2;
|
|
endposY += _state.TileSize / 2;
|
|
break;
|
|
}
|
|
|
|
var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize / 3)
|
|
.Value ?? _fonts.Last().Value;
|
|
var fscale = 1.2f;
|
|
var width = Math.Abs(endposX - posX);
|
|
var height = Math.Abs(posY - endposY);
|
|
var tilesWidth = width / (double)_state.TileSize;
|
|
var tilesHeight = height / (double)_state.TileSize;
|
|
tilesWidth = Math.Round(tilesWidth * 2, MidpointRounding.AwayFromZero) / 2;
|
|
tilesHeight = Math.Round(tilesHeight * 2, MidpointRounding.AwayFromZero) / 2;
|
|
var xmeasure = ffont.MeasureString($"{tilesWidth}");
|
|
var ymeasure = ffont.MeasureString($"{tilesHeight}");
|
|
float widthX = 0, widthY = 0, heightX = 0, heightY = 0;
|
|
|
|
var area = new Rectangle();
|
|
if (posX != endposX && posY != endposY)
|
|
{
|
|
if (posX > endposX && posY > endposY || posX < endposX && posY < endposY)
|
|
{
|
|
area = new Rectangle(posX, posY, endposX - posX, endposY - posY);
|
|
|
|
if (posX > endposX && posY > endposY)
|
|
{
|
|
widthX = endposX + width / 2 - xmeasure.X / 2;
|
|
widthY = endposY - ymeasure.Y * 1.2f;
|
|
|
|
heightX = posX + xmeasure.X / 2;
|
|
heightY = endposY + height / 2 - ymeasure.Y / 2;
|
|
}
|
|
else if (posX < endposX && posY < endposY)
|
|
{
|
|
widthX = posX + width / 2 - xmeasure.X / 2;
|
|
widthY = posY - ymeasure.Y * 1.2f;
|
|
|
|
heightX = endposX + xmeasure.X / 2;
|
|
heightY = posY + height / 2 - ymeasure.Y / 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (endposY < posY)
|
|
{
|
|
area = new Rectangle(posX, endposY, endposX - posX, posY - endposY);
|
|
|
|
widthX = posX + width / 2 - xmeasure.X / 2;
|
|
widthY = endposY - ymeasure.Y * 1.2f;
|
|
|
|
heightX = endposX + xmeasure.X / 2;
|
|
heightY = endposY + height / 2 - ymeasure.Y / 2;
|
|
}
|
|
|
|
if (endposX < posX)
|
|
{
|
|
area = new Rectangle(endposX, posY, posX - endposX, endposY - posY);
|
|
|
|
widthX = endposX + width / 2 - xmeasure.X / 2;
|
|
widthY = posY - ymeasure.Y * 1.2f;
|
|
|
|
heightX = posX + xmeasure.X / 2;
|
|
heightY = posY + height / 2 - ymeasure.Y / 2;
|
|
}
|
|
}
|
|
|
|
_spriteBatch.Draw(_transparentRedRectangle, area, null, Color.White, 0, new Vector2(0, 0),
|
|
SpriteEffects.None, 1);
|
|
|
|
_spriteBatch.DrawString(ffont,
|
|
$"{tilesWidth}",
|
|
new Vector2(
|
|
widthX,
|
|
widthY
|
|
),
|
|
Color.Red,
|
|
0,
|
|
Vector2.Zero,
|
|
fscale,
|
|
SpriteEffects.None,
|
|
0);
|
|
|
|
_spriteBatch.DrawString(ffont,
|
|
$"{tilesHeight}",
|
|
new Vector2(
|
|
heightX, heightY
|
|
),
|
|
Color.Red,
|
|
0,
|
|
Vector2.Zero,
|
|
fscale,
|
|
SpriteEffects.None,
|
|
0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawSelectedIntersection()
|
|
{
|
|
if (_state.InsertMode == InsertMode.Overlay && _state.SelectedOverlay.Intersection)
|
|
{
|
|
var overlay = new Vector2(_state.SelectedOverlay.X * _state.TileSize,
|
|
_state.SelectedOverlay.Y * _state.TileSize);
|
|
_spriteBatch.DrawCircle(overlay, _state.TileSize / 3f, 100, Color.Red, 2);
|
|
}
|
|
}
|
|
|
|
private void DrawSelectedWall()
|
|
{
|
|
if (_state.InsertMode == InsertMode.Wall)
|
|
{
|
|
var startWall = new Vector2(_state.SelectedWall.X * _state.TileSize,
|
|
_state.SelectedWall.Y * _state.TileSize);
|
|
_spriteBatch.DrawLine(startWall, _state.TileSize,
|
|
MathHelper.ToRadians(90 * _state.SelectedWall.Rotation), Color.Red, 2);
|
|
}
|
|
}
|
|
|
|
private void DrawTiles()
|
|
{
|
|
for (var i = 0; i < _sessionData.Map.Values.Count; i++)
|
|
{
|
|
var tile = _sessionData.Map.Values.ElementAt(i);
|
|
var content = Content.Load<Texture2D>($"tiles/{tile.ID}");
|
|
|
|
var posX = tile.X * _state.TileSize + _state.TileSize / 2f;
|
|
var posY = tile.Y * _state.TileSize + _state.TileSize / 2f;
|
|
|
|
_spriteBatch.Draw(content, new Vector2(posX, posY),
|
|
null, Color.White, MathHelper.ToRadians(90 * tile.Rotation),
|
|
new Vector2(content.Width / 2, content.Height / 2), (float)_state.TileSize / content.Width,
|
|
SpriteEffects.None, 0);
|
|
}
|
|
}
|
|
|
|
private void DrawWalls()
|
|
{
|
|
for (var i = 0; i < _sessionData.Walls.Values.Count; i++)
|
|
{
|
|
var wall = _sessionData.Walls.Values.ElementAt(i);
|
|
var content = _wallsContent[$"{wall.ID}"];
|
|
var scale = _state.TileSize / (float)content.Height;
|
|
var offset = scale * content.Width / 2f;
|
|
var posX = wall.X * _state.TileSize;
|
|
var posY = wall.Y * _state.TileSize;
|
|
if (wall.Rotation == 1)
|
|
posX -= (int)offset;
|
|
else if (wall.Rotation == 0) posY += (int)offset;
|
|
_spriteBatch.Draw(content, new Vector2(posX, posY), null, Color.White,
|
|
MathHelper.ToRadians(90 * (wall.Rotation - 1)), new Vector2(0, 0), scale, SpriteEffects.None, 0);
|
|
}
|
|
}
|
|
|
|
private void EditNote(Note note)
|
|
{
|
|
_state.SelectedNote = new Note { X = note.X, Y = note.Y, Text = note.Text };
|
|
new NoteWindow(_communicationManager, note).ShowInModalWindow(_desktop, $" Note on {note.X}:{note.Y}");
|
|
}
|
|
|
|
private bool GetPointerVector(Point target, out Vector2[] points)
|
|
{
|
|
var offset = _state.TileSize / 2;
|
|
var leftBound = 200 + offset;
|
|
var topBound = 75 + offset;
|
|
var bottomBound = 25 + offset;
|
|
var rightBound = offset;
|
|
points = Array.Empty<Vector2>();
|
|
var center = new Point((Window.ClientBounds.Width + leftBound) / 2 - (int)_state.ViewportCenter.X,
|
|
Window.ClientBounds.Height / 2 - (int)_state.ViewportCenter.Y);
|
|
|
|
// center
|
|
var p1 = new Vector2(center.X, center.Y);
|
|
|
|
// point
|
|
var p2 = new Vector2(
|
|
target.X * _state.TileSize + offset,
|
|
target.Y * _state.TileSize + offset);
|
|
|
|
// top right
|
|
var p3 = new Vector2(
|
|
Window.ClientBounds.Width - _state.ViewportCenter.X - rightBound,
|
|
topBound - _state.ViewportCenter.Y);
|
|
|
|
//bottom right
|
|
var p4 = new Vector2(
|
|
Window.ClientBounds.Width - _state.ViewportCenter.X - rightBound,
|
|
Window.ClientBounds.Height - _state.ViewportCenter.Y - bottomBound);
|
|
|
|
var ua1 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) /
|
|
((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y));
|
|
|
|
p3 = new Vector2(leftBound - _state.ViewportCenter.X, topBound - _state.ViewportCenter.Y);
|
|
p4 = new Vector2(Window.ClientBounds.Width - _state.ViewportCenter.X, topBound - _state.ViewportCenter.Y);
|
|
var ua2 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) /
|
|
((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y));
|
|
|
|
p3 = new Vector2(leftBound - _state.ViewportCenter.X, topBound - _state.ViewportCenter.Y);
|
|
p4 = new Vector2(leftBound - _state.ViewportCenter.X,
|
|
Window.ClientBounds.Height - _state.ViewportCenter.Y - bottomBound);
|
|
var ua3 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) /
|
|
((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y));
|
|
|
|
p3 = new Vector2(leftBound - _state.ViewportCenter.X,
|
|
Window.ClientBounds.Height - _state.ViewportCenter.Y - bottomBound);
|
|
p4 = new Vector2(Window.ClientBounds.Width - _state.ViewportCenter.X,
|
|
Window.ClientBounds.Height - _state.ViewportCenter.Y - bottomBound);
|
|
var ua4 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) /
|
|
((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y));
|
|
|
|
var uas = new List<float> { ua1, ua2, ua3, ua4 };
|
|
if (uas.Any(u => u > 0 && u < 1))
|
|
{
|
|
var ua = uas.Where(u => u > 0 && u < 1).Min();
|
|
var i = uas.IndexOf(ua);
|
|
var x = p1.X + ua * (p2.X - p1.X);
|
|
var y = p1.Y + ua * (p2.Y - p1.Y);
|
|
|
|
switch (i)
|
|
{
|
|
case 0:
|
|
x += offset;
|
|
points = new[]
|
|
{ new(x, y), new Vector2(x - 20, y - 10), new Vector2(x - 20, y + 10), new Vector2(x, y) };
|
|
break;
|
|
case 1:
|
|
y -= offset;
|
|
points = new[]
|
|
{ new(x, y), new Vector2(x - 10, y + 20), new Vector2(x + 10, y + 20), new Vector2(x, y) };
|
|
break;
|
|
case 2:
|
|
x -= offset;
|
|
points = new[]
|
|
{ new(x, y), new Vector2(x + 20, y + 10), new Vector2(x + 20, y - 10), new Vector2(x, y) };
|
|
break;
|
|
case 3:
|
|
y += offset;
|
|
points = new[]
|
|
{ new(x, y), new Vector2(x + 10, y - 20), new Vector2(x - 10, y - 20), new Vector2(x, y) };
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool IsMapElementOffscreen(BaseMapEntity item)
|
|
{
|
|
SnapPoint start, end;
|
|
|
|
switch (item)
|
|
{
|
|
case Line l:
|
|
start = l.Start;
|
|
end = l.End;
|
|
break;
|
|
|
|
case Room room:
|
|
start = room.Start;
|
|
end = room.End;
|
|
break;
|
|
default:
|
|
return true;
|
|
}
|
|
|
|
var visibleTilesX = GraphicsDevice.Viewport.Width / _state.TileSize + 1;
|
|
var visibleTilesY = GraphicsDevice.Viewport.Height / _state.TileSize + 1;
|
|
|
|
var screenPositionTopLeft =
|
|
new Point(200 - _state.TileSize + 0 * _state.TileSize - (int)_state.ViewportCenter.X,
|
|
0 * _state.TileSize + _state.TileSize - (int)_state.ViewportCenter.Y);
|
|
var screenPositionBottomRight = new Point(visibleTilesX * _state.TileSize - (int)_state.ViewportCenter.X,
|
|
visibleTilesY * _state.TileSize - 20 - (int)_state.ViewportCenter.Y);
|
|
var tileTopLeft = new Point(screenPositionTopLeft.X / _state.TileSize,
|
|
screenPositionTopLeft.Y / _state.TileSize);
|
|
var tileBottomRight = new Point(screenPositionBottomRight.X / _state.TileSize,
|
|
screenPositionBottomRight.Y / _state.TileSize);
|
|
|
|
if (start.X < tileTopLeft.X && start.Y < tileTopLeft.Y && start.X > tileBottomRight.X &&
|
|
start.Y > tileBottomRight.Y &&
|
|
end.X < tileTopLeft.X && end.Y < tileTopLeft.Y && end.X > tileBottomRight.X && end.Y > tileBottomRight.Y
|
|
)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
private bool IsOffscreen(Tile position)
|
|
{
|
|
var boxTL = new Point(200 - _state.TileSize / 2, 75 - _state.TileSize / 2);
|
|
var boxBR = new Point(GraphicsDevice.Viewport.Width + _state.TileSize / 2,
|
|
GraphicsDevice.Viewport.Height - 25 + _state.TileSize / 2);
|
|
|
|
var tileTL = new Point(position.X * _state.TileSize + (int)_state.ViewportCenter.X,
|
|
position.Y * _state.TileSize + (int)_state.ViewportCenter.Y);
|
|
var tileBR = new Point(position.X * _state.TileSize + (int)_state.ViewportCenter.X + _state.TileSize,
|
|
position.Y * _state.TileSize + (int)_state.ViewportCenter.Y + _state.TileSize);
|
|
|
|
return tileTL.X <= boxTL.X || tileTL.Y <= boxTL.Y || tileBR.X >= boxBR.X || tileBR.Y >= boxBR.Y;
|
|
}
|
|
|
|
private void OnClientSizeChanged(object sender, EventArgs e)
|
|
{
|
|
_renderTarget?.Dispose();
|
|
try
|
|
{
|
|
ResetRenderTarget();
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("rendertarget dispose exception");
|
|
}
|
|
}
|
|
|
|
private void OnContextMenuDeleteNoteClick(object sender, EventArgs e)
|
|
{
|
|
_desktop.HideContextMenu();
|
|
_sessionData.DeleteNote(_state.SelectedNote);
|
|
}
|
|
|
|
private void OnContextMenuNewNoteClick(object sender, EventArgs e)
|
|
{
|
|
_desktop.HideContextMenu();
|
|
new NoteWindow(_communicationManager, new Note()).ShowInModalWindow(_desktop,
|
|
$" Note on {_state.HoveredTile.X}:{_state.HoveredTile.Y}");
|
|
}
|
|
|
|
private void OnContextMenuPingClick(object sender, EventArgs e, Tile location)
|
|
{
|
|
_desktop.HideContextMenu();
|
|
_communicationManager.Ping(location).SafeFireAndForget();
|
|
}
|
|
|
|
private void OnContextMenuViewNoteClick(object sender, EventArgs e)
|
|
{
|
|
_desktop.HideContextMenu();
|
|
EditNote(_state.SelectedNote);
|
|
}
|
|
|
|
private async Task OnHubDisconnected(Exception arg)
|
|
{
|
|
// ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Hub disconnected", Type = "SignalR Client Events", Source = _settings.MachineName });
|
|
_mainWidget.lblConnectionStatus.Text = "Disconnected";
|
|
await Task.Yield();
|
|
}
|
|
|
|
private async Task OnHubReconnected(string arg)
|
|
{
|
|
// ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Hub reconnected", Type = "SignalR Client Events", Source = _settings.MachineName });
|
|
_mainWidget.lblConnectionStatus.Text = "Connected";
|
|
await Task.Yield();
|
|
}
|
|
|
|
private async Task OnHubReconnecting(Exception arg)
|
|
{
|
|
// ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Reconnecting Hub", Type = "SignalR Client Events", Source = _settings.MachineName });
|
|
_mainWidget.lblConnectionStatus.Text = "Reconnecting";
|
|
await Task.Yield();
|
|
}
|
|
|
|
private void OnOverlayButtonClicked(object sender, EventArgs e)
|
|
{
|
|
_state.CurrentOverlayId = ((ImageButton)sender).Id;
|
|
_mainWidget.ClearSelection();
|
|
((ImageButton)sender).Border = new SolidBrush(Color.Red);
|
|
((ImageButton)sender).BorderThickness = new Thickness(2);
|
|
_state.InsertMode = InsertMode.Overlay;
|
|
}
|
|
|
|
private void OnTileButtonTouchEntered(object sender, EventArgs e)
|
|
{
|
|
var mouseState = Mouse.GetState().Position;
|
|
mouseState.X += 10;
|
|
mouseState.Y += 10;
|
|
_lblOverlayName.Visible = true;
|
|
_lblOverlayName.Text = ((ImageButton)sender).Id;
|
|
_desktop.ShowContextMenu(_lblOverlayName, mouseState);
|
|
}
|
|
|
|
private void OnTileButtonTouchLeft(object sender, EventArgs e)
|
|
{
|
|
_desktop.HideContextMenu();
|
|
_lblOverlayName.Visible = false;
|
|
}
|
|
|
|
private void OnTxtOverlaySearchChange(object sender, ValueChangedEventArgs<string> e)
|
|
{
|
|
AddItemToToolGrid(_mainWidget.GridOverlays, OnOverlayButtonClicked, _spriteSheet, e.NewValue);
|
|
}
|
|
|
|
private void OnWallButtonClicked(object sender, EventArgs e)
|
|
{
|
|
_state.CurrentWallId = ((ImageButton)sender).Id;
|
|
_mainWidget.ClearSelection();
|
|
((ImageButton)sender).Border = new SolidBrush(Color.Red);
|
|
((ImageButton)sender).BorderThickness = new Thickness(2);
|
|
_state.InsertMode = InsertMode.Wall;
|
|
}
|
|
|
|
private void ResetRenderTarget()
|
|
{
|
|
_renderTarget = new RenderTarget2D(GraphicsDevice,
|
|
GraphicsDevice.Viewport.Width,
|
|
GraphicsDevice.Viewport.Height,
|
|
false,
|
|
SurfaceFormat.Color,
|
|
DepthFormat.None,
|
|
0,
|
|
RenderTargetUsage.DiscardContents);
|
|
}
|
|
}
|
|
} |