Skip to content

Commit

Permalink
v8.12.0-rc.2 (#57)
Browse files Browse the repository at this point in the history
* `[Exiled::API]` Removing breaking changes (#54)
Co-authored-by: VALERA771 <72030575+VALERA771@users.noreply.github.com>
Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com>

* `Scp330` sound fix (#55)
Co-authored-by: IRacle <79921583+IRacle1@users.noreply.github.com>
Co-authored-by: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com>
  • Loading branch information
Misaka-ZeroTwo authored Aug 12, 2024
1 parent 724131b commit f4abc04
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 22 deletions.
11 changes: 11 additions & 0 deletions EXILED/Exiled.API/Features/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2411,6 +2411,17 @@ public ushort GetAmmoLimit(AmmoType type, bool ignoreArmor = false)
return InventorySystem.Configs.InventoryLimits.GetAmmoLimit(type.GetItemType(), referenceHub);
}

/// <summary>
/// Gets the maximum amount of ammo the player can hold, given the ammo <see cref="AmmoType"/>.
/// </summary>
/// <param name="type">The <see cref="AmmoType"/> of the ammo to check.</param>
/// <returns>The maximum amount of ammo this player can carry.</returns>
[Obsolete("Use Player::GetAmmoLimit(AmmoType, bool) instead.")]
public int GetAmmoLimit(AmmoType type)
{
return (int)InventorySystem.Configs.InventoryLimits.GetAmmoLimit(type.GetItemType(), referenceHub);
}

/// <summary>
/// Gets the maximum amount of ammo the player can hold, given the ammo <see cref="AmmoType"/>.
/// This limit will scale with the armor the player is wearing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public InteractingScp330EventArgs(Player player, int usage)
Candy = Scp330Candies.GetRandom();
UsageCount = usage;
ShouldSever = usage >= 2;
ShouldPlaySound = true;
IsAllowed = Player.IsHuman;
}

Expand All @@ -53,10 +54,16 @@ public InteractingScp330EventArgs(Player player, int usage)
/// </summary>
public bool ShouldSever { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the sound should be played.
/// </summary>
/// <remarks>It won't work if <see cref="IsAllowed"/> = <see langword="false"/>.</remarks>
public bool ShouldPlaySound { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the player is allowed to interact with SCP-330.
/// </summary>
public bool IsAllowed { get; set; } = true;
public bool IsAllowed { get; set; }

/// <summary>
/// Gets the <see cref="API.Features.Player" /> triggering the event.
Expand Down
67 changes: 46 additions & 21 deletions EXILED/Exiled.Events/Patches/Events/Scp330/InteractingScp330.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ 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;
using Exiled.Events.Handlers;
using HarmonyLib;
using Interactables.Interobjects;
using InventorySystem.Items.Usables.Scp330;
using PluginAPI.Events;

using static HarmonyLib.AccessTools;

Expand All @@ -34,9 +36,7 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label shouldNotSever = generator.DefineLabel();
Label returnLabel = generator.DefineLabel();
Label enableEffectLabel = generator.DefineLabel();

LocalBuilder ev = generator.DeclareLocal(typeof(InteractingScp330EventArgs));

Expand Down Expand Up @@ -74,35 +74,60 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
new(OpCodes.Brfalse, returnLabel),
});

// 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;
/* 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];
Expand Down

0 comments on commit f4abc04

Please sign in to comment.