diff --git a/Content.Client/Backmen/StationAI/AiVisualizerSystem.cs b/Content.Client/Backmen/StationAI/AiVisualizerSystem.cs new file mode 100644 index 00000000000..29d470a2a1b --- /dev/null +++ b/Content.Client/Backmen/StationAI/AiVisualizerSystem.cs @@ -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 +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnUpdate); + } + + protected override void OnAppearanceChange(EntityUid uid, StationAIComponent component, ref AppearanceChangeEvent args) + { + if (HasComp(uid)) + { + base.OnAppearanceChange(uid, component, ref args); + return; + } + + UpdateAppearance(uid, component, args.Component, args.Sprite); + } + + private void OnUpdate(Entity ent, ref AfterAutoHandleStateEvent args) + { + if (HasComp(ent)) + { + return; + } + if (!TryComp(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(id, PowerDeviceVisuals.Powered, out var powered, appearance); + AppearanceSystem.TryGetData(id, AiVisuals.Dead, out var dead, appearance); + AppearanceSystem.TryGetData(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); + } + } +} diff --git a/Content.Server/Backmen/StationAI/InnateItemSystem.cs b/Content.Server/Backmen/StationAI/InnateItemSystem.cs index 437abb2b55a..0890c62fc8f 100644 --- a/Content.Server/Backmen/StationAI/InnateItemSystem.cs +++ b/Content.Server/Backmen/StationAI/InnateItemSystem.cs @@ -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; @@ -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() { @@ -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); diff --git a/Content.Server/Backmen/StationAI/Systems/AICameraSystem.cs b/Content.Server/Backmen/StationAI/Systems/AICameraSystem.cs index f56075bdfb7..2f4de15adfd 100644 --- a/Content.Server/Backmen/StationAI/Systems/AICameraSystem.cs +++ b/Content.Server/Backmen/StationAI/Systems/AICameraSystem.cs @@ -42,10 +42,16 @@ public override void Initialize() SubscribeLocalEvent(OnEyeMove); SubscribeLocalEvent(OnActiveCameraDisable); + SubscribeLocalEvent(OnRemove); SubscribeLocalEvent(OnMoveToCam); SubscribeLocalEvent(OnShootCam); } + private void OnRemove(Entity ent, ref EntityTerminatingEvent args) + { + OnCameraOffline(ent); + } + [ValidatePrototypeId] private const string BulletDisabler = "BulletDisabler"; @@ -88,6 +94,11 @@ private void OnMoveToCam(Entity ent, ref EyeMoveToCam args) } private void OnActiveCameraDisable(Entity ent, ref SurveillanceCameraDeactivateEvent args) + { + OnCameraOffline(ent); + } + + private void OnCameraOffline(Entity ent) { foreach (var viewer in ent.Comp.ActiveViewers) { diff --git a/Content.Server/Backmen/StationAI/Systems/AIEyeSystem.cs b/Content.Server/Backmen/StationAI/Systems/AIEyeSystem.cs index 5a80701b06f..ec2e35a0b8c 100644 --- a/Content.Server/Backmen/StationAI/Systems/AIEyeSystem.cs +++ b/Content.Server/Backmen/StationAI/Systems/AIEyeSystem.cs @@ -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!; @@ -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() { @@ -56,7 +55,6 @@ public override void Initialize() SubscribeLocalEvent(OnMindRemoved); SubscribeLocalEvent(OnMindRemoved2); - SubscribeLocalEvent(OnMobStateChanged); SubscribeLocalEvent(OnGetLaws); SubscribeLocalEvent(OnPowerChange); @@ -136,7 +134,7 @@ private void OnGetLaws(Entity ent, ref GetSiliconLawsEvent a private void OnInit(EntityUid uid, AIEyePowerComponent component, ComponentInit args) { - if (!_entityManager.HasComponent(uid)) + if (!HasComp(uid)) return; _actions.AddAction(uid, ref component.EyePowerAction, component.PrototypeAction); @@ -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; @@ -177,7 +177,9 @@ private void OnPowerUsed(EntityUid uid, AIEyePowerComponent component, AIEyePowe var projection = EntityManager.CreateEntityUninitialized(component.Prototype, coords); ai.ActiveEye = projection; EnsureComp(projection).AiCore = (uid, ai); - EnsureComp(projection).SelectedLaw = ai.SelectedLaw; + var eyeStation = EnsureComp(projection); + eyeStation.SelectedLaw = ai.SelectedLaw; + eyeStation.SelectedLayer = ai.SelectedLayer; EnsureComp(projection); var core = MetaData(uid); // Consistent name @@ -185,6 +187,8 @@ private void OnPowerUsed(EntityUid uid, AIEyePowerComponent component, AIEyePowe 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; @@ -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) @@ -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 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); } } diff --git a/Content.Server/Backmen/StationAI/Systems/AiEnemySystem.cs b/Content.Server/Backmen/StationAI/Systems/AiEnemySystem.cs index c7313017cca..0b4adaae698 100644 --- a/Content.Server/Backmen/StationAI/Systems/AiEnemySystem.cs +++ b/Content.Server/Backmen/StationAI/Systems/AiEnemySystem.cs @@ -4,6 +4,7 @@ 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; @@ -11,6 +12,7 @@ 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() { @@ -27,6 +29,9 @@ private void OnMarkAsTarget(Entity ent, ref GetVerbsE if (!HasComp(args.User) && !HasComp(args.User)) return; + if (_mobState.IsDead(args.User)) + return; + var u = args.User; AlternativeVerb verb = new() { @@ -43,15 +48,29 @@ private void OnMarkAsTarget(Entity ent, ref GetVerbsE private void ToggleEnemy(EntityUid argsUser, Entity ent) { - var source = argsUser; - if (TryComp(argsUser, out var aiEyeComponent)) + var core = argsUser; + if (TryComp(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(ent)) RemCompDeferred(ent); else - EnsureComp(ent).Source = source; + EnsureComp(ent).Source = core; } [ValidatePrototypeId] diff --git a/Content.Server/Backmen/StationAI/Systems/StationAISystem.cs b/Content.Server/Backmen/StationAI/Systems/StationAISystem.cs index 028a14a1b6e..af2faa75460 100644 --- a/Content.Server/Backmen/StationAI/Systems/StationAISystem.cs +++ b/Content.Server/Backmen/StationAI/Systems/StationAISystem.cs @@ -9,14 +9,20 @@ using Content.Shared.Backmen.StationAI; using Content.Shared.Backmen.StationAI.Events; using Content.Shared.Backmen.StationAI.UI; +using Content.Shared.Destructible; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction.Events; using Content.Shared.Item; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Systems; using Content.Shared.Nuke; using Content.Shared.Roles; using Content.Shared.Roles.Jobs; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; using Robust.Shared.Player; +using Robust.Shared.Random; namespace Content.Server.Backmen.StationAI.Systems; @@ -30,6 +36,11 @@ public sealed class StationAISystem : EntitySystem [Dependency] private readonly NukeSystem _nuke = default!; [Dependency] private readonly RoleSystem _role = default!; [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly IRobustRandom _robust = default!; + public override void Initialize() { @@ -41,9 +52,12 @@ public override void Initialize() SubscribeLocalEvent(CanInteraction); - SubscribeLocalEvent(OnHealthOverlayEvent); + SubscribeLocalEvent(OnHealthOverlayEvent); SubscribeLocalEvent(OnToggleNuke); SubscribeLocalEvent(OnRoleUpdateIfNeed); + + //SubscribeLocalEvent(OnDestruction); + SubscribeLocalEvent(OnMobStateChanged); } [ValidatePrototypeId] @@ -75,6 +89,9 @@ private void OnRoleUpdateIfNeed(Entity ent, ref PlayerAttach private void OnToggleNuke(Entity ent, ref ToggleArmNukeEvent args) { + if (_mobState.IsDead(ent)) + return; + if (!TryComp(ent, out var nuke)) { return; @@ -121,6 +138,8 @@ private void CanInteraction(Entity ent, ref InteractionAttem args.Cancel(); return; } + if (_mobState.IsDead(core)) + return; if (args.Target != null && Transform(core).GridUid != Transform(args.Target.Value).GridUid) { @@ -173,11 +192,19 @@ private void OnStartup(EntityUid uid, StationAIComponent component, MapInitEvent _actions.AddAction(uid, ref component.ActionId, component.Action); _hands.AddHand(uid,"SAI",HandLocation.Middle); - if (!HasComp(uid) && TryComp(uid, out var nuke)) + if (!HasComp(uid)) { - (nuke as dynamic).Status = NukeStatus.COOLDOWN; - (nuke as dynamic).CooldownTime = 1; - _actions.AddAction(uid, ref component.NukeToggleId, component.NukeToggle); + component.SelectedLayer = _robust.Pick(component.Layers.Keys); + Dirty(uid,component); + + _appearance.SetData(uid, AiVisuals.Dead, false); + _appearance.SetData(uid, AiVisuals.InEye, false); + if (TryComp(uid, out var nuke)) + { + (nuke as dynamic).Status = NukeStatus.COOLDOWN; + (nuke as dynamic).CooldownTime = 1; + _actions.AddAction(uid, ref component.NukeToggleId, component.NukeToggle); + } } } @@ -187,8 +214,19 @@ private void OnShutdown(EntityUid uid, StationAIComponent component, ComponentSh _actions.RemoveAction(uid, component.NukeToggleId); } - private void OnHealthOverlayEvent(AIHealthOverlayEvent args) + private void OnHealthOverlayEvent(Entity ent, ref AIHealthOverlayEvent args) { + var core = ent.Owner; + if (TryComp(ent, out var eye)) + { + core = eye.AiCore?.Owner ?? EntityUid.Invalid; + } + + if (!core.Valid) + return; + if (_mobState.IsDead(core)) + return; + if (HasComp(args.Performer)) { RemCompDeferred(args.Performer); @@ -203,4 +241,41 @@ private void OnHealthOverlayEvent(AIHealthOverlayEvent args) } args.Handled = true; } + + private static readonly SoundSpecifier AiDeath = + new SoundPathSpecifier("/Audio/Machines/AI/borg_death.ogg"); + private void OnMobStateChanged(EntityUid uid, StationAIComponent component, MobStateChangedEvent args) + { + if (HasComp(uid)) + return; + + if (args.OldMobState != MobState.Dead && args.NewMobState == MobState.Dead) + { + SetAsDead((uid,component),true); + } + else if (args.OldMobState != MobState.Alive && args.NewMobState == MobState.Alive) + { + SetAsDead((uid,component),false); + } + + } + + private void SetAsDead(Entity ent,bool state) + { + if (state) + { + if (ent.Comp.ActiveEye.IsValid()) + { + QueueDel(ent.Comp.ActiveEye); + } + + _audioSystem.PlayPvs(AiDeath, ent); + _appearance.SetData(ent, AiVisuals.Dead, true); + } + else + { + _appearance.SetData(ent, AiVisuals.Dead, false); + _mobState.ChangeMobState(ent, MobState.Alive); + } + } } diff --git a/Content.Shared/Backmen/StationAI/Components/StationAIComponent.cs b/Content.Shared/Backmen/StationAI/Components/StationAIComponent.cs index 9f7065e77ba..818fb13e2f7 100644 --- a/Content.Shared/Backmen/StationAI/Components/StationAIComponent.cs +++ b/Content.Shared/Backmen/StationAI/Components/StationAIComponent.cs @@ -1,10 +1,11 @@ using Robust.Shared.Prototypes; using Content.Shared.Random; using Content.Shared.Silicons.Laws; +using Robust.Shared.GameStates; namespace Content.Shared.Backmen.StationAI; -[RegisterComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class StationAIComponent : Component { [DataField("action")] @@ -25,4 +26,13 @@ public sealed partial class StationAIComponent : Component public EntProtoId NukeToggle = "AIToggleArmNuke"; public EntityUid? NukeToggleId; + + [DataField("layers", required: true)] + [ViewVariables] + public Dictionary Layers = new(); + + [DataField("defaultLayer", required: true)] + [AutoNetworkedField] + [ViewVariables(VVAccess.ReadWrite)] + public string SelectedLayer = "blue"; } diff --git a/Content.Shared/Backmen/StationAI/UI/Key.cs b/Content.Shared/Backmen/StationAI/UI/Key.cs index cfa9ad2f0aa..1a24f796863 100644 --- a/Content.Shared/Backmen/StationAI/UI/Key.cs +++ b/Content.Shared/Backmen/StationAI/UI/Key.cs @@ -7,3 +7,17 @@ public enum AICameraListUiKey : byte { Key, } + +[Serializable, NetSerializable] +public enum AiVisuals : byte +{ + InEye, + Dead +} + +[Serializable, NetSerializable] +public enum AiVisualLayers : byte +{ + Dead, + NotInEye +} diff --git a/Resources/Prototypes/Backmen/Entities/Mobs/Player/stationai.yml b/Resources/Prototypes/Backmen/Entities/Mobs/Player/stationai.yml index 9b1f2903810..7c63290de60 100644 --- a/Resources/Prototypes/Backmen/Entities/Mobs/Player/stationai.yml +++ b/Resources/Prototypes/Backmen/Entities/Mobs/Player/stationai.yml @@ -6,8 +6,233 @@ - type: Tag tags: - CannotSuicide + - type: TTS + voice: TrainingRobot - type: StationAI lawsId: LawsStationAIDefault + defaultLayer: blue + layers: + blue: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead"] + state: blue_dead + shader: unshaded + - map: ["enum.PowerDeviceVisualLayers.Powered"] + state: blue + shader: unshaded + - map: ["enum.AiVisualLayers.NotInEye"] + state: not_in_eye + thinking: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: thinking_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: thinking + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + alien: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: thinking_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: thinking + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + angel: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: angel_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: angel + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + banned: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: banned_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: banned + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + bliss: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: bliss_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: bliss + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + clown: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: clown_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: clown + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + database: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: database_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: database + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + gentoo: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: gentoo_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: gentoo + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + glitchman: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: glitchman_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: glitchman + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + goon: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: goon_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: goon + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + hades: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: hades_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: hades + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + heartline: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: heartline_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: heartline + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + house: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: house_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: house + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + inverted: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: inverted_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: inverted + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + monochrome: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: monochrome_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: monochrome + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + murica: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: murica_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: murica + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + rainbow: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: murica_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: rainbow + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + red: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: red_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: red + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + red_october: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: red_october_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: red_october + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + static: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: static_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: static + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + weird: + - state: 4 + - map: [ "enum.AiVisualLayers.Dead" ] + state: weird_dead + shader: unshaded + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: weird + shader: unshaded + - map: [ "enum.AiVisualLayers.NotInEye" ] + state: not_in_eye + - type: Visibility - type: UserInterface interfaces: @@ -156,6 +381,7 @@ description: Host for an AI. Likely more A than I. components: - type: BorgAINT + - type: Repairable - type: Electrified shockDamage: 30 shockTime: 5 @@ -167,12 +393,6 @@ params: variation: 0.65 volume: -10 - - type: GenericVisualizer - visuals: - enum.PowerDeviceVisuals.Powered: - enum.PowerDeviceVisualLayers.Powered: - True: { visible: true } - False: { visible: false } - type: ExtensionCableReceiver - type: LitOnPowered - type: ApcPowerReceiver @@ -224,26 +444,14 @@ charge: 12000 maxCharge: 120000 pricePerJoule: 0 - # - type: GenericVisualizer - # visuals: - # enum.PowerDeviceVisuals.VisualState: - # enum.PowerDeviceVisualLayers.Powered: - # Idle: { state: "ai-blue" } - # enum.PowerDeviceVisuals.Powered: - # enum.PowerDeviceVisualLayers.Powered: - # True: { visible: true } - # False: { visible: false } - type: Sprite sprite: Backmen/Mobs/Silicon/ai.rsi drawdepth: Mobs noRot: true layers: - state: 4 - - map: ["enum.PowerDeviceVisualLayers.Powered"] - state: blue - shader: unshaded - type: Damageable - damageContainer: Inorganic + damageContainer: Silicon - type: Bloodstream bloodReagent: Oil bloodlossDamage: @@ -265,90 +473,6 @@ - type: NpcFactionMember factions: - NanoTrasen - - type: RandomSprite - available: - - enum.PowerDeviceVisualLayers.Powered: - thinking: "" - - enum.PowerDeviceVisualLayers.Powered: - alien: "" - - enum.PowerDeviceVisualLayers.Powered: - angel: "" - - enum.PowerDeviceVisualLayers.Powered: - banned: "" - - enum.PowerDeviceVisualLayers.Powered: - bliss: "" - - enum.PowerDeviceVisualLayers.Powered: - blue: "" - - enum.PowerDeviceVisualLayers.Powered: - clown: "" - - enum.PowerDeviceVisualLayers.Powered: - database: "" - - enum.PowerDeviceVisualLayers.Powered: - dorf: "" - - enum.PowerDeviceVisualLayers.Powered: - firewall: "" - - enum.PowerDeviceVisualLayers.Powered: - fuzzy: "" - - enum.PowerDeviceVisualLayers.Powered: - gentoo: "" - - enum.PowerDeviceVisualLayers.Powered: - glitchman: "" - - enum.PowerDeviceVisualLayers.Powered: - goon: "" - - enum.PowerDeviceVisualLayers.Powered: - hades: "" - - enum.PowerDeviceVisualLayers.Powered: - heartline: "" - - enum.PowerDeviceVisualLayers.Powered: - helios: "" - - enum.PowerDeviceVisualLayers.Powered: - house: "" - - enum.PowerDeviceVisualLayers.Powered: - inverted: "" - - enum.PowerDeviceVisualLayers.Powered: - matrix: "" - - enum.PowerDeviceVisualLayers.Powered: - monochrome: "" - - enum.PowerDeviceVisualLayers.Powered: - murica: "" - - enum.PowerDeviceVisualLayers.Powered: - nanotrasen: "" - - enum.PowerDeviceVisualLayers.Powered: - not_malf: "" - - enum.PowerDeviceVisualLayers.Powered: - president: "" - - enum.PowerDeviceVisualLayers.Powered: - rainbow: "" - - enum.PowerDeviceVisualLayers.Powered: - red: "" - - enum.PowerDeviceVisualLayers.Powered: - red_october: "" - - enum.PowerDeviceVisualLayers.Powered: - static: "" - - enum.PowerDeviceVisualLayers.Powered: - syndicat_meow: "" - - enum.PowerDeviceVisualLayers.Powered: - text: "" - - enum.PowerDeviceVisualLayers.Powered: - too_deep: "" - - enum.PowerDeviceVisualLayers.Powered: - triumvirate: "" - - enum.PowerDeviceVisualLayers.Powered: - triumvirate-m: "" - - enum.PowerDeviceVisualLayers.Powered: - weird: "" - - enum.PowerDeviceVisualLayers.Powered: - random: "" - - enum.PowerDeviceVisualLayers.Powered: - gondola: "" - - enum.PowerDeviceVisualLayers.Powered: - plain: "" - - enum.PowerDeviceVisualLayers.Powered: - cat: "" - - enum.PowerDeviceVisualLayers.Powered: - blob: "" - - enum.PowerDeviceVisualLayers.Powered: - malicious: "" - type: entity id: AIEye diff --git a/Resources/Textures/Backmen/Mobs/Silicon/ai.rsi/meta.json b/Resources/Textures/Backmen/Mobs/Silicon/ai.rsi/meta.json index 05f78144207..4b615c24c38 100644 --- a/Resources/Textures/Backmen/Mobs/Silicon/ai.rsi/meta.json +++ b/Resources/Textures/Backmen/Mobs/Silicon/ai.rsi/meta.json @@ -8,6 +8,9 @@ "name": "aieye", "delays": [[0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.1, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.15, 0.1, 0.1, 0.1, 0.1]] }, + { + "name": "not_in_eye" + }, { "name": "icon-camera" }, diff --git a/Resources/Textures/Backmen/Mobs/Silicon/ai.rsi/not_in_eye.png b/Resources/Textures/Backmen/Mobs/Silicon/ai.rsi/not_in_eye.png new file mode 100644 index 00000000000..8536d3fe8a0 Binary files /dev/null and b/Resources/Textures/Backmen/Mobs/Silicon/ai.rsi/not_in_eye.png differ