From e3062e9dfdd799b51598afbfe6d9ffec7ed4264e Mon Sep 17 00:00:00 2001 From: Yamato Date: Sun, 1 Dec 2024 17:44:01 +0100 Subject: [PATCH 1/2] Fix --- .../Patches/Fixes/NWFixDetonationTimer.cs | 2 +- .../Patches/Fixes/PositionSpawnScp0492Fix.cs | 0 .../Patches/Fixes/Scp3114FriendlyFireFix.cs | 124 ++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) delete mode 100644 EXILED/Exiled.Events/Patches/Fixes/PositionSpawnScp0492Fix.cs diff --git a/EXILED/Exiled.Events/Patches/Fixes/NWFixDetonationTimer.cs b/EXILED/Exiled.Events/Patches/Fixes/NWFixDetonationTimer.cs index 2d51cfcaef..0eeafc3c0e 100644 --- a/EXILED/Exiled.Events/Patches/Fixes/NWFixDetonationTimer.cs +++ b/EXILED/Exiled.Events/Patches/Fixes/NWFixDetonationTimer.cs @@ -23,7 +23,7 @@ internal class NWFixDetonationTimer private static void Postfix() { AlphaWarheadSyncInfo networkInfo = default; - networkInfo.ScenarioId = (byte)Array.IndexOf(AlphaWarheadController.Singleton._startScenarios, AlphaWarheadController.Singleton._startScenarios.OrderBy(d => Math.Abs(d.TimeToDetonate - ConfigFile.ServerConfig.GetInt("warhead_tminus_start_duration", 90))).First()); + networkInfo.ScenarioId = (byte)Array.IndexOf(AlphaWarheadController.Singleton._startScenarios, AlphaWarheadController.Singleton._startScenarios.OrderBy(d => Math.Abs(d.TimeToDetonate - ConfigFile.ServerConfig.GetByte("warhead_tminus_start_duration", 90))).First()); AlphaWarheadController.Singleton.NetworkInfo = networkInfo; return; diff --git a/EXILED/Exiled.Events/Patches/Fixes/PositionSpawnScp0492Fix.cs b/EXILED/Exiled.Events/Patches/Fixes/PositionSpawnScp0492Fix.cs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs b/EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs index e69de29bb2..3d9b4d2acb 100644 --- a/EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs +++ b/EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs @@ -0,0 +1,124 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Fixes +{ +#pragma warning disable SA1402 // File may only contain a single type + using System.Collections.Generic; + using System.Reflection.Emit; + + using API.Features.Pools; + + using Exiled.API.Features; + + using Footprinting; + using HarmonyLib; + using InventorySystem.Items.Pickups; + using InventorySystem.Items.ThrowableProjectiles; + using PlayerRoles; + using PlayerStatsSystem; + + using static HarmonyLib.AccessTools; + + /// + /// Patches the delegate. + /// Fix Throwing a ghostlight with Scp in the room stun 079. + /// Bug reported to NW (https://git.scpslgame.com/northwood-qa/scpsl-bug-reporting/-/issues/55). + /// + [HarmonyPatch(typeof(Scp2176Projectile), nameof(Scp2176Projectile.ServerShatter))] + internal class Scp3114FriendlyFireFix + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + Label cnt = generator.DefineLabel(); + + int offset = 0; + int index = newInstructions.FindIndex(x => x.LoadsField(Field(typeof(RoomLightController), nameof(RoomLightController.Instances)))) + offset; + + Label skip = newInstructions[index].labels[0]; + + offset = -4; + index += offset; + + newInstructions.InsertRange(index, new[] + { + // if (this.PreviousOwner.Role.GetTeam() is Team.SCPs) + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Ldfld, Field(typeof(Scp2176Projectile), nameof(Scp2176Projectile.PreviousOwner))), + new(OpCodes.Ldfld, Field(typeof(Footprint), nameof(Footprint.Role))), + new(OpCodes.Call, Method(typeof(PlayerRolesUtils), nameof(PlayerRolesUtils.GetTeam), new[] { typeof(RoleTypeId) })), + new(OpCodes.Ldc_I4_0), + new(OpCodes.Ceq), + + new(OpCodes.Brfalse_S, cnt), + + new(OpCodes.Pop), + new(OpCodes.Br_S, skip), + + new CodeInstruction(OpCodes.Nop).WithLabels(cnt), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } + + /// + /// Patches the delegate. + /// Fix Throwing a ghostlight with Scp in the room stun 079. + /// Bug reported to NW (https://git.scpslgame.com/northwood-qa/scpsl-bug-reporting/-/issues/55). + /// + [HarmonyPatch(typeof(CollisionDetectionPickup), nameof(CollisionDetectionPickup.ProcessCollision))] + internal class Scp3114FriendlyFireFix2 : AttackerDamageHandler + { +#pragma warning disable SA1600 // Elements should be documented + public Scp3114FriendlyFireFix2(Footprint attacker, float damage) + { + Attacker = attacker; + Damage = damage; + AllowSelfDamage = false; + ServerLogsText = "Scp3114 Fix"; + } + + public override Footprint Attacker { get; set; } + + public override bool AllowSelfDamage { get; } + + public override float Damage { get; set; } + + public override string ServerLogsText { get; } +#pragma warning restore SA1600 // Elements should be documented + + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int offset = 0; + int index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ldnull) + offset; + + // replace null with new Scp3114FriendlyFireFix2(this.PreviousOwner, num2) + newInstructions.RemoveAt(index); + newInstructions.InsertRange(index, new CodeInstruction[] + { + // new Scp3114FriendlyFireFix2(this.PreviousOwner, num2) + new(OpCodes.Ldarg_0), + new(OpCodes.Ldfld, Field(typeof(CollisionDetectionPickup), nameof(CollisionDetectionPickup.PreviousOwner))), + new(OpCodes.Ldloc_3), + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(Scp3114FriendlyFireFix2))[0]), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file From cec6fbc92fcd3980a288f37585433afbcc1abaa0 Mon Sep 17 00:00:00 2001 From: Yamato Date: Sun, 1 Dec 2024 17:46:53 +0100 Subject: [PATCH 2/2] Fix --- .../Fixes/Fix106RegenerationWithScp244.cs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 EXILED/Exiled.Events/Patches/Fixes/Fix106RegenerationWithScp244.cs diff --git a/EXILED/Exiled.Events/Patches/Fixes/Fix106RegenerationWithScp244.cs b/EXILED/Exiled.Events/Patches/Fixes/Fix106RegenerationWithScp244.cs new file mode 100644 index 0000000000..15da68148a --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Fixes/Fix106RegenerationWithScp244.cs @@ -0,0 +1,72 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Fixes +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using API.Features.Pools; + using CustomPlayerEffects; + using HarmonyLib; + using InventorySystem.Items.Usables.Scp244.Hypothermia; + using PlayerRoles; + using PlayerRoles.PlayableScps.Scp106; + + using static HarmonyLib.AccessTools; + + /// + /// Patches the delegate. + /// Fix than SCP-106 regenerates slower in SCP-244 even if they are in stalk. + /// Bug reported to NW (https://git.scpslgame.com/northwood-qa/scpsl-bug-reporting/-/issues/367). + /// + [HarmonyPatch(typeof(Hypothermia), nameof(Hypothermia.Update))] + internal class Fix106RegenerationWithScp244 + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + LocalBuilder scp106Role = generator.DeclareLocal(typeof(Scp106Role)); + Label continueLabel = generator.DefineLabel(); + + int offset = 1; + int index = newInstructions.FindLastIndex(x => x.operand == (object)Method(typeof(SpawnProtected), nameof(SpawnProtected.CheckPlayer))) + offset; + + Label skip = (Label)newInstructions[index].operand; + + index += offset; + + newInstructions[index].labels.Add(continueLabel); + + newInstructions.InsertRange(index, new[] + { + // Scp106Role scp106Role = base.Hub.roleManager.CurrentRole as Scp106Role; + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(StatusEffectBase), nameof(StatusEffectBase.Hub))), + new CodeInstruction(OpCodes.Ldfld, Field(typeof(ReferenceHub), nameof(ReferenceHub.roleManager))), + new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(PlayerRoleManager), nameof(PlayerRoleManager.CurrentRole))), + new CodeInstruction(OpCodes.Isinst, typeof(Scp106Role)), + new CodeInstruction(OpCodes.Stloc_S, scp106Role.LocalIndex), + + // if (scp106Role is null) goto continueLabel + new CodeInstruction(OpCodes.Ldloc_S, scp106Role.LocalIndex), + new CodeInstruction(OpCodes.Brfalse_S, continueLabel), + + // if (!scp106Role.IsStalking) goto skip + new CodeInstruction(OpCodes.Ldloc_S, scp106Role.LocalIndex), + new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.IsStalking))), + new CodeInstruction(OpCodes.Brtrue_S, skip), + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file