SecretPluginLaboratories/CustomClasses/NegromancerHandler.cs
2025-07-14 09:38:20 +02:00

152 lines
4.8 KiB
C#

using CustomPlayerEffects;
using LabApi.Events.Arguments.Scp049Events;
using LabApi.Events.Handlers;
using LabApi.Features.Console;
using LabApi.Features.Wrappers;
using MEC;
using PlayerRoles;
using PlayerRoles.PlayableScps.Scp049;
using PlayerRoles.PlayableScps.Scp106;
namespace CustomClasses;
public class NegromancerHandler : CustomClassHandler
{
protected override void SendSpawnMessage(Player player, CustomClassConfig config)
{
player.SendBroadcast("You are the <color=#6e2e99>Negromancer</color>! Revived players become your <color=#3c1361>Shadow</color>.", CustomClasses.BroadcastDuration);
}
}
public class NegromancerManager
{
private readonly CustomClasses _plugin;
public static bool IsNegromancer(Player player) => player.CustomInfo.Contains("Shadowmancer");
public static bool IsShadow(Player player) => player.CustomInfo.Contains("Shadow") && !IsNegromancer(player);
public NegromancerManager(CustomClasses plugin)
{
_plugin = plugin;
Scp049Events.ResurrectedBody += OnScp049ResurrectedBody;
Timing.RunCoroutine(HealNearbyShadows());
Scp106Events.TeleportingPlayer += ev =>
{
if (!IsShadow(ev.Player)) return;
ev.IsAllowed = false;
ev.Target.EnableEffect<CardiacArrest>(1, float.PositiveInfinity);
ev.Target.Damage(40f, ev.Player);
ev.Player.SendHitMarker();
};
Scp106Events.UsingHunterAtlas += ev =>
{
if (!IsShadow(ev.Player)) return;
ev.IsAllowed = false;
var position = ev.DestinationPosition;
var room = Room.GetRoomAtPosition(position);
if (room?.LightController == null)
{
return;
}
var stat = ev.Player.GetStatModule<VigorStat>();
stat.CurValue = 0;
room.LightController.FlickerLights(3);
};
Scp106Events.ChangingSubmersionStatus += ev =>
{
if (!IsShadow(ev.Player)) return;
ev.IsAllowed = false;
var stat = ev.Player.GetStatModule<VigorStat>();
ev.Player.DisableEffect<MovementBoost>();
var scaled = stat.CurValue * 40f;
var scaledByte = (byte)scaled;
if(scaledByte < 15) scaledByte = 15;
Logger.Debug($"Scaled {stat.CurValue} to {scaledByte}");
ev.Player.EnableEffect<MovementBoost>(scaledByte, 20);
stat.CurValue = 0;
Timing.CallDelayed(10, () =>
{
ev.Player.DisableEffect<MovementBoost>();
ev.Player.EnableEffect<MovementBoost>(10, float.PositiveInfinity);
});
};
Scp106Events.ChangingVigor += ev =>
{
if (!IsShadow(ev.Player)) return;
var delta = ev.Value - ev.OldValue;
delta *= 0.5f;
ev.Value = ev.OldValue + delta;
};
}
private static IEnumerator<float> HealNearbyShadows()
{
while (true)
{
yield return Timing.WaitForSeconds(1);
try
{
Player.ReadyList.Where(IsNegromancer).Where(x =>
{
var scp = x.RoleBase as Scp049Role;
if (scp == null)
{
Logger.Error("Negromancer has no Scp049Role");
return false;
}
scp.SubroutineModule.TryGetSubroutine(out Scp049CallAbility ability);
if (ability) return ability.IsMarkerShown;
Logger.Error("Negromancer has no Scp049CallAbility");
return false;
}).ToList().ForEach(player =>
{
Player.ReadyList.Where(IsShadow).Where(x =>
{
var distance = (x.Position - player.Position).SqrMagnitudeIgnoreY();
return distance < 64;
}
).ToList().ForEach(x => x.Heal(10));
});
}
catch (Exception e)
{
// ignored
}
}
// ReSharper disable once IteratorNeverReturns
}
private void OnScp049ResurrectedBody(Scp049ResurrectedBodyEventArgs ev)
{
var classManager = _plugin.ClassManager;
if (classManager == null ||
!IsNegromancer(ev.Player)) return;
ev.Target.SetRole(RoleTypeId.Scp106, RoleChangeReason.Respawn, RoleSpawnFlags.None);
classManager.ForceSpawn(ev.Target, classManager.GetConfig<NegromancerShadowConfig>(), typeof(NegromancerShadowConfig), null);
}
}