From d89917696354352f17b7db6a047cd92b471cb5c6 Mon Sep 17 00:00:00 2001 From: Kacper Drobny Date: Sat, 8 Dec 2018 00:45:23 +0100 Subject: [PATCH] refactoring of minipanel (#36) --- OpenDiablo2.Common/Enums/ePanelFrameType.cs | 3 +- OpenDiablo2.Common/Interfaces/IGameState.cs | 8 +- .../Interfaces/UI/ICharacterPanel.cs | 8 +- .../Interfaces/UI/IInventoryPanel.cs | 8 +- .../Interfaces/UI/IMiniPanel.cs | 4 + OpenDiablo2.Common/Interfaces/UI/IPanel.cs | 13 ++ OpenDiablo2.Common/OpenDiablo2.Common.csproj | 1 + OpenDiablo2.Core/AutofacModule.cs | 4 +- OpenDiablo2.Core/GameState/GameState.cs | 21 +-- OpenDiablo2.Core/Map Engine/MapEngine.cs | 2 +- OpenDiablo2.Core/UI/CharacterPanel.cs | 10 +- OpenDiablo2.Core/UI/InventoryPanel.cs | 9 +- OpenDiablo2.Core/UI/MiniPanel.cs | 173 +++++++++++------- OpenDiablo2.Scenes/Game.cs | 64 ++----- 14 files changed, 162 insertions(+), 166 deletions(-) create mode 100644 OpenDiablo2.Common/Interfaces/UI/IPanel.cs diff --git a/OpenDiablo2.Common/Enums/ePanelFrameType.cs b/OpenDiablo2.Common/Enums/ePanelFrameType.cs index f8e3c2b8..fef4ded9 100644 --- a/OpenDiablo2.Common/Enums/ePanelFrameType.cs +++ b/OpenDiablo2.Common/Enums/ePanelFrameType.cs @@ -3,6 +3,7 @@ public enum ePanelFrameType { Left, - Right + Right, + Center } } diff --git a/OpenDiablo2.Common/Interfaces/IGameState.cs b/OpenDiablo2.Common/Interfaces/IGameState.cs index 6cc3c677..89983a29 100644 --- a/OpenDiablo2.Common/Interfaces/IGameState.cs +++ b/OpenDiablo2.Common/Interfaces/IGameState.cs @@ -16,15 +16,11 @@ namespace OpenDiablo2.Common.Interfaces Palette CurrentPalette { get; } IEnumerable PlayerInfos { get; } - bool ToggleShowInventoryPanel(); - bool ShowInventoryPanel { get; set; } - - bool ToggleShowCharacterPanel(); - bool ShowCharacterPanel { get; set; } - Item SelectedItem { get; } void SelectItem(Item item); + int CameraOffset { get; set; } + void Initialize(string text, eHero value, eSessionType sessionType); void Update(long ms); IEnumerable GetMapCellInfo(int cellX, int cellY, eRenderCellType renderCellType); diff --git a/OpenDiablo2.Common/Interfaces/UI/ICharacterPanel.cs b/OpenDiablo2.Common/Interfaces/UI/ICharacterPanel.cs index 3199519d..679c822e 100644 --- a/OpenDiablo2.Common/Interfaces/UI/ICharacterPanel.cs +++ b/OpenDiablo2.Common/Interfaces/UI/ICharacterPanel.cs @@ -1,10 +1,6 @@ -using System; - -namespace OpenDiablo2.Common.Interfaces +namespace OpenDiablo2.Common.Interfaces { - public interface ICharacterPanel : IDisposable + public interface ICharacterPanel : IPanel { - void Render(); - void Update(); } } diff --git a/OpenDiablo2.Common/Interfaces/UI/IInventoryPanel.cs b/OpenDiablo2.Common/Interfaces/UI/IInventoryPanel.cs index 50f842a2..58a20a20 100644 --- a/OpenDiablo2.Common/Interfaces/UI/IInventoryPanel.cs +++ b/OpenDiablo2.Common/Interfaces/UI/IInventoryPanel.cs @@ -1,10 +1,6 @@ -using System; - -namespace OpenDiablo2.Common.Interfaces +namespace OpenDiablo2.Common.Interfaces { - public interface IInventoryPanel : IDisposable + public interface IInventoryPanel : IPanel { - void Render(); - void Update(); } } diff --git a/OpenDiablo2.Common/Interfaces/UI/IMiniPanel.cs b/OpenDiablo2.Common/Interfaces/UI/IMiniPanel.cs index f5764e8a..85a9177c 100644 --- a/OpenDiablo2.Common/Interfaces/UI/IMiniPanel.cs +++ b/OpenDiablo2.Common/Interfaces/UI/IMiniPanel.cs @@ -4,6 +4,10 @@ namespace OpenDiablo2.Common.Interfaces { public interface IMiniPanel : IDisposable { + bool IsLeftPanelVisible { get; } + bool IsRightPanelVisible { get; } + + void OnMenuToggle(bool isToggled); void Render(); void Update(); } diff --git a/OpenDiablo2.Common/Interfaces/UI/IPanel.cs b/OpenDiablo2.Common/Interfaces/UI/IPanel.cs new file mode 100644 index 00000000..85c065ff --- /dev/null +++ b/OpenDiablo2.Common/Interfaces/UI/IPanel.cs @@ -0,0 +1,13 @@ +using OpenDiablo2.Common.Enums; +using System; + +namespace OpenDiablo2.Common.Interfaces +{ + public interface IPanel : IDisposable + { + eButtonType PanelType { get; } + ePanelFrameType FrameType { get; } + void Render(); + void Update(); + } +} diff --git a/OpenDiablo2.Common/OpenDiablo2.Common.csproj b/OpenDiablo2.Common/OpenDiablo2.Common.csproj index 355d520c..d78ae2a7 100644 --- a/OpenDiablo2.Common/OpenDiablo2.Common.csproj +++ b/OpenDiablo2.Common/OpenDiablo2.Common.csproj @@ -85,6 +85,7 @@ + diff --git a/OpenDiablo2.Core/AutofacModule.cs b/OpenDiablo2.Core/AutofacModule.cs index 1a12d811..e7834e9f 100644 --- a/OpenDiablo2.Core/AutofacModule.cs +++ b/OpenDiablo2.Core/AutofacModule.cs @@ -23,8 +23,8 @@ namespace OpenDiablo2.Core builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().InstancePerDependency(); builder.RegisterType().As().InstancePerDependency(); - builder.RegisterType().As().InstancePerDependency(); - builder.RegisterType().As().InstancePerDependency(); + builder.RegisterType().AsImplementedInterfaces().InstancePerDependency(); + builder.RegisterType().AsImplementedInterfaces().InstancePerDependency(); builder.RegisterType().As().InstancePerDependency(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); diff --git a/OpenDiablo2.Core/GameState/GameState.cs b/OpenDiablo2.Core/GameState/GameState.cs index f8961324..75ac8fa9 100644 --- a/OpenDiablo2.Core/GameState/GameState.cs +++ b/OpenDiablo2.Core/GameState/GameState.cs @@ -32,9 +32,6 @@ namespace OpenDiablo2.Core.GameState_ public Palette CurrentPalette => paletteProvider.PaletteTable[$"ACT{Act}"]; public List PlayerInfos { get; private set; } = new List(); - public bool ShowInventoryPanel { get; set; } = false; - public bool ShowCharacterPanel { get; set; } = false; - readonly private IMouseCursor originalMouseCursor; public int Seed { get; internal set; } @@ -42,6 +39,8 @@ namespace OpenDiablo2.Core.GameState_ public Item SelectedItem { get; internal set; } public object ThreadLocker { get; } = new object(); + public int CameraOffset { get; set; } = 0; + IEnumerable IGameState.PlayerInfos => PlayerInfos; const double Deg2Rad = Math.PI / 180.0; @@ -189,7 +188,7 @@ namespace OpenDiablo2.Core.GameState_ var map = GetMap(ref cellX, ref cellY); if (map == null) - return new List(); + return Enumerable.Empty(); if (cellY >= map.FileData.Height || cellX >= map.FileData.Width) return new List(); // Temporary code @@ -236,20 +235,6 @@ namespace OpenDiablo2.Core.GameState_ } - public bool ToggleShowInventoryPanel() - { - ShowInventoryPanel = !ShowInventoryPanel; - - return ShowInventoryPanel; - } - - public bool ToggleShowCharacterPanel() - { - ShowCharacterPanel = !ShowCharacterPanel; - - return ShowCharacterPanel; - } - public void SelectItem(Item item) { if(item == null) diff --git a/OpenDiablo2.Core/Map Engine/MapEngine.cs b/OpenDiablo2.Core/Map Engine/MapEngine.cs index 57ef8e4b..7165b5c6 100644 --- a/OpenDiablo2.Core/Map Engine/MapEngine.cs +++ b/OpenDiablo2.Core/Map Engine/MapEngine.cs @@ -55,7 +55,7 @@ namespace OpenDiablo2.Core.Map_Engine public void Render() { - var xOffset = (gameState.ShowInventoryPanel ? -200 : 0) + (gameState.ShowCharacterPanel ? 200 : 0); + var xOffset = gameState.CameraOffset; var cx = -(cameraLocation.X - Math.Truncate(cameraLocation.X)); var cy = -(cameraLocation.Y - Math.Truncate(cameraLocation.Y)); diff --git a/OpenDiablo2.Core/UI/CharacterPanel.cs b/OpenDiablo2.Core/UI/CharacterPanel.cs index b6fbac47..6f08f9a1 100644 --- a/OpenDiablo2.Core/UI/CharacterPanel.cs +++ b/OpenDiablo2.Core/UI/CharacterPanel.cs @@ -10,21 +10,20 @@ namespace OpenDiablo2.Core.UI { private readonly IRenderWindow renderWindow; private ISprite sprite; - private IPanelFrame panelFrame; public Point Location { get; set; } - public CharacterPanel(IRenderWindow renderWindow, Func createPanelFrame) + public CharacterPanel(IRenderWindow renderWindow) { this.renderWindow = renderWindow; - this.panelFrame = createPanelFrame(ePanelFrameType.Left); sprite = renderWindow.LoadSprite(ResourcePaths.InventoryCharacterPanel, Palettes.Units, new Point(79,61)); Location = new Point(0, 0); - - } + public eButtonType PanelType => eButtonType.MinipanelCharacter; + public ePanelFrameType FrameType => ePanelFrameType.Left; + public void Update() { @@ -32,7 +31,6 @@ namespace OpenDiablo2.Core.UI public void Render() { - panelFrame.Render(); renderWindow.Draw(sprite, 2, 2, 0); } diff --git a/OpenDiablo2.Core/UI/InventoryPanel.cs b/OpenDiablo2.Core/UI/InventoryPanel.cs index 28e33767..d62491ff 100644 --- a/OpenDiablo2.Core/UI/InventoryPanel.cs +++ b/OpenDiablo2.Core/UI/InventoryPanel.cs @@ -14,7 +14,6 @@ namespace OpenDiablo2.Core.UI { private readonly IRenderWindow renderWindow; private ISprite sprite; - private IPanelFrame panelFrame; private Point location; public Point Location { @@ -25,6 +24,9 @@ namespace OpenDiablo2.Core.UI } } + public eButtonType PanelType => eButtonType.MinipanelInventory; + public ePanelFrameType FrameType => ePanelFrameType.Right; + // Test vars public IItemContainer helmContainer, armorContainer, weaponLeftContainer, weaponRightContainer, beltContainer, gloveContainer, bootsContainer; private Point previouslyContainedItem; @@ -32,10 +34,9 @@ namespace OpenDiablo2.Core.UI private IItemContainer ringtRightContainer; private IItemContainer amuletContainer; - public InventoryPanel(Func createPanelFrame, IRenderWindow renderWindow, IItemManager itemManager, Func createItemContainer) + public InventoryPanel(IRenderWindow renderWindow, IItemManager itemManager, Func createItemContainer) { this.renderWindow = renderWindow; - this.panelFrame = createPanelFrame(ePanelFrameType.Right); sprite = renderWindow.LoadSprite(ResourcePaths.InventoryCharacterPanel, Palettes.Units, new Point(402,61)); Location = new Point(400, 0); @@ -83,7 +84,6 @@ namespace OpenDiablo2.Core.UI public void Update() { - helmContainer.Update(); amuletContainer.Update(); armorContainer.Update(); @@ -98,7 +98,6 @@ namespace OpenDiablo2.Core.UI public void Render() { - panelFrame.Render(); renderWindow.Draw(sprite, 2, 2, 1); helmContainer.Render(); diff --git a/OpenDiablo2.Core/UI/MiniPanel.cs b/OpenDiablo2.Core/UI/MiniPanel.cs index 714b591d..ee914005 100644 --- a/OpenDiablo2.Core/UI/MiniPanel.cs +++ b/OpenDiablo2.Core/UI/MiniPanel.cs @@ -1,101 +1,150 @@ using System; +using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; +using System.Linq; using OpenDiablo2.Common; using OpenDiablo2.Common.Enums; using OpenDiablo2.Common.Interfaces; namespace OpenDiablo2.Core.UI { - // TODO: Self-align when side panels are open public sealed class MiniPanel : IMiniPanel { + private static readonly IEnumerable panelButtons = new[] { eButtonType.MinipanelCharacter, eButtonType.MinipanelInventory, + eButtonType.MinipanelSkill, eButtonType.MinipanelAutomap, eButtonType.MinipanelMessage, eButtonType.MinipanelQuest, eButtonType.MinipanelMenu }; + private readonly IRenderWindow renderWindow; - private ISprite sprite; + 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 IButton characterBtn, inventoryBtn, skillBtn, automapBtn, messageBtn, questBtn, menuBtn; + private bool isPanelVisible; - private Point location = new Point(); - public Point Location - { - get => location; - set - { - if (location == value) - return; - location = value; + public IPanel LeftPanel { get; private set; } + public IPanel RightPanel { get; private set; } + public bool IsLeftPanelVisible => LeftPanel != null; + public bool IsRightPanelVisible => RightPanel != null; - sprite.Location = new Point(value.X, value.Y + sprite.LocalFrameSize.Height); - } - } - - public MiniPanel(IRenderWindow renderWindow, IGameState gameState, Func createButton) + public MiniPanel(IRenderWindow renderWindow, IGameState gameState, + IEnumerable panels, Func createButton, + Func createPanelFrame) { this.renderWindow = renderWindow; - + this.gameState = gameState; + this.panels = panels; + leftPanelFrame = createPanelFrame(ePanelFrameType.Left); + rightPanelFrame = createPanelFrame(ePanelFrameType.Right); + sprite = renderWindow.LoadSprite(ResourcePaths.MinipanelSmall, Palettes.Units); - Location = new Point(800/2-sprite.LocalFrameSize.Width/2, 526); - characterBtn = createButton(eButtonType.MinipanelCharacter); - characterBtn.Location = new Point(3 + Location.X, 3 + Location.Y); - characterBtn.OnActivate = () => gameState.ToggleShowCharacterPanel(); + buttons = panelButtons.Select((x, i) => + { + var newBtn = createButton(x); + newBtn.OnActivate = () => + { + var panel = panels.SingleOrDefault(o => o.PanelType == x); + if (panel == null) return; + TogglePanel(panel); + }; + return newBtn; + }).ToList().AsReadOnly(); - inventoryBtn = createButton(eButtonType.MinipanelInventory); - inventoryBtn.Location = new Point(24 + Location.X, 3 + Location.Y); - inventoryBtn.OnActivate = () => gameState.ToggleShowInventoryPanel(); - - skillBtn = createButton(eButtonType.MinipanelSkill); - skillBtn.Location = new Point(45 + Location.X, 3 + Location.Y); - - automapBtn = createButton(eButtonType.MinipanelAutomap); - automapBtn.Location = new Point(66 + Location.X, 3 + Location.Y); - - messageBtn = createButton(eButtonType.MinipanelMessage); - messageBtn.Location = new Point(87 + Location.X, 3 + Location.Y); - - questBtn = createButton(eButtonType.MinipanelQuest); - questBtn.Location = new Point(108 + Location.X, 3 + Location.Y); - - menuBtn = createButton(eButtonType.MinipanelMenu); - menuBtn.Location = new Point(129 + Location.X, 3 + Location.Y); + UpdatePanelLocation(); + OnMenuToggle(true); } + public void OnMenuToggle(bool isToggled) => isPanelVisible = isToggled; public void Update() { - characterBtn.Update(); - inventoryBtn.Update(); - skillBtn.Update(); - automapBtn.Update(); - messageBtn.Update(); - questBtn.Update(); - menuBtn.Update(); + if (IsLeftPanelVisible) + { + LeftPanel.Update(); + leftPanelFrame.Update(); + } + + if (IsRightPanelVisible) + { + RightPanel.Update(); + rightPanelFrame.Update(); + } + if (!isPanelVisible || (IsLeftPanelVisible && IsRightPanelVisible)) + return; + + foreach (var button in buttons) + button.Update(); } public void Render() { + if (IsLeftPanelVisible) + { + LeftPanel.Render(); + leftPanelFrame.Render(); + } + + if (IsRightPanelVisible) + { + RightPanel.Render(); + rightPanelFrame.Render(); + } + + if (!isPanelVisible || (IsLeftPanelVisible && IsRightPanelVisible)) + return; + renderWindow.Draw(sprite); - - characterBtn.Render(); - inventoryBtn.Render(); - skillBtn.Render(); - automapBtn.Render(); - messageBtn.Render(); - questBtn.Render(); - menuBtn.Render(); + + foreach (var button in buttons) + button.Render(); } public void Dispose() { - characterBtn.Dispose(); - inventoryBtn.Dispose(); - skillBtn.Dispose(); - automapBtn.Dispose(); - messageBtn.Dispose(); - questBtn.Dispose(); - menuBtn.Dispose(); + foreach (var button in buttons) + button.Dispose(); 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() + { + sprite.Location = new Point((800 - sprite.LocalFrameSize.Width + (int)(gameState.CameraOffset * 1.3f)) / 2, + 526 + sprite.LocalFrameSize.Height); + + for (int i = 0; i < buttons.Count; i++) + buttons[i].Location = new Point(3 + 21 * i + sprite.Location.X, 3 + sprite.Location.Y - sprite.LocalFrameSize.Height); + } } } diff --git a/OpenDiablo2.Scenes/Game.cs b/OpenDiablo2.Scenes/Game.cs index 96853ede..7824f655 100644 --- a/OpenDiablo2.Scenes/Game.cs +++ b/OpenDiablo2.Scenes/Game.cs @@ -25,11 +25,8 @@ namespace OpenDiablo2.Scenes private ISprite panelSprite, healthManaSprite, gameGlobeOverlapSprite; - private IMiniPanel minipanel; - private ICharacterPanel characterpanel; - private IInventoryPanel inventorypanel; - - private bool showMinipanel = false; + private readonly IMiniPanel minipanel; + private IButton runButton, menuButton; private eMovementType lastMovementType = eMovementType.Stopped; private byte lastDirection = 255; @@ -46,9 +43,7 @@ namespace OpenDiablo2.Scenes IItemManager itemManager, ISessionManager sessionManager, Func createButton, - Func createMiniPanel, - Func createCharacterPanel, - Func createInventoryPanel + Func createMiniPanel ) { this.renderWindow = renderWindow; @@ -65,19 +60,15 @@ namespace OpenDiablo2.Scenes gameGlobeOverlapSprite = renderWindow.LoadSprite(ResourcePaths.GameGlobeOverlap, Palettes.Act1); minipanel = createMiniPanel(); - // Maybe? Not sure. - // miniPanel.OnMenuActivate(); - - characterpanel = createCharacterPanel(); - inventorypanel = createInventoryPanel(); 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 = OnMenuToggle; + menuButton.OnToggle = minipanel.OnMenuToggle; /*var item = itemManager.getItem("hdm"); var cursorsprite = renderWindow.LoadSprite(ResourcePaths.GeneratePathForItem(item.InvFile), Palettes.Units); @@ -85,11 +76,6 @@ namespace OpenDiablo2.Scenes renderWindow.MouseCursor = renderWindow.LoadCursor(cursorsprite, 0, new Point(cursorsprite.FrameSize.Width/2, cursorsprite.FrameSize.Height / 2));*/ } - private void OnMenuToggle(bool isToggled) - { - this.showMinipanel = isToggled; - } - private void OnRunToggle(bool isToggled) { log.Debug("Run Toggle: " + isToggled); @@ -108,15 +94,7 @@ namespace OpenDiablo2.Scenes private void DrawPanel() { - if(gameState.ShowInventoryPanel) - { - inventorypanel.Render(); - } - - if (gameState.ShowCharacterPanel) - { - characterpanel.Render(); - } + minipanel.Render(); // Render the background bottom bar renderWindow.Draw(panelSprite, 0, new Point(0, 600)); @@ -134,11 +112,6 @@ namespace OpenDiablo2.Scenes renderWindow.Draw(healthManaSprite, 1, new Point(692, 588)); renderWindow.Draw(gameGlobeOverlapSprite, 1, new Point(693, 591)); - if(showMinipanel) - { - minipanel.Render(); - } - runButton.Render(); @@ -149,20 +122,7 @@ namespace OpenDiablo2.Scenes { var seconds = ms / 1000f; - if(showMinipanel) - { - minipanel.Update(); - } - - if (gameState.ShowInventoryPanel) - { - inventorypanel.Update(); - } - - if (gameState.ShowCharacterPanel) - { - characterpanel.Update(); - } + minipanel.Update(); runButton.Update(); menuButton.Update(); @@ -177,17 +137,15 @@ namespace OpenDiablo2.Scenes 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) + if (minipanel.IsRightPanelVisible && mouseInfoProvider.MouseX >= 400) return; - if (gameState.ShowCharacterPanel && mouseInfoProvider.MouseX < 400) + if (minipanel.IsLeftPanelVisible && mouseInfoProvider.MouseX < 400) return; // TODO: Filter movement for inventory panel - var xOffset = (gameState.ShowInventoryPanel ? -200 : 0) + (gameState.ShowCharacterPanel ? 200 : 0); - - var mx = (mouseInfoProvider.MouseX - 400) - xOffset; + var mx = (mouseInfoProvider.MouseX - 400) - gameState.CameraOffset; var my = (mouseInfoProvider.MouseY - 300); var tx = (mx / 60f + my / 40f) / 2f; @@ -216,4 +174,4 @@ namespace OpenDiablo2.Scenes } } -} +}