128 lines
3.2 KiB
C#
128 lines
3.2 KiB
C#
using HarmonyLib;
|
|
using MIU;
|
|
using System.Collections.Generic;
|
|
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;
|
|
|
|
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))
|
|
return;
|
|
skin = Config.skins[Config.otherPlayers[controller.nickname]];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (MarbleManager.Replaying && !Config.inAllReplays)
|
|
{
|
|
string replayName = null;
|
|
|
|
GamePlayManager.Get().GetCurrentReplays(delegate (List<Replay> replays)
|
|
{
|
|
if (replays.Count > 0)
|
|
replayName = replays[0].Player;
|
|
});
|
|
|
|
Shared.Log("MarbleHolderSetMarblePatch 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]];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
skin = Config.skins[Config.currentSkin];
|
|
}
|
|
}
|
|
|
|
if (skin != null)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|