miuu-custom-cosmetic-loader/Patches/MarbleHolderPatches.cs
Terry Hearst af4ef66db5 Combine multiplayer and replay skin hijacking
Really nice simplification here, I could remove two patches at once and clear out some headaches. Now, the logic for switching skins in multiplayer and in replays is in the same place, which is great and will make it more expandable in the future
2024-01-02 01:22:31 -05:00

86 lines
2.2 KiB
C#

using HarmonyLib;
using MIU;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
namespace CustomCosmeticLoader.Patches
{
/*
* Private fields/values for MarbleHolder to be used in the patches
*/
internal static class MarbleHolderValues
{
internal static FieldInfo mbcField = typeof(MarbleHolder).GetField("mbc", BindingFlags.NonPublic | BindingFlags.Instance);
}
/*
* In multiplayer and Replays, hijack the current marble and set it to be the marble we're hijacking, then apply the skin
*/
[HarmonyPatch(typeof(MarbleHolder), nameof(MarbleHolder.CheckSet))]
internal class MarbleHolderCheckSetPatch
{
static void Postfix(MarbleHolder __instance, Cosmetic.Set cs)
{
if (!Config.enabled)
return;
if (!NetworkManager.IsMultiplayer && !MarbleManager.Replaying)
return;
// Don't hijack the soccer ball or zombie skins
if (cs.skin == "SoccerBall_V4" || cs.skin == "Zombie")
return;
MarbleController controller = MarbleHolderValues.mbcField.GetValue(__instance) as MarbleController;
if (controller == null)
return;
Texture2D skin = null;
if (NetworkManager.IsMultiplayer)
{
if (controller.isMyClientMarble())
{
skin = Config.skins[Config.currentSkin];
}
else
{
if (Config.otherPlayers.ContainsKey(controller.nickname))
skin = Config.skins[Config.otherPlayers[controller.nickname]];
}
}
else if (MarbleManager.Replaying) // Should always be true
{
string replayName = null;
GamePlayManager.Get().GetCurrentReplays(delegate (List<Replay> replays)
{
if (replays.Count > 0)
replayName = replays[0].Player;
});
Shared.Log("MarbleHolderCheckSetPatch Replay name: " + replayName);
if (replayName == Player.Current.Name)
{
skin = Config.skins[Config.currentSkin];
}
else
{
if (Config.otherPlayers.ContainsKey(replayName))
skin = Config.skins[Config.otherPlayers[replayName]];
}
}
if (skin == null)
return;
__instance.SetMarble(Shared.SkinToHijack);
Shared.ApplyCustomTexture(__instance.currentMarble, skin);
// Reset this to what it should be incase it's used later
__instance.CosmeticSet.skin = cs.skin;
}
}
}