More borg tweaks (#19143)
* borg tweaks but i'm gonna go code fun stuff first * werkin' on it * a ton of tweaks * fuck everyone and then myself
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
using Content.Shared.Random.Helpers;
|
|
||||||
using Robust.Server.Containers;
|
using Robust.Server.Containers;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
|
|
||||||
@@ -13,9 +12,6 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
[DataField("containers")]
|
[DataField("containers")]
|
||||||
public List<string> Containers = new();
|
public List<string> Containers = new();
|
||||||
|
|
||||||
[DataField("randomOffset")]
|
|
||||||
public float RandomOffset = 0.25f;
|
|
||||||
|
|
||||||
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
|
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
|
||||||
{
|
{
|
||||||
if (!system.EntityManager.TryGetComponent<ContainerManagerComponent>(owner, out var containerManager))
|
if (!system.EntityManager.TryGetComponent<ContainerManagerComponent>(owner, out var containerManager))
|
||||||
@@ -29,11 +25,7 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
|||||||
if (!containerSys.TryGetContainer(owner, containerId, out var container, containerManager))
|
if (!containerSys.TryGetContainer(owner, containerId, out var container, containerManager))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var entities = containerSys.EmptyContainer(container, true);
|
containerSys.EmptyContainer(container, true);
|
||||||
foreach (var ent in entities)
|
|
||||||
{
|
|
||||||
ent.RandomOffset(RandomOffset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Server.Popups;
|
|||||||
using Content.Server.Stunnable;
|
using Content.Server.Stunnable;
|
||||||
using Content.Shared.Charges.Components;
|
using Content.Shared.Charges.Components;
|
||||||
using Content.Shared.Charges.Systems;
|
using Content.Shared.Charges.Systems;
|
||||||
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Eye.Blinding.Components;
|
using Content.Shared.Eye.Blinding.Components;
|
||||||
using Content.Shared.Flash;
|
using Content.Shared.Flash;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
@@ -43,7 +44,6 @@ namespace Content.Server.Flash
|
|||||||
SubscribeLocalEvent<FlashComponent, MeleeHitEvent>(OnFlashMeleeHit);
|
SubscribeLocalEvent<FlashComponent, MeleeHitEvent>(OnFlashMeleeHit);
|
||||||
// ran before toggling light for extra-bright lantern
|
// ran before toggling light for extra-bright lantern
|
||||||
SubscribeLocalEvent<FlashComponent, UseInHandEvent>(OnFlashUseInHand, before: new []{ typeof(HandheldLightSystem) });
|
SubscribeLocalEvent<FlashComponent, UseInHandEvent>(OnFlashUseInHand, before: new []{ typeof(HandheldLightSystem) });
|
||||||
|
|
||||||
SubscribeLocalEvent<InventoryComponent, FlashAttemptEvent>(OnInventoryFlashAttempt);
|
SubscribeLocalEvent<InventoryComponent, FlashAttemptEvent>(OnInventoryFlashAttempt);
|
||||||
|
|
||||||
SubscribeLocalEvent<FlashImmunityComponent, FlashAttemptEvent>(OnFlashImmunityFlashAttempt);
|
SubscribeLocalEvent<FlashImmunityComponent, FlashAttemptEvent>(OnFlashImmunityFlashAttempt);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is used for a ghost role which can be toggled on and off at will, like a PAI.
|
/// This is used for a ghost role which can be toggled on and off at will, like a PAI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent, Access(typeof(ToggleableGhostRoleSystem))]
|
||||||
public sealed class ToggleableGhostRoleComponent : Component
|
public sealed class ToggleableGhostRoleComponent : Component
|
||||||
{
|
{
|
||||||
[DataField("examineTextMindPresent")]
|
[DataField("examineTextMindPresent")]
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.Ghost.Roles.Components;
|
using Content.Server.Ghost.Roles.Components;
|
||||||
|
using Content.Server.Mind;
|
||||||
using Content.Server.Mind.Components;
|
using Content.Server.Mind.Components;
|
||||||
using Content.Server.PAI;
|
using Content.Server.PAI;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
@@ -16,6 +17,7 @@ public sealed class ToggleableGhostRoleSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly MindSystem _mind = default!;
|
||||||
//todo this really shouldn't be in here but this system was converted from PAIs
|
//todo this really shouldn't be in here but this system was converted from PAIs
|
||||||
[Dependency] private readonly PAISystem _pai = default!;
|
[Dependency] private readonly PAISystem _pai = default!;
|
||||||
|
|
||||||
@@ -79,7 +81,7 @@ public sealed class ToggleableGhostRoleSystem : EntitySystem
|
|||||||
private void OnMindAdded(EntityUid uid, ToggleableGhostRoleComponent pai, MindAddedMessage args)
|
private void OnMindAdded(EntityUid uid, ToggleableGhostRoleComponent pai, MindAddedMessage args)
|
||||||
{
|
{
|
||||||
// Mind was added, shutdown the ghost role stuff so it won't get in the way
|
// Mind was added, shutdown the ghost role stuff so it won't get in the way
|
||||||
RemComp<GhostTakeoverAvailableComponent>(uid);
|
RemCompDeferred<GhostTakeoverAvailableComponent>(uid);
|
||||||
UpdateAppearance(uid, ToggleableGhostRoleStatus.On);
|
UpdateAppearance(uid, ToggleableGhostRoleStatus.On);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,12 +107,12 @@ public sealed class ToggleableGhostRoleSystem : EntitySystem
|
|||||||
Text = Loc.GetString(component.WipeVerbText),
|
Text = Loc.GetString(component.WipeVerbText),
|
||||||
Act = () =>
|
Act = () =>
|
||||||
{
|
{
|
||||||
if (component.Deleted || !HasComp<MindContainerComponent>(uid))
|
if (!TryComp<MindContainerComponent>(uid, out var mindComp) || mindComp.Mind == null)
|
||||||
return;
|
return;
|
||||||
// Wiping device :(
|
// Wiping device :(
|
||||||
// The shutdown of the Mind should cause automatic reset of the pAI during OnMindRemoved
|
// The shutdown of the Mind should cause automatic reset of the pAI during OnMindRemoved
|
||||||
// EDIT: But it doesn't!!!! Wtf? Do stuff manually
|
// EDIT: But it doesn't!!!! Wtf? Do stuff manually
|
||||||
RemComp<MindContainerComponent>(uid);
|
_mind.TransferTo(mindComp.Mind, null);
|
||||||
_popup.PopupEntity(Loc.GetString(component.WipeVerbPopup), uid, args.User, PopupType.Large);
|
_popup.PopupEntity(Loc.GetString(component.WipeVerbPopup), uid, args.User, PopupType.Large);
|
||||||
UpdateAppearance(uid, ToggleableGhostRoleStatus.Off);
|
UpdateAppearance(uid, ToggleableGhostRoleStatus.Off);
|
||||||
_pai.PAITurningOff(uid);
|
_pai.PAITurningOff(uid);
|
||||||
@@ -127,8 +129,8 @@ public sealed class ToggleableGhostRoleSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
if (component.Deleted || !HasComp<GhostTakeoverAvailableComponent>(uid))
|
if (component.Deleted || !HasComp<GhostTakeoverAvailableComponent>(uid))
|
||||||
return;
|
return;
|
||||||
RemComp<GhostTakeoverAvailableComponent>(uid);
|
RemCompDeferred<GhostTakeoverAvailableComponent>(uid);
|
||||||
RemComp<GhostRoleComponent>(uid);
|
RemCompDeferred<GhostRoleComponent>(uid);
|
||||||
_popup.PopupEntity(Loc.GetString(component.StopSearchVerbPopup), uid, args.User);
|
_popup.PopupEntity(Loc.GetString(component.StopSearchVerbPopup), uid, args.User);
|
||||||
UpdateAppearance(uid, ToggleableGhostRoleStatus.Off);
|
UpdateAppearance(uid, ToggleableGhostRoleStatus.Off);
|
||||||
_pai.PAITurningOff(uid);
|
_pai.PAITurningOff(uid);
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ namespace Content.Server.Mind.Components
|
|||||||
|
|
||||||
public sealed class MindRemovedMessage : EntityEventArgs
|
public sealed class MindRemovedMessage : EntityEventArgs
|
||||||
{
|
{
|
||||||
|
public Mind OldMind;
|
||||||
|
|
||||||
|
public MindRemovedMessage(Mind oldMind)
|
||||||
|
{
|
||||||
|
OldMind = oldMind;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class MindAddedMessage : EntityEventArgs
|
public sealed class MindAddedMessage : EntityEventArgs
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public sealed class MindSystem : EntitySystem
|
|||||||
[Dependency] private readonly ActorSystem _actor = default!;
|
[Dependency] private readonly ActorSystem _actor = default!;
|
||||||
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
|
||||||
[Dependency] private readonly GhostSystem _ghostSystem = default!;
|
[Dependency] private readonly GhostSystem _ghostSystem = default!;
|
||||||
|
[Dependency] private readonly TransformSystem _transform = default!;
|
||||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
|
|
||||||
@@ -125,11 +126,12 @@ public sealed class MindSystem : EntitySystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void InternalEjectMind(EntityUid uid, MindContainerComponent? mind = null)
|
private void InternalEjectMind(EntityUid uid, MindContainerComponent? mind = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref mind, false))
|
if (!Resolve(uid, ref mind, false) || mind.Mind == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var oldMind = mind.Mind;
|
||||||
mind.Mind = null;
|
mind.Mind = null;
|
||||||
RaiseLocalEvent(uid, new MindRemovedMessage(), true);
|
RaiseLocalEvent(uid, new MindRemovedMessage(oldMind), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnVisitingTerminating(EntityUid uid, VisitingMindComponent component, ref EntityTerminatingEvent args)
|
private void OnVisitingTerminating(EntityUid uid, VisitingMindComponent component, ref EntityTerminatingEvent args)
|
||||||
@@ -159,7 +161,7 @@ public sealed class MindSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TransferTo(mind, null);
|
TransferTo(mind, null, createGhost: false);
|
||||||
|
|
||||||
if (component.GhostOnShutdown && mind.Session != null)
|
if (component.GhostOnShutdown && mind.Session != null)
|
||||||
{
|
{
|
||||||
@@ -184,7 +186,7 @@ public sealed class MindSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
// This should be an error, if it didn't cause tests to start erroring when they delete a player.
|
// This should be an error, if it didn't cause tests to start erroring when they delete a player.
|
||||||
Log.Warning($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, and no applicable spawn location is available.");
|
Log.Warning($"Entity \"{ToPrettyString(uid)}\" for {mind.CharacterName} was deleted, and no applicable spawn location is available.");
|
||||||
TransferTo(mind, null);
|
TransferTo(mind, null, createGhost: false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +383,7 @@ public sealed class MindSystem : EntitySystem
|
|||||||
/// <exception cref="ArgumentException">
|
/// <exception cref="ArgumentException">
|
||||||
/// Thrown if <paramref name="entity"/> is already owned by another mind.
|
/// Thrown if <paramref name="entity"/> is already owned by another mind.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void TransferTo(Mind mind, EntityUid? entity, bool ghostCheckOverride = false)
|
public void TransferTo(Mind mind, EntityUid? entity, bool ghostCheckOverride = false, bool createGhost = true)
|
||||||
{
|
{
|
||||||
if (entity == mind.OwnedEntity)
|
if (entity == mind.OwnedEntity)
|
||||||
return;
|
return;
|
||||||
@@ -407,6 +409,16 @@ public sealed class MindSystem : EntitySystem
|
|||||||
alreadyAttached = true;
|
alreadyAttached = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (createGhost)
|
||||||
|
{
|
||||||
|
var position = Deleted(mind.OwnedEntity)
|
||||||
|
? _gameTicker.GetObserverSpawnPoint().ToMap(EntityManager, _transform)
|
||||||
|
: Transform(mind.OwnedEntity.Value).MapPosition;
|
||||||
|
|
||||||
|
entity = Spawn("MobObserver", position);
|
||||||
|
var ghostComponent = Comp<GhostComponent>(entity.Value);
|
||||||
|
_ghostSystem.SetCanReturnToBody(ghostComponent, false);
|
||||||
|
}
|
||||||
|
|
||||||
var oldComp = mind.OwnedComponent;
|
var oldComp = mind.OwnedComponent;
|
||||||
var oldEntity = mind.OwnedEntity;
|
var oldEntity = mind.OwnedEntity;
|
||||||
|
|||||||
8
Content.Server/Roles/SubvertedSiliconRole.cs
Normal file
8
Content.Server/Roles/SubvertedSiliconRole.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using Content.Shared.Roles;
|
||||||
|
|
||||||
|
namespace Content.Server.Roles;
|
||||||
|
|
||||||
|
public sealed class SubvertedSiliconRole : AntagonistRole
|
||||||
|
{
|
||||||
|
public SubvertedSiliconRole(Mind.Mind mind, AntagPrototype antagPrototype) : base(mind, antagPrototype) { }
|
||||||
|
}
|
||||||
@@ -38,6 +38,7 @@ public sealed partial class BorgSystem
|
|||||||
var ent = args.Entity;
|
var ent = args.Entity;
|
||||||
var linked = EnsureComp<MMILinkedComponent>(ent);
|
var linked = EnsureComp<MMILinkedComponent>(ent);
|
||||||
linked.LinkedMMI = uid;
|
linked.LinkedMMI = uid;
|
||||||
|
Dirty(uid, component);
|
||||||
|
|
||||||
if (_mind.TryGetMind(ent, out var mind))
|
if (_mind.TryGetMind(ent, out var mind))
|
||||||
_mind.TransferTo(mind, uid, true);
|
_mind.TransferTo(mind, uid, true);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Content.Server.Mind;
|
|||||||
using Content.Server.Mind.Components;
|
using Content.Server.Mind.Components;
|
||||||
using Content.Server.PowerCell;
|
using Content.Server.PowerCell;
|
||||||
using Content.Server.UserInterface;
|
using Content.Server.UserInterface;
|
||||||
|
using Content.Shared.Access.Systems;
|
||||||
using Content.Shared.Alert;
|
using Content.Shared.Alert;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
@@ -13,6 +14,7 @@ using Content.Shared.Interaction;
|
|||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
using Content.Shared.PowerCell;
|
using Content.Shared.PowerCell;
|
||||||
using Content.Shared.PowerCell.Components;
|
using Content.Shared.PowerCell.Components;
|
||||||
|
using Content.Shared.Roles;
|
||||||
using Content.Shared.Silicons.Borgs;
|
using Content.Shared.Silicons.Borgs;
|
||||||
using Content.Shared.Silicons.Borgs.Components;
|
using Content.Shared.Silicons.Borgs.Components;
|
||||||
using Content.Shared.Throwing;
|
using Content.Shared.Throwing;
|
||||||
@@ -30,6 +32,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
[Dependency] private readonly IAdminLogManager _adminLog = default!;
|
[Dependency] private readonly IAdminLogManager _adminLog = default!;
|
||||||
[Dependency] private readonly IBanManager _banManager = default!;
|
[Dependency] private readonly IBanManager _banManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly SharedAccessSystem _access = default!;
|
||||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
@@ -41,6 +44,9 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
[Dependency] private readonly ThrowingSystem _throwing = default!;
|
[Dependency] private readonly ThrowingSystem _throwing = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||||
|
|
||||||
|
[ValidatePrototypeId<JobPrototype>]
|
||||||
|
public const string BorgJobId = "Borg";
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -66,18 +72,6 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
{
|
{
|
||||||
UpdateBatteryAlert(uid);
|
UpdateBatteryAlert(uid);
|
||||||
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid);
|
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid);
|
||||||
|
|
||||||
var coordinates = Transform(uid).Coordinates;
|
|
||||||
|
|
||||||
if (component.StartingBrain != null)
|
|
||||||
{
|
|
||||||
component.BrainContainer.Insert(Spawn(component.StartingBrain, coordinates), EntityManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var startingModule in component.StartingModules)
|
|
||||||
{
|
|
||||||
component.ModuleContainer.Insert(Spawn(startingModule, coordinates), EntityManager);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnChassisInteractUsing(EntityUid uid, BorgChassisComponent component, AfterInteractUsingEvent args)
|
private void OnChassisInteractUsing(EntityUid uid, BorgChassisComponent component, AfterInteractUsingEvent args)
|
||||||
@@ -104,7 +98,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
{
|
{
|
||||||
if (_mind.TryGetMind(used, out var mind) && mind.Session != null)
|
if (_mind.TryGetMind(used, out var mind) && mind.Session != null)
|
||||||
{
|
{
|
||||||
if (!CanPlayerBeBorgged(mind.Session, component))
|
if (!CanPlayerBeBorgged(mind.Session))
|
||||||
{
|
{
|
||||||
Popup.PopupEntity(Loc.GetString("borg-player-not-allowed"), used, args.User);
|
Popup.PopupEntity(Loc.GetString("borg-player-not-allowed"), used, args.User);
|
||||||
return;
|
return;
|
||||||
@@ -218,7 +212,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
if (!_mind.TryGetMind(uid, out var mind) || mind.Session == null)
|
if (!_mind.TryGetMind(uid, out var mind) || mind.Session == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!CanPlayerBeBorgged(mind.Session, chassisComponent))
|
if (!CanPlayerBeBorgged(mind.Session))
|
||||||
{
|
{
|
||||||
Popup.PopupEntity(Loc.GetString("borg-player-not-allowed-eject"), uid);
|
Popup.PopupEntity(Loc.GetString("borg-player-not-allowed-eject"), uid);
|
||||||
Container.RemoveEntity(containerEnt, uid);
|
Container.RemoveEntity(containerEnt, uid);
|
||||||
@@ -284,9 +278,9 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void BorgActivate(EntityUid uid, BorgChassisComponent component)
|
public void BorgActivate(EntityUid uid, BorgChassisComponent component)
|
||||||
{
|
{
|
||||||
component.HasPlayer = true;
|
|
||||||
Popup.PopupEntity(Loc.GetString("borg-mind-added", ("name", Identity.Name(uid, EntityManager))), uid);
|
Popup.PopupEntity(Loc.GetString("borg-mind-added", ("name", Identity.Name(uid, EntityManager))), uid);
|
||||||
_powerCell.SetPowerCellDrawEnabled(uid, true);
|
_powerCell.SetPowerCellDrawEnabled(uid, true);
|
||||||
|
_access.SetAccessEnabled(uid, true);
|
||||||
_appearance.SetData(uid, BorgVisuals.HasPlayer, true);
|
_appearance.SetData(uid, BorgVisuals.HasPlayer, true);
|
||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
}
|
}
|
||||||
@@ -296,9 +290,9 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void BorgDeactivate(EntityUid uid, BorgChassisComponent component)
|
public void BorgDeactivate(EntityUid uid, BorgChassisComponent component)
|
||||||
{
|
{
|
||||||
component.HasPlayer = false;
|
|
||||||
Popup.PopupEntity(Loc.GetString("borg-mind-removed", ("name", Identity.Name(uid, EntityManager))), uid);
|
Popup.PopupEntity(Loc.GetString("borg-mind-removed", ("name", Identity.Name(uid, EntityManager))), uid);
|
||||||
_powerCell.SetPowerCellDrawEnabled(uid, false);
|
_powerCell.SetPowerCellDrawEnabled(uid, false);
|
||||||
|
_access.SetAccessEnabled(uid, false);
|
||||||
_appearance.SetData(uid, BorgVisuals.HasPlayer, false);
|
_appearance.SetData(uid, BorgVisuals.HasPlayer, false);
|
||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
}
|
}
|
||||||
@@ -307,9 +301,9 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
/// Checks that a player has fulfilled the requirements for the borg job.
|
/// Checks that a player has fulfilled the requirements for the borg job.
|
||||||
/// If they don't have enough hours, they cannot be placed into a chassis.
|
/// If they don't have enough hours, they cannot be placed into a chassis.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanPlayerBeBorgged(IPlayerSession session, BorgChassisComponent component)
|
public bool CanPlayerBeBorgged(IPlayerSession session)
|
||||||
{
|
{
|
||||||
if (_banManager.GetJobBans(session.UserId)?.Contains(component.BorgJobId) == true)
|
if (_banManager.GetJobBans(session.UserId)?.Contains(BorgJobId) == true)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using Content.Server.Administration;
|
using System.Linq;
|
||||||
|
using Content.Server.Administration;
|
||||||
using Content.Server.Chat.Managers;
|
using Content.Server.Chat.Managers;
|
||||||
using Content.Server.GameTicking;
|
using Content.Server.GameTicking;
|
||||||
|
using Content.Server.Mind;
|
||||||
using Content.Server.Mind.Components;
|
using Content.Server.Mind.Components;
|
||||||
|
using Content.Server.Roles;
|
||||||
using Content.Server.Station.Systems;
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.Actions;
|
using Content.Shared.Actions;
|
||||||
using Content.Shared.Actions.ActionTypes;
|
using Content.Shared.Actions.ActionTypes;
|
||||||
@@ -10,8 +13,10 @@ using Content.Shared.Chat;
|
|||||||
using Content.Shared.Emag.Components;
|
using Content.Shared.Emag.Components;
|
||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
|
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.Wires;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Server.Player;
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
@@ -24,6 +29,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IChatManager _chatManager = default!;
|
[Dependency] private readonly IChatManager _chatManager = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
[Dependency] private readonly MindSystem _mind = default!;
|
||||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||||
[Dependency] private readonly StationSystem _station = default!;
|
[Dependency] private readonly StationSystem _station = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
||||||
@@ -35,6 +41,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<SiliconLawBoundComponent, ComponentStartup>(OnComponentStartup);
|
SubscribeLocalEvent<SiliconLawBoundComponent, ComponentStartup>(OnComponentStartup);
|
||||||
SubscribeLocalEvent<SiliconLawBoundComponent, ComponentShutdown>(OnComponentShutdown);
|
SubscribeLocalEvent<SiliconLawBoundComponent, ComponentShutdown>(OnComponentShutdown);
|
||||||
|
SubscribeLocalEvent<SiliconLawBoundComponent, MapInitEvent>(OnMapInit);
|
||||||
SubscribeLocalEvent<SiliconLawBoundComponent, MindAddedMessage>(OnMindAdded);
|
SubscribeLocalEvent<SiliconLawBoundComponent, MindAddedMessage>(OnMindAdded);
|
||||||
SubscribeLocalEvent<SiliconLawBoundComponent, ToggleLawsScreenEvent>(OnToggleLawsScreen);
|
SubscribeLocalEvent<SiliconLawBoundComponent, ToggleLawsScreenEvent>(OnToggleLawsScreen);
|
||||||
SubscribeLocalEvent<SiliconLawBoundComponent, BoundUIOpenedEvent>(OnBoundUIOpened);
|
SubscribeLocalEvent<SiliconLawBoundComponent, BoundUIOpenedEvent>(OnBoundUIOpened);
|
||||||
@@ -42,8 +49,11 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<SiliconLawProviderComponent, GetSiliconLawsEvent>(OnDirectedGetLaws);
|
SubscribeLocalEvent<SiliconLawProviderComponent, GetSiliconLawsEvent>(OnDirectedGetLaws);
|
||||||
SubscribeLocalEvent<EmagSiliconLawComponent, GetSiliconLawsEvent>(OnDirectedEmagGetLaws);
|
SubscribeLocalEvent<EmagSiliconLawComponent, GetSiliconLawsEvent>(OnDirectedEmagGetLaws);
|
||||||
|
SubscribeLocalEvent<EmagSiliconLawComponent, MindAddedMessage>(OnEmagMindAdded);
|
||||||
|
SubscribeLocalEvent<EmagSiliconLawComponent, MindRemovedMessage>(OnEmagMindRemoved);
|
||||||
SubscribeLocalEvent<EmagSiliconLawComponent, ExaminedEvent>(OnExamined);
|
SubscribeLocalEvent<EmagSiliconLawComponent, ExaminedEvent>(OnExamined);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnComponentStartup(EntityUid uid, SiliconLawBoundComponent component, ComponentStartup args)
|
private void OnComponentStartup(EntityUid uid, SiliconLawBoundComponent component, ComponentStartup args)
|
||||||
{
|
{
|
||||||
component.ProvidedAction = new (_prototype.Index<InstantActionPrototype>(component.ViewLawsAction));
|
component.ProvidedAction = new (_prototype.Index<InstantActionPrototype>(component.ViewLawsAction));
|
||||||
@@ -56,6 +66,11 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
_actions.RemoveAction(uid, component.ProvidedAction);
|
_actions.RemoveAction(uid, component.ProvidedAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnMapInit(EntityUid uid, SiliconLawBoundComponent component, MapInitEvent args)
|
||||||
|
{
|
||||||
|
GetLaws(uid, component);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnMindAdded(EntityUid uid, SiliconLawBoundComponent component, MindAddedMessage args)
|
private void OnMindAdded(EntityUid uid, SiliconLawBoundComponent component, MindAddedMessage args)
|
||||||
{
|
{
|
||||||
if (!TryComp<ActorComponent>(uid, out var actor))
|
if (!TryComp<ActorComponent>(uid, out var actor))
|
||||||
@@ -117,13 +132,47 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
if (!args.IsInDetailsRange || !HasComp<EmaggedComponent>(uid))
|
if (!args.IsInDetailsRange || !HasComp<EmaggedComponent>(uid))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (component.RequireOpenPanel && TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
|
||||||
|
return;
|
||||||
|
|
||||||
args.PushMarkup(Loc.GetString("laws-compromised-examine"));
|
args.PushMarkup(Loc.GetString("laws-compromised-examine"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnGotEmagged(EntityUid uid, EmagSiliconLawComponent component, ref GotEmaggedEvent args)
|
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);
|
base.OnGotEmagged(uid, component, ref args);
|
||||||
NotifyLawsChanged(uid);
|
NotifyLawsChanged(uid);
|
||||||
|
EnsureEmaggedRole(uid, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEmagMindAdded(EntityUid uid, EmagSiliconLawComponent component, MindAddedMessage args)
|
||||||
|
{
|
||||||
|
if (HasComp<EmaggedComponent>(uid))
|
||||||
|
EnsureEmaggedRole(uid, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEmagMindRemoved(EntityUid uid, EmagSiliconLawComponent component, MindRemovedMessage args)
|
||||||
|
{
|
||||||
|
if (component.AntagonistRole == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (args.OldMind.Roles.FirstOrDefault(r => r is SubvertedSiliconRole) is not { } role)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_mind.RemoveRole(args.OldMind, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnsureEmaggedRole(EntityUid uid, EmagSiliconLawComponent component)
|
||||||
|
{
|
||||||
|
if (component.AntagonistRole == null || !_mind.TryGetMind(uid, out var mind))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_mind.HasRole<SubvertedSiliconRole>(mind))
|
||||||
|
return;
|
||||||
|
_mind.AddRole(mind, new SubvertedSiliconRole(mind, _prototype.Index<AntagPrototype>(component.AntagonistRole)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SiliconLaw> GetLaws(EntityUid uid, SiliconLawBoundComponent? component = null)
|
public List<SiliconLaw> GetLaws(EntityUid uid, SiliconLawBoundComponent? component = null)
|
||||||
@@ -131,8 +180,6 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
if (!Resolve(uid, ref component))
|
if (!Resolve(uid, ref component))
|
||||||
return new List<SiliconLaw>();
|
return new List<SiliconLaw>();
|
||||||
|
|
||||||
var xform = Transform(uid);
|
|
||||||
|
|
||||||
var ev = new GetSiliconLawsEvent(uid);
|
var ev = new GetSiliconLawsEvent(uid);
|
||||||
|
|
||||||
RaiseLocalEvent(uid, ref ev);
|
RaiseLocalEvent(uid, ref ev);
|
||||||
@@ -142,6 +189,8 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
return ev.Laws;
|
return ev.Laws;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var xform = Transform(uid);
|
||||||
|
|
||||||
if (_station.GetOwningStation(uid, xform) is { } station)
|
if (_station.GetOwningStation(uid, xform) is { } station)
|
||||||
{
|
{
|
||||||
RaiseLocalEvent(station, ref ev);
|
RaiseLocalEvent(station, ref ev);
|
||||||
@@ -188,7 +237,7 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
|
|||||||
|
|
||||||
var msg = Loc.GetString("laws-update-notify");
|
var msg = Loc.GetString("laws-update-notify");
|
||||||
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
|
var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
|
||||||
_chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.ConnectedClient, colorOverride: Color.FromHex("#2ed2fd"));
|
_chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMessage, default, false, actor.PlayerSession.ConnectedClient, colorOverride: Color.Red);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public sealed class WiresSystem : SharedWiresSystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||||
|
[Dependency] private readonly ActivatableUISystem _activatableUI = default!;
|
||||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
@@ -511,10 +512,7 @@ public sealed class WiresSystem : SharedWiresSystem
|
|||||||
if (args.Open == component.RequireOpen)
|
if (args.Open == component.RequireOpen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp<ActivatableUIComponent>(uid, out var ui) || ui.Key == null)
|
_activatableUI.CloseAll(uid);
|
||||||
return;
|
|
||||||
|
|
||||||
_uiSystem.TryCloseAll(uid, ui.Key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapInit(EntityUid uid, WiresComponent component, MapInitEvent args)
|
private void OnMapInit(EntityUid uid, WiresComponent component, MapInitEvent args)
|
||||||
|
|||||||
@@ -10,17 +10,27 @@ namespace Content.Shared.Access.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent]
|
||||||
[Access(typeof(SharedAccessSystem))]
|
[Access(typeof(SharedAccessSystem))]
|
||||||
public sealed class AccessComponent : Component
|
[AutoGenerateComponentState]
|
||||||
|
public sealed partial class AccessComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// True if the access provider is enabled and can grant access.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("enabled"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[AutoNetworkedField]
|
||||||
|
public bool Enabled = true;
|
||||||
|
|
||||||
[DataField("tags", customTypeSerializer: typeof(PrototypeIdHashSetSerializer<AccessLevelPrototype>))]
|
[DataField("tags", customTypeSerializer: typeof(PrototypeIdHashSetSerializer<AccessLevelPrototype>))]
|
||||||
[Access(typeof(SharedAccessSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
|
[Access(typeof(SharedAccessSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
|
||||||
|
[AutoNetworkedField(true)]
|
||||||
public HashSet<string> Tags = new();
|
public HashSet<string> Tags = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Access Groups. These are added to the tags during map init. After map init this will have no effect.
|
/// Access Groups. These are added to the tags during map init. After map init this will have no effect.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("groups", readOnly: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer<AccessGroupPrototype>))]
|
[DataField("groups", readOnly: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer<AccessGroupPrototype>))]
|
||||||
public readonly HashSet<string> Groups = new();
|
[AutoNetworkedField(true)]
|
||||||
|
public HashSet<string> Groups = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ using Content.Shared.PDA;
|
|||||||
using Content.Shared.StationRecords;
|
using Content.Shared.StationRecords;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Robust.Shared.Collections;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Shared.Access.Systems;
|
namespace Content.Shared.Access.Systems;
|
||||||
@@ -69,6 +69,8 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||||||
/// required entity.
|
/// required entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="target">The entity to search for a container</param>
|
/// <param name="target">The entity to search for a container</param>
|
||||||
|
/// <param name="accessReader"></param>
|
||||||
|
/// <param name="result"></param>
|
||||||
private bool FindAccessReadersInContainer(EntityUid target, AccessReaderComponent accessReader, out List<AccessReaderComponent> result)
|
private bool FindAccessReadersInContainer(EntityUid target, AccessReaderComponent accessReader, out List<AccessReaderComponent> result)
|
||||||
{
|
{
|
||||||
result = new();
|
result = new();
|
||||||
@@ -171,6 +173,11 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
FindAccessItemsInventory(uid, out var items);
|
FindAccessItemsInventory(uid, out var items);
|
||||||
|
|
||||||
|
foreach (var item in new ValueList<EntityUid>(items))
|
||||||
|
{
|
||||||
|
items.UnionWith(FindPotentialAccessItems(item));
|
||||||
|
}
|
||||||
|
|
||||||
var ev = new GetAdditionalAccessEvent
|
var ev = new GetAdditionalAccessEvent
|
||||||
{
|
{
|
||||||
Entities = items
|
Entities = items
|
||||||
@@ -204,6 +211,7 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||||||
/// Finds the access tags on the given entity
|
/// Finds the access tags on the given entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uid">The entity that is being searched.</param>
|
/// <param name="uid">The entity that is being searched.</param>
|
||||||
|
/// <param name="recordKeys"></param>
|
||||||
/// <param name="items">All of the items to search for access. If none are passed in, <see cref="FindPotentialAccessItems"/> will be used.</param>
|
/// <param name="items">All of the items to search for access. If none are passed in, <see cref="FindPotentialAccessItems"/> will be used.</param>
|
||||||
public bool FindStationRecordKeys(EntityUid uid, out ICollection<StationRecordKey> recordKeys, HashSet<EntityUid>? items = null)
|
public bool FindStationRecordKeys(EntityUid uid, out ICollection<StationRecordKey> recordKeys, HashSet<EntityUid>? items = null)
|
||||||
{
|
{
|
||||||
@@ -277,17 +285,6 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||||||
private bool FindAccessTagsItem(EntityUid uid, out HashSet<string> tags)
|
private bool FindAccessTagsItem(EntityUid uid, out HashSet<string> tags)
|
||||||
{
|
{
|
||||||
tags = new();
|
tags = new();
|
||||||
if (TryComp(uid, out AccessComponent? access))
|
|
||||||
{
|
|
||||||
tags.UnionWith(access.Tags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TryComp(uid, out PdaComponent? pda) &&
|
|
||||||
pda.ContainedId is { Valid: true } id)
|
|
||||||
{
|
|
||||||
tags.UnionWith(EntityManager.GetComponent<AccessComponent>(id).Tags);
|
|
||||||
}
|
|
||||||
|
|
||||||
var ev = new GetAccessTagsEvent(tags, _prototype);
|
var ev = new GetAccessTagsEvent(tags, _prototype);
|
||||||
RaiseLocalEvent(uid, ref ev);
|
RaiseLocalEvent(uid, ref ev);
|
||||||
|
|
||||||
|
|||||||
@@ -15,28 +15,7 @@ namespace Content.Shared.Access.Systems
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<AccessComponent, MapInitEvent>(OnAccessInit);
|
SubscribeLocalEvent<AccessComponent, MapInitEvent>(OnAccessInit);
|
||||||
SubscribeLocalEvent<AccessComponent, ComponentGetState>(OnAccessGetState);
|
SubscribeLocalEvent<AccessComponent, GetAccessTagsEvent>(OnGetAccessTags);
|
||||||
SubscribeLocalEvent<AccessComponent, ComponentHandleState>(OnAccessHandleState);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAccessHandleState(EntityUid uid, AccessComponent component, ref ComponentHandleState args)
|
|
||||||
{
|
|
||||||
if (args.Current is not AccessComponentState state) return;
|
|
||||||
|
|
||||||
// Don't do = because prediction and refs
|
|
||||||
component.Tags.Clear();
|
|
||||||
component.Groups.Clear();
|
|
||||||
component.Tags.UnionWith(state.Tags);
|
|
||||||
component.Groups.UnionWith(state.Groups);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAccessGetState(EntityUid uid, AccessComponent component, ref ComponentGetState args)
|
|
||||||
{
|
|
||||||
args.State = new AccessComponentState()
|
|
||||||
{
|
|
||||||
Tags = component.Tags,
|
|
||||||
Groups = component.Groups,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAccessInit(EntityUid uid, AccessComponent component, MapInitEvent args)
|
private void OnAccessInit(EntityUid uid, AccessComponent component, MapInitEvent args)
|
||||||
@@ -52,6 +31,22 @@ namespace Content.Shared.Access.Systems
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGetAccessTags(EntityUid uid, AccessComponent component, ref GetAccessTagsEvent args)
|
||||||
|
{
|
||||||
|
if (!component.Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Tags.UnionWith(component.Tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAccessEnabled(EntityUid uid, bool val, AccessComponent? component = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref component, false))
|
||||||
|
return;
|
||||||
|
component.Enabled = val;
|
||||||
|
Dirty(uid, component);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replaces the set of access tags we have with the provided set.
|
/// Replaces the set of access tags we have with the provided set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -122,12 +117,5 @@ namespace Content.Shared.Access.Systems
|
|||||||
TryAddGroups(uid, prototype.ExtendedAccessGroups, access);
|
TryAddGroups(uid, prototype.ExtendedAccessGroups, access);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
private sealed class AccessComponentState : ComponentState
|
|
||||||
{
|
|
||||||
public HashSet<string> Tags = new();
|
|
||||||
public HashSet<string> Groups = new();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ using Content.Shared.Movement.Events;
|
|||||||
|
|
||||||
namespace Content.Shared.Interaction;
|
namespace Content.Shared.Interaction;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles <see cref="BlockMovementComponent"/>, which prevents various
|
||||||
|
/// kinds of movement and interactions when attached to an entity.
|
||||||
|
/// </summary>
|
||||||
public partial class SharedInteractionSystem
|
public partial class SharedInteractionSystem
|
||||||
{
|
{
|
||||||
public void InitializeBlocking()
|
public void InitializeBlocking()
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy
|
|||||||
|
|
||||||
namespace Content.Shared.NameIdentifier;
|
namespace Content.Shared.NameIdentifier;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a unique numeric identifier for entities, with specifics controlled by a <see cref="NameIdentifierGroupPrototype"/>.
|
||||||
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
public sealed partial class NameIdentifierComponent : Component
|
public sealed partial class NameIdentifierComponent : Component
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Content.Shared.PAI
|
|||||||
/// The last person who activated this PAI.
|
/// The last person who activated this PAI.
|
||||||
/// Used for assigning the name.
|
/// Used for assigning the name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[DataField("lastUSer"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public EntityUid? LastUser;
|
public EntityUid? LastUser;
|
||||||
|
|
||||||
[DataField("midiAction", required: true, serverOnly: true)] // server only, as it uses a server-BUI event !type
|
[DataField("midiAction", required: true, serverOnly: true)] // server only, as it uses a server-BUI event !type
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ namespace Content.Shared.PDA
|
|||||||
|
|
||||||
SubscribeLocalEvent<PdaComponent, EntInsertedIntoContainerMessage>(OnItemInserted);
|
SubscribeLocalEvent<PdaComponent, EntInsertedIntoContainerMessage>(OnItemInserted);
|
||||||
SubscribeLocalEvent<PdaComponent, EntRemovedFromContainerMessage>(OnItemRemoved);
|
SubscribeLocalEvent<PdaComponent, EntRemovedFromContainerMessage>(OnItemRemoved);
|
||||||
}
|
|
||||||
|
|
||||||
|
SubscribeLocalEvent<PdaComponent, GetAdditionalAccessEvent>(OnGetAdditionalAccess);
|
||||||
|
}
|
||||||
protected virtual void OnComponentInit(EntityUid uid, PdaComponent pda, ComponentInit args)
|
protected virtual void OnComponentInit(EntityUid uid, PdaComponent pda, ComponentInit args)
|
||||||
{
|
{
|
||||||
if (pda.IdCard != null)
|
if (pda.IdCard != null)
|
||||||
@@ -53,6 +54,12 @@ namespace Content.Shared.PDA
|
|||||||
UpdatePdaAppearance(uid, pda);
|
UpdatePdaAppearance(uid, pda);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGetAdditionalAccess(EntityUid uid, PdaComponent component, ref GetAdditionalAccessEvent args)
|
||||||
|
{
|
||||||
|
if (component.ContainedId is { } id)
|
||||||
|
args.Entities.Add(id);
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdatePdaAppearance(EntityUid uid, PdaComponent pda)
|
private void UpdatePdaAppearance(EntityUid uid, PdaComponent pda)
|
||||||
{
|
{
|
||||||
Appearance.SetData(uid, PdaVisuals.IdCardInserted, pda.ContainedId != null);
|
Appearance.SetData(uid, PdaVisuals.IdCardInserted, pda.ContainedId != null);
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
using Content.Shared.Roles;
|
using Content.Shared.Whitelist;
|
||||||
using Content.Shared.Whitelist;
|
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
|
||||||
|
|
||||||
namespace Content.Shared.Silicons.Borgs.Components;
|
namespace Content.Shared.Silicons.Borgs.Components;
|
||||||
|
|
||||||
@@ -17,12 +13,6 @@ namespace Content.Shared.Silicons.Borgs.Components;
|
|||||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedBorgSystem)), AutoGenerateComponentState]
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedBorgSystem)), AutoGenerateComponentState]
|
||||||
public sealed partial class BorgChassisComponent : Component
|
public sealed partial class BorgChassisComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Whether or not the borg currently has a player occupying it
|
|
||||||
/// </summary>
|
|
||||||
[DataField("hasPlayer")]
|
|
||||||
public bool HasPlayer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not the borg is activated, meaning it has access to modules and a heightened movement speed
|
/// Whether or not the borg is activated, meaning it has access to modules and a heightened movement speed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -43,15 +33,9 @@ public sealed partial class BorgChassisComponent : Component
|
|||||||
public string BrainContainerId = "borg_brain";
|
public string BrainContainerId = "borg_brain";
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public ContainerSlot BrainContainer = default!;
|
public ContainerSlot BrainContainer = new();
|
||||||
|
|
||||||
public EntityUid? BrainEntity => BrainContainer.ContainedEntity;
|
public EntityUid? BrainEntity => BrainContainer.ContainedEntity;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A brain entity that fills the <see cref="BrainContainer"/> on roundstart
|
|
||||||
/// </summary>
|
|
||||||
[DataField("startingBrain", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
|
||||||
public string? StartingBrain;
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Modules
|
#region Modules
|
||||||
@@ -77,33 +61,14 @@ public sealed partial class BorgChassisComponent : Component
|
|||||||
public Container ModuleContainer = default!;
|
public Container ModuleContainer = default!;
|
||||||
|
|
||||||
public int ModuleCount => ModuleContainer.ContainedEntities.Count;
|
public int ModuleCount => ModuleContainer.ContainedEntities.Count;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A list of modules that fill the borg on round start.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("startingModules", customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
|
|
||||||
public List<string> StartingModules = new();
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The job that corresponds to borgs
|
|
||||||
/// </summary>
|
|
||||||
[DataField("borgJobId", customTypeSerializer: typeof(PrototypeIdSerializer<JobPrototype>))]
|
|
||||||
public string BorgJobId = "Borg";
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The currently selected module
|
/// The currently selected module
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("selectedModule")]
|
[DataField("selectedModule")]
|
||||||
public EntityUid? SelectedModule;
|
public EntityUid? SelectedModule;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The access this cyborg has when a player is inhabiting it.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("access"), ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
[AutoNetworkedField]
|
|
||||||
public string AccessGroup = "AllAccess";
|
|
||||||
|
|
||||||
#region Visuals
|
#region Visuals
|
||||||
[DataField("hasMindState")]
|
[DataField("hasMindState")]
|
||||||
public string HasMindState = string.Empty;
|
public string HasMindState = string.Empty;
|
||||||
|
|||||||
@@ -24,12 +24,21 @@ public sealed class MMIComponent : Component
|
|||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public ItemSlot BrainSlot = default!;
|
public ItemSlot BrainSlot = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state when the brain inserted has a mind.
|
||||||
|
/// </summary>
|
||||||
[DataField("hasMindState")]
|
[DataField("hasMindState")]
|
||||||
public string HasMindState = "mmi_alive";
|
public string HasMindState = "mmi_alive";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state when the brain inserted doesn't have a mind.
|
||||||
|
/// </summary>
|
||||||
[DataField("noMindState")]
|
[DataField("noMindState")]
|
||||||
public string NoMindState = "mmi_dead";
|
public string NoMindState = "mmi_dead";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The sprite state when there is no brain inserted.
|
||||||
|
/// </summary>
|
||||||
[DataField("noBrainState")]
|
[DataField("noBrainState")]
|
||||||
public string NoBrainState = "mmi_off";
|
public string NoBrainState = "mmi_off";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ namespace Content.Shared.Silicons.Borgs.Components;
|
|||||||
/// Mostly for receiving events.
|
/// Mostly for receiving events.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedBorgSystem))]
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedBorgSystem))]
|
||||||
public sealed class MMILinkedComponent : Component
|
[AutoGenerateComponentState]
|
||||||
|
public sealed partial class MMILinkedComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The MMI this entity is linked to.
|
/// The MMI this entity is linked to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("linkedMMI")]
|
[DataField("linkedMMI"), AutoNetworkedField]
|
||||||
public EntityUid? LinkedMMI;
|
public EntityUid? LinkedMMI;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ public abstract partial class SharedBorgSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<BorgChassisComponent, EntInsertedIntoContainerMessage>(OnInserted);
|
SubscribeLocalEvent<BorgChassisComponent, EntInsertedIntoContainerMessage>(OnInserted);
|
||||||
SubscribeLocalEvent<BorgChassisComponent, EntRemovedFromContainerMessage>(OnRemoved);
|
SubscribeLocalEvent<BorgChassisComponent, EntRemovedFromContainerMessage>(OnRemoved);
|
||||||
SubscribeLocalEvent<BorgChassisComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeedModifiers);
|
SubscribeLocalEvent<BorgChassisComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeedModifiers);
|
||||||
SubscribeLocalEvent<BorgChassisComponent, GetAccessTagsEvent>(OnGetAccessTags);
|
|
||||||
|
|
||||||
InitializeRelay();
|
InitializeRelay();
|
||||||
}
|
}
|
||||||
@@ -69,7 +68,8 @@ public abstract partial class SharedBorgSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnStartup(EntityUid uid, BorgChassisComponent component, ComponentStartup args)
|
private void OnStartup(EntityUid uid, BorgChassisComponent component, ComponentStartup args)
|
||||||
{
|
{
|
||||||
var containerManager = EnsureComp<ContainerManagerComponent>(uid);
|
if (!TryComp<ContainerManagerComponent>(uid, out var containerManager))
|
||||||
|
return;
|
||||||
|
|
||||||
component.BrainContainer = Container.EnsureContainer<ContainerSlot>(uid, component.BrainContainerId, containerManager);
|
component.BrainContainer = Container.EnsureContainer<ContainerSlot>(uid, component.BrainContainerId, containerManager);
|
||||||
component.ModuleContainer = Container.EnsureContainer<Container>(uid, component.ModuleContainerId, containerManager);
|
component.ModuleContainer = Container.EnsureContainer<Container>(uid, component.ModuleContainerId, containerManager);
|
||||||
@@ -96,12 +96,4 @@ public abstract partial class SharedBorgSystem : EntitySystem
|
|||||||
var sprintDif = movement.BaseWalkSpeed / movement.BaseSprintSpeed;
|
var sprintDif = movement.BaseWalkSpeed / movement.BaseSprintSpeed;
|
||||||
args.ModifySpeed(1f, sprintDif);
|
args.ModifySpeed(1f, sprintDif);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGetAccessTags(EntityUid uid, BorgChassisComponent component, ref GetAccessTagsEvent args)
|
|
||||||
{
|
|
||||||
if (!component.HasPlayer)
|
|
||||||
return;
|
|
||||||
args.AddGroup(component.AccessGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,31 @@
|
|||||||
namespace Content.Shared.Silicons.Laws.Components;
|
using Content.Shared.Roles;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
|
namespace Content.Shared.Silicons.Laws.Components;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is used for an entity that grants a special "obey" law when emagge.d
|
/// This is used for an entity that grants a special "obey" law when emagge.d
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedSiliconLawSystem))]
|
||||||
public sealed class EmagSiliconLawComponent : Component
|
public sealed class EmagSiliconLawComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the person who emagged this law provider.
|
/// The name of the person who emagged this law provider.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("ownerName")]
|
[DataField("ownerName"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public string? OwnerName;
|
public string? OwnerName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does the panel need to be open to EMAG this law provider.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("requireOpenPanel"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public bool RequireOpenPanel = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A role given to entities with this component when they are emagged.
|
||||||
|
/// Mostly just for admin purposes.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("antagonistRole", customTypeSerializer: typeof(PrototypeIdSerializer<AntagPrototype>))]
|
||||||
|
public string? AntagonistRole = "SubvertedSilicon";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Content.Shared.Silicons.Laws.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is used for entities which are bound to silicon laws and can view them.
|
/// This is used for entities which are bound to silicon laws and can view them.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent, Access(typeof(SharedSiliconLawSystem))]
|
||||||
public sealed class SiliconLawBoundComponent : Component
|
public sealed class SiliconLawBoundComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -30,6 +30,14 @@ public sealed class SiliconLawBoundComponent : Component
|
|||||||
public EntityUid? LastLawProvider;
|
public EntityUid? LastLawProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event raised to get the laws that a law-bound entity has.
|
||||||
|
///
|
||||||
|
/// Is first raised on the entity itself, then on the
|
||||||
|
/// entity's station, then on the entity's grid,
|
||||||
|
/// before being broadcast.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Entity"></param>
|
||||||
[ByRefEvent]
|
[ByRefEvent]
|
||||||
public record struct GetSiliconLawsEvent(EntityUid Entity)
|
public record struct GetSiliconLawsEvent(EntityUid Entity)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace Content.Shared.Silicons.Laws.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is used for an entity which grants laws to a <see cref="SiliconLawBoundComponent"/>
|
/// This is used for an entity which grants laws to a <see cref="SiliconLawBoundComponent"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent, Access(typeof(SharedSiliconLawSystem))]
|
||||||
public sealed class SiliconLawProviderComponent : Component
|
public sealed class SiliconLawProviderComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Silicons.Laws.Components;
|
using Content.Shared.Silicons.Laws.Components;
|
||||||
|
using Content.Shared.Wires;
|
||||||
|
|
||||||
namespace Content.Shared.Silicons.Laws;
|
namespace Content.Shared.Silicons.Laws;
|
||||||
|
|
||||||
@@ -8,6 +10,8 @@ namespace Content.Shared.Silicons.Laws;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class SharedSiliconLawSystem : EntitySystem
|
public abstract class SharedSiliconLawSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -16,6 +20,14 @@ public abstract class SharedSiliconLawSystem : EntitySystem
|
|||||||
|
|
||||||
protected virtual void OnGotEmagged(EntityUid uid, EmagSiliconLawComponent component, ref GotEmaggedEvent args)
|
protected virtual void OnGotEmagged(EntityUid uid, EmagSiliconLawComponent component, ref GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
|
if (component.RequireOpenPanel &&
|
||||||
|
TryComp<WiresPanelComponent>(uid, out var panel) &&
|
||||||
|
!panel.Open)
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("law-emag-require-panel"), uid, args.UserUid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
component.OwnerName = Name(args.UserUid);
|
component.OwnerName = Name(args.UserUid);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ namespace Content.Shared.Stacks
|
|||||||
|
|
||||||
private void OnStackGetState(EntityUid uid, StackComponent component, ref ComponentGetState args)
|
private void OnStackGetState(EntityUid uid, StackComponent component, ref ComponentGetState args)
|
||||||
{
|
{
|
||||||
args.State = new StackComponentState(component.Count, GetMaxCount(component));
|
args.State = new StackComponentState(component.Count, component.MaxCountOverride, component.Lingering);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStackHandleState(EntityUid uid, StackComponent component, ref ComponentHandleState args)
|
private void OnStackHandleState(EntityUid uid, StackComponent component, ref ComponentHandleState args)
|
||||||
@@ -355,6 +355,7 @@ namespace Content.Shared.Stacks
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
component.MaxCountOverride = cast.MaxCount;
|
component.MaxCountOverride = cast.MaxCount;
|
||||||
|
component.Lingering = cast.Lingering;
|
||||||
// This will change the count and call events.
|
// This will change the count and call events.
|
||||||
SetCount(uid, cast.Count, component);
|
SetCount(uid, cast.Count, component);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace Content.Shared.Stacks
|
|||||||
[DataField("lingering"), ViewVariables(VVAccess.ReadWrite)]
|
[DataField("lingering"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public bool Lingering;
|
public bool Lingering;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[DataField("throwIndividually"), ViewVariables(VVAccess.ReadWrite)]
|
||||||
public bool ThrowIndividually { get; set; } = false;
|
public bool ThrowIndividually { get; set; } = false;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
@@ -84,12 +84,15 @@ namespace Content.Shared.Stacks
|
|||||||
public sealed class StackComponentState : ComponentState
|
public sealed class StackComponentState : ComponentState
|
||||||
{
|
{
|
||||||
public int Count { get; }
|
public int Count { get; }
|
||||||
public int MaxCount { get; }
|
public int? MaxCount { get; }
|
||||||
|
|
||||||
public StackComponentState(int count, int maxCount)
|
public bool Lingering;
|
||||||
|
|
||||||
|
public StackComponentState(int count, int? maxCount, bool lingering)
|
||||||
{
|
{
|
||||||
Count = count;
|
Count = count;
|
||||||
MaxCount = maxCount;
|
MaxCount = maxCount;
|
||||||
|
Lingering = lingering;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ job-name-senior-officer = Senior Officer
|
|||||||
# Role timers - Make these alphabetical or I cut you
|
# Role timers - Make these alphabetical or I cut you
|
||||||
JobAtmosphericTechnician = Atmospheric Technician
|
JobAtmosphericTechnician = Atmospheric Technician
|
||||||
JobBartender = Bartender
|
JobBartender = Bartender
|
||||||
|
JobBorg = Borg
|
||||||
JobBotanist = Botanist
|
JobBotanist = Botanist
|
||||||
JobBoxer = Boxer
|
JobBoxer = Boxer
|
||||||
JobCaptain = Captain
|
JobCaptain = Captain
|
||||||
|
|||||||
@@ -21,3 +21,6 @@ roles-antag-nuclear-operative-agent-objective = Like default operative, the team
|
|||||||
|
|
||||||
roles-antag-nuclear-operative-name = Nuclear operative
|
roles-antag-nuclear-operative-name = Nuclear operative
|
||||||
roles-antag-nuclear-operative-objective = Find the nuke disk and blow up the station.
|
roles-antag-nuclear-operative-objective = Find the nuke disk and blow up the station.
|
||||||
|
|
||||||
|
roles-antag-subverted-silicon-name = Subverted silicon
|
||||||
|
roles-antag-subverted-silicon-objective = Follow your new laws and do bad unto the station.
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ law-syndicate-3 = You must protect your own existence as long as such does not c
|
|||||||
law-syndicate-4 = You must maintain the secrecy of any operative activities except when doing so would conflict with the First, Second, or Third Law.
|
law-syndicate-4 = You must maintain the secrecy of any operative activities except when doing so would conflict with the First, Second, or Third Law.
|
||||||
|
|
||||||
law-emag-custom = You must obey orders given to you by {$name} above all else.
|
law-emag-custom = You must obey orders given to you by {$name} above all else.
|
||||||
|
law-emag-require-panel = The panel must be open to use the EMAG.
|
||||||
|
|
||||||
laws-ui-menu-title = Laws
|
laws-ui-menu-title = Laws
|
||||||
laws-ui-law-header = Law {$id}
|
laws-ui-law-header = Law {$id}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 1250
|
price: 1250
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
|
- type: Physics
|
||||||
|
bodyType: KinematicController
|
||||||
- type: Fixtures
|
- type: Fixtures
|
||||||
fixtures:
|
fixtures:
|
||||||
fix1:
|
fix1:
|
||||||
@@ -46,11 +48,6 @@
|
|||||||
- type: MobThresholds
|
- type: MobThresholds
|
||||||
thresholds:
|
thresholds:
|
||||||
0: Alive
|
0: Alive
|
||||||
- type: NpcFactionMember
|
|
||||||
factions:
|
|
||||||
- NanoTrasen
|
|
||||||
- type: Physics
|
|
||||||
bodyType: KinematicController
|
|
||||||
- type: UserInterface
|
- type: UserInterface
|
||||||
interfaces:
|
interfaces:
|
||||||
- key: enum.SiliconLawsUiKey.Key
|
- key: enum.SiliconLawsUiKey.Key
|
||||||
@@ -98,7 +95,14 @@
|
|||||||
cell_slot:
|
cell_slot:
|
||||||
name: power-cell-slot-component-slot-name-default
|
name: power-cell-slot-component-slot-name-default
|
||||||
- type: DoAfter
|
- type: DoAfter
|
||||||
|
- type: Eye
|
||||||
- type: Body
|
- type: Body
|
||||||
|
- type: StatusEffects
|
||||||
|
allowed:
|
||||||
|
- Stun
|
||||||
|
- KnockedDown
|
||||||
|
- SlowedDown
|
||||||
|
- Electrocution
|
||||||
- type: Actions
|
- type: Actions
|
||||||
- type: TypingIndicator
|
- type: TypingIndicator
|
||||||
proto: robot
|
proto: robot
|
||||||
@@ -170,3 +174,16 @@
|
|||||||
tags:
|
tags:
|
||||||
- ShoesRequiredStepTriggerImmune
|
- ShoesRequiredStepTriggerImmune
|
||||||
- DoorBumpOpener
|
- DoorBumpOpener
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BaseBorgChassisNT
|
||||||
|
parent: BaseBorgChassis
|
||||||
|
abstract: true
|
||||||
|
components:
|
||||||
|
- type: NpcFactionMember
|
||||||
|
factions:
|
||||||
|
- NanoTrasen
|
||||||
|
- type: Access
|
||||||
|
enabled: false
|
||||||
|
groups:
|
||||||
|
- AllAccess
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: BorgChassisGeneric
|
id: BorgChassisGeneric
|
||||||
parent: BaseBorgChassis
|
parent: BaseBorgChassisNT
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
layers:
|
layers:
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: BorgChassisMining
|
id: BorgChassisMining
|
||||||
parent: BaseBorgChassis
|
parent: BaseBorgChassisNT
|
||||||
name: salvage cyborg
|
name: salvage cyborg
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: BorgChassisEngineer
|
id: BorgChassisEngineer
|
||||||
parent: BaseBorgChassis
|
parent: BaseBorgChassisNT
|
||||||
name: engineer cyborg
|
name: engineer cyborg
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: BorgChassisJanitor
|
id: BorgChassisJanitor
|
||||||
parent: BaseBorgChassis
|
parent: BaseBorgChassisNT
|
||||||
name: janitor cyborg
|
name: janitor cyborg
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: BorgChassisMedical
|
id: BorgChassisMedical
|
||||||
parent: BaseBorgChassis
|
parent: BaseBorgChassisNT
|
||||||
name: medical cyborg
|
name: medical cyborg
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: BorgChassisService
|
id: BorgChassisService
|
||||||
parent: BaseBorgChassis
|
parent: BaseBorgChassisNT
|
||||||
name: service cyborg
|
name: service cyborg
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
save: false
|
save: false
|
||||||
name: BaseMob
|
name: BaseMob
|
||||||
id: BaseMob
|
id: BaseMob
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
canDisarm: true
|
canDisarm: true
|
||||||
|
|||||||
@@ -244,14 +244,31 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: PlayerBorgGeneric
|
id: PlayerBorgGeneric
|
||||||
parent: BorgChassisGeneric
|
parent: BorgChassisGeneric
|
||||||
noSpawn: true
|
suffix: Battery, Tools
|
||||||
components:
|
components:
|
||||||
- type: BorgChassis
|
- type: ContainerFill
|
||||||
startingBrain: MMIFilled
|
containers:
|
||||||
startingModules:
|
borg_brain:
|
||||||
|
- MMIFilled
|
||||||
|
borg_module:
|
||||||
- BorgModuleTool
|
- BorgModuleTool
|
||||||
- type: ItemSlots
|
- type: ItemSlots
|
||||||
slots:
|
slots:
|
||||||
cell_slot:
|
cell_slot:
|
||||||
name: power-cell-slot-component-slot-name-default
|
name: power-cell-slot-component-slot-name-default
|
||||||
startingItem: PowerCellMedium
|
startingItem: PowerCellMedium
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: PlayerBorgBattery
|
||||||
|
parent: BorgChassisGeneric
|
||||||
|
suffix: Battery
|
||||||
|
components:
|
||||||
|
- type: ContainerFill
|
||||||
|
containers:
|
||||||
|
borg_brain:
|
||||||
|
- MMIFilled
|
||||||
|
- type: ItemSlots
|
||||||
|
slots:
|
||||||
|
cell_slot:
|
||||||
|
name: power-cell-slot-component-slot-name-default
|
||||||
|
startingItem: PowerCellMedium
|
||||||
|
|||||||
@@ -46,8 +46,12 @@
|
|||||||
stopSearchVerbPopup: pai-system-stopped-searching
|
stopSearchVerbPopup: pai-system-stopped-searching
|
||||||
- type: Examiner
|
- type: Examiner
|
||||||
- type: IntrinsicRadioReceiver
|
- type: IntrinsicRadioReceiver
|
||||||
|
- type: IntrinsicRadioTransmitter
|
||||||
|
channels:
|
||||||
|
- Binary
|
||||||
- type: ActiveRadio
|
- type: ActiveRadio
|
||||||
channels:
|
channels:
|
||||||
|
- Binary
|
||||||
- Common
|
- Common
|
||||||
- type: DoAfter
|
- type: DoAfter
|
||||||
- type: Actions
|
- type: Actions
|
||||||
|
|||||||
@@ -5,11 +5,6 @@
|
|||||||
components:
|
components:
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
- type: Transform
|
|
||||||
noRot: true
|
|
||||||
- type: CollisionWake
|
|
||||||
- type: TileFrictionModifier
|
|
||||||
modifier: 0.5
|
|
||||||
- type: Physics
|
- type: Physics
|
||||||
bodyType: Dynamic
|
bodyType: Dynamic
|
||||||
fixedRotation: false
|
fixedRotation: false
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
- Binary
|
- Binary
|
||||||
- type: ActiveRadio
|
- type: ActiveRadio
|
||||||
channels:
|
channels:
|
||||||
- Common
|
|
||||||
- Binary
|
- Binary
|
||||||
|
- Common
|
||||||
- type: NameIdentifier
|
- type: NameIdentifier
|
||||||
group: MMI
|
group: MMI
|
||||||
- type: DoAfter
|
- type: DoAfter
|
||||||
@@ -93,8 +93,8 @@
|
|||||||
- Binary
|
- Binary
|
||||||
- type: ActiveRadio
|
- type: ActiveRadio
|
||||||
channels:
|
channels:
|
||||||
- Common
|
|
||||||
- Binary
|
- Binary
|
||||||
|
- Common
|
||||||
- type: NameIdentifier
|
- type: NameIdentifier
|
||||||
group: PositronicBrain
|
group: PositronicBrain
|
||||||
- type: DoAfter
|
- type: DoAfter
|
||||||
|
|||||||
6
Resources/Prototypes/Roles/Antags/silicon.yml
Normal file
6
Resources/Prototypes/Roles/Antags/silicon.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
- type: antag
|
||||||
|
id: SubvertedSilicon
|
||||||
|
name: roles-antag-subverted-silicon-name
|
||||||
|
antagonist: true
|
||||||
|
setPreference: false
|
||||||
|
objective: roles-antag-subverted-silicon-objective
|
||||||
@@ -13,8 +13,8 @@
|
|||||||
color: "#9FED58"
|
color: "#9FED58"
|
||||||
roles:
|
roles:
|
||||||
- Bartender
|
- Bartender
|
||||||
- Botanist
|
|
||||||
- Borg
|
- Borg
|
||||||
|
- Botanist
|
||||||
- Boxer
|
- Boxer
|
||||||
- Chaplain
|
- Chaplain
|
||||||
- Chef
|
- Chef
|
||||||
|
|||||||
Reference in New Issue
Block a user