diff --git a/Content.Server/_NF/PeacefulZone/PeacefulZoneGeneratorComponent.cs b/Content.Server/_NF/PeacefulZone/PeacefulZoneGeneratorComponent.cs new file mode 100644 index 00000000000..0d3bcccfacc --- /dev/null +++ b/Content.Server/_NF/PeacefulZone/PeacefulZoneGeneratorComponent.cs @@ -0,0 +1,32 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Content.Shared.Containers.ItemSlots; +using Robust.Server.GameObjects; +using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; + +namespace Content.Server._NF.PeacefulZone +{ + [RegisterComponent] + public sealed partial class PeacefulZoneGeneratorComponent : Component + { + public List OldListEntities = new(); + public List IntermediateListEntities = new(); + + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] + public TimeSpan NextUpdate; + + /// + /// The interval at which this component updates. + /// + [DataField] + public TimeSpan UpdateInterval = TimeSpan.FromSeconds(1); + + [DataField("radius")] + public int Radius = 5; + + [DataField("rolesImmun")] + public List> RolesImmun = new(); + } +} diff --git a/Content.Server/_NF/PeacefulZone/PeacefulZoneGeneratorSystem.cs b/Content.Server/_NF/PeacefulZone/PeacefulZoneGeneratorSystem.cs new file mode 100644 index 00000000000..60316693961 --- /dev/null +++ b/Content.Server/_NF/PeacefulZone/PeacefulZoneGeneratorSystem.cs @@ -0,0 +1,94 @@ +using Robust.Server.GameObjects; +using Robust.Shared.Timing; +using Content.Shared.Humanoid; +using Content.Shared.CombatMode.Pacification; +using Content.Shared.Mind; +using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; + + +namespace Content.Server._NF.PeacefulZone +{ + public sealed class PeacefulZoneGeneratorSystem : EntitySystem + { + [Dependency] private readonly UserInterfaceSystem _userInterface = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IEntityManager _entMan = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; + [Dependency] private readonly SharedJobSystem _jobSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnComponentInit); + } + + private void OnComponentInit(EntityUid uid, PeacefulZoneGeneratorComponent component, ComponentInit args) + { + foreach (var humanoid_uid in _lookup.GetEntitiesInRange(Transform(uid).Coordinates, component.Radius)) + { + if (TryComp(humanoid_uid, out var pacifComp)) + continue; + + if (!_mindSystem.TryGetMind(humanoid_uid, out var mindId, out var mind)) + continue; + + _jobSystem.MindTryGetJobId(mindId, out var jobId); + + if (jobId != null) + if (component.RolesImmun.Contains(jobId!.Value)) + continue; + + AddComp(humanoid_uid); + component.OldListEntities.Add(_entMan.GetNetEntity(humanoid_uid)); + } + + component.NextUpdate = _gameTiming.CurTime + component.UpdateInterval; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var gen_query = AllEntityQuery(); + while (gen_query.MoveNext(out var gen_uid, out var component)) + { + var query = _lookup.GetEntitiesInRange(Transform(gen_uid).Coordinates, component.Radius); + foreach (var humanoid_uid in query) + { + if (!_mindSystem.TryGetMind(humanoid_uid, out var mindId, out var mind)) + continue; + + _jobSystem.MindTryGetJobId(mindId, out var jobId); + + if (jobId != null) + if (component.RolesImmun.Contains(jobId!.Value)) + continue; + + if (component.OldListEntities.Contains(_entMan.GetNetEntity(humanoid_uid))) + { + component.IntermediateListEntities.Add(_entMan.GetNetEntity(humanoid_uid)); + component.OldListEntities.Remove(_entMan.GetNetEntity(humanoid_uid)); + } + else + { + AddComp(humanoid_uid); + component.IntermediateListEntities.Add(_entMan.GetNetEntity(humanoid_uid)); + } + } + + foreach (var humanoid_net_uid in component.OldListEntities) + { + RemComp(GetEntity(humanoid_net_uid)); + } + + component.OldListEntities.Clear(); + component.OldListEntities.AddRange(component.IntermediateListEntities); + component.IntermediateListEntities.Clear(); + + component.NextUpdate += component.UpdateInterval; + } + } + } +} diff --git a/Resources/Locale/ru-RU/_NF/PeacefulZone.ftl b/Resources/Locale/ru-RU/_NF/PeacefulZone.ftl new file mode 100644 index 00000000000..02f1060564f --- /dev/null +++ b/Resources/Locale/ru-RU/_NF/PeacefulZone.ftl @@ -0,0 +1,2 @@ +peaceful-zone-name = Мирная зона +peaceful-zone-description = Волшебство NT творит чудеса... diff --git a/Resources/Prototypes/_NF/peaceful_zone.yml b/Resources/Prototypes/_NF/peaceful_zone.yml new file mode 100644 index 00000000000..009c86b004a --- /dev/null +++ b/Resources/Prototypes/_NF/peaceful_zone.yml @@ -0,0 +1,22 @@ +- type: entity + parent: MarkerBase + id: PeacefulZone + name: peaceful-zone-name + description: peaceful-zone-description + components: + - type: Sprite + sprite: _NF/peacefulzone.rsi + state: peaceful_zone + - type: PeacefulZoneGenerator + radius: 300 # this is the value chosen by Kmin + rolesImmun: + - Bailiff + - Brigmedic + - Cadet + - Deputy + - DetectiveNF + - SeniorOfficer + - Sheriff + - SecurityGuard + - StationRepresentative + - StationTrafficController diff --git a/Resources/Textures/_NF/peacefulzone.rsi/meta.json b/Resources/Textures/_NF/peacefulzone.rsi/meta.json new file mode 100644 index 00000000000..f18168bfd55 --- /dev/null +++ b/Resources/Textures/_NF/peacefulzone.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by BeatusCrow(github/discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "peaceful_zone" + } + ] +} diff --git a/Resources/Textures/_NF/peacefulzone.rsi/peaceful_zone.png b/Resources/Textures/_NF/peacefulzone.rsi/peaceful_zone.png new file mode 100644 index 00000000000..783c4128f2d Binary files /dev/null and b/Resources/Textures/_NF/peacefulzone.rsi/peaceful_zone.png differ