diff --git a/Content.Server/_Sunrise/AddWantedStatus/AddWantedStatusSystem.cs b/Content.Server/_Sunrise/AddWantedStatus/AddWantedStatusSystem.cs new file mode 100644 index 0000000000..5c3ca94a21 --- /dev/null +++ b/Content.Server/_Sunrise/AddWantedStatus/AddWantedStatusSystem.cs @@ -0,0 +1,101 @@ +using Content.Server.Actions; +using Content.Server.CriminalRecords.Systems; +using Content.Server.Radio.EntitySystems; +using Content.Server.Station.Systems; +using Content.Server.StationRecords.Systems; +using Content.Shared._Sunrise.AddWantedStatus; +using Content.Shared.Actions; +using Content.Shared.Clothing.Components; +using Content.Shared.Humanoid; +using Content.Shared.IdentityManagement; +using Content.Shared.Security; +using Content.Shared.StationRecords; + +namespace Content.Server._Sunrise.AddWantedStatus; + +public sealed partial class AddWantedStatusSystem : EntitySystem +{ + [Dependency] private readonly ActionsSystem _actions = default!; + [Dependency] private readonly CriminalRecordsSystem _criminalRecords = default!; + [Dependency] private readonly StationRecordsSystem _records = default!; + [Dependency] private readonly StationSystem _station = default!; + [Dependency] private readonly RadioSystem _radio = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnAddWanted); + SubscribeLocalEvent(OnGetItemActions); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + var (uid, comp) = ent; + if (string.IsNullOrEmpty(comp.Action)) + return; + + _actions.AddAction(uid, ref comp.ActionEntity, comp.Action); + } + + private void OnAddWanted(Entity ent, ref AddWantedEvent args) + { + var target = args.Target; + var performer = args.Performer; + if (!HasComp(target)) + return; + + if (_station.GetOwningStation(performer) is not { } station) + return; + + var targetName = Identity.Name(target, EntityManager); + + foreach (var (key, record) in _records.GetRecordsOfType(station)) + { + if (!string.Equals(record.Name?.Trim(), targetName?.Trim(), StringComparison.OrdinalIgnoreCase)) + continue; + + var recordKey = new StationRecordKey(key, station); + var reason = Loc.GetString("criminal-records-reason-visor"); + + if (_criminalRecords.TryChangeStatus(recordKey, SecurityStatus.Wanted, reason)) + { + SendRadioMessage(ent, reason, performer, record); + break; + } + } + } + + private void OnGetItemActions(Entity ent, ref GetItemActionsEvent args) + { + if (!TryComp(ent.Owner, out var comp)) + return; + + if (comp.Slots != args.SlotFlags) + return; + + args.AddAction(ent.Comp.ActionEntity); + } + + + private void SendRadioMessage(EntityUid sender, string? reason, EntityUid officerUid, GeneralStationRecord record) + { + var wantedName = record.Name; + var wantedJobTitle = record.JobTitle ?? Loc.GetString("job-name-unknown"); + var officer = Loc.GetString("criminal-records-console-unknown-officer"); + + // Officer + var getIdEvent = new TryGetIdentityShortInfoEvent(null, officerUid); + RaiseLocalEvent(getIdEvent); + if (getIdEvent.Title != null) + officer = getIdEvent.Title; + + // Reason + if (string.IsNullOrWhiteSpace(reason)) + reason = Loc.GetString("wanted-list-unknown-reason-label"); + + var message = Loc.GetString("criminal-records-console-wanted", [("name", wantedName), ("officer", officer), ("reason", reason), ("job", wantedJobTitle)]); + _radio.SendRadioMessage(sender, message, "Security", sender); + } +} diff --git a/Content.Shared/_Sunrise/AddWantedStatus/AddWantedEvent.cs b/Content.Shared/_Sunrise/AddWantedStatus/AddWantedEvent.cs new file mode 100644 index 0000000000..25e868d28f --- /dev/null +++ b/Content.Shared/_Sunrise/AddWantedStatus/AddWantedEvent.cs @@ -0,0 +1,7 @@ +using Content.Shared.Actions; + +namespace Content.Shared._Sunrise.AddWantedStatus; + +public sealed partial class AddWantedEvent : EntityTargetActionEvent +{ +} diff --git a/Content.Shared/_Sunrise/AddWantedStatus/AddWantedStatusComponent.cs b/Content.Shared/_Sunrise/AddWantedStatus/AddWantedStatusComponent.cs new file mode 100644 index 0000000000..5551c45dd2 --- /dev/null +++ b/Content.Shared/_Sunrise/AddWantedStatus/AddWantedStatusComponent.cs @@ -0,0 +1,16 @@ +using Content.Shared.Actions.Components; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared._Sunrise.AddWantedStatus; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class AddWantedStatusComponent : Component +{ + [DataField] + public EntProtoId Action = "ActionAddWanted"; + + [AutoNetworkedField, ViewVariables] + public EntityUid? ActionEntity; +} + diff --git a/Resources/Locale/ru-RU/_prototypes/_sunrise/actions/add_wanted.ftl b/Resources/Locale/ru-RU/_prototypes/_sunrise/actions/add_wanted.ftl new file mode 100644 index 0000000000..8d098317ac --- /dev/null +++ b/Resources/Locale/ru-RU/_prototypes/_sunrise/actions/add_wanted.ftl @@ -0,0 +1,2 @@ +ent-ActionAddWanted = Установить розыск + .desc = Устанавливает статус розыска на цель. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_strings/_sunrise/add-wanted-status/add-wanted-status.ftl b/Resources/Locale/ru-RU/_strings/_sunrise/add-wanted-status/add-wanted-status.ftl new file mode 100644 index 0000000000..571b2a2d5b --- /dev/null +++ b/Resources/Locale/ru-RU/_strings/_sunrise/add-wanted-status/add-wanted-status.ftl @@ -0,0 +1 @@ +criminal-records-reason-visor = Установлено охранным визором \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml b/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml index 678ffc08bb..ec870ced49 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml @@ -4,15 +4,15 @@ name: gar glasses description: Go beyond impossible and kick reason to the curb! components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/gar.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/gar.rsi - - type: MeleeWeapon - attackRate: 1.5 - damage: - types: - Blunt: 7 + - type: Sprite + sprite: Clothing/Eyes/Glasses/gar.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/gar.rsi + - type: MeleeWeapon + attackRate: 1.5 + damage: + types: + Blunt: 7 - type: entity parent: ClothingEyesBase @@ -20,18 +20,18 @@ name: orange gar glasses description: Just who the hell do you think I am?! components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/gar.rsi - state: icon-alt - - type: Clothing - sprite: Clothing/Eyes/Glasses/gar.rsi - equippedPrefix: alt - - type: Item - heldPrefix: alt - - type: MeleeWeapon - damage: - types: - Blunt: 10 + - type: Sprite + sprite: Clothing/Eyes/Glasses/gar.rsi + state: icon-alt + - type: Clothing + sprite: Clothing/Eyes/Glasses/gar.rsi + equippedPrefix: alt + - type: Item + heldPrefix: alt + - type: MeleeWeapon + damage: + types: + Blunt: 10 - type: entity parent: ClothingEyesBase @@ -39,18 +39,18 @@ name: giga gar glasses description: We evolve past the person we were a minute before. Little by little we advance with each turn. That's how a drill works! components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/gar.rsi - state: icon-super - - type: Clothing - sprite: Clothing/Eyes/Glasses/gar.rsi - equippedPrefix: super - - type: Item - heldPrefix: super - - type: MeleeWeapon - damage: - types: - Blunt: 10 + - type: Sprite + sprite: Clothing/Eyes/Glasses/gar.rsi + state: icon-super + - type: Clothing + sprite: Clothing/Eyes/Glasses/gar.rsi + equippedPrefix: super + - type: Item + heldPrefix: super + - type: MeleeWeapon + damage: + types: + Blunt: 10 - type: entity parent: [ClothingEyesBase, BaseEngineeringContraband] @@ -58,13 +58,13 @@ name: engineering goggles #less confusion description: Green-tinted goggles using a proprietary polymer that provides protection from eye damage of all types. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/meson.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/meson.rsi - - type: EyeProtection - - type: IdentityBlocker - coverage: EYES + - type: Sprite + sprite: Clothing/Eyes/Glasses/meson.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/meson.rsi + - type: EyeProtection + - type: IdentityBlocker + coverage: EYES - type: entity parent: ClothingEyesBase @@ -72,15 +72,15 @@ name: glasses description: A pair of spectacular spectacles with prescription lenses. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/glasses.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/glasses.rsi - - type: VisionCorrection - - type: Tag - tags: - - HamsterWearable - - WhitelistChameleon + - type: Sprite + sprite: Clothing/Eyes/Glasses/glasses.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/glasses.rsi + - type: VisionCorrection + - type: Tag + tags: + - HamsterWearable + - WhitelistChameleon - type: entity parent: ClothingEyesBase @@ -88,13 +88,13 @@ name: jensen glasses description: A pair of yellow tinted folding glasses. You never asked for these. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/jensen.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/jensen.rsi - - type: Tag - tags: - - WhitelistChameleon + - type: Sprite + sprite: Clothing/Eyes/Glasses/jensen.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/jensen.rsi + - type: Tag + tags: + - WhitelistChameleon - type: entity parent: ClothingEyesBase @@ -102,15 +102,15 @@ name: jamjar glasses description: These retro glasses remind you of a simpler time. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/jamjar.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/jamjar.rsi - - type: VisionCorrection - - type: Tag - tags: - - HamsterWearable - - WhitelistChameleon + - type: Sprite + sprite: Clothing/Eyes/Glasses/jamjar.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/jamjar.rsi + - type: VisionCorrection + - type: Tag + tags: + - HamsterWearable + - WhitelistChameleon - type: entity parent: ClothingEyesBase @@ -118,14 +118,14 @@ name: outlaw glasses description: A must for every self-respecting undercover agent. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/outlawglasses.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/outlawglasses.rsi - - type: VisionCorrection - - type: IdentityBlocker - - type: StaticPrice - price: 500 + - type: Sprite + sprite: Clothing/Eyes/Glasses/outlawglasses.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/outlawglasses.rsi + - type: VisionCorrection + - type: IdentityBlocker + - type: StaticPrice + price: 500 - type: entity parent: ClothingEyesBase @@ -133,16 +133,16 @@ name: cheap sunglasses description: A pair of black sunglasses. Doesn't block light well, more of an accessory than something useful. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/sunglasses.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/sunglasses.rsi - - type: Tag - tags: - - HamsterWearable - - WhitelistChameleon - - type: IdentityBlocker - coverage: EYES + - type: Sprite + sprite: Clothing/Eyes/Glasses/sunglasses.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/sunglasses.rsi + - type: Tag + tags: + - HamsterWearable + - WhitelistChameleon + - type: IdentityBlocker + coverage: EYES - type: entity parent: ClothingEyesGlassesCheapSunglasses @@ -150,14 +150,14 @@ name: sun glasses description: A pair of black sunglasses. components: - - type: FlashImmunity - - type: EyeProtection - protectionTime: 5 - - type: Tag - tags: - - Sunglasses - - HamsterWearable - - WhitelistChameleon + - type: FlashImmunity + - type: EyeProtection + protectionTime: 5 + - type: Tag + tags: + - Sunglasses + - HamsterWearable + - WhitelistChameleon - type: entity parent: [ClothingEyesBase, ShowSecurityIcons, BaseSecurityContraband] @@ -165,26 +165,27 @@ name: security glasses description: Upgraded sunglasses that provide flash immunity and a security HUD. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/secglasses.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/secglasses.rsi - - type: FlashImmunity - - type: EyeProtection - protectionTime: 5 - - type: Construction - graph: GlassesSecHUD - node: glassesSec - - type: Tag - tags: - - HamsterWearable - - WhitelistChameleon - - type: GuideHelp - guides: - - Security - - Antagonists - - type: IdentityBlocker - coverage: EYES + - type: Sprite + sprite: Clothing/Eyes/Glasses/secglasses.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/secglasses.rsi + - type: FlashImmunity + - type: EyeProtection + protectionTime: 5 + - type: Construction + graph: GlassesSecHUD + node: glassesSec + - type: Tag + tags: + - HamsterWearable + - WhitelistChameleon + - type: GuideHelp + guides: + - Security + - Antagonists + - type: IdentityBlocker + coverage: EYES + - type: AddWantedStatus # Sunrise-edit - type: entity parent: [ClothingEyesBase, BaseCommandContraband] @@ -192,20 +193,20 @@ name: administration glasses description: Upgraded sunglasses that provide flash immunity and show ID card status. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/commandglasses.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/commandglasses.rsi - - type: FlashImmunity - - type: EyeProtection - protectionTime: 5 - - type: Tag - tags: - - HamsterWearable - - WhitelistChameleon - - type: IdentityBlocker - coverage: EYES - - type: ShowJobIcons + - type: Sprite + sprite: Clothing/Eyes/Glasses/commandglasses.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/commandglasses.rsi + - type: FlashImmunity + - type: EyeProtection + protectionTime: 5 + - type: Tag + tags: + - HamsterWearable + - WhitelistChameleon + - type: IdentityBlocker + coverage: EYES + - type: ShowJobIcons - type: entity parent: ClothingEyesBase @@ -213,15 +214,15 @@ name: mercenary glasses description: Glasses made for combat, to protect the eyes from bright blinding flashes. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/mercglasses.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/mercglasses.rsi - - type: FlashImmunity - - type: EyeProtection - protectionTime: 5 - - type: IdentityBlocker - coverage: EYES + - type: Sprite + sprite: Clothing/Eyes/Glasses/mercglasses.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/mercglasses.rsi + - type: FlashImmunity + - type: EyeProtection + protectionTime: 5 + - type: IdentityBlocker + coverage: EYES #Make a scanner category when these actually function and we get the trayson - type: entity @@ -230,22 +231,22 @@ name: optical thermal scanner description: Thermals in the shape of glasses. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/thermal.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/thermal.rsi - - type: GroupExamine - - type: IdentityBlocker - coverage: EYES - # Sunrise-Start - - type: ToggleClothing - action: ActionToggleThermalVision - disableOnUnequip: true - targetSlot: eyes - - type: ComponentToggler - parent: true - components: - - type: ThermalVision + - type: Sprite + sprite: Clothing/Eyes/Glasses/thermal.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/thermal.rsi + - type: GroupExamine + - type: IdentityBlocker + coverage: EYES + # Sunrise-Start + - type: ToggleClothing + action: ActionToggleThermalVision + disableOnUnequip: true + targetSlot: eyes + - type: ComponentToggler + parent: true + components: + - type: ThermalVision # Sunrise-End - type: entity @@ -263,41 +264,46 @@ coverage: EYES - type: entity - parent: [ClothingEyesBase, BaseMajorContraband, PowerCellSlotSmallItem, BaseNightVisionDevice] # Sunrise-Edit + parent: [ + ClothingEyesBase, + BaseMajorContraband, + PowerCellSlotSmallItem, + BaseNightVisionDevice, + ] # Sunrise-Edit id: ClothingEyesVisorNinja name: ninja visor description: An advanced visor protecting a ninja's eyes from flashing lights. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/ninjavisor.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/ninjavisor.rsi - - type: FlashImmunity - # Sunrise-Start - - type: ItemToggle - predictable: false - onUse: false - canActivateInhand: false - soundActivate: - path: /Audio/_Sunrise/Items/Goggles/activate.ogg - soundDeactivate: - path: /Audio/_Sunrise/Items/Goggles/deactivate.ogg - soundFailToActivate: - path: /Audio/Machines/button.ogg - - type: PowerCellSlot - cellSlotId: cell_slot - - type: ContainerContainer - containers: - cell_slot: !type:ContainerSlot - - type: ItemSlots - slots: - cell_slot: - name: power-cell-slot-component-slot-name-default - startingItem: PowerCellSmall - - type: ToggleCellDraw - - type: PowerCellDraw - drawRate: 3.5 - useRate: 20 + - type: Sprite + sprite: Clothing/Eyes/Glasses/ninjavisor.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/ninjavisor.rsi + - type: FlashImmunity + # Sunrise-Start + - type: ItemToggle + predictable: false + onUse: false + canActivateInhand: false + soundActivate: + path: /Audio/_Sunrise/Items/Goggles/activate.ogg + soundDeactivate: + path: /Audio/_Sunrise/Items/Goggles/deactivate.ogg + soundFailToActivate: + path: /Audio/Machines/button.ogg + - type: PowerCellSlot + cellSlotId: cell_slot + - type: ContainerContainer + containers: + cell_slot: !type:ContainerSlot + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellSmall + - type: ToggleCellDraw + - type: PowerCellDraw + drawRate: 3.5 + useRate: 20 # Sunrise-End - type: entity @@ -306,17 +312,17 @@ name: noir-tech glasses description: A pair of glasses that simulate what the world looked like before the invention of color. components: - - type: Sprite - sprite: Clothing/Eyes/Glasses/noir.rsi - - type: Clothing - sprite: Clothing/Eyes/Glasses/sunglasses.rsi - - type: IdentityBlocker - coverage: EYES - - type: FlashImmunity - - type: EyeProtection - protectionTime: 5 - - type: NoirOverlay - - type: Tag - tags: - - HamsterWearable - - WhitelistChameleon + - type: Sprite + sprite: Clothing/Eyes/Glasses/noir.rsi + - type: Clothing + sprite: Clothing/Eyes/Glasses/sunglasses.rsi + - type: IdentityBlocker + coverage: EYES + - type: FlashImmunity + - type: EyeProtection + protectionTime: 5 + - type: NoirOverlay + - type: Tag + tags: + - HamsterWearable + - WhitelistChameleon diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml index 384ec7bf1c..600efd6d7b 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml @@ -61,6 +61,7 @@ tags: - HudSecurity - WhitelistChameleon + - type: AddWantedStatus # Sunrise-edit - type: entity parent: [ClothingEyesBase, BaseCommandContraband] diff --git a/Resources/Prototypes/_Sunrise/Actions/add_wanted.yml b/Resources/Prototypes/_Sunrise/Actions/add_wanted.yml new file mode 100644 index 0000000000..bb1321e495 --- /dev/null +++ b/Resources/Prototypes/_Sunrise/Actions/add_wanted.yml @@ -0,0 +1,15 @@ +- type: entity + id: ActionAddWanted + name: Submit a wanted + description: Puts the target on the wanted list. + components: + - type: Action + useDelay: 1 + icon: + sprite: Clothing/Eyes/Hud/sec.rsi + state: icon + - type: TargetAction + range: -1 + - type: EntityTargetAction + canTargetSelf: false + event: !type:AddWantedEvent