1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-20 22:25:24 +00:00

Finished supporting player movement. Fixed seed bug.

This commit is contained in:
Tim Sarbin 2018-12-01 20:17:51 -05:00
parent f6d80c707c
commit 4a77e47ddd
21 changed files with 141 additions and 79 deletions

View File

@ -10,6 +10,7 @@ namespace OpenDiablo2.Common.Interfaces
IEnumerable<PlayerState> Players { get; }
int Seed { get; }
void Update(int ms);
void InitializeNewGame();
int SpawnNewPlayer(int clientHash, string playerName, eHero heroType);
}

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Drawing;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces.MessageBus;
using OpenDiablo2.Common.Models;
namespace OpenDiablo2.Common.Interfaces

View File

@ -1,6 +1,6 @@
using System.Collections.Generic;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces.MessageBus;
using OpenDiablo2.Common.Models;
namespace OpenDiablo2.Common.Interfaces
{
@ -9,7 +9,7 @@ namespace OpenDiablo2.Common.Interfaces
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 delegate void OnMoveRequest(int clientHash, int direction, eMovementType movementType);
public delegate void OnMoveRequest(int clientHash, byte direction, eMovementType movementType);
public interface ISessionEventProvider
{

View File

@ -16,6 +16,6 @@ namespace OpenDiablo2.Common.Interfaces
void Stop();
void JoinGame(string playerName, eHero heroType);
void MoveRequest(int direction, eMovementType movementType);
void MoveRequest(byte direction, eMovementType movementType);
}
}

View File

@ -11,8 +11,8 @@ namespace OpenDiablo2.Common.Models.Mobs
public readonly int Id;
public bool Alive { get; protected set; } = true;
protected float X = 0;
protected float Y = 0;
public float X { get; set; } = 0;
public float Y { get; set; } = 0;
protected Stat Health;

View File

@ -11,6 +11,8 @@ namespace OpenDiablo2.Common.Models.Mobs
private IHeroTypeConfig HeroTypeConfig;
private ILevelExperienceConfig ExperienceConfig;
public int ClientHash { get; protected set; }
public byte MovementDirection { get; set; } = 0;
public eMovementType MovementType { get; set; } = eMovementType.Stopped;
// Player character stats
protected Stat Vitality;

View File

