[Access(typeof(SharedIdCardSystem), typeof(SharedPdaSystem), typeof(SharedAgentIdCardSystem), Other = AccessPermissions.ReadWrite)]
public LocId? JobTitle;
+ [DataField]
+ [AutoNetworkedField]
private string? _jobTitle;
[Access(typeof(SharedIdCardSystem), typeof(SharedPdaSystem), typeof(SharedAgentIdCardSystem), Other = AccessPermissions.ReadWriteExecute)]
/// </summary>
[DataField]
[AutoNetworkedField]
- public HashSet<ProtoId<DepartmentPrototype>>? AllowedDepartments = ["Security"];
+ public HashSet<ProtoId<DepartmentPrototype>> AllowedDepartments = new();
+
+ /// <summary>
+ /// Which jobs is this item restricted to?
+ /// If empty, no jobs are allowed to use this beyond the allowed departments.
+ /// </summary>
+ [DataField]
+ [AutoNetworkedField]
+ public HashSet<ProtoId<JobPrototype>> AllowedJobs = new();
}
public LocId ExamineText;
/// <summary>
- /// When examining the contraband, should this take into account the viewer's departments?
+ /// When examining the contraband, should this take into account the viewer's departments and job?
/// </summary>
[DataField]
- public bool ShowDepartments;
+ public bool ShowDepartmentsAndJobs;
}
contraband.Severity = other.Severity;
contraband.AllowedDepartments = other.AllowedDepartments;
+ contraband.AllowedJobs = other.AllowedJobs;
Dirty(uid, contraband);
}
using (args.PushGroup(nameof(ContrabandComponent)))
{
+ // TODO shouldn't department prototypes have a localized name instead of just using the ID for this?
+ var localizedDepartments = ent.Comp.AllowedDepartments.Select(p => Loc.GetString($"department-{p.Id}"));
+ var localizedJobs = ent.Comp.AllowedJobs.Select(p => _proto.Index(p).LocalizedName);
+
var severity = _proto.Index(ent.Comp.Severity);
- if (severity.ShowDepartments && ent.Comp is { AllowedDepartments: not null })
+ if (severity.ShowDepartmentsAndJobs)
{
- // TODO shouldn't department prototypes have a localized name instead of just using the ID for this?
- var list = ContentLocalizationManager.FormatList(ent.Comp.AllowedDepartments.Select(p => Loc.GetString($"department-{p.Id}")).ToList());
+ //creating a combined list of jobs and departments for the restricted text
+ var list = ContentLocalizationManager.FormatList(localizedDepartments.Concat(localizedJobs).ToList());
// department restricted text
args.PushMarkup(Loc.GetString("contraband-examine-text-Restricted-department", ("departments", list)));
}
// text based on ID card
- List<ProtoId<DepartmentPrototype>>? departments = null;
+ List<ProtoId<DepartmentPrototype>> departments = new();
+ var jobId = "";
+
if (_id.TryFindIdCard(args.Examiner, out var id))
{
departments = id.Comp.JobDepartments;
+ if (id.Comp.LocalizedJobTitle is not null)
+ {
+ jobId = id.Comp.LocalizedJobTitle;
+ }
}
- // either its fully restricted, you have no departments, or your departments dont intersect with the restricted departments
- if (ent.Comp.AllowedDepartments is null
- || departments is null
- || !departments.Intersect(ent.Comp.AllowedDepartments).Any())
+ // for the jobs we compare the localized string in case you use an agent ID or custom job name that is not a prototype
+ if (departments.Intersect(ent.Comp.AllowedDepartments).Any()
+ || localizedJobs.Contains(jobId))
+ {
+ // you are allowed to use this!
+ args.PushMarkup(Loc.GetString("contraband-examine-text-in-the-clear"));
+ }
+ else
{
+ // straight to jail!
args.PushMarkup(Loc.GetString("contraband-examine-text-avoid-carrying-around"));
- return;
}
-
- // otherwise fine to use :tm:
- args.PushMarkup(Loc.GetString("contraband-examine-text-in-the-clear"));
}
}
}
# Belts without visualizers
- type: entity
- parent: [ClothingBeltAmmoProviderBase, BaseRestrictedContraband]
+ parent: [ClothingBeltAmmoProviderBase, BaseSecurityBartenderContraband]
id: ClothingBeltBandolier
name: bandolier
description: A bandolier for holding shotgun ammunition.
- EncryptionKeyCommon
- type: entity
- parent: [ClothingHeadset, BaseRestrictedContraband]
+ parent: [ClothingHeadset, BaseSecurityLawyerContraband]
id: ClothingHeadsetSecurity
name: security headset
description: This is used by your elite security force.
# Numbers for armor here largely taken from /tg/.
# NOTE: Half of the kind of armor you're probably thinking of is in vests.yml. These should probably be merged some day.
-#Basic armor vest
+#Basic armor vest for inheritance
- type: entity
parent: [ClothingOuterBaseMedium, AllowSuitStorageClothing, BaseRestrictedContraband]
- id: ClothingOuterArmorBasic
+ id: ClothingOuterArmorBase
name: armor vest
+ abstract: true
description: A standard Type I armored vest that provides decent protection against most types of damage.
components:
- type: Sprite
- type: ExplosionResistance
damageCoefficient: 0.90
+#Standard armor vest, allowed for security and bartenders
+- type: entity
+ parent: [ BaseSecurityBartenderContraband, ClothingOuterArmorBase]
+ id: ClothingOuterArmorBasic
+
#Alternate / slim basic armor vest
- type: entity
parent: ClothingOuterArmorBasic
- type: GroupExamine
- type: entity
- parent: ClothingOuterArmorBasic
+ parent: ClothingOuterArmorBase
id: ClothingOuterArmorBulletproof
name: bulletproof vest
description: A Type III heavy bulletproof vest that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent.
damageCoefficient: 0.80
- type: entity
- parent: ClothingOuterArmorBasic
+ parent: ClothingOuterArmorBase
id: ClothingOuterArmorReflective
name: reflective vest
description: An armored vest with advanced shielding to protect against energy weapons.
sprite: Clothing/OuterClothing/Coats/bomber.rsi
- type: entity
- parent: [ClothingOuterStorageBase, AllowSuitStorageClothing, ClothingOuterArmorBasic]
+ parent: [ClothingOuterStorageBase, AllowSuitStorageClothing, ClothingOuterArmorBase]
id: ClothingOuterCoatDetective
name: detective trenchcoat
description: An 18th-century multi-purpose trenchcoat. Someone who wears this means serious business.
#Detective's vest
- type: entity
- parent: [ClothingOuterArmorBasic, BaseRestrictedContraband]
+ parent: [ClothingOuterArmorBase, BaseRestrictedContraband]
id: ClothingOuterVestDetective
name: detective's vest
description: A hard-boiled private investigator's armored vest.
sprite: Clothing/Shoes/Specific/cult.rsi
- type: entity
- parent: ClothingShoesBase
+ parent: [ ClothingShoesBase, BaseJanitorContraband ]
id: ClothingShoesGaloshes
name: galoshes
description: Rubber boots.
- state: robotics_label
- type: entity
- parent: [ EncryptionKey, BaseSecurityContraband ]
+ parent: [ EncryptionKey, BaseSecurityLawyerContraband ]
id: EncryptionKeySecurity
name: security encryption key
description: An encryption key used by security.
- type: entity
id: ShellShotgunBeanbag
name: shell (.50 beanbag)
- parent: BaseShellShotgun
+ parent: [ BaseShellShotgun, BaseSecurityBartenderContraband ]
components:
- type: Tag
tags:
- type: entity
id: ShellShotgunFlare
name: shell (.50 flare)
- parent: BaseShellShotgun
+ parent: [ BaseShellShotgun, BaseSecurityBartenderContraband ]
components:
- type: Tag
tags:
- type: entity
name: double-barreled shotgun
- parent: [BaseWeaponShotgun, BaseGunWieldable, BaseMinorContraband]
+ parent: [BaseWeaponShotgun, BaseGunWieldable, BaseSecurityBartenderContraband]
id: WeaponShotgunDoubleBarreled
description: An immortal classic. Uses .50 shotgun shells.
components:
- type: entity
name: sawn-off shotgun
- parent: BaseWeaponShotgun
+ parent: [ BaseWeaponShotgun, BaseSecurityBartenderContraband ]
id: WeaponShotgunSawn
description: Groovy! Uses .50 shotgun shells.
components:
doAfterDuration: 4.0
- type: Contraband
severity: Syndicate
- allowedDepartments: null
- type: Sprite
sprite: Objects/Weapons/Melee/e_dagger.rsi
layers:
components:
- type: Contraband
severity: Syndicate
- # no one should be carrying this around visibly!
- allowedDepartments: null
# minor contraband not departmentally restricted -- improvised weapons etc
- type: entity
components:
- type: Contraband
severity: Minor
- # according to space law no dept is authorized to have
- allowedDepartments: null
# major contraband, for things like guns or weaponry that don't belong to any department and aren't syndicate specific
- type: entity
components:
- type: Contraband
severity: Major
- allowedDepartments: null
# minor contraband by default restricted to security only
- type: entity
- type: Contraband
allowedDepartments: [ Medical, Science ]
+# contraband restricted by job by some degree
+- type: entity
+ id: BaseSecurityBartenderContraband
+ parent: BaseRestrictedContraband
+ abstract: true
+ components:
+ - type: Contraband
+ allowedDepartments: [ Security ]
+ allowedJobs: [ Bartender ]
+
+- type: entity
+ id: BaseSecurityLawyerContraband
+ parent: BaseRestrictedContraband
+ abstract: true
+ components:
+ - type: Contraband
+ allowedDepartments: [ Security ]
+ allowedJobs: [ Lawyer ]
+
+- type: entity
+ id: BaseJanitorContraband
+ parent: BaseRestrictedContraband
+ abstract: true
+ components:
+ - type: Contraband
+ allowedJobs: [ Janitor ]
+
# for ~objective items
- type: entity
id: BaseGrandTheftContraband
- type: contrabandSeverity
id: Restricted
examineText: contraband-examine-text-Restricted
- showDepartments: true
+ showDepartmentsAndJobs: true
# Having this as a regular crew member is considered grand theft. (nuke disk, captain's gear, objective items, etc)
- type: contrabandSeverity