mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
151 lines
5.5 KiB
C#
151 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using AmongUs.GameOptions;
|
|
using UnityEngine;
|
|
|
|
namespace EHR.Impostor
|
|
{
|
|
public class Abyssbringer : RoleBase
|
|
{
|
|
public static bool On;
|
|
|
|
private static OptionItem BlackHolePlaceCooldown;
|
|
private static OptionItem BlackHoleDespawnMode;
|
|
private static OptionItem BlackHoleDespawnTime;
|
|
private static OptionItem BlackHoleMovesTowardsNearestPlayer;
|
|
private static OptionItem BlackHoleMoveSpeed;
|
|
|
|
private List<(BlackHole NetObject, long PlaceTimeStamp, Vector2 Position)> BlackHoles = [];
|
|
public override bool IsEnable => On;
|
|
|
|
public static void SetupCustomOption()
|
|
{
|
|
int id = 649800;
|
|
const TabGroup tab = TabGroup.ImpostorRoles;
|
|
const CustomRoles role = CustomRoles.Abyssbringer;
|
|
Options.SetupRoleOptions(id++, tab, role);
|
|
BlackHolePlaceCooldown = new IntegerOptionItem(++id, "BlackHolePlaceCooldown", new(1, 180, 1), 30, tab)
|
|
.SetParent(Options.CustomRoleSpawnChances[role])
|
|
.SetValueFormat(OptionFormat.Seconds);
|
|
BlackHoleDespawnMode = new StringOptionItem(++id, "BlackHoleDespawnMode", Enum.GetNames<DespawnMode>(), 0, tab)
|
|
.SetParent(Options.CustomRoleSpawnChances[role]);
|
|
BlackHoleDespawnTime = new IntegerOptionItem(++id, "BlackHoleDespawnTime", new(1, 60, 1), 15, tab)
|
|
.SetParent(BlackHoleDespawnMode)
|
|
.SetValueFormat(OptionFormat.Seconds);
|
|
BlackHoleMovesTowardsNearestPlayer = new BooleanOptionItem(++id, "BlackHoleMovesTowardsNearestPlayer", true, tab)
|
|
.SetParent(Options.CustomRoleSpawnChances[role]);
|
|
BlackHoleMoveSpeed = new FloatOptionItem(++id, "BlackHoleMoveSpeed", new(0.25f, 10f, 0.25f), 1f, tab)
|
|
.SetParent(BlackHoleMovesTowardsNearestPlayer);
|
|
}
|
|
|
|
public override void Add(byte playerId)
|
|
{
|
|
On = true;
|
|
BlackHoles = [];
|
|
}
|
|
|
|
public override void Init()
|
|
{
|
|
On = false;
|
|
}
|
|
|
|
public override void ApplyGameOptions(IGameOptions opt, byte playerId)
|
|
{
|
|
if (Options.UsePhantomBasis.GetBool()) AURoleOptions.PhantomCooldown = BlackHolePlaceCooldown.GetInt();
|
|
else
|
|
{
|
|
AURoleOptions.ShapeshifterCooldown = BlackHolePlaceCooldown.GetInt();
|
|
AURoleOptions.ShapeshifterDuration = 1f;
|
|
}
|
|
}
|
|
|
|
public override bool OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool shapeshifting)
|
|
{
|
|
if (!shapeshifting && !Options.UseUnshiftTrigger.GetBool()) return true;
|
|
CreateBlackHole(shapeshifter);
|
|
return false;
|
|
}
|
|
|
|
public override void OnPet(PlayerControl pc)
|
|
{
|
|
CreateBlackHole(pc);
|
|
}
|
|
|
|
public override bool OnVanish(PlayerControl pc)
|
|
{
|
|
CreateBlackHole(pc);
|
|
return false;
|
|
}
|
|
|
|
private void CreateBlackHole(PlayerControl shapeshifter)
|
|
{
|
|
var pos = shapeshifter.Pos();
|
|
BlackHoles.Add((new(pos), Utils.TimeStamp, pos));
|
|
}
|
|
|
|
public override void OnFixedUpdate(PlayerControl pc)
|
|
{
|
|
int count = BlackHoles.Count;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var blackHole = BlackHoles[i];
|
|
|
|
var despawnMode = (DespawnMode)BlackHoleDespawnMode.GetValue();
|
|
switch (despawnMode)
|
|
{
|
|
case DespawnMode.AfterTime when Utils.TimeStamp - blackHole.PlaceTimeStamp > BlackHoleDespawnTime.GetInt():
|
|
RemoveBlackHole();
|
|
continue;
|
|
case DespawnMode.AfterMeeting when GameStates.IsMeeting:
|
|
RemoveBlackHole();
|
|
continue;
|
|
}
|
|
|
|
var nearestPlayer = Main.AllAlivePlayerControls.Without(pc).MinBy(x => Vector2.Distance(x.Pos(), blackHole.Position));
|
|
if (nearestPlayer != null)
|
|
{
|
|
var pos = nearestPlayer.Pos();
|
|
|
|
if (BlackHoleMovesTowardsNearestPlayer.GetBool() && GameStates.IsInTask && !ExileController.Instance)
|
|
{
|
|
var direction = (pos - blackHole.Position).normalized;
|
|
var newPosition = blackHole.Position + direction * BlackHoleMoveSpeed.GetFloat() * Time.fixedDeltaTime;
|
|
blackHole.NetObject.TP(newPosition);
|
|
blackHole.Position = newPosition;
|
|
}
|
|
|
|
if (Vector2.Distance(pos, blackHole.Position) < 0.5f)
|
|
{
|
|
nearestPlayer.RpcExileV2();
|
|
|
|
var state = Main.PlayerStates[nearestPlayer.PlayerId];
|
|
state.deathReason = PlayerState.DeathReason.Consumed;
|
|
state.SetDead();
|
|
|
|
if (despawnMode == DespawnMode.After1PlayerEaten)
|
|
{
|
|
RemoveBlackHole();
|
|
}
|
|
}
|
|
}
|
|
|
|
continue;
|
|
|
|
void RemoveBlackHole()
|
|
{
|
|
BlackHoles.RemoveAt(i);
|
|
blackHole.NetObject.Despawn();
|
|
}
|
|
}
|
|
}
|
|
|
|
enum DespawnMode
|
|
{
|
|
None,
|
|
AfterTime,
|
|
After1PlayerEaten,
|
|
AfterMeeting
|
|
}
|
|
}
|
|
} |