using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using SideLoader;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace CraftableRunicBlades;
[BepInPlugin("com.merofos.outward.craftablerunicblades", "Craftable Runic Blades", "0.1.4")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class CraftableRunicBladesPlugin : BaseUnityPlugin
{
private sealed class RunicWeaponDefinition
{
public readonly int ItemId;
public readonly string Marker;
public readonly string DisplayName;
public readonly string IconRelativePath;
public readonly string IconId;
public readonly string[] VisualNameTokens;
public RunicWeaponDefinition(int itemId, string marker, string displayName, string iconRelativePath, string iconId, params string[] visualNameTokens)
{
ItemId = itemId;
Marker = marker;
DisplayName = displayName;
IconRelativePath = iconRelativePath;
IconId = iconId;
VisualNameTokens = visualNameTokens;
}
}
private const string PluginGuid = "com.merofos.outward.craftablerunicblades";
private const string SideLoaderGuid = "com.sinai.SideLoader";
private const string PluginName = "Craftable Runic Blades";
private const string PluginVersion = "0.1.4";
private const int VanillaRunicBladeItemId = 2000100;
private const string CapturedRunicBladeMaterialName = "mat_itm_crystalBladeRunicBladeLight";
private const string CapturedRunicBladeMainTextureName = "tex_fx_PerlinNoiseGray";
private const string CapturedRunicBladeWaveTextureName = "tex_env_waterWave_n";
private static readonly float[] VisualRetryDelays = new float[8] { 0f, 0.1f, 0.25f, 0.5f, 1f, 2f, 4f, 8f };
private static readonly HashSet<string> s_missingTextureWarnings = new HashSet<string>();
private static readonly FieldInfo ItemIconField = typeof(Item).GetField("m_itemIcon", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly FieldInfo ItemIconPathField = typeof(Item).GetField("m_itemIconPath", BindingFlags.Instance | BindingFlags.NonPublic);
private static Texture s_capturedMainTexture;
private static Texture s_capturedWaveTexture;
private static readonly RunicWeaponDefinition[] WeaponDefinitions = new RunicWeaponDefinition[2]
{
new RunicWeaponDefinition(-2525300, "RunicBlade", "Runic Blade", "SideLoader/Items/-2525300-Runic_Blade/runic_blade_item_icon.png", "MEROFOS_CraftableRunicBladeIcon", "2000090", "oldlegiongladius", "old legion gladius", "runicblade", "runic blade", "-2525300", "2525300"),
new RunicWeaponDefinition(-2525310, "GreatRunicBlade", "Great Runic Blade", "SideLoader/Items/-2525310-Great_Runic_Blade/great_runic_blade_item_icon.png", "MEROFOS_CraftableGreatRunicBladeIcon", "2100130", "pathfinderclaymore", "pathfinder claymore", "greatrunicblade", "great runic blade", "-2525310", "2525310")
};
private readonly Dictionary<string, Material> _materialCache = new Dictionary<string, Material>();
private readonly Dictionary<string, Sprite> _iconCache = new Dictionary<string, Sprite>();
private readonly Dictionary<int, Item> _knownRunicItems = new Dictionary<int, Item>();
private readonly HashSet<string> _loggedIconFailures = new HashSet<string>();
private readonly HashSet<int> _pendingVisualRetries = new HashSet<int>();
private Material _runicBladeSourceMaterial;
private bool _capturedTexturesReady;
private bool _loggedNoRenderer;
private int _runicMaterialGeneration;
private bool _loggedPrefabMaterialFailure;
private static string PluginDirectory
{
get
{
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!string.IsNullOrEmpty(directoryName))
{
return directoryName;
}
return ".";
}
}
private void Awake()
{
SL.OnPacksLoaded += OnSideLoaderPacksLoaded;
for (int i = 0; i < WeaponDefinitions.Length; i++)
{
SL_Item.AddOnInstanceStartListener(WeaponDefinitions[i].ItemId, (Action<Item>)OnRunicWeaponInstanceStart);
}
TryRefreshCapturedTextureState();
TryRefreshRunicBladeSourceMaterial(allowLoadedMaterialSearch: false);
Debug.Log((object)"[Craftable Runic Blades] Loaded.");
}
private void OnSideLoaderPacksLoaded()
{
for (int i = 0; i < WeaponDefinitions.Length; i++)
{
ApplyRunicWeaponIconToPrefab(WeaponDefinitions[i]);
}
((MonoBehaviour)this).StartCoroutine(PreloadRunicBladeMaterialWhenReady());
}
private void OnRunicWeaponInstanceStart(Item item)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
RunicWeaponDefinition runicWeaponDefinition = FindDefinition(item);
if (runicWeaponDefinition != null)
{
ApplyRunicWeaponIcon(item, runicWeaponDefinition);
_knownRunicItems[((Object)item).GetInstanceID()] = item;
item.OnProcessVisual -= new ProcessVisual(OnRunicWeaponProcessVisual);
item.OnProcessVisual += new ProcessVisual(OnRunicWeaponProcessVisual);
QueueRunicVisualApply(item);
}
}
private void OnRunicWeaponProcessVisual(Item item)
{
QueueRunicVisualApply(item);
}
private void QueueRunicVisualApply(Item item)
{
RunicWeaponDefinition runicWeaponDefinition = FindDefinition(item);
if (runicWeaponDefinition != null)
{
TryRefreshCapturedTextureState();
TryRefreshRunicBladeSourceMaterial(allowLoadedMaterialSearch: true);
ApplyRunicVisual(item, runicWeaponDefinition, logMissingRenderer: false);
int instanceID = ((Object)item).GetInstanceID();
if (_pendingVisualRetries.Add(instanceID))
{
((MonoBehaviour)this).StartCoroutine(ApplyRunicVisualWhenReady(item, runicWeaponDefinition.ItemId, instanceID));
}
}
}
private IEnumerator ApplyRunicVisualWhenReady(Item item, int itemId, int instanceId)
{
bool applied = false;
RunicWeaponDefinition definition = FindDefinition(itemId);
for (int i = 0; i < VisualRetryDelays.Length; i++)
{
float num = VisualRetryDelays[i];
if (num > 0f)
{
yield return (object)new WaitForSecondsRealtime(num);
}
else
{
yield return null;
}
if ((Object)(object)item == (Object)null || definition == null)
{
break;
}
TryRefreshCapturedTextureState();
TryRefreshRunicBladeSourceMaterial(allowLoadedMaterialSearch: true);
applied |= ApplyRunicVisual(item, definition, logMissingRenderer: false);
}
if (!applied && (Object)(object)item != (Object)null && definition != null)
{
ApplyRunicVisual(item, definition, logMissingRenderer: true);
}
_pendingVisualRetries.Remove(instanceId);
}
private bool ApplyRunicVisual(Item item, RunicWeaponDefinition definition, bool logMissingRenderer)
{
if ((Object)(object)item == (Object)null || definition == null || item.ItemID != definition.ItemId)
{
return false;
}
if (ApplyToKnownVisualRoots(item, definition))
{
return true;
}
if (logMissingRenderer && !_loggedNoRenderer)
{
_loggedNoRenderer = true;
Debug.LogWarning((object)"[Craftable Runic Blades] Could not find a safe renderer to recolor.");
}
return false;
}
private void TryRefreshRunicBladeSourceMaterial(bool allowLoadedMaterialSearch)
{
if (!((Object)(object)_runicBladeSourceMaterial != (Object)null))
{
Material val = LoadCapturedRunicBladeMaterial();
if ((Object)(object)val == (Object)null)
{
val = FindRunicBladePrefabMaterial();
}
if ((Object)(object)val == (Object)null && allowLoadedMaterialSearch)
{
val = FindLoadedCapturedRunicBladeMaterial();
}
if (!((Object)(object)val == (Object)null))
{
_runicBladeSourceMaterial = val;
_runicMaterialGeneration++;
_materialCache.Clear();
Debug.Log((object)("[Craftable Runic Blades] Captured Runic Blade material '" + ((Object)val).name + "' with shader '" + ((Object)val.shader).name + "'."));
RefreshKnownRunicItems();
}
}
}
private IEnumerator PreloadRunicBladeMaterialWhenReady()
{
float[] delays = new float[5] { 0f, 0.25f, 1f, 2f, 4f };
for (int i = 0; i < delays.Length; i++)
{
if (delays[i] > 0f)
{
yield return (object)new WaitForSecondsRealtime(delays[i]);
}
else
{
yield return null;
}
TryRefreshRunicBladeSourceMaterial(allowLoadedMaterialSearch: true);
if ((Object)(object)_runicBladeSourceMaterial != (Object)null)
{
break;
}
}
}
private void RefreshKnownRunicItems()
{
List<int> list = new List<int>();
foreach (KeyValuePair<int, Item> knownRunicItem in _knownRunicItems)
{
Item value = knownRunicItem.Value;
if ((Object)(object)value == (Object)null)
{
list.Add(knownRunicItem.Key);
}
else
{
QueueRunicVisualApply(value);
}
}
for (int i = 0; i < list.Count; i++)
{
_knownRunicItems.Remove(list[i]);
}
}
private void ApplyRunicWeaponIconToPrefab(RunicWeaponDefinition definition)
{
try
{
if (ResourcesPrefabManager.Instance != null)
{
Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(definition.ItemId);
ApplyRunicWeaponIcon(itemPrefab, definition);
}
}
catch (Exception ex)
{
LogIconFailure(definition, "Could not apply custom icon to prefab: " + ex.Message);
}
}
private void ApplyRunicWeaponIcon(Item item, RunicWeaponDefinition definition)
{
if ((Object)(object)item == (Object)null || definition == null || item.ItemID != definition.ItemId)
{
return;
}
Sprite runicWeaponIcon = GetRunicWeaponIcon(definition);
if ((Object)(object)runicWeaponIcon == (Object)null)
{
return;
}
try
{
if (ItemIconField != null)
{
ItemIconField.SetValue(item, runicWeaponIcon);
}
if (ItemIconPathField != null)
{
ItemIconPathField.SetValue(item, definition.IconId);
}
else
{
item.ItemIconPath = definition.IconId;
}
}
catch (Exception ex)
{
LogIconFailure(definition, "Could not apply custom icon: " + ex.Message);
}
}
private Sprite GetRunicWeaponIcon(RunicWeaponDefinition definition)
{
if (_iconCache.TryGetValue(definition.IconId, out var value) && (Object)(object)value != (Object)null)
{
return value;
}
string text = Path.Combine(PluginDirectory, definition.IconRelativePath.Replace('/', Path.DirectorySeparatorChar));
try
{
Texture2D val = CustomTextures.LoadTexture(text, false, false);
if ((Object)(object)val == (Object)null)
{
LogIconFailure(definition, "Could not load custom icon from " + text);
return null;
}
((Object)val).name = definition.IconId;
Sprite val2 = CustomTextures.CreateSprite(val, (SpriteBorderTypes)1);
((Object)val2).name = definition.IconId;
_iconCache[definition.IconId] = val2;
return val2;
}
catch (Exception ex)
{
LogIconFailure(definition, "Could not create custom icon: " + ex.Message);
return null;
}
}
private void LogIconFailure(RunicWeaponDefinition definition, string message)
{
string item = ((definition == null) ? "unknown" : definition.IconId);
if (_loggedIconFailures.Add(item))
{
Debug.LogWarning((object)("[Craftable Runic Blades] " + message));
}
}
private void TryRefreshCapturedTextureState()
{
bool flag = CapturedRunicBladeTexturesReady();
if (flag != _capturedTexturesReady)
{
_capturedTexturesReady = flag;
if (flag)
{
_runicMaterialGeneration++;
_materialCache.Clear();
Debug.Log((object)"[Craftable Runic Blades] Captured Runic Blade fallback textures are ready.");
}
}
}
private bool ApplyToKnownVisualRoots(Item item, RunicWeaponDefinition definition)
{
HashSet<int> visitedRoots = new HashSet<int>();
bool flag = false;
bool flag2 = SafeIsInWorld(item);
bool flag3 = SafeIsEquipped(item);
if (!flag2 && !flag3)
{
HideKnownItemVisuals(item);
return false;
}
ItemVisual val = SafeGetCurrentVisual(item);
if ((Object)(object)val != (Object)null)
{
flag |= ApplyToVisualRoot(((Component)val).gameObject, visitedRoots, definition);
}
ItemVisual val2 = SafeGetLoadedVisual(item);
if ((Object)(object)val2 != (Object)null)
{
flag |= ApplyToVisualRoot(((Component)val2).gameObject, visitedRoots, definition);
}
if (flag2)
{
flag |= ApplyToVisualRoot(((Component)item).gameObject, visitedRoots, definition);
}
return flag;
}
private bool ApplyToVisualRoot(GameObject root, HashSet<int> visitedRoots, RunicWeaponDefinition definition)
{
if ((Object)(object)root == (Object)null)
{
return false;
}
int instanceID = ((Object)root).GetInstanceID();
if (!visitedRoots.Add(instanceID))
{
return false;
}
Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
if (!ApplyToRenderers(componentsInChildren, definition, requireVisualName: true))
{
return ApplyToRenderers(componentsInChildren, definition, requireVisualName: false);
}
return true;
}
private bool ApplyToRenderers(Renderer[] renderers, RunicWeaponDefinition definition, bool requireVisualName)
{
bool result = false;
foreach (Renderer val in renderers)
{
if (!ShouldPatchRenderer(val, definition, requireVisualName))
{
continue;
}
Material[] sharedMaterials = val.sharedMaterials;
if (sharedMaterials == null || sharedMaterials.Length == 0)
{
continue;
}
Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
bool flag = false;
for (int j = 0; j < sharedMaterials.Length; j++)
{
Material val2 = sharedMaterials[j];
if ((Object)(object)val2 == (Object)null || ShouldSkipMaterial(val2))
{
array[j] = val2;
}
else if (IsPermanentRunicBladeMaterial(val2) && !ShouldRefreshRunicMaterial(val2))
{
result = true;
array[j] = val2;
}
else
{
array[j] = GetRunicMaterial(val2, definition);
flag = true;
result = true;
}
}
if (flag)
{
val.sharedMaterials = array;
}
}
return result;
}
private Material GetRunicMaterial(Material original, RunicWeaponDefinition definition)
{
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Expected O, but got Unknown
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Expected O, but got Unknown
string text = ((Object)original).name ?? string.Empty;
int itemId = definition.ItemId;
string key = itemId + "|" + ((Object)original).GetInstanceID();
if (_materialCache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
{
return value;
}
Material runicBladeSourceMaterial = GetRunicBladeSourceMaterial();
Material val;
if ((Object)(object)runicBladeSourceMaterial != (Object)null)
{
val = new Material(runicBladeSourceMaterial);
((Object)val).name = "MEROFOS_PermanentRunicBlades_Exact_" + definition.Marker + "_" + ((Object)runicBladeSourceMaterial).name;
}
else
{
val = new Material(original);
ApplyCapturedRunicBladeMaterial(val, definition.Marker);
Material obj = val;
((Object)obj).name = ((Object)obj).name + "_" + text;
}
_materialCache[key] = val;
return val;
}
private bool ShouldRefreshRunicMaterial(Material material)
{
string text = ((Object)material).name ?? string.Empty;
if ((Object)(object)_runicBladeSourceMaterial != (Object)null && text.StartsWith("MEROFOS_PermanentRunicBlades_Captured_", StringComparison.Ordinal))
{
return true;
}
if (CapturedRunicBladeTexturesReady() && text.StartsWith("MEROFOS_PermanentRunicBlades_Captured_", StringComparison.Ordinal))
{
if (HasTexture(material, "_MainTex") && HasTexture(material, "_NormalMap"))
{
return !HasTexture(material, "_DistortMap");
}
return true;
}
return false;
}
private Material GetRunicBladeSourceMaterial()
{
if ((Object)(object)_runicBladeSourceMaterial != (Object)null)
{
return _runicBladeSourceMaterial;
}
TryRefreshRunicBladeSourceMaterial(allowLoadedMaterialSearch: true);
return _runicBladeSourceMaterial;
}
private static void ApplyRunicShader(Material material)
{
Shader val = Shader.Find("Custom/Distort/DistortTextureSpec");
if ((Object)(object)val != (Object)null)
{
material.shader = val;
}
}
private static Material LoadCapturedRunicBladeMaterial()
{
string[] array = new string[5] { "mat_itm_crystalBladeRunicBladeLight", "Materials/mat_itm_crystalBladeRunicBladeLight", "_Materials/mat_itm_crystalBladeRunicBladeLight", "Items/mat_itm_crystalBladeRunicBladeLight", "Weapons/mat_itm_crystalBladeRunicBladeLight" };
for (int i = 0; i < array.Length; i++)
{
Material val = Resources.Load<Material>(array[i]);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private static Material FindLoadedCapturedRunicBladeMaterial()
{
Material[] array = Resources.FindObjectsOfTypeAll<Material>();
foreach (Material val in array)
{
if (!((Object)(object)val == (Object)null) && ((Object)val).name != null && !((Object)val).name.StartsWith("MEROFOS_PermanentRunicBlades_", StringComparison.Ordinal))
{
string name = ((Object)val).name;
if (string.Equals(name, "mat_itm_crystalBladeRunicBladeLight", StringComparison.Ordinal) || name.StartsWith("mat_itm_crystalBladeRunicBladeLight ", StringComparison.Ordinal) || name.StartsWith("mat_itm_crystalBladeRunicBladeLight(", StringComparison.Ordinal))
{
return val;
}
}
}
return null;
}
private Material FindRunicBladePrefabMaterial()
{
try
{
if (ResourcesPrefabManager.Instance == null)
{
return null;
}
Material val = FindMaterialOnItem(ResourcesPrefabManager.Instance.GetItemPrefab(2000100));
if ((Object)(object)val != (Object)null)
{
return val;
}
}
catch (Exception ex)
{
if (!_loggedPrefabMaterialFailure)
{
_loggedPrefabMaterialFailure = true;
Debug.LogWarning((object)("[Craftable Runic Blades] Could not inspect vanilla Runic Blade prefab material: " + ex.Message));
}
}
return null;
}
private static Material FindMaterialOnItem(Item item)
{
if ((Object)(object)item == (Object)null)
{
return null;
}
Material val = FindMaterialInRenderers(((Component)item).GetComponentsInChildren<Renderer>(true));
if ((Object)(object)val != (Object)null)
{
return val;
}
ItemVisual val2 = SafeGetCurrentVisual(item);
if ((Object)(object)val2 != (Object)null)
{
val = FindMaterialInRenderers(((Component)val2).GetComponentsInChildren<Renderer>(true));
if ((Object)(object)val != (Object)null)
{
return val;
}
}
ItemVisual val3 = SafeGetLoadedVisual(item);
if ((Object)(object)val3 != (Object)null)
{
val = FindMaterialInRenderers(((Component)val3).GetComponentsInChildren<Renderer>(true));
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private static Material FindMaterialInRenderers(Renderer[] renderers)
{
if (renderers == null)
{
return null;
}
foreach (Renderer val in renderers)
{
if ((Object)(object)val == (Object)null || val is TrailRenderer || val is LineRenderer || val is ParticleSystemRenderer)
{
continue;
}
Material[] sharedMaterials = val.sharedMaterials;
if (sharedMaterials == null)
{
continue;
}
foreach (Material val2 in sharedMaterials)
{
if ((Object)(object)val2 != (Object)null && IsCapturedRunicBladeMaterialName(((Object)val2).name))
{
return val2;
}
}
}
return null;
}
private static bool IsCapturedRunicBladeMaterialName(string materialName)
{
if (string.IsNullOrEmpty(materialName))
{
return false;
}
if (materialName.StartsWith("MEROFOS_PermanentRunicBlades_", StringComparison.Ordinal))
{
return false;
}
if (!string.Equals(materialName, "mat_itm_crystalBladeRunicBladeLight", StringComparison.Ordinal) && !materialName.StartsWith("mat_itm_crystalBladeRunicBladeLight ", StringComparison.Ordinal) && !materialName.StartsWith("mat_itm_crystalBladeRunicBladeLight(", StringComparison.Ordinal) && !materialName.StartsWith("MEROFOS_RunicDagger_Exact_mat_itm_crystalBladeRunicBladeLight", StringComparison.Ordinal))
{
return materialName.StartsWith("MEROFOS_RunicArsenal_Exact_mat_itm_crystalBladeRunicBladeLight", StringComparison.Ordinal);
}
return true;
}
private static void ApplyCapturedRunicBladeMaterial(Material material, string marker)
{
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
((Object)material).name = "MEROFOS_PermanentRunicBlades_Captured_" + marker + "_mat_itm_crystalBladeRunicBladeLight";
material.renderQueue = 2000;
ApplyRunicShader(material);
SetTexture(material, "_MainTex", GetCapturedMainTexture());
SetTexture(material, "_NormalMap", GetCapturedWaveTexture());
SetTexture(material, "_DistortMap", GetCapturedWaveTexture());
SetColor(material, "_Color", new Color(14.55578f, 6.948529f, 15f, 1f));
SetColor(material, "_SpecColor", new Color(0.3455882f, 0.3455882f, 0.3455882f, 0.759f));
SetFloat(material, "_NormalStrength", 1f);
SetFloat(material, "_Speed", 1f);
SetFloat(material, "_Scale", 2f);
SetFloat(material, "_MaskPow", 0f);
material.shaderKeywords = new string[2] { "_ALPHATEST_ON", "_NORMALMAP" };
material.EnableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_NORMALMAP");
}
private static bool CapturedRunicBladeTexturesReady()
{
if ((Object)(object)GetCapturedMainTexture() != (Object)null)
{
return (Object)(object)GetCapturedWaveTexture() != (Object)null;
}
return false;
}
private static Texture GetCapturedMainTexture()
{
if ((Object)(object)s_capturedMainTexture == (Object)null)
{
s_capturedMainTexture = FindTexture("tex_fx_PerlinNoiseGray");
}
return s_capturedMainTexture;
}
private static Texture GetCapturedWaveTexture()
{
if ((Object)(object)s_capturedWaveTexture == (Object)null)
{
s_capturedWaveTexture = FindTexture("tex_env_waterWave_n");
}
return s_capturedWaveTexture;
}
private static Texture FindTexture(string textureName)
{
string[] array = new string[6]
{
textureName,
"Textures/" + textureName,
"_Textures/" + textureName,
"FX/" + textureName,
"VFX/" + textureName,
"Environment/" + textureName
};
for (int i = 0; i < array.Length; i++)
{
Texture val = Resources.Load<Texture>(array[i]);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
Texture[] array2 = Resources.FindObjectsOfTypeAll<Texture>();
foreach (Texture val2 in array2)
{
if ((Object)(object)val2 != (Object)null && string.Equals(((Object)val2).name, textureName, StringComparison.Ordinal))
{
return val2;
}
}
if (!s_missingTextureWarnings.Contains(textureName))
{
s_missingTextureWarnings.Add(textureName);
Debug.LogWarning((object)("[Craftable Runic Blades] Could not find texture '" + textureName + "' for captured Runic Blade material."));
}
return null;
}
private static void SetColor(Material material, string propertyName, Color value)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
if (material.HasProperty(propertyName))
{
material.SetColor(propertyName, value);
}
}
private static void SetFloat(Material material, string propertyName, float value)
{
if (material.HasProperty(propertyName))
{
material.SetFloat(propertyName, value);
}
}
private static void SetTexture(Material material, string propertyName, Texture texture)
{
if ((Object)(object)texture != (Object)null && material.HasProperty(propertyName))
{
material.SetTexture(propertyName, texture);
}
}
private static bool HasTexture(Material material, string propertyName)
{
if (material.HasProperty(propertyName))
{
return (Object)(object)material.GetTexture(propertyName) != (Object)null;
}
return false;
}
private static bool IsPermanentRunicBladeMaterial(Material material)
{
if ((Object)(object)material != (Object)null && ((Object)material).name != null)
{
return ((Object)material).name.StartsWith("MEROFOS_PermanentRunicBlades_", StringComparison.Ordinal);
}
return false;
}
private static bool ShouldPatchRenderer(Renderer renderer, RunicWeaponDefinition definition, bool requireVisualName)
{
if ((Object)(object)renderer == (Object)null || renderer is TrailRenderer || renderer is LineRenderer || renderer is ParticleSystemRenderer)
{
return false;
}
if (requireVisualName && !HasRunicWeaponVisualName(((Component)renderer).transform, definition))
{
return false;
}
string text = ((((Object)renderer).name == null) ? string.Empty : ((Object)renderer).name.ToLowerInvariant());
if (!text.Contains("highlight") && !text.Contains("trail") && !text.Contains("linecast") && !text.Contains("gateframe") && !text.Contains("hair") && !text.Contains("head"))
{
return !text.Contains("face");
}
return false;
}
private static bool ShouldSkipMaterial(Material material)
{
string text = ((((Object)material).name == null) ? string.Empty : ((Object)material).name.ToLowerInvariant());
if (!text.Contains("hair") && !text.Contains("skin") && !text.Contains("head") && !text.Contains("face") && !text.Contains("beard"))
{
return text.StartsWith("mat_cha_", StringComparison.Ordinal);
}
return true;
}
private static bool HasRunicWeaponVisualName(Transform transform, RunicWeaponDefinition definition)
{
Transform val = transform;
while ((Object)(object)val != (Object)null)
{
string text = ((((Object)val).name == null) ? string.Empty : ((Object)val).name.ToLowerInvariant());
for (int i = 0; i < definition.VisualNameTokens.Length; i++)
{
if (text.Contains(definition.VisualNameTokens[i]))
{
return true;
}
}
val = val.parent;
}
return false;
}
private static ItemVisual SafeGetCurrentVisual(Item item)
{
try
{
return item.CurrentVisual;
}
catch
{
return null;
}
}
private static ItemVisual SafeGetLoadedVisual(Item item)
{
try
{
return item.LoadedVisual;
}
catch
{
return null;
}
}
private static bool SafeIsInWorld(Item item)
{
try
{
return (Object)(object)item != (Object)null && item.IsInWorld;
}
catch
{
return false;
}
}
private static bool SafeIsEquipped(Item item)
{
try
{
return (Object)(object)item != (Object)null && item.IsEquipped;
}
catch
{
return false;
}
}
private static void HideKnownItemVisuals(Item item)
{
ItemVisual val = SafeGetCurrentVisual(item);
if ((Object)(object)val != (Object)null)
{
SafeHideVisual(val);
}
ItemVisual val2 = SafeGetLoadedVisual(item);
if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)val)
{
SafeHideVisual(val2);
}
}
private static void SafeHideVisual(ItemVisual visual)
{
try
{
visual.Hide();
}
catch
{
}
}
private static RunicWeaponDefinition FindDefinition(Item item)
{
if ((Object)(object)item == (Object)null)
{
return null;
}
return FindDefinition(item.ItemID);
}
private static RunicWeaponDefinition FindDefinition(int itemId)
{
for (int i = 0; i < WeaponDefinitions.Length; i++)
{
if (WeaponDefinitions[i].ItemId == itemId)
{
return WeaponDefinitions[i];
}
}
return null;
}
}