@ -1,12 +1,10 @@
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
namespace OpenDiablo2.Common.Models
{
public sealed class PlayerInfo
{

View File

@ -1,22 +1,27 @@
using System;
using System.Collections.Generic;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Models.Mobs;
namespace OpenDiablo2.Common.Interfaces.MessageBus
namespace OpenDiablo2.Common.Models
{
public sealed class PlayerLocationDetails
{
public int PlayerId { get; set; }
public float PlayerX { get; set; }
public float PlayerY { get; set; }
public eMovementType MovementType { get; set; }
public int MovementDirection { get; set; }
// TODO: They may not be on the same 'anchor map'...
public byte[] GetBytes()
{
var result = new List<byte>();
result.AddRange(BitConverter.GetBytes(PlayerId));
result.AddRange(BitConverter.GetBytes(PlayerX));
result.AddRange(BitConverter.GetBytes(PlayerY));
result.AddRange(BitConverter.GetBytes((Int32)PlayerId));
result.AddRange(BitConverter.GetBytes((float)PlayerX));
result.AddRange(BitConverter.GetBytes((float)PlayerY));
result.AddRange(BitConverter.GetBytes((Int32)MovementDirection));
result.AddRange(BitConverter.GetBytes((byte)MovementType));
return result.ToArray();
}
@ -25,10 +30,12 @@ namespace OpenDiablo2.Common.Interfaces.MessageBus
{
PlayerId = BitConverter.ToInt32(data, offset + 0),
PlayerX = BitConverter.ToSingle(data, offset + 4),
PlayerY = BitConverter.ToSingle(data, offset + 8)
PlayerY = BitConverter.ToSingle(data, offset + 8),
MovementDirection = BitConverter.ToInt32(data, offset + 12),
MovementType = (eMovementType)data[offset + 16]
};
public static int SizeInBytes => 12;
public static int SizeInBytes => 17;
}
public static class PlayerLocationDetailsExtensions
@ -38,7 +45,9 @@ namespace OpenDiablo2.Common.Interfaces.MessageBus
{
PlayerId = source.Id,
PlayerX = source.GetPosition().X,
PlayerY = source.GetPosition().Y
PlayerY = source.GetPosition().Y,
MovementType = source.MovementType,
MovementDirection = source.MovementDirection
};
}
}

View File

@ -76,8 +76,8 @@
<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="Models\PlayerInfo.cs" />
<Compile Include="Models\PlayerLocationDetails.cs" />
<Compile Include="Interfaces\UI\IButton.cs" />
<Compile Include="Interfaces\UI\IPanelFrame.cs" />
<Compile Include="Interfaces\UI\IInventoryPanel.cs" />

View File

@ -4,7 +4,6 @@ using System.Drawing;
using System.Linq;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Interfaces.MessageBus;
using OpenDiablo2.Common.Models;
using OpenDiablo2.Core.Map_Engine;
@ -30,8 +29,7 @@ namespace OpenDiablo2.Core.GameState_
public int Act { get; private set; }
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 List<PlayerInfo> PlayerInfos { get; private set; } = new List<PlayerInfo>();
public bool ShowInventoryPanel { get; set; } = false;
public bool ShowCharacterPanel { get; set; } = false;
@ -40,6 +38,10 @@ namespace OpenDiablo2.Core.GameState_
public object ThreadLocker { get; } = new object();
IEnumerable<PlayerInfo> IGameState.PlayerInfos => PlayerInfos;
const double Deg2Rad = Math.PI / 180.0;
public GameState(
ISceneManager sceneManager,
IResourceManager resourceManager,
@ -80,11 +82,18 @@ namespace OpenDiablo2.Core.GameState_
=> getMapEngine().FocusedPlayerId = playerId;
private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo)
=> this.PlayerInfos = playerInfo;
=> this.PlayerInfos = playerInfo.ToList();
private void OnLocatePlayers(int clientHash, IEnumerable<PlayerLocationDetails> playerLocationDetails)
{
PlayerLocationDetails = playerLocationDetails;
foreach (var player in PlayerInfos)
{
var details = playerLocationDetails.FirstOrDefault(x => x.PlayerId == player.LocationDetails.PlayerId);
if (details == null)
continue;
player.LocationDetails = details;
}
}
private void OnSetSeedEvent(int clientHash, int seed)
@ -407,6 +416,24 @@ namespace OpenDiablo2.Core.GameState_
{
animationTime += ((float)ms / 1000f);
animationTime -= (float)Math.Truncate(animationTime);
var seconds = ms / 1000f;
foreach (var player in PlayerInfos)
UpdatePlayer(player, seconds);
}
private void UpdatePlayer(PlayerInfo player, float seconds)
{
if (player.LocationDetails.MovementType == eMovementType.Stopped)
return;
var rads = (float)player.LocationDetails.MovementDirection * 22 * (float)Deg2Rad;
var moveX = (float)Math.Cos(rads) * seconds * 2f;
var moveY = (float)Math.Sin(rads) * seconds * 2f;
player.LocationDetails.PlayerX += moveX;
player.LocationDetails.PlayerY += moveY;
}
public void Dispose()

View File

@ -16,6 +16,8 @@ namespace OpenDiablo2.GameServer_
public int Seed { get; private set; }
public IEnumerable<PlayerState> Players => mobManager.Players;
const double Deg2Rad = Math.PI / 180.0;
public GameServer(IMobManager mobManager)
{
this.mobManager = mobManager;
@ -36,6 +38,30 @@ namespace OpenDiablo2.GameServer_
return newPlayer.Id;
}
public void Update(int ms)
{
var seconds = (float)ms / 1000f;
foreach(var player in Players)
{
UpdatePlayerMovement(player, seconds);
}
}
private void UpdatePlayerMovement(PlayerState player, float seconds)
{
// TODO: We need to do collision detection here...
if (player.MovementType == eMovementType.Stopped)
return;
var rads = (float)player.MovementDirection * 22 * (float)Deg2Rad;
var moveX = (float)Math.Cos(rads) * seconds * 2f;
var moveY = (float)Math.Sin(rads) * seconds * 2f;
player.X += moveX;
player.Y += moveY;
}
public void Dispose()
{
}

View File

@ -1,5 +1,6 @@
using System;
using System.Drawing;
using System.Numerics;
using OpenDiablo2.Common;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
@ -31,10 +32,9 @@ namespace OpenDiablo2.Scenes
private bool showMinipanel = false;
private IButton runButton, menuButton;
private eMovementType lastMovementType = eMovementType.Stopped;
private int lastDirection = -1;
private byte lastDirection = 255;
const double Rad2Deg = 180.0 / Math.PI;
const double Deg2Rad = Math.PI / 180.0;
public Game(
IRenderWindow renderWindow,
@ -154,36 +154,6 @@ namespace OpenDiablo2.Scenes
menuButton.Update();
HandleMovement();
//var xMod = 0f;
//var yMod = 0f;
//if (keyboardInfoProvider.KeyIsPressed(80 /*left*/))
//{
// xMod = -8f * seconds;
//}
//if (keyboardInfoProvider.KeyIsPressed(79 /*right*/))
//{
// xMod = 8f * seconds;
//}
//if (keyboardInfoProvider.KeyIsPressed(81 /*down*/))
//{
// yMod = 10f * seconds;
//}
//if (keyboardInfoProvider.KeyIsPressed(82 /*up*/))
//{
// yMod = -10f * seconds;
//}
//if (xMod != 0f || yMod != 0f)
//{
// xMod *= .5f;
// yMod *= .5f;
// mapEngine.CameraLocation = new PointF(mapEngine.CameraLocation.X + xMod, mapEngine.CameraLocation.Y + yMod);
//}
mapEngine.Update(ms);
}
@ -203,19 +173,27 @@ namespace OpenDiablo2.Scenes
// TODO: Filter movement for inventory panel
var xOffset = (gameState.ShowInventoryPanel ? -200 : 0) + (gameState.ShowCharacterPanel ? 200 : 0);
var cursorDirection = (int)Math.Round(((Math.Atan2(300 - mouseInfoProvider.MouseY, mouseInfoProvider.MouseX - (400 + xOffset)) * Rad2Deg) + 180) / 32);
var mx = (mouseInfoProvider.MouseX - 400) - xOffset;
var my = (mouseInfoProvider.MouseY - 300);
if (mouseInfoProvider.LeftMouseDown && (lastMovementType == eMovementType.Stopped || lastDirection != cursorDirection))
var tx = (mx / 60f + my / 40f) / 2f;
var ty = (my / 40f - (mx / 60f)) / 2f;
var cursorDirection = (int)Math.Round(Math.Atan2(ty, tx) * Rad2Deg);
if (cursorDirection < 0)
cursorDirection += 360;
var actualDirection = (byte)(cursorDirection / 22);
if (mouseInfoProvider.LeftMouseDown && (lastMovementType == eMovementType.Stopped || lastDirection != actualDirection))
{
lastDirection = cursorDirection;
lastDirection = actualDirection;
lastMovementType = runButton.Toggled ? eMovementType.Running : eMovementType.Walking;
sessionManager.MoveRequest(cursorDirection, lastMovementType);
sessionManager.MoveRequest(actualDirection, lastMovementType);
}
else if (!mouseInfoProvider.LeftMouseDown && lastMovementType != eMovementType.Stopped)
{
lastDirection = cursorDirection;
lastDirection = actualDirection;
lastMovementType = eMovementType.Stopped;
sessionManager.MoveRequest(cursorDirection, lastMovementType);
sessionManager.MoveRequest(actualDirection, lastMovementType);
}
}

