diff --git a/EXILED/Exiled.Events/EventArgs/Scp330/InteractingScp330EventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp330/InteractingScp330EventArgs.cs index b87238842..45a587755 100644 --- a/EXILED/Exiled.Events/EventArgs/Scp330/InteractingScp330EventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Scp330/InteractingScp330EventArgs.cs @@ -35,6 +35,7 @@ public InteractingScp330EventArgs(Player player, int usage) Candy = Scp330Candies.GetRandom(); UsageCount = usage; ShouldSever = usage >= 2; + ShouldPlaySound = true; IsAllowed = Player.IsHuman; } @@ -53,10 +54,16 @@ public InteractingScp330EventArgs(Player player, int usage) /// public bool ShouldSever { get; set; } + /// + /// Gets or sets a value indicating whether the sound should be played. + /// + /// It won't work if = . + public bool ShouldPlaySound { get; set; } + /// /// Gets or sets a value indicating whether the player is allowed to interact with SCP-330. /// - public bool IsAllowed { get; set; } = true; + public bool IsAllowed { get; set; } /// /// Gets the triggering the event. diff --git a/EXILED/Exiled.Events/Patches/Events/Scp330/InteractingScp330.cs b/EXILED/Exiled.Events/Patches/Events/Scp330/InteractingScp330.cs index c8ff97d32..bcb4f5308 100644 --- a/EXILED/Exiled.Events/Patches/Events/Scp330/InteractingScp330.cs +++ b/EXILED/Exiled.Events/Patches/Events/Scp330/InteractingScp330.cs @@ -10,6 +10,7 @@ namespace Exiled.Events.Patches.Events.Scp330 using System.Collections.Generic; using System.Reflection.Emit; + using Exiled.API.Features; using Exiled.API.Features.Pools; using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Scp330; @@ -17,6 +18,7 @@ namespace Exiled.Events.Patches.Events.Scp330 using HarmonyLib; using Interactables.Interobjects; using InventorySystem.Items.Usables.Scp330; + using PluginAPI.Events; using static HarmonyLib.AccessTools; @@ -34,9 +36,7 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); - Label shouldNotSever = generator.DefineLabel(); Label returnLabel = generator.DefineLabel(); - Label enableEffectLabel = generator.DefineLabel(); LocalBuilder ev = generator.DeclareLocal(typeof(InteractingScp330EventArgs)); @@ -74,35 +74,60 @@ private static IEnumerable Transpiler(IEnumerable instruction.Calls(Method(typeof(Scp330Interobject), nameof(Scp330Interobject.RpcMakeSound)))) + addShouldSeverOffset; + /* next code will used to override sound rpc check by EXILED + * old: + * if (args.PlaySound) + * new: + * if (args.PlaySound && ev.PlaySound) + */ - int serverEffectLocationStart = -1; - int enableEffect = newInstructions.FindLastIndex( - instruction => instruction.LoadsField(Field(typeof(ReferenceHub), nameof(ReferenceHub.playerEffectsController)))) + serverEffectLocationStart; + offset = 1; + index = newInstructions.FindLastIndex( + instruction => instruction.Calls(PropertyGetter(typeof(PlayerInteractScp330Event), nameof(PlayerInteractScp330Event.PlaySound)))) + offset; - newInstructions[enableEffect].WithLabels(enableEffectLabel); newInstructions.InsertRange( - addShouldSeverIndex, + index, + new[] + { + // load ev.ShouldPlaySound and or operation with nw property. + new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingScp330EventArgs), nameof(InteractingScp330EventArgs.ShouldPlaySound))), + new(OpCodes.And), + }); + + /* next code will used to override Sever check by EXILED + * old: + * if (args.AllowPunishment && uses >= 2) + * new: + * if (args.AllowPunishment && ev.ShouldSever) + */ + + // set `notSeverLabel` + offset = -1; + index = newInstructions.FindLastIndex( + instruction => instruction.LoadsField(Field(typeof(Scp330Interobject), nameof(Scp330Interobject._takenCandies)))) + offset; + + Label notSeverLabel = newInstructions[index].labels[0]; + + offset = 2; + index = newInstructions.FindLastIndex( + instruction => instruction.Calls(PropertyGetter(typeof(PlayerInteractScp330Event), nameof(PlayerInteractScp330Event.AllowPunishment)))) + offset; + + // remove `uses >= 2` check, to override that by ev.ShouldSever + newInstructions.RemoveRange(index, 3); + + newInstructions.InsertRange( + index, new[] { // if (!ev.ShouldSever) // goto shouldNotSever; - new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex), + new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex), new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingScp330EventArgs), nameof(InteractingScp330EventArgs.ShouldSever))), - new(OpCodes.Brfalse, shouldNotSever), - new(OpCodes.Br, enableEffectLabel), + new(OpCodes.Brfalse_S, notSeverLabel), }); - // This will let us jump to the taken candies code and lock until ldarg_0, meaning we allow base game logic handle candy adding. - int addTakenCandiesOffset = -1; - int addTakenCandiesIndex = newInstructions.FindLastIndex( - instruction => instruction.LoadsField(Field(typeof(Scp330Interobject), nameof(Scp330Interobject._takenCandies)))) + addTakenCandiesOffset; - - newInstructions[addTakenCandiesIndex].WithLabels(shouldNotSever); - newInstructions[newInstructions.Count - 1].WithLabels(returnLabel); + newInstructions[newInstructions.Count - 1].labels.Add(returnLabel); for (int z = 0; z < newInstructions.Count; z++) yield return newInstructions[z];