From 86a6ac4a2b2636b35d501628823df09b20c8303b Mon Sep 17 00:00:00 2001 From: Bright0 <55061890+Bright0@users.noreply.github.com> Date: Tue, 28 Jul 2020 16:13:39 -0600 Subject: [PATCH] Adds Handheld Radio/Listener system (#1457) * re-do of old PR that got fuckied upp * simplify foreach as suggested * pass distance to PassSpeechData for a check, remove GetListenRange() * adds RadioQuery instead of subscribing/unsubscribing * change SpreadMessage to accept owner rather than component * change RadioQuery to EntityQuery * remove declared EntityQuery (oops, didn't know what shadowcommander meant) * refactor ListeningSystem & refactor added chat logic into listen sys * IGNORE the oopsie STOP LOOKING --- Content.Server/Chat/ChatManager.cs | 13 +++ .../Components/ListeningComponent.cs | 31 ++++++ .../GameObjects/Components/RadioComponent.cs | 90 ++++++++++++++++++ .../EntitySystems/ListeningSystem.cs | 38 ++++++++ .../GameObjects/EntitySystems/RadioSystem.cs | 49 ++++++++++ Content.Server/Interfaces/IListen.cs | 17 ++++ .../Prototypes/Entities/Objects/radio.yml | 18 ++++ Resources/Textures/Objects/Devices/radio.png | Bin 0 -> 536 bytes 8 files changed, 256 insertions(+) create mode 100644 Content.Server/GameObjects/Components/ListeningComponent.cs create mode 100644 Content.Server/GameObjects/Components/RadioComponent.cs create mode 100644 Content.Server/GameObjects/EntitySystems/ListeningSystem.cs create mode 100644 Content.Server/GameObjects/EntitySystems/RadioSystem.cs create mode 100644 Content.Server/Interfaces/IListen.cs create mode 100644 Resources/Prototypes/Entities/Objects/radio.yml create mode 100644 Resources/Textures/Objects/Devices/radio.png diff --git a/Content.Server/Chat/ChatManager.cs b/Content.Server/Chat/ChatManager.cs index c57fe6c464..6f79bb9d29 100644 --- a/Content.Server/Chat/ChatManager.cs +++ b/Content.Server/Chat/ChatManager.cs @@ -10,6 +10,15 @@ using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; using Robust.Shared.Localization; +using Robust.Shared.Log; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; +using Content.Server.GameObjects.Components; +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Interactable; +using Content.Server.GameObjects.EntitySystems; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Robust.Shared.Interfaces.Map; namespace Content.Server.Chat { @@ -21,6 +30,7 @@ namespace Content.Server.Chat private const int VoiceRange = 7; // how far voice goes in world units #pragma warning disable 649 + [Dependency] private readonly IEntitySystemManager _entitySystemManager; [Dependency] private readonly IServerNetManager _netManager; [Dependency] private readonly IPlayerManager _playerManager; [Dependency] private readonly ILocalizationManager _localizationManager; @@ -67,6 +77,9 @@ namespace Content.Server.Chat msg.MessageWrap = $"{source.Name} says, \"{{0}}\""; msg.SenderEntity = source.Uid; _netManager.ServerSendToMany(msg, clients.ToList()); + + var listeners = _entitySystemManager.GetEntitySystem(); + listeners.PingListeners(source, pos, message); } public void EntityMe(IEntity source, string action) diff --git a/Content.Server/GameObjects/Components/ListeningComponent.cs b/Content.Server/GameObjects/Components/ListeningComponent.cs new file mode 100644 index 0000000000..655e594bef --- /dev/null +++ b/Content.Server/GameObjects/Components/ListeningComponent.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Content.Server.GameObjects.Components.Interactable; +using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Components; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; + +namespace Content.Server.GameObjects.Components +{ + [RegisterComponent] + public class ListeningComponent : Component + { + + public override string Name => "Listening"; + + public void PassSpeechData(string speech, IEntity source, float distance) + { + + foreach (var listener in Owner.GetAllComponents()) + { + if (distance > listener.GetListenRange()) { continue; } + listener.HeardSpeech(speech, source); + } + } + } +} diff --git a/Content.Server/GameObjects/Components/RadioComponent.cs b/Content.Server/GameObjects/Components/RadioComponent.cs new file mode 100644 index 0000000000..e5e7661a5b --- /dev/null +++ b/Content.Server/GameObjects/Components/RadioComponent.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces; +using Content.Server.Interfaces.Chat; +using Content.Server.Interfaces.GameObjects.Components.Interaction; +using Content.Shared.Interfaces.GameObjects.Components; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Components; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components.Interactable +{ + [RegisterComponent] + class RadioComponent : Component, IUse, IListen + { +#pragma warning disable 649 + [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; + [Dependency] private readonly IServerNotifyManager _notifyManager = default!; +#pragma warning restore 649 + + public override string Name => "Radio"; + + private bool _radioOn; + private int _listenRange = 7; + private RadioSystem _radioSystem = default!; + + [ViewVariables] + public bool RadioOn + { + get => _radioOn; + private set + { + _radioOn = value; + Dirty(); + } + } + + public override void Initialize() + { + base.Initialize(); + + _radioSystem = _entitySystemManager.GetEntitySystem(); + + RadioOn = false; + } + + public void PassOnMessage(string message) + { + if(RadioOn) + { + _radioSystem.SpreadMessage(Owner, message); + } + } + + public void Speaker(string message) + { + var chat = IoCManager.Resolve(); + chat.EntitySay(Owner, message); + } + + public bool UseEntity(UseEntityEventArgs eventArgs) + { + RadioOn = !RadioOn; + if(RadioOn) + { + _notifyManager.PopupMessage(Owner, eventArgs.User, "The radio is now on."); + } + else + { + _notifyManager.PopupMessage(Owner, eventArgs.User, "The radio is now off."); + } + return true; + } + + public void HeardSpeech(string speech, IEntity source) + { + PassOnMessage(speech); + } + + public int GetListenRange() + { + return _listenRange; + } + } +} diff --git a/Content.Server/GameObjects/EntitySystems/ListeningSystem.cs b/Content.Server/GameObjects/EntitySystems/ListeningSystem.cs new file mode 100644 index 0000000000..e4e518e1a8 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/ListeningSystem.cs @@ -0,0 +1,38 @@ +using Content.Server.GameObjects.Components; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Content.Server.GameObjects.EntitySystems +{ + class ListeningSystem : EntitySystem + { +#pragma warning disable 649 + [Dependency] private readonly IMapManager _mapManager; + [Dependency] private readonly IEntitySystemManager _entitySystemManager; +#pragma warning restore 649 + + public override void Initialize() + { + base.Initialize(); + EntityQuery = new TypeEntityQuery(typeof(ListeningComponent)); + } + + public void PingListeners(IEntity source, GridCoordinates sourcePos, string message) + { + foreach (var listener in RelevantEntities) + { + var dist = sourcePos.Distance(_mapManager, listener.Transform.GridPosition); + + listener.GetComponent() + .PassSpeechData(message, source, dist); + } + } + } +} diff --git a/Content.Server/GameObjects/EntitySystems/RadioSystem.cs b/Content.Server/GameObjects/EntitySystems/RadioSystem.cs new file mode 100644 index 0000000000..0d8ddf85db --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/RadioSystem.cs @@ -0,0 +1,49 @@ +using Content.Server.GameObjects.Components.Interactable; +using JetBrains.Annotations; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Content.Server.GameObjects.EntitySystems +{ + class RadioSystem : EntitySystem + { + private List _messages; + + public override void Initialize() + { + base.Initialize(); + + EntityQuery = new TypeEntityQuery(typeof(RadioComponent)); + _messages = new List(); + } + + public void SpreadMessage(IEntity source, string message) + { + if (_messages.Contains(message)) + { + return; + } + + _messages.Add(message); + + foreach (var radioEntity in RelevantEntities) + { + var radio = radioEntity.GetComponent(); + if (radioEntity == source || !radio.RadioOn) + { + continue; + } + + radio.Speaker(message); + } + + _messages.Remove(message); + } + } +} diff --git a/Content.Server/Interfaces/IListen.cs b/Content.Server/Interfaces/IListen.cs new file mode 100644 index 0000000000..c778c0adee --- /dev/null +++ b/Content.Server/Interfaces/IListen.cs @@ -0,0 +1,17 @@ +using Robust.Shared.Interfaces.GameObjects; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Content.Server.Interfaces +{ + /// + /// Interface for objects such as radios meant to have an effect when speech is heard. + /// + public interface IListen + { + void HeardSpeech(string speech, IEntity source); + + int GetListenRange(); + } +} diff --git a/Resources/Prototypes/Entities/Objects/radio.yml b/Resources/Prototypes/Entities/Objects/radio.yml new file mode 100644 index 0000000000..f087bc6a2c --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/radio.yml @@ -0,0 +1,18 @@ +- type: entity + name: "baseradio" + parent: BaseItem + id: BaseRadio + abstract: true + +- type: entity + name: "Handheld Radio" + description: A handy handheld radio. + parent: BaseRadio + id: handrad + components: + - type: Sprite + texture: Objects/Devices/radio.png + - type: Icon + texture: Objects/Devices/radio.png + - type: Listening + - type: Radio diff --git a/Resources/Textures/Objects/Devices/radio.png b/Resources/Textures/Objects/Devices/radio.png new file mode 100644 index 0000000000000000000000000000000000000000..eb57264b858e705554298b886911a667fa507548 GIT binary patch literal 536 zcmV+z0_XjSP)Px$(n&-?R9J=WR=rOGF&uqYhzcwOS#DyGgaL5i%Y@zK28oM_D}$qn6N`(6zraD` zVjPW&VPSDq5(z;J#KZ_L4wZmNBoZZrI^gl)SFQyyQQp#P@7MQxef{0Fz!+ov1vs5f zCOVf4LxA7!7oIy50Y;;7^a6Tquh;9s0`wx2ToJ;2ML&wBOJ;USKnt)2Bvwu`iIqBML0Dyi-ktI5??6gsVe3|^+c z*CSzj#6yOmd|gMQ(Ez0slu|rRlrT9h;rR}zoU;wByqX=z&Q$yQ7K;T2g8{W#O)JHx z5c&@Qz~XTf2h9vj0H!V~D6VY+;4ebW0%i*Z$sQ)m5hS?TZ;vHS#r8uGu)f6+&Lwe$ zTYTNm`)Gb0)|ZnHF+b+Odnk$m_pQ6rKTPci@eFhth7_f*t)v+D76=RQxZQ}w;|M7V zV)3{rjkthxHrq+AIxtcJUpY|C@g0cV0!oQ?f?so>_dHNnK1dC4-(c)v!oIUv