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