Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions EXILED/Exiled.Events/Patches/Fixes/Fix106RegenerationWithScp244.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// -----------------------------------------------------------------------
// <copyright file="Fix106RegenerationWithScp244.cs" company="ExMod Team">
// Copyright (c) ExMod Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

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;

/// <summary>
/// Patches the <see cref="Hypothermia.Update()"/> 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).
/// </summary>
[HarmonyPatch(typeof(Hypothermia), nameof(Hypothermia.Update))]
internal class Fix106RegenerationWithScp244
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.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<CodeInstruction>.Pool.Return(newInstructions);
}
}
}
2 changes: 1 addition & 1 deletion EXILED/Exiled.Events/Patches/Fixes/NWFixDetonationTimer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Empty file.
124 changes: 124 additions & 0 deletions EXILED/Exiled.Events/Patches/Fixes/Scp3114FriendlyFireFix.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// -----------------------------------------------------------------------
// <copyright file="Scp3114FriendlyFireFix.cs" company="ExMod Team">
// Copyright (c) ExMod Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

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;

/// <summary>
/// Patches the <see cref="Scp2176Projectile.ServerShatter()"/> 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).
/// </summary>
[HarmonyPatch(typeof(Scp2176Projectile), nameof(Scp2176Projectile.ServerShatter))]
internal class Scp3114FriendlyFireFix
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.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<CodeInstruction>.Pool.Return(newInstructions);
}
}

/// <summary>
/// Patches the <see cref="CollisionDetectionPickup.ProcessCollision(UnityEngine.Collision)"/> 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).
/// </summary>
[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<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.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<CodeInstruction>.Pool.Return(newInstructions);
}
}
}