Files
wwdpublic/Content.Shared/Roles/JobPrototype.cs
Timfa 60053a10d4 Coat and Scrubs Restricted to Respective Employers (#2134)
<!--
This is a semi-strict format, you can add/remove sections as needed but
the order/format should be kept the same
Remove these comments before submitting
-->

# Description

<!--
Explain this PR in as much detail as applicable

Some example prompts to consider:
How might this affect the game? The codebase?
What might be some alternatives to this?
How/Who does this benefit/hurt [the game/codebase]?
-->

Some coats and scrubs in loadout are branded with specific corporation
logo's.
This PR restricts specifically those items to the employers that they
are from.

Note that we have coats from other companies currently not listed as
available employers too. Perhaps we should consider adding them?

# Updated:
This PR now also includes CCVars that can disable a part, or the
entirety, of Contractors for downstreams that prefer free-form RP over
gameplay.
While I was at it, I made it so that AI and Borgs don't get Passports.

---

# Changelog

<!--
You can add an author after the `🆑` to change the name that appears
in the changelog (ex: `🆑 Death`)
Leaving it blank will default to your GitHub display name
This includes all available types for the changelog
-->

🆑
- tweak: Restricted some corporate jackets and scrubs to that specific
corporation.
- tweak: Downstreams can now disable Contractors entirely or partially
if they prefer freeform-rp over gameplay facilitating RP
- tweak: Station AI and Borg are no longer people and don't get
passports.

(cherry picked from commit 445bdc5c1b04c9f41460fb1cc6986e736732508e)
2025-04-04 15:01:26 +03:00

214 lines
8.1 KiB
C#

using Content.Shared.Access;
using Content.Shared.Guidebook;
using Content.Shared.Customization.Systems;
using Content.Shared.Dataset;
using Content.Shared.Players.PlayTimeTracking;
using Content.Shared.Roles;
using Content.Shared.StatusIcon;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Roles
{
/// <summary>
/// Describes information for a single job on the station.
/// </summary>
[Prototype("job")]
public sealed partial class JobPrototype : IPrototype
{
[ViewVariables]
[IdDataField]
public string ID { get; private set; } = default!;
[DataField("playTimeTracker", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<PlayTimeTrackerPrototype>))]
public string PlayTimeTracker { get; private set; } = string.Empty;
[DataField("supervisors")]
public string Supervisors { get; private set; } = "nobody";
/// <summary>
/// The name of this job as displayed to players.
/// </summary>
[DataField("name")]
public string Name { get; private set; } = string.Empty;
[ViewVariables(VVAccess.ReadOnly)]
public string LocalizedName => Loc.GetString(Name);
/// <summary>
/// The name of this job as displayed to players.
/// </summary>
[DataField("description")]
public string? Description { get; private set; }
[ViewVariables(VVAccess.ReadOnly)]
public string? LocalizedDescription => Description is null ? null : Loc.GetString(Description);
[DataField("requirements")]
public List<CharacterRequirement>? Requirements;
[DataField("joinNotifyCrew")]
public bool JoinNotifyCrew { get; private set; } = false;
[DataField("requireAdminNotify")]
public bool RequireAdminNotify { get; private set; } = false;
[DataField("setPreference")]
public bool SetPreference { get; private set; } = true;
/// <summary>
/// Whether this job should show in the ID Card Console.
/// If set to null, it will default to SetPreference's value.
/// </summary>
[DataField]
public bool? OverrideConsoleVisibility { get; private set; } = null;
[DataField("canBeAntag")]
public bool CanBeAntag { get; private set; } = true;
/// <summary>
/// Used by Contractors to determine if a given job should have a passport
/// This should be disabled for Borgs and Station AI, for example.
/// </summary>
[DataField("canHavePassport")]
public bool CanHavePassport { get; private set; } = true;
/// <summary>
/// Nyano/DV: For e.g. prisoners, they'll never use their latejoin spawner.
/// </summary>
[DataField("alwaysUseSpawner")]
public bool AlwaysUseSpawner { get; } = false;
/// <summary>
/// Whether this job is a head.
/// The job system will try to pick heads before other jobs on the same priority level.
/// </summary>
[DataField("weight")]
public int Weight { get; private set; }
/// <summary>
/// How to sort this job relative to other jobs in the UI.
/// Jobs with a higher value with sort before jobs with a lower value.
/// If not set, <see cref="Weight"/> is used as a fallback.
/// </summary>
[DataField]
public int? DisplayWeight { get; private set; }
public int RealDisplayWeight => DisplayWeight ?? Weight;
/// <summary>
/// A numerical score for how much easier this job is for antagonists.
/// For traitors, reduces starting TC by this amount. Other gamemodes can use it for whatever they find fitting.
/// </summary>
[DataField("antagAdvantage")]
public int AntagAdvantage = 0;
[DataField("startingGear", customTypeSerializer: typeof(PrototypeIdSerializer<StartingGearPrototype>))]
public string? StartingGear { get; private set; }
/// <summary>
/// If this has a value, it will randomly set the entity name of the
/// entity upon spawn based on the dataset.
/// </summary>
[DataField]
public ProtoId<LocalizedDatasetPrototype>? NameDataset;
/// <summary>
/// A list of requirements that when satisfied, add or replace from the base starting gear.
/// </summary>
[DataField("conditionalStartingGear")]
public List<ConditionalStartingGear>? ConditionalStartingGears { get; private set; }
/// <summary>
/// Use this to spawn in as a non-humanoid (borg, test subject, etc.)
/// Starting gear will be ignored.
/// If you want to just add special attributes to a humanoid, use AddComponentSpecial instead.
/// </summary>
[DataField("jobEntity", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? JobEntity = null;
[DataField]
public ProtoId<JobIconPrototype> Icon { get; private set; } = "JobIconUnknown";
[DataField("special", serverOnly: true)]
public JobSpecial[] Special { get; private set; } = Array.Empty<JobSpecial>();
[DataField("afterLoadoutSpecial", serverOnly: true)]
public JobSpecial[] AfterLoadoutSpecial { get; private set; } = [];
[DataField("access")]
public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> Access { get; private set; } = Array.Empty<ProtoId<AccessLevelPrototype>>();
[DataField("accessGroups")]
public IReadOnlyCollection<ProtoId<AccessGroupPrototype>> AccessGroups { get; private set; } = Array.Empty<ProtoId<AccessGroupPrototype>>();
[DataField("extendedAccess")]
public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> ExtendedAccess { get; private set; } = Array.Empty<ProtoId<AccessLevelPrototype>>();
[DataField("extendedAccessGroups")]
public IReadOnlyCollection<ProtoId<AccessGroupPrototype>> ExtendedAccessGroups { get; private set; } = Array.Empty<ProtoId<AccessGroupPrototype>>();
[DataField]
public bool Whitelisted;
[DataField]
public bool SpawnLoadout = true;
[DataField]
public bool ApplyTraits = true;
/// <summary>
/// Optional list of guides associated with this role. If the guides are opened, the first entry in this list
/// will be used to select the currently selected guidebook.
/// </summary>
[DataField]
public List<ProtoId<GuideEntryPrototype>>? Guides;
}
/// <summary>
/// Starting gear that will only be applied upon satisfying requirements.
/// </summary>
[DataDefinition]
public sealed partial class ConditionalStartingGear
{
/// <summary>
/// The requirements to check.
/// </summary>
[DataField(required: true)]
public List<CharacterRequirement> Requirements;
/// <summary>
/// The starting gear to apply, replacing the equivalent slots.
/// </summary>
[DataField(required: true)]
public ProtoId<StartingGearPrototype> Id { get; private set; }
}
/// <summary>
/// Sorts <see cref="JobPrototype"/>s appropriately for display in the UI,
/// respecting their <see cref="JobPrototype.Weight"/>.
/// </summary>
public sealed class JobUIComparer : IComparer<JobPrototype>
{
public static readonly JobUIComparer Instance = new();
public int Compare(JobPrototype? x, JobPrototype? y)
{
if (ReferenceEquals(x, y))
return 0;
if (ReferenceEquals(null, y))
return 1;
if (ReferenceEquals(null, x))
return -1;
var cmp = -x.RealDisplayWeight.CompareTo(y.RealDisplayWeight);
if (cmp != 0)
return cmp;
return string.Compare(x.ID, y.ID, StringComparison.Ordinal);
}
}
}