various fixes + new custom class shadowmancer
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
using System.Net;
|
||||
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
|
||||
{
|
||||
public override void HandleSpawn(Player player, CustomClassConfig config, Random random)
|
||||
{
|
||||
player.SendBroadcast("You are the <color=#6e2e99>Negromancer</color>! Revived players become your <color=#3c1361>Shadow</color>.", CustomClasses.BroadcastDuration);
|
||||
const string customInfo = "<color=#A0A0A0>Shadowmancer</color>";
|
||||
if (!Player.ValidateCustomInfo(customInfo, out var reason))
|
||||
{
|
||||
Logger.Error($"Invalid custom info for Negromancer: {reason}");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.CustomInfo = customInfo;
|
||||
player.InfoArea |= PlayerInfoArea.CustomInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
// Check if the reviver is a Negromancer
|
||||
if (classManager == null ||
|
||||
!IsNegromancer(ev.Player)) return;
|
||||
|
||||
ev.Target.SetRole(RoleTypeId.Scp106, RoleChangeReason.Respawn, RoleSpawnFlags.None);
|
||||
classManager.ForceSpawn(ev.Target, _plugin.NegromancerShadowConfig, typeof(NegromancerShadowConfig), null);
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user