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
This commit is contained in:
Bright0
2020-07-28 16:13:39 -06:00
committed by GitHub
parent b5667230c1
commit 86a6ac4a2b
8 changed files with 256 additions and 0 deletions

View File

@@ -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<ListeningSystem>();
listeners.PingListeners(source, pos, message);
}
public void EntityMe(IEntity source, string action)

View File

@@ -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<IListen>())
{
if (distance > listener.GetListenRange()) { continue; }
listener.HeardSpeech(speech, source);
}
}
}
}

View File

@@ -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<RadioSystem>();
RadioOn = false;
}
public void PassOnMessage(string message)
{
if(RadioOn)
{
_radioSystem.SpreadMessage(Owner, message);
}
}
public void Speaker(string message)
{
var chat = IoCManager.Resolve<IChatManager>();
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;
}
}
}

View File

@@ -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<ListeningComponent>()
.PassSpeechData(message, source, dist);
}
}
}
}

View File

@@ -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<string> _messages;
public override void Initialize()
{
base.Initialize();
EntityQuery = new TypeEntityQuery(typeof(RadioComponent));
_messages = new List<string>();
}
public void SpreadMessage(IEntity source, string message)
{
if (_messages.Contains(message))
{
return;
}
_messages.Add(message);
foreach (var radioEntity in RelevantEntities)
{
var radio = radioEntity.GetComponent<RadioComponent>();
if (radioEntity == source || !radio.RadioOn)
{
continue;
}
radio.Speaker(message);
}
_messages.Remove(message);
}
}
}

View File

@@ -0,0 +1,17 @@
using Robust.Shared.Interfaces.GameObjects;
using System;
using System.Collections.Generic;
using System.Text;
namespace Content.Server.Interfaces
{
/// <summary>
/// Interface for objects such as radios meant to have an effect when speech is heard.
/// </summary>
public interface IListen
{
void HeardSpeech(string speech, IEntity source);
int GetListenRange();
}
}

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B