Support for customizing other players marbles in multiplayer
This commit is contained in:
parent
2ac822a487
commit
1befbcc31f
3 changed files with 65 additions and 8 deletions
27
Config.cs
27
Config.cs
|
@ -18,12 +18,14 @@ namespace CustomCosmeticLoader
|
||||||
public const string PROPERTY_SKIN_NAME_TO_HIJACK = "skinNameToHijack";
|
public const string PROPERTY_SKIN_NAME_TO_HIJACK = "skinNameToHijack";
|
||||||
public const string PROPERTY_IN_MAIN_MENU = "inMainMenu";
|
public const string PROPERTY_IN_MAIN_MENU = "inMainMenu";
|
||||||
public const string PROPERTY_IN_COSMETIC_MENU = "inCosmeticMenu";
|
public const string PROPERTY_IN_COSMETIC_MENU = "inCosmeticMenu";
|
||||||
|
public const string PROPERTY_OTHER_PLAYERS = "otherPlayers";
|
||||||
|
|
||||||
public static bool enabled = true;
|
public static bool enabled = true;
|
||||||
public static string currentSkin;
|
public static string currentSkin;
|
||||||
public static string skinNameToHijack = "Swirl_M"; // Mirage, simple skin with nice properties
|
public static string skinNameToHijack = "Swirl_M"; // Mirage, simple skin with nice properties
|
||||||
public static bool inMainMenu = true;
|
public static bool inMainMenu = true;
|
||||||
public static bool inCosmeticMenu = false;
|
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>();
|
public static Dictionary<string, Texture2D> skins = new Dictionary<string, Texture2D>();
|
||||||
|
|
||||||
|
@ -75,6 +77,25 @@ namespace CustomCosmeticLoader
|
||||||
|
|
||||||
if (data[PROPERTY_IN_COSMETIC_MENU] != null)
|
if (data[PROPERTY_IN_COSMETIC_MENU] != null)
|
||||||
inCosmeticMenu = data[PROPERTY_IN_COSMETIC_MENU].AsBool;
|
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()
|
public static void SaveConfig()
|
||||||
|
@ -88,6 +109,12 @@ namespace CustomCosmeticLoader
|
||||||
{ PROPERTY_IN_COSMETIC_MENU, inCosmeticMenu ? "true" : "false" },
|
{ 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());
|
File.WriteAllText(GetConfigPath(), node.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using Parse.Common.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace CustomCosmeticLoader.Patches
|
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))]
|
[HarmonyPatch(typeof(MarbleHolder), nameof(MarbleHolder.SetMarble))]
|
||||||
internal class MarbleHolderSetMarblePatch
|
internal class MarbleHolderSetMarblePatch
|
||||||
{
|
{
|
||||||
|
@ -19,15 +32,22 @@ namespace CustomCosmeticLoader.Patches
|
||||||
if (!Config.inCosmeticMenu && __instance == CosmeticPanel.cosmHolder)
|
if (!Config.inCosmeticMenu && __instance == CosmeticPanel.cosmHolder)
|
||||||
return;
|
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)
|
if (NetworkManager.IsMultiplayer)
|
||||||
{
|
{
|
||||||
MarbleController controller = __instance.GetComponentInParent<MarbleController>();
|
MarbleController controller = MarbleHolderValues.MbcField.GetValue(__instance) as MarbleController;
|
||||||
if (!controller.isMyClientMarble())
|
if (controller == null)
|
||||||
return;
|
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)
|
if (!NetworkManager.IsMultiplayer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FieldInfo mbcField = typeof(MarbleHolder).GetField("mbc", BindingFlags.NonPublic | BindingFlags.Instance);
|
MarbleController controller = MarbleHolderValues.MbcField.GetValue(__instance) as MarbleController;
|
||||||
MarbleController controller = mbcField.GetValue(__instance) as MarbleController;
|
|
||||||
|
|
||||||
if (controller == null)
|
if (controller == null)
|
||||||
return;
|
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
|
// Don't hijack the soccer ball or zombie skins
|
||||||
if (cs.skin == "SoccerBall_V4" || cs.skin == "Zombie")
|
if (cs.skin == "SoccerBall_V4" || cs.skin == "Zombie")
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -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>();
|
MeshRenderer[] componentsInChildren = marbleObject.GetComponentsInChildren<MeshRenderer>();
|
||||||
for (int i = 0; i < componentsInChildren.Length; i++)
|
for (int i = 0; i < componentsInChildren.Length; i++)
|
||||||
{
|
{
|
||||||
Material[] materials = componentsInChildren[i].materials;
|
Material[] materials = componentsInChildren[i].materials;
|
||||||
foreach (Material material in materials)
|
foreach (Material material in materials)
|
||||||
material.mainTexture = Config.skins[Config.currentSkin];
|
material.mainTexture = skin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue