using Content.Server.GameTicking.Rules; using Content.Server.Antag; using Content.Server.Mind; using Content.Server.RoundEnd; using Content.Shared.Mobs; using System.Linq; using Content.Server._White.Wizard.Appearance; using Content.Server.Objectives; using Content.Server.StationEvents.Components; using Content.Shared._White.Wizard.Appearance; using Content.Shared.Mind; using Content.Shared.Objectives.Components; namespace Content.Server._White.Wizard; /// /// This handles... /// public sealed class WizardRuleSystem : GameRuleSystem { [Dependency] private readonly MindSystem _mind = default!; [Dependency] private readonly RoundEndSystem _roundEndSystem = default!; [Dependency] private readonly ObjectivesSystem _objectives = default!; [Dependency] private readonly WizardAppearanceSystem _wizardAppearance = default!; private const string WizardObjective = "WizardSurviveObjective"; /// public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnAntagSelectEntity); SubscribeLocalEvent(AfterEntitySelected); SubscribeLocalEvent(OnMobStateChanged); SubscribeLocalEvent(OnObjectivesTextGetInfo); } private void OnObjectivesTextGetInfo(Entity ent, ref ObjectivesTextGetInfoEvent args) { args.Minds = ent.Comp.WizardMinds; args.AgentName = Loc.GetString("wizard-round-end-agent-name"); } private void OnMobStateChanged(EntityUid uid, WizardComponent component, MobStateChangedEvent ev) { if (ev.NewMobState == MobState.Dead && component.EndRoundOnDeath) CheckAnnouncement(); } private void GiveObjectives(EntityUid mindId, MindComponent mind, WizardRuleComponent wizardRule) { _mind.TryAddObjective(mindId, mind, WizardObjective); var difficulty = 0f; for (var pick = 0; pick < 6 && 8 > difficulty; pick++) { var objective = _objectives.GetRandomObjective(mindId, mind, wizardRule.ObjectiveGroup); if (objective == null) continue; _mind.AddObjective(mindId, mind, objective.Value); var adding = Comp(objective.Value).Difficulty; difficulty += adding; } } private void AfterEntitySelected(Entity ent, ref AfterAntagEntitySelectedEvent args) { MakeWizard(args.EntityUid, ent); } private void OnAntagSelectEntity(Entity ent, ref AntagSelectEntityEvent args) { if (args.Handled) return; if (!args.Entity.HasValue) return; var wizardAppearanceComponent = EnsureComp(args.Entity.Value); // TODO: Пофиксить, что игрун сохраняет свой прототип вместе с расой и остаются абилки расы var entity = _wizardAppearance.GetWizardEntity(wizardAppearanceComponent); if (entity != EntityUid.Invalid) args.Entity = entity; } private void MakeWizard(EntityUid wizard, WizardRuleComponent component, bool giveObjectives = true) { if (!_mind.TryGetMind(wizard, out var mindId, out var mind)) return; component.WizardMinds.Add(mindId); if (!giveObjectives) return; GiveObjectives(mindId, mind, component); } private void CheckAnnouncement() { // Check for all at once gamemode if (GameTicker.GetActiveGameRules().Where(HasComp).Any()) return; var query = QueryActiveRules(); while (query.MoveNext(out _, out _, out var wizard, out _)) { _roundEndSystem.DoRoundEndBehavior( wizard.RoundEndBehavior, wizard.EvacShuttleTime, wizard.RoundEndTextSender, wizard.RoundEndTextShuttleCall, wizard.RoundEndTextAnnouncement); return; } } }