forked from Exiled-Team/EXILED
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* snow pile * list fix --------- Co-authored-by: Yamato <[email protected]>
- Loading branch information
Showing
7 changed files
with
297 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="Snowpile.cs" company="Exiled Team"> | ||
// Copyright (c) Exiled Team. All rights reserved. | ||
// Licensed under the CC BY-SA 3.0 license. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
namespace Exiled.API.Features | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
using Exiled.API.Interfaces; | ||
using UnityEngine; | ||
|
||
using Basepile = global::Snowpile; | ||
|
||
/// <summary> | ||
/// A wrapper for <see cref="Basepile"/>. | ||
/// </summary> | ||
public class Snowpile : IWorldSpace, IWrapper<Basepile> | ||
{ | ||
/// <summary> | ||
/// A <see cref="Dictionary{TKey,TValue}"/> with <see cref="Basepile"/> to <see cref="Snowpile"/>. | ||
/// </summary> | ||
internal static readonly Dictionary<Basepile, Snowpile> BaseToWrapper = new(); | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Snowpile"/> class. | ||
/// </summary> | ||
/// <param name="snowpile">The <see cref="Basepile"/> instance.</param> | ||
public Snowpile(Basepile snowpile) | ||
{ | ||
Base = snowpile; | ||
|
||
BaseToWrapper.Add(snowpile, this); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the list of all snowpiles. | ||
/// </summary> | ||
public static IReadOnlyCollection<Snowpile> List => BaseToWrapper.Values; | ||
|
||
/// <inheritdoc/> | ||
public Basepile Base { get; } | ||
|
||
/// <inheritdoc/> | ||
public Vector3 Position | ||
{ | ||
get => Base._position; | ||
set => Base.Network_position = value; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public Quaternion Rotation | ||
{ | ||
get => Base._rotation; | ||
set => Base.Network_rotation = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets amount of uses that this snowpile can handle. | ||
/// </summary> | ||
public int RemainingUses | ||
{ | ||
get => Base._remainingUses; | ||
set => Base.Network_remainingUses = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether or not this snowpile should regenerate amount of usages. | ||
/// </summary> | ||
public bool Regenerate | ||
{ | ||
get => Base._regenerate; | ||
set => Base._regenerate = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets a current timer of regeneration. | ||
/// </summary> | ||
public float RegenerationTimer | ||
{ | ||
get => Base._regenerationTimer; | ||
set => Base._regenerationTimer = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets time how much snowpile should regenerate 1 snow ball. | ||
/// </summary> | ||
public float RegenerationDuration | ||
{ | ||
get => Base._regenerationDuration; | ||
set => Base._regenerationDuration = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets maximal amount of uses that this snowpile can has.. | ||
/// </summary> | ||
public int InitUses | ||
{ | ||
get => Base._initialUses; | ||
set => Base._initialUses = value; | ||
} | ||
|
||
/// <summary> | ||
/// Gets a <see cref="Snowpile"/> which is connected to it's base game analog. | ||
/// </summary> | ||
/// <param name="snowpile">Base game analog.</param> | ||
/// <returns>A <see cref="Snowpile"/> instance or <see langword="null"/>.</returns> | ||
public static Snowpile Get(Basepile snowpile) => BaseToWrapper.TryGetValue(snowpile, out Snowpile pile) ? pile : new Snowpile(snowpile); | ||
|
||
/// <summary> | ||
/// Gets a <see cref="IEnumerable{T}"/> of <see cref="Snowpile"/> filtered based on a predicate. | ||
/// </summary> | ||
/// <param name="predicate">The condition to satisfy.</param> | ||
/// <returns>A <see cref="IEnumerable{T}"/> of <see cref="Player"/> which contains elements that satisfy the condition.</returns> | ||
public static IEnumerable<Snowpile> Get(Func<Snowpile, bool> predicate) => List.Where(predicate); | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
Exiled.Events/EventArgs/Player/InteractingSnowpileEventArgs.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="InteractingSnowpileEventArgs.cs" company="Exiled Team"> | ||
// Copyright (c) Exiled Team. All rights reserved. | ||
// Licensed under the CC BY-SA 3.0 license. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
namespace Exiled.Events.EventArgs.Player | ||
{ | ||
using Exiled.API.Features; | ||
using Exiled.Events.EventArgs.Interfaces; | ||
|
||
/// <summary> | ||
/// Contains all information before a <see cref="API.Features.Player"/> is interacting with snowpile. | ||
/// </summary> | ||
public class InteractingSnowpileEventArgs : IPlayerEvent, IDeniableEvent | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="InteractingSnowpileEventArgs"/> class. | ||
/// </summary> | ||
/// <param name="player"><inheritdoc cref="Player"/></param> | ||
/// <param name="snowpile"><inheritdoc cref="Snowpile"/></param> | ||
/// <param name="isAllowed"><inheritdoc cref="IsAllowed"/></param> | ||
public InteractingSnowpileEventArgs(Player player, Snowpile snowpile, bool isAllowed = true) | ||
{ | ||
Player = player; | ||
Snowpile = snowpile; | ||
IsAllowed = isAllowed; | ||
} | ||
|
||
/// <summary> | ||
/// Gets a snowpile with which player is interacting. | ||
/// </summary> | ||
public Snowpile Snowpile { get; } | ||
|
||
/// <inheritdoc/> | ||
public Player Player { get; } | ||
|
||
/// <inheritdoc/> | ||
public bool IsAllowed { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether or not should be checked if player already has a snowball. | ||
/// </summary> | ||
public bool ShouldCheck { get; set; } = true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
Exiled.Events/Patches/Events/Player/InteractingSnowpile.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="InteractingSnowpile.cs" company="Exiled Team"> | ||
// Copyright (c) Exiled Team. All rights reserved. | ||
// Licensed under the CC BY-SA 3.0 license. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
namespace Exiled.Events.Patches.Events.Player | ||
{ | ||
using System.Collections.Generic; | ||
using System.Reflection; | ||
using System.Reflection.Emit; | ||
|
||
using Exiled.API.Features; | ||
using Exiled.API.Features.Pools; | ||
using Exiled.Events.Attributes; | ||
using Exiled.Events.EventArgs.Player; | ||
using HarmonyLib; | ||
|
||
using static HarmonyLib.AccessTools; | ||
|
||
/// <summary> | ||
/// Patches <see cref="global::Snowpile.ServerInteract"/> | ||
/// to add <see cref="Handlers.Player.InteractingSnowpile"/> event. | ||
/// </summary> | ||
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.InteractingSnowpile))] | ||
[HarmonyPatch(typeof(global::Snowpile), nameof(global::Snowpile.ServerInteract))] | ||
internal class InteractingSnowpile | ||
{ | ||
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) | ||
{ | ||
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions); | ||
|
||
int offset = -1; | ||
int index = newInstructions.FindLastIndex(x => x.operand is FieldInfo info && info == Field(typeof(ReferenceHub), nameof(ReferenceHub.inventory))) + offset; | ||
|
||
Label skipCheckLabel = generator.DefineLabel(); | ||
Label retLabel = generator.DefineLabel(); | ||
|
||
newInstructions[index].labels.Add(skipCheckLabel); | ||
newInstructions[newInstructions.Count - 1].labels.Add(retLabel); | ||
|
||
LocalBuilder ev = generator.DeclareLocal(typeof(InteractingSnowpileEventArgs)); | ||
|
||
offset = 1; | ||
index = newInstructions.FindIndex(x => x.opcode == OpCodes.Ret) + offset; | ||
|
||
newInstructions.InsertRange( | ||
index, | ||
new[] | ||
{ | ||
// Player.Get(hub); | ||
new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]), | ||
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), | ||
|
||
// Snowpile.Get(this); | ||
new(OpCodes.Ldarg_0), | ||
new(OpCodes.Call, Method(typeof(Snowpile), nameof(Snowpile.Get), new[] { typeof(global::Snowpile) })), | ||
|
||
// true | ||
new(OpCodes.Ldc_I4_1), | ||
|
||
// InteractingSnowpileEventArgs ev = new(Player, Snowpile, true); | ||
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(InteractingSnowpileEventArgs))[0]), | ||
new(OpCodes.Dup), | ||
new(OpCodes.Dup), | ||
new(OpCodes.Stloc_S, ev.LocalIndex), | ||
|
||
// Handlers.Player.OnInteractingSnowpile(ev); | ||
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnInteractingSnowpile))), | ||
|
||
// if (!ev.IsAllowed) | ||
// return; | ||
new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingSnowpileEventArgs), nameof(InteractingSnowpileEventArgs.IsAllowed))), | ||
new(OpCodes.Brfalse_S, retLabel), | ||
|
||
// if (!ev.ShouldCheck) | ||
// goto skipCheckLabel; | ||
new(OpCodes.Ldloc_S, ev.LocalIndex), | ||
new(OpCodes.Callvirt, PropertyGetter(typeof(InteractingSnowpileEventArgs), nameof(InteractingSnowpileEventArgs.ShouldCheck))), | ||
new(OpCodes.Brfalse_S, skipCheckLabel), | ||
}); | ||
|
||
for (int z = 0; z < newInstructions.Count; z++) | ||
yield return newInstructions[z]; | ||
|
||
ListPool<CodeInstruction>.Pool.Return(newInstructions); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="SnowpileListAdd.cs" company="Exiled Team"> | ||
// Copyright (c) Exiled Team. All rights reserved. | ||
// Licensed under the CC BY-SA 3.0 license. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
namespace Exiled.Events.Patches.Generic | ||
{ | ||
using HarmonyLib; | ||
|
||
#pragma warning disable SA1313 | ||
|
||
/// <summary> | ||
/// Patches <see cref="Snowpile.Awake"/> to control list. | ||
/// </summary> | ||
[HarmonyPatch(typeof(Snowpile), nameof(Snowpile.Awake))] | ||
internal class SnowpileListAdd | ||
{ | ||
private static void Postfix(Snowpile __instance) | ||
{ | ||
_ = new Exiled.API.Features.Snowpile(__instance); | ||
} | ||
} | ||
} |