View File

@ -41,6 +41,10 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />

View File

@ -2,4 +2,5 @@
<packages>
<package id="Autofac" version="4.8.1" targetFramework="net461" />
<package id="log4net" version="2.0.8" targetFramework="net461" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" />
</packages>

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
@ -12,7 +7,7 @@ namespace OpenDiablo2.ServiceBus.Message_Frames.Client
[MessageFrame(eMessageFrameType.MoveRequest)]
public sealed class MFMoveRequest : IMessageFrame
{
public int Direction { get; set; } = 0;
public byte Direction { get; set; } = 0;
public eMovementType MovementType { get; set; } = eMovementType.Stopped;
public byte[] Data
@ -27,7 +22,7 @@ namespace OpenDiablo2.ServiceBus.Message_Frames.Client
public MFMoveRequest() { }
public MFMoveRequest(int direction, eMovementType movementType)
public MFMoveRequest(byte direction, eMovementType movementType)
{
this.Direction = direction;
this.MovementType = movementType;

View File

@ -4,7 +4,7 @@ using System.Linq;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Interfaces.MessageBus;
using OpenDiablo2.Common.Models;
namespace OpenDiablo2.ServiceBus.Message_Frames.Server
{

View File

@ -4,7 +4,7 @@ using System.Linq;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Interfaces.MessageBus;
using OpenDiablo2.Common.Models;
namespace OpenDiablo2.ServiceBus.Message_Frames.Server
{

View File

@ -12,7 +12,7 @@ namespace OpenDiablo2.ServiceBus.Message_Frames.Server
public byte[] Data
{
get => BitConverter.GetBytes(Seed);
set => BitConverter.ToInt32(value, 0);
set => Seed = BitConverter.ToInt32(value, 0);
}
public Int32 Seed { get; private set; }

View File

@ -145,11 +145,11 @@ namespace OpenDiablo2.ServiceBus
});
}
public void MoveRequest(int direction, eMovementType movementType)
public void MoveRequest(byte direction, eMovementType movementType)
=> Task.Run(() =>
{
Send(new MFMoveRequest(direction, movementType));
NoOp();
ProcessMessageFrame<MFLocatePlayers>();
});
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -7,7 +8,7 @@ using NetMQ.Sockets;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Interfaces.MessageBus;
using OpenDiablo2.Common.Models;
using OpenDiablo2.ServiceBus.Message_Frames.Server;
namespace OpenDiablo2.ServiceBus
@ -34,6 +35,8 @@ namespace OpenDiablo2.ServiceBus
public OnPlayerInfoEvent OnPlayerInfo { get; set; }
public OnFocusOnPlayer OnFocusOnPlayer { get; set; }
const int serverUpdateRate = 30;
public SessionServer(
eSessionType sessionType,
IGameServer gameServer,
@ -83,22 +86,41 @@ namespace OpenDiablo2.ServiceBus
});
running = true;
WaitServerStartEvent.Set();
Task.Run(() =>
{
var lastRun = DateTime.Now;
while(running)
{
var newTime = DateTime.Now;
var timeDiff = (newTime - lastRun).TotalMilliseconds;
lastRun = newTime;
gameServer.Update((int)timeDiff);
if (timeDiff < serverUpdateRate)
Thread.Sleep((int)Math.Min(serverUpdateRate, Math.Max(0, serverUpdateRate - timeDiff)));
}
});
resetEvent.WaitOne();
proactor.Dispose();
running = false;
responseSocket.Dispose();
log.Info("Session server has stopped.");
}
private void OnMovementRequestHandler(int clientHash, int direction, eMovementType movementType)
private void OnMovementRequestHandler(int clientHash, byte direction, eMovementType movementType)
{
// TODO: Actually move the player ....
var player = gameServer.Players.FirstOrDefault(x => x.ClientHash == clientHash);
if (player == null)
return;
log.Info($"Player {player.Id} requested to move in {direction} direction: {movementType.ToString()}");
NoOp();
// TODO: The server needs to actually manage player movement...
player.MovementDirection = direction;
player.MovementType = movementType;
player.MovementDirection = direction;
Send(new MFLocatePlayers(gameServer.Players.Select(x => x.ToPlayerLocationDetails())));
}
public void Stop()

View File

@ -5,7 +5,7 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2B0CF1AC-06DD-4322-AE8B-FF8A8C70A3CD}</ProjectGuid>
<OutputType>Exe</OutputType>
<OutputType>WinExe</OutputType>
<RootNamespace>OpenDiablo2</RootNamespace>
<AssemblyName>OpenDiablo2</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>