Support for customizing other players marbles in multiplayer

This commit is contained in:
Terry Hearst 2023-09-04 02:30:54 -04:00
parent 2ac822a487
commit 1befbcc31f
3 changed files with 65 additions and 8 deletions

View file

@ -18,12 +18,14 @@ namespace CustomCosmeticLoader
public const string PROPERTY_SKIN_NAME_TO_HIJACK = "skinNameToHijack";
public const string PROPERTY_IN_MAIN_MENU = "inMainMenu";
public const string PROPERTY_IN_COSMETIC_MENU = "inCosmeticMenu";
public const string PROPERTY_OTHER_PLAYERS = "otherPlayers";
public static bool enabled = true;
public static string currentSkin;
public static string skinNameToHijack = "Swirl_M"; // Mirage, simple skin with nice properties
public static bool inMainMenu = true;
public static bool inCosmeticMenu = false;
public static Dictionary<string, string> otherPlayers = new Dictionary<string, string>();
public static Dictionary<string, Texture2D> skins = new Dictionary<string, Texture2D>();
@ -75,6 +77,25 @@ namespace CustomCosmeticLoader
if (data[PROPERTY_IN_COSMETIC_MENU] != null)
inCosmeticMenu = data[PROPERTY_IN_COSMETIC_MENU].AsBool;
if (data[PROPERTY_OTHER_PLAYERS] != null)
{
JSONClass otherPlayersData = data[PROPERTY_OTHER_PLAYERS].AsObject;
if (otherPlayersData != null)
{
foreach (KeyValuePair<string, JSONNode> node in otherPlayersData)
{
string nickname = node.Key;
string skinName = node.Value.Value;
Debug.Log("Other player: " + nickname + " | " + skinName);
if (skins.ContainsKey(skinName))
{
Debug.Log("Skin found, adding other player!");
otherPlayers.Add(nickname, skinName);
}
}
}
}
}
public static void SaveConfig()
@ -88,6 +109,12 @@ namespace CustomCosmeticLoader
{ PROPERTY_IN_COSMETIC_MENU, inCosmeticMenu ? "true" : "false" },
};
JSONNode otherPlayersData = new JSONClass();
foreach (KeyValuePair<string, string> otherPlayer in otherPlayers)
otherPlayersData.Add(otherPlayer.Key, otherPlayer.Value);
node.Add(PROPERTY_OTHER_PLAYERS, otherPlayersData);
File.WriteAllText(GetConfigPath(), node.ToString());
}

View file

@ -1,10 +1,23 @@
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;
}
}
}
[HarmonyPatch(typeof(MarbleHolder), nameof(MarbleHolder.SetMarble))]
internal class MarbleHolderSetMarblePatch
{
@ -19,15 +32,22 @@ namespace CustomCosmeticLoader.Patches
if (!Config.inCosmeticMenu && __instance == CosmeticPanel.cosmHolder)
return;
// If this is a networked game, ONLY apply to my marble and not anyone else happening to use our SkinToHijack
Texture2D skin = null;
if (NetworkManager.IsMultiplayer)
{
MarbleController controller = __instance.GetComponentInParent<MarbleController>();
if (!controller.isMyClientMarble())
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);
Shared.ApplyCustomTexture(__instance.currentMarble, skin);
}
}
@ -42,12 +62,19 @@ namespace CustomCosmeticLoader.Patches
if (!NetworkManager.IsMultiplayer)
return;
FieldInfo mbcField = typeof(MarbleHolder).GetField("mbc", BindingFlags.NonPublic | BindingFlags.Instance);
MarbleController controller = mbcField.GetValue(__instance) as MarbleController;
MarbleController controller = MarbleHolderValues.MbcField.GetValue(__instance) as MarbleController;
if (controller == null)
return;
Debug.Log("========= MarbleHolder.CheckSet with nickname " + controller.nickname);
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;

View file

@ -37,14 +37,17 @@ namespace CustomCosmeticLoader
}
}
public static void ApplyCustomTexture(GameObject marbleObject)
public static void ApplyCustomTexture(GameObject marbleObject, Texture2D skin = null)
{
if (skin == null)
skin = Config.skins[Config.currentSkin];
MeshRenderer[] componentsInChildren = marbleObject.GetComponentsInChildren<MeshRenderer>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
Material[] materials = componentsInChildren[i].materials;
foreach (Material material in materials)
material.mainTexture = Config.skins[Config.currentSkin];
material.mainTexture = skin;
}
}
}