diff --git a/Content.Server/_Mono/POI/POICaptureSystem.cs b/Content.Server/_Mono/POI/POICaptureSystem.cs
new file mode 100644
index 00000000000..7c65ec8c2d4
--- /dev/null
+++ b/Content.Server/_Mono/POI/POICaptureSystem.cs
@@ -0,0 +1,244 @@
+using Content.Server.Radio.EntitySystems;
+using Content.Shared._Mono.POI.Components;
+using Content.Shared.Access.Components;
+using Content.Shared._NF.Shipyard.Components;
+using Content.Shared.NPC.Prototypes;
+using Content.Shared.Popups;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Timing;
+
+namespace Content.Server._Mono.POI;
+
+///
+/// Handles active POI capture progress.
+/// Runs once per second and only checks active captures.
+///
+public sealed class POICaptureSystem : EntitySystem
+{
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+ [Dependency] private readonly SharedPopupSystem _popup = default!;
+ [Dependency] private readonly RadioSystem _radio = default!;
+ [Dependency] private readonly IPrototypeManager _prototype = default!;
+
+
+ private TimeSpan _nextUpdate;
+
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ _nextUpdate = _gameTiming.CurTime;
+ }
+
+
+ public override void Update(float frameTime)
+ {
+ if (_gameTiming.CurTime < _nextUpdate)
+ return;
+
+
+ _nextUpdate = _gameTiming.CurTime + TimeSpan.FromSeconds(1);
+
+
+ var query = EntityQueryEnumerator();
+
+ while (query.MoveNext(out var uid, out var capture))
+ {
+ TickCapture(uid, capture);
+ }
+ }
+
+
+ private void TickCapture(
+ EntityUid uid,
+ POICaptureComponent capture)
+ {
+ if (capture.CapturingEntity == null)
+ {
+ CancelCapture(uid);
+ return;
+ }
+
+
+ if (!TryComp(uid, out var poi))
+ {
+ CancelCapture(uid);
+ return;
+ }
+
+
+ //
+ // Initial capture announcement
+ //
+ if (capture.LastBroadcastPercent == -1)
+ {
+ var playerName = "Unknown";
+ var factionName = "Unknown";
+
+
+ if (capture.CapturingEntity is { } capturer)
+ playerName = Name(capturer);
+
+
+ if (capture.CapturingIdCard is { } idCard &&
+ TryComp(idCard, out var card))
+ {
+ if (_prototype.TryIndex(card.Faction, out var faction))
+ factionName = faction.Name;
+ else
+ factionName = card.Faction;
+ }
+
+
+ _radio.SendRadioMessage(
+ uid,
+ $"{playerName} for faction {factionName} is attempting to capture {Name(uid)}. Stand by.",
+ "Traffic",
+ uid);
+
+
+ capture.LastBroadcastPercent = 0;
+ }
+
+
+ var elapsed =
+ _gameTiming.CurTime - capture.CaptureStart;
+
+
+ var progress =
+ (float)(elapsed.TotalSeconds /
+ capture.CaptureDuration.TotalSeconds) * 100f;
+
+
+ poi.CaptureProgress = Math.Clamp(progress, 0f, 100f);
+ poi.IsBeingCaptured = true;
+
+
+ Dirty(uid, poi);
+
+
+ //
+ // Progress announcements every 20%
+ //
+ var broadcast =
+ (int)(poi.CaptureProgress / 20) * 20;
+
+
+ if (broadcast > capture.LastBroadcastPercent)
+ {
+ capture.LastBroadcastPercent = broadcast;
+
+
+ _radio.SendRadioMessage(
+ uid,
+ $"{Name(uid)} capture progress: {broadcast}%.",
+ "Traffic",
+ uid);
+ }
+
+
+ if (poi.CaptureProgress >= 100f)
+ {
+ CompleteCapture(uid, poi, capture);
+ }
+ }
+
+
+ private void CompleteCapture(
+ EntityUid uid,
+ CapturablePOIComponent poi,
+ POICaptureComponent capture)
+ {
+ poi.OwnerFaction = "Rogue";
+
+ poi.CaptureProgress = 0;
+ poi.IsBeingCaptured = false;
+
+
+ Dirty(uid, poi);
+
+
+ var playerName = "Unknown";
+ var factionName = "Unknown";
+
+
+ if (capture.CapturingEntity is { } capturer)
+ playerName = Name(capturer);
+
+
+ if (capture.CapturingIdCard is { } idCard &&
+ TryComp(idCard, out var card))
+ {
+ if (_prototype.TryIndex(card.Faction, out var faction))
+ factionName = faction.Name;
+ else
+ factionName = card.Faction;
+
+
+ //
+ // Remove previous ownership deeds
+ //
+ RemoveExistingDeeds(uid);
+
+
+ //
+ // Assign new ownership deed
+ //
+ var deed = EnsureComp(idCard);
+
+ deed.ShuttleUid = uid;
+ deed.ShuttleName = Name(uid);
+ deed.ShuttleOwner = card.FullName ?? "Unknown";
+ deed.DeedHolder = idCard;
+ }
+
+
+ _radio.SendRadioMessage(
+ uid,
+ $"{Name(uid)} has been captured by {playerName} for faction {factionName}.",
+ "Traffic",
+ uid);
+
+
+ _popup.PopupEntity(
+ $"{Name(uid)} capture complete. Ownership transferred.",
+ uid);
+
+
+ RemComp(uid);
+ }
+
+
+ ///
+ /// Removes any existing deeds that reference this POI.
+ /// Ensures only one ID card owns the captured location.
+ ///
+ private void RemoveExistingDeeds(EntityUid poiUid)
+ {
+ var query = EntityQueryEnumerator();
+
+ while (query.MoveNext(out var deedUid, out var deed))
+ {
+ if (deed.ShuttleUid != poiUid)
+ continue;
+
+ RemComp(deedUid);
+ }
+ }
+
+
+ private void CancelCapture(EntityUid uid)
+ {
+ if (TryComp(uid, out var poi))
+ {
+ poi.CaptureProgress = 0;
+ poi.IsBeingCaptured = false;
+
+ Dirty(uid, poi);
+ }
+
+
+ RemComp(uid);
+ }
+}
\ No newline at end of file
diff --git a/Content.Shared/Access/Components/IdCardComponent.cs b/Content.Shared/Access/Components/IdCardComponent.cs
index c8e4c087814..88d146762a7 100644
--- a/Content.Shared/Access/Components/IdCardComponent.cs
+++ b/Content.Shared/Access/Components/IdCardComponent.cs
@@ -1,4 +1,6 @@
using Content.Shared._Mono.Company;
+using Content.Shared._Mono.POI.Systems;
+using Content.Shared.NPC.Prototypes;
using Content.Shared.Access.Systems;
using Content.Shared.PDA;
using Content.Shared.Roles;
@@ -11,7 +13,7 @@ namespace Content.Shared.Access.Components;
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState]
-[Access(typeof(SharedIdCardSystem), typeof(SharedPdaSystem), typeof(SharedAgentIdCardSystem), Other = AccessPermissions.ReadWrite)]
+[Access(typeof(SharedIdCardSystem), typeof(SharedPdaSystem), typeof(SharedAgentIdCardSystem), typeof(CapturableShuttleConsoleSystem), Other = AccessPermissions.ReadWrite)]
public sealed partial class IdCardComponent : Component
{
[DataField]
@@ -46,12 +48,20 @@ public sealed partial class IdCardComponent : Component
public List> JobDepartments = new();
///
- /// The company name associated with this ID card
+ /// The company name associated with this ID card.
///
[DataField]
[AutoNetworkedField]
public ProtoId CompanyName = "None";
+ ///
+ /// The NPC faction associated with this ID card.
+ /// Used for POI capture, IFF and faction-based systems.
+ ///
+ [DataField]
+ [AutoNetworkedField]
+ public ProtoId Faction = "CC";
+
///
/// Determines if accesses from this card should be logged by
///
diff --git a/Content.Shared/NPC/Prototypes/NpcFactionPrototype.cs b/Content.Shared/NPC/Prototypes/NpcFactionPrototype.cs
index 5aab66e5c42..1a438db5970 100644
--- a/Content.Shared/NPC/Prototypes/NpcFactionPrototype.cs
+++ b/Content.Shared/NPC/Prototypes/NpcFactionPrototype.cs
@@ -34,8 +34,13 @@ public sealed partial class NpcFactionPrototype : IPrototype
/// Mono - Is this faction checked for default hostility?
///
[DataField]
- public bool DefaultHostileIncluded = true;
+ public bool DefaultHostileIncluded = true;
+ ///
+ /// Display name of the faction.
+ ///
+ [DataField]
+ public string Name { get; private set; } = string.Empty;
}
///
diff --git a/Content.Shared/_Mono/POI/Components/CapturablePOIComponent.cs b/Content.Shared/_Mono/POI/Components/CapturablePOIComponent.cs
new file mode 100644
index 00000000000..3c35b252a0d
--- /dev/null
+++ b/Content.Shared/_Mono/POI/Components/CapturablePOIComponent.cs
@@ -0,0 +1,58 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared._Mono.POI.Components;
+
+///
+/// Marks an entity as a capturable point of interest.
+/// Stores the permanent ownership state of the POI.
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class CapturablePOIComponent : Component
+{
+ ///
+ /// Current owning faction/company of this POI.
+ /// Example:
+ /// TSF
+ /// USSP
+ /// Pirates
+ /// Rogue
+ ///
+ [DataField]
+ [AutoNetworkedField]
+ public string? OwnerFaction;
+
+
+ ///
+ /// Current owner name.
+ /// Used for ship deed ownership text.
+ ///
+ [DataField]
+ [AutoNetworkedField]
+ public string? OwnerName;
+
+
+ ///
+ /// Display name of the captured entity.
+ /// Used for shuttle deed naming.
+ ///
+ [DataField]
+ [AutoNetworkedField]
+ public string? POIName;
+
+
+ ///
+ /// Current capture progress percentage.
+ /// 0-100.
+ ///
+ [DataField]
+ [AutoNetworkedField]
+ public float CaptureProgress;
+
+
+ ///
+ /// True while a capture is active.
+ ///
+ [DataField]
+ [AutoNetworkedField]
+ public bool IsBeingCaptured;
+}
\ No newline at end of file
diff --git a/Content.Shared/_Mono/POI/Components/CapturableShuttleConsoleComponent.cs b/Content.Shared/_Mono/POI/Components/CapturableShuttleConsoleComponent.cs
new file mode 100644
index 00000000000..70d5207d49a
--- /dev/null
+++ b/Content.Shared/_Mono/POI/Components/CapturableShuttleConsoleComponent.cs
@@ -0,0 +1,39 @@
+using Content.Shared._Mono.POI.Systems;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared._Mono.POI.Components;
+
+///
+/// Component for a capturable POI console.
+/// Stores configuration and the currently inserted ID card.
+///
+[RegisterComponent, NetworkedComponent]
+[Access(typeof(CapturableShuttleConsoleSystem))]
+public sealed partial class CapturableShuttleConsoleComponent : Component
+{
+ ///
+ /// Time required to complete a capture in seconds.
+ ///
+ [DataField]
+ public float CaptureTime = 6f;
+
+ ///
+ /// Percentage interval between capture progress announcements.
+ ///
+ [DataField]
+ public int BroadcastInterval = 2;
+
+ ///
+ /// Name of the ID card container slot.
+ /// Must match the slot name in the YAML.
+ ///
+ [DataField]
+ public string IdSlot = "id_slot";
+
+ ///
+ /// The ID card currently inserted into the console.
+ /// Set by EntInsertedIntoContainerMessage and
+ /// cleared by EntRemovedFromContainerMessage.
+ ///
+ public EntityUid? InsertedId;
+}
\ No newline at end of file
diff --git a/Content.Shared/_Mono/POI/Components/POICaptureComponent.cs b/Content.Shared/_Mono/POI/Components/POICaptureComponent.cs
new file mode 100644
index 00000000000..82a4717bcd9
--- /dev/null
+++ b/Content.Shared/_Mono/POI/Components/POICaptureComponent.cs
@@ -0,0 +1,54 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared._Mono.POI.Components;
+
+///
+/// Tracks an active capture attempt on a capturable POI.
+/// This stores temporary capture state, while CapturablePOIComponent stores ownership.
+///
+[RegisterComponent, NetworkedComponent]
+public sealed partial class POICaptureComponent : Component
+{
+ ///
+ /// Entity currently performing the capture.
+ ///
+ public EntityUid? CapturingEntity;
+
+
+ ///
+ /// ID card used to capture the POI.
+ /// Receives the ShuttleDeedComponent when capture completes.
+ ///
+ public EntityUid? CapturingIdCard;
+
+
+ ///
+ /// Character name of the person who started the capture.
+ /// Stored because the entity may not resolve later.
+ ///
+ public string CapturingPlayerName = "Unknown";
+
+
+ ///
+ /// Company/faction stored from the inserted ID card.
+ ///
+ public string CapturingFaction = "None";
+
+
+ ///
+ /// Time when capture started.
+ ///
+ public TimeSpan CaptureStart;
+
+
+ ///
+ /// Time required to complete capture.
+ ///
+ public TimeSpan CaptureDuration = TimeSpan.FromMinutes(5);
+
+
+ ///
+ /// Last announced capture percentage.
+ ///
+ public int LastBroadcastPercent = -1;
+}
\ No newline at end of file
diff --git a/Content.Shared/_Mono/POI/Systems/CapturableShuttleConsoleSystem.cs b/Content.Shared/_Mono/POI/Systems/CapturableShuttleConsoleSystem.cs
new file mode 100644
index 00000000000..7862ce480e2
--- /dev/null
+++ b/Content.Shared/_Mono/POI/Systems/CapturableShuttleConsoleSystem.cs
@@ -0,0 +1,173 @@
+using Content.Shared._Mono.POI.Components;
+using Content.Shared.Access.Components;
+using Content.Shared.Popups;
+using Content.Shared.Verbs;
+using Robust.Shared.Containers;
+using Robust.Shared.Timing;
+
+namespace Content.Shared._Mono.POI.Systems;
+
+public sealed class CapturableShuttleConsoleSystem : EntitySystem
+{
+ [Dependency] private readonly SharedPopupSystem _popup = default!;
+ [Dependency] private readonly IGameTiming _gameTiming = default!;
+
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnIdInserted);
+ SubscribeLocalEvent(OnIdRemoved);
+
+ SubscribeLocalEvent>(AddCaptureVerb);
+ }
+
+
+ private void OnIdInserted(
+ EntityUid uid,
+ CapturableShuttleConsoleComponent component,
+ EntInsertedIntoContainerMessage args)
+ {
+ if (args.Container.ID != component.IdSlot)
+ return;
+
+
+ if (!HasComp(args.Entity))
+ return;
+
+
+ component.InsertedId = args.Entity;
+ }
+
+
+ private void OnIdRemoved(
+ EntityUid uid,
+ CapturableShuttleConsoleComponent component,
+ EntRemovedFromContainerMessage args)
+ {
+ if (args.Container.ID != component.IdSlot)
+ return;
+
+
+ component.InsertedId = null;
+ }
+
+
+ private void AddCaptureVerb(
+ EntityUid uid,
+ CapturableShuttleConsoleComponent component,
+ GetVerbsEvent args)
+ {
+ if (component.InsertedId == null)
+ return;
+
+
+ args.Verbs.Add(new Verb
+ {
+ Text = "Start Capture",
+
+ Act = () =>
+ {
+ TryStartCapture(
+ uid,
+ component,
+ args.User);
+ }
+ });
+ }
+
+
+ private void TryStartCapture(
+ EntityUid console,
+ CapturableShuttleConsoleComponent component,
+ EntityUid user)
+ {
+ if (component.InsertedId == null)
+ {
+ _popup.PopupClient(
+ "Insert an ID card first.",
+ console,
+ user);
+
+ return;
+ }
+
+
+ var consoleTransform = Transform(console);
+
+
+ if (consoleTransform.GridUid == null)
+ {
+ _popup.PopupClient(
+ "This console is not located on a valid grid.",
+ console,
+ user);
+
+ return;
+ }
+
+
+ var grid = consoleTransform.GridUid.Value;
+
+
+ var poi = EnsureComp(grid);
+
+
+ if (TryComp(grid, out var existingCapture) &&
+ existingCapture.CapturingEntity != null)
+ {
+ _popup.PopupClient(
+ "This location is already being captured.",
+ console,
+ user);
+
+ return;
+ }
+
+
+ var capture = EnsureComp(grid);
+
+
+ // Person who pressed the capture button
+ capture.CapturingEntity = user;
+ capture.CapturingPlayerName = Name(user);
+
+
+ // ID card in the console
+ capture.CapturingIdCard = component.InsertedId.Value;
+
+
+ // Capture timing
+ capture.CaptureStart = _gameTiming.CurTime;
+ capture.CaptureDuration = TimeSpan.FromSeconds(component.CaptureTime);
+
+
+ // Force start announcement
+ capture.LastBroadcastPercent = -1;
+
+
+ // Store faction/company from inserted ID card
+ if (TryComp(component.InsertedId.Value, out var card))
+ {
+ capture.CapturingFaction = card.CompanyName.ToString();
+ }
+ else
+ {
+ capture.CapturingFaction = "None";
+ }
+
+
+ poi.CaptureProgress = 0;
+ poi.IsBeingCaptured = true;
+
+
+ Dirty(grid, poi);
+
+
+ _popup.PopupClient(
+ "POI capture started.",
+ console,
+ user);
+ }
+}
\ No newline at end of file
diff --git a/Content.Shared/_Mono/Shipyard/ShipAccessReaderSystem.cs b/Content.Shared/_Mono/Shipyard/ShipAccessReaderSystem.cs
index 0135d3576b3..9f510bf73b3 100644
--- a/Content.Shared/_Mono/Shipyard/ShipAccessReaderSystem.cs
+++ b/Content.Shared/_Mono/Shipyard/ShipAccessReaderSystem.cs
@@ -13,6 +13,7 @@
using Content.Shared.Ghost;
using Content.Shared.Silicons.StationAi;
using Robust.Shared.Map;
+using Content.Shared._Mono.POI.Components;
namespace Content.Shared._Mono.Shipyard;
@@ -112,6 +113,24 @@ public bool HasShipAccess(EntityUid user, EntityUid target, ShipAccessReaderComp
var gridUid = targetTransform.GridUid.Value;
+ // Find all accessible ID cards once
+ var accessibleCards = FindAccessibleIdCards(user);
+
+ // POI faction access
+ if (TryComp(gridUid, out var poi))
+ {
+ if (!string.IsNullOrEmpty(poi.OwnerFaction))
+ {
+ foreach (var cardUid in accessibleCards)
+ {
+ if (TryComp(cardUid, out var card) && card.CompanyName == poi.OwnerFaction)
+ {
+ return true;
+ }
+ }
+ }
+ }
+
// Check if the grid has a ship deed (is a purchased ship)
if (!TryComp(gridUid, out var shipDeed))
{
@@ -119,9 +138,6 @@ public bool HasShipAccess(EntityUid user, EntityUid target, ShipAccessReaderComp
return true; // Not a ship with a deed, allow normal access
}
- // Find all accessible ID cards for the user
- var accessibleCards = FindAccessibleIdCards(user);
-
// Check for company-based access (USSP, Rogue, TSF) using ID card company
if (TryComp(gridUid, out var shipCompany))
{
diff --git a/Content.Shared/_NF/Shipyard/Components/ShuttleDeedComponent.cs b/Content.Shared/_NF/Shipyard/Components/ShuttleDeedComponent.cs
index fa63688394b..94dd6f5d9dc 100644
--- a/Content.Shared/_NF/Shipyard/Components/ShuttleDeedComponent.cs
+++ b/Content.Shared/_NF/Shipyard/Components/ShuttleDeedComponent.cs
@@ -1,13 +1,14 @@
using Content.Shared._NF.ShuttleRecords;
using Robust.Shared.GameStates;
using Content.Shared.Shuttles.Systems;
+using Content.Shared.Access.Components;
namespace Content.Shared._NF.Shipyard.Components;
///
/// Tied to an ID card when a ship is purchased. 1 ship per captain.
///
-[RegisterComponent, NetworkedComponent, Access(typeof(SharedShipyardSystem), typeof(SharedShuttleRecordsSystem), typeof(SharedShuttleConsoleLockSystem))]
+[RegisterComponent, NetworkedComponent, Access(typeof(SharedShipyardSystem), typeof(SharedShuttleRecordsSystem), typeof(SharedShuttleConsoleLockSystem), Other = AccessPermissions.ReadWrite)]
public sealed partial class ShuttleDeedComponent : Component
{
public const int MaxNameLength = 30;
diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
index b6cf64178f9..0a249b3f588 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
@@ -688,6 +688,8 @@
tags:
- NuclearOperative
- SyndicateAgent
+ - type: IdCard
+ faction: PDV
- type: entity
parent: IDCardStandard
diff --git a/Resources/Prototypes/_Mono/Entities/Objects/Devices/Misc/identification_cards.yml b/Resources/Prototypes/_Mono/Entities/Objects/Devices/Misc/identification_cards.yml
index 9a398e11a0c..03831ae01cd 100644
--- a/Resources/Prototypes/_Mono/Entities/Objects/Devices/Misc/identification_cards.yml
+++ b/Resources/Prototypes/_Mono/Entities/Objects/Devices/Misc/identification_cards.yml
@@ -1,6 +1,15 @@
#MARK: USSP
- type: entity
parent: IDCardStandard
+ id: USSPBaseIDCard
+ name: USSP identification card
+ abstract: true
+ components:
+ - type: IdCard
+ faction: USSP
+
+- type: entity
+ parent: USSPBaseIDCard
id: USSPRiflemanIDCard
name: USSP rifleman ID card
components:
@@ -11,9 +20,11 @@
layers:
- state: usspbase
- state: id_rifleman
-
+ - type: IdCard
+ faction: USSP
+
- type: entity
- parent: IDCardStandard
+ parent: USSPBaseIDCard
id: USSPSergeantIDCard
name: USSP serzhant ID card
components:
@@ -24,9 +35,11 @@
layers:
- state: usspbase
- state: id_sergeant
-
+ - type: IdCard
+ faction: USSP
+
- type: entity
- parent: IDCardStandard
+ parent: USSPBaseIDCard
id: USSPCommissarIDCard
name: USSP commissar ID card
components:
@@ -37,11 +50,21 @@
layers:
- state: usspbase
- state: id_commissar
-
+ - type: IdCard
+ faction: USSP
+
# MARK: Medical
+- type: entity
+ parent: IDCardStandard
+ id: MedicalBaseIDCard
+ name: USSP identification card
+ abstract: true
+ components:
+ - type: IdCard
+ faction: CC
- type: entity
- parent: [IDCardStandard]
+ parent: MedicalBaseIDCard
id: MedMedicIDCard
name: emergency responder ID card
components:
@@ -56,11 +79,12 @@
sprite: _NF/Objects/Misc/id_cards.rsi
- type: Item
heldPrefix: medic
-
+ - type: IdCard
+ faction: CC
+
# MARK: TSF Engi
-
- type: entity
- parent: IDCardStandard
+ parent: CadetIDCard
id: TsfEngiIDCard
name: TSFMC engineer ID card
components:
@@ -75,11 +99,10 @@
sprite: _NF/Objects/Misc/id_cards.rsi
- type: Item
heldPrefix: nfsd
-
+
# MARK: MARSOC
-
- type: entity
- parent: IDCardStandard
+ parent: CadetIDCard
id: TsfMarsocIDCard
name: TSFMC MARSOC operative ID card
components:
@@ -93,7 +116,7 @@
sprite: Objects/Misc/id_cards.rsi
- type: Item
heldPrefix: blue
-
+
# MARK: PDV
- type: entity
@@ -108,7 +131,7 @@
layers:
- state: base
- state: id_rakhshan
-
+
- type: entity
parent: PirateIDCard
id: PDVDenasvarIDCard
@@ -122,7 +145,7 @@
layers:
- state: base
- state: id_denasvar
-
+
- type: entity
parent: PirateIDCard
id: PDVAsvaranIDCard
@@ -135,7 +158,7 @@
layers:
- state: base
- state: id_asvaran
-
+
- type: entity
parent: PirateIDCard
id: PDVGrandVizierIDCard
@@ -148,7 +171,7 @@
layers:
- state: vizierbase
- state: id_vizier
-
+
- type: entity
parent: PirateIDCard
id: PDVTarkhanIDCard
@@ -161,10 +184,10 @@
layers:
- state: vizierbase
- state: id_vizier
-
+
- type: entity
name: spasaka ID card
- parent: [ IDCardStandard, BaseFactionGearPDVT2 ]
+ parent: [ PirateIDCard, BaseFactionGearPDVT2 ]
id: PDVSpasakaIDCard
suffix: Chameleon
components:
@@ -199,10 +222,19 @@
type: ChameleonBoundUserInterface
- type: Contraband # Frontier
hideValues: true # Frontier
-
+
#MARK: Viper Group
- type: entity
parent: IDCardStandard
+ id: VGBaseIDCard
+ name: VG identification card
+ abstract: true
+ components:
+ - type: IdCard
+ faction: VG
+
+- type: entity
+ parent: VGBaseIDCard
id: VGInfanteerIDCard
name: VG infanteer ID card
components:
@@ -217,9 +249,9 @@
sprite: Objects/Misc/id_cards.rsi
- type: Item
heldPrefix: default
-
+
- type: entity
- parent: IDCardStandard
+ parent: VGBaseIDCard
id: VGLieutenantIDCard
name: VG lieutenant ID card
components:
@@ -234,9 +266,9 @@
sprite: Objects/Misc/id_cards.rsi
- type: Item
heldPrefix: default
-
+
- type: entity
- parent: IDCardStandard
+ parent: VGBaseIDCard
id: VGCommanderIDCard
name: VG commander ID card
components:
@@ -250,4 +282,4 @@
- type: Clothing
sprite: Objects/Misc/id_cards.rsi
- type: Item
- heldPrefix: default
+ heldPrefix: default
\ No newline at end of file
diff --git a/Resources/Prototypes/_Mono/Entities/Structures/Machines/computers.yml b/Resources/Prototypes/_Mono/Entities/Structures/Machines/computers.yml
index 01dd3b817c6..3b6bcd5066c 100644
--- a/Resources/Prototypes/_Mono/Entities/Structures/Machines/computers.yml
+++ b/Resources/Prototypes/_Mono/Entities/Structures/Machines/computers.yml
@@ -10,3 +10,41 @@
- type: AccessReader
enabled: false
+- type: entity
+ parent: ComputerShuttle
+ id: ShuttleConsoleCapturable
+ name: POI capture console
+ description: Used to claim control of a point of interest.
+ components:
+ - type: CapturableShuttleConsole
+ - type: ItemSlots
+ slots:
+ disk_slot:
+ name: Disk
+ insertSound:
+ path: /Audio/Machines/terminal_insert_disc.ogg
+ ejectSound:
+ path: /Audio/Machines/terminal_insert_disc.ogg
+ whitelist:
+ components:
+ - ShuttleDestinationCoordinates
+ id_slot:
+ name: ID Card
+ insertSound:
+ path: /Audio/Machines/id_swipe.ogg
+ ejectSound:
+ path: /Audio/Machines/id_swipe.ogg
+ whitelist:
+ components:
+ - IdCard
+ - type: ContainerContainer
+ containers:
+ board: !type:Container
+ ents: []
+ disk_slot: !type:ContainerSlot {}
+ key_slots: !type:Container
+ id_slot: !type:ContainerSlot {}
+ - type: ContainerFill
+ containers:
+ key_slots:
+ - EncryptionKeyTraffic
\ No newline at end of file
diff --git a/Resources/Prototypes/_Mono/ai_factions.yml b/Resources/Prototypes/_Mono/ai_factions.yml
index e7df8215b2e..6f5c400268c 100644
--- a/Resources/Prototypes/_Mono/ai_factions.yml
+++ b/Resources/Prototypes/_Mono/ai_factions.yml
@@ -1,5 +1,6 @@
- type: npcFaction
id: CC
+ name: CC
hostile:
- SimpleHostile
- Zombie
@@ -30,6 +31,7 @@
- type: npcFaction
id: USSP
+ name: USSP
neutral:
- CC
- NanoTrasen
@@ -52,6 +54,7 @@
- type: npcFaction
id: MD
+ name: MD
friendly:
- CC
neutral:
@@ -73,6 +76,7 @@
- type: npcFaction
id: VG
+ name: VG
neutral:
- CC
- NanoTrasen
diff --git a/Resources/Prototypes/_NF/Entities/Objects/Devices/Misc/identification_cards.yml b/Resources/Prototypes/_NF/Entities/Objects/Devices/Misc/identification_cards.yml
index 47ed900b0be..96a6d60893f 100644
--- a/Resources/Prototypes/_NF/Entities/Objects/Devices/Misc/identification_cards.yml
+++ b/Resources/Prototypes/_NF/Entities/Objects/Devices/Misc/identification_cards.yml
@@ -30,6 +30,8 @@
- state: idmercenary
- type: Clothing
sprite: _NF/Objects/Misc/id_cards.rsi
+ - type: IdCard
+ faction: Private Contractors
- type: entity
parent: IDCardStandard
@@ -45,6 +47,8 @@
- state: idpilot
- type: Clothing
sprite: _NF/Objects/Misc/id_cards.rsi
+ - type: IdCard
+ faction: CC
- type: entity
parent: IDCardStandard
@@ -62,6 +66,8 @@
sprite: _NF/Objects/Misc/id_cards.rsi
- type: Item
heldPrefix: silver
+ - type: IdCard
+ faction: CC
- type: entity
parent: IDCardStandard
@@ -75,6 +81,8 @@
layers:
- state: nfsd
- state: idpublicaffairsliaison
+ - type: IdCard
+ faction: TSF
- type: entity
parent: IDCardStandard
@@ -92,6 +100,8 @@
sprite: _NF/Objects/Misc/id_cards.rsi
- type: Item
heldPrefix: nfsd
+ - type: IdCard
+ faction: TSF
- type: entity
parent: CadetIDCard
@@ -105,7 +115,9 @@
layers:
- state: nfsd
- state: idnfsddeputy
-
+ - type: IdCard
+ faction: TSF
+
- type: entity
parent: CadetIDCard
id: BrigmedicNFIDCard
@@ -118,7 +130,9 @@
layers:
- state: nfsd
- state: idnfsdbrigmed
-
+ - type: IdCard
+ faction: TSF
+
- type: entity
parent: CadetIDCard
id: SergeantIDCard
@@ -131,7 +145,9 @@
layers:
- state: nfsd
- state: idnfsdsergeant
-
+ - type: IdCard
+ faction: TSF
+
- type: entity
parent: CadetIDCard
id: BailiffIDCard
@@ -144,7 +160,9 @@
layers:
- state: nfsd
- state: idnfsdbailiff
-
+ - type: IdCard
+ faction: TSF
+
- type: entity
parent: CadetIDCard
id: ShriffIDCard
@@ -159,7 +177,9 @@
- state: idnfsdsheriff
- type: Item
heldPrefix: silver
-
+ - type: IdCard
+ faction: TSF
+
- type: entity
parent: CadetIDCard
id: NFDetectiveIDCard
@@ -172,7 +192,9 @@
layers:
- state: nfsd
- state: idnfsddetective
-
+ - type: IdCard
+ faction: TSF
+
- type: entity
parent: SecurityIDCard
id: SecurityGuardIDCard
@@ -180,7 +202,9 @@
components:
- type: PresetIdCard
job: SecurityGuard
-
+ - type: IdCard
+ faction: CC
+
- type: entity
parent: ERTChaplainIDCard
id: ERTMailCarrierIDCard
@@ -188,12 +212,13 @@
components:
- type: IdCard
jobTitle: job-title-ert-mail-carrier
+ faction: CC
- type: Sprite
sprite: _NF/Objects/Misc/id_cards.rsi
layers:
- state: gold
- state: ert_mailcarrier
-
+
- type: entity
parent: HoPIDCard
id: SrIDCard
@@ -201,7 +226,9 @@
components:
- type: PresetIdCard
job: StationRepresentative
-
+ - type: IdCard
+ faction: CC
+
- type: entity
parent: CCServiceWorkerIDCard
id: CCServiceWorkerNFIDCard #Mono
@@ -215,14 +242,18 @@
layers:
- state: default
- state: idvalet
-
+ - type: IdCard
+ faction: CC
+
- type: entity
parent: JanitorIDCard
id: NFJanitorIDCard
components:
- type: PresetIdCard
job: NFJanitor
-
+ - type: IdCard
+ faction: CC
+
- type: entity
parent: PassengerIDCard
id: ContractorIDCard
@@ -235,7 +266,9 @@
layers:
- state: default
- state: idcontractor
-
+ - type: IdCard
+ faction: CC
+
- type: entity
parent: PunPunIDCard
id: YipYipIDCard
@@ -243,7 +276,9 @@
components:
- type: PresetIdCard
name: Yip Yip
-
+ - type: IdCard
+ faction: CC
+
- type: entity
parent: IDCardStandard
id: DocIDCard
@@ -260,7 +295,9 @@
sprite: _NF/Objects/Misc/id_cards.rsi
- type: Item
heldPrefix: medic #temporary to OBSERVE
-
+ - type: IdCard
+ faction: CC
+
# Cats
- type: entity
parent: CourierIDCard
@@ -269,7 +306,9 @@
components:
- type: PresetIdCard
name: Clippy
-
+ - type: IdCard
+ faction: CC
+
- type: entity
parent: PDVAsvaranIDCard
id: ClarpyIDCard
@@ -277,7 +316,9 @@
components:
- type: PresetIdCard
name: Clarpy
-
+ - type: IdCard
+ faction: PDV
+
- type: entity
parent: DeputyIDCard
id: CappyIDCard
@@ -285,3 +326,6 @@
components:
- type: PresetIdCard
name: Cappy
+ - type: IdCard
+ faction: TSF
+
\ No newline at end of file