Визоры СБ теперь могут накладывать статус розыска (#2738)

This commit is contained in:
Hero010h 2025-08-09 18:07:20 +03:00 committed by GitHub
parent 83ff871aab
commit 5e2d623e62
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 344 additions and 195 deletions

View file

@ -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<AddWantedStatusComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<AddWantedStatusComponent, AddWantedEvent>(OnAddWanted);
SubscribeLocalEvent<AddWantedStatusComponent, GetItemActionsEvent>(OnGetItemActions);
}
private void OnMapInit(Entity<AddWantedStatusComponent> 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<AddWantedStatusComponent> ent, ref AddWantedEvent args)
{
var target = args.Target;
var performer = args.Performer;
if (!HasComp<HumanoidAppearanceComponent>(target))
return;
if (_station.GetOwningStation(performer) is not { } station)
return;
var targetName = Identity.Name(target, EntityManager);
foreach (var (key, record) in _records.GetRecordsOfType<GeneralStationRecord>(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<AddWantedStatusComponent> ent, ref GetItemActionsEvent args)
{
if (!TryComp<ClothingComponent>(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);
}
}

View file

@ -0,0 +1,7 @@
using Content.Shared.Actions;
namespace Content.Shared._Sunrise.AddWantedStatus;
public sealed partial class AddWantedEvent : EntityTargetActionEvent
{
}

View file

@ -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<TargetActionComponent> Action = "ActionAddWanted";
[AutoNetworkedField, ViewVariables]
public EntityUid? ActionEntity;
}

View file

@ -0,0 +1,2 @@
ent-ActionAddWanted = Установить розыск
.desc = Устанавливает статус розыска на цель.

View file

@ -0,0 +1 @@
criminal-records-reason-visor = Установлено охранным визором

View file

@ -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

View file

@ -61,6 +61,7 @@
tags:
- HudSecurity
- WhitelistChameleon
- type: AddWantedStatus # Sunrise-edit
- type: entity
parent: [ClothingEyesBase, BaseCommandContraband]

View file

@ -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