Skip to content

Commit

Permalink
SAIv3
Browse files Browse the repository at this point in the history
  • Loading branch information
Rxup committed Feb 18, 2024
1 parent 6cdc0e4 commit 821e465
Show file tree
Hide file tree
Showing 11 changed files with 484 additions and 141 deletions.
84 changes: 84 additions & 0 deletions Content.Client/Backmen/StationAI/AiVisualizerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.Linq;
using Content.Client.Power;
using Content.Shared.Backmen.StationAI;
using Content.Shared.Backmen.StationAI.UI;
using Content.Shared.Power;
using Robust.Client.GameObjects;

namespace Content.Client.Backmen.StationAI;

public sealed class AiVisualizerSystem : VisualizerSystem<StationAIComponent>
{
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<StationAIComponent, AfterAutoHandleStateEvent>(OnUpdate);
}

protected override void OnAppearanceChange(EntityUid uid, StationAIComponent component, ref AppearanceChangeEvent args)
{
if (HasComp<AIEyeComponent>(uid))
{
base.OnAppearanceChange(uid, component, ref args);
return;
}

UpdateAppearance(uid, component, args.Component, args.Sprite);
}

private void OnUpdate(Entity<StationAIComponent> ent, ref AfterAutoHandleStateEvent args)
{
if (HasComp<AIEyeComponent>(ent))
{
return;
}
if (!TryComp<SpriteComponent>(ent, out var spriteComponent))
{
return;
}

if (!ent.Comp.Layers.ContainsKey(ent.Comp.SelectedLayer))
return;

var layers = ent.Comp.Layers[ent.Comp.SelectedLayer];

foreach (var layer in spriteComponent.AllLayers.ToArray())
{
spriteComponent.RemoveLayer(layer);
}

foreach (var layer in layers)
{
spriteComponent.AddLayer(layer);
}

UpdateAppearance(ent, ent, sprite: spriteComponent);
}

private void UpdateAppearance(EntityUid id, StationAIComponent sign, AppearanceComponent? appearance = null,
SpriteComponent? sprite = null)
{
if (!Resolve(id, ref appearance, ref sprite))
return;

AppearanceSystem.TryGetData<bool>(id, PowerDeviceVisuals.Powered, out var powered, appearance);
AppearanceSystem.TryGetData<bool>(id, AiVisuals.Dead, out var dead, appearance);
AppearanceSystem.TryGetData<bool>(id, AiVisuals.InEye, out var inEye, appearance);

if (sprite.LayerMapTryGet(AiVisualLayers.NotInEye, out var eyeLayer))
{
sprite.LayerSetVisible(eyeLayer, powered && !inEye && !dead);
}

if (sprite.LayerMapTryGet(AiVisualLayers.Dead, out var deadLayer))
{
sprite.LayerSetVisible(deadLayer, powered && dead);
}

if (sprite.LayerMapTryGet(PowerDeviceVisualLayers.Powered, out var poweredLayer))
{
sprite.LayerSetVisible(poweredLayer, powered && !dead);
}
}
}
9 changes: 9 additions & 0 deletions Content.Server/Backmen/StationAI/InnateItemSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Content.Shared.Backmen.StationAI.Events;
using Content.Shared.Interaction;
using Content.Shared.Mind.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Tag;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
Expand All @@ -14,6 +15,7 @@ public sealed partial class InnateItemSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly TagSystem _tagSystem = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;

public override void Initialize()
{
Expand Down Expand Up @@ -84,6 +86,13 @@ private void StartBeforeInteract(EntityUid uid, InnateItemComponent component, I
{
return;
}
if (_mobState.IsDead(aiEyeComponent.AiCore.Value))
return;
}
else
{
if (_mobState.IsDead(uid))
return;
}

EnsureItem(uid, component, args.Item);
Expand Down
11 changes: 11 additions & 0 deletions Content.Server/Backmen/StationAI/Systems/AICameraSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,16 @@ public override void Initialize()

SubscribeLocalEvent<AIEyeComponent, MoveEvent>(OnEyeMove);
SubscribeLocalEvent<AICameraComponent, SurveillanceCameraDeactivateEvent>(OnActiveCameraDisable);
SubscribeLocalEvent<AICameraComponent, EntityTerminatingEvent>(OnRemove);
SubscribeLocalEvent<AIEyeComponent, EyeMoveToCam>(OnMoveToCam);
SubscribeLocalEvent<AIEyeComponent, AIEyeCampShootActionEvent>(OnShootCam);
}

private void OnRemove(Entity<AICameraComponent> ent, ref EntityTerminatingEvent args)
{
OnCameraOffline(ent);
}

[ValidatePrototypeId<EntityPrototype>]
private const string BulletDisabler = "BulletDisabler";

Expand Down Expand Up @@ -88,6 +94,11 @@ private void OnMoveToCam(Entity<AIEyeComponent> ent, ref EyeMoveToCam args)
}

private void OnActiveCameraDisable(Entity<AICameraComponent> ent, ref SurveillanceCameraDeactivateEvent args)
{
OnCameraOffline(ent);
}

private void OnCameraOffline(Entity<AICameraComponent> ent)
{
foreach (var viewer in ent.Comp.ActiveViewers)
{
Expand Down
48 changes: 21 additions & 27 deletions Content.Server/Backmen/StationAI/Systems/AIEyeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ public sealed class AIEyePowerSystem : EntitySystem
[Dependency] private readonly MindSystem _mindSystem = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly TransformSystem _transformSystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;

[Dependency] private readonly MobStateSystem _mobState = default!;

[Dependency] private readonly VisibilitySystem _visibilitySystem = default!;
[Dependency] private readonly MetaDataSystem _metaDataSystem = default!;
Expand All @@ -40,6 +37,8 @@ public sealed class AIEyePowerSystem : EntitySystem
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;

[Dependency] private readonly AICameraSystem _cameraSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;

public override void Initialize()
{
Expand All @@ -56,7 +55,6 @@ public override void Initialize()
SubscribeLocalEvent<AIEyeComponent, MindRemovedMessage>(OnMindRemoved);
SubscribeLocalEvent<AIEyeComponent, MindUnvisitedMessage>(OnMindRemoved2);

SubscribeLocalEvent<StationAIComponent, MobStateChangedEvent>(OnMobStateChanged);
SubscribeLocalEvent<StationAIComponent, GetSiliconLawsEvent>(OnGetLaws);

SubscribeLocalEvent<StationAIComponent, PowerChangedEvent>(OnPowerChange);
Expand Down Expand Up @@ -136,7 +134,7 @@ private void OnGetLaws(Entity<StationAIComponent> ent, ref GetSiliconLawsEvent a

private void OnInit(EntityUid uid, AIEyePowerComponent component, ComponentInit args)
{
if (!_entityManager.HasComponent<StationAIComponent>(uid))
if (!HasComp<StationAIComponent>(uid))
return;

_actions.AddAction(uid, ref component.EyePowerAction, component.PrototypeAction);
Expand All @@ -160,13 +158,15 @@ private void OnPowerReturnUsed(EntityUid uid, AIEyeComponent component, AIEyePow
)
return;

_mindSystem.UnVisit(mindId.MindId.Value, mind);
QueueDel(args.Performer);
ClearState(args.Performer);
args.Handled = true;
}

private void OnPowerUsed(EntityUid uid, AIEyePowerComponent component, AIEyePowerActionEvent args)
{
if (_mobState.IsDead(args.Performer))
return;

if (!_mindSystem.TryGetMind(args.Performer, out var mindId, out var mind))
return;

Expand All @@ -177,14 +177,18 @@ private void OnPowerUsed(EntityUid uid, AIEyePowerComponent component, AIEyePowe
var projection = EntityManager.CreateEntityUninitialized(component.Prototype, coords);
ai.ActiveEye = projection;
EnsureComp<AIEyeComponent>(projection).AiCore = (uid, ai);
EnsureComp<StationAIComponent>(projection).SelectedLaw = ai.SelectedLaw;
var eyeStation = EnsureComp<StationAIComponent>(projection);
eyeStation.SelectedLaw = ai.SelectedLaw;
eyeStation.SelectedLayer = ai.SelectedLayer;
EnsureComp<SiliconLawBoundComponent>(projection);
var core = MetaData(uid);
// Consistent name
_metaDataSystem.SetEntityName(projection, core.EntityName != "" ? core.EntityName : "Invalid AI");
EntityManager.InitializeAndStartEntity(projection, coords.GetMapId(EntityManager));

_transformSystem.AttachToGridOrMap(projection);

_appearance.SetData(uid, AiVisuals.InEye, true);
_mindSystem.Visit(mindId, projection, mind); // Mind swap

args.Handled = true;
Expand Down Expand Up @@ -221,15 +225,15 @@ private void OnMindRemoved(EntityUid uid, AIEyeComponent component, MindRemovedM
{
_uiSystem.TryCloseAll(uid, AICameraListUiKey.Key);
QueueDel(uid);
if (component.AiCore?.Comp != null)
component.AiCore.Value.Comp.ActiveEye = EntityUid.Invalid;
if(component.AiCore.HasValue)
OnReturnToCore(component.AiCore.Value);
}
private void OnMindRemoved2(EntityUid uid, AIEyeComponent component, MindUnvisitedMessage args)
{
_uiSystem.TryCloseAll(uid, AICameraListUiKey.Key);
QueueDel(uid);
if (component.AiCore?.Comp != null)
component.AiCore.Value.Comp.ActiveEye = EntityUid.Invalid;
if(component.AiCore.HasValue)
OnReturnToCore(component.AiCore.Value);
}

private void ClearState(EntityUid uid, AIEyeComponent? component = null)
Expand All @@ -248,23 +252,13 @@ private void ClearState(EntityUid uid, AIEyeComponent? component = null)
_mindSystem.UnVisit(mindId, mind);
}

component.AiCore.Value.Comp.ActiveEye = EntityUid.Invalid;
_uiSystem.TryCloseAll(uid, AICameraListUiKey.Key);
OnReturnToCore(component.AiCore.Value);
}

private static readonly SoundSpecifier AIDeath =
new SoundPathSpecifier("/Audio/Backmen/Machines/AI/borg_death.ogg");

private void OnMobStateChanged(EntityUid uid, StationAIComponent component, MobStateChangedEvent args)
private void OnReturnToCore(Entity<StationAIComponent> ent)
{
if (!_mobState.IsDead(uid))
return;

if (component.ActiveEye.IsValid() && _mindSystem.TryGetMind(uid, out var mindId, out var mind))
{
ClearState(component.ActiveEye);
}

_audioSystem.PlayPvs(AIDeath, uid);
ent.Comp.ActiveEye = EntityUid.Invalid;
_uiSystem.TryCloseAll(ent, AICameraListUiKey.Key);
_appearance.SetData(ent, AiVisuals.InEye, false);
}
}
27 changes: 23 additions & 4 deletions Content.Server/Backmen/StationAI/Systems/AiEnemySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
using Content.Shared.Backmen.StationAI.Components;
using Content.Shared.Backmen.StationAI.Systems;
using Content.Shared.Examine;
using Content.Shared.Mobs.Systems;
using Content.Shared.Verbs;

namespace Content.Server.Backmen.StationAI.Systems;

public sealed class AiEnemySystem : SharedAiEnemySystem
{
[Dependency] private readonly NpcFactionSystem _faction = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;

public override void Initialize()
{
Expand All @@ -27,6 +29,9 @@ private void OnMarkAsTarget(Entity<NpcFactionMemberComponent> ent, ref GetVerbsE
if (!HasComp<StationAIComponent>(args.User) && !HasComp<BorgAINTComponent>(args.User))
return;

if (_mobState.IsDead(args.User))
return;

var u = args.User;
AlternativeVerb verb = new()
{
Expand All @@ -43,15 +48,29 @@ private void OnMarkAsTarget(Entity<NpcFactionMemberComponent> ent, ref GetVerbsE

private void ToggleEnemy(EntityUid argsUser, Entity<NpcFactionMemberComponent> ent)
{
var source = argsUser;
if (TryComp<AIEyeComponent>(argsUser, out var aiEyeComponent))
var core = argsUser;
if (TryComp<AIEyeComponent>(core, out var eyeComponent))
{
if(eyeComponent.AiCore == null)
return;
core = eyeComponent.AiCore.Value.Owner;
}

if (!core.Valid)
{
source = aiEyeComponent.AiCore?.Owner ?? EntityUid.Invalid;
return;
}

var xform = Transform(core);
if (xform.GridUid != Transform(ent).GridUid || !xform.Anchored)
{
return;
}

if (HasComp<AIEnemyNTComponent>(ent))
RemCompDeferred<AIEnemyNTComponent>(ent);
else
EnsureComp<AIEnemyNTComponent>(ent).Source = source;
EnsureComp<AIEnemyNTComponent>(ent).Source = core;
}

[ValidatePrototypeId<NpcFactionPrototype>]
Expand Down
Loading

0 comments on commit 821e465

Please sign in to comment.