* 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
This commit is contained in:
chromiumboy
2024-12-17 13:18:15 -06:00
committed by GitHub
parent ab8447956c
commit 7780b867ac
43 changed files with 3129 additions and 8 deletions

View File

@@ -20,12 +20,15 @@ using Content.Shared.Verbs;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Network;
using Robust.Shared.Physics;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
using System.Diagnostics.CodeAnalysis;
namespace Content.Shared.Silicons.StationAi;
@@ -68,6 +71,8 @@ public abstract partial class SharedStationAiSystem : EntitySystem
[ValidatePrototypeId<EntityPrototype>]
private static readonly EntProtoId DefaultAi = "StationAiBrain";
private const float MaxVisionMultiplier = 5f;
public override void Initialize()
{
base.Initialize();
@@ -344,16 +349,47 @@ public abstract partial class SharedStationAiSystem : EntitySystem
AttachEye(ent);
}
private bool SetupEye(Entity<StationAiCoreComponent> ent)
public void SwitchRemoteEntityMode(Entity<StationAiCoreComponent> ent, bool isRemote)
{
if (isRemote == ent.Comp.Remote)
return;
ent.Comp.Remote = isRemote;
EntityCoordinates? coords = ent.Comp.RemoteEntity != null ? Transform(ent.Comp.RemoteEntity.Value).Coordinates : null;
// Attach new eye
ClearEye(ent);
if (SetupEye(ent, coords))
AttachEye(ent);
// Adjust user FoV
var user = GetInsertedAI(ent);
if (TryComp<EyeComponent>(user, out var eye))
_eye.SetDrawFov(user.Value, !isRemote);
}
private bool SetupEye(Entity<StationAiCoreComponent> ent, EntityCoordinates? coords = null)
{
if (_net.IsClient)
return false;
if (ent.Comp.RemoteEntity != null)
return false;
if (ent.Comp.RemoteEntityProto != null)
var proto = ent.Comp.RemoteEntityProto;
if (coords == null)
coords = Transform(ent.Owner).Coordinates;
if (!ent.Comp.Remote)
proto = ent.Comp.PhysicalEntityProto;
if (proto != null)
{
ent.Comp.RemoteEntity = SpawnAtPosition(ent.Comp.RemoteEntityProto, Transform(ent.Owner).Coordinates);
ent.Comp.RemoteEntity = SpawnAtPosition(proto, coords.Value);
Dirty(ent);
}
@@ -364,6 +400,7 @@ public abstract partial class SharedStationAiSystem : EntitySystem
{
if (_net.IsClient)
return;
QueueDel(ent.Comp.RemoteEntity);
ent.Comp.RemoteEntity = null;
Dirty(ent);
@@ -392,6 +429,17 @@ public abstract partial class SharedStationAiSystem : EntitySystem
_mover.SetRelay(user, ent.Comp.RemoteEntity.Value);
}
private EntityUid? GetInsertedAI(Entity<StationAiCoreComponent> ent)
{
if (!_containers.TryGetContainer(ent.Owner, StationAiHolderComponent.Container, out var container) ||
container.ContainedEntities.Count != 1)
{
return null;
}
return container.ContainedEntities[0];
}
private void OnAiInsert(Entity<StationAiCoreComponent> ent, ref EntInsertedIntoContainerMessage args)
{
if (args.Container.ID != StationAiCoreComponent.Container)
@@ -400,6 +448,7 @@ public abstract partial class SharedStationAiSystem : EntitySystem
if (_timing.ApplyingState)
return;
ent.Comp.Remote = true;
SetupEye(ent);
// Just so text and the likes works properly
@@ -413,6 +462,8 @@ public abstract partial class SharedStationAiSystem : EntitySystem
if (_timing.ApplyingState)
return;
ent.Comp.Remote = true;
// Reset name to whatever
_metadata.SetEntityName(ent.Owner, Prototype(ent.Owner)?.Name ?? string.Empty);
@@ -424,6 +475,7 @@ public abstract partial class SharedStationAiSystem : EntitySystem
_eye.SetDrawFov(args.Entity, true, eyeComp);
_eye.SetTarget(args.Entity, null, eyeComp);
}
ClearEye(ent);
}
@@ -478,6 +530,36 @@ public abstract partial class SharedStationAiSystem : EntitySystem
return _blocker.CanComplexInteract(entity.Owner);
}
public bool TryGetStationAiCore(Entity<StationAiHeldComponent?> ent, [NotNullWhen(true)] out Entity<StationAiCoreComponent>? parentEnt)
{
parentEnt = null;
var parent = Transform(ent).ParentUid;
if (!parent.IsValid())
return false;
if (!TryComp<StationAiCoreComponent>(parent, out var stationAiCore))
return false;
parentEnt = new Entity<StationAiCoreComponent>(parent, stationAiCore);
return true;
}
public bool TryGetInsertedAI(Entity<StationAiCoreComponent> ent, [NotNullWhen(true)] out Entity<StationAiHeldComponent>? insertedAi)
{
insertedAi = null;
var insertedEnt = GetInsertedAI(ent);
if (TryComp<StationAiHeldComponent>(insertedEnt, out var stationAiHeld))
{
insertedAi = (insertedEnt.Value, stationAiHeld);
return true;
}
return false;
}
}
public sealed partial class JumpToCoreEvent : InstantActionEvent

View File

@@ -15,6 +15,7 @@ public sealed partial class StationAiCoreComponent : Component
/// <summary>
/// Can it move its camera around and interact remotely with things.
/// When false, the AI is being projected into a local area, such as a holopad
/// </summary>
[DataField, AutoNetworkedField]
public bool Remote = true;
@@ -25,8 +26,17 @@ public sealed partial class StationAiCoreComponent : Component
[DataField, AutoNetworkedField]
public EntityUid? RemoteEntity;
/// <summary>
/// Prototype that represents the 'eye' of the AI
/// </summary>
[DataField(readOnly: true)]
public EntProtoId? RemoteEntityProto = "StationAiHolo";
/// <summary>
/// Prototype that represents the physical avatar of the AI
/// </summary>
[DataField(readOnly: true)]
public EntProtoId? PhysicalEntityProto = "StationAiHoloLocal";
public const string Container = "station_ai_mind_slot";
}