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

Station AI Features and Fixes (Also General Fixes) #1525

Merged
merged 36 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4c58204
Add some more stuff to AI whitelist (#31564)
metalgearsloth Aug 28, 2024
cac7af6
Basically every electronic device can now be used by the AI. (#31730)
ScarKy0 Sep 5, 2024
4c7f223
Fixed the mail system
sleepyyapril Jan 13, 2025
ad2918a
As a stop-gap, CPR will not loop at all.
sleepyyapril Jan 13, 2025
47d6695
Predict IntrinsicUI (#31310)
metalgearsloth Aug 22, 2024
59d76ec
Adding intellicard functionality. (#32347)
ScarKy0 Oct 22, 2024
a094f12
Renamed circuit boards to law boards (#31914)
ScarKy0 Sep 10, 2024
c0dee96
Added many old ion lawsets for borgs and AI. (#31664)
ScarKy0 Sep 3, 2024
7c9ae06
Swap to "law board"
sleepyyapril Jan 13, 2025
f1bc10f
FTL + AI fixes (#31952)
metalgearsloth Sep 8, 2024
d703f05
Give AI a Sound Cue when an Antimov board is inserted (#32625)
poklj Oct 17, 2024
82883da
Add AI warp points (#31559)
metalgearsloth Aug 28, 2024
402b1cf
prevent typing sound from playing when AI interacts with consoles (#3…
MendaxxDev Oct 21, 2024
669ae86
Predict EmitSoundOnUIOpen (#31464)
metalgearsloth Aug 26, 2024
689c12a
all the laws
sleepyyapril Jan 13, 2025
29716b6
You can now pet the AI core. (#33788)
ScarKy0 Dec 9, 2024
09eeefe
Fixed AI Actions (#31823)
ScarKy0 Sep 5, 2024
04db7b2
Resprite
sleepyyapril Jan 13, 2025
35d882c
Set name before announcement
sleepyyapril Jan 13, 2025
a31d41e
Gave AI a comms console (#31852)
ScarKy0 Sep 12, 2024
13e3abd
Holopads (#32711)
chromiumboy Dec 17, 2024
280e88f
Tweaks for the holopad (#33928)
chromiumboy Dec 19, 2024
1bee0f1
Port rename
sleepyyapril Jan 13, 2025
cca34a0
imports
sleepyyapril Jan 13, 2025
1ec188a
fix duplicate
sleepyyapril Jan 13, 2025
a36cffd
!
sleepyyapril Jan 13, 2025
cf39230
fix repeating standing/laying bug
sleepyyapril Jan 13, 2025
fa0b7f3
Merge branch 'master' of https://github.com/Simple-Station/Einstein-E…
sleepyyapril Jan 13, 2025
efbb566
fix
sleepyyapril Jan 13, 2025
ed1a0fa
jank fix
sleepyyapril Jan 13, 2025
f222b54
!
sleepyyapril Jan 13, 2025
fb613cb
Fix
sleepyyapril Jan 13, 2025
24bd4ab
Merge branch 'master' into more-fixes
sleepyyapril Jan 13, 2025
100f25c
less jank
sleepyyapril Jan 13, 2025
6a0f75d
Merge branch 'more-fixes' of https://github.com/sleepyyapril/Einstein…
sleepyyapril Jan 13, 2025
7f3973c
Fixed epilepsy worldwide
sleepyyapril Jan 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions Content.Client/Chat/UI/SpeechBubble.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using Content.Client.Chat.Managers;
using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Speech;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
Expand All @@ -17,6 +19,8 @@ public abstract class SpeechBubble : Control
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] protected readonly IConfigurationManager ConfigManager = default!;

private readonly SharedTransformSystem _transformSystem;

public enum SpeechType : byte
{
Emote,
Expand Down Expand Up @@ -83,6 +87,7 @@ public SpeechBubble(ChatMessage message, EntityUid senderEntity, string speechSt
{
IoCManager.InjectDependencies(this);
_senderEntity = senderEntity;
_transformSystem = _entityManager.System<SharedTransformSystem>();

// Use text clipping so new messages don't overlap old ones being pushed up.
RectClipContent = true;
Expand Down Expand Up @@ -139,8 +144,13 @@ protected override void FrameUpdate(FrameEventArgs args)
Modulate = Color.White;
}

var offset = (-_eyeManager.CurrentEye.Rotation).ToWorldVec() * -EntityVerticalOffset;
var worldPos = xform.WorldPosition + offset;
var baseOffset = 0f;

if (_entityManager.TryGetComponent<SpeechComponent>(_senderEntity, out var speech))
baseOffset = speech.SpeechBubbleOffset;

var offset = (-_eyeManager.CurrentEye.Rotation).ToWorldVec() * -(EntityVerticalOffset + baseOffset);
var worldPos = _transformSystem.GetWorldPosition(xform) + offset;

var lowerCenter = _eyeManager.WorldToScreen(worldPos) / UIScale;
var screenPos = lowerCenter - new Vector2(ContentSize.X / 2, ContentSize.Y + _verticalOffsetAchieved);
Expand Down
2 changes: 1 addition & 1 deletion Content.Client/DeltaV/Hologram/HologramSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override void Initialize()
{
base.Initialize();

_shader = _protoMan.Index<ShaderPrototype>("Hologram").InstanceUnique();
_shader = _protoMan.Index<ShaderPrototype>("HologramDeltaV").InstanceUnique();
SubscribeLocalEvent<HologramComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<HologramComponent, ComponentStartup>(OnStartup);
}
Expand Down
101 changes: 101 additions & 0 deletions Content.Client/Holopad/HolopadBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using Content.Shared.Holopad;
using Content.Shared.Silicons.StationAi;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Shared.Player;
using System.Numerics;

namespace Content.Client.Holopad;

public sealed class HolopadBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly ISharedPlayerManager _playerManager = default!;
[Dependency] private readonly IClyde _displayManager = default!;

[ViewVariables]
private HolopadWindow? _window;

public HolopadBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}

protected override void Open()
{
base.Open();

_window = this.CreateWindow<HolopadWindow>();
_window.Title = Loc.GetString("holopad-window-title", ("title", EntMan.GetComponent<MetaDataComponent>(Owner).EntityName));

if (this.UiKey is not HolopadUiKey)
{
Close();
return;
}

var uiKey = (HolopadUiKey)this.UiKey;

// AIs will see a different holopad interface to crew when interacting with them in the world
if (uiKey == HolopadUiKey.InteractionWindow && EntMan.HasComponent<StationAiHeldComponent>(_playerManager.LocalEntity))
uiKey = HolopadUiKey.InteractionWindowForAi;

_window.SetState(Owner, uiKey);
_window.UpdateState(new Dictionary<NetEntity, string>());

// Set message actions
_window.SendHolopadStartNewCallMessageAction += SendHolopadStartNewCallMessage;
_window.SendHolopadAnswerCallMessageAction += SendHolopadAnswerCallMessage;
_window.SendHolopadEndCallMessageAction += SendHolopadEndCallMessage;
_window.SendHolopadStartBroadcastMessageAction += SendHolopadStartBroadcastMessage;
_window.SendHolopadActivateProjectorMessageAction += SendHolopadActivateProjectorMessage;
_window.SendHolopadRequestStationAiMessageAction += SendHolopadRequestStationAiMessage;

// If this call is addressed to an AI, open the window in the bottom right hand corner of the screen
if (uiKey == HolopadUiKey.AiRequestWindow)
_window.OpenCenteredAt(new Vector2(1f, 1f));

// Otherwise offset to the left so the holopad can still be seen
else
_window.OpenCenteredAt(new Vector2(0.3333f, 0.50f));
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

var castState = (HolopadBoundInterfaceState)state;
EntMan.TryGetComponent<TransformComponent>(Owner, out var xform);

_window?.UpdateState(castState.Holopads);
}

public void SendHolopadStartNewCallMessage(NetEntity receiver)
{
SendMessage(new HolopadStartNewCallMessage(receiver));
}

public void SendHolopadAnswerCallMessage()
{
SendMessage(new HolopadAnswerCallMessage());
}

public void SendHolopadEndCallMessage()
{
SendMessage(new HolopadEndCallMessage());
}

public void SendHolopadStartBroadcastMessage()
{
SendMessage(new HolopadStartBroadcastMessage());
}

public void SendHolopadActivateProjectorMessage()
{
SendMessage(new HolopadActivateProjectorMessage());
}

public void SendHolopadRequestStationAiMessage()
{
SendMessage(new HolopadStationAiRequestMessage());
}
}
172 changes: 172 additions & 0 deletions Content.Client/Holopad/HolopadSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
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;
}
}
Loading
Loading