using System.Linq; using Content.Server._Sunrise.NewLife; using Content.Server.Chat.Managers; using Content.Server.GameTicking; using Content.Server.Mind; using Content.Server.Objectives; using Content.Server.Roles; using Content.Shared.Mind; using Content.Shared.Mind.Components; using Content.Shared.Roles; using Robust.Server.GameObjects; using Robust.Shared.Prototypes; using Robust.Shared.Timing; namespace Content.Server._Sunrise.PlanetPrison { public sealed class PlanetPrisonSystem : EntitySystem { [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly SharedRoleSystem _roleSystem = default!; [Dependency] private readonly GameTicker _gameTicker = default!; [Dependency] private readonly TransformSystem _transformSystem = default!; [Dependency] private readonly NewLifeSystem _newLifeSystem = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [ValidatePrototypeId] private const string MindRole = "MindRolePlanetPrisoner"; [ValidatePrototypeId] private const string EscapeObjective = "PlanetPrisonerEscapeObjective"; [ValidatePrototypeId] private const string GameRule = "PlanetPrison"; private const float EscapeDistance = 150f; public TimeSpan NextTick = TimeSpan.Zero; public TimeSpan RefreshCooldown = TimeSpan.FromSeconds(5); public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnMindAdded); SubscribeLocalEvent(OnObjectivesTextGetInfo); SubscribeLocalEvent(OnObjectivesTextPrepend); SubscribeLocalEvent(OnGetBriefing); } private void OnGetBriefing(EntityUid uid, PlanetPrisonerRoleComponent component, ref GetBriefingEvent args) { if (!TryComp(uid, out var mind) || mind.OwnedEntity == null) return; if (HasComp(uid)) return; args.Append(Loc.GetString("planet-prisoner-role-greeting")); } private void OnObjectivesTextPrepend(EntityUid uid, PlanetPrisonRuleComponent comp, ref ObjectivesTextPrependEvent args) { var planetPrisonRule = GetPlanetPrisonRule(); if (planetPrisonRule == null) return; args.Text += Loc.GetString("planet-prison-round-end-result", ("count", planetPrisonRule.EscapedPrisoners.Count)); } private void OnObjectivesTextGetInfo(EntityUid uid, PlanetPrisonRuleComponent comp, ref ObjectivesTextGetInfoEvent args) { args.Minds = comp.PrisonersMinds; args.AgentName = Loc.GetString("planet-prisoner-round-end-name"); } public override void Update(float frameTime) { if (NextTick > _gameTiming.CurTime) return; NextTick += RefreshCooldown; var planetPrisonRule = GetPlanetPrisonRule(); if (planetPrisonRule == null) return; var planetPrisonStation = EntityQuery().FirstOrDefault(); if (planetPrisonStation == null || planetPrisonStation.PrisonGrid == EntityUid.Invalid) return; var xformPrison = Transform(planetPrisonStation.PrisonGrid); var prisonPosition = _transformSystem.GetMapCoordinates(xformPrison); base.Update(frameTime); var query = AllEntityQuery(); while (query.MoveNext(out var prisoner, out _, out var xform)) { var prisonerPosition = _transformSystem.GetMapCoordinates(xform); if (!_mindSystem.TryGetMind(prisoner, out var mindId, out var mind)) { continue; } if (prisonerPosition.MapId != planetPrisonStation.MapId) { // А вот нехуй играть не по правилам QueueDel(prisoner); continue; } var distance = (prisonerPosition.Position - prisonPosition.Position).Length(); if (!(distance > EscapeDistance)) continue; if (planetPrisonRule.EscapedPrisoners.Contains(mindId)) continue; // Не ну а чо QueueDel(prisoner); planetPrisonRule.EscapedPrisoners.Add(mindId); if (mind.Session != null) { _newLifeSystem.SetNextAllowRespawn(mind.Session.UserId, _gameTiming.CurTime); } } } public PlanetPrisonRuleComponent? GetPlanetPrisonRule() { var planetPrisonRule = EntityQuery().FirstOrDefault(); return planetPrisonRule; } public PlanetPrisonRuleComponent StartPlanetPrisonRule() { _gameTicker.StartGameRule(GameRule, out var ruleEntity); var planetPrisonRule = Comp(ruleEntity); return planetPrisonRule; } public bool PrisonerEscaped(EntityUid mind) { var planetPrisonRule = GetPlanetPrisonRule(); if (planetPrisonRule == null) return false; return planetPrisonRule.EscapedPrisoners.Contains(mind); } private void OnMindAdded(EntityUid uid, PlanetPrisonerComponent component, MindAddedMessage args) { var planetPrisonRule = GetPlanetPrisonRule() ?? StartPlanetPrisonRule(); if (!_mindSystem.TryGetMind(uid, out var mindId, out var mind)) { return; } if (component.FirstMindAdded) return; component.FirstMindAdded = true; if (_roleSystem.MindHasRole(mindId)) { _roleSystem.MindTryRemoveRole(mindId); } _roleSystem.MindAddRole(mindId, MindRole); _mindSystem.TryAddObjective(mindId, mind, EscapeObjective); planetPrisonRule.PrisonersMinds.Add((mindId, Name(uid))); } } }