using System.Linq; using Content.Server.Chemistry.Components.SolutionManager; using Content.Server.Mind; using Content.Server.Mind.Components; using Content.Server.Power.Components; using Content.Shared.Tag; using Robust.Server.Bql; namespace Content.Server.Bql { public sealed class QuerySelectors { [RegisterBqlQuerySelector] public sealed class MindfulQuerySelector : BqlQuerySelector { public override string Token => "mindful"; public override QuerySelectorArgument[] Arguments => Array.Empty(); public override IEnumerable DoSelection(IEnumerable input, IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { return input.Where(e => { if (entityManager.TryGetComponent(e, out var mind)) return (mind.Mind?.VisitingEntity == e) ^ isInverted; return isInverted; }); } public override IEnumerable DoInitialSelection(IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { return DoSelection( entityManager.EntityQuery().Select(x => x.Owner), arguments, isInverted, entityManager); } } [RegisterBqlQuerySelector] public sealed class TaggedQuerySelector : BqlQuerySelector { public override string Token => "tagged"; public override QuerySelectorArgument[] Arguments => new [] { QuerySelectorArgument.String }; public override IEnumerable DoSelection(IEnumerable input, IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { return input.Where(e => (entityManager.TryGetComponent(e, out var tag) && tag.Tags.Contains((string) arguments[0])) ^ isInverted); } public override IEnumerable DoInitialSelection(IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { return DoSelection(entityManager.EntityQuery().Select(x => x.Owner), arguments, isInverted, entityManager); } } [RegisterBqlQuerySelector] public sealed class AliveQuerySelector : BqlQuerySelector { public override string Token => "alive"; public override QuerySelectorArgument[] Arguments => Array.Empty(); public override IEnumerable DoSelection(IEnumerable input, IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { var mindSystem = entityManager.System(); return input.Where(e => entityManager.TryGetComponent(e, out var mind) && mind.Mind != null && !mindSystem.IsCharacterDeadPhysically(mind.Mind)); } public override IEnumerable DoInitialSelection(IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { return DoSelection(entityManager.EntityQuery().Select(x => x.Owner), arguments, isInverted, entityManager); } } [RegisterBqlQuerySelector] public sealed class HasReagentQuerySelector : BqlQuerySelector { public override string Token => "hasreagent"; public override QuerySelectorArgument[] Arguments => new [] { QuerySelectorArgument.String }; public override IEnumerable DoSelection(IEnumerable input, IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { var reagent = (string) arguments[0]; return input.Where(e => { if (entityManager.TryGetComponent(e, out var solutionContainerManagerComponent)) { return solutionContainerManagerComponent.Solutions .Any(solution => solution.Value.ContainsReagent(reagent)) ^ isInverted; } return isInverted; }); } public override IEnumerable DoInitialSelection(IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { return DoSelection(entityManager.EntityQuery().Select(x => x.Owner), arguments, isInverted, entityManager); } } [RegisterBqlQuerySelector] public sealed class ApcPoweredQuerySelector : BqlQuerySelector { public override string Token => "apcpowered"; public override QuerySelectorArgument[] Arguments => Array.Empty(); public override IEnumerable DoSelection(IEnumerable input, IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { return input.Where(e => entityManager.TryGetComponent(e, out var apcPowerReceiver) ? apcPowerReceiver.Powered ^ isInverted : isInverted); } public override IEnumerable DoInitialSelection(IReadOnlyList arguments, bool isInverted, IEntityManager entityManager) { return DoSelection(entityManager.EntityQuery().Select(x => x.Owner), arguments, isInverted, entityManager); } } } }