Add TryGetPrimaryDepartment to jobs system (#23317)

* add primary departments

* make command and station specific secondary

* add a unit test

* fixy

* compile

* webedit ops

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
deltanedas
2024-01-14 08:18:34 +00:00
committed by GitHub
parent 1346cc051d
commit d1d11d09c7
4 changed files with 81 additions and 0 deletions

View File

@@ -0,0 +1,48 @@
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
using Robust.Shared.Prototypes;
using System.Linq;
namespace Content.IntegrationTests.Tests.Station;
[TestFixture]
[TestOf(typeof(SharedJobSystem))]
public sealed class JobTest
{
/// <summary>
/// Ensures that every job belongs to at most 1 primary department.
/// Having no primary department is ok.
/// </summary>
[Test]
public async Task PrimaryDepartmentsTest()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
var prototypeManager = server.ResolveDependency<IPrototypeManager>();
await server.WaitAssertion(() =>
{
// only checking primary departments so don't bother with others
var departments = prototypeManager.EnumeratePrototypes<DepartmentPrototype>()
.Where(department => department.Primary)
.ToList();
var jobs = prototypeManager.EnumeratePrototypes<JobPrototype>();
foreach (var job in jobs)
{
// not actually using the jobs system since that will return the first department
// and we need to test that there is never more than 1, so it not sorting them is correct
var primaries = 0;
foreach (var department in departments)
{
if (!department.Roles.Contains(job.ID))
continue;
primaries++;
Assert.That(primaries, Is.EqualTo(1), $"The job {job.ID} has more than 1 primary department!");
}
}
});
await pair.CleanReturnAsync();
}
}

View File

@@ -23,4 +23,11 @@ public sealed partial class DepartmentPrototype : IPrototype
[ViewVariables(VVAccess.ReadWrite), [ViewVariables(VVAccess.ReadWrite),
DataField("roles", customTypeSerializer: typeof(PrototypeIdListSerializer<JobPrototype>))] DataField("roles", customTypeSerializer: typeof(PrototypeIdListSerializer<JobPrototype>))]
public List<string> Roles = new(); public List<string> Roles = new();
/// <summary>
/// Whether this is a primary department or not.
/// For example, CE's primary department is engineering since Command has primary: false.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool Primary = true;
} }

View File

@@ -76,6 +76,30 @@ public abstract class SharedJobSystem : EntitySystem
return false; return false;
} }
/// <summary>
/// Like <see cref="TryGetDepartment"/> but ignores any non-primary departments.
/// For example, with CE it will return Engineering but with captain it will
/// not return anything, since Command is not a primary department.
/// </summary>
public bool TryGetPrimaryDepartment(string jobProto, [NotNullWhen(true)] out DepartmentPrototype? departmentPrototype)
{
// not sorting it since there should only be 1 primary department for a job.
// this is enforced by the job tests.
var departmentProtos = _protoManager.EnumeratePrototypes<DepartmentPrototype>();
foreach (var department in departmentProtos)
{
if (department.Primary && department.Roles.Contains(jobProto))
{
departmentPrototype = department;
return true;
}
}
departmentPrototype = null;
return false;
}
public bool MindHasJobWithId(EntityUid? mindId, string prototypeId) public bool MindHasJobWithId(EntityUid? mindId, string prototypeId)
{ {
return CompOrNull<JobComponent>(mindId)?.Prototype == prototypeId; return CompOrNull<JobComponent>(mindId)?.Prototype == prototypeId;

View File

@@ -43,6 +43,7 @@
- HeadOfSecurity - HeadOfSecurity
- ResearchDirector - ResearchDirector
- Quartermaster - Quartermaster
primary: false
- type: department - type: department
id: Engineering id: Engineering
@@ -95,3 +96,4 @@
- Reporter - Reporter
- Zookeeper - Zookeeper
- Psychologist - Psychologist
primary: false