Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Skyheim v1.3.12
skyheim.dll
Decompiled a year ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using SimpleJSON; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Serialization; using UnityEngine.UI; using skyheim; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("skyheim")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("skyheim")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("454bec7c-7837-4169-b004-c0b761e01612")] [assembly: AssemblyFileVersion("1.3.12.0")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.12.0")] [module: UnverifiableCode] public class AssetManager { public static AssetBundle AssetBundle; public static Object[] AssetBundleObjects; public static UnityAction<ZNetScene> OnSceneAwake; public static UnityAction<ObjectDB> OnObjectDBAwake; public static void Create(Harmony harmony, string assetBundle) { harmony.PatchAll(typeof(AssetManager)); LoadAssetsFromBundle(assetBundle); } public static void LoadAssetsFromBundle(string bundleName) { AssetBundle = GetAssetBundleFromResources(bundleName); AssetBundleObjects = AssetBundle.LoadAllAssets(); } public static AssetBundle GetAssetBundleFromResources(string fileName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(fileName)); using Stream stream = executingAssembly.GetManifestResourceStream(name); return AssetBundle.LoadFromStream(stream); } public static IEnumerable<T> GetGameObjects<T>() where T : Component { Object[] assetBundleObjects = AssetBundleObjects; foreach (Object obj in assetBundleObjects) { GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null); if (val != null) { T component = val.GetComponent<T>(); if (component != null) { yield return component; } } } } public static T GetGameObject<T>(string id) where T : Component { Object[] assetBundleObjects = AssetBundleObjects; foreach (Object obj in assetBundleObjects) { GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null); if (val != null && ((Object)val).name == id) { T component = val.GetComponent<T>(); if (component != null) { return component; } } } return default(T); } public static GameObject GetGameObject(string id) { Object[] assetBundleObjects = AssetBundleObjects; foreach (Object obj in assetBundleObjects) { GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null); if (val != null && ((Object)val).name == id) { return val; } } return null; } public static IEnumerable<T> GetAssets<T>() { Object[] assetBundleObjects = AssetBundleObjects; foreach (Object val in assetBundleObjects) { if (val is T) { yield return (T)(object)((val is T) ? val : null); } } } public static T GetAsset<T>(string name) { Object[] assetBundleObjects = AssetBundleObjects; foreach (Object val in assetBundleObjects) { if (val.name == name && val is T) { return (T)(object)((val is T) ? val : null); } } return default(T); } public static T LoadAsset<T>(string name) where T : Object { return AssetBundle.LoadAsset<T>(name); } public static void LoadItems(ObjectDB db) { IEnumerable<ItemDrop> gameObjects = AssetManager.GetGameObjects<ItemDrop>(); db.m_items.AddRange(gameObjects.Select((ItemDrop x) => ((Component)x).gameObject)); db.UpdateRegisters(); } public static void RegisterRecipes(ObjectDB db) { db.m_recipes.AddRange(from x in GetAssets<SkyheimRecipe>() select x.Convert()); db.m_recipes.AddRange(GetAssets<Recipe>()); } public static void RegisterStatusEffects(ObjectDB db) { db.m_StatusEffects.AddRange(GetAssets<StatusEffect>()); } public static void RegisterPieces() { foreach (SkyheimPieceData gameObject in AssetManager.GetGameObjects<SkyheimPieceData>()) { ItemDrop tool = gameObject.Tool; if (tool != null) { List<GameObject> pieces = tool.m_itemData.m_shared.m_buildPieces.m_pieces; if (!pieces.Contains(((Component)gameObject).gameObject)) { gameObject.Convert(); pieces.Add(((Component)gameObject).gameObject); } } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPostfix] public static void ObjectDB_Awake_Postfix(ObjectDB __instance) { if ((Object)(object)ZNetScene.instance != (Object)null) { OnObjectDBAwake?.Invoke(__instance); LoadItems(__instance); RegisterRecipes(__instance); RegisterStatusEffects(__instance); } } [HarmonyPatch(typeof(FejdStartup), "SetupObjectDB")] [HarmonyPostfix] public static void FejdStartup_SetupObjectDB_Postfix(FejdStartup __instance) { LoadItems(((Component)__instance).GetComponent<ObjectDB>()); } [HarmonyPatch(typeof(ZNetScene), "Awake")] [HarmonyPostfix] public static void ZNetScene_Awake_Postfix(ZNetScene __instance) { foreach (ZNetView gameObject in AssetManager.GetGameObjects<ZNetView>()) { __instance.m_namedPrefabs.Add(StringExtensionMethods.GetStableHashCode(((Object)gameObject).name), ((Component)gameObject).gameObject); } RegisterPieces(); OnSceneAwake?.Invoke(__instance); } } public class AssetType : PropertyAttribute { public Type Type { get; protected set; } public AssetType(Type type) { Type = type; } } public static class CommonUtils { [Serializable] public class SerializableWrapper<T> { public T Value; public SerializableWrapper(T v) { Value = v; } } public struct DistanceSort : IComparer<Collider> { private Vector3 _target; public DistanceSort(Vector3 target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _target = target; } public int Compare(Collider a, Collider b) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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) //IL_0027: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)a).transform.position; Vector3 position2 = ((Component)b).transform.position; return Vector3.Distance(position, _target).CompareTo(Vector3.Distance(position2, _target)); } } public static long PlayerID => Game.instance.GetPlayerProfile().GetPlayerID(); [Conditional("DEBUG")] public static void Log(string str) { Debug.Log((object)str); } [Conditional("DEBUG")] public static void LogFields(object obj) { FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo obj2 in fields) { _ = obj2.Name; obj2.GetValue(obj); } } public static T ConvertPrefabReference<T>(string prefabReference) where T : Component { if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !string.IsNullOrEmpty(prefabReference)) { GameObject prefab = ZNetScene.instance.GetPrefab(prefabReference); if ((Object)(object)prefab != (Object)null) { return prefab.GetComponent<T>(); } } return default(T); } public static GameObject ConvertPrefabReference(string prefabReference) { if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !string.IsNullOrEmpty(prefabReference)) { return ZNetScene.instance.GetPrefab(prefabReference); } return null; } public static T GetItemComponent<T>(ItemData item) where T : Component { if (item == null || !Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return default(T); } return item.m_dropPrefab.GetComponent<T>(); } public static T Clone<T>(T obj) { return (T)obj.GetType().GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(obj, null); } public static T Get<T>(this IDictionary dict, string key, T defaultValue = default(T)) { if (dict.Contains(key)) { return (T)Convert.ChangeType(dict[key], typeof(T)); } return defaultValue; } public static JSONNode ToJSON<T>(T obj) { Type type = obj.GetType(); if (obj is IList) { JSONArray jSONArray = new JSONArray(); { foreach (object item in obj as IList) { jSONArray.Add(ToJSON(item)); } return jSONArray; } } if (type.IsClass && !(obj is string)) { Type type2 = obj.GetType(); JSONObject jSONObject = new JSONObject(); FieldInfo[] fields = type2.GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { jSONObject.Add(fieldInfo.Name, ToJSON(fieldInfo.GetValue(obj))); } return jSONObject; } return (JSONNode)typeof(JSONNode).GetMethod("op_Implicit", new Type[1] { obj.GetType() }).Invoke(null, new object[1] { obj }); } } public class NameAttribute : PropertyAttribute { public string Name { get; private set; } public NameAttribute(string name) { Name = name; } } public class PrefabReferenceType : PropertyAttribute { public Type ComponentType { get; protected set; } public PrefabReferenceType(Type componentType) { ComponentType = componentType; } } public class SkyheimPieceData : MonoBehaviour, ISerializationCallbackReceiver { [Header("Requirements")] [SerializeField] [PrefabReferenceType(typeof(CraftingStation))] [FormerlySerializedAs("m_craftingStation")] private string _craftingStation; [SerializeField] [PrefabReferenceType(typeof(ItemDrop))] [FormerlySerializedAs("m_craftingTool")] private string _craftingTool; [SerializeField] [PrefabReferenceType(typeof(Piece))] [FormerlySerializedAs("m_template")] private string _template; [SerializeField] [FormerlySerializedAs("m_resources")] private List<SkyheimRecipe.SkyheimRequirement> _resources; [SerializeField] [HideInInspector] [FormerlySerializedAs("m_resources_internal")] private string _resourcesInternal; public ItemDrop Tool => CommonUtils.ConvertPrefabReference<ItemDrop>(_craftingTool); public void Convert() { RuntimeDeserialize(); Piece component = ((Component)this).GetComponent<Piece>(); component.m_craftingStation = CommonUtils.ConvertPrefabReference<CraftingStation>(_craftingStation); component.m_resources = ((IEnumerable<SkyheimRecipe.SkyheimRequirement>)_resources).Select((Func<SkyheimRecipe.SkyheimRequirement, Requirement>)((SkyheimRecipe.SkyheimRequirement x) => x)).ToArray(); Piece val = (string.IsNullOrEmpty(_template) ? null : CommonUtils.ConvertPrefabReference<Piece>(_template)); if (!((Object)(object)val != (Object)null)) { return; } component.m_placeEffect = val.m_placeEffect; WearNTear component2 = ((Component)component).GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component2)) { WearNTear component3 = ((Component)val).GetComponent<WearNTear>(); if (component3 != null) { component2.m_hitEffect = component3.m_hitEffect; component2.m_destroyedEffect = component3.m_destroyedEffect; component2.m_switchEffect = component3.m_switchEffect; } } } public void RuntimeDeserialize() { _resources = new List<SkyheimRecipe.SkyheimRequirement>(); JSONNode.Enumerator enumerator = JSONNode.Parse(_resourcesInternal).AsArray.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<string, JSONNode> current = enumerator.Current; _resources.Add(new SkyheimRecipe.SkyheimRequirement(current.Value)); } } public void OnBeforeSerialize() { JSONNode jSONNode = CommonUtils.ToJSON(_resources); _resourcesInternal = jSONNode.ToString(); } public void OnAfterDeserialize() { } } [CreateAssetMenu(menuName = "Skyheim/Recipe")] public class SkyheimRecipe : ScriptableObject, ISerializationCallbackReceiver { [Serializable] public class SkyheimRequirement { [PrefabReferenceType(typeof(ItemDrop))] [FormerlySerializedAs("ResItem")] public string ResourceItem; [FormerlySerializedAs("m_amount")] public int Amount = 1; [FormerlySerializedAs("m_amountPerLevel")] public int AmountPerLevel = 1; [FormerlySerializedAs("m_recover")] public bool Recover = true; public SkyheimRequirement() { } public SkyheimRequirement(JSONNode j) { ResourceItem = j["ResourceItem"]; Amount = j["Amount"]; AmountPerLevel = j["AmountPerLevel"]; Recover = j["Recover"]; } public static implicit operator Requirement(SkyheimRequirement r) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown return new Requirement { m_resItem = CommonUtils.ConvertPrefabReference<ItemDrop>(r.ResourceItem), m_amount = r.Amount, m_amountPerLevel = r.AmountPerLevel, m_recover = r.Recover }; } } [SerializeField] [PrefabReferenceType(typeof(ItemDrop))] [FormerlySerializedAs("m_item")] private string _item; [SerializeField] [FormerlySerializedAs("m_amount")] private int _amount = 1; [SerializeField] [FormerlySerializedAs("m_enabled")] private bool _enabled = true; [Header("Requirements")] [SerializeField] [PrefabReferenceType(typeof(CraftingStation))] [FormerlySerializedAs("m_craftingStation")] private string _craftingStation; [SerializeField] [PrefabReferenceType(typeof(CraftingStation))] [FormerlySerializedAs("m_repairStation")] private string _repairStation; [SerializeField] [FormerlySerializedAs("m_minStationLevel")] private int _minStationLevel = 1; [SerializeField] [FormerlySerializedAs("m_resources")] private List<SkyheimRequirement> _resources; [SerializeField] [HideInInspector] [FormerlySerializedAs("m_resources_internal")] private string _resourcesInternal; public Recipe Convert() { RuntimeDeserialize(); Recipe obj = ScriptableObject.CreateInstance<Recipe>(); ((Object)obj).name = ((Object)this).name; obj.m_item = CommonUtils.ConvertPrefabReference<ItemDrop>(_item); obj.m_craftingStation = CommonUtils.ConvertPrefabReference<CraftingStation>(_craftingStation); obj.m_repairStation = CommonUtils.ConvertPrefabReference<CraftingStation>(_repairStation); obj.m_resources = ((IEnumerable<SkyheimRequirement>)_resources).Select((Func<SkyheimRequirement, Requirement>)((SkyheimRequirement x) => x)).ToArray(); obj.m_amount = _amount; obj.m_enabled = _enabled; obj.m_minStationLevel = _minStationLevel; return obj; } public void RuntimeDeserialize() { JSONNode jSONNode = JSONNode.Parse(_resourcesInternal); _resources = new List<SkyheimRequirement>(); JSONNode.Enumerator enumerator = jSONNode.AsArray.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<string, JSONNode> current = enumerator.Current; _resources.Add(new SkyheimRequirement(current.Value)); } } public void OnBeforeSerialize() { JSONNode jSONNode = CommonUtils.ToJSON(_resources); _resourcesInternal = jSONNode.ToString(); } public void OnAfterDeserialize() { } } public class ChainAoe : MonoBehaviour, IProjectile { [Flags] public enum EHitFlags { None = 0, Owner = 1, Friendly = 2, Enemy = 4, Characters = 8, Props = 0x10 } public float Radius = 10f; public int ChainCount = 5; public SkyheimItemData.ESkillType Skill; public EHitFlags HitFlags; public LineRenderer Chain; public float Lifetime = 1f; public float HitDelay = 0.1f; public string OriginJoint; public float ScaleMin = 1f; public float ScaleMax = 1f; public EffectList ImpactEffects = new EffectList(); private ZNetView _nview; private Character _owner; private HitData _hitData; private int _rayMask; private Transform _chainOrigin; private readonly List<GameObject> _targets = new List<GameObject>(); private readonly List<Collider> _colliders = new List<Collider>(); private Vector3[] _positions; private int _hitIndex; protected void Awake() { _positions = (Vector3[])(object)new Vector3[ChainCount + 1]; Chain.useWorldSpace = true; _nview = ((Component)this).GetComponentInParent<ZNetView>(); if ((Object)(object)_nview != (Object)null && _nview.GetZDO() != null) { _nview.Register<ZPackage>("Trigger", (Action<long, ZPackage>)RPC_Trigger); } } public string GetTooltipString(int itemQuality) { return string.Empty; } public int GetRayMask() { if (_rayMask == 0) { if (HitFlags.HasFlag(EHitFlags.Characters)) { _rayMask |= LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" }); } if (HitFlags.HasFlag(EHitFlags.Props)) { _rayMask |= LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "hitbox", "character_noenv", "vehicle" }); } } return _rayMask; } public void Setup(Character owner, Vector3 velocity, float hitNoise, HitData hitData, ItemData item, ItemData ammo) { _hitData = hitData; _owner = owner; } private void UpdateChain() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) _positions[0] = (Object.op_Implicit((Object)(object)_chainOrigin) ? _chainOrigin.position : _owner.GetCenterPoint()); for (int i = 0; i <= _hitIndex; i++) { Collider val = _colliders[i]; if ((Object)(object)val != (Object)null) { Vector3[] positions = _positions; int num = i + 1; Bounds bounds = val.bounds; positions[num] = ((Bounds)(ref bounds)).center; } } Chain.positionCount = _hitIndex + 2; Chain.SetPositions(_positions); Chain.widthMultiplier = Random.Range(ScaleMin, ScaleMax); ((Renderer)Chain).material.SetTextureOffset("_MainTex", Vector2.left * Time.time); } protected void FixedUpdate() { if (_targets.Count > 0) { UpdateChain(); } if (_nview.IsOwner() && Lifetime > 0f) { Lifetime -= Time.fixedDeltaTime; if (Lifetime <= 0f) { ZNetScene.instance.Destroy(((Component)this).gameObject); } } } private IEnumerator StaggerVisuals() { int i = 0; while (i < _targets.Count) { _hitIndex = i; EffectList impactEffects = ImpactEffects; Bounds bounds = _colliders[i].bounds; impactEffects.Create(((Bounds)(ref bounds)).center, Quaternion.identity, (Transform)null, 1f, -1); yield return (object)new WaitForSecondsRealtime(HitDelay); int num = i + 1; i = num; } } private IEnumerator StaggerDamage() { int i = 0; while (i < _targets.Count) { yield return (object)new WaitForSecondsRealtime(HitDelay); GameObject obj = _targets[i]; Collider val = _colliders[i]; IDestructible component = obj.GetComponent<IDestructible>(); Vector3 position = ((Component)val).transform.position; HitData val2 = CommonUtils.Clone<HitData>(_hitData); val2.m_hitCollider = val; Vector3 val3 = position - ((Component)this).transform.position; val2.m_dir = ((Vector3)(ref val3)).normalized; val2.m_point = position; component.Damage(val2); int num = i + 1; i = num; } } private void SeekTargets(Transform origin) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Physics.OverlapSphere(origin.position, Radius, GetRayMask()); Array.Sort(array, new CommonUtils.DistanceSort(origin.position)); Collider[] array2 = array; foreach (Collider val in array2) { GameObject val2 = Projectile.FindHitObject(val); if (IsValidTarget(_owner, val2)) { _targets.Add(val2); if (_targets.Count < ChainCount) { SeekTargets(((Component)val).transform); } break; } } } public void Trigger(GameObject target) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)target) && _nview.IsOwner()) { SeekTargets(target.transform); int count = _targets.Count; ZPackage val = new ZPackage(); val.Write(((Component)_owner).GetComponent<ZNetView>().GetZDO().m_uid); val.Write(count); for (int i = 0; i < count; i++) { ZDOID uid = _targets[i].GetComponent<ZNetView>().GetZDO().m_uid; val.Write(uid); } _targets.Clear(); _nview.InvokeRPC("Trigger", new object[1] { val }); if (Object.op_Implicit((Object)(object)_owner) && _owner.IsPlayer() && Skill != 0) { _owner.RaiseSkill((SkillType)Skill, 1f); } } } public bool IsValidTarget(Character owner, GameObject gameObject) { IDestructible val = default(IDestructible); if (!gameObject.TryGetComponent<IDestructible>(ref val)) { return false; } if (_targets.Contains(gameObject)) { return false; } if (!Object.op_Implicit((Object)(object)gameObject.GetComponent<ZNetView>())) { return false; } Character component = gameObject.GetComponent<Character>(); if (component != null) { if (!HitFlags.HasFlag(EHitFlags.Characters)) { return false; } if (!HitFlags.HasFlag(EHitFlags.Owner) && (Object)(object)component == (Object)(object)owner) { return false; } bool flag = BaseAI.IsEnemy(owner, component); if (!HitFlags.HasFlag(EHitFlags.Enemy) && flag) { return false; } if (!HitFlags.HasFlag(EHitFlags.Friendly) && !flag) { return false; } } else if (!HitFlags.HasFlag(EHitFlags.Props)) { return false; } return true; } private void RPC_Trigger(long playerId, ZPackage data) { //IL_0001: 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_0074: 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) //IL_0080: Unknown result type (might be due to invalid IL or missing references) ZDOID val = data.ReadZDOID(); GameObject val2 = ZNetScene.instance.FindInstance(val); _owner = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent<Character>() : null); if ((Object)(object)_owner == (Object)null) { return; } if (!string.IsNullOrEmpty(OriginJoint)) { _chainOrigin = Utils.FindChild(_owner.GetVisual().transform, OriginJoint, (IterativeSearchType)0); } int num = data.ReadInt(); for (int i = 0; i < num; i++) { ZDOID val3 = data.ReadZDOID(); GameObject val4 = ZNetScene.instance.FindInstance(val3); if ((Object)(object)val4 != (Object)null) { Collider componentInChildren = val4.GetComponentInChildren<Collider>(); if ((Object)(object)componentInChildren != (Object)null) { _colliders.Add(componentInChildren); _targets.Add(val4); } } } ((MonoBehaviour)this).StartCoroutine(StaggerVisuals()); if (_nview.IsOwner()) { ((MonoBehaviour)this).StartCoroutine(StaggerDamage()); } } } [CreateAssetMenu(menuName = "Skyheim/DropModifier")] public class DropModifier : ScriptableObject { [PrefabReferenceType(typeof(CharacterDrop))] public string EnemyDrop; [PrefabReferenceType(typeof(ItemDrop))] public string ItemDrop; public Drop Drop = new Drop(); public void Apply() { Drop.m_prefab = ZNetScene.instance.GetPrefab(ItemDrop); ZNetScene.instance.GetPrefab(EnemyDrop).GetComponent<CharacterDrop>().m_drops.Add(Drop); } } public class SkyheimAltar : MonoBehaviour { public enum ImbueType { Eitr } public Action OnProcessComplete; [SerializeField] private SkyheimAltarContainer _chest; [SerializeField] private GameObject _activeEffect; private bool _inUse; private static SkyheimAltarTuning s_tuning; private ZNetView _nview; private bool _processing; private float _startTime; private float _duration; public SkyheimAltarContainer Container => _chest; public bool Processing => _processing; public float TimeRemaining { get { float num = ZNet.instance.GetTime().Ticks / 10000000; return Mathf.Max(0f, _duration - (num - _startTime)); } } private SkyheimAltarTuning Tuning { get { if ((Object)(object)s_tuning == (Object)null) { s_tuning = AssetManager.GetAsset<SkyheimAltarTuning>("altar_tuning"); s_tuning.RuntimeDeserialize(); } return s_tuning; } } private bool NetValidate { get { _ = (Object)(object)_nview == (Object)null; return (Object)(object)_nview != (Object)null; } } protected void Awake() { if (((Component)this).TryGetComponent<ZNetView>(ref _nview)) { _nview.Register<float, float>("RPC_StartProcess", (Action<long, float, float>)RPC_StartProcess); _nview.Register<bool>("RPC_StopProcess", (Action<long, bool>)RPC_StopProcess); } Load(); UpdateVisual(); } private void Load() { ZDO zDO = _nview.GetZDO(); if (zDO != null) { _processing = zDO.GetBool("Started", false); _startTime = zDO.GetFloat("StartTime", 0f); _duration = zDO.GetFloat("Duration", 0f); } } private void Save() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (NetValidate) { _nview.IsOwner(); ZDO zDO = _nview.GetZDO(); if (zDO != null) { zDO.Set("Started", _processing); zDO.Set("StartTime", _startTime); zDO.Set("Duration", _duration); ZDOMan.instance.ForceSendZDO(_nview.GetZDO().m_uid); } } } private void StartProcess(float duration) { if (NetValidate && _nview.IsOwner()) { float startTime = ZNet.instance.GetTime().Ticks / 10000000; _processing = true; _startTime = startTime; _duration = duration; Save(); _nview.InvokeRPC(0L, "RPC_StartProcess", new object[2] { _startTime, _duration }); } } public void CancelProcess() { FinishProcess(completed: false); } public SkyheimArmorRecipe GetActiveRecipe() { foreach (SkyheimArmorRecipe recipe in Tuning.Recipes) { ItemData item = ((Container)_chest).GetInventory().GetItem(recipe.SourceItemDrop, -1, true); if (item != null && !item.m_customData.ContainsKey("sh_mod_type")) { return recipe; } } return null; } public bool HasEitrShards(SkyheimArmorRecipe recipe) { return ((Container)_chest).GetInventory().CountPrefabItems(Tuning.EitrShardPrefab) >= recipe.EitrShardsRequired; } private void FinishProcess(bool completed) { if (NetValidate && _processing && _nview.IsOwner()) { _nview.InvokeRPC(0L, "RPC_StopProcess", new object[1] { completed }); } } private void RPC_StartProcess(long playerID, float startTime, float duration) { _processing = true; _startTime = startTime; _duration = duration; UpdateVisual(); } private void UpdateVisual() { _activeEffect.SetActive(_processing); } private void RPC_StopProcess(long playerID, bool completed) { _processing = false; UpdateVisual(); if (_nview.IsOwner()) { Save(); if (completed) { CraftItem(); } } } private void CraftItem() { foreach (SkyheimArmorRecipe recipe in Tuning.Recipes) { Inventory inventory = ((Container)_chest).GetInventory(); bool flag = false; ItemData item = inventory.GetItem(recipe.SourceItemDrop, -1, true); if (item != null && !item.m_customData.ContainsKey("sh_mod_eitr") && inventory.CountPrefabItems(Tuning.EitrShardPrefab) >= recipe.EitrShardsRequired) { inventory.RemovePrefabItem(Tuning.EitrShardPrefab, recipe.EitrShardsRequired); item.m_customData["sh_mod_type"] = ImbueType.Eitr.ToString(); item.m_customData["sh_mod_eitr"] = recipe.EitrModifier.ToString(); item.m_customData["sh_mod_eitr_regen"] = recipe.EitrRegenModifier.ToString(); item.m_customData["sh_mod_armor"] = recipe.ArmorModifier.ToString(); item.m_customData["sh_mod_name"] = "Imbued " + item.m_shared.m_name; flag = true; } if (flag) { ((Container)_chest).Save(); } } } protected void Update() { if (_processing) { if (TimeRemaining <= 0f) { FinishProcess(completed: true); OnProcessComplete?.Invoke(); } } else if (((Container)_chest).IsInUse() && ((Container)_chest).IsOwner()) { _inUse = true; } else if (_inUse && !((Container)_chest).IsInUse()) { _inUse = false; SkyheimArmorRecipe activeRecipe = GetActiveRecipe(); if (activeRecipe != null && HasEitrShards(activeRecipe)) { StartProcess(((Character)Player.m_localPlayer).InGodMode() ? 5f : activeRecipe.CraftingTime); } } } } public class ManaBar : MonoBehaviour { [SerializeField] [FormerlySerializedAs("m_manaBar")] private GameObject _manaBar; [SerializeField] [FormerlySerializedAs("m_manaAnimator")] private Animator _manaAnimator; [SerializeField] [FormerlySerializedAs("m_manaBar2Root")] private RectTransform _manaBar2Root; [SerializeField] [FormerlySerializedAs("m_manaBar2Fast")] private GuiBar _manaBar2Fast; [SerializeField] [FormerlySerializedAs("m_manaBar2Slow")] private GuiBar _manaBar2Slow; private readonly float _manaBarBorderBuffer = 16f; private void SetManaBarSize(float size) { _manaBar2Root.SetSizeWithCurrentAnchors((Axis)0, size + _manaBarBorderBuffer); _manaBar2Slow.SetWidth(size); _manaBar2Fast.SetWidth(size); } public void UpdateMana(Hud hud, float mana, float maxMana) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) _manaBar.SetActive(false); _manaAnimator.SetBool("Visible", mana < maxMana); SetManaBarSize(maxMana / 25f * 32f); Transform transform = ((Component)_manaBar2Root).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (hud.m_buildHud.activeSelf || hud.m_shipHudRoot.activeSelf) { val.anchoredPosition = new Vector2(0f, 158f); } else { val.anchoredPosition = new Vector2(0f, 98f); } _manaBar2Slow.SetValue(mana / maxMana); _manaBar2Fast.SetValue(mana / maxMana); } } public class RandomAttackOffset : SkyheimAttack { [SerializeField] private float _attackOffset; public override bool OnFiringProjectileBurst(Player player, Attack attack) { attack.m_attackOffset = Random.Range(0f - _attackOffset, _attackOffset); return true; } } public class ResetRotation : MonoBehaviour { protected void Start() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.rotation = Quaternion.identity; } protected void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.rotation = Quaternion.identity; } } [CreateAssetMenu(menuName = "Skyheim/SE/Barkskin")] public class SE_Barkskin : StatusEffect { [Header("SE_Barskin")] [SerializeField] private float _maxArmor; [SerializeField] private float _staminaMultiplier; [SerializeField] private float _maxArmorPerQuality; [SerializeField] private float _baseDuration; [SerializeField] private float _durationMultiplierPerSkillLevel; private int? _staminaModifier; private int _armorModifier; public float ArmorModifier => _armorModifier; public override void Setup(Character character) { base.m_character = character; Player val = (Player)(object)((character is Player) ? character : null); if (val != null) { _staminaModifier = GetStaminaModifier(val); ((Character)val).UseStamina((float)_staminaModifier.Value); } TriggerStartEffects(); } protected void TriggerStartEffects() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) ((StatusEffect)this).RemoveStartEffects(); Transform val = ((Component)base.m_character).transform; int num = -1; Character character = base.m_character; Player val2 = (Player)(object)((character is Player) ? character : null); if (val2 != null) { num = val2.GetPlayerModel(); val = ((Component)val2).GetComponent<VisEquipment>().m_backShield; } float radius = base.m_character.GetRadius(); base.m_startEffectInstances = base.m_startEffects.Create(base.m_character.GetCenterPoint(), ((Component)base.m_character).transform.rotation, val, radius * 2f, num); } public override void SetLevel(int itemLevel, float skillLevel) { float num = _staminaModifier ?? GetStaminaModifier(null); _armorModifier = Mathf.FloorToInt(Mathf.Min(num, _maxArmor + _maxArmorPerQuality * (float)(itemLevel - 1))); base.m_ttl = _baseDuration + _baseDuration * _durationMultiplierPerSkillLevel * skillLevel; ((StatusEffect)this).SetLevel(itemLevel, skillLevel); } public override string GetTooltipString() { string timeString = StatusEffect.GetTimeString(base.m_ttl, true, false); string text = SkyheimPlugin.L("$sh_se_rune_barskin_desc_detailed", _armorModifier, _staminaMultiplier * 100f, timeString); return base.m_tooltip + "\n" + text; } public float ModifyMaxStamina(float maxStamina) { return maxStamina * (1f - _staminaMultiplier); } private int GetStaminaModifier(Player player) { float num = (((Object)(object)player == (Object)null) ? Player.m_localPlayer.m_maxStamina : player.m_maxStamina); float num2 = num * (1f - _staminaMultiplier); return Mathf.FloorToInt(num - num2); } } [CreateAssetMenu(menuName = "Skyheim/SE/Frozen")] public class SE_Frozen : StatusEffect { public override void Setup(Character character) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) ((StatusEffect)this).Setup(character); GameObject[] startEffectInstances = base.m_startEffectInstances; for (int i = 0; i < startEffectInstances.Length; i++) { startEffectInstances[i].transform.localPosition = Vector3.zero; } } public override void UpdateStatusEffect(float dt) { ((StatusEffect)this).UpdateStatusEffect(dt); } public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 dir) { speed = 0f; } } [CreateAssetMenu(menuName = "Skyheim/SE/Heal")] public class SE_Heal : SE_Stats { [Header("SE_Heal")] [SerializeField] [Tooltip("Increases amount healed by x per quality.")] private float _healthPerQuality = 5f; [SerializeField] [Tooltip("Increases duration of effect by x% per skill level.")] private float _durationPerSkill = 0.01f; [SerializeField] [Tooltip("Base amount to heal.")] private float _baseHealth = 40f; [SerializeField] [Tooltip("Base duration.")] private float _baseDuration = 4f; public override void Setup(Character character) { ((SE_Stats)this).Setup(character); } public override void SetLevel(int itemLevel, float skillLevel) { float num = 1f + _durationPerSkill * skillLevel; base.m_healthOverTimeDuration = _baseDuration * num; ((StatusEffect)this).m_ttl = base.m_healthOverTimeDuration; base.m_healthOverTimeTicks = base.m_healthOverTimeDuration / base.m_healthOverTimeInterval; base.m_healthOverTimeTickHP = (_baseHealth + _healthPerQuality * (float)(itemLevel - 1)) / base.m_healthOverTimeTicks * num; ((StatusEffect)this).SetLevel(itemLevel, skillLevel); } public override string GetTooltipString() { int num = Mathf.CeilToInt(base.m_healthOverTimeTickHP * base.m_healthOverTimeTicks); string timeString = StatusEffect.GetTimeString(((StatusEffect)this).m_ttl, true, false); return ((StatusEffect)this).m_tooltip + "\n" + SkyheimPlugin.L("$sh_se_rune_heal_desc_detailed", num, timeString); } } [CreateAssetMenu(menuName = "Skyheim/SE/Windfury")] public class SE_Windfury : StatusEffect { [Header("SE_Windfury")] [SerializeField] [Tooltip("Proc Chance per item level.")] private float[] _procChance = new float[5] { 0.2f, 0.25f, 0.3f, 0.4f, 0.45f }; [SerializeField] private EffectList _onDamageDealtEffects; private float _currentProcChance = 0.2f; private GameObject[] _activeOnHitEffects; public override void Setup(Character character) { ((StatusEffect)this).Setup(character); } public override void SetLevel(int itemLevel, float skillLevel) { _currentProcChance = _procChance[itemLevel - 1]; ((StatusEffect)this).SetLevel(itemLevel, skillLevel); } public override string GetTooltipString() { float num = Mathf.CeilToInt(_currentProcChance * 100f); string text = SkyheimPlugin.L("$sh_se_rune_windfury_desc_detailed", num); return base.m_tooltip + "\n" + text; } public void OnDamageDealt(Character target, HitData hit) { Character attacker = hit.GetAttacker(); Humanoid val = (Humanoid)(object)((attacker is Humanoid) ? attacker : null); if (val != null && IsMeleeAttack(val.m_currentAttack) && Random.Range(0f, 1f) <= _currentProcChance) { ApplyOnHitEffect(); HitData val2 = hit.Clone(); target.m_nview.InvokeRPC("RPC_Damage", new object[1] { val2 }); } static bool IsMeleeAttack(Attack attack) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if ((int)attack.m_attackType != 0) { return (int)attack.m_attackType == 1; } return true; } } public override void Stop() { ((StatusEffect)this).Stop(); RemoveOnHitEffects(); } private void RemoveOnHitEffects() { if (_activeOnHitEffects == null || !((Object)(object)ZNetScene.instance != (Object)null)) { return; } GameObject[] activeOnHitEffects = _activeOnHitEffects; foreach (GameObject val in activeOnHitEffects) { if (Object.op_Implicit((Object)(object)val)) { ZNetView component = val.GetComponent<ZNetView>(); if (component.IsValid()) { component.ClaimOwnership(); component.Destroy(); } } } _activeOnHitEffects = null; } private void ApplyOnHitEffect() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) RemoveOnHitEffects(); float radius = base.m_character.GetRadius(); Character character = base.m_character; Player val = (Player)(object)((character is Player) ? character : null); int num = ((val != null) ? val.GetPlayerModel() : (-1)); _activeOnHitEffects = _onDamageDealtEffects.Create(base.m_character.GetCenterPoint(), ((Component)base.m_character).transform.rotation, ((Component)base.m_character).transform, radius * 2f, num); } } public class SkyheimAltarContainer : Container, Hoverable, Interactable { private SkyheimAltar _parent; protected void Awake() { ((Container)this).Awake(); _parent = ((Component)this).GetComponentInParent<SkyheimAltar>(); if (Object.op_Implicit((Object)(object)base.m_nview)) { base.m_nview.Unregister("OpenRespons"); base.m_nview.Register<bool>("OpenRespons", (Action<long, bool>)RPC_OpenRespons); } } public void RPC_OpenRespons(long uid, bool granted) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { if (granted) { InventoryGui.instance.Show((Container)(object)this, 1); SkyheimAltarPanel.Instance.Show(_parent); } else { ((Character)Player.m_localPlayer).Message((MessageType)2, "$msg_inuse", 0, (Sprite)null); } } } } public class SkyheimAltarPanel : MonoBehaviour { public static SkyheimAltarPanel Instance; [SerializeField] private Transform _leftRoot; [SerializeField] private Transform _rightRoot; [SerializeField] private Text _header; [SerializeField] private Text _timeText; [SerializeField] private Text _descriptionText; private static GameObject s_inventoryElement; private Element _leftSlot; private Element _rightSlot; private Container _container; private SkyheimAltar _altar; private long _containerRevision; public static void Bind(Harmony harmony) { harmony.PatchAll(typeof(SkyheimAltarPanel)); } public void Show(SkyheimAltar altar) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (_leftSlot == null && _rightSlot == null) { _leftSlot = CreateElement(_leftRoot, new Vector2i(0, 0)); _rightSlot = CreateElement(_rightRoot, new Vector2i(1, 0)); } _altar = altar; _container = (Container)(object)altar.Container; _containerRevision = _container.m_lastRevision; _header.text = _container.GetHoverName(); _altar.OnProcessComplete = delegate { UpdateGui(); }; ((Component)this).gameObject.SetActive(true); UpdateGui(); } protected void SetTimeRemaining(float t) { t = Mathf.Floor(t); string timeString = StatusEffect.GetTimeString(t, true, false); _timeText.text = SkyheimPlugin.L("$sh_altar_time_remaining", timeString); } protected void Awake() { InventoryGrid playerGrid = InventoryGui.instance.m_playerGrid; playerGrid.m_onSelected = (Action<InventoryGrid, ItemData, Vector2i, Modifier>)Delegate.Combine(playerGrid.m_onSelected, new Action<InventoryGrid, ItemData, Vector2i, Modifier>(OnSelected)); } protected void Update() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_container != (Object)null && _container.IsOwner()) { InventoryGui instance = InventoryGui.instance; _container.SetInUse(true); ((Component)instance.m_container).gameObject.SetActive(false); instance.m_containerGrid.UpdateInventory(_container.GetInventory(), (Player)null, instance.m_dragItem); if (instance.m_firstContainerUpdate) { instance.m_containerGrid.ResetView(); instance.m_firstContainerUpdate = false; } float autoCloseDistance = instance.m_autoCloseDistance; if (Vector3.Distance(((Component)_container).transform.position, ((Component)Player.m_localPlayer).transform.position) > autoCloseDistance) { Close(); } } if ((Object)(object)_altar != (Object)null && _altar.Processing) { SetTimeRemaining(_altar.TimeRemaining); } } private Element CreateElement(Transform parent, Vector2i position) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown GameObject val = Object.Instantiate<GameObject>(s_inventoryElement, parent); Transform transform = val.transform; ((RectTransform)((transform is RectTransform) ? transform : null)).anchoredPosition = Vector2.zero; ((Behaviour)((Component)val.transform.Find("binding")).GetComponent<TMP_Text>()).enabled = false; val.GetComponentInChildren<UIInputHandler>().m_onLeftDown = OnLeftClick; return new Element { m_pos = position, m_go = val, m_icon = ((Component)val.transform.Find("icon")).GetComponent<Image>(), m_amount = ((Component)val.transform.Find("amount")).GetComponent<TMP_Text>(), m_quality = ((Component)val.transform.Find("quality")).GetComponent<TMP_Text>(), m_equiped = ((Component)val.transform.Find("equiped")).GetComponent<Image>(), m_queued = ((Component)val.transform.Find("queued")).GetComponent<Image>(), m_noteleport = ((Component)val.transform.Find("noteleport")).GetComponent<Image>(), m_food = ((Component)val.transform.Find("foodicon")).GetComponent<Image>(), m_selected = ((Component)val.transform.Find("selected")).gameObject, m_tooltip = val.GetComponent<UITooltip>(), m_durability = ((Component)val.transform.Find("durability")).GetComponent<GuiBar>() }; } private void UpdateSlot(Element element) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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) ItemData itemAt = _container.GetInventory().GetItemAt(element.m_pos.x, element.m_pos.y); if (itemAt != null) { ((Behaviour)element.m_icon).enabled = true; element.m_icon.sprite = itemAt.GetIcon(); ((Graphic)element.m_icon).color = Color.white; bool flag = itemAt.m_shared.m_useDurability && itemAt.m_durability < itemAt.GetMaxDurability(); ((Component)element.m_durability).gameObject.SetActive(flag); if (flag) { if (itemAt.m_durability <= 0f) { element.m_durability.SetValue(1f); element.m_durability.SetColor((Color)((Mathf.Sin(Time.time * 10f) > 0f) ? Color.red : new Color(0f, 0f, 0f, 0f))); } else { element.m_durability.SetValue(itemAt.GetDurabilityPercentage()); element.m_durability.ResetColor(); } } ((Behaviour)element.m_equiped).enabled = false; ((Behaviour)element.m_queued).enabled = false; ((Behaviour)element.m_noteleport).enabled = !itemAt.m_shared.m_teleportable; ((Behaviour)element.m_food).enabled = false; ((Behaviour)element.m_quality).enabled = itemAt.m_shared.m_maxQuality > 1; if (itemAt.m_shared.m_maxQuality > 1) { element.m_quality.text = itemAt.m_quality.ToString(); } ((Behaviour)element.m_amount).enabled = itemAt.m_shared.m_maxStackSize > 1; if (itemAt.m_shared.m_maxStackSize > 1) { element.m_amount.text = $"{itemAt.m_stack}/{itemAt.m_shared.m_maxStackSize}"; } } else { ((Component)element.m_durability).gameObject.SetActive(false); ((Behaviour)element.m_icon).enabled = false; ((Behaviour)element.m_amount).enabled = false; ((Behaviour)element.m_quality).enabled = false; ((Behaviour)element.m_equiped).enabled = false; ((Behaviour)element.m_queued).enabled = false; ((Behaviour)element.m_noteleport).enabled = false; ((Behaviour)element.m_food).enabled = false; element.m_tooltip.m_text = ""; element.m_tooltip.m_topic = ""; } } private void CheckRevisionChanged() { if (_container.m_lastRevision != _containerRevision) { _containerRevision = _container.m_lastRevision; _altar.CancelProcess(); } } private void OnLeftClick(UIInputHandler clickHandler) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)clickHandler).gameObject; Vector2i buttonPos = GetButtonPos(gameObject); ItemData itemAt = _container.GetInventory().GetItemAt(buttonPos.x, buttonPos.y); Modifier val = (Modifier)0; InventoryGrid containerGrid = InventoryGui.instance.m_containerGrid; InventoryGui.instance.OnSelectedItem(containerGrid, itemAt, buttonPos, val); CheckRevisionChanged(); UpdateGui(); } private void OnSelected(InventoryGrid grid, ItemData data, Vector2i i, Modifier modifier) { if (((Component)this).gameObject.activeSelf) { CheckRevisionChanged(); UpdateGui(); } } private Vector2i GetButtonPos(GameObject gameObject) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_leftSlot.m_go == (Object)(object)gameObject)) { return _rightSlot.m_pos; } return _leftSlot.m_pos; } protected void OnDisable() { _altar.OnProcessComplete = null; _container.SetInUse(false); ((Component)this).gameObject.SetActive(false); } private void UpdateGui() { UpdateSlot(_leftSlot); UpdateSlot(_rightSlot); SkyheimArmorRecipe skyheimArmorRecipe = (((Object)(object)_altar != (Object)null) ? _altar.GetActiveRecipe() : null); _descriptionText.text = ((skyheimArmorRecipe != null) ? skyheimArmorRecipe.GetImbueTooltip() : string.Empty); if (_altar.Processing) { return; } if (skyheimArmorRecipe != null) { if (_altar.HasEitrShards(skyheimArmorRecipe)) { _timeText.text = SkyheimPlugin.L("$sh_altar_close_to_start"); } else { _timeText.text = SkyheimPlugin.L("$sh_altar_needs_more_shards"); } } else { _timeText.text = SkyheimPlugin.L("$sh_altar_place_armor"); } } private void Close() { ((Component)this).gameObject.SetActive(false); InventoryGui.instance.CloseContainer(); } [HarmonyPatch(typeof(InventoryGui), "Awake")] [HarmonyPostfix] protected static void InventoryGui_Awake_Postfix(InventoryGui __instance) { GameObject obj = Object.Instantiate<GameObject>(AssetManager.GetGameObject("altar_panel"), ((Component)__instance.m_inventoryRoot).transform); Instance = obj.GetComponent<SkyheimAltarPanel>(); UIGroupHandler component = obj.GetComponent<UIGroupHandler>(); CollectionExtensions.AddItem<UIGroupHandler>((IEnumerable<UIGroupHandler>)__instance.m_uiGroups, component); s_inventoryElement = __instance.m_containerGrid.m_elementPrefab; int siblingIndex = ((Transform)__instance.m_container).GetSiblingIndex(); obj.transform.SetSiblingIndex(siblingIndex + 1); } [HarmonyPatch(typeof(InventoryGui), "UpdateContainer")] [HarmonyPrefix] protected static bool InventoryGui_UpdateContainer_Prefix() { return !((Component)Instance).gameObject.activeSelf; } } [CreateAssetMenu(menuName = "Skyheim/Altar Tuning")] public class SkyheimAltarTuning : ScriptableObject, ISerializationCallbackReceiver { [PrefabReferenceType(typeof(ItemDrop))] public string EitrShardPrefab; public List<SkyheimArmorRecipe> Recipes; [SerializeField] [HideInInspector] private string _recipesInternal; public void RuntimeDeserialize() { JSONNode jSONNode = JSONNode.Parse(_recipesInternal); Recipes = new List<SkyheimArmorRecipe>(); JSONNode.Enumerator enumerator = jSONNode.AsArray.GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<string, JSONNode> current = enumerator.Current; Recipes.Add(new SkyheimArmorRecipe(current.Value)); } } public void OnBeforeSerialize() { if (Recipes != null) { JSONNode jSONNode = CommonUtils.ToJSON(Recipes); _recipesInternal = jSONNode.ToString(); } } public void OnAfterDeserialize() { } } [Serializable] public class SkyheimArmorRecipe { public string SourceItemDrop; public int EitrShardsRequired; public float EitrModifier; public float EitrRegenModifier; public float ArmorModifier; public float CraftingTime = 30f; public SkyheimArmorRecipe() { } public SkyheimArmorRecipe(JSONNode j) { SourceItemDrop = j["SourceItemDrop"]; EitrShardsRequired = j["EitrShardsRequired"]; EitrModifier = j["EitrModifier"]; EitrRegenModifier = j["EitrRegenModifier"]; ArmorModifier = j["ArmorModifier"]; CraftingTime = j["CraftingTime"]; } public string GetImbueTooltip() { string text = $"Eitr Shards Required: <color=orange>{EitrShardsRequired}</color>\nMaximum Eitr: <color=orange>+{EitrModifier}</color>"; if (EitrRegenModifier != 0f) { text += $"\nEitr Regen Modifier: <color=orange>+{EitrRegenModifier * 100f}%</color>"; } if (ArmorModifier != 0f) { text += $"\nArmor Modifier: <color=orange>-{ArmorModifier * 100f}%</color>"; } string timeString = StatusEffect.GetTimeString(CraftingTime, true, true); return text + "\nTime to Craft: <color=orange>" + timeString + "</color>"; } } public class SkyheimAttack : MonoBehaviour { public virtual bool OnAttackStart(Attack attack, Player player, ItemData weapon) { return true; } public virtual void OnAttackStarted(Player player, Attack attack) { } public virtual bool OnAttackTrigger(Player player, Attack attack) { return true; } public virtual void OnAttackUpdate(Player player, Attack attack, float dt) { } public virtual bool OnFiringProjectileBurst(Player player, Attack attack) { return true; } public virtual void OnProjectileFired(Player player, Attack attack, IProjectile projectile) { } public virtual void OnAttackStop(Player player, Attack attack) { } } public class SkyheimAttackBlink : SkyheimAttack { public float Speed = 2f; public override void OnAttackStarted(Player player, Attack attack) { attack.m_zanim.SetSpeed(Speed); } public override bool OnAttackTrigger(Player player, Attack attack) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0095: 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_0098: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00fe: Unknown result type (might be due to invalid IL or missing references) int mask = LayerMask.GetMask(new string[12] { "Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox", "character_noenv", "vehicle" }); Vector3 val = ((Component)player).transform.position + ((Component)player).transform.up * 1.5f; Vector3 aimDir = ((Humanoid)player).GetAimDir(val); float num = 15f + (float)(attack.GetWeapon().m_quality - 1) * 5f; RaycastHit val2 = default(RaycastHit); Vector3 val3 = (Physics.Raycast(val, aimDir, ref val2, num, mask, (QueryTriggerInteraction)1) ? (((RaycastHit)(ref val2)).point + aimDir * -1f) : (val + aimDir * num)); player.m_teleportCooldown = 2f; ((Character)player).TeleportTo(val3, ((Character)player).GetLookYaw(), false); player.m_teleportTimer = 20f; return true; } } public class SkyheimAttackChainLightning : SkyheimAttack { public float Range = 25f; private readonly Dictionary<Attack, GameObject> _targets = new Dictionary<Attack, GameObject>(); public override bool OnAttackStart(Attack attack, Player player, ItemData weapon) { GameObject attackProjectile = weapon.m_shared.m_attack.m_attackProjectile; if ((Object)(object)attackProjectile == (Object)null) { return false; } GameObject target = GetTarget(player, attackProjectile.GetComponent<IProjectile>()); if ((Object)(object)target == (Object)null) { ((Character)player).Message((MessageType)2, "No target in range", 0, (Sprite)null); return false; } _targets[attack] = target; return true; } private GameObject GetTarget(Player player, IProjectile projectile) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) ChainAoe chainAoe = projectile as ChainAoe; if ((Object)(object)chainAoe == (Object)null) { return null; } int rayMask = chainAoe.GetRayMask(); Vector3 centerPoint = ((Character)player).GetCenterPoint(); Vector3 val = centerPoint + ((Humanoid)player).GetAimDir(centerPoint) * Range; Collider[] array = Physics.OverlapCapsule(centerPoint, val, 1f, rayMask, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { GameObject val2 = Projectile.FindHitObject(array[i]); if (Object.op_Implicit((Object)(object)val2) && chainAoe.IsValidTarget((Character)(object)player, val2)) { return val2; } } return null; } public override void OnProjectileFired(Player player, Attack attack, IProjectile projectile) { _targets.TryGetValue(attack, out var value); if ((Object)(object)value != (Object)null) { _targets.Remove(attack); ChainAoe chainAoe = projectile as ChainAoe; if ((Object)(object)chainAoe != (Object)null) { chainAoe.Trigger(value); } } } } public class SkyheimAttackGlacialSpike : SkyheimAttack { [SerializeField] private float _attackOffset; [SerializeField] private int _baseProjectileBursts = 3; [SerializeField] private int _projectileBurstPerQuality = 1; [SerializeField] private EffectList _spawnEffects = new EffectList(); private bool _attackTriggered; public override bool OnAttackStart(Attack attack, Player player, ItemData weapon) { weapon.m_shared.m_attack.m_projectileBursts = _baseProjectileBursts + _projectileBurstPerQuality * (weapon.m_quality - 1); return true; } public override bool OnAttackTrigger(Player player, Attack attack) { _attackTriggered = true; return true; } public override void OnAttackUpdate(Player player, Attack attack, float dt) { if (_attackTriggered && attack.m_attackDone) { if (attack.m_projectileBurstsFired < attack.m_projectileBursts) { attack.UpdateProjectile(dt); } else { _attackTriggered = false; } } } public override bool OnFiringProjectileBurst(Player player, Attack attack) { //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) _spawnEffects.Create(((Component)player).transform.position, ((Component)player).transform.rotation, (Transform)null, 1f, -1); float attackOffset = Random.Range(0f - _attackOffset, _attackOffset); attack.m_attackOffset = attackOffset; return true; } } public class SkyheimAttackGoodberry : SkyheimAttack { [SerializeField] private ItemDrop _spawnItem; public override bool OnAttackTrigger(Player player, Attack attack) { if ((Object)(object)_spawnItem != (Object)null) { ItemData val = _spawnItem.m_itemData.Clone(); val.m_dropPrefab = ((Component)_spawnItem).gameObject; val.m_stack = attack.m_weapon.m_quality; ((Humanoid)player).GetInventory().AddItem(val); } return true; } } public class SkyheimAttackInvigorate : SkyheimAttack { [SerializeField] private SE_Stats _statusEffect; public override bool OnAttackTrigger(Player player, Attack attack) { float num = Mathf.Max(0f, (float)(attack.GetWeapon().m_quality - 1)); _statusEffect.m_staminaOverTimeDuration = 10f + 10f * num; ((StatusEffect)_statusEffect).m_ttl = _statusEffect.m_staminaOverTimeDuration; _statusEffect.m_staminaOverTime = 20f + 25f * num; ((Character)player).GetSEMan().AddStatusEffect((StatusEffect)(object)_statusEffect, true, 0, 0f); float num2 = 0.2f + num * 0.05f; ((Character)player).AddStamina(((Character)player).GetMaxStamina() * num2); return true; } } public class SkyheimAttackLight : SkyheimAttack { private float _cooldownStart; public override bool OnAttackStart(Attack attack, Player player, ItemData weapon) { if (_cooldownStart > 0f && Time.time - _cooldownStart < 0.5f) { return false; } _cooldownStart = Time.time; GameObject lastProjectile = weapon.m_lastProjectile; if ((Object)(object)lastProjectile != (Object)null) { ZNetScene.instance.Destroy(lastProjectile); weapon.m_lastProjectile = null; return false; } return true; } } public class SkyheimAttackRecall : SkyheimAttack { public override bool OnAttackStart(Attack attack, Player player, ItemData weapon) { if (!((Humanoid)player).IsTeleportable()) { ((Character)player).Message((MessageType)1, "An item prevents you from teleporting.", 0, (Sprite)null); return false; } return true; } public override bool OnAttackTrigger(Player player, Attack attack) { Game.instance.RequestRespawn(1.25f, false); return true; } } public class SkyheimAttackStatusEffect : SkyheimAttack { [SerializeField] private StatusEffect _statusEffect; public override bool OnAttackTrigger(Player player, Attack attack) { if ((Object)(object)_statusEffect != (Object)null) { int quality = attack.GetWeapon().m_quality; ((Character)player).GetSEMan().AddStatusEffect(_statusEffect, true, quality, 0f); } return true; } } public class SkyheimCooldownItem : MonoBehaviour { [SerializeField] private Text _text; [SerializeField] private Image _swipe; public Vector2i Location { get; private set; } = new Vector2i(-1, -1); public void SetCooldown(float duration, float pct) { _text.text = ((duration > 0f) ? StatusEffect.GetTimeString(duration, false, false) : string.Empty); _swipe.fillAmount = pct; } public void Awake() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) InventoryGrid componentInParent = ((Component)this).GetComponentInParent<InventoryGrid>(); if (componentInParent != null) { int count = componentInParent.m_elements.Count; int width = componentInParent.m_width; int num = count / width; Location = new Vector2i(count - num * width, num); } else { HotkeyBar componentInParent2 = ((Component)this).GetComponentInParent<HotkeyBar>(); if (componentInParent2 != null) { Location = new Vector2i(componentInParent2.m_elements.Count, 0); } } } public void OnEnable() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (Location.x >= 0 && Location.y >= 0) { SkyheimCooldown.Instance.RegisterUpdateable(this); } SetCooldown(0f, 0f); } public void OnDisable() { SkyheimCooldown.Instance.UnregisterUpdateable(this); SetCooldown(0f, 0f); } } public class SkyheimItemData : MonoBehaviour { public enum ESkillType { None = 0, Swords = 1, Knives = 2, Clubs = 3, Polearms = 4, Spears = 5, Blocking = 6, Axes = 7, Bows = 8, vFireMagic = 9, vFrostMagic = 10, Unarmed = 11, Pickaxes = 12, WoodCutting = 13, Jump = 100, Sneak = 101, Run = 102, Swim = 103, NatureMagic = 200, HolyMagic = 201, FireMagic = 202, FrostMagic = 203, All = 999 } public ESkillType SkillType; public float ManaUsed; public float ManaDrain; public float Cooldown; public bool Beneficial; protected void Awake() { ItemDrop component = ((Component)this).GetComponent<ItemDrop>(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(SkyheimPlugin.L(component.m_itemData.m_shared.m_description)); if (Cooldown > 0f) { stringBuilder.AppendLine(SkyheimPlugin.L("$sh_item_cooldown", StatusEffect.GetTimeString(Cooldown, true, false))); } if (ManaDrain > 0f) { stringBuilder.AppendLine(SkyheimPlugin.L("$sh_item_eitr_drain", ManaDrain)); } component.m_itemData.m_shared.m_description = stringBuilder.ToString(); } } [CreateAssetMenu(menuName = "Skyheim/Tuning")] public class SkyheimTuning : ScriptableObject { private static SkyheimTuning s_instance; public static SkyheimTuning Tuning { get { if ((Object)(object)s_instance == (Object)null) { s_instance = AssetManager.GetAsset<SkyheimTuning>("skyheim_tuning"); } return s_instance; } } } public static class InventoryExtensions { public static int CountPrefabItems(this Inventory inventory, string name) { return inventory.GetAllItems().Sum((ItemData x) => (((Object)x.m_dropPrefab).name == name) ? x.m_stack : 0); } public static void RemovePrefabItem(this Inventory inventory, string name, int count) { ItemData item = inventory.GetItem(name, -1, true); inventory.RemoveItem(item.m_shared.m_name, count, -1, true); } public static bool HasResources(this Inventory inventory, List<SkyheimRecipe.SkyheimRequirement> resources) { foreach (SkyheimRecipe.SkyheimRequirement resource in resources) { if (inventory.CountPrefabItems(resource.ResourceItem) <= resource.Amount) { return false; } } return true; } public static void RemoveResources(this Inventory inventory, List<SkyheimRecipe.SkyheimRequirement> resources) { foreach (SkyheimRecipe.SkyheimRequirement resource in resources) { inventory.RemovePrefabItem(resource.ResourceItem, resource.Amount); } } } namespace skyheim { public class SkyheimArmor { public static void Create(Harmony harmony) { harmony.PatchAll(typeof(SkyheimArmor)); } [HarmonyPatch(typeof(Player), "SetMaxEitr")] [HarmonyPrefix] public static bool Player_SetMaxEitr_Prefix(Player __instance, ref float eitr) { float totalModifier = 0f; AccumulateItem(((Humanoid)__instance).m_chestItem); AccumulateItem(((Humanoid)__instance).m_helmetItem); AccumulateItem(((Humanoid)__instance).m_legItem); eitr += totalModifier; return true; void AccumulateItem(ItemData data) { if (data != null) { totalModifier += data.m_customData.Get("sh_mod_eitr", 0); } } } [HarmonyPatch(typeof(Player), "GetEquipmentEitrRegenModifier")] [HarmonyPostfix] public static void Player_GetEquipmentEitrRegenModifier_Postfix(Player __instance, ref float __result) { float totalModifier = 0f; AccumulateItem(((Humanoid)__instance).m_chestItem); AccumulateItem(((Humanoid)__instance).m_helmetItem); AccumulateItem(((Humanoid)__instance).m_legItem); __result += totalModifier; void AccumulateItem(ItemData data) { if (data != null) { totalModifier += data.m_customData.Get("sh_mod_eitr_regen", 0f); } } } [HarmonyPatch(typeof(ItemDrop), "GetHoverName")] [HarmonyPostfix] public static void ItemDrop_GetHoverName_Postfix(ItemDrop __instance, ref string __result) { if (__instance.m_itemData != null) { __result = Localization.instance.Localize(__instance.m_itemData.m_customData.Get("sh_mod_name", __result)); } } [HarmonyPatch(typeof(ItemDrop), "GetHoverText")] [HarmonyPostfix] public static void ItemDrop_GetHoverText_Postfix(ItemDrop __instance, ref string __result) { if (__instance.m_itemData != null) { string text = __instance.m_itemData.m_customData.Get<string>("sh_mod_name"); if (text != null) { string oldValue = Localization.instance.Localize(__instance.m_itemData.m_shared.m_name); __result = Localization.instance.Localize(__result.Replace(oldValue, text)); } } } [HarmonyPatch(typeof(ItemData), "GetArmor", new Type[] { typeof(int), typeof(float) })] [HarmonyPostfix] public static void ItemDrop_GetArmor_Postfix(ItemData __instance, ref float __result) { float num = __instance.m_customData.Get("sh_mod_armor", 0f); __result = Mathf.Round(Mathf.Max(1f, __result - __result * num)); } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(int) })] [HarmonyPostfix] public static void ItemDrop_GetTooltip_Postfix(ItemData __instance, ref string __result) { string text = __instance.m_customData.Get<string>("sh_mod_eitr"); if (text != null) { StringBuilder stringBuilder = new StringBuilder("\n\n"); stringBuilder.AppendLine(SkyheimPlugin.L("$sh_armor_eitr_imbued")); stringBuilder.AppendLine(SkyheimPlugin.L("$sh_armor_mod_eitr_max", text)); float num = __instance.m_customData.Get("sh_mod_eitr_regen", 0f); if (num > 0f) { stringBuilder.AppendLine(SkyheimPlugin.L("$sh_armor_mod_eitr_regen", (int)(num * 100f))); } float num2 = __instance.m_customData.Get("sh_mod_armor", 0f); if (num2 > 0f) { stringBuilder.AppendLine(SkyheimPlugin.L("$sh_armor_mod_reduced_armor", (int)(num2 * 100f))); } __result += stringBuilder; } } [HarmonyPatch(typeof(InventoryGrid), "CreateItemTooltip")] [HarmonyPrefix] public static bool InventoryGrid_CreateItemTooltip_Prefix(InventoryGrid __instance, ItemData item, UITooltip tooltip) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) string text = item.m_customData.Get("sh_mod_name", item.m_shared.m_name); tooltip.Set(text, item.GetTooltip(-1), __instance.m_tooltipAnchor, default(Vector2)); return false; } } public class SkyheimCooldown { public class Cooldown { public float Value; public static implicit operator Cooldown(float f) { return new Cooldown { Value = f }; } public static implicit operator float(Cooldown c) { return c.Value; } public override string ToString() { return Value.ToString(); } } public static SkyheimCooldown Instance; private readonly GameObject _cooldownPrefab; private readonly Dictionary<string, Cooldown> _cooldowns = new Dictionary<string, Cooldown>(); private readonly List<SkyheimCooldownItem> _updateables = new List<SkyheimCooldownItem>(); private const string COOLDOWN_PREFIX = "sh_"; public static void Create(Harmony harmony) { harmony.PatchAll(typeof(SkyheimCooldown)); Instance = new SkyheimCooldown(); } public SkyheimCooldown() { _cooldownPrefab = AssetManager.GetGameObject("item_cooldown"); SkyheimPlugin.Instance.OnUpdate += Update; } public void SetCooldown(string id, float duration) { _cooldowns[id] = duration; } public float GetCooldown(string id) { if (!_cooldowns.TryGetValue(id, out var value)) { return 0f; } return value.Value; } public bool OnAttackStart(ItemData weapon) { SkyheimItemData itemComponent = CommonUtils.GetItemComponent<SkyheimItemData>(weapon); if ((Object)(object)itemComponent != (Object)null && itemComponent.Cooldown > 0f) { return GetCooldown(((Object)itemComponent).name) <= 0f; } return true; } public void OnAttackTrigger(SkyheimItemData itemData) { if ((Object)(object)itemData != (Object)null && itemData.Cooldown > 0f) { SetCooldown(((Object)itemData).name, itemData.Cooldown); } } public void RegisterUpdateable(SkyheimCooldownItem item) { if (!_updateables.Contains(item)) { _updateables.Add(item); } } public void UnregisterUpdateable(SkyheimCooldownItem item) { _updateables.Remove(item); } public void Update(float dt) { //IL_008b: 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) foreach (KeyValuePair<string, Cooldown> cooldown2 in _cooldowns) { Cooldown value = cooldown2.Value; float value2 = Mathf.Max(0f, (float)cooldown2.Value - dt); value.Value = value2; } if (!((Object)(object)Player.m_localPlayer != (Object)null)) { return; } Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); foreach (SkyheimCooldownItem updateable in _updateables) { SkyheimItemData itemComponent = CommonUtils.GetItemComponent<SkyheimItemData>(inventory.GetItemAt(updateable.Location.x, updateable.Location.y)); if ((Object)(object)itemComponent != (Object)null && itemComponent.Cooldown > 0f) { float cooldown = GetCooldown(((Object)itemComponent).name); updateable.SetCooldown(cooldown, cooldown / itemComponent.Cooldown); } else { updateable.SetCooldown(0f, 0f); } } } public List<string> SaveCooldowns(Dictionary<string, string> data) { List<string> list = new List<string>(); foreach (KeyValuePair<string, Cooldown> cooldown in _cooldowns) { if ((float)cooldown.Value > 30f) { string key = "sh_" + cooldown.Key; data[key] = cooldown.Value.ToString(); list.Add(cooldown.Key); } } return list; } public void LoadCooldowns(Dictionary<string, string> data) { _cooldowns.Clear(); List<string> list = new List<string>(); foreach (KeyValuePair<string, string> datum in data) { if (datum.Key.StartsWith("sh_")) { string key = datum.Key.Substring("sh_".Length); _cooldowns[key] = float.Parse(datum.Value); list.Add(datum.Key); } } foreach (string item in list) { data.Remove(item); } } [HarmonyPatch(typeof(InventoryGui), "Awake")] [HarmonyPostfix] public static void InventoryGui_Awake_Postfix(InventoryGui __instance) { InventoryGrid componentInChildren = ((Component)__instance.m_player).GetComponentInChildren<InventoryGrid>(); GameObject val = Object.Instantiate<GameObject>(componentInChildren.m_elementPrefab); val.GetComponent<UITooltip>().m_text = string.Empty; Object.Instantiate<GameObject>(Instance._cooldownPrefab, val.transform); componentInChildren.m_elementPrefab = val; } [HarmonyPatch(typeof(Hud), "Awake")] [HarmonyPostfix] public static void Hud_Awake_Postfix(Hud __instance) { HotkeyBar componentInChildren = ((Component)((Component)__instance).transform).GetComponentInChildren<HotkeyBar>(); GameObject val = Object.Instantiate<GameObject>(componentInChildren.m_elementPrefab); Object.Instantiate<GameObject>(Instance._cooldownPrefab, val.transform); componentInChildren.m_elementPrefab = val; } [HarmonyPatch(typeof(Player), "Save")] [HarmonyPrefix] public static void Player_Save_Prefix(Player __instance, out List<string> __state) { __state = Instance.SaveCooldowns(__instance.m_knownTexts); } [HarmonyPatch(typeof(Player), "Save")] [HarmonyPostfix] public static void Player_Save_Postfix(Player __instance, List<string> __state) { foreach (string item in __state) { __instance.m_knownTexts.Remove(item); } } [HarmonyPatch(typeof(Player), "Load")] [HarmonyPostfix] public static void Player_Load_Postfix(Player __instance) { Instance.LoadCooldowns(__instance.m_knownTexts); } } public delegate void UpdateEvent(float dt); [BepInPlugin("skyheim", "Skyheim", "1.3.12")] public class SkyheimPlugin : BaseUnityPlugin { public static SkyheimPlugin Instance; private Harmony _harmony; private static readonly int _statusEffectBarkskin = StringExtensionMethods.GetStableHashCode("se_rune_barkskin"); private static readonly int _statusEffectWarmth = StringExtensionMethods.GetStableHashCode("se_rune_warmth"); private static readonly int _statusEffectWindfury = StringExtensionMethods.GetStableHashCode("se_rune_windfury"); public event UpdateEvent OnUpdate; public static string L(string key, params object[] values) { string[] array = values.Select((object x) => $"{x}").ToArray(); return Localization.instance.Localize(key, array); } public static string L(string key) { return Localization.instance.Localize(key); } protected void Awake() { Instance = this; _harmony = Harmony.CreateAndPatchAll(typeof(SkyheimPlugin), (string)null); AssetManager.Create(_harmony, "skyheim"); AssetManager.OnSceneAwake = OnSceneAwake; SkyheimSkills.Create(_harmony); SkyheimCooldown.Create(_harmony); SkyheimArmor.Create(_harmony); SkyheimAltarPanel.Bind(_harmony); } protected void Update() { this.OnUpdate?.Invoke(Time.deltaTime); } protected void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchAll((string)null); } } private void OnSceneAwake(ZNetScene _) { ApplyDropModifiers(); } private static string GetAssemblyDirectory() { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } private void ApplyDropModifiers() { foreach (DropModifier asset in AssetManager.GetAssets<DropModifier>()) { asset.Apply(); } } private static void ApplyLocalization() { try { StreamReader streamReader = new StreamReader(Path.Combine(GetAssemblyDirectory(), "skyheim.json")); string aJSON = streamReader.ReadToEnd(); streamReader.Close(); JSONNode jSONNode = JSON.Parse(aJSON); string selectedLanguage = Localization.instance.GetSelectedLanguage(); JSONNode.Enumerator enumerator = (jSONNode.GetValueOrDefault(selectedLanguage, null) ?? jSONNode["English"]).GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<string, JSONNode> current = enumerator.Current; Localization.instance.AddWord(current.Key, (string)current.Value); } } catch (Exception) { } } [HarmonyPatch(typeof(SE_Wet), "UpdateStatusEffect")] [HarmonyPostfix] public static void SE_Wet_UpdateStatusEffect_Postfix(SE_Wet __instance, float dt) { if (((StatusEffect)__instance).m_character.m_seman.HaveStatusEffect(_statusEffectWarmth)) { ((StatusEffect)__instance).m_time = ((StatusEffect)__instance).m_time + dt * 10f; } } [HarmonyPatch(typeof(EnvMan), "CalculateWet")] [HarmonyPostfix] public static void EnvMan_CalculateWet_Postfix(ref bool __result) { if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).m_seman.HaveStatusEffect(_statusEffectWarmth)) { __result = false; } } [HarmonyPatch(typeof(Character), "RPC_Damage")] [HarmonyPrefix] public static void Character_RPC_Damage_Prefix(Character __instance, HitData hit) { if (hit.m_statusEffectHash != 0) { __instance.m_seman.RemoveStatusEffect(hit.m_statusEffectHash, true); } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] [HarmonyPostfix] public static void Player_GetBodyArmor_Postfix(Player __instance, ref float __result) { StatusEffect statusEffect = ((Character)__instance).m_seman.GetStatusEffect(_statusEffectBarkskin); if ((Object)(object)statusEffect != (Object)null && statusEffect is SE_Barkskin sE_Barkskin) { __result += sE_Barkskin.ArmorModifier; } } [HarmonyPatch(typeof(Player), "GetMaxStamina")] [HarmonyPostfix] public static void Player_GetMaxStamina_Postfix(Player __instance, ref float __result) { StatusEffect statusEffect = ((Character)__instance).m_seman.GetStatusEffect(_statusEffectBarkskin); if ((Object)(object)statusEffect != (Object)null && statusEffect is SE_Barkskin sE_Barkskin) { __result = sE_Barkskin.ModifyMaxStamina(__result); } } [HarmonyPatch(typeof(HitData), "SetAttacker")] [HarmonyPostfix] public static void HitData_SetAttacker_Postfix(HitData __instance, Character attacker) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)attacker) || !attacker.IsPlayer()) { return; } GameObject dropPrefab = ((Humanoid)((attacker is Player) ? attacker : null)).GetCurrentWeapon().m_dropPrefab; if ((Object)(object)dropPrefab != (Object)null) { SkyheimItemData component = dropPrefab.GetComponent<SkyheimItemData>(); if (component != null && component.Beneficial) { __instance.m_attacker = ZDOID.None; } } } [HarmonyPatch(typeof(Player), "Load")] [HarmonyPostfix] public static void Player_Load_Postfix() { ApplyLocalization(); } [HarmonyPatch(typeof(Attack), "Start")] [HarmonyPrefix] public static bool Attack_Start_Prefix(Attack __instance, Humanoid character, ItemData weapon, ZSyncAnimation zanim) { if ((Object)(object)character != (Object)(object)Player.m_localPlayer) { return true; } __instance.m_zanim = zanim; if (!((Character)character).InGodMode() && !SkyheimCooldown.Instance.OnAttackStart(weapon)) { return false; } SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(weapon); if (!((Object)(object)itemComponent == (Object)null)) { return itemComponent.OnAttackStart(__instance, Player.m_localPlayer, weapon); } return true; } [HarmonyPatch(typeof(Attack), "HaveAmmo")] [HarmonyPostfix] public static void Attack_HaveAmmo_Postfix(Humanoid character, ItemData weapon, ref bool __result) { if (__result && !((Object)(object)character != (Object)(object)Player.m_localPlayer) && !((Character)character).InGodMode() && !SkyheimCooldown.Instance.OnAttackStart(weapon)) { __result = false; } } [HarmonyPatch(typeof(Attack), "Start")] [HarmonyPostfix] public static void Attack_Start_Postfix(Attack __instance, ref bool __result) { if (!((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) && __result) { CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon)?.OnAttackStarted(Player.m_localPlayer, __instance); } } [HarmonyPatch(typeof(Attack), "OnAttackTrigger")] [HarmonyPrefix] public static bool Attack_OnAttackTrigger_Prefix(Attack __instance) { if ((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) { return true; } SkyheimItemData itemComponent = CommonUtils.GetItemComponent<SkyheimItemData>(__instance.m_weapon); if (itemComponent != null) { SkyheimCooldown.Instance.OnAttackTrigger(itemComponent); } SkyheimAttack itemComponent2 = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon); if (Object.op_Implicit((Object)(object)itemComponent2) && !itemComponent2.OnAttackTrigger(Player.m_localPlayer, __instance)) { __instance.Stop(); return false; } return true; } [HarmonyPatch(typeof(Attack), "FireProjectileBurst")] [HarmonyPrefix] public static bool Attack_FireProjectileBurst_Prefix(Attack __instance) { if ((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) { return true; } SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon); if (!((Object)(object)itemComponent == (Object)null)) { return itemComponent.OnFiringProjectileBurst(Player.m_localPlayer, __instance); } return true; } [HarmonyPatch(typeof(Attack), "FireProjectileBurst")] [HarmonyPostfix] public static void Attack_FireProjectileBurst_Postfix(Attack __instance) { if (!((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) && !((Object)(object)__instance.m_weapon.m_lastProjectile == (Object)null)) { SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon); if ((Object)(object)itemComponent != (Object)null) { IProjectile component = __instance.m_weapon.m_lastProjectile.GetComponent<IProjectile>(); itemComponent.OnProjectileFired(Player.m_localPlayer, __instance, component); } } } [HarmonyPatch(typeof(Attack), "Stop")] [HarmonyPostfix] public static void Attack_Stop_Postfix(Attack __instance) { if ((Object)(object)__instance.m_character == (Object)(object)Player.m_localPlayer) { SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon); if ((Object)(object)itemComponent != (Object)null) { itemComponent.OnAttackStop(Player.m_localPlayer, __instance); } } } [HarmonyPatch(typeof(Attack), "Update")] [HarmonyPostfix] public static void Attack_Update_Postfix(Attack __instance, float dt) { if ((Object)(object)__instance.m_character == (Object)(object)Player.m_localPlayer) { SkyheimAttack itemComponent = CommonUtils.GetItemComponent<SkyheimAttack>(__instance.m_weapon); if ((Object)(object)itemComponent != (Object)null) { itemComponent.OnAttackUpdate(Player.m_localPlayer, __instance, dt); } } } [HarmonyPatch(typeof(Hud), "Update")] [HarmonyPostfix] public static void Hud_Update_Postfix() { if (!((Object)(object)Player.m_localPlayer != (Object)null)) { return; } ItemData currentWeapon = ((Humanoid)Player.m_localPlayer).GetCurrentWeapon(); if (currentWeapon == null || !((Object)(object)currentWeapon.m_dropPrefab != (Object)null)) { return; } SkyheimItemData component = currentWeapon.m_dropPrefab.GetComponent<SkyheimItemData>(); if (Object.op_Implicit((Object)(object)component) && component.ManaDrain > 0f) { Player localPlayer = Player.m_localPlayer; localPlayer.m_eitr -= component.ManaDrain * Time.deltaTime; if (Player.m_localPlayer.m_eitr <= 0f) { ((Humanoid)Player.m_localPlayer).UnequipItem(currentWeapon, true); } } } [HarmonyPatch(typeof(CraftingStation), "GetLevel")] [HarmonyPostfix] public static void CraftingStation_GetLevel_Postfix(CraftingStation __instance, ref int __result) { SkyheimAltar skyheimAltar = default(SkyheimAltar); if (((Component)__instance).TryGetComponent<SkyheimAltar>(ref skyheimAltar)) { __result = 5; } } [HarmonyPatch(typeof(Character), "Damage")] [HarmonyPostfix] public static void Character_Damage_Postfix(Character __instance, HitData hit) { if (__instance.m_nview.IsValid() && !((Object)(object)hit.GetAttacker() != (Object)(object)Player.m_localPlayer)) { SEMan sEMan = hit.GetAttacker().GetSEMan(); if (sEMan.HaveStatusEffect(_statusEffectWindfury)) { (sEMan.GetStatusEffect(_statusEffectWindfury) as SE_Windfury).OnDamageDealt(__instance, hit); } } } } public class SkyheimSkills { private class SkillInfo { public string Name; public SkillDef SkillDef; } private static readonly Dictionary<int, SkillInfo> s_skills = new Dictionary<int, SkillInfo>(); public static void Create(Harmony harmony) { harmony.PatchAll(typeof(SkyheimSkills)); Register(SkyheimItemData.ESkillType.NatureMagic, "Nature magic", "Nature magic", AssetManager.GetAsset<Sprite>("skill_nature_magic")); Register(SkyheimItemData.ESkillType.HolyMagic, "Holy magic", "Holy magic", AssetManager.GetAsset<Sprite>("skill_holy_magic")); Register(SkyheimItemData.ESkillType.FireMagic, "Fire magic", "Fire magic", AssetManager.GetAsset<Sprite>("skill_fire_magic")); Register(SkyheimItemData.ESkillType.FrostMagic, "Frost magic", "Frost magic", AssetManager.GetAsset<Sprite>("skill_frost_magic")); foreach (SkyheimItemData gameObject in AssetManager.GetGameObjects<SkyheimItemData>()) { SetSkillType(gameObject); } } private static void SetSkillType(SkyheimItemData itemData) { SetSkillType(((Component)itemData).GetComponent<ItemDrop>(), itemData.SkillType); } private static void SetSkillType<T>(ItemDrop itemDrop, T skill_type) where T : IConvertible { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) int num = Convert.ToInt32(skill_type); itemDrop.m_itemData.m_shared.m_skillType = (SkillType)num; GameObject attackProjectile = itemDrop.m_itemData.m_shared.m_attack.m_attackProjectile; Aoe val = (((Object)(object)attackProjectile != (Object)null) ? attackProjectile.GetComponent<Aoe>() : null); if ((Object)(object)val != (Object)null) { val.m_skill = (SkillType)num; } } private static void Register<T>(T id, string name, string description, Sprite icon, float increaseStep = 1f) where T : IConvertible { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown int num = Convert.ToInt32(id); s_skills[num] = new SkillInfo { Name = name, SkillDef = new SkillDef { m_skill = (SkillType)num, m_increseStep = increaseStep, m_description = description, m_icon = icon } }; } private static SkillDef GetSkill(SkillType type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected I4, but got Unknown s_skills.TryGetValue((int)type, out var value); return value?.SkillDef; } private static SkillDef GetSkill(string name) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown name = name.ToLower(); foreach (SkillInfo value in s_skills.Values) { if (((SkyheimItemData.ESkillType)value.SkillDef.m_skill).ToString().ToLower() == name) { return value.SkillDef; } } return null; } [HarmonyPatch(typeof(Skills), "GetSkillDef")] [HarmonyPostfix] protected static void Skills_GetSkillDef_Postfix(Skills __instance, SkillType type, ref SkillDef __result) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (__result == null) { SkillDef skill = GetSkill(type); if (skill != null) { __instance.m_skills.Add(skill); __result = skill; } } } [HarmonyPatch(typeof(Skills), "CheatRaiseSkill")] [HarmonyPrefix] protected static bool Skills_CheatRaiseSkill_Prefix(Skills __instance, string name, float value) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) SkillDef skill = GetSkill(name); if (skill != null) { Skill skill2 = __instance.GetSkill(skill.m_skill); skill2.m_level = Mathf.Clamp(skill2.m_level + value, 0f, 100f); if (__instance.m_useSkillCap) { __instance.RebalanceSkills(skill.m_skill); } string text = $"Skill increased {skill2.m_info.m_skill}: {(int)skill2.m_level}"; ((Character)__instance.m_player).Message((MessageType)1, text, 0, skill2.m_info.m_icon); Console.instance.Print($"Skill {name} = {skill2.m_level}"); return false; } return true; } [HarmonyPatch(typeof(Skills), "CheatResetSkill")] [HarmonyPrefix] protected static bool Skills_CheatResetSkill_Prefix(Skills __instance, string name) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) SkillDef skill = GetSkill(name); if (skill != null) { __instance.ResetSkill(skill.m_skill); Console.instance.Print("Skill " + name + " reset"); return false; } return true; } [HarmonyPatch(typeof(Skills), "IsSkillValid")] [HarmonyPostfix] protected static void Skills_IsSkillValid_Postfix(SkillType type, ref bool __result) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected I4, but got Unknown __result = __result || s_skills.ContainsKey((int)type); } } } namespace SimpleJSON { public enum JSONNodeType { Array = 1, Object = 2, String = 3, Number = 4, NullValue = 5, Boolean = 6, None = 7, Custom = 255 } public enum JSONTextMode { Compact, Indent } public abstract class JSONNode { public struct Enumerator { private enum Type { None, Array, Object } private Type type; private Dictionary<string, JSONNode>.Enumerator m_Object; private List<JSONNode>.Enumerator m_Array; public bool IsValid => type != Type.None; public KeyValuePair<string, JSONNode> Current { get { if (type == Type.Array) { return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current); } if (type == Type.Object) { return m_Object.Current; } return new KeyValuePair<string, JSONNode>(string.Empty, null); } } public Enumerator(List<JSONNode>.Enumerator aArrayEnum) { type = Type.Array; m_Object = default(Dictionary<string, JSONNode>.Enumerator); m_Array = aArrayEnum; } public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) { type = Type.Object; m_Object = aDictEnum; m_Array = default(List<JSONNode>.Enumerator); } public bool MoveNext() { if (type == Type.Array) { return m_Array.MoveNext(); } if (type == Type.Object) { return m_Object.MoveNext(); } return false; } } public struct ValueEnumerator { private Enumerator m_Enumerator; public JSONNode Current => m_Enumerator.Current.Value; public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } public ValueEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } public bool MoveNext() { return m_Enumerator.MoveNext(); } public ValueEnumerator GetEnumerator() { return this; } } public struct KeyEnumerator { private Enumerator m_Enumerator; public string Current => m_Enumerator.Current.Key; public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } public KeyEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } public bool MoveNext() { return m_Enumerator.MoveNext(); } public KeyEnumerator GetEnumerator() { return this; } } public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IDisposable, IEnumerator, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable { private JSONNode m_Node; private Enumerator m_Enumerator; public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current; object IEnumerator.Current => m_Enumerator.Current; internal LinqEnumerator(JSONNode aNode) { m_Node = aNode; if (m_Node != null) { m_Enumerator = m_Node.GetEnumerator(); } } public bool MoveNext() { return m_Enumerator.MoveNext(); } public void Dispose() { m_Node = null; m_Enumerator = default(Enumerator); } public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator() { return new LinqEnumerator(m_Node); } public void Reset() { if (m_Node != null) { m_Enumerator = m_Node.GetEnumerator(); } } IEnumerator IEnumerable.GetEnumerator() { return new LinqEnumerator(m_Node); } } public static bool forceASCII = false; public static bool longAsString = false; public static bool allowLineComments = true; [ThreadStatic] private static StringBuilder m_EscapeBuilder; public abstract JSONNodeType Tag { get; } public virtual JSONNode this[int aIndex] { get { return null; } set { } } public virtual JSONNode this[string aKey] { get { return null; } set { } } public virtual string Value { get { return ""; } set { } } public virtual int Count => 0; public virtual bool IsNumber => false; public virtual bool IsString => false; public virtual bool IsBoolean => false; public virtual bool IsNull => false; public virtual bool IsArray => false; public virtual bool IsObject => false; public virtual bool Inline { get { return false; } set { } } public virtual IEnumerable<JSONNode> Children { get { yield break; } } public IEnumerable<JSONNode> DeepChildren { get { foreach (JSONNode child in Children) { foreach (JSONNode deepChild in child.DeepChildren) { yield return deepChild; } } } } public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this); public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator()); public ValueEnumerator Values => new ValueEnumerator(GetEnumerator()); public virtual double AsDouble { get { double result = 0.0; if (double.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out result)) { return result; } return 0.0; } set { Value = value.ToString(CultureInfo.InvariantCulture); } } public virtual int AsInt { get { return (int)AsDouble; } set { AsDouble = value; } } public virtual float AsFloat { get { return (float)AsDouble; } set { AsDouble = value; } } public virtual bool AsBool { get { bool result = false; if (bool.TryParse(Value, out result)) { return result; } return !string.IsNullOrEmpty(Value); } set { Value = (value ? "true" : "false"); } } public virtual long AsLong { get { long result = 0L; if (long.TryParse(Value, out result)) { return result; } return 0L; } set { Value = value.ToString(); } } public virtual ulong AsULong { get { ulong result = 0uL; if (ulong.TryParse(Value, out result)) { return result; } return 0uL; } set { Value = value.ToString(); } } public virtual JSONArray AsArray => this as JSONArray; public virtual JSONObject AsObject => this as JSONObject; internal static StringBuilder EscapeBuilder { get { if (m_EscapeBuilder == null) { m_EscapeBuilder = new StringBuilder(); } return m_EscapeBuilder; }