Seperate EMAG into EMAG and Authentication Disruptor (#34337)
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
using Content.Server.Wires;
|
using Content.Server.Wires;
|
||||||
using Content.Shared.Access;
|
using Content.Shared.Access;
|
||||||
using Content.Shared.Access.Components;
|
using Content.Shared.Access.Components;
|
||||||
using Content.Shared.Emag.Components;
|
|
||||||
using Content.Shared.Wires;
|
using Content.Shared.Wires;
|
||||||
|
|
||||||
namespace Content.Server.Access;
|
namespace Content.Server.Access;
|
||||||
@@ -31,11 +30,9 @@ public sealed partial class AccessWireAction : ComponentWireAction<AccessReaderC
|
|||||||
|
|
||||||
public override bool Mend(EntityUid user, Wire wire, AccessReaderComponent comp)
|
public override bool Mend(EntityUid user, Wire wire, AccessReaderComponent comp)
|
||||||
{
|
{
|
||||||
if (!EntityManager.HasComponent<EmaggedComponent>(wire.Owner))
|
comp.Enabled = true;
|
||||||
{
|
EntityManager.Dirty(wire.Owner, comp);
|
||||||
comp.Enabled = true;
|
|
||||||
EntityManager.Dirty(wire.Owner, comp);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +55,7 @@ public sealed partial class AccessWireAction : ComponentWireAction<AccessReaderC
|
|||||||
{
|
{
|
||||||
if (!wire.IsCut)
|
if (!wire.IsCut)
|
||||||
{
|
{
|
||||||
if (EntityManager.TryGetComponent<AccessReaderComponent>(wire.Owner, out var access) && !EntityManager.HasComponent<EmaggedComponent>(wire.Owner))
|
if (EntityManager.TryGetComponent<AccessReaderComponent>(wire.Owner, out var access))
|
||||||
{
|
{
|
||||||
access.Enabled = true;
|
access.Enabled = true;
|
||||||
EntityManager.Dirty(wire.Owner, access);
|
EntityManager.Dirty(wire.Owner, access);
|
||||||
|
|||||||
@@ -245,6 +245,10 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
|
|||||||
$"{ToPrettyString(player):player} has modified {ToPrettyString(accessReaderEnt.Value):entity} with the following allowed access level holders: [{string.Join(", ", addedTags.Union(removedTags))}] [{string.Join(", ", newAccessList)}]");
|
$"{ToPrettyString(player):player} has modified {ToPrettyString(accessReaderEnt.Value):entity} with the following allowed access level holders: [{string.Join(", ", addedTags.Union(removedTags))}] [{string.Join(", ", newAccessList)}]");
|
||||||
|
|
||||||
accessReaderEnt.Value.Comp.AccessLists = ConvertAccessListToHashSet(newAccessList);
|
accessReaderEnt.Value.Comp.AccessLists = ConvertAccessListToHashSet(newAccessList);
|
||||||
|
|
||||||
|
var ev = new OnAccessOverriderAccessUpdatedEvent(player);
|
||||||
|
RaiseLocalEvent(component.TargetAccessReaderId, ref ev);
|
||||||
|
|
||||||
Dirty(accessReaderEnt.Value);
|
Dirty(accessReaderEnt.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,8 +116,11 @@ public sealed class TechAnomalySystem : EntitySystem
|
|||||||
|
|
||||||
if (_random.Prob(tech.Comp.EmagSupercritProbability))
|
if (_random.Prob(tech.Comp.EmagSupercritProbability))
|
||||||
{
|
{
|
||||||
_emag.DoEmagEffect(tech, source);
|
var sourceEv = new GotEmaggedEvent(tech, EmagType.Access | EmagType.Interaction);
|
||||||
_emag.DoEmagEffect(tech, sink);
|
RaiseLocalEvent(source, ref sourceEv);
|
||||||
|
|
||||||
|
var sinkEv = new GotEmaggedEvent(tech, EmagType.Access | EmagType.Interaction);
|
||||||
|
RaiseLocalEvent(sink, ref sinkEv);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateNewLink(tech, source, sink);
|
CreateNewLink(tech, source, sink);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public sealed class FireAlarmSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly AtmosDeviceNetworkSystem _atmosDevNet = default!;
|
[Dependency] private readonly AtmosDeviceNetworkSystem _atmosDevNet = default!;
|
||||||
[Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!;
|
[Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||||
[Dependency] private readonly AccessReaderSystem _access = default!;
|
[Dependency] private readonly AccessReaderSystem _access = default!;
|
||||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||||
@@ -77,11 +78,18 @@ public sealed class FireAlarmSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, FireAlarmComponent component, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, FireAlarmComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
if (TryComp<AtmosAlarmableComponent>(uid, out var alarmable))
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
{
|
return;
|
||||||
// Remove the atmos alarmable component permanently from this device.
|
|
||||||
_atmosAlarmable.ForceAlert(uid, AtmosAlarmType.Emagged, alarmable);
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
RemCompDeferred<AtmosAlarmableComponent>(uid);
|
return;
|
||||||
}
|
|
||||||
|
if (!TryComp<AtmosAlarmableComponent>(uid, out var alarmable))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Remove the atmos alarmable component permanently from this device.
|
||||||
|
_atmosAlarmable.ForceAlert(uid, AtmosAlarmType.Emagged, alarmable);
|
||||||
|
RemCompDeferred<AtmosAlarmableComponent>(uid);
|
||||||
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Content.Server.Bed
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
[Dependency] private readonly ActionsSystem _actionsSystem = default!;
|
[Dependency] private readonly ActionsSystem _actionsSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly SleepingSystem _sleepingSystem = default!;
|
[Dependency] private readonly SleepingSystem _sleepingSystem = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
||||||
@@ -114,7 +115,12 @@ namespace Content.Server.Bed
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, StasisBedComponent component, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, StasisBedComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
args.Repeatable = true;
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
// Reset any metabolisms first so they receive the multiplier correctly
|
// Reset any metabolisms first so they receive the multiplier correctly
|
||||||
UpdateMetabolisms(uid, component, false);
|
UpdateMetabolisms(uid, component, false);
|
||||||
component.Multiplier = 1 / component.Multiplier;
|
component.Multiplier = 1 / component.Multiplier;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Content.Shared.Cargo.Components;
|
|||||||
using Content.Shared.Cargo.Events;
|
using Content.Shared.Cargo.Events;
|
||||||
using Content.Shared.Cargo.Prototypes;
|
using Content.Shared.Cargo.Prototypes;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Emag.Components;
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Paper;
|
using Content.Shared.Paper;
|
||||||
@@ -21,6 +21,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
public sealed partial class CargoSystem
|
public sealed partial class CargoSystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How much time to wait (in seconds) before increasing bank accounts balance.
|
/// How much time to wait (in seconds) before increasing bank accounts balance.
|
||||||
@@ -41,6 +42,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
SubscribeLocalEvent<CargoOrderConsoleComponent, ComponentInit>(OnInit);
|
SubscribeLocalEvent<CargoOrderConsoleComponent, ComponentInit>(OnInit);
|
||||||
SubscribeLocalEvent<CargoOrderConsoleComponent, InteractUsingEvent>(OnInteractUsing);
|
SubscribeLocalEvent<CargoOrderConsoleComponent, InteractUsingEvent>(OnInteractUsing);
|
||||||
SubscribeLocalEvent<CargoOrderConsoleComponent, BankBalanceUpdatedEvent>(OnOrderBalanceUpdated);
|
SubscribeLocalEvent<CargoOrderConsoleComponent, BankBalanceUpdatedEvent>(OnOrderBalanceUpdated);
|
||||||
|
SubscribeLocalEvent<CargoOrderConsoleComponent, GotEmaggedEvent>(OnEmagged);
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +77,17 @@ namespace Content.Server.Cargo.Systems
|
|||||||
_timer = 0;
|
_timer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnEmagged(Entity<CargoOrderConsoleComponent> ent, ref GotEmaggedEvent args)
|
||||||
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(ent, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateConsole(float frameTime)
|
private void UpdateConsole(float frameTime)
|
||||||
{
|
{
|
||||||
_timer += frameTime;
|
_timer += frameTime;
|
||||||
@@ -192,7 +205,7 @@ namespace Content.Server.Cargo.Systems
|
|||||||
order.Approved = true;
|
order.Approved = true;
|
||||||
_audio.PlayPvs(component.ConfirmSound, uid);
|
_audio.PlayPvs(component.ConfirmSound, uid);
|
||||||
|
|
||||||
if (!HasComp<EmaggedComponent>(uid))
|
if (!_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
{
|
{
|
||||||
var tryGetIdentityShortInfoEvent = new TryGetIdentityShortInfoEvent(uid, player);
|
var tryGetIdentityShortInfoEvent = new TryGetIdentityShortInfoEvent(uid, player);
|
||||||
RaiseLocalEvent(tryGetIdentityShortInfoEvent);
|
RaiseLocalEvent(tryGetIdentityShortInfoEvent);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ namespace Content.Server.Cloning
|
|||||||
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
|
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
|
||||||
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
|
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
|
||||||
[Dependency] private readonly SharedJobSystem _jobs = default!;
|
[Dependency] private readonly SharedJobSystem _jobs = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
public readonly Dictionary<MindComponent, EntityUid> ClonesWaitingForMind = new();
|
public readonly Dictionary<MindComponent, EntityUid> ClonesWaitingForMind = new();
|
||||||
public const float EasyModeCloningCost = 0.7f;
|
public const float EasyModeCloningCost = 0.7f;
|
||||||
@@ -276,10 +277,15 @@ namespace Content.Server.Cloning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnEmagged(EntityUid uid, CloningPodComponent clonePod, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, CloningPodComponent clonePod, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!this.IsPowered(uid, EntityManager))
|
if (!this.IsPowered(uid, EntityManager))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_audio.PlayPvs(clonePod.SparkSound, uid);
|
|
||||||
_popupSystem.PopupEntity(Loc.GetString("cloning-pod-component-upgrade-emag-requirement"), uid);
|
_popupSystem.PopupEntity(Loc.GetString("cloning-pod-component-upgrade-emag-requirement"), uid);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
@@ -309,7 +315,7 @@ namespace Content.Server.Cloning
|
|||||||
var indices = _transformSystem.GetGridTilePositionOrDefault((uid, transform));
|
var indices = _transformSystem.GetGridTilePositionOrDefault((uid, transform));
|
||||||
var tileMix = _atmosphereSystem.GetTileMixture(transform.GridUid, null, indices, true);
|
var tileMix = _atmosphereSystem.GetTileMixture(transform.GridUid, null, indices, true);
|
||||||
|
|
||||||
if (HasComp<EmaggedComponent>(uid))
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
{
|
{
|
||||||
_audio.PlayPvs(clonePod.ScreamSound, uid);
|
_audio.PlayPvs(clonePod.ScreamSound, uid);
|
||||||
Spawn(clonePod.MobSpawnId, transform.Coordinates);
|
Spawn(clonePod.MobSpawnId, transform.Coordinates);
|
||||||
@@ -327,7 +333,7 @@ namespace Content.Server.Cloning
|
|||||||
}
|
}
|
||||||
_puddleSystem.TrySpillAt(uid, bloodSolution, out _);
|
_puddleSystem.TrySpillAt(uid, bloodSolution, out _);
|
||||||
|
|
||||||
if (!HasComp<EmaggedComponent>(uid))
|
if (!_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
{
|
{
|
||||||
_material.SpawnMultipleFromMaterial(_robustRandom.Next(1, (int) (clonePod.UsedBiomass / 2.5)), clonePod.RequiredMaterial, Transform(uid).Coordinates);
|
_material.SpawnMultipleFromMaterial(_robustRandom.Next(1, (int) (clonePod.UsedBiomass / 2.5)), clonePod.RequiredMaterial, Transform(uid).Coordinates);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ using Content.Shared.Chat;
|
|||||||
using Content.Shared.Communications;
|
using Content.Shared.Communications;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.DeviceNetwork;
|
using Content.Shared.DeviceNetwork;
|
||||||
using Content.Shared.Emag.Components;
|
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -177,7 +176,7 @@ namespace Content.Server.Communications
|
|||||||
|
|
||||||
private bool CanUse(EntityUid user, EntityUid console)
|
private bool CanUse(EntityUid user, EntityUid console)
|
||||||
{
|
{
|
||||||
if (TryComp<AccessReaderComponent>(console, out var accessReaderComponent) && !HasComp<EmaggedComponent>(console))
|
if (TryComp<AccessReaderComponent>(console, out var accessReaderComponent))
|
||||||
{
|
{
|
||||||
return _accessReaderSystem.IsAllowed(user, console, accessReaderComponent);
|
return _accessReaderSystem.IsAllowed(user, console, accessReaderComponent);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||||
[Dependency] private readonly FaxecuteSystem _faxecute = default!;
|
[Dependency] private readonly FaxecuteSystem _faxecute = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
private const string PaperSlotId = "Paper";
|
private const string PaperSlotId = "Paper";
|
||||||
|
|
||||||
@@ -227,7 +228,7 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.KnownFaxes.ContainsValue(newName) && !HasComp<EmaggedComponent>(uid)) // Allow existing names if emagged for fun
|
if (component.KnownFaxes.ContainsValue(newName) && !_emag.CheckFlag(uid, EmagType.Interaction)) // Allow existing names if emagged for fun
|
||||||
{
|
{
|
||||||
_popupSystem.PopupEntity(Loc.GetString("fax-machine-popup-name-exist"), uid);
|
_popupSystem.PopupEntity(Loc.GetString("fax-machine-popup-name-exist"), uid);
|
||||||
return;
|
return;
|
||||||
@@ -246,7 +247,12 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, FaxMachineComponent component, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, FaxMachineComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
_audioSystem.PlayPvs(component.EmagSound, uid);
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +266,7 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case FaxConstants.FaxPingCommand:
|
case FaxConstants.FaxPingCommand:
|
||||||
var isForSyndie = HasComp<EmaggedComponent>(uid) &&
|
var isForSyndie = _emag.CheckFlag(uid, EmagType.Interaction) &&
|
||||||
args.Data.ContainsKey(FaxConstants.FaxSyndicateData);
|
args.Data.ContainsKey(FaxConstants.FaxSyndicateData);
|
||||||
if (!isForSyndie && !component.ResponsePings)
|
if (!isForSyndie && !component.ResponsePings)
|
||||||
return;
|
return;
|
||||||
@@ -405,7 +411,7 @@ public sealed class FaxSystem : EntitySystem
|
|||||||
{ DeviceNetworkConstants.Command, FaxConstants.FaxPingCommand }
|
{ DeviceNetworkConstants.Command, FaxConstants.FaxPingCommand }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (HasComp<EmaggedComponent>(uid))
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
payload.Add(FaxConstants.FaxSyndicateData, true);
|
payload.Add(FaxConstants.FaxSyndicateData, true);
|
||||||
|
|
||||||
_deviceNetworkSystem.QueuePacket(uid, null, payload);
|
_deviceNetworkSystem.QueuePacket(uid, null, payload);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using Content.Shared.Chemistry.Reagent;
|
|||||||
using Content.Shared.UserInterface;
|
using Content.Shared.UserInterface;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Emag.Components;
|
using Content.Shared.Emag.Components;
|
||||||
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Lathe;
|
using Content.Shared.Lathe;
|
||||||
using Content.Shared.Materials;
|
using Content.Shared.Materials;
|
||||||
@@ -42,6 +43,7 @@ namespace Content.Server.Lathe
|
|||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly ContainerSystem _container = default!;
|
[Dependency] private readonly ContainerSystem _container = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _uiSys = default!;
|
[Dependency] private readonly UserInterfaceSystem _uiSys = default!;
|
||||||
[Dependency] private readonly MaterialStorageSystem _materialStorage = default!;
|
[Dependency] private readonly MaterialStorageSystem _materialStorage = default!;
|
||||||
[Dependency] private readonly PopupSystem _popup = default!;
|
[Dependency] private readonly PopupSystem _popup = default!;
|
||||||
@@ -292,7 +294,7 @@ namespace Content.Server.Lathe
|
|||||||
{
|
{
|
||||||
if (uid != args.Lathe || !TryComp<TechnologyDatabaseComponent>(uid, out var technologyDatabase))
|
if (uid != args.Lathe || !TryComp<TechnologyDatabaseComponent>(uid, out var technologyDatabase))
|
||||||
return;
|
return;
|
||||||
if (!args.getUnavailable && !HasComp<EmaggedComponent>(uid))
|
if (!args.getUnavailable && !_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
return;
|
return;
|
||||||
foreach (var recipe in component.EmagDynamicRecipes)
|
foreach (var recipe in component.EmagDynamicRecipes)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace Content.Server.Nutrition.EntitySystems;
|
|||||||
public sealed class FatExtractorSystem : EntitySystem
|
public sealed class FatExtractorSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly HungerSystem _hunger = default!;
|
[Dependency] private readonly HungerSystem _hunger = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
@@ -36,8 +37,13 @@ public sealed class FatExtractorSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnGotEmagged(EntityUid uid, FatExtractorComponent component, ref GotEmaggedEvent args)
|
private void OnGotEmagged(EntityUid uid, FatExtractorComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
args.Repeatable = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClosed(EntityUid uid, FatExtractorComponent component, ref StorageAfterCloseEvent args)
|
private void OnClosed(EntityUid uid, FatExtractorComponent component, ref StorageAfterCloseEvent args)
|
||||||
@@ -103,7 +109,7 @@ public sealed class FatExtractorSystem : EntitySystem
|
|||||||
if (_hunger.GetHunger(hunger) < component.NutritionPerSecond)
|
if (_hunger.GetHunger(hunger) < component.NutritionPerSecond)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (hunger.CurrentThreshold < component.MinHungerThreshold && !HasComp<EmaggedComponent>(uid))
|
if (hunger.CurrentThreshold < component.MinHungerThreshold && !_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
||||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly FoodSystem _foodSystem = default!;
|
[Dependency] private readonly FoodSystem _foodSystem = default!;
|
||||||
[Dependency] private readonly ExplosionSystem _explosionSystem = default!;
|
[Dependency] private readonly ExplosionSystem _explosionSystem = default!;
|
||||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||||
@@ -63,7 +64,7 @@ namespace Content.Server.Nutrition.EntitySystems
|
|||||||
forced = false;
|
forced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity.Comp.ExplodeOnUse || HasComp<EmaggedComponent>(entity.Owner))
|
if (entity.Comp.ExplodeOnUse || _emag.CheckFlag(entity, EmagType.Interaction))
|
||||||
{
|
{
|
||||||
_explosionSystem.QueueExplosion(entity.Owner, "Default", entity.Comp.ExplosionIntensity, 0.5f, 3, canCreateVacuum: false);
|
_explosionSystem.QueueExplosion(entity.Owner, "Default", entity.Comp.ExplosionIntensity, 0.5f, 3, canCreateVacuum: false);
|
||||||
EntityManager.DeleteEntity(entity);
|
EntityManager.DeleteEntity(entity);
|
||||||
@@ -161,8 +162,15 @@ namespace Content.Server.Nutrition.EntitySystems
|
|||||||
args.Args.Target.Value);
|
args.Args.Target.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEmagged(Entity<VapeComponent> entity, ref GotEmaggedEvent args)
|
private void OnEmagged(Entity<VapeComponent> entity, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(entity, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Content.Server.Power.Components;
|
|||||||
using Content.Server.Power.Pow3r;
|
using Content.Server.Power.Pow3r;
|
||||||
using Content.Shared.Access.Systems;
|
using Content.Shared.Access.Systems;
|
||||||
using Content.Shared.APC;
|
using Content.Shared.APC;
|
||||||
using Content.Shared.Emag.Components;
|
|
||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Rounding;
|
using Content.Shared.Rounding;
|
||||||
@@ -19,6 +18,7 @@ public sealed class ApcSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
|
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly PopupSystem _popup = default!;
|
[Dependency] private readonly PopupSystem _popup = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
@@ -111,7 +111,12 @@ public sealed class ApcSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, ApcComponent comp, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, ApcComponent comp, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
// no fancy conditions
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +175,7 @@ public sealed class ApcSystem : EntitySystem
|
|||||||
|
|
||||||
private ApcChargeState CalcChargeState(EntityUid uid, PowerState.Battery battery)
|
private ApcChargeState CalcChargeState(EntityUid uid, PowerState.Battery battery)
|
||||||
{
|
{
|
||||||
if (HasComp<EmaggedComponent>(uid))
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
return ApcChargeState.Emag;
|
return ApcChargeState.Emag;
|
||||||
|
|
||||||
if (battery.CurrentStorage / battery.Capacity > ApcComponent.HighPowerThreshold)
|
if (battery.CurrentStorage / battery.Capacity > ApcComponent.HighPowerThreshold)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Server.Research.Components;
|
|||||||
using Content.Shared.UserInterface;
|
using Content.Shared.UserInterface;
|
||||||
using Content.Shared.Access.Components;
|
using Content.Shared.Access.Components;
|
||||||
using Content.Shared.Emag.Components;
|
using Content.Shared.Emag.Components;
|
||||||
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Research.Components;
|
using Content.Shared.Research.Components;
|
||||||
using Content.Shared.Research.Prototypes;
|
using Content.Shared.Research.Prototypes;
|
||||||
@@ -11,6 +12,8 @@ namespace Content.Server.Research.Systems;
|
|||||||
|
|
||||||
public sealed partial class ResearchSystem
|
public sealed partial class ResearchSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
private void InitializeConsole()
|
private void InitializeConsole()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<ResearchConsoleComponent, ConsoleUnlockTechnologyMessage>(OnConsoleUnlock);
|
SubscribeLocalEvent<ResearchConsoleComponent, ConsoleUnlockTechnologyMessage>(OnConsoleUnlock);
|
||||||
@@ -18,6 +21,7 @@ public sealed partial class ResearchSystem
|
|||||||
SubscribeLocalEvent<ResearchConsoleComponent, ResearchServerPointsChangedEvent>(OnPointsChanged);
|
SubscribeLocalEvent<ResearchConsoleComponent, ResearchServerPointsChangedEvent>(OnPointsChanged);
|
||||||
SubscribeLocalEvent<ResearchConsoleComponent, ResearchRegistrationChangedEvent>(OnConsoleRegistrationChanged);
|
SubscribeLocalEvent<ResearchConsoleComponent, ResearchRegistrationChangedEvent>(OnConsoleRegistrationChanged);
|
||||||
SubscribeLocalEvent<ResearchConsoleComponent, TechnologyDatabaseModifiedEvent>(OnConsoleDatabaseModified);
|
SubscribeLocalEvent<ResearchConsoleComponent, TechnologyDatabaseModifiedEvent>(OnConsoleDatabaseModified);
|
||||||
|
SubscribeLocalEvent<ResearchConsoleComponent, GotEmaggedEvent>(OnEmagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnConsoleUnlock(EntityUid uid, ResearchConsoleComponent component, ConsoleUnlockTechnologyMessage args)
|
private void OnConsoleUnlock(EntityUid uid, ResearchConsoleComponent component, ConsoleUnlockTechnologyMessage args)
|
||||||
@@ -39,7 +43,7 @@ public sealed partial class ResearchSystem
|
|||||||
if (!UnlockTechnology(uid, args.Id, act))
|
if (!UnlockTechnology(uid, args.Id, act))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!HasComp<EmaggedComponent>(uid))
|
if (!_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
{
|
{
|
||||||
var getIdentityEvent = new TryGetIdentityShortInfoEvent(uid, act);
|
var getIdentityEvent = new TryGetIdentityShortInfoEvent(uid, act);
|
||||||
RaiseLocalEvent(getIdentityEvent);
|
RaiseLocalEvent(getIdentityEvent);
|
||||||
@@ -52,7 +56,7 @@ public sealed partial class ResearchSystem
|
|||||||
);
|
);
|
||||||
_radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false);
|
_radio.SendRadioMessage(uid, message, component.AnnouncementChannel, uid, escapeMarkup: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncClientWithServer(uid);
|
SyncClientWithServer(uid);
|
||||||
UpdateConsoleInterface(uid, component);
|
UpdateConsoleInterface(uid, component);
|
||||||
}
|
}
|
||||||
@@ -100,4 +104,15 @@ public sealed partial class ResearchSystem
|
|||||||
UpdateConsoleInterface(uid, component);
|
UpdateConsoleInterface(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnEmagged(Entity<ResearchConsoleComponent> ent, ref GotEmaggedEvent args)
|
||||||
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(ent, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public sealed partial class RevenantSystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly ThrowingSystem _throwing = default!;
|
[Dependency] private readonly ThrowingSystem _throwing = default!;
|
||||||
[Dependency] private readonly EntityStorageSystem _entityStorage = default!;
|
[Dependency] private readonly EntityStorageSystem _entityStorage = default!;
|
||||||
[Dependency] private readonly EmagSystem _emag = default!;
|
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
|
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
|
||||||
[Dependency] private readonly GhostSystem _ghost = default!;
|
[Dependency] private readonly GhostSystem _ghost = default!;
|
||||||
@@ -343,7 +342,8 @@ public sealed partial class RevenantSystem
|
|||||||
_whitelistSystem.IsBlacklistPass(component.MalfunctionBlacklist, ent))
|
_whitelistSystem.IsBlacklistPass(component.MalfunctionBlacklist, ent))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
_emag.DoEmagEffect(uid, ent); //it does not emag itself. adorable.
|
var ev = new GotEmaggedEvent(uid, EmagType.Interaction | EmagType.Access);
|
||||||
|
RaiseLocalEvent(ent, ref ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using Content.Server.DeviceNetwork;
|
|||||||
using Content.Server.DeviceNetwork.Components;
|
using Content.Server.DeviceNetwork.Components;
|
||||||
using Content.Server.DeviceNetwork.Systems;
|
using Content.Server.DeviceNetwork.Systems;
|
||||||
using Content.Server.Explosion.Components;
|
using Content.Server.Explosion.Components;
|
||||||
|
using Content.Shared.Emag.Systems;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.Silicons.Borgs;
|
namespace Content.Server.Silicons.Borgs;
|
||||||
@@ -15,6 +16,8 @@ namespace Content.Server.Silicons.Borgs;
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public sealed partial class BorgSystem
|
public sealed partial class BorgSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
private void InitializeTransponder()
|
private void InitializeTransponder()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<BorgTransponderComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
|
SubscribeLocalEvent<BorgTransponderComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
|
||||||
@@ -127,7 +130,7 @@ public sealed partial class BorgSystem
|
|||||||
|
|
||||||
private bool CheckEmagged(EntityUid uid, string name)
|
private bool CheckEmagged(EntityUid uid, string name)
|
||||||
{
|
{
|
||||||
if (HasComp<EmaggedComponent>(uid))
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
{
|
{
|
||||||
Popup.PopupEntity(Loc.GetString($"borg-transponder-emagged-{name}-popup"), uid, uid, PopupType.LargeCaution);
|
Popup.PopupEntity(Loc.GetString($"borg-transponder-emagged-{name}-popup"), uid, uid, PopupType.LargeCaution);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using Content.Server.Roles;
|
|||||||
using Content.Server.Station.Systems;
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Content.Shared.Chat;
|
using Content.Shared.Chat;
|
||||||
using Content.Shared.Emag.Components;
|
|
||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Content.Shared.Mind;
|
using Content.Shared.Mind;
|
||||||
@@ -14,7 +13,6 @@ using Content.Shared.Mind.Components;
|
|||||||
using Content.Shared.Roles;
|
using Content.Shared.Roles;
|
||||||
using Content.Shared.Silicons.Laws;
|
using Content.Shared.Silicons.Laws;
|
||||||
using Content.Shared.Silicons.Laws.Components;
|
using Content.Shared.Silicons.Laws.Components;
|
||||||
using Content.Shared.Stunnable;
|
|
||||||
using Content.Shared.Wires;
|
using Content.Shared.Wires;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
@@ -22,7 +20,6 @@ using Robust.Shared.Containers;
|
|||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Toolshed;
|
using Robust.Shared.Toolshed;
|
||||||
using Robust.Shared.Audio;
|
|
||||||
|
|
||||||
namespace Content.Server.Silicons.Laws;
|
namespace Content.Server.Silicons.Laws;
|
||||||
|
|
||||||
@@ -34,8 +31,8 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
[Dependency] private readonly SharedRoleSystem _roles = default!;
|
[Dependency] private readonly SharedRoleSystem _roles = default!;
|
||||||
[Dependency] private readonly StationSystem _station = default!;
|
[Dependency] private readonly StationSystem _station = default!;
|
||||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
|
||||||
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
@@ -52,7 +49,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
SubscribeLocalEvent<SiliconLawProviderComponent, IonStormLawsEvent>(OnIonStormLaws);
|
SubscribeLocalEvent<SiliconLawProviderComponent, IonStormLawsEvent>(OnIonStormLaws);
|
||||||
SubscribeLocalEvent<SiliconLawProviderComponent, MindAddedMessage>(OnLawProviderMindAdded);
|
SubscribeLocalEvent<SiliconLawProviderComponent, MindAddedMessage>(OnLawProviderMindAdded);
|
||||||
SubscribeLocalEvent<SiliconLawProviderComponent, MindRemovedMessage>(OnLawProviderMindRemoved);
|
SubscribeLocalEvent<SiliconLawProviderComponent, MindRemovedMessage>(OnLawProviderMindRemoved);
|
||||||
SubscribeLocalEvent<SiliconLawProviderComponent, GotEmaggedEvent>(OnEmagLawsAdded);
|
SubscribeLocalEvent<SiliconLawProviderComponent, SiliconEmaggedEvent>(OnEmagLawsAdded);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapInit(EntityUid uid, SiliconLawBoundComponent component, MapInitEvent args)
|
private void OnMapInit(EntityUid uid, SiliconLawBoundComponent component, MapInitEvent args)
|
||||||
@@ -135,7 +132,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
private void OnIonStormLaws(EntityUid uid, SiliconLawProviderComponent component, ref IonStormLawsEvent args)
|
private void OnIonStormLaws(EntityUid uid, SiliconLawProviderComponent component, ref IonStormLawsEvent args)
|
||||||
{
|
{
|
||||||
// Emagged borgs are immune to ion storm
|
// Emagged borgs are immune to ion storm
|
||||||
if (!HasComp<EmaggedComponent>(uid))
|
if (!_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
{
|
{
|
||||||
component.Lawset = args.Lawset;
|
component.Lawset = args.Lawset;
|
||||||
|
|
||||||
@@ -152,9 +149,8 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEmagLawsAdded(EntityUid uid, SiliconLawProviderComponent component, ref GotEmaggedEvent args)
|
private void OnEmagLawsAdded(EntityUid uid, SiliconLawProviderComponent component, ref SiliconEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (component.Lawset == null)
|
if (component.Lawset == null)
|
||||||
component.Lawset = GetLawset(component.Laws);
|
component.Lawset = GetLawset(component.Laws);
|
||||||
|
|
||||||
@@ -164,7 +160,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
// Add the first emag law before the others
|
// Add the first emag law before the others
|
||||||
component.Lawset?.Laws.Insert(0, new SiliconLaw
|
component.Lawset?.Laws.Insert(0, new SiliconLaw
|
||||||
{
|
{
|
||||||
LawString = Loc.GetString("law-emag-custom", ("name", Name(args.UserUid)), ("title", Loc.GetString(component.Lawset.ObeysTo))),
|
LawString = Loc.GetString("law-emag-custom", ("name", Name(args.user)), ("title", Loc.GetString(component.Lawset.ObeysTo))),
|
||||||
Order = 0
|
Order = 0
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -176,20 +172,6 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnGotEmagged(EntityUid uid, EmagSiliconLawComponent component, ref GotEmaggedEvent args)
|
|
||||||
{
|
|
||||||
if (component.RequireOpenPanel && TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
|
|
||||||
return;
|
|
||||||
|
|
||||||
base.OnGotEmagged(uid, component, ref args);
|
|
||||||
NotifyLawsChanged(uid, component.EmaggedSound);
|
|
||||||
if(_mind.TryGetMind(uid, out var mindId, out _))
|
|
||||||
EnsureSubvertedSiliconRole(mindId);
|
|
||||||
|
|
||||||
_stunSystem.TryParalyze(uid, component.StunTime, true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureSubvertedSiliconRole(EntityUid mindId)
|
private void EnsureSubvertedSiliconRole(EntityUid mindId)
|
||||||
{
|
{
|
||||||
if (!_roles.MindHasRole<SubvertedSiliconRoleComponent>(mindId))
|
if (!_roles.MindHasRole<SubvertedSiliconRoleComponent>(mindId))
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace Content.Server.VendingMachines
|
|||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
[Dependency] private readonly SpeakOnUIClosedSystem _speakOnUIClosed = default!;
|
[Dependency] private readonly SpeakOnUIClosedSystem _speakOnUIClosed = default!;
|
||||||
[Dependency] private readonly SharedPointLightSystem _light = default!;
|
[Dependency] private readonly SharedPointLightSystem _light = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
private const float WallVendEjectDistanceFromWall = 1f;
|
private const float WallVendEjectDistanceFromWall = 1f;
|
||||||
|
|
||||||
@@ -48,7 +49,6 @@ namespace Content.Server.VendingMachines
|
|||||||
|
|
||||||
SubscribeLocalEvent<VendingMachineComponent, PowerChangedEvent>(OnPowerChanged);
|
SubscribeLocalEvent<VendingMachineComponent, PowerChangedEvent>(OnPowerChanged);
|
||||||
SubscribeLocalEvent<VendingMachineComponent, BreakageEventArgs>(OnBreak);
|
SubscribeLocalEvent<VendingMachineComponent, BreakageEventArgs>(OnBreak);
|
||||||
SubscribeLocalEvent<VendingMachineComponent, GotEmaggedEvent>(OnEmagged);
|
|
||||||
SubscribeLocalEvent<VendingMachineComponent, DamageChangedEvent>(OnDamageChanged);
|
SubscribeLocalEvent<VendingMachineComponent, DamageChangedEvent>(OnDamageChanged);
|
||||||
SubscribeLocalEvent<VendingMachineComponent, PriceCalculationEvent>(OnVendingPrice);
|
SubscribeLocalEvent<VendingMachineComponent, PriceCalculationEvent>(OnVendingPrice);
|
||||||
SubscribeLocalEvent<VendingMachineComponent, EmpPulseEvent>(OnEmpPulse);
|
SubscribeLocalEvent<VendingMachineComponent, EmpPulseEvent>(OnEmpPulse);
|
||||||
@@ -123,12 +123,6 @@ namespace Content.Server.VendingMachines
|
|||||||
TryUpdateVisualState(uid, vendComponent);
|
TryUpdateVisualState(uid, vendComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEmagged(EntityUid uid, VendingMachineComponent component, ref GotEmaggedEvent args)
|
|
||||||
{
|
|
||||||
// only emag if there are emag-only items
|
|
||||||
args.Handled = component.EmaggedInventory.Count > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDamageChanged(EntityUid uid, VendingMachineComponent component, DamageChangedEvent args)
|
private void OnDamageChanged(EntityUid uid, VendingMachineComponent component, DamageChangedEvent args)
|
||||||
{
|
{
|
||||||
if (!args.DamageIncreased && component.Broken)
|
if (!args.DamageIncreased && component.Broken)
|
||||||
@@ -232,7 +226,7 @@ namespace Content.Server.VendingMachines
|
|||||||
if (!TryComp<AccessReaderComponent>(uid, out var accessReader))
|
if (!TryComp<AccessReaderComponent>(uid, out var accessReader))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (_accessReader.IsAllowed(sender, uid, accessReader) || HasComp<EmaggedComponent>(uid))
|
if (_accessReader.IsAllowed(sender, uid, accessReader))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Popup.PopupEntity(Loc.GetString("vending-machine-component-try-eject-access-denied"), uid);
|
Popup.PopupEntity(Loc.GetString("vending-machine-component-try-eject-access-denied"), uid);
|
||||||
@@ -422,7 +416,7 @@ namespace Content.Server.VendingMachines
|
|||||||
if (!Resolve(uid, ref component))
|
if (!Resolve(uid, ref component))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (type == InventoryType.Emagged && HasComp<EmaggedComponent>(uid))
|
if (type == InventoryType.Emagged && _emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
return component.EmaggedInventory.GetValueOrDefault(entryId);
|
return component.EmaggedInventory.GetValueOrDefault(entryId);
|
||||||
|
|
||||||
if (type == InventoryType.Contraband && component.Contraband)
|
if (type == InventoryType.Contraband && component.Contraband)
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public sealed partial class AccessReaderComponent : Component
|
|||||||
/// Whether or not emag interactions have an effect on this.
|
/// Whether or not emag interactions have an effect on this.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public bool BreakOnEmag = true;
|
public bool BreakOnAccessBreaker = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataDefinition, Serializable, NetSerializable]
|
[DataDefinition, Serializable, NetSerializable]
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Shared.Access.Components;
|
using Content.Shared.Access.Components;
|
||||||
using Content.Shared.DeviceLinking.Events;
|
using Content.Shared.DeviceLinking.Events;
|
||||||
using Content.Shared.Emag.Components;
|
|
||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Hands.EntitySystems;
|
using Content.Shared.Hands.EntitySystems;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
@@ -24,6 +23,7 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly SharedGameTicker _gameTicker = default!;
|
[Dependency] private readonly SharedGameTicker _gameTicker = default!;
|
||||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||||
@@ -71,17 +71,28 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
if (args.User == null) // AutoLink (and presumably future external linkers) have no user.
|
if (args.User == null) // AutoLink (and presumably future external linkers) have no user.
|
||||||
return;
|
return;
|
||||||
if (!HasComp<EmaggedComponent>(uid) && !IsAllowed(args.User.Value, uid, component))
|
if (!IsAllowed(args.User.Value, uid, component))
|
||||||
args.Cancel();
|
args.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEmagged(EntityUid uid, AccessReaderComponent reader, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, AccessReaderComponent reader, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
if (!reader.BreakOnEmag)
|
if (!_emag.CompareFlag(args.Type, EmagType.Access))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!reader.BreakOnAccessBreaker)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!GetMainAccessReader(uid, out var accessReader))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (accessReader.Value.Comp.AccessLists.Count < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Repeatable = true;
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
reader.Enabled = false;
|
accessReader.Value.Comp.AccessLists.Clear();
|
||||||
reader.AccessLog.Clear();
|
accessReader.Value.Comp.AccessLog.Clear();
|
||||||
Dirty(uid, reader);
|
Dirty(uid, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +146,7 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,3 +45,6 @@ namespace Content.Shared.Access.Systems
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ByRefEvent]
|
||||||
|
public record struct OnAccessOverriderAccessUpdatedEvent(EntityUid UserUid, bool Handled = false);
|
||||||
|
|||||||
@@ -46,15 +46,6 @@ public sealed partial class CloningPodComponent : Component
|
|||||||
[DataField("mobSpawnId"), ViewVariables(VVAccess.ReadWrite)]
|
[DataField("mobSpawnId"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public EntProtoId MobSpawnId = "MobAbomination";
|
public EntProtoId MobSpawnId = "MobAbomination";
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Emag sound effects.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("sparkSound")]
|
|
||||||
public SoundSpecifier SparkSound = new SoundCollectionSpecifier("sparks")
|
|
||||||
{
|
|
||||||
Params = AudioParams.Default.WithVolume(8),
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Remove this from here when cloning and/or zombies are refactored
|
// TODO: Remove this from here when cloning and/or zombies are refactored
|
||||||
[DataField("screamSound")]
|
[DataField("screamSound")]
|
||||||
public SoundSpecifier ScreamSound = new SoundCollectionSpecifier("ZombieScreams")
|
public SoundSpecifier ScreamSound = new SoundCollectionSpecifier("ZombieScreams")
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public sealed partial class DisposalDoAfterEvent : SimpleDoAfterEvent
|
|||||||
public abstract class SharedDisposalUnitSystem : EntitySystem
|
public abstract class SharedDisposalUnitSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] protected readonly IGameTiming GameTiming = default!;
|
[Dependency] protected readonly IGameTiming GameTiming = default!;
|
||||||
|
[Dependency] protected readonly EmagSystem _emag = default!;
|
||||||
[Dependency] protected readonly MetaDataSystem Metadata = default!;
|
[Dependency] protected readonly MetaDataSystem Metadata = default!;
|
||||||
[Dependency] protected readonly SharedJointSystem Joints = default!;
|
[Dependency] protected readonly SharedJointSystem Joints = default!;
|
||||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||||
@@ -102,6 +103,12 @@ public abstract class SharedDisposalUnitSystem : EntitySystem
|
|||||||
|
|
||||||
protected void OnEmagged(EntityUid uid, SharedDisposalUnitComponent component, ref GotEmaggedEvent args)
|
protected void OnEmagged(EntityUid uid, SharedDisposalUnitComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (component.DisablePressure == true)
|
||||||
|
return;
|
||||||
|
|
||||||
component.DisablePressure = true;
|
component.DisablePressure = true;
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public abstract partial class SharedDoorSystem : EntitySystem
|
|||||||
[Dependency] private readonly INetManager _net = default!;
|
[Dependency] private readonly INetManager _net = default!;
|
||||||
[Dependency] protected readonly SharedPhysicsSystem PhysicsSystem = default!;
|
[Dependency] protected readonly SharedPhysicsSystem PhysicsSystem = default!;
|
||||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||||
[Dependency] protected readonly TagSystem Tags = default!;
|
[Dependency] protected readonly TagSystem Tags = default!;
|
||||||
[Dependency] protected readonly SharedAudioSystem Audio = default!;
|
[Dependency] protected readonly SharedAudioSystem Audio = default!;
|
||||||
@@ -77,8 +78,6 @@ public abstract partial class SharedDoorSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<DoorComponent, WeldableAttemptEvent>(OnWeldAttempt);
|
SubscribeLocalEvent<DoorComponent, WeldableAttemptEvent>(OnWeldAttempt);
|
||||||
SubscribeLocalEvent<DoorComponent, WeldableChangedEvent>(OnWeldChanged);
|
SubscribeLocalEvent<DoorComponent, WeldableChangedEvent>(OnWeldChanged);
|
||||||
SubscribeLocalEvent<DoorComponent, GetPryTimeModifierEvent>(OnPryTimeModifier);
|
SubscribeLocalEvent<DoorComponent, GetPryTimeModifierEvent>(OnPryTimeModifier);
|
||||||
|
|
||||||
SubscribeLocalEvent<DoorComponent, OnAttemptEmagEvent>(OnAttemptEmag);
|
|
||||||
SubscribeLocalEvent<DoorComponent, GotEmaggedEvent>(OnEmagged);
|
SubscribeLocalEvent<DoorComponent, GotEmaggedEvent>(OnEmagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,31 +117,24 @@ public abstract partial class SharedDoorSystem : EntitySystem
|
|||||||
_activeDoors.Remove(door);
|
_activeDoors.Remove(door);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAttemptEmag(EntityUid uid, DoorComponent door, ref OnAttemptEmagEvent args)
|
|
||||||
{
|
|
||||||
if (!TryComp<AirlockComponent>(uid, out var airlock))
|
|
||||||
{
|
|
||||||
args.Handled = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsBolted(uid) || !airlock.Powered)
|
|
||||||
{
|
|
||||||
args.Handled = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (door.State != DoorState.Closed)
|
|
||||||
{
|
|
||||||
args.Handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEmagged(EntityUid uid, DoorComponent door, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, DoorComponent door, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Access))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<AirlockComponent>(uid, out var airlock))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (IsBolted(uid) || !airlock.Powered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (door.State != DoorState.Closed)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!SetState(uid, DoorState.Emagging, door))
|
if (!SetState(uid, DoorState.Emagging, door))
|
||||||
return;
|
return;
|
||||||
Audio.PlayPredicted(door.SparkSound, uid, args.UserUid, AudioParams.Default.WithVolume(8));
|
|
||||||
|
args.Repeatable = true;
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
@@ -14,7 +16,21 @@ public sealed partial class EmagComponent : Component
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The tag that marks an entity as immune to emags
|
/// The tag that marks an entity as immune to emags
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("emagImmuneTag", customTypeSerializer: typeof(PrototypeIdSerializer<TagPrototype>)), ViewVariables(VVAccess.ReadWrite)]
|
[DataField]
|
||||||
[AutoNetworkedField]
|
[AutoNetworkedField]
|
||||||
public string EmagImmuneTag = "EmagImmune";
|
public ProtoId<TagPrototype> EmagImmuneTag = "EmagImmune";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What type of emag effect this device will do
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
[AutoNetworkedField]
|
||||||
|
public EmagType EmagType = EmagType.Interaction;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What sound should the emag play when used
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
[AutoNetworkedField]
|
||||||
|
public SoundSpecifier EmagSound = new SoundCollectionSpecifier("sparks");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Shared.Emag.Systems;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
namespace Content.Shared.Emag.Components;
|
namespace Content.Shared.Emag.Components;
|
||||||
@@ -5,7 +6,12 @@ namespace Content.Shared.Emag.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marker component for emagged entities
|
/// Marker component for emagged entities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
public sealed partial class EmaggedComponent : Component
|
public sealed partial class EmaggedComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The EmagType flags that were used to emag this device
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public EmagType EmagType = EmagType.None;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ using Content.Shared.Emag.Components;
|
|||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Silicons.Laws.Components;
|
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
|
using Robust.Shared.Audio.Systems;
|
||||||
|
|
||||||
namespace Content.Shared.Emag.Systems;
|
namespace Content.Shared.Emag.Systems;
|
||||||
|
|
||||||
@@ -23,88 +23,123 @@ public sealed class EmagSystem : EntitySystem
|
|||||||
[Dependency] private readonly SharedChargesSystem _charges = default!;
|
[Dependency] private readonly SharedChargesSystem _charges = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
[Dependency] private readonly TagSystem _tag = default!;
|
[Dependency] private readonly TagSystem _tag = default!;
|
||||||
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<EmagComponent, AfterInteractEvent>(OnAfterInteract);
|
SubscribeLocalEvent<EmagComponent, AfterInteractEvent>(OnAfterInteract);
|
||||||
|
SubscribeLocalEvent<EmaggedComponent, OnAccessOverriderAccessUpdatedEvent>(OnAccessOverriderAccessUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnAccessOverriderAccessUpdated(Entity<EmaggedComponent> entity, ref OnAccessOverriderAccessUpdatedEvent args)
|
||||||
|
{
|
||||||
|
if (!CompareFlag(entity.Comp.EmagType, EmagType.Access))
|
||||||
|
return;
|
||||||
|
|
||||||
|
entity.Comp.EmagType &= ~EmagType.Access;
|
||||||
|
Dirty(entity);
|
||||||
|
}
|
||||||
private void OnAfterInteract(EntityUid uid, EmagComponent comp, AfterInteractEvent args)
|
private void OnAfterInteract(EntityUid uid, EmagComponent comp, AfterInteractEvent args)
|
||||||
{
|
{
|
||||||
if (!args.CanReach || args.Target is not { } target)
|
if (!args.CanReach || args.Target is not { } target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Handled = TryUseEmag(uid, args.User, target, comp);
|
args.Handled = TryEmagEffect((uid, comp), args.User, target);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to use the emag on a target entity
|
|
||||||
/// </summary>
|
|
||||||
public bool TryUseEmag(EntityUid uid, EntityUid user, EntityUid target, EmagComponent? comp = null)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref comp, false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (_tag.HasTag(target, comp.EmagImmuneTag))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TryComp<LimitedChargesComponent>(uid, out var charges);
|
|
||||||
if (_charges.IsEmpty(uid, charges))
|
|
||||||
{
|
|
||||||
_popup.PopupClient(Loc.GetString("emag-no-charges"), user, user);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var handled = DoEmagEffect(user, target);
|
|
||||||
if (!handled)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
_popup.PopupClient(Loc.GetString("emag-success", ("target", Identity.Entity(target, EntityManager))), user,
|
|
||||||
user, PopupType.Medium);
|
|
||||||
|
|
||||||
_adminLogger.Add(LogType.Emag, LogImpact.High, $"{ToPrettyString(user):player} emagged {ToPrettyString(target):target}");
|
|
||||||
|
|
||||||
if (charges != null)
|
|
||||||
_charges.UseCharge(uid, charges);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Does the emag effect on a specified entity
|
/// Does the emag effect on a specified entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DoEmagEffect(EntityUid user, EntityUid target)
|
public bool TryEmagEffect(Entity<EmagComponent?> ent, EntityUid user, EntityUid target)
|
||||||
{
|
{
|
||||||
// prevent emagging twice
|
if (!Resolve(ent, ref ent.Comp, false))
|
||||||
if (HasComp<EmaggedComponent>(target))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var onAttemptEmagEvent = new OnAttemptEmagEvent(user);
|
if (_tag.HasTag(target, ent.Comp.EmagImmuneTag))
|
||||||
RaiseLocalEvent(target, ref onAttemptEmagEvent);
|
|
||||||
|
|
||||||
// prevent emagging if attempt fails
|
|
||||||
if (onAttemptEmagEvent.Handled)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var emaggedEvent = new GotEmaggedEvent(user);
|
TryComp<LimitedChargesComponent>(ent, out var charges);
|
||||||
|
if (_charges.IsEmpty(ent, charges))
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("emag-no-charges"), user, user);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var emaggedEvent = new GotEmaggedEvent(user, ent.Comp.EmagType);
|
||||||
RaiseLocalEvent(target, ref emaggedEvent);
|
RaiseLocalEvent(target, ref emaggedEvent);
|
||||||
|
|
||||||
if (emaggedEvent.Handled && !emaggedEvent.Repeatable)
|
if (!emaggedEvent.Handled)
|
||||||
EnsureComp<EmaggedComponent>(target);
|
return false;
|
||||||
|
|
||||||
|
_popup.PopupPredicted(Loc.GetString("emag-success", ("target", Identity.Entity(target, EntityManager))), user, user, PopupType.Medium);
|
||||||
|
|
||||||
|
_audio.PlayPredicted(ent.Comp.EmagSound, ent, ent);
|
||||||
|
|
||||||
|
_adminLogger.Add(LogType.Emag, LogImpact.High, $"{ToPrettyString(user):player} emagged {ToPrettyString(target):target} with flag(s): {ent.Comp.EmagType}");
|
||||||
|
|
||||||
|
if (charges != null && emaggedEvent.Handled)
|
||||||
|
_charges.UseCharge(ent, charges);
|
||||||
|
|
||||||
|
if (!emaggedEvent.Repeatable)
|
||||||
|
{
|
||||||
|
EnsureComp<EmaggedComponent>(target, out var emaggedComp);
|
||||||
|
|
||||||
|
emaggedComp.EmagType |= ent.Comp.EmagType;
|
||||||
|
Dirty(target, emaggedComp);
|
||||||
|
}
|
||||||
|
|
||||||
return emaggedEvent.Handled;
|
return emaggedEvent.Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether an entity has the EmaggedComponent with a set flag.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">The target entity to check for the flag.</param>
|
||||||
|
/// <param name="flag">The EmagType flag to check for.</param>
|
||||||
|
/// <returns>True if entity has EmaggedComponent and the provided flag. False if the entity lacks EmaggedComponent or provided flag.</returns>
|
||||||
|
public bool CheckFlag(EntityUid target, EmagType flag)
|
||||||
|
{
|
||||||
|
if (!TryComp<EmaggedComponent>(target, out var comp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((comp.EmagType & flag) == flag)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compares a flag to the target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">The target flag to check.</param>
|
||||||
|
/// <param name="flag">The flag to check for within the target.</param>
|
||||||
|
/// <returns>True if target contains flag. Otherwise false.</returns>
|
||||||
|
public bool CompareFlag(EmagType target, EmagType flag)
|
||||||
|
{
|
||||||
|
if ((target & flag) == flag)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum EmagType : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Interaction = 1 << 1,
|
||||||
|
Access = 1 << 2
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows a popup to emag user (client side only!) and adds <see cref="EmaggedComponent"/> to the entity when handled
|
/// Shows a popup to emag user (client side only!) and adds <see cref="EmaggedComponent"/> to the entity when handled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="UserUid">Emag user</param>
|
/// <param name="UserUid">Emag user</param>
|
||||||
|
/// <param name="Type">The emag type to use</param>
|
||||||
/// <param name="Handled">Did the emagging succeed? Causes a user-only popup to show on client side</param>
|
/// <param name="Handled">Did the emagging succeed? Causes a user-only popup to show on client side</param>
|
||||||
/// <param name="Repeatable">Can the entity be emagged more than once? Prevents adding of <see cref="EmaggedComponent"/></param>
|
/// <param name="Repeatable">Can the entity be emagged more than once? Prevents adding of <see cref="EmaggedComponent"/></param>
|
||||||
/// <remarks>Needs to be handled in shared/client, not just the server, to actually show the emagging popup</remarks>
|
/// <remarks>Needs to be handled in shared/client, not just the server, to actually show the emagging popup</remarks>
|
||||||
[ByRefEvent]
|
[ByRefEvent]
|
||||||
public record struct GotEmaggedEvent(EntityUid UserUid, bool Handled = false, bool Repeatable = false);
|
public record struct GotEmaggedEvent(EntityUid UserUid, EmagType Type, bool Handled = false, bool Repeatable = false);
|
||||||
|
|
||||||
[ByRefEvent]
|
|
||||||
public record struct OnAttemptEmagEvent(EntityUid UserUid, bool Handled = false);
|
|
||||||
|
|||||||
@@ -59,12 +59,6 @@ public sealed partial class FaxMachineComponent : Component
|
|||||||
[DataField]
|
[DataField]
|
||||||
public bool ReceiveNukeCodes { get; set; } = false;
|
public bool ReceiveNukeCodes { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sound to play when fax has been emagged
|
|
||||||
/// </summary>
|
|
||||||
[DataField]
|
|
||||||
public SoundSpecifier EmagSound = new SoundCollectionSpecifier("sparks");
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sound to play when fax printing new message
|
/// Sound to play when fax printing new message
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public abstract class SharedLatheSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
[Dependency] private readonly SharedMaterialStorageSystem _materialStorage = default!;
|
[Dependency] private readonly SharedMaterialStorageSystem _materialStorage = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
public readonly Dictionary<string, List<LatheRecipePrototype>> InverseRecipes = new();
|
public readonly Dictionary<string, List<LatheRecipePrototype>> InverseRecipes = new();
|
||||||
|
|
||||||
@@ -66,6 +67,12 @@ public abstract class SharedLatheSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, EmagLatheRecipesComponent component, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, EmagLatheRecipesComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Content.Shared.Actions;
|
|||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Light.Components;
|
using Content.Shared.Light.Components;
|
||||||
using Content.Shared.Mind.Components;
|
using Content.Shared.Mind.Components;
|
||||||
|
using Content.Shared.Storage.Components;
|
||||||
using Content.Shared.Toggleable;
|
using Content.Shared.Toggleable;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
@@ -22,6 +23,7 @@ public sealed class UnpoweredFlashlightSystem : EntitySystem
|
|||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||||
[Dependency] private readonly SharedPointLightSystem _light = default!;
|
[Dependency] private readonly SharedPointLightSystem _light = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -78,6 +80,9 @@ public sealed class UnpoweredFlashlightSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnGotEmagged(EntityUid uid, UnpoweredFlashlightComponent component, ref GotEmaggedEvent args)
|
private void OnGotEmagged(EntityUid uid, UnpoweredFlashlightComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!_light.TryGetLight(uid, out var light))
|
if (!_light.TryGetLight(uid, out var light))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ public sealed partial class LockComponent : Component
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not an emag disables it.
|
/// Whether or not an emag disables it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("breakOnEmag")]
|
[DataField]
|
||||||
[AutoNetworkedField]
|
[AutoNetworkedField]
|
||||||
public bool BreakOnEmag = true;
|
public bool BreakOnAccessBreaker = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Amount of do-after time needed to lock the entity.
|
/// Amount of do-after time needed to lock the entity.
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public sealed class LockSystem : EntitySystem
|
|||||||
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
|
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
|
||||||
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||||
[Dependency] private readonly ActivatableUISystem _activatableUI = default!;
|
[Dependency] private readonly ActivatableUISystem _activatableUI = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _sharedPopupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _sharedPopupSystem = default!;
|
||||||
@@ -295,7 +296,10 @@ public sealed class LockSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, LockComponent component, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, LockComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
if (!component.Locked || !component.BreakOnEmag)
|
if (!_emag.CompareFlag(args.Type, EmagType.Access))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!component.Locked || !component.BreakOnAccessBreaker)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_audio.PlayPredicted(component.UnlockSound, uid, args.UserUid);
|
_audio.PlayPredicted(component.UnlockSound, uid, args.UserUid);
|
||||||
@@ -307,7 +311,7 @@ public sealed class LockSystem : EntitySystem
|
|||||||
var ev = new LockToggledEvent(false);
|
var ev = new LockToggledEvent(false);
|
||||||
RaiseLocalEvent(uid, ref ev, true);
|
RaiseLocalEvent(uid, ref ev, true);
|
||||||
|
|
||||||
RemComp<LockComponent>(uid); //Literally destroys the lock as a tell it was emagged
|
args.Repeatable = true;
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public abstract class SharedMaterialReclaimerSystem : EntitySystem
|
|||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] protected readonly SharedContainerSystem Container = default!;
|
[Dependency] protected readonly SharedContainerSystem Container = default!;
|
||||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
public const string ActiveReclaimerContainerId = "active-material-reclaimer-container";
|
public const string ActiveReclaimerContainerId = "active-material-reclaimer-container";
|
||||||
|
|
||||||
@@ -60,6 +61,12 @@ public abstract class SharedMaterialReclaimerSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, MaterialReclaimerComponent component, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, MaterialReclaimerComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +214,7 @@ public abstract class SharedMaterialReclaimerSystem : EntitySystem
|
|||||||
component.Enabled &&
|
component.Enabled &&
|
||||||
!component.Broken &&
|
!component.Broken &&
|
||||||
HasComp<BodyComponent>(victim) &&
|
HasComp<BodyComponent>(victim) &&
|
||||||
HasComp<EmaggedComponent>(uid);
|
_emag.CheckFlag(uid, EmagType.Interaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public abstract partial class SharedCryoPodSystem: EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
||||||
[Dependency] private readonly StandingStateSystem _standingStateSystem = default!;
|
[Dependency] private readonly StandingStateSystem _standingStateSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||||
@@ -156,9 +157,13 @@ public abstract partial class SharedCryoPodSystem: EntitySystem
|
|||||||
protected void OnEmagged(EntityUid uid, CryoPodComponent? cryoPodComponent, ref GotEmaggedEvent args)
|
protected void OnEmagged(EntityUid uid, CryoPodComponent? cryoPodComponent, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref cryoPodComponent))
|
if (!Resolve(uid, ref cryoPodComponent))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cryoPodComponent.PermaLocked && cryoPodComponent.Locked)
|
||||||
|
return;
|
||||||
|
|
||||||
cryoPodComponent.PermaLocked = true;
|
cryoPodComponent.PermaLocked = true;
|
||||||
cryoPodComponent.Locked = true;
|
cryoPodComponent.Locked = true;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Ninja.Systems;
|
using Content.Shared.Ninja.Systems;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
using Content.Shared.Whitelist;
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
@@ -17,11 +19,23 @@ public sealed partial class EmagProviderComponent : Component
|
|||||||
/// The tag that marks an entity as immune to emagging.
|
/// The tag that marks an entity as immune to emagging.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public ProtoId<TagPrototype> EmagImmuneTag = "EmagImmune";
|
public ProtoId<TagPrototype> AccessBreakerImmuneTag = "AccessBreakerImmune";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whitelist that entities must be on to work.
|
/// Whitelist that entities must be on to work.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public EntityWhitelist? Whitelist;
|
public EntityWhitelist? Whitelist;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What type of emag this will provide.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public EmagType EmagType = EmagType.Access;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What sound should the emag play when used
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public SoundSpecifier EmagSound = new SoundCollectionSpecifier("sparks");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Shared.Interaction;
|
|||||||
using Content.Shared.Ninja.Components;
|
using Content.Shared.Ninja.Components;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
using Content.Shared.Whitelist;
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Audio.Systems;
|
||||||
|
|
||||||
namespace Content.Shared.Ninja.Systems;
|
namespace Content.Shared.Ninja.Systems;
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ namespace Content.Shared.Ninja.Systems;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class EmagProviderSystem : EntitySystem
|
public sealed class EmagProviderSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly EmagSystem _emag = default!;
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
@@ -42,14 +44,18 @@ public sealed class EmagProviderSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// only allowed to emag non-immune entities
|
// only allowed to emag non-immune entities
|
||||||
if (_tag.HasTag(target, comp.EmagImmuneTag))
|
if (_tag.HasTag(target, comp.AccessBreakerImmuneTag))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var handled = _emag.DoEmagEffect(uid, target);
|
var emagEv = new GotEmaggedEvent(uid, EmagType.Access);
|
||||||
if (!handled)
|
RaiseLocalEvent(args.Target, ref emagEv);
|
||||||
|
|
||||||
|
if (!emagEv.Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_adminLogger.Add(LogType.Emag, LogImpact.High, $"{ToPrettyString(uid):player} emagged {ToPrettyString(target):target}");
|
_audio.PlayPredicted(comp.EmagSound, uid, uid);
|
||||||
|
|
||||||
|
_adminLogger.Add(LogType.Emag, LogImpact.High, $"{ToPrettyString(uid):player} emagged {ToPrettyString(target):target} with flag(s): {ent.Comp.EmagType}");
|
||||||
var ev = new EmaggedSomethingEvent(target);
|
var ev = new EmaggedSomethingEvent(target);
|
||||||
RaiseLocalEvent(uid, ref ev);
|
RaiseLocalEvent(uid, ref ev);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
@@ -57,7 +63,7 @@ public sealed class EmagProviderSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised on the player when emagging something.
|
/// Raised on the player when access breaking something.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ByRefEvent]
|
[ByRefEvent]
|
||||||
public record struct EmaggedSomethingEvent(EntityUid Target);
|
public record struct EmaggedSomethingEvent(EntityUid Target);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Content.Shared.Pinpointer;
|
|||||||
public abstract class SharedPinpointerSystem : EntitySystem
|
public abstract class SharedPinpointerSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -137,6 +138,15 @@ public abstract class SharedPinpointerSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, PinpointerComponent component, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, PinpointerComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (component.CanRetarget)
|
||||||
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
component.CanRetarget = true;
|
component.CanRetarget = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,4 @@ public sealed partial class EmaggableMedibotComponent : Component
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
|
[DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public Dictionary<MobState, MedibotTreatment> Replacements = new();
|
public Dictionary<MobState, MedibotTreatment> Replacements = new();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sound to play when the bot has been emagged
|
|
||||||
/// </summary>
|
|
||||||
[DataField]
|
|
||||||
public SoundSpecifier SparkSound = new SoundCollectionSpecifier("sparks")
|
|
||||||
{
|
|
||||||
Params = AudioParams.Default.WithVolume(8f)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Content.Shared.Silicons.Bots;
|
|||||||
public sealed class MedibotSystem : EntitySystem
|
public sealed class MedibotSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
[Dependency] private SharedInteractionSystem _interaction = default!;
|
[Dependency] private SharedInteractionSystem _interaction = default!;
|
||||||
[Dependency] private SharedSolutionContainerSystem _solutionContainer = default!;
|
[Dependency] private SharedSolutionContainerSystem _solutionContainer = default!;
|
||||||
[Dependency] private SharedPopupSystem _popup = default!;
|
[Dependency] private SharedPopupSystem _popup = default!;
|
||||||
@@ -36,10 +37,14 @@ public sealed class MedibotSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, EmaggableMedibotComponent comp, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, EmaggableMedibotComponent comp, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
if (!TryComp<MedibotComponent>(uid, out var medibot))
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_audio.PlayPredicted(comp.SparkSound, uid, args.UserUid);
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<MedibotComponent>(uid, out var medibot))
|
||||||
|
return;
|
||||||
|
|
||||||
foreach (var (state, treatment) in comp.Replacements)
|
foreach (var (state, treatment) in comp.Replacements)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
|
using Content.Shared.Mind;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Silicons.Laws.Components;
|
using Content.Shared.Silicons.Laws.Components;
|
||||||
|
using Content.Shared.Stunnable;
|
||||||
using Content.Shared.Wires;
|
using Content.Shared.Wires;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
|
||||||
namespace Content.Shared.Silicons.Laws;
|
namespace Content.Shared.Silicons.Laws;
|
||||||
|
|
||||||
@@ -11,22 +14,29 @@ namespace Content.Shared.Silicons.Laws;
|
|||||||
public abstract partial class SharedSiliconLawSystem : EntitySystem
|
public abstract partial class SharedSiliconLawSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
InitializeUpdater();
|
InitializeUpdater();
|
||||||
SubscribeLocalEvent<EmagSiliconLawComponent, GotEmaggedEvent>(OnGotEmagged);
|
SubscribeLocalEvent<EmagSiliconLawComponent, GotEmaggedEvent>(OnGotEmagged);
|
||||||
SubscribeLocalEvent<EmagSiliconLawComponent, OnAttemptEmagEvent>(OnAttemptEmag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnAttemptEmag(EntityUid uid, EmagSiliconLawComponent component, ref OnAttemptEmagEvent args)
|
private void OnGotEmagged(EntityUid uid, EmagSiliconLawComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
//prevent self emagging
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// prevent self-emagging
|
||||||
if (uid == args.UserUid)
|
if (uid == args.UserUid)
|
||||||
{
|
{
|
||||||
_popup.PopupClient(Loc.GetString("law-emag-cannot-emag-self"), uid, args.UserUid);
|
_popup.PopupClient(Loc.GetString("law-emag-cannot-emag-self"), uid, args.UserUid);
|
||||||
args.Handled = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,14 +45,33 @@ public abstract partial class SharedSiliconLawSystem : EntitySystem
|
|||||||
!panel.Open)
|
!panel.Open)
|
||||||
{
|
{
|
||||||
_popup.PopupClient(Loc.GetString("law-emag-require-panel"), uid, args.UserUid);
|
_popup.PopupClient(Loc.GetString("law-emag-require-panel"), uid, args.UserUid);
|
||||||
args.Handled = true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
var ev = new SiliconEmaggedEvent(args.UserUid);
|
||||||
|
RaiseLocalEvent(uid, ref ev);
|
||||||
|
|
||||||
protected virtual void OnGotEmagged(EntityUid uid, EmagSiliconLawComponent component, ref GotEmaggedEvent args)
|
|
||||||
{
|
|
||||||
component.OwnerName = Name(args.UserUid);
|
component.OwnerName = Name(args.UserUid);
|
||||||
|
|
||||||
|
NotifyLawsChanged(uid, component.EmaggedSound);
|
||||||
|
if(_mind.TryGetMind(uid, out var mindId, out _))
|
||||||
|
EnsureSubvertedSiliconRole(mindId);
|
||||||
|
|
||||||
|
_stunSystem.TryParalyze(uid, component.StunTime, true);
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void NotifyLawsChanged(EntityUid uid, SoundSpecifier? cue = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void EnsureSubvertedSiliconRole(EntityUid mindId)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ByRefEvent]
|
||||||
|
public record struct SiliconEmaggedEvent(EntityUid user);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public abstract class SharedSingularityGeneratorSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
#region Dependencies
|
#region Dependencies
|
||||||
[Dependency] protected readonly SharedPopupSystem PopupSystem = default!;
|
[Dependency] protected readonly SharedPopupSystem PopupSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
#endregion Dependencies
|
#endregion Dependencies
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
@@ -22,7 +23,16 @@ public abstract class SharedSingularityGeneratorSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(EntityUid uid, SingularityGeneratorComponent component, ref GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, SingularityGeneratorComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (component.FailsafeDisabled)
|
||||||
|
return;
|
||||||
|
|
||||||
component.FailsafeDisabled = true;
|
component.FailsafeDisabled = true;
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Content.Shared.Emag.Components;
|
|||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Shared.DoAfter;
|
using Content.Shared.DoAfter;
|
||||||
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
@@ -19,11 +20,14 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem
|
|||||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||||
[Dependency] protected readonly SharedPopupSystem Popup = default!;
|
[Dependency] protected readonly SharedPopupSystem Popup = default!;
|
||||||
[Dependency] protected readonly IRobustRandom Randomizer = default!;
|
[Dependency] protected readonly IRobustRandom Randomizer = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<VendingMachineComponent, MapInitEvent>(OnMapInit);
|
SubscribeLocalEvent<VendingMachineComponent, MapInitEvent>(OnMapInit);
|
||||||
|
SubscribeLocalEvent<VendingMachineComponent, GotEmaggedEvent>(OnEmagged);
|
||||||
|
|
||||||
SubscribeLocalEvent<VendingMachineRestockComponent, AfterInteractEvent>(OnAfterInteract);
|
SubscribeLocalEvent<VendingMachineRestockComponent, AfterInteractEvent>(OnAfterInteract);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,9 +53,21 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem
|
|||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnEmagged(EntityUid uid, VendingMachineComponent component, ref GotEmaggedEvent args)
|
||||||
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// only emag if there are emag-only items
|
||||||
|
args.Handled = component.EmaggedInventory.Count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns all of the vending machine's inventory. Only includes emagged and contraband inventories if
|
/// Returns all of the vending machine's inventory. Only includes emagged and contraband inventories if
|
||||||
/// <see cref="EmaggedComponent"/> exists and <see cref="VendingMachineComponent.Contraband"/> is true
|
/// <see cref="EmaggedComponent"/> with the EmagType.Interaction flag exists and <see cref="VendingMachineComponent.Contraband"/> is true
|
||||||
/// are <c>true</c> respectively.
|
/// are <c>true</c> respectively.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uid"></param>
|
/// <param name="uid"></param>
|
||||||
@@ -64,7 +80,7 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem
|
|||||||
|
|
||||||
var inventory = new List<VendingMachineInventoryEntry>(component.Inventory.Values);
|
var inventory = new List<VendingMachineInventoryEntry>(component.Inventory.Values);
|
||||||
|
|
||||||
if (HasComp<EmaggedComponent>(uid))
|
if (_emag.CheckFlag(uid, EmagType.Interaction))
|
||||||
inventory.AddRange(component.EmaggedInventory.Values);
|
inventory.AddRange(component.EmaggedInventory.Values);
|
||||||
|
|
||||||
if (component.Contraband)
|
if (component.Contraband)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public abstract class SharedArtifactCrusherSystem : EntitySystem
|
|||||||
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
|
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
|
||||||
[Dependency] protected readonly SharedAudioSystem AudioSystem = default!;
|
[Dependency] protected readonly SharedAudioSystem AudioSystem = default!;
|
||||||
[Dependency] protected readonly SharedContainerSystem ContainerSystem = default!;
|
[Dependency] protected readonly SharedContainerSystem ContainerSystem = default!;
|
||||||
|
[Dependency] private readonly EmagSystem _emag = default!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
@@ -40,6 +41,15 @@ public abstract class SharedArtifactCrusherSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmagged(Entity<ArtifactCrusherComponent> ent, ref GotEmaggedEvent args)
|
private void OnEmagged(Entity<ArtifactCrusherComponent> ent, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_emag.CheckFlag(ent, EmagType.Interaction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ent.Comp.AutoLock)
|
||||||
|
return;
|
||||||
|
|
||||||
ent.Comp.AutoLock = true;
|
ent.Comp.AutoLock = true;
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
emag-success = The card zaps something in {THE($target)}.
|
emag-success = The device zaps something in {THE($target)}.
|
||||||
emag-no-charges = No charges left!
|
emag-no-charges = No charges left!
|
||||||
|
|||||||
@@ -113,7 +113,10 @@ uplink-chest-rig-name = Chest Rig
|
|||||||
uplink-chest-rig-desc = Explosion-resistant tactical webbing used for holding traitor goods.
|
uplink-chest-rig-desc = Explosion-resistant tactical webbing used for holding traitor goods.
|
||||||
|
|
||||||
uplink-emag-name = Emag
|
uplink-emag-name = Emag
|
||||||
uplink-emag-desc = The business card of the syndicate, this sequencer is able to break open airlocks and tamper with a variety of station devices. Recharges automatically.
|
uplink-emag-desc = The business card of the syndicate, this sequencer is able to tamper with a variety of station devices. Recharges automatically.
|
||||||
|
|
||||||
|
uplink-access-breaker-name = Access Breaker
|
||||||
|
uplink-access-breaker-desc = A hacked access configurator and a good friend of the emag. This device is able to force airlocks open as well as erase access requirements from station equipment. Recharges automatically.
|
||||||
|
|
||||||
uplink-agent-id-card-name = Agent ID Card
|
uplink-agent-id-card-name = Agent ID Card
|
||||||
uplink-agent-id-card-desc = A modified ID card that can copy accesses from other cards and change its name and job title at-will.
|
uplink-agent-id-card-desc = A modified ID card that can copy accesses from other cards and change its name and job title at-will.
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ thief-backpack-category-syndie-name = syndie kit
|
|||||||
thief-backpack-category-syndie-description =
|
thief-backpack-category-syndie-description =
|
||||||
Trinkets from a disavowed past, or stolen from a careless agent?
|
Trinkets from a disavowed past, or stolen from a careless agent?
|
||||||
You've made some connections. Whiskey, echo...
|
You've made some connections. Whiskey, echo...
|
||||||
Includes: An Emag, Interdyne cigs, a Syndicate codeword,
|
Includes: An Emag, Access Breaker, Interdyne cigs, a Syndicate codeword,
|
||||||
a Radio Jammer, a lighter and some strange red crystals.
|
a Radio Jammer, a lighter and some strange red crystals.
|
||||||
|
|
||||||
thief-backpack-category-sleeper-name = sleeper kit
|
thief-backpack-category-sleeper-name = sleeper kit
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
- RadioJammer
|
- RadioJammer
|
||||||
- TraitorCodePaper
|
- TraitorCodePaper
|
||||||
- Emag
|
- Emag
|
||||||
|
- AccessBreaker
|
||||||
- Lighter
|
- Lighter
|
||||||
- CigPackSyndicate
|
- CigPackSyndicate
|
||||||
- Telecrystal10 #The thief cannot use them, but it may induce communication with traitors
|
- Telecrystal10 #The thief cannot use them, but it may induce communication with traitors
|
||||||
|
|||||||
@@ -865,16 +865,29 @@
|
|||||||
|
|
||||||
# Disruption
|
# Disruption
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: UplinkAccessBreaker
|
||||||
|
name: uplink-access-breaker-name
|
||||||
|
description: uplink-access-breaker-desc
|
||||||
|
productEntity: AccessBreaker
|
||||||
|
discountCategory: veryRareDiscounts
|
||||||
|
discountDownTo:
|
||||||
|
Telecrystal: 3
|
||||||
|
cost:
|
||||||
|
Telecrystal: 5
|
||||||
|
categories:
|
||||||
|
- UplinkDisruption
|
||||||
|
|
||||||
- type: listing
|
- type: listing
|
||||||
id: UplinkEmag
|
id: UplinkEmag
|
||||||
name: uplink-emag-name
|
name: uplink-emag-name
|
||||||
description: uplink-emag-desc
|
description: uplink-emag-desc
|
||||||
productEntity: Emag
|
productEntity: Emag
|
||||||
discountCategory: veryRareDiscounts
|
discountCategory: rareDiscounts
|
||||||
discountDownTo:
|
discountDownTo:
|
||||||
Telecrystal: 5
|
Telecrystal: 2
|
||||||
cost:
|
cost:
|
||||||
Telecrystal: 8
|
Telecrystal: 4
|
||||||
categories:
|
categories:
|
||||||
- UplinkDisruption
|
- UplinkDisruption
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,6 @@
|
|||||||
- cell_slot
|
- cell_slot
|
||||||
- type: Lock
|
- type: Lock
|
||||||
locked: true
|
locked: true
|
||||||
breakOnEmag: false
|
|
||||||
unlockOnClick: false
|
unlockOnClick: false
|
||||||
- type: ActivatableUIRequiresLock
|
- type: ActivatableUIRequiresLock
|
||||||
- type: LockedWiresPanel
|
- type: LockedWiresPanel
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
- type: Appearance
|
- type: Appearance
|
||||||
- type: AccessReader
|
- type: AccessReader
|
||||||
access: [ [ "CentralCommand" ] ]
|
access: [ [ "CentralCommand" ] ]
|
||||||
breakOnEmag: false
|
breakOnAccessBreaker: false
|
||||||
- type: Lock
|
- type: Lock
|
||||||
lockOnClick: false
|
lockOnClick: false
|
||||||
breakOnEmag: false
|
breakOnAccessBreaker: false
|
||||||
- type: EntityStorage
|
- type: EntityStorage
|
||||||
capacity: 1 # Its smol.
|
capacity: 1 # Its smol.
|
||||||
itemCanStoreMobs: false # just leaving this here explicitly since I know at some point someone will want to use this to hold a mob. This also prevents it from becoming His Grace.
|
itemCanStoreMobs: false # just leaving this here explicitly since I know at some point someone will want to use this to hold a mob. This also prevents it from becoming His Grace.
|
||||||
|
|||||||
@@ -570,7 +570,7 @@
|
|||||||
id: BorgModuleOperative
|
id: BorgModuleOperative
|
||||||
parent: [ BaseBorgModuleSyndicate, BaseProviderBorgModule, BaseSyndicateContraband ]
|
parent: [ BaseBorgModuleSyndicate, BaseProviderBorgModule, BaseSyndicateContraband ]
|
||||||
name: operative cyborg module
|
name: operative cyborg module
|
||||||
description: A module that comes with a crowbar, an Emag and a syndicate pinpointer.
|
description: A module that comes with a crowbar, an Emag, an Access Breaker and a syndicate pinpointer.
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
layers:
|
layers:
|
||||||
@@ -580,6 +580,7 @@
|
|||||||
items:
|
items:
|
||||||
- Crowbar
|
- Crowbar
|
||||||
- Emag
|
- Emag
|
||||||
|
- AccessBreaker
|
||||||
- PinpointerSyndicateNuclear
|
- PinpointerSyndicateNuclear
|
||||||
- type: BorgModuleIcon
|
- type: BorgModuleIcon
|
||||||
icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-operative-module }
|
icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-operative-module }
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
- type: entity
|
||||||
|
parent: [BaseItem, BaseSyndicateContraband]
|
||||||
|
id: AccessBreakerUnlimited
|
||||||
|
suffix: Unlimited
|
||||||
|
name: authentication disruptor
|
||||||
|
description: A hacked access configurator, specialized to unlock and erase access from digital locks.
|
||||||
|
components:
|
||||||
|
- type: Emag
|
||||||
|
emagType: Access
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Tools/access_breaker.rsi
|
||||||
|
state: icon
|
||||||
|
- type: Item
|
||||||
|
sprite: Objects/Tools/access_breaker.rsi
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: AccessBreakerUnlimited
|
||||||
|
id: AccessBreaker
|
||||||
|
suffix: Limited
|
||||||
|
components:
|
||||||
|
- type: LimitedCharges
|
||||||
|
- type: AutoRecharge
|
||||||
@@ -98,10 +98,10 @@
|
|||||||
stateLocked: cursed_door
|
stateLocked: cursed_door
|
||||||
stateUnlocked: decursed_door
|
stateUnlocked: decursed_door
|
||||||
- type: Lock
|
- type: Lock
|
||||||
breakOnEmag: false
|
breakOnAccessBreaker: false
|
||||||
- type: AccessReader
|
- type: AccessReader
|
||||||
access: [["Wizard"]]
|
access: [["Wizard"]]
|
||||||
breakOnEmag: false
|
breakOnAccessBreaker: false
|
||||||
- type: Projectile
|
- type: Projectile
|
||||||
deleteOnCollide: false
|
deleteOnCollide: false
|
||||||
onlyCollideWhenShot: true
|
onlyCollideWhenShot: true
|
||||||
|
|||||||
@@ -621,7 +621,7 @@
|
|||||||
color: "#3c5eb5"
|
color: "#3c5eb5"
|
||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
- EmagImmune
|
- AccessBreakerImmune
|
||||||
- type: ItemSlots
|
- type: ItemSlots
|
||||||
- type: ContainerContainer
|
- type: ContainerContainer
|
||||||
containers:
|
containers:
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
visible: false
|
visible: false
|
||||||
map: ["enum.FatExtractorVisualLayers.Smoke"]
|
map: ["enum.FatExtractorVisualLayers.Smoke"]
|
||||||
- type: Lock
|
- type: Lock
|
||||||
breakOnEmag: false
|
breakOnAccessBreaker: false
|
||||||
- type: GenericVisualizer
|
- type: GenericVisualizer
|
||||||
visuals:
|
visuals:
|
||||||
enum.StorageVisuals.Open:
|
enum.StorageVisuals.Open:
|
||||||
|
|||||||
@@ -101,6 +101,7 @@
|
|||||||
responsePings: false
|
responsePings: false
|
||||||
notifyAdmins: true
|
notifyAdmins: true
|
||||||
- type: Emagged
|
- type: Emagged
|
||||||
|
emagType: Interaction
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: FaxMachineBase
|
parent: FaxMachineBase
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
- type: ActivatableUI
|
- type: ActivatableUI
|
||||||
key: enum.CryostorageUIKey.Key
|
key: enum.CryostorageUIKey.Key
|
||||||
- type: AccessReader
|
- type: AccessReader
|
||||||
breakOnEmag: false
|
breakOnAccessBreaker: false
|
||||||
access: [["Cryogenics"]]
|
access: [["Cryogenics"]]
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
- type: Cryostorage
|
- type: Cryostorage
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# PUT YOUR TAGS IN ALPHABETICAL ORDER
|
# PUT YOUR TAGS IN ALPHABETICAL ORDER
|
||||||
|
|
||||||
|
- type: Tag
|
||||||
|
id: AccessBreakerImmune
|
||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: AirAlarm
|
id: AirAlarm
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 141 B |
BIN
Resources/Textures/Objects/Tools/access_breaker.rsi/icon.png
Normal file
BIN
Resources/Textures/Objects/Tools/access_breaker.rsi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 353 B |
Binary file not shown.
|
After Width: | Height: | Size: 383 B |
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Made by 20kdc (GitHub), edited by DieselMohawk (GitHub)",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "inhand-left",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-right",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "icon",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-BELT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user