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.Permissions; using System.Text; using BepInEx; using Ent1tyRaces.Commands; using Ent1tyRaces.Races; using Ent1tyRaces.UI; using HarmonyLib; using Jotunn; using Jotunn.Entities; using Jotunn.Managers; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Ent1tyRaces")] [assembly: AssemblyDescription("Human, Dragonborn, and Vampire races for Valheim")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Ent1tyRaces")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] namespace Ent1tyRaces { public enum BreathElement { Fire, Poison, Lightning, Ice } public enum ElfType { High, Wood, Drow } public enum GenasiType { Air, Earth, Fire, Water } public enum GiantType { Cloud, Fire, Frost, Hill, Stone, Storm } public enum GnomeType { Forest, Rock } [BepInPlugin("com.ent1ty303.ent1tyraces", "Ent1tyRaces", "2.3.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Ent1tyRacesPlugin : BaseUnityPlugin { public const string PluginGUID = "com.ent1ty303.ent1tyraces"; public const string PluginName = "Ent1tyRaces"; public const string PluginVersion = "2.3.5"; private Harmony _harmony; public static Ent1tyRacesPlugin Instance { get; private set; } private void Awake() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown Instance = this; _harmony = new Harmony("com.ent1ty303.ent1tyraces"); ApplyPatchesSafely(); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RaceCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new BreathCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new TypeCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new LegacyCommand()); ((Component)this).gameObject.AddComponent(); Logger.LogInfo((object)"Ent1tyRaces v2.3.5 loaded OK. Create: race/type/legacy/breath | Admin: /race /type /legacy /breath (devcommands)"); } private void ApplyPatchesSafely() { foreach (Type item in from t in Assembly.GetExecutingAssembly().GetTypes() where t.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0 select t) { try { _harmony.CreateClassProcessor(item).Patch(); Logger.LogInfo((object)("Ent1tyRaces: patched " + item.Name)); } catch (Exception ex) { Logger.LogWarning((object)("Ent1tyRaces: skipped " + item.Name + " — " + ex.Message)); } } } private void OnDestroy() { Instance = null; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } public enum RaceType { Human, Dragonborn, Vampire, Elf, Aarakocra, Giant, Genasi, Dwarf, Gnome, Halfling, Orc, Tiefling, Aasimar } public enum TieflingLegacy { Abyssal, Chthonic, Infernal } } namespace Ent1tyRaces.UI { internal static class CharacterCreateRaceUI { private static GameObject _root; private static TMP_Dropdown _dropdown; private static GameObject _subtypeRoot; private static TMP_Text _subtypeLabel; private static TMP_Dropdown _subtypeDropdown; private static TMP_Text _hoverText; private static GameObject _hoverPanel; private static bool _suppressChange; private static bool _suppressSubtypeChange; private static RaceType _pendingRace = RaceType.Human; private static string _pendingSubtype = string.Empty; private static readonly List Options = new List(); private static readonly List SubtypeKeys = new List(); private static readonly Color DecayedGold = RaceUiSkin.DecayedGold; private static GameObject _raceRow; private static Image _rootPlate; private const string UiBuildTag = "Ent1tyRaces_CharacterRaceCreate_v6"; public static RaceType PendingRace => _pendingRace; public static void ShowForCreation() { FejdStartup instance = FejdStartup.instance; if (!((Object)(object)instance == (Object)null)) { GameObject newCharacterPanel = instance.m_newCharacterPanel; if ((Object)(object)newCharacterPanel == (Object)null || !newCharacterPanel.activeInHierarchy) { Hide(); return; } _pendingRace = RaceType.Human; _pendingSubtype = string.Empty; EnsureUi(newCharacterPanel.transform); PositionBelowHairTone(newCharacterPanel.transform); RefreshDropdown(); RefreshSubtypeUi(); } } public static void Hide() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } HideHover(); } public static void ApplyPendingToPreview(Player preview) { if (!((Object)(object)preview == (Object)null)) { RaceManager.ApplyRaceForNewCharacter(preview, _pendingRace); if (NeedsSubtype(_pendingRace) && !string.IsNullOrEmpty(_pendingSubtype)) { RaceManager.ApplySubtypeForNewCharacter(preview, _pendingRace, _pendingSubtype); } } } public static void LockAndPersistIfNeeded() { FejdStartup instance = FejdStartup.instance; if ((Object)(object)instance == (Object)null || ((Object)(object)instance.m_newCharacterPanel != (Object)null && instance.m_newCharacterPanel.activeInHierarchy)) { return; } Player previewPlayer = instance.GetPreviewPlayer(); if ((Object)(object)previewPlayer == (Object)null || RaceManager.IsRaceChoiceLocked(previewPlayer)) { Hide(); return; } RaceManager.LockRaceChoice(previewPlayer); List value = Traverse.Create((object)instance).Field("m_profiles").GetValue>(); int value2 = Traverse.Create((object)instance).Field("m_profileIndex").GetValue(); if (value != null && value2 >= 0 && value2 < value.Count) { PlayerProfile obj = value[value2]; obj.SavePlayerData(previewPlayer); obj.Save(); } Hide(); } public static bool NeedsSubtype(RaceType race) { switch (race) { case RaceType.Dragonborn: case RaceType.Elf: case RaceType.Giant: case RaceType.Genasi: case RaceType.Gnome: case RaceType.Tiefling: return true; default: return false; } } private static void PositionBelowHairTone(Transform panel) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { RectTransform component = _root.GetComponent(); float num = (NeedsSubtype(_pendingRace) ? 88f : 44f); component.sizeDelta = new Vector2(Mathf.Max(component.sizeDelta.x, 340f), num); PlayerCustomizaton componentInChildren = ((Component)panel).GetComponentInChildren(true); Slider val = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.m_hairTone : null); if ((Object)(object)val == (Object)null) { ((Transform)component).SetParent(panel, false); component.anchorMin = new Vector2(0.5f, 0f); component.anchorMax = new Vector2(0.5f, 0f); component.pivot = new Vector2(0.5f, 0f); component.anchoredPosition = new Vector2(0f, 100f); return; } Transform transform = ((Component)val).transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); Transform val3 = (((Object)(object)((Transform)val2).parent != (Object)null) ? ((Transform)val2).parent : panel); ((Transform)component).SetParent(val3, false); component.anchorMin = val2.anchorMin; component.anchorMax = val2.anchorMax; component.pivot = new Vector2(0.5f, 1f); component.sizeDelta = new Vector2(Mathf.Max(val2.sizeDelta.x, 340f), num); float num2 = 52f; float y = val2.anchoredPosition.y; Rect rect = val2.rect; float num3 = y - ((Rect)(ref rect)).height - num2; component.anchoredPosition = new Vector2(val2.anchoredPosition.x, num3); ((Transform)component).SetAsLastSibling(); } } private static void EnsureUi(Transform parent) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Expected O, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null && ((Object)_root).name != "Ent1tyRaces_CharacterRaceCreate_v6") { Object.Destroy((Object)(object)_root); _root = null; _dropdown = null; _subtypeRoot = null; _subtypeDropdown = null; _subtypeLabel = null; _hoverPanel = null; _hoverText = null; _raceRow = null; _rootPlate = null; } if ((Object)(object)_root != (Object)null) { _root.SetActive(true); return; } TMP_FontAsset font = FindMenuFont(parent); _root = new GameObject("Ent1tyRaces_CharacterRaceCreate_v6", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = _root.GetComponent(); ((Transform)component).SetParent(parent, false); component.sizeDelta = new Vector2(340f, 44f); _rootPlate = _root.GetComponent(); RaceUiSkin.ApplyPanel(_rootPlate); ((Graphic)_rootPlate).raycastTarget = false; GameObject val = new GameObject("Rim", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component2 = val.GetComponent(); ((Transform)component2).SetParent((Transform)(object)component, false); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = new Vector2(-4f, -4f); component2.offsetMax = new Vector2(4f, 4f); ((Transform)component2).SetAsFirstSibling(); RaceUiSkin.ApplyRim(val.GetComponent()); ((Graphic)val.GetComponent()).raycastTarget = false; _raceRow = new GameObject("RaceRow", new Type[1] { typeof(RectTransform) }); RectTransform component3 = _raceRow.GetComponent(); ((Transform)component3).SetParent((Transform)(object)component, false); component3.anchorMin = new Vector2(0f, 1f); component3.anchorMax = new Vector2(1f, 1f); component3.pivot = new Vector2(0.5f, 1f); component3.anchoredPosition = new Vector2(0f, -4f); component3.sizeDelta = new Vector2(-20f, 36f); CreateLabel(component3, "Label", "Race", new Vector2(10f, 0f), font, DecayedGold); GameObject obj = BuildDropdownSkeleton(component3, "RaceDropdown", font, out _dropdown); PopulateRaceOptions(); ((UnityEvent)(object)_dropdown.onValueChanged).AddListener((UnityAction)OnRaceChanged); BuildHoverPanel(component, font); obj.AddComponent().Bind(_dropdown, ShowRaceHover, HideHover); _subtypeRoot = new GameObject("SubtypeRow", new Type[1] { typeof(RectTransform) }); RectTransform component4 = _subtypeRoot.GetComponent(); ((Transform)component4).SetParent((Transform)(object)component, false); component4.anchorMin = new Vector2(0f, 1f); component4.anchorMax = new Vector2(1f, 1f); component4.pivot = new Vector2(0.5f, 1f); component4.anchoredPosition = new Vector2(0f, -44f); component4.sizeDelta = new Vector2(-20f, 36f); _subtypeLabel = CreateLabel(component4, "SubtypeLabel", "Type", new Vector2(10f, 0f), font, DecayedGold); GameObject obj2 = BuildDropdownSkeleton(component4, "SubtypeDropdown", font, out _subtypeDropdown); ((UnityEvent)(object)_subtypeDropdown.onValueChanged).AddListener((UnityAction)OnSubtypeChanged); obj2.AddComponent().Bind(_subtypeDropdown, () => _pendingRace, () => SubtypeKeys, ShowSubtypeHover, HideHover); _subtypeRoot.SetActive(false); } private static TMP_Text CreateLabel(RectTransform parent, string name, string text, Vector2 anchored, TMP_FontAsset font, Color color, float width = 88f) { //IL_0014: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_00a2: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent((Transform)(object)parent, false); component.anchorMin = new Vector2(0f, 0.5f); component.anchorMax = new Vector2(0f, 0.5f); component.pivot = new Vector2(0f, 0.5f); component.anchoredPosition = anchored; component.sizeDelta = new Vector2(width, 32f); TMP_Text val2 = (TMP_Text)(object)val.AddComponent(); val2.text = text; val2.fontSize = 18f; val2.alignment = (TextAlignmentOptions)4097; ((Graphic)val2).color = color; val2.enableWordWrapping = false; val2.overflowMode = (TextOverflowModes)0; if ((Object)(object)font != (Object)null) { val2.font = font; } return val2; } private static GameObject BuildDropdownSkeleton(RectTransform parent, string name, TMP_FontAsset font, out TMP_Dropdown dropdown) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) GameObject val = DefaultControls.CreateDropdown(GetDefaultResources()); ((Object)val).name = name; RectTransform component = val.GetComponent(); ((Transform)component).SetParent((Transform)(object)parent, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = new Vector2(102f, 0f); component.offsetMax = Vector2.zero; Object.DestroyImmediate((Object)(object)val.GetComponent()); Text[] componentsInChildren = val.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } dropdown = val.AddComponent(); WireTmpDropdownParts(val, dropdown, font); PaintParchment(val); return val; } private static void PaintParchment(GameObject dropGo) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) Image[] componentsInChildren = dropGo.GetComponentsInChildren(true); foreach (Image val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { string name = ((Object)((Component)val).gameObject).name; if (name.Contains("Arrow") || name.Contains("Checkmark") || name.Contains("Item Checkmark")) { val.sprite = RaceUiSkin.BrassField; ((Graphic)val).color = DecayedGold; val.type = (Type)0; } else if (name.Contains("Item") && !name.Contains("Label")) { RaceUiSkin.ApplyField(val); ((Graphic)val).color = new Color(0.75f, 0.65f, 0.45f, 1f); } else { RaceUiSkin.ApplyField(val); } } } } private static void WireTmpDropdownParts(GameObject dropGo, TMP_Dropdown dropdown, TMP_FontAsset font) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) Transform val = dropGo.transform.Find("Label"); if ((Object)(object)val != (Object)null) { TMP_Text val2 = (TMP_Text)(object)(((Component)val).gameObject.GetComponent() ?? ((Component)val).gameObject.AddComponent()); val2.fontSize = 18f; ((Graphic)val2).color = DecayedGold; val2.alignment = (TextAlignmentOptions)4097; if ((Object)(object)font != (Object)null) { val2.font = font; } dropdown.captionText = val2; } Transform val3 = dropGo.transform.Find("Template/Viewport/Content/Item/Item Label"); if ((Object)(object)val3 != (Object)null) { TMP_Text val4 = (TMP_Text)(object)(((Component)val3).gameObject.GetComponent() ?? ((Component)val3).gameObject.AddComponent()); val4.fontSize = 17f; ((Graphic)val4).color = DecayedGold; if ((Object)(object)font != (Object)null) { val4.font = font; } dropdown.itemText = val4; } Transform val5 = dropGo.transform.Find("Template"); if ((Object)(object)val5 != (Object)null) { RectTransform val6 = (dropdown.template = (RectTransform)(object)((val5 is RectTransform) ? val5 : null)); if ((Object)(object)val6 != (Object)null) { val6.sizeDelta = new Vector2(val6.sizeDelta.x, 180f); } ScrollRect component = ((Component)val5).GetComponent(); if ((Object)(object)component != (Object)null) { component.scrollSensitivity = 45f; component.movementType = (MovementType)2; component.inertia = true; } ((Component)val5).gameObject.SetActive(false); } } private static void BuildHoverPanel(RectTransform rootRt, TMP_FontAsset font) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_004d: 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) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) _hoverPanel = new GameObject("RaceHoverPanel", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = _hoverPanel.GetComponent(); ((Transform)component).SetParent((Transform)(object)rootRt, false); component.anchorMin = new Vector2(1f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(14f, 0f); component.sizeDelta = new Vector2(420f, 160f); RaceUiSkin.ApplyPanel(_hoverPanel.GetComponent()); ((Graphic)_hoverPanel.GetComponent()).raycastTarget = false; GameObject val = new GameObject("HoverRim", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component2 = val.GetComponent(); ((Transform)component2).SetParent((Transform)(object)component, false); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = new Vector2(-4f, -4f); component2.offsetMax = new Vector2(4f, 4f); ((Transform)component2).SetAsFirstSibling(); RaceUiSkin.ApplyRim(val.GetComponent()); ((Graphic)val.GetComponent()).raycastTarget = false; GameObject val2 = new GameObject("HoverText", new Type[1] { typeof(RectTransform) }); RectTransform component3 = val2.GetComponent(); ((Transform)component3).SetParent((Transform)(object)component, false); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = new Vector2(14f, 12f); component3.offsetMax = new Vector2(-14f, -12f); _hoverText = (TMP_Text)(object)val2.AddComponent(); _hoverText.fontSize = 15f; _hoverText.alignment = (TextAlignmentOptions)257; ((Graphic)_hoverText).color = DecayedGold; _hoverText.enableWordWrapping = true; _hoverText.overflowMode = (TextOverflowModes)0; ((Graphic)_hoverText).raycastTarget = false; _hoverText.margin = Vector4.zero; if ((Object)(object)font != (Object)null) { _hoverText.font = font; } _hoverPanel.SetActive(false); } private static void PopulateRaceOptions() { Options.Clear(); Options.AddRange(RaceManager.AllSelectableRaces); _dropdown.ClearOptions(); List list = new List(); foreach (RaceType option in Options) { list.Add(RaceManager.GetRacePrettyName(option)); } _dropdown.AddOptions(list); } private static void RefreshDropdown() { if (!((Object)(object)_dropdown == (Object)null)) { int num = Options.IndexOf(_pendingRace); if (num < 0) { num = 0; _pendingRace = Options[0]; } _suppressChange = true; _dropdown.value = num; _dropdown.RefreshShownValue(); _suppressChange = false; ((Selectable)_dropdown).interactable = true; if ((Object)(object)_root != (Object)null) { _root.SetActive(true); } } } private static void RefreshSubtypeUi() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_subtypeRoot == (Object)null || (Object)(object)_subtypeDropdown == (Object)null) { return; } if (!NeedsSubtype(_pendingRace)) { _subtypeRoot.SetActive(false); _pendingSubtype = string.Empty; if ((Object)(object)FejdStartup.instance != (Object)null) { PositionBelowHairTone(FejdStartup.instance.m_newCharacterPanel.transform); } return; } _subtypeRoot.SetActive(true); if ((Object)(object)_subtypeLabel != (Object)null) { TMP_Text subtypeLabel = _subtypeLabel; subtypeLabel.text = _pendingRace switch { RaceType.Tiefling => "Legacy", RaceType.Dragonborn => "Breath", _ => "Type", }; ((Graphic)_subtypeLabel).color = DecayedGold; } SubtypeKeys.Clear(); List list = new List(); GetSubtypeOptions(_pendingRace, SubtypeKeys, list); _suppressSubtypeChange = true; _subtypeDropdown.ClearOptions(); _subtypeDropdown.AddOptions(list); int num = Mathf.Max(0, SubtypeKeys.IndexOf(_pendingSubtype)); if (string.IsNullOrEmpty(_pendingSubtype) || num < 0) { num = 0; } _pendingSubtype = SubtypeKeys[num]; _subtypeDropdown.value = num; _subtypeDropdown.RefreshShownValue(); _suppressSubtypeChange = false; if ((Object)(object)FejdStartup.instance != (Object)null) { PositionBelowHairTone(FejdStartup.instance.m_newCharacterPanel.transform); } } private static void GetSubtypeOptions(RaceType race, List keys, List labels) { switch (race) { case RaceType.Elf: keys.AddRange(new string[3] { "high", "wood", "drow" }); labels.AddRange(new string[3] { "High", "Wood", "Drow" }); break; case RaceType.Giant: keys.AddRange(new string[6] { "cloud", "fire", "frost", "hill", "stone", "storm" }); labels.AddRange(new string[6] { "Cloud", "Fire", "Frost", "Hill", "Stone", "Storm" }); break; case RaceType.Genasi: keys.AddRange(new string[4] { "air", "earth", "fire", "water" }); labels.AddRange(new string[4] { "Air", "Earth", "Fire", "Water" }); break; case RaceType.Gnome: keys.AddRange(new string[2] { "forest", "rock" }); labels.AddRange(new string[2] { "Forest", "Rock" }); break; case RaceType.Tiefling: keys.AddRange(new string[3] { "abyssal", "chthonic", "infernal" }); labels.AddRange(new string[3] { "Abyssal", "Chthonic", "Infernal" }); break; case RaceType.Dragonborn: keys.AddRange(new string[4] { "fire", "poison", "lightning", "ice" }); labels.AddRange(new string[4] { "Fire", "Poison", "Lightning", "Ice" }); break; case RaceType.Vampire: case RaceType.Aarakocra: case RaceType.Dwarf: case RaceType.Halfling: case RaceType.Orc: break; } } private static void OnRaceChanged(int index) { if (!_suppressChange && !((Object)(object)_dropdown == (Object)null) && index >= 0 && index < Options.Count) { _pendingRace = Options[index]; _pendingSubtype = string.Empty; RefreshSubtypeUi(); HideHover(); } } private static void OnSubtypeChanged(int index) { if (!_suppressSubtypeChange && index >= 0 && index < SubtypeKeys.Count) { _pendingSubtype = SubtypeKeys[index]; } } public static void ShowRaceHover(RaceType race) { ShowHoverText(RaceDescriptions.GetHoverText(race)); } public static void ShowSubtypeHover(RaceType race, string subtypeKey) { ShowHoverText(RaceDescriptions.GetSubtypeHoverText(race, subtypeKey)); } public static void ShowHover(RaceType race) { ShowRaceHover(race); } private static void ShowHoverText(string text) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) if (!((Object)(object)_hoverPanel == (Object)null) && !((Object)(object)_hoverText == (Object)null)) { RectTransform component = _hoverPanel.GetComponent(); component.anchoredPosition = new Vector2(14f, 0f); _hoverText.text = text ?? string.Empty; _hoverPanel.SetActive(true); Canvas.ForceUpdateCanvases(); Rect rect = component.rect; float num = Mathf.Max(80f, ((Rect)(ref rect)).width - 28f); float num2 = Mathf.Clamp(_hoverText.GetPreferredValues(_hoverText.text, num, 0f).y + 28f, 120f, 520f); component.sizeDelta = new Vector2(420f, num2); ClampHoverOnScreen(); } } private static void ClampHoverOnScreen() { //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_hoverPanel == (Object)null || (Object)(object)_root == (Object)null) { return; } RectTransform component = _hoverPanel.GetComponent(); Canvas componentInParent = _root.GetComponentInParent(); if ((Object)(object)component == (Object)null || (Object)(object)componentInParent == (Object)null) { return; } Transform transform = ((Component)componentInParent).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (!((Object)(object)val == (Object)null)) { Vector3[] array = (Vector3[])(object)new Vector3[4]; component.GetWorldCorners(array); Vector3[] array2 = (Vector3[])(object)new Vector3[4]; val.GetWorldCorners(array2); float num = 8f; float num2 = 0f; float num3 = 0f; if (array[2].x > array2[2].x - num) { num2 = array2[2].x - num - array[2].x; } if (array[0].x + num2 < array2[0].x + num) { num2 += array2[0].x + num - (array[0].x + num2); } if (array[0].y < array2[0].y + num) { num3 = array2[0].y + num - array[0].y; } if (Mathf.Abs(num2) > 0.5f || Mathf.Abs(num3) > 0.5f) { Vector3 val2 = ((Transform)component).parent.InverseTransformVector(new Vector3(num2, num3, 0f)); component.anchoredPosition += new Vector2(val2.x, val2.y); } } } public static void HideHover() { if ((Object)(object)_hoverPanel != (Object)null) { _hoverPanel.SetActive(false); } } private static TMP_FontAsset FindMenuFont(Transform parent) { TMP_Text componentInChildren = ((Component)parent).GetComponentInChildren(true); if (!((Object)(object)componentInChildren != (Object)null)) { return null; } return componentInChildren.font; } private static Resources GetDefaultResources() { //IL_001f: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) Texture2D whiteTexture = Texture2D.whiteTexture; Sprite val = Sprite.Create(whiteTexture, new Rect(0f, 0f, (float)((Texture)whiteTexture).width, (float)((Texture)whiteTexture).height), new Vector2(0.5f, 0.5f), 100f); return new Resources { standard = val, background = val, inputField = val, knob = val, checkmark = val, dropdown = val, mask = val }; } } internal class RaceDropdownHoverHook : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { private TMP_Dropdown _dropdown; private Action _onHover; private Action _onExit; private bool _wired; public void Bind(TMP_Dropdown dropdown, Action onHover, Action onExit) { _dropdown = dropdown; _onHover = onHover; _onExit = onExit; } private void Update() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown if ((Object)(object)_dropdown == (Object)null) { return; } Transform template = (Transform)(object)_dropdown.template; if ((Object)(object)template == (Object)null || !((Component)template).gameObject.activeInHierarchy) { _wired = false; } else { if (_wired) { return; } _wired = true; Transform val = template.Find("Viewport/Content"); if ((Object)(object)val == (Object)null) { return; } RaceType[] allSelectableRaces = RaceManager.AllSelectableRaces; int num = 0; foreach (Transform item in val) { Transform val2 = item; if (((Object)val2).name.Contains("Item")) { RaceType race = ((num < allSelectableRaces.Length) ? allSelectableRaces[num] : RaceType.Human); num++; (((Component)val2).gameObject.GetComponent() ?? ((Component)val2).gameObject.AddComponent()).Setup(race, _onHover, _onExit); } } } } public void OnPointerEnter(PointerEventData eventData) { if (!((Object)(object)_dropdown == (Object)null) && ((Selectable)_dropdown).interactable) { int value = _dropdown.value; RaceType[] allSelectableRaces = RaceManager.AllSelectableRaces; if (value >= 0 && value < allSelectableRaces.Length) { _onHover?.Invoke(allSelectableRaces[value]); } } } public void OnPointerExit(PointerEventData eventData) { TMP_Dropdown dropdown = _dropdown; if ((Object)(object)((dropdown != null) ? dropdown.template : null) == (Object)null || !((Component)_dropdown.template).gameObject.activeInHierarchy) { _onExit?.Invoke(); } } } internal class RaceOptionHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { private RaceType _race; private Action _onHover; private Action _onExit; public void Setup(RaceType race, Action onHover, Action onExit) { _race = race; _onHover = onHover; _onExit = onExit; } public void OnPointerEnter(PointerEventData eventData) { _onHover?.Invoke(_race); } public void OnPointerExit(PointerEventData eventData) { } } internal class SubtypeDropdownHoverHook : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { private TMP_Dropdown _dropdown; private Func _getRace; private Func> _getKeys; private Action _onHover; private Action _onExit; private bool _wired; public void Bind(TMP_Dropdown dropdown, Func getRace, Func> getKeys, Action onHover, Action onExit) { _dropdown = dropdown; _getRace = getRace; _getKeys = getKeys; _onHover = onHover; _onExit = onExit; } private void Update() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown if ((Object)(object)_dropdown == (Object)null) { return; } Transform template = (Transform)(object)_dropdown.template; if ((Object)(object)template == (Object)null || !((Component)template).gameObject.activeInHierarchy) { _wired = false; } else { if (_wired) { return; } _wired = true; Transform val = template.Find("Viewport/Content"); if ((Object)(object)val == (Object)null) { return; } List list = _getKeys?.Invoke() ?? new List(); int num = 0; foreach (Transform item in val) { Transform val2 = item; if (((Object)val2).name.Contains("Item")) { string key = ((num < list.Count) ? list[num] : string.Empty); num++; (((Component)val2).gameObject.GetComponent() ?? ((Component)val2).gameObject.AddComponent()).Setup(key, () => _getRace?.Invoke() ?? RaceType.Human, _onHover, _onExit); } } } } public void OnPointerEnter(PointerEventData eventData) { if (!((Object)(object)_dropdown == (Object)null) && ((Selectable)_dropdown).interactable) { List list = _getKeys?.Invoke() ?? new List(); int value = _dropdown.value; if (value >= 0 && value < list.Count) { _onHover?.Invoke(_getRace?.Invoke() ?? RaceType.Human, list[value]); } } } public void OnPointerExit(PointerEventData eventData) { TMP_Dropdown dropdown = _dropdown; if ((Object)(object)((dropdown != null) ? dropdown.template : null) == (Object)null || !((Component)_dropdown.template).gameObject.activeInHierarchy) { _onExit?.Invoke(); } } } internal class SubtypeOptionHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { private string _key; private Func _getRace; private Action _onHover; private Action _onExit; public void Setup(string key, Func getRace, Action onHover, Action onExit) { _key = key; _getRace = getRace; _onHover = onHover; _onExit = onExit; } public void OnPointerEnter(PointerEventData eventData) { _onHover?.Invoke(_getRace?.Invoke() ?? RaceType.Human, _key); } public void OnPointerExit(PointerEventData eventData) { } } internal static class RaceUiSkin { public static readonly Color DecayedGold = new Color(0.82f, 0.62f, 0.28f, 1f); public static readonly Color DecayedGoldDim = new Color(0.55f, 0.4f, 0.14f, 1f); private static Sprite _iconSprite; private static Sprite _brassSprite; private static Sprite _panelSprite; private static bool _triedLoad; public static Sprite StonePanel { get { if (!((Object)(object)_panelSprite != (Object)null)) { return _panelSprite = BuildStoneTile(256); } return _panelSprite; } } public static Sprite BrassField { get { if (!((Object)(object)_brassSprite != (Object)null)) { return _brassSprite = BuildBrassTile(192); } return _brassSprite; } } public static Sprite IconAccent => EnsureIconLoaded(); private static Sprite EnsureIconLoaded() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (_triedLoad) { return _iconSprite; } _triedLoad = true; try { string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? ""; string[] array = new string[3] { Path.Combine(path, "icon.png"), Path.Combine(path, "..", "icon.png"), Path.Combine(path, "Ent1tyRaces", "icon.png") }; for (int i = 0; i < array.Length; i++) { string fullPath = Path.GetFullPath(array[i]); if (File.Exists(fullPath)) { byte[] bytes = File.ReadAllBytes(fullPath); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (TryLoadPng(val, bytes)) { ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; _iconSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); Logger.LogInfo((object)("Ent1tyRaces: UI skin loaded icon from " + fullPath)); return _iconSprite; } Object.Destroy((Object)(object)val); } } } catch (Exception ex) { Logger.LogWarning((object)("Ent1tyRaces: could not load icon.png for UI skin (" + ex.Message + ")")); } return null; } private static bool TryLoadPng(Texture2D tex, byte[] bytes) { try { MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[2] { typeof(Texture2D), typeof(byte[]) }); if (methodInfo == null) { return false; } return (bool)methodInfo.Invoke(null, new object[2] { tex, bytes }); } catch { return false; } } private static Sprite BuildStoneTile(int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)0; ((Texture)val).filterMode = (FilterMode)1; Color[] array = (Color[])(object)new Color[size * size]; Color val2 = default(Color); Color val3 = default(Color); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = FractalNoise((float)j * 0.09f, (float)i * 0.09f); float num2 = FractalNoise((float)j * 0.55f + 11f, (float)i * 0.55f + 3f); float num3 = FractalNoise((float)j * 0.21f + 20f, (float)i * 0.21f + 7f); float num4 = Mathf.Lerp(0.04f, 0.16f, num * 0.7f + num2 * 0.3f); float num5 = ((float)j - (float)size * 0.5f) / (float)size; float num6 = ((float)i - (float)size * 0.5f) / (float)size; float num7 = Mathf.Abs(Mathf.Sin(Mathf.Sqrt(num5 * num5 + num6 * num6) * 28f + num3)); float num8 = Mathf.SmoothStep(0.92f, 1f, num7) * 0.04f; ((Color)(ref val2))..ctor(num4 - num8, num4 * 0.96f - num8, num4 * 0.88f - num8, 1f); float num9 = Mathf.SmoothStep(0.68f, 0.9f, num3); ((Color)(ref val3))..ctor(0.42f, 0.3f, 0.1f, 1f); array[i * size + j] = Color.Lerp(val2, val3, num9 * 0.18f); } } for (int k = 0; k < size; k++) { for (int l = 0; l < size; l++) { float num10 = (float)l / (float)(size - 1) * 2f - 1f; float num11 = (float)k / (float)(size - 1) * 2f - 1f; float num12 = Mathf.Max(Mathf.Abs(num10), Mathf.Abs(num11)); float num13 = Mathf.SmoothStep(0.5f, 1f, num12) * 0.4f; Color val4 = array[k * size + l]; val4.r *= 1f - num13; val4.g *= 1f - num13; val4.b *= 1f - num13; array[k * size + l] = val4; } } val.SetPixels(array); val.Apply(false, false); return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f); } private static Sprite BuildBrassTile(int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)0; ((Texture)val).filterMode = (FilterMode)1; Color[] array = (Color[])(object)new Color[size * size]; Color val2 = default(Color); Color val3 = default(Color); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = FractalNoise((float)j * 0.13f, (float)i * 0.13f); float num2 = FractalNoise((float)j * 0.41f + 3f, (float)i * 0.41f + 9f); float num3 = FractalNoise((float)j * 0.9f, (float)i * 0.08f + 40f); ((Color)(ref val2))..ctor(0.78f, 0.58f, 0.24f, 1f); ((Color)(ref val3))..ctor(0.52f, 0.38f, 0.14f, 1f); Color val4 = Color.Lerp(new Color(0.22f, 0.15f, 0.05f, 1f), Color.Lerp(val3, val2, num), Mathf.Pow(num, 0.85f)); if (num2 > 0.66f) { val4 = Color.Lerp(val4, new Color(0.08f, 0.06f, 0.02f, 1f), (num2 - 0.66f) * 2.8f); } if (num3 > 0.78f) { val4 = Color.Lerp(val4, val2, (num3 - 0.78f) * 1.2f); } array[i * size + j] = val4; } } val.SetPixels(array); val.Apply(false, false); return Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), 100f); } private static float FractalNoise(float x, float y) { float num = 0f; float num2 = 0.5f; float num3 = 1f; for (int i = 0; i < 5; i++) { num += num2 * Mathf.PerlinNoise(x * num3, y * num3); num3 *= 2.03f; num2 *= 0.5f; } return Mathf.Clamp01(num); } public static void ApplyPanel(Image image, bool useIconBackdrop = false) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { Sprite val = (useIconBackdrop ? EnsureIconLoaded() : null); if ((Object)(object)val != (Object)null) { image.sprite = val; image.type = (Type)0; image.preserveAspect = false; ((Graphic)image).color = new Color(0.45f, 0.4f, 0.32f, 0.98f); } else { image.sprite = StonePanel; image.type = (Type)2; image.pixelsPerUnitMultiplier = 1.15f; ((Graphic)image).color = Color.white; } } } public static void ApplyField(Image image) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { image.sprite = BrassField; image.type = (Type)2; image.pixelsPerUnitMultiplier = 1.25f; ((Graphic)image).color = Color.white; } } public static void ApplyRim(Image image) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { image.sprite = BrassField; image.type = (Type)2; image.pixelsPerUnitMultiplier = 0.9f; ((Graphic)image).color = new Color(0.55f, 0.4f, 0.14f, 1f); } } } internal class VampireDayNightIndicator : MonoBehaviour { private RectTransform _iconRoot; private TMP_Text _iconText; private void LateUpdate() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)EnvMan.instance == (Object)null) { HideIcon(); return; } RaceType race = RaceManager.GetRace(localPlayer); if (race != RaceType.Vampire && race != RaceType.Dwarf && !ElfTypeManager.IsDrow(localPlayer) && !GenasiTypeManager.Is(localPlayer, GenasiType.Fire)) { HideIcon(); return; } if (VampireVisionState.LastEnv != null) { if (GenasiTypeManager.Is(localPlayer, GenasiType.Fire)) { VampireVision.ApplyRedNightVision(VampireVisionState.LastEnv); } else { VampireVision.ApplyMiddayVision(VampireVisionState.LastEnv); } } if (race == RaceType.Vampire) { UpdateDayNightIcon(); } else { HideIcon(); } } private void UpdateDayNightIcon() { //IL_00a9: 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) if (!((Object)(object)Hud.instance?.m_healthText == (Object)null) && !((Object)(object)Hud.instance.m_healthPanel == (Object)null)) { EnsureIcon(); ((Component)_iconRoot).gameObject.SetActive(true); if (EnvMan.IsDay()) { _iconText.text = "☀"; ((Graphic)_iconText).color = new Color(1f, 0.86f, 0.25f, 1f); } else { _iconText.text = "N"; ((Graphic)_iconText).color = new Color(0.78f, 0.84f, 1f, 1f); } } } private void EnsureIcon() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0062: 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) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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) if (!((Object)(object)_iconRoot != (Object)null)) { TMP_Text healthText = Hud.instance.m_healthText; GameObject val = new GameObject("Ent1tyRaces_VampireDayNight"); _iconRoot = val.AddComponent(); ((Transform)_iconRoot).SetParent((Transform)(object)Hud.instance.m_healthPanel, false); ((Transform)_iconRoot).SetAsLastSibling(); _iconRoot.anchorMin = new Vector2(0f, 1f); _iconRoot.anchorMax = new Vector2(0f, 1f); _iconRoot.pivot = new Vector2(0f, 1f); _iconRoot.anchoredPosition = new Vector2(-28f, -4f); _iconRoot.sizeDelta = new Vector2(24f, 24f); _iconText = (TMP_Text)(object)val.AddComponent(); _iconText.font = healthText.font; _iconText.fontSharedMaterial = healthText.fontSharedMaterial; _iconText.fontSize = healthText.fontSize * 0.95f; _iconText.alignment = (TextAlignmentOptions)514; ((Graphic)_iconText).raycastTarget = false; _iconText.fontStyle = (FontStyles)1; } } private void HideIcon() { if ((Object)(object)_iconRoot != (Object)null) { ((Component)_iconRoot).gameObject.SetActive(false); } } private void OnDestroy() { if ((Object)(object)_iconRoot != (Object)null) { Object.Destroy((Object)(object)((Component)_iconRoot).gameObject); } } } } namespace Ent1tyRaces.Races { internal static class AarakocraFlight { private const float SeaLevel = 30f; private const float MaxAltitudeAboveSea = 120f; private const float AshlandsFallMultiplier = 5f; private const float FlyMoveStaminaPerSecond = 7f; private const float FlyRunStaminaMult = 1.45f; private static readonly HashSet FlyingPlayers = new HashSet(); private static readonly FieldInfo CurrentVelField = AccessTools.Field(typeof(Character), "m_currentVel"); private static readonly FieldInfo LastGroundTouchField = AccessTools.Field(typeof(Character), "m_lastGroundTouch"); private static readonly FieldInfo MaxAirAltitudeField = AccessTools.Field(typeof(Character), "m_maxAirAltitude"); private static readonly int SlowFallHash = StringExtensionMethods.GetStableHashCode("SlowFall"); private static readonly FieldInfo WaterLevelField = AccessTools.Field(typeof(Character), "m_waterLevel"); private static readonly RaycastHit[] SolidHits = (RaycastHit[])(object)new RaycastHit[32]; private static int _solidRayMask; public static bool IsFlying(Player player) { if ((Object)(object)player != (Object)null) { return FlyingPlayers.Contains(player); } return false; } public static void Toggle(Player player) { if ((Object)(object)player == (Object)null) { return; } if (IsFlightEnvironmentBlocked(player, out var message)) { if (IsFlying(player)) { DisableFlight(player, message); } else { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } } else if (FlyingPlayers.Contains(player)) { DisableFlight(player, "You fold your wings."); } else { EnableFlight(player); } } public static void Update(Player player) { if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Aarakocra) { return; } if (IsTooHigh(player)) { if (IsFlying(player)) { DisableFlight(player, "Too high for flying."); } RemoveFeatherFall(player); } else if (IsInAshlands(player) && !IsAboveAshlandsLand(player)) { if (IsFlying(player)) { DisableFlight(player, "The heat is too heavy for flight"); } if (((Character)player).InWater() || ((Character)player).IsSwimming()) { EnsureFeatherFall(player); return; } RemoveFeatherFall(player); ApplyAshlandsOceanPlunge(player); } else { EnsureFeatherFall(player); if (IsFlying(player) && IsFlightEnvironmentBlocked(player, out var message)) { DisableFlight(player, message); } } } public static bool TryHandleMotion(Character character, float dt) { Player val = (Player)(object)((character is Player) ? character : null); if (val == null || !IsFlying(val)) { return false; } if (RaceManager.GetRace(val) != RaceType.Aarakocra) { FlyingPlayers.Remove(val); return false; } if (IsTooHigh(val)) { DisableFlight(val, "Too high for flying."); RemoveFeatherFall(val); return false; } if (IsFlightEnvironmentBlocked(val, out var message)) { DisableFlight(val, message); return false; } ApplyFlightPhysics(val, dt); return true; } private static void EnableFlight(Player player) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) FlyingPlayers.Add(player); Rigidbody component = ((Component)player).GetComponent(); if ((Object)(object)component != (Object)null) { component.useGravity = false; component.isKinematic = true; component.linearVelocity = Vector3.zero; component.angularVelocity = Vector3.zero; } ((Character)player).Message((MessageType)1, "Wings unfurled.", 0, (Sprite)null); } private static void ApplyFlightPhysics(Player player, float dt) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) Rigidbody component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null) { return; } float num = (((Character)player).IsRunning() ? ((float)Character.m_debugFlySpeed * 2.5f) : ((float)Character.m_debugFlySpeed)); Vector3 val = ((Character)player).GetMoveDir() * num; bool num2 = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump"); bool flag = ZInput.GetKey((KeyCode)306, true) || ZInput.GetButtonPressedTimer("JoyCrouch") > 0.33f; if (num2) { val.y = num; } else if (flag) { val.y = 0f - num; } if ((((Character)player).InWater() || ((Character)player).IsSwimming()) && val.y < 0f) { val.y = 0f; } if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { float num3 = 7f * dt; if (((Character)player).IsRunning()) { num3 *= 1.45f; } if (!((Character)player).HaveStamina(num3 + 0.05f)) { val = Vector3.zero; if (Time.frameCount % 90 == 0) { ((Character)player).Message((MessageType)1, "Too weary to flap.", 0, (Sprite)null); } } else { ((Character)player).UseStamina(num3); } } Vector3 val2 = val; Vector3 val3 = ((Component)player).transform.position + val2 * dt; if (GetAltitudeAboveSea(val3) >= 120f) { val3.y = 150f; DisableFlight(player, "Too high for flying."); RemoveFeatherFall(player); } component.useGravity = false; component.isKinematic = true; ((Component)player).transform.position = val3; component.linearVelocity = Vector3.zero; component.angularVelocity = Vector3.zero; CurrentVelField?.SetValue(player, val2); LastGroundTouchField?.SetValue(player, 0f); MaxAirAltitudeField?.SetValue(player, val3.y); } private static void ApplyAshlandsOceanPlunge(Player player) { //IL_0028: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) Rigidbody component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null)) { if (component.isKinematic) { component.isKinematic = false; } component.useGravity = true; Vector3 linearVelocity = component.linearVelocity; linearVelocity.y += Physics.gravity.y * 4f * Time.deltaTime; if (linearVelocity.y > 0f) { linearVelocity.y = 0f; } component.linearVelocity = linearVelocity; CurrentVelField?.SetValue(player, linearVelocity); } } private static void DisableFlight(Player player, string message) { if (!((Object)(object)player == (Object)null)) { bool num = FlyingPlayers.Remove(player); Rigidbody component = ((Component)player).GetComponent(); if ((Object)(object)component != (Object)null) { component.isKinematic = false; component.useGravity = true; } if (num && !string.IsNullOrEmpty(message)) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } } } private static void EnsureFeatherFall(Player player) { if (IsTooHigh(player)) { RemoveFeatherFall(player); return; } SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null && !sEMan.HaveStatusEffect(SlowFallHash)) { sEMan.AddStatusEffect(SlowFallHash, true, 0, 0f); } } public static void RemoveFeatherFall(Player player) { if (player != null) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SlowFallHash, true); } } } private static float GetAltitudeAboveSea(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return position.y - 30f; } private static bool IsTooHigh(Player player) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)null) { return GetAltitudeAboveSea(((Component)player).transform.position) >= 120f; } return false; } private static bool IsFlightEnvironmentBlocked(Player player, out string message) { message = null; if ((Object)(object)player == (Object)null) { return false; } if (IsInAshlands(player) && !IsAboveAshlandsLand(player)) { message = "The heat is too heavy for flight"; return true; } return false; } private static float EstimateWaterSurfaceY(Player player) { if (WaterLevelField?.GetValue(player) is float num && num > -9000f) { return num; } return 30f; } private static bool IsInAshlands(Player player) { //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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } Vector3 position = ((Component)player).transform.position; return WorldGenerator.IsAshlands(position.x, position.z); } public static bool IsAboveAshlandsLand(Player player) { //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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } Vector3 position = ((Component)player).transform.position; if (!WorldGenerator.IsAshlands(position.x, position.z)) { return true; } if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } Vector3 val = position; if (ZoneSystem.instance.IsLava(ref val, false) || ZoneSystem.IsLavaPreHeightmap(position, 0.6f)) { return true; } float num = 30f; if (WorldGenerator.instance != null && WorldGenerator.instance.GetHeight(position.x, position.z) > num + 0.5f) { return true; } if (ZoneSystem.instance.GetGroundHeight(position) > num + 0.25f) { return true; } return HasFlyableSolidAboveWater(position, num); } private static int GetSolidRayMask() { if (_solidRayMask == 0) { _solidRayMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" }); } return _solidRayMask; } private static bool HasFlyableSolidAboveWater(Vector3 position, float waterLevel) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0054: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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) int num = Physics.RaycastNonAlloc(new Vector3(position.x, Mathf.Max(position.y, waterLevel) + 500f, position.z), Vector3.down, SolidHits, 5000f, GetSolidRayMask(), (QueryTriggerInteraction)1); float num2 = float.NegativeInfinity; float num3 = float.NegativeInfinity; for (int i = 0; i < num; i++) { RaycastHit val = SolidHits[i]; if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null || IsWaterCollider(((RaycastHit)(ref val)).collider)) { continue; } if ((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent() != (Object)null) { if (((RaycastHit)(ref val)).point.y > num3) { num3 = ((RaycastHit)(ref val)).point.y; } } else if (((RaycastHit)(ref val)).point.y > num2) { num2 = ((RaycastHit)(ref val)).point.y; } } if (num2 >= waterLevel - 0.5f) { return true; } return num3 > waterLevel + 0.25f; } private static bool IsWaterCollider(Collider collider) { if ((Object)(object)collider == (Object)null) { return false; } if ((Object)(object)((Component)collider).GetComponentInParent() != (Object)null) { return true; } string name = ((Object)collider).name; if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLowerInvariant(); if (!text.Contains("water")) { return text.Contains("liquid"); } return true; } } internal static class AarakocraTalons { private const string BonusKey = "Ent1ty303.TalonDamage"; private const string AbsorbedKey = "Ent1ty303.TalonAbsorbed"; public static string GetLastAbsorbedKnifeId(Player player) { if (!PlayerDataStore.TryGetString(player, "Ent1ty303.TalonAbsorbed", out var value) || string.IsNullOrEmpty(value)) { return null; } string[] array = value.Split(new char[1] { '|' }); for (int num = array.Length - 1; num >= 0; num--) { if (!string.IsNullOrEmpty(array[num])) { return array[num]; } } return null; } public static void Update(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(player) == RaceType.Aarakocra && (ZInput.GetKeyDown((KeyCode)308, true) || ZInput.GetKeyDown((KeyCode)307, true))) { TryAbsorbKnife(player); } } public static void TryAbsorbKnife(Player player) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); if (currentWeapon?.m_shared == null || (int)currentWeapon.m_shared.m_skillType != 2) { ((Character)player).Message((MessageType)2, "Hold a knife to absorb into your talons.", 0, (Sprite)null); return; } if (IsButcherKnife(currentWeapon)) { ((Character)player).Message((MessageType)2, "Talons refuse the butcher's blade.", 0, (Sprite)null); return; } string name = currentWeapon.m_shared.m_name; if (HasAbsorbed(player, name)) { ((Character)player).Message((MessageType)2, "Those talons already remember this blade.", 0, (Sprite)null); return; } float knifeTotalDamage = GetKnifeTotalDamage(currentWeapon); if (knifeTotalDamage <= 0f) { ((Character)player).Message((MessageType)2, "This knife has no edge to absorb.", 0, (Sprite)null); return; } float num = GetTalonBonus(player) + knifeTotalDamage; PlayerDataStore.SetFloat(player, "Ent1ty303.TalonDamage", num); MarkAbsorbed(player, name); AarakocraTalonVisuals.RememberKnife(player, currentWeapon); ((Humanoid)player).UnequipItem(currentWeapon, true); ((Humanoid)player).GetInventory().RemoveOneItem(currentWeapon); ((Character)player).Message((MessageType)2, $"Talons drink the steel. Unarmed +{knifeTotalDamage:0.#} (total +{num:0.#}).", 0, (Sprite)null); } private static bool IsButcherKnife(ItemData weapon) { if (weapon?.m_shared == null) { return false; } string obj = (((Object)(object)weapon.m_dropPrefab != (Object)null) ? ((Object)weapon.m_dropPrefab).name : string.Empty); string text = weapon.m_shared.m_name ?? string.Empty; if (obj.IndexOf("KnifeButcher", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("butcher", StringComparison.OrdinalIgnoreCase) < 0) { return text.IndexOf("knife_butcher", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static float GetKnifeTotalDamage(ItemData weapon) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (weapon == null) { return 0f; } try { DamageTypes damage = weapon.GetDamage(); return ((DamageTypes)(ref damage)).GetTotalDamage(); } catch { return ((DamageTypes)(ref weapon.m_shared.m_damages)).GetTotalDamage(); } } private static bool HasAbsorbed(Player player, string knifeId) { if (!PlayerDataStore.TryGetString(player, "Ent1ty303.TalonAbsorbed", out var value) || string.IsNullOrEmpty(value)) { return false; } string[] array = value.Split(new char[1] { '|' }); for (int i = 0; i < array.Length; i++) { if (array[i] == knifeId) { return true; } } return false; } private static void MarkAbsorbed(Player player, string knifeId) { if (PlayerDataStore.TryGetString(player, "Ent1ty303.TalonAbsorbed", out var value) && !string.IsNullOrEmpty(value)) { PlayerDataStore.SetString(player, "Ent1ty303.TalonAbsorbed", value + "|" + knifeId); } else { PlayerDataStore.SetString(player, "Ent1ty303.TalonAbsorbed", knifeId); } } public static float GetTalonBonus(Player player) { if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Aarakocra) { return 0f; } if (!PlayerDataStore.TryGetFloat(player, "Ent1ty303.TalonDamage", out var value)) { return 0f; } return value; } public static void ApplyUnarmedBonus(Player player, HitData hit) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if (hit != null && !((Object)(object)player == (Object)null) && (int)hit.m_skill == 11) { float talonBonus = GetTalonBonus(player); if (!(talonBonus <= 0f)) { hit.m_damage.m_slash += talonBonus * 0.5f; hit.m_damage.m_pierce += talonBonus * 0.5f; } } } } internal static class AarakocraTalonVisuals { private const string LastKnifeKey = "Ent1ty303.TalonLastKnife"; private static readonly MethodInfo AttachItemMethod = AccessTools.Method(typeof(VisEquipment), "AttachItem", new Type[5] { typeof(int), typeof(int), typeof(Transform), typeof(bool), typeof(bool) }, (Type[])null); private static GameObject _rightKnife; private static GameObject _leftKnife; private static string _loadedPrefab; private static bool _visible; public static void RememberKnife(Player player, ItemData weapon) { if (!((Object)(object)player == (Object)null) && !((Object)(object)weapon?.m_dropPrefab == (Object)null)) { PlayerDataStore.SetString(player, "Ent1ty303.TalonLastKnife", ((Object)weapon.m_dropPrefab).name); } } public static void Update(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } if (RaceManager.GetRace(player) != RaceType.Aarakocra) { Hide(); } else if (!((Character)player).InAttack() || !DragonbornBreathInput.IsUnarmed(player) || ResolveKnifePrefab(player) == null) { if (_visible) { SetVisible(visible: false); } } else { EnsureAttached(player); SetVisible(visible: true); } } private static string ResolveKnifePrefab(Player player) { if (PlayerDataStore.TryGetString(player, "Ent1ty303.TalonLastKnife", out var value) && !string.IsNullOrEmpty(value) && (Object)(object)ObjectDB.instance != (Object)null && (Object)(object)ObjectDB.instance.GetItemPrefab(value) != (Object)null) { return value; } string lastAbsorbedKnifeId = AarakocraTalons.GetLastAbsorbedKnifeId(player); if (string.IsNullOrEmpty(lastAbsorbedKnifeId) || (Object)(object)ObjectDB.instance == (Object)null) { return null; } string text = FindKnifePrefabBySharedName(lastAbsorbedKnifeId); if (string.IsNullOrEmpty(text)) { return null; } PlayerDataStore.SetString(player, "Ent1ty303.TalonLastKnife", text); return text; } private static string FindKnifePrefabBySharedName(string sharedName) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 foreach (GameObject item in ObjectDB.instance.m_items) { if (!((Object)(object)item == (Object)null)) { ItemDrop component = item.GetComponent(); if (component?.m_itemData?.m_shared != null && (int)component.m_itemData.m_shared.m_skillType == 2 && component.m_itemData.m_shared.m_name == sharedName) { return ((Object)item).name; } } } return null; } private static void EnsureAttached(Player player) { string text = ResolveKnifePrefab(player); if (!string.IsNullOrEmpty(text)) { VisEquipment componentInChildren = ((Component)player).GetComponentInChildren(); if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)componentInChildren.m_rightHand == (Object)null) && !((Object)(object)componentInChildren.m_leftHand == (Object)null) && (!(_loadedPrefab == text) || !((Object)(object)_rightKnife != (Object)null) || !((Object)(object)_leftKnife != (Object)null))) { Hide(); int stableHashCode = StringExtensionMethods.GetStableHashCode(text); _rightKnife = Attach(componentInChildren, stableHashCode, componentInChildren.m_rightHand); _leftKnife = Attach(componentInChildren, stableHashCode, componentInChildren.m_leftHand); _loadedPrefab = text; TuneTalonTransform(_rightKnife, mirror: false); TuneTalonTransform(_leftKnife, mirror: true); } } } private static GameObject Attach(VisEquipment vis, int hash, Transform hand) { if (AttachItemMethod == null) { return null; } object? obj = AttachItemMethod.Invoke(vis, new object[5] { hash, 0, hand, false, false }); return (GameObject)((obj is GameObject) ? obj : null); } private static void TuneTalonTransform(GameObject knife, bool mirror) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)knife == (Object)null)) { knife.transform.localPosition = new Vector3(mirror ? (-0.02f) : 0.02f, 0.02f, 0.06f); knife.transform.localRotation = Quaternion.Euler(-20f, mirror ? (-90f) : 90f, 180f); knife.transform.localScale = Vector3.one * 0.85f; } } private static void SetVisible(bool visible) { _visible = visible; if ((Object)(object)_rightKnife != (Object)null) { _rightKnife.SetActive(visible); } if ((Object)(object)_leftKnife != (Object)null) { _leftKnife.SetActive(visible); } } private static void Hide() { if ((Object)(object)_rightKnife != (Object)null) { Object.Destroy((Object)(object)_rightKnife); _rightKnife = null; } if ((Object)(object)_leftKnife != (Object)null) { Object.Destroy((Object)(object)_leftKnife); _leftKnife = null; } _loadedPrefab = null; _visible = false; } } internal static class AasimarWisp { private static GameObject _ball; private static Light _light; private static readonly int DemisterHash = StringExtensionMethods.GetStableHashCode("Demister"); public static void Update(Player player) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } if (RaceManager.GetRace(player) != RaceType.Aasimar) { Remove(player); return; } SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(DemisterHash, true); } EnsureBall(player); if (!((Object)(object)_ball == (Object)null)) { float time = Time.time; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Mathf.Cos(time * 1.4f) * 1.1f, 1.3f + Mathf.Sin(time * 2.1f) * 0.25f, Mathf.Sin(time * 1.4f) * 1.1f); _ball.transform.position = ((Component)player).transform.position + val; } } public static void Remove(Player player) { if (player != null) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(DemisterHash, true); } } if ((Object)(object)_ball != (Object)null) { Object.Destroy((Object)(object)_ball); _ball = null; _light = null; } } private static void EnsureBall(Player player) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown if ((Object)(object)_ball != (Object)null) { return; } _ball = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)_ball).name = "Ent1tyRaces_AasimarWisp"; Object.Destroy((Object)(object)_ball.GetComponent()); _ball.transform.localScale = Vector3.one * 0.18f; MeshRenderer component = _ball.GetComponent(); if ((Object)(object)component != (Object)null) { Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Standard"); if ((Object)(object)val != (Object)null) { ((Renderer)component).material = new Material(val) { color = new Color(0.75f, 0.82f, 1f, 0.28f) }; } } _light = _ball.AddComponent(); _light.color = new Color(0.92f, 0.95f, 1f, 1f); _light.intensity = 4.2f; _light.range = 22f; _light.shadows = (LightShadows)0; Object.DontDestroyOnLoad((Object)(object)_ball); } } internal static class AasimarHealBreath { private const float AoeRadius = 4f; private const float AoeRange = 8f; private const float BreathCooldown = 1f; private static float _nextBreath; private static readonly Dictionary ActiveHeals = new Dictionary(); public static bool TryStartFromAttack(Player player) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || RaceManager.GetRace(player) != RaceType.Aasimar) { return false; } if (!DragonbornBreathInput.AreBreathButtonsHeld()) { return false; } if (Time.time < _nextBreath) { return true; } float breathElementDamage = DragonbornBreath.GetBreathElementDamage(player); if (breathElementDamage <= 0f) { return true; } float breathStaminaCostPublic = DragonbornBreath.GetBreathStaminaCostPublic(player); if (!((Character)player).HaveStamina(breathStaminaCostPublic + 0.1f)) { ((Character)player).Message((MessageType)2, "Not enough stamina to heal.", 0, (Sprite)null); return true; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player); ((Character)player).UseStamina(breathStaminaCostPublic); Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 val = eyePoint + lookDir * 4f; DragonbornBreath.SpawnBreathFx(BreathElement.Poison, eyePoint, lookDir); List list = new List { (Character)(object)player }; List list2 = new List(); Character.GetCharactersInRange(val, 4f, list2); foreach (Character item in list2) { if (!((Object)(object)item == (Object)null) && !item.IsDead() && !((Object)(object)item == (Object)(object)player) && (item is Player || item.IsTamed())) { Vector3 val2 = item.GetCenterPoint() - eyePoint; if (!(((Vector3)(ref val2)).magnitude > 8f) && !(Vector3.Dot(((Vector3)(ref val2)).normalized, lookDir) < 0.2f)) { list.Add(item); } } } StartHealBurst(player, list, breathElementDamage); _nextBreath = Time.time + 1f; return true; } public static void Update(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(player) == RaceType.Aasimar && DragonbornBreathInput.ShouldSuppressTowerShieldBlock(player)) { DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); if (DragonbornBreathInput.IsAttackPressed()) { DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player); } } } private static void StartHealBurst(Player caster, List targets, float totalHeal) { if ((Object)(object)Ent1tyRacesPlugin.Instance == (Object)null) { float amount = totalHeal / 5f; for (int i = 0; i < 5; i++) { ApplyHealTick(targets, amount); } } else { if (ActiveHeals.TryGetValue(caster, out var value) && value != null) { ((MonoBehaviour)Ent1tyRacesPlugin.Instance).StopCoroutine(value); } ActiveHeals[caster] = ((MonoBehaviour)Ent1tyRacesPlugin.Instance).StartCoroutine(HealBurstRoutine(caster, targets, totalHeal)); } } private static IEnumerator HealBurstRoutine(Player caster, List targets, float totalHeal) { try { float interval = 0.2f; float perTick = totalHeal / 5f; for (int tick = 0; tick < 5; tick++) { ApplyHealTick(targets, perTick); if (tick < 4) { yield return (object)new WaitForSeconds(interval); } } } finally { if ((Object)(object)caster != (Object)null) { ActiveHeals.Remove(caster); } } } private static void ApplyHealTick(List targets, float amount) { if (amount <= 0f || targets == null) { return; } foreach (Character target in targets) { if (!((Object)(object)target == (Object)null) && !target.IsDead()) { target.Heal(amount, true); } } } } internal static class AasimarFlight { private static readonly int SlowFallHash = StringExtensionMethods.GetStableHashCode("SlowFall"); private static readonly FieldInfo BodyField = AccessTools.Field(typeof(Character), "m_body"); private static readonly FieldInfo LastGroundNormalField = AccessTools.Field(typeof(Character), "m_lastGroundNormal"); private static readonly FieldInfo MoveDirField = AccessTools.Field(typeof(Character), "m_moveDir"); private static int _airJumpsLeft = 1; private static int _prevAlmanacJumpCount; public static void Update(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(player) == RaceType.Aasimar) { EnsureFeatherFall(player); if (((Character)player).IsOnGround()) { _airJumpsLeft = 1; _prevAlmanacJumpCount = 0; } } } public static void TryAlmanacCompatibleAirJump(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || RaceManager.GetRace(player) != RaceType.Aasimar) { return; } if (((Character)player).IsOnGround()) { _airJumpsLeft = 1; _prevAlmanacJumpCount = AlmanacAirJumpBridge.GetJumpCount(); return; } if (IsUnderwaterOrSwimming(player) || _airJumpsLeft <= 0) { _prevAlmanacJumpCount = AlmanacAirJumpBridge.GetJumpCount(); return; } if (!ZInput.GetButtonDown("Jump") && !ZInput.GetButtonDown("JoyJump")) { _prevAlmanacJumpCount = AlmanacAirJumpBridge.GetJumpCount(); return; } int jumpCount = AlmanacAirJumpBridge.GetJumpCount(); int airBenderMaxJumps = AlmanacAirJumpBridge.GetAirBenderMaxJumps(); if (jumpCount > _prevAlmanacJumpCount) { _prevAlmanacJumpCount = jumpCount; return; } _prevAlmanacJumpCount = jumpCount; if (!AlmanacAirJumpBridge.HasAirBenderAltActive() && (airBenderMaxJumps <= 0 || jumpCount >= airBenderMaxJumps)) { TryAirJump(player); } } public static bool TryAirJump(Player player) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Aasimar || ((Character)player).IsOnGround()) { return false; } if (IsUnderwaterOrSwimming(player) || _airJumpsLeft <= 0) { return false; } if (!((Character)player).HaveStamina(((Character)player).m_jumpStaminaUsage * 0.4f)) { return false; } ((Character)player).UseStamina(((Character)player).m_jumpStaminaUsage * 0.4f); object? obj = BodyField?.GetValue(player); Rigidbody val = (Rigidbody)((obj is Rigidbody) ? obj : null); if (val == null) { return false; } Vector3 val2 = ((LastGroundNormalField?.GetValue(player) is Vector3 val3) ? val3 : Vector3.up); Vector3 val4 = ((MoveDirField?.GetValue(player) is Vector3 val5) ? val5 : Vector3.zero); Vector3 linearVelocity = val.linearVelocity; linearVelocity.y = 0f; Vector3 val6 = linearVelocity; Vector3 val7 = val2 + Vector3.up; linearVelocity = val6 + ((Vector3)(ref val7)).normalized * ((Character)player).m_jumpForce; linearVelocity += val4 * ((Character)player).m_jumpForceForward; val.linearVelocity = linearVelocity; _airJumpsLeft--; return true; } private static bool IsUnderwaterOrSwimming(Player player) { if (((Character)player).IsSwimming()) { return true; } return GenasiWaterSwimPose.IsHeadUnderLiquid(player); } public static void RemoveFeatherFall(Player player) { if (player != null) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SlowFallHash, true); } } } private static void EnsureFeatherFall(Player player) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null && !sEMan.HaveStatusEffect(SlowFallHash)) { sEMan.AddStatusEffect(SlowFallHash, true, 0, 0f); } } } internal static class AlmanacAirJumpBridge { private const string AlmanacAsm = "AlmanacClasses"; private const string AirBenderTypeName = "AlmanacClasses.Classes.Abilities.Core.AirBender"; private const string PlayerManagerTypeName = "AlmanacClasses.Classes.PlayerManager"; private static bool _resolved; private static bool _present; private static FieldInfo _jumpCountField; private static FieldInfo _talentsField; private static MethodInfo _getLevelMethod; private static FieldInfo _passiveActiveField; public static bool IsAlmanacPresent { get { EnsureResolved(); return _present; } } public static void EnsureResolved() { if (_resolved) { return; } _resolved = true; try { Assembly assembly = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly2 in assemblies) { if (assembly2.GetName().Name == "AlmanacClasses") { assembly = assembly2; break; } } if (assembly == null) { return; } Type type = assembly.GetType("AlmanacClasses.Classes.Abilities.Core.AirBender"); Type type2 = assembly.GetType("AlmanacClasses.Classes.PlayerManager"); if (!(type == null) && !(type2 == null)) { _jumpCountField = type.GetField("JumpCount", BindingFlags.Static | BindingFlags.NonPublic); _talentsField = type2.GetField("m_playerTalents", BindingFlags.Static | BindingFlags.Public); if (!(_jumpCountField == null) && !(_talentsField == null)) { _present = true; } } } catch (Exception ex) { Logger.LogWarning((object)("Ent1tyRaces: Almanac jump bridge failed (" + ex.Message + ")")); _present = false; } } public static int GetJumpCount() { EnsureResolved(); if (!_present || _jumpCountField == null) { return 0; } try { return (int)_jumpCountField.GetValue(null); } catch { return 0; } } public static int GetAirBenderMaxJumps() { EnsureResolved(); if (!_present || _talentsField == null) { return 0; } try { if (!(_talentsField.GetValue(null) is IDictionary dictionary)) { return 0; } if (!dictionary.Contains("AirBender")) { return 0; } object obj = dictionary["AirBender"]; if (obj == null) { return 0; } if (_passiveActiveField == null) { _passiveActiveField = obj.GetType().GetField("m_passiveActive", BindingFlags.Instance | BindingFlags.Public); } if (_passiveActiveField != null) { object value = _passiveActiveField.GetValue(obj); if (value is bool && !(bool)value) { return 0; } } if (_getLevelMethod == null) { _getLevelMethod = obj.GetType().GetMethod("GetLevel", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null); } if (_getLevelMethod == null) { return 0; } return (_getLevelMethod.Invoke(obj, null) is int num) ? Mathf.Max(0, num) : 0; } catch { return 0; } } public static bool HasAirBenderAltActive() { EnsureResolved(); if (!_present || _talentsField == null) { return false; } try { if (!(_talentsField.GetValue(null) is IDictionary dictionary) || !dictionary.Contains("AirBenderAlt")) { return false; } object obj = dictionary["AirBenderAlt"]; if (obj == null) { return false; } object obj2 = obj.GetType().GetField("m_passiveActive", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj); bool flag = default(bool); int num; if (obj2 is bool) { flag = (bool)obj2; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } } internal static class BodyScale { public const float Giant = 2f; public const float SlightlySmall = 0.75f; public const float GnomeScale = 0.5f; public const float TieflingScale = 0.95f; public const float HalflingScale = 0.65f; public const float Normal = 1f; public static float GetScale(Player player) { if ((Object)(object)player == (Object)null) { return 1f; } return RaceManager.GetRace(player) switch { RaceType.Giant => 2f, RaceType.Dwarf => 0.75f, RaceType.Gnome => 0.5f, RaceType.Tiefling => 0.95f, RaceType.Halfling => 0.65f, _ => 1f, }; } public static void Update(Player player) { //IL_0011: 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) //IL_001c: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0043: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { float scale = GetScale(player); Vector3 val = Vector3.one * scale; Vector3 val2 = ((Component)player).transform.localScale - val; if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { ((Component)player).transform.localScale = val; } } } } internal static class BreathDamageApplicator { internal const float BreathHitMarker = -4242f; internal const float MountainShiftYellowMarker = 1f; private static readonly MethodInfo BlockAttackMethod = AccessTools.Method(typeof(Character), "BlockAttack", new Type[2] { typeof(HitData), typeof(Character) }, (Type[])null); private static readonly MethodInfo GetWeakSpotMethod = AccessTools.Method(typeof(Character), "GetWeakSpot", new Type[1] { typeof(short) }, (Type[])null); private static readonly MethodInfo DamageArmorDurabilityMethod = AccessTools.Method(typeof(Character), "DamageArmorDurability", new Type[1] { typeof(HitData) }, (Type[])null); private static readonly FieldInfo BaseAiField = AccessTools.Field(typeof(Character), "m_baseAI"); public static void MarkBreathHit(HitData hit) { if (hit != null) { hit.m_pushForce = -4242f; } } public static bool IsBreathHit(HitData hit) { if (hit != null) { return Mathf.Approximately(hit.m_pushForce, -4242f); } return false; } public static void ApplyBreathTick(Player attacker, Character target, HitData hit, BreathElement element, float tickDamage, bool mountainShiftYellow) { if (!((Object)(object)attacker == (Object)null) && !((Object)(object)target == (Object)null) && hit != null && !(tickDamage <= 0f)) { ElementResistance.SetElementDamage(hit, element, tickDamage); MarkBreathHit(hit); hit.m_healthReturn = (mountainShiftYellow ? 1f : 0f); target.Damage(hit); } } public static void ApplyBreathDamage(Character target, HitData hit) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || hit == null || !target.m_nview.IsOwner()) { return; } Character attacker = hit.GetAttacker(); if (GetHealthBlocked(target, hit, attacker)) { return; } if ((Object)(object)attacker != (Object)null && !attacker.IsPlayer()) { float difficultyDamageScalePlayer = Game.instance.GetDifficultyDamageScalePlayer(((Component)target).transform.position); hit.ApplyModifier(difficultyDamageScalePlayer); hit.ApplyModifier(Game.m_enemyDamageRate); } target.GetSEMan().OnDamaged(hit, attacker); object? obj = BaseAiField?.GetValue(target); BaseAI val = (BaseAI)((obj is BaseAI) ? obj : null); if ((Object)(object)val != (Object)null && val.IsAggravatable() && !val.IsAggravated() && (Object)(object)attacker != (Object)null && attacker.IsPlayer() && hit.GetTotalDamage() > 0f) { BaseAI.AggravateAllInArea(((Component)target).transform.position, 20f, (AggravatedReason)0); } if (hit.m_blockable && target.IsBlocking()) { BlockAttackMethod?.Invoke(target, new object[2] { hit, attacker }); return; } Player val2 = (Player)(object)((target is Player) ? target : null); if (val2 != null) { target.AddAdrenaline(val2.m_nonBlockDamageAdrenaline); } object? obj2 = GetWeakSpotMethod?.Invoke(target, new object[1] { hit.m_weakSpot }); WeakSpot val3 = (WeakSpot)((obj2 is WeakSpot) ? obj2 : null); DamageModifiers damageModifiers = target.GetDamageModifiers(val3); DamageModifier val4 = default(DamageModifier); hit.ApplyResistance(damageModifiers, ref val4); if (target.IsPlayer()) { hit.ApplyArmor(target.GetBodyArmor()); DamageArmorDurabilityMethod?.Invoke(target, new object[1] { hit }); } else if (Game.m_worldLevel > 0) { hit.ApplyArmor((float)(Game.m_worldLevel * Game.instance.m_worldLevelEnemyBaseAC)); } float totalDamage = hit.GetTotalDamage(); DamageModifier val5 = val4; if (Mathf.Approximately(hit.m_healthReturn, 1f)) { val5 = (DamageModifier)2; } else { Player val6 = (Player)(object)((attacker is Player) ? attacker : null); if (val6 != null) { val5 = MountainShiftDisplay.GetDisplayModifier(val6, hit, val4); } } target.ApplyDamage(hit, false, true, val5); MountainShiftDamageText.Show((Player)(object)((attacker is Player) ? attacker : null), hit, val4, hit.m_point, totalDamage, target.IsPlayer() || target.IsTamed()); } private static bool GetHealthBlocked(Character target, HitData hit, Character attacker) { if (target.GetHealth() <= 0f || target.IsDead() || target.IsTeleporting() || target.InCutscene() || (hit.m_dodgeable && target.IsDodgeInvincible()) || (hit.HaveAttacker() && (Object)(object)attacker == (Object)null)) { return true; } if (target.IsPlayer() && !target.IsPVPEnabled() && (Object)(object)attacker != (Object)null && attacker.IsPlayer()) { return !hit.m_ignorePVP; } return false; } } [HarmonyPatch(typeof(Character), "RPC_Damage", new Type[] { typeof(long), typeof(HitData) })] internal static class DragonbornBreathRpcDamagePatch { private static bool Prefix(Character __instance, HitData hit) { if (!BreathDamageApplicator.IsBreathHit(hit)) { return true; } BreathDamageApplicator.ApplyBreathDamage(__instance, hit); return false; } } internal struct BreathStrikeTarget { public Character Target; public HitData Template; public BreathElement Element; public float TotalDamage; public bool MountainShiftYellow; } internal static class BreathDamageOverTime { public const int TickCount = 5; private static readonly Dictionary ActiveRoutines = new Dictionary(); public static void StartBurst(Player attacker, List strikes) { if ((Object)(object)attacker == (Object)null || strikes == null || strikes.Count == 0) { return; } if ((Object)(object)Ent1tyRacesPlugin.Instance == (Object)null) { ApplyBurstImmediate(attacker, strikes); return; } if (ActiveRoutines.TryGetValue(attacker, out var value) && value != null) { ((MonoBehaviour)Ent1tyRacesPlugin.Instance).StopCoroutine(value); } Coroutine value2 = ((MonoBehaviour)Ent1tyRacesPlugin.Instance).StartCoroutine(BurstRoutine(attacker, strikes)); ActiveRoutines[attacker] = value2; } private static IEnumerator BurstRoutine(Player attacker, List strikes) { try { float interval = 0.2f; for (int tick = 0; tick < 5; tick++) { if ((Object)(object)attacker == (Object)null) { break; } ApplyTickToTargets(attacker, strikes); if (tick < 4) { yield return (object)new WaitForSeconds(interval); } } } finally { if ((Object)(object)attacker != (Object)null && ActiveRoutines.TryGetValue(attacker, out var value) && value != null) { ActiveRoutines.Remove(attacker); } } } private static void ApplyBurstImmediate(Player attacker, List strikes) { for (int i = 0; i < 5; i++) { ApplyTickToTargets(attacker, strikes); } } private static void ApplyTickToTargets(Player attacker, List strikes) { foreach (BreathStrikeTarget strike in strikes) { if (!((Object)(object)strike.Target == (Object)null) && !strike.Target.IsDead() && BreathTargetFilter.CanBreathDamage(attacker, strike.Target)) { float tickDamage = strike.TotalDamage / 5f; HitData hit = strike.Template.Clone(); BreathDamageApplicator.ApplyBreathTick(attacker, strike.Target, hit, strike.Element, tickDamage, strike.MountainShiftYellow); } } } } public static class BreathManager { private const string CustomBreathKey = "Ent1ty303.BreathElement"; public static BreathElement GetBreathElement(Player player) { if ((Object)(object)player == (Object)null) { return BreathElement.Fire; } if (PlayerDataStore.TryGetInt(player, "Ent1ty303.BreathElement", out var value) && Enum.IsDefined(typeof(BreathElement), value)) { return (BreathElement)value; } return BreathElement.Fire; } public static bool TrySetBreathElement(Player player, BreathElement element, out string message) { message = null; if ((Object)(object)player == (Object)null) { message = "Load a character first."; return false; } if (RaceManager.GetRace(player) != RaceType.Dragonborn) { message = "Only Dragonborn can attune a breath element."; return false; } PlayerDataStore.SetInt(player, "Ent1ty303.BreathElement", (int)element); message = element switch { BreathElement.Fire => "Your breath burns with flame.", BreathElement.Poison => "Your breath hisses with venom.", BreathElement.Lightning => "Your breath crackles with thunder.", BreathElement.Ice => "Your breath freezes the air.", _ => $"Breath attuned to {element}.", }; if (((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } return true; } public static BreathElement ParseBreathElement(string value) { if (string.IsNullOrWhiteSpace(value)) { return BreathElement.Fire; } switch (value.Trim().ToLowerInvariant()) { case "fire": return BreathElement.Fire; case "poison": return BreathElement.Poison; case "lightning": return BreathElement.Lightning; case "ice": case "frost": return BreathElement.Ice; default: { BreathElement result; return Enum.TryParse(value, ignoreCase: true, out result) ? result : BreathElement.Fire; } } } } internal static class BreathTargetFilter { public static bool CanBreathDamage(Player attacker, Character target) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)attacker == (Object)null || (Object)(object)target == (Object)null || (Object)(object)target == (Object)(object)attacker || target.IsDead()) { return false; } if (target.IsPlayer()) { Player val = (Player)(object)((target is Player) ? target : null); if (val == null) { return false; } return ((Character)val).IsPVPEnabled(); } if (target.IsTamed()) { if (IsPlayersTame(attacker, target)) { return false; } if (!BaseAI.IsEnemy((Character)(object)attacker, target)) { return false; } } if (!BaseAI.IsEnemy((Character)(object)attacker, target) && target.GetFaction() == ((Character)attacker).GetFaction()) { return false; } return true; } private static bool IsPlayersTame(Player player, Character target) { long playerID = player.GetPlayerID(); long sessionPlayerId = GetSessionPlayerId(player); long owner = target.GetOwner(); if (owner != 0L && (owner == playerID || owner == sessionPlayerId)) { return true; } ZNetView component = ((Component)target).GetComponent(); if ((Object)(object)component != (Object)null && component.IsValid()) { long num = component.GetZDO().GetLong("owner", 0L); if (num != 0L && (num == playerID || num == sessionPlayerId)) { return true; } } return false; } private static long GetSessionPlayerId(Player player) { if ((Object)(object)player == (Object)null) { return 0L; } if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.GetUID(); } return player.GetPlayerID(); } } internal static class CloudGiantJump { private const float JumpStaminaMult = 0.45f; private const int MaxAirJumps = 1; private static readonly FieldInfo BodyField = AccessTools.Field(typeof(Character), "m_body"); private static readonly FieldInfo LastGroundNormalField = AccessTools.Field(typeof(Character), "m_lastGroundNormal"); private static readonly FieldInfo MoveDirField = AccessTools.Field(typeof(Character), "m_moveDir"); private static int _airJumpsLeft = 1; private static float _savedJumpStamina = -1f; public static void Update(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && GiantTypeManager.Is(player, GiantType.Cloud) && ((Character)player).IsOnGround()) { _airJumpsLeft = 1; } } public static bool IsCloud(Player player) { return GiantTypeManager.Is(player, GiantType.Cloud); } public static void BeginReducedJumpStamina(Character character) { if (_savedJumpStamina < 0f) { _savedJumpStamina = character.m_jumpStaminaUsage; character.m_jumpStaminaUsage *= 0.45f; } } public static void EndReducedJumpStamina(Character character) { if (_savedJumpStamina >= 0f) { character.m_jumpStaminaUsage = _savedJumpStamina; _savedJumpStamina = -1f; } } public static bool TryAirJump(Player player) { if (!IsCloud(player) || ((Character)player).IsOnGround() || ((Character)player).IsDead() || ((Character)player).IsEncumbered()) { return false; } if (_airJumpsLeft <= 0) { return false; } float num = ((Character)player).m_jumpStaminaUsage * 0.45f; if (!((Character)player).HaveStamina(num * 0.5f)) { Hud instance = Hud.instance; if (instance != null) { instance.StaminaBarEmptyFlash(); } return false; } ((Character)player).UseStamina(num); ApplyJumpVelocity(player); _airJumpsLeft--; return true; } private static void ApplyJumpVelocity(Player player) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) object? obj = BodyField?.GetValue(player); Rigidbody val = (Rigidbody)((obj is Rigidbody) ? obj : null); if (val != null) { Vector3 val2 = ((LastGroundNormalField?.GetValue(player) is Vector3 val3) ? val3 : Vector3.up); Vector3 val4 = ((MoveDirField?.GetValue(player) is Vector3 val5) ? val5 : Vector3.zero); float skillFactor = ((Character)player).GetSkillFactor((SkillType)100); float num = 1f + skillFactor * 0.4f; Vector3 val6 = val.linearVelocity; Vector3 val7 = val2 + Vector3.up; Vector3 normalized = ((Vector3)(ref val7)).normalized; float num2 = ((Character)player).m_jumpForce * num * 1f; float num3 = Vector3.Dot(normalized, val6); if (num3 < num2) { val6 += normalized * (num2 - num3); } val6 += val4 * ((Character)player).m_jumpForceForward * num * 1f; ((Character)player).ForceJump(val6, true); ((Character)player).RaiseSkill((SkillType)100, 1f); } } } internal static class CloudGiantTeleport { private const float MaxRange = 28f; private const float CooldownSeconds = 4f; private static float _nextReadyTime; private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[32]; public static void Update(Player player) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && GiantTypeManager.Is(player, GiantType.Cloud) && DragonbornBreathInput.AreBreathButtonsHeld() && DragonbornBreathInput.IsAttackPressed()) { if (Time.time < _nextReadyTime) { ((Character)player).Message((MessageType)2, "Clouds still gathering...", 0, (Sprite)null); return; } if (!TryFindTeleportPoint(player, out var destination)) { ((Character)player).Message((MessageType)2, "No landing in sight.", 0, (Sprite)null); return; } GiantBody.BlinkTo(player, destination); _nextReadyTime = Time.time + 4f; ((Character)player).Message((MessageType)2, "You step through the mist.", 0, (Sprite)null); SpawnCloudFx(destination); } } private static bool TryFindTeleportPoint(Player player, out Vector3 destination) { //IL_0007: 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_0012: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) destination = ((Component)player).transform.position; Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; int num = Physics.RaycastNonAlloc(eyePoint, normalized, Hits, 28f, -1, (QueryTriggerInteraction)1); float num2 = 28f; Vector3 val = eyePoint + normalized * 28f; Vector3 val2 = Vector3.up; for (int i = 0; i < num; i++) { RaycastHit val3 = Hits[i]; if (!((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null) && !((RaycastHit)(ref val3)).collider.isTrigger && !((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent() == (Object)(object)player) && ((RaycastHit)(ref val3)).distance > 0.75f && ((RaycastHit)(ref val3)).distance < num2) { num2 = ((RaycastHit)(ref val3)).distance; val = ((RaycastHit)(ref val3)).point; val2 = ((RaycastHit)(ref val3)).normal; } } destination = val + val2 * 0.35f + Vector3.up * 0.1f; RaycastHit val4 = default(RaycastHit); if (Physics.Raycast(destination + Vector3.up * 2f, Vector3.down, ref val4, 8f, -1, (QueryTriggerInteraction)1) && (Object)(object)((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent() != (Object)(object)player) { destination = ((RaycastHit)(ref val4)).point + Vector3.up * 0.15f; } return true; } private static void SpawnCloudFx(Vector3 pos) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNetScene.instance == (Object)null)) { GameObject val = ZNetScene.instance.GetPrefab("vfx_odin_despawn") ?? ZNetScene.instance.GetPrefab("vfx_WishbonePing") ?? ZNetScene.instance.GetPrefab("vfx_Frost"); if ((Object)(object)val != (Object)null) { Object.Instantiate(val, pos, Quaternion.identity); } } } } public static class DragonbornBreath { private const float AoeRadius = 4f; private const float AoeRange = 8f; public const float FxLifetimeSeconds = 1f; private static readonly Dictionary ElementFxPrefabs = new Dictionary { { BreathElement.Fire, new string[2] { "vfx_torch_hit", "vfx_fireball_explosion" } }, { BreathElement.Poison, new string[2] { "vfx_Poison", "vfx_poisonarrow_hit" } }, { BreathElement.Lightning, new string[3] { "fx_lightningweapon_hit", "fx_chainlightning_hit", "fx_lightningstaffprojectile_hit" } }, { BreathElement.Ice, new string[3] { "vfx_Frost", "vfx_Freezing", "vfx_frostarrow_hit" } } }; public static bool TryExecute(Player player, Attack attack) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) //IL_0056: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } float breathStaminaCost = GetBreathStaminaCost(player, attack); if (!((Character)player).HaveStamina(breathStaminaCost + 0.1f)) { return false; } ((Character)player).UseStamina(breathStaminaCost); BreathElement breathElement = BreathManager.GetBreathElement(player); TrinketBonus equippedBonus = TrinketBonusRegistry.GetEquippedBonus(player); float num = GetUnarmedDamage(player) + equippedBonus.ElementDamage; Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 val = eyePoint + lookDir * 4f; SpawnElementFx(breathElement, eyePoint, lookDir); List list = new List(); Character.GetCharactersInRange(val, 4f, list); List list2 = new List(); foreach (Character item in list) { if (!BreathTargetFilter.CanBreathDamage(player, item)) { continue; } Vector3 val2 = item.GetCenterPoint() - eyePoint; if (!(((Vector3)(ref val2)).magnitude > 8f) && !(Vector3.Dot(((Vector3)(ref val2)).normalized, lookDir) < 0.2f)) { HitData val3 = new HitData(); val3.m_skill = (SkillType)11; val3.m_point = item.GetCenterPoint(); val3.m_dir = lookDir; val3.m_pushForce = 0f; val3.SetAttacker((Character)(object)player); float shiftedDamage = num; if (equippedBonus.MountainResShift) { ApplyMountainResistanceShift(player, breathElement, shiftedDamage, out shiftedDamage); } list2.Add(new BreathStrikeTarget { Target = item, Template = val3, Element = breathElement, TotalDamage = shiftedDamage, MountainShiftYellow = MountainShiftDisplay.ShouldShowResistanceShiftYellow(player, breathElement) }); } } BreathDamageOverTime.StartBurst(player, list2); return true; } private static float GetBreathStaminaCost(Player player, Attack attack) { if (attack != null) { return attack.m_attackStamina; } ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); if (currentWeapon?.m_shared?.m_attack != null) { return currentWeapon.m_shared.m_attack.m_attackStamina; } return 10f; } private static void ApplyMountainResistanceShift(Player player, BreathElement element, float baseDamage, out float shiftedDamage) { shiftedDamage = baseDamage; float resistancePercent = ElementResistance.GetResistancePercent(player, element); if (!(resistancePercent <= 0f)) { shiftedDamage = baseDamage * (1f + resistancePercent / 100f); } } public static float GetOceanArmorBonus(Player player) { if (RaceManager.GetRace(player) != RaceType.Dragonborn) { return 0f; } if (!TrinketBonusRegistry.GetEquippedBonus(player).OceanArmor) { return 0f; } return 30f; } public static float GetUnarmedDamage(Player player) { if ((Object)(object)player == (Object)null) { return 10f; } float skillFactor = ((Character)player).GetSkillFactor((SkillType)11); return 10f + skillFactor * 20f; } public static float GetBreathElementDamage(Player player) { return GetUnarmedDamage(player) + TrinketBonusRegistry.GetEquippedBonus(player).ElementDamage; } public static void SpawnBreathFx(BreathElement element, Vector3 origin, Vector3 direction) { //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) SpawnElementFx(element, origin, direction); } public static float GetBreathStaminaCostPublic(Player player) { return GetBreathStaminaCost(player, (player == null) ? null : ((Humanoid)player).GetCurrentWeapon()?.m_shared?.m_attack); } private static void SpawnElementFx(BreathElement element, Vector3 origin, Vector3 direction) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNetScene.instance == (Object)null)) { float[] array = new float[3] { 1.5f, 3.5f, 5.5f }; foreach (float num in array) { SpawnFxBurst(element, origin + direction * num, direction); } } } private static void SpawnFxBurst(BreathElement element, Vector3 position, Vector3 direction) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!ElementFxPrefabs.TryGetValue(element, out var value)) { return; } string[] array = value; foreach (string text in array) { GameObject prefab = ZNetScene.instance.GetPrefab(text); if (!((Object)(object)prefab == (Object)null)) { ScheduleFxCleanup(Object.Instantiate(prefab, position, Quaternion.LookRotation(direction))); break; } } } private static void ScheduleFxCleanup(GameObject instance) { if (!((Object)(object)instance == (Object)null)) { TimedDestruction component = instance.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_timeout = 1f; component.Trigger(); } else { Object.Destroy((Object)(object)instance, 1f); } } } } internal static class DragonbornBreathInput { public static bool IsBlockHeld() { if (!ZInput.GetButton("Block") && !ZInput.GetButton("SecondaryAttack") && !ZInput.GetButton("Guard")) { return Input.GetMouseButton(1); } return true; } public static bool IsAttackHeld() { if (!ZInput.GetButton("Attack")) { return Input.GetMouseButton(0); } return true; } public static bool IsAttackPressed() { if (!ZInput.GetButtonDown("Attack")) { return Input.GetMouseButtonDown(0); } return true; } public static bool AreBreathButtonsHeld() { if (IsBlockHeld()) { return IsAttackHeld(); } return false; } public static bool IsUnarmed(Player player) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 ItemData val = ((player != null) ? ((Humanoid)player).GetCurrentWeapon() : null); if (val?.m_shared == null) { return true; } return (int)val.m_shared.m_skillType == 11; } public static bool ShouldSuppressTowerShieldBlock(Player player) { if ((Object)(object)player == (Object)null || !AreBreathButtonsHeld()) { return false; } RaceType race = RaceManager.GetRace(player); if (race != RaceType.Dragonborn && race != RaceType.Aasimar) { return ElfTypeManager.IsHighElf(player); } return true; } } internal static class DragonbornBreathCombat { private static readonly int BlockingAnimHash = ZSyncAnimation.GetHash("blocking"); public static void CancelUnarmedAttack(Humanoid humanoid) { if (!((Object)(object)humanoid == (Object)null)) { humanoid.m_currentAttack = null; if ((Object)(object)((Character)humanoid).m_zanim != (Object)null) { ((Character)humanoid).m_zanim.SetBool("attack", false); } } } public static void ForceBlockDown(Humanoid humanoid) { if (!((Object)(object)humanoid == (Object)null)) { ((Character)humanoid).m_blocking = false; humanoid.m_blockTimer = 0f; if ((Object)(object)((Character)humanoid).m_zanim != (Object)null) { ((Character)humanoid).m_zanim.SetBool(BlockingAnimHash, false); } if ((Object)(object)((Character)humanoid).m_nview != (Object)null && ((Character)humanoid).m_nview.IsValid()) { ((Character)humanoid).m_nview.GetZDO().Set(ZDOVars.s_isBlockingHash, false); } Traverse.Create((object)humanoid).Field("m_internalBlockingState").SetValue((object)false); } } public static void RefreshTowerShieldBlockVisual(Player player) { if ((Object)(object)player == (Object)null || !DragonbornShieldHelper.HasTowerShieldEquipped((Humanoid)(object)player) || !DragonbornBreathInput.IsBlockHeld() || DragonbornBreathInput.ShouldSuppressTowerShieldBlock(player)) { return; } ((Character)player).m_blocking = true; if (((Character)player).IsBlocking()) { if ((Object)(object)((Character)player).m_zanim != (Object)null) { ((Character)player).m_zanim.SetBool(BlockingAnimHash, true); } if ((Object)(object)((Character)player).m_nview != (Object)null && ((Character)player).m_nview.IsValid()) { ((Character)player).m_nview.GetZDO().Set(ZDOVars.s_isBlockingHash, true); } Traverse.Create((object)player).Field("m_internalBlockingState").SetValue((object)true); } } } internal static class DragonbornShieldHelper { private static readonly string[] TowerShieldPrefabNames = new string[6] { "ShieldWoodTower", "ShieldBoneTower", "ShieldIronTower", "ShieldBlackmetalTower", "ShieldFlametalTower", "ShieldSerpentscale" }; public static ItemData GetEquippedShield(Humanoid humanoid) { if ((Object)(object)humanoid == (Object)null) { return null; } ItemData currentBlocker = humanoid.GetCurrentBlocker(); if (currentBlocker != null) { return currentBlocker; } return humanoid.GetLeftItem(); } public static bool HasTowerShieldEquipped(Humanoid humanoid) { return IsTowerShield(GetEquippedShield(humanoid)); } public static bool IsTowerShield(ItemData shield) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if (shield?.m_shared == null) { return false; } if ((int)shield.m_shared.m_itemType != 5) { return false; } string text = (((Object)(object)shield.m_dropPrefab != (Object)null) ? ((Object)shield.m_dropPrefab).name : string.Empty); string text2 = shield.m_shared.m_name ?? string.Empty; string[] towerShieldPrefabNames = TowerShieldPrefabNames; foreach (string value in towerShieldPrefabNames) { if (text.Equals(value, StringComparison.OrdinalIgnoreCase) || text2.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } if (text.IndexOf("Tower", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("tower", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (text.IndexOf("Serpentscale", StringComparison.OrdinalIgnoreCase) < 0) { return text2.IndexOf("serpentscale", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } } internal static class DrowShadowArmor { private const float ArmorPerHit = 3f; private const float DurationSeconds = 5f; private static float _stackedArmor; private static float _expiresAt; public static void TriggerOnHit(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && ElfTypeManager.IsDrow(player)) { if (Time.time >= _expiresAt) { _stackedArmor = 0f; } _stackedArmor += 3f; _expiresAt = Time.time + 5f; } } public static float GetArmorBonus(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !ElfTypeManager.IsDrow(player)) { return 0f; } if (Time.time >= _expiresAt) { _stackedArmor = 0f; return 0f; } return _stackedArmor; } } internal static class DwarfBuiltRefund { public const string ZdoKey = "Ent1tyRaces.DwarfBuilt"; public static int HalveCost(int amount) { if (amount <= 0) { return amount; } return Mathf.Max(1, Mathf.CeilToInt((float)amount * 0.5f)); } public static void TryMarkOnSetCreator(Piece piece, long creatorId) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)piece == (Object)null) && !((Object)(object)localPlayer == (Object)null) && RaceManager.GetRace(localPlayer) == RaceType.Dwarf && creatorId == localPlayer.GetPlayerID()) { ZNetView component = ((Component)piece).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { component.GetZDO().Set("Ent1tyRaces.DwarfBuilt", true); } } } public static bool IsDwarfBuilt(Piece piece) { if ((Object)(object)piece == (Object)null) { return false; } ZNetView component = ((Component)piece).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } return component.GetZDO().GetBool("Ent1tyRaces.DwarfBuilt", false); } } internal static class DwarfCrater { private const float Radius = 1.5f; private const float Depth = 1f; private const float ArmWindow = 1.75f; private static readonly MethodInfo DoOperationMethod = AccessTools.Method(typeof(TerrainComp), "DoOperation", new Type[2] { typeof(Vector3), typeof(Settings) }, (Type[])null); private static bool _armed; private static float _armedUntil; public static void Update(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(player) == RaceType.Dwarf) { if (Input.GetMouseButton(2) && ((Character)player).InAttack()) { _armed = true; _armedUntil = Time.time + 1.75f; } if (_armed && Time.time > _armedUntil) { _armed = false; } } } public static void TryOnHit(Player attacker, Character target) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)attacker == (Object)null || (Object)(object)target == (Object)null || (Object)(object)attacker != (Object)(object)Player.m_localPlayer || RaceManager.GetRace(attacker) != RaceType.Dwarf) { return; } bool mouseButton = Input.GetMouseButton(2); bool flag = _armed && Time.time <= _armedUntil; if (mouseButton || flag) { _armed = false; Vector3 val = ((Component)target).transform.position - ((Component)attacker).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = ((Character)attacker).GetLookDir(); val.y = 0f; } ((Vector3)(ref val)).Normalize(); Vector3 val2 = ((Component)target).transform.position + val * 1.85f; if (Location.IsInsideNoBuildLocation(val2) || Location.IsInsideNoBuildLocation(((Component)target).transform.position)) { ((Character)attacker).Message((MessageType)2, "The earth here is godly", 0, (Sprite)null); } else { DigAt(val2); } } } private static void DigAt(Vector3 pos) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.GetGroundHeight(pos) : pos.y); object obj = TerrainComp.FindTerrainCompiler(pos); if (obj == null) { Heightmap obj2 = Heightmap.FindHeightmap(pos); obj = ((obj2 != null) ? obj2.GetAndCreateTerrainCompiler() : null); } TerrainComp val = (TerrainComp)obj; if ((Object)(object)val == (Object)null || DoOperationMethod == null) { Logger.LogWarning((object)"Ent1tyRaces: Dwarf crater — no TerrainComp at hit."); return; } float num2 = num - 1f; Settings val2 = new Settings { m_level = true, m_levelRadius = 1.5f, m_levelOffset = 0f, m_square = false, m_raise = false, m_smooth = true, m_smoothRadius = 2f, m_smoothPower = 3f, m_paintCleared = false }; DoOperationMethod.Invoke(val, new object[2] { (object)new Vector3(pos.x, num2, pos.z), val2 }); } } internal static class ElementResistance { public static DamageType ToDamageType(BreathElement element) { //IL_001b: 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_0028: 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_002d: Unknown result type (might be due to invalid IL or missing references) return (DamageType)(element switch { BreathElement.Poison => 256, BreathElement.Lightning => 128, BreathElement.Ice => 64, _ => 32, }); } public static void SetElementDamage(HitData hit, BreathElement element, float amount) { if (hit != null) { hit.m_damage.m_damage = 0f; hit.m_damage.m_blunt = 0f; hit.m_damage.m_slash = 0f; hit.m_damage.m_pierce = 0f; hit.m_damage.m_fire = 0f; hit.m_damage.m_frost = 0f; hit.m_damage.m_lightning = 0f; hit.m_damage.m_poison = 0f; hit.m_damage.m_spirit = 0f; switch (element) { case BreathElement.Poison: hit.m_damage.m_poison = amount; break; case BreathElement.Fire: hit.m_damage.m_fire = amount; break; case BreathElement.Lightning: hit.m_damage.m_lightning = amount; break; case BreathElement.Ice: hit.m_damage.m_frost = amount; break; default: hit.m_damage.m_damage = amount; break; } } } public static void MultiplyElementDamage(ref HitData hit, BreathElement element, float multiplier) { if (hit != null && !(multiplier <= 1f)) { switch (element) { case BreathElement.Poison: hit.m_damage.m_poison *= multiplier; break; case BreathElement.Fire: hit.m_damage.m_fire *= multiplier; break; case BreathElement.Lightning: hit.m_damage.m_lightning *= multiplier; break; case BreathElement.Ice: hit.m_damage.m_frost *= multiplier; break; default: hit.m_damage.m_damage *= multiplier; break; } } } public static float GetResistancePercent(Player player, BreathElement element) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0f; } DamageType damageType = ToDamageType(element); float num = 0f; if (((Humanoid)player).GetInventory() != null) { foreach (ItemData equippedItem in ((Humanoid)player).GetInventory().GetEquippedItems()) { if (equippedItem?.m_shared != null) { float itemResistanceModifier = GetItemResistanceModifier(equippedItem, damageType); if (itemResistanceModifier > 0f) { num += itemResistanceModifier; } } } } num += GetStatusEffectResistance(player, element); return Mathf.Max(0f, num); } private static float GetItemResistanceModifier(ItemData item, DamageType damageType) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_003b: Unknown result type (might be due to invalid IL or missing references) float num = 0f; if (item.m_shared.m_damageModifiers == null) { return num; } foreach (DamageModPair damageModifier in item.m_shared.m_damageModifiers) { if (damageModifier.m_type == damageType) { num += DamageModifierToResistPercent(damageModifier.m_modifier); } } return num; } private static float DamageModifierToResistPercent(DamageModifier modifier) { //IL_0000: 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) //IL_0024: Expected I4, but got Unknown return (modifier - 1) switch { 6 => 25f, 0 => 50f, 4 => 75f, 2 => 100f, 3 => 100f, _ => 0f, }; } private static float GetStatusEffectResistance(Player player, BreathElement element) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan == null) { return 0f; } switch (element) { case BreathElement.Fire: { float num = 0f; if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Potion_barleywine"))) { num += 50f; } if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SetEffect_WolfArmor"))) { num += 20f; } if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SetEffect_FenringArmor"))) { num += 25f; } return num; } case BreathElement.Poison: if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("Potion_poisonresist"))) { return 50f; } return 0f; case BreathElement.Ice: if (sEMan.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SetEffect_WolfArmor"))) { return 20f; } return 0f; default: return 0f; } } } public static class ElfTypeManager { private const string CustomElfTypeKey = "Ent1ty303.ElfType"; public static ElfType GetElfType(Player player) { if ((Object)(object)player == (Object)null) { return ElfType.High; } if (PlayerDataStore.TryGetInt(player, "Ent1ty303.ElfType", out var value) && Enum.IsDefined(typeof(ElfType), value)) { return (ElfType)value; } return ElfType.High; } public static bool TrySetElfType(Player player, ElfType elfType, out string message) { message = null; if ((Object)(object)player == (Object)null) { message = "Load a character first."; return false; } if (RaceManager.GetRace(player) != RaceType.Elf) { message = "Only Elves can choose a lineage."; return false; } PlayerDataStore.SetInt(player, "Ent1ty303.ElfType", (int)elfType); message = elfType switch { ElfType.High => "Sunfire answers you. RMB+LMB unarmed fires a wide light beam.", ElfType.Wood => "The forest claims you. Free run stamina; near trees you fade — bows bite deep.", ElfType.Drow => "The Underdark smiles. Free sneak stamina; night and poison listen.", _ => $"Lineage set to {elfType}.", }; if (((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } return true; } public static ElfType ParseElfType(string value) { if (string.IsNullOrWhiteSpace(value)) { return ElfType.High; } string text = value.Trim().ToLowerInvariant(); if (text != null) { int length = text.Length; if (length != 4) { if (length == 7) { char c = text[0]; if (c != 'd') { if (c != 'h') { if (c == 'w' && text == "woodelf") { goto IL_00eb; } } else if (text == "highelf") { goto IL_00e7; } } else if (text == "darkelf") { goto IL_00ef; } } } else { char c = text[1]; if ((uint)c <= 105u) { if (c != 'a') { if (c == 'i' && text == "high") { goto IL_00e7; } } else if (text == "dark") { goto IL_00ef; } } else if (c != 'o') { if (c == 'r' && text == "drow") { goto IL_00ef; } } else if (text == "wood") { goto IL_00eb; } } } ElfType result; return Enum.TryParse(value, ignoreCase: true, out result) ? result : ElfType.High; IL_00eb: return ElfType.Wood; IL_00ef: return ElfType.Drow; IL_00e7: return ElfType.High; } public static bool IsHighElf(Player player) { if (RaceManager.GetRace(player) == RaceType.Elf) { return GetElfType(player) == ElfType.High; } return false; } public static bool IsWoodElf(Player player) { if (RaceManager.GetRace(player) == RaceType.Elf) { return GetElfType(player) == ElfType.Wood; } return false; } public static bool IsDrow(Player player) { if (RaceManager.GetRace(player) == RaceType.Elf) { return GetElfType(player) == ElfType.Drow; } return false; } } internal class FrostAuraFollower : MonoBehaviour { private Character _target; private float _hardExpireAt; public static void Attach(Character target, float maxSeconds = 8f) { //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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null)) { FrostAuraFollower componentInChildren = ((Component)target).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren._hardExpireAt = Time.time + maxSeconds; componentInChildren.RefreshParticles(); return; } GameObject val = new GameObject("Ent1tyRaces_FrostAura"); val.transform.SetParent(((Component)target).transform, false); val.transform.localPosition = Vector3.up * (target.GetHeight() * 0.45f); FrostAuraFollower frostAuraFollower = val.AddComponent(); frostAuraFollower._target = target; frostAuraFollower._hardExpireAt = Time.time + maxSeconds; frostAuraFollower.BuildParticles(); } } private void RefreshParticles() { ParticleSystem component = ((Component)this).GetComponent(); if ((Object)(object)component != (Object)null && !component.isPlaying) { component.Play(); } } private void BuildParticles() { //IL_000c: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown ParticleSystem obj = ((Component)this).gameObject.AddComponent(); MainModule main = obj.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.1f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.15f, 0.55f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.08f, 0.22f); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.75f, 0.92f, 1f, 0.75f), new Color(0.45f, 0.75f, 1f, 0.35f)); ((MainModule)(ref main)).maxParticles = 48; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.05f); EmissionModule emission = obj.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(22f); ShapeModule shape = obj.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = Mathf.Max(0.45f, ((Object)(object)_target != (Object)null) ? (_target.GetRadius() * 0.9f) : 0.6f); ParticleSystemRenderer component = ((Component)this).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { Shader val = Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Particles/Additive") ?? Shader.Find("Sprites/Default"); if ((Object)(object)val != (Object)null) { ((Renderer)component).material = new Material(val); } } } private void LateUpdate() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_target == (Object)null || _target.IsDead() || Time.time >= _hardExpireAt) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } SEMan sEMan = _target.GetSEMan(); if (sEMan == null || (!sEMan.HaveStatusEffect(SEMan.s_statusEffectFrost) && !sEMan.HaveStatusEffect(SEMan.s_statusEffectCold))) { Object.Destroy((Object)(object)((Component)this).gameObject); } else { ((Component)this).transform.position = _target.GetCenterPoint(); } } } internal static class FrostBeamWeakenText { private static bool _pendingPurpleMinusOne; public static void ShowPurpleMinusOne(Vector3 feetPosition) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)DamageText.instance == (Object)null)) { _pendingPurpleMinusOne = true; DamageText.instance.ShowText((TextType)0, feetPosition, 1f, false); } } public static bool TryConsumePendingPurpleMinusOne() { if (!_pendingPurpleMinusOne) { return false; } _pendingPurpleMinusOne = false; return true; } } internal static class GenasiAir { private const float LevitateRange = 10f; private const float MinHoldDistance = 2.5f; private const float MaxHoldDistance = 12f; private const float StaminaPerSecond = 8f; private const float LargeStaminaMult = 2f; private const float CollisionSpeedThreshold = 10f; private const float MinPctDamage = 0.015f; private const float MaxPctDamage = 0.04f; private const float SmoothTime = 0.28f; private static readonly FieldInfo BodyField = AccessTools.Field(typeof(Character), "m_body"); private static readonly FieldInfo CurrentVelField = AccessTools.Field(typeof(Character), "m_currentVel"); private static Character _held; private static float _holdDistance = 5f; private static Vector3 _smoothVelocity; private static float _nextImpactTime; private static GameObject _airFxRoot; private static ParticleSystem _airParticles; public static bool ShouldSuppressAttacks(Player player) { if ((Object)(object)player != (Object)null && GenasiTypeManager.Is(player, GenasiType.Air)) { return DragonbornBreathInput.AreBreathButtonsHeld(); } return false; } public static void Update(Player player) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !GenasiTypeManager.Is(player, GenasiType.Air)) { Release(); return; } SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectSmoked, true); } if (!DragonbornBreathInput.AreBreathButtonsHeld()) { Release(); return; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); float y = Input.mouseScrollDelta.y; if (Mathf.Abs(y) > 0.01f) { _holdDistance = Mathf.Clamp(_holdDistance + y * 0.75f, 2.5f, 12f); } if ((Object)(object)_held == (Object)null || _held.IsDead()) { _held = FindLevitateTarget(player); _smoothVelocity = Vector3.zero; if ((Object)(object)_held == (Object)null) { HideAirFx(); return; } } bool flag = !IsSmallEnough(player, _held); float num = 8f * (flag ? 2f : 1f) * Time.deltaTime; if (player.GetStamina() < num + 0.1f) { Release(); ((Character)player).Message((MessageType)2, "Winds falter — no stamina.", 0, (Sprite)null); return; } ((Character)player).UseStamina(num); Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 val = eyePoint + ((Vector3)(ref lookDir)).normalized * _holdDistance; Vector3 next = Vector3.SmoothDamp(((Component)_held).transform.position, val, ref _smoothVelocity, 0.28f, 18f, Time.deltaTime); ApplySmoothPosition(_held, next); UpdateAirFx(_held.GetCenterPoint()); float magnitude = ((Vector3)(ref _smoothVelocity)).magnitude; if (magnitude >= 10f && Time.time >= _nextImpactTime) { Vector3 normalized; if (!(((Vector3)(ref _smoothVelocity)).sqrMagnitude > 0.01f)) { lookDir = ((Character)player).GetLookDir(); normalized = ((Vector3)(ref lookDir)).normalized; } else { normalized = ((Vector3)(ref _smoothVelocity)).normalized; } Vector3 moveDir = normalized; if (TryCollisionDamage(player, _held, moveDir, magnitude)) { _nextImpactTime = Time.time + 0.45f; } } } private static void ApplySmoothPosition(Character target, Vector3 next) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) ((Component)target).transform.position = next; object? obj = BodyField?.GetValue(target); Rigidbody val = (Rigidbody)((obj is Rigidbody) ? obj : null); if (val != null) { val.position = next; val.linearVelocity = Vector3.zero; val.angularVelocity = Vector3.zero; } CurrentVelField?.SetValue(target, Vector3.zero); } private static void Release() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) _held = null; _smoothVelocity = Vector3.zero; HideAirFx(); } private static bool IsSmallEnough(Player player, Character target) { return GiantBody.IsSmallerThan(target, (Character)(object)player); } private static Character FindLevitateTarget(Player player) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_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) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) Character result = null; float num = 10f; Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; List list = new List(); Character.GetCharactersInRange(((Component)player).transform.position, 10f, list); foreach (Character item in list) { if (BreathTargetFilter.CanBreathDamage(player, item)) { Vector3 val = item.GetCenterPoint() - eyePoint; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude > 10f) && !(Vector3.Dot(((Vector3)(ref val)).normalized, normalized) < 0.25f) && magnitude < num) { num = magnitude; result = item; } } } return result; } private static bool TryCollisionDamage(Player player, Character held, Vector3 moveDir, float speed) { //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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) float num = held.GetRadius() + 0.35f; RaycastHit val = default(RaycastHit); if (!Physics.SphereCast(held.GetCenterPoint(), num * 0.55f, moveDir, ref val, Mathf.Max(0.35f, speed * Time.deltaTime + 0.25f), -1, (QueryTriggerInteraction)1)) { return false; } if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null || ((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(((Component)held).transform)) { return false; } float num2 = Mathf.InverseLerp(10f, 26f, speed); float maxHealthPercent = Mathf.Lerp(0.015f, 0.04f, num2); ApplyImpact(player, held, maxHealthPercent, ((RaycastHit)(ref val)).point); Character componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent != (Object)(object)held && BreathTargetFilter.CanBreathDamage(player, componentInParent)) { ApplyImpact(player, componentInParent, maxHealthPercent, ((RaycastHit)(ref val)).point); } return true; } private static void ApplyImpact(Player player, Character target, float maxHealthPercent, Vector3 point) { //IL_0013: 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_001b: 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_0021: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_003c: 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) //IL_0046: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown float blunt = Mathf.Max(1f, target.GetMaxHealth() * maxHealthPercent); HitData val = new HitData { m_skill = (SkillType)11, m_point = point }; Vector3 val2 = target.GetCenterPoint() - ((Character)player).GetCenterPoint(); val.m_dir = ((Vector3)(ref val2)).normalized; val.m_hitType = (HitType)2; val.m_dodgeable = false; val.m_blockable = false; HitData val3 = val; val3.m_damage.m_blunt = blunt; val3.SetAttacker((Character)(object)player); target.Damage(val3); } private static void UpdateAirFx(Vector3 pos) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) EnsureAirFx(); if (!((Object)(object)_airFxRoot == (Object)null)) { _airFxRoot.transform.position = pos; if ((Object)(object)_airParticles != (Object)null && !_airParticles.isPlaying) { _airParticles.Play(); } } } private static void HideAirFx() { if ((Object)(object)_airParticles != (Object)null && _airParticles.isPlaying) { _airParticles.Stop(true, (ParticleSystemStopBehavior)0); } } private static void EnsureAirFx() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0048: 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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown if ((Object)(object)_airFxRoot != (Object)null && (Object)(object)_airParticles != (Object)null) { return; } _airFxRoot = new GameObject("Ent1tyRaces_AirLevitateFx"); Object.DontDestroyOnLoad((Object)(object)_airFxRoot); _airParticles = _airFxRoot.AddComponent(); MainModule main = _airParticles.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.7f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.6f, 2.2f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.08f, 0.28f); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.85f, 0.95f, 1f, 0.55f), new Color(0.65f, 0.85f, 1f, 0.2f)); ((MainModule)(ref main)).maxParticles = 60; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.15f); EmissionModule emission = _airParticles.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(28f); ShapeModule shape = _airParticles.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.85f; ParticleSystemRenderer component = _airFxRoot.GetComponent(); if ((Object)(object)component != (Object)null) { Shader val = Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Particles/Additive") ?? Shader.Find("Sprites/Default"); if ((Object)(object)val != (Object)null) { ((Renderer)component).material = new Material(val); } } _airParticles.Stop(true, (ParticleSystemStopBehavior)0); } } internal static class GenasiEarth { private const float BendRadius = 1.35f; private const float RaiseAmount = 0.45f; private const float LowerAmount = 0.45f; private const float MaxRange = 8f; private const float Cooldown = 0.25f; private const float StaminaCost = 4f; private static readonly MethodInfo DoOperationMethod = AccessTools.Method(typeof(TerrainComp), "DoOperation", new Type[2] { typeof(Vector3), typeof(Settings) }, (Type[])null); private static float _nextReadyTime; public static void Update(Player player) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !GenasiTypeManager.Is(player, GenasiType.Earth)) { return; } bool num = DragonbornBreathInput.IsBlockHeld(); bool flag = num && DragonbornBreathInput.IsAttackPressed(); bool flag2 = num && Input.GetMouseButtonDown(2); if ((!flag && !flag2) || Time.time < _nextReadyTime) { return; } if (!((Character)player).HaveStamina(4.1f)) { ((Character)player).Message((MessageType)2, "Too weary to shape the earth.", 0, (Sprite)null); return; } if (!TryGetAimPoint(player, out var point)) { ((Character)player).Message((MessageType)2, "No ground in reach.", 0, (Sprite)null); return; } if (Location.IsInsideNoBuildLocation(point)) { ((Character)player).Message((MessageType)2, "The earth here is immortal", 0, (Sprite)null); _nextReadyTime = Time.time + 0.25f; DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player); return; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player); ((Character)player).UseStamina(4f); _nextReadyTime = Time.time + 0.25f; float num2 = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.GetGroundHeight(point) : point.y); if (flag) { TryLevelExact(point.x, point.z, num2 + 0.45f); ((Character)player).Message((MessageType)1, "The earth rises.", 0, (Sprite)null); } else { TryLevelExact(point.x, point.z, num2 - 0.45f); ((Character)player).Message((MessageType)1, "The earth sinks.", 0, (Sprite)null); } } private static bool TryGetAimPoint(Player player, out Vector3 point) { //IL_0007: 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_0012: 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) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_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) //IL_0069: 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_007a: 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) //IL_0085: Unknown result type (might be due to invalid IL or missing references) point = ((Component)player).transform.position; Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; RaycastHit val = default(RaycastHit); if (Physics.Raycast(eyePoint, normalized, ref val, 8f, -1, (QueryTriggerInteraction)1)) { point = ((RaycastHit)(ref val)).point; return true; } Vector3 val2 = eyePoint + normalized * 4f; if ((Object)(object)ZoneSystem.instance != (Object)null) { point = new Vector3(val2.x, ZoneSystem.instance.GetGroundHeight(val2), val2.z); return true; } return false; } private static bool TryLevelExact(float x, float z, float y) { //IL_0003: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) //IL_004f: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) TerrainComp comp = GetComp(new Vector3(x, y, z)); if ((Object)(object)comp == (Object)null || DoOperationMethod == null) { return false; } Settings val = new Settings { m_level = true, m_levelRadius = 1.35f, m_levelOffset = 0f, m_square = false, m_raise = false, m_smooth = true, m_smoothRadius = 1.75f, m_smoothPower = 3f, m_paintCleared = false }; DoOperationMethod.Invoke(comp, new object[2] { (object)new Vector3(x, y, z), val }); return true; } private static TerrainComp GetComp(Vector3 worldPos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) TerrainComp val = TerrainComp.FindTerrainCompiler(worldPos); if ((Object)(object)val != (Object)null) { return val; } Heightmap val2 = Heightmap.FindHeightmap(worldPos); if (!((Object)(object)val2 != (Object)null)) { return null; } return val2.GetAndCreateTerrainCompiler(); } } internal static class GenasiFire { private sealed class FirePatch { public Vector3 Position; public float ExpireAt; public float NextTick; public float NextFxRefresh; public GameObject Root; public ParticleSystem Particles; } private const float TrailInterval = 0.4f; private const float PatchRadius = 2.2f; private const float PatchLifetime = 10f; private const float TickInterval = 0.35f; private const float MoveThreshold = 0.15f; private const float MinPatchSpacing = 1.4f; private static float _nextTrailTime; private static Vector3 _lastPos = new Vector3(float.MaxValue, 0f, 0f); private static readonly List Patches = new List(); public static void Update(Player player) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } TickPatches(player); if (!GenasiTypeManager.Is(player, GenasiType.Fire)) { return; } Vector3 position = ((Component)player).transform.position; Vector3 val = position - _lastPos; if (((Vector3)(ref val)).sqrMagnitude < 0.0225f || Time.time < _nextTrailTime) { return; } foreach (FirePatch patch in Patches) { val = patch.Position - position; if (((Vector3)(ref val)).sqrMagnitude < 1.9599999f) { _lastPos = position; return; } } _lastPos = position; _nextTrailTime = Time.time + 0.4f; SpawnPatch(position); } private static void SpawnPatch(Vector3 pos) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.GetGroundHeight(pos) : pos.y); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(pos.x, num + 0.05f, pos.z); FirePatch firePatch = new FirePatch { Position = val, ExpireAt = Time.time + 10f, NextTick = Time.time, NextFxRefresh = Time.time }; EnsureFireVisual(firePatch, val); SpawnBurstFx(val); Patches.Add(firePatch); } public static GameObject CreateGroundFireVisual(Vector3 ground, float radius = 2.2f) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_007f: 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_00bf: 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_00d7: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Expected O, but got Unknown GameObject val = new GameObject("Ent1tyRaces_GroundFire"); val.transform.position = ground; ParticleSystem obj = val.AddComponent(); MainModule main = obj.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.2f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.4f, 1.4f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.18f, 0.45f); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.55f, 0.1f, 0.95f), new Color(1f, 0.2f, 0.05f, 0.7f)); ((MainModule)(ref main)).maxParticles = 40; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.35f); EmissionModule emission = obj.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(17f); ShapeModule shape = obj.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)10; ((ShapeModule)(ref shape)).radius = radius * 0.65f; ColorOverLifetimeModule colorOverLifetime = obj.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val2 = new Gradient(); val2.SetKeys((GradientColorKey[])(object)new GradientColorKey[3] { new GradientColorKey(new Color(1f, 0.85f, 0.2f), 0f), new GradientColorKey(new Color(1f, 0.25f, 0.05f), 0.55f), new GradientColorKey(new Color(0.15f, 0.05f, 0.02f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(0.9f, 0f), new GradientAlphaKey(0.7f, 0.4f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val2); ParticleSystemRenderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { Shader val3 = Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Particles/Additive") ?? Shader.Find("Sprites/Default"); if ((Object)(object)val3 != (Object)null) { ((Renderer)component).material = new Material(val3); } } return val; } private static void EnsureFireVisual(FirePatch patch, Vector3 ground) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)patch.Root != (Object)null)) { patch.Root = CreateGroundFireVisual(ground); patch.Particles = patch.Root.GetComponent(); } } private static void SpawnBurstFx(Vector3 ground) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) SpawnBurstFxPublic(ground); } public static void SpawnBurstFxPublic(Vector3 ground) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { return; } string[] array = new string[4] { "vfx_torch_hit", "vfx_FireWork_1", "vfx_fireball_explosion", "fx_fireball_explosion" }; foreach (string text in array) { GameObject prefab = ZNetScene.instance.GetPrefab(text); if (!((Object)(object)prefab == (Object)null)) { Object.Instantiate(prefab, ground, Quaternion.identity); break; } } } private static void TickPatches(Player owner) { //IL_006a: 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) float time = Time.time; for (int num = Patches.Count - 1; num >= 0; num--) { FirePatch firePatch = Patches[num]; if (time >= firePatch.ExpireAt) { if ((Object)(object)firePatch.Root != (Object)null) { Object.Destroy((Object)(object)firePatch.Root); } Patches.RemoveAt(num); } else { if (time >= firePatch.NextFxRefresh) { firePatch.NextFxRefresh = time + 4.4f; SpawnBurstFx(firePatch.Position); } if (!((Object)(object)owner == (Object)null) && !(time < firePatch.NextTick)) { firePatch.NextTick = time + 0.35f; BurnAt(owner, firePatch.Position); } } } } private static void BurnAt(Player owner, Vector3 pos) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0089: Expected O, but got Unknown float num = DragonbornBreath.GetBreathElementDamage(owner) * 0.5f * 0.35f; if (num <= 0f) { return; } List list = new List(); Character.GetCharactersInRange(pos, 2.2f, list); foreach (Character item in list) { if (!BreathTargetFilter.CanBreathDamage(owner, item)) { continue; } HitData val = new HitData { m_skill = (SkillType)11, m_point = item.GetCenterPoint(), m_dir = Vector3.up, m_hitType = (HitType)2, m_dodgeable = false, m_blockable = false }; val.m_damage.m_fire = num; val.SetAttacker((Character)(object)owner); BreathDamageApplicator.MarkBreathHit(val); item.Damage(val); SEMan sEMan = item.GetSEMan(); if (sEMan != null) { StatusEffect statusEffect = sEMan.GetStatusEffect(SEMan.s_statusEffectBurning); SE_Burning val2 = (SE_Burning)(object)((statusEffect is SE_Burning) ? statusEffect : null); if ((Object)(object)val2 == (Object)null) { StatusEffect obj = sEMan.AddStatusEffect(SEMan.s_statusEffectBurning, true, 0, 0f); val2 = (SE_Burning)(object)((obj is SE_Burning) ? obj : null); } if (val2 != null) { val2.AddFireDamage(num); } } } } } public static class GenasiTypeManager { private const string CustomKey = "Ent1ty303.GenasiType"; public static GenasiType GetGenasiType(Player player) { if ((Object)(object)player == (Object)null) { return GenasiType.Air; } if (PlayerDataStore.TryGetInt(player, "Ent1ty303.GenasiType", out var value) && Enum.IsDefined(typeof(GenasiType), value)) { return (GenasiType)value; } return GenasiType.Air; } public static bool TrySetGenasiType(Player player, GenasiType genasiType, out string message) { message = null; if ((Object)(object)player == (Object)null) { message = "Load a character first."; return false; } if (RaceManager.GetRace(player) != RaceType.Genasi) { message = "Only Genasi can choose an element."; return false; } PlayerDataStore.SetInt(player, "Ent1ty303.GenasiType", (int)genasiType); message = genasiType switch { GenasiType.Air => "Air Genasi: RMB+LMB levitates foes (large = 2× stamina).", GenasiType.Earth => "Earth Genasi: RMB+LMB / RMB+MMB shovel-shape earth. Free run stamina.", GenasiType.Fire => "Fire Genasi: flame walk lights the ground (half-strength fire).", GenasiType.Water => "Water Genasi: swim free. Near water, RMB+LMB channels poison tide.", _ => $"Element set to {genasiType}.", }; if (((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } return true; } public static GenasiType Parse(string value) { if (string.IsNullOrWhiteSpace(value)) { return GenasiType.Air; } switch (value.Trim().ToLowerInvariant()) { case "wind": case "air": return GenasiType.Air; case "rock": case "stone": case "earth": return GenasiType.Earth; case "fire": case "flame": return GenasiType.Fire; case "aqua": case "water": return GenasiType.Water; default: { GenasiType result; return Enum.TryParse(value, ignoreCase: true, out result) ? result : GenasiType.Air; } } } public static bool Is(Player player, GenasiType type) { if (RaceManager.GetRace(player) == RaceType.Genasi) { return GetGenasiType(player) == type; } return false; } } internal static class GenasiWaterBreath { private const float MinDistance = 5f; private const float MaxDistance = 18f; private const float CloudRadius = 2.4f; private const float DamagePerSecond = 35f; private const float TickInterval = 0.12f; private const float StaminaPerSecond = 10f; private const float DistanceAdjustSpeed = 7f; private const float WaterLookRange = 5f; private static bool _active; private static float _cloudDistance = 5f; private static float _nextTick; private static GameObject _cloudRoot; private static ParticleSystem _particles; public static bool ShouldSuppressAttacks(Player player) { if (!_active) { return IsLookingAtNearbyWater(player); } return true; } public static void Update(Player player) { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !GenasiTypeManager.Is(player, GenasiType.Water)) { Deactivate(); return; } if (!DragonbornBreathInput.AreBreathButtonsHeld()) { Deactivate(); return; } if (!_active) { if (!IsLookingAtNearbyWater(player)) { if (Time.frameCount % 45 == 0) { ((Character)player).Message((MessageType)2, "Look at water within 5m to channel the tide.", 0, (Sprite)null); } return; } _active = true; _cloudDistance = 5f; ((Character)player).Message((MessageType)2, "Poison tide rises.", 0, (Sprite)null); } float num = 10f * Time.deltaTime; if (player.GetStamina() < num + 0.1f) { Deactivate(); ((Character)player).Message((MessageType)2, "Tide breaks — no stamina.", 0, (Sprite)null); return; } ((Character)player).UseStamina(num); DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); if (ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump") || Input.GetKey((KeyCode)32)) { _cloudDistance = Mathf.Min(18f, _cloudDistance + 7f * Time.deltaTime); } if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305) || ZInput.GetKey((KeyCode)306, true)) { _cloudDistance = Mathf.Max(5f, _cloudDistance - 7f * Time.deltaTime); } Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 center = eyePoint + ((Vector3)(ref lookDir)).normalized * _cloudDistance; UpdateCloudVisual(center); if (Time.time >= _nextTick) { _nextTick = Time.time + 0.12f; ApplyCloudDamage(player, center, 0.12f); } } private static void Deactivate() { _active = false; if ((Object)(object)_cloudRoot != (Object)null) { _cloudRoot.SetActive(false); } } private static bool IsLookingAtNearbyWater(Player player) { //IL_0013: 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_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_0022: 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) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) if (((Character)player).InWater() || ((Character)player).IsSwimming()) { return true; } Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; for (float num = 0.5f; num <= 5f; num += 0.5f) { Vector3 val = eyePoint + normalized * num; Collider[] array = Physics.OverlapSphere(val, 1.1f, -1, (QueryTriggerInteraction)2); foreach (Collider val2 in array) { if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)((Component)val2).GetComponentInParent() != (Object)null) { return true; } string text = ((Object)((Component)val2).gameObject).name.ToLowerInvariant(); if (text.Contains("water") || text.Contains("ocean") || text.Contains("lake")) { return true; } } } if ((Object)(object)ZoneSystem.instance != (Object)null) { float groundHeight = ZoneSystem.instance.GetGroundHeight(val); float liquidLevel = ((Character)player).GetLiquidLevel(); if (liquidLevel > groundHeight + 0.15f && Mathf.Abs(val.y - liquidLevel) < 2.5f) { return true; } } } return false; } private static void ApplyCloudDamage(Player player, Vector3 center, float tickSeconds) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown float poison = 35f * tickSeconds; List list = new List(); Character.GetCharactersInRange(center, 2.4f, list); foreach (Character item in list) { if (BreathTargetFilter.CanBreathDamage(player, item)) { HitData val = new HitData { m_skill = (SkillType)11, m_point = item.GetCenterPoint() }; Vector3 val2 = item.GetCenterPoint() - center; val.m_dir = ((Vector3)(ref val2)).normalized; val.m_hitType = (HitType)2; val.m_dodgeable = true; val.m_blockable = true; HitData val3 = val; val3.m_damage.m_poison = poison; val3.SetAttacker((Character)(object)player); BreathDamageApplicator.MarkBreathHit(val3); item.Damage(val3); } } } private static void UpdateCloudVisual(Vector3 center) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) EnsureCloud(); _cloudRoot.SetActive(true); _cloudRoot.transform.position = center; if ((Object)(object)ZNetScene.instance != (Object)null && Time.frameCount % 8 == 0) { GameObject val = ZNetScene.instance.GetPrefab("vfx_ColdBall_Hit") ?? ZNetScene.instance.GetPrefab("vfx_Frost") ?? ZNetScene.instance.GetPrefab("vfx_Potion_health_medium"); if ((Object)(object)val != (Object)null) { Object.Instantiate(val, center, Quaternion.identity); } } } private static void EnsureCloud() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown if (!((Object)(object)_cloudRoot != (Object)null)) { _cloudRoot = new GameObject("Ent1tyRaces_WaterGenasiTide"); Object.DontDestroyOnLoad((Object)(object)_cloudRoot); _particles = _cloudRoot.AddComponent(); MainModule main = _particles.main; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.9f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.4f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.8f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.35f, 0.65f, 0.95f, 0.55f)); ((MainModule)(ref main)).maxParticles = 80; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; EmissionModule emission = _particles.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(40f); ShapeModule shape = _particles.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 1.6800001f; ParticleSystemRenderer component = _cloudRoot.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).material = new Material(Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Sprites/Default")); } } } } internal static class GenasiWaterCamera { private const float UnderwaterMinDistance = -1000f; private static float? _cachedMinWaterDistance; public static void Update(Player player) { GameCamera instance = GameCamera.instance; if ((Object)(object)instance == (Object)null) { return; } if ((Object)(object)player != (Object)null && GenasiTypeManager.Is(player, GenasiType.Water) && (((Character)player).IsSwimming() || ((Character)player).InWater())) { if (!_cachedMinWaterDistance.HasValue) { _cachedMinWaterDistance = instance.m_minWaterDistance; } instance.m_minWaterDistance = -1000f; } else if (_cachedMinWaterDistance.HasValue) { instance.m_minWaterDistance = _cachedMinWaterDistance.Value; _cachedMinWaterDistance = null; } } } internal static class GenasiWaterDive { public const float DefaultSwimDepth = 1.4f; private const float MaxDiveDepth = 40f; private const float DiveSpeed = 3.5f; private static float _baseSwimSpeed = -1f; public static bool IsWaterGenasiSwimming(Player player) { if ((Object)(object)player != (Object)null && GenasiTypeManager.Is(player, GenasiType.Water)) { return ((Character)player).IsSwimming(); } return false; } public static void Update(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !GenasiTypeManager.Is(player, GenasiType.Water)) { return; } if (_baseSwimSpeed < 0f) { _baseSwimSpeed = ((Character)player).m_swimSpeed; } ((Character)player).m_swimSpeed = Mathf.Max(((Character)player).m_swimSpeed, _baseSwimSpeed * 4f); if (!((Character)player).InWater()) { ((Character)player).m_swimDepth = 1.4f; } else if (!GenasiWaterSwimPose.IsForceUpright && ((Character)player).IsSwimming() && !((Character)player).IsOnGround()) { bool num = ZInput.GetButton("Jump") || ZInput.GetButton("JoyJump"); bool flag = ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch"); if (num) { ((Character)player).m_swimDepth = Mathf.Max(1.4f, ((Character)player).m_swimDepth - 3.5f * Time.deltaTime); } else if (flag && CanDive(player)) { ((Character)player).m_swimDepth = Mathf.Min(40f, ((Character)player).m_swimDepth + 3.5f * Time.deltaTime); } } } private static bool CanDive(Player player) { //IL_0032: 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) if (!((Character)player).InWater() || ((Character)player).IsOnGround() || !((Character)player).IsSwimming()) { return false; } if ((Object)(object)ZoneSystem.instance != (Object)null) { float groundHeight = ZoneSystem.instance.GetGroundHeight(((Component)player).transform.position); if (((Component)player).transform.position.y - groundHeight < 1f) { return false; } } return true; } public static void RegenStaminaInWater(Player player, float dt) { if (!((Object)(object)player == (Object)null) && GenasiTypeManager.Is(player, GenasiType.Water) && (((Character)player).IsSwimming() || ((Character)player).InWater())) { float maxStamina = ((Character)player).GetMaxStamina(); if (!(player.GetStamina() >= maxStamina)) { float num = player.m_staminaRegen * 0.85f * dt * Game.m_staminaRegenRate; player.m_stamina = Mathf.Min(maxStamina, player.m_stamina + num); } } } } internal static class GenasiWaterSwimPose { private const KeyCode PoseKey = (KeyCode)122; private const KeyCode UprightKey = (KeyCode)120; private const float UprightSwimDepth = 500f; private static readonly int InWaterHash = ZSyncAnimation.GetHash("inWater"); private static readonly int OnGroundHash = ZSyncAnimation.GetHash("onGround"); private static readonly FieldInfo SwimTimerField = AccessTools.Field(typeof(Character), "m_swimTimer"); private static readonly FieldInfo MaxAirAltitudeField = AccessTools.Field(typeof(Character), "m_maxAirAltitude"); private static bool _poseActive; private static bool _forceUpright; private static float _suppressSitUntil; private static int _uprightKeyFrame = -1; private static float _savedSwimDepth = 1.4f; public static bool IsPoseActive => _poseActive; public static bool IsForceUpright => _forceUpright; public static bool ShouldSuppressSit() { return Time.time < _suppressSitUntil; } public static void TryArmSitSuppressForX(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && WasUprightKeyPressed() && IsInWaterContext(player) && (_poseActive || IsAnimatorInWater(player) || IsSwimmingRaw(player))) { _suppressSitUntil = Time.time + 0.25f; } } private static bool IsSwimmingRaw(Player player) { if (SwimTimerField?.GetValue(player) is float num) { return num < 0.5f; } if ((Object)(object)player != (Object)null) { return ((Character)player).IsSwimming(); } return false; } public static bool IsFullySubmerged(Player player) { //IL_0013: 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) if ((Object)(object)player == (Object)null) { return false; } float liquidLevel = ((Character)player).GetLiquidLevel(); float y = ((Character)player).GetHeadPoint().y; float y2 = ((Component)player).transform.position.y; if (liquidLevel < y2 - 4f) { return false; } return y < liquidLevel - 0.08f; } public static bool IsHeadUnderLiquid(Player player) { return IsFullySubmerged(player); } private static bool IsInWaterContext(Player player) { if ((Object)(object)player != (Object)null) { if (!((Character)player).InWater() && !((Character)player).InLiquid()) { return IsFullySubmerged(player); } return true; } return false; } public static bool HasFullWet(Player player) { if ((Object)(object)player == (Object)null) { return false; } SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan == null || !sEMan.HaveStatusEffect(SEMan.s_statusEffectWet)) { return false; } StatusEffect statusEffect = sEMan.GetStatusEffect(SEMan.s_statusEffectWet); if ((Object)(object)statusEffect == (Object)null || statusEffect.m_ttl <= 0f) { return false; } return statusEffect.GetRemaningTime() >= statusEffect.m_ttl - 1f; } public static void Update(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !GenasiTypeManager.Is(player, GenasiType.Water)) { ClearAll(player); return; } if (!IsInWaterContext(player)) { ClearAll(player); return; } if (_poseActive && (!IsFullySubmerged(player) || HasFullWet(player))) { StopPose(player); } if (WasUprightKeyPressed()) { if (_poseActive || IsAnimatorInWater(player) || IsSwimmingRaw(player)) { ActivateUpright(player); } return; } if (_forceUpright) { ForceUprightState(player); } if (_poseActive) { ForceSwimState(player); SuppressFallWhileSubmerged(player); } if (WasJumpPressed()) { TryEnterSwimFromEmptyJump(player); } if (WasPoseKeyPressed()) { TryActivateSwimStroke(player); } } private static void TryEnterSwimFromEmptyJump(Player player) { if (IsFullySubmerged(player) && !HasFullWet(player) && !((Character)player).IsOnGround() && (!IsSwimmingRaw(player) || _forceUpright)) { int airBenderMaxJumps = AlmanacAirJumpBridge.GetAirBenderMaxJumps(); if (airBenderMaxJumps <= 0 || AlmanacAirJumpBridge.GetJumpCount() >= airBenderMaxJumps) { TryActivateSwimStroke(player); } } } private static void TryActivateSwimStroke(Player player) { if (IsFullySubmerged(player) && !HasFullWet(player)) { _forceUpright = false; RestoreSwimDepth(player); _poseActive = true; ((Character)player).Message((MessageType)2, "Swim stroke.", 0, (Sprite)null); ForceSwimState(player); } } private static bool WasJumpPressed() { if (!ZInput.GetButtonDown("Jump")) { return ZInput.GetButtonDown("JoyJump"); } return true; } private static void ActivateUpright(Player player) { StopPose(player); _forceUpright = true; _suppressSitUntil = Time.time + 0.2f; if (((Character)player).IsSitting()) { ((Character)player).StopEmote(); } if (((Character)player).m_swimDepth < 250f) { _savedSwimDepth = Mathf.Max(1.4f, ((Character)player).m_swimDepth); } ForceUprightState(player); } public static void ForceSwimState(Player player) { if (_poseActive && !((Object)(object)player == (Object)null) && IsFullySubmerged(player) && !_forceUpright) { SwimTimerField?.SetValue(player, 0f); if (((Character)player).m_swimDepth <= 1.4499999f || ((Character)player).m_swimDepth >= 250f) { ((Character)player).m_swimDepth = 1.4f; } if ((Object)(object)((Character)player).m_zanim != (Object)null) { ((Character)player).m_zanim.SetBool(InWaterHash, true); ((Character)player).m_zanim.SetBool(OnGroundHash, false); } } } public static void ForceUprightState(Player player) { if (_forceUpright && !((Object)(object)player == (Object)null)) { ((Character)player).m_swimDepth = 500f; SwimTimerField?.SetValue(player, 999f); if ((Object)(object)((Character)player).m_zanim != (Object)null) { ((Character)player).m_zanim.SetBool(InWaterHash, false); } if ((Object)(object)((Character)player).m_body != (Object)null) { ((Character)player).m_body.useGravity = true; } } } public static bool ShouldSkipUpdateSwimming(Character character) { Player val = (Player)(object)((character is Player) ? character : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer && GenasiTypeManager.Is(val, GenasiType.Water)) { return _forceUpright; } return false; } public static void SuppressFallWhileSubmerged(Player player) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && IsFullySubmerged(player) && !_forceUpright) { MaxAirAltitudeField?.SetValue(player, ((Component)player).transform.position.y); } } public static void LateUpdateVisual(Player player) { if (_forceUpright) { ForceUprightState(player); } else if (_poseActive) { ForceSwimState(player); SuppressFallWhileSubmerged(player); } } private static bool WasPoseKeyPressed() { if (!ZInput.GetKeyDown((KeyCode)122, true) && !Input.GetKeyDown((KeyCode)122)) { return Input.GetKeyDown((KeyCode)122); } return true; } private static bool WasUprightKeyPressed() { if (_uprightKeyFrame == Time.frameCount) { return true; } int num; if (!ZInput.GetKeyDown((KeyCode)120, true) && !Input.GetKeyDown((KeyCode)120)) { num = (Input.GetKeyDown((KeyCode)120) ? 1 : 0); if (num == 0) { goto IL_0038; } } else { num = 1; } _uprightKeyFrame = Time.frameCount; goto IL_0038; IL_0038: return (byte)num != 0; } private static bool IsAnimatorInWater(Player player) { if ((Object)(object)((Character)(player?)).m_animator == (Object)null) { return false; } return ((Character)player).m_animator.GetBool(InWaterHash); } private static void StopPose(Player player) { if (_poseActive) { _poseActive = false; } } private static void RestoreSwimDepth(Player player) { if (!((Object)(object)player == (Object)null) && ((Character)player).m_swimDepth >= 250f) { ((Character)player).m_swimDepth = ((_savedSwimDepth > 0f) ? _savedSwimDepth : 1.4f); } } private static void ClearAll(Player player) { StopPose(player); if (_forceUpright) { _forceUpright = false; RestoreSwimDepth(player); } } } internal static class GenasiWaterTouchOfWater { public const string ZdoKey = "Ent1tyRaces.TouchOfWater"; public static void TryMarkOnPlaced(WearNTear wear) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)wear == (Object)null) && !((Object)(object)localPlayer == (Object)null) && GenasiTypeManager.Is(localPlayer, GenasiType.Water) && !((Object)(object)wear.m_nview == (Object)null) && wear.m_nview.IsValid()) { Piece component = ((Component)wear).GetComponent(); if (!((Object)(object)component != (Object)null) || component.GetCreator() == 0L || component.GetCreator() == localPlayer.GetPlayerID()) { wear.m_nview.GetZDO().Set("Ent1tyRaces.TouchOfWater", true); } } } public static bool IsProtected(WearNTear wear) { if ((Object)(object)wear == (Object)null || (Object)(object)wear.m_nview == (Object)null || !wear.m_nview.IsValid()) { return false; } return wear.m_nview.GetZDO().GetBool("Ent1tyRaces.TouchOfWater", false); } } internal static class GenasiWaterWet { public static bool IsBlessedWet(Player player) { if ((Object)(object)player != (Object)null && GenasiTypeManager.Is(player, GenasiType.Water) && ((Character)player).GetSEMan() != null) { return ((Character)player).GetSEMan().HaveStatusEffect(SEMan.s_statusEffectWet); } return false; } public static void ApplyIncomingResists(Player player, HitData hit) { if (IsBlessedWet(player) && hit != null) { hit.m_damage.m_fire *= 0.5f; hit.m_damage.m_lightning *= 0.5f; hit.m_damage.m_frost *= 0.5f; } } public static void ClearColdWhileBlessed(Player player) { if (IsBlessedWet(player)) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectCold, true); } if (sEMan != null) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectFreezing, true); } } } public static bool ShouldBlockColdStatus(Player player, int nameHash) { if (!IsBlessedWet(player)) { return false; } if (nameHash != SEMan.s_statusEffectCold) { return nameHash == SEMan.s_statusEffectFreezing; } return true; } } internal static class GiantBody { public const float Scale = 2f; public const float CarryWeight = 600f; public const float InteractReachMult = 2f; public const float JumpMult = 1f; private const float DefaultInteractDistance = 5f; private static readonly FieldInfo BodyField = AccessTools.Field(typeof(Character), "m_body"); public static void Update(Player player) { if ((Object)(object)player == (Object)null) { return; } bool flag = RaceManager.GetRace(player) == RaceType.Giant; BodyScale.Update(player); if (!((Object)(object)player != (Object)(object)Player.m_localPlayer)) { float num = (flag ? 10f : 5f); if (Mathf.Abs(player.m_maxInteractDistance - num) > 0.01f) { player.m_maxInteractDistance = num; } } } public static float GetEffectiveSize(Character character) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return 0f; } return character.GetHeight() * ((Component)character).transform.localScale.y; } public static bool IsSmallerThan(Character target, Character giant) { return GetEffectiveSize(target) < GetEffectiveSize(giant) - 0.05f; } public static void BlinkTo(Player player, Vector3 position) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { ((Component)player).transform.position = position; object? obj = BodyField?.GetValue(player); Rigidbody val = (Rigidbody)((obj is Rigidbody) ? obj : null); if (val != null) { val.position = position; val.linearVelocity = Vector3.zero; val.angularVelocity = Vector3.zero; } } } } internal static class GiantCombat { public const float FireBonus = 18f; private const float StoneHpArmorFactor = 0.08f; private static bool _reflectingThorns; public static float FrostBonus => 9f; public static void ApplyOutgoingBonuses(Player player, Character target, HitData hit) { if ((Object)(object)player == (Object)null || hit == null || RaceManager.GetRace(player) != RaceType.Giant) { return; } switch (GiantTypeManager.GetGiantType(player)) { case GiantType.Fire: hit.m_damage.m_fire += 18f; break; case GiantType.Frost: hit.m_damage.m_frost += FrostBonus; break; case GiantType.Hill: HitDamageUtil.ModifyAll(hit, 1.25f); if ((Object)(object)target != (Object)null && GiantBody.IsSmallerThan(target, (Character)(object)player)) { hit.m_staggerMultiplier = Mathf.Max(hit.m_staggerMultiplier, 100f); } break; } } public static void ApplyIncomingMitigation(Player player, HitData hit) { if (!((Object)(object)player == (Object)null) && hit != null && GiantTypeManager.Is(player, GiantType.Stone)) { float total = HitDamageUtil.GetTotal(hit); if (!(total <= 0f)) { float stoneArmorBonus = GetStoneArmorBonus(player); float multiplier = Mathf.Clamp01((total - stoneArmorBonus) / total); HitDamageUtil.ModifyAll(hit, multiplier); } } } public static float GetStoneArmorBonus(Player player) { if ((Object)(object)player == (Object)null || !GiantTypeManager.Is(player, GiantType.Stone)) { return 0f; } return Mathf.Round(((Character)player).GetHealth() * 0.08f); } public static void TryApplyFrostSlow(Player attacker, Character target) { if (!((Object)(object)attacker == (Object)null) && !((Object)(object)target == (Object)null) && GiantTypeManager.Is(attacker, GiantType.Frost)) { SEMan sEMan = target.GetSEMan(); if (sEMan != null) { sEMan.AddStatusEffect(SEMan.s_statusEffectFrost, true, 0, 0f); sEMan.AddStatusEffect(SEMan.s_statusEffectCold, true, 0, 0f); FrostAuraFollower.Attach(target); } } } public static void TryStormThorns(Player stormGiant, Character attacker, float hpLost) { //IL_0043: 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) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_005b: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown if (_reflectingThorns || (Object)(object)stormGiant == (Object)null || (Object)(object)attacker == (Object)null || hpLost <= 0f || !GiantTypeManager.Is(stormGiant, GiantType.Storm) || (Object)(object)attacker == (Object)(object)stormGiant || attacker.IsDead()) { return; } _reflectingThorns = true; try { HitData val = new HitData { m_skill = (SkillType)0, m_point = attacker.GetCenterPoint() }; Vector3 val2 = attacker.GetCenterPoint() - ((Character)stormGiant).GetCenterPoint(); val.m_dir = ((Vector3)(ref val2)).normalized; val.m_hitType = (HitType)1; val.m_dodgeable = false; val.m_blockable = false; HitData val3 = val; val3.m_damage.m_lightning = hpLost; val3.SetAttacker((Character)(object)stormGiant); attacker.Damage(val3); } finally { _reflectingThorns = false; } } } public static class GiantTypeManager { private const string CustomKey = "Ent1ty303.GiantType"; public static GiantType GetGiantType(Player player) { if ((Object)(object)player == (Object)null) { return GiantType.Cloud; } if (PlayerDataStore.TryGetInt(player, "Ent1ty303.GiantType", out var value) && Enum.IsDefined(typeof(GiantType), value)) { return (GiantType)value; } return GiantType.Cloud; } public static bool TrySetGiantType(Player player, GiantType giantType, out string message) { message = null; if ((Object)(object)player == (Object)null) { message = "Load a character first."; return false; } if (RaceManager.GetRace(player) != RaceType.Giant) { message = "Only Giants can choose a giant type."; return false; } PlayerDataStore.SetInt(player, "Ent1ty303.GiantType", (int)giantType); message = giantType switch { GiantType.Cloud => "Cloud Giant: RMB+LMB blinks through mist. No fall damage; light double jump.", GiantType.Fire => "Fire Giant: your blows carry flame.", GiantType.Frost => "Frost Giant: blows chill and slow — frost shows even in rain.", GiantType.Hill => "Hill Giant: 125% Cloud smash; smaller foes stagger.", GiantType.Stone => "Stone Giant: health hardens your hide. RMB+LMB hurls a boulder.", GiantType.Storm => "Storm Giant: lightning thorns answer every wound.", _ => $"Giant type set to {giantType}.", }; if (((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } return true; } public static GiantType Parse(string value) { if (string.IsNullOrWhiteSpace(value)) { return GiantType.Cloud; } switch (value.Trim().ToLowerInvariant()) { case "cloud": return GiantType.Cloud; case "fire": return GiantType.Fire; case "frost": case "cold": case "ice": return GiantType.Frost; case "hill": return GiantType.Hill; case "stone": case "rock": return GiantType.Stone; case "storm": case "lightning": case "thunder": return GiantType.Storm; default: { GiantType result; return Enum.TryParse(value, ignoreCase: true, out result) ? result : GiantType.Cloud; } } } public static bool Is(Player player, GiantType type) { if (RaceManager.GetRace(player) == RaceType.Giant) { return GetGiantType(player) == type; } return false; } } internal static class GnomeForest { private const float AllyRange = 20f; public static bool IsAnimalFaction(Faction faction) { //IL_0000: 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) //IL_0004: Invalid comparison between Unknown and I4 if (faction - 1 <= 1) { return true; } return false; } public static bool ShouldProtectGnome(Character a, Character b) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)(((a is Player) ? a : null) ?? ((b is Player) ? b : null)); Character val2 = ((a is Player) ? b : a); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || !GnomeTypeManager.Is(val, GnomeType.Forest)) { return false; } Vector3 val3 = ((Component)val).transform.position - ((Component)val2).transform.position; if (((Vector3)(ref val3)).sqrMagnitude > 400f) { return false; } return IsAnimalFaction(val2.GetFaction()); } } [HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[] { typeof(Character), typeof(Character) })] public static class GnomeForestIsEnemyPatch { private static void Postfix(Character a, Character b, ref bool __result) { if (__result && GnomeForest.ShouldProtectGnome(a, b)) { __result = false; } } } internal static class GnomeRock { private const float Cooldown = 20f; private const float BuffDuration = 10f; private static float _nextReadyTime; private static float _buffUntil; public static bool HasEmpowerBuff(Player player) { if ((Object)(object)player != (Object)null && GnomeTypeManager.Is(player, GnomeType.Rock)) { return Time.time < _buffUntil; } return false; } public static void Update(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && GnomeTypeManager.Is(player, GnomeType.Rock) && DragonbornBreathInput.AreBreathButtonsHeld()) { DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); if (DragonbornBreathInput.IsAttackPressed()) { DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player); } } } public static bool TryStartFromAttack(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !GnomeTypeManager.Is(player, GnomeType.Rock)) { return false; } if (!DragonbornBreathInput.AreBreathButtonsHeld()) { return false; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player); if (Time.time < _nextReadyTime) { ((Character)player).Message((MessageType)2, "Stone song still echoes...", 0, (Sprite)null); return true; } RepairGear(player); _buffUntil = Time.time + 10f; _nextReadyTime = Time.time + 20f; ((Character)player).Message((MessageType)2, "Rock craft: gear restored & empowered!", 0, (Sprite)null); return true; } private static void RepairGear(Player player) { int num = 0; num += TryRepair(((Humanoid)player).GetRightItem()); num += TryRepair(((Humanoid)player).GetLeftItem()); Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory != null) { foreach (ItemData equippedItem in inventory.GetEquippedItems()) { num += TryRepair(equippedItem); } } if (num <= 0) { ((Character)player).Message((MessageType)1, "Nothing to repair.", 0, (Sprite)null); } } private static int TryRepair(ItemData item) { if (item?.m_shared == null || IsMagical(item)) { return 0; } if (!item.m_shared.m_useDurability) { return 0; } float maxDurability = item.GetMaxDurability(); if (item.m_durability >= maxDurability - 0.01f) { return 0; } item.m_durability = maxDurability; return 1; } private static bool IsMagical(ItemData item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0021: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0028: 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_002d: Invalid comparison between Unknown and I4 if ((int)item.m_shared.m_itemType == 24) { return true; } ItemType itemType = item.m_shared.m_itemType; if ((itemType - 6 <= 1 || (int)itemType == 11 || itemType - 17 <= 1) ? true : false) { return false; } StatusEffect attackStatusEffect = item.m_shared.m_attackStatusEffect; if (!string.IsNullOrEmpty((attackStatusEffect != null) ? ((Object)attackStatusEffect).name : null)) { return true; } string text = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : ""); if (text.IndexOf("Staff", StringComparison.OrdinalIgnoreCase) < 0) { return text.IndexOf("Magic", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } } public static class GnomeTypeManager { private const string CustomKey = "Ent1ty303.GnomeType"; public static GnomeType GetGnomeType(Player player) { if ((Object)(object)player == (Object)null) { return GnomeType.Forest; } if (PlayerDataStore.TryGetInt(player, "Ent1ty303.GnomeType", out var value) && Enum.IsDefined(typeof(GnomeType), value)) { return (GnomeType)value; } return GnomeType.Forest; } public static bool TrySetGnomeType(Player player, GnomeType gnomeType, out string message) { message = null; if ((Object)(object)player == (Object)null) { message = "Load a character first."; return false; } if (RaceManager.GetRace(player) != RaceType.Gnome) { message = "Only Gnomes can choose a type."; return false; } PlayerDataStore.SetInt(player, "Ent1ty303.GnomeType", (int)gnomeType); message = gnomeType switch { GnomeType.Forest => "Forest Gnome: beasts near you fight for you, not against you.", GnomeType.Rock => "Rock Gnome: LMB+RMB to repair & empower non-magical gear (20s CD).", _ => $"Gnome type set to {gnomeType}.", }; if (((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } return true; } public static GnomeType Parse(string value) { if (string.IsNullOrWhiteSpace(value)) { return GnomeType.Forest; } switch (value.Trim().ToLowerInvariant()) { case "forest": case "wood": case "animal": return GnomeType.Forest; case "rock": case "stone": return GnomeType.Rock; default: { GnomeType result; return Enum.TryParse(value, ignoreCase: true, out result) ? result : GnomeType.Forest; } } } public static bool Is(Player player, GnomeType type) { if (RaceManager.GetRace(player) == RaceType.Gnome) { return GetGnomeType(player) == type; } return false; } } internal static class HalflingBody { private static readonly HashSet IgnoredPairs = new HashSet(); private static readonly FieldInfo ColliderField = AccessTools.Field(typeof(Character), "m_collider"); public static void Update(Player player) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return; } if (RaceManager.GetRace(player) != RaceType.Halfling) { ClearIgnores(player); return; } Collider[] allColliders = GetAllColliders((Character)(object)player); if (allColliders.Length == 0) { return; } List list = new List(); Character.GetCharactersInRange(((Component)player).transform.position, 16f, list); float effectiveSize = GiantBody.GetEffectiveSize((Character)(object)player); foreach (Character item in list) { if ((Object)(object)item == (Object)null || (Object)(object)item == (Object)(object)player || item.IsDead()) { continue; } Player val = (Player)(object)((item is Player) ? item : null); if (val != null) { if (RaceManager.GetRace(val) == RaceType.Gnome) { continue; } } else if (GiantBody.GetEffectiveSize(item) <= effectiveSize + 0.05f) { continue; } IgnoreAgainst(allColliders, item); } } public static bool IsInsideLargerCreature(Player player) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Halfling) { return false; } float effectiveSize = GiantBody.GetEffectiveSize((Character)(object)player); List list = new List(); Character.GetCharactersInRange(((Component)player).transform.position, 6f, list); foreach (Character item in list) { if ((Object)(object)item == (Object)(object)player || item.IsDead()) { continue; } Player val = (Player)(object)((item is Player) ? item : null); if (val != null) { if (RaceManager.GetRace(val) == RaceType.Gnome) { continue; } } else if (GiantBody.GetEffectiveSize(item) <= effectiveSize + 0.05f) { continue; } float num = Vector3.Distance(((Character)player).GetCenterPoint(), item.GetCenterPoint()); float num2 = ((item is Player) ? 1.1f : (item.GetRadius() + 0.35f)); if (num < num2) { return true; } } return false; } public static void ApplyCrit(Player player, HitData hit) { if (!((Object)(object)player == (Object)null) && hit != null && RaceManager.GetRace(player) == RaceType.Halfling && Random.value <= 0.2f) { HitDamageUtil.ModifyAll(hit, 2.5f); } } private static void IgnoreAgainst(Collider[] selfCols, Character other) { Collider[] allColliders = GetAllColliders(other); foreach (Collider val in selfCols) { if ((Object)(object)val == (Object)null) { continue; } Collider[] array = allColliders; foreach (Collider val2 in array) { if (!((Object)(object)val2 == (Object)null)) { int item = Hash(val, val2); if (IgnoredPairs.Add(item)) { Physics.IgnoreCollision(val, val2, true); } } } } } private static void ClearIgnores(Player player) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (IgnoredPairs.Count == 0) { return; } Collider[] allColliders = GetAllColliders((Character)(object)player); List list = new List(); Character.GetCharactersInRange(((Component)player).transform.position, 40f, list); foreach (Character item in list) { Collider[] allColliders2 = GetAllColliders(item); Collider[] array = allColliders; foreach (Collider val in array) { if ((Object)(object)val == (Object)null) { continue; } Collider[] array2 = allColliders2; foreach (Collider val2 in array2) { if ((Object)(object)val2 != (Object)null) { Physics.IgnoreCollision(val, val2, false); } } } } IgnoredPairs.Clear(); } private static Collider[] GetAllColliders(Character character) { if ((Object)(object)character == (Object)null) { return Array.Empty(); } List list = new List(); object? obj = ColliderField?.GetValue(character); Collider val = (Collider)((obj is Collider) ? obj : null); if (val != null && (Object)(object)val != (Object)null) { list.Add(val); } Collider[] componentsInChildren = ((Component)character).GetComponentsInChildren(true); if (componentsInChildren != null) { Collider[] array = componentsInChildren; foreach (Collider val2 in array) { if ((Object)(object)val2 != (Object)null && !list.Contains(val2)) { list.Add(val2); } } } return list.ToArray(); } private static int Hash(Collider a, Collider b) { int instanceID = ((Object)a).GetInstanceID(); int instanceID2 = ((Object)b).GetInstanceID(); if (instanceID >= instanceID2) { return (instanceID2 * 397) ^ instanceID; } return (instanceID * 397) ^ instanceID2; } } internal static class HighElfLightBeam { private const float BeamRadius = 1.55f; private const float MaxBeamDistance = 2000f; private const float StaminaCostPerSecond = 12f; private const float DamageTickInterval = 0.1f; private const float BaseDamagePerSecond = 45f; private const float VisualStartForward = 0.85f; private const float FireDamageShare = 0.25f; private const float SpiritDamageShare = 0.75f; private const string ZdoBeamOn = "Ent1ty303.SunfireOn"; private const string ZdoBeamLen = "Ent1ty303.SunfireLen"; private static readonly Dictionary LastDamageTick = new Dictionary(); private static readonly Dictionary RemoteBeams = new Dictionary(); private static GameObject _beamRoot; private static LineRenderer _beamLine; private static readonly RaycastHit[] RayHits = (RaycastHit[])(object)new RaycastHit[32]; public static bool ShouldFire(Player player) { if ((Object)(object)player != (Object)null && ElfTypeManager.IsHighElf(player) && DragonbornBreathInput.IsUnarmed(player)) { return DragonbornBreathInput.AreBreathButtonsHeld(); } return false; } public static void Tick(Player player) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { HideLocalBeam(); SyncBeamZdo(player, on: false, 0f); return; } if (!ShouldFire(player)) { HideLocalBeam(); SyncBeamZdo(player, on: false, 0f); return; } float num = 12f * Time.deltaTime; if (player.GetStamina() < num + 0.1f) { HideLocalBeam(); SyncBeamZdo(player, on: false, 0f); ((Character)player).Message((MessageType)2, "Not enough stamina for the Sunfire beam.", 0, (Sprite)null); return; } ((Character)player).UseStamina(num); Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; float beamLength = GetBeamLength(eyePoint, normalized); UpdateLocalBeamVisual(eyePoint + normalized * 0.85f, normalized, Mathf.Max(0.1f, beamLength - 0.85f)); SyncBeamZdo(player, on: true, beamLength); long playerID = player.GetPlayerID(); float time = Time.time; if (!LastDamageTick.TryGetValue(playerID, out var value) || time - value >= 0.1f) { LastDamageTick[playerID] = time; ApplyBeamDamage(player, eyePoint, normalized, beamLength, 0.1f); } } public static void TickRemoteVisuals() { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer == (Object)null || (Object)(object)allPlayer == (Object)(object)Player.m_localPlayer) { continue; } long playerID = allPlayer.GetPlayerID(); hashSet.Add(playerID); ZNetView component = ((Component)allPlayer).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { HideRemoteBeam(playerID); continue; } ZDO zDO = component.GetZDO(); if (!zDO.GetBool("Ent1ty303.SunfireOn", false)) { HideRemoteBeam(playerID); continue; } float num = zDO.GetFloat("Ent1ty303.SunfireLen", 20f); Vector3 eyePoint = ((Character)allPlayer).GetEyePoint(); Vector3 lookDir = ((Character)allPlayer).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; UpdateRemoteBeamVisual(playerID, eyePoint + normalized * 0.85f, normalized, Mathf.Max(0.1f, num - 0.85f)); } List list = new List(); foreach (long key in RemoteBeams.Keys) { if (!hashSet.Contains(key)) { list.Add(key); } } foreach (long item in list) { HideRemoteBeam(item); } } private static void SyncBeamZdo(Player player, bool on, float length) { if ((Object)(object)player == (Object)null) { return; } ZNetView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner()) { ZDO zDO = component.GetZDO(); zDO.Set("Ent1ty303.SunfireOn", on); if (on) { zDO.Set("Ent1ty303.SunfireLen", length); } } } private static float GetBeamLength(Vector3 origin, Vector3 direction) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) int num = Physics.RaycastNonAlloc(origin, direction, RayHits, 2000f, -1, (QueryTriggerInteraction)1); float num2 = 2000f; for (int i = 0; i < num; i++) { RaycastHit val = RayHits[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((RaycastHit)(ref val)).collider.isTrigger && ((RaycastHit)(ref val)).distance > 0.5f && ((RaycastHit)(ref val)).distance < num2) { num2 = ((RaycastHit)(ref val)).distance; } } return num2; } private static void ApplyBeamDamage(Player player, Vector3 origin, Vector3 direction, float beamLength, float tickSeconds) { //IL_004e: 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_0054: 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_005b: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown float num = GetScaledDamagePerSecond(player) * tickSeconds; if (num <= 0f) { return; } float fire = num * 0.25f; float spirit = num * 0.75f; int num2 = 0; foreach (Character allCharacter in Character.GetAllCharacters()) { if (BreathTargetFilter.CanBreathDamage(player, allCharacter)) { Vector3 val = allCharacter.GetCenterPoint() - origin; float num3 = Vector3.Dot(val, direction); if (!(num3 < 0f) && !(num3 > beamLength + allCharacter.GetRadius()) && !(Vector3.Distance(origin + direction * num3, allCharacter.GetCenterPoint()) > 1.55f + allCharacter.GetRadius())) { Vector3 normalized = ((Vector3)(ref val)).normalized; HitData val2 = new HitData { m_hitCollider = (Collider)(object)allCharacter.m_collider, m_skill = (SkillType)11, m_point = allCharacter.GetCenterPoint(), m_dir = normalized, m_backstabBonus = 1f, m_dodgeable = true, m_blockable = true, m_hitType = (HitType)2 }; val2.m_damage.m_fire = fire; val2.m_damage.m_spirit = spirit; val2.SetAttacker((Character)(object)player); BreathDamageApplicator.MarkBreathHit(val2); allCharacter.Damage(val2); num2++; } } } if (num2 <= 0 && Time.frameCount % 120 == 0) { ((Character)player).Message((MessageType)1, "Sunfire sears empty air.", 0, (Sprite)null); } } private static float GetScaledDamagePerSecond(Player player) { TrinketBonus equippedBonus = TrinketBonusRegistry.GetEquippedBonus(player); float skillFactor = ((Character)player).GetSkillFactor((SkillType)11); float num = 10f + skillFactor * 20f; return 45f + num + equippedBonus.ElementDamage; } private static LineRenderer CreateBeamLine(string name) { //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: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); Object.DontDestroyOnLoad((Object)val); LineRenderer obj = val.AddComponent(); obj.useWorldSpace = true; obj.positionCount = 2; obj.startWidth = 0.55f; obj.endWidth = 0.12f; obj.numCapVertices = 4; ((Renderer)obj).material = new Material(Shader.Find("Sprites/Default")); obj.startColor = new Color(1f, 0.98f, 0.72f, 0.95f); obj.endColor = new Color(1f, 0.82f, 0.35f, 0.15f); ((Renderer)obj).enabled = false; return obj; } private static void EnsureLocalBeamVisual() { if (!((Object)(object)_beamRoot != (Object)null) || !((Object)(object)_beamLine != (Object)null)) { _beamLine = CreateBeamLine("Ent1tyRaces_HighElfSunfireBeam"); _beamRoot = ((Component)_beamLine).gameObject; } } private static void UpdateLocalBeamVisual(Vector3 visualStart, Vector3 direction, float length) { //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_0023: 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_002a: Unknown result type (might be due to invalid IL or missing references) EnsureLocalBeamVisual(); ((Renderer)_beamLine).enabled = true; _beamLine.SetPosition(0, visualStart); _beamLine.SetPosition(1, visualStart + direction * length); } private static void HideLocalBeam() { if ((Object)(object)_beamLine != (Object)null) { ((Renderer)_beamLine).enabled = false; } } private static void UpdateRemoteBeamVisual(long playerId, Vector3 visualStart, Vector3 direction, float length) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) if (!RemoteBeams.TryGetValue(playerId, out var value) || (Object)(object)value == (Object)null) { value = CreateBeamLine($"Ent1tyRaces_SunfireBeam_{playerId}"); RemoteBeams[playerId] = value; } ((Renderer)value).enabled = true; value.SetPosition(0, visualStart); value.SetPosition(1, visualStart + direction * length); } private static void HideRemoteBeam(long playerId) { if (RemoteBeams.TryGetValue(playerId, out var value) && (Object)(object)value != (Object)null) { ((Renderer)value).enabled = false; } } } internal static class HitDamageUtil { public static void ModifyAll(HitData hit, float multiplier) { //IL_0012: 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) //IL_0021: 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) if (hit != null && !Mathf.Approximately(multiplier, 1f)) { DamageTypes damage = hit.m_damage; ((DamageTypes)(ref damage)).Modify(multiplier); hit.m_damage = damage; } } public static float GetTotal(HitData hit) { if (hit == null) { return 0f; } return ((DamageTypes)(ref hit.m_damage)).GetTotalDamage(); } } internal static class MountainShiftDamageText { private static bool _pendingYellow; public static void Show(Player attacker, HitData hit, DamageModifier resistanceModifier, Vector3 point, float damage, bool targetIsPlayerOrTame) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) if (!((Object)(object)DamageText.instance == (Object)null) && !(damage <= 0.1f)) { if (ShouldForceYellow(attacker, hit, resistanceModifier)) { _pendingYellow = true; DamageText.instance.ShowText((TextType)2, point, damage, false); } else { DamageText.instance.ShowText(resistanceModifier, point, damage, targetIsPlayerOrTame); } } } public static bool TryConsumePendingYellow() { if (!_pendingYellow) { return false; } _pendingYellow = false; return true; } public static void MarkPendingYellow() { _pendingYellow = true; } public static bool ShouldForceYellow(Player attacker, HitData hit, DamageModifier resistanceModifier) { if (hit != null && hit.m_healthReturn >= 0.5f) { return true; } if ((Object)(object)attacker == (Object)null || hit == null) { return false; } return MountainShiftDisplay.ShouldShowResistanceShiftYellow(attacker, hit); } } internal static class MountainShiftDisplay { public static bool ShouldShowResistanceShiftYellow(Player player, BreathElement element) { if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Dragonborn) { return false; } if (!TrinketBonusRegistry.GetEquippedBonus(player).MountainResShift) { return false; } return ElementResistance.GetResistancePercent(player, element) > 0f; } public static bool ShouldShowResistanceShiftYellow(Player player, HitData hit) { if ((Object)(object)player == (Object)null || hit == null || RaceManager.GetRace(player) != RaceType.Dragonborn) { return false; } if (!TrinketBonusRegistry.GetEquippedBonus(player).MountainResShift) { return false; } if (hit.m_damage.m_fire > 0.01f && ElementResistance.GetResistancePercent(player, BreathElement.Fire) > 0f) { return true; } if (hit.m_damage.m_frost > 0.01f && ElementResistance.GetResistancePercent(player, BreathElement.Ice) > 0f) { return true; } if (hit.m_damage.m_lightning > 0.01f && ElementResistance.GetResistancePercent(player, BreathElement.Lightning) > 0f) { return true; } if (hit.m_damage.m_poison > 0.01f && ElementResistance.GetResistancePercent(player, BreathElement.Poison) > 0f) { return true; } return false; } public static DamageModifier GetDisplayModifier(Player player, HitData hit, DamageModifier resistanceModifier) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (ShouldShowResistanceShiftYellow(player, hit)) { return (DamageModifier)2; } return resistanceModifier; } } internal static class OrcRage { private const float DashDuration = 10f; private const float DashCooldown = 40f; private const float LastStandCooldown = 600f; private const float BounceHp = 101f; private const float DashMaxMult = 1.5f; private const float BounceFloor = 1.05f; private static float _dashUntil; private static float _dashReadyAt; private static float _lastStandReadyAt; private static float _savedMaxHp = -1f; private static bool _dashActive; private static bool _inHealthRewrite; public static bool IsDashing(Player player) { if ((Object)(object)player != (Object)null && RaceManager.GetRace(player) == RaceType.Orc && _dashActive) { return Time.time < _dashUntil; } return false; } public static void ApplyDashMaxHealthBonus(Player player, ref float health) { if (IsDashing(player)) { health *= 1.5f; } } public static void Update(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || RaceManager.GetRace(player) != RaceType.Orc) { EndDash(player); return; } if (_dashActive && Time.time >= _dashUntil) { EndDash(player); } TryBounceFromFloor(player); if (ZInput.GetKeyDown((KeyCode)122, true) || Input.GetKeyDown((KeyCode)122)) { if (Time.time < _dashReadyAt) { ((Character)player).Message((MessageType)2, "Rage still cooling...", 0, (Sprite)null); } else { BeginDash(player); } } } public static bool RewriteIncomingHealth(Player player, ref float health) { if (_inHealthRewrite || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return true; } if (RaceManager.GetRace(player) != RaceType.Orc) { return true; } if (health <= 0f) { if (Time.time < _lastStandReadyAt) { return true; } _lastStandReadyAt = Time.time + 600f; health = BounceTarget(player); ((Character)player).Message((MessageType)2, "Blood of the clan refuses death!", 0, (Sprite)null); return true; } if (health <= 1.05f) { float num = BounceTarget(player); if (num > health + 0.01f) { health = num; } } return true; } public static void OnRealDeath(Player player) { if ((Object)(object)player != (Object)null && RaceManager.GetRace(player) == RaceType.Orc) { _lastStandReadyAt = 0f; } } private static float BounceTarget(Player player) { return Mathf.Min(101f, Mathf.Max(1f, ((Character)player).GetMaxHealth())); } private static void TryBounceFromFloor(Player player) { float health = ((Character)player).GetHealth(); if (health <= 0f || health > 1.05f) { return; } float num = BounceTarget(player); if (num <= health + 0.01f) { return; } _inHealthRewrite = true; try { ((Character)player).SetHealth(num); } finally { _inHealthRewrite = false; } } private static void BeginDash(Player player) { float health = ((Character)player).GetHealth(); float maxHealth = ((Character)player).GetMaxHealth(); _dashUntil = Time.time + 10f; _dashReadyAt = Time.time + 40f; _dashActive = true; _savedMaxHp = maxHealth; player.SetMaxHealth(maxHealth, true); float maxHealth2 = ((Character)player).GetMaxHealth(); ((Character)player).SetHealth(Mathf.Min(health * 1.5f, maxHealth2)); try { ((Character)player).AddAdrenaline(999f); } catch { } ((Character)player).Message((MessageType)2, "Blood rush!", 0, (Sprite)null); } private static void EndDash(Player player) { if (_dashActive) { float num = (((Object)(object)player != (Object)null) ? ((Character)player).GetMaxHealth() : 0f); float num2 = ((num > 0.01f) ? (((Character)player).GetHealth() / num) : 1f); _dashActive = false; _dashUntil = 0f; _savedMaxHp = -1f; if (!((Object)(object)player == (Object)null)) { float num3 = num / 1.5f; player.SetMaxHealth(num3, true); float maxHealth = ((Character)player).GetMaxHealth(); ((Character)player).SetHealth(Mathf.Clamp(num2 * maxHealth, 1.06f, maxHealth)); } } } } internal static class PlayerDataStore { public static bool HasKey(Player player, string key) { if (player?.m_customData != null) { return player.m_customData.ContainsKey(key); } return false; } public static bool TryGetInt(Player player, string key, out int value) { value = 0; if (player?.m_customData == null || !player.m_customData.TryGetValue(key, out var value2)) { return false; } return int.TryParse(value2, out value); } public static void SetInt(Player player, string key, int value) { if (player?.m_customData != null) { player.m_customData[key] = value.ToString(); } } public static bool TryGetBool(Player player, string key, out bool value) { value = false; if (player?.m_customData == null || !player.m_customData.TryGetValue(key, out var value2)) { return false; } return bool.TryParse(value2, out value); } public static void SetBool(Player player, string key, bool value) { if (player?.m_customData != null) { player.m_customData[key] = (value ? "true" : "false"); } } public static bool TryGetFloat(Player player, string key, out float value) { value = 0f; if (player?.m_customData == null || !player.m_customData.TryGetValue(key, out var value2)) { return false; } return float.TryParse(value2, NumberStyles.Float, CultureInfo.InvariantCulture, out value); } public static void SetFloat(Player player, string key, float value) { if (player?.m_customData != null) { player.m_customData[key] = value.ToString(CultureInfo.InvariantCulture); } } public static bool TryGetString(Player player, string key, out string value) { value = null; if (player?.m_customData == null || !player.m_customData.TryGetValue(key, out var value2)) { return false; } value = value2; return true; } public static void SetString(Player player, string key, string value) { if (player?.m_customData != null) { player.m_customData[key] = value ?? string.Empty; } } } internal static class RaceDescriptions { private const string CompendiumHint = "\n\nGo to the Compendium (in inventory, press Valkyrie button) to view your race description and abilities."; public static string GetHoverText(RaceType race) { return BuildRaceCreateText(race) + "\n\nGo to the Compendium (in inventory, press Valkyrie button) to view your race description and abilities."; } public static string GetSubtypeHoverText(RaceType race, string subtypeKey) { if (string.IsNullOrEmpty(subtypeKey)) { return GetHoverText(race); } string key = subtypeKey.Trim().ToLowerInvariant(); return race switch { RaceType.Elf => GetElfSubtype(key), RaceType.Giant => GetGiantSubtype(key), RaceType.Genasi => GetGenasiSubtype(key), RaceType.Gnome => GetGnomeSubtype(key), RaceType.Tiefling => GetTieflingSubtype(key), RaceType.Dragonborn => GetBreathSubtype(key), _ => BuildRaceCreateText(race), } + "\n\nGo to the Compendium (in inventory, press Valkyrie button) to view your race description and abilities."; } public static string GetCompendiumText(Player player) { if ((Object)(object)player == (Object)null) { return "No character loaded."; } RaceType race = RaceManager.GetRace(player); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("").Append(RaceManager.GetRacePrettyName(race)); string subtypePrettyName = GetSubtypePrettyName(player, race); if (!string.IsNullOrEmpty(subtypePrettyName)) { stringBuilder.Append(" — ").Append(subtypePrettyName); } stringBuilder.Append("\n\n"); stringBuilder.Append(GetRaceLore(race)).Append("\n\n"); stringBuilder.Append("Abilities\n"); stringBuilder.Append(GetRaceKitClear(race)); string playerSubtypeKitClear = GetPlayerSubtypeKitClear(player, race); if (!string.IsNullOrEmpty(playerSubtypeKitClear)) { stringBuilder.Append("\n\n").Append(subtypePrettyName).Append("\n"); stringBuilder.Append(playerSubtypeKitClear); } if (race != RaceType.Human) { stringBuilder.Append("\n\nShared\n"); stringBuilder.Append("• −25% outgoing damage vs Humans (Human deals full damage)"); } return stringBuilder.ToString(); } private static string BuildRaceCreateText(RaceType race) { return RaceManager.GetRacePrettyName(race) + "\n\n" + GetRaceLore(race) + "\n\nKit:\n" + GetRaceKitClear(race) + ((race != RaceType.Human) ? "\n• −25% outgoing damage vs Humans" : "\n• Full outgoing damage (other races deal 25% less)"); } private static string GetRaceLore(RaceType race) { return race switch { RaceType.Human => "Children of Midgard’s stubbornness. No dragon blood, no midnight thirst — only will and skill.", RaceType.Dragonborn => "Scales over sinew. Proud, blunt, and never far from an element that wants out — pick Breath at creation.", RaceType.Vampire => "Night wrote its scripture on your throat. The sun is a sermon you refuse — unless roof or sunbrella intervenes.", RaceType.Elf => "Older than the first mead-hall rumor. Lineage shapes the gift — pick Type at creation.", RaceType.Aarakocra => "Sky-folk with hollow bones and little patience for floors. The wind is a highway; heat and height still collect tolls.", RaceType.Giant => "Twice the height, twice the bootprint. Every breed remembers a different sky — pick Type at creation.", RaceType.Genasi => "Elemental blood that never quite cooled. Pick Type: air, earth, fire, or water that builds cabins on the seafloor.", RaceType.Dwarf => "Short stacks of stubborn and steel. Stone remembers your kin; poison hesitates.", RaceType.Gnome => "Small enough to hide behind a turnip, clever enough to bargain with beasts — or a hammer. Pick Type.", RaceType.Halfling => "Second breakfast is a combat plan. You slip where larger folk lodge, and luck arrives mid-swing.", RaceType.Orc => "War-drums under the ribs. When the body should fail, something older laughs and stands up anyway.", RaceType.Tiefling => "Hell’s paperwork stamped in horn and smile. Legacy chooses which cousin answers — pick Legacy.", RaceType.Aasimar => "Heaven left a night-light in your bones. You shine through mist and knit allies with breath.", _ => string.Empty, }; } private static string GetRaceKitClear(RaceType race) { return race switch { RaceType.Human => "• No racial bonuses or penalties beyond full damage", RaceType.Dragonborn => "• Choose Breath: Fire, Poison, Lightning, or Ice (see Breath hover / Compendium)\n• Hold RMB+LMB — elemental breath\n• +Armor from race; Ocean trinket adds more armor\n• Mountain trinket + matching resists can shift breath & yellow floaters\n• Change breath later: /breath (requires devcommands)", RaceType.Vampire => "• Sun damage after day 5 outdoors (blocked by shelter, or ALT while holding a shield = sunbrella)\n• ALT (shield in hand) — toggle sunbrella (blocks sun & rain; blocks blocking)\n• Immune to frost; +fire vulnerability\n• Night vision\n• Blood foods, +pierce damage, lifesteal on hits", RaceType.Elf => "• Choose Type: High, Wood, or Drow (see Type hover / Compendium)\n• Lineage abilities listed under that Type", RaceType.Aarakocra => "• Z — toggle flight on/off\n• While flying: Space — ascend · Ctrl — dive\n• Flying movement drains stamina (hover still is free)\n• Feather fall from height (passive)\n• ALT while holding a knife — absorb it into talons (+unarmed damage; not butcher knife)\n• Wings work underwater (cannot dive with wings)\n• Ashlands: flight fails when not safely above land", RaceType.Giant => "• ~2× body scale; increased carry weight\n• Choose Type: Cloud, Fire, Frost, Hill, Stone, or Storm", RaceType.Genasi => "• Choose Type: Air, Earth, Fire, or Water\n• Element abilities listed under that Type", RaceType.Dwarf => "• 0.75× height\n• Night vision (not cold-proof)\n• +Poison resistance; poison fades faster\n• +20% armor\n• Hold MMB while your attack connects — dig crater under target\n• +50% axe & pickaxe attack speed\n• Hoe / hammer / cultivator: 0 stamina use, −50% build cost, no workbench required\n• Pieces you build refund only the half-cost you paid when broken (no material dupe)", RaceType.Gnome => "• 0.50× height\n• Choose Type: Forest or Rock", RaceType.Halfling => "• 0.65× height\n• Collision pass-through vs larger creatures & other players (not Gnomes)\n• 20% chance for huge critical hits\n• While overlapping a larger creature: enemies barely detect you", RaceType.Orc => "• Z — Blood Rush (10s): +100% move speed, +50% max HP, fills adrenaline (40s cooldown)\n• Last Stand (passive): lethal hit → set HP to min(101, max HP); 10 min cooldown (resets on death)\n• Dropping to ≤1 HP also snaps you to 101 when Last Stand applies", RaceType.Tiefling => "• 0.95× height\n• Choose Legacy: Abyssal, Chthonic, or Infernal", RaceType.Aasimar => "• Normal height\n• +Fire resistance; +frost resistance (blocks mountain cold)\n• White wisp light (does not clear mist)\n• Hold RMB+LMB — healing breath (burst heal self/allies)\n• Feather fall (passive)\n• Jump in mid-air — +1 air jump (uses after Almanac AirBender jumps if present)", _ => "• See race kit", }; } private static string GetSubtypePrettyName(Player player, RaceType race) { return race switch { RaceType.Elf => ElfTypeManager.GetElfType(player).ToString(), RaceType.Giant => GiantTypeManager.GetGiantType(player).ToString(), RaceType.Genasi => GenasiTypeManager.GetGenasiType(player).ToString(), RaceType.Gnome => GnomeTypeManager.GetGnomeType(player).ToString(), RaceType.Tiefling => TieflingLegacyManager.GetLegacy(player).ToString(), RaceType.Dragonborn => BreathManager.GetBreathElement(player).ToString(), _ => null, }; } private static string GetPlayerSubtypeKitClear(Player player, RaceType race) { return race switch { RaceType.Elf => GetElfSubtypeKit(ElfTypeManager.GetElfType(player).ToString().ToLowerInvariant()), RaceType.Giant => GetGiantSubtypeKit(GiantTypeManager.GetGiantType(player).ToString().ToLowerInvariant()), RaceType.Genasi => GetGenasiSubtypeKit(GenasiTypeManager.GetGenasiType(player).ToString().ToLowerInvariant()), RaceType.Gnome => GetGnomeSubtypeKit(GnomeTypeManager.GetGnomeType(player).ToString().ToLowerInvariant()), RaceType.Tiefling => GetTieflingSubtypeKit(TieflingLegacyManager.GetLegacy(player).ToString().ToLowerInvariant()), RaceType.Dragonborn => GetBreathSubtypeKit(BreathManager.GetBreathElement(player).ToString().ToLowerInvariant()), _ => null, }; } private static string GetBreathSubtype(string key) { string text; switch (key) { case "fire": text = "Fire Breath"; break; case "poison": text = "Poison Breath"; break; case "lightning": text = "Lightning Breath"; break; case "ice": case "frost": text = "Ice Breath"; break; default: text = "Breath"; break; } string text2 = text; return text2 + "\n\n" + GetBreathSubtypeLore(key) + "\n\nKit:\n" + GetBreathSubtypeKit(key); } private static string GetBreathSubtypeLore(string key) { switch (key) { case "fire": return "Ember in the lungs. The classic dragon’s answer."; case "poison": return "A green hiss that turns air into a warning."; case "lightning": return "Thunder that never waits for the storm."; case "ice": case "frost": return "Winter exhaled — sharp enough to bite."; default: return string.Empty; } } private static string GetBreathSubtypeKit(string key) { switch (key) { case "fire": return "• Hold RMB+LMB — fire breath (elemental damage burst)"; case "poison": return "• Hold RMB+LMB — poison breath (elemental damage burst)"; case "lightning": return "• Hold RMB+LMB — lightning breath (elemental damage burst)"; case "ice": case "frost": return "• Hold RMB+LMB — ice / frost breath (elemental damage burst)"; default: return "• Hold RMB+LMB — elemental breath"; } } private static string GetElfSubtype(string key) { string text = key switch { "high" => "High Elf", "wood" => "Wood Elf", "drow" => "Drow", _ => "Elf", }; return text + "\n\n" + GetElfSubtypeLore(key) + "\n\nKit:\n" + GetElfSubtypeKit(key); } private static string GetElfSubtypeLore(string key) { return key switch { "high" => "Sunfire sits behind your teeth like a polite war.", "wood" => "Bark under the fingernails; the forest asks if you can vanish.", "drow" => "The Underdark smiles with too many teeth.", _ => string.Empty, }; } private static string GetElfSubtypeKit(string key) { return key switch { "high" => "• Hold RMB+LMB while unarmed — sunfire / spirit beam\n• Weapon hits deal bonus elemental damage", "wood" => "• 0 run stamina drain\n• Near trees: stealth increases (harder for enemies to detect you)\n• +Bow damage", "drow" => "• 0 sneak stamina drain\n• +100% knife damage\n• +Poison damage / poison effects on hits\n• Shadow armor (passive): each hit you land grants +3 body armor for 5s (stacks; timer refreshes)", _ => "• See Elf Type", }; } private static string GetGiantSubtype(string key) { if (string.IsNullOrEmpty(key)) { return BuildRaceCreateText(RaceType.Giant); } string text = char.ToUpperInvariant(key[0]) + key.Substring(1) + " Giant"; return text + "\n\n" + GetGiantSubtypeLore(key) + "\n\nKit:\n" + GetGiantSubtypeKit(key); } private static string GetGiantSubtypeLore(string key) { return key switch { "cloud" => "Mist for blood, sky for a door.", "fire" => "Forge-heat that never left the bone.", "frost" => "Winter learned your name and kept the receipt.", "hill" => "A boulder’s idea of a handshake.", "stone" => "Patience measured in cliffs.", "storm" => "Thunder takes attendance.", _ => string.Empty, }; } private static string GetGiantSubtypeKit(string key) { return key switch { "cloud" => "• Hold RMB+LMB — blink along look direction\n• Jump in mid-air — +1 air jump (reduced stamina cost)\n• 0 fall damage", "fire" => "• Attacks deal bonus fire damage", "frost" => "• Attacks deal bonus frost damage\n• Attacks apply slow (frost readable in rain)", "hill" => "• +25% smash vs Cloud baseline\n• Hits on smaller foes apply stagger", "stone" => "• Body armor bonus based on current HP (more HP = more armor)\n• Hold RMB+LMB — throw boulder", "storm" => "• When you take damage: lightning damage reflects to the attacker", _ => "• See Giant Type", }; } private static string GetGenasiSubtype(string key) { if (string.IsNullOrEmpty(key)) { return BuildRaceCreateText(RaceType.Genasi); } string text = char.ToUpperInvariant(key[0]) + key.Substring(1) + " Genasi"; return text + "\n\n" + GetGenasiSubtypeLore(key) + "\n\nKit:\n" + GetGenasiSubtypeKit(key); } private static string GetGenasiSubtypeLore(string key) { return key switch { "air" => "Wind with a pulse.", "earth" => "The ground is a suggestion you edit.", "fire" => "Embers under the skin.", "water" => "Salt in the veins. Wet is a blessing; depth is a hallway; hearths still burn below the waves.", _ => string.Empty, }; } private static string GetGenasiSubtypeKit(string key) { return key switch { "air" => "• Hold RMB+LMB — levitate look-at target (large foes: 2× stamina cost)\n• Mouse wheel while levitating — pull closer / push farther\n• −35% swim stamina drain", "earth" => "• Hold RMB+LMB — raise earth ahead\n• Hold RMB+MMB — lower earth ahead\n• 0 run stamina drain", "fire" => "• Flame-walk (passive): leave a ground fire trail as you move (50% normal fire strength)", "water" => "• Z — Swim stroke (fully submerged only; blocked if Wet timer is full ~2:00)\n• X — Exit swim → upright + gravity (only while swimming / inWater)\n• Space (Jump) with 0 jumps left underwater — enter swim stroke\n• Ctrl / Crouch — dive deeper · Space — ascend (while swimming)\n• R — hide/show hands (equip while submerged)\n• Hold RMB+LMB near water — poison tide\n• +300% swim speed (4× base)\n• 0 swim stamina drain\n• While Wet: +health/stamina/eitr regen; +resist fire / frost / lightning\n• 0 fall damage while fully submerged\n• Build & light fires underwater\n• Touch of Water (passive): pieces you build are immune to rain & water weathering", _ => "• See Genasi Type", }; } private static string GetGnomeSubtype(string key) { string text = ((key == "forest") ? "Forest Gnome" : ((key == "rock") ? "Rock Gnome" : "Gnome")); return text + "\n\n" + GetGnomeSubtypeLore(key) + "\n\nKit:\n" + GetGnomeSubtypeKit(key); } private static string GetGnomeSubtypeLore(string key) { if (!(key == "forest")) { if (key == "rock") { return "Gears in the marrow; a hammer is a love language."; } return string.Empty; } return "Whispers to squirrels and worse."; } private static string GetGnomeSubtypeKit(string key) { if (!(key == "forest")) { if (key == "rock") { return "• Hold RMB+LMB — repair & empower non-magical held/equipped gear (20s cooldown)\n• Hammer repairs cost 0 stamina"; } return "• See Gnome Type"; } return "• Nearby animals will not aggro you (passive)"; } private static string GetTieflingSubtype(string key) { string text = key switch { "abyssal" => "Abyssal Tiefling", "chthonic" => "Chthonic Tiefling", "infernal" => "Infernal Tiefling", _ => "Tiefling", }; return text + "\n\n" + GetTieflingSubtypeLore(key) + "\n\nKit:\n" + GetTieflingSubtypeKit(key); } private static string GetTieflingSubtypeLore(string key) { return key switch { "abyssal" => "The Abyss doesn’t knock — it oozes.", "chthonic" => "Deep places keep cold secrets.", "infernal" => "Baator’s branding iron left a smirk.", _ => string.Empty, }; } private static string GetTieflingSubtypeKit(string key) { return key switch { "abyssal" => "• +Poison resistance\n• Hold RMB+LMB with trinkets — poison breath / green beam / stun aura (by progression)", "chthonic" => "• +Frost resistance; frost on hit\n• Trinket: +max HP\n• Hold RMB+LMB with beam trinket — chill/slow; −1 enemy damage per tick (purple floater)", "infernal" => "• +Fire resistance; immune to your own hellfire\n• Hold RMB+LMB — basic fire (through Swamp, damage ÷3)\n• Hold RMB+LMB — emerald flame (Mountains→Plains)\n• Hold RMB+LMB — darkness cloud (Mistlands+)", _ => "• See Tiefling Legacy", }; } } public static class RaceManager { private const string CustomRaceKey = "Ent1ty303.Race"; private const string CustomLockKey = "Ent1ty303.RaceLocked"; private const string ZdoRaceKey = "Ent1ty303.Race"; private const string ZdoLockKey = "Ent1ty303.RaceLocked"; public static RaceType[] AllSelectableRaces { get; } = new RaceType[13] { RaceType.Human, RaceType.Dragonborn, RaceType.Vampire, RaceType.Elf, RaceType.Aarakocra, RaceType.Giant, RaceType.Genasi, RaceType.Dwarf, RaceType.Gnome, RaceType.Halfling, RaceType.Orc, RaceType.Tiefling, RaceType.Aasimar }; public static RaceType GetRace(Player player) { if ((Object)(object)player == (Object)null) { return RaceType.Human; } if ((Object)(object)player != (Object)(object)Player.m_localPlayer) { return GetRaceFromZdo(player); } if (PlayerDataStore.TryGetInt(player, "Ent1ty303.Race", out var value)) { return (RaceType)value; } return MigrateRaceFromZdo(player); } public static RaceType GetRaceFromZdo(Player player) { ZNetView val = ((player != null) ? ((Component)player).GetComponent() : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { return RaceType.Human; } return (RaceType)val.GetZDO().GetInt("Ent1ty303.Race", 0); } public static bool IsNonHuman(Player player) { return GetRace(player) != RaceType.Human; } public static bool IsRaceChoiceLocked(Player player) { if ((Object)(object)player == (Object)null) { return false; } if (PlayerDataStore.TryGetBool(player, "Ent1ty303.RaceLocked", out var value)) { return value; } ZNetView component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } bool num = component.GetZDO().GetBool("Ent1ty303.RaceLocked", false); if (num) { PlayerDataStore.SetBool(player, "Ent1ty303.RaceLocked", value: true); } return num; } public static bool TryChooseRace(Player player, RaceType race, out string message, bool silent = false) { message = null; if ((Object)(object)player == (Object)null) { message = "Load a character first."; return false; } if (IsRaceChoiceLocked(player)) { message = $"Your race is sealed: {GetRace(player)}. Odin does not do refunds."; return false; } SetRace(player, race, silent); LockRaceChoice(player); ApplyDefaultSubtype(player, race); message = (silent ? string.Empty : ("Race set to: " + GetRaceDisplayName(race))); if (!silent && race == RaceType.Vampire) { message += "\nWARNING: GET SHIELD BY DAY 5 AND PRESS ALT WITH IT IN HAND"; if (((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, "WARNING: GET SHIELD BY DAY 5 AND PRESS ALT WITH IT IN HAND", 0, (Sprite)null); } } return true; } private static void ApplyDefaultSubtype(Player player, RaceType race) { switch (race) { case RaceType.Elf: PlayerDataStore.SetInt(player, "Ent1ty303.ElfType", 0); break; case RaceType.Giant: PlayerDataStore.SetInt(player, "Ent1ty303.GiantType", 0); break; case RaceType.Genasi: PlayerDataStore.SetInt(player, "Ent1ty303.GenasiType", 0); break; case RaceType.Gnome: PlayerDataStore.SetInt(player, "Ent1ty303.GnomeType", 0); break; case RaceType.Tiefling: PlayerDataStore.SetInt(player, "Ent1ty303.TieflingLegacy", 0); break; case RaceType.Dragonborn: PlayerDataStore.SetInt(player, "Ent1ty303.BreathElement", 0); break; case RaceType.Vampire: case RaceType.Aarakocra: case RaceType.Dwarf: case RaceType.Halfling: case RaceType.Orc: break; } } public static void ApplyRaceForNewCharacter(Player player, RaceType race) { if (!((Object)(object)player == (Object)null)) { SetRace(player, race, silent: true); ApplyDefaultSubtype(player, race); } } public static void ApplySubtypeForNewCharacter(Player player, RaceType race, string raw) { if (!((Object)(object)player == (Object)null) && !string.IsNullOrWhiteSpace(raw)) { switch (race) { case RaceType.Elf: PlayerDataStore.SetInt(player, "Ent1ty303.ElfType", (int)ElfTypeManager.ParseElfType(raw)); break; case RaceType.Giant: PlayerDataStore.SetInt(player, "Ent1ty303.GiantType", (int)GiantTypeManager.Parse(raw)); break; case RaceType.Genasi: PlayerDataStore.SetInt(player, "Ent1ty303.GenasiType", (int)GenasiTypeManager.Parse(raw)); break; case RaceType.Gnome: PlayerDataStore.SetInt(player, "Ent1ty303.GnomeType", (int)GnomeTypeManager.Parse(raw)); break; case RaceType.Tiefling: PlayerDataStore.SetInt(player, "Ent1ty303.TieflingLegacy", (int)TieflingLegacyManager.Parse(raw)); break; case RaceType.Dragonborn: PlayerDataStore.SetInt(player, "Ent1ty303.BreathElement", (int)BreathManager.ParseBreathElement(raw)); break; case RaceType.Vampire: case RaceType.Aarakocra: case RaceType.Dwarf: case RaceType.Halfling: case RaceType.Orc: break; } } } public static string GetRaceDisplayName(RaceType race) { return race switch { RaceType.Dragonborn => "dragonborn", RaceType.Vampire => "vampire", RaceType.Elf => "elf", RaceType.Aarakocra => "aarakocra", RaceType.Giant => "giant", RaceType.Genasi => "genasi", RaceType.Dwarf => "dwarf", RaceType.Gnome => "gnome", RaceType.Halfling => "halfling", RaceType.Orc => "orc", RaceType.Tiefling => "tiefling", RaceType.Aasimar => "aasimar", RaceType.Human => "human", _ => race.ToString().ToLowerInvariant(), }; } public static string GetRacePrettyName(RaceType race) { return race switch { RaceType.Dragonborn => "Dragonborn", RaceType.Vampire => "Vampire", RaceType.Elf => "Elf", RaceType.Aarakocra => "Aarakocra", RaceType.Giant => "Giant", RaceType.Genasi => "Genasi", RaceType.Dwarf => "Dwarf", RaceType.Gnome => "Gnome", RaceType.Halfling => "Halfling", RaceType.Orc => "Orc", RaceType.Tiefling => "Tiefling", RaceType.Aasimar => "Aasimar", RaceType.Human => "Human", _ => race.ToString(), }; } public static string GetRaceDetail(Player player) { RaceType race = GetRace(player); return race switch { RaceType.Elf => $"{race} ({ElfTypeManager.GetElfType(player)})", RaceType.Giant => $"{race} ({GiantTypeManager.GetGiantType(player)})", RaceType.Genasi => $"{race} ({GenasiTypeManager.GetGenasiType(player)})", RaceType.Gnome => $"{race} ({GnomeTypeManager.GetGnomeType(player)})", RaceType.Tiefling => $"{race} ({TieflingLegacyManager.GetLegacy(player)})", RaceType.Dragonborn => $"{race} ({BreathManager.GetBreathElement(player)})", _ => race.ToString(), }; } public static void SetRace(Player player, RaceType race, bool silent = false) { if (!((Object)(object)player == (Object)null)) { PlayerDataStore.SetInt(player, "Ent1ty303.Race", (int)race); SyncRaceToZdo(player, race); if (!silent && ((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, "Race set to: " + GetRaceDisplayName(race), 0, (Sprite)null); } } } public static void LockRaceChoice(Player player) { if (!((Object)(object)player == (Object)null)) { PlayerDataStore.SetBool(player, "Ent1ty303.RaceLocked", value: true); SyncLockToZdo(player, locked: true); } } public static bool TryResetRace(Player player, out string message) { message = null; if ((Object)(object)player == (Object)null) { message = "Load a character first."; return false; } if ((Object)(object)Console.instance == (Object)null || !((Terminal)Console.instance).IsCheatsEnabled()) { message = "Enable devcommands first, then /race reset."; return false; } PlayerDataStore.SetInt(player, "Ent1ty303.Race", 0); PlayerDataStore.SetBool(player, "Ent1ty303.RaceLocked", value: false); SyncRaceToZdo(player, RaceType.Human); SyncLockToZdo(player, locked: false); if (player.m_customData != null) { player.m_customData.Remove("Ent1ty303.ElfType"); player.m_customData.Remove("Ent1ty303.GiantType"); player.m_customData.Remove("Ent1ty303.GenasiType"); player.m_customData.Remove("Ent1ty303.BreathElement"); player.m_customData.Remove("Ent1ty303.GnomeType"); player.m_customData.Remove("Ent1ty303.TieflingLegacy"); } AarakocraFlight.RemoveFeatherFall(player); AasimarFlight.RemoveFeatherFall(player); AasimarWisp.Remove(player); message = "Race unlocked. Use /race to choose again."; if (((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } return true; } public static void SyncFromCustomData(Player player) { if (!((Object)(object)player == (Object)null)) { if (PlayerDataStore.TryGetInt(player, "Ent1ty303.Race", out var value)) { SyncRaceToZdo(player, (RaceType)value); } if (PlayerDataStore.TryGetBool(player, "Ent1ty303.RaceLocked", out var value2) && value2) { SyncLockToZdo(player, locked: true); } } } public static RaceType ParseRace(string value) { if (string.IsNullOrWhiteSpace(value)) { return RaceType.Human; } switch (value.Trim().ToLowerInvariant()) { case "human": return RaceType.Human; case "dragon": case "dragonborn": return RaceType.Dragonborn; case "vampire": return RaceType.Vampire; case "elves": case "elf": return RaceType.Elf; case "aarakocra": case "aara": case "bird": return RaceType.Aarakocra; case "giant": case "giants": return RaceType.Giant; case "genasi": case "elemental": return RaceType.Genasi; case "dwarf": case "dwarves": return RaceType.Dwarf; case "gnome": case "gnomes": return RaceType.Gnome; case "hobbit": case "hin": case "halfling": return RaceType.Halfling; case "orc": case "orcs": return RaceType.Orc; case "devil": case "teifling": case "tiefling": return RaceType.Tiefling; case "angel": case "aasimar": return RaceType.Aasimar; default: { RaceType result; return Enum.TryParse(value, ignoreCase: true, out result) ? result : RaceType.Human; } } } public static RaceType RollRandomNonHuman() { RaceType[] array = new RaceType[12] { RaceType.Dragonborn, RaceType.Vampire, RaceType.Elf, RaceType.Aarakocra, RaceType.Giant, RaceType.Genasi, RaceType.Dwarf, RaceType.Gnome, RaceType.Halfling, RaceType.Orc, RaceType.Tiefling, RaceType.Aasimar }; return array[Random.Range(0, array.Length)]; } private static RaceType MigrateRaceFromZdo(Player player) { ZNetView component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return RaceType.Human; } int num = component.GetZDO().GetInt("Ent1ty303.Race", 0); bool flag = component.GetZDO().GetBool("Ent1ty303.RaceLocked", false); if (num != 0 || flag) { PlayerDataStore.SetInt(player, "Ent1ty303.Race", num); if (flag) { PlayerDataStore.SetBool(player, "Ent1ty303.RaceLocked", value: true); } } return (RaceType)num; } private static void SyncRaceToZdo(Player player, RaceType race) { ZNetView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { component.GetZDO().Set("Ent1ty303.Race", (int)race); } } private static void SyncLockToZdo(Player player, bool locked) { ZNetView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { component.GetZDO().Set("Ent1ty303.RaceLocked", locked); } } } internal static class StoneGiantRock { private const float CooldownSeconds = 1.25f; private const float StaminaCost = 12f; private const float ThrowSpeed = 28f; private const float DamagePerHealth = 0.04f; private const float MinDamage = 18f; private const float MaxDamage = 70f; private static readonly MethodInfo ProjectileSetup = AccessTools.Method(typeof(Projectile), "Setup", (Type[])null, (Type[])null); private static float _nextReadyTime; public static void Update(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !GiantTypeManager.Is(player, GiantType.Stone) || !DragonbornBreathInput.AreBreathButtonsHeld() || !DragonbornBreathInput.IsAttackPressed()) { return; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); if (!(Time.time < _nextReadyTime)) { if (!((Character)player).HaveStamina(12.1f)) { ((Character)player).Message((MessageType)2, "Too weary to throw.", 0, (Sprite)null); return; } if (!TryThrow(player)) { ((Character)player).Message((MessageType)2, "No rock to throw.", 0, (Sprite)null); return; } ((Character)player).UseStamina(12f); _nextReadyTime = Time.time + 1.25f; } } private static bool TryThrow(Player player) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { return false; } GameObject prefab = ZNetScene.instance.GetPrefab("Greydwarf_throw_projectile"); if ((Object)(object)prefab == (Object)null) { return false; } Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 val = eyePoint + ((Vector3)(ref lookDir)).normalized * 0.6f; lookDir = ((Character)player).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; float blunt = Mathf.Clamp(((Character)player).GetHealth() * 0.04f, 18f, 70f); GameObject val2 = Object.Instantiate(prefab, val, Quaternion.LookRotation(normalized)); Projectile component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); return false; } component.m_spawnOnHit = null; component.m_spawnOnHitChance = 0f; component.m_spawnCount = 0; component.m_aoe = 0f; component.m_gravity = 12f; component.m_ttl = 8f; HitData val3 = new HitData { m_skill = (SkillType)11, m_damage = { m_blunt = blunt }, m_pushForce = 35f, m_dodgeable = true, m_blockable = true, m_hitType = (HitType)2, m_dir = normalized, m_point = val }; val3.SetAttacker((Character)(object)player); Vector3 val4 = normalized * 28f; if (!InvokeSetup(component, player, val4, val3)) { Traverse obj = Traverse.Create((object)component); obj.Field("m_owner").SetValue((object)player); obj.Field("m_vel").SetValue((object)val4); obj.Field("m_originalHitData").SetValue((object)val3); component.m_damage = val3.m_damage; } return true; } private static bool InvokeSetup(Projectile proj, Player player, Vector3 velocity, HitData hit) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if (ProjectileSetup == null) { return false; } ParameterInfo[] parameters = ProjectileSetup.GetParameters(); try { if (parameters.Length >= 6) { ProjectileSetup.Invoke(proj, new object[6] { player, velocity, -1f, hit, null, null }); return true; } if (parameters.Length == 5) { ProjectileSetup.Invoke(proj, new object[5] { player, velocity, -1f, hit, null }); return true; } if (parameters.Length == 4) { ProjectileSetup.Invoke(proj, new object[4] { player, velocity, -1f, hit }); return true; } } catch { return false; } return false; } } internal static class TieflingAbyssal { private const float BreathCooldown = 1f; private static float _nextBreath; private static readonly Dictionary StunImmuneUntil = new Dictionary(); private static readonly Dictionary NextBreakoutRoll = new Dictionary(); public static void Update(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !TieflingLegacyManager.Is(player, TieflingLegacy.Abyssal)) { return; } if (TrinketGates.AbyssalStun(player)) { TickStunAura(player); } if (TrinketGates.AbyssalBeam(player)) { TieflingBeams.Tick(player, TieflingBeams.Mode.PoisonGreen); } else if (TrinketGates.AbyssalBreath(player) && DragonbornBreathInput.AreBreathButtonsHeld() && DragonbornBreathInput.IsAttackPressed() && !(Time.time < _nextBreath)) { DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player); BreathElement breathElement = BreathManager.GetBreathElement(player); PlayerDataStore.SetInt(player, "Ent1ty303.BreathElement", 1); bool num = DragonbornBreath.TryExecute(player, ((Humanoid)player).GetCurrentWeapon()?.m_shared?.m_attack); PlayerDataStore.SetInt(player, "Ent1ty303.BreathElement", (int)breathElement); if (num) { _nextBreath = Time.time + 1f; } } } private static void TickStunAura(Player player) { //IL_000c: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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) //IL_0099: 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) List list = new List(); Character.GetCharactersInRange(((Component)player).transform.position, 6f, list); float time = Time.time; Vector3 centerPoint = ((Character)player).GetCenterPoint(); foreach (Character item in list) { if (!BreathTargetFilter.CanBreathDamage(player, item)) { continue; } long key = ((Object)item).GetInstanceID(); if (StunImmuneUntil.TryGetValue(key, out var value) && time < value) { continue; } Vector3 val = item.GetCenterPoint() - centerPoint; Vector3 val2 = ((Vector3)(ref val)).normalized; if (((Vector3)(ref val2)).sqrMagnitude < 0.001f) { val2 = Vector3.forward; } item.Stagger(val2); if (!NextBreakoutRoll.TryGetValue(key, out var value2) || time >= value2) { NextBreakoutRoll[key] = time + 1f; if (Random.value <= 0.2f) { StunImmuneUntil[key] = time + 30f; } } } } } internal static class TieflingBeams { public enum Mode { PoisonGreen, FrostBlue } private const float StaminaPerSecond = 12f; private const float TickInterval = 0.1f; private const float BeamRadius = 1.2f; private const float MaxDist = 2000f; private const float StackLingerSeconds = 1.25f; private static GameObject _root; private static LineRenderer _line; private static readonly Dictionary LastTick = new Dictionary(); private static readonly Dictionary DebuffStacks = new Dictionary(); private static readonly Dictionary StackExpireAt = new Dictionary(); private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[32]; public static int GetFrostWeakenStacks(Character character) { if ((Object)(object)character == (Object)null) { return 0; } PruneExpiredStacks(); long key = ((Object)character).GetInstanceID(); if (!DebuffStacks.TryGetValue(key, out var value)) { return 0; } return value; } public static void ApplyFrostWeakenToOutgoing(Character attacker, HitData hit) { int frostWeakenStacks = GetFrostWeakenStacks(attacker); if (frostWeakenStacks > 0 && hit != null) { float totalDamage = hit.GetTotalDamage(); if (!(totalDamage <= 0.01f)) { float num = Mathf.Max(0f, totalDamage - (float)frostWeakenStacks); ((DamageTypes)(ref hit.m_damage)).Modify(num / totalDamage); } } } public static void Tick(Player player, Mode mode) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { Hide(); return; } if (!DragonbornBreathInput.AreBreathButtonsHeld() || !DragonbornBreathInput.IsUnarmed(player)) { Hide(); return; } float num = 12f * Time.deltaTime; if (player.GetStamina() < num + 0.1f) { Hide(); return; } ((Character)player).UseStamina(num); DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; float num2 = 2000f; int num3 = Physics.RaycastNonAlloc(eyePoint, normalized, Hits, 2000f, -1, (QueryTriggerInteraction)1); for (int i = 0; i < num3; i++) { if (!((Object)(object)((RaycastHit)(ref Hits[i])).collider == (Object)null) && !((RaycastHit)(ref Hits[i])).collider.isTrigger && !((Object)(object)((Component)((RaycastHit)(ref Hits[i])).collider).GetComponentInParent() == (Object)(object)player)) { num2 = Mathf.Min(num2, ((RaycastHit)(ref Hits[i])).distance); } } DrawBeam(eyePoint + normalized * 0.85f, normalized, num2, mode); DamageAlongBeam(player, eyePoint, normalized, num2, mode); } private static void DamageAlongBeam(Player player, Vector3 origin, Vector3 dir, float length, Mode mode) { //IL_0021: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_01d0: Unknown result type (might be due to invalid IL or missing references) float poison = (45f + TrinketBonusRegistry.GetEquippedBonus(player).ElementDamage) * 0.1f; List list = new List(); Character.GetCharactersInRange(origin + dir * (length * 0.5f), Mathf.Max(8f, length * 0.5f), list); float time = Time.time; foreach (Character item in list) { if (!BreathTargetFilter.CanBreathDamage(player, item)) { continue; } Vector3 val = item.GetCenterPoint() - origin; float num = Vector3.Dot(val, dir); if (num < 0.5f || num > length) { continue; } Vector3 val2 = Vector3.Cross(dir, val); if (((Vector3)(ref val2)).magnitude > 1.2f + item.GetRadius()) { continue; } long key = ((Object)item).GetInstanceID(); if (LastTick.TryGetValue(key, out var value) && time - value < 0.1f) { continue; } LastTick[key] = time; HitData val3 = new HitData { m_skill = (SkillType)11, m_point = item.GetCenterPoint(), m_dir = dir, m_hitType = (HitType)2 }; val3.SetAttacker((Character)(object)player); if (mode == Mode.PoisonGreen) { val3.m_damage.m_poison = poison; BreathDamageApplicator.MarkBreathHit(val3); item.Damage(val3); continue; } SEMan sEMan = item.GetSEMan(); if (sEMan != null) { sEMan.AddStatusEffect(SEMan.s_statusEffectCold, true, 0, 0f); } SEMan sEMan2 = item.GetSEMan(); if (sEMan2 != null) { sEMan2.AddStatusEffect(SEMan.s_statusEffectFrost, true, 0, 0f); } if (!DebuffStacks.TryGetValue(key, out var value2)) { value2 = 0; } value2++; DebuffStacks[key] = value2; StackExpireAt[key] = time + 1.25f; FrostBeamWeakenText.ShowPurpleMinusOne(((Component)item).transform.position); } } private static void PruneExpiredStacks() { float time = Time.time; List list = new List(); foreach (KeyValuePair item in StackExpireAt) { if (time >= item.Value) { list.Add(item.Key); } } foreach (long item2 in list) { StackExpireAt.Remove(item2); DebuffStacks.Remove(item2); } } private static void DrawBeam(Vector3 start, Vector3 dir, float length, Mode mode) { //IL_0074: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) EnsureLine(); ((Renderer)_line).enabled = true; if (mode == Mode.PoisonGreen) { _line.startColor = new Color(0.35f, 1f, 0.25f, 0.95f); _line.endColor = new Color(0.1f, 0.55f, 0.1f, 0.2f); } else { _line.startColor = new Color(0.55f, 0.85f, 1f, 0.95f); _line.endColor = new Color(0.3f, 0.55f, 0.95f, 0.2f); } _line.startWidth = 0.55f; _line.endWidth = 0.55f; _line.numCapVertices = 4; _line.numCornerVertices = 2; _line.SetPosition(0, start); _line.SetPosition(1, start + dir * Mathf.Max(length, 0.5f)); } private static void EnsureLine() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown if (!((Object)(object)_line != (Object)null)) { _root = new GameObject("Ent1tyRaces_TieflingBeam"); Object.DontDestroyOnLoad((Object)(object)_root); _line = _root.AddComponent(); _line.useWorldSpace = true; _line.positionCount = 2; ((Renderer)_line).material = new Material(Shader.Find("Sprites/Default")); _line.textureMode = (LineTextureMode)0; _line.alignment = (LineAlignment)0; ((Renderer)_line).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_line).receiveShadows = false; ((Renderer)_line).enabled = false; } } private static void Hide() { if ((Object)(object)_line != (Object)null) { ((Renderer)_line).enabled = false; } } } internal static class TieflingChthonic { public static void Update(Player player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer) && TieflingLegacyManager.Is(player, TieflingLegacy.Chthonic) && TrinketGates.ChthonicBeam(player)) { TieflingBeams.Tick(player, TieflingBeams.Mode.FrostBlue); } } public static void ApplyFrostOnHit(Player attacker, Character target, HitData hit) { if ((Object)(object)attacker == (Object)null || hit == null || !TieflingLegacyManager.Is(attacker, TieflingLegacy.Chthonic)) { return; } hit.m_damage.m_frost += 12f; if ((Object)(object)target != (Object)null) { SEMan sEMan = target.GetSEMan(); if (sEMan != null) { sEMan.AddStatusEffect(SEMan.s_statusEffectFrost, true, 0, 0f); } SEMan sEMan2 = target.GetSEMan(); if (sEMan2 != null) { sEMan2.AddStatusEffect(SEMan.s_statusEffectCold, true, 0, 0f); } } } public static float GetBonusMaxHealth(Player player) { if (!TieflingLegacyManager.Is(player, TieflingLegacy.Chthonic)) { return 0f; } if (TrinketGates.ChthonicPlainsHp(player)) { return 100f; } if (TrinketGates.ChthonicMountainsHp(player)) { return 50f; } return 0f; } } internal static class TieflingInfernal { private enum ZoneKind { None, BasicFire, EmeraldFlame, Darkness } private const float AbilityDuration = 10f; private const float FlameDps = 25f; private const float DarkDpsMult = 1.5f; private const float CloudRadius = 10f; private const float BasicFlameRadius = 3.5f; private const float EmeraldFlameRadius = 3.5f; private static float _expireAt; private static Vector3 _center; private static ZoneKind _zone; private static GameObject _fxRoot; private static readonly List Scratch = new List(); private static bool _chordWasHeld; public static bool IsOwnFireActive { get { bool flag = Time.time < _expireAt; if (flag) { ZoneKind zone = _zone; bool flag2 = (uint)(zone - 1) <= 1u; flag = flag2; } return flag; } } public static bool IsInOwnFireZone(Vector3 point) { //IL_001e: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!IsOwnFireActive) { return false; } float num = ((_zone == ZoneKind.EmeraldFlame) ? 6f : 5f); Vector3 val = point - _center; return ((Vector3)(ref val)).sqrMagnitude <= num * num; } public static bool IsInDarknessCloud(Vector3 point) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //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) if (Time.time < _expireAt && _zone == ZoneKind.Darkness) { Vector3 val = point - _center; return ((Vector3)(ref val)).sqrMagnitude <= 100f; } return false; } public static bool BlocksVision(Vector3 from, Vector3 to) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (Time.time >= _expireAt || _zone != ZoneKind.Darkness) { return false; } if (IsInDarknessCloud(from) || IsInDarknessCloud(to)) { return true; } Vector3 val = _center - from; Vector3 val2 = to - from; Vector3 val3 = from + Vector3.Project(val, ((Vector3)(ref val2)).normalized); Vector3 val4 = val3 - from; val2 = to - from; float num = Vector3.Dot(val4, ((Vector3)(ref val2)).normalized); val2 = to - from; float magnitude = ((Vector3)(ref val2)).magnitude; if (num < 0f || num > magnitude) { return false; } val2 = val3 - _center; return ((Vector3)(ref val2)).sqrMagnitude <= 100f; } public static void Update(Player player) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !TieflingLegacyManager.Is(player, TieflingLegacy.Infernal)) { _chordWasHeld = false; return; } TickZone(player); if (IsInOwnFireZone(((Character)player).GetCenterPoint())) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectBurning, true); } } bool flag = DragonbornBreathInput.AreBreathButtonsHeld(); bool num = flag && !_chordWasHeld; _chordWasHeld = flag; if (num) { DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); if (TrinketGates.InfernalDarkness(player)) { SpawnDarkness(player); } else if (TrinketGates.InfernalFlame(player)) { SpawnEmeraldFlame(player); } else if (TrinketGates.InfernalBasicFire(player)) { SpawnBasicFire(player); } else { ((Character)player).Message((MessageType)2, "Need a trinket for higher Infernal powers.", 0, (Sprite)null); } } } private static void SpawnBasicFire(Player player) { //IL_000b: 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_002c: Unknown result type (might be due to invalid IL or missing references) if (TryAim(player, out var point)) { _center = point; _zone = ZoneKind.BasicFire; _expireAt = Time.time + 10f; ClearFx(); _fxRoot = SpawnBasicFireFx(point); ((Character)player).Message((MessageType)2, "Hellfire kindles.", 0, (Sprite)null); } } private static void SpawnEmeraldFlame(Player player) { //IL_000b: 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_002c: Unknown result type (might be due to invalid IL or missing references) if (TryAim(player, out var point)) { _center = point; _zone = ZoneKind.EmeraldFlame; _expireAt = Time.time + 10f; ClearFx(); _fxRoot = SpawnFaderFlameFx(point); ((Character)player).Message((MessageType)2, "The Emerald Flame blooms.", 0, (Sprite)null); } } private static void SpawnDarkness(Player player) { //IL_000b: 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_002c: Unknown result type (might be due to invalid IL or missing references) if (TryAim(player, out var point)) { _center = point; _zone = ZoneKind.Darkness; _expireAt = Time.time + 10f; ClearFx(); _fxRoot = SpawnDarknessFx(point); ((Character)player).Message((MessageType)2, "Darkness swallows the light.", 0, (Sprite)null); } } private static GameObject SpawnDarknessFx(Vector3 point) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0017: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0116: Expected O, but got Unknown GameObject val = new GameObject("Ent1tyRaces_DarkCloud"); val.transform.position = point; AddSmokeLayer(val, point, 9.5f, 90f, new MinMaxCurve(2.5f, 5.5f), new Color(0f, 0f, 0f, 0.92f), new Color(0.02f, 0.02f, 0.02f, 0.55f), 180); AddSmokeLayer(val, point, 7f, 55f, new MinMaxCurve(3.5f, 7f), new Color(0f, 0f, 0f, 0.75f), new Color(0.05f, 0.05f, 0.05f, 0.35f), 100); AddSmokeLayer(val, point, 4.5f, 30f, new MinMaxCurve(4f, 8f), new Color(0f, 0f, 0f, 0.95f), new Color(0f, 0f, 0f, 0.6f), 60); return val; } private static void AddSmokeLayer(GameObject root, Vector3 point, float radius, float rate, MinMaxCurve size, Color a, Color b, int maxParticles) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_00d3: 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_00e4: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("SmokeLayer"); val.transform.SetParent(root.transform, false); val.transform.position = point; ParticleSystem val2 = val.AddComponent(); MainModule main = val2.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(3.5f); ((MainModule)(ref main)).startSize = size; ((MainModule)(ref main)).startColor = new MinMaxGradient(a, b); ((MainModule)(ref main)).maxParticles = maxParticles; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.05f, 0.35f); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.05f); EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(rate); ShapeModule shape = val2.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = radius; ColorOverLifetimeModule colorOverLifetime = val2.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val3 = new Gradient(); val3.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(Color.black, 0f), new GradientColorKey(Color.black, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[4] { new GradientAlphaKey(0.15f, 0f), new GradientAlphaKey(0.9f, 0.25f), new GradientAlphaKey(0.7f, 0.7f), new GradientAlphaKey(0.05f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val3); SizeOverLifetimeModule sizeOverLifetime = val2.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, AnimationCurve.EaseInOut(0f, 0.6f, 1f, 1.4f)); ParticleSystemRenderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).material = new Material(Shader.Find("Particles/Standard Unlit") ?? Shader.Find("Legacy Shaders/Particles/Alpha Blended") ?? Shader.Find("Sprites/Default")); ((Renderer)component).material.color = Color.black; } } private static GameObject SpawnBasicFireFx(Vector3 point) { //IL_0000: 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) GameObject obj = GenasiFire.CreateGroundFireVisual(point, 3.5f); ((Object)obj).name = "Ent1tyRaces_BasicHellfire"; GenasiFire.SpawnBurstFxPublic(point); return obj; } private static void TickZone(Player player) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown if (Time.time >= _expireAt || _zone == ZoneKind.None) { ClearFx(); _zone = ZoneKind.None; return; } float num = ((_zone == ZoneKind.Darkness) ? 10f : ((_zone == ZoneKind.EmeraldFlame) ? 3.5f : 3.5f)); float num2 = 25f * ((_zone == ZoneKind.Darkness) ? 1.5f : 1f); if (_zone == ZoneKind.BasicFire) { num2 /= 3f; } float num3 = num2 * Time.deltaTime; Scratch.Clear(); Character.GetCharactersInRange(_center, num, Scratch); foreach (Character item in Scratch) { if ((Object)(object)item == (Object)null || (Object)(object)item == (Object)(object)player) { continue; } Player val = (Player)(object)((item is Player) ? item : null); if ((val == null || RaceManager.GetRace(val) != RaceType.Tiefling) && BreathTargetFilter.CanBreathDamage(player, item)) { HitData val2 = new HitData { m_point = item.GetCenterPoint(), m_dir = Vector3.up, m_hitType = (HitType)2 }; val2.SetAttacker((Character)(object)player); if (_zone == ZoneKind.Darkness) { val2.m_damage.m_damage = num3; } else { val2.m_damage.m_fire = num3; } BreathDamageApplicator.MarkBreathHit(val2); item.Damage(val2); } } } private static bool TryAim(Player player, out Vector3 point) { //IL_0007: 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_0012: 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) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_003c: 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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) point = ((Component)player).transform.position; Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 normalized = ((Vector3)(ref lookDir)).normalized; RaycastHit val = default(RaycastHit); if (Physics.Raycast(eyePoint, normalized, ref val, 25f, -1, (QueryTriggerInteraction)1)) { point = ((RaycastHit)(ref val)).point; return true; } point = eyePoint + normalized * 8f; if ((Object)(object)ZoneSystem.instance != (Object)null) { point.y = ZoneSystem.instance.GetGroundHeight(point); } return true; } private static GameObject SpawnFaderFlameFx(Vector3 point) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { return SpawnBasicFireFx(point); } string[] array = new string[9] { "fx_Fader_emeraldflame", "vfx_Fader_emeraldflame", "fx_fader_fire", "vfx_fader_fire", "fx_Fader_Fire", "vfx_Fader_Fire", "fx_emeraldflame", "vfx_emeraldflame", "fx_greenflame" }; foreach (string text in array) { GameObject prefab = ZNetScene.instance.GetPrefab(text); if ((Object)(object)prefab != (Object)null) { Logger.LogInfo((object)("Ent1tyRaces: Infernal using prefab '" + text + "'")); return Object.Instantiate(prefab, point, Quaternion.identity); } } try { Dictionary value = Traverse.Create((object)ZNetScene.instance).Field("m_namedPrefabs").GetValue>(); if (value != null) { foreach (KeyValuePair item in value) { if (!((Object)(object)item.Value == (Object)null)) { string name = ((Object)item.Value).name; string text2 = name.ToLowerInvariant(); if ((text2.Contains("fader") && (text2.Contains("fire") || text2.Contains("flame") || text2.Contains("emerald"))) || text2.Contains("emeraldflame") || text2.Contains("emerald_flame")) { Logger.LogInfo((object)("Ent1tyRaces: Infernal using scanned prefab '" + name + "'")); return Object.Instantiate(item.Value, point, Quaternion.identity); } } } } } catch { } Logger.LogWarning((object)"Ent1tyRaces: Fader emerald flame prefab not found — using green fallback."); GameObject val = new GameObject("Ent1tyRaces_EmeraldFlameFallback"); val.transform.position = point; ParticleSystem obj2 = val.AddComponent(); MainModule main = obj2.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.4f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.4f, 1.1f); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(0.2f, 1f, 0.35f, 0.95f), new Color(0.05f, 0.55f, 0.15f, 0.7f)); ((MainModule)(ref main)).maxParticles = 70; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.3f); EmissionModule emission = obj2.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(30f); ShapeModule shape = obj2.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)10; ((ShapeModule)(ref shape)).radius = 2.2f; return val; } private static void ClearFx() { if ((Object)(object)_fxRoot != (Object)null) { Object.Destroy((Object)(object)_fxRoot); _fxRoot = null; } } } public static class TieflingLegacyManager { private const string CustomKey = "Ent1ty303.TieflingLegacy"; public static TieflingLegacy GetLegacy(Player player) { if ((Object)(object)player == (Object)null) { return TieflingLegacy.Abyssal; } if (PlayerDataStore.TryGetInt(player, "Ent1ty303.TieflingLegacy", out var value) && Enum.IsDefined(typeof(TieflingLegacy), value)) { return (TieflingLegacy)value; } return TieflingLegacy.Abyssal; } public static bool TrySetLegacy(Player player, TieflingLegacy legacy, out string message) { message = null; if ((Object)(object)player == (Object)null) { message = "Load a character first."; return false; } if (RaceManager.GetRace(player) != RaceType.Tiefling) { message = "Only Tieflings can choose a legacy."; return false; } PlayerDataStore.SetInt(player, "Ent1ty303.TieflingLegacy", (int)legacy); message = legacy switch { TieflingLegacy.Abyssal => "Abyssal: poison bloodline. Trinkets unlock breath, beam, stun aura.", TieflingLegacy.Chthonic => "Chthonic: frost bloodline. Trinkets unlock HP and slow beam.", TieflingLegacy.Infernal => "Infernal: fire bloodline. R summons emerald flame / darkness.", _ => $"Legacy set to {legacy}.", }; if (((Character)player).IsOwner()) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } return true; } public static TieflingLegacy Parse(string value) { if (string.IsNullOrWhiteSpace(value)) { return TieflingLegacy.Abyssal; } switch (value.Trim().ToLowerInvariant()) { case "abyssal": case "abyss": case "poison": return TieflingLegacy.Abyssal; case "cthonic": case "frost": case "chthonic": case "underworld": return TieflingLegacy.Chthonic; case "infernal": case "fire": case "hell": return TieflingLegacy.Infernal; default: { TieflingLegacy result; return Enum.TryParse(value, ignoreCase: true, out result) ? result : TieflingLegacy.Abyssal; } } } public static bool Is(Player player, TieflingLegacy legacy) { if (RaceManager.GetRace(player) == RaceType.Tiefling) { return GetLegacy(player) == legacy; } return false; } } public enum TrinketTier { None, BlackForest, Swamp, Ocean, Mountains, Plains, Mistlands, Ashlands } public readonly struct TrinketBonus { public TrinketTier Tier { get; } public float ElementDamage { get; } public bool OceanArmor { get; } public bool MountainResShift { get; } public TrinketBonus(TrinketTier tier, float elementDamage, bool oceanArmor, bool mountainResShift) { Tier = tier; ElementDamage = elementDamage; OceanArmor = oceanArmor; MountainResShift = mountainResShift; } } public static class TrinketBonusRegistry { private static readonly Dictionary TrinketMap = new Dictionary { { "TrinketBronzeHealth", new TrinketBonus(TrinketTier.BlackForest, 30f, oceanArmor: false, mountainResShift: false) }, { "TrinketBronzeStamina", new TrinketBonus(TrinketTier.BlackForest, 30f, oceanArmor: false, mountainResShift: false) }, { "TrinketIronHealth", new TrinketBonus(TrinketTier.Swamp, 50f, oceanArmor: false, mountainResShift: false) }, { "TrinketIronStamina", new TrinketBonus(TrinketTier.Swamp, 50f, oceanArmor: false, mountainResShift: false) }, { "TrinketChitinSwim", new TrinketBonus(TrinketTier.Ocean, 100f, oceanArmor: true, mountainResShift: false) }, { "TrinketSilverDamage", new TrinketBonus(TrinketTier.Mountains, 90f, oceanArmor: false, mountainResShift: true) }, { "TrinketSilverResist", new TrinketBonus(TrinketTier.Mountains, 90f, oceanArmor: false, mountainResShift: true) }, { "TrinketBlackDamageHealth", new TrinketBonus(TrinketTier.Plains, 102f, oceanArmor: false, mountainResShift: false) }, { "TrinketBlackStamina", new TrinketBonus(TrinketTier.Plains, 102f, oceanArmor: false, mountainResShift: false) }, { "TrinketCarapaceEitr", new TrinketBonus(TrinketTier.Mistlands, 126f, oceanArmor: false, mountainResShift: false) }, { "TrinketScaleStaminaDamage", new TrinketBonus(TrinketTier.Mistlands, 126f, oceanArmor: false, mountainResShift: false) }, { "TrinketFlametalEitr", new TrinketBonus(TrinketTier.Ashlands, 170f, oceanArmor: false, mountainResShift: false) }, { "TrinketFlametalStaminaHealth", new TrinketBonus(TrinketTier.Ashlands, 170f, oceanArmor: false, mountainResShift: false) } }; public static TrinketBonus GetEquippedBonus(Player player) { ItemData equippedTrinket = GetEquippedTrinket(player); if (equippedTrinket == null) { return default(TrinketBonus); } string key = (((Object)(object)equippedTrinket.m_dropPrefab != (Object)null) ? ((Object)equippedTrinket.m_dropPrefab).name : NormalizeItemName(equippedTrinket.m_shared.m_name)); if (!TrinketMap.TryGetValue(key, out var value)) { return default(TrinketBonus); } return value; } public static ItemData GetEquippedTrinket(Player player) { if (((player != null) ? ((Humanoid)player).GetInventory() : null) == null) { return null; } return ((IEnumerable)((Humanoid)player).GetInventory().GetAllItems()).FirstOrDefault((Func)((ItemData item) => item != null && item.m_equipped && item.m_shared != null && (int)item.m_shared.m_itemType == 24)); } public static string GetEquippedTrinketDebugName(Player player) { ItemData equippedTrinket = GetEquippedTrinket(player); if (equippedTrinket != null) { return GetEquippedTrinketPrefabName(equippedTrinket); } return "(none)"; } private static string GetEquippedTrinketPrefabName(ItemData trinket) { if (!((Object)(object)trinket.m_dropPrefab != (Object)null)) { return trinket.m_shared.m_name; } return ((Object)trinket.m_dropPrefab).name; } private static string NormalizeItemName(string name) { if (string.IsNullOrEmpty(name)) { return string.Empty; } if (!name.StartsWith("$item_")) { return name.TrimStart(new char[1] { '$' }); } return name.Substring("$item_".Length); } } internal static class TrinketGates { public static TrinketTier Tier(Player player) { return TrinketBonusRegistry.GetEquippedBonus(player).Tier; } public static bool BlackForestToSwamp(Player player) { TrinketTier trinketTier = Tier(player); if ((uint)(trinketTier - 1) <= 2u) { return true; } return false; } public static bool MountainsToPlains(Player player) { TrinketTier trinketTier = Tier(player); if ((uint)(trinketTier - 4) <= 1u) { return true; } return false; } public static bool MistlandsPlus(Player player) { TrinketTier trinketTier = Tier(player); if ((uint)(trinketTier - 6) <= 1u) { return true; } return false; } public static bool AbyssalBreath(Player player) { return BlackForestToSwamp(player); } public static bool AbyssalBeam(Player player) { return MountainsToPlains(player); } public static bool AbyssalStun(Player player) { return MistlandsPlus(player); } public static bool ChthonicMountainsHp(Player player) { return Tier(player) == TrinketTier.Mountains; } public static bool ChthonicPlainsHp(Player player) { return Tier(player) == TrinketTier.Plains; } public static bool ChthonicBeam(Player player) { return MistlandsPlus(player); } public static bool InfernalBasicFire(Player player) { TrinketTier trinketTier = Tier(player); if ((uint)trinketTier <= 3u) { return true; } return false; } public static bool InfernalFlame(Player player) { return MountainsToPlains(player); } public static bool InfernalDarkness(Player player) { return MistlandsPlus(player); } } internal readonly struct PendingAttackCosts { public float Stamina { get; } public float Eitr { get; } public PendingAttackCosts(float stamina, float eitr) { Stamina = stamina; Eitr = eitr; } } internal static class VampireAttackTracker { private static readonly Dictionary PendingAttackCosts = new Dictionary(); public static void RecordAttackCosts(Player player, float staminaCost, float eitrCost) { if (!((Object)(object)player == (Object)null) && (!(staminaCost <= 0f) || !(eitrCost <= 0f))) { PendingAttackCosts[player.GetPlayerID()] = new PendingAttackCosts(staminaCost, eitrCost); } } public static PendingAttackCosts ConsumeAttackCosts(Player player) { if ((Object)(object)player == (Object)null) { return default(PendingAttackCosts); } long playerID = player.GetPlayerID(); if (!PendingAttackCosts.TryGetValue(playerID, out var value)) { return default(PendingAttackCosts); } PendingAttackCosts.Remove(playerID); return value; } } public static class VampireFood { public const float BloodPuddingHealth = 300f; public const float BloodPuddingStamina = 300f; public const float BloodPuddingEitr = 300f; public const float BloodPuddingDuration = 2400f; public const float ActiveFoodThreshold = 10f; public const float BloodTasteHeal = 20f; public const string BloodTasteMessage = "A taste of blood."; private const string BloodPuddingToken = "bloodpudding"; private const string BloodPuddingPrefab = "BloodPudding"; private static readonly string[] VampireMeadBloodTasteStatusNames = new string[5] { "Potion_frostresist", "Potion_health_medium", "Potion_health_minor", "Potion_health_major", "Potion_health_lingering" }; private static readonly string[] BloodTastePrefabNames = new string[6] { "BlackSoup", "FeastSwamps", "MeadHealthMedium", "MeadFrostResist", "MeadMediumHealth", "MeadMinorHealth" }; private static readonly string[] BloodTasteNameTokens = new string[7] { "blacksoup", "feastswamps", "mead_hp_medium", "mead_frostres", "mead_mediumhealth", "mead_minorhealth", "frostresist" }; public static bool IsBloodPudding(ItemData item) { if (item?.m_shared == null) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name.Equals("BloodPudding", StringComparison.OrdinalIgnoreCase)) { return true; } return (item.m_shared.m_name ?? string.Empty).IndexOf("bloodpudding", StringComparison.OrdinalIgnoreCase) >= 0; } public static bool IsBloodTasteItem(ItemData item) { if (item?.m_shared == null || IsBloodPudding(item)) { return false; } string[] bloodTastePrefabNames; if ((Object)(object)item.m_dropPrefab != (Object)null) { bloodTastePrefabNames = BloodTastePrefabNames; foreach (string value in bloodTastePrefabNames) { if (((Object)item.m_dropPrefab).name.Equals(value, StringComparison.OrdinalIgnoreCase)) { return true; } } } string text = (item.m_shared.m_name ?? string.Empty).ToLowerInvariant(); bloodTastePrefabNames = BloodTasteNameTokens; foreach (string value2 in bloodTastePrefabNames) { if (text.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } public static bool IsBloodTasteFood(Food food) { if (food == null || IsBloodPuddingFood(food)) { return false; } if (IsBloodTasteItem(food.m_item)) { return true; } string text = food.m_name ?? string.Empty; string[] bloodTasteNameTokens = BloodTasteNameTokens; foreach (string value in bloodTasteNameTokens) { if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } bloodTasteNameTokens = BloodTastePrefabNames; foreach (string value2 in bloodTasteNameTokens) { if (text.Equals(value2, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } public static bool IsBloodPuddingFood(Food food) { if (food == null) { return false; } if (IsBloodFoodName(food.m_name)) { return true; } return IsBloodPudding(food.m_item); } public static bool HasAnyBloodPuddingFood(Player player) { if (player?.m_foods == null) { return false; } foreach (Food food in player.m_foods) { if (IsBloodPuddingFood(food)) { return true; } } return false; } public static bool HasActiveBloodPudding(Player player) { return HasActiveBloodPudding(player, 10f); } public static bool HasActiveBloodPudding(Player player, float flashingThreshold) { if (player?.m_foods == null) { return false; } foreach (Food food in player.m_foods) { if (!(food.m_time <= flashingThreshold) && IsBloodPuddingFood(food)) { return true; } } return false; } public static bool HasActiveNonBloodFood(Player player, float flashingThreshold) { if (player?.m_foods == null) { return false; } foreach (Food food in player.m_foods) { if (!(food.m_time <= flashingThreshold) && !IsBloodPuddingFood(food)) { return true; } } return false; } public static void ShowBloodTasteMessage(Player player) { ((Character)player).Message((MessageType)2, "A taste of blood.", 0, (Sprite)null); } public static void ApplyBloodTasteMeadBonus(Player player) { ShowBloodTasteMessage(player); AddMeadBloodTasteMaxHealth(player); } public static float GetMeadMaxHealthBonus(Player player) { SEMan val = ((player != null) ? ((Character)player).GetSEMan() : null); if (val == null) { return 0f; } float num = 0f; string[] vampireMeadBloodTasteStatusNames = VampireMeadBloodTasteStatusNames; foreach (string text in vampireMeadBloodTasteStatusNames) { if (val.HaveStatusEffect(StringExtensionMethods.GetStableHashCode(text))) { num += 20f; } } return num; } private static void AddMeadBloodTasteMaxHealth(Player player) { if (!((Object)(object)player == (Object)null) && !(((Character)player).GetHealth() <= 0f) && !((Character)player).IsDead()) { ApplyVampireFoodMaxStats(player, flashBar: true); } } public static void ApplyVampireFoodMaxStats(Player player, bool flashBar = false) { if (!((Object)(object)player == (Object)null) && RaceManager.GetRace(player) == RaceType.Vampire && !HasAnyBloodPuddingFood(player)) { CalculateVampireFoodTotals(player, out var hp, out var stamina, out var eitr); player.SetMaxHealth(hp, flashBar); player.SetMaxStamina(stamina, flashBar); player.SetMaxEitr(eitr, flashBar); } } public static void CalculateVampireFoodTotals(Player player, out float hp, out float stamina, out float eitr) { hp = player.GetBaseFoodHP(); stamina = Traverse.Create((object)player).Field("m_baseStamina").GetValue(); eitr = 0f; if (player?.m_foods == null) { hp += GetMeadMaxHealthBonus(player); return; } foreach (Food food in player.m_foods) { if (IsBloodTasteFood(food)) { ApplyBloodTasteSlotStats(food); } hp += food.m_health; stamina += food.m_stamina; eitr += food.m_eitr; } hp += GetMeadMaxHealthBonus(player); } public static void ApplyBloodTasteFoodBonus(Player player) { ShowBloodTasteMessage(player); AddImmediateHealth(player); } public static bool TryCalculateFoodTotals(Player player, out float hp, out float stamina, out float eitr) { hp = player.GetBaseFoodHP(); stamina = Traverse.Create((object)player).Field("m_baseStamina").GetValue(); eitr = 0f; if (player?.m_foods == null || player.m_foods.Count == 0) { return false; } foreach (Food food in player.m_foods) { hp += GetFoodHealthContribution(food); stamina += food.m_stamina; eitr += food.m_eitr; } return true; } public static bool TryApplyBloodTasteFoodStats(Player player, out float hp, out float stamina, out float eitr) { hp = player.GetBaseFoodHP(); stamina = Traverse.Create((object)player).Field("m_baseStamina").GetValue(); eitr = 0f; bool result = false; if (player?.m_foods == null) { return false; } foreach (Food food in player.m_foods) { if (IsBloodTasteFood(food)) { result = true; ApplyBloodTasteSlotStats(food); } hp += food.m_health; stamina += food.m_stamina; eitr += food.m_eitr; } return result; } private static float GetFoodHealthContribution(Food food) { if (IsBloodTasteFood(food) && food.m_item?.m_shared != null) { float vanillaFoodStatFactor = GetVanillaFoodStatFactor(food); return food.m_item.m_shared.m_food * vanillaFoodStatFactor + 20f; } return food.m_health; } private static void ApplyBloodTasteSlotStats(Food food) { if (food?.m_item?.m_shared != null) { float vanillaFoodStatFactor = GetVanillaFoodStatFactor(food); food.m_health = food.m_item.m_shared.m_food * vanillaFoodStatFactor + 20f; } } private static float GetVanillaFoodStatFactor(Food food) { float foodBurnTime = food.m_item.m_shared.m_foodBurnTime; if (foodBurnTime <= 0f) { return 0f; } return Mathf.Pow(Mathf.Clamp01(food.m_time / foodBurnTime), 0.3f); } public static void ApplyVampireBloodPuddingBuff(Player player, ItemData item) { //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_003c: 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) //IL_004e: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown player.m_foods.Clear(); player.m_foods.Add(new Food { m_name = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : "$item_bloodpudding"), m_item = item, m_time = 2400f, m_health = 300f, m_stamina = 300f, m_eitr = 300f }); UpdateBloodPuddingFood(player, 0f, forceUpdate: true); } public static void UpdateBloodPuddingFood(Player player, float dt, bool forceUpdate) { Traverse val = Traverse.Create((object)player).Field("m_foodUpdateTimer"); float num = val.GetValue() + dt; if (num >= 1f || forceUpdate) { num -= 1f; for (int num2 = player.m_foods.Count - 1; num2 >= 0; num2--) { Food val2 = player.m_foods[num2]; if (IsBloodPuddingFood(val2)) { val2.m_time -= 1f; ApplyBloodPuddingSlotStats(val2); if (val2.m_time <= 0f) { ((Character)player).Message((MessageType)2, "$msg_food_done", 0, (Sprite)null); player.m_foods.RemoveAt(num2); } } } ApplyBloodPuddingMaxStats(player, forceUpdate); } val.SetValue((object)num); } private static void AddImmediateHealth(Player player) { if ((Object)(object)((Character)(player?)).m_nview == (Object)null || !((Character)player).m_nview.IsOwner()) { return; } float health = ((Character)player).GetHealth(); if (!(health <= 0f) && !((Character)player).IsDead()) { float num = Mathf.Min(health + 20f, ((Character)player).GetMaxHealth()); if (num > health + 0.01f) { ((Character)player).SetHealth(num); } } } private static void ApplyBloodPuddingSlotStats(Food food) { float foodStatFactor = GetFoodStatFactor(food.m_time); food.m_health = 300f * foodStatFactor; food.m_stamina = 300f * foodStatFactor; food.m_eitr = 300f * foodStatFactor; } private static void ApplyBloodPuddingMaxStats(Player player, bool flashBar) { float num = player.GetBaseFoodHP(); float num2 = Traverse.Create((object)player).Field("m_baseStamina").GetValue(); float num3 = 0f; foreach (Food food in player.m_foods) { num += food.m_health; num2 += food.m_stamina; num3 += food.m_eitr; } player.SetMaxHealth(num, flashBar); player.SetMaxStamina(num2, flashBar); player.SetMaxEitr(num3, flashBar); } private static float GetFoodStatFactor(float remainingTime) { return Mathf.Pow(Mathf.Clamp01(remainingTime / 2400f), 0.3f); } private static bool IsBloodFoodName(string foodName) { if (foodName != null) { return foodName.IndexOf("bloodpudding", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } } internal static class VampireSunbrella { private sealed class FakeArmState { public GameObject Pole; public readonly List<(Transform bone, Vector3 scale)> HiddenBones = new List<(Transform, Vector3)>(); } public const bool UseFakeShoulderArm = false; private static readonly HashSet ActivePlayers = new HashSet(); private static readonly Dictionary FakeArms = new Dictionary(); private static readonly FieldInfo LeftItemInstanceField = AccessTools.Field(typeof(VisEquipment), "m_leftItemInstance"); private static readonly FieldInfo CurrentLeftItemHashField = AccessTools.Field(typeof(VisEquipment), "m_currentLeftItemHash"); private static readonly FieldInfo CurrentLeftItemVariantField = AccessTools.Field(typeof(VisEquipment), "m_currentLeftItemVariant"); private static readonly MethodInfo SetupVisEquipmentMethod = AccessTools.Method(typeof(Humanoid), "SetupVisEquipment", new Type[2] { typeof(VisEquipment), typeof(bool) }, (Type[])null); public static bool IsActive(Player player) { if ((Object)(object)player != (Object)null) { return ActivePlayers.Contains(player); } return false; } public static bool HasShieldEquipped(Player player) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 if ((Object)(object)player == (Object)null) { return false; } ItemData leftItem = ((Humanoid)player).GetLeftItem(); if (leftItem?.m_shared != null && (int)leftItem.m_shared.m_itemType == 5) { return true; } ItemData currentBlocker = ((Humanoid)player).GetCurrentBlocker(); if (currentBlocker?.m_shared != null) { return (int)currentBlocker.m_shared.m_itemType == 5; } return false; } public static void Toggle(Player player) { if (!((Object)(object)player == (Object)null) && RaceManager.GetRace(player) == RaceType.Vampire) { if (IsActive(player)) { Disable(player, "You lower your sunbrella."); return; } if (!HasShieldEquipped(player)) { ((Character)player).Message((MessageType)2, "Need a shield to block the sun.", 0, (Sprite)null); return; } ActivePlayers.Add(player); DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); ((Character)player).Message((MessageType)2, "Sunbrella raised. Blocking disabled.", 0, (Sprite)null); } } public static void Disable(Player player, string message = null) { if (!((Object)(object)player == (Object)null) && ActivePlayers.Remove(player)) { TearDownFakeArm(player); RestoreShieldVisual(player); if (!string.IsNullOrEmpty(message)) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null); } } } public static void Update(Player player) { if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Vampire) { if ((Object)(object)player != (Object)null && ActivePlayers.Remove(player)) { TearDownFakeArm(player); RestoreShieldVisual(player); } return; } if (ZInput.GetKeyDown((KeyCode)308, true) || ZInput.GetKeyDown((KeyCode)307, true)) { Toggle(player); } if (IsActive(player)) { if (!HasShieldEquipped(player)) { Disable(player, "Sunbrella dropped — no shield."); } else { DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); } } } public static void LateUpdateVisual(Player player) { if (!((Object)(object)player == (Object)null) && IsActive(player) && HasShieldEquipped(player)) { ApplyLegacyOverheadShieldVisual(player); } } private static void ApplyLegacyOverheadShieldVisual(Player player) { //IL_006f: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) VisEquipment component = ((Component)player).GetComponent(); if ((Object)(object)component == (Object)null) { return; } object? obj = LeftItemInstanceField?.GetValue(component); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)val == (Object)null)) { if ((Object)(object)val.transform.parent != (Object)null) { val.transform.SetParent((Transform)null, true); } Vector3 position = (((Object)(object)component.m_helmet != (Object)null) ? component.m_helmet : ((Component)player).transform).position + Vector3.up * 0.08f; Quaternion rotation = ((Component)player).transform.rotation * Quaternion.Euler(180f, 0f, 0f); val.transform.position = position; val.transform.rotation = rotation; } } private static void EnsureFakeArm(Player player) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) if (FakeArms.ContainsKey(player)) { return; } CharacterAnimEvent componentInChildren = ((Component)player).GetComponentInChildren(); if ((Object)(object)(((Object)(object)componentInChildren != (Object)null) ? componentInChildren.m_leftShoulder : null) == (Object)null) { VisEquipment component = ((Component)player).GetComponent(); if (!((Object)(object)component != (Object)null) || !((Object)(object)component.m_leftHand != (Object)null)) { _ = ((Component)player).transform; } else { _ = component.m_leftHand; } } FakeArmState fakeArmState = new FakeArmState(); HideLeftArmBones(player, fakeArmState); GameObject val = GameObject.CreatePrimitive((PrimitiveType)2); Object.Destroy((Object)(object)val.GetComponent()); ((Object)val).name = "Ent1tyRaces_SunbrellaArm"; MeshRenderer component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).material = new Material(Shader.Find("Standard") ?? Shader.Find("Diffuse")); Color color = default(Color); ((Color)(ref color))..ctor(0.72f, 0.55f, 0.42f, 1f); ((Renderer)component2).material.color = color; } fakeArmState.Pole = val; FakeArms[player] = fakeArmState; } private static void HideLeftArmBones(Player player, FakeArmState state) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)player).transform.Find("Visual") ?? ((Component)player).transform; string[] array = new string[9] { "LeftArm", "LeftForeArm", "LeftHand", "Left_Arm", "Left_ForeArm", "Left_Hand", "l_arm", "l_forearm", "l_hand" }; Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Transform val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null) { continue; } string name = ((Object)val2).name; bool flag = false; string[] array2 = array; foreach (string value in array2) { if (name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; break; } } if (flag) { state.HiddenBones.Add((val2, val2.localScale)); val2.localScale = Vector3.zero; } } } private static void ApplyFakeArmVisual(Player player) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00d3: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) EnsureFakeArm(player); if (!FakeArms.TryGetValue(player, out var value) || (Object)(object)value.Pole == (Object)null) { ApplyLegacyOverheadShieldVisual(player); return; } CharacterAnimEvent componentInChildren = ((Component)player).GetComponentInChildren(); Transform obj = (((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_leftShoulder != (Object)null) ? componentInChildren.m_leftShoulder : ((Component)player).transform); VisEquipment component = ((Component)player).GetComponent(); object? obj2 = LeftItemInstanceField?.GetValue(component); GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); Vector3 val2 = obj.position + Vector3.up * (0.55f * ((Component)player).transform.localScale.y); if ((Object)(object)component != (Object)null && (Object)(object)component.m_helmet != (Object)null) { val2 = component.m_helmet.position + Vector3.up * 0.08f; } Vector3 position = obj.position; Vector3 position2 = (position + val2) * 0.5f; float num = Mathf.Max(0.15f, Vector3.Distance(position, val2)); value.Pole.transform.position = position2; Transform transform = value.Pole.transform; Vector3 val3 = val2 - position; transform.up = ((Vector3)(ref val3)).normalized; value.Pole.transform.localScale = new Vector3(0.045f, num * 0.5f, 0.045f); if ((Object)(object)val != (Object)null) { if ((Object)(object)val.transform.parent != (Object)null) { val.transform.SetParent((Transform)null, true); } val.transform.position = val2; val.transform.rotation = ((Component)player).transform.rotation * Quaternion.Euler(180f, 0f, 0f); } } private static void TearDownFakeArm(Player player) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (!FakeArms.TryGetValue(player, out var value)) { return; } foreach (var (val, localScale) in value.HiddenBones) { if ((Object)(object)val != (Object)null) { val.localScale = localScale; } } if ((Object)(object)value.Pole != (Object)null) { Object.Destroy((Object)(object)value.Pole); } FakeArms.Remove(player); } private static void RestoreShieldVisual(Player player) { VisEquipment component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null)) { CurrentLeftItemHashField?.SetValue(component, 0); CurrentLeftItemVariantField?.SetValue(component, -1); if (SetupVisEquipmentMethod != null) { SetupVisEquipmentMethod.Invoke(player, new object[2] { component, false }); } } } } internal static class VampireSunlight { private const float FireTickInterval = 0.5f; private const float FireTickDamage = 0.8f; private const int SunGraceDays = 5; private static float _nextFireTick; public static bool IsInSunGracePeriod() { if ((Object)(object)EnvMan.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return true; } return EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds()) < 5; } public static bool IsShelteredFromSun(Player player) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_003e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return true; } if (VampireSunbrella.IsActive(player)) { return true; } if (player.InShelter()) { return true; } return Physics.Raycast(((Component)player).transform.position + Vector3.up * 0.2f, Vector3.up, 20f, LayerMask.GetMask(new string[3] { "Default", "static_solid", "piece" })); } public static void Update(Player player) { if ((Object)(object)player == (Object)null || !((Character)player).IsOwner() || RaceManager.GetRace(player) != RaceType.Vampire) { return; } if (VampireSunbrella.IsActive(player)) { SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectWet, true); } } if (EnvMan.IsDay() && !IsInSunGracePeriod() && !IsShelteredFromSun(player)) { float time = Time.time; if (!(time < _nextFireTick)) { _nextFireTick = time + 0.5f; Ignite(player); } } } private static void Ignite(Player player) { //IL_001e: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown SEMan sEMan = ((Character)player).GetSEMan(); if (sEMan != null) { sEMan.AddStatusEffect(SEMan.s_statusEffectBurning, true, 0, 0f); } HitData val = new HitData { m_damage = { m_fire = 0.8f }, m_point = ((Character)player).GetCenterPoint(), m_dir = Vector3.up, m_hitType = (HitType)5, m_blockable = false, m_dodgeable = false }; ((Character)player).Damage(val); if (Time.frameCount % 60 == 0) { ((Character)player).Message((MessageType)1, "The sun burns your flesh!", 0, (Sprite)null); } } } internal static class VampireVision { private static readonly int AmbientColorShaderId = Shader.PropertyToID("_AmbientColor"); public static void ApplyMiddayVision(EnvSetup env) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0071: Unknown result type (might be due to invalid IL or missing references) if (env != null && !((Object)(object)EnvMan.instance == (Object)null)) { RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientLight = env.m_ambColorDay; Shader.SetGlobalColor(AmbientColorShaderId, env.m_ambColorDay); RenderSettings.fogColor = env.m_fogColorDay; RenderSettings.fogDensity = env.m_fogDensityDay * 0.5f; Light dirLight = EnvMan.instance.m_dirLight; if (!((Object)(object)dirLight == (Object)null)) { dirLight.intensity = env.m_lightIntensityDay; dirLight.color = env.m_sunColorDay; } } } public static void ApplyRedNightVision(EnvSetup env) { //IL_0018: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) ApplyMiddayVision(env); if (env != null && !((Object)(object)EnvMan.instance == (Object)null)) { Color val = (RenderSettings.ambientLight = Color.Lerp(env.m_ambColorDay, new Color(1f, 0.28f, 0.22f), 0.55f)); Shader.SetGlobalColor(AmbientColorShaderId, val); RenderSettings.fogColor = Color.Lerp(env.m_fogColorDay, new Color(0.85f, 0.25f, 0.18f), 0.45f); Light dirLight = EnvMan.instance.m_dirLight; if ((Object)(object)dirLight != (Object)null) { dirLight.color = Color.Lerp(env.m_sunColorDay, new Color(1f, 0.4f, 0.28f), 0.5f); } } } } internal static class VampireVisionState { internal static EnvSetup LastEnv; internal static float LastDayInt; internal static float LastNightInt; } internal static class WoodElfTrees { private static readonly Collider[] OverlapBuffer = (Collider[])(object)new Collider[192]; public static bool IsNearTree(Player player, float radius) { //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_001b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } int num = Physics.OverlapSphereNonAlloc(((Component)player).transform.position + Vector3.up, radius, OverlapBuffer, -1, (QueryTriggerInteraction)2); for (int i = 0; i < num; i++) { Collider val = OverlapBuffer[i]; if ((Object)(object)val == (Object)null) { continue; } if (!((Object)(object)((Component)val).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null)) { Destructible componentInParent = ((Component)val).GetComponentInParent(); if (componentInParent == null || !IsTreeName(((Object)componentInParent).name)) { Transform root = ((Component)val).transform.root; if (IsTreeName(((Object)(object)root != (Object)null) ? ((Object)root).name : ((Object)val).name)) { return true; } continue; } } return true; } return false; } private static bool IsTreeName(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLowerInvariant(); if (!text.Contains("tree") && !text.Contains("beech") && !text.Contains("oak") && !text.Contains("birch") && !text.Contains("pine") && !text.Contains("fir") && !text.Contains("asp") && !text.Contains("ygg") && !text.Contains("bush") && !text.Contains("shrub") && !text.Contains("stump") && !text.Contains("log") && !text.Contains("root") && !text.Contains("branch") && !text.Contains("stubbe")) { return text.Contains("vegetation"); } return true; } } } namespace Ent1tyRaces.Patches { [HarmonyPatch(typeof(Player), "Update")] public static class AarakocraFlightInputPatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(__instance) == RaceType.Aarakocra) { if (ZInput.GetKeyDown((KeyCode)122, true)) { AarakocraFlight.Toggle(__instance); } AarakocraTalons.Update(__instance); AarakocraTalonVisuals.Update(__instance); AarakocraFlight.Update(__instance); } } } [HarmonyPatch(typeof(Character), "UpdateMotion")] public static class AarakocraFlightMotionPatch { private static bool Prefix(Character __instance, float dt) { return !AarakocraFlight.TryHandleMotion(__instance, dt); } } [HarmonyPatch(typeof(Player), "ToggleDebugFly")] public static class AarakocraBlockDebugFlyPatch { private static bool Prefix(Player __instance) { if (RaceManager.GetRace(__instance) != RaceType.Aarakocra) { return true; } AarakocraFlight.Toggle(__instance); return false; } } [HarmonyPatch(typeof(FejdStartup), "OnCharacterNew")] public static class FejdOnCharacterNewRacePatch { private static void Postfix() { CharacterCreateRaceUI.ShowForCreation(); } } [HarmonyPatch(typeof(FejdStartup), "OnNewCharacterDone")] public static class FejdOnNewCharacterDoneRacePatch { private static void Prefix(FejdStartup __instance) { CharacterCreateRaceUI.ApplyPendingToPreview(__instance.GetPreviewPlayer()); } private static void Postfix() { CharacterCreateRaceUI.LockAndPersistIfNeeded(); } } [HarmonyPatch(typeof(FejdStartup), "OnNewCharacterCancel")] public static class FejdOnNewCharacterCancelRacePatch { private static void Postfix() { CharacterCreateRaceUI.Hide(); } } [HarmonyPatch(typeof(FejdStartup), "ShowCharacterSelection")] public static class FejdShowCharacterSelectionHideRaceCreatePatch { private static void Postfix() { CharacterCreateRaceUI.Hide(); } } [HarmonyPatch(typeof(FejdStartup), "OnSelelectCharacterBack")] public static class FejdLeaveCharacterScreenRaceCreatePatch { private static void Postfix() { CharacterCreateRaceUI.Hide(); } } [HarmonyPatch(typeof(Character), "RPC_Damage")] public static class RaceRpcDamagePatches { private static void Prefix(Character __instance, HitData hit, ref float __state) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) __state = (((Object)(object)__instance != (Object)null) ? __instance.GetHealth() : 0f); if (hit == null || (Object)(object)__instance == (Object)null) { return; } TieflingBeams.ApplyFrostWeakenToOutgoing(hit.GetAttacker(), hit); Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { RaceType race = RaceManager.GetRace(val); if (race == RaceType.Vampire || ElfTypeManager.IsDrow(val)) { hit.m_damage.m_frost = 0f; } if (race == RaceType.Vampire) { hit.m_damage.m_fire *= 2f; } if (GenasiTypeManager.Is(val, GenasiType.Fire)) { hit.m_damage.m_fire *= 0.5f; } if (GenasiTypeManager.Is(val, GenasiType.Water) || race == RaceType.Dwarf || TieflingLegacyManager.Is(val, TieflingLegacy.Abyssal)) { hit.m_damage.m_poison *= 0.5f; } if (TieflingLegacyManager.Is(val, TieflingLegacy.Chthonic) || race == RaceType.Aasimar) { hit.m_damage.m_frost *= 0.5f; } if (TieflingLegacyManager.Is(val, TieflingLegacy.Infernal)) { if ((object)hit.GetAttacker() == val || TieflingInfernal.IsInOwnFireZone(((Character)val).GetCenterPoint())) { hit.m_damage.m_fire = 0f; } else { hit.m_damage.m_fire *= 0.5f; } } else if (race == RaceType.Aasimar) { hit.m_damage.m_fire *= 0.5f; } GenasiWaterWet.ApplyIncomingResists(val, hit); GiantCombat.ApplyIncomingMitigation(val, hit); } Character attacker = hit.GetAttacker(); Player val2 = (Player)(object)((attacker is Player) ? attacker : null); if (val2 != null) { RaceType race2 = RaceManager.GetRace(val2); if (race2 == RaceType.Vampire) { hit.m_damage.m_pierce += 20f; } ApplyElfCombatBonuses(val2, hit); GiantCombat.ApplyOutgoingBonuses(val2, __instance, hit); AarakocraTalons.ApplyUnarmedBonus(val2, hit); TieflingChthonic.ApplyFrostOnHit(val2, __instance, hit); HalflingBody.ApplyCrit(val2, hit); if (GenasiTypeManager.Is(val2, GenasiType.Earth)) { HitDamageUtil.ModifyAll(hit, 1.25f); } if (GnomeRock.HasEmpowerBuff(val2)) { HitDamageUtil.ModifyAll(hit, 2f); } if (race2 != RaceType.Human) { HitDamageUtil.ModifyAll(hit, 0.75f); } } } private static void Postfix(Character __instance, HitData hit, float __state) { if (hit == null || (Object)(object)__instance == (Object)null) { return; } float num = __state - __instance.GetHealth(); Character attacker = hit.GetAttacker(); Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && num > 0f) { GiantCombat.TryStormThorns(val, attacker, num); } Player val2 = (Player)(object)((attacker is Player) ? attacker : null); if (val2 != null) { GiantCombat.TryApplyFrostSlow(val2, __instance); if (ElfTypeManager.IsDrow(val2) && num > 0f) { DrowShadowArmor.TriggerOnHit(val2); } DwarfCrater.TryOnHit(val2, __instance); } Player val3 = (Player)(object)((attacker is Player) ? attacker : null); if (val3 != null && RaceManager.GetRace(val3) == RaceType.Vampire && !(num <= 0f)) { ((Character)val3).Heal(num, true); PendingAttackCosts pendingAttackCosts = VampireAttackTracker.ConsumeAttackCosts(val3); ((Character)val3).AddStamina(num + pendingAttackCosts.Stamina); ((Character)val3).AddEitr(num + pendingAttackCosts.Eitr); } } private static void ApplyElfCombatBonuses(Player player, HitData hit) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 if (ElfTypeManager.IsHighElf(player)) { hit.m_damage.m_fire *= 2f; hit.m_damage.m_frost *= 2f; hit.m_damage.m_lightning *= 2f; hit.m_damage.m_poison *= 2f; hit.m_damage.m_spirit *= 2f; } if (ElfTypeManager.IsWoodElf(player) && ((int)hit.m_skill == 8 || (int)hit.m_skill == 14)) { HitDamageUtil.ModifyAll(hit, 2f); } if (!ElfTypeManager.IsDrow(player)) { return; } if ((int)hit.m_skill == 2) { HitDamageUtil.ModifyAll(hit, 2f); } if (EnvMan.IsNight()) { hit.m_damage.m_slash *= 2f; hit.m_damage.m_pierce *= 2f; if (hit.m_backstabBonus > 1f) { hit.m_backstabBonus *= 11f; } } } } [HarmonyPatch] public static class DragonbornBreathPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Humanoid), "StartAttack", new Type[2] { typeof(Character), typeof(bool) }, (Type[])null); } private static bool Prefix(Humanoid __instance, ref bool __result, Character target, bool secondaryAttack) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (RaceManager.GetRace(val) != RaceType.Dragonborn) { return true; } if (secondaryAttack || !DragonbornBreathInput.AreBreathButtonsHeld()) { return true; } DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)val); DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)val); Attack attack = ((Humanoid)val).GetCurrentWeapon()?.m_shared?.m_attack; if (!DragonbornBreath.TryExecute(val, attack)) { __result = false; return false; } __result = true; return false; } } [HarmonyPatch(typeof(Player), "Update")] public static class DragonbornBreathInputPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || (RaceManager.GetRace(__instance) != RaceType.Dragonborn && !ElfTypeManager.IsHighElf(__instance))) { return; } if (!DragonbornBreathInput.ShouldSuppressTowerShieldBlock(__instance)) { DragonbornBreathCombat.RefreshTowerShieldBlockVisual(__instance); return; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)__instance); if (DragonbornBreathInput.IsAttackPressed()) { DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)__instance); } } } [HarmonyPatch] public static class DragonbornTowerShieldBlockPatch { private static IEnumerable TargetMethods() { MethodInfo playerBlock = AccessTools.Method(typeof(Player), "UpdateBlock", (Type[])null, (Type[])null); MethodInfo humanoidBlock = AccessTools.Method(typeof(Humanoid), "UpdateBlock", (Type[])null, (Type[])null); if (playerBlock != null) { yield return playerBlock; } if (humanoidBlock != null && humanoidBlock != playerBlock) { yield return humanoidBlock; } } private static bool Prefix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (!DragonbornBreathInput.ShouldSuppressTowerShieldBlock(val)) { return true; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)val); return false; } } [HarmonyPatch] public static class DragonbornTowerShieldIsBlockingPatch { private static IEnumerable TargetMethods() { MethodInfo playerBlocking = AccessTools.Method(typeof(Player), "IsBlocking", (Type[])null, (Type[])null); MethodInfo humanoidBlocking = AccessTools.Method(typeof(Humanoid), "IsBlocking", (Type[])null, (Type[])null); if (playerBlocking != null) { yield return playerBlocking; } if (humanoidBlocking != null && humanoidBlocking != playerBlocking) { yield return humanoidBlocking; } } private static void Postfix(Humanoid __instance, ref bool __result) { if (__result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && DragonbornBreathInput.ShouldSuppressTowerShieldBlock(val)) { __result = false; } } } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] public static class DragonbornOceanArmorPatch { private const float DragonbornBaseArmor = 20f; private static void Postfix(Player __instance, ref float __result) { if (RaceManager.GetRace(__instance) == RaceType.Dragonborn) { __result += 20f; } __result += DragonbornBreath.GetOceanArmorBonus(__instance); } } [HarmonyPatch(typeof(Player), "OnSpawned", new Type[] { typeof(bool) })] public static class PlayerRaceRestorePatch { private static void Postfix(Player __instance, bool spawnValkyrie) { if (!((Object)(object)__instance == (Object)null) && ((Character)__instance).IsOwner()) { RaceManager.SyncFromCustomData(__instance); } } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] public static class DwarfArmorPatch { private static void Postfix(Player __instance, ref float __result) { if (RaceManager.GetRace(__instance) == RaceType.Dwarf) { __result = Mathf.Round(__result * 1.2f); } } } [HarmonyPatch(typeof(SEMan), "ModifyHomeItemStaminaUsage")] public static class DwarfHomeItemStaminaPatch { private static void Postfix(SEMan __instance, ref float staminaUse) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null) { if (RaceManager.GetRace(val) == RaceType.Dwarf && (DwarfTools.IsHoe(((Humanoid)val).GetRightItem()) || DwarfTools.IsHammer(((Humanoid)val).GetRightItem()) || DwarfTools.IsCultivator(((Humanoid)val).GetRightItem()))) { staminaUse = 0f; } if (GnomeTypeManager.Is(val, GnomeType.Rock) && DwarfTools.IsHammer(((Humanoid)val).GetRightItem())) { staminaUse = 0f; } } } } [HarmonyPatch] public static class DwarfRequirementAmountPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Requirement), "GetAmount", (Type[])null, (Type[])null); } private static void Postfix(ref int __result) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && RaceManager.GetRace(localPlayer) == RaceType.Dwarf && __result > 0) { __result = DwarfBuiltRefund.HalveCost(__result); } } } [HarmonyPatch(typeof(Piece), "SetCreator")] public static class DwarfBuiltMarkPatch { private static void Postfix(Piece __instance, long uid) { DwarfBuiltRefund.TryMarkOnSetCreator(__instance, uid); } } [HarmonyPatch(typeof(Piece), "DropResources")] public static class DwarfBuiltDropResourcesPatch { private static void Prefix(Piece __instance) { if (DwarfBuiltRefund.IsDwarfBuilt(__instance)) { DwarfRefundDropState.Begin(__instance); } } private static void Finalizer(Piece __instance) { DwarfRefundDropState.End(__instance); } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] public static class DwarfPieceRequirementsPatch { private static void Prefix(Player __instance, Piece piece) { if (RaceManager.GetRace(__instance) == RaceType.Dwarf && piece?.m_resources != null) { DwarfCostState.Begin(piece); } } private static void Finalizer(Player __instance, Piece piece) { DwarfCostState.End(piece); } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] public static class DwarfWorkbenchBypassPatch { private static bool Prefix(Player __instance, Piece piece, RequirementMode mode, ref bool __result) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 if (RaceManager.GetRace(__instance) != RaceType.Dwarf) { return true; } if (!DwarfTools.IsHoe(((Humanoid)__instance).GetRightItem()) && !DwarfTools.IsHammer(((Humanoid)__instance).GetRightItem()) && !DwarfTools.IsCultivator(((Humanoid)__instance).GetRightItem())) { return true; } if ((Object)(object)piece?.m_craftingStation != (Object)null && (int)mode != 1) { DwarfWorkbenchState.Begin(piece); } return true; } private static void Finalizer(Piece piece) { DwarfWorkbenchState.End(piece); } } [HarmonyPatch] public static class DwarfPoisonDurationPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(SE_Poison), "AddDamage", (Type[])null, (Type[])null); } private static void Postfix(StatusEffect __instance) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && RaceManager.GetRace(val) == RaceType.Dwarf) { __instance.m_time += 2f; } } } [HarmonyPatch(typeof(CharacterAnimEvent), "Speed")] public static class DwarfToolSpeedPatch { private static void Prefix(CharacterAnimEvent __instance, ref float speedScale) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 //IL_0071: 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_0076: Invalid comparison between Unknown and I4 Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && RaceManager.GetRace(val) == RaceType.Dwarf && ((Character)val).InAttack()) { SkillType valueOrDefault = (((Humanoid)val).GetCurrentWeapon()?.m_shared?.m_skillType).GetValueOrDefault(); if (((int)valueOrDefault == 7 || valueOrDefault - 12 <= 1) ? true : false) { speedScale *= 1.5f; } } } } internal static class DwarfCostState { private static Piece _piece; private static int[] _saved; public static void Begin(Piece piece) { if (piece?.m_resources == null || (Object)(object)_piece != (Object)null) { return; } _piece = piece; _saved = new int[piece.m_resources.Length]; for (int i = 0; i < piece.m_resources.Length; i++) { _saved[i] = piece.m_resources[i].m_amount; if (piece.m_resources[i].m_amount > 0) { piece.m_resources[i].m_amount = DwarfBuiltRefund.HalveCost(piece.m_resources[i].m_amount); } } } public static void End(Piece piece) { if (!((Object)(object)_piece == (Object)null) && !((Object)(object)piece != (Object)(object)_piece) && _saved != null) { for (int i = 0; i < _piece.m_resources.Length && i < _saved.Length; i++) { _piece.m_resources[i].m_amount = _saved[i]; } _piece = null; _saved = null; } } } internal static class DwarfRefundDropState { private static Piece _piece; private static int[] _saved; public static void Begin(Piece piece) { if (piece?.m_resources == null || (Object)(object)_piece != (Object)null) { return; } _piece = piece; _saved = new int[piece.m_resources.Length]; for (int i = 0; i < piece.m_resources.Length; i++) { _saved[i] = piece.m_resources[i].m_amount; if (piece.m_resources[i].m_amount > 0 && piece.m_resources[i].m_recover) { piece.m_resources[i].m_amount = DwarfBuiltRefund.HalveCost(piece.m_resources[i].m_amount); } } } public static void End(Piece piece) { if (!((Object)(object)_piece == (Object)null) && !((Object)(object)piece != (Object)(object)_piece) && _saved != null) { for (int i = 0; i < _piece.m_resources.Length && i < _saved.Length; i++) { _piece.m_resources[i].m_amount = _saved[i]; } _piece = null; _saved = null; } } } internal static class DwarfWorkbenchState { private static Piece _piece; private static CraftingStation _saved; public static void Begin(Piece piece) { if (!((Object)(object)piece == (Object)null) && !((Object)(object)_piece != (Object)null)) { _piece = piece; _saved = piece.m_craftingStation; piece.m_craftingStation = null; } } public static void End(Piece piece) { if (!((Object)(object)_piece == (Object)null) && !((Object)(object)piece != (Object)(object)_piece)) { _piece.m_craftingStation = _saved; _piece = null; _saved = null; } } } internal static class DwarfTools { public static bool IsBuildTool(ItemData item) { if (!IsHoe(item) && !IsHammer(item)) { return IsCultivator(item); } return true; } public static bool IsHammer(ItemData item) { if (item?.m_shared == null) { return false; } return (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : (item.m_shared.m_name ?? "")).IndexOf("hammer", StringComparison.OrdinalIgnoreCase) >= 0; } public static bool IsCultivator(ItemData item) { if (item?.m_shared == null) { return false; } return (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : (item.m_shared.m_name ?? "")).IndexOf("Cultivator", StringComparison.OrdinalIgnoreCase) >= 0; } public static bool IsHoe(ItemData item) { if (item?.m_shared == null) { return false; } return (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : (item.m_shared.m_name ?? "")).IndexOf("Hoe", StringComparison.OrdinalIgnoreCase) >= 0; } } [HarmonyPatch] public static class HighElfLightBeamPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Humanoid), "StartAttack", new Type[2] { typeof(Character), typeof(bool) }, (Type[])null); } private static bool Prefix(Humanoid __instance, ref bool __result, bool secondaryAttack) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (!ElfTypeManager.IsHighElf(val)) { return true; } if (secondaryAttack || !DragonbornBreathInput.IsUnarmed(val)) { return true; } if (!DragonbornBreathInput.AreBreathButtonsHeld()) { return true; } DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)val); DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)val); __result = false; return false; } } [HarmonyPatch(typeof(Player), "Update")] public static class HighElfLightBeamTickPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { HighElfLightBeam.Tick(__instance); } if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { HighElfLightBeam.TickRemoteVisuals(); } } } [HarmonyPatch(typeof(Player), "UpdateStealth")] public static class WoodElfStealthPatch { private static readonly FieldInfo StealthFactorField = AccessTools.Field(typeof(Player), "m_stealthFactor"); private static readonly FieldInfo StealthFactorTargetField = AccessTools.Field(typeof(Player), "m_stealthFactorTarget"); private static readonly FieldInfo LastStealthPosField = AccessTools.Field(typeof(Player), "m_lastStealthPosition"); private static bool Prefix(Player __instance, float dt) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (!ElfTypeManager.IsWoodElf(__instance) || !WoodElfTrees.IsNearTree(__instance, 10f)) { return true; } float num = (((Character)__instance).IsCrouching() ? 0.001f : 0.02f); float num2 = Mathf.MoveTowards((StealthFactorField != null) ? ((float)StealthFactorField.GetValue(__instance)) : num, num, dt); StealthFactorField?.SetValue(__instance, num2); StealthFactorTargetField?.SetValue(__instance, num); LastStealthPosField?.SetValue(__instance, ((Component)__instance).transform.position); if ((Object)(object)((Character)__instance).m_nview != (Object)null && ((Character)__instance).m_nview.IsValid()) { ((Character)__instance).m_nview.GetZDO().Set(ZDOVars.s_stealth, num2); } return false; } } [HarmonyPatch(typeof(BaseAI), "CanSenseTarget", new Type[] { typeof(Transform), typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(bool), typeof(bool), typeof(Character), typeof(bool), typeof(bool) })] public static class WoodElfCanSensePatch { private static void Postfix(Character target, ref bool __result) { if (__result) { Player val = (Player)(object)((target is Player) ? target : null); if (val != null && ElfTypeManager.IsWoodElf(val) && WoodElfTrees.IsNearTree(val, 10f)) { __result = false; } } } } [HarmonyPatch(typeof(Player), "Update")] public static class GenasiUpdatePatch { private static readonly MethodInfo ShowHandItemsMethod = AccessTools.Method(typeof(Humanoid), "ShowHandItems", new Type[2] { typeof(bool), typeof(bool) }, (Type[])null); private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { GenasiEarth.Update(__instance); GenasiAir.Update(__instance); GenasiFire.Update(__instance); GenasiWaterBreath.Update(__instance); GenasiWaterDive.Update(__instance); GenasiWaterDive.RegenStaminaInWater(__instance, Time.deltaTime); GenasiWaterCamera.Update(__instance); GenasiWaterSwimPose.Update(__instance); TryWaterGenasiHideToggle(__instance); } } private static void TryWaterGenasiHideToggle(Player player) { if (!GenasiTypeManager.Is(player, GenasiType.Water) || (!((Character)player).IsSwimming() && !((Character)player).InWater()) || (!ZInput.GetButtonDown("Hide") && (!ZInput.GetButtonUp("JoyHide") || !(ZInput.GetButtonLastPressedTimer("JoyHide") < 0.33f))) || ((Humanoid)player).GetRightItem() != null || ((Humanoid)player).GetLeftItem() != null) { return; } GenasiWaterIsSwimmingBypassPatch.BypassCount++; try { ShowHandItemsMethod?.Invoke(player, new object[2] { false, true }); } finally { if (GenasiWaterIsSwimmingBypassPatch.BypassCount > 0) { GenasiWaterIsSwimmingBypassPatch.BypassCount--; } } } } [HarmonyPatch(typeof(Player), "LateUpdate")] public static class GenasiWaterSwimPoseLateUpdatePatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { GenasiWaterSwimPose.LateUpdateVisual(__instance); } } } [HarmonyPatch(typeof(Character), "UpdateSwimming")] public static class GenasiWaterSwimAnimPatch { private static bool Prefix(Character __instance) { if (!GenasiWaterSwimPose.ShouldSkipUpdateSwimming(__instance)) { return true; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { GenasiWaterSwimPose.ForceUprightState(val); } return false; } private static void Postfix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && GenasiTypeManager.Is(val, GenasiType.Water)) { if (GenasiWaterSwimPose.IsForceUpright) { GenasiWaterSwimPose.ForceUprightState(val); } else if (GenasiWaterSwimPose.IsPoseActive) { GenasiWaterSwimPose.ForceSwimState(val); } } } } [HarmonyPatch(typeof(Character), "UpdateWater")] public static class GenasiWaterUpdateWaterUprightPatch { private static void Postfix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && GenasiTypeManager.Is(val, GenasiType.Water) && GenasiWaterSwimPose.IsForceUpright) { GenasiWaterSwimPose.ForceUprightState(val); } } } [HarmonyPatch(typeof(Player), "Update")] [HarmonyPriority(800)] public static class GenasiWaterXSuppressSitEarlyPatch { private static void Prefix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && GenasiTypeManager.Is(__instance, GenasiType.Water)) { GenasiWaterSwimPose.TryArmSitSuppressForX(__instance); } } } [HarmonyPatch(typeof(Player), "StartEmote")] public static class GenasiWaterBlockSitOnXPatch { private static bool Prefix(string emote) { if (emote == "sit" && GenasiWaterSwimPose.ShouldSuppressSit()) { return false; } return true; } } [HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[] { typeof(int), typeof(bool), typeof(int), typeof(float) })] public static class GenasiWaterWetNoResetUnderwaterPatch { private static bool Prefix(SEMan __instance, int nameHash, bool resetTime) { if (!resetTime || nameHash != SEMan.s_statusEffectWet) { return true; } Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val == null || !GenasiTypeManager.Is(val, GenasiType.Water)) { return true; } if (!GenasiWaterSwimPose.IsFullySubmerged(val)) { return true; } if (__instance.HaveStatusEffect(SEMan.s_statusEffectWet)) { return false; } return true; } } [HarmonyPatch(typeof(Character), "UpdateMotion")] public static class GenasiWaterForceSwimMotionPatch { private static void Prefix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && GenasiTypeManager.Is(val, GenasiType.Water)) { if (GenasiWaterSwimPose.IsForceUpright) { GenasiWaterSwimPose.ForceUprightState(val); } else if (GenasiWaterSwimPose.IsPoseActive) { GenasiWaterSwimPose.ForceSwimState(val); } if (GenasiWaterSwimPose.IsFullySubmerged(val)) { GenasiWaterSwimPose.SuppressFallWhileSubmerged(val); } } } } [HarmonyPatch(typeof(Character), "ApplyLiquidResistance")] public static class GenasiWaterLiquidResistancePatch { private static bool Prefix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { return !GenasiTypeManager.Is(val, GenasiType.Water); } return true; } } [HarmonyPatch(typeof(SEMan), "ModifyFallDamage")] public static class GenasiWaterFallDamagePatch { private static void Postfix(SEMan __instance, ref float damage) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Water) && GenasiWaterSwimPose.IsFullySubmerged(val)) { damage = 0f; } } } [HarmonyPatch(typeof(Humanoid), "HideHandItems")] public static class GenasiWaterHideHandItemsPatch { private static bool Prefix(Humanoid __instance, bool onlyRightHand) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || !GenasiTypeManager.Is(val, GenasiType.Water)) { return true; } if (!((Character)val).InWater()) { return true; } if (onlyRightHand) { return true; } if (ZInput.GetButtonDown("Hide")) { return true; } if (ZInput.GetButtonUp("JoyHide") && ZInput.GetButtonLastPressedTimer("JoyHide") < 0.33f) { return true; } return false; } } [HarmonyPatch(typeof(Player), "SetMaxStamina")] public static class GenasiAirSetMaxStaminaPatch { private static void Prefix(Player __instance, ref float stamina) { if (GenasiTypeManager.Is(__instance, GenasiType.Air)) { stamina *= 1.15f; } } } [HarmonyPatch(typeof(Player), "UseStamina")] public static class GenasiAirStaminaDrainPatch { private static void Prefix(Player __instance, ref float v) { if (GenasiTypeManager.Is(__instance, GenasiType.Air)) { float num = 0.9f; if (((Character)__instance).IsSwimming() || ((Character)__instance).InWater()) { num = 0.7f; } v *= num; } } } [HarmonyPatch(typeof(Player), "GetJogSpeedFactor")] public static class GenasiSpeedJogPatch { private static void Postfix(Player __instance, ref float __result) { if (GenasiTypeManager.Is(__instance, GenasiType.Air)) { __result *= 1.12f; } if (RaceManager.GetRace(__instance) == RaceType.Vampire) { __result *= 1.15f; } } } [HarmonyPatch(typeof(Player), "GetRunSpeedFactor")] public static class GenasiSpeedRunPatch { private static void Postfix(Player __instance, ref float __result) { if (GenasiTypeManager.Is(__instance, GenasiType.Air)) { __result *= 1.12f; } if (RaceManager.GetRace(__instance) == RaceType.Vampire) { __result *= 1.15f; } if (GenasiTypeManager.Is(__instance, GenasiType.Water) && (((Character)__instance).InLiquid() || ((Character)__instance).InWater())) { __result *= 1.15f; } } } [HarmonyPatch(typeof(SEMan), "ModifyRunStaminaDrain")] public static class RaceRunStaminaPatch { private static void Postfix(SEMan __instance, ref float drain) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && (ElfTypeManager.IsWoodElf(val) || GenasiTypeManager.Is(val, GenasiType.Earth))) { drain = 0f; } } } [HarmonyPatch(typeof(SEMan), "ModifySneakStaminaUsage")] public static class DrowSneakStaminaPatch { private static void Postfix(SEMan __instance, ref float staminaUse) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && ElfTypeManager.IsDrow(val)) { staminaUse = 0f; } } } [HarmonyPatch(typeof(Character), "Jump")] public static class GenasiAirJumpPatch { private static void Prefix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Air)) { __instance.m_jumpForce *= 1.18f; __instance.m_jumpForceForward *= 1.1f; } } private static void Postfix(Character __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Air)) { __instance.m_jumpForce /= 1.18f; __instance.m_jumpForceForward /= 1.1f; } } } [HarmonyPatch(typeof(SEMan), "ModifySwimStaminaUsage")] public static class GenasiSwimStaminaPatch { private static void Postfix(SEMan __instance, ref float staminaUse) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null) { if (GenasiTypeManager.Is(val, GenasiType.Water)) { staminaUse = 0f; } else if (GenasiTypeManager.Is(val, GenasiType.Air)) { staminaUse *= 0.65f; } } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] public static class GenasiAbilityAttackSuppressPatch { private static bool Prefix(Humanoid __instance, ref bool __result, bool secondaryAttack) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (!secondaryAttack && GenasiTypeManager.Is(val, GenasiType.Earth) && DragonbornBreathInput.IsBlockHeld() && (DragonbornBreathInput.IsAttackHeld() || DragonbornBreathInput.IsAttackPressed() || Input.GetMouseButton(2) || Input.GetMouseButtonDown(2))) { DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)val); DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)val); __result = false; return false; } if (secondaryAttack || !DragonbornBreathInput.AreBreathButtonsHeld()) { return true; } if ((!GenasiTypeManager.Is(val, GenasiType.Water) || !GenasiWaterBreath.ShouldSuppressAttacks(val)) && !GenasiAir.ShouldSuppressAttacks(val) && !GiantTypeManager.Is(val, GiantType.Cloud) && !GiantTypeManager.Is(val, GiantType.Stone) && RaceManager.GetRace(val) != RaceType.Aasimar && RaceManager.GetRace(val) != RaceType.Tiefling) { return true; } DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)val); DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)val); __result = false; return false; } } [HarmonyPatch(typeof(Humanoid), "UpdateEquipment", new Type[] { typeof(float) })] public static class GenasiWaterUpdateEquipmentPatch { private static void Prefix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Water)) { GenasiWaterIsSwimmingBypassPatch.BypassCount++; } } private static void Finalizer(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Water) && GenasiWaterIsSwimmingBypassPatch.BypassCount > 0) { GenasiWaterIsSwimmingBypassPatch.BypassCount--; } } } [HarmonyPatch(typeof(Character), "IsSwimming")] public static class GenasiWaterIsSwimmingBypassPatch { internal static int BypassCount; private static void Postfix(Character __instance, ref bool __result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Water)) { if (BypassCount > 0) { __result = false; } else if (GenasiWaterSwimPose.IsForceUpright) { __result = false; } } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] public static class GenasiWaterEquipItemPatch { private static void Prefix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Water)) { GenasiWaterIsSwimmingBypassPatch.BypassCount++; } } private static void Finalizer(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Water) && GenasiWaterIsSwimmingBypassPatch.BypassCount > 0) { GenasiWaterIsSwimmingBypassPatch.BypassCount--; } } } [HarmonyPatch(typeof(WearNTear), "OnPlaced")] public static class GenasiWaterTouchOfWaterMarkPatch { private static void Postfix(WearNTear __instance) { GenasiWaterTouchOfWater.TryMarkOnPlaced(__instance); } } [HarmonyPatch(typeof(WearNTear), "HaveRoof")] public static class GenasiWaterTouchOfWaterRoofPatch { private static void Postfix(WearNTear __instance, ref bool __result) { if (GenasiWaterTouchOfWater.IsProtected(__instance)) { __result = true; } } } [HarmonyPatch(typeof(WearNTear), "IsUnderWater")] public static class GenasiWaterTouchOfWaterUnderwaterPatch { private static void Postfix(WearNTear __instance, ref bool __result) { if (GenasiWaterTouchOfWater.IsProtected(__instance)) { __result = false; } } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] public static class GenasiWaterBuildPatch { private static readonly FieldRef PlacementGhostRef = AccessTools.FieldRefAccess("m_placementGhost"); private static readonly FieldRef PlacementStatusRef = AccessTools.FieldRefAccess("m_placementStatus"); private static void Prefix(Player __instance, ref bool __state) { __state = false; if (!GenasiTypeManager.Is(__instance, GenasiType.Water)) { return; } GameObject val = PlacementGhostRef.Invoke(__instance); if (!((Object)(object)val == (Object)null)) { Piece component = val.GetComponent(); if (!((Object)(object)component == (Object)null) && component.m_noInWater) { component.m_noInWater = false; __state = true; } } } private static void Postfix(Player __instance, bool __state) { GameObject val = PlacementGhostRef.Invoke(__instance); if (__state && (Object)(object)val != (Object)null) { Piece component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_noInWater = true; } } if (GenasiTypeManager.Is(__instance, GenasiType.Water) && ((Character)__instance).InWater() && (int)PlacementStatusRef.Invoke(__instance) == 1) { PlacementStatusRef.Invoke(__instance) = (PlacementStatus)0; } } } [HarmonyPatch(typeof(Player), "SetControls")] public static class GenasiWaterPreventCrouchPatch { private static void Prefix(Player __instance, ref bool crouch) { if (GenasiTypeManager.Is(__instance, GenasiType.Water) && ((Character)__instance).IsSwimming()) { crouch = false; } } } [HarmonyPatch(typeof(SEMan), "ModifyHealthRegen")] public static class GenasiWaterWetHealthRegenPatch { private static void Postfix(SEMan __instance, ref float regenMultiplier) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && GenasiWaterWet.IsBlessedWet(val)) { regenMultiplier += 0.25f; } } } [HarmonyPatch(typeof(SEMan), "ModifyStaminaRegen")] public static class GenasiWaterWetStaminaRegenPatch { private static void Postfix(SEMan __instance, ref float staminaMultiplier) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && GenasiWaterWet.IsBlessedWet(val)) { staminaMultiplier += 0.15f; } } } [HarmonyPatch(typeof(SEMan), "ModifyEitrRegen")] public static class GenasiWaterWetEitrRegenPatch { private static void Postfix(SEMan __instance, ref float eitrMultiplier) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && GenasiWaterWet.IsBlessedWet(val)) { eitrMultiplier += 0.15f; } } } [HarmonyPatch(typeof(Bed), "CheckWet")] public static class GenasiWaterBedWetPatch { private static void Postfix(Player human, ref bool __result) { if (!__result && GenasiTypeManager.Is(human, GenasiType.Water)) { __result = true; } } } [HarmonyPatch(typeof(Player), "UpdateEnvStatusEffects")] public static class GenasiWaterClearColdPatch { private static void Postfix(Player __instance) { GenasiWaterWet.ClearColdWhileBlessed(__instance); } } [HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[] { typeof(int), typeof(bool), typeof(int), typeof(float) })] public static class GenasiWaterBlockColdWhileWetPatch { private static readonly FieldInfo CharacterField = AccessTools.Field(typeof(SEMan), "m_character"); private static bool Prefix(SEMan __instance, int nameHash, ref StatusEffect __result) { object? obj = CharacterField?.GetValue(__instance); object? obj2 = ((obj is Character) ? obj : null); Player val = (Player)((obj2 is Player) ? obj2 : null); if (val != null && GenasiWaterWet.ShouldBlockColdStatus(val, nameHash)) { __result = null; return false; } return true; } } [HarmonyPatch(typeof(Fish), "GetHoverText")] public static class GenasiWaterFishHoverPatch { private static void Postfix(Fish __instance, ref string __result) { if (GenasiTypeManager.Is(Player.m_localPlayer, GenasiType.Water) && !__instance.IsOutOfWater()) { __result = Localization.instance.Localize(__instance.m_name + "\n[$KEY_Use] $inventory_pickup"); } } } [HarmonyPatch(typeof(Fish), "Interact")] public static class GenasiWaterFishInteractPatch { private static bool Prefix(Fish __instance, Humanoid character, bool repeat, ref bool __result) { if (!repeat) { Player val = (Player)(object)((character is Player) ? character : null); if (val != null && GenasiTypeManager.Is(val, GenasiType.Water)) { if (__instance.IsOutOfWater()) { return true; } __result = __instance.Pickup(character); return false; } } return true; } } [HarmonyPatch(typeof(Player), "GetPlayerNoiseRange")] public static class GenasiWaterFishIgnorePatch { private static void Postfix(ref Player __result) { if ((Object)(object)__result != (Object)null && GenasiTypeManager.Is(__result, GenasiType.Water)) { __result = null; } } } [HarmonyPatch(typeof(Player), "Update")] public static class GiantUpdatePatch { private static void Postfix(Player __instance) { GiantBody.Update(__instance); if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { CloudGiantTeleport.Update(__instance); CloudGiantJump.Update(__instance); StoneGiantRock.Update(__instance); } } } [HarmonyPatch(typeof(Player), "GetMaxCarryWeight")] public static class GiantCarryWeightPatch { private static void Postfix(Player __instance, ref float __result) { if (RaceManager.GetRace(__instance) == RaceType.Giant) { float num = __result - __instance.m_maxCarryWeight; __result = 600f + Mathf.Max(0f, num); } } } [HarmonyPatch(typeof(SEMan), "ModifyFallDamage")] public static class GiantFallDamagePatch { private static void Postfix(SEMan __instance, ref float damage) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); Player val = (Player)(object)((value is Player) ? value : null); if (val != null && RaceManager.GetRace(val) == RaceType.Giant) { if (GiantTypeManager.Is(val, GiantType.Cloud)) { damage = 0f; } else { damage *= 0.5f; } } } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] public static class GiantStoneArmorPatch { private static void Postfix(Player __instance, ref float __result) { __result += GiantCombat.GetStoneArmorBonus(__instance); __result += DrowShadowArmor.GetArmorBonus(__instance); } } [HarmonyPatch(typeof(Character), "Jump")] public static class GiantJumpPatch { private static bool Prefix(Character __instance, ref int __state) { __state = 0; Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || RaceManager.GetRace(val) != RaceType.Giant) { return true; } if (CloudGiantJump.IsCloud(val) && !((Character)val).IsOnGround()) { CloudGiantJump.TryAirJump(val); return false; } __instance.m_jumpForce *= 1f; __instance.m_jumpForceForward *= 1f; __state = 1; if (CloudGiantJump.IsCloud(val)) { CloudGiantJump.BeginReducedJumpStamina(__instance); __state = 2; } return true; } private static void Postfix(Character __instance, int __state) { if (__state > 0) { if (__state >= 2) { CloudGiantJump.EndReducedJumpStamina(__instance); } __instance.m_jumpForce /= 1f; __instance.m_jumpForceForward /= 1f; } } } [HarmonyPatch(typeof(DamageText), "AddInworldText")] public static class MountainShiftYellowTextColorPatch { private static readonly FieldInfo WorldTextsField = AccessTools.Field(typeof(DamageText), "m_worldTexts"); private static readonly Color PurpleMinusOne = new Color(0.72f, 0.28f, 1f, 1f); private static void Postfix(DamageText __instance) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (!(WorldTextsField?.GetValue(__instance) is IList { Count: not 0 } list)) { return; } TMP_Text value = Traverse.Create(list[list.Count - 1]).Field("m_textField").GetValue(); if (!((Object)(object)value == (Object)null)) { if (FrostBeamWeakenText.TryConsumePendingPurpleMinusOne()) { value.text = "-1"; ((Graphic)value).color = PurpleMinusOne; } else if (MountainShiftDamageText.TryConsumePendingYellow()) { ((Graphic)value).color = new Color(1f, 1f, 0f, 1f); } } } } [HarmonyPatch(typeof(Player), "Update")] public static class NewRacesUpdatePatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { HalflingBody.Update(__instance); GnomeRock.Update(__instance); OrcRage.Update(__instance); DwarfCrater.Update(__instance); TieflingAbyssal.Update(__instance); TieflingChthonic.Update(__instance); TieflingInfernal.Update(__instance); AasimarWisp.Update(__instance); AasimarHealBreath.Update(__instance); AasimarFlight.Update(__instance); } } } [HarmonyPatch(typeof(Player), "SetMaxHealth")] public static class TieflingChthonicMaxHpPatch { private static void Prefix(Player __instance, ref float health) { health += TieflingChthonic.GetBonusMaxHealth(__instance); OrcRage.ApplyDashMaxHealthBonus(__instance, ref health); } } [HarmonyPatch(typeof(Player), "GetJogSpeedFactor")] public static class OrcDashJogPatch { private static void Postfix(Player __instance, ref float __result) { if (OrcRage.IsDashing(__instance)) { __result *= 2f; } GnomeRock.HasEmpowerBuff(__instance); } } [HarmonyPatch(typeof(Player), "GetRunSpeedFactor")] public static class OrcDashRunPatch { private static void Postfix(Player __instance, ref float __result) { if (OrcRage.IsDashing(__instance)) { __result *= 2f; } } } [HarmonyPatch(typeof(Character), "SetHealth")] public static class OrcLastStandPatch { private static bool Prefix(Character __instance, ref float health) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (RaceManager.GetRace(val) != RaceType.Orc) { return true; } if (!OrcRage.RewriteIncomingHealth(val, ref health)) { return false; } if (health <= 0f) { OrcRage.OnRealDeath(val); } return true; } } [HarmonyPatch] public static class AasimarHealBreathAttackPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Humanoid), "StartAttack", new Type[2] { typeof(Character), typeof(bool) }, (Type[])null); } private static bool Prefix(Humanoid __instance, ref bool __result, bool secondaryAttack) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (secondaryAttack) { return true; } if (RaceManager.GetRace(val) == RaceType.Aasimar && AasimarHealBreath.TryStartFromAttack(val)) { __result = true; return false; } if (GnomeRock.TryStartFromAttack(val)) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(Player), "Update")] [HarmonyAfter(new string[] { "RustyMods.AlmanacClasses" })] public static class AasimarAirJumpAlmanacCompatPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { AasimarFlight.TryAlmanacCompatibleAirJump(__instance); } } } [HarmonyPatch(typeof(Player), "UpdateStealth")] public static class HalflingStealthPatch { private static void Postfix(Player __instance) { if (HalflingBody.IsInsideLargerCreature(__instance)) { Traverse.Create((object)__instance).Field("m_stealthFactor").SetValue((object)0.02f); Traverse.Create((object)__instance).Field("m_stealthFactorTarget").SetValue((object)0.02f); } } } [HarmonyPatch(typeof(BaseAI), "CanSenseTarget", new Type[] { typeof(Transform), typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(bool), typeof(bool), typeof(Character), typeof(bool), typeof(bool) })] public static class HalflingCanSensePatch { private static void Postfix(Character target, ref bool __result) { if (__result) { Player val = (Player)(object)((target is Player) ? target : null); if (val != null && HalflingBody.IsInsideLargerCreature(val)) { __result = false; } } } } [HarmonyPatch(typeof(BaseAI), "CanSeeTarget", new Type[] { typeof(Character) })] public static class InfernalDarknessVisionPatch { private static void Postfix(BaseAI __instance, Character target, ref bool __result) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (__result && !((Object)(object)target == (Object)null) && !((Object)(object)__instance == (Object)null)) { Character value = Traverse.Create((object)__instance).Field("m_character").GetValue(); if (!((Object)(object)value == (Object)null) && TieflingInfernal.BlocksVision(value.GetCenterPoint(), target.GetCenterPoint())) { __result = false; } } } } [HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")] [HarmonyAfter(new string[] { "RustyMods.AlmanacClasses" })] public static class RaceCompendiumTabPatch { private static readonly FieldInfo TextsField = AccessTools.Field(typeof(TextsDialog), "m_texts"); private static void Postfix(TextsDialog __instance) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !(TextsField == null) && TextsField.GetValue(__instance) is List list) { string compendiumText = RaceDescriptions.GetCompendiumText(localPlayer); TextInfo item = new TextInfo("Race", compendiumText); list.Insert(0, item); } } } [HarmonyPatch(typeof(Fireplace), "IsBurning")] public static class FireplaceIsBurningPatch { private static readonly FieldRef CheckWaterLevelRef = AccessTools.FieldRefAccess("m_checkWaterLevel"); private static void Prefix(Fireplace __instance, ref bool __state) { __state = CheckWaterLevelRef.Invoke(__instance); CheckWaterLevelRef.Invoke(__instance) = false; } private static void Postfix(Fireplace __instance, bool __state) { CheckWaterLevelRef.Invoke(__instance) = __state; } } [HarmonyPatch(typeof(Fireplace), "CheckWet")] public static class FireplaceCheckWetPatch { private static readonly FieldRef WetRef = AccessTools.FieldRefAccess("m_wet"); private static readonly FieldRef PreviousWaterVolumeRef = AccessTools.FieldRefAccess("m_previousWaterVolume"); private static void Postfix(Fireplace __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) WaterVolume val = PreviousWaterVolumeRef.Invoke(__instance); if (Floating.IsUnderWater(((Component)__instance).transform.position, ref val)) { WetRef.Invoke(__instance) = false; PreviousWaterVolumeRef.Invoke(__instance) = val; } } } [HarmonyPatch] public static class VampireAttackStaminaPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Humanoid), "StartAttack", new Type[2] { typeof(Character), typeof(bool) }, (Type[])null); } private static void Postfix(Humanoid __instance, bool __result, Character target, bool secondaryAttack) { if (!__result) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && RaceManager.GetRace(val) == RaceType.Vampire) { ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon(); if (currentWeapon?.m_shared != null) { Attack val2 = (secondaryAttack ? currentWeapon.m_shared.m_secondaryAttack : currentWeapon.m_shared.m_attack); VampireAttackTracker.RecordAttackCosts(val, val2.m_attackStamina, val2.m_attackEitr); } } } } [HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[] { typeof(int), typeof(bool), typeof(int), typeof(float) })] public static class VampireBlockStatusEffectPatch { private static readonly FieldInfo CharacterField = AccessTools.Field(typeof(SEMan), "m_character"); private static bool Prefix(SEMan __instance, int nameHash, ref StatusEffect __result) { object? obj = CharacterField?.GetValue(__instance); object? obj2 = ((obj is Character) ? obj : null); Player val = (Player)((obj2 is Player) ? obj2 : null); if (val == null) { return true; } if ((nameHash == SEMan.s_statusEffectCold || nameHash == SEMan.s_statusEffectFreezing) && HasColdImmunity(val)) { __result = null; return false; } if (nameHash == SEMan.s_statusEffectRested && RaceManager.GetRace(val) == RaceType.Vampire) { __result = null; return false; } if (nameHash == SEMan.s_statusEffectWet && VampireSunbrella.IsActive(val)) { __result = null; return false; } if (nameHash == SEMan.s_statusEffectSmoked && GenasiTypeManager.Is(val, GenasiType.Air)) { __result = null; return false; } return true; } internal static bool HasColdImmunity(Player player) { if ((Object)(object)player == (Object)null) { return false; } RaceType race = RaceManager.GetRace(player); if (race != RaceType.Vampire && race != RaceType.Aasimar) { return ElfTypeManager.IsDrow(player); } return true; } } [HarmonyPatch(typeof(Player), "ShowTutorial")] public static class VampireColdTutorialPatch { private static bool Prefix(Player __instance, string name) { if (!VampireBlockStatusEffectPatch.HasColdImmunity(__instance)) { return true; } return name != "cold"; } } [HarmonyPatch(typeof(Player), "UpdateEnvStatusEffects")] public static class VampireColdImmunityPatch { private static void Postfix(Player __instance) { if (VampireBlockStatusEffectPatch.HasColdImmunity(__instance)) { SEMan sEMan = ((Character)__instance).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectCold, true); sEMan.RemoveStatusEffect(SEMan.s_statusEffectFreezing, true); } } } } [HarmonyPatch(typeof(Player), "Update")] public static class VampireStatusCleanupPatch { private static readonly Dictionary LastMeadBonus = new Dictionary(); private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)null || !((Character)__instance).IsOwner() || RaceManager.GetRace(__instance) != RaceType.Vampire) { return; } SEMan sEMan = ((Character)__instance).GetSEMan(); if (sEMan == null) { return; } if (sEMan.HaveStatusEffect(SEMan.s_statusEffectRested)) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectRested, false); } if (!VampireFood.HasAnyBloodPuddingFood(__instance)) { float meadMaxHealthBonus = VampireFood.GetMeadMaxHealthBonus(__instance); if (!LastMeadBonus.TryGetValue(__instance, out var value) || !Mathf.Approximately(value, meadMaxHealthBonus)) { LastMeadBonus[__instance] = meadMaxHealthBonus; VampireFood.ApplyVampireFoodMaxStats(__instance); } } } } [HarmonyPatch(typeof(Player), "SetSleeping")] public static class VampireSleepRestedPatch { private static void Postfix(Player __instance, bool sleep) { if (!sleep && RaceManager.GetRace(__instance) == RaceType.Vampire) { SEMan sEMan = ((Character)__instance).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectRested, false); } } } } [HarmonyPatch(typeof(Player), "ConsumeItem", new Type[] { typeof(Inventory), typeof(ItemData), typeof(bool) })] public static class VampireConsumeFoodPatch { private static bool Prefix(Player __instance, ItemData item, ref bool __result) { if (RaceManager.GetRace(__instance) != RaceType.Vampire || item?.m_shared == null) { return true; } if (item.m_shared.m_food > 0f) { bool flag = VampireFood.IsBloodPudding(item); bool flag2 = VampireFood.HasActiveBloodPudding(__instance); bool flag3 = VampireFood.HasActiveNonBloodFood(__instance, 10f); if (flag && flag3) { ((Character)__instance).Message((MessageType)2, "Mortal food still holds you — blood pudding must wait.", 0, (Sprite)null); __result = false; return false; } if (!flag && flag2) { ((Character)__instance).Message((MessageType)2, "Blood pudding owns your hunger for now.", 0, (Sprite)null); __result = false; return false; } } return true; } private static void Postfix(Player __instance, ItemData item, bool __result) { if (__result && RaceManager.GetRace(__instance) == RaceType.Vampire) { if (VampireFood.IsBloodPudding(item)) { VampireFood.ApplyVampireBloodPuddingBuff(__instance, item); } else if (VampireFood.IsBloodTasteItem(item) && item.m_shared.m_food <= 0f) { VampireFood.ApplyBloodTasteMeadBonus(__instance); } } } } [HarmonyPatch(typeof(Player), "EatFood")] public static class VampireEatFoodPatch { private static void Postfix(Player __instance, ItemData item, bool __result) { if (__result && RaceManager.GetRace(__instance) == RaceType.Vampire && item?.m_shared != null && !(item.m_shared.m_food <= 0f) && VampireFood.IsBloodTasteItem(item)) { VampireFood.ApplyBloodTasteFoodBonus(__instance); } } } [HarmonyPatch(typeof(Character), "SetMaxHealth", new Type[] { typeof(float) })] public static class VampireMaxHealthClampPatch { private static void Prefix(Character __instance, ref float health) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && RaceManager.GetRace(val) == RaceType.Vampire && !VampireFood.HasAnyBloodPuddingFood(val)) { VampireFood.CalculateVampireFoodTotals(val, out var hp, out var _, out var _); if (health < hp - 0.5f) { health = hp; } } } } [HarmonyPatch(typeof(Player), "UpdateFood")] public static class VampireBloodPuddingUpdateFoodPatch { private static bool Prefix(Player __instance, float dt, bool forceUpdate) { if (RaceManager.GetRace(__instance) != RaceType.Vampire || !VampireFood.HasAnyBloodPuddingFood(__instance)) { return true; } VampireFood.UpdateBloodPuddingFood(__instance, dt, forceUpdate); return false; } } [HarmonyPatch(typeof(Player), "UpdateFood")] public static class VampireBloodTasteFoodStatsPatch { private static void Postfix(Player __instance) { if (RaceManager.GetRace(__instance) == RaceType.Vampire) { VampireFood.ApplyVampireFoodMaxStats(__instance); } } } [HarmonyPatch(typeof(Player), "UpdateFood")] public static class VampireBloodPuddingRegenPatch { private static void Postfix(Player __instance, float dt) { if (RaceManager.GetRace(__instance) == RaceType.Vampire && VampireFood.HasActiveBloodPudding(__instance)) { ((Character)__instance).Heal(50f * dt, false); ((Character)__instance).AddStamina(100f * dt); ((Character)__instance).AddEitr(100f * dt); } } } [HarmonyPatch(typeof(Player), "RaiseSkill")] public static class VampireBloodPuddingXpPatch { private static void Prefix(Player __instance, ref float value) { if (RaceManager.GetRace(__instance) == RaceType.Vampire && VampireFood.HasActiveBloodPudding(__instance)) { value *= 6f; } } } [HarmonyPatch(typeof(Player), "Update")] public static class VampireSunlightUpdatePatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(__instance) == RaceType.Vampire) { VampireSunbrella.Update(__instance); VampireSunlight.Update(__instance); } } } [HarmonyPatch(typeof(Player), "LateUpdate")] public static class VampireSunbrellaLateUpdatePatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(__instance) == RaceType.Vampire && VampireSunbrella.IsActive(__instance)) { VampireSunbrella.LateUpdateVisual(__instance); } } } [HarmonyPatch(typeof(Player), "UpdateEnvStatusEffects")] public static class VampireSunbrellaRainPatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && VampireSunbrella.IsActive(__instance)) { SEMan sEMan = ((Character)__instance).GetSEMan(); if (sEMan != null) { sEMan.RemoveStatusEffect(SEMan.s_statusEffectWet, true); } } } } [HarmonyPatch] public static class VampireSunbrellaBlockPatch { private static IEnumerable TargetMethods() { MethodInfo playerBlock = AccessTools.Method(typeof(Player), "UpdateBlock", (Type[])null, (Type[])null); MethodInfo humanoidBlock = AccessTools.Method(typeof(Humanoid), "UpdateBlock", (Type[])null, (Type[])null); if (playerBlock != null) { yield return playerBlock; } if (humanoidBlock != null && humanoidBlock != playerBlock) { yield return humanoidBlock; } } private static bool Prefix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return true; } if (!VampireSunbrella.IsActive(val)) { return true; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)val); return false; } } [HarmonyPatch] public static class VampireSunbrellaIsBlockingPatch { private static IEnumerable TargetMethods() { MethodInfo playerBlocking = AccessTools.Method(typeof(Player), "IsBlocking", (Type[])null, (Type[])null); MethodInfo humanoidBlocking = AccessTools.Method(typeof(Humanoid), "IsBlocking", (Type[])null, (Type[])null); if (playerBlocking != null) { yield return playerBlocking; } if (humanoidBlocking != null && humanoidBlocking != playerBlocking) { yield return humanoidBlocking; } } private static void Postfix(Humanoid __instance, ref bool __result) { if (__result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && VampireSunbrella.IsActive(val)) { __result = false; } } } } [HarmonyPatch(typeof(EnvMan), "SetEnv", new Type[] { typeof(EnvSetup), typeof(float), typeof(float), typeof(float), typeof(float), typeof(float) })] public static class VampireNightVisionPatch { private static void Postfix(EnvSetup env, float dayInt, float nightInt) { VampireVisionState.LastEnv = env; VampireVisionState.LastDayInt = dayInt; VampireVisionState.LastNightInt = nightInt; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && env != null && HasNightVision(localPlayer)) { if (GenasiTypeManager.Is(localPlayer, GenasiType.Fire)) { VampireVision.ApplyRedNightVision(env); } else { VampireVision.ApplyMiddayVision(env); } } } internal static bool HasNightVision(Player player) { RaceType race = RaceManager.GetRace(player); if (race != RaceType.Vampire && race != RaceType.Dwarf && !ElfTypeManager.IsDrow(player)) { return GenasiTypeManager.Is(player, GenasiType.Fire); } return true; } } [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class DragonbornMountainShiftDamageTextPatch { private static void Prefix(HitData hit, bool showDamageText, ref DamageModifier mod) { if (showDamageText && hit != null) { Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null && MountainShiftDamageText.ShouldForceYellow(val, hit, mod)) { mod = (DamageModifier)2; MountainShiftDamageText.MarkPendingYellow(); } } } } } namespace Ent1tyRaces.Commands { public class BreathCommand : ConsoleCommand { public override string Name => "breath"; public override string Help => "Admin: breath fire|poison|lightning|ice (requires devcommands). First pick is on character creation."; public override bool IsCheat => true; public override bool IsNetwork => true; public override void Run(string[] args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Console.instance.Print("Breath command can only be used in-game."); return; } if (!TypeCommand.CheatsOk()) { Console.instance.Print("Enable devcommands first. First breath pick is on character creation."); return; } if (RaceManager.GetRace(localPlayer) != RaceType.Dragonborn) { Console.instance.Print("Only Dragonborn can attune a breath element."); return; } if (args.Length == 0) { Console.instance.Print($"Current breath: {BreathManager.GetBreathElement(localPlayer)}"); Console.instance.Print("Usage: breath fire | poison | lightning | ice"); return; } bool flag; switch (args[0].ToLowerInvariant()) { case "fire": case "poison": case "lightning": case "ice": case "frost": flag = true; break; default: flag = false; break; } if (!flag) { Console.instance.Print("Unknown element '" + args[0] + "'."); return; } BreathElement element = BreathManager.ParseBreathElement(args[0]); BreathManager.TrySetBreathElement(localPlayer, element, out var message); Console.instance.Print(message); } public override List CommandOptionList() { return new List { "fire", "poison", "lightning", "ice" }; } } [HarmonyPatch(typeof(Chat), "SendText")] public static class ChatBreathCommandPatch { private static bool Prefix(string text) { if (string.IsNullOrWhiteSpace(text) || !text.TrimStart(Array.Empty()).StartsWith("/breath")) { return true; } string[] array = text.Trim().Split(new char[1] { ' ' }); string[] array2 = ((array.Length > 1) ? array.Skip(1).ToArray() : new string[0]); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Load a character first."); return false; } if (!TypeCommand.CheatsOk()) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Choose Breath on character creation. Admin: enable devcommands, then /breath."); return false; } if (RaceManager.GetRace(localPlayer) != RaceType.Dragonborn) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Only Dragonborn can attune a breath element."); return false; } if (array2.Length == 0) { BreathElement breathElement = BreathManager.GetBreathElement(localPlayer); ((Terminal)Chat.instance).AddString($"[Ent1tyRaces] Current breath: {breathElement}"); ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Usage: /breath fire | poison | lightning | ice"); return false; } bool flag; switch (array2[0].ToLowerInvariant()) { case "fire": case "poison": case "lightning": case "ice": case "frost": flag = true; break; default: flag = false; break; } if (!flag) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Unknown element '" + array2[0] + "'."); return false; } BreathElement element = BreathManager.ParseBreathElement(array2[0]); BreathManager.TrySetBreathElement(localPlayer, element, out var message); ((Terminal)Chat.instance).AddString("[Ent1tyRaces] " + message); return false; } } [HarmonyPatch(typeof(Chat), "SendText")] public static class ChatLegacyCommandPatch { private static bool Prefix(string text) { if (string.IsNullOrWhiteSpace(text) || !text.TrimStart(Array.Empty()).StartsWith("/legacy")) { return true; } string[] array = text.Trim().Split(new char[1] { ' ' }); string[] array2 = ((array.Length > 1) ? array.Skip(1).ToArray() : new string[0]); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Load a character first."); return false; } if (!TypeCommand.CheatsOk()) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Choose Legacy on character creation. Admin: enable devcommands, then /legacy."); return false; } if (RaceManager.GetRace(localPlayer) != RaceType.Tiefling) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Only Tieflings can choose a legacy."); return false; } if (array2.Length == 0) { ((Terminal)Chat.instance).AddString($"[Ent1tyRaces] Current legacy: {TieflingLegacyManager.GetLegacy(localPlayer)}"); ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Usage: /legacy abyssal | chthonic | infernal"); return false; } LegacyCommand.TryApply(localPlayer, array2[0], out var message); ((Terminal)Chat.instance).AddString("[Ent1tyRaces] " + message); return false; } } [HarmonyPatch(typeof(Chat), "SendText")] public static class ChatRaceCommandPatch { private static bool Prefix(string text) { if (string.IsNullOrWhiteSpace(text) || !text.TrimStart(Array.Empty()).StartsWith("/race")) { return true; } string[] array = text.Trim().Split(new char[1] { ' ' }); string[] array2 = ((array.Length > 1) ? array.Skip(1).ToArray() : new string[0]); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Load a character first."); return false; } if (array2.Length != 0 && array2[0].Equals("reset", StringComparison.OrdinalIgnoreCase)) { RaceManager.TryResetRace(localPlayer, out var message); ((Terminal)Chat.instance).AddString("[Ent1tyRaces] " + message); return false; } if (RaceManager.IsRaceChoiceLocked(localPlayer)) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Your race is sealed: " + RaceManager.GetRaceDetail(localPlayer) + ". Odin does not do refunds."); ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Admin: /race reset (requires devcommands), then /race ."); return false; } if (array2.Length == 0) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Usage: /race | /race reset"); ((Terminal)Chat.instance).AddString("[Ent1tyRaces] First pick is on character creation. After reset, use /race ."); return false; } RaceType race = (array2[0].Equals("random", StringComparison.OrdinalIgnoreCase) ? RaceManager.RollRandomNonHuman() : RaceManager.ParseRace(array2[0])); if (!RaceManager.TryChooseRace(localPlayer, race, out var message2)) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] " + message2); return false; } string[] array3 = message2.Split(new char[1] { '\n' }); foreach (string text2 in array3) { if (!string.IsNullOrWhiteSpace(text2)) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] " + text2); } } return false; } } [HarmonyPatch(typeof(Chat), "SendText")] public static class ChatTypeCommandPatch { private static bool Prefix(string text) { if (string.IsNullOrWhiteSpace(text) || !text.TrimStart(Array.Empty()).StartsWith("/type")) { return true; } string[] array = text.Trim().Split(new char[1] { ' ' }); string[] array2 = ((array.Length > 1) ? array.Skip(1).ToArray() : new string[0]); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Load a character first."); return false; } if (!TypeCommand.CheatsOk()) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Choose Type on character creation. Admin: enable devcommands, then /type."); return false; } RaceType race = RaceManager.GetRace(localPlayer); bool flag; switch (race) { case RaceType.Elf: case RaceType.Giant: case RaceType.Genasi: case RaceType.Gnome: flag = true; break; default: flag = false; break; } if (!flag) { ((Terminal)Chat.instance).AddString("[Ent1tyRaces] Only Elves, Giants, Genasi, and Gnomes use /type. Tieflings: /legacy"); return false; } if (array2.Length == 0) { TypeCommand.PrintCurrent(localPlayer, race); return false; } TypeCommand.TryApplyType(localPlayer, race, array2[0], out var message); ((Terminal)Chat.instance).AddString("[Ent1tyRaces] " + message); return false; } } public class LegacyCommand : ConsoleCommand { public override string Name => "legacy"; public override string Help => "Admin: legacy abyssal|chthonic|infernal (requires devcommands). First pick is on character creation."; public override bool IsCheat => true; public override bool IsNetwork => true; public override void Run(string[] args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Console.instance.Print("Legacy command can only be used in-game."); } else if (!TypeCommand.CheatsOk()) { Console.instance.Print("Enable devcommands first. First legacy pick is on character creation."); } else if (RaceManager.GetRace(localPlayer) != RaceType.Tiefling) { Console.instance.Print("Only Tieflings can choose a legacy."); } else if (args.Length == 0) { Console.instance.Print($"Current legacy: {TieflingLegacyManager.GetLegacy(localPlayer)}"); Console.instance.Print("Usage: legacy abyssal | chthonic | infernal"); } else { TryApply(localPlayer, args[0], out var message); Console.instance.Print(message); } } internal static bool TryApply(Player player, string raw, out string message) { bool flag; switch (raw.Trim().ToLowerInvariant()) { case "abyssal": case "cthonic": case "abyss": case "frost": case "chthonic": case "infernal": case "fire": case "hell": case "poison": case "underworld": flag = true; break; default: flag = false; break; } if (!flag) { message = "Unknown legacy '" + raw + "'."; return false; } return TieflingLegacyManager.TrySetLegacy(player, TieflingLegacyManager.Parse(raw), out message); } public override List CommandOptionList() { return new List { "abyssal", "chthonic", "infernal" }; } } public class RaceCommand : ConsoleCommand { public override string Name => "race"; public override string Help => "race — choose race after /race reset. First choice is on character creation. race reset requires devcommands."; public override bool IsCheat => false; public override bool IsNetwork => true; public override void Run(string[] args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Console.instance.Print("Race command can only be used in-game."); } else if (args.Length != 0 && args[0].Equals("reset", StringComparison.OrdinalIgnoreCase)) { RaceManager.TryResetRace(localPlayer, out var message); Console.instance.Print(message); } else if (args.Length != 0 && args[0].Equals("debugtrinket", StringComparison.OrdinalIgnoreCase)) { Console.instance.Print("Equipped trinket: " + TrinketBonusRegistry.GetEquippedTrinketDebugName(localPlayer)); TrinketBonus equippedBonus = TrinketBonusRegistry.GetEquippedBonus(localPlayer); Console.instance.Print($"Element bonus: +{equippedBonus.ElementDamage}, ocean armor: {equippedBonus.OceanArmor}, mountain shift: {equippedBonus.MountainResShift}"); } else if (RaceManager.IsRaceChoiceLocked(localPlayer)) { Console.instance.Print("Your race is sealed: " + RaceManager.GetRaceDetail(localPlayer) + ". Odin does not do refunds."); Console.instance.Print("Admin: race reset (requires devcommands), then race ."); } else if (args.Length == 0) { Console.instance.Print("Usage: race | race reset"); Console.instance.Print("First race pick is on character creation. After reset, use race ."); } else { RaceType race = (args[0].Equals("random", StringComparison.OrdinalIgnoreCase) ? RaceManager.RollRandomNonHuman() : RaceManager.ParseRace(args[0])); RaceManager.TryChooseRace(localPlayer, race, out var message2); Console.instance.Print(message2); } } public override List CommandOptionList() { return new List { "human", "dragonborn", "vampire", "elf", "aarakocra", "giant", "genasi", "dwarf", "gnome", "halfling", "orc", "tiefling", "aasimar", "random", "reset" }; } } public class TypeCommand : ConsoleCommand { public override string Name => "type"; public override string Help => "Admin: type (requires devcommands). First pick is on character creation."; public override bool IsCheat => true; public override bool IsNetwork => true; public override void Run(string[] args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Console.instance.Print("Type command can only be used in-game."); return; } if (!CheatsOk()) { Console.instance.Print("Enable devcommands first. First type pick is on character creation."); return; } RaceType race = RaceManager.GetRace(localPlayer); bool flag; switch (race) { case RaceType.Elf: case RaceType.Giant: case RaceType.Genasi: case RaceType.Gnome: flag = true; break; default: flag = false; break; } if (!flag) { Console.instance.Print("Only Elves, Giants, Genasi, and Gnomes can choose a type. Tieflings: legacy"); return; } if (args.Length == 0) { PrintCurrent(localPlayer, race); return; } TryApplyType(localPlayer, race, args[0], out var message); Console.instance.Print(message); } internal static bool CheatsOk() { if ((Object)(object)Console.instance != (Object)null) { return ((Terminal)Console.instance).IsCheatsEnabled(); } return false; } internal static void PrintCurrent(Player player, RaceType race) { switch (race) { case RaceType.Elf: Console.instance.Print($"Current lineage: {ElfTypeManager.GetElfType(player)}"); Console.instance.Print("Usage: type high | wood | drow"); break; case RaceType.Giant: Console.instance.Print($"Current giant type: {GiantTypeManager.GetGiantType(player)}"); Console.instance.Print("Usage: type cloud | fire | frost | hill | stone | storm"); break; case RaceType.Genasi: Console.instance.Print($"Current element: {GenasiTypeManager.GetGenasiType(player)}"); Console.instance.Print("Usage: type air | earth | fire | water"); break; case RaceType.Gnome: Console.instance.Print($"Current gnome type: {GnomeTypeManager.GetGnomeType(player)}"); Console.instance.Print("Usage: type forest | rock"); break; case RaceType.Aarakocra: case RaceType.Dwarf: break; } } internal static bool TryApplyType(Player player, RaceType race, string raw, out string message) { message = null; string text = raw.Trim().ToLowerInvariant(); bool flag; switch (race) { case RaceType.Elf: if (text != null) { int length = text.Length; if (length != 4) { if (length == 7) { char c = text[0]; if (c != 'd') { if (c != 'h') { if (c == 'w' && text == "woodelf") { goto IL_00f9; } } else if (text == "highelf") { goto IL_00f9; } } else if (text == "darkelf") { goto IL_00f9; } } } else { char c = text[1]; if ((uint)c <= 105u) { if (c != 'a') { if (c == 'i' && text == "high") { goto IL_00f9; } } else if (text == "dark") { goto IL_00f9; } } else if (c != 'o') { if (c == 'r' && text == "drow") { goto IL_00f9; } } else if (text == "wood") { goto IL_00f9; } } } flag = false; goto IL_00ff; case RaceType.Giant: switch (text) { case "cloud": case "frost": case "stone": case "storm": case "hill": case "rock": case "cold": case "fire": case "ice": case "lightning": case "thunder": flag = true; break; default: flag = false; break; } if (!flag) { message = "Unknown giant type '" + raw + "'."; return false; } return GiantTypeManager.TrySetGiantType(player, GiantTypeManager.Parse(raw), out message); case RaceType.Genasi: switch (text) { case "rock": case "wind": case "aqua": case "fire": case "stone": case "water": case "earth": case "flame": case "air": flag = true; break; default: flag = false; break; } if (!flag) { message = "Unknown genasi element '" + raw + "'."; return false; } return GenasiTypeManager.TrySetGenasiType(player, GenasiTypeManager.Parse(raw), out message); case RaceType.Gnome: switch (text) { case "forest": case "wood": case "animal": case "rock": case "stone": flag = true; break; default: flag = false; break; } if (!flag) { message = "Unknown gnome type '" + raw + "'."; return false; } return GnomeTypeManager.TrySetGnomeType(player, GnomeTypeManager.Parse(raw), out message); default: { message = "This race has no subtypes."; return false; } IL_00f9: flag = true; goto IL_00ff; IL_00ff: if (!flag) { message = "Unknown lineage '" + raw + "'."; return false; } return ElfTypeManager.TrySetElfType(player, ElfTypeManager.ParseElfType(raw), out message); } } public override List CommandOptionList() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return new List(); } return RaceManager.GetRace(localPlayer) switch { RaceType.Elf => new List { "high", "wood", "drow" }, RaceType.Giant => new List { "cloud", "fire", "frost", "hill", "stone", "storm" }, RaceType.Genasi => new List { "air", "earth", "fire", "water" }, RaceType.Gnome => new List { "forest", "rock" }, _ => new List(), }; } } }