using Content.Server.Actions;
using Content.Server.Popups;
using Content.Server.Stunnable;
using Content.Shared._EE.Shadowling;
using Content.Shared.Actions;
using Content.Shared.Popups;
using Content.Shared.StatusEffect;
using Robust.Server.GameObjects;
namespace Content.Server._EE.Shadowling;
///
/// This handles the logic of the Collective Mind ability.
/// The Collective Mind ability lets you gain new actions, and informs you
/// how many Thralls are required to ascend. At the same time, it stuns all Thralls for a very short amount of time.
///
public sealed class ShadowlingCollectiveMindSystem : EntitySystem
{
///
[Dependency] private readonly ActionsSystem _actions = default!;
[Dependency] private readonly PopupSystem _popups = default!;
[Dependency] private readonly StunSystem _stun = default!;
[Dependency] private readonly IComponentFactory _compFactory = default!;
[Dependency] private readonly TransformSystem _transform = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent(OnCollectiveMind);
}
private void OnCollectiveMind(EntityUid uid, ShadowlingCollectiveMindComponent comp, CollectiveMindEvent args)
{
if (!TryComp(uid, out var actions))
return;
if (!TryComp(uid, out var sling))
return;
if (comp.AbilitiesAdded >= comp.Locked.Count)
{
_popups.PopupEntity(Loc.GetString("shadowling-collective-mind-ascend"), uid, uid, PopupType.Medium);
return;
}
comp.AmountOfThralls = sling.Thralls.Count;
var thrallsRemaining = comp.ThrallsRequiredForAscension - comp.AmountOfThralls; // aka Thralls required for ascension
if (thrallsRemaining < 0)
thrallsRemaining = 0;
var abiltiesAddedCount = 0;
// Can we gain this power?
foreach (var actionData in comp.Locked)
{
if (comp.AmountOfThralls >= actionData.UnlockAtThralls)
{
if (actionData.Added)
continue;
_actions.AddAction(args.Performer, actionData.ActionPrototype, actionData.ActionEntity, component: actions);
var componentToAdd = _compFactory.GetComponent(actionData.ActionComponentName);
EntityManager.AddComponent(args.Performer, componentToAdd);
++abiltiesAddedCount;
++comp.AbilitiesAdded;
actionData.Added = true;
}
}
if (abiltiesAddedCount > 0)
{
_popups.PopupEntity(
Loc.GetString("shadowling-collective-mind-success", ("thralls", thrallsRemaining)),
uid,
uid,
PopupType.Medium);
var effectEnt = Spawn(comp.CollectiveMindEffect, _transform.GetMapCoordinates(uid));
_transform.SetParent(effectEnt, uid);
}
else
{
_popups.PopupEntity(Loc.GetString("shadowling-collective-mind-failure", ("thralls", thrallsRemaining)),
uid,
uid,
PopupType.Medium);
return;
}
// Stun starts here.
// Scales with amount of abilities added.
// If no abilities were added, nothing happens as seen from the return statement above.
foreach (var thrall in sling.Thralls)
{
if (!HasComp(thrall))
return;
_stun.TryParalyze(thrall, TimeSpan.FromSeconds(comp.BaseStunTime * abiltiesAddedCount + 1), false);
}
}
}