From 862ea62b4440aa2f698bb1db17c0a71bc1d063f2 Mon Sep 17 00:00:00 2001 From: Kacper Drobny Date: Sun, 9 Dec 2018 21:12:15 +0100 Subject: [PATCH] added slot switch in inventory (#41) * refactoring of minipanel * removed unnecessary fields * panel location is now relative to the panel position * adjusted inventory sprites * added close button to panels * added slot switch in inventory panel --- OpenDiablo2.Common/Enums/eButtonType.cs | 1 + OpenDiablo2.Common/Interfaces/UI/IButton.cs | 10 ++ OpenDiablo2.Common/Models/ButtonLayout.cs | 4 +- OpenDiablo2.Common/ResourcePaths.cs | 3 +- OpenDiablo2.Core/UI/Button.cs | 32 +++-- OpenDiablo2.Core/UI/CharacterPanel.cs | 10 +- OpenDiablo2.Core/UI/InventoryPanel.cs | 124 ++++++++++++++------ 7 files changed, 127 insertions(+), 57 deletions(-) diff --git a/OpenDiablo2.Common/Enums/eButtonType.cs b/OpenDiablo2.Common/Enums/eButtonType.cs index 2521c6ea..b0788235 100644 --- a/OpenDiablo2.Common/Enums/eButtonType.cs +++ b/OpenDiablo2.Common/Enums/eButtonType.cs @@ -12,6 +12,7 @@ Menu, GoldCoin, Close, + SecondaryInvHand, MinipanelCharacter, MinipanelInventory, MinipanelSkill, diff --git a/OpenDiablo2.Common/Interfaces/UI/IButton.cs b/OpenDiablo2.Common/Interfaces/UI/IButton.cs index aafe5551..846a37a1 100644 --- a/OpenDiablo2.Common/Interfaces/UI/IButton.cs +++ b/OpenDiablo2.Common/Interfaces/UI/IButton.cs @@ -40,6 +40,16 @@ namespace OpenDiablo2.Common.Interfaces /// Point Location { get; set; } + /// + /// Area from upper left corner that reacts to clicking + /// + Size ClickableRect { get; set; } + + /// + /// Indicates if button sprite should react to Toggle and Activate on hover + /// + bool AllowFrameChange { get; set; } + /// /// Assigning a function to this property will cause that function to be called /// when the button is toggled on or off. diff --git a/OpenDiablo2.Common/Models/ButtonLayout.cs b/OpenDiablo2.Common/Models/ButtonLayout.cs index f209b24f..cf47f04e 100644 --- a/OpenDiablo2.Common/Models/ButtonLayout.cs +++ b/OpenDiablo2.Common/Models/ButtonLayout.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Drawing; using OpenDiablo2.Common.Enums; namespace OpenDiablo2.Common.Models @@ -27,7 +28,8 @@ namespace OpenDiablo2.Common.Models {eButtonType.MinipanelMessage, new ButtonLayout {XSegments = 1, ResourceName = ResourcePaths.MinipanelButton,PaletteName = Palettes.Units, BaseFrame = 10 } }, {eButtonType.MinipanelQuest, new ButtonLayout {XSegments = 1, ResourceName = ResourcePaths.MinipanelButton,PaletteName = Palettes.Units, BaseFrame = 12 } }, {eButtonType.MinipanelMenu, new ButtonLayout {XSegments = 1, ResourceName = ResourcePaths.MinipanelButton,PaletteName = Palettes.Units, BaseFrame = 14 } }, - + + {eButtonType.SecondaryInvHand, new ButtonLayout {XSegments = 1, ResourceName = ResourcePaths.InventoryWeaponsTab, PaletteName = Palettes.Units } }, {eButtonType.Run, new ButtonLayout {XSegments = 1, ResourceName = ResourcePaths.RunButton,PaletteName = Palettes.Units, Toggleable = true } }, {eButtonType.Menu, new ButtonLayout {XSegments = 1, ResourceName = ResourcePaths.MenuButton,PaletteName = Palettes.Units, Toggleable = true } }, {eButtonType.GoldCoin, new ButtonLayout {XSegments = 1, ResourceName = ResourcePaths.GoldCoinButton,PaletteName = Palettes.Units } }, diff --git a/OpenDiablo2.Common/ResourcePaths.cs b/OpenDiablo2.Common/ResourcePaths.cs index 91f650f6..c2cda5e4 100644 --- a/OpenDiablo2.Common/ResourcePaths.cs +++ b/OpenDiablo2.Common/ResourcePaths.cs @@ -122,7 +122,8 @@ namespace OpenDiablo2.Common public const string MinipanelButton = @"data\global\ui\PANEL\minipanelbtn.DC6"; public const string Frame = @"data\global\ui\PANEL\800borderframe.dc6"; - public const string InventoryCharacterPanel = @"data\global\ui\PANEL\invchar.DC6"; + public const string InventoryCharacterPanel = @"data\global\ui\PANEL\invchar6.DC6"; + public const string InventoryWeaponsTab = @"data\global\ui\PANEL\invchar6Tab.DC6"; public const string RunButton = @"data\global\ui\PANEL\runbutton.dc6"; public const string MenuButton = @"data\global\ui\PANEL\menubutton.DC6"; diff --git a/OpenDiablo2.Core/UI/Button.cs b/OpenDiablo2.Core/UI/Button.cs index a61a42a2..d5f07495 100644 --- a/OpenDiablo2.Core/UI/Button.cs +++ b/OpenDiablo2.Core/UI/Button.cs @@ -40,6 +40,9 @@ namespace OpenDiablo2.Core.UI private Point labelOffset = new Point(); + public Size ClickableRect { get; set; } + public bool AllowFrameChange { get; set; } = true; + private bool enabled = true; public bool Enabled { @@ -136,8 +139,10 @@ namespace OpenDiablo2.Core.UI return; } - var hovered = mouseInfoProvider.MouseX >= location.X && mouseInfoProvider.MouseX < (location.X + buttonWidth) - && mouseInfoProvider.MouseY >= location.Y && mouseInfoProvider.MouseY < (location.Y + buttonHeight); + int clickWidth = ClickableRect.Width > 0 ? ClickableRect.Width : buttonWidth; + int clickHeight = ClickableRect.Height > 0 ? ClickableRect.Height : buttonHeight; + var hovered = mouseInfoProvider.MouseX >= location.X && mouseInfoProvider.MouseX < (location.X + clickWidth) + && mouseInfoProvider.MouseY >= location.Y && mouseInfoProvider.MouseY < (location.Y + clickHeight); if (!activeLock && hovered && mouseInfoProvider.LeftMouseDown && !mouseInfoProvider.ReserveMouse) @@ -179,17 +184,20 @@ namespace OpenDiablo2.Core.UI { var frame = buttonLayout.BaseFrame; - if(Toggled && pressed) + if (AllowFrameChange) { - frame = buttonLayout.BaseFrame + 3; - } - else if(pressed) - { - frame = buttonLayout.BaseFrame + 1; - } - else if(Toggled) - { - frame = buttonLayout.BaseFrame + 2; + if (Toggled && pressed) + { + frame = buttonLayout.BaseFrame + 3; + } + else if (pressed) + { + frame = buttonLayout.BaseFrame + 1; + } + else if (Toggled) + { + frame = buttonLayout.BaseFrame + 2; + } } renderWindow.Draw(sprite, buttonLayout.XSegments, 1, frame); diff --git a/OpenDiablo2.Core/UI/CharacterPanel.cs b/OpenDiablo2.Core/UI/CharacterPanel.cs index 2fdbb50b..2ca53585 100644 --- a/OpenDiablo2.Core/UI/CharacterPanel.cs +++ b/OpenDiablo2.Core/UI/CharacterPanel.cs @@ -26,7 +26,7 @@ namespace OpenDiablo2.Core.UI public sealed class CharacterPanel : ICharacterPanel { private readonly IRenderWindow renderWindow; - private readonly ISprite sprite; + private readonly ISprite panelSprite; private readonly IButton closeButton; @@ -38,10 +38,10 @@ namespace OpenDiablo2.Core.UI { this.renderWindow = renderWindow; - sprite = renderWindow.LoadSprite(ResourcePaths.InventoryCharacterPanel, Palettes.Act1, FrameType.GetOffset(), true); + panelSprite = renderWindow.LoadSprite(ResourcePaths.InventoryCharacterPanel, Palettes.Act1, FrameType.GetOffset(), true); closeButton = createButton(eButtonType.Close); - closeButton.Location = sprite.Location + new Size(128, 388); + closeButton.Location = panelSprite.Location + new Size(128, 388); closeButton.OnActivate = () => OnPanelClosed?.Invoke(this); } @@ -55,14 +55,14 @@ namespace OpenDiablo2.Core.UI public void Render() { - renderWindow.Draw(sprite, 2, 2, 0); + renderWindow.Draw(panelSprite, 2, 2, 0); closeButton.Render(); } public void Dispose() { - sprite.Dispose(); + panelSprite.Dispose(); } } } diff --git a/OpenDiablo2.Core/UI/InventoryPanel.cs b/OpenDiablo2.Core/UI/InventoryPanel.cs index 46f258ec..009f0e9f 100644 --- a/OpenDiablo2.Core/UI/InventoryPanel.cs +++ b/OpenDiablo2.Core/UI/InventoryPanel.cs @@ -29,18 +29,13 @@ namespace OpenDiablo2.Core.UI public sealed class InventoryPanel : IInventoryPanel { private readonly IRenderWindow renderWindow; - private readonly ISprite sprite; + private readonly ISprite panelSprite; + + public IItemContainer helmContainer, armorContainer, beltContainer, gloveContainer, bootsContainer, + leftHandContainer, rightHandContainer, secondaryLeftHandContainer, secondaryRightHandContainer, + ringtLeftContainer, ringtRightContainer, amuletContainer; - public eButtonType PanelType => eButtonType.MinipanelInventory; - public ePanelFrameType FrameType => ePanelFrameType.Right; - - // Test vars - public IItemContainer helmContainer, armorContainer, weaponLeftContainer, weaponRightContainer, beltContainer, gloveContainer, bootsContainer; - private readonly IItemContainer ringtLeftContainer; - private readonly IItemContainer ringtRightContainer; - private readonly IItemContainer amuletContainer; - - private readonly IButton closeButton, goldButton; + private readonly IButton closeButton, secondaryLeftButton, secondaryRightButton, goldButton; public event OnPanelClosedEvent OnPanelClosed; @@ -51,67 +46,104 @@ namespace OpenDiablo2.Core.UI { this.renderWindow = renderWindow; - sprite = renderWindow.LoadSprite(ResourcePaths.InventoryCharacterPanel, Palettes.Units, FrameType.GetOffset(), true); + panelSprite = renderWindow.LoadSprite(ResourcePaths.InventoryCharacterPanel, Palettes.Units, FrameType.GetOffset(), true); closeButton = createButton(eButtonType.Close); - closeButton.Location = sprite.Location + new Size(18, 384); + closeButton.Location = panelSprite.Location + new Size(18, 384); closeButton.OnActivate = () => OnPanelClosed?.Invoke(this); + secondaryLeftButton = createButton(eButtonType.SecondaryInvHand); + secondaryLeftButton.Location = panelSprite.Location + new Size(15, 22); + secondaryLeftButton.OnActivate = ToggleWeaponsSlot; + secondaryLeftButton.ClickableRect = new Size(0, 20); + secondaryLeftButton.AllowFrameChange = false; + + secondaryRightButton = createButton(eButtonType.SecondaryInvHand); + secondaryRightButton.Location = panelSprite.Location + new Size(246, 22); + secondaryRightButton.OnActivate = ToggleWeaponsSlot; + secondaryRightButton.ClickableRect = new Size(0, 20); + secondaryRightButton.AllowFrameChange = false; + goldButton = createButton(eButtonType.GoldCoin); - goldButton.Location = sprite.Location + new Size(84, 391); + goldButton.Location = panelSprite.Location + new Size(84, 391); goldButton.OnActivate = OpenGoldDrop; helmContainer = createItemContainer(eItemContainerType.Helm); - helmContainer.Location = sprite.Location + new Size(135, 5); + helmContainer.Location = panelSprite.Location + new Size(135, 5); helmContainer.SetContainedItem(itemManager.getItem("cap")); amuletContainer = createItemContainer(eItemContainerType.Amulet); - amuletContainer.Location = sprite.Location + new Size(209, 34); + amuletContainer.Location = panelSprite.Location + new Size(209, 34); amuletContainer.SetContainedItem(itemManager.getItem("vip")); armorContainer = createItemContainer(eItemContainerType.Armor); - armorContainer.Location = sprite.Location + new Size(135, 75); + armorContainer.Location = panelSprite.Location + new Size(135, 75); armorContainer.SetContainedItem(itemManager.getItem("hla")); - - weaponLeftContainer = createItemContainer(eItemContainerType.Weapon); - weaponLeftContainer.Location = sprite.Location + new Size(20, 47); - weaponLeftContainer.SetContainedItem(itemManager.getItem("ame")); - - weaponRightContainer = createItemContainer(eItemContainerType.Weapon); - weaponRightContainer.Location = sprite.Location + new Size(253, 47); - weaponRightContainer.SetContainedItem(itemManager.getItem("paf")); - + + leftHandContainer = createItemContainer(eItemContainerType.Weapon); + leftHandContainer.Location = panelSprite.Location + new Size(20, 47); + leftHandContainer.SetContainedItem(itemManager.getItem("ame")); + + rightHandContainer = createItemContainer(eItemContainerType.Weapon); + rightHandContainer.Location = panelSprite.Location + new Size(253, 47); + rightHandContainer.SetContainedItem(itemManager.getItem("paf")); + + secondaryLeftHandContainer = createItemContainer(eItemContainerType.Weapon); + secondaryLeftHandContainer.Location = panelSprite.Location + new Size(24, 45); + secondaryLeftHandContainer.SetContainedItem(itemManager.getItem("crs")); + + secondaryRightHandContainer = createItemContainer(eItemContainerType.Weapon); + secondaryRightHandContainer.Location = panelSprite.Location + new Size(257, 45); + secondaryRightHandContainer.SetContainedItem(itemManager.getItem("kit")); + beltContainer = createItemContainer(eItemContainerType.Belt); - beltContainer.Location = sprite.Location + new Size(136, 178); + beltContainer.Location = panelSprite.Location + new Size(136, 178); beltContainer.SetContainedItem(itemManager.getItem("vbl")); ringtLeftContainer = createItemContainer(eItemContainerType.Ring); - ringtLeftContainer.Location = sprite.Location + new Size(95, 179); + ringtLeftContainer.Location = panelSprite.Location + new Size(95, 179); ringtLeftContainer.SetContainedItem(itemManager.getItem("rin")); ringtRightContainer = createItemContainer(eItemContainerType.Ring); - ringtRightContainer.Location = sprite.Location + new Size(209, 179); + ringtRightContainer.Location = panelSprite.Location + new Size(209, 179); ringtRightContainer.SetContainedItem(itemManager.getItem("rin")); gloveContainer = createItemContainer(eItemContainerType.Glove); - gloveContainer.Location = sprite.Location + new Size(20, 179); + gloveContainer.Location = panelSprite.Location + new Size(20, 179); gloveContainer.SetContainedItem(itemManager.getItem("tgl")); bootsContainer = createItemContainer(eItemContainerType.Boots); - bootsContainer.Location = sprite.Location + new Size(251, 178); + bootsContainer.Location = panelSprite.Location + new Size(251, 178); bootsContainer.SetContainedItem(itemManager.getItem("lbt")); } + public eButtonType PanelType => eButtonType.MinipanelInventory; + public ePanelFrameType FrameType => ePanelFrameType.Right; + + public bool IsSecondaryEquipped { get; private set; } + public void Update() { + if (IsSecondaryEquipped) + { + secondaryLeftHandContainer.Update(); + secondaryRightHandContainer.Update(); + } + else + { + leftHandContainer.Update(); + rightHandContainer.Update(); + } + + secondaryLeftButton.Update(); + secondaryRightButton.Update(); + closeButton.Update(); goldButton.Update(); helmContainer.Update(); amuletContainer.Update(); armorContainer.Update(); - weaponLeftContainer.Update(); - weaponRightContainer.Update(); beltContainer.Update(); ringtLeftContainer.Update(); ringtRightContainer.Update(); @@ -121,7 +153,20 @@ namespace OpenDiablo2.Core.UI public void Render() { - renderWindow.Draw(sprite, 2, 2, 1); + renderWindow.Draw(panelSprite, 2, 2, 1); + + if (IsSecondaryEquipped) + { + secondaryLeftButton.Render(); + secondaryRightButton.Render(); + secondaryLeftHandContainer.Render(); + secondaryRightHandContainer.Render(); + } + else + { + leftHandContainer.Render(); + rightHandContainer.Render(); + } closeButton.Render(); goldButton.Render(); @@ -129,8 +174,6 @@ namespace OpenDiablo2.Core.UI helmContainer.Render(); amuletContainer.Render(); armorContainer.Render(); - weaponLeftContainer.Render(); - weaponRightContainer.Render(); beltContainer.Render(); ringtLeftContainer.Render(); ringtRightContainer.Render(); @@ -140,12 +183,17 @@ namespace OpenDiablo2.Core.UI public void Dispose() { - sprite.Dispose(); + panelSprite.Dispose(); + } + + private void ToggleWeaponsSlot() + { + IsSecondaryEquipped = !IsSecondaryEquipped; } private void OpenGoldDrop() { - // todo; + } } }