diff --git a/OpenDiablo2.Common/Interfaces/UI/IButton.cs b/OpenDiablo2.Common/Interfaces/UI/IButton.cs
index 4b4196b5..aafe5551 100644
--- a/OpenDiablo2.Common/Interfaces/UI/IButton.cs
+++ b/OpenDiablo2.Common/Interfaces/UI/IButton.cs
@@ -46,6 +46,11 @@ namespace OpenDiablo2.Common.Interfaces
///
OnToggleDelegate OnToggle { get; set; }
+ ///
+ /// Toggle the button. Only valid for toggle buttons.
+ ///
+ bool Toggle();
+
string Text { get; set; }
///
diff --git a/OpenDiablo2.Common/Interfaces/UI/IGameHUD.cs b/OpenDiablo2.Common/Interfaces/UI/IGameHUD.cs
new file mode 100644
index 00000000..d9dbe362
--- /dev/null
+++ b/OpenDiablo2.Common/Interfaces/UI/IGameHUD.cs
@@ -0,0 +1,16 @@
+namespace OpenDiablo2.Common.Interfaces
+{
+ public interface IGameHUD
+ {
+ bool IsRunningEnabled { get; }
+ bool IsLeftPanelVisible { get; }
+ bool IsRightPanelVisible { get; }
+
+ bool IsMouseOver();
+ void OpenPanel(IPanel panel);
+ void OpenPanels(IPanel leftPanel, IPanel rightPanel);
+
+ void Render();
+ void Update();
+ }
+}
\ No newline at end of file
diff --git a/OpenDiablo2.Common/Interfaces/UI/IMiniPanel.cs b/OpenDiablo2.Common/Interfaces/UI/IMiniPanel.cs
index 85a9177c..77e5af11 100644
--- a/OpenDiablo2.Common/Interfaces/UI/IMiniPanel.cs
+++ b/OpenDiablo2.Common/Interfaces/UI/IMiniPanel.cs
@@ -2,11 +2,14 @@
namespace OpenDiablo2.Common.Interfaces
{
+ public delegate void PanelSelectedEvent(IPanel panel);
+
public interface IMiniPanel : IDisposable
{
- bool IsLeftPanelVisible { get; }
- bool IsRightPanelVisible { get; }
+ event PanelSelectedEvent PanelSelected;
+ bool IsMouseOver();
+ void UpdatePanelLocation();
void OnMenuToggle(bool isToggled);
void Render();
void Update();
diff --git a/OpenDiablo2.Common/OpenDiablo2.Common.csproj b/OpenDiablo2.Common/OpenDiablo2.Common.csproj
index 478d0935..b79410aa 100644
--- a/OpenDiablo2.Common/OpenDiablo2.Common.csproj
+++ b/OpenDiablo2.Common/OpenDiablo2.Common.csproj
@@ -89,6 +89,7 @@
+
diff --git a/OpenDiablo2.Core/AutofacModule.cs b/OpenDiablo2.Core/AutofacModule.cs
index ece95c62..abb07991 100644
--- a/OpenDiablo2.Core/AutofacModule.cs
+++ b/OpenDiablo2.Core/AutofacModule.cs
@@ -38,6 +38,7 @@ namespace OpenDiablo2.Core
builder.RegisterType().AsImplementedInterfaces().SingleInstance();
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
+ builder.RegisterType().As().InstancePerDependency();
builder.RegisterType().As().InstancePerDependency();
builder.RegisterType().As().InstancePerDependency();
builder.RegisterType().AsImplementedInterfaces().InstancePerDependency();
diff --git a/OpenDiablo2.Core/OpenDiablo2.Core.csproj b/OpenDiablo2.Core/OpenDiablo2.Core.csproj
index d3dc4b4a..a19e3c60 100644
--- a/OpenDiablo2.Core/OpenDiablo2.Core.csproj
+++ b/OpenDiablo2.Core/OpenDiablo2.Core.csproj
@@ -70,6 +70,7 @@
+
diff --git a/OpenDiablo2.Core/UI/Button.cs b/OpenDiablo2.Core/UI/Button.cs
index 2d39d2eb..a36a1edd 100644
--- a/OpenDiablo2.Core/UI/Button.cs
+++ b/OpenDiablo2.Core/UI/Button.cs
@@ -2,16 +2,10 @@
using OpenDiablo2.Common.Interfaces;
using OpenDiablo2.Common.Models;
using System;
-using System.Collections.Generic;
using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace OpenDiablo2.Core.UI
{
-
-
public sealed class Button : IButton
{
private readonly IMouseInfoProvider mouseInfoProvider;
diff --git a/OpenDiablo2.Core/UI/GameHUD.cs b/OpenDiablo2.Core/UI/GameHUD.cs
new file mode 100644
index 00000000..5eee4e93
--- /dev/null
+++ b/OpenDiablo2.Core/UI/GameHUD.cs
@@ -0,0 +1,181 @@
+using OpenDiablo2.Common;
+using OpenDiablo2.Common.Enums;
+using OpenDiablo2.Common.Interfaces;
+using System;
+using System.Diagnostics;
+using System.Drawing;
+
+namespace OpenDiablo2.Core.UI
+{
+ public class GameHUD : IGameHUD
+ {
+ private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ private readonly IRenderWindow renderWindow;
+ private readonly IGameState gameState;
+ private readonly IMouseInfoProvider mouseInfoProvider;
+ private readonly IMiniPanel minipanel;
+
+ private readonly IButton runButton, menuButton;
+ private readonly ISprite panelSprite, healthManaSprite, gameGlobeOverlapSprite;
+ private readonly IPanelFrame leftPanelFrame, rightPanelFrame;
+
+ public GameHUD(
+ IRenderWindow renderWindow,
+ IGameState gameState,
+ IMouseInfoProvider mouseInfoProvider,
+ Func createMiniPanel,
+ Func createButton,
+ Func createPanelFrame)
+ {
+ this.renderWindow = renderWindow;
+ this.gameState = gameState;
+ this.mouseInfoProvider = mouseInfoProvider;
+ minipanel = createMiniPanel();
+ minipanel.PanelSelected += OpenPanel;
+
+ leftPanelFrame = createPanelFrame(ePanelFrameType.Left);
+ rightPanelFrame = createPanelFrame(ePanelFrameType.Right);
+
+ runButton = createButton(eButtonType.Run);
+ runButton.Location = new Point(256, 570);
+ runButton.OnToggle = OnRunToggle;
+
+ menuButton = createButton(eButtonType.Menu);
+ menuButton.Location = new Point(393, 561);
+ menuButton.OnToggle = minipanel.OnMenuToggle;
+ menuButton.Toggle();
+
+ panelSprite = renderWindow.LoadSprite(ResourcePaths.GamePanels, Palettes.Act1);
+ healthManaSprite = renderWindow.LoadSprite(ResourcePaths.HealthMana, Palettes.Act1);
+ gameGlobeOverlapSprite = renderWindow.LoadSprite(ResourcePaths.GameGlobeOverlap, Palettes.Act1);
+ }
+
+ public IPanel LeftPanel { get; private set; }
+ public IPanel RightPanel { get; private set; }
+ public bool ArePanelsBounded { get; private set; } = false;
+
+ public bool IsLeftPanelVisible => LeftPanel != null;
+ public bool IsRightPanelVisible => RightPanel != null;
+ public bool IsRunningEnabled => runButton.Toggled;
+
+ public void OpenPanel(IPanel panel)
+ {
+ switch (panel.FrameType)
+ {
+ case ePanelFrameType.Left:
+ LeftPanel = LeftPanel == panel ? null : panel;
+ UpdateCameraOffset();
+ if (ArePanelsBounded)
+ RightPanel = null;
+ ArePanelsBounded = false;
+ break;
+
+ case ePanelFrameType.Right:
+ RightPanel = RightPanel == panel ? null : panel;
+ UpdateCameraOffset();
+ if (ArePanelsBounded)
+ LeftPanel = null;
+ ArePanelsBounded = false;
+ break;
+
+ case ePanelFrameType.Center:
+ // todo; write logic for "center" panels
+ break;
+
+ default:
+ Debug.Fail("Unknown frame type");
+ break;
+ }
+ }
+
+ // used when panels are bounded with each other (shops/chest)
+ public void OpenPanels(IPanel leftPanel, IPanel rightPanel)
+ {
+ if (leftPanel.FrameType != ePanelFrameType.Left || rightPanel.FrameType != ePanelFrameType.Right)
+ throw new ArgumentException("wrong panel position.");
+
+ LeftPanel = leftPanel;
+ RightPanel = rightPanel;
+ UpdateCameraOffset();
+ ArePanelsBounded = true;
+ }
+
+ public bool IsMouseOver()
+ {
+ return mouseInfoProvider.MouseY >= 550
+ || minipanel.IsMouseOver()
+ || IsRightPanelVisible && mouseInfoProvider.MouseX >= 400
+ || IsLeftPanelVisible && mouseInfoProvider.MouseX < 400;
+ }
+
+ public void Render()
+ {
+ if (IsLeftPanelVisible)
+ {
+ LeftPanel.Render();
+ leftPanelFrame.Render();
+ }
+
+ if (IsRightPanelVisible)
+ {
+ RightPanel.Render();
+ rightPanelFrame.Render();
+ }
+
+ if (!IsLeftPanelVisible || !IsRightPanelVisible)
+ minipanel.Render();
+
+ // Render the background bottom bar
+ renderWindow.Draw(panelSprite, 0, new Point(0, 600));
+ renderWindow.Draw(panelSprite, 1, new Point(166, 600));
+ renderWindow.Draw(panelSprite, 2, new Point(294, 600));
+ renderWindow.Draw(panelSprite, 3, new Point(422, 600));
+ renderWindow.Draw(panelSprite, 4, new Point(550, 600));
+ renderWindow.Draw(panelSprite, 5, new Point(685, 600));
+
+ // Render the health bar
+ renderWindow.Draw(healthManaSprite, 0, new Point(30, 587));
+ renderWindow.Draw(gameGlobeOverlapSprite, 0, new Point(28, 595));
+
+ // Render the mana bar
+ renderWindow.Draw(healthManaSprite, 1, new Point(692, 588));
+ renderWindow.Draw(gameGlobeOverlapSprite, 1, new Point(693, 591));
+
+ runButton.Render();
+ menuButton.Render();
+ }
+
+ public void Update()
+ {
+ runButton.Update();
+ menuButton.Update();
+
+ if (IsLeftPanelVisible)
+ {
+ LeftPanel.Update();
+ leftPanelFrame.Update();
+ }
+
+ if (IsRightPanelVisible)
+ {
+ RightPanel.Update();
+ rightPanelFrame.Update();
+ }
+
+ if(!IsLeftPanelVisible || !IsRightPanelVisible)
+ minipanel.Update();
+ }
+
+ private void UpdateCameraOffset()
+ {
+ gameState.CameraOffset = (IsRightPanelVisible ? -200 : 0) + (IsLeftPanelVisible ? 200 : 0);
+ minipanel.UpdatePanelLocation();
+ }
+
+ private void OnRunToggle(bool isToggled)
+ {
+ log.Debug("Run Toggle: " + isToggled);
+ }
+ }
+}
diff --git a/OpenDiablo2.Core/UI/MiniPanel.cs b/OpenDiablo2.Core/UI/MiniPanel.cs
index ee914005..d4e9df9c 100644
--- a/OpenDiablo2.Core/UI/MiniPanel.cs
+++ b/OpenDiablo2.Core/UI/MiniPanel.cs
@@ -1,11 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Drawing;
-using System.Linq;
-using OpenDiablo2.Common;
+using OpenDiablo2.Common;
using OpenDiablo2.Common.Enums;
using OpenDiablo2.Common.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
namespace OpenDiablo2.Core.UI
{
@@ -15,29 +14,26 @@ namespace OpenDiablo2.Core.UI
eButtonType.MinipanelSkill, eButtonType.MinipanelAutomap, eButtonType.MinipanelMessage, eButtonType.MinipanelQuest, eButtonType.MinipanelMenu };
private readonly IRenderWindow renderWindow;
+ private readonly IMouseInfoProvider mouseInfoProvider;
private readonly IGameState gameState;
private readonly ISprite sprite;
private readonly IReadOnlyList buttons;
private readonly IEnumerable panels;
- private readonly IPanelFrame leftPanelFrame;
- private readonly IPanelFrame rightPanelFrame;
private bool isPanelVisible;
- public IPanel LeftPanel { get; private set; }
- public IPanel RightPanel { get; private set; }
- public bool IsLeftPanelVisible => LeftPanel != null;
- public bool IsRightPanelVisible => RightPanel != null;
+ public event PanelSelectedEvent PanelSelected;
- public MiniPanel(IRenderWindow renderWindow, IGameState gameState,
- IEnumerable panels, Func createButton,
- Func createPanelFrame)
+ public MiniPanel(IRenderWindow renderWindow,
+ IGameState gameState,
+ IMouseInfoProvider mouseInfoProvider,
+ IEnumerable panels,
+ Func createButton)
{
this.renderWindow = renderWindow;
+ this.mouseInfoProvider = mouseInfoProvider;
this.gameState = gameState;
this.panels = panels;
- leftPanelFrame = createPanelFrame(ePanelFrameType.Left);
- rightPanelFrame = createPanelFrame(ePanelFrameType.Right);
sprite = renderWindow.LoadSprite(ResourcePaths.MinipanelSmall, Palettes.Units);
@@ -48,53 +44,29 @@ namespace OpenDiablo2.Core.UI
{
var panel = panels.SingleOrDefault(o => o.PanelType == x);
if (panel == null) return;
- TogglePanel(panel);
+ PanelSelected?.Invoke(panel);
};
return newBtn;
}).ToList().AsReadOnly();
UpdatePanelLocation();
- OnMenuToggle(true);
}
public void OnMenuToggle(bool isToggled) => isPanelVisible = isToggled;
- public void Update()
+ public bool IsMouseOver()
{
- if (IsLeftPanelVisible)
- {
- LeftPanel.Update();
- leftPanelFrame.Update();
- }
+ int xDiff = mouseInfoProvider.MouseX - sprite.Location.X;
+ int yDiff = mouseInfoProvider.MouseY - sprite.Location.Y + sprite.LocalFrameSize.Height;
- if (IsRightPanelVisible)
- {
- RightPanel.Update();
- rightPanelFrame.Update();
- }
-
- if (!isPanelVisible || (IsLeftPanelVisible && IsRightPanelVisible))
- return;
-
- foreach (var button in buttons)
- button.Update();
+ return isPanelVisible
+ && xDiff >= 0 && xDiff <= sprite.LocalFrameSize.Width
+ && yDiff >= 0 && yDiff <= sprite.LocalFrameSize.Height;
}
public void Render()
{
- if (IsLeftPanelVisible)
- {
- LeftPanel.Render();
- leftPanelFrame.Render();
- }
-
- if (IsRightPanelVisible)
- {
- RightPanel.Render();
- rightPanelFrame.Render();
- }
-
- if (!isPanelVisible || (IsLeftPanelVisible && IsRightPanelVisible))
+ if (!isPanelVisible)
return;
renderWindow.Draw(sprite);
@@ -103,6 +75,15 @@ namespace OpenDiablo2.Core.UI
button.Render();
}
+ public void Update()
+ {
+ if (!isPanelVisible)
+ return;
+
+ foreach (var button in buttons)
+ button.Update();
+ }
+
public void Dispose()
{
foreach (var button in buttons)
@@ -111,34 +92,7 @@ namespace OpenDiablo2.Core.UI
sprite.Dispose();
}
- private void TogglePanel(IPanel panel)
- {
- switch (panel.FrameType)
- {
- case ePanelFrameType.Left:
- LeftPanel = LeftPanel == panel ? null : panel;
- break;
- case ePanelFrameType.Right:
- RightPanel = RightPanel == panel ? null : panel;
- break;
- case ePanelFrameType.Center:
- // todo; stack center panels
- break;
- default:
- Debug.Fail("Unknown frame type");
- break;
- }
-
- UpdateCameraOffset();
- }
-
- private void UpdateCameraOffset()
- {
- gameState.CameraOffset = (IsRightPanelVisible ? -200 : 0) + (IsLeftPanelVisible ? 200 : 0);
- UpdatePanelLocation();
- }
-
- private void UpdatePanelLocation()
+ public void UpdatePanelLocation()
{
sprite.Location = new Point((800 - sprite.LocalFrameSize.Width + (int)(gameState.CameraOffset * 1.3f)) / 2,
526 + sprite.LocalFrameSize.Height);
diff --git a/OpenDiablo2.Scenes/Game.cs b/OpenDiablo2.Scenes/Game.cs
index 0cf5eb6f..2472a59b 100644
--- a/OpenDiablo2.Scenes/Game.cs
+++ b/OpenDiablo2.Scenes/Game.cs
@@ -18,6 +18,7 @@ namespace OpenDiablo2.Scenes
private readonly IGameState gameState;
private readonly ISessionManager sessionManager;
private readonly IKeyboardInfoProvider keyboardInfoProvider;
+ private readonly IGameHUD gameHUD;
//private ISprite[] testSprite;
@@ -39,8 +40,7 @@ namespace OpenDiablo2.Scenes
IKeyboardInfoProvider keyboardInfoProvider,
IItemManager itemManager,
ISessionManager sessionManager,
- Func createButton,
- Func createMiniPanel
+ IGameHUD gameHUD
)
{
this.renderWindow = renderWindow;
@@ -49,31 +49,11 @@ namespace OpenDiablo2.Scenes
this.mouseInfoProvider = mouseInfoProvider;
this.keyboardInfoProvider = keyboardInfoProvider;
this.sessionManager = sessionManager;
-
-
- panelSprite = renderWindow.LoadSprite(ResourcePaths.GamePanels, Palettes.Act1);
- healthManaSprite = renderWindow.LoadSprite(ResourcePaths.HealthMana, Palettes.Act1);
- gameGlobeOverlapSprite = renderWindow.LoadSprite(ResourcePaths.GameGlobeOverlap, Palettes.Act1);
-
- minipanel = createMiniPanel();
-
- runButton = createButton(eButtonType.Run);
- runButton.Location = new Point(256, 570);
- runButton.OnToggle = OnRunToggle;
-
- // move to minipanel?
- menuButton = createButton(eButtonType.Menu);
- menuButton.Location = new Point(393, 561);
- menuButton.OnToggle = minipanel.OnMenuToggle;
+ this.gameHUD = gameHUD;
//var item = itemManager.getItem("hdm");
}
- private void OnRunToggle(bool isToggled)
- {
- log.Debug("Run Toggle: " + isToggled);
- }
-
public void Render()
{
// TODO: Maybe show some sort of connecting/loading message?
@@ -81,63 +61,25 @@ namespace OpenDiablo2.Scenes
return;
mapEngine.Render();
- DrawPanel();
-
- }
-
- private void DrawPanel()
- {
- minipanel.Render();
-
- // Render the background bottom bar
- renderWindow.Draw(panelSprite, 0, new Point(0, 600));
- renderWindow.Draw(panelSprite, 1, new Point(166, 600));
- renderWindow.Draw(panelSprite, 2, new Point(294, 600));
- renderWindow.Draw(panelSprite, 3, new Point(422, 600));
- renderWindow.Draw(panelSprite, 4, new Point(550, 600));
- renderWindow.Draw(panelSprite, 5, new Point(685, 600));
-
- // Render the health bar
- renderWindow.Draw(healthManaSprite, 0, new Point(30, 587));
- renderWindow.Draw(gameGlobeOverlapSprite, 0, new Point(28, 595));
-
- // Render the mana bar
- renderWindow.Draw(healthManaSprite, 1, new Point(692, 588));
- renderWindow.Draw(gameGlobeOverlapSprite, 1, new Point(693, 591));
-
-
-
- runButton.Render();
- menuButton.Render();
+ gameHUD.Render();
}
public void Update(long ms)
{
var seconds = ms / 1000f;
- minipanel.Update();
-
- runButton.Update();
- menuButton.Update();
-
HandleMovement();
mapEngine.Update(ms);
+ gameHUD.Update();
}
private void HandleMovement()
{
- if (mouseInfoProvider.MouseY > 530) // 550 is what it should be, but the minipanel check needs to happent oo
+ // todo; if clicked on hud, then we don't move. But when clicked on map and move cursor over hud, then it's fine
+ if (gameHUD.IsMouseOver())
return;
- if (minipanel.IsRightPanelVisible && mouseInfoProvider.MouseX >= 400)
- return;
-
- if (minipanel.IsLeftPanelVisible && mouseInfoProvider.MouseX < 400)
- return;
-
-
- // TODO: Filter movement for inventory panel
var mx = (mouseInfoProvider.MouseX - 400) - gameState.CameraOffset;
var my = (mouseInfoProvider.MouseY - 300);
@@ -153,7 +95,7 @@ namespace OpenDiablo2.Scenes
if (mouseInfoProvider.LeftMouseDown && (lastMovementType == eMovementType.Stopped || lastDirection != actualDirection))
{
lastDirection = actualDirection;
- lastMovementType = runButton.Toggled ? eMovementType.Running : eMovementType.Walking;
+ lastMovementType = gameHUD.IsRunningEnabled ? eMovementType.Running : eMovementType.Walking;
sessionManager.MoveRequest(actualDirection, lastMovementType);
}
else if (!mouseInfoProvider.LeftMouseDown && lastMovementType != eMovementType.Stopped)