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

Added move request frame. Inventory and character panels now offset map rendering appropriately.

This commit is contained in:
Tim Sarbin 2018-12-01 15:22:55 -05:00
parent 99bf86a21e
commit f6d80c707c
14 changed files with 186 additions and 44 deletions

View File

@ -9,6 +9,8 @@
LocatePlayers = 0x03,
PlayerInfo = 0x04,
FocusOnPlayer = 0x05,
MoveRequest = 0x06,
PlayerMove = 0x07,
MAX = 0xFF, // NOTE:

View File

@ -0,0 +1,9 @@
namespace OpenDiablo2.Common.Enums
{
public enum eMovementType
{
Stopped,
Walking,
Running
}
}

View File

@ -9,6 +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 interface ISessionEventProvider
{
@ -17,5 +18,6 @@ namespace OpenDiablo2.Common.Interfaces
OnLocatePlayersEvent OnLocatePlayers { get; set; }
OnPlayerInfoEvent OnPlayerInfo { get; set; }
OnFocusOnPlayer OnFocusOnPlayer { get; set; }
OnMoveRequest OnMoveRequest { get; set; }
}
}

View File

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

View File

@ -30,6 +30,11 @@ namespace OpenDiablo2.Common.Interfaces
/// </summary>
bool Enabled { get; set; }
/// <summary>
/// If true, the button is pushed down, false otherwise. Only valid for toggle buttons.
/// </summary>
bool Toggled { get; }
/// <summary>
/// The position of the button on the screen.
/// </summary>

View File

@ -56,6 +56,7 @@
<Compile Include="Attributes\SceneAttribute.cs" />
<Compile Include="AutofacModule.cs" />
<Compile Include="Enums\eMessageFrameType.cs" />
<Compile Include="Enums\eMovementType.cs" />
<Compile Include="Enums\ePanelFrameType.cs" />
<Compile Include="Enums\eButtonType.cs" />
<Compile Include="Enums\eHero.cs" />

View File

@ -55,6 +55,8 @@ namespace OpenDiablo2.Core.Map_Engine
public void Render()
{
var xOffset = (gameState.ShowInventoryPanel ? -200 : 0) + (gameState.ShowCharacterPanel ? 200 : 0);
var cx = -(cameraLocation.X - Math.Truncate(cameraLocation.X));
var cy = -(cameraLocation.Y - Math.Truncate(cameraLocation.Y));
@ -73,16 +75,16 @@ namespace OpenDiablo2.Core.Map_Engine
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.Floor))
renderWindow.DrawMapCell(cellInfo, 320 + (int)px + (int)ox, 210 + (int)py + (int)oy);
renderWindow.DrawMapCell(cellInfo, 320 + (int)px + (int)ox + xOffset, 210 + (int)py + (int)oy);
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallLower))
renderWindow.DrawMapCell(cellInfo, 320 + (int)px + (int)ox, 210 + (int)py + (int)oy);
renderWindow.DrawMapCell(cellInfo, 320 + (int)px + (int)ox + xOffset, 210 + (int)py + (int)oy);
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallUpper))
renderWindow.DrawMapCell(cellInfo, 320 + (int)px + (int)ox, 210 + (int)py + (int)oy);
renderWindow.DrawMapCell(cellInfo, 320 + (int)px + (int)ox + xOffset, 210 + (int)py + (int)oy);
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.Roof))
renderWindow.DrawMapCell(cellInfo, 320 + (int)px + (int)ox, 210 + (int)py + (int)oy);
renderWindow.DrawMapCell(cellInfo, 320 + (int)px + (int)ox + xOffset, 210 + (int)py + (int)oy);
}
}

View File

