* Initial resources commit * Initial code commit * Added additional resources * Continuing to build holopad and telephone systems * Added hologram shader * Added hologram system and entity * Holo calls now have a hologram of the user appear on them * Initial implementation of holopads transmitting nearby chatter * Added support for linking across multiple telephones/holopads/entities * Fixed a bunch of bugs * Tried simplifying holopad entity dependence, added support for mid-call user switching * Replaced PVS expansion with manually networked sprite states * Adjusted volume of ring tone * Added machine board * Minor features and tweaks * Resolving merge conflict * Recommit audio attributions * Telephone chat adjustments * Added support for AI interactions with holopads * Building the holopad UI * Holopad UI finished * Further UI tweaks * Station AI can hear local chatter when being projected from a holopad * Minor bug fixes * Added wire panels to holopads * Basic broadcasting * Start of emergency broadcasting code * Fixing issues with broadcasting * More work on emergency broadcasting * Updated holopad visuals * Added cooldown text to emergency broadcast and control lock out screen * Code clean up * Fixed issue with timing * Broadcasting now requires command access * Fixed some bugs * Added multiple holopad prototypes with different ranges * The AI no longer requires power to interact with holopads * Fixed some additional issues * Addressing more issues * Added emote support for holograms * Changed the broadcast lockout durations to their proper values * Added AI vision wire to holopads * Bug fixes * AI vision and interaction wires can be added to the same wire panel * Fixed error * More bug fixes * Fixed test fail * Embellished the emergency call lock out window * Holopads play borg sounds when speaking * Borg and AI names are listed as the caller ID on the holopad * Borg chassis can now be seen on holopad holograms * Holopad returns to a machine frame when badly damaged * Clarified some text * Fix merge conflict * Fixed merge conflict * Fixing merge conflict * Fixing merge conflict * Fixing merge conflict * Offset menu on open * AI can alt click on holopads to activate the projector * Bug fixes for intellicard interactions * Fixed speech issue with intellicards * The UI automatically opens for the AI when it alt-clicks on the holopad * Simplified shader math * Telephones will auto hang up 60 seconds after the last person on a call stops speaking * Added better support for AI requests when multiple AI cores are on the station * The call controls pop up for the AI when they accept a summons from a holopad * Compatibility mode fix for the hologram shader * Further shader fixes for compatibility mode * File clean up * More cleaning up * Removed access requirements from quantum holopads so they can used by nukies * The title of the holopad window now reflects the name of the device * Linked telephones will lose their connection if both move out of range of each other
173 lines
6.3 KiB
C#
173 lines
6.3 KiB
C#
using Content.Shared.Chat.TypingIndicator;
|
|
using Content.Shared.Holopad;
|
|
using Robust.Client.GameObjects;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.Player;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Timing;
|
|
using System.Linq;
|
|
|
|
namespace Content.Client.Holopad;
|
|
|
|
public sealed class HolopadSystem : SharedHolopadSystem
|
|
{
|
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<HolopadHologramComponent, ComponentInit>(OnComponentInit);
|
|
SubscribeLocalEvent<HolopadHologramComponent, BeforePostShaderRenderEvent>(OnShaderRender);
|
|
SubscribeAllEvent<TypingChangedEvent>(OnTypingChanged);
|
|
|
|
SubscribeNetworkEvent<PlayerSpriteStateRequest>(OnPlayerSpriteStateRequest);
|
|
SubscribeNetworkEvent<PlayerSpriteStateMessage>(OnPlayerSpriteStateMessage);
|
|
}
|
|
|
|
private void OnComponentInit(EntityUid uid, HolopadHologramComponent component, ComponentInit ev)
|
|
{
|
|
if (!TryComp<SpriteComponent>(uid, out var sprite))
|
|
return;
|
|
|
|
UpdateHologramSprite(uid);
|
|
}
|
|
|
|
private void OnShaderRender(EntityUid uid, HolopadHologramComponent component, BeforePostShaderRenderEvent ev)
|
|
{
|
|
if (ev.Sprite.PostShader == null)
|
|
return;
|
|
|
|
ev.Sprite.PostShader.SetParameter("t", (float)_timing.CurTime.TotalSeconds * component.ScrollRate);
|
|
}
|
|
|
|
private void OnTypingChanged(TypingChangedEvent ev, EntitySessionEventArgs args)
|
|
{
|
|
var uid = args.SenderSession.AttachedEntity;
|
|
|
|
if (!Exists(uid))
|
|
return;
|
|
|
|
if (!HasComp<HolopadUserComponent>(uid))
|
|
return;
|
|
|
|
var netEv = new HolopadUserTypingChangedEvent(GetNetEntity(uid.Value), ev.IsTyping);
|
|
RaiseNetworkEvent(netEv);
|
|
}
|
|
|
|
private void OnPlayerSpriteStateRequest(PlayerSpriteStateRequest ev)
|
|
{
|
|
var targetPlayer = GetEntity(ev.TargetPlayer);
|
|
var player = _playerManager.LocalSession?.AttachedEntity;
|
|
|
|
// Ignore the request if received by a player who isn't the target
|
|
if (targetPlayer != player)
|
|
return;
|
|
|
|
if (!TryComp<SpriteComponent>(player, out var playerSprite))
|
|
return;
|
|
|
|
var spriteLayerData = new List<PrototypeLayerData>();
|
|
|
|
if (playerSprite.Visible)
|
|
{
|
|
// Record the RSI paths, state names and shader paramaters of all visible layers
|
|
for (int i = 0; i < playerSprite.AllLayers.Count(); i++)
|
|
{
|
|
if (!playerSprite.TryGetLayer(i, out var layer))
|
|
continue;
|
|
|
|
if (!layer.Visible ||
|
|
string.IsNullOrEmpty(layer.ActualRsi?.Path.ToString()) ||
|
|
string.IsNullOrEmpty(layer.State.Name))
|
|
continue;
|
|
|
|
var layerDatum = new PrototypeLayerData();
|
|
layerDatum.RsiPath = layer.ActualRsi.Path.ToString();
|
|
layerDatum.State = layer.State.Name;
|
|
|
|
if (layer.CopyToShaderParameters != null)
|
|
{
|
|
var key = (string)layer.CopyToShaderParameters.LayerKey;
|
|
|
|
if (playerSprite.LayerMapTryGet(key, out var otherLayerIdx) &&
|
|
playerSprite.TryGetLayer(otherLayerIdx, out var otherLayer) &&
|
|
otherLayer.Visible)
|
|
{
|
|
layerDatum.MapKeys = new() { key };
|
|
|
|
layerDatum.CopyToShaderParameters = new PrototypeCopyToShaderParameters()
|
|
{
|
|
LayerKey = key,
|
|
ParameterTexture = layer.CopyToShaderParameters.ParameterTexture,
|
|
ParameterUV = layer.CopyToShaderParameters.ParameterUV
|
|
};
|
|
}
|
|
}
|
|
|
|
spriteLayerData.Add(layerDatum);
|
|
}
|
|
}
|
|
|
|
// Return the recorded data to the server
|
|
var evResponse = new PlayerSpriteStateMessage(ev.TargetPlayer, spriteLayerData.ToArray());
|
|
RaiseNetworkEvent(evResponse);
|
|
}
|
|
|
|
private void OnPlayerSpriteStateMessage(PlayerSpriteStateMessage ev)
|
|
{
|
|
UpdateHologramSprite(GetEntity(ev.SpriteEntity), ev.SpriteLayerData);
|
|
}
|
|
|
|
private void UpdateHologramSprite(EntityUid uid, PrototypeLayerData[]? layerData = null)
|
|
{
|
|
if (!TryComp<SpriteComponent>(uid, out var hologramSprite))
|
|
return;
|
|
|
|
if (!TryComp<HolopadHologramComponent>(uid, out var holopadhologram))
|
|
return;
|
|
|
|
for (int i = hologramSprite.AllLayers.Count() - 1; i >= 0; i--)
|
|
hologramSprite.RemoveLayer(i);
|
|
|
|
if (layerData == null || layerData.Length == 0)
|
|
{
|
|
layerData = new PrototypeLayerData[1];
|
|
layerData[0] = new PrototypeLayerData()
|
|
{
|
|
RsiPath = holopadhologram.RsiPath,
|
|
State = holopadhologram.RsiState
|
|
};
|
|
}
|
|
|
|
for (int i = 0; i < layerData.Length; i++)
|
|
{
|
|
var layer = layerData[i];
|
|
layer.Shader = "unshaded";
|
|
|
|
hologramSprite.AddLayer(layerData[i], i);
|
|
}
|
|
|
|
UpdateHologramShader(uid, hologramSprite, holopadhologram);
|
|
}
|
|
|
|
private void UpdateHologramShader(EntityUid uid, SpriteComponent sprite, HolopadHologramComponent holopadHologram)
|
|
{
|
|
// Find the texture height of the largest layer
|
|
float texHeight = sprite.AllLayers.Max(x => x.PixelSize.Y);
|
|
|
|
var instance = _prototypeManager.Index<ShaderPrototype>(holopadHologram.ShaderName).InstanceUnique();
|
|
instance.SetParameter("color1", new Vector3(holopadHologram.Color1.R, holopadHologram.Color1.G, holopadHologram.Color1.B));
|
|
instance.SetParameter("color2", new Vector3(holopadHologram.Color2.R, holopadHologram.Color2.G, holopadHologram.Color2.B));
|
|
instance.SetParameter("alpha", holopadHologram.Alpha);
|
|
instance.SetParameter("intensity", holopadHologram.Intensity);
|
|
instance.SetParameter("texHeight", texHeight);
|
|
instance.SetParameter("t", (float)_timing.CurTime.TotalSeconds * holopadHologram.ScrollRate);
|
|
|
|
sprite.PostShader = instance;
|
|
sprite.RaiseShaderEvent = true;
|
|
}
|
|
}
|