using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using PersonalWardrobe.Presentation;
using PersonalWardrobe.Presentation.Cards;
using PersonalWardrobe.Utils;
using Photon.Pun;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.Kirshoo.PersonalWardrobe")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.6.1.0")]
[assembly: AssemblyInformationalVersion("0.6.1+63e7f96e7a8b86ebf3481de1f25cc947d603dccd")]
[assembly: AssemblyProduct("com.github.Kirshoo.PersonalWardrobe")]
[assembly: AssemblyTitle("PersonalWardrobe")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.6.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace PersonalWardrobe
{
public class Loadout
{
[JsonIgnore]
public int IdleIndex = -1;
[JsonIgnore]
public bool IsActive;
[JsonProperty("name")]
public string Name { get; set; } = string.Empty;
[JsonProperty("skin")]
public int SkinIndex { get; set; }
[JsonProperty("accessory")]
public int AccessoryIndex { get; set; }
[JsonProperty("hat")]
public int HatIndex { get; set; }
[JsonProperty("outfit")]
public int OutfitIndex { get; set; }
[JsonProperty("eyes")]
public int EyesIndex { get; set; }
[JsonProperty("mouth")]
public int MouthIndex { get; set; }
[JsonProperty("sash")]
public int SashIndex { get; set; }
public static bool Equals(Loadout lhs, Loadout rhs)
{
return lhs.Name == rhs.Name;
}
public static bool Equals(Loadout lhs, string name)
{
return lhs.Name == name;
}
}
public class Wardrobe
{
[JsonProperty("version")]
public int Version = 2;
[JsonProperty("last_active")]
public int LastActiveIndex;
[JsonProperty("wardrobe")]
public List<Loadout> Loadouts = new List<Loadout>();
}
[BepInPlugin("com.github.Kirshoo.PersonalWardrobe", "PersonalWardrobe", "0.6.1")]
public class Plugin : BaseUnityPlugin
{
public static readonly string configFolder = Path.Combine(Paths.ConfigPath, "PersonalWardrobe");
public static readonly string loadoutsPath = Path.Combine(configFolder, "wardrobe.json");
public static readonly string loadoutsBackupPath = Path.Combine(configFolder, "~wardrobe.json");
internal static ConfigEntry<KeyCode> toggleMenuButton = null;
private GameObject menuObj;
private WardrobeMenu menu;
internal static TMP_FontAsset? font = null;
public const string Id = "com.github.Kirshoo.PersonalWardrobe";
internal static ManualLogSource Log { get; private set; } = null;
private Wardrobe Wardrobe { get; set; }
public static string Name => "PersonalWardrobe";
public static string Version => "0.6.1";
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
((MonoBehaviour)this).StartCoroutine(new FontUtil.FontLoader().LoadFontCoroutine("DarumaDropOne-Regular SDF", delegate(TMP_FontAsset font)
{
Plugin.font = font;
}));
try
{
WardrobeManager.Instance.EnsureWardrobe();
}
catch (Exception ex)
{
Log.LogError((object)("Wardrobe Load error: " + ex.Message));
throw;
}
toggleMenuButton = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ToggleMenu", (KeyCode)290, "Button to toggle Wardrobe UI");
Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
}
private void OnApplicationQuit()
{
WardrobeManager.SaveWardrobeToFile();
}
private void EnsureMenu()
{
if (!((Object)(object)menuObj != (Object)null))
{
CreateMenu();
}
}
private void CreateMenu()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
menuObj = new GameObject("Wardrobe");
Object.DontDestroyOnLoad((Object)(object)menuObj);
menu = menuObj.AddComponent<WardrobeMenu>();
}
private void Update()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(toggleMenuButton.Value) && WardrobeMenu.CanCreatePreview())
{
EnsureMenu();
menu.ToggleOpen();
}
}
}
internal class WardrobeManager
{
private static WardrobeManager _instance;
private Wardrobe wardrobe;
public const string DefaultLoadoutName = "New Template";
public static WardrobeManager Instance
{
get
{
if (_instance == null)
{
_instance = new WardrobeManager();
}
return _instance;
}
}
public Wardrobe Wardrobe
{
get
{
EnsureWardrobe();
return wardrobe;
}
}
public WardrobeManager()
{
if (_instance == null)
{
_instance = this;
LoadWardrobe();
}
}
public void LoadWardrobe()
{
Directory.CreateDirectory(Plugin.configFolder);
if (!File.Exists(Plugin.loadoutsPath))
{
Wardrobe wardrobe = new Wardrobe();
File.WriteAllText(Plugin.loadoutsPath, JsonConvert.SerializeObject((object)wardrobe, (Formatting)1));
Plugin.Log.LogInfo((object)"Created a default wardrobe file.");
}
string text = File.ReadAllText(Plugin.loadoutsPath);
Wardrobe wardrobe2 = JsonConvert.DeserializeObject<Wardrobe>(text);
if (wardrobe2 == null)
{
throw new FileLoadException("Deserialization returned null");
}
this.wardrobe = MigrateVersion(wardrobe2);
Plugin.Log.LogInfo((object)$"Loaded wardrobe: v{this.wardrobe.Version}.");
}
public Wardrobe MigrateVersion(Wardrobe oldWardrobe)
{
if (oldWardrobe.Version < 2)
{
oldWardrobe.LastActiveIndex = 0;
oldWardrobe.Version = 2;
}
return oldWardrobe;
}
public void EnsureWardrobe()
{
if (wardrobe == null)
{
LoadWardrobe();
}
}
public void SaveWardrobe()
{
File.WriteAllText(Plugin.loadoutsBackupPath, JsonConvert.SerializeObject((object)wardrobe, (Formatting)1));
Plugin.Log.LogInfo((object)"Wardrobe is saved.");
}
public void SaveLoadout(Loadout loadout)
{
EnsureWardrobe();
int index = GetIndex(loadout);
if (index == -1)
{
wardrobe.Loadouts.Add(loadout);
}
else
{
wardrobe.Loadouts[index] = loadout;
}
SaveWardrobe();
}
public static void SaveWardrobeToFile()
{
if (File.Exists(Plugin.loadoutsBackupPath))
{
string contents = File.ReadAllText(Plugin.loadoutsBackupPath);
File.WriteAllText(Plugin.loadoutsPath, contents);
File.Delete(Plugin.loadoutsBackupPath);
Plugin.Log.LogInfo((object)"Backup removed and main file is up to date.");
}
}
public Loadout GetLoadout(string name)
{
EnsureWardrobe();
Loadout loadout = wardrobe.Loadouts.Find((Loadout x) => Loadout.Equals(x, name));
if (loadout == null)
{
Plugin.Log.LogDebug((object)("Unable to find \"" + name + "\" loadout. Returning default."));
return new Loadout
{
Name = name
};
}
return loadout;
}
public bool IsInWardrobe(Loadout loadout)
{
if (wardrobe == null)
{
throw new InvalidOperationException("Wardrobe is not initialized.");
}
return wardrobe.Loadouts.Exists((Loadout other) => Loadout.Equals(other, loadout));
}
public int GetIndex(Loadout loadout)
{
if (wardrobe == null)
{
throw new InvalidOperationException("Wardrobe is not initialized.");
}
if (!IsInWardrobe(loadout))
{
return -1;
}
return wardrobe.Loadouts.FindIndex((Loadout other) => Loadout.Equals(other, loadout));
}
public Loadout GetLoadout(int index)
{
EnsureWardrobe();
if (index < 0 || index >= wardrobe.Loadouts.Count)
{
Plugin.Log.LogDebug((object)"Index is out of bounds. Returning default.");
return new Loadout
{
Name = string.Format("{0} #{1}", "New Template", wardrobe.Loadouts.Count)
};
}
return wardrobe.Loadouts[index];
}
}
internal class WardrobeMenu : MenuWindow
{
public GameObject uiObject;
private Canvas canvas;
private WardrobeManager wardrobe;
private CardManager cardManager;
private Loadout? currentLoadout;
private const int LoadoutCount = 5;
private GameObject rigObjectsRoot;
private List<OutfitThumbnailRig> rigs = new List<OutfitThumbnailRig>();
private List<LoadoutCard> uiCards = new List<LoadoutCard>();
private CarouselController controller;
public override bool openOnStart => false;
public override bool closeOnPause => true;
public WardrobeMenu()
{
wardrobe = WardrobeManager.Instance;
int num = wardrobe.Wardrobe.LastActiveIndex;
if (num < 0)
{
num = 0;
}
LoadLoadout(wardrobe.GetLoadout(num));
CreateRigs();
CreateUI();
SubscribeToEvents();
}
public void CreateUI()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Expected O, but got Unknown
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Expected O, but got Unknown
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0202: Expected O, but got Unknown
//IL_023e: Unknown result type (might be due to invalid IL or missing references)
//IL_026c: Unknown result type (might be due to invalid IL or missing references)
//IL_0295: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
uiObject = new GameObject("WardrobeMenu");
canvas = uiObject.AddComponent<Canvas>();
canvas.renderMode = (RenderMode)0;
uiObject.AddComponent<CanvasScaler>();
uiObject.AddComponent<GraphicRaycaster>();
Object.DontDestroyOnLoad((Object)(object)uiObject);
GameObject val = new GameObject("WardrobeBackground");
val.transform.SetParent(((Component)canvas).transform, false);
RectTransform val2 = val.AddComponent<RectTransform>();
val2.anchorMin = new Vector2(0.5f, 0.5f);
val2.anchorMax = new Vector2(0.5f, 0.5f);
val2.pivot = new Vector2(0.5f, 0.5f);
val2.anchoredPosition = Vector2.zero;
GameObject val3 = new GameObject("WardrobeBackgroundDim");
val3.transform.SetParent(val.transform, false);
Image val4 = val3.AddComponent<Image>();
((Graphic)val4).color = new Color(0f, 0f, 0f, 0.8f);
RectTransform component = ((Component)val4).GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = Vector2.zero;
component.offsetMax = Vector2.zero;
component.sizeDelta = new Vector2((float)Screen.width, (float)Screen.height);
GameObject val5 = new GameObject("WardrobeBackgroundImage");
val5.transform.SetParent(val.transform, false);
Image val6 = val5.AddComponent<Image>();
((Graphic)val6).color = ColorUtil.FromRGB(223, 218, 194);
RectTransform component2 = ((Component)val6).GetComponent<RectTransform>();
component2.sizeDelta = new Vector2(600f, 200f);
component2.anchoredPosition = Vector2.zero;
val3.transform.SetAsFirstSibling();
val5.transform.SetAsLastSibling();
GameObject val7 = CreateCarousel();
val7.transform.SetParent(val.transform, false);
GameObject val8 = new GameObject("WardrobeText");
val8.transform.SetParent(((Component)canvas).transform, false);
TextMeshProUGUI val9 = val8.AddComponent<TextMeshProUGUI>();
if ((Object)(object)Plugin.font != (Object)null)
{
((TMP_Text)val9).font = Plugin.font;
}
((Graphic)val9).color = Color.white;
((TMP_Text)val9).fontSize = 42f;
((TMP_Text)val9).alignment = (TextAlignmentOptions)514;
((TMP_Text)val9).text = $"In Wardrobe Menu - Press {Plugin.toggleMenuButton.Value} to exit";
RectTransform component3 = ((Component)val9).GetComponent<RectTransform>();
component3.sizeDelta = new Vector2(1000f, 100f);
component3.anchoredPosition = new Vector2(0f, 300f);
}
private void SaveLoadout(string loadoutName)
{
Plugin.Log.LogDebug((object)"Overriding saved loadout with current cosmetics.");
CharacterCustomizationData customizationData = CharacterCustomization.GetCustomizationData(PhotonNetwork.LocalPlayer);
if (customizationData == null)
{
Plugin.Log.LogError((object)"Unable to retreive current cosmetics data.");
return;
}
Loadout loadout = new Loadout
{
Name = loadoutName,
SkinIndex = customizationData.currentSkin,
AccessoryIndex = customizationData.currentAccessory,
EyesIndex = customizationData.currentEyes,
MouthIndex = customizationData.currentMouth,
HatIndex = customizationData.currentHat,
OutfitIndex = customizationData.currentOutfit,
SashIndex = customizationData.currentSash
};
wardrobe.SaveLoadout(loadout);
}
private void LoadLoadout(Loadout loadout)
{
if (currentLoadout != null)
{
currentLoadout.IsActive = false;
}
CharacterCustomization.SetCharacterSkinColor(loadout.SkinIndex);
CharacterCustomization.SetCharacterAccessory(loadout.AccessoryIndex);
CharacterCustomization.SetCharacterEyes(loadout.EyesIndex);
CharacterCustomization.SetCharacterMouth(loadout.MouthIndex);
CharacterCustomization.SetCharacterHat(loadout.HatIndex);
CharacterCustomization.SetCharacterOutfit(loadout.OutfitIndex);
CharacterCustomization.SetCharacterSash(loadout.SashIndex);
currentLoadout = loadout;
currentLoadout.IsActive = true;
}
private void LoadLoadout(string loadoutName)
{
Plugin.Log.LogDebug((object)"Overriding current cosmetics with saved loadout.");
Loadout loadout = wardrobe.GetLoadout(loadoutName);
if (loadout == null)
{
Plugin.Log.LogError((object)("Unable to find loadout with name " + loadoutName));
}
else
{
LoadLoadout(loadout);
}
}
private GameObject CreateCarousel()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Expected O, but got Unknown
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Expected O, but got Unknown
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Loadouts");
RectTransform val2 = val.AddComponent<RectTransform>();
val2.anchorMin = new Vector2(0.5f, 0.5f);
val2.anchorMax = new Vector2(0.5f, 0.5f);
val2.sizeDelta = new Vector2(1000f, 500f);
val2.anchoredPosition = new Vector2(0.5f, 0.5f);
cardManager = val.AddComponent<CardManager>();
GameObject val3 = new GameObject("Cards");
val3.transform.SetParent(((Component)val2).transform, false);
List<ICard> list = new List<ICard>();
for (int i = 0; i < rigs.Count; i++)
{
GameObject val4 = new GameObject("LoadoutCard");
val4.transform.SetParent(val3.transform, false);
LoadoutCard card = val4.AddComponent<LoadoutCard>();
card.SetPreviewRig(rigs[i]);
((UnityEvent)card.Button.onClick).AddListener((UnityAction)delegate
{
if (card.AssignedLoadout == null)
{
Plugin.Log.LogWarning((object)"Pressed on a card with no loadout. Do nothing.");
}
else
{
if (!wardrobe.IsInWardrobe(card.AssignedLoadout))
{
Plugin.Log.LogDebug((object)"Pressed on a card with new loadout. Forcefully adding new loadout.");
wardrobe.SaveLoadout(card.AssignedLoadout);
}
if (currentLoadout != null && Loadout.Equals(currentLoadout, card.AssignedLoadout.Name))
{
Plugin.Log.LogWarning((object)"Selected current loadout. Do nothing.");
}
else
{
SwitchLoadout(card.AssignedLoadout);
cardManager.UpdateCardVisibility();
}
}
});
list.Add(card);
uiCards.Add(card);
}
cardManager.Initialize(rigs, list);
controller = val.AddComponent<CarouselController>();
controller.Initialize(cardManager);
controller.CarouselSize = 5;
controller.ItemSpacing = LoadoutCard.CardActualSize.x + 20f;
cardManager.SubscribeToEvents(controller);
return val;
}
private void CreateRigs()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
Object.Destroy((Object)(object)rigObjectsRoot);
rigObjectsRoot = new GameObject("OutfitThumbnailRigs");
rigs = new List<OutfitThumbnailRig>();
for (int i = 0; i < 5; i++)
{
GameObject val = new GameObject("Rig");
val.transform.SetParent(rigObjectsRoot.transform, false);
rigs.Add(CreateThumbnailRig(val));
val.transform.localPosition = new Vector3(20f * (float)i, -999f, 0f);
}
}
private OutfitThumbnailRig CreateThumbnailRig(GameObject rigObj)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Expected O, but got Unknown
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("PortraitCamera");
val.transform.SetParent(rigObj.transform, false);
Camera val2 = val.AddComponent<Camera>();
val2.clearFlags = (CameraClearFlags)2;
val2.backgroundColor = new Color(0.3255f, 0.5922f, 0.8667f, 1f);
val2.orthographic = true;
val2.orthographicSize = 1.2f;
val2.nearClipPlane = 0.1f;
val2.farClipPlane = 10f;
((Behaviour)val2).enabled = true;
GameObject val3 = Object.Instantiate<GameObject>(((Component)PassportManager.instance.dummy).gameObject);
val3.transform.SetParent(rigObj.transform);
OutfitThumbnailRig result = new OutfitThumbnailRig(val2, val3);
GameObject val4 = new GameObject("SpotLight");
val4.transform.SetParent(rigObj.transform, false);
val4.transform.localPosition = new Vector3(0f, 2.5f, -2f);
val4.transform.LookAt(val3.transform.position);
Light val5 = val4.AddComponent<Light>();
val5.intensity = 2f;
val5.range = 10f;
val5.spotAngle = 45f;
return result;
}
public void SubscribeToEvents()
{
SceneManager.activeSceneChanged += OnSceneChanged;
}
private void OnSceneChanged(Scene oldScene, Scene newScene)
{
if (CanCreatePreview() && !((Object)(object)cardManager == (Object)null))
{
CreateRigs();
for (int i = 0; i < uiCards.Count && i < rigs.Count; i++)
{
uiCards[i].SetPreviewRig(rigs[i]);
}
cardManager.UpdateRigs(rigs);
controller.OverrideScrollPosition(0f);
}
}
public static bool CanCreatePreview()
{
PassportManager instance = PassportManager.instance;
object obj;
if (instance == null)
{
obj = null;
}
else
{
PlayerCustomizationDummy dummy = instance.dummy;
obj = ((dummy != null) ? ((Component)dummy).gameObject : null);
}
return (Object)obj != (Object)null;
}
public void SwitchLoadout(Loadout loadout)
{
wardrobe.Wardrobe.LastActiveIndex = wardrobe.GetIndex(loadout);
if (currentLoadout != null)
{
SaveLoadout(currentLoadout.Name);
}
LoadLoadout(loadout);
cardManager.UpdateCardVisibility();
}
public void Awake()
{
uiObject.SetActive(false);
}
public void ToggleOpen()
{
if (!((MenuWindow)this).isOpen)
{
((MenuWindow)this).Open();
uiObject.SetActive(true);
}
else
{
((MenuWindow)this).Close();
}
}
public override void OnClose()
{
uiObject.SetActive(false);
}
}
}
namespace PersonalWardrobe.Utils
{
internal static class ColorUtil
{
public static Color FromRGB(int red, int green, int blue)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
return FromRGB(red, green, blue, 1f);
}
public static Color FromRGB(int red, int green, int blue, float alpha)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
red = Math.Clamp(red, 0, 255);
green = Math.Clamp(green, 0, 255);
blue = Math.Clamp(blue, 0, 255);
return new Color((float)red / 255f, (float)green / 255f, (float)blue / 255f, alpha);
}
}
internal class FontUtil
{
public struct FontLoader
{
public int MAX_LOAD_FONT_RETRIES;
public float BACKOFF_DELAY_MILLISECONDS;
public FontLoader()
{
MAX_LOAD_FONT_RETRIES = 5;
BACKOFF_DELAY_MILLISECONDS = 0.05f;
}
public IEnumerator LoadFontCoroutine(string fontname, Action<TMP_FontAsset> callback)
{
int retries = MAX_LOAD_FONT_RETRIES;
TMP_FontAsset font = null;
while (retries > 0)
{
font = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset asset) => ((Object)asset).name == fontname));
if ((Object)(object)font != (Object)null)
{
Plugin.Log.LogDebug((object)("Found " + fontname + "! Proceeding..."));
break;
}
retries--;
Plugin.Log.LogDebug((object)$"Failed to load {fontname} font, retrying after {(float)(MAX_LOAD_FONT_RETRIES - retries) * BACKOFF_DELAY_MILLISECONDS}s...");
yield return (object)new WaitForSeconds((float)(MAX_LOAD_FONT_RETRIES - retries) * BACKOFF_DELAY_MILLISECONDS);
}
if ((Object)(object)font == (Object)null)
{
Plugin.Log.LogWarning((object)("Failed to load " + fontname + " font, fallback to built in font..."));
font = Resources.GetBuiltinResource<TMP_FontAsset>("LiberationSans SDF");
}
callback?.Invoke(font);
}
}
}
}
namespace PersonalWardrobe.Presentation
{
internal class CarouselController : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
{
public int CarouselSize = 5;
public float ItemSpacing = 150f;
private CardManager? manager;
private int leftIndex;
private float scrollPosition;
public float ScrollThreshold = 20f;
public float CenterScale = 1.2f;
public float EdgeScale = 0.7f;
public float CenterAlpha = 1f;
public float EdgeAlpha = 0.5f;
private bool isDragging;
private float velocity;
private const float drag = 0.5f;
public float MaxAlphaDistance => ItemSpacing * 1.2f;
public event Action<int, int> ItemsChanged;
public void Initialize(CardManager manager)
{
this.manager = manager;
}
public bool IsIntialized()
{
return (Object)(object)manager != (Object)null;
}
private void Move(float amount)
{
scrollPosition += amount;
}
public void Update()
{
UpdateControls();
UpdateScrollPosition();
if (IsIntialized())
{
UpdateItemIndex();
CenterOnClosestCard();
UpdateCardPositions();
}
}
private void UpdateControls()
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown((KeyCode)276))
{
Move(0f - ItemSpacing);
}
if (Input.GetKeyDown((KeyCode)275))
{
Move(ItemSpacing);
}
if (Mouse.current.leftButton.isPressed)
{
velocity = (0f - ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue().x) * ItemSpacing / ScrollThreshold;
}
}
private void UpdateItemIndex()
{
int num = Mathf.RoundToInt(scrollPosition / ItemSpacing);
if (num != leftIndex)
{
this.ItemsChanged?.Invoke(num - leftIndex, num);
leftIndex = num;
}
}
private void UpdateScrollPosition()
{
scrollPosition += velocity * Time.deltaTime;
velocity *= Mathf.Pow(isDragging ? 1f : 0.5f, Time.deltaTime);
}
private void CenterOnClosestCard()
{
}
private void UpdateCardPositions()
{
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
if (!IsIntialized())
{
return;
}
int num = manager.Cards.Count();
float num2 = (scrollPosition - (float)leftIndex * ItemSpacing) % ItemSpacing;
float num3 = (float)(CarouselSize - 1) * ItemSpacing * 0.5f;
for (int i = 0; i < num; i++)
{
int index = (leftIndex % num + i + num) % num;
float num4 = (float)i * ItemSpacing - num2 - num3;
float num5 = Mathf.Clamp01(Mathf.Abs(num4) / (ItemSpacing * (float)CarouselSize / 2f));
float num6 = Mathf.Lerp(CenterScale, EdgeScale, num5);
float alpha = 1f;
if (Mathf.Abs(num4) > MaxAlphaDistance)
{
float num7 = Mathf.InverseLerp(0.3f, 1f, num5);
alpha = Mathf.Lerp(CenterAlpha, EdgeAlpha, num7);
}
ICard card = manager.Cards[index];
card.SetPosition(new Vector3(num4, 0f, 0f));
card.SetScale(Vector3.one * num6);
card.SetAlpha(alpha);
}
}
public void OverrideScrollPosition(float newPosition)
{
scrollPosition = newPosition;
velocity = 0f;
leftIndex = 0;
this.ItemsChanged?.Invoke(0, 0);
}
public void OnBeginDrag(PointerEventData eventData)
{
isDragging = true;
}
public void OnDrag(PointerEventData eventData)
{
}
public void OnEndDrag(PointerEventData eventData)
{
isDragging = false;
}
}
internal class CircularBuffer<T>
{
private readonly T[] buffer;
private int head;
public T this[int index]
{
get
{
return buffer[(head + index) % buffer.Length];
}
set
{
buffer[(head + index) % buffer.Length] = value;
}
}
public int Count => buffer.Length;
public CircularBuffer(T[] buf)
{
buffer = buf;
head = 0;
}
public void RotateLeft(int amount = 1)
{
head = (head + amount) % buffer.Length;
}
public void RotateRight(int amount = 1)
{
if (amount > buffer.Length)
{
amount %= buffer.Length;
}
head = (head - amount + buffer.Length) % buffer.Length;
}
}
internal class OutfitThumbnailRig
{
private Camera camera;
private GameObject dummy;
private PlayerCustomizationDummy customizations;
private Animator dummyAnimator;
private const int MAX_IDLES = 8;
public RenderTexture Texture { get; private set; }
public event Action<Loadout>? OnLoadoutChange;
public OutfitThumbnailRig(Camera camera, GameObject dummy)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
this.camera = camera;
Texture = new RenderTexture(150, 250, 16);
camera.targetTexture = Texture;
this.dummy = dummy;
customizations = this.dummy.GetComponent<PlayerCustomizationDummy>();
dummyAnimator = this.dummy.GetComponentInChildren<Animator>();
((Component)this.camera).transform.localPosition = new Vector3(0f, 1.1f, -3f);
((Component)this.camera).transform.localRotation = Quaternion.identity;
this.dummy.transform.localPosition = Vector3.zero;
this.dummy.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
}
public void LookIntoNothing()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
((Component)camera).transform.localPosition = new Vector3(0f, -20f, -3f);
((Component)camera).transform.localRotation = Quaternion.identity;
}
public void LookAtDummy()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
((Component)camera).transform.localPosition = new Vector3(0f, 1.1f, -3f);
((Component)camera).transform.localRotation = Quaternion.identity;
}
public void ApplyLoadout(Loadout loadout)
{
if (!((Object)(object)customizations == (Object)null))
{
LookAtDummy();
customizations.SetPlayerColor(loadout.SkinIndex);
int playerHat = loadout.HatIndex;
if (Singleton<Customization>.Instance.fits[loadout.OutfitIndex].overrideHat)
{
playerHat = Singleton<Customization>.Instance.fits[loadout.OutfitIndex].overrideHatIndex;
}
customizations.SetPlayerHat(playerHat);
customizations.SetPlayerCostume(loadout.OutfitIndex);
SetAccessory(customizations.refs, loadout.AccessoryIndex);
SetEyes(customizations.refs, loadout.EyesIndex);
SetMouth(customizations.refs, loadout.MouthIndex);
SetSash(customizations.refs, loadout.SashIndex);
if (loadout.IdleIndex == -1)
{
loadout.IdleIndex = SetRandomIdle();
}
else
{
SetIdle(loadout.IdleIndex);
}
this.OnLoadoutChange?.Invoke(loadout);
}
}
public void Destroy()
{
Object.Destroy((Object)(object)dummy);
Object.Destroy((Object)(object)Texture);
}
private void SetEyes(CustomizationRefs refs, int index)
{
Texture texture = Singleton<Customization>.Instance.eyes[index].texture;
Renderer[] eyeRenderers = refs.EyeRenderers;
for (int i = 0; i < eyeRenderers.Length; i++)
{
eyeRenderers[i].material.SetTexture(CharacterCustomization.MainTex, texture);
}
}
private void SetMouth(CustomizationRefs refs, int index)
{
Texture texture = Singleton<Customization>.Instance.mouths[index].texture;
refs.mouthRenderer.material.SetTexture(CharacterCustomization.MainTex, texture);
}
private void SetAccessory(CustomizationRefs refs, int index)
{
CustomizationOption val = Singleton<Customization>.Instance.accessories[index];
Texture texture = val.texture;
refs.accessoryRenderer.material.SetTexture(CharacterCustomization.MainTex, texture);
refs.accessoryRenderer.material.renderQueue = (val.drawUnderEye ? 3007 : 3009);
refs.accessoryEnabled = !val.isThirdEye;
refs.thirdEye.gameObject.SetActive(val.isThirdEye);
}
private void SetSash(CustomizationRefs refs, int index)
{
List<Material> materials = new List<Material>
{
refs.sashRenderer.materials[0],
refs.sashAscentMaterials[index]
};
refs.sashRenderer.SetMaterials(materials);
}
private void SetIdle(int index)
{
dummyAnimator.SetFloat(CharacterCustomization.Idle, (float)index);
}
public int SetRandomIdle()
{
int num = Random.Range(0, 8);
SetIdle(num);
return num;
}
}
}
namespace PersonalWardrobe.Presentation.Cards
{
internal class CardManager : MonoBehaviour
{
private CircularBuffer<OutfitThumbnailRig> rigs;
private List<ICard> cards;
public CarouselController? controller;
private int savedPosition;
public IReadOnlyList<ICard> Cards => cards;
public void Initialize(List<OutfitThumbnailRig> rigs, List<ICard> cards)
{
this.rigs = new CircularBuffer<OutfitThumbnailRig>(rigs.ToArray());
this.cards = cards;
UpdateCardVisibility();
}
public void UpdateRigs(List<OutfitThumbnailRig> rigs)
{
this.rigs = new CircularBuffer<OutfitThumbnailRig>(rigs.ToArray());
}
public void SetSavedOffset(int newOffset)
{
savedPosition = newOffset;
}
public void SubscribeToEvents(CarouselController controller)
{
this.controller = controller;
controller.ItemsChanged += UpdateCardVisibility;
}
public void UpdateCardVisibility(int delta = 0, int position = int.MaxValue)
{
if (cards == null || rigs == null)
{
return;
}
if (delta < 0)
{
rigs.RotateRight(Mathf.Abs(delta));
}
else if (delta > 0)
{
rigs.RotateLeft(Mathf.Abs(delta));
}
if (position == int.MaxValue)
{
position = savedPosition;
}
int num = WardrobeManager.Instance.Wardrobe.Loadouts.Count + 1;
for (int i = 0; i < rigs.Count && i < cards.Count; i++)
{
int num2 = (position % num + i + num) % num;
Loadout loadout = WardrobeManager.Instance.GetLoadout(num2);
rigs[i].ApplyLoadout(loadout);
if (num2 >= WardrobeManager.Instance.Wardrobe.Loadouts.Count)
{
rigs[i].LookIntoNothing();
}
}
savedPosition = position;
}
}
internal interface ICard
{
void SetPosition(Vector3 position);
void SetRotation(Quaternion rotation);
void SetScale(Vector3 scale);
void SetAlpha(float alpha);
}
internal class LoadoutCard : MonoBehaviour, ICard
{
public static readonly Vector2 PreviewSize = new Vector2(150f, 250f);
public const float BorderSize = 10f;
public bool IsActive;
private GameObject BackgroundObject;
private GameObject PreviewObject;
private GameObject LabelObject;
private RawImage previewImage;
private OutfitThumbnailRig? currentRig;
private Loadout? _loadout;
public static Vector2 CardActualSize => PreviewSize + 2f * new Vector2(10f, 10f);
public CanvasGroup CanvasGroup { get; private set; }
public Button Button { get; private set; }
public Loadout? AssignedLoadout
{
get
{
return _loadout;
}
set
{
_loadout = value;
TextMeshProUGUI component = LabelObject.GetComponent<TextMeshProUGUI>();
((TMP_Text)component).text = _loadout?.Name ?? "";
SetActive(_loadout?.IsActive ?? false);
UpdateBackgroundColor();
}
}
public void Awake()
{
CanvasGroup = ((Component)this).gameObject.AddComponent<CanvasGroup>();
Button = ((Component)this).gameObject.AddComponent<Button>();
CreateLabel();
CreateBackground();
CreatePreview();
}
private void CreateBackground()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)BackgroundObject != (Object)null))
{
BackgroundObject = new GameObject("Background", new Type[1] { typeof(Image) });
BackgroundObject.transform.SetParent(((Component)this).transform, false);
Image component = BackgroundObject.GetComponent<Image>();
((Graphic)component).color = Color.white;
((Graphic)component).rectTransform.sizeDelta = CardActualSize;
BackgroundObject.transform.SetAsFirstSibling();
}
}
private void CreatePreview()
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)PreviewObject != (Object)null))
{
PreviewObject = new GameObject("Preview", new Type[2]
{
typeof(RawImage),
typeof(RectTransform)
});
PreviewObject.transform.SetParent(((Component)this).transform, false);
RectTransform component = PreviewObject.GetComponent<RectTransform>();
component.anchorMin = new Vector2(0.5f, 0.5f);
component.anchorMax = new Vector2(0.5f, 0.5f);
component.pivot = new Vector2(0.5f, 0.5f);
component.sizeDelta = PreviewSize;
component.anchoredPosition = Vector2.zero;
previewImage = PreviewObject.GetComponent<RawImage>();
((Graphic)previewImage).raycastTarget = false;
((Component)this).gameObject.AddComponent<Button>();
}
}
private void CreateLabel()
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)LabelObject != (Object)null))
{
LabelObject = new GameObject("Label", new Type[2]
{
typeof(RectTransform),
typeof(TextMeshProUGUI)
});
LabelObject.transform.SetParent(((Component)this).transform, false);
TextMeshProUGUI component = LabelObject.GetComponent<TextMeshProUGUI>();
((TMP_Text)component).overflowMode = (TextOverflowModes)0;
((TMP_Text)component).textWrappingMode = (TextWrappingModes)1;
if ((Object)(object)Plugin.font != (Object)null)
{
((TMP_Text)component).font = Plugin.font;
}
((Graphic)component).color = Color.white;
((TMP_Text)component).fontWeight = (FontWeight)700;
((TMP_Text)component).fontSize = 28f;
((TMP_Text)component).alignment = (TextAlignmentOptions)514;
RectTransform component2 = ((Component)component).GetComponent<RectTransform>();
component2.anchorMin = new Vector2(0.5f, 0.5f);
component2.anchorMax = new Vector2(0.5f, 0.5f);
component2.pivot = new Vector2(0.5f, 0.5f);
component2.anchoredPosition = Vector2.zero;
((Transform)component2).localPosition = -1f * new Vector3(0f, 0.5f * (CardActualSize.y + 50f), 0f);
}
}
public void SetPreviewRig(OutfitThumbnailRig rig)
{
if ((Object)(object)previewImage == (Object)null)
{
Plugin.Log.LogWarning((object)"Setting preview rig before preview image is created. Create preview first.");
return;
}
if (currentRig != null)
{
currentRig.OnLoadoutChange -= RigLoadoutChanged;
}
currentRig = rig;
previewImage.texture = (Texture)(object)rig.Texture;
currentRig.OnLoadoutChange += RigLoadoutChanged;
}
public void RigLoadoutChanged(Loadout loadout)
{
AssignedLoadout = loadout;
}
public void UpdateBackgroundColor()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
Image component = BackgroundObject.GetComponent<Image>();
((Graphic)component).color = (IsActive ? ColorUtil.FromRGB(120, 255, 160) : Color.white);
}
public void SetActive(bool active)
{
IsActive = active;
}
public void SetPosition(Vector3 position)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
((Component)this).gameObject.transform.localPosition = position;
}
public void SetRotation(Quaternion rotation)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
((Component)this).gameObject.transform.localRotation = rotation;
}
public void SetScale(Vector3 scale)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
((Component)this).gameObject.transform.localScale = scale;
}
public void SetAlpha(float alpha)
{
CanvasGroup.alpha = alpha;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}