Continue Toilet Master

This commit is contained in:
Gurge44 committed 2024-05-27 16:42:20 +02:00
1 parent 9b7012c36d
commit 37bf93267f
3 files changed
+128 -17

No files matched your search

+62 -1
View File
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
// ReSharper disable ConvertIfStatementToReturnStatement
@@ -72,5 +74,64 @@ namespace EHR
{
return firstCollection.Concat(collections.SelectMany(x => x));
}
/// <summary>
/// Executes an action for each element in a collection in parallel
/// </summary>
/// <param name="collection">The collection to iterate over</param>
/// <param name="action">The action to execute for each element</param>
/// <typeparam name="T">The type of the elements in the collection</typeparam>
public static void Do<T>(this IEnumerable<T> collection, System.Action<T> action)
{
Parallel.ForEach(collection, action);
}
/// <summary>
/// Executes an action for each element in a collection in parallel
/// </summary>
/// <param name="collection">The collection to iterate over</param>
/// <param name="action">The action to execute for each element</param>
/// <typeparam name="T">The type of the elements in the collection</typeparam>
public static void Do<T>(this ParallelQuery<T> collection, System.Action<T> action)
{
collection.ForAll(action);
}
/// <summary>
/// Executes an action for each element in a collection in parallel if the predicate is true
/// </summary>
/// <param name="collection">The collection to iterate over</param>
/// <param name="predicate">The predicate to check for each element</param>
/// <param name="action">The action to execute for each element that satisfies the predicate</param>
/// <typeparam name="T">The type of the elements in the collection</typeparam>
public static void DoIf<T>(this IEnumerable<T> collection, System.Func<T, bool> predicate, System.Action<T> action)
{
var partitioner = Partitioner.Create(collection.Where(predicate));
Parallel.ForEach(partitioner, action);
}
/// <summary>
/// Executes an action for each element in a collection in parallel if the predicate is true
/// </summary>
/// <param name="collection">The collection to iterate over</param>
/// <param name="predicate">The predicate to check for each element</param>
/// <param name="action">The action to execute for each element that satisfies the predicate</param>
/// <typeparam name="T">The type of the elements in the collection</typeparam>
public static void DoIf<T>(this ParallelQuery<T> collection, System.Func<T, bool> predicate, System.Action<T> action)
{
collection.Where(predicate).ForAll(action);
}
/// <summary>
/// Removes an element from a collection
/// </summary>
/// <param name="collection">The collection to remove the element from</param>
/// <param name="element">The element to remove</param>
/// <typeparam name="T">The type of the elements in the collection</typeparam>
/// <returns>A collection containing all elements of <paramref name="collection"/> except for <paramref name="element"/></returns>
public static ParallelQuery<T> Remove<T>(this IEnumerable<T> collection, T element)
{
return collection.AsParallel().Where(x => !x.Equals(element));
}
}
}
+64 -14
View File
@@ -9,10 +9,6 @@ namespace EHR.Crewmate
public class ToiletMaster : RoleBase
{
public static bool On;
public override bool IsEnable => On;
private Dictionary<Vector2, (Toilet NetObject, int Uses)> Toilets = [];
Dictionary<byte, (Poop Poop, long TimeStamp)> ActivePoops = [];
private static OptionItem AbilityCooldown;
private static OptionItem AbilityUses;
@@ -23,14 +19,17 @@ namespace EHR.Crewmate
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 Dictionary<byte, (Poop Poop, long TimeStamp, object Data)> ActivePoops = [];
Dictionary<byte, long> PlayersUsingToilet = [];
enum ToiletVisibilityOptions
{
Instant,
Delayed,
AfterMeeting,
Invisible
}
private Dictionary<Vector2, (Toilet NetObject, int Uses)> Toilets = [];
public override bool IsEnable => On;
public static void SetupCustomOption()
{
@@ -62,6 +61,24 @@ namespace EHR.Crewmate
RedPoopRadius = FloatOptionItem.Create(++id, "TM.RedPoopRadius", new(0f, 5f, 0.25f), 1f, tab)
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster])
.SetValueFormat(OptionFormat.Multiplier);
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)
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster]);
AbilityChargesWhenFinishedTasks = FloatOptionItem.Create(++id, "AbilityChargesWhenFinishedTasks", new(0f, 5f, 0.05f), 0.1f, tab)
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster]);
Enum.GetValues<Poop>().Do(poop =>
{
PoopDurationSettings[poop] = IntegerOptionItem.Create(++id, $"TM.{poop}PoopDuration", new(0, 60, 1), 10, tab)
.SetParent(CustomRoleSpawnChances[CustomRoles.ToiletMaster])
.SetValueFormat(OptionFormat.Seconds);
});
}
public override void Add(byte playerId)
@@ -69,6 +86,7 @@ namespace EHR.Crewmate
On = true;
Toilets = [];
ActivePoops = [];
PlayersUsingToilet = [];
}
public override void Init()
@@ -90,20 +108,52 @@ namespace EHR.Crewmate
{
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;
toilet.Uses++;
var poop = Enum.GetValues<Poop>().Shuffle()[0];
var poop = Enum.GetValues<Poop>().RandomElement();
switch (poop)
{
// INCOMPLETE
case Poop.Brown:
Main.AllPlayerSpeed[pc.PlayerId] += BrownPoopSpeedBoost.GetFloat();
ActivePoops[pc.PlayerId] = (poop, Utils.TimeStamp, null);
break;
case Poop.Green:
var radius = GreenPoopRadius.GetFloat();
var isKillerNearby = Main.AllAlivePlayerControls.Any(x => x.PlayerId != pc.PlayerId && Vector2.Distance(x.Pos(), pos) <= radius);
var color = isKillerNearby ? Color.red : Color.green;
var str = Translator.GetString(isKillerNearby ? "TM.GreenPoopKiller" : "TM.GreenPoop");
pc.Notify(Utils.ColorString(color, str));
break;
case Poop.Red:
var duration = RedPoopRoleBlockDuration.GetInt();
List<PlayerControl> affectedPlayers = [];
Utils.GetPlayersInRadius(RedPoopRadius.GetFloat(), pos).Remove(pc).Do(x =>
{
x.BlockRole(duration);
Main.AllPlayerSpeed[x.PlayerId] = Main.MinSpeed;
affectedPlayers.Add(x);
});
ActivePoops[pc.PlayerId] = (poop, Utils.TimeStamp, affectedPlayers);
break;
}
Logger.Info($"{pc.GetNameWithRole()} used a toilet => {poop} poop", "ToiletMaster");
}
catch
{
return;
PlayersUsingToilet.Remove(pc.PlayerId);
}
}
enum ToiletVisibilityOptions
{
Instant,
Delayed,
AfterMeeting,
Invisible
}
enum Poop
{
Brown,
+2 -2
View File
@@ -252,8 +252,8 @@ namespace EHR.Roles.Neutral
return new(title, allAnswersList.ToArray(), correctIndex);
IEnumerable<string> GetTwoRandomNames(string except) => Main.AllPlayerControls.Select(x => x?.GetRealName()).Where(x => x != except).Shuffle().TakeLast(2);
IEnumerable<string> GetTwoRandomNumbers(params int[] nums) => Enumerable.Range(nums[1], nums[2]).Where(x => x != nums[0]).Shuffle().Take(2).Select(x => x.ToString());
IEnumerable<string> GetTwoRandomNames(string except) => Main.AllPlayerControls.Select(x => x?.GetRealName()).Remove(except).Shuffle().TakeLast(2);
IEnumerable<string> GetTwoRandomNumbers(params int[] nums) => Enumerable.Range(nums[1], nums[2]).Remove(nums[0]).Shuffle().Take(2).Select(x => x.ToString());
}
public override void OnReportDeadBody()