From 6408f44818cc300010b4c37eef4ee1a67199a47a Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Mon, 23 Feb 2026 07:36:48 +0100
Subject: [PATCH 01/17] Exiled.Utility
---
EXILED/EXILED.sln | 12 +-
.../Commands/TpsCommand.cs | 2 +-
EXILED/Exiled.Utility/Config.cs | 114 ++++++++++++++++++
EXILED/Exiled.Utility/Exiled.Utility.csproj | 57 +++++++++
EXILED/Exiled.Utility/Utility.cs | 93 ++++++++++++++
EXILED/build.ps1 | 1 +
6 files changed, 276 insertions(+), 3 deletions(-)
rename EXILED/{Exiled.Events => Exiled.Utility}/Commands/TpsCommand.cs (97%)
create mode 100644 EXILED/Exiled.Utility/Config.cs
create mode 100644 EXILED/Exiled.Utility/Exiled.Utility.csproj
create mode 100644 EXILED/Exiled.Utility/Utility.cs
diff --git a/EXILED/EXILED.sln b/EXILED/EXILED.sln
index 60b7f5f72c..6c48410428 100644
--- a/EXILED/EXILED.sln
+++ b/EXILED/EXILED.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.4.33205.214
+# Visual Studio Version 18
+VisualStudioVersion = 18.3.11512.155 d18.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exiled.Events", "Exiled.Events\Exiled.Events.csproj", "{1E6C4350-5067-4CE7-91DB-6420D027A4FC}"
EndProject
@@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exiled.CustomRoles", "Exile
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "docs", "docs\docs.csproj", "{BE130A80-6819-44C6-AA1B-BF068DEA67FF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exiled.Utility", "Exiled.Utility\Exiled.Utility.csproj", "{70A4E012-0DBB-18AA-A972-770281EEF726}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -82,6 +84,12 @@ Global
{BE130A80-6819-44C6-AA1B-BF068DEA67FF}.Installer|Any CPU.Build.0 = Installer|Any CPU
{BE130A80-6819-44C6-AA1B-BF068DEA67FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE130A80-6819-44C6-AA1B-BF068DEA67FF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {70A4E012-0DBB-18AA-A972-770281EEF726}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {70A4E012-0DBB-18AA-A972-770281EEF726}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {70A4E012-0DBB-18AA-A972-770281EEF726}.Installer|Any CPU.ActiveCfg = Installer|Any CPU
+ {70A4E012-0DBB-18AA-A972-770281EEF726}.Installer|Any CPU.Build.0 = Installer|Any CPU
+ {70A4E012-0DBB-18AA-A972-770281EEF726}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {70A4E012-0DBB-18AA-A972-770281EEF726}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/EXILED/Exiled.Events/Commands/TpsCommand.cs b/EXILED/Exiled.Utility/Commands/TpsCommand.cs
similarity index 97%
rename from EXILED/Exiled.Events/Commands/TpsCommand.cs
rename to EXILED/Exiled.Utility/Commands/TpsCommand.cs
index 14c0def05e..dcbe781824 100644
--- a/EXILED/Exiled.Events/Commands/TpsCommand.cs
+++ b/EXILED/Exiled.Utility/Commands/TpsCommand.cs
@@ -5,7 +5,7 @@
//
// -----------------------------------------------------------------------
-namespace Exiled.Events.Commands
+namespace Exiled.Utility.Commands
{
using System;
diff --git a/EXILED/Exiled.Utility/Config.cs b/EXILED/Exiled.Utility/Config.cs
new file mode 100644
index 0000000000..886aef6da5
--- /dev/null
+++ b/EXILED/Exiled.Utility/Config.cs
@@ -0,0 +1,114 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Utility
+{
+ using System.ComponentModel;
+
+ using API.Interfaces;
+
+ ///
+ public sealed class Config : IConfig
+ {
+ ///
+ public bool IsEnabled { get; set; } = true;
+
+ ///
+ public bool Debug { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether events are only patched if they have delegates subscribed to them.
+ ///
+ [Description("Indicates whether events are patched only if they have delegates subscribed to them")]
+ public bool UseDynamicPatching { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether SCP-173 can be blocked by the tutorial.
+ ///
+ [Description("Indicates whether SCP-173 can be blocked by the tutorial")]
+ public bool CanTutorialBlockScp173 { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether SCP-096 can be triggered by the tutorial.
+ ///
+ [Description("Indicates whether SCP-096 can be triggered by the tutorial")]
+ public bool CanTutorialTriggerScp096 { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether SCP-049 can activate the sense ability on tutorials.
+ ///
+ [Description("Indicates whether SCP-049 can sense tutorial players")]
+ public bool CanScp049SenseTutorial { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether tutorial is affected by SCP-079 scan.
+ ///
+ [Description("Indicates whether tutorial is affected by SCP-079 scan.")]
+ public bool TutorialNotAffectedByScp079Scan { get; set; } = false;
+
+ ///
+ /// Gets or sets a value indicating whether flashbangs flash original thrower.
+ ///
+ [Description("Indicates whether flashbangs flash original thrower.")]
+ public bool CanFlashbangsAffectThrower { get; set; } = false;
+
+ ///
+ /// Gets or sets a value indicating whether the name tracking (invisible EXILED version string added to the end of the server name) is enabled or not.
+ ///
+ [Description("Indicates whether the name tracking (invisible EXILED version string added to the end of the server name) is enabled or not")]
+ public bool IsNameTrackingEnabled { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether the inventory should be dropped before being set as spectator, through commands or plugins.
+ ///
+ [Description("Indicates whether the inventory should be dropped before being set as spectator, through commands or plugins")]
+ public bool ShouldDropInventory { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether the blood can be spawned.
+ ///
+ [Description("Indicates whether the blood can be spawned")]
+ public bool CanSpawnBlood { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether keycard throw can affect basic doors.
+ ///
+ /// TODO: Make a poll about removing this config. (unimplemented since 9.6.0-beta7)
+ [Description("Indicates whether thrown keycards can affect doors that don't require any permissions")]
+ public bool CanKeycardThrowAffectDoors { get; set; } = false;
+
+ ///
+ /// Gets or sets a value indicating whether the SCP079 will recontained if there are no SCPs left.
+ ///
+ [Description("Indicates whether the SCP079 will recontained if there are no SCPs left.")]
+ public bool RecontainScp079IfNoScpsLeft { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether configs has to be reloaded every time a round restarts.
+ ///
+ [Description("Indicates whether configs have to be reloaded every round restart")]
+ public bool ShouldReloadConfigsAtRoundRestart { get; set; } = false;
+
+ ///
+ /// Gets or sets a value indicating whether translations has to be reloaded every time a round restarts.
+ ///
+ [Description("Indicates whether translations has to be reloaded every round restart")]
+ public bool ShouldReloadTranslationsAtRoundRestart { get; set; } = false;
+
+ ///
+ /// Gets a value indicating whether bans should be logged.
+ ///
+ [Description("Indicates whether bans should be logged")]
+ public bool ShouldLogBans { get; private set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether to log RA commands.
+ ///
+ [Description("Whether to log RA commands.")]
+ public bool LogRaCommands { get; set; } = true;
+ }
+}
diff --git a/EXILED/Exiled.Utility/Exiled.Utility.csproj b/EXILED/Exiled.Utility/Exiled.Utility.csproj
new file mode 100644
index 0000000000..cca7e1e48a
--- /dev/null
+++ b/EXILED/Exiled.Utility/Exiled.Utility.csproj
@@ -0,0 +1,57 @@
+
+
+
+
+ Library
+ Exiled.Utility
+ true
+ Debug;Release;Installer
+ AnyCPU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if not "$(EXILED_DEV_REFERENCES)"=="" copy /y "$(OutputPath)$(AssemblyName).dll" "$(EXILED_DEV_REFERENCES)\Plugins\"
+
+
+ if [[ ! -z "$EXILED_DEV_REFERENCES" ]]; then cp "$(OutputPath)$(AssemblyName).dll" "$EXILED_DEV_REFERENCES/Plugins/"; fi
+
+
+
diff --git a/EXILED/Exiled.Utility/Utility.cs b/EXILED/Exiled.Utility/Utility.cs
new file mode 100644
index 0000000000..c0a6a24d15
--- /dev/null
+++ b/EXILED/Exiled.Utility/Utility.cs
@@ -0,0 +1,93 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Utility
+{
+ using System;
+ using System.Diagnostics;
+
+ using API.Enums;
+ using API.Features;
+ using CentralAuth;
+ using Exiled.API.Features.Core.UserSettings;
+ using Exiled.Events.Features;
+ using HarmonyLib;
+ using InventorySystem.Items.Pickups;
+ using InventorySystem.Items.Usables;
+ using PlayerRoles.Ragdolls;
+ using PlayerRoles.RoleAssign;
+
+ using Respawning;
+ using UnityEngine.SceneManagement;
+ using UserSettings.ServerSpecific;
+
+ ///
+ /// Patch and unpatch events into the game.
+ ///
+ public sealed class Utility : Plugin
+ {
+ ///
+ /// Gets the plugin instance.
+ ///
+ public static Utility Instance { get; private set; }
+
+ ///
+ /// Gets the Harmony instance.
+ ///
+ public static Harmony Harmony { get; private set; }
+
+ ///
+ public override PluginPriority Priority { get; } = PluginPriority.Higher;
+
+ ///
+ public override void OnEnabled()
+ {
+ Instance = this;
+ base.OnEnabled();
+
+ Stopwatch watch = Stopwatch.StartNew();
+
+ Patch();
+
+ watch.Stop();
+
+ Log.Info($"{(Config.UseDynamicPatching ? "Non-event" : "All")} patches completed in {watch.Elapsed}");
+
+ ServerConsole.ReloadServerName();
+ }
+
+ ///
+ public override void OnDisabled()
+ {
+ base.OnDisabled();
+
+ Unpatch();
+ }
+
+ ///
+ /// Patches all events.
+ ///
+ public void Patch()
+ {
+ Harmony = new Harmony($"com.{nameof(Utility)}.ExiledTeam-{DateTime.Now.Ticks}");
+ GlobalPatchProcessor.PatchAll(Harmony, out int failedPatch);
+ if (failedPatch != 0)
+ Log.Error($"Patching failed! There are {failedPatch} broken patches.");
+ }
+
+ ///
+ /// Unpatches all events.
+ ///
+ public void Unpatch()
+ {
+ Log.Debug("Unpatching events...");
+ Harmony.UnpatchAll(Harmony.Id);
+ Harmony = null;
+ Log.Debug("All events have been unpatched complete. Goodbye!");
+ }
+ }
+}
diff --git a/EXILED/build.ps1 b/EXILED/build.ps1
index 2b4f5a54c8..07b30ee294 100644
--- a/EXILED/build.ps1
+++ b/EXILED/build.ps1
@@ -9,6 +9,7 @@ $Projects = @(
'Exiled.API',
'Exiled.Permissions',
'Exiled.Events',
+ 'Exiled.Utility',
'Exiled.CreditTags',
'Exiled.Example',
'Exiled.CustomItems',
From aefd9780b9b2b136f6060e281ac54bc91d31c852 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Mon, 23 Feb 2026 08:03:19 +0100
Subject: [PATCH 02/17] Move Scp079Recontain file into Utility
---
EXILED/Exiled.Utility/Exiled.Utility.csproj | 5 -----
.../Generic => Exiled.Utility/Patches}/Scp079Recontain.cs | 6 +++---
2 files changed, 3 insertions(+), 8 deletions(-)
rename EXILED/{Exiled.Events/Patches/Generic => Exiled.Utility/Patches}/Scp079Recontain.cs (91%)
diff --git a/EXILED/Exiled.Utility/Exiled.Utility.csproj b/EXILED/Exiled.Utility/Exiled.Utility.csproj
index cca7e1e48a..323fecd1f6 100644
--- a/EXILED/Exiled.Utility/Exiled.Utility.csproj
+++ b/EXILED/Exiled.Utility/Exiled.Utility.csproj
@@ -42,11 +42,6 @@
-
-
-
-
-
if not "$(EXILED_DEV_REFERENCES)"=="" copy /y "$(OutputPath)$(AssemblyName).dll" "$(EXILED_DEV_REFERENCES)\Plugins\"
diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp079Recontain.cs b/EXILED/Exiled.Utility/Patches/Scp079Recontain.cs
similarity index 91%
rename from EXILED/Exiled.Events/Patches/Generic/Scp079Recontain.cs
rename to EXILED/Exiled.Utility/Patches/Scp079Recontain.cs
index f92a59482f..3ce9e801dc 100644
--- a/EXILED/Exiled.Events/Patches/Generic/Scp079Recontain.cs
+++ b/EXILED/Exiled.Utility/Patches/Scp079Recontain.cs
@@ -5,7 +5,7 @@
//
// -----------------------------------------------------------------------
-namespace Exiled.Events.Patches.Generic
+namespace Exiled.Utility.Patches
{
using System.Collections.Generic;
using System.Reflection.Emit;
@@ -37,8 +37,8 @@ private static IEnumerable Transpiler(IEnumerable
Date: Mon, 23 Feb 2026 08:03:32 +0100
Subject: [PATCH 03/17] more config stuff
---
EXILED/Exiled.Events/Config.cs | 1 -
.../Patches/Generic/Scp173BeingLooked.cs | 2 +-
EXILED/Exiled.Utility/Config.cs | 68 +++++--------------
3 files changed, 19 insertions(+), 52 deletions(-)
diff --git a/EXILED/Exiled.Events/Config.cs b/EXILED/Exiled.Events/Config.cs
index fd244f699b..56a8206e74 100644
--- a/EXILED/Exiled.Events/Config.cs
+++ b/EXILED/Exiled.Events/Config.cs
@@ -77,7 +77,6 @@ public sealed class Config : IConfig
///
/// Gets or sets a value indicating whether keycard throw can affect basic doors.
///
- /// TODO: Make a poll about removing this config. (unimplemented since 9.6.0-beta7)
[Description("Indicates whether thrown keycards can affect doors that don't require any permissions")]
public bool CanKeycardThrowAffectDoors { get; set; } = false;
diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp173BeingLooked.cs b/EXILED/Exiled.Events/Patches/Generic/Scp173BeingLooked.cs
index aadad0c087..763b23f88c 100644
--- a/EXILED/Exiled.Events/Patches/Generic/Scp173BeingLooked.cs
+++ b/EXILED/Exiled.Events/Patches/Generic/Scp173BeingLooked.cs
@@ -69,7 +69,7 @@ private static IEnumerable Transpiler(IEnumerable
public sealed class Config : IConfig
@@ -20,18 +23,19 @@ public sealed class Config : IConfig
///
public bool Debug { get; set; }
- ///
- /// Gets or sets a value indicating whether events are only patched if they have delegates subscribed to them.
- ///
- [Description("Indicates whether events are patched only if they have delegates subscribed to them")]
- public bool UseDynamicPatching { get; set; } = true;
-
///
/// Gets or sets a value indicating whether SCP-173 can be blocked by the tutorial.
///
[Description("Indicates whether SCP-173 can be blocked by the tutorial")]
- public bool CanTutorialBlockScp173 { get; set; } = true;
-
+ public Dictionary CanTutorialBlockScp173 { get; set; } =
+ Events.Events.Instance.Config.CanTutorialBlockScp173 ?
+ new()
+ {
+ { RoleTypeId.Tutorial.ToString(), 0 },
+ }
+ : new() { };
+
+ /*
///
/// Gets or sets a value indicating whether SCP-096 can be triggered by the tutorial.
///
@@ -49,66 +53,30 @@ public sealed class Config : IConfig
///
[Description("Indicates whether tutorial is affected by SCP-079 scan.")]
public bool TutorialNotAffectedByScp079Scan { get; set; } = false;
+ */
///
/// Gets or sets a value indicating whether flashbangs flash original thrower.
///
[Description("Indicates whether flashbangs flash original thrower.")]
- public bool CanFlashbangsAffectThrower { get; set; } = false;
-
- ///
- /// Gets or sets a value indicating whether the name tracking (invisible EXILED version string added to the end of the server name) is enabled or not.
- ///
- [Description("Indicates whether the name tracking (invisible EXILED version string added to the end of the server name) is enabled or not")]
- public bool IsNameTrackingEnabled { get; set; } = true;
+ public bool CanFlashbangsAffectThrower { get; set; } = Events.Events.Instance.Config.CanFlashbangsAffectThrower;
///
/// Gets or sets a value indicating whether the inventory should be dropped before being set as spectator, through commands or plugins.
///
[Description("Indicates whether the inventory should be dropped before being set as spectator, through commands or plugins")]
- public bool ShouldDropInventory { get; set; } = true;
+ public bool ShouldDropInventory { get; set; } = Events.Events.Instance.Config.ShouldDropInventory;
///
/// Gets or sets a value indicating whether the blood can be spawned.
///
- [Description("Indicates whether the blood can be spawned")]
- public bool CanSpawnBlood { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether keycard throw can affect basic doors.
- ///
- /// TODO: Make a poll about removing this config. (unimplemented since 9.6.0-beta7)
- [Description("Indicates whether thrown keycards can affect doors that don't require any permissions")]
- public bool CanKeycardThrowAffectDoors { get; set; } = false;
+ [Description("Indicates whether the Decal (Blood, Bullet, Buckshot, GlassCrack) can be spawned")]
+ public List PreventDecalSpawn { get; set; } = Events.Events.Instance.Config.CanSpawnBlood ? new() { DecalPoolType.Blood } : new() { };
///
/// Gets or sets a value indicating whether the SCP079 will recontained if there are no SCPs left.
///
[Description("Indicates whether the SCP079 will recontained if there are no SCPs left.")]
- public bool RecontainScp079IfNoScpsLeft { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether configs has to be reloaded every time a round restarts.
- ///
- [Description("Indicates whether configs have to be reloaded every round restart")]
- public bool ShouldReloadConfigsAtRoundRestart { get; set; } = false;
-
- ///
- /// Gets or sets a value indicating whether translations has to be reloaded every time a round restarts.
- ///
- [Description("Indicates whether translations has to be reloaded every round restart")]
- public bool ShouldReloadTranslationsAtRoundRestart { get; set; } = false;
-
- ///
- /// Gets a value indicating whether bans should be logged.
- ///
- [Description("Indicates whether bans should be logged")]
- public bool ShouldLogBans { get; private set; } = true;
-
- ///
- /// Gets or sets a value indicating whether to log RA commands.
- ///
- [Description("Whether to log RA commands.")]
- public bool LogRaCommands { get; set; } = true;
+ public bool RecontainScp079IfNoScpsLeft { get; set; } = Events.Events.Instance.Config.RecontainScp079IfNoScpsLeft;
}
}
From 430566ad7fda5cdff8d0b2a07c8ce56eae7ce2eb Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Mon, 23 Feb 2026 08:12:17 +0100
Subject: [PATCH 04/17] remove Dynamic
---
EXILED/Exiled.Utility/Utility.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/EXILED/Exiled.Utility/Utility.cs b/EXILED/Exiled.Utility/Utility.cs
index c0a6a24d15..d99082c0e9 100644
--- a/EXILED/Exiled.Utility/Utility.cs
+++ b/EXILED/Exiled.Utility/Utility.cs
@@ -55,7 +55,7 @@ public override void OnEnabled()
watch.Stop();
- Log.Info($"{(Config.UseDynamicPatching ? "Non-event" : "All")} patches completed in {watch.Elapsed}");
+ Log.Info($"patches completed in {watch.Elapsed}");
ServerConsole.ReloadServerName();
}
From 07d0c076a28bfb0d390469198a385f682ccde85c Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Mon, 23 Feb 2026 08:45:03 +0100
Subject: [PATCH 05/17] NewEnumForAllStuffThatWasAboutTutorial
---
EXILED/Exiled.Utility/Config.cs | 5 ++-
.../NewEnumForAllStuffThatWasAboutTutorial.cs | 43 +++++++++++++++++++
2 files changed, 46 insertions(+), 2 deletions(-)
create mode 100644 EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
diff --git a/EXILED/Exiled.Utility/Config.cs b/EXILED/Exiled.Utility/Config.cs
index 8efb5c2b74..4298599806 100644
--- a/EXILED/Exiled.Utility/Config.cs
+++ b/EXILED/Exiled.Utility/Config.cs
@@ -12,6 +12,7 @@ namespace Exiled.Utility
using API.Interfaces;
using Decals;
+ using Exiled.Utility.Enums;
using PlayerRoles;
///
@@ -27,11 +28,11 @@ public sealed class Config : IConfig
/// Gets or sets a value indicating whether SCP-173 can be blocked by the tutorial.
///
[Description("Indicates whether SCP-173 can be blocked by the tutorial")]
- public Dictionary CanTutorialBlockScp173 { get; set; } =
+ public Dictionary CanTutorialBlockScp173 { get; set; } =
Events.Events.Instance.Config.CanTutorialBlockScp173 ?
new()
{
- { RoleTypeId.Tutorial.ToString(), 0 },
+ { RoleTypeId.Tutorial.ToString(), NewEnumForAllStuffThatWasAboutTutorial.CanTutorialBlockScp173 },
}
: new() { };
diff --git a/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs b/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
new file mode 100644
index 0000000000..f0b8d81324
--- /dev/null
+++ b/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
@@ -0,0 +1,43 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Utility.Enums
+{
+ using System;
+
+ ///
+ /// All available screen aspect ratio types.
+ ///
+ [Flags]
+ public enum NewEnumForAllStuffThatWasAboutTutorial
+ {
+ ///
+ /// Unknown aspect ratio.
+ ///
+ None = 0,
+
+ ///
+ /// Prevent from blocking Scp173.
+ ///
+ CanBlockScp173 = 1,
+
+ ///
+ /// Prevent from being target of Scp096.
+ ///
+ CanTriggerScp096 = 2,
+
+ ///
+ /// Prevent from being target of Scp049.
+ ///
+ CanScp049Sense = 4,
+
+ ///
+ /// Prevent Player to be Alarmed by Scp079.
+ ///
+ NotAffectedByScp079Scan = 8,
+ }
+}
From eb69e7b4491f20a145e152b8fe379c4def4b1080 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Mon, 23 Feb 2026 08:57:19 +0100
Subject: [PATCH 06/17] idk how to make it
---
EXILED/Exiled.Utility/Config.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/EXILED/Exiled.Utility/Config.cs b/EXILED/Exiled.Utility/Config.cs
index 4298599806..e6da1c5c5f 100644
--- a/EXILED/Exiled.Utility/Config.cs
+++ b/EXILED/Exiled.Utility/Config.cs
@@ -27,12 +27,12 @@ public sealed class Config : IConfig
///
/// Gets or sets a value indicating whether SCP-173 can be blocked by the tutorial.
///
- [Description("Indicates whether SCP-173 can be blocked by the tutorial")]
- public Dictionary CanTutorialBlockScp173 { get; set; } =
+ [Description("Indicates whether RoleTypeId or CustomRole(Name or Id) prevented behaviours")]
+ public Dictionary NewStuffThatWasAboutTutorial { get; set; } =
Events.Events.Instance.Config.CanTutorialBlockScp173 ?
new()
{
- { RoleTypeId.Tutorial.ToString(), NewEnumForAllStuffThatWasAboutTutorial.CanTutorialBlockScp173 },
+ { RoleTypeId.Tutorial.ToString(), NewEnumForAllStuffThatWasAboutTutorial.CanBlockScp173 },
}
: new() { };
From 3c3e3f663fa8b3d0432c7831021dbdb2373563c1 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Mon, 23 Feb 2026 10:24:21 +0100
Subject: [PATCH 07/17] removing all config stuff inside Exiled.Events that
arent related to event
---
EXILED/Exiled.Events/Handlers/Internal/Round.cs | 2 +-
.../Patches/Events/Map/ExplodingFlashGrenade.cs | 7 ++-----
.../Patches/Generic/CanScp049SenseTutorial.cs | 17 +----------------
EXILED/Exiled.Utility/Config.cs | 2 +-
4 files changed, 5 insertions(+), 23 deletions(-)
diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs
index cebcffa749..d6e7a9565b 100644
--- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs
+++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs
@@ -104,7 +104,7 @@ public static void OnActivatingSense(ActivatingSenseEventArgs ev)
{
if (ev.Target is null)
return;
- if ((Events.Instance.Config.CanScp049SenseTutorial || ev.Target.Role.Type is not RoleTypeId.Tutorial) && !Scp049Role.TurnedPlayers.Contains(ev.Target))
+ if (!Scp049Role.TurnedPlayers.Contains(ev.Target))
return;
ev.Target = ev.Scp049.SenseAbility.CanFindTarget(out ReferenceHub hub) ? Player.Get(hub) : null;
}
diff --git a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
index 88549bc13a..d78daefdff 100644
--- a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
@@ -26,7 +26,7 @@ namespace Exiled.Events.Patches.Events.Map
///
/// Patches .
- /// Adds the event and .
+ /// Adds the event"/>.
///
[HarmonyPatch(typeof(FlashbangGrenade), nameof(FlashbangGrenade.ServerFuseEnd))]
internal static class ExplodingFlashGrenade
@@ -69,10 +69,7 @@ private static void ProcessEvent(FlashbangGrenade instance, float distance)
if ((instance.transform.position - player.Position).sqrMagnitude > distance)
continue;
- if (!ExiledEvents.Instance.Config.CanFlashbangsAffectThrower && instance.PreviousOwner.CompareLife(player.ReferenceHub))
- continue;
-
- if (!IndividualFriendlyFire.CheckFriendlyFirePlayer(instance.PreviousOwner, player.ReferenceHub) && !instance.PreviousOwner.CompareLife(player.ReferenceHub))
+ if (!IndividualFriendlyFire.CheckFriendlyFirePlayer(instance.PreviousOwner, player.ReferenceHub))
continue;
if (Physics.Linecast(instance.transform.position, player.CameraTransform.position, instance.BlindingMask))
diff --git a/EXILED/Exiled.Events/Patches/Generic/CanScp049SenseTutorial.cs b/EXILED/Exiled.Events/Patches/Generic/CanScp049SenseTutorial.cs
index 01d7daaee5..d069e8d1c2 100644
--- a/EXILED/Exiled.Events/Patches/Generic/CanScp049SenseTutorial.cs
+++ b/EXILED/Exiled.Events/Patches/Generic/CanScp049SenseTutorial.cs
@@ -36,7 +36,6 @@ private static IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Brfalse);
Label continueLabel = (Label)newInstructions[index].operand;
- Label skip = generator.DefineLabel();
index += 1;
@@ -46,22 +45,8 @@ private static IEnumerable Transpiler(IEnumerable), nameof(Plugin.Config))),
- new(OpCodes.Callvirt, PropertyGetter(typeof(Config), nameof(Config.CanScp049SenseTutorial))),
- new(OpCodes.Brfalse_S, continueLabel),
-
// if (Scp049Role.TurnedPlayers.Contains(Player.Get(referenceHub)))
- new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(API.Features.Roles.Scp049Role), nameof(API.Features.Roles.Scp049Role.TurnedPlayers))).WithLabels(skip),
+ new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(API.Features.Roles.Scp049Role), nameof(API.Features.Roles.Scp049Role.TurnedPlayers))),
new(OpCodes.Ldloc_S, 6),
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
new(OpCodes.Callvirt, Method(typeof(HashSet), nameof(HashSet.Contains))),
diff --git a/EXILED/Exiled.Utility/Config.cs b/EXILED/Exiled.Utility/Config.cs
index e6da1c5c5f..fcdd93c522 100644
--- a/EXILED/Exiled.Utility/Config.cs
+++ b/EXILED/Exiled.Utility/Config.cs
@@ -69,7 +69,7 @@ public sealed class Config : IConfig
public bool ShouldDropInventory { get; set; } = Events.Events.Instance.Config.ShouldDropInventory;
///
- /// Gets or sets a value indicating whether the blood can be spawned.
+ /// Gets or sets a value indicating whether Decal spawned.
///
[Description("Indicates whether the Decal (Blood, Bullet, Buckshot, GlassCrack) can be spawned")]
public List PreventDecalSpawn { get; set; } = Events.Events.Instance.Config.CanSpawnBlood ? new() { DecalPoolType.Blood } : new() { };
From 8195400b6cac8eedf40ef3e9dbf058246d78af8f Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Mon, 23 Feb 2026 16:24:22 +0100
Subject: [PATCH 08/17] remove config check
---
.../Patches/Generic/ParseVisionInformation.cs | 27 +++----------------
1 file changed, 3 insertions(+), 24 deletions(-)
diff --git a/EXILED/Exiled.Events/Patches/Generic/ParseVisionInformation.cs b/EXILED/Exiled.Events/Patches/Generic/ParseVisionInformation.cs
index 42e6c1013d..86b2bd91de 100644
--- a/EXILED/Exiled.Events/Patches/Generic/ParseVisionInformation.cs
+++ b/EXILED/Exiled.Events/Patches/Generic/ParseVisionInformation.cs
@@ -38,37 +38,16 @@ private static IEnumerable Transpiler(IEnumerable), nameof(Plugin.Config))),
- new(OpCodes.Callvirt, PropertyGetter(typeof(Config), nameof(Config.CanTutorialTriggerScp096))),
- new(OpCodes.Brfalse_S, returnLabel),
-
- // || Scp096Role.TurnedPlayers.Contains(Player.Get(referenceHub))
- new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(Scp096Role), nameof(Scp096Role.TurnedPlayers))).WithLabels(secondCheckPointer),
+ // if (!Scp096Role.TurnedPlayers.Contains(Player.Get(referenceHub)))
+ new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(Scp096Role), nameof(Scp096Role.TurnedPlayers))),
new(OpCodes.Ldarg_1),
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
new(OpCodes.Callvirt, Method(typeof(HashSet), nameof(HashSet.Contains))),
From abc061c5c419a8ccd7249ae238814cfa685fb9aa Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 01:49:36 +0100
Subject: [PATCH 09/17] Adding: EventHandler to Utility
---
.../Commands/SpawnPrefabType.cs | 67 +++++++++++++++++++
EXILED/Exiled.Utility/Config.cs | 5 +-
.../NewEnumForAllStuffThatWasAboutTutorial.cs | 9 ++-
EXILED/Exiled.Utility/EventHandler.cs | 52 ++++++++++++++
EXILED/Exiled.Utility/Exiled.Utility.csproj | 4 ++
EXILED/Exiled.Utility/Utility.cs | 36 ++++------
6 files changed, 147 insertions(+), 26 deletions(-)
create mode 100644 EXILED/Exiled.Utility/Commands/SpawnPrefabType.cs
create mode 100644 EXILED/Exiled.Utility/EventHandler.cs
diff --git a/EXILED/Exiled.Utility/Commands/SpawnPrefabType.cs b/EXILED/Exiled.Utility/Commands/SpawnPrefabType.cs
new file mode 100644
index 0000000000..f56a7fe9ef
--- /dev/null
+++ b/EXILED/Exiled.Utility/Commands/SpawnPrefabType.cs
@@ -0,0 +1,67 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Utility.Commands
+{
+ using System;
+
+ using CommandSystem;
+ using Exiled.API.Enums;
+ using Exiled.API.Features;
+
+ ///
+ /// Command for spawning .
+ ///
+ [CommandHandler(typeof(RemoteAdminCommandHandler))]
+ public class SpawnPrefabType : ICommand, IUsageProvider
+ {
+ ///
+ public string Command { get; } = "PrefabType";
+
+ ///
+ public string[] Aliases { get; } = Array.Empty();
+
+ ///
+ public string Description { get; } = "Spawning PrefabType";
+
+ ///
+ public string[] Usage { get; } = new string[] { $"{string.Join(", ", EnumUtils.Names)}", };
+
+ ///
+ public bool Execute(ArraySegment arguments, ICommandSender sender, out string response)
+ {
+ if (!sender.CheckPermission(PlayerPermissions.FacilityManagement, out response))
+ {
+ return false;
+ }
+
+ Player.TryGet(sender, out Player player);
+ if (player is null)
+ {
+ response = "You must be a player to use this command.";
+ return false;
+ }
+
+ if (arguments.Count < 1)
+ {
+ response = $"Please, use: {Command} {Usage}";
+ return false;
+ }
+
+ if (Enum.TryParse(arguments.At(0), out PrefabType prefabType))
+ {
+ response = $"\"{arguments.At(0)}\" is not a valid prefab type.";
+ return false;
+ }
+
+ PrefabHelper.Spawn(prefabType, player.Position, player.Rotation);
+
+ response = "Spawning prefab type...";
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.Utility/Config.cs b/EXILED/Exiled.Utility/Config.cs
index fcdd93c522..901a6227fd 100644
--- a/EXILED/Exiled.Utility/Config.cs
+++ b/EXILED/Exiled.Utility/Config.cs
@@ -34,7 +34,10 @@ public sealed class Config : IConfig
{
{ RoleTypeId.Tutorial.ToString(), NewEnumForAllStuffThatWasAboutTutorial.CanBlockScp173 },
}
- : new() { };
+ : new()
+ {
+ { RoleTypeId.Tutorial.ToString(), NewEnumForAllStuffThatWasAboutTutorial.None },
+ };
/*
///
diff --git a/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs b/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
index f0b8d81324..d59ced9d22 100644
--- a/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
+++ b/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
@@ -16,7 +16,12 @@ namespace Exiled.Utility.Enums
public enum NewEnumForAllStuffThatWasAboutTutorial
{
///
- /// Unknown aspect ratio.
+ /// All.
+ ///
+ All = -1,
+
+ ///
+ /// None.
///
None = 0,
@@ -31,7 +36,7 @@ public enum NewEnumForAllStuffThatWasAboutTutorial
CanTriggerScp096 = 2,
///
- /// Prevent from being target of Scp049.
+ /// Prevent from being target of Scp049 and stagger Scp0492.
///
CanScp049Sense = 4,
diff --git a/EXILED/Exiled.Utility/EventHandler.cs b/EXILED/Exiled.Utility/EventHandler.cs
new file mode 100644
index 0000000000..b031cd390e
--- /dev/null
+++ b/EXILED/Exiled.Utility/EventHandler.cs
@@ -0,0 +1,52 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Utility
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Threading.Tasks;
+ using Decals;
+ using Exiled.API.Features;
+ using Exiled.Events.EventArgs.Map;
+ using InventorySystem.Items.Firearms.Modules;
+ using PlayerRoles;
+
+#pragma warning disable CS1591 // Commentaire XML manquant pour le type ou le membre visible publiquement
+#pragma warning disable SA1600 // Elements should be documented
+ public class EventHandler
+ {
+ public Config Config { get; internal set; }
+
+ public void OnWaitingForPlayers()
+ {
+ if (!Config.RecontainScp079IfNoScpsLeft)
+ PlayerRoleManager.OnServerRoleSet -= Recontainer.Base.OnServerRoleChanged;
+ }
+
+ public void OnPlacingBulletHole(PlacingBulletHoleEventArgs ev)
+ {
+ ImpactEffectsModule impactEffectsModule = ev.Firearm.HitscanHitregModule._impactEffectsModule;
+ int? num = null;
+ for (int i = 0; i < impactEffectsModule.AttachmentOverrides.Length; i++)
+ {
+ if (impactEffectsModule.AttachmentOverrides[i].GetEnabled(ev.Firearm.Base))
+ {
+ num = new int?(i);
+ break;
+ }
+ }
+
+ DecalPoolType decalPoolType = ev.Firearm.HitscanHitregModule._impactEffectsModule.GetSettings(num).BulletholeDecal;
+
+ if (Config.PreventDecalSpawn.Contains(decalPoolType))
+ ev.IsAllowed = false;
+ }
+ }
+}
diff --git a/EXILED/Exiled.Utility/Exiled.Utility.csproj b/EXILED/Exiled.Utility/Exiled.Utility.csproj
index 323fecd1f6..be661cdea8 100644
--- a/EXILED/Exiled.Utility/Exiled.Utility.csproj
+++ b/EXILED/Exiled.Utility/Exiled.Utility.csproj
@@ -11,6 +11,10 @@
+
+
+
+
diff --git a/EXILED/Exiled.Utility/Utility.cs b/EXILED/Exiled.Utility/Utility.cs
index d99082c0e9..4b3ad3769c 100644
--- a/EXILED/Exiled.Utility/Utility.cs
+++ b/EXILED/Exiled.Utility/Utility.cs
@@ -11,19 +11,8 @@ namespace Exiled.Utility
using System.Diagnostics;
using API.Enums;
- using API.Features;
- using CentralAuth;
- using Exiled.API.Features.Core.UserSettings;
- using Exiled.Events.Features;
+ using Exiled.API.Features;
using HarmonyLib;
- using InventorySystem.Items.Pickups;
- using InventorySystem.Items.Usables;
- using PlayerRoles.Ragdolls;
- using PlayerRoles.RoleAssign;
-
- using Respawning;
- using UnityEngine.SceneManagement;
- using UserSettings.ServerSpecific;
///
/// Patch and unpatch events into the game.
@@ -35,6 +24,11 @@ public sealed class Utility : Plugin
///
public static Utility Instance { get; private set; }
+ ///
+ /// Gets the eventHandler.
+ ///
+ public static EventHandler EventHandler { get; private set; }
+
///
/// Gets the Harmony instance.
///
@@ -47,17 +41,15 @@ public sealed class Utility : Plugin
public override void OnEnabled()
{
Instance = this;
- base.OnEnabled();
-
- Stopwatch watch = Stopwatch.StartNew();
+ EventHandler = new EventHandler
+ {
+ Config = Config,
+ };
+ Events.Handlers.Server.WaitingForPlayers += EventHandler.OnWaitingForPlayers;
+ Events.Handlers.Map.PlacingBulletHole += EventHandler.OnPlacingBulletHole;
Patch();
-
- watch.Stop();
-
- Log.Info($"patches completed in {watch.Elapsed}");
-
- ServerConsole.ReloadServerName();
+ base.OnEnabled();
}
///
@@ -84,10 +76,8 @@ public void Patch()
///
public void Unpatch()
{
- Log.Debug("Unpatching events...");
Harmony.UnpatchAll(Harmony.Id);
Harmony = null;
- Log.Debug("All events have been unpatched complete. Goodbye!");
}
}
}
From 3527880c1ef6760ead7829fd089ba04d8ea7f9d7 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 02:12:58 +0100
Subject: [PATCH 10/17] This is ASS code to show what should be improve in
Exiled
---
.../Exiled.API/Features/Roles/Scp0492Role.cs | 7 +++
.../Scp0492/TriggeringBloodlustEvent.cs | 15 +++++++
.../NewEnumForAllStuffThatWasAboutTutorial.cs | 7 ++-
EXILED/Exiled.Utility/EventHandler.cs | 45 +++++++++++++++++++
EXILED/Exiled.Utility/Exiled.Utility.csproj | 1 +
5 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/EXILED/Exiled.API/Features/Roles/Scp0492Role.cs b/EXILED/Exiled.API/Features/Roles/Scp0492Role.cs
index 7250aa4662..59aacd81ca 100644
--- a/EXILED/Exiled.API/Features/Roles/Scp0492Role.cs
+++ b/EXILED/Exiled.API/Features/Roles/Scp0492Role.cs
@@ -7,6 +7,8 @@
namespace Exiled.API.Features.Roles
{
+ using System.Collections.Generic;
+
using PlayerRoles;
using PlayerRoles.PlayableScps.HumeShield;
using PlayerRoles.PlayableScps.Scp049;
@@ -45,6 +47,11 @@ internal Scp0492Role(ZombieRole baseRole)
ConsumeAbility = zombieConsumeAbility492;
}
+ ///
+ /// Gets a list of players who are turned away from SCP-049 Sense Ability.
+ ///
+ public static HashSet TurnedPlayers { get; } = new(20);
+
///
public override RoleTypeId Type { get; } = RoleTypeId.Scp0492;
diff --git a/EXILED/Exiled.Events/Patches/Events/Scp0492/TriggeringBloodlustEvent.cs b/EXILED/Exiled.Events/Patches/Events/Scp0492/TriggeringBloodlustEvent.cs
index 32cd7264d0..722e94f1e6 100644
--- a/EXILED/Exiled.Events/Patches/Events/Scp0492/TriggeringBloodlustEvent.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Scp0492/TriggeringBloodlustEvent.cs
@@ -12,6 +12,7 @@ namespace Exiled.Events.Patches.Events.Scp0492
using Exiled.API.Features;
using Exiled.API.Features.Pools;
+ using Exiled.API.Features.Roles;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Scp0492;
@@ -38,17 +39,31 @@ private static IEnumerable Transpiler(IEnumerable), nameof(HashSet.Contains))),
+ new(OpCodes.Brfalse_S, continueLabel),
});
for (int z = 0; z < newInstructions.Count; z++)
diff --git a/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs b/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
index d59ced9d22..d16b35ac30 100644
--- a/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
+++ b/EXILED/Exiled.Utility/Enums/NewEnumForAllStuffThatWasAboutTutorial.cs
@@ -40,9 +40,14 @@ public enum NewEnumForAllStuffThatWasAboutTutorial
///
CanScp049Sense = 4,
+ ///
+ /// Prevent from being target of Scp049 and stagger Scp0492.
+ ///
+ CanScp0492Sense = 4,
+
///
/// Prevent Player to be Alarmed by Scp079.
///
- NotAffectedByScp079Scan = 8,
+ NotAffectedByScp079Scan = 16,
}
}
diff --git a/EXILED/Exiled.Utility/EventHandler.cs b/EXILED/Exiled.Utility/EventHandler.cs
index b031cd390e..29681870fc 100644
--- a/EXILED/Exiled.Utility/EventHandler.cs
+++ b/EXILED/Exiled.Utility/EventHandler.cs
@@ -12,9 +12,14 @@ namespace Exiled.Utility
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+
using Decals;
using Exiled.API.Features;
+ using Exiled.API.Features.Roles;
+ using Exiled.CustomRoles.API.Features;
using Exiled.Events.EventArgs.Map;
+ using Exiled.Events.EventArgs.Player;
+ using Exiled.Utility.Enums;
using InventorySystem.Items.Firearms.Modules;
using PlayerRoles;
@@ -30,6 +35,46 @@ public void OnWaitingForPlayers()
PlayerRoleManager.OnServerRoleSet -= Recontainer.Base.OnServerRoleChanged;
}
+ public void OnSpawned(SpawnedEventArgs ev)
+ {
+ Scp173Role.TurnedPlayers.Remove(ev.Player);
+ Scp096Role.TurnedPlayers.Remove(ev.Player);
+ Scp049Role.TurnedPlayers.Remove(ev.Player);
+ Scp0492Role.TurnedPlayers.Remove(ev.Player);
+ string role = ev.Player.Role.Type.ToString();
+ foreach (CustomRole customRole in CustomRole.Registered)
+ {
+ if (customRole.Check(ev.Player))
+ {
+ role = customRole.Name;
+ break;
+ }
+ }
+
+ if (Config.NewStuffThatWasAboutTutorial.TryGetValue(role, out NewEnumForAllStuffThatWasAboutTutorial bruh))
+ {
+ if (bruh.HasFlag(NewEnumForAllStuffThatWasAboutTutorial.CanBlockScp173))
+ {
+ Scp173Role.TurnedPlayers.Add(ev.Player);
+ }
+
+ if (bruh.HasFlag(NewEnumForAllStuffThatWasAboutTutorial.CanTriggerScp096))
+ {
+ Scp096Role.TurnedPlayers.Add(ev.Player);
+ }
+
+ if (bruh.HasFlag(NewEnumForAllStuffThatWasAboutTutorial.CanScp049Sense))
+ {
+ Scp049Role.TurnedPlayers.Add(ev.Player);
+ }
+
+ if (bruh.HasFlag(NewEnumForAllStuffThatWasAboutTutorial.CanScp0492Sense))
+ {
+ Scp0492Role.TurnedPlayers.Add(ev.Player);
+ }
+ }
+ }
+
public void OnPlacingBulletHole(PlacingBulletHoleEventArgs ev)
{
ImpactEffectsModule impactEffectsModule = ev.Firearm.HitscanHitregModule._impactEffectsModule;
diff --git a/EXILED/Exiled.Utility/Exiled.Utility.csproj b/EXILED/Exiled.Utility/Exiled.Utility.csproj
index be661cdea8..fb8692eb27 100644
--- a/EXILED/Exiled.Utility/Exiled.Utility.csproj
+++ b/EXILED/Exiled.Utility/Exiled.Utility.csproj
@@ -17,6 +17,7 @@
+
From c2e4560d91d82486dafe831b40f47561768859b5 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 02:15:43 +0100
Subject: [PATCH 11/17] we don't have BloodDecalEvent
---
EXILED/Exiled.Utility/Utility.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/EXILED/Exiled.Utility/Utility.cs b/EXILED/Exiled.Utility/Utility.cs
index 4b3ad3769c..b042843f27 100644
--- a/EXILED/Exiled.Utility/Utility.cs
+++ b/EXILED/Exiled.Utility/Utility.cs
@@ -48,6 +48,8 @@ public override void OnEnabled()
Events.Handlers.Server.WaitingForPlayers += EventHandler.OnWaitingForPlayers;
Events.Handlers.Map.PlacingBulletHole += EventHandler.OnPlacingBulletHole;
+
+ // BloodDecal is Missing
Patch();
base.OnEnabled();
}
From 2c87b972716ca060a3233c0ea6a7a980f1ad72d7 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 02:16:44 +0100
Subject: [PATCH 12/17] remove commented code
---
EXILED/Exiled.Utility/Config.cs | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/EXILED/Exiled.Utility/Config.cs b/EXILED/Exiled.Utility/Config.cs
index 901a6227fd..bfabdddd59 100644
--- a/EXILED/Exiled.Utility/Config.cs
+++ b/EXILED/Exiled.Utility/Config.cs
@@ -39,26 +39,6 @@ public sealed class Config : IConfig
{ RoleTypeId.Tutorial.ToString(), NewEnumForAllStuffThatWasAboutTutorial.None },
};
- /*
- ///
- /// Gets or sets a value indicating whether SCP-096 can be triggered by the tutorial.
- ///
- [Description("Indicates whether SCP-096 can be triggered by the tutorial")]
- public bool CanTutorialTriggerScp096 { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether SCP-049 can activate the sense ability on tutorials.
- ///
- [Description("Indicates whether SCP-049 can sense tutorial players")]
- public bool CanScp049SenseTutorial { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether tutorial is affected by SCP-079 scan.
- ///
- [Description("Indicates whether tutorial is affected by SCP-079 scan.")]
- public bool TutorialNotAffectedByScp079Scan { get; set; } = false;
- */
-
///
/// Gets or sets a value indicating whether flashbangs flash original thrower.
///
From 5f271e186a74d763f2c59721c9cf3e652461d353 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 02:23:03 +0100
Subject: [PATCH 13/17] feat: `Player.LifeIdentifier`
---
EXILED/Exiled.API/Features/Player.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs
index 522a0a2113..9d500ca681 100644
--- a/EXILED/Exiled.API/Features/Player.cs
+++ b/EXILED/Exiled.API/Features/Player.cs
@@ -1199,6 +1199,11 @@ public bool IsSpectatable
///
public Footprint Footprint => new(ReferenceHub);
+ ///
+ /// Gets the player's UniqueLifeIdentifier.
+ ///
+ public int LifeIdentifier => ReferenceHub.roleManager.CurrentRole.UniqueLifeIdentifier;
+
///
/// Gets or sets a value indicating whether the player is spawn protected.
///
From 6b0b3a3ae935c0e3db53bd7980df40a264df5235 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 02:23:14 +0100
Subject: [PATCH 14/17] this is required
---
.../Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
index d78daefdff..8ed622394d 100644
--- a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
@@ -69,7 +69,7 @@ private static void ProcessEvent(FlashbangGrenade instance, float distance)
if ((instance.transform.position - player.Position).sqrMagnitude > distance)
continue;
- if (!IndividualFriendlyFire.CheckFriendlyFirePlayer(instance.PreviousOwner, player.ReferenceHub))
+ if (!IndividualFriendlyFire.CheckFriendlyFirePlayer(instance.PreviousOwner, player.ReferenceHub) && instance.PreviousOwner.LifeIdentifier == player.Footprint.LifeIdentifier)
continue;
if (Physics.Linecast(instance.transform.position, player.CameraTransform.position, instance.BlindingMask))
From f6786420c493378d35cbea3a63dc2c5e6a7282cf Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 02:27:16 +0100
Subject: [PATCH 15/17] comment
---
EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
index 8ed622394d..f376123a9e 100644
--- a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
@@ -69,6 +69,7 @@ private static void ProcessEvent(FlashbangGrenade instance, float distance)
if ((instance.transform.position - player.Position).sqrMagnitude > distance)
continue;
+ // LifeIdentifier check is needed to fix NW Bug https://git.scpslgame.com/northwood-qa/scpsl-bug-reporting/-/issues/2811
if (!IndividualFriendlyFire.CheckFriendlyFirePlayer(instance.PreviousOwner, player.ReferenceHub) && instance.PreviousOwner.LifeIdentifier == player.Footprint.LifeIdentifier)
continue;
From ccdeac7c2e4fb371f3818a12d0a517fb208469e8 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 02:53:25 +0100
Subject: [PATCH 16/17] =?UTF-8?q?doing=20stuff=20it's=203am=20i=20am=20laz?=
=?UTF-8?q?y=20to=20write=20correct=20commit=20=F0=9F=AA=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
EXILED/Exiled.Events/Config.cs | 48 -------------------
EXILED/Exiled.Events/Events.cs | 2 -
.../Exiled.Events/Handlers/Internal/Round.cs | 7 ---
.../Patches/Generic/CanScp049SenseTutorial.cs | 4 +-
.../Patches/Generic/Scp079Scan.cs | 14 ------
EXILED/Exiled.Utility/Config.cs | 16 ++-----
EXILED/Exiled.Utility/EventHandler.cs | 15 ++++++
EXILED/Exiled.Utility/Utility.cs | 7 ++-
8 files changed, 26 insertions(+), 87 deletions(-)
diff --git a/EXILED/Exiled.Events/Config.cs b/EXILED/Exiled.Events/Config.cs
index 56a8206e74..4fea2e64ab 100644
--- a/EXILED/Exiled.Events/Config.cs
+++ b/EXILED/Exiled.Events/Config.cs
@@ -26,66 +26,18 @@ public sealed class Config : IConfig
[Description("Indicates whether events are patched only if they have delegates subscribed to them")]
public bool UseDynamicPatching { get; set; } = true;
- ///
- /// Gets or sets a value indicating whether SCP-173 can be blocked by the tutorial.
- ///
- [Description("Indicates whether SCP-173 can be blocked by the tutorial")]
- public bool CanTutorialBlockScp173 { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether SCP-096 can be triggered by the tutorial.
- ///
- [Description("Indicates whether SCP-096 can be triggered by the tutorial")]
- public bool CanTutorialTriggerScp096 { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether SCP-049 can activate the sense ability on tutorials.
- ///
- [Description("Indicates whether SCP-049 can sense tutorial players")]
- public bool CanScp049SenseTutorial { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether tutorial is affected by SCP-079 scan.
- ///
- [Description("Indicates whether tutorial is affected by SCP-079 scan.")]
- public bool TutorialNotAffectedByScp079Scan { get; set; } = false;
-
- ///
- /// Gets or sets a value indicating whether flashbangs flash original thrower.
- ///
- [Description("Indicates whether flashbangs flash original thrower.")]
- public bool CanFlashbangsAffectThrower { get; set; } = false;
-
///
/// Gets or sets a value indicating whether the name tracking (invisible EXILED version string added to the end of the server name) is enabled or not.
///
[Description("Indicates whether the name tracking (invisible EXILED version string added to the end of the server name) is enabled or not")]
public bool IsNameTrackingEnabled { get; set; } = true;
- ///
- /// Gets or sets a value indicating whether the inventory should be dropped before being set as spectator, through commands or plugins.
- ///
- [Description("Indicates whether the inventory should be dropped before being set as spectator, through commands or plugins")]
- public bool ShouldDropInventory { get; set; } = true;
-
- ///
- /// Gets or sets a value indicating whether the blood can be spawned.
- ///
- [Description("Indicates whether the blood can be spawned")]
- public bool CanSpawnBlood { get; set; } = true;
-
///
/// Gets or sets a value indicating whether keycard throw can affect basic doors.
///
[Description("Indicates whether thrown keycards can affect doors that don't require any permissions")]
public bool CanKeycardThrowAffectDoors { get; set; } = false;
- ///
- /// Gets or sets a value indicating whether the SCP079 will recontained if there are no SCPs left.
- ///
- [Description("Indicates whether the SCP079 will recontained if there are no SCPs left.")]
- public bool RecontainScp079IfNoScpsLeft { get; set; } = true;
-
///
/// Gets or sets a value indicating whether configs has to be reloaded every time a round restarts.
///
diff --git a/EXILED/Exiled.Events/Events.cs b/EXILED/Exiled.Events/Events.cs
index f01919aff5..fb3cbdaa20 100644
--- a/EXILED/Exiled.Events/Events.cs
+++ b/EXILED/Exiled.Events/Events.cs
@@ -65,7 +65,6 @@ public override void OnEnabled()
Handlers.Server.WaitingForPlayers += Handlers.Internal.Round.OnWaitingForPlayers;
Handlers.Server.RestartingRound += Handlers.Internal.Round.OnRestartingRound;
Handlers.Server.RoundStarted += Handlers.Internal.Round.OnRoundStarted;
- Handlers.Player.ChangingRole += Handlers.Internal.Round.OnChangingRole;
Handlers.Player.SpawningRagdoll += Handlers.Internal.Round.OnSpawningRagdoll;
Handlers.Scp049.ActivatingSense += Handlers.Internal.Round.OnActivatingSense;
Handlers.Player.Verified += Handlers.Internal.Round.OnVerified;
@@ -113,7 +112,6 @@ public override void OnDisabled()
Handlers.Server.WaitingForPlayers -= Handlers.Internal.Round.OnWaitingForPlayers;
Handlers.Server.RestartingRound -= Handlers.Internal.Round.OnRestartingRound;
Handlers.Server.RoundStarted -= Handlers.Internal.Round.OnRoundStarted;
- Handlers.Player.ChangingRole -= Handlers.Internal.Round.OnChangingRole;
Handlers.Player.SpawningRagdoll -= Handlers.Internal.Round.OnSpawningRagdoll;
Handlers.Scp049.ActivatingSense -= Handlers.Internal.Round.OnActivatingSense;
Handlers.Player.Verified -= Handlers.Internal.Round.OnVerified;
diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs
index d6e7a9565b..015a9fe7d8 100644
--- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs
+++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs
@@ -82,13 +82,6 @@ public static void OnRestartingRound()
///
public static void OnRoundStarted() => MultiAdminFeatures.CallEvent(MultiAdminFeatures.EventType.ROUND_START);
- ///
- public static void OnChangingRole(ChangingRoleEventArgs ev)
- {
- if (!ev.Player.IsHost && ev.NewRole == RoleTypeId.Spectator && ev.Reason is not SpawnReason.Destroyed && Events.Instance.Config.ShouldDropInventory)
- ev.Player.Inventory.ServerDropEverything();
- }
-
///
public static void OnSpawningRagdoll(SpawningRagdollEventArgs ev)
{
diff --git a/EXILED/Exiled.Events/Patches/Generic/CanScp049SenseTutorial.cs b/EXILED/Exiled.Events/Patches/Generic/CanScp049SenseTutorial.cs
index d069e8d1c2..222d4ecd73 100644
--- a/EXILED/Exiled.Events/Patches/Generic/CanScp049SenseTutorial.cs
+++ b/EXILED/Exiled.Events/Patches/Generic/CanScp049SenseTutorial.cs
@@ -20,11 +20,9 @@ namespace Exiled.Events.Patches.Generic
using static HarmonyLib.AccessTools;
- using ExiledEvents = Exiled.Events.Events;
-
///
/// Patches .
- /// .
+ /// .
///
[HarmonyPatch(typeof(Scp049SenseAbility), nameof(Scp049SenseAbility.CanFindTarget))]
internal static class CanScp049SenseTutorial
diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp079Scan.cs b/EXILED/Exiled.Events/Patches/Generic/Scp079Scan.cs
index 6b4b93e406..b3bd692607 100644
--- a/EXILED/Exiled.Events/Patches/Generic/Scp079Scan.cs
+++ b/EXILED/Exiled.Events/Patches/Generic/Scp079Scan.cs
@@ -41,20 +41,6 @@ private static IEnumerable Transpiler(IEnumerable), nameof(Plugin.Config))),
- new(OpCodes.Callvirt, PropertyGetter(typeof(Config), nameof(Config.TutorialNotAffectedByScp079Scan))),
- new(OpCodes.Brfalse_S, returnLabel),
-
// if (Scp079Role.TurnedPlayers.Contains(Player.Get(referenceHub)))
new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(API.Features.Roles.Scp079Role), nameof(API.Features.Roles.Scp079Role.TurnedPlayers))).WithLabels(skip),
new(OpCodes.Ldarg_1),
diff --git a/EXILED/Exiled.Utility/Config.cs b/EXILED/Exiled.Utility/Config.cs
index bfabdddd59..2d3bccebab 100644
--- a/EXILED/Exiled.Utility/Config.cs
+++ b/EXILED/Exiled.Utility/Config.cs
@@ -28,13 +28,7 @@ public sealed class Config : IConfig
/// Gets or sets a value indicating whether SCP-173 can be blocked by the tutorial.
///
[Description("Indicates whether RoleTypeId or CustomRole(Name or Id) prevented behaviours")]
- public Dictionary NewStuffThatWasAboutTutorial { get; set; } =
- Events.Events.Instance.Config.CanTutorialBlockScp173 ?
- new()
- {
- { RoleTypeId.Tutorial.ToString(), NewEnumForAllStuffThatWasAboutTutorial.CanBlockScp173 },
- }
- : new()
+ public Dictionary NewStuffThatWasAboutTutorial { get; set; } = new()
{
{ RoleTypeId.Tutorial.ToString(), NewEnumForAllStuffThatWasAboutTutorial.None },
};
@@ -43,24 +37,24 @@ public sealed class Config : IConfig
/// Gets or sets a value indicating whether flashbangs flash original thrower.
///
[Description("Indicates whether flashbangs flash original thrower.")]
- public bool CanFlashbangsAffectThrower { get; set; } = Events.Events.Instance.Config.CanFlashbangsAffectThrower;
+ public bool CanFlashbangsAffectThrower { get; set; } = false;
///
/// Gets or sets a value indicating whether the inventory should be dropped before being set as spectator, through commands or plugins.
///
[Description("Indicates whether the inventory should be dropped before being set as spectator, through commands or plugins")]
- public bool ShouldDropInventory { get; set; } = Events.Events.Instance.Config.ShouldDropInventory;
+ public bool ShouldDropInventory { get; set; } = false;
///
/// Gets or sets a value indicating whether Decal spawned.
///
[Description("Indicates whether the Decal (Blood, Bullet, Buckshot, GlassCrack) can be spawned")]
- public List PreventDecalSpawn { get; set; } = Events.Events.Instance.Config.CanSpawnBlood ? new() { DecalPoolType.Blood } : new() { };
+ public List PreventDecalSpawn { get; set; } = new() { };
///
/// Gets or sets a value indicating whether the SCP079 will recontained if there are no SCPs left.
///
[Description("Indicates whether the SCP079 will recontained if there are no SCPs left.")]
- public bool RecontainScp079IfNoScpsLeft { get; set; } = Events.Events.Instance.Config.RecontainScp079IfNoScpsLeft;
+ public bool RecontainScp079IfNoScpsLeft { get; set; } = true;
}
}
diff --git a/EXILED/Exiled.Utility/EventHandler.cs b/EXILED/Exiled.Utility/EventHandler.cs
index 29681870fc..7f1e958720 100644
--- a/EXILED/Exiled.Utility/EventHandler.cs
+++ b/EXILED/Exiled.Utility/EventHandler.cs
@@ -14,12 +14,14 @@ namespace Exiled.Utility
using System.Threading.Tasks;
using Decals;
+ using Exiled.API.Enums;
using Exiled.API.Features;
using Exiled.API.Features.Roles;
using Exiled.CustomRoles.API.Features;
using Exiled.Events.EventArgs.Map;
using Exiled.Events.EventArgs.Player;
using Exiled.Utility.Enums;
+ using InventorySystem;
using InventorySystem.Items.Firearms.Modules;
using PlayerRoles;
@@ -35,12 +37,20 @@ public void OnWaitingForPlayers()
PlayerRoleManager.OnServerRoleSet -= Recontainer.Base.OnServerRoleChanged;
}
+ ///
+ public void OnChangingRole(ChangingRoleEventArgs ev)
+ {
+ if (!ev.Player.IsHost && ev.NewRole == RoleTypeId.Spectator && ev.Reason is not SpawnReason.Destroyed && Config.ShouldDropInventory)
+ ev.Player.Inventory.ServerDropEverything();
+ }
+
public void OnSpawned(SpawnedEventArgs ev)
{
Scp173Role.TurnedPlayers.Remove(ev.Player);
Scp096Role.TurnedPlayers.Remove(ev.Player);
Scp049Role.TurnedPlayers.Remove(ev.Player);
Scp0492Role.TurnedPlayers.Remove(ev.Player);
+ Scp079Role.TurnedPlayers.Remove(ev.Player);
string role = ev.Player.Role.Type.ToString();
foreach (CustomRole customRole in CustomRole.Registered)
{
@@ -72,6 +82,11 @@ public void OnSpawned(SpawnedEventArgs ev)
{
Scp0492Role.TurnedPlayers.Add(ev.Player);
}
+
+ if (bruh.HasFlag(NewEnumForAllStuffThatWasAboutTutorial.NotAffectedByScp079Scan))
+ {
+ Scp079Role.TurnedPlayers.Add(ev.Player);
+ }
}
}
diff --git a/EXILED/Exiled.Utility/Utility.cs b/EXILED/Exiled.Utility/Utility.cs
index b042843f27..42bdcbcd60 100644
--- a/EXILED/Exiled.Utility/Utility.cs
+++ b/EXILED/Exiled.Utility/Utility.cs
@@ -9,6 +9,7 @@ namespace Exiled.Utility
{
using System;
using System.Diagnostics;
+ using System.Runtime.InteropServices;
using API.Enums;
using Exiled.API.Features;
@@ -45,7 +46,7 @@ public override void OnEnabled()
{
Config = Config,
};
-
+ Events.Handlers.Player.ChangingRole += EventHandler.OnChangingRole;
Events.Handlers.Server.WaitingForPlayers += EventHandler.OnWaitingForPlayers;
Events.Handlers.Map.PlacingBulletHole += EventHandler.OnPlacingBulletHole;
@@ -58,7 +59,9 @@ public override void OnEnabled()
public override void OnDisabled()
{
base.OnDisabled();
-
+ Events.Handlers.Player.ChangingRole += EventHandler.OnChangingRole;
+ Events.Handlers.Server.WaitingForPlayers += EventHandler.OnWaitingForPlayers;
+ Events.Handlers.Map.PlacingBulletHole += EventHandler.OnPlacingBulletHole;
Unpatch();
}
From 59147ff36a6be2fc52047a806a65d2dee3150916 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 7 Mar 2026 03:24:15 +0100
Subject: [PATCH 17/17] SpawnPrefabType
---
EXILED/Exiled.API/Enums/PrefabType.cs | 1 +
EXILED/Exiled.API/Features/PrefabHelper.cs | 18 +++++++++++++++++-
.../Exiled.Utility/Commands/SpawnPrefabType.cs | 5 +++--
EXILED/Exiled.Utility/Utility.cs | 2 --
4 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/EXILED/Exiled.API/Enums/PrefabType.cs b/EXILED/Exiled.API/Enums/PrefabType.cs
index 43936f1d80..c3ce00898d 100644
--- a/EXILED/Exiled.API/Enums/PrefabType.cs
+++ b/EXILED/Exiled.API/Enums/PrefabType.cs
@@ -12,6 +12,7 @@ namespace Exiled.API.Enums
///
/// Type of prefab.
///
+ ///
public enum PrefabType
{
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
diff --git a/EXILED/Exiled.API/Features/PrefabHelper.cs b/EXILED/Exiled.API/Features/PrefabHelper.cs
index 179991e635..22579651ac 100644
--- a/EXILED/Exiled.API/Features/PrefabHelper.cs
+++ b/EXILED/Exiled.API/Features/PrefabHelper.cs
@@ -14,8 +14,8 @@ namespace Exiled.API.Features
using Exiled.API.Enums;
using Exiled.API.Features.Attributes;
-
using MapGeneration.Distributors;
+ using MapGeneration.RoomConnectors;
using Mirror;
using UnityEngine;
@@ -57,6 +57,11 @@ public static PrefabAttribute GetPrefabAttribute(this PrefabType prefabType)
/// Returns the .
public static GameObject GetPrefab(PrefabType prefabType)
{
+ if (prefabType is PrefabType.HCZOneSided or PrefabType.HCZTwoSided)
+ {
+ prefabType = PrefabType.HCZBreakableDoor;
+ }
+
if (Prefabs.TryGetValue(prefabType, out (GameObject, Component) prefab))
return prefab.Item1;
@@ -112,6 +117,17 @@ public static GameObject Spawn(PrefabType prefabType, Vector3 position = default
positionSync.Network_rotationY = (sbyte)Mathf.RoundToInt(rotation.Value.eulerAngles.y / 5.625F);
}
+ if (prefabType is PrefabType.HCZOneSided or PrefabType.HCZTwoSided or PrefabType.HCZBreakableDoor)
+ {
+ newGameObject.GetComponent().Network_syncBitmask = prefabType switch
+ {
+ PrefabType.HCZTwoSided => 0b00000000,
+ PrefabType.HCZOneSided => 0b00000001,
+ PrefabType.HCZBreakableDoor => 0b00000011,
+ _ => 0
+ };
+ }
+
NetworkServer.Spawn(newGameObject);
return newGameObject;
diff --git a/EXILED/Exiled.Utility/Commands/SpawnPrefabType.cs b/EXILED/Exiled.Utility/Commands/SpawnPrefabType.cs
index f56a7fe9ef..7c84c9a388 100644
--- a/EXILED/Exiled.Utility/Commands/SpawnPrefabType.cs
+++ b/EXILED/Exiled.Utility/Commands/SpawnPrefabType.cs
@@ -8,6 +8,7 @@
namespace Exiled.Utility.Commands
{
using System;
+ using System.Linq;
using CommandSystem;
using Exiled.API.Enums;
@@ -48,11 +49,11 @@ public bool Execute(ArraySegment arguments, ICommandSender sender, out s
if (arguments.Count < 1)
{
- response = $"Please, use: {Command} {Usage}";
+ response = $"Please, use: {Command} {string.Join(", ", EnumUtils.Names)}";
return false;
}
- if (Enum.TryParse(arguments.At(0), out PrefabType prefabType))
+ if (!Enum.TryParse(arguments.At(0), out PrefabType prefabType))
{
response = $"\"{arguments.At(0)}\" is not a valid prefab type.";
return false;
diff --git a/EXILED/Exiled.Utility/Utility.cs b/EXILED/Exiled.Utility/Utility.cs
index 42bdcbcd60..3b26d74666 100644
--- a/EXILED/Exiled.Utility/Utility.cs
+++ b/EXILED/Exiled.Utility/Utility.cs
@@ -8,8 +8,6 @@
namespace Exiled.Utility
{
using System;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
using API.Enums;
using Exiled.API.Features;