mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
202 lines
6.9 KiB
C#
202 lines
6.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using AmongUs.GameOptions;
|
|
using static EHR.Options;
|
|
using static EHR.Translator;
|
|
using static EHR.Utils;
|
|
|
|
namespace EHR.Roles;
|
|
|
|
internal class Sprayer : RoleBase
|
|
{
|
|
private static byte SprayerId = byte.MaxValue;
|
|
|
|
private static OptionItem KillCooldown;
|
|
private static OptionItem HasImpostorVision;
|
|
public static OptionItem CanVent;
|
|
private static OptionItem CD;
|
|
private static OptionItem UseLimitOpt;
|
|
public static OptionItem LoweredVision;
|
|
private static OptionItem LoweredSpeed;
|
|
private static OptionItem EffectDuration;
|
|
private static OptionItem MaxTrappedTimes;
|
|
|
|
private static readonly Dictionary<Vector2, SprayedArea> Traps = [];
|
|
private static readonly Dictionary<byte, int> TrappedCount = [];
|
|
public static readonly List<byte> LowerVisionList = [];
|
|
private static readonly Dictionary<byte, long> LastUpdate = [];
|
|
private static int Id => 643240;
|
|
|
|
private static PlayerControl SprayerPC => GetPlayerById(SprayerId);
|
|
|
|
public override bool IsEnable => SprayerId != byte.MaxValue;
|
|
|
|
public override void SetupCustomOption()
|
|
{
|
|
SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Sprayer);
|
|
|
|
KillCooldown = new FloatOptionItem(Id + 2, "KillCooldown", new(0f, 180f, 0.5f), 22.5f, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer])
|
|
.SetValueFormat(OptionFormat.Seconds);
|
|
|
|
HasImpostorVision = new BooleanOptionItem(Id + 3, "ImpostorVision", true, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer]);
|
|
|
|
CanVent = new BooleanOptionItem(Id + 4, "CanVent", true, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer]);
|
|
|
|
CD = new IntegerOptionItem(Id + 5, "AbilityCooldown", new(0, 90, 1), 15, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer])
|
|
.SetValueFormat(OptionFormat.Seconds);
|
|
|
|
UseLimitOpt = new IntegerOptionItem(Id + 6, "AbilityUseLimit", new(1, 90, 1), 5, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer])
|
|
.SetValueFormat(OptionFormat.Times);
|
|
|
|
LoweredVision = new FloatOptionItem(Id + 7, "FFA_LowerVision", new(0.05f, 1.5f, 0.05f), 0.25f, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer])
|
|
.SetValueFormat(OptionFormat.Multiplier);
|
|
|
|
LoweredSpeed = new FloatOptionItem(Id + 8, "FFA_DecreasedSpeed", new(0.05f, 3f, 0.05f), 0.8f, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer])
|
|
.SetValueFormat(OptionFormat.Multiplier);
|
|
|
|
EffectDuration = new IntegerOptionItem(Id + 10, "NegativeEffectDuration", new(1, 90, 1), 10, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer])
|
|
.SetValueFormat(OptionFormat.Seconds);
|
|
|
|
MaxTrappedTimes = new IntegerOptionItem(Id + 9, "SprayerMaxTrappedTimes", new(1, 90, 1), 3, TabGroup.NeutralRoles)
|
|
.SetParent(CustomRoleSpawnChances[CustomRoles.Sprayer])
|
|
.SetValueFormat(OptionFormat.Times);
|
|
}
|
|
|
|
public override void Init()
|
|
{
|
|
SprayerId = byte.MaxValue;
|
|
Traps.Clear();
|
|
TrappedCount.Clear();
|
|
LowerVisionList.Clear();
|
|
LastUpdate.Clear();
|
|
}
|
|
|
|
public override void Add(byte playerId)
|
|
{
|
|
SprayerId = playerId;
|
|
playerId.SetAbilityUseLimit(UseLimitOpt.GetFloat());
|
|
|
|
foreach (PlayerControl pc in Main.CachedAlivePlayerControls()) TrappedCount[pc.PlayerId] = 0;
|
|
}
|
|
|
|
public override void SetKillCooldown(byte id)
|
|
{
|
|
Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat();
|
|
}
|
|
|
|
public override bool CanUseImpostorVentButton(PlayerControl pc)
|
|
{
|
|
return CanVent.GetBool();
|
|
}
|
|
|
|
public override bool CanUseSabotage(PlayerControl pc)
|
|
{
|
|
return base.CanUseSabotage(pc) || (pc.IsAlive() && !(UsePhantomBasis.GetBool() && UsePhantomBasisForNKs.GetBool()));
|
|
}
|
|
|
|
public override void ApplyGameOptions(IGameOptions opt, byte id)
|
|
{
|
|
opt.SetVision(HasImpostorVision.GetBool());
|
|
if (UsePhantomBasis.GetBool() && UsePhantomBasisForNKs.GetBool()) AURoleOptions.PhantomCooldown = CD.GetInt();
|
|
}
|
|
|
|
public override bool OnSabotage(PlayerControl pc)
|
|
{
|
|
PlaceTrap();
|
|
return pc.Is(CustomRoles.Mischievous);
|
|
}
|
|
|
|
public override void OnPet(PlayerControl pc)
|
|
{
|
|
PlaceTrap();
|
|
}
|
|
|
|
public override bool OnVanish(PlayerControl pc)
|
|
{
|
|
PlaceTrap();
|
|
return false;
|
|
}
|
|
|
|
public override bool OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool shapeshifting)
|
|
{
|
|
if (!shapeshifting) return true;
|
|
|
|
PlaceTrap();
|
|
return false;
|
|
}
|
|
|
|
private void PlaceTrap()
|
|
{
|
|
if (!IsEnable || SprayerId.GetAbilityUseLimit() <= 0 || SprayerPC.HasAbilityCD()) return;
|
|
|
|
Vector2 pos = SprayerPC.Pos();
|
|
Traps[pos] = new(pos, SprayerPC);
|
|
SprayerPC.RpcRemoveAbilityUse();
|
|
|
|
if (SprayerId.GetAbilityUseLimit() > 0) SprayerPC.AddAbilityCD(CD.GetInt());
|
|
|
|
SprayerPC.Notify(GetString("SprayerNotify"));
|
|
}
|
|
|
|
public override void OnCheckPlayerPosition(PlayerControl pc)
|
|
{
|
|
if (!IsEnable || !GameStates.IsInTask || Traps.Count == 0) return;
|
|
|
|
long now = TimeStamp;
|
|
|
|
if (pc.PlayerId == SprayerId) return;
|
|
|
|
LastUpdate.TryAdd(pc.PlayerId, now);
|
|
if (LastUpdate[pc.PlayerId] + 3 > now) return;
|
|
|
|
LastUpdate[pc.PlayerId] = now;
|
|
|
|
foreach (KeyValuePair<Vector2, SprayedArea> trap in Traps)
|
|
{
|
|
if (FastVector2.DistanceWithinRange(pc.Pos(), trap.Key, 2f))
|
|
{
|
|
byte playerId = pc.PlayerId;
|
|
float tempSpeed = Main.AllPlayerSpeed[playerId];
|
|
Main.AllPlayerSpeed[playerId] = LoweredSpeed.GetFloat();
|
|
LowerVisionList.Add(playerId);
|
|
TrappedCount[playerId]++;
|
|
|
|
if (TrappedCount[playerId] > MaxTrappedTimes.GetInt())
|
|
{
|
|
pc.Suicide(realKiller: SprayerPC);
|
|
TrappedCount.Remove(playerId);
|
|
}
|
|
else
|
|
{
|
|
pc.MarkDirtySettings();
|
|
|
|
LateTask.New(() =>
|
|
{
|
|
Main.AllPlayerSpeed[playerId] = tempSpeed;
|
|
LowerVisionList.Remove(playerId);
|
|
if (GameStates.IsInTask) pc.MarkDirtySettings();
|
|
}, EffectDuration.GetFloat(), "Sprayer Revert Effects");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void OnReportDeadBody()
|
|
{
|
|
Traps.Clear();
|
|
}
|
|
|
|
public override void AfterMeetingTasks()
|
|
{
|
|
if (Main.PlayerStates[SprayerId].IsDead) return;
|
|
if (SprayerId.GetAbilityUseLimit() > 0) SprayerPC.AddAbilityCD(Math.Max(15, CD.GetInt()));
|
|
}
|
|
} |