Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Handheld Radio/Listener system #1457

Merged
merged 9 commits into from
Jul 28, 2020
13 changes: 13 additions & 0 deletions Content.Server/Chat/ChatManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
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
{
Expand All @@ -21,6 +30,7 @@ internal sealed class ChatManager : IChatManager
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;
Expand Down Expand Up @@ -67,6 +77,9 @@ public void EntitySay(IEntity source, string message)
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)
Expand Down
31 changes: 31 additions & 0 deletions Content.Server/GameObjects/Components/ListeningComponent.cs
Original file line number Diff line number Diff line change
@@ -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);
Bright0 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
90 changes: 90 additions & 0 deletions Content.Server/GameObjects/Components/RadioComponent.cs
Original file line number Diff line number Diff line change
@@ -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>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gonna need @PJB3005's feedback on this. Should the RadioSystem be saved like this or should it just be fetched every time on line 56.


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;
}
}
}
38 changes: 38 additions & 0 deletions Content.Server/GameObjects/EntitySystems/ListeningSystem.cs
Original file line number Diff line number Diff line change
@@ -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);
Comment on lines +33 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
listener.GetComponent<ListeningComponent>()
.PassSpeechData(message, source, dist);
foreach (var listener in entity.GetAllComponents<IListen>())
{
if (dist > listener.GetListenRange())
{
continue;
}
listener.HeardSpeech(message, source);
}

}
}
}
}
49 changes: 49 additions & 0 deletions Content.Server/GameObjects/EntitySystems/RadioSystem.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
17 changes: 17 additions & 0 deletions Content.Server/Interfaces/IListen.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
18 changes: 18 additions & 0 deletions Resources/Prototypes/Entities/Objects/radio.yml
Original file line number Diff line number Diff line change
@@ -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 added Resources/Textures/Objects/Devices/radio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.