mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
b180ac0ebc
5 files changed
+100
-19
No files matched your search
@@ -204,6 +204,7 @@ public enum CustomRoles
|
||||
Tether,
|
||||
TimeManager,
|
||||
TimeMaster,
|
||||
ToiletMaster,
|
||||
Tornado,
|
||||
Tracker,
|
||||
Transmitter,
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EHR.Roles.Crewmate;
|
||||
using HarmonyLib;
|
||||
using Hazel;
|
||||
using InnerNet;
|
||||
using UnityEngine;
|
||||
@@ -34,7 +33,7 @@ namespace EHR
|
||||
public void Despawn()
|
||||
{
|
||||
PC.Despawn();
|
||||
AllObjects.Remove(Id);
|
||||
_ = new LateTask(() => AllObjects.Remove(Id), 0.001f, log: false);
|
||||
}
|
||||
|
||||
protected void Hide(PlayerControl player)
|
||||
@@ -284,10 +283,10 @@ namespace EHR
|
||||
|
||||
internal sealed class Toilet : CustomNetObject
|
||||
{
|
||||
internal Toilet(Vector2 position, IEnumerable<byte> visibleList)
|
||||
internal Toilet(Vector2 position, ParallelQuery<PlayerControl> hideList)
|
||||
{
|
||||
CreateNetObject("INCOMPLETE", position);
|
||||
Main.AllAlivePlayerControls.ExceptBy(visibleList, x => x.PlayerId).Do(Hide);
|
||||
hideList.Do(Hide);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using AmongUs.Data;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Crewmate;
|
||||
using EHR.Modules;
|
||||
using EHR.Neutral;
|
||||
using EHR.Patches;
|
||||
@@ -2388,6 +2389,7 @@ public static class Utils
|
||||
CustomRoles.Sentinel => Sentinel.PatrolCooldown.GetInt(),
|
||||
CustomRoles.Druid => Druid.VentCooldown.GetInt(),
|
||||
CustomRoles.Sentry => Roles.Impostor.Sentry.ShowInfoCooldown.GetInt(),
|
||||
CustomRoles.ToiletMaster => ToiletMaster.AbilityCooldown.GetInt(),
|
||||
CustomRoles.Sniper => Options.DefaultShapeshiftCooldown.GetInt(),
|
||||
CustomRoles.Assassin => Assassin.AssassinateCooldownOpt.GetInt(),
|
||||
CustomRoles.Undertaker => Undertaker.UndertakerAssassinateCooldown.GetInt(),
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Crewmate;
|
||||
using EHR.Modules;
|
||||
using EHR.Neutral;
|
||||
using EHR.Patches;
|
||||
@@ -223,6 +224,8 @@ class CheckMurderPatch
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ToiletMaster.OnAnyoneCheckMurderStart(killer, target)) return false;
|
||||
|
||||
Simon.RemoveTarget(killer, Simon.Instruction.Kill);
|
||||
|
||||
if (Mastermind.ManipulatedPlayers.ContainsKey(killer.PlayerId))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using UnityEngine;
|
||||
using static EHR.Options;
|
||||
|
||||
@@ -10,27 +11,30 @@ namespace EHR.Crewmate
|
||||
{
|
||||
public static bool On;
|
||||
|
||||
private static OptionItem AbilityCooldown;
|
||||
public static OptionItem AbilityCooldown;
|
||||
private static OptionItem AbilityUses;
|
||||
private static OptionItem ToiletDuration;
|
||||
private static OptionItem ToiletVisibility;
|
||||
private static OptionItem ToiletUseRadius;
|
||||
private static OptionItem PoopDuration;
|
||||
private static OptionItem ToiletUseTime;
|
||||
private static OptionItem BrownPoopSpeedBoost;
|
||||
private static OptionItem GreenPoopRadius;
|
||||
private static OptionItem RedPoopRadius;
|
||||
private static OptionItem RedPoopRoleBlockDuration;
|
||||
private static OptionItem RedPoopFreezeDuration;
|
||||
private static OptionItem PurplePoopNotifyOnKillAttempt;
|
||||
public static OptionItem AbilityUseGainWithEachTaskCompleted;
|
||||
public static OptionItem AbilityChargesWhenFinishedTasks;
|
||||
private static Dictionary<Poop, OptionItem> PoopDurationSettings = [];
|
||||
private static readonly Dictionary<Poop, OptionItem> PoopDurationSettings = [];
|
||||
|
||||
private Dictionary<byte, (Poop Poop, long TimeStamp, object Data)> ActivePoops = [];
|
||||
Dictionary<byte, long> PlayersUsingToilet = [];
|
||||
private Dictionary<byte, long> PlayersUsingToilet = [];
|
||||
|
||||
private Dictionary<Vector2, (Toilet NetObject, int Uses)> Toilets = [];
|
||||
static ToiletVisibilityOptions ToiletVisible => (ToiletVisibilityOptions)ToiletVisibility.GetValue();
|
||||
public override bool IsEnable => On;
|
||||
|
||||
private static ParallelQuery<PlayerControl> EmptyParallelQuery => Enumerable.Empty<PlayerControl>().AsParallel();
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
int id = 644700;
|
||||
@@ -49,7 +53,7 @@ namespace EHR.Crewmate
|
||||
ToiletUseRadius = FloatOptionItem.Create(++id, "TM.ToiletUseRadius", new(0f, 5f, 0.25f), 1f, tab)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster])
|
||||
.SetValueFormat(OptionFormat.Multiplier);
|
||||
PoopDuration = IntegerOptionItem.Create(++id, "TM.PoopDuration", new(0, 60, 1), 10, tab)
|
||||
ToiletUseTime = IntegerOptionItem.Create(++id, "TM.ToiletUseTime", new(0, 60, 1), 5, tab)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
BrownPoopSpeedBoost = FloatOptionItem.Create(++id, "TM.BrownPoopSpeedBoost", new(0f, 3f, 0.05f), 0.5f, tab)
|
||||
@@ -64,9 +68,6 @@ namespace EHR.Crewmate
|
||||
RedPoopRoleBlockDuration = IntegerOptionItem.Create(++id, "TM.RedPoopRoleBlockDuration", new(0, 60, 1), 10, tab)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
RedPoopFreezeDuration = IntegerOptionItem.Create(++id, "TM.RedPoopFreezeDuration", new(0, 60, 1), 10, tab)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
PurplePoopNotifyOnKillAttempt = BooleanOptionItem.Create(++id, "TM.PurplePoopNotifyOnKillAttempt", false, tab)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster]);
|
||||
AbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(++id, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 0.6f, tab)
|
||||
@@ -81,37 +82,74 @@ namespace EHR.Crewmate
|
||||
});
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
public override void Init()
|
||||
{
|
||||
On = true;
|
||||
On = false;
|
||||
Toilets = [];
|
||||
ActivePoops = [];
|
||||
PlayersUsingToilet = [];
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
public override void Add(byte playerId)
|
||||
{
|
||||
On = false;
|
||||
On = true;
|
||||
playerId.SetAbilityUseLimit(AbilityUses.GetFloat());
|
||||
}
|
||||
|
||||
public override void OnPet(PlayerControl pc)
|
||||
{
|
||||
var pos = pc.Pos();
|
||||
Toilets[pos] = (new(pos, [pc.PlayerId]), 0);
|
||||
ParallelQuery<PlayerControl> hideList = ToiletVisible switch
|
||||
{
|
||||
ToiletVisibilityOptions.Instant => EmptyParallelQuery,
|
||||
_ => Main.AllPlayerControls.Remove(pc)
|
||||
};
|
||||
Toilets[pos] = (new(pos, hideList), 0);
|
||||
|
||||
if (ToiletVisible == ToiletVisibilityOptions.Delayed)
|
||||
_ = new LateTask(() => Toilets[pos] = (new(pos, EmptyParallelQuery), Toilets[pos].Uses), 5f, log: false);
|
||||
}
|
||||
|
||||
public override void OnGlobalFixedUpdate(PlayerControl pc, bool lowLoad)
|
||||
{
|
||||
if (lowLoad || !pc.IsAlive() || !GameStates.IsInTask) return;
|
||||
|
||||
if (ActivePoops.TryGetValue(pc.PlayerId, out var activePoop) && activePoop.TimeStamp + PoopDurationSettings[activePoop.Poop].GetInt() <= Utils.TimeStamp)
|
||||
{
|
||||
ActivePoops.Remove(pc.PlayerId);
|
||||
switch (activePoop.Poop)
|
||||
{
|
||||
case Poop.Brown:
|
||||
Main.AllPlayerSpeed[pc.PlayerId] -= BrownPoopSpeedBoost.GetFloat();
|
||||
break;
|
||||
case Poop.Red:
|
||||
var defaultSpeed = Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod);
|
||||
((List<PlayerControl>)activePoop.Data).Do(x =>
|
||||
{
|
||||
Main.AllPlayerSpeed[x.PlayerId] = defaultSpeed;
|
||||
x.MarkDirtySettings();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var pos = pc.Pos();
|
||||
var toilet = Toilets.First(x => Vector2.Distance(x.Key, pos) <= ToiletUseRadius.GetFloat()).Value;
|
||||
if (toilet.Uses >= AbilityUses.GetInt() || PlayersUsingToilet.ContainsKey(pc.PlayerId)) return;
|
||||
|
||||
if (toilet.Uses >= AbilityUses.GetInt()) return;
|
||||
if (!PlayersUsingToilet.TryGetValue(pc.PlayerId, out var ts))
|
||||
{
|
||||
PlayersUsingToilet[pc.PlayerId] = Utils.TimeStamp;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ts + ToiletUseTime.GetInt() > Utils.TimeStamp) return;
|
||||
toilet.Uses++;
|
||||
|
||||
var poop = Enum.GetValues<Poop>().RandomElement();
|
||||
if (poop != Poop.Green) pc.Notify(Utils.ColorString(GetPoopColor(poop), Translator.GetString($"TM.{poop}PoopNotify")));
|
||||
switch (poop)
|
||||
{
|
||||
case Poop.Brown:
|
||||
@@ -132,10 +170,15 @@ namespace EHR.Crewmate
|
||||
{
|
||||
x.BlockRole(duration);
|
||||
Main.AllPlayerSpeed[x.PlayerId] = Main.MinSpeed;
|
||||
x.MarkDirtySettings();
|
||||
affectedPlayers.Add(x);
|
||||
});
|
||||
ActivePoops[pc.PlayerId] = (poop, Utils.TimeStamp, affectedPlayers);
|
||||
break;
|
||||
case Poop.Blue:
|
||||
case Poop.Purple:
|
||||
ActivePoops[pc.PlayerId] = (poop, Utils.TimeStamp, null);
|
||||
break;
|
||||
}
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole()} used a toilet => {poop} poop", "ToiletMaster");
|
||||
@@ -146,6 +189,39 @@ namespace EHR.Crewmate
|
||||
}
|
||||
}
|
||||
|
||||
public override void AfterMeetingTasks()
|
||||
{
|
||||
if (ToiletVisible == ToiletVisibilityOptions.AfterMeeting)
|
||||
Toilets.Values.Do(x => x.NetObject = new(Toilets.GetKeyByValue((x.NetObject, x.Uses)), EmptyParallelQuery));
|
||||
}
|
||||
|
||||
static Color GetPoopColor(Poop poop)
|
||||
{
|
||||
return poop switch
|
||||
{
|
||||
Poop.Brown => Palette.Brown,
|
||||
Poop.Green => Color.green,
|
||||
Poop.Red => Color.red,
|
||||
Poop.Purple => Palette.Purple,
|
||||
Poop.Blue => Color.blue,
|
||||
_ => Color.white
|
||||
};
|
||||
}
|
||||
|
||||
public static bool OnAnyoneCheckMurderStart(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
foreach (var state in Main.PlayerStates.Values)
|
||||
{
|
||||
if (state.Role is ToiletMaster tm && tm.ActivePoops.TryGetValue(killer.PlayerId, out var poop) && poop.Poop == Poop.Blue)
|
||||
{
|
||||
killer.RpcCheckAndMurder(target);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum ToiletVisibilityOptions
|
||||
{
|
||||
Instant,
|
||||
|
||||
Reference in new issue
Block a user