using System.Linq; using System.Text; using Content.Shared.Mind; using Content.Shared.Preferences; using Content.Shared.Roles; using JetBrains.Annotations; using Robust.Shared.Configuration; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Utility; namespace Content.Shared.Customization.Systems; [ImplicitDataDefinitionForInheritors, MeansImplicitUse] [Serializable, NetSerializable] public abstract partial class CharacterLogicRequirement : CharacterRequirement { [DataField] public List Requirements { get; private set; } = new(); } /// /// Requires all of the requirements to be true /// [UsedImplicitly] [Serializable, NetSerializable] public sealed partial class CharacterLogicAndRequirement : CharacterLogicRequirement { public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile, Dictionary playTimes, bool whitelisted, IPrototype prototype, IEntityManager entityManager, IPrototypeManager prototypeManager, IConfigurationManager configManager, out string? reason, int depth = 0, MindComponent? mind = null) { var succeeded = entityManager.EntitySysManager.GetEntitySystem() .CheckRequirementsValid(Requirements, job, profile, playTimes, whitelisted, prototype, entityManager, prototypeManager, configManager, out var reasons, depth + 1); if (reasons.Count == 0) { reason = null; return succeeded; } var reasonBuilder = new StringBuilder(); foreach (var message in reasons) reasonBuilder.Append(Loc.GetString("character-logic-and-requirement-listprefix", ("indent", new string(' ', depth * 2))) + message); reason = Loc.GetString("character-logic-and-requirement", ("inverted", Inverted), ("options", reasonBuilder.ToString())); return succeeded; } } /// /// Requires any of the requirements to be true /// [UsedImplicitly] [Serializable, NetSerializable] public sealed partial class CharacterLogicOrRequirement : CharacterLogicRequirement { public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile, Dictionary playTimes, bool whitelisted, IPrototype prototype, IEntityManager entityManager, IPrototypeManager prototypeManager, IConfigurationManager configManager, out string? reason, int depth = 0, MindComponent? mind = null) { var succeeded = false; var reasons = new List(); var characterRequirements = entityManager.EntitySysManager.GetEntitySystem(); foreach (var requirement in Requirements) { if (characterRequirements.CheckRequirementValid(requirement, job, profile, playTimes, whitelisted, prototype, entityManager, prototypeManager, configManager, out var raisin, depth + 1)) { succeeded = true; break; } if (raisin != null) reasons.Add(raisin); } if (reasons.Count == 0) { reason = null; return succeeded; } var reasonBuilder = new StringBuilder(); foreach (var message in reasons) reasonBuilder.Append(Loc.GetString("character-logic-or-requirement-listprefix", ("indent", new string(' ', depth * 2))) + message); reason = Loc.GetString("character-logic-or-requirement", ("inverted", Inverted), ("options", reasonBuilder.ToString())); return succeeded; } } /// /// Requires only one of the requirements to be true /// [UsedImplicitly] [Serializable, NetSerializable] public sealed partial class CharacterLogicXorRequirement : CharacterLogicRequirement { public override bool IsValid(JobPrototype job, HumanoidCharacterProfile profile, Dictionary playTimes, bool whitelisted, IPrototype prototype, IEntityManager entityManager, IPrototypeManager prototypeManager, IConfigurationManager configManager, out string? reason, int depth = 0, MindComponent? mind = null) { var reasons = new List(); var succeeded = false; var characterRequirements = entityManager.EntitySysManager.GetEntitySystem(); foreach (var requirement in Requirements) { if (characterRequirements.CheckRequirementValid(requirement, job, profile, playTimes, whitelisted, prototype, entityManager, prototypeManager, configManager, out var raisin, depth + 1)) { if (succeeded) { succeeded = false; break; } succeeded = true; } if (raisin != null) reasons.Add(raisin); } if (reasons.Count == 0) { reason = null; return succeeded; } var reasonBuilder = new StringBuilder(); foreach (var message in reasons) reasonBuilder.Append(Loc.GetString("character-logic-xor-requirement-listprefix", ("indent", new string(' ', depth * 2))) + message); reason = Loc.GetString("character-logic-xor-requirement", ("inverted", Inverted), ("options", reasonBuilder.ToString())); return succeeded; } }