Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,9 +1087,11 @@ private void OnSpeciesInfoButtonPressed(BaseButton.ButtonEventArgs args)
/// </summary>
public void RefreshJobs()
{
RemoveBlockedJobPriorities();
JobList.DisposeAllChildren();
_jobCategories.Clear();
_jobPriorities.Clear();
var activeProfile = Profile ?? HumanoidCharacterProfile.DefaultWithSpecies();

// Get all displayed departments
var departments = new List<DepartmentPrototype>();
Expand Down Expand Up @@ -1165,10 +1167,12 @@ public void RefreshJobs()

if (!_requirements.CheckJobWhitelist(job, out var reason))
selector.LockRequirements(reason);
else if (activeProfile.GetBackgroundBlockedMessage(job.ID, _prototypeManager, _cfgManager) is { } backgroundMessage)
selector.LockRequirements(backgroundMessage);
else if (!_characterRequirementsSystem.CheckRequirementsValid(
_roleSystem.GetJobRequirement(job) ?? new(),
job,
Profile ?? HumanoidCharacterProfile.DefaultWithSpecies(),
activeProfile,
_requirements.GetRawPlayTimeTrackers(),
_requirements.IsWhitelisted(),
job,
Expand Down Expand Up @@ -1462,6 +1466,7 @@ private void SetSpecies(string newSpecies)
private void SetNationality(string newNationality)
{
Profile = Profile?.WithNationality(newNationality);
RemoveBlockedJobPriorities();
UpdateCharacterRequired();
IsDirty = true;
ReloadProfilePreview();
Expand All @@ -1472,6 +1477,7 @@ private void SetNationality(string newNationality)
private void SetEmployer(string newEmployer)
{
Profile = Profile?.WithEmployer(newEmployer);
RemoveBlockedJobPriorities();
UpdateCharacterRequired();
IsDirty = true;
ReloadProfilePreview();
Expand All @@ -1482,13 +1488,27 @@ private void SetEmployer(string newEmployer)
private void SetLifepath(string newLifepath)
{
Profile = Profile?.WithLifepath(newLifepath);
RemoveBlockedJobPriorities();
UpdateCharacterRequired();
IsDirty = true;
ReloadProfilePreview();
ReloadClothes(); // Lifepaths may have specific gear, reload the clothes
UpdateLifepathDescription(newLifepath);
}

private void RemoveBlockedJobPriorities()
{
if (Profile is null)
return;

var blockedJobs = Profile.GetBlockedJobs(_prototypeManager, _cfgManager);
if (blockedJobs.Count == 0)
return;

foreach (var blockedJob in blockedJobs)
Profile = Profile.WithJobPriority(blockedJob, JobPriority.Never);
}

private void SetName(string newName)
{
Profile = Profile?.WithName(newName);
Expand Down
67 changes: 67 additions & 0 deletions Content.Shared/Preferences/HumanoidCharacterProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,71 @@ public static HumanoidCharacterProfile RandomWithSpecies(string species = Shared
return profile;
// WD EDIT END
}
//IH - start
public HashSet<ProtoId<JobPrototype>> GetBlockedJobs(IPrototypeManager prototypeManager, IConfigurationManager configurationManager)
{
var blocked = new HashSet<ProtoId<JobPrototype>>();

if (!configurationManager.GetCVar(CCVars.ContractorsEnabled)
|| !configurationManager.GetCVar(CCVars.ContractorsCharacterRequirementsEnabled))
return blocked;

if (prototypeManager.TryIndex<NationalityPrototype>(Nationality, out var nationality))
blocked.UnionWith(nationality.BlockingJobs);

if (prototypeManager.TryIndex<EmployerPrototype>(Employer, out var employer))
blocked.UnionWith(employer.BlockingJobs);

if (prototypeManager.TryIndex<LifepathPrototype>(Lifepath, out var lifepath))
blocked.UnionWith(lifepath.BlockingJobs);

return blocked;
}

public bool IsJobBlockedByBackground(ProtoId<JobPrototype> jobId, IPrototypeManager prototypeManager, IConfigurationManager configurationManager)
{
return GetBlockedJobs(prototypeManager, configurationManager).Contains(jobId);
}

public FormattedMessage? GetBackgroundBlockedMessage(ProtoId<JobPrototype> jobId, IPrototypeManager prototypeManager, IConfigurationManager configurationManager)
{
if (!configurationManager.GetCVar(CCVars.ContractorsEnabled)
|| !configurationManager.GetCVar(CCVars.ContractorsCharacterRequirementsEnabled))
return null;

var entries = new List<string>();

void AddEntry(string typeLoc, string? nameKey)
{
if (string.IsNullOrEmpty(nameKey))
return;

var type = Loc.GetString(typeLoc);
var name = Loc.GetString(nameKey);
entries.Add($"{type}: {name}");
}

if (prototypeManager.TryIndex<NationalityPrototype>(Nationality, out var nationality)
&& nationality.BlockingJobs.Contains(jobId))
AddEntry("contractor-background-type-nationality", nationality.NameKey);

if (prototypeManager.TryIndex<EmployerPrototype>(Employer, out var employer)
&& employer.BlockingJobs.Contains(jobId))
AddEntry("contractor-background-type-employer", employer.NameKey);

if (prototypeManager.TryIndex<LifepathPrototype>(Lifepath, out var lifepath)
&& lifepath.BlockingJobs.Contains(jobId))
AddEntry("contractor-background-type-lifepath", lifepath.NameKey);

if (entries.Count == 0)
return null;

var message = Loc.GetString("contractor-background-job-blocked",
("backgrounds", string.Join(", ", entries)));

return FormattedMessage.FromUnformatted(message);
}
//IH - end
public HumanoidCharacterProfile WithName(string name) => new(this) { Name = name };
public HumanoidCharacterProfile WithFlavorText(string flavorText) => new(this) { FlavorText = flavorText };
public HumanoidCharacterProfile WithVoice(string voice) => new(this) { Voice = voice }; // WD EDIT
Expand Down Expand Up @@ -689,6 +753,9 @@ public void EnsureValid(ICommonSession session, IDependencyCollection collection
_ => false
}));

foreach (var blockedJob in GetBlockedJobs(prototypeManager, configManager))
priorities.Remove(blockedJob);

var hasHighPrio = false;
foreach (var (key, value) in priorities)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Shared.Traits;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Content.Shared.Roles;

namespace Content.Shared._EE.Contractors.Prototypes;

Expand Down Expand Up @@ -32,6 +33,9 @@ public sealed partial class EmployerPrototype : IPrototype
[DataField]
public List<CharacterRequirement> Requirements = new();

[DataField]
public List<ProtoId<JobPrototype>> BlockingJobs { get; } = new();

[DataField(serverOnly: true)]
public TraitFunction[] Functions { get; private set; } = Array.Empty<TraitFunction>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Robust.Shared.Serialization.Manager;
using Content.Shared.Customization.Systems;
using Content.Shared.Traits;
using Content.Shared.Roles;


namespace Content.Shared._EE.Contractors.Prototypes;
Expand All @@ -24,6 +25,9 @@ public sealed partial class LifepathPrototype : IPrototype
[DataField]
public List<CharacterRequirement> Requirements = new();

[DataField]
public List<ProtoId<JobPrototype>> BlockingJobs { get; } = new();

[DataField(serverOnly: true)]
public TraitFunction[] Functions { get; private set; } = Array.Empty<TraitFunction>();
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Content.Shared._EE.Contractors.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Content.Shared.Customization.Systems;
using Content.Shared.Traits;
using Content.Shared.Roles;


namespace Content.Shared._EE.Contractors.Prototypes;
Expand Down Expand Up @@ -37,6 +37,9 @@ public sealed partial class NationalityPrototype : IPrototype
[DataField]
public List<CharacterRequirement> Requirements = new();

[DataField]
public List<ProtoId<JobPrototype>> BlockingJobs { get; } = new();

[DataField(serverOnly: true)]
public TraitFunction[] Functions { get; private set; } = Array.Empty<TraitFunction>();

Expand Down
4 changes: 4 additions & 0 deletions Resources/Locale/en-US/_EE/contractors/backgrounds.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
contractor-background-job-blocked = Your selected background prevents choosing this job: {$backgrounds}
contractor-background-type-nationality = Nationality
contractor-background-type-employer = Employer
contractor-background-type-lifepath = Lifepath
47 changes: 12 additions & 35 deletions Resources/Locale/en-US/_EE/contractors/employer.ftl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
humanoid-profile-editor-employer-label = Employer
humanoid-profile-editor-employer-label = Employer

character-employer-requirement = You must{$inverted ->
[true]{" "}not
Expand All @@ -7,43 +7,20 @@ character-employer-requirement = You must{$inverted ->

employer_name_nanotrasen = NanoTrasen
employer_name_nanotrasen_command = NanoTrasen Command
employer_description_nanotrasen = The economic engine of the Republic of Biesel and the galaxy’s foremost leader in phoron research. With near-total control over Biesel’s economy and infrastructure, NanoTrasen presents itself as a champion of progress and prosperity—though critics argue it values profit above all else.
employer_description_nanotrasen = You are a NanoTrasen employee assigned to the concession station in the Gray Zone. The corporation built the infrastructure, covers housing, insurance, and labs, and expects you to meet the expansion targets. Instead of directives from Central Command, you receive profit KPIs, inspections, and bonuses for exceeding plan. Corporate Oversight and the plenipotentiary monitor every decision; reporting follows NT regulations, and any dispute quickly escalates into a legal audit. Loyalty and discipline are the currency for your next promotion.

employer_name_unemployed = Unemployed
employer_description_unemployed = Whether down on their luck or simply unwilling to work, the unemployed survive however they can. Some live off government subsidies, others turn to freelance work—or less legal alternatives. Either way, society tends to look down on them.
employer_name_government = Government Service
employer_name_government_command = Government Service Command
employer_description_government = You are a state officer seconded to the station to represent the law and control the concession. The Captain, Head of Personnel, law enforcement, and the magistrate corps are appointed through the legislature and still answer to the governor, even if NanoTrasen covers part of their budget. Your job is to balance federal directives, the station council, and corporate profit goals: process paperwork, conduct hearings, command your department, and keep the ledgers ready for the next audit.

employer_name_hephaestusindustries = Hephaestus Industries
employer_name_hephaestusindustries_command = Hephaestus Industries Command
employer_description_hephaestusindustries = A sprawling manufacturing conglomerate responsible for producing everything from mining drills to military hardware. If it has moving parts, Hephaestus probably made it. Known for their no-nonsense corporate culture and deep ties to industrial and frontier colonies.
employer_name_contractors = Contractors
employer_name_contractors_command = Contractors Command
employer_description_contractors = You are a contractor working for a private firm granted operational control over entire departments. Your company runs engineering, medical, logistics, or service divisions, supplying equipment and personnel while meeting concession payments and revenue targets. In return you maintain insurance, keep reactors stable, move cargo, and defend the firm's interests on the council floor. Your contract is your lifeline—reputation, negotiation, and readiness to operate under any conditions determine how long you stay on the station. Example partners:
TraumaTrust (medical outsourcing and MEDEVAC insurance). Their care packages mandate regular health audits and deploy field clinics for preventive treatment.
Arclight Systems (engineering and energy infrastructure). They maintain schematics for every critical system, keep spare modules on reserve, and schedule emergency engineering shifts.
Voidway Logistics (freight corridors and express delivery). The firm oversees shuttle routes, cargo labelling, and insurance coverage for each shipment.
LumenCare Hospitality (services, housing, and VR leisure). The company sets service standards, manages cleaning drones, and maintains the station's VR leisure suites.

employer_name_einsteinengines = Einstein Engines
employer_name_einsteinengines_command = Einstein Engines Command
employer_description_einsteinengines = The galaxy’s premier manufacturer of FTL drives and starship technology. Despite their technical prowess, the company is infamous for harsh working conditions, cutthroat internal politics, and an aggressive legal department that makes their lawsuits as feared as their patents.

employer_name_zenghupharmaceuticals = Zeng-Hu Pharmaceuticals
employer_name_zenghupharmaceuticals_command = Zeng-Hu Pharmaceuticals Command
employer_description_zenghupharmaceuticals = The leading name in biotechnology, cybernetics, and pharmaceuticals. Their cutting-edge medical treatments and cybernetic implants have saved countless lives, but their ethics are often called into question—especially by those who can't afford their exorbitant prices.

employer_name_zavodskoiinterstellar = Zavodskoi Interstellar
employer_name_zavodskoiinterstellar_command = Zavodskoi Interstellar Command
employer_description_zavodskoiinterstellar = Zavodskoi Interstellar, formerly Necropolis Industries, is a weapons and aerospace manufacturing and development conglomerate. Zavodskoi distributes everything from light to heavy arms, space vessel weapons, ship-building, aircraft, ground vehicles, combat spacesuits, and military software. They also produce the Z.I. line of positronics, used for private security and military contracting.

employer_name_interdyne = Interdyne
employer_name_interdyne_command = Interdyne Command
employer_description_interdyne = A leading name in Solarian biomedical research, cybernetics, and pharmaceutical development. Unlike its competitor Zeng-Hu, Interdyne takes a more pragmatic approach, prioritising efficiency and durability over elegance. Its advanced medical implants and combat-grade augmentations are standard issue in the Solarian military, making it the go-to choice for those who expect to take a beating—and keep fighting.

employer_name_idrisincorporated = Idris Incorporated
employer_name_idrisincorporated_command = Idris Incorporated Command
employer_description_idrisincorporated = Idris Incorporated is an interstellar corporate bank headquartered in the Sol Alliance. The bank has begun offering hiring bonuses to those who work for other major interstellar corporations to draw people away from their competitors. However, they are still in a struggle with NanoTrasen due to its large employee base mainly using the company's bank as their method of storing funds, preventing Idris from having a large number of members.

employer_name_orionexpress = Orion Express
employer_name_orionexpress_command = Orion Express Command
employer_description_orionexpress = Orion Express is a manufactured megacorporation designed to handle logistics in the wake of the phoron scarcity, and the sudden entangling of supply lines that left the galaxy struggling for more resources. Its main branch is dedicated to cargo services and transport, but also features a fledgling robotics division mainly focused on industrial synthetics to aid in its logistics missions.

employer_name_pmcg = PMCG
employer_name_pmcg_command = PMCG Command
employer_description_pmcg = A coalition of security contractors, the Private Military Contracting Group is one of the elements born from the necessity of protecting an ever-growing corporate empire. Gathering mercenaries from all across the galaxy, the Private Military Contracting Group deploys a diverse force to anywhere they are needed.

employer_name_eastorioncompany = East-Orion Company
employer_name_eastorioncompany_command = East-Orion Company Command
employer_description_eastorioncompany = A Nederlandic initiative to exploit an untapped market in 2157, the United East-Orion Company was an old idea made new. Rooted in tradition that went back centuries, two large agricultural corporations — the New-Nederic agricultural machinery manufacturer and the Farmer's Civil Union — came together under one banner to offer planet-honed skillsets to a growing number of corporate space stations.
Loading
Loading