Skip to content

Commit

Permalink
Merge branch 'dev' into PRThanIMade
Browse files Browse the repository at this point in the history
  • Loading branch information
louis1706 authored Aug 6, 2024
2 parents 6faf295 + 3ffe156 commit 2373057
Showing 1 changed file with 7 additions and 80 deletions.
87 changes: 7 additions & 80 deletions EXILED/Exiled.Events/Patches/Events/Scp330/InteractingScp330.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,12 @@ namespace Exiled.Events.Patches.Events.Scp330
using System.Collections.Generic;
using System.Reflection.Emit;

using API.Features.Pools;

using CustomPlayerEffects;
using Exiled.API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Scp330;
using Exiled.Events.Handlers;

using HarmonyLib;

using Interactables.Interobjects;

using InventorySystem;
using InventorySystem.Items.Usables.Scp330;

using static HarmonyLib.AccessTools;
Expand Down Expand Up @@ -79,69 +73,25 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
new(OpCodes.Brfalse, returnLabel),
});

// Logic to find the only ServerProcessPickup and replace with our own.
int removeServerProcessOffset = -2;
int removeServerProcessIndex = newInstructions.FindLastIndex(
instruction => instruction.Calls(Method(typeof(Scp330Bag), nameof(Scp330Bag.ServerProcessPickup)))) + removeServerProcessOffset;

newInstructions.RemoveRange(removeServerProcessIndex, 3);

// Replace NW server process logic.
newInstructions.InsertRange(
removeServerProcessIndex,
new[]
{
// ldarg.1 is already in the stack

// ev.Candy
new CodeInstruction(OpCodes.Ldloc, ev),
new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(InteractingScp330EventArgs), nameof(InteractingScp330EventArgs.Candy))),

// bag
new CodeInstruction(OpCodes.Ldloca_S, 3),

// ServerProcessPickup(ReferenceHub, CandyKindID, Scp330Bag)
new CodeInstruction(OpCodes.Call, Method(typeof(InteractingScp330), nameof(ServerProcessPickup), new[] { typeof(ReferenceHub), typeof(CandyKindID), typeof(Scp330Bag).MakeByRefType() })),
});

// This is to find the location of RpcMakeSound to remove the original code and add a new sever logic structure (Start point)
int addShouldSeverOffset = 1;
int addShouldSeverIndex = newInstructions.FindLastIndex(
instruction => instruction.Calls(Method(typeof(Scp330Interobject), nameof(Scp330Interobject.RpcMakeSound)))) + addShouldSeverOffset;

// This is to find the location of the next return (End point)
int includeSameLine = 1;
int nextReturn = newInstructions.FindIndex(addShouldSeverIndex, instruction => instruction.opcode == OpCodes.Ret) + includeSameLine;
Label originalLabel = newInstructions[addShouldSeverIndex].ExtractLabels()[0];

// Remove original code from after RpcMakeSound to next return and then fully replace it.
newInstructions.RemoveRange(addShouldSeverIndex, nextReturn - addShouldSeverIndex);

addShouldSeverIndex = newInstructions.FindLastIndex(
instruction => instruction.Calls(Method(typeof(Scp330Interobject), nameof(Scp330Interobject.RpcMakeSound)))) + addShouldSeverOffset;
int serverEffectLocationStart = -1;
int enableEffect = newInstructions.FindLastIndex(
instruction => instruction.LoadsField(Field(typeof(PlayerEffectsController), nameof(ReferenceHub.playerEffectsController)))) + serverEffectLocationStart;

newInstructions.InsertRange(
addShouldSeverIndex,
new CodeInstruction[]
new[]
{
// if (!ev.ShouldSever)
// goto shouldNotSever;
new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex).WithLabels(originalLabel),
new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingScp330EventArgs), nameof(InteractingScp330EventArgs.ShouldSever))),
new(OpCodes.Brfalse, shouldNotSever),

// ev.Player.EnableEffect("SevereHands", 1, 0f, false)
new(OpCodes.Ldloc, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingScp330EventArgs), nameof(InteractingScp330EventArgs.Player))),
new(OpCodes.Ldstr, nameof(SeveredHands)),
new(OpCodes.Ldc_I4_1),
new(OpCodes.Ldc_R4, 0f),
new(OpCodes.Ldc_I4_0),
new(OpCodes.Callvirt, Method(typeof(Player), nameof(Player.EnableEffect), new[] { typeof(string), typeof(byte), typeof(float), typeof(bool) })),
new(OpCodes.Pop),

// return;
new(OpCodes.Ret),
new(OpCodes.Br, enableEffect),
});

// This will let us jump to the taken candies code and lock until ldarg_0, meaning we allow base game logic handle candy adding.
Expand All @@ -157,28 +107,5 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}

private static bool ServerProcessPickup(ReferenceHub player, CandyKindID candy, out Scp330Bag bag)
{
if (!Scp330Bag.TryGetBag(player, out bag))
{
player.inventory.ServerAddItem(ItemType.SCP330);

if (!Scp330Bag.TryGetBag(player, out bag))
return false;

bag.Candies = new List<CandyKindID> { candy };
bag.ServerRefreshBag();

return true;
}

bool result = bag.TryAddSpecific(candy);

if (bag.AcquisitionAlreadyReceived)
bag.ServerRefreshBag();

return result;
}
}
}

0 comments on commit 2373057

Please sign in to comment.