more refactoring
This commit is contained in:
parent
d61f46d07a
commit
886d2a88b0
13 changed files with 592 additions and 573 deletions
|
@ -15,12 +15,8 @@ namespace SignalRChat.Hubs
|
||||||
{
|
{
|
||||||
public class SledgemapperHub : Hub<ISledgemapperClient>
|
public class SledgemapperHub : Hub<ISledgemapperClient>
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
public SledgemapperHub() { }
|
||||||
private readonly MyDbContext _dbcontext;
|
private static Dictionary<string, Session> _sessions = new Dictionary<string, Session>();
|
||||||
|
|
||||||
// public SledgemapperHub(IMediator mediator) => _mediator = mediator;
|
|
||||||
public SledgemapperHub(MyDbContext dbcontext, IMediator mediator) { _dbcontext = dbcontext; _mediator = mediator; }
|
|
||||||
private static Dictionary<string, SessionData> _sessions = new Dictionary<string, SessionData>();
|
|
||||||
public List<string> Colors = new List<string>{"CC0000",
|
public List<string> Colors = new List<string>{"CC0000",
|
||||||
"CC3300",
|
"CC3300",
|
||||||
"FFCC00",
|
"FFCC00",
|
||||||
|
@ -33,86 +29,86 @@ namespace SignalRChat.Hubs
|
||||||
|
|
||||||
public async Task NewTile(string sessionName, Tile tile)
|
public async Task NewTile(string sessionName, Tile tile)
|
||||||
{
|
{
|
||||||
var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
// var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||||
|
|
||||||
|
|
||||||
var existingTile = _sessions[sessionName].Map.TryGetValue(tile.ToString(), out var t);
|
// var existingTile = _sessions[sessionName].Map.TryGetValue(tile.ToString(), out var t);
|
||||||
if (existingTile)
|
// if (existingTile)
|
||||||
{
|
// {
|
||||||
_sessions[sessionName].Map.TryRemove(t.ToString(), out var rtile);
|
// _sessions[sessionName].Map.TryRemove(t.ToString(), out var rtile);
|
||||||
}
|
// }
|
||||||
_sessions[sessionName].Map.TryAdd(tile.ToString(), tile);
|
// _sessions[sessionName].Map.TryAdd(tile.ToString(), tile);
|
||||||
|
|
||||||
var jsonString = JsonSerializer.Serialize<Tile>(tile);
|
// var jsonString = JsonSerializer.Serialize<Tile>(tile);
|
||||||
|
|
||||||
_dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog
|
// _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog
|
||||||
{
|
// {
|
||||||
Operation = "N",
|
// Operation = "N",
|
||||||
SessionName = sessionName,
|
// SessionName = sessionName,
|
||||||
Type = "T",
|
// Type = "T",
|
||||||
Timestamp = timestamp,
|
// Timestamp = timestamp,
|
||||||
Object = jsonString
|
// Object = jsonString
|
||||||
});
|
// });
|
||||||
await _dbcontext.SaveChangesAsync();
|
// await _dbcontext.SaveChangesAsync();
|
||||||
|
|
||||||
await Clients.Group(sessionName).NewTile(tile);
|
await Clients.Group(sessionName).NewTile(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task NewWall(string sessionName, Wall tile)
|
public async Task NewWall(string sessionName, Wall tile)
|
||||||
{
|
{
|
||||||
var existingTile = _sessions[sessionName].Walls.TryGetValue(tile.ToString(), out var t);
|
// var existingTile = _sessions[sessionName].Walls.TryGetValue(tile.ToString(), out var t);
|
||||||
if (existingTile)
|
// if (existingTile)
|
||||||
{
|
// {
|
||||||
_sessions[sessionName].Walls.TryRemove(t.ToString(), out var rtile);
|
// _sessions[sessionName].Walls.TryRemove(t.ToString(), out var rtile);
|
||||||
}
|
// }
|
||||||
_sessions[sessionName].Walls.TryAdd(tile.ToString(), tile);
|
// _sessions[sessionName].Walls.TryAdd(tile.ToString(), tile);
|
||||||
await Clients.Group(sessionName).NewWall(tile);
|
await Clients.Group(sessionName).NewWall(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task NewOverlay(string sessionName, Overlay tile)
|
public async Task NewOverlay(string sessionName, Overlay tile)
|
||||||
{
|
{
|
||||||
var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
// var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||||
var existingTile = _sessions[sessionName].Overlays.TryGetValue(tile.ToString(), out var t);
|
// var existingTile = _sessions[sessionName].Overlays.TryGetValue(tile.ToString(), out var t);
|
||||||
if (existingTile)
|
// if (existingTile)
|
||||||
{
|
// {
|
||||||
_sessions[sessionName].Overlays.TryRemove(t.ToString(), out var rtile);
|
// _sessions[sessionName].Overlays.TryRemove(t.ToString(), out var rtile);
|
||||||
}
|
// }
|
||||||
_sessions[sessionName].Overlays.TryAdd(tile.ToString(), tile);
|
// _sessions[sessionName].Overlays.TryAdd(tile.ToString(), tile);
|
||||||
var jsonString = JsonSerializer.Serialize<Overlay>(tile);
|
// var jsonString = JsonSerializer.Serialize<Overlay>(tile);
|
||||||
|
|
||||||
_dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog
|
// _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog
|
||||||
{
|
// {
|
||||||
Operation = "N",
|
// Operation = "N",
|
||||||
SessionName = sessionName,
|
// SessionName = sessionName,
|
||||||
Type = "O",
|
// Type = "O",
|
||||||
Timestamp = timestamp,
|
// Timestamp = timestamp,
|
||||||
Object = jsonString
|
// Object = jsonString
|
||||||
});
|
// });
|
||||||
await _dbcontext.SaveChangesAsync();
|
// await _dbcontext.SaveChangesAsync();
|
||||||
await Clients.Group(sessionName).NewOverlay(tile);
|
await Clients.Group(sessionName).NewOverlay(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteTile(string sessionName, Tile tile)
|
public async Task DeleteTile(string sessionName, Tile tile)
|
||||||
{
|
{
|
||||||
_sessions[sessionName].Map.TryRemove(tile.ToString(), out var rtile);
|
// _sessions[sessionName].Map.TryRemove(tile.ToString(), out var rtile);
|
||||||
await Clients.Group(sessionName).DeleteTile(tile);
|
await Clients.Group(sessionName).DeleteTile(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteWall(string sessionName, Wall tile)
|
public async Task DeleteWall(string sessionName, Wall tile)
|
||||||
{
|
{
|
||||||
_sessions[sessionName].Walls.TryRemove(tile.ToString(), out var rtile);
|
//_sessions[sessionName].Walls.TryRemove(tile.ToString(), out var rtile);
|
||||||
await Clients.Group(sessionName).DeleteWall(tile);
|
await Clients.Group(sessionName).DeleteWall(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteOverlay(string sessionName, Overlay tile)
|
public async Task DeleteOverlay(string sessionName, Overlay tile)
|
||||||
{
|
{
|
||||||
_sessions[sessionName].Overlays.TryRemove(tile.ToString(), out var rtile);
|
//_sessions[sessionName].Overlays.TryRemove(tile.ToString(), out var rtile);
|
||||||
await Clients.Group(sessionName).DeleteOverlay(tile);
|
await Clients.Group(sessionName).DeleteOverlay(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SessionData> NewSession(string sessionName, string initials)
|
public async Task<Session> NewSession(string sessionName, string initials)
|
||||||
{
|
{
|
||||||
var session = new SessionData();
|
var session = new Session();
|
||||||
session.Colors = new List<string>(Colors);
|
session.Colors = new List<string>(Colors);
|
||||||
session.Colors.Shuffle();
|
session.Colors.Shuffle();
|
||||||
var player = new Player { Position = new Tile { X = 0, Y = 0 }, ConnectionId = Context.ConnectionId, Color = session.Colors[0], Initials = initials };
|
var player = new Player { Position = new Tile { X = 0, Y = 0 }, ConnectionId = Context.ConnectionId, Color = session.Colors[0], Initials = initials };
|
||||||
|
@ -124,7 +120,7 @@ namespace SignalRChat.Hubs
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SessionData> JoinSession(string sessionName, string initials)
|
public async Task<Session> JoinSession(string sessionName, string initials)
|
||||||
{
|
{
|
||||||
if (_sessions.ContainsKey(sessionName))
|
if (_sessions.ContainsKey(sessionName))
|
||||||
{
|
{
|
||||||
|
@ -148,12 +144,12 @@ namespace SignalRChat.Hubs
|
||||||
await Clients.Group(sessionName).PlayerUpdate(player);
|
await Clients.Group(sessionName).PlayerUpdate(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SessionData> Refresh(string sessionName)
|
public async Task<Session> Refresh(string sessionName)
|
||||||
{
|
{
|
||||||
return _sessions[sessionName];
|
return _sessions[sessionName];
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Sync(string sessionName, SessionData map)
|
public async Task Sync(string sessionName, Session map)
|
||||||
{
|
{
|
||||||
_sessions[sessionName].Map = map.Map;
|
_sessions[sessionName].Map = map.Map;
|
||||||
_sessions[sessionName].Overlays = map.Overlays;
|
_sessions[sessionName].Overlays = map.Overlays;
|
||||||
|
|
|
@ -14,6 +14,6 @@ namespace Sledgemapper.Clients
|
||||||
Task DeleteOverlay(Overlay overlay);
|
Task DeleteOverlay(Overlay overlay);
|
||||||
Task NewPlayer(Player player);
|
Task NewPlayer(Player player);
|
||||||
Task PlayerUpdate(Player player);
|
Task PlayerUpdate(Player player);
|
||||||
Task UpdateMap(SessionData player);
|
Task UpdateMap(Session player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
namespace Sledgemapper.Shared.Entities
|
namespace Sledgemapper.Shared.Entities
|
||||||
{
|
{
|
||||||
public class Overlay
|
public class Overlay :BaseMapEntity
|
||||||
{
|
{
|
||||||
public int X { get; set; }
|
|
||||||
public int Y { get; set; }
|
|
||||||
public string ID { get; set; }
|
|
||||||
public bool Intersection { get; set; }
|
public bool Intersection { get; set; }
|
||||||
public int Rotation { get; set; }
|
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,52 +4,24 @@ using System;
|
||||||
|
|
||||||
namespace Sledgemapper.Shared.Entities
|
namespace Sledgemapper.Shared.Entities
|
||||||
{
|
{
|
||||||
public class TileAddedEventArgs : EventArgs
|
public class MapEntityAddedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public Tile Tile { get; set; }
|
public BaseMapEntity MapEntity { get; private set; }
|
||||||
public TileAddedEventArgs(Tile tile) => Tile = tile;
|
public MapEntityAddedEventArgs(BaseMapEntity mapEntity) => MapEntity = mapEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OverlayAddedEventArgs : EventArgs
|
public class MapEntityDeletedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public Overlay Overlay { get; set; }
|
public BaseMapEntity MapEntity { get; private set; }
|
||||||
public OverlayAddedEventArgs(Overlay overlay) => Overlay = overlay;
|
public MapEntityDeletedEventArgs(BaseMapEntity mapEntity) => MapEntity = mapEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WallAddedEventArgs : EventArgs
|
public class Session
|
||||||
{
|
{
|
||||||
public Wall Wall { get; set; }
|
public event EventHandler<MapEntityAddedEventArgs> MapEntityAdded;
|
||||||
public WallAddedEventArgs(Wall wall) => Wall = wall;
|
public event EventHandler<MapEntityDeletedEventArgs> MapEntityDeleted;
|
||||||
}
|
|
||||||
|
|
||||||
public class WallDeletedEventArgs : EventArgs
|
public Session()
|
||||||
{
|
|
||||||
public Wall Wall { get; set; }
|
|
||||||
public WallDeletedEventArgs(Wall wall) => Wall = wall;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OverlayDeletedEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public Overlay Overlay { get; set; }
|
|
||||||
public OverlayDeletedEventArgs(Overlay overlay) => Overlay = overlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TileDeletedEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public Tile Tile { get; set; }
|
|
||||||
public TileDeletedEventArgs(Tile tile) => Tile = tile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SessionData
|
|
||||||
{
|
|
||||||
public event EventHandler<TileAddedEventArgs> TileAdded;
|
|
||||||
public event EventHandler<OverlayAddedEventArgs> OverlayAdded;
|
|
||||||
public event EventHandler<WallAddedEventArgs> WallAdded;
|
|
||||||
public event EventHandler<WallDeletedEventArgs> WallDeleted;
|
|
||||||
public event EventHandler<OverlayDeletedEventArgs> OverlayDeleted;
|
|
||||||
public event EventHandler<TileDeletedEventArgs> TileDeleted;
|
|
||||||
|
|
||||||
public SessionData()
|
|
||||||
{
|
{
|
||||||
Map = new ConcurrentDictionary<string, Tile>();
|
Map = new ConcurrentDictionary<string, Tile>();
|
||||||
Overlays = new ConcurrentDictionary<string, Overlay>();
|
Overlays = new ConcurrentDictionary<string, Overlay>();
|
||||||
|
@ -64,6 +36,7 @@ namespace Sledgemapper.Shared.Entities
|
||||||
public bool IsValid { get; set; }
|
public bool IsValid { get; set; }
|
||||||
public List<Player> Players { get; set; }
|
public List<Player> Players { get; set; }
|
||||||
public List<string> Colors;
|
public List<string> Colors;
|
||||||
|
public string SessionName { get; set; }
|
||||||
|
|
||||||
public void NewTile(Tile selectedTile, string tileId)
|
public void NewTile(Tile selectedTile, string tileId)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +57,7 @@ namespace Sledgemapper.Shared.Entities
|
||||||
}
|
}
|
||||||
|
|
||||||
Map.TryAdd(newTile.ToString(), newTile);
|
Map.TryAdd(newTile.ToString(), newTile);
|
||||||
OnRaiseTileAddedEvent(new TileAddedEventArgs(newTile));
|
OnRaiseMapEntityAddedEvent(new MapEntityAddedEventArgs(newTile));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NewOverlay(Overlay selectedOverlay, string overlayId)
|
public void NewOverlay(Overlay selectedOverlay, string overlayId)
|
||||||
|
@ -105,7 +78,7 @@ namespace Sledgemapper.Shared.Entities
|
||||||
}
|
}
|
||||||
|
|
||||||
Overlays.TryAdd(newOverlay.ToString(), newOverlay);
|
Overlays.TryAdd(newOverlay.ToString(), newOverlay);
|
||||||
OnRaiseOverlayAddedEvent(new OverlayAddedEventArgs(newOverlay));
|
OnRaiseMapEntityAddedEvent(new MapEntityAddedEventArgs(newOverlay));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NewWall(Wall selectedWall, string wallId)
|
public void NewWall(Wall selectedWall, string wallId)
|
||||||
|
@ -122,7 +95,7 @@ namespace Sledgemapper.Shared.Entities
|
||||||
}
|
}
|
||||||
|
|
||||||
Walls.TryAdd(newWall.ToString(), newWall);
|
Walls.TryAdd(newWall.ToString(), newWall);
|
||||||
OnRaiseWallAddedEvent(new WallAddedEventArgs(newWall));
|
OnRaiseMapEntityAddedEvent(new MapEntityAddedEventArgs(newWall));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteWall(Wall wall)
|
public void DeleteWall(Wall wall)
|
||||||
|
@ -134,82 +107,48 @@ namespace Sledgemapper.Shared.Entities
|
||||||
var removed = Walls.TryRemove(wall.ToString(), out var _);
|
var removed = Walls.TryRemove(wall.ToString(), out var _);
|
||||||
if (removed)
|
if (removed)
|
||||||
{
|
{
|
||||||
OnRaiseWallDeletedEvent(new WallDeletedEventArgs(wall));
|
OnRaiseMapEntityDeletedEvent(new MapEntityDeletedEventArgs(wall));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteOverlay(Overlay overlay)
|
public void DeleteOverlay(Overlay overlay)
|
||||||
{
|
{
|
||||||
if (overlay is null)
|
if (overlay is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var removed = Overlays.TryRemove(overlay.ToString(), out var _);
|
var removed = Overlays.TryRemove(overlay.ToString(), out var _);
|
||||||
if (removed)
|
if (removed)
|
||||||
{
|
{
|
||||||
OnRaiseOverlayDeletedEvent(new OverlayDeletedEventArgs(overlay));
|
OnRaiseMapEntityDeletedEvent(new MapEntityDeletedEventArgs(overlay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteTile(Tile tile)
|
public void DeleteTile(Tile tile)
|
||||||
{
|
{
|
||||||
if (tile is null)
|
if (tile is null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var removed = Map.TryRemove(tile.ToString(), out var _);
|
var removed = Map.TryRemove(tile.ToString(), out var _);
|
||||||
if (removed)
|
if (removed)
|
||||||
{
|
{
|
||||||
OnRaiseTileDeletedEvent(new TileDeletedEventArgs(tile));
|
OnRaiseMapEntityDeletedEvent(new MapEntityDeletedEventArgs(tile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnRaiseTileAddedEvent(TileAddedEventArgs e)
|
protected virtual void OnRaiseMapEntityAddedEvent(MapEntityAddedEventArgs e)
|
||||||
{
|
{
|
||||||
var raiseEvent = TileAdded;
|
var raiseEvent = MapEntityAdded;
|
||||||
if (raiseEvent != null)
|
if (raiseEvent != null)
|
||||||
{
|
{
|
||||||
raiseEvent(this, e);
|
raiseEvent(this, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnRaiseOverlayAddedEvent(OverlayAddedEventArgs e)
|
protected virtual void OnRaiseMapEntityDeletedEvent(MapEntityDeletedEventArgs e)
|
||||||
{
|
{
|
||||||
var raiseEvent = OverlayAdded;
|
var raiseEvent = MapEntityDeleted;
|
||||||
if (raiseEvent != null)
|
|
||||||
{
|
|
||||||
raiseEvent(this, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnRaiseWallAddedEvent(WallAddedEventArgs e)
|
|
||||||
{
|
|
||||||
var raiseEvent = WallAdded
|
|
||||||
;
|
|
||||||
if (raiseEvent != null)
|
|
||||||
{
|
|
||||||
raiseEvent(this, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected virtual void OnRaiseWallDeletedEvent(WallDeletedEventArgs e)
|
|
||||||
{
|
|
||||||
var raiseEvent = WallDeleted;
|
|
||||||
if (raiseEvent != null)
|
|
||||||
{
|
|
||||||
raiseEvent(this, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected virtual void OnRaiseOverlayDeletedEvent(OverlayDeletedEventArgs e)
|
|
||||||
{
|
|
||||||
var raiseEvent = OverlayDeleted;
|
|
||||||
if (raiseEvent != null)
|
|
||||||
{
|
|
||||||
raiseEvent(this, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protected virtual void OnRaiseTileDeletedEvent(TileDeletedEventArgs e)
|
|
||||||
{
|
|
||||||
var raiseEvent = TileDeleted;
|
|
||||||
if (raiseEvent != null)
|
if (raiseEvent != null)
|
||||||
{
|
{
|
||||||
raiseEvent(this, e);
|
raiseEvent(this, e);
|
|
@ -1,18 +1,19 @@
|
||||||
namespace Sledgemapper.Shared.Entities
|
namespace Sledgemapper.Shared.Entities
|
||||||
{
|
{
|
||||||
|
public abstract class BaseMapEntity
|
||||||
|
{
|
||||||
public class Tile
|
public int X { get; set; }
|
||||||
{
|
|
||||||
public int X { get; set; }
|
|
||||||
public int Y { get; set; }
|
public int Y { get; set; }
|
||||||
public string ID { get; set; }
|
public string ID { get; set; }
|
||||||
public int Rotation { get; set; }
|
public int Rotation { get; set; }
|
||||||
|
public override string ToString()
|
||||||
public override string ToString()
|
|
||||||
{
|
{
|
||||||
return $"{X}_{Y}";
|
return $"{X}_{Y}";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Tile :BaseMapEntity
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,10 @@
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public class Wall
|
public class Wall :BaseMapEntity
|
||||||
{
|
{
|
||||||
public int X { get; set; }
|
|
||||||
public int Y { get; set; }
|
|
||||||
public string ID { get; set; }
|
|
||||||
public int Rotation { get; set; }
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"{X}_{Y}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
Sledgemapper/ChannelsQueue.cs
Normal file
40
Sledgemapper/ChannelsQueue.cs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Threading.Channels;
|
||||||
|
|
||||||
|
namespace Sledgemapper
|
||||||
|
{
|
||||||
|
public class ChannelsQueue
|
||||||
|
{
|
||||||
|
private readonly ChannelWriter<Action> _writer;
|
||||||
|
|
||||||
|
public ChannelsQueue()
|
||||||
|
{
|
||||||
|
var channel = Channel.CreateUnbounded<Action>(new UnboundedChannelOptions() { SingleReader = true });
|
||||||
|
var reader = channel.Reader;
|
||||||
|
_writer = channel.Writer;
|
||||||
|
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
while (await reader.WaitToReadAsync())
|
||||||
|
{
|
||||||
|
// Fast loop around available jobs
|
||||||
|
while (reader.TryRead(out var job))
|
||||||
|
{
|
||||||
|
job.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Enqueue(Action job)
|
||||||
|
{
|
||||||
|
_writer.TryWrite(job);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
_writer.Complete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
160
Sledgemapper/CommunicationManager.cs
Normal file
160
Sledgemapper/CommunicationManager.cs
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
|
using Polly;
|
||||||
|
using Refit;
|
||||||
|
using Sledgemapper.Shared.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Sledgemapper
|
||||||
|
{
|
||||||
|
public class CommunicationManager
|
||||||
|
{
|
||||||
|
public IMapApi Api { get; private set; }
|
||||||
|
public HubConnection Connection { get; private set; }
|
||||||
|
public Session SessionData;
|
||||||
|
private ChannelsQueue Queue = new ChannelsQueue();
|
||||||
|
|
||||||
|
public CommunicationManager(Session sessionData)
|
||||||
|
{
|
||||||
|
SessionData = sessionData;
|
||||||
|
Connection = new HubConnectionBuilder()
|
||||||
|
.WithAutomaticReconnect()
|
||||||
|
|
||||||
|
.WithUrl("http://localhost:5000/SledgemapperHub")
|
||||||
|
|
||||||
|
// .WithUrl("http://hub.michelescandura.com:5000/SledgemapperHub")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var httpClientHandler = new HttpClientHandler();
|
||||||
|
|
||||||
|
//if (myConfigurationService.VerifySslCertificate == false)
|
||||||
|
//{
|
||||||
|
httpClientHandler.ServerCertificateCustomValidationCallback =
|
||||||
|
(message, certificate, chain, sslPolicyErrors) => true;
|
||||||
|
//}
|
||||||
|
|
||||||
|
Api = RestService.For<IMapApi>(
|
||||||
|
new HttpClient(httpClientHandler)
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri("http://localhost:5000")
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Connection.On<Session>("UpdateMap", (map) =>
|
||||||
|
{
|
||||||
|
SessionData.Map = map.Map;
|
||||||
|
SessionData.Walls = map.Walls;
|
||||||
|
SessionData.Overlays = map.Overlays;
|
||||||
|
});
|
||||||
|
|
||||||
|
Connection.On<Player>("PlayerUpdate", (player) =>
|
||||||
|
{
|
||||||
|
var p = SessionData.Players.FirstOrDefault(m => m.ConnectionId == player.ConnectionId);
|
||||||
|
if (p != null)
|
||||||
|
{
|
||||||
|
p.Position = player.Position;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Connection.On<Tile>("DeleteTile", (tile) =>
|
||||||
|
{
|
||||||
|
SessionData.Map.Remove(tile.ToString(), out var _);
|
||||||
|
});
|
||||||
|
|
||||||
|
Connection.On<Wall>("DeleteWall", (tile) =>
|
||||||
|
{
|
||||||
|
SessionData.Walls.Remove(tile.ToString(), out var _);
|
||||||
|
});
|
||||||
|
|
||||||
|
Connection.On<Overlay>("DeleteOverlay", (tile) =>
|
||||||
|
{
|
||||||
|
SessionData.Overlays.Remove(tile.ToString(), out var _);
|
||||||
|
});
|
||||||
|
|
||||||
|
Connection.On<Tile>("NewTile", (tile) =>
|
||||||
|
{
|
||||||
|
SessionData.Map.Remove(tile.ToString(), out var _);
|
||||||
|
SessionData.Map.TryAdd(tile.ToString(), tile);
|
||||||
|
});
|
||||||
|
|
||||||
|
Connection.On<Wall>("NewWall", (tile) =>
|
||||||
|
{
|
||||||
|
SessionData.Walls.Remove(tile.ToString(), out var _);
|
||||||
|
SessionData.Walls.TryAdd(tile.ToString(), tile);
|
||||||
|
});
|
||||||
|
|
||||||
|
Connection.On<Overlay>("NewOverlay", (tile) =>
|
||||||
|
{
|
||||||
|
SessionData.Overlays.Remove(tile.ToString(), out var _);
|
||||||
|
SessionData.Overlays.TryAdd(tile.ToString(), tile);
|
||||||
|
});
|
||||||
|
|
||||||
|
Connection.On<Player>("NewPlayer", (player) =>
|
||||||
|
{
|
||||||
|
var p = SessionData.Players.FirstOrDefault(m => m.ConnectionId == player.ConnectionId);
|
||||||
|
if (p is null)
|
||||||
|
{
|
||||||
|
SessionData.Players.Add(player);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.Color = player.Color;
|
||||||
|
p.Position = player.Position;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Execute(Func<Task> call)
|
||||||
|
{
|
||||||
|
await Policy
|
||||||
|
.Handle<ApiException>(ex => ex.StatusCode == HttpStatusCode.RequestTimeout)
|
||||||
|
.RetryForeverAsync()
|
||||||
|
//.RetryAsync(Polly.RetrySyntax., async (exception, retryCount) => await Task.Delay(500))
|
||||||
|
.ExecuteAsync(async () => await call().ConfigureAwait(false))
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Enqueue(BaseMapEntity entity, TileAction action)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case TileAction.Add:
|
||||||
|
switch (entity)
|
||||||
|
{
|
||||||
|
case Tile tile:
|
||||||
|
Queue.Enqueue(async () => await Execute(async () => await Api.NewTile(tile, SessionData.SessionName)));
|
||||||
|
break;
|
||||||
|
case Overlay overlay:
|
||||||
|
Queue.Enqueue(async () => await Execute(async () => await Api.NewOverlay(overlay, SessionData.SessionName)));
|
||||||
|
break;
|
||||||
|
case Wall wall:
|
||||||
|
Queue.Enqueue(async () => await Execute(async () => await Api.NewWall(wall, SessionData.SessionName)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TileAction.Delete:
|
||||||
|
switch (entity)
|
||||||
|
{
|
||||||
|
case Tile tile:
|
||||||
|
Queue.Enqueue(async () => await Execute(async () => await Api.DeleteTile(tile, SessionData.SessionName)));
|
||||||
|
break;
|
||||||
|
case Overlay overlay:
|
||||||
|
Queue.Enqueue(async () => await Execute(async () => await Api.DeleteOverlay(overlay, SessionData.SessionName)));
|
||||||
|
break;
|
||||||
|
case Wall wall:
|
||||||
|
Queue.Enqueue(async () => await Execute(async () => await Api.DeleteWall(wall, SessionData.SessionName)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
@ -12,44 +12,23 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using Sledgemapper.Shared.Entities;
|
using Sledgemapper.Shared.Entities;
|
||||||
using Refit;
|
|
||||||
using System.Net.Http;
|
|
||||||
using Polly.Retry;
|
|
||||||
using Polly.Timeout;
|
|
||||||
using Polly;
|
|
||||||
using Polly.Extensions.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace Sledgemapper
|
namespace Sledgemapper
|
||||||
{
|
{
|
||||||
public class Sledgemapper : Game
|
public class Sledgemapper : Game
|
||||||
{
|
{
|
||||||
|
private CommunicationManager _communicationManager;
|
||||||
|
private State _state;
|
||||||
private GraphicsDeviceManager _graphics;
|
private GraphicsDeviceManager _graphics;
|
||||||
private SpriteBatch _spriteBatch;
|
private SpriteBatch _spriteBatch;
|
||||||
private Tile _selectedTile = new Tile { X = 1, Y = 1 };
|
|
||||||
private Tile _hoveredTile = new Tile { X = 1, Y = 1 };
|
|
||||||
private Wall _selectedWall = new Wall { X = 1, Y = 1 };
|
|
||||||
private Overlay _selectedOverlay = new Overlay { X = 1, Y = 1 };
|
|
||||||
private int _tileSize = 30;
|
|
||||||
private HubConnection connection;
|
|
||||||
private AsyncRetryPolicy<HttpResponseMessage> retryPolicy;
|
|
||||||
private AsyncTimeoutPolicy<HttpResponseMessage> timeoutPolicy;
|
|
||||||
private readonly Desktop _desktop;
|
private readonly Desktop _desktop;
|
||||||
private string _currentTileId = "";
|
|
||||||
private string _currentWallId = "";
|
|
||||||
private string _currentOverlayId = "";
|
|
||||||
private InsertMode _insertMode;
|
|
||||||
private string _session;
|
|
||||||
private KeyboardState oldState;
|
private KeyboardState oldState;
|
||||||
private MouseState oldMouseState;
|
private MouseState oldMouseState;
|
||||||
private Vector3 _viewportCenter = new Vector3(0, 0, 0);
|
private Vector3 _viewportCenter = new Vector3(0, 0, 0);
|
||||||
private SpriteFont font;
|
private SpriteFont font;
|
||||||
private Dictionary<string, SpriteFont> _fonts;
|
private Dictionary<string, SpriteFont> _fonts;
|
||||||
private SessionData _sessionData;
|
private Session _sessionData;
|
||||||
private IMapApi _api;
|
|
||||||
|
|
||||||
public Sledgemapper()
|
public Sledgemapper()
|
||||||
{
|
{
|
||||||
|
@ -57,118 +36,19 @@ namespace Sledgemapper
|
||||||
Content.RootDirectory = "Content";
|
Content.RootDirectory = "Content";
|
||||||
_desktop = new Desktop();
|
_desktop = new Desktop();
|
||||||
MyraEnvironment.Game = this;
|
MyraEnvironment.Game = this;
|
||||||
_sessionData = new SessionData();
|
_sessionData = new Session();
|
||||||
IsFixedTimeStep = false;
|
IsFixedTimeStep = false;
|
||||||
|
_communicationManager = new CommunicationManager(_sessionData);
|
||||||
|
_state = new State();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
// TODO: Add your initialization logic here
|
|
||||||
IsMouseVisible = true;
|
IsMouseVisible = true;
|
||||||
Window.AllowUserResizing = true;
|
Window.AllowUserResizing = true;
|
||||||
Players = new List<Player>();
|
|
||||||
connection = new HubConnectionBuilder()
|
|
||||||
.WithAutomaticReconnect()
|
|
||||||
|
|
||||||
.WithUrl("http://localhost:5000/SledgemapperHub")
|
|
||||||
|
|
||||||
// .WithUrl("http://hub.michelescandura.com:5000/SledgemapperHub")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
retryPolicy = HttpPolicyExtensions
|
|
||||||
.HandleTransientHttpError()
|
|
||||||
.Or<TimeoutRejectedException>() // Thrown by Polly's TimeoutPolicy if the inner call gets timeout.
|
|
||||||
.WaitAndRetryAsync(2, _ => TimeSpan.FromMilliseconds(500));
|
|
||||||
|
|
||||||
timeoutPolicy = Policy
|
|
||||||
.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromMilliseconds(500));
|
|
||||||
|
|
||||||
var httpClientHandler = new HttpClientHandler();
|
|
||||||
|
|
||||||
//if (myConfigurationService.VerifySslCertificate == false)
|
|
||||||
//{
|
|
||||||
httpClientHandler.ServerCertificateCustomValidationCallback =
|
|
||||||
(message, certificate, chain, sslPolicyErrors) => true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
_api = RestService.For<IMapApi>(
|
|
||||||
new HttpClient(httpClientHandler)
|
|
||||||
{
|
|
||||||
BaseAddress = new Uri("http://localhost:5000")
|
|
||||||
}
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
connection.On<SessionData>("UpdateMap", (map) =>
|
|
||||||
{
|
|
||||||
_sessionData.Map = map.Map;
|
|
||||||
_sessionData.Walls = map.Walls;
|
|
||||||
_sessionData.Overlays = map.Overlays;
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.On<Player>("PlayerUpdate", (player) =>
|
|
||||||
{
|
|
||||||
var p = Players.FirstOrDefault(m => m.ConnectionId == player.ConnectionId);
|
|
||||||
if (p != null)
|
|
||||||
{
|
|
||||||
p.Position = player.Position;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.On<Tile>("DeleteTile", (tile) =>
|
|
||||||
{
|
|
||||||
_sessionData.Map.Remove(tile.ToString(), out var _);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.On<Wall>("DeleteWall", (tile) =>
|
|
||||||
{
|
|
||||||
_sessionData.Walls.Remove(tile.ToString(), out var _);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.On<Overlay>("DeleteOverlay", (tile) =>
|
|
||||||
{
|
|
||||||
_sessionData.Overlays.Remove(tile.ToString(), out var _);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.On<Tile>("NewTile", (tile) =>
|
|
||||||
{
|
|
||||||
_sessionData.Map.Remove(tile.ToString(), out var _);
|
|
||||||
_sessionData.Map.TryAdd(tile.ToString(), tile);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.On<Wall>("NewWall", (tile) =>
|
|
||||||
{
|
|
||||||
_sessionData.Walls.Remove(tile.ToString(), out var _);
|
|
||||||
_sessionData.Walls.TryAdd(tile.ToString(), tile);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.On<Overlay>("NewOverlay", (tile) =>
|
|
||||||
{
|
|
||||||
_sessionData.Overlays.Remove(tile.ToString(), out var _);
|
|
||||||
_sessionData.Overlays.TryAdd(tile.ToString(), tile);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection.On<Player>("NewPlayer", (player) =>
|
|
||||||
{
|
|
||||||
var p = Players.FirstOrDefault(m => m.ConnectionId == player.ConnectionId);
|
|
||||||
if (p is null)
|
|
||||||
{
|
|
||||||
Players.Add(player);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p.Color = player.Color;
|
|
||||||
p.Position = player.Position;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Player> Players { get; set; }
|
|
||||||
|
|
||||||
private HorizontalMenu BuildMenu()
|
private HorizontalMenu BuildMenu()
|
||||||
{
|
{
|
||||||
var menu = new HorizontalMenu();
|
var menu = new HorizontalMenu();
|
||||||
|
@ -240,25 +120,27 @@ namespace Sledgemapper
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (connection.State != HubConnectionState.Connected)
|
if (_communicationManager.Connection.State != HubConnectionState.Connected)
|
||||||
{ await connection.StartAsync(); }
|
{ await _communicationManager.Connection.StartAsync(); }
|
||||||
var successful = false;
|
var successful = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await connection?.InvokeAsync<SessionData>("JoinSession", textbox.Text, initialsTextbox.Text);
|
var result = await _communicationManager.Connection?.InvokeAsync<Session>("JoinSession", textbox.Text, initialsTextbox.Text);
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
_sessionData.Map = result.Map;
|
_sessionData.Map = result.Map;
|
||||||
_sessionData.Walls = result.Walls;
|
_sessionData.Walls = result.Walls;
|
||||||
_sessionData.Overlays = result.Overlays;
|
_sessionData.Overlays = result.Overlays;
|
||||||
Players = result.Players;
|
_sessionData.Players = result.Players;
|
||||||
|
_sessionData.MapEntityAdded += OnMapEntityAdded;
|
||||||
|
|
||||||
}
|
}
|
||||||
successful = result != null; ;
|
successful = result != null; ;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
if (successful)
|
if (successful)
|
||||||
{
|
{
|
||||||
_session = textbox.Text;
|
_sessionData.SessionName = textbox.Text;
|
||||||
window.Close();
|
window.Close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -311,34 +193,30 @@ namespace Sledgemapper
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (connection.State != HubConnectionState.Connected)
|
if (_communicationManager.Connection.State != HubConnectionState.Connected)
|
||||||
{ await connection.StartAsync(); }
|
{ await _communicationManager.Connection.StartAsync(); }
|
||||||
var successful = false;
|
var successful = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var session = await connection?.InvokeAsync<SessionData>("NewSession", textbox.Text, initialsTextbox.Text);
|
var session = await _communicationManager.Connection?.InvokeAsync<Session>("NewSession", textbox.Text, initialsTextbox.Text);
|
||||||
if (session != null)
|
if (session != null)
|
||||||
{
|
{
|
||||||
_sessionData = session;
|
_sessionData = session;
|
||||||
session.TileAdded += OnTileAdded;
|
_sessionData.SessionName = textbox.Text;
|
||||||
session.OverlayAdded += OnOverlayAdded;
|
session.MapEntityAdded += OnMapEntityAdded;
|
||||||
session.WallAdded += OnWallAdded;
|
session.Players = session.Players;
|
||||||
session.TileDeleted += OnTileDeleted;
|
|
||||||
session.WallDeleted += OnWallDeleted;
|
|
||||||
session.OverlayDeleted += OnOverlayDeleted;
|
|
||||||
Players = session.Players;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
successful = session != null;
|
successful = session != null;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
if (successful)
|
if (successful)
|
||||||
{
|
{
|
||||||
_session = textbox.Text;
|
_sessionData.SessionName = textbox.Text;
|
||||||
|
_communicationManager.SessionData = _sessionData;
|
||||||
window.Close();
|
window.Close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -395,7 +273,7 @@ namespace Sledgemapper
|
||||||
using (StreamReader file = File.OpenText(dialog.FilePath))
|
using (StreamReader file = File.OpenText(dialog.FilePath))
|
||||||
{
|
{
|
||||||
JsonSerializer serializer = new JsonSerializer();
|
JsonSerializer serializer = new JsonSerializer();
|
||||||
_sessionData = (SessionData)serializer.Deserialize(file, typeof(SessionData));
|
_sessionData = (Session)serializer.Deserialize(file, typeof(Session));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -404,7 +282,7 @@ namespace Sledgemapper
|
||||||
|
|
||||||
private async void OnMenuConnectSyncSelected(object sender, EventArgs e)
|
private async void OnMenuConnectSyncSelected(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
await connection?.InvokeAsync("Sync", _session, _sessionData);
|
await _communicationManager.Connection?.InvokeAsync("Sync", _sessionData.SessionName, _sessionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadContent()
|
protected override void LoadContent()
|
||||||
|
@ -445,7 +323,7 @@ namespace Sledgemapper
|
||||||
var tileButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 };
|
var tileButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 };
|
||||||
tileButton.Click += (s, e) =>
|
tileButton.Click += (s, e) =>
|
||||||
{
|
{
|
||||||
_currentTileId = ((ImageButton)s).Id;
|
_state._currentTileId = ((ImageButton)s).Id;
|
||||||
|
|
||||||
ClearSelection(wallGrid);
|
ClearSelection(wallGrid);
|
||||||
ClearSelection(tileGrid);
|
ClearSelection(tileGrid);
|
||||||
|
@ -453,7 +331,7 @@ namespace Sledgemapper
|
||||||
|
|
||||||
((ImageButton)s).Border = new SolidBrush(Color.Red);
|
((ImageButton)s).Border = new SolidBrush(Color.Red);
|
||||||
((ImageButton)s).BorderThickness = new Myra.Graphics2D.Thickness(2);
|
((ImageButton)s).BorderThickness = new Myra.Graphics2D.Thickness(2);
|
||||||
_insertMode = InsertMode.Tile;
|
_state._insertMode = InsertMode.Tile;
|
||||||
};
|
};
|
||||||
tileGrid.Widgets.Add(tileButton);
|
tileGrid.Widgets.Add(tileButton);
|
||||||
indexY++;
|
indexY++;
|
||||||
|
@ -473,7 +351,7 @@ namespace Sledgemapper
|
||||||
var wallButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 };
|
var wallButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 };
|
||||||
wallButton.Click += (s, e) =>
|
wallButton.Click += (s, e) =>
|
||||||
{
|
{
|
||||||
_currentWallId = ((ImageButton)s).Id;
|
_state._currentWallId = ((ImageButton)s).Id;
|
||||||
ClearSelection(wallGrid);
|
ClearSelection(wallGrid);
|
||||||
ClearSelection(tileGrid);
|
ClearSelection(tileGrid);
|
||||||
ClearSelection(overlayGrid);
|
ClearSelection(overlayGrid);
|
||||||
|
@ -481,7 +359,7 @@ namespace Sledgemapper
|
||||||
|
|
||||||
((ImageButton)s).Border = new SolidBrush(Color.Red);
|
((ImageButton)s).Border = new SolidBrush(Color.Red);
|
||||||
((ImageButton)s).BorderThickness = new Myra.Graphics2D.Thickness(2);
|
((ImageButton)s).BorderThickness = new Myra.Graphics2D.Thickness(2);
|
||||||
_insertMode = InsertMode.Wall;
|
_state._insertMode = InsertMode.Wall;
|
||||||
|
|
||||||
};
|
};
|
||||||
wallGrid.Widgets.Add(wallButton);
|
wallGrid.Widgets.Add(wallButton);
|
||||||
|
@ -502,16 +380,14 @@ namespace Sledgemapper
|
||||||
var overlayButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 };
|
var overlayButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 };
|
||||||
overlayButton.Click += (s, e) =>
|
overlayButton.Click += (s, e) =>
|
||||||
{
|
{
|
||||||
_currentOverlayId = ((ImageButton)s).Id;
|
_state._currentOverlayId = ((ImageButton)s).Id;
|
||||||
ClearSelection(wallGrid);
|
ClearSelection(wallGrid);
|
||||||
ClearSelection(tileGrid);
|
ClearSelection(tileGrid);
|
||||||
ClearSelection(overlayGrid);
|
ClearSelection(overlayGrid);
|
||||||
|
|
||||||
|
|
||||||
((ImageButton)s).Border = new SolidBrush(Color.Red);
|
((ImageButton)s).Border = new SolidBrush(Color.Red);
|
||||||
((ImageButton)s).BorderThickness = new Myra.Graphics2D.Thickness(2);
|
((ImageButton)s).BorderThickness = new Myra.Graphics2D.Thickness(2);
|
||||||
_insertMode = InsertMode.Overlay;
|
_state._insertMode = InsertMode.Overlay;
|
||||||
|
|
||||||
};
|
};
|
||||||
overlayGrid.Widgets.Add(overlayButton);
|
overlayGrid.Widgets.Add(overlayButton);
|
||||||
indexY++;
|
indexY++;
|
||||||
|
@ -529,7 +405,7 @@ namespace Sledgemapper
|
||||||
_desktop.Root = mainPanel;
|
_desktop.Root = mainPanel;
|
||||||
// TODO: use this.Content to load your game content here
|
// TODO: use this.Content to load your game content here
|
||||||
}
|
}
|
||||||
bool _draw;
|
|
||||||
protected override void Update(GameTime gameTime)
|
protected override void Update(GameTime gameTime)
|
||||||
{
|
{
|
||||||
// if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
// if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
||||||
|
@ -542,55 +418,55 @@ namespace Sledgemapper
|
||||||
|
|
||||||
var screenPosition = new Point((mouseState.Position.X - (int)_viewportCenter.X), (mouseState.Position.Y - (int)_viewportCenter.Y));
|
var screenPosition = new Point((mouseState.Position.X - (int)_viewportCenter.X), (mouseState.Position.Y - (int)_viewportCenter.Y));
|
||||||
|
|
||||||
_hoveredTile.X = screenPosition.X / _tileSize;
|
_state._hoveredTile.X = screenPosition.X / _state._tileSize;
|
||||||
_hoveredTile.Y = screenPosition.Y / _tileSize;
|
_state._hoveredTile.Y = screenPosition.Y / _state._tileSize;
|
||||||
if (screenPosition.X < 0)
|
if (screenPosition.X < 0)
|
||||||
{
|
{
|
||||||
_hoveredTile.X--;
|
_state._hoveredTile.X--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screenPosition.Y < 0)
|
if (screenPosition.Y < 0)
|
||||||
{
|
{
|
||||||
_hoveredTile.Y--;
|
_state._hoveredTile.Y--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_insertMode == InsertMode.Wall)
|
if (_state._insertMode == InsertMode.Wall)
|
||||||
{
|
{
|
||||||
SelectClosestWall(screenPosition);
|
_state.SelectClosestWall(screenPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_insertMode == InsertMode.Overlay)
|
if (_state._insertMode == InsertMode.Overlay)
|
||||||
{
|
{
|
||||||
SelectOverlay(screenPosition);
|
_state.SelectOverlay(screenPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouseState.LeftButton == ButtonState.Pressed && mouseState.LeftButton != oldMouseState.LeftButton)
|
if (mouseState.LeftButton == ButtonState.Pressed && mouseState.LeftButton != oldMouseState.LeftButton)
|
||||||
{
|
{
|
||||||
_selectedTile.X = _hoveredTile.X;
|
_state._selectedTile.X = _state._hoveredTile.X;
|
||||||
_selectedTile.Y = _hoveredTile.Y;
|
_state._selectedTile.Y = _state._hoveredTile.Y;
|
||||||
connection?.SendAsync("UpdatePosition", _session, _selectedTile);
|
_communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _state._selectedTile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newState.IsKeyDown(Keys.LeftControl)
|
if (newState.IsKeyDown(Keys.LeftControl)
|
||||||
&& mouseState.LeftButton == ButtonState.Pressed
|
&& mouseState.LeftButton == ButtonState.Pressed
|
||||||
&& ((mouseState.LeftButton != oldMouseState.LeftButton) || (_selectedTile.X != _hoveredTile.X && _selectedTile.Y != _hoveredTile.Y)))
|
&& ((mouseState.LeftButton != oldMouseState.LeftButton) || (_state._selectedTile.X != _state._hoveredTile.X && _state._selectedTile.Y != _state._hoveredTile.Y)))
|
||||||
{
|
{
|
||||||
switch (_insertMode)
|
switch (_state._insertMode)
|
||||||
{
|
{
|
||||||
case InsertMode.Tile:
|
case InsertMode.Tile:
|
||||||
_selectedTile.X = _hoveredTile.X;
|
_state._selectedTile.X = _state._hoveredTile.X;
|
||||||
_selectedTile.Y = _hoveredTile.Y;
|
_state._selectedTile.Y = _state._hoveredTile.Y;
|
||||||
connection?.SendAsync("UpdatePosition", _session, _selectedTile);
|
_communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _state._selectedTile);
|
||||||
|
|
||||||
_sessionData.NewTile(_selectedTile, _currentTileId);
|
_sessionData.NewTile(_state._selectedTile, _state._currentTileId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InsertMode.Wall:
|
case InsertMode.Wall:
|
||||||
_sessionData.NewWall(_selectedWall, _currentWallId);
|
_sessionData.NewWall(_state._selectedWall, _state._currentWallId);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case InsertMode.Overlay:
|
case InsertMode.Overlay:
|
||||||
_sessionData.NewOverlay(_selectedOverlay, _currentOverlayId);
|
_sessionData.NewOverlay(_state._selectedOverlay, _state._currentOverlayId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,12 +480,12 @@ namespace Sledgemapper
|
||||||
{
|
{
|
||||||
if (mouseState.ScrollWheelValue > oldMouseState.ScrollWheelValue)
|
if (mouseState.ScrollWheelValue > oldMouseState.ScrollWheelValue)
|
||||||
{
|
{
|
||||||
_tileSize = System.Math.Min(120, _tileSize + 10);
|
_state._tileSize = Math.Min(120, _state._tileSize + 10);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (mouseState.ScrollWheelValue < oldMouseState.ScrollWheelValue)
|
else if (mouseState.ScrollWheelValue < oldMouseState.ScrollWheelValue)
|
||||||
{
|
{
|
||||||
_tileSize = System.Math.Max(10, _tileSize - 10);
|
_state._tileSize = Math.Max(10, _state._tileSize - 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,18 +495,18 @@ namespace Sledgemapper
|
||||||
|
|
||||||
if (newState.IsKeyDown(Keys.Delete))
|
if (newState.IsKeyDown(Keys.Delete))
|
||||||
{
|
{
|
||||||
switch (_insertMode)
|
switch (_state._insertMode)
|
||||||
{
|
{
|
||||||
case InsertMode.Tile:
|
case InsertMode.Tile:
|
||||||
_selectedTile.X = _hoveredTile.X;
|
_state._selectedTile.X = _state._hoveredTile.X;
|
||||||
_selectedTile.Y = _hoveredTile.Y;
|
_state._selectedTile.Y = _state._hoveredTile.Y;
|
||||||
_sessionData.DeleteTile(_selectedTile);
|
_sessionData.DeleteTile(_state._selectedTile);
|
||||||
break;
|
break;
|
||||||
case InsertMode.Wall:
|
case InsertMode.Wall:
|
||||||
_sessionData.DeleteWall(_selectedWall);
|
_sessionData.DeleteWall(_state._selectedWall);
|
||||||
break;
|
break;
|
||||||
case InsertMode.Overlay:
|
case InsertMode.Overlay:
|
||||||
_sessionData.DeleteOverlay(_selectedOverlay);
|
_sessionData.DeleteOverlay(_state._selectedOverlay);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,22 +517,22 @@ namespace Sledgemapper
|
||||||
{
|
{
|
||||||
case Keys.Left:
|
case Keys.Left:
|
||||||
if (oldState.IsKeyUp(Keys.Left) && newState.IsKeyDown(Keys.Left))
|
if (oldState.IsKeyUp(Keys.Left) && newState.IsKeyDown(Keys.Left))
|
||||||
{ _selectedTile.X--; }
|
{ _state._selectedTile.X--; }
|
||||||
break;
|
break;
|
||||||
case Keys.Right:
|
case Keys.Right:
|
||||||
if (oldState.IsKeyUp(Keys.Right) && newState.IsKeyDown(Keys.Right))
|
if (oldState.IsKeyUp(Keys.Right) && newState.IsKeyDown(Keys.Right))
|
||||||
{ _selectedTile.X++; }
|
{ _state._selectedTile.X++; }
|
||||||
break;
|
break;
|
||||||
case Keys.Up:
|
case Keys.Up:
|
||||||
if (oldState.IsKeyUp(Keys.Up) && newState.IsKeyDown(Keys.Up))
|
if (oldState.IsKeyUp(Keys.Up) && newState.IsKeyDown(Keys.Up))
|
||||||
{ _selectedTile.Y--; }
|
{ _state._selectedTile.Y--; }
|
||||||
break;
|
break;
|
||||||
case Keys.Down:
|
case Keys.Down:
|
||||||
if (oldState.IsKeyUp(Keys.Down) && newState.IsKeyDown(Keys.Down))
|
if (oldState.IsKeyUp(Keys.Down) && newState.IsKeyDown(Keys.Down))
|
||||||
{ _selectedTile.Y++; }
|
{ _state._selectedTile.Y++; }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
connection?.SendAsync("UpdatePosition", _session, _selectedTile);
|
_communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _state._selectedTile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,24 +548,57 @@ namespace Sledgemapper
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GraphicsDevice.Clear(Color.DarkGray);
|
GraphicsDevice.Clear(Color.DarkGray);
|
||||||
var sessionData = _sessionData;
|
|
||||||
|
|
||||||
// TODO: Add your drawing code here
|
// TODO: Add your drawing code here
|
||||||
var visibleTilesX = GraphicsDevice.Viewport.Width / _tileSize + 1;
|
var visibleTilesX = GraphicsDevice.Viewport.Width / _state._tileSize + 1;
|
||||||
var visibleTilesY = GraphicsDevice.Viewport.Height / _tileSize + 1;
|
var visibleTilesY = GraphicsDevice.Viewport.Height / _state._tileSize + 1;
|
||||||
|
|
||||||
_spriteBatch.Begin(transformMatrix: Matrix.CreateTranslation(_viewportCenter));
|
_spriteBatch.Begin(transformMatrix: Matrix.CreateTranslation(_viewportCenter));
|
||||||
|
|
||||||
|
DrawGrid(visibleTilesX, visibleTilesY);
|
||||||
|
DrawTiles();
|
||||||
|
DrawWalls();
|
||||||
|
DrawOverlays();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(_sessionData.SessionName))
|
||||||
|
{
|
||||||
|
_spriteBatch.DrawRectangle(new Rectangle(_state._selectedTile.X * _state._tileSize, _state._selectedTile.Y * _state._tileSize, _state._tileSize - 1, _state._tileSize - 1), Color.Red, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawPlayers();
|
||||||
|
|
||||||
|
var startWall = new Vector2(_state._selectedWall.X * _state._tileSize, _state._selectedWall.Y * _state._tileSize);
|
||||||
|
if (_state._insertMode == InsertMode.Wall)
|
||||||
|
{
|
||||||
|
_spriteBatch.DrawLine(startWall, _state._tileSize, MathHelper.ToRadians(90 * _state._selectedWall.Rotation), Color.Red, 2);
|
||||||
|
}
|
||||||
|
var overlay = new Vector2(_state._selectedOverlay.X * _state._tileSize, _state._selectedOverlay.Y * _state._tileSize);
|
||||||
|
if (_state._insertMode == InsertMode.Overlay)
|
||||||
|
{
|
||||||
|
if (_state._selectedOverlay.Intersection)
|
||||||
|
{
|
||||||
|
_spriteBatch.DrawCircle(overlay, _state._tileSize / 3, 100, Color.Red, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_spriteBatch.End();
|
||||||
|
|
||||||
|
_desktop?.Render();
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawGrid(int visibleTilesX, int visibleTilesY)
|
||||||
|
{
|
||||||
for (var i = -1; i < visibleTilesX + 2; i++)
|
for (var i = -1; i < visibleTilesX + 2; i++)
|
||||||
{
|
{
|
||||||
var posX1 = i * _tileSize - _viewportCenter.X;
|
var posX1 = i * _state._tileSize - _viewportCenter.X;
|
||||||
var posY1 = -_viewportCenter.Y;
|
var posY1 = -_viewportCenter.Y;
|
||||||
posX1 = posX1 - posX1 % _tileSize;
|
posX1 = posX1 - posX1 % _state._tileSize;
|
||||||
posY1 = posY1 - posY1 % _tileSize;
|
posY1 = posY1 - posY1 % _state._tileSize;
|
||||||
var posX2 = i * _tileSize - _viewportCenter.X;
|
var posX2 = i * _state._tileSize - _viewportCenter.X;
|
||||||
var posY2 = GraphicsDevice.Viewport.Height - _viewportCenter.Y;
|
var posY2 = GraphicsDevice.Viewport.Height - _viewportCenter.Y;
|
||||||
posX2 = posX2 - posX2 % _tileSize;
|
posX2 = posX2 - posX2 % _state._tileSize;
|
||||||
posY2 = posY2 - posY2 % _tileSize;
|
posY2 = posY2 - posY2 % _state._tileSize;
|
||||||
|
|
||||||
_spriteBatch.DrawLine(
|
_spriteBatch.DrawLine(
|
||||||
posX1, posY1,
|
posX1, posY1,
|
||||||
|
@ -701,41 +610,93 @@ namespace Sledgemapper
|
||||||
for (var i = -1; i < visibleTilesY + 2; i++)
|
for (var i = -1; i < visibleTilesY + 2; i++)
|
||||||
{
|
{
|
||||||
var posX1 = -_viewportCenter.X;
|
var posX1 = -_viewportCenter.X;
|
||||||
var posY1 = i * _tileSize - _viewportCenter.Y;
|
var posY1 = i * _state._tileSize - _viewportCenter.Y;
|
||||||
posX1 = posX1 - posX1 % _tileSize;
|
posX1 = posX1 - posX1 % _state._tileSize;
|
||||||
posY1 = posY1 - posY1 % _tileSize;
|
posY1 = posY1 - posY1 % _state._tileSize;
|
||||||
var posX2 = GraphicsDevice.Viewport.Width - _viewportCenter.X;
|
var posX2 = GraphicsDevice.Viewport.Width - _viewportCenter.X;
|
||||||
var posY2 = i * _tileSize - _viewportCenter.Y;
|
var posY2 = i * _state._tileSize - _viewportCenter.Y;
|
||||||
posX2 = posX2 - posX2 % _tileSize;
|
posX2 = posX2 - posX2 % _state._tileSize;
|
||||||
posY2 = posY2 - posY2 % _tileSize;
|
posY2 = posY2 - posY2 % _state._tileSize;
|
||||||
|
|
||||||
_spriteBatch.DrawLine(posX1, posY1,
|
_spriteBatch.DrawLine(posX1, posY1,
|
||||||
posX2,
|
posX2,
|
||||||
posY2,
|
posY2,
|
||||||
Color.Black);
|
Color.Black);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var tile in sessionData.Map.Values)
|
private void DrawTiles()
|
||||||
|
{
|
||||||
|
foreach (var tile in _sessionData.Map.Values)
|
||||||
{
|
{
|
||||||
|
|
||||||
var content = Content.Load<Texture2D>($"tiles/{tile.ID}");
|
var content = Content.Load<Texture2D>($"tiles/{tile.ID}");
|
||||||
var destinationRectangle = new Rectangle(tile.X * _tileSize, tile.Y * _tileSize, _tileSize, _tileSize);
|
|
||||||
|
|
||||||
var posX = tile.X * _tileSize + _tileSize / 2f;
|
var posX = tile.X * _state._tileSize + _state._tileSize / 2f;
|
||||||
var posY = tile.Y * _tileSize + _tileSize / 2f;
|
var posY = tile.Y * _state._tileSize + _state._tileSize / 2f;
|
||||||
|
|
||||||
_spriteBatch.Draw(content, new Vector2(posX, posY),
|
_spriteBatch.Draw(content, new Vector2(posX, posY),
|
||||||
null, Color.White, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_tileSize - 1) / content.Width, SpriteEffects.None, 0);
|
null, Color.White, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_state._tileSize - 1) / content.Width, SpriteEffects.None, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var wall in sessionData.Walls.Values)
|
private void DrawPlayers()
|
||||||
|
{
|
||||||
|
foreach (var player in _sessionData.Players.Copy<List<Player>>())
|
||||||
{
|
{
|
||||||
|
var hexs = player.Color.Split(2).ToArray();
|
||||||
|
var color = new Color(int.Parse(hexs[0], System.Globalization.NumberStyles.HexNumber),
|
||||||
|
int.Parse(hexs[1], System.Globalization.NumberStyles.HexNumber),
|
||||||
|
int.Parse(hexs[2], System.Globalization.NumberStyles.HexNumber));
|
||||||
|
_spriteBatch.DrawRectangle(new Rectangle(player.Position.X * _state._tileSize, player.Position.Y * _state._tileSize, _state._tileSize - 1, _state._tileSize - 1), color, 2);
|
||||||
|
|
||||||
|
var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state._tileSize).Value ?? _fonts.Last().Value;
|
||||||
|
|
||||||
|
var fscale = (float)_state._tileSize / ((float)ffont.LineSpacing * 2);
|
||||||
|
_spriteBatch.DrawString(ffont,
|
||||||
|
player.Initials,
|
||||||
|
new Vector2(player.Position.X * _state._tileSize + 2, player.Position.Y * _state._tileSize + _state._tileSize - 2 - ffont.LineSpacing * fscale),
|
||||||
|
color,
|
||||||
|
0,
|
||||||
|
Vector2.Zero,
|
||||||
|
fscale,
|
||||||
|
SpriteEffects.None,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawOverlays()
|
||||||
|
{
|
||||||
|
foreach (var tile in _sessionData.Overlays.Values)
|
||||||
|
{
|
||||||
|
var content = Content.Load<Texture2D>($"overlays/{tile.ID}");
|
||||||
|
if (tile.Intersection)
|
||||||
|
{
|
||||||
|
var posX = tile.X * _state._tileSize;
|
||||||
|
var posY = tile.Y * _state._tileSize;
|
||||||
|
|
||||||
|
_spriteBatch.Draw(content, new Vector2(posX, posY),
|
||||||
|
null, new Color(24, 118, 157), MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_state._tileSize - 10) / content.Width, SpriteEffects.None, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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, new Color(24, 118, 157), MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_state._tileSize - 10) / content.Width, SpriteEffects.None, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawWalls()
|
||||||
|
{
|
||||||
|
foreach (var wall in _sessionData.Walls.Values)
|
||||||
|
{
|
||||||
var content = Content.Load<Texture2D>($"walls/{wall.ID}");
|
var content = Content.Load<Texture2D>($"walls/{wall.ID}");
|
||||||
var scale = _tileSize / (float)content.Height;
|
var scale = _state._tileSize / (float)content.Height;
|
||||||
var offset = scale * content.Width / 2f;
|
var offset = scale * content.Width / 2f;
|
||||||
var posX = wall.X * _tileSize;
|
var posX = wall.X * _state._tileSize;
|
||||||
var posY = wall.Y * _tileSize;
|
var posY = wall.Y * _state._tileSize;
|
||||||
if (wall.Rotation == 1)
|
if (wall.Rotation == 1)
|
||||||
{
|
{
|
||||||
posX -= (int)offset;
|
posX -= (int)offset;
|
||||||
|
@ -744,82 +705,8 @@ namespace Sledgemapper
|
||||||
{
|
{
|
||||||
posY += (int)offset;
|
posY += (int)offset;
|
||||||
}
|
}
|
||||||
// _spriteBatch.Draw(content, new Vector2(posX, posY),null, Color.White, MathHelper.ToRadians(90 * (wall.Rotation - 1)), new Vector2(offset, 0), scale, SpriteEffects.None, 0);
|
|
||||||
_spriteBatch.Draw(content, new Vector2(posX, posY), null, Color.White, MathHelper.ToRadians(90 * (wall.Rotation - 1)), new Vector2(0, 0), scale, SpriteEffects.None, 0);
|
_spriteBatch.Draw(content, new Vector2(posX, posY), null, Color.White, MathHelper.ToRadians(90 * (wall.Rotation - 1)), new Vector2(0, 0), scale, SpriteEffects.None, 0);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var tile in sessionData.Overlays.Values)
|
|
||||||
{
|
|
||||||
|
|
||||||
var content = Content.Load<Texture2D>($"overlays/{tile.ID}");
|
|
||||||
// System.Console.WriteLine(tile.Rotation);
|
|
||||||
if (tile.Intersection)
|
|
||||||
{
|
|
||||||
var posX = tile.X * _tileSize;
|
|
||||||
var posY = tile.Y * _tileSize;
|
|
||||||
|
|
||||||
_spriteBatch.Draw(content, new Vector2(posX, posY),
|
|
||||||
null, new Color(24, 118, 157), MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_tileSize - 10) / content.Width, SpriteEffects.None, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var posX = tile.X * _tileSize + _tileSize / 2f;
|
|
||||||
var posY = tile.Y * _tileSize + _tileSize / 2f;
|
|
||||||
|
|
||||||
_spriteBatch.Draw(content, new Vector2(posX, posY),
|
|
||||||
null, new Color(24, 118, 157), MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_tileSize - 10) / content.Width, SpriteEffects.None, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(_session))
|
|
||||||
{
|
|
||||||
_spriteBatch.DrawRectangle(new Rectangle(_selectedTile.X * _tileSize, _selectedTile.Y * _tileSize, _tileSize - 1, _tileSize - 1), Color.Red, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var player in Players.Copy<List<Player>>())
|
|
||||||
{
|
|
||||||
|
|
||||||
var hexs = player.Color.Split(2).ToArray();
|
|
||||||
var color = new Color(int.Parse(hexs[0], System.Globalization.NumberStyles.HexNumber),
|
|
||||||
int.Parse(hexs[1], System.Globalization.NumberStyles.HexNumber),
|
|
||||||
int.Parse(hexs[2], System.Globalization.NumberStyles.HexNumber));
|
|
||||||
_spriteBatch.DrawRectangle(new Rectangle(player.Position.X * _tileSize, player.Position.Y * _tileSize, _tileSize - 1, _tileSize - 1), color, 2);
|
|
||||||
|
|
||||||
var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _tileSize).Value ?? _fonts.Last().Value;
|
|
||||||
|
|
||||||
var fscale = (float)_tileSize / ((float)ffont.LineSpacing * 2);
|
|
||||||
_spriteBatch.DrawString(ffont,
|
|
||||||
player.Initials,
|
|
||||||
new Vector2(player.Position.X * _tileSize + 2, player.Position.Y * _tileSize + _tileSize - 2 - ffont.LineSpacing * fscale),
|
|
||||||
color,
|
|
||||||
0,
|
|
||||||
Vector2.Zero,
|
|
||||||
fscale,
|
|
||||||
SpriteEffects.None,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
var startWall = new Vector2(_selectedWall.X * _tileSize, _selectedWall.Y * _tileSize);
|
|
||||||
if (_insertMode == InsertMode.Wall)
|
|
||||||
{
|
|
||||||
_spriteBatch.DrawLine(startWall, _tileSize, MathHelper.ToRadians(90 * _selectedWall.Rotation), Color.Red, 2);
|
|
||||||
}
|
|
||||||
var overlay = new Vector2(_selectedOverlay.X * _tileSize, _selectedOverlay.Y * _tileSize);
|
|
||||||
if (_insertMode == InsertMode.Overlay)
|
|
||||||
{
|
|
||||||
if (_selectedOverlay.Intersection)
|
|
||||||
{
|
|
||||||
_spriteBatch.DrawCircle(overlay, _tileSize / 3, 100, Color.Red, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_spriteBatch.End();
|
|
||||||
|
|
||||||
_desktop?.Render();
|
|
||||||
base.Draw(gameTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearSelection(Grid grid)
|
private void ClearSelection(Grid grid)
|
||||||
|
@ -830,136 +717,20 @@ namespace Sledgemapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float Sign(Point p1, Point p2, Point p3) { return (p1.X - p3.X) * (p2.Y - p3.Y) - (p2.X - p3.X) * (p1.Y - p3.Y); }
|
private void OnMapEntityAdded(object sender, MapEntityAddedEventArgs e)
|
||||||
|
|
||||||
private bool PointInTri(Point pt, Point v1, Point v2, Point v3)
|
|
||||||
{
|
{
|
||||||
bool b1, b2, b3;
|
_communicationManager.Enqueue(e.MapEntity, TileAction.Add);
|
||||||
b1 = Sign(pt, v1, v2) < 0.0f;
|
|
||||||
b2 = Sign(pt, v2, v3) < 0.0f;
|
|
||||||
b3 = Sign(pt, v3, v1) < 0.0f;
|
|
||||||
return ((b1 == b2) && (b2 == b3));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SelectClosestWall(Point mousePosition)
|
private void OnMapEntityDeleted(object sender, MapEntityDeletedEventArgs e)
|
||||||
{
|
{
|
||||||
var topLeft = new Point(_hoveredTile.X * _tileSize, _hoveredTile.Y * _tileSize);
|
_communicationManager.Enqueue(e.MapEntity, TileAction.Delete);
|
||||||
var bottomLeft = new Point(_hoveredTile.X * _tileSize, _hoveredTile.Y * _tileSize + _tileSize);
|
|
||||||
var topRight = new Point(_hoveredTile.X * _tileSize + _tileSize, _hoveredTile.Y * _tileSize);
|
|
||||||
var bottomRight = new Point(_hoveredTile.X * _tileSize + _tileSize, _hoveredTile.Y * _tileSize + _tileSize);
|
|
||||||
var center = new Point(_hoveredTile.X * _tileSize + _tileSize / 2, _hoveredTile.Y * _tileSize + _tileSize / 2);
|
|
||||||
var leftWall = PointInTri(mousePosition, topLeft, center, bottomLeft);
|
|
||||||
var rightWall = PointInTri(mousePosition, topRight, bottomRight, center);
|
|
||||||
var topWall = PointInTri(mousePosition, topLeft, topRight, center);
|
|
||||||
var bottomtWall = PointInTri(mousePosition, bottomLeft, center, bottomRight);
|
|
||||||
|
|
||||||
if (leftWall)
|
|
||||||
{
|
|
||||||
_selectedWall.X = _hoveredTile.X;
|
|
||||||
_selectedWall.Y = _hoveredTile.Y;
|
|
||||||
_selectedWall.Rotation = 1;
|
|
||||||
}
|
|
||||||
else if (rightWall)
|
|
||||||
{
|
|
||||||
_selectedWall.X = _hoveredTile.X + 1;
|
|
||||||
_selectedWall.Y = _hoveredTile.Y;
|
|
||||||
_selectedWall.Rotation = 1;
|
|
||||||
}
|
|
||||||
else if (topWall)
|
|
||||||
{
|
|
||||||
_selectedWall.X = _hoveredTile.X;
|
|
||||||
_selectedWall.Y = _hoveredTile.Y;
|
|
||||||
_selectedWall.Rotation = 0;
|
|
||||||
}
|
|
||||||
else if (bottomtWall)
|
|
||||||
{
|
|
||||||
_selectedWall.X = _hoveredTile.X;
|
|
||||||
_selectedWall.Y = _hoveredTile.Y + 1;
|
|
||||||
_selectedWall.Rotation = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SelectOverlay(Point mousePosition)
|
|
||||||
{
|
|
||||||
_selectedOverlay.X = _hoveredTile.X;
|
|
||||||
_selectedOverlay.Y = _hoveredTile.Y;
|
|
||||||
var q1 = System.Math.Pow(mousePosition.X - _hoveredTile.X * _tileSize, 2);
|
|
||||||
var q2 = System.Math.Pow((_hoveredTile.Y * _tileSize - mousePosition.Y), 2);
|
|
||||||
var s = System.Math.Sqrt(q1 + q2);
|
|
||||||
|
|
||||||
if (s < _tileSize / 3)
|
|
||||||
{
|
|
||||||
_selectedOverlay.Intersection = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
q1 = System.Math.Pow(mousePosition.X - (_hoveredTile.X + 1) * _tileSize, 2);
|
|
||||||
// var q2 = System.Math.Pow((_hoveredTile.Y * _tileSize - mousePosition.Y), 2);
|
|
||||||
s = System.Math.Sqrt(q1 + q2);
|
|
||||||
if (s < _tileSize / 3)
|
|
||||||
{
|
|
||||||
_selectedOverlay.X = _selectedOverlay.X + 1;
|
|
||||||
_selectedOverlay.Intersection = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//q1 = System.Math.Pow(mousePosition.X - (_hoveredTile.X + 1) * _tileSize, 2);
|
|
||||||
q2 = System.Math.Pow(((_hoveredTile.Y + 1) * _tileSize - mousePosition.Y), 2);
|
|
||||||
s = System.Math.Sqrt(q1 + q2);
|
|
||||||
if (s < _tileSize / 3)
|
|
||||||
{
|
|
||||||
_selectedOverlay.X = _selectedOverlay.X + 1;
|
|
||||||
_selectedOverlay.Y = _selectedOverlay.Y + 1;
|
|
||||||
_selectedOverlay.Intersection = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
q1 = System.Math.Pow(mousePosition.X - _hoveredTile.X * _tileSize, 2);
|
|
||||||
q2 = System.Math.Pow(((_hoveredTile.Y + 1) * _tileSize - mousePosition.Y), 2);
|
|
||||||
s = System.Math.Sqrt(q1 + q2);
|
|
||||||
if (s < _tileSize / 3)
|
|
||||||
{
|
|
||||||
_selectedOverlay.X = _selectedOverlay.X;
|
|
||||||
_selectedOverlay.Y = _selectedOverlay.Y + 1;
|
|
||||||
_selectedOverlay.Intersection = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_selectedOverlay.Intersection = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Execute(Func<Task> call)
|
|
||||||
{
|
|
||||||
await Policy
|
|
||||||
.Handle<ApiException>(ex => ex.StatusCode == HttpStatusCode.RequestTimeout)
|
|
||||||
.RetryAsync(5, async (exception, retryCount) => await Task.Delay(500))
|
|
||||||
.ExecuteAsync(async () => await call().ConfigureAwait(false))
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void OnOverlayAdded(object sender, OverlayAddedEventArgs e)
|
|
||||||
{
|
|
||||||
await Execute(() => _api.NewOverlay(e.Overlay, _session));
|
|
||||||
}
|
|
||||||
private void OnTileAdded(object sender, TileAddedEventArgs e)
|
|
||||||
{
|
|
||||||
_api.NewTile(e.Tile, _session);
|
|
||||||
}
|
|
||||||
private void OnWallAdded(object sender, WallAddedEventArgs e)
|
|
||||||
{
|
|
||||||
_api.NewWall(e.Wall, _session);
|
|
||||||
}
|
|
||||||
private void OnOverlayDeleted(object sender, OverlayDeletedEventArgs e)
|
|
||||||
{
|
|
||||||
_api.DeleteOverlay(e.Overlay, _session);
|
|
||||||
}
|
|
||||||
private void OnTileDeleted(object sender, TileDeletedEventArgs e)
|
|
||||||
{
|
|
||||||
_api.DeleteTile(e.Tile, _session);
|
|
||||||
}
|
|
||||||
private void OnWallDeleted(object sender, WallDeletedEventArgs e)
|
|
||||||
{
|
|
||||||
_api.DeleteWall(e.Wall, _session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum TileAction
|
||||||
|
{
|
||||||
|
Add,
|
||||||
|
Delete
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
<TrimmerRootAssembly Include="Microsoft.Xna.Framework.Content.ContentTypeReader" Visible="false" />
|
<TrimmerRootAssembly Include="Microsoft.Xna.Framework.Content.ContentTypeReader" Visible="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AsyncAwaitBestPractices" Version="5.0.2" />
|
||||||
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.0.1641" />
|
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.0.1641" />
|
||||||
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.0.1641" />
|
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.0.1641" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client">
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client">
|
||||||
|
|
100
Sledgemapper/State.cs
Normal file
100
Sledgemapper/State.cs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
|
using Sledgemapper.Shared.Entities;
|
||||||
|
|
||||||
|
namespace Sledgemapper
|
||||||
|
{
|
||||||
|
public class State
|
||||||
|
{
|
||||||
|
public Tile _selectedTile = new Tile { X = 1, Y = 1 };
|
||||||
|
public Tile _hoveredTile = new Tile { X = 1, Y = 1 };
|
||||||
|
public Wall _selectedWall = new Wall { X = 1, Y = 1 };
|
||||||
|
public Overlay _selectedOverlay = new Overlay { X = 1, Y = 1 };
|
||||||
|
public int _tileSize = 30;
|
||||||
|
public string _currentTileId = "";
|
||||||
|
public string _currentWallId = "";
|
||||||
|
public string _currentOverlayId = "";
|
||||||
|
public InsertMode _insertMode;
|
||||||
|
|
||||||
|
public void SelectClosestWall(Point mousePosition)
|
||||||
|
{
|
||||||
|
var topLeft = new Point(_hoveredTile.X * _tileSize, _hoveredTile.Y * _tileSize);
|
||||||
|
var bottomLeft = new Point(_hoveredTile.X * _tileSize, _hoveredTile.Y * _tileSize + _tileSize);
|
||||||
|
var topRight = new Point(_hoveredTile.X * _tileSize + _tileSize, _hoveredTile.Y * _tileSize);
|
||||||
|
var bottomRight = new Point(_hoveredTile.X * _tileSize + _tileSize, _hoveredTile.Y * _tileSize + _tileSize);
|
||||||
|
var center = new Point(_hoveredTile.X * _tileSize + _tileSize / 2, _hoveredTile.Y * _tileSize + _tileSize / 2);
|
||||||
|
|
||||||
|
if (Utils.PointInTri(mousePosition, topLeft, center, bottomLeft)) //left wall
|
||||||
|
{
|
||||||
|
_selectedWall.X = _hoveredTile.X;
|
||||||
|
_selectedWall.Y = _hoveredTile.Y;
|
||||||
|
_selectedWall.Rotation = 1;
|
||||||
|
}
|
||||||
|
else if (Utils.PointInTri(mousePosition, topRight, bottomRight, center)) //right wall
|
||||||
|
{
|
||||||
|
_selectedWall.X = _hoveredTile.X + 1;
|
||||||
|
_selectedWall.Y = _hoveredTile.Y;
|
||||||
|
_selectedWall.Rotation = 1;
|
||||||
|
}
|
||||||
|
else if (Utils.PointInTri(mousePosition, topLeft, topRight, center)) //top wall
|
||||||
|
{
|
||||||
|
_selectedWall.X = _hoveredTile.X;
|
||||||
|
_selectedWall.Y = _hoveredTile.Y;
|
||||||
|
_selectedWall.Rotation = 0;
|
||||||
|
}
|
||||||
|
else if (Utils.PointInTri(mousePosition, bottomLeft, center, bottomRight)) //bottom wall
|
||||||
|
{
|
||||||
|
_selectedWall.X = _hoveredTile.X;
|
||||||
|
_selectedWall.Y = _hoveredTile.Y + 1;
|
||||||
|
_selectedWall.Rotation = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void SelectOverlay(Point mousePosition)
|
||||||
|
{
|
||||||
|
_selectedOverlay.X = _hoveredTile.X;
|
||||||
|
_selectedOverlay.Y = _hoveredTile.Y;
|
||||||
|
var q1 = Math.Pow(mousePosition.X - _hoveredTile.X * _tileSize, 2);
|
||||||
|
var q2 = Math.Pow((_hoveredTile.Y * _tileSize - mousePosition.Y), 2);
|
||||||
|
var s = Math.Sqrt(q1 + q2);
|
||||||
|
|
||||||
|
if (s < _tileSize / 3)
|
||||||
|
{
|
||||||
|
_selectedOverlay.Intersection = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
q1 = Math.Pow(mousePosition.X - (_hoveredTile.X + 1) * _tileSize, 2);
|
||||||
|
s = Math.Sqrt(q1 + q2);
|
||||||
|
if (s < _tileSize / 3)
|
||||||
|
{
|
||||||
|
_selectedOverlay.X = _selectedOverlay.X + 1;
|
||||||
|
_selectedOverlay.Intersection = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//q1 = System.Math.Pow(mousePosition.X - (_hoveredTile.X + 1) * _tileSize, 2);
|
||||||
|
q2 = Math.Pow(((_hoveredTile.Y + 1) * _tileSize - mousePosition.Y), 2);
|
||||||
|
s = Math.Sqrt(q1 + q2);
|
||||||
|
if (s < _tileSize / 3)
|
||||||
|
{
|
||||||
|
_selectedOverlay.X = _selectedOverlay.X + 1;
|
||||||
|
_selectedOverlay.Y = _selectedOverlay.Y + 1;
|
||||||
|
_selectedOverlay.Intersection = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
q1 = Math.Pow(mousePosition.X - _hoveredTile.X * _tileSize, 2);
|
||||||
|
q2 = Math.Pow(((_hoveredTile.Y + 1) * _tileSize - mousePosition.Y), 2);
|
||||||
|
s = Math.Sqrt(q1 + q2);
|
||||||
|
if (s < _tileSize / 3)
|
||||||
|
{
|
||||||
|
_selectedOverlay.X = _selectedOverlay.X;
|
||||||
|
_selectedOverlay.Y = _selectedOverlay.Y + 1;
|
||||||
|
_selectedOverlay.Intersection = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedOverlay.Intersection = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
Sledgemapper/Utils.cs
Normal file
20
Sledgemapper/Utils.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Sledgemapper.Shared.Entities;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Sledgemapper
|
||||||
|
{
|
||||||
|
public static class Utils
|
||||||
|
{
|
||||||
|
private static float Sign(Point p1, Point p2, Point p3) { return (p1.X - p3.X) * (p2.Y - p3.Y) - (p2.X - p3.X) * (p1.Y - p3.Y); }
|
||||||
|
|
||||||
|
public static bool PointInTri(Point pt, Point v1, Point v2, Point v3)
|
||||||
|
{
|
||||||
|
bool b1, b2, b3;
|
||||||
|
b1 = Sign(pt, v1, v2) < 0.0f;
|
||||||
|
b2 = Sign(pt, v2, v3) < 0.0f;
|
||||||
|
b3 = Sign(pt, v3, v1) < 0.0f;
|
||||||
|
return ((b1 == b2) && (b2 == b3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue