using Content.Shared.Doors.Components;
+using Content.Shared.Electrocution;
using Content.Shared.Silicons.StationAi;
using Robust.Shared.Utility;
public sealed partial class StationAiSystem
{
+ private readonly ResPath _aiActionsRsi = new ResPath("/Textures/Interface/Actions/actions_ai.rsi");
+
private void InitializeAirlock()
{
SubscribeLocalEvent<DoorBoltComponent, GetStationAiRadialEvent>(OnDoorBoltGetRadial);
+ SubscribeLocalEvent<AirlockComponent, GetStationAiRadialEvent>(OnEmergencyAccessGetRadial);
+ SubscribeLocalEvent<ElectrifiedComponent, GetStationAiRadialEvent>(OnDoorElectrifiedGetRadial);
}
private void OnDoorBoltGetRadial(Entity<DoorBoltComponent> ent, ref GetStationAiRadialEvent args)
{
- args.Actions.Add(new StationAiRadial()
- {
- Sprite = ent.Comp.BoltsDown ?
- new SpriteSpecifier.Rsi(
- new ResPath("/Textures/Structures/Doors/Airlocks/Standard/basic.rsi"), "open") :
- new SpriteSpecifier.Rsi(
- new ResPath("/Textures/Structures/Doors/Airlocks/Standard/basic.rsi"), "closed"),
- Tooltip = ent.Comp.BoltsDown ? Loc.GetString("bolt-open") : Loc.GetString("bolt-close"),
- Event = new StationAiBoltEvent()
+ args.Actions.Add(
+ new StationAiRadial
+ {
+ Sprite = ent.Comp.BoltsDown
+ ? new SpriteSpecifier.Rsi(_aiActionsRsi, "unbolt_door")
+ : new SpriteSpecifier.Rsi(_aiActionsRsi, "bolt_door"),
+ Tooltip = ent.Comp.BoltsDown
+ ? Loc.GetString("bolt-open")
+ : Loc.GetString("bolt-close"),
+ Event = new StationAiBoltEvent
+ {
+ Bolted = !ent.Comp.BoltsDown,
+ }
+ }
+ );
+ }
+
+ private void OnEmergencyAccessGetRadial(Entity<AirlockComponent> ent, ref GetStationAiRadialEvent args)
+ {
+ args.Actions.Add(
+ new StationAiRadial
+ {
+ Sprite = ent.Comp.EmergencyAccess
+ ? new SpriteSpecifier.Rsi(_aiActionsRsi, "emergency_off")
+ : new SpriteSpecifier.Rsi(_aiActionsRsi, "emergency_on"),
+ Tooltip = ent.Comp.EmergencyAccess
+ ? Loc.GetString("emergency-access-off")
+ : Loc.GetString("emergency-access-on"),
+ Event = new StationAiEmergencyAccessEvent
+ {
+ EmergencyAccess = !ent.Comp.EmergencyAccess,
+ }
+ }
+ );
+ }
+
+ private void OnDoorElectrifiedGetRadial(Entity<ElectrifiedComponent> ent, ref GetStationAiRadialEvent args)
+ {
+ args.Actions.Add(
+ new StationAiRadial
{
- Bolted = !ent.Comp.BoltsDown,
+ Sprite = ent.Comp.Enabled
+ ? new SpriteSpecifier.Rsi(_aiActionsRsi, "door_overcharge_off")
+ : new SpriteSpecifier.Rsi(_aiActionsRsi, "door_overcharge_on"),
+ Tooltip = ent.Comp.Enabled
+ ? Loc.GetString("electrify-door-off")
+ : Loc.GetString("electrify-door-on"),
+ Event = new StationAiElectrifiedEvent
+ {
+ Electrified = !ent.Comp.Enabled,
+ }
}
- });
+ );
}
}
args.Verbs.Add(bolt);
}
- if (TryComp<AirlockComponent>(args.Target, out var airlock))
+ if (TryComp<AirlockComponent>(args.Target, out var airlockComp))
{
Verb emergencyAccess = new()
{
- Text = airlock.EmergencyAccess ? "Emergency Access Off" : "Emergency Access On",
+ Text = airlockComp.EmergencyAccess ? "Emergency Access Off" : "Emergency Access On",
Category = VerbCategory.Tricks,
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/emergency_access.png")),
Act = () =>
{
- _airlockSystem.ToggleEmergencyAccess(args.Target, airlock);
+ _airlockSystem.SetEmergencyAccess((args.Target, airlockComp), !airlockComp.EmergencyAccess);
},
Impact = LogImpact.Medium,
- Message = Loc.GetString(airlock.EmergencyAccess
+ Message = Loc.GetString(airlockComp.EmergencyAccess
? "admin-trick-emergency-access-off-description"
: "admin-trick-emergency-access-on-description"),
- Priority = (int) (airlock.EmergencyAccess ? TricksVerbPriorities.EmergencyAccessOff : TricksVerbPriorities.EmergencyAccessOn),
+ Priority = (int) (airlockComp.EmergencyAccess ? TricksVerbPriorities.EmergencyAccessOff : TricksVerbPriorities.EmergencyAccessOn),
};
args.Verbs.Add(emergencyAccess);
}
using Content.Server.Electrocution;
+using Content.Shared.Electrocution;
using Content.Shared.Construction;
namespace Content.Server.Construction.Completions;
using Content.Server.Wires;
using Content.Shared.Doors;
using Content.Shared.Doors.Components;
-using Content.Shared.Doors.Systems;
using Content.Shared.Wires;
namespace Content.Server.Doors;
}
_audio.PlayPvs(electrified.ShockNoises, targetUid, AudioParams.Default.WithVolume(electrified.ShockVolume));
}
+
+ public void SetElectrifiedWireCut(Entity<ElectrifiedComponent> ent, bool value)
+ {
+ if (ent.Comp.IsWireCut == value)
+ {
+ return;
+ }
+
+ ent.Comp.IsWireCut = value;
+ Dirty(ent);
+ }
}
using Content.Server.Electrocution;
+using Content.Shared.Electrocution;
using Content.Server.Power.Components;
using Content.Server.Wires;
using Content.Shared.Power;
&& !EntityManager.TryGetComponent(used, out electrified))
return;
+ _electrocutionSystem.SetElectrifiedWireCut((used, electrified), setting);
electrified.Enabled = setting;
}
case OperatingMode.ToggleEmergencyAccess:
if (airlockComp != null)
{
- _airlock.ToggleEmergencyAccess(args.Target.Value, airlockComp);
+ _airlock.SetEmergencyAccess((args.Target.Value, airlockComp), !airlockComp.EmergencyAccess);
_adminLogger.Add(LogType.Action, LogImpact.Medium,
$"{ToPrettyString(args.User):player} used {ToPrettyString(args.Used)} on {ToPrettyString(args.Target.Value)} to set emergency access {(airlockComp.EmergencyAccess ? "on" : "off")}");
}
using Content.Shared.DeviceLinking;
using Content.Shared.Doors.Systems;
+using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
[ViewVariables(VVAccess.ReadWrite)]
[DataField, AutoNetworkedField]
public bool EmergencyAccess = false;
+
+ /// <summary>
+ /// Sound to play when the airlock emergency access is turned on.
+ /// </summary>
+ [DataField]
+ public SoundSpecifier EmergencyOnSound = new SoundPathSpecifier("/Audio/Machines/airlock_emergencyon.ogg");
+
+ /// <summary>
+ /// Sound to play when the airlock emergency access is turned off.
+ /// </summary>
+ [DataField]
+ public SoundSpecifier EmergencyOffSound = new SoundPathSpecifier("/Audio/Machines/airlock_emergencyoff.ogg");
/// <summary>
/// Pry modifier for a powered airlock.
using Content.Shared.Doors.Components;
+using Robust.Shared.Audio.Systems;
using Content.Shared.Popups;
using Content.Shared.Prying.Components;
using Content.Shared.Wires;
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
+ [Dependency] protected readonly SharedAudioSystem Audio = default!;
[Dependency] protected readonly SharedDoorSystem DoorSystem = default!;
+ [Dependency] protected readonly SharedPopupSystem Popup = default!;
[Dependency] private readonly SharedWiresSystem _wiresSystem = default!;
public override void Initialize()
Appearance.SetData(uid, DoorVisuals.EmergencyLights, component.EmergencyAccess);
}
- public void ToggleEmergencyAccess(EntityUid uid, AirlockComponent component)
+ public void SetEmergencyAccess(Entity<AirlockComponent> ent, bool value, EntityUid? user = null, bool predicted = false)
{
- component.EmergencyAccess = !component.EmergencyAccess;
- Dirty(uid, component); // This only runs on the server apparently so we need this.
- UpdateEmergencyLightStatus(uid, component);
+ if(!ent.Comp.Powered)
+ return;
+
+ if (ent.Comp.EmergencyAccess == value)
+ return;
+
+ ent.Comp.EmergencyAccess = value;
+ Dirty(ent, ent.Comp); // This only runs on the server apparently so we need this.
+ UpdateEmergencyLightStatus(ent, ent.Comp);
+
+ var sound = ent.Comp.EmergencyAccess ? ent.Comp.EmergencyOnSound : ent.Comp.EmergencyOffSound;
+ if (predicted)
+ Audio.PlayPredicted(sound, ent, user: user);
+ else
+ Audio.PlayPvs(sound, ent);
}
public void SetAutoCloseDelayModifier(AirlockComponent component, float value)
public void SetBoltsDown(Entity<DoorBoltComponent> ent, bool value, EntityUid? user = null, bool predicted = false)
{
+ TrySetBoltDown(ent, value, user, predicted);
+ }
+
+ public bool TrySetBoltDown(
+ Entity<DoorBoltComponent> ent,
+ bool value,
+ EntityUid? user = null,
+ bool predicted = false
+ )
+ {
+ if (!_powerReceiver.IsPowered(ent.Owner))
+ return false;
if (ent.Comp.BoltsDown == value)
- return;
+ return false;
ent.Comp.BoltsDown = value;
Dirty(ent, ent.Comp);
Audio.PlayPredicted(sound, ent, user: user);
else
Audio.PlayPvs(sound, ent);
+ return true;
}
private void OnStateChanged(Entity<DoorBoltComponent> entity, ref DoorStateChangedEvent args)
using Content.Shared.Interaction;
using Content.Shared.Physics;
using Content.Shared.Popups;
+using Content.Shared.Power.EntitySystems;
using Content.Shared.Prying.Components;
using Content.Shared.Prying.Systems;
using Content.Shared.Stunnable;
[Dependency] private readonly PryingSystem _pryingSystem = default!;
[Dependency] protected readonly SharedPopupSystem Popup = default!;
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
+ [Dependency] private readonly SharedPowerReceiverSystem _powerReceiver = default!;
[ValidatePrototypeId<TagPrototype>]
+using Robust.Shared.GameStates;
using Robust.Shared.Audio;
-namespace Content.Server.Electrocution;
+namespace Content.Shared.Electrocution;
/// <summary>
/// Component for things that shock users on touch.
/// </summary>
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ElectrifiedComponent : Component
{
- [DataField("enabled")]
+ [DataField, AutoNetworkedField]
public bool Enabled = true;
/// <summary>
/// Should player get damage on collide
/// </summary>
- [DataField("onBump")]
+ [DataField, AutoNetworkedField]
public bool OnBump = true;
/// <summary>
/// Should player get damage on attack
/// </summary>
- [DataField("onAttacked")]
+ [DataField, AutoNetworkedField]
public bool OnAttacked = true;
/// <summary>
/// When true - disables power if a window is present in the same tile
/// </summary>
- [DataField("noWindowInTile")]
+ [DataField, AutoNetworkedField]
public bool NoWindowInTile = false;
/// <summary>
/// Should player get damage on interact with empty hand
/// </summary>
- [DataField("onHandInteract")]
+ [DataField, AutoNetworkedField]
public bool OnHandInteract = true;
/// <summary>
/// Should player get damage on interact while holding an object in their hand
/// </summary>
- [DataField("onInteractUsing")]
+ [DataField, AutoNetworkedField]
public bool OnInteractUsing = true;
/// <summary>
/// Indicates if the entity requires power to function
/// </summary>
- [DataField("requirePower")]
+ [DataField, AutoNetworkedField]
public bool RequirePower = true;
/// <summary>
/// Indicates if the entity uses APC power
/// </summary>
- [DataField("usesApcPower")]
+ [DataField, AutoNetworkedField]
public bool UsesApcPower = false;
/// <summary>
/// Identifier for the high voltage node.
/// </summary>
- [DataField("highVoltageNode")]
+ [DataField, AutoNetworkedField]
public string? HighVoltageNode;
/// <summary>
/// Identifier for the medium voltage node.
/// </summary>
- [DataField("mediumVoltageNode")]
+ [DataField, AutoNetworkedField]
public string? MediumVoltageNode;
/// <summary>
/// Identifier for the low voltage node.
/// </summary>
- [DataField("lowVoltageNode")]
+ [DataField, AutoNetworkedField]
public string? LowVoltageNode;
/// <summary>
/// Damage multiplier for HV electrocution
/// </summary>
- [DataField]
+ [DataField, AutoNetworkedField]
public float HighVoltageDamageMultiplier = 3f;
/// <summary>
/// Shock time multiplier for HV electrocution
/// </summary>
- [DataField]
+ [DataField, AutoNetworkedField]
public float HighVoltageTimeMultiplier = 1.5f;
/// <summary>
/// Damage multiplier for MV electrocution
/// </summary>
- [DataField]
+ [DataField, AutoNetworkedField]
public float MediumVoltageDamageMultiplier = 2f;
/// <summary>
/// Shock time multiplier for MV electrocution
/// </summary>
- [DataField]
+ [DataField, AutoNetworkedField]
public float MediumVoltageTimeMultiplier = 1.25f;
- [DataField("shockDamage")]
+ [DataField, AutoNetworkedField]
public float ShockDamage = 7.5f;
/// <summary>
/// Shock time, in seconds.
/// </summary>
- [DataField("shockTime")]
+ [DataField, AutoNetworkedField]
public float ShockTime = 8f;
- [DataField("siemensCoefficient")]
+ [DataField, AutoNetworkedField]
public float SiemensCoefficient = 1f;
- [DataField("shockNoises")]
+ [DataField, AutoNetworkedField]
public SoundSpecifier ShockNoises = new SoundCollectionSpecifier("sparks");
- [DataField("playSoundOnShock")]
+ [DataField, AutoNetworkedField]
+ public SoundPathSpecifier AirlockElectrifyDisabled = new("/Audio/Machines/airlock_electrify_on.ogg");
+
+ [DataField, AutoNetworkedField]
+ public SoundPathSpecifier AirlockElectrifyEnabled = new("/Audio/Machines/airlock_electrify_off.ogg");
+
+ [DataField, AutoNetworkedField]
public bool PlaySoundOnShock = true;
- [DataField("shockVolume")]
+ [DataField, AutoNetworkedField]
public float ShockVolume = 20;
- [DataField]
+ [DataField, AutoNetworkedField]
public float Probability = 1f;
+
+ [DataField, AutoNetworkedField]
+ public bool IsWireCut = false;
}
Dirty(uid, insulated);
}
+ /// <summary>
+ /// Sets electrified value of component and marks dirty if required.
+ /// </summary>
+ public void SetElectrified(Entity<ElectrifiedComponent> ent, bool value)
+ {
+ if (ent.Comp.Enabled == value)
+ {
+ return;
+ }
+
+ ent.Comp.Enabled = value;
+ Dirty(ent, ent.Comp);
+ }
+
/// <param name="uid">Entity being electrocuted.</param>
/// <param name="sourceUid">Source entity of the electrocution.</param>
/// <param name="shockDamage">How much shock damage the entity takes.</param>
using System.Diagnostics.CodeAnalysis;
-using Content.Shared.Examine;
using Content.Shared.Power.Components;
namespace Content.Shared.Power.EntitySystems;
{
public abstract bool ResolveApc(EntityUid entity, [NotNullWhen(true)] ref SharedApcPowerReceiverComponent? component);
+ /// <summary>
+ /// Checks if entity is APC-powered device, and if it have power.
+ /// </summary>
public bool IsPowered(Entity<SharedApcPowerReceiverComponent?> entity)
{
if (!ResolveApc(entity.Owner, ref entity.Comp))
using Content.Shared.Doors.Components;
using Robust.Shared.Serialization;
+using Content.Shared.Electrocution;
namespace Content.Shared.Silicons.StationAi;
private void InitializeAirlock()
{
SubscribeLocalEvent<DoorBoltComponent, StationAiBoltEvent>(OnAirlockBolt);
+ SubscribeLocalEvent<AirlockComponent, StationAiEmergencyAccessEvent>(OnAirlockEmergencyAccess);
+ SubscribeLocalEvent<ElectrifiedComponent, StationAiElectrifiedEvent>(OnElectrified);
}
+ /// <summary>
+ /// Attempts to bolt door. If wire was cut (AI or for bolts) or its not powered - notifies AI and does nothing.
+ /// </summary>
private void OnAirlockBolt(EntityUid ent, DoorBoltComponent component, StationAiBoltEvent args)
{
- _doors.SetBoltsDown((ent, component), args.Bolted, args.User, predicted: true);
+ if (component.BoltWireCut)
+ {
+ ShowDeviceNotRespondingPopup(args.User);
+ return;
+ }
+
+ var setResult = _doors.TrySetBoltDown((ent, component), args.Bolted, args.User, predicted: true);
+ if (!setResult)
+ {
+ ShowDeviceNotRespondingPopup(args.User);
+ }
+ }
+
+ /// <summary>
+ /// Attempts to bolt door. If wire was cut (AI) or its not powered - notifies AI and does nothing.
+ /// </summary>
+ private void OnAirlockEmergencyAccess(EntityUid ent, AirlockComponent component, StationAiEmergencyAccessEvent args)
+ {
+ if (!PowerReceiver.IsPowered(ent))
+ {
+ ShowDeviceNotRespondingPopup(args.User);
+ return;
+ }
+
+ _airlocks.SetEmergencyAccess((ent, component), args.EmergencyAccess, args.User, predicted: true);
+ }
+
+ /// <summary>
+ /// Attempts to bolt door. If wire was cut (AI or for one of power-wires) or its not powered - notifies AI and does nothing.
+ /// </summary>
+ private void OnElectrified(EntityUid ent, ElectrifiedComponent component, StationAiElectrifiedEvent args)
+ {
+ if (
+ component.IsWireCut
+ || !PowerReceiver.IsPowered(ent)
+ )
+ {
+ ShowDeviceNotRespondingPopup(args.User);
+ return;
+ }
+
+ _electrify.SetElectrified((ent, component), args.Electrified);
+ var soundToPlay = component.Enabled
+ ? component.AirlockElectrifyDisabled
+ : component.AirlockElectrifyEnabled;
+ _audio.PlayLocal(soundToPlay, ent, args.User);
}
}
+/// <summary> Event for StationAI attempt at bolting/unbolting door. </summary>
[Serializable, NetSerializable]
public sealed class StationAiBoltEvent : BaseStationAiAction
{
+ /// <summary> Marker, should be door bolted or unbolted. </summary>
public bool Bolted;
}
+
+/// <summary> Event for StationAI attempt at setting emergency access for door on/off. </summary>
+[Serializable, NetSerializable]
+public sealed class StationAiEmergencyAccessEvent : BaseStationAiAction
+{
+ /// <summary> Marker, should door have emergency access on or off. </summary>
+ public bool EmergencyAccess;
+}
+
+/// <summary> Event for StationAI attempt at electrifying/de-electrifying door. </summary>
+[Serializable, NetSerializable]
+public sealed class StationAiElectrifiedEvent : BaseStationAiAction
+{
+ /// <summary> Marker, should door be electrified or no. </summary>
+ public bool Electrified;
+}
using Content.Shared.Actions.Events;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction.Events;
+using Content.Shared.Popups;
using Content.Shared.Verbs;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
/*
* Added when an entity is inserted into a StationAiCore.
*/
-
- //TODO: Fix this, please
- private const string JobNameLocId = "job-name-station-ai";
+
+ //TODO: Fix this, please
+ private const string JobNameLocId = "job-name-station-ai";
private void InitializeHeld()
{
SubscribeLocalEvent<StationAiHeldComponent, InteractionAttemptEvent>(OnHeldInteraction);
SubscribeLocalEvent<StationAiHeldComponent, AttemptRelayActionComponentChangeEvent>(OnHeldRelay);
SubscribeLocalEvent<StationAiHeldComponent, JumpToCoreEvent>(OnCoreJump);
- SubscribeLocalEvent<TryGetIdentityShortInfoEvent>(OnTryGetIdentityShortInfo);
+ SubscribeLocalEvent<TryGetIdentityShortInfoEvent>(OnTryGetIdentityShortInfo);
}
-
- private void OnTryGetIdentityShortInfo(TryGetIdentityShortInfoEvent args)
+
+ private void OnTryGetIdentityShortInfo(TryGetIdentityShortInfoEvent args)
{
if (args.Handled)
{
{
return;
}
- args.Title = $"{Name(args.ForActor)} ({Loc.GetString(JobNameLocId)})";
+ args.Title = $"{Name(args.ForActor)} ({Loc.GetString(JobNameLocId)})";
args.Handled = true;
}
return;
if (TryComp(ev.Actor, out StationAiHeldComponent? aiComp) &&
- (!ValidateAi((ev.Actor, aiComp)) ||
- !HasComp<StationAiWhitelistComponent>(ev.Target)))
+ (!TryComp(ev.Target, out StationAiWhitelistComponent? whitelistComponent) ||
+ !ValidateAi((ev.Actor, aiComp))))
{
+ if (whitelistComponent is { Enabled: false })
+ {
+ ShowDeviceNotRespondingPopup(ev.Actor);
+ }
ev.Cancel();
}
}
private void OnHeldInteraction(Entity<StationAiHeldComponent> ent, ref InteractionAttemptEvent args)
{
- // Cancel if it's not us or something with a whitelist.
- args.Cancelled = ent.Owner != args.Target &&
- args.Target != null &&
- (!TryComp(args.Target, out StationAiWhitelistComponent? whitelist) || !whitelist.Enabled);
+ // Cancel if it's not us or something with a whitelist, or whitelist is disabled.
+ args.Cancelled = (!TryComp(args.Target, out StationAiWhitelistComponent? whitelistComponent)
+ || !whitelistComponent.Enabled)
+ && ent.Owner != args.Target
+ && args.Target != null;
+ if (whitelistComponent is { Enabled: false })
+ {
+ ShowDeviceNotRespondingPopup(ent.Owner);
+ }
}
private void OnTargetVerbs(Entity<StationAiWhitelistComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
{
- if (!args.CanComplexInteract ||
- !ent.Comp.Enabled ||
- !HasComp<StationAiHeldComponent>(args.User) ||
- !HasComp<StationAiWhitelistComponent>(args.Target))
+ if (!args.CanComplexInteract
+ || !HasComp<StationAiHeldComponent>(args.User))
{
return;
}
var user = args.User;
+
var target = args.Target;
var isOpen = _uiSystem.IsUiOpen(target, AiUi.Key, user);
- args.Verbs.Add(new AlternativeVerb()
+ var verb = new AlternativeVerb
{
Text = isOpen ? Loc.GetString("ai-close") : Loc.GetString("ai-open"),
- Act = () =>
+ Act = () =>
{
+ // no need to show menu if device is not powered.
+ if (!PowerReceiver.IsPowered(ent.Owner))
+ {
+ ShowDeviceNotRespondingPopup(user);
+ return;
+ }
+
if (isOpen)
{
_uiSystem.CloseUi(ent.Owner, AiUi.Key, user);
_uiSystem.OpenUi(ent.Owner, AiUi.Key, user);
}
}
- });
+ };
+ args.Verbs.Add(verb);
+ }
+
+ private void ShowDeviceNotRespondingPopup(EntityUid toEntity)
+ {
+ _popup.PopupClient(Loc.GetString("ai-device-not-responding"), toEntity, PopupType.MediumCaution);
}
}
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Database;
using Content.Shared.Doors.Systems;
+using Content.Shared.Electrocution;
using Content.Shared.Interaction;
using Content.Shared.Item.ItemToggle;
using Content.Shared.Mind;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
+using Content.Shared.Popups;
using Content.Shared.Power;
+using Content.Shared.Power.EntitySystems;
using Content.Shared.StationAi;
using Content.Shared.Verbs;
+using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.Map.Components;
using Robust.Shared.Network;
public abstract partial class SharedStationAiSystem : EntitySystem
{
- [Dependency] private readonly ISharedAdminManager _admin = default!;
- [Dependency] private readonly IGameTiming _timing = default!;
- [Dependency] private readonly INetManager _net = default!;
- [Dependency] private readonly ItemSlotsSystem _slots = default!;
- [Dependency] private readonly ItemToggleSystem _toggles = default!;
- [Dependency] private readonly ActionBlockerSystem _blocker = default!;
- [Dependency] private readonly MetaDataSystem _metadata = default!;
- [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
- [Dependency] private readonly SharedContainerSystem _containers = default!;
- [Dependency] private readonly SharedDoorSystem _doors = default!;
- [Dependency] private readonly SharedEyeSystem _eye = default!;
+ [Dependency] private readonly ISharedAdminManager _admin = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
+ [Dependency] private readonly INetManager _net = default!;
+ [Dependency] private readonly ItemSlotsSystem _slots = default!;
+ [Dependency] private readonly ItemToggleSystem _toggles = default!;
+ [Dependency] private readonly ActionBlockerSystem _blocker = default!;
+ [Dependency] private readonly MetaDataSystem _metadata = default!;
+ [Dependency] private readonly SharedAirlockSystem _airlocks = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
+ [Dependency] private readonly SharedContainerSystem _containers = default!;
+ [Dependency] private readonly SharedDoorSystem _doors = default!;
+ [Dependency] private readonly SharedElectrocutionSystem _electrify = default!;
+ [Dependency] private readonly SharedEyeSystem _eye = default!;
[Dependency] protected readonly SharedMapSystem Maps = default!;
- [Dependency] private readonly SharedMindSystem _mind = default!;
- [Dependency] private readonly SharedMoverController _mover = default!;
- [Dependency] private readonly SharedTransformSystem _xforms = default!;
- [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
- [Dependency] private readonly StationAiVisionSystem _vision = default!;
+ [Dependency] private readonly SharedMindSystem _mind = default!;
+ [Dependency] private readonly SharedMoverController _mover = default!;
+ [Dependency] private readonly SharedPopupSystem _popup = default!;
+ [Dependency] private readonly SharedPowerReceiverSystem PowerReceiver = default!;
+ [Dependency] private readonly SharedTransformSystem _xforms = default!;
+ [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
+ [Dependency] private readonly StationAiVisionSystem _vision = default!;
// StationAiHeld is added to anything inside of an AI core.
// StationAiHolder indicates it can hold an AI positronic brain (e.g. holocard / core).
license: "CC0-1.0"
copyright: "by Ko4erga"
source: "https://github.com/space-wizards/space-station-14/pull/30431"
+
+- files:
+ - airlock_emergencyoff.ogg
+ - airlock_emergencyon.ogg
+ - airlock_electrify_off.ogg
+ - airlock_electrify_on.ogg
+ license: "CC0-1.0"
+ copyright: "by ScarKy0"
+ source: "https://github.com/space-wizards/space-station-14/pull/32012"
bolt-close = Close bolt
bolt-open = Open bolt
+emergency-access-on = Enable emergency access
+emergency-access-off = Disable emergency access
+
+electrify-door-on = Enable overcharge
+electrify-door-off = Disable overcharge
+
toggle-light = Toggle light
+
+ai-device-not-responding = Device is not responding
{
- "version": 1,
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/blob/c473a8bcc28fbd80827dfca5660d81ca6e833e2c/icons/hud/screen_ai.dmi",
- "size": {
- "x": 32,
- "y": 32
- },
- "states": [
- {
- "name": "ai_core"
- },
- {
- "name": "camera_light"
- },
- {
- "name": "crew_monitor"
- },
- {
- "name": "manifest"
- },
- {
- "name": "state_laws"
- },
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/blob/c473a8bcc28fbd80827dfca5660d81ca6e833e2c/icons/hud/screen_ai.dmi , some sprites updated by ScarKy0(Discord), door actions by ScarKy0(Discord) and @Max_tanuki(Twitter)",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "ai_core"
+ },
+ {
+ "name": "camera_light"
+ },
+ {
+ "name": "crew_monitor"
+ },
+ {
+ "name": "manifest"
+ },
+ {
+ "name": "state_laws"
+ },
{
"name": "station_records"
},
},
{
"name": "comms_console"
+ },
+ {
+ "name": "emergency_off"
+ },
+ {
+ "name": "emergency_on"
+ },
+ {
+ "name": "bolt_door"
+ },
+ {
+ "name": "unbolt_door"
+ },
+ {
+ "name": "door_overcharge_on"
+ },
+ {
+ "name": "door_overcharge_off"
}
- ]
+ ]
}