1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-12-25 19:46:50 -05:00

Added player location and info message frames. Added camera focus and focus player message frame.

This commit is contained in:
Tim Sarbin 2018-12-01 12:10:16 -05:00
parent 1c5a0d3361
commit 99bf86a21e
14 changed files with 184 additions and 18 deletions

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OpenDiablo2.Common.Enums
namespace OpenDiablo2.Common.Enums
{
// TODO: I don't think this needs to live in core...
public enum eMessageFrameType
@ -13,6 +7,9 @@ namespace OpenDiablo2.Common.Enums
SetSeed = 0x01,
JoinGame = 0x02,
LocatePlayers = 0x03,
PlayerInfo = 0x04,
FocusOnPlayer = 0x05,
MAX = 0xFF, // NOTE:
// You absolutely cannot have a higher ID than this without

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Drawing;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces.MessageBus;
using OpenDiablo2.Common.Models;
namespace OpenDiablo2.Common.Interfaces
@ -14,6 +15,7 @@ namespace OpenDiablo2.Common.Interfaces
int Seed { get; }
string MapName { get; }
Palette CurrentPalette { get; }
IEnumerable<PlayerInfo> PlayerInfos { get; }
bool ToggleShowInventoryPanel();
bool ShowInventoryPanel { get; set; }

View File

@ -4,7 +4,7 @@ namespace OpenDiablo2.Common.Interfaces
{
public interface IMapEngine
{
int FocusedMobId { get; set; }
int FocusedPlayerId { get; set; }
PointF CameraLocation { get; set; }
void Update(long ms);
void Render();

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces.MessageBus;
@ -8,11 +7,15 @@ namespace OpenDiablo2.Common.Interfaces
public delegate void OnSetSeedEvent(int clientHash, int seed);
public delegate void OnJoinGameEvent(int clientHash, eHero heroType, string playerName);
public delegate void OnLocatePlayersEvent(int clientHash, IEnumerable<PlayerLocationDetails> playerLocationDetails);
public delegate void OnPlayerInfoEvent(int clientHash, IEnumerable<PlayerInfo> playerInfo);
public delegate void OnFocusOnPlayer(int clientHash, int playerId);
public interface ISessionEventProvider
{
OnSetSeedEvent OnSetSeed { get; set; }
OnJoinGameEvent OnJoinGame { get; set; }
OnLocatePlayersEvent OnLocatePlayers { get; set; }
OnPlayerInfoEvent OnPlayerInfo { get; set; }
OnFocusOnPlayer OnFocusOnPlayer { get; set; }
}
}

View File

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Models.Mobs;
namespace OpenDiablo2.Common.Interfaces.MessageBus
{
public sealed class PlayerInfo
{
public string Name { get; set; }
public eHero Hero { get; set; }
public PlayerLocationDetails LocationDetails { get; set; }
public byte[] GetBytes()
{
var result = new List<byte>();
var nameBytes = Encoding.UTF8.GetBytes(Name);
result.Add((byte)Hero);
result.AddRange(BitConverter.GetBytes((Int32)nameBytes.Length));
result.AddRange(nameBytes);
result.AddRange(LocationDetails.GetBytes());
return result.ToArray();
}
public static PlayerInfo FromBytes(byte[] data, int offset = 0)
{
var result = new PlayerInfo();
result.Hero = (eHero)data[offset];
var nameLength = BitConverter.ToInt32(data, offset + 1);
result.Name = Encoding.UTF8.GetString(data, offset + 5, nameLength);
result.LocationDetails = PlayerLocationDetails.FromBytes(data, offset + 5 + nameLength);
return result;
}
public int SizeInBytes => 5 + Encoding.UTF8.GetByteCount(Name) + PlayerLocationDetails.SizeInBytes;
}
public static class PlayerInfoExtensions
{
public static PlayerInfo ToPlayerInfo(this PlayerState source)
=> new PlayerInfo
{
Hero = source.HeroType,
LocationDetails = new PlayerLocationDetails
{
PlayerId = source.Id,
PlayerX = source.GetPosition().X,
PlayerY = source.GetPosition().Y
},
Name = source.Name
};
}
}

View File

@ -75,6 +75,7 @@
<Compile Include="Interfaces\MessageBus\IMessageFrame.cs" />
<Compile Include="Interfaces\MessageBus\ISessionManager.cs" />
<Compile Include="Interfaces\MessageBus\ISessionServer.cs" />
<Compile Include="Interfaces\MessageBus\PlayerInfo.cs" />
<Compile Include="Interfaces\MessageBus\PlayerLocationDetails.cs" />
<Compile Include="Interfaces\UI\IButton.cs" />
<Compile Include="Interfaces\UI\IPanelFrame.cs" />

View File

@ -31,6 +31,7 @@ namespace OpenDiablo2.Core.GameState_
public string MapName { get; private set; }
public Palette CurrentPalette => paletteProvider.PaletteTable[$"ACT{Act}"];
public IEnumerable<PlayerLocationDetails> PlayerLocationDetails { get; private set; } = new List<PlayerLocationDetails>();
public IEnumerable<PlayerInfo> PlayerInfos { get; private set; } = new List<PlayerInfo>();
public bool ShowInventoryPanel { get; set; } = false;
public bool ShowCharacterPanel { get; set; } = false;
@ -66,6 +67,8 @@ namespace OpenDiablo2.Core.GameState_
sessionManager.OnSetSeed += OnSetSeedEvent;
sessionManager.OnLocatePlayers += OnLocatePlayers;
sessionManager.OnPlayerInfo += OnPlayerInfo;
sessionManager.OnFocusOnPlayer += OnFocusOnPlayer;
mapInfo = new List<MapInfo>();
sceneManager.ChangeScene("Game");
@ -73,6 +76,12 @@ namespace OpenDiablo2.Core.GameState_
sessionManager.JoinGame(characterName, hero);
}
private void OnFocusOnPlayer(int clientHash, int playerId)
=> getMapEngine().FocusedPlayerId = playerId;
private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo)
=> this.PlayerInfos = playerInfo;
private void OnLocatePlayers(int clientHash, IEnumerable<PlayerLocationDetails> playerLocationDetails)
{
PlayerLocationDetails = playerLocationDetails;

View File

@ -1,5 +1,6 @@
using System;
using System.Drawing;
using System.Linq;
using OpenDiablo2.Common;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
@ -12,7 +13,7 @@ namespace OpenDiablo2.Core.Map_Engine
private readonly IRenderWindow renderWindow;
private readonly IResourceManager resourceManager;
public int FocusedMobId { get; set; } = -1;
public int FocusedPlayerId { get; set; } = 0;
private PointF cameraLocation = new PointF();
public PointF CameraLocation
@ -91,6 +92,15 @@ namespace OpenDiablo2.Core.Map_Engine
public void Update(long ms)
{
if (FocusedPlayerId != 0)
{
var player = gameState.PlayerInfos.FirstOrDefault(x => x.LocationDetails.PlayerId == FocusedPlayerId);
if (player != null)
{
// TODO: Maybe smooth movement? Maybe not?
CameraLocation = new PointF(player.LocationDetails.PlayerX, player.LocationDetails.PlayerY);
}
}
}

View File

@ -80,13 +80,10 @@ namespace OpenDiablo2.Scenes
public void Render()
{
/*
if (gameState.MapDirty)
RedrawMap();
// TODO: Maybe show some sort of connecting/loading message?
if (mapEngine.FocusedPlayerId == 0)
return;
for (int i = 0; i < gameState.MapData.Width * gameState.MapData.Height; i++)
renderWindow.Draw(testSprite[i]);
*/
mapEngine.Render();
DrawPanel();

View File

@ -0,0 +1,28 @@
using System;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
namespace OpenDiablo2.ServiceBus.Message_Frames.Server
{
[MessageFrame(eMessageFrameType.FocusOnPlayer)]
public sealed class MFFocusOnPlayer : IMessageFrame
{
public int PlayerToFocusOn { get; set; } = 0;
public byte[] Data
{
get => BitConverter.GetBytes((Int32)PlayerToFocusOn);
set => PlayerToFocusOn = BitConverter.ToInt32(value, 0);
}
public MFFocusOnPlayer() { }
public MFFocusOnPlayer(int playerId)
{
this.PlayerToFocusOn = playerId;
}
public void Process(int clientHash, ISessionEventProvider sessionEventProvider)
=> sessionEventProvider.OnFocusOnPlayer(clientHash, PlayerToFocusOn);
}
}

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Interfaces.MessageBus;
namespace OpenDiablo2.ServiceBus.Message_Frames.Server
{
[MessageFrame(eMessageFrameType.PlayerInfo)]
public sealed class MFPlayerInfo : IMessageFrame
{
public IEnumerable<PlayerInfo> PlayerInfos { get; set; } = new List<PlayerInfo>();
public byte[] Data
{
get
{
var result = BitConverter.GetBytes(PlayerInfos.Count())
.Concat(PlayerInfos.SelectMany(x => x.GetBytes()))
.ToArray();
return result;
}
set
{
var count = BitConverter.ToInt32(value, 0);
var playerInfos = new List<PlayerInfo>();
var offset = 4;
for (var i = 0; i < count; i++)
{
var playerInfo = PlayerInfo.FromBytes(value, offset);
playerInfos.Add(playerInfo);
offset += playerInfo.SizeInBytes;
}
PlayerInfos = playerInfos;
}
}
public MFPlayerInfo() { }
public MFPlayerInfo(IEnumerable<PlayerInfo> playerInfo)
{
this.PlayerInfos = playerInfo;
}
public void Process(int clientHash, ISessionEventProvider sessionEventProvider)
=> sessionEventProvider.OnPlayerInfo(clientHash, PlayerInfos);
}
}

View File

@ -59,6 +59,8 @@
<ItemGroup>
<Compile Include="AutofacModule.cs" />
<Compile Include="Message Frames\Client\MFJoinGame.cs" />
<Compile Include="Message Frames\Server\MFFocusOnPlayer.cs" />
<Compile Include="Message Frames\Server\MFPlayerInfo.cs" />
<Compile Include="Message Frames\Server\MFLocatePlayers.cs" />
<Compile Include="Message Frames\Server\MFSetSeed.cs" />
<Compile Include="SessionManager.cs" />

View File

@ -30,6 +30,8 @@ namespace OpenDiablo2.ServiceBus
public OnSetSeedEvent OnSetSeed { get; set; }
public OnJoinGameEvent OnJoinGame { get; set; }
public OnLocatePlayersEvent OnLocatePlayers { get; set; }
public OnPlayerInfoEvent OnPlayerInfo { get; set; }
public OnFocusOnPlayer OnFocusOnPlayer { get; set; }
public SessionManager(
eSessionType sessionType,
@ -128,7 +130,9 @@ namespace OpenDiablo2.ServiceBus
{
Send(new MFJoinGame(playerName, heroType));
ProcessMessageFrame<MFSetSeed>();
ProcessMessageFrame<MFPlayerInfo>();
ProcessMessageFrame<MFLocatePlayers>();
ProcessMessageFrame<MFFocusOnPlayer>();
});
}
}

View File

@ -28,6 +28,8 @@ namespace OpenDiablo2.ServiceBus
public OnSetSeedEvent OnSetSeed { get; set; }
public OnJoinGameEvent OnJoinGame { get; set; }
public OnLocatePlayersEvent OnLocatePlayers { get; set; }
public OnPlayerInfoEvent OnPlayerInfo { get; set; }
public OnFocusOnPlayer OnFocusOnPlayer { get; set; }
public SessionServer(
eSessionType sessionType,
@ -108,7 +110,9 @@ namespace OpenDiablo2.ServiceBus
{
gameServer.SpawnNewPlayer(clientHash, playerName, heroType);
Send(new MFSetSeed(gameServer.Seed), true);
Send(new MFLocatePlayers(gameServer.Players.Select(x => x.ToPlayerLocationDetails())));
Send(new MFPlayerInfo(gameServer.Players.Select(x => x.ToPlayerInfo())), true);
Send(new MFLocatePlayers(gameServer.Players.Select(x => x.ToPlayerLocationDetails())), true);
Send(new MFFocusOnPlayer(gameServer.Players.First(x => x.ClientHash == clientHash).Id));
}
}
}