Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Ent1tyRacesBETA v2.0.0
plugins\Ent1tyRaces.dll
Decompiled 20 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; 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.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.0.0")] [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.0.0"; 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<VampireDayNightIndicator>(); Logger.LogInfo((object)"Ent1tyRaces v2.0.0 loaded OK. Chat: /race dwarf | /type forest | /legacy abyssal"); } 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 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<RectTransform>(); ((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<TextMeshProUGUI>(); _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<Player> FlyingPlayers = new HashSet<Player>(); 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<Rigidbody>(); 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<Rigidbody>(); 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<Rigidbody>(); 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<Rigidbody>(); 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<Heightmap>() != (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<WaterVolume>() != (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<ItemDrop>(); 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<VisEquipment>(); 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_00b6: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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<Collider>()); _ball.transform.localScale = Vector3.one * 0.22f; MeshRenderer component = _ball.GetComponent<MeshRenderer>(); 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 = Color.white }; } } _light = _ball.AddComponent<Light>(); _light.color = Color.white; _light.intensity = 1.4f; _light.range = 10f; Object.DontDestroyOnLoad((Object)(object)_ball); } } internal static class AasimarHealBreath { private const float AoeRadius = 4f; private const float AoeRange = 8f; public static void Update(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_0085: 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_008c: 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_0096: 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_0107: 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_011f: 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) if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || RaceManager.GetRace(player) != RaceType.Aasimar || !DragonbornBreathInput.AreBreathButtonsHeld() || !DragonbornBreathInput.IsAttackPressed()) { return; } DragonbornBreathCombat.ForceBlockDown((Humanoid)(object)player); DragonbornBreathCombat.CancelUnarmedAttack((Humanoid)(object)player); float breathElementDamage = DragonbornBreath.GetBreathElementDamage(player); if (breathElementDamage <= 0f) { return; } float num = 12f; if (!((Character)player).HaveStamina(num + 0.1f)) { ((Character)player).Message((MessageType)2, "Not enough stamina to heal.", 0, (Sprite)null); return; } ((Character)player).UseStamina(num); Vector3 eyePoint = ((Character)player).GetEyePoint(); Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 val = eyePoint + lookDir * 4f; SpawnHealFx(eyePoint); ((Character)player).Heal(breathElementDamage * 0.35f, true); List<Character> list = new List<Character>(); Character.GetCharactersInRange(val, 4f, list); foreach (Character item in list) { 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)) { item.Heal(breathElementDamage, true); } } } } private static void SpawnHealFx(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_Potion_health_medium") ?? ZNetScene.instance.GetPrefab("vfx_HealthUpgrade") ?? ZNetScene.instance.GetPrefab("fx_guardstone_activate"); if ((Object)(object)val != (Object)null) { Object.Instantiate<GameObject>(val, pos, Quaternion.identity); } } } } 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; 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; } } } public static bool TryAirJump(Player player) { //IL_0093: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00e2: 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) //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_00ef: 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_00fe: 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_010a: 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_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_0120: 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) if ((Object)(object)player == (Object)null || RaceManager.GetRace(player) != RaceType.Aasimar || ((Character)player).IsOnGround()) { return false; } if (_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; } 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 BodyScale { public const float Giant = 2f; public const float SlightlySmall = 0.75f; public const float VerySmall = 0.5f; 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.75f, RaceType.Tiefling => 0.75f, RaceType.Halfling => 0.5f, _ => 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<Player, Coroutine> ActiveRoutines = new Dictionary<Player, Coroutine>(); public static void StartBurst(Player attacker, List<BreathStrikeTarget> 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<BreathStrikeTarget> 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<BreathStrikeTarget> strikes) { for (int i = 0; i < 5; i++) { ApplyTickToTargets(attacker, strikes); } } private static void ApplyTickToTargets(Player attacker, List<BreathStrikeTarget> 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<BreathElement>(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<ZNetView>(); 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<Character>() == (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<Character>() != (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<GameObject>(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<BreathElement, string[]> ElementFxPrefabs = new Dictionary<BreathElement, string[]> { { 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<Character> list = new List<Character>(); Character.GetCharactersInRange(val, 4f, list); List<BreathStrikeTarget> list2 = new List<BreathStrikeTarget>(); 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; } 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<GameObject>(prefab, position, Quaternion.LookRotation(direction))); break; } } } private static void ScheduleFxCleanup(GameObject instance) { if (!((Object)(object)instance == (Object)null)) { TimedDestruction component = instance.GetComponent<TimedDestruction>(); 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; } if (RaceManager.GetRace(player) != RaceType.Dragonborn) { 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 DwarfCrater { private const float Radius = 1f; private const float Depth = 0.35f; private static readonly MethodInfo DoOperationMethod = AccessTools.Method(typeof(TerrainComp), "DoOperation", new Type[2] { typeof(Vector3), typeof(Settings) }, (Type[])null); public static void TryOnHit(Player attacker, Character target) { //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_0059: 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_0060: 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_0094: 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_00a0: 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_00bd: 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_00cb: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00f7: 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)attacker == (Object)null) && !((Object)(object)target == (Object)null) && !((Object)(object)attacker != (Object)(object)Player.m_localPlayer) && RaceManager.GetRace(attacker) == RaceType.Dwarf && Input.GetMouseButton(2)) { Vector3 position = ((Component)target).transform.position; float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.GetGroundHeight(position) : position.y); object obj = TerrainComp.FindTerrainCompiler(position); if (obj == null) { Heightmap obj2 = Heightmap.FindHeightmap(position); obj = ((obj2 != null) ? obj2.GetAndCreateTerrainCompiler() : null); } TerrainComp val = (TerrainComp)obj; if (!((Object)(object)val == (Object)null) && !(DoOperationMethod == null)) { Settings val2 = new Settings { m_level = true, m_levelRadius = 1f, m_levelOffset = 0f, m_square = false, m_raise = false, m_smooth = true, m_smoothRadius = 1.35f, m_smoothPower = 3f, m_paintCleared = false }; DoOperationMethod.Invoke(val, new object[2] { (object)new Vector3(position.x, num - 0.35f, position.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<ElfType>(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<FrostAuraFollower>(); 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>(); frostAuraFollower._target = target; frostAuraFollower._hardExpireAt = Time.time + maxSeconds; frostAuraFollower.BuildParticles(); } } private void RefreshParticles() { ParticleSystem component = ((Component)this).GetComponent<ParticleSystem>(); 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<ParticleSystem>(); 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<ParticleSystemRenderer>(); 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)nu