diff --git a/Content.Client/Content.Client.csproj b/Content.Client/Content.Client.csproj index 4927d2da9e..8dbc915a17 100644 --- a/Content.Client/Content.Client.csproj +++ b/Content.Client/Content.Client.csproj @@ -62,8 +62,9 @@ - + + @@ -82,6 +83,10 @@ {31d24303-f6a9-4d53-bb03-a73edcb3186d} sfml-system + + {d17de83d-a592-461f-8af2-53f9e22e1d0f} + sfml-window + {302b877e-0000-0000-0000-000000000000} SS14.Client.Graphics @@ -105,4 +110,4 @@ - + \ No newline at end of file diff --git a/Content.Client/GameObjects/Components/Items/HandsComponent.cs b/Content.Client/GameObjects/Components/Items/ClientHandsComponent.cs similarity index 53% rename from Content.Client/GameObjects/Components/Items/HandsComponent.cs rename to Content.Client/GameObjects/Components/Items/ClientHandsComponent.cs index 315b9aa7d2..3688198afe 100644 --- a/Content.Client/GameObjects/Components/Items/HandsComponent.cs +++ b/Content.Client/GameObjects/Components/Items/ClientHandsComponent.cs @@ -1,5 +1,10 @@ -using Content.Client.Interfaces.GameObjects; +using Content.Client.Interfaces.GameObjects; +using Content.Client.UserInterface; using Content.Shared.GameObjects; +using Lidgren.Network; +using SS14.Client.Interfaces.UserInterface; +using SS14.Client.UserInterface; +using SS14.Shared; using SS14.Shared.GameObjects; using SS14.Shared.Interfaces.GameObjects; using SS14.Shared.IoC; @@ -10,6 +15,7 @@ namespace Content.Client.GameObjects public class HandsComponent : SharedHandsComponent, IHandsComponent { private readonly Dictionary hands = new Dictionary(); + public string ActiveIndex { get; private set; } public IEntity GetEntity(string index) { @@ -29,6 +35,21 @@ namespace Content.Client.GameObjects { hands[hand.Key] = Owner.EntityManager.GetEntity(hand.Value); } + + ActiveIndex = cast.ActiveIndex; + + var uiMgr = (UserInterfaceManager)IoCManager.Resolve(); + + if (uiMgr.GetSingleComponentByGuiComponentType(GuiComponentType.HandsUi) == null) + { + uiMgr.AddComponent(new HandsGui()); + } + uiMgr.ComponentUpdate(GuiComponentType.HandsUi, this); + } + + public void SendChangeHand(string index) + { + Owner.SendComponentNetworkMessage(this, NetDeliveryMethod.ReliableUnordered, index); } } } diff --git a/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs b/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs index 06a9f6c1c7..91002b3cc9 100644 --- a/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs +++ b/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs @@ -1,9 +1,4 @@ -using Content.Client.Interfaces.GameObjects; -using Content.Shared.GameObjects; -using SS14.Shared.GameObjects; -using SS14.Shared.Interfaces.GameObjects; -using SS14.Shared.IoC; -using System.Collections.Generic; +using SS14.Shared.Interfaces.GameObjects; namespace Content.Client.Interfaces.GameObjects { @@ -12,5 +7,8 @@ namespace Content.Client.Interfaces.GameObjects public interface IHandsComponent { IEntity GetEntity(string index); + string ActiveIndex { get; } + + void SendChangeHand(string index); } } diff --git a/Content.Client/UserInterface/HandsGui.cs b/Content.Client/UserInterface/HandsGui.cs new file mode 100644 index 0000000000..92eb8be029 --- /dev/null +++ b/Content.Client/UserInterface/HandsGui.cs @@ -0,0 +1,192 @@ +using Content.Client.Interfaces.GameObjects; +using OpenTK.Graphics; +using SFML.Graphics; +using SFML.Window; +using SS14.Client.GameObjects; +using SS14.Client.Graphics; +using SS14.Client.Graphics.Utility; +using SS14.Client.Interfaces.Player; +using SS14.Client.Interfaces.Resource; +using SS14.Client.Interfaces.UserInterface; +using SS14.Client.UserInterface.Components; +using SS14.Shared; +using SS14.Shared.Interfaces.GameObjects; +using SS14.Shared.IoC; +using SS14.Shared.Maths; + +namespace Content.Client.UserInterface +{ + public class HandsGui : GuiComponent + { + private readonly Color4 _inactiveColor = new Color4(90, 90, 90, 255); + + private readonly IPlayerManager _playerManager = IoCManager.Resolve(); + private readonly IUserInterfaceManager _userInterfaceManager = IoCManager.Resolve(); + private readonly Sprite handSlot; + private readonly int spacing = 1; + + private UiHandInfo LeftHand; + private UiHandInfo RightHand; + private Box2i handL; + private Box2i handR; + + public HandsGui() + { + var _resMgr = IoCManager.Resolve(); + ComponentClass = GuiComponentType.HandsUi; + handSlot = _resMgr.GetSprite("hand"); + ZDepth = 5; + } + + public override void ComponentUpdate(params object[] args) + { + base.ComponentUpdate(args); + UpdateHandIcons(); + } + + public override void Update(float frameTime) + { + var slotBounds = handSlot.GetLocalBounds(); + var width = (int)((slotBounds.Width * 2) + spacing); + var height = (int)slotBounds.Height; + Position = new Vector2i((int)(CluwneLib.Window.Viewport.Width - width) / 2, (int)CluwneLib.Window.Viewport.Height - height - 10); + handL = Box2i.FromDimensions(Position.X, Position.Y, (int)slotBounds.Width, (int)slotBounds.Height); + handR = Box2i.FromDimensions(Position.X + (int)slotBounds.Width + spacing, Position.Y, (int)slotBounds.Width, (int)slotBounds.Height); + ClientArea = Box2i.FromDimensions(Position.X, Position.Y, width, (int)slotBounds.Height); + } + + public override void Render() + { + if (_playerManager?.ControlledEntity == null) + { + return; + } + + IEntity entity = _playerManager.ControlledEntity; + if (!entity.TryGetComponent(out var hands)) + { + return; + } + + var leftActive = hands.ActiveIndex == "left"; + + handSlot.Color = Color.White; + handSlot.SetTransformToRect(leftActive ? handL : handR); + handSlot.Draw(); + + handSlot.Color = _inactiveColor.Convert(); + handSlot.SetTransformToRect(leftActive ? handR : handL); + handSlot.Draw(); + + if (LeftHand.Entity != null && LeftHand.HeldSprite != null) + { + var bounds = LeftHand.HeldSprite.GetLocalBounds(); + LeftHand.HeldSprite.SetTransformToRect( + Box2i.FromDimensions(handL.Left + (int)(handL.Width / 2f - bounds.Width / 2f), + handL.Top + (int)(handL.Height / 2f - bounds.Height / 2f), + (int)bounds.Width, (int)bounds.Height)); + LeftHand.HeldSprite.Draw(); + } + + if (RightHand.Entity != null && RightHand.HeldSprite != null) + { + var bounds = RightHand.HeldSprite.GetLocalBounds(); + RightHand.HeldSprite.SetTransformToRect( + Box2i.FromDimensions(handR.Left + (int)(handR.Width / 2f - bounds.Width / 2f), + handR.Top + (int)(handR.Height / 2f - bounds.Height / 2f), + (int)bounds.Width, (int)bounds.Height)); + RightHand.HeldSprite.Draw(); + } + } + + public void UpdateHandIcons() + { + if (_playerManager?.ControlledEntity == null) + { + return; + } + + IEntity entity = _playerManager.ControlledEntity; + if (!entity.TryGetComponent(out var hands)) + { + return; + } + + var left = hands.GetEntity("left"); + var right = hands.GetEntity("right"); + + if (left != null) + { + if (left != LeftHand.Entity) + { + LeftHand.Entity = left; + LeftHand.HeldSprite = GetIconSprite(left); + } + } + else + { + LeftHand.Entity = null; + LeftHand.HeldSprite = null; + } + + if (right != null) + { + if (right != RightHand.Entity) + { + RightHand.Entity = right; + RightHand.HeldSprite = GetIconSprite(right); + } + } + else + { + RightHand.Entity = null; + RightHand.HeldSprite = null; + } + } + + private void SendSwitchHandTo(string index) + { + IEntity entity = _playerManager.ControlledEntity; + if (!entity.TryGetComponent(out var hands)) + { + return; + } + hands.SendChangeHand(index); + } + + public override bool MouseDown(MouseButtonEventArgs e) + { + if (e.Button != Mouse.Button.Right) + { + return false; + } + if (handL.Contains(e.X, e.Y)) + { + SendSwitchHandTo("left"); + return true; + } + if (handR.Contains(e.X, e.Y)) + { + SendSwitchHandTo("right"); + return true; + } + return false; + } + + private static Sprite GetIconSprite(IEntity entity) + { + Sprite icon = null; + if (entity.TryGetComponent(out var component)) + { + icon = component.Icon; + } + return icon ?? IoCManager.Resolve().DefaultSprite(); + } + + private struct UiHandInfo + { + public IEntity Entity { get; set; } + public Sprite HeldSprite { get; set; } + } + } +} diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj index d2cdb12b80..da2735d7f1 100644 --- a/Content.Server/Content.Server.csproj +++ b/Content.Server/Content.Server.csproj @@ -59,7 +59,7 @@ - + @@ -91,4 +91,4 @@ - + \ No newline at end of file diff --git a/Content.Server/GameObjects/Components/Items/ItemComponent.cs b/Content.Server/GameObjects/Components/Items/ItemComponent.cs index efebe59f4c..113fc2c6ef 100644 --- a/Content.Server/GameObjects/Components/Items/ItemComponent.cs +++ b/Content.Server/GameObjects/Components/Items/ItemComponent.cs @@ -1,6 +1,7 @@ -using Content.Server.Interfaces.GameObjects; +using Content.Server.Interfaces.GameObjects; using SS14.Shared.GameObjects; using SS14.Shared.Interfaces.GameObjects; +using SS14.Server.Interfaces.GameObjects; using System; namespace Content.Server.GameObjects @@ -20,6 +21,11 @@ namespace Content.Server.GameObjects } ContainingSlot = null; + + foreach (var component in Owner.GetComponents()) + { + component.Visible = true; + } } public void EquippedToSlot(IInventorySlot slot) @@ -30,6 +36,11 @@ namespace Content.Server.GameObjects } ContainingSlot = slot; + + foreach (var component in Owner.GetComponents()) + { + component.Visible = false; + } } } } diff --git a/Content.Server/GameObjects/Components/Items/HandsComponent.cs b/Content.Server/GameObjects/Components/Items/ServerHandsComponent.cs similarity index 93% rename from Content.Server/GameObjects/Components/Items/HandsComponent.cs rename to Content.Server/GameObjects/Components/Items/ServerHandsComponent.cs index f5f20970b9..e5ea4c9572 100644 --- a/Content.Server/GameObjects/Components/Items/HandsComponent.cs +++ b/Content.Server/GameObjects/Components/Items/ServerHandsComponent.cs @@ -4,12 +4,11 @@ using SS14.Server.GameObjects.Events; using SS14.Server.Interfaces.GameObjects; using SS14.Shared; using SS14.Shared.GameObjects; -using SS14.Shared.Interfaces.GameObjects; using SS14.Shared.Utility; -using System.Collections.Generic; using System; -using System.Linq; +using System.Collections.Generic; using YamlDotNet.RepresentationModel; +using Lidgren.Network; namespace Content.Server.GameObjects { @@ -224,7 +223,7 @@ namespace Content.Server.GameObjects dict[hand.Key] = hand.Value.Item.Owner.Uid; } } - return new HandsComponentState(dict); + return new HandsComponentState(dict, ActiveIndex); } // Game logic goes here. @@ -276,5 +275,19 @@ namespace Content.Server.GameObjects PutInHand(item, ActiveIndex, fallback: false); } + + public override void HandleNetworkMessage(IncomingEntityComponentMessage message, NetConnection sender) + { + if (message.MessageParameters.Count != 1) + { + return; + } + var index = message.MessageParameters[0]; + if (index is string newIndex && HasHand(newIndex)) + { + ActiveIndex = newIndex; + } + base.HandleNetworkMessage(message, sender); + } } } diff --git a/Content.Shared/Content.Shared.csproj b/Content.Shared/Content.Shared.csproj index 7618413325..c200d1c88f 100644 --- a/Content.Shared/Content.Shared.csproj +++ b/Content.Shared/Content.Shared.csproj @@ -56,7 +56,7 @@ - + @@ -97,4 +97,4 @@ - + \ No newline at end of file diff --git a/Content.Shared/GameObjects/Components/Items/HandsComponent.cs b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs similarity index 80% rename from Content.Shared/GameObjects/Components/Items/HandsComponent.cs rename to Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs index bac1c58156..a6bd76d5d4 100644 --- a/Content.Shared/GameObjects/Components/Items/HandsComponent.cs +++ b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs @@ -1,4 +1,4 @@ -using SS14.Shared.GameObjects; +using SS14.Shared.GameObjects; using System; using System.Collections.Generic; @@ -16,10 +16,12 @@ namespace Content.Shared.GameObjects public class HandsComponentState : ComponentState { public readonly Dictionary Hands; + public readonly string ActiveIndex; - public HandsComponentState(Dictionary hands) + public HandsComponentState(Dictionary hands, string activeIndex) : base(ContentNetIDs.HANDS) { Hands = hands; + ActiveIndex = activeIndex; } } } diff --git a/Resources/Prototypes/Entities/Items.yml b/Resources/Prototypes/Entities/Items.yml index c531503e36..28667c3eba 100644 --- a/Resources/Prototypes/Entities/Items.yml +++ b/Resources/Prototypes/Entities/Items.yml @@ -5,3 +5,10 @@ components: - type: Item +- type: entity + name: "Mop 2: Handle edition" + parent: Mop + id: MopItem + components: + - type: Item +