@ -39,7 +39,7 @@ namespace OpenDiablo2.Core.UI
private bool pressed = false;
private bool active = false; // When true, button is actively being focus pressed
private bool activeLock = false; // When true, we have locked the mouse from everything else
private bool toggled = false;
public bool Toggled { get; private set; } = false;
private Point labelOffset = new Point();
@ -100,20 +100,20 @@ namespace OpenDiablo2.Core.UI
public bool Toggle()
{
toggled = !toggled;
Toggled = !Toggled;
OnToggle?.Invoke(toggled);
OnToggle?.Invoke(Toggled);
return toggled;
return Toggled;
}
public bool Toggle(bool isToggled)
{
if(toggled != isToggled)
if(Toggled != isToggled)
{
OnToggle?.Invoke(isToggled);
toggled = isToggled;
Toggled = isToggled;
}
return isToggled;
@ -177,7 +177,7 @@ namespace OpenDiablo2.Core.UI
{
var frame = buttonLayout.BaseFrame;
if(toggled && pressed)
if(Toggled && pressed)
{
frame = buttonLayout.BaseFrame + 3;
}
@ -185,7 +185,7 @@ namespace OpenDiablo2.Core.UI
{
frame = buttonLayout.BaseFrame + 1;
}
else if(toggled)
else if(Toggled)
{
frame = buttonLayout.BaseFrame + 2;
}

View File

@ -15,7 +15,9 @@ namespace OpenDiablo2.Scenes
private readonly IRenderWindow renderWindow;
private readonly IResourceManager resourceManager;
private readonly IMapEngine mapEngine;
private readonly IMouseInfoProvider mouseInfoProvider;
private readonly IGameState gameState;
private readonly ISessionManager sessionManager;
private readonly IKeyboardInfoProvider keyboardInfoProvider;
//private ISprite[] testSprite;
@ -28,13 +30,20 @@ namespace OpenDiablo2.Scenes
private bool showMinipanel = false;
private IButton runButton, menuButton;
private eMovementType lastMovementType = eMovementType.Stopped;
private int lastDirection = -1;
const double Rad2Deg = 180.0 / Math.PI;
const double Deg2Rad = Math.PI / 180.0;
public Game(
IRenderWindow renderWindow,
IResourceManager resourceManager,
IMapEngine mapEngine,
IGameState gameState,
IMouseInfoProvider mouseInfoProvider,
IKeyboardInfoProvider keyboardInfoProvider,
ISessionManager sessionManager,
Func<eButtonType, IButton> createButton,
Func<IMiniPanel> createMiniPanel,
Func<ICharacterPanel> createCharacterPanel,
@ -45,7 +54,9 @@ namespace OpenDiablo2.Scenes
this.resourceManager = resourceManager;
this.mapEngine = mapEngine;
this.gameState = gameState;
this.mouseInfoProvider = mouseInfoProvider;
this.keyboardInfoProvider = keyboardInfoProvider;
this.sessionManager = sessionManager;
panelSprite = renderWindow.LoadSprite(ResourcePaths.GamePanels, Palettes.Act1);
@ -130,6 +141,8 @@ namespace OpenDiablo2.Scenes
public void Update(long ms)
{
var seconds = ms / 1000f;
if(showMinipanel)
{
minipanel.Update();
@ -140,40 +153,72 @@ namespace OpenDiablo2.Scenes
runButton.Update();
menuButton.Update();
var seconds = (float)ms / 1000f;
var xMod = 0f;
var yMod = 0f;
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(80 /*left*/))
//{
// xMod = -8f * seconds;
//}
if (keyboardInfoProvider.KeyIsPressed(81 /*down*/))
{
yMod = 10f * seconds;
}
//if (keyboardInfoProvider.KeyIsPressed(79 /*right*/))
//{
// xMod = 8f * seconds;
//}
if (keyboardInfoProvider.KeyIsPressed(82 /*up*/))
{
yMod = -10f * seconds;
}
//if (keyboardInfoProvider.KeyIsPressed(81 /*down*/))
//{
// yMod = 10f * seconds;
//}
if (xMod != 0f || yMod != 0f)
{
xMod *= .5f;
yMod *= .5f;
mapEngine.CameraLocation = new PointF(mapEngine.CameraLocation.X + xMod, mapEngine.CameraLocation.Y + yMod);
}
//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);
}
private void HandleMovement()
{
if (mouseInfoProvider.MouseY > 530) // 550 is what it should be, but the minipanel check needs to happent oo
return;
if (gameState.ShowInventoryPanel && mouseInfoProvider.MouseX >= 400)
return;
if (gameState.ShowCharacterPanel && mouseInfoProvider.MouseX < 400)
return;
// 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);
if (mouseInfoProvider.LeftMouseDown && (lastMovementType == eMovementType.Stopped || lastDirection != cursorDirection))
{
lastDirection = cursorDirection;
lastMovementType = runButton.Toggled ? eMovementType.Running : eMovementType.Walking;
sessionManager.MoveRequest(cursorDirection, lastMovementType);
}
else if (!mouseInfoProvider.LeftMouseDown && lastMovementType != eMovementType.Stopped)
{
lastDirection = cursorDirection;
lastMovementType = eMovementType.Stopped;
sessionManager.MoveRequest(cursorDirection, lastMovementType);
}
}
public void Dispose()
{

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenDiablo2.Common.Attributes;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
namespace OpenDiablo2.ServiceBus.Message_Frames.Client
{
[MessageFrame(eMessageFrameType.MoveRequest)]
public sealed class MFMoveRequest : IMessageFrame
{
public int Direction { get; set; } = 0;
public eMovementType MovementType { get; set; } = eMovementType.Stopped;
public byte[] Data
{
get => new byte[] { (byte)Direction, (byte)MovementType };
set
{
Direction = value[0];
MovementType = (eMovementType)value[1];
}
}
public MFMoveRequest() { }
public MFMoveRequest(int direction, eMovementType movementType)
{
this.Direction = direction;
this.MovementType = movementType;
}
public void Process(int clientHash, ISessionEventProvider sessionEventProvider)
=> sessionEventProvider.OnMoveRequest(clientHash, Direction, MovementType);
}
}

View File

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

View File

@ -32,10 +32,11 @@ namespace OpenDiablo2.ServiceBus
public OnLocatePlayersEvent OnLocatePlayers { get; set; }
public OnPlayerInfoEvent OnPlayerInfo { get; set; }
public OnFocusOnPlayer OnFocusOnPlayer { get; set; }
public OnMoveRequest OnMoveRequest { get; set; }
public SessionManager(
eSessionType sessionType,
Func<eSessionType, ISessionServer> getSessionServer,
eSessionType sessionType,
Func<eSessionType, ISessionServer> getSessionServer,
Func<eMessageFrameType, IMessageFrame> getMessageFrame,
Func<IGameState> getGameState
)
@ -75,7 +76,7 @@ namespace OpenDiablo2.ServiceBus
default:
throw new ApplicationException("This session type is currently unsupported.");
}
running = true;
resetEvent.WaitOne();
running = false;
@ -100,10 +101,10 @@ namespace OpenDiablo2.ServiceBus
Stop();
}
public void Send(IMessageFrame messageFrame)
public void Send(IMessageFrame messageFrame, bool more = false)
{
var attr = messageFrame.GetType().GetCustomAttributes(true).First(x => typeof(MessageFrameAttribute).IsAssignableFrom(x.GetType())) as MessageFrameAttribute;
requestSocket.SendFrame(new byte[] { (byte)attr.FrameType }.Concat(messageFrame.Data).ToArray());
requestSocket.SendFrame(new byte[] { (byte)attr.FrameType }.Concat(messageFrame.Data).ToArray(), more);
}
private void ProcessMessageFrame<T>() where T : IMessageFrame, new()
@ -113,6 +114,7 @@ namespace OpenDiablo2.ServiceBus
var bytes = requestSocket.ReceiveFrameBytes();
var frameType = (eMessageFrameType)bytes[0];
var frameData = bytes.Skip(1).ToArray(); // TODO: Can we maybe use pointers? This seems wasteful
var messageFrame = getMessageFrame(frameType);
if (messageFrame.GetType() != typeof(T))
@ -124,6 +126,13 @@ namespace OpenDiablo2.ServiceBus
}
}
private void NoOp()
{
var bytes = requestSocket.ReceiveFrameBytes();
if ((eMessageFrameType)bytes[0] != eMessageFrameType.None)
throw new ApplicationException("Excepted a NoOp but got a command instead!");
}
public void JoinGame(string playerName, eHero heroType)
{
Task.Run(() =>
@ -135,5 +144,12 @@ namespace OpenDiablo2.ServiceBus
ProcessMessageFrame<MFFocusOnPlayer>();
});
}
public void MoveRequest(int direction, eMovementType movementType)
=> Task.Run(() =>
{
Send(new MFMoveRequest(direction, movementType));
NoOp();
});
}
}

View File

@ -25,8 +25,11 @@ namespace OpenDiablo2.ServiceBus
private bool running = false;
private ResponseSocket responseSocket;
public OnSetSeedEvent OnSetSeed { get; set; }
public OnJoinGameEvent OnJoinGame { get; set; }
public OnMoveRequest OnMoveRequest { get; set; }
// TODO: Fix interface so we don't need this in the session server
public OnSetSeedEvent OnSetSeed { get; set; }
public OnLocatePlayersEvent OnLocatePlayers { get; set; }
public OnPlayerInfoEvent OnPlayerInfo { get; set; }
public OnFocusOnPlayer OnFocusOnPlayer { get; set; }
@ -67,6 +70,7 @@ namespace OpenDiablo2.ServiceBus
}
OnJoinGame += OnJoinGameHandler;
OnMoveRequest += OnMovementRequestHandler;
var proactor = new NetMQProactor(responseSocket, (socket, message) =>
{
@ -86,6 +90,16 @@ namespace OpenDiablo2.ServiceBus
log.Info("Session server has stopped.");
}
private void OnMovementRequestHandler(int clientHash, int 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();
}
public void Stop()
{
@ -100,6 +114,11 @@ namespace OpenDiablo2.ServiceBus
Stop();
}
private void NoOp()
{
responseSocket.SendFrame(new byte[] { (byte)eMessageFrameType.None });
}
private void Send(IMessageFrame messageFrame, bool more = false)
{
var attr = messageFrame.GetType().GetCustomAttributes(true).First(x => typeof(MessageFrameAttribute).IsAssignableFrom(x.GetType())) as MessageFrameAttribute;

View File

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