using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using LazyBearTechnology;
using Microsoft.CodeAnalysis;
using Timbn.GraveyardKeeperTwo.Core.Framework;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Timbn.GraveyardKeeperTwo.ZombieCustomizer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+42577719540a953590d1b1b778a9af1bc1cbf13e")]
[assembly: AssemblyProduct("Timbn Zombie Customizer")]
[assembly: AssemblyTitle("Timbn.GraveyardKeeperTwo.ZombieCustomizer")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
int ICollection.Count => _items.Count;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
object IList.this[int index]
{
get
{
return _items[index];
}
set
{
throw new NotSupportedException();
}
}
bool IList.IsFixedSize => true;
bool IList.IsReadOnly => true;
int IReadOnlyCollection<T>.Count => _items.Count;
T IReadOnlyList<T>.this[int index] => _items[index];
int ICollection<T>.Count => _items.Count;
bool ICollection<T>.IsReadOnly => true;
T IList<T>.this[int index]
{
get
{
return _items[index];
}
set
{
throw new NotSupportedException();
}
}
public <>z__ReadOnlyList(List<T> items)
{
_items = items;
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_items).GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
((ICollection)_items).CopyTo(array, index);
}
int IList.Add(object value)
{
throw new NotSupportedException();
}
void IList.Clear()
{
throw new NotSupportedException();
}
bool IList.Contains(object value)
{
return ((IList)_items).Contains(value);
}
int IList.IndexOf(object value)
{
return ((IList)_items).IndexOf(value);
}
void IList.Insert(int index, object value)
{
throw new NotSupportedException();
}
void IList.Remove(object value)
{
throw new NotSupportedException();
}
void IList.RemoveAt(int index)
{
throw new NotSupportedException();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return ((IEnumerable<T>)_items).GetEnumerator();
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
throw new NotSupportedException();
}
bool ICollection<T>.Contains(T item)
{
return _items.Contains(item);
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
_items.CopyTo(array, arrayIndex);
}
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
int IList<T>.IndexOf(T item)
{
return _items.IndexOf(item);
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
}
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 Timbn.GraveyardKeeperTwo.ZombieCustomizer
{
[BepInPlugin("Timbn.GraveyardKeeperTwo.ZombieCustomizer", "Timbn Zombie Customizer", "1.0.0")]
[BepInDependency("Timbn.GraveyardKeeperTwo.Core", "1.3.0")]
public class Plugin : TimbnFrameworkPlugin<Plugin>
{
protected override void BindConfig(ConfigFile config)
{
PluginConfig.Bind(config);
}
protected override void OnAwake()
{
((TimbnFrameworkPlugin)this).Text.Add("timbn_zombie_restyle", "Customize Appearance");
ZombieTint.PaintAll(reset: false);
TimbnFrameworkPlugin<Plugin>.Logger.LogMessage((object)"Zombie Customizer started. Click a zombie's portrait in its inspect window to restyle it.");
}
protected override void OnDestroyed()
{
ZombieCustomization.Stop();
RestyleButton.Remove();
ZombieTint.PaintAll(reset: true);
}
}
internal static class PluginConfig
{
private const string _section = "Clothes Colors";
private static readonly Color[] _defaults = (Color[])(object)new Color[10]
{
new Color(1f, 0.55f, 0.55f),
new Color(1f, 0.75f, 0.45f),
new Color(1f, 1f, 0.55f),
new Color(0.6f, 1f, 0.6f),
new Color(0.55f, 1f, 1f),
new Color(0.6f, 0.7f, 1f),
new Color(0.8f, 0.6f, 1f),
new Color(1f, 0.65f, 0.85f),
new Color(0.7f, 0.7f, 0.7f),
new Color(0.45f, 0.45f, 0.5f)
};
public static IReadOnlyList<ConfigEntry<Color>> ClothesColors { get; private set; } = Array.Empty<ConfigEntry<Color>>();
public static void Bind(ConfigFile config)
{
List<ConfigEntry<Color>> list = new List<ConfigEntry<Color>>();
list.AddRange(_defaults.Select((Color color, int i) => config.Bind<Color>("Clothes Colors", $"ClothesColor{i + 1}", color, "One of the colors offered in the Clothes Color row when you customize a zombie. It tints the zombie's clothes, so white leaves them as they are and darker colors show more. Changing it does not recolor zombies you already styled.")));
ClothesColors = new <>z__ReadOnlyList<ConfigEntry<Color>>(list);
}
}
internal static class RestyleButton
{
[CompilerGenerated]
private static class <>O
{
public static UnityAction <0>__OnClick;
}
public const string TooltipKey = "timbn_zombie_restyle";
private const string _name = "TimbnRestyleButton";
private static readonly FieldRef<UIZombieWorkerWindow, UIWorkerIcon> _workerIcon = AccessTools.FieldRefAccess<UIZombieWorkerWindow, UIWorkerIcon>("workerIcon");
private static UIZombieWorkerWindowData? _data;
public static void Attach(UIZombieWorkerWindow window, UIZombieWorkerWindowData data)
{
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: 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_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: 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_0117: Expected O, but got Unknown
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Expected O, but got Unknown
_data = data;
UIWorkerIcon val = _workerIcon.Invoke(window);
if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform.Find("TimbnRestyleButton") != (Object)null))
{
GameObject val2 = new GameObject("TimbnRestyleButton", new Type[3]
{
typeof(RectTransform),
typeof(Image),
typeof(Button)
});
RectTransform val3 = (RectTransform)val2.transform;
((Transform)val3).SetParent(((Component)val).transform, false);
val3.anchorMin = Vector2.zero;
val3.anchorMax = Vector2.one;
val3.offsetMin = Vector2.zero;
val3.offsetMax = Vector2.zero;
((Transform)val3).SetAsLastSibling();
Image component = val2.GetComponent<Image>();
((Graphic)component).color = Color.clear;
((Graphic)component).raycastTarget = true;
ButtonClickedEvent onClick = val2.GetComponent<Button>().onClick;
object obj = <>O.<0>__OnClick;
if (obj == null)
{
UnityAction val4 = OnClick;
<>O.<0>__OnClick = val4;
obj = (object)val4;
}
((UnityEvent)onClick).AddListener((UnityAction)obj);
UIMouseTooltip.Attach(val2, "timbn_zombie_restyle", (RectTransform)null, false, false, default(UIMouseTooltipEdges), default(Vector2), (string)null);
}
}
public static void Remove()
{
_data = null;
UIZombieWorkerWindow window = LazyUI.GetWindow<UIZombieWorkerWindow>();
UIWorkerIcon val = (((Object)(object)window == (Object)null) ? null : _workerIcon.Invoke(window));
Transform val2 = (((Object)(object)val == (Object)null) ? null : ((Component)val).transform.Find("TimbnRestyleButton"));
if ((Object)(object)val2 != (Object)null)
{
Object.Destroy((Object)(object)((Component)val2).gameObject);
}
}
private static void OnClick()
{
UIZombieWorkerWindowData data = _data;
if (((data != null) ? data.ZombieWgoData : null) != null)
{
((LazyWindow<UIZombieWorkerWindowData>)(object)LazyUI.GetWindow<UIZombieWorkerWindow>()).Close();
ZombieCustomization.Open(data.ZombieWgoData, data);
}
}
}
internal static class ZombieCustomization
{
private sealed class Session(ZombieWgoData zombie, ZombieSkinPool pool)
{
public ZombieWgoData Zombie { get; } = zombie;
public ZombieSkinPool Pool { get; } = pool;
public int Body { get; set; } = ((WgoData)zombie).GetGameResInt("zombie_body_id");
public int Head { get; set; } = ((WgoData)zombie).GetGameResInt("zombie_head_id");
public string BodyColor { get; set; } = ((WgoData)zombie).GameResStr.Get("zombie_body_lut", "") ?? string.Empty;
public string HeadColor { get; set; } = ((WgoData)zombie).GameResStr.Get("zombie_head_lut", "") ?? string.Empty;
public Color Tint { get; set; } = ZombieTint.Read((WgoData)(object)zombie);
public List<Color> Palette { get; } = ZombieTint.Palette(ZombieTint.Read((WgoData)(object)zombie));
public UIZombieWorkerWindowData? ReturnTo { get; set; }
}
private static readonly FieldRef<UICustomizationWindow, UICharacterOptionSwitcher> _hairSwitcher = Switcher("hairSwitcher");
private static readonly FieldRef<UICustomizationWindow, UICharacterOptionSwitcher> _beardSwitcher = Switcher("beardSwitcher");
private static readonly FieldRef<UICustomizationWindow, UICharacterOptionSwitcher> _bodySwitcher = Switcher("bodySwitcher");
private static readonly FieldRef<UICustomizationWindow, UICharacterOptionSwitcher> _headColorSwitcher = Switcher("hedColorSwitch");
private static readonly FieldRef<UICustomizationWindow, UICharacterOptionSwitcher> _bodyColorSwitcher = Switcher("bdy1ColorSwitch");
private static readonly FieldRef<UICustomizationWindow, UICharacterOptionSwitcher> _secondBodyColorSwitcher = Switcher("bdy2ColorSwitch");
private static readonly FieldRef<UICustomizationWindow, UICharacterOptionSwitcher> _thirdBodyColorSwitcher = Switcher("bdy3ColorSwitch");
private static readonly FieldRef<UICustomizationWindow, Sprite> _unavailableSprite = AccessTools.FieldRefAccess<UICustomizationWindow, Sprite>("nonInteractableSwitcherImage");
private static readonly MethodInfo _setupZombieSkin = AccessTools.Method(typeof(WgoPart), "SetupZombieSkin", (Type[])null, (Type[])null);
private static readonly MethodInfo _updateDropView = AccessTools.Method(typeof(DropView), "UpdateView", (Type[])null, (Type[])null);
private const string _headRenderer = "hed";
private static readonly List<(Material Material, Shader Shader)> _swappedShaders = new List<(Material, Shader)>();
private static readonly List<(SpriteRenderer Renderer, Color Color)> _previewColors = new List<(SpriteRenderer, Color)>();
private static readonly Dictionary<int, Texture2D> _swatches = new Dictionary<int, Texture2D>();
private static Session? _session;
private static bool _loggedShaders;
public static void Open(ZombieWgoData zombie, UIZombieWorkerWindowData returnTo)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
ZombieSkinPool worker = ZombieSkinPool.Worker;
if (worker == null || worker.Bodies.Count == 0 || worker.Heads.Count == 0)
{
TimbnFrameworkPlugin<Plugin>.Logger.LogWarning((object)"No zombie skin pool found, nothing to choose from.");
return;
}
_session = new Session(zombie, worker)
{
ReturnTo = returnTo
};
UICustomizationWindowData val = new UICustomizationWindowData
{
CurrentData = PlayerCustomizationData.Copy(MainGame.PlayerData.customization)
};
((LazyWindow<UICustomizationWindowData>)(object)LazyUI.GetWindow<UICustomizationWindow>()).Open(val);
}
public static void OnWindowOpened(UICustomizationWindow window)
{
Session session = _session;
if (session != null)
{
ZombieSkinPool pool = session.Pool;
Bind(window, _hairSwitcher.Invoke(window), pool.Heads, session.Head, delegate(int value)
{
session.Head = value;
});
Bind(window, _bodySwitcher.Invoke(window), pool.Bodies, session.Body, delegate(int value)
{
session.Body = value;
});
Bind(window, _headColorSwitcher.Invoke(window), pool.HeadColors, session.HeadColor, delegate(string value)
{
session.HeadColor = value;
});
BindTint(_bodyColorSwitcher.Invoke(window), session);
Disable(window, _beardSwitcher.Invoke(window));
Disable(window, _secondBodyColorSwitcher.Invoke(window));
Disable(window, _thirdBodyColorSwitcher.Invoke(window));
UseColorSwapShader(session.Zombie);
ShowPreview(session);
}
}
public static bool TryApply(UICustomizationWindow window)
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
Session session = _session;
if (session == null)
{
return false;
}
ZombieWgoData zombie = session.Zombie;
ZombieSkinHelper.ApplySkinToZombieWgoData((WgoData)(object)zombie, session.Body, session.Head, session.BodyColor, session.HeadColor);
ZombieTint.Save((WgoData)(object)zombie, session.Tint);
Redraw(zombie);
Wgo wgoViewGlobal = GameScene.GetWgoViewGlobal(((WgoData)zombie).UniqueId);
if ((Object)(object)wgoViewGlobal != (Object)null)
{
ZombieTint.Paint((Component)(object)wgoViewGlobal, session.Tint);
}
TimbnFrameworkPlugin<Plugin>.Logger.LogMessage((object)($"Restyled {LLBase.L(zombie.Name)} to body {session.Body}, head {session.Head}, " + "colors " + Describe(session.BodyColor) + " and " + Describe(session.HeadColor) + ", clothes tint " + ZombieTint.Describe(session.Tint) + "."));
((LazyWindow<UICustomizationWindowData>)(object)window).Close();
return true;
}
public static void OnWindowClosed()
{
UIZombieWorkerWindowData val = _session?.ReturnTo;
RestorePreview();
_session = null;
if (val != null)
{
((LazyWindow<UIZombieWorkerWindowData>)(object)LazyUI.GetWindow<UIZombieWorkerWindow>()).Open(val);
}
}
public static void Stop()
{
if (_session != null)
{
_session.ReturnTo = null;
UICustomizationWindow window = LazyUI.GetWindow<UICustomizationWindow>();
if ((Object)(object)window != (Object)null && ((LazyWindow<UICustomizationWindowData>)(object)window).IsShown)
{
((LazyWindow<UICustomizationWindowData>)(object)window).Close();
}
_session = null;
}
}
private static void Bind<TValue>(UICustomizationWindow window, UICharacterOptionSwitcher switcher, List<TValue> values, TValue current, Action<TValue> choose)
{
if (values.Count <= 1)
{
Disable(window, switcher);
return;
}
int num = Math.Max(0, values.IndexOf(current));
choose(values[num]);
string[] array = (from i in Enumerable.Range(1, values.Count)
select $"{i}/{values.Count}").ToArray();
switcher.IsInteractable = true;
switcher.Initialize((Action<int>)delegate(int i)
{
choose(values[i]);
if (_session != null)
{
ShowPreview(_session);
}
}, array, num, false);
switcher.SetColorImage((Texture2D)null);
}
private static void BindTint(UICharacterOptionSwitcher switcher, Session session)
{
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
List<Color> palette = session.Palette;
string[] array = (from i in Enumerable.Range(1, palette.Count)
select $"{i}/{palette.Count}").ToArray();
int num = Math.Max(0, palette.FindIndex((Color color) => ZombieTint.Same(color, session.Tint)));
switcher.IsInteractable = true;
switcher.Initialize((Action<int>)delegate(int i)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
session.Tint = palette[i];
switcher.SetColorImage(Swatch(i, palette[i]));
ShowPreview(session);
}, array, num, false);
switcher.SetColorImage(Swatch(num, palette[num]));
}
private static Texture2D Swatch(int index, Color color)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
if (_swatches.TryGetValue(index, out Texture2D value))
{
return value;
}
value = new Texture2D(1, 1);
value.SetPixel(0, 0, color);
value.Apply();
_swatches[index] = value;
return value;
}
private static void Disable(UICustomizationWindow window, UICharacterOptionSwitcher switcher)
{
switcher.IsInteractable = false;
switcher.SetSprite(_unavailableSprite.Invoke(window));
}
private static void ShowPreview(Session session)
{
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
SkinPresetGK2 presetForCustomizationData = ZombieSkinHelper.GetPresetForCustomizationData("zombie_worker", session.Body, session.Head, session.BodyColor, session.HeadColor);
PlayerAnimation customizationCharacter = MainGame.PlayerController.View.CustomizationCharacter;
((AnimationComponent)customizationCharacter).ChangeSkinPreset(presetForCustomizationData);
if (_previewColors.Count == 0)
{
SpriteRenderer[] componentsInChildren = ((Component)customizationCharacter).GetComponentsInChildren<SpriteRenderer>(true);
foreach (SpriteRenderer val in componentsInChildren)
{
if (ZombieTint.IsBodyPart(((Object)val).name))
{
_previewColors.Add((val, val.color));
}
}
}
ZombieTint.Paint((Component)(object)customizationCharacter, session.Tint);
}
private static void UseColorSwapShader(ZombieWgoData zombie)
{
LogColorSwapShaders();
Shader val = FindColorSwapShader(zombie);
if ((Object)(object)val == (Object)null)
{
TimbnFrameworkPlugin<Plugin>.Logger.LogWarning((object)"Found no zombie head shader to borrow, so the preview shows hair in its raw magenta.");
return;
}
SpriteRenderer[] componentsInChildren = ((Component)MainGame.PlayerController.View.CustomizationCharacter).GetComponentsInChildren<SpriteRenderer>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Material material = ((Renderer)componentsInChildren[i]).material;
if (!((Object)(object)material.shader == (Object)(object)val))
{
_swappedShaders.Add((material, material.shader));
material.shader = val;
}
}
TimbnFrameworkPlugin<Plugin>.Logger.LogMessage((object)$"Preview borrowed the {((Object)val).name} shader for {_swappedShaders.Count} sprites.");
}
private static void RestorePreview()
{
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
foreach (var (val, shader) in _swappedShaders)
{
if ((Object)(object)val != (Object)null)
{
val.shader = shader;
}
}
foreach (var (val2, color) in _previewColors)
{
if ((Object)(object)val2 != (Object)null)
{
val2.color = color;
}
}
foreach (Texture2D value in _swatches.Values)
{
Object.Destroy((Object)(object)value);
}
_swappedShaders.Clear();
_previewColors.Clear();
_swatches.Clear();
}
private static Shader? FindColorSwapShader(ZombieWgoData zombie)
{
Wgo wgoViewGlobal = GameScene.GetWgoViewGlobal(((WgoData)zombie).UniqueId);
return (((Object)(object)wgoViewGlobal == (Object)null) ? null : HeadShader(((Component)wgoViewGlobal).GetComponentsInChildren<SpriteRenderer>(true))) ?? HeadShader(Resources.FindObjectsOfTypeAll<SpriteRenderer>());
}
private static Shader? HeadShader(IEnumerable<SpriteRenderer> renderers)
{
return (from r in renderers
where ((Object)r).name == "hed" && (Object)(object)((Renderer)r).sharedMaterial != (Object)null && ((Renderer)r).sharedMaterial.HasProperty(SkinChangerGK2.shaderPaletteLutId)
select ((Renderer)r).sharedMaterial.shader).FirstOrDefault();
}
private static void LogColorSwapShaders()
{
if (!_loggedShaders)
{
_loggedShaders = true;
IEnumerable<string> values = (from s in Resources.FindObjectsOfTypeAll<Shader>()
where s.FindPropertyIndex("_ReplaceLUT") >= 0
select ((Object)s).name).Distinct();
TimbnFrameworkPlugin<Plugin>.Logger.LogMessage((object)("Loaded shaders with a color swap LUT: " + string.Join(", ", values) + "."));
}
}
private static void Redraw(ZombieWgoData zombie)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Invalid comparison between Unknown and I4
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
Wgo wgoViewGlobal = GameScene.GetWgoViewGlobal(((WgoData)zombie).UniqueId);
if ((Object)(object)wgoViewGlobal == (Object)null)
{
GameScene val = default(GameScene);
DropView obj = default(DropView);
if (MainGame.PlayerController.TryGetCurrentGameScene(ref val) && val.TryGetDropView(zombie.ZombieItem, ref obj))
{
_updateDropView.Invoke(obj, Array.Empty<object>());
}
}
else if ((int)zombie.ZombieType == 8)
{
wgoViewGlobal.OnZombieItemsChanged(new Inventory(zombie.ZombieItem));
}
else if (!((Object)(object)wgoViewGlobal.MainWgoPart == (Object)null))
{
WGODef definition = ((ObjectLinkedToDefinition<WGODef>)(object)zombie).Definition;
string text = ((definition == null) ? string.Empty : (definition.hasCustomVisualId ? definition.customVisualId : ((BalanceBaseObject)definition).id));
_setupZombieSkin.Invoke(wgoViewGlobal.MainWgoPart, new object[2] { zombie, text });
}
}
private static string Describe(string color)
{
if (!string.IsNullOrEmpty(color))
{
return color;
}
return "none";
}
private static FieldRef<UICustomizationWindow, UICharacterOptionSwitcher> Switcher(string field)
{
return AccessTools.FieldRefAccess<UICustomizationWindow, UICharacterOptionSwitcher>(field);
}
}
internal sealed class ZombieSkinPool
{
private static ZombieSkinPool? _worker;
public List<int> Bodies { get; } = bodies?.Distinct().ToList() ?? new List<int>();
public List<int> Heads { get; } = heads?.Distinct().ToList() ?? new List<int>();
public List<string> BodyColors { get; } = bodyColors?.Select((Texture2D t) => ((Object)t).name).ToList() ?? new List<string>();
public List<string> HeadColors { get; } = headColors?.Select((Texture2D t) => ((Object)t).name).ToList() ?? new List<string>();
public static ZombieSkinPool? Worker => _worker ?? (_worker = Read("zombie_worker"));
public ZombieSkinPool(List<int>? bodies, List<int>? heads, List<Texture2D>? bodyColors, List<Texture2D>? headColors)
{
}
private static ZombieSkinPool? Read(string dataId)
{
IList value = Traverse.Create((object)LazySingletonSO<ZombieCustomizationConfig>.Instance).Field("zombieRolledDatas").GetValue<IList>();
if (value == null)
{
return null;
}
foreach (object item in value)
{
Traverse val = Traverse.Create(item);
if (!(val.Field("id").GetValue<string>() != dataId))
{
return new ZombieSkinPool(val.Field("bodyIds").GetValue<List<int>>(), val.Field("headIds").GetValue<List<int>>(), val.Field("bodyTextures").GetValue<List<Texture2D>>(), val.Field("headTextures").GetValue<List<Texture2D>>());
}
}
return null;
}
}
internal static class ZombieTint
{
private const string _key = "timbn_zombie_tint";
private static readonly string[] _bodyParts = new string[3] { "bdy", "arm", "leg" };
public static Color Read(WgoData zombie)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
string text = zombie.GameResStr.Get("timbn_zombie_tint", "");
if (string.IsNullOrEmpty(text))
{
return Color.white;
}
Color color = default(Color);
if (!ColorUtility.TryParseHtmlString("#" + text, ref color))
{
return Color.white;
}
return Opaque(color);
}
public static void Save(WgoData zombie, Color color)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
zombie.GameResStr.Set("timbn_zombie_tint", IsPlain(color) ? string.Empty : ColorUtility.ToHtmlStringRGB(color));
}
public static List<Color> Palette(Color current)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
List<Color> list = new List<Color>(1) { Color.white };
list.AddRange(PluginConfig.ClothesColors.Select((ConfigEntry<Color> entry) => Opaque(entry.Value)));
if (!list.Any((Color color) => Same(color, current)))
{
list.Insert(1, Opaque(current));
}
return list;
}
public static bool Same(Color first, Color second)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return ColorUtility.ToHtmlStringRGB(first) == ColorUtility.ToHtmlStringRGB(second);
}
public static string Describe(Color color)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (!IsPlain(color))
{
return "#" + ColorUtility.ToHtmlStringRGB(color);
}
return "none";
}
public static void Paint(Component root, Color color)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
SpriteRenderer[] componentsInChildren = root.GetComponentsInChildren<SpriteRenderer>(true);
foreach (SpriteRenderer val in componentsInChildren)
{
if (IsBodyPart(((Object)val).name))
{
val.color = color;
}
}
}
public static void PaintAll(bool reset)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
if (!TimbnGame.IsInGame)
{
return;
}
ZombieSystemData zombieSystemData = MainGame.ZombieSystemData;
foreach (SGuid zombieOnSceneWgoId in zombieSystemData.zombieOnSceneWgoIds)
{
ZombieWgoData zombie = zombieSystemData.GetZombie(zombieOnSceneWgoId);
Wgo val = ((zombie == null) ? null : GameScene.GetWgoViewGlobal(((WgoData)zombie).UniqueId));
if ((Object)(object)val != (Object)null)
{
Paint((Component)(object)val, reset ? Color.white : Read((WgoData)(object)zombie));
}
}
}
public static bool IsBodyPart(string name)
{
return _bodyParts.Any(name.StartsWith);
}
private static bool IsPlain(Color color)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
return Same(color, Color.white);
}
private static Color Opaque(Color color)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
return new Color(color.r, color.g, color.b, 1f);
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "Timbn.GraveyardKeeperTwo.ZombieCustomizer";
public const string PLUGIN_NAME = "Timbn Zombie Customizer";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace Timbn.GraveyardKeeperTwo.ZombieCustomizer.Patches
{
[HarmonyPatch(typeof(UICustomizationWindow))]
internal static class UICustomizationWindowPatch
{
[HarmonyPatch("Open")]
[HarmonyPostfix]
private static void OpenPostFix(UICustomizationWindow __instance)
{
ZombieCustomization.OnWindowOpened(__instance);
}
[HarmonyPatch("OnApplyPressed")]
[HarmonyPrefix]
private static bool OnApplyPressedPreFix(UICustomizationWindow __instance)
{
return !ZombieCustomization.TryApply(__instance);
}
[HarmonyPatch("Close")]
[HarmonyPostfix]
private static void ClosePostFix()
{
ZombieCustomization.OnWindowClosed();
}
}
[HarmonyPatch(typeof(UIZombieWorkerWindow))]
internal static class UIZombieWorkerWindowPatch
{
[HarmonyPatch("Open")]
[HarmonyPostfix]
private static void OpenPostFix(UIZombieWorkerWindow __instance, UIZombieWorkerWindowData data)
{
RestyleButton.Attach(__instance, data);
}
}
[HarmonyPatch(typeof(WgoPart))]
internal static class WgoPartPatch
{
[HarmonyPatch("SetupZombieSkin")]
[HarmonyPostfix]
private static void SetupZombieSkinPostFix(WgoPart __instance, ZombieWgoData zombieWgoData)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
ZombieTint.Paint((Component)(object)__instance, ZombieTint.Read((WgoData)(object)zombieWgoData));
}
}
}