miuu-custom-cosmetic-loader/Patches/MarbleHolderPatches.cs

92 lines
2.4 KiB
C#

using HarmonyLib;
using Parse.Common.Internal;
using System;
using System.Reflection;
using UnityEngine;
namespace CustomCosmeticLoader.Patches
{
internal static class MarbleHolderValues
{
private static FieldInfo _mbcField = typeof(MarbleHolder).GetField("mbc", BindingFlags.NonPublic | BindingFlags.Instance);
public static FieldInfo MbcField
{
get
{
return _mbcField;
}
}
}
/*
* Applies the custom skin texture to the marble in both singleplayer and multiplayer, if the cosmetic chosen is the
* one we're hijacking. In multiplayer, do some extra checks to only apply the custom texture to our marble
*/
[HarmonyPatch(typeof(MarbleHolder), nameof(MarbleHolder.SetMarble))]
internal class MarbleHolderSetMarblePatch
{
static void Postfix(MarbleHolder __instance, Cosmetic marbleObject)
{
if (!Config.enabled)
return;
if (marbleObject.Id != Config.skinNameToHijack && Config.skinNameToHijack != "*")
return;
if (!Config.inCosmeticMenu && __instance == CosmeticPanel.cosmHolder)
return;
Texture2D skin = null;
if (NetworkManager.IsMultiplayer)
{
MarbleController controller = MarbleHolderValues.MbcField.GetValue(__instance) as MarbleController;
if (controller == null)
return;
if (!controller.isMyClientMarble())
{
if (!Config.otherPlayers.ContainsKey(controller.nickname))
return;
skin = Config.skins[Config.otherPlayers[controller.nickname]];
}
}
Shared.ApplyCustomTexture(__instance.currentMarble, skin);
}
}
/*
* In multiplayer, hijack the current marble and set it to be the marble we're hijacking. Later, the actual texture
* will be replaced by the patch above
*/
[HarmonyPatch(typeof(MarbleHolder), nameof(MarbleHolder.CheckSet))]
internal class MarbleHolderCheckSetPatch
{
static void Postfix(MarbleHolder __instance, Cosmetic.Set cs)
{
if (!Config.enabled)
return;
if (!NetworkManager.IsMultiplayer)
return;
MarbleController controller = MarbleHolderValues.MbcField.GetValue(__instance) as MarbleController;
if (controller == null)
return;
if (!controller.isMyClientMarble())
{
if (!Config.otherPlayers.ContainsKey(controller.nickname))
return;
}
// Don't hijack the soccer ball or zombie skins
if (cs.skin == "SoccerBall_V4" || cs.skin == "Zombie")
return;
__instance.SetMarble(Shared.SkinToHijack);
__instance.CosmeticSet.skin = cs.skin;
}
}
}