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 WeaponArts v0.14.1
WeaponArts.dll
Decompiled 2 days 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.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace WeaponArts; [BepInPlugin("j1ga.weaponarts", "Weapon Arts", "0.14.1")] public class WeaponArtsPlugin : BaseUnityPlugin { internal enum ArtKind { DamageMult, Dot, Stagger, Vampirism, AoEHeal, AoEBurst, Pierce, Bleed, Expose, Berserk } internal class Art { public string Id; public int Hash; public string NameRu; public string DescRu; public string NameEn; public string DescEn; public ArtKind Kind; public SkillType Skill; public int Hand; public bool UsesEitr; public ConfigEntry<float> Mag; public ConfigEntry<float> Win; public ConfigEntry<float> Cd; public ConfigEntry<float> Cost; public ConfigEntry<float> Radius; public ConfigEntry<float> HLo0; public ConfigEntry<float> HLo1; public ConfigEntry<float> HHi0; public ConfigEntry<float> HHi1; public bool IncludeSelf; public ConfigEntry<float> Bonus; public ConfigEntry<float> Linger; public ConfigEntry<int> Shots; public ConfigEntry<float> Regen; public bool Heal1H; public string Name => L(NameEn ?? NameRu, NameRu); public string Desc => L(DescEn ?? DescRu, DescRu); public Art En(string name, string desc) { NameEn = name; DescEn = desc; return this; } } private struct Bleed { public float Dps; public float Until; public ZDOID Attacker; } private class HitState { public Art Art; public float Hp; public float Before; public float After; } [HarmonyPatch(typeof(MonsterAI), "UpdateTarget")] private static class MonsterAI_UpdateTarget_Patch { private static void Postfix(MonsterAI __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null || instance._tainted.Count == 0 || (Object)(object)__instance == (Object)null) { return; } try { Character component = ((Component)__instance).GetComponent<Character>(); if (!((Object)(object)component == (Object)null)) { Character val = instance.HeldTarget(component.GetZDOID()); if (!((Object)(object)val == (Object)null) && !val.IsDead() && (Object)(object)((BaseAI)__instance).GetTargetCreature() != (Object)(object)val) { instance.ForceTarget(__instance, val); } } } catch (Exception e) { instance.Fail("UpdateTarget", e); } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] private static class Character_RPC_Damage_Patch { private static void Prefix(Character __instance, HitData hit, out HitState __state) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) __state = null; if (s_bleedTick) { s_penActive = true; s_penFraction = 1f; return; } s_penActive = false; WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.Active || (Object)(object)__instance == (Object)null || hit == null) { return; } try { if (instance.TauntActive && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { float num = Mathf.Clamp(instance._tauntReduction, 0f, 0.9f); if (num > 0f) { hit.ApplyModifier(1f - num); } } if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && instance.BerserkActive) { float berserkReduction = instance.BerserkReduction; if (berserkReduction > 0f) { hit.ApplyModifier(1f - berserkReduction); } } if (__instance.IsPlayer()) { return; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null || !attacker.IsPlayer()) { return; } float before = TotalDamage(hit.m_damage); bool flag = __instance.IsBoss(); float num2 = (flag ? instance.Sv(instance._cfgBossFactor) : 1f); float num3 = instance.ExposedFraction(__instance); if (num3 > 0f) { hit.ApplyModifier(1f + num3); } if (!instance.AttackerArt(attacker, out var a, out var power)) { if (num3 > 0f && instance._cfgDebug.Value) { __state = new HitState(); __state.Hp = __instance.GetHealth(); __state.Before = before; __state.After = TotalDamage(hit.m_damage); } return; } switch (a.Kind) { case ArtKind.DamageMult: hit.ApplyModifier(1f + (power - 1f) * num2); break; case ArtKind.Dot: { ref DamageTypes damage = ref hit.m_damage; damage.m_poison += power * num2; break; } case ArtKind.Bleed: instance.RegisterBleed(__instance, power * num2, hit.m_attacker); break; case ArtKind.Stagger: if (!flag) { hit.m_staggerMultiplier = Mathf.Max(hit.m_staggerMultiplier, 100f); } break; case ArtKind.Pierce: s_penActive = true; s_penFraction = Mathf.Clamp(power * num2, 0f, 0.95f); if (a.Bonus != null) { hit.ApplyModifier(1f + instance.Sv(a.Bonus) * num2); } break; case ArtKind.Expose: instance.MarkExposed(__instance, Mathf.Clamp(power * num2, 0f, 1f), instance.Sv(a.Linger)); break; } if (a.Kind == ArtKind.Vampirism || instance._cfgDebug.Value) { __state = new HitState(); __state.Art = a; __state.Hp = __instance.GetHealth(); __state.Before = before; __state.After = TotalDamage(hit.m_damage); } } catch (Exception e) { instance.Fail("RPC_Damage", e); } } private static void Finalizer() { s_penActive = false; } private static void Postfix(Character __instance, HitData hit, HitState __state) { s_penActive = false; WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null || __state == null || (Object)(object)__instance == (Object)null || hit == null) { return; } try { float num = __state.Hp - __instance.GetHealth(); Art art = __state.Art; instance.Debug("hit " + ((Object)__instance).name + " by " + ((art != null) ? art.Id : "-") + ": damage " + __state.Before.ToString("0.0") + " -> " + __state.After.ToString("0.0") + " (x" + ((__state.Before > 0f) ? (__state.After / __state.Before) : 1f).ToString("0.00") + "), hp lost " + num.ToString("0.0") + ", exposed " + instance.ExposedFraction(__instance).ToString("0.00") + ", staggering " + __instance.IsStaggering()); if (art == null || art.Kind != ArtKind.Vampirism || num <= 0f) { return; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null || !instance.AttackerArt(attacker, out var a, out var power) || a.Kind != ArtKind.Vampirism || power <= 0f) { return; } float num2 = (__instance.IsBoss() ? instance.Sv(instance._cfgBossFactor) : 1f); float num3 = num * power * num2; if (num3 <= 0f) { return; } ZNetView component = ((Component)attacker).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { if (component.IsOwner()) { attacker.Heal(num3, false); return; } component.InvokeRPC(component.GetZDO().GetOwner(), "RPC_Heal", new object[2] { num3, false }); } } catch (Exception e) { instance.Fail("RPC_Damage.post", e); } } } [HarmonyPatch(typeof(HitData), "ApplyResistance")] private static class HitData_ApplyResistance_Patch { private static void Prefix(HitData __instance, out DamageTypes __state) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) __state = __instance.m_damage; } private static void Postfix(HitData __instance, DamageTypes __state) { if (s_penActive && !(WeaponArtsPlugin.s_penFraction <= 0f)) { float s_penFraction = WeaponArtsPlugin.s_penFraction; __instance.m_damage.m_blunt = Restore(__state.m_blunt, __instance.m_damage.m_blunt, s_penFraction); __instance.m_damage.m_slash = Restore(__state.m_slash, __instance.m_damage.m_slash, s_penFraction); __instance.m_damage.m_pierce = Restore(__state.m_pierce, __instance.m_damage.m_pierce, s_penFraction); __instance.m_damage.m_fire = Restore(__state.m_fire, __instance.m_damage.m_fire, s_penFraction); __instance.m_damage.m_frost = Restore(__state.m_frost, __instance.m_damage.m_frost, s_penFraction); __instance.m_damage.m_lightning = Restore(__state.m_lightning, __instance.m_damage.m_lightning, s_penFraction); __instance.m_damage.m_poison = Restore(__state.m_poison, __instance.m_damage.m_poison, s_penFraction); __instance.m_damage.m_spirit = Restore(__state.m_spirit, __instance.m_damage.m_spirit, s_penFraction); } } private static float Restore(float before, float after, float f) { if (after <= 0f || after >= before) { return after; } return after + (before - after) * f; } } [HarmonyPatch(typeof(Projectile), "Setup")] private static class Projectile_Setup_Patch { private static void Postfix(Character owner, ItemData item) { WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null || (Object)(object)owner == (Object)null || (Object)(object)owner != (Object)(object)Player.m_localPlayer) { return; } try { instance.OnLocalShot(item); } catch (Exception e) { instance.Fail("Projectile.Setup", e); } } } [HarmonyPatch(typeof(Chat), "OnNewChatMessage")] private static class Chat_OnNewChatMessage_Patch { private static void Postfix(long senderID, Type type, string text) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.Active) { return; } try { instance.OnChat(senderID, type, text); } catch (Exception e) { instance.Fail("chat", e); } } } [HarmonyPatch(typeof(Character), "Damage")] private static class Character_Damage_Patch { private static void Prefix(Character __instance, HitData hit) { WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null || hit == null || instance._proxies.Count == 0) { return; } try { instance.ReduceProxyHit(__instance, hit); } catch (Exception e) { instance.Fail("Damage", e); } } } private class Proxy { public ZDOID Id; public string Name; public int LastEmoteId; public float LastSeen; public float CooldownUntil; public bool ReadyAnnounced; public string ArtName = ""; public int ArtHash; public float ArtUntil; public float ArtPower; public float TauntUntil; public float TauntReduction; public int TauntCount; public float NextReapply; public long SinceMs; public float BerserkUntil; public float BerserkReduction; public float BerserkRegen; public float NextRegen; } [HarmonyPatch(typeof(ZNet), "Awake")] private static class ZNet_Awake_Patch { private static void Postfix() { WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null) { return; } try { instance.RegisterRpc(); } catch (Exception e) { instance.Fail("ZNet.Awake", e); } } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] private static class ZNet_RPC_PeerInfo_Patch { private static void Postfix(ZNet __instance, ZRpc rpc) { WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null || instance._disabledByErrors) { return; } try { instance.OnPeerInfo(__instance, rpc); } catch (Exception e) { instance.Fail("ZNet.RPC_PeerInfo", e); } } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] private static class ZNet_OnDestroy_Patch { private static void Postfix() { WeaponArtsPlugin instance = Instance; if ((Object)(object)instance == (Object)null) { return; } try { ((MonoBehaviour)instance).StopAllCoroutines(); instance.ClearServerValues(); } catch (Exception e) { instance.Fail("ZNet.OnDestroy", e); } } } private struct Hold { public float Until; public ZDOID Target; public long Since; } private struct AiSettings { public MonsterAI Ai; public float CircleInterval; public bool Circulate; public bool CirculateFlying; } private const float ShotGrace = 2.5f; internal const float MinWindow = 6f; public const string Guid = "j1ga.weaponarts"; public const string Name = "Weapon Arts"; public const string Version = "0.14.1"; private const int MaxErrors = 25; private const string VisualHelp = "None; GuardianPower (the forsaken-power activation flash); or a registered prefab name, e.g. fx_eikthyr_stomp, fx_Adrenaline1, fx_guardstone_activate, vfx_perfectblock, fx_gjall_taunt."; private const float ProxyForgetAfter = 120f; private const float ProxyShotWindow = 10f; private const string SyncRpc = "j1ga.weaponarts.config"; private const int SyncVersion = 1; private const float ReapplyInterval = 0.25f; private readonly List<Art> _arts = new List<Art>(); private readonly Dictionary<int, Art> _artByHash = new Dictionary<int, Art>(); private readonly Dictionary<string, float> _activeUntil = new Dictionary<string, float>(); private float _berserkUntil; private float _berserkReduction; private float _berserkRegen; private float _berserkNextTick; internal static readonly int ZdoExposedUntil = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.exposed.until"); internal static readonly int ZdoExposed = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.exposed"); private readonly Dictionary<string, int> _shotsLeft = new Dictionary<string, int>(); internal static bool s_bleedTick; private ConfigEntry<float> _cfgBleedSeconds; private ConfigEntry<float> _cfgBleedInterval; private readonly Dictionary<ZDOID, Bleed> _bleeds = new Dictionary<ZDOID, Bleed>(); private readonly List<ZDOID> _bleedScratch = new List<ZDOID>(); private float _nextBleedTick; private ConfigEntry<bool> _cfgEnabled; private ConfigEntry<bool> _cfgDebug; private ConfigEntry<KeyboardShortcut> _cfgKey; private ConfigEntry<bool> _cfgShowHud; private static ConfigEntry<string> _cfgLanguage; private ConfigEntry<float> _cfgGlobalCooldown; private ConfigEntry<float> _cfgBossFactor; private ConfigEntry<float> _cfgSkillPowerScale; private ConfigEntry<float> _cfgTierPowerScale; private ConfigEntry<float> _cfgSkillDurationScale; private ConfigEntry<float> _cfgRefWeaponDamage; public static WeaponArtsPlugin Instance; private Harmony _harmony; internal static readonly int ZdoArt = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.art"); internal static readonly int ZdoUntil = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.until"); internal static readonly int ZdoPower = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.power"); private readonly Dictionary<string, float> _cooldownUntil = new Dictionary<string, float>(); private float _gcdUntil; private string _lastArtId = ""; private float _lastActivated; private int _errorCount; private bool _disabledByErrors; private readonly HashSet<string> _loggedErrors = new HashSet<string>(); private string _lastLoadout = ""; private ConfigEntry<string> _cfgTauntSound; private ConfigEntry<string> _cfgTauntVisual; private readonly HashSet<string> _warnedEffects = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private ConfigEntry<string> _cfgArtSound; private ConfigEntry<string> _cfgArtVisual; private ConfigEntry<string> _cfgHealVisual; private ConfigEntry<string> _cfgMendVisual; private ConfigEntry<string> _cfgMendAnimation; private EffectList _shamanCast; private EffectList _shamanHit; private GameObject _shamanAoe; private bool _shamanResolved; private static readonly FieldInfo s_zanim = AccessTools.Field(typeof(Character), "m_zanim"); internal static bool s_penActive; internal static float s_penFraction; private ConfigEntry<bool> _cfgProxy; private ConfigEntry<string> _cfgProxyProvider; private ConfigEntry<string> _cfgProxyEmote; private ConfigEntry<string> _cfgProxyChat; private ConfigEntry<string> _cfgProxyQuery; private ConfigEntry<float> _cfgProxySkill; private ConfigEntry<float> _cfgProxyCooldownFactor; private ConfigEntry<bool> _cfgProxyAnnounce; private ConfigEntry<bool> _cfgProxyAnnounceReady; private static readonly int ModMarkHash = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.mod"); private float _nextMark; private readonly Dictionary<ZDOID, Proxy> _proxies = new Dictionary<ZDOID, Proxy>(); private readonly List<ZDOID> _proxyScratch = new List<ZDOID>(); private float _nextProxyPoll; private ConfigEntry<bool> _cfgSync; private bool _syncDirty; private bool _serverSynced; private readonly Dictionary<string, object> _serverByKey = new Dictionary<string, object>(); private FieldInfo _fiTargetCreature; private FieldInfo _fiTargetStatic; private FieldInfo _fiLastKnownTargetPos; private FieldInfo _fiBeenAtLastPos; private FieldInfo _fiTimeSinceSensed; private MethodInfo _miSetAlerted; private MethodInfo _miGetBlocker; private ConfigEntry<string> _cfgShieldMode; private ConfigEntry<float> _cfgTowerParry; private ConfigEntry<float> _cfgTauntRadius; private ConfigEntry<float> _cfgTauntDuration; private ConfigEntry<float> _cfgTauntCooldown; private ConfigEntry<float> _cfgTauntStamina; private ConfigEntry<float> _cfgTauntReductionBase; private ConfigEntry<float> _cfgTauntReductionBest; private ConfigEntry<float> _cfgTauntRefBlock; private ConfigEntry<bool> _cfgTauntBosses; private ConfigEntry<bool> _cfgTauntTamed; private ConfigEntry<bool> _cfgTauntAggravate; private ConfigEntry<bool> _cfgTauntChargeStraight; private ConfigEntry<float> _cfgTauntSkillGain; private ConfigEntry<float> _cfgTauntSkillCap; private readonly Dictionary<ZDOID, Hold> _tainted = new Dictionary<ZDOID, Hold>(); private readonly List<ZDOID> _tauntScratch = new List<ZDOID>(); private static readonly int HoldByHash = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.holdby"); private static readonly int HoldUntilHash = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.holduntil"); private static readonly int HoldSinceHash = StringExtensionMethods.GetStableHashCode("j1ga.weaponarts.holdsince"); private readonly Dictionary<ZDOID, AiSettings> _straight = new Dictionary<ZDOID, AiSettings>(); private float _tauntUntil; private float _tauntCdUntil; private float _tauntNextReapply; private float _tauntReduction; private long _tauntSinceMs; private int _tauntCount; private ConfigEntry<float> _cfgHudX; private ConfigEntry<float> _cfgHudY; private ConfigEntry<int> _cfgHudFont; private GUIStyle _nameStyle; private GUIStyle _descStyle; private GUIStyle _shadowStyle; private int _styleSize = -1; internal bool BerserkActive => Time.time < _berserkUntil; internal float BerserkReduction { get { if (!BerserkActive) { return 0f; } return _berserkReduction; } } private bool Active { get { if (!_disabledByErrors) { return Sb(_cfgEnabled); } return false; } } private bool ProxyOn => _cfgProxy.Value; private bool TauntActive { get { if (Active) { return Time.time < _tauntUntil; } return false; } } private bool CanForceTarget { get { if (_fiTargetCreature != null && _fiTargetStatic != null && _fiLastKnownTargetPos != null && _fiBeenAtLastPos != null) { return _fiTimeSinceSensed != null; } return false; } } private Art Add(string id, string name, string desc, ArtKind kind, SkillType skill, int hand, float mag, float win, float cd, float cost, bool eitr) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown Art art = new Art(); art.Id = id; art.Hash = StringExtensionMethods.GetStableHashCode(id); art.NameRu = name; art.DescRu = desc; art.Kind = kind; art.Skill = skill; art.Hand = hand; art.UsesEitr = eitr; string text = "03 Arts - " + id; art.Mag = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Magnitude", mag, "Base strength at skill 0 with the weakest weapon (grows with TierPowerBonus/SkillPowerBonus). Damage arts: multiplier; DoT: poison/bleed per hit; lifesteal: fraction; pierce: fraction of resistance ignored; expose: extra damage taken by the target; stagger: unused (every hit staggers)."); if (kind == ArtKind.Pierce) { art.Bonus = ((BaseUnityPlugin)this).Config.Bind<float>(text, "DamageBonus", 0.225f, new ConfigDescription("Extra damage on top of the resistance ignore (0.15 = +15%), so the art matters on unresisting targets too.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), new object[0])); } if (kind == ArtKind.Berserk) { art.Regen = ((BaseUnityPlugin)this).Config.Bind<float>(text, "RegenPerSecond", 10f, new ConfigDescription("HP restored per second while berserk (fixed, not scaled by tier/skill).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), new object[0])); } if (kind == ArtKind.Expose) { art.Linger = ((BaseUnityPlugin)this).Config.Bind<float>(text, "ExposeSeconds", 8f, new ConfigDescription("Seconds a struck target stays exposed (takes more damage from everyone).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), new object[0])); } art.Win = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Window", win, new ConfigDescription("Seconds the art lasts (before skill/tier scaling; +50% cap).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(6f, 30f), new object[0])); art.Cd = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Cooldown", cd, new ConfigDescription("Seconds before reuse.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 600f), new object[0])); art.Cost = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Cost", cost, new ConfigDescription("Stamina (or eitr) spent.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[0])); _arts.Add(art); _artByHash[art.Hash] = art; return art; } private Art AddHeal(string id, string name, string desc, SkillType skill, int hand, float cd, float cost, float lo0, float lo1, float hi0, float hi1, float radius, bool self) { //IL_002f: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown Art art = new Art(); art.Id = id; art.Hash = StringExtensionMethods.GetStableHashCode(id); art.NameRu = name; art.DescRu = desc; art.Kind = ArtKind.AoEHeal; art.Skill = skill; art.Hand = hand; art.IncludeSelf = self; string text = "03 Arts - " + id; art.Cd = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Cooldown", cd, new ConfigDescription("Seconds before reuse.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 600f), new object[0])); art.Cost = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Cost", cost, new ConfigDescription("Stamina spent.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[0])); art.Radius = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Radius", radius, new ConfigDescription("Heal radius, m.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 40f), new object[0])); art.HLo0 = ((BaseUnityPlugin)this).Config.Bind<float>(text, "HealLoMin", lo0, "Lower bound of the heal roll at min tier/skill."); art.HLo1 = ((BaseUnityPlugin)this).Config.Bind<float>(text, "HealLoMax", lo1, "Lower bound at max tier/skill."); art.HHi0 = ((BaseUnityPlugin)this).Config.Bind<float>(text, "HealHiMin", hi0, "Upper bound of the heal roll at min tier/skill."); art.HHi1 = ((BaseUnityPlugin)this).Config.Bind<float>(text, "HealHiMax", hi1, "Upper bound at max tier/skill."); _arts.Add(art); _artByHash[art.Hash] = art; return art; } private Art AddBurst(string id, string name, string desc, SkillType skill, int hand, float mag, float cd, float cost, float radius) { //IL_002f: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown Art art = new Art(); art.Id = id; art.Hash = StringExtensionMethods.GetStableHashCode(id); art.NameRu = name; art.DescRu = desc; art.Kind = ArtKind.AoEBurst; art.Skill = skill; art.Hand = hand; string text = "03 Arts - " + id; art.Mag = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Magnitude", mag, "Damage as a fraction of weapon damage (1.3 = 130%)."); art.Cd = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Cooldown", cd, new ConfigDescription("Seconds before reuse.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 600f), new object[0])); art.Cost = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Cost", cost, new ConfigDescription("Stamina spent.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[0])); art.Radius = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Radius", radius, new ConfigDescription("Burst radius, m.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), new object[0])); _arts.Add(art); _artByHash[art.Hash] = art; return art; } private void BuildArts() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0064: 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_00df: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Expected O, but got Unknown //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Expected O, but got Unknown //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) SkillType skill = (SkillType)1; SkillType skill2 = (SkillType)7; SkillType skill3 = (SkillType)5; SkillType skill4 = (SkillType)4; SkillType skill5 = (SkillType)2; SkillType skill6 = (SkillType)11; SkillType skill7 = (SkillType)8; SkillType skill8 = (SkillType)14; Add("Onslaught", "Натиск", "меч 2H: +урон по цели", ArtKind.DamageMult, skill, 2, 1.525f, 6f, 43f, 30f, eitr: false).En("Onslaught", "2H sword: more damage to the target"); Add("Bloodthirst", "Кровожадность", "меч 1H: вампиризм с урона", ArtKind.Vampirism, skill, 1, 0.3f, 6f, 48f, 25f, eitr: false).En("Bloodthirst", "1H sword: lifesteal from damage dealt"); Add("Berserk", "Берсерк", "боевой топор: меньше урона по себе + реген HP", ArtKind.Berserk, skill2, 2, 0.375f, 10f, 54f, 30f, eitr: false).En("Berserk", "battleaxe: take less damage + regenerate HP"); Add("Bleed", "Кровотечение", "топор 1H: физический DoT (обходит броню)", ArtKind.Bleed, skill2, 1, 12f, 6f, 32f, 25f, eitr: false).En("Bleed", "1H axe: physical damage over time"); Add("Rend", "Рассечение", "копьё: цель уязвима (+урон от всех)", ArtKind.Expose, skill3, 1, 0.3f, 6f, 38f, 30f, eitr: false).En("Rend", "spear: the target is exposed (more damage from everyone)"); Add("Impale", "Пронзание", "пика: сильный игнор сопротивлений + урон", ArtKind.Pierce, skill3, 2, 0.95f, 6f, 48f, 30f, eitr: false).En("Impale", "pike: strong resistance ignore + damage"); Add("Crushing", "Дробящий", "атгейр: каждый удар вгоняет в стаггер", ArtKind.Stagger, skill4, 0, 1f, 6f, 48f, 30f, eitr: false).En("Crushing", "atgeir: every hit staggers"); Add("Envenom", "Отравление", "ножи: сильный яд на ударах", ArtKind.Dot, skill5, 0, 18f, 6f, 32f, 25f, eitr: false).En("Envenom", "knives: strong poison on hits"); Add("Fury", "Ярость", "кулаки: крит на каждом ударе", ArtKind.DamageMult, skill6, 0, 2f, 6f, 43f, 25f, eitr: false).En("Fury", "fists: a critical hit on every blow"); Art art = Add("Focus", "Фокус", "лук: следующие выстрелы критуют", ArtKind.DamageMult, skill7, 0, 2.5f, 22.5f, 48f, 20f, eitr: false).En("Focus", "bow: the next shots are critical"); Art art2 = Add("PiercingBolts", "Бронебой", "арбалет: болты игнорят сопротивления + урон", ArtKind.Pierce, skill8, 0, 0.9f, 22.5f, 48f, 20f, eitr: false).En("Piercing Bolts", "crossbow: bolts ignore resistances + damage"); art.Shots = ((BaseUnityPlugin)this).Config.Bind<int>("03 Arts - Focus", "Shots", 3, new ConfigDescription("The art lasts this many shots (Window is the time cap).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), new object[0])); art2.Shots = ((BaseUnityPlugin)this).Config.Bind<int>("03 Arts - PiercingBolts", "Shots", 3, new ConfigDescription("The art lasts this many shots (Window is the time cap).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), new object[0])); SkillType skill9 = (SkillType)3; SkillType skill10 = (SkillType)9; SkillType skill11 = (SkillType)10; AddHeal("Rally", "Клич", "кувалда 2H: хил себе и союзникам", skill9, 2, 60f, 40f, 15f, 60f, 25f, 100f, 10f, self: true).En("Rally", "2H sledge: heal yourself and allies"); AddHeal("Mend", "Исцеление", "булава 1H: хил только союзникам", skill9, 1, 50f, 30f, 10f, 40f, 16f, 65f, 8f, self: false).En("Mend", "1H mace: heal allies only").Heal1H = true; Add("EitrSurgeElem", "Вспышка эйтра", "посох стихий: +магический урон", ArtKind.DamageMult, skill10, 0, 1.6f, 6f, 60f, 30f, eitr: true).En("Eitr Surge", "elemental staff: more magic damage"); Add("EitrSurgeBlood", "Вспышка эйтра", "посох крови: +магический урон", ArtKind.DamageMult, skill11, 0, 1.6f, 6f, 60f, 30f, eitr: true).En("Eitr Surge", "blood staff: more magic damage"); } private static int HandOf(ItemType t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if ((int)t == 3) { return 1; } if ((int)t == 14 || (int)t == 22 || (int)t == 20) { return 2; } return 0; } internal Art ArtFor(ItemData weapon) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (weapon == null || weapon.m_shared == null) { return null; } SkillType skillType = weapon.m_shared.m_skillType; int num = HandOf(weapon.m_shared.m_itemType); for (int i = 0; i < _arts.Count; i++) { Art art = _arts[i]; if (art.Skill == skillType && (art.Hand == 0 || art.Hand == num)) { return art; } } return null; } internal Art CurrentArt(Player p) { if ((Object)(object)p == (Object)null) { return null; } return ArtFor(((Humanoid)p).GetCurrentWeapon()); } internal static float TotalDamage(DamageTypes d) { return d.m_blunt + d.m_slash + d.m_pierce + d.m_fire + d.m_frost + d.m_lightning + d.m_poison + d.m_spirit; } private static float WeaponTotalDamage(ItemData w) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (w != null) { return TotalDamage(w.GetDamage()); } return 0f; } internal bool AttackerArt(Character attacker, out Art a, out float power) { a = null; power = 0f; if ((Object)(object)attacker == (Object)null) { return false; } int hash = 0; ZDO val = OwnZdo(attacker); if (val != null) { hash = val.GetInt(ZdoArt, 0); if (hash != 0) { long num = val.GetLong(ZdoUntil, 0L); if (num == 0 || NowTicks() >= num) { hash = 0; } else { power = val.GetFloat(ZdoPower, 0f); } } } if (hash == 0 && !ProxyWindowArt(attacker, out hash, out power)) { return false; } if (_artByHash.TryGetValue(hash, out a)) { return power > 0f; } return false; } private void TryActivate(Player p) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) if (TauntShieldEquipped(p)) { ActivateTaunt(p); return; } ItemData currentWeapon = ((Humanoid)p).GetCurrentWeapon(); Art art = ArtFor(currentWeapon); if (art == null) { Message(p, L("No art for this weapon", "Нет активки для этого оружия")); return; } float time = Time.time; if (time < _gcdUntil) { Message(p, L("Global cooldown: ", "Общий КД: ") + Mathf.CeilToInt(_gcdUntil - time) + L("s", "с")); return; } if (_cooldownUntil.TryGetValue(art.Id, out var value) && time < value) { Message(p, art.Name + L(": cooldown ", ": КД ") + Mathf.CeilToInt(value - time) + L("s", "с")); return; } float value2 = art.Cost.Value; if (value2 > 0f && !(art.UsesEitr ? ((Character)p).HaveEitr(value2) : ((Character)p).HaveStamina(value2))) { Message(p, art.Name + (art.UsesEitr ? L(": not enough eitr", ": не хватает эйтра") : L(": not enough stamina", ": не хватает стамины"))); return; } float num = Mathf.Clamp01(WeaponTotalDamage(currentWeapon) / Mathf.Max(1f, Sv(_cfgRefWeaponDamage))); float skillFactor = ((Character)p).GetSkillFactor(art.Skill); float num2 = PowerScale(num, skillFactor); float p2 = 0.5f * num + 0.5f * skillFactor; if (value2 > 0f) { if (art.UsesEitr) { ((Character)p).UseEitr(value2); } else { ((Character)p).UseStamina(value2); } } string text; if (art.Kind == ArtKind.AoEHeal) { text = art.Name + " (" + DoHeal(p, art, p2) + ")"; } else if (art.Kind == ArtKind.AoEBurst) { text = art.Name + " (" + DoBurst(p, art, currentWeapon, num2) + ")"; } else { float num3 = Sv(art.Mag); float num4 = ((art.Kind == ArtKind.DamageMult || art.Kind == ArtKind.Stagger) ? (1f + (num3 - 1f) * num2) : (num3 * num2)); float num5 = Mathf.Clamp(skillFactor * Sv(_cfgSkillDurationScale) * (0.5f + 0.5f * num), 0f, 0.5f); float num6 = Mathf.Max(6f, Sv(art.Win)) * (1f + num5); ZDO val = OwnZdo((Character)(object)p); if (val != null) { val.Set(ZdoArt, art.Hash, false); val.Set(ZdoUntil, NowTicks() + (long)(num6 * 10000000f)); val.Set(ZdoPower, num4); } _activeUntil[art.Id] = time + num6; if (art.Kind == ArtKind.Berserk) { _berserkUntil = time + num6; _berserkReduction = Mathf.Clamp(num4, 0f, 0.8f); _berserkRegen = ((art.Regen != null) ? Sv(art.Regen) : 0f); _berserkNextTick = time + 1f; } if (art.Shots != null) { _shotsLeft[art.Id] = Mathf.Max(1, art.Shots.Value); text = art.Name + "! " + _shotsLeft[art.Id] + L(" shots (up to ", " выстр. (до ") + FormatTime(num6) + L("s)", "с)"); } else { text = art.Name + "! " + FormatTime(num6) + L("s", "с"); } Debug("Activated " + art.Id + ": power " + num4.ToString("0.00") + ", window " + FormatTime(num6) + "s"); } _cooldownUntil[art.Id] = time + art.Cd.Value; _gcdUntil = time + _cfgGlobalCooldown.Value; _lastArtId = art.Id; _lastActivated = time; try { PlayArtEffects((Humanoid)(object)p, art); } catch (Exception e) { Fail("art effects", e); } Message(p, text); Debug("Activated " + art.Id + " (tier " + FormatTime(num) + ", skill " + FormatTime(skillFactor) + ")"); } private int DoHeal(Player p, Art a, float p01) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) float num = Sv(a.HLo0) + (Sv(a.HLo1) - Sv(a.HLo0)) * p01; float num2 = Sv(a.HHi0) + (Sv(a.HHi1) - Sv(a.HHi0)) * p01; if (num2 < num) { num2 = num; } float num3 = Random.Range(num, num2); float num4 = Sv(a.Radius) * Sv(a.Radius); Vector3 position = ((Component)p).transform.position; int num5 = 0; List<Player> allPlayers = Player.GetAllPlayers(); for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if ((Object)(object)val == (Object)null || ((Character)val).IsDead() || ((Object)(object)val == (Object)(object)p && !a.IncludeSelf)) { continue; } Vector3 val2 = ((Component)val).transform.position - position; if (!(((Vector3)(ref val2)).sqrMagnitude > num4)) { HealChar((Character)(object)val, num3); try { PlayHealHit(a, (Character)(object)val); } catch (Exception e) { Fail("heal hit fx", e); } num5++; } } Debug(a.Id + ": heal " + FormatTime(num3) + " to " + num5 + " (roll " + FormatTime(num) + "-" + FormatTime(num2) + ")"); return num5; } private static void HealChar(Character c, float amt) { if ((Object)(object)c == (Object)null || amt <= 0f) { return; } ZNetView component = ((Component)c).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { if (component.IsOwner()) { c.Heal(amt, true); return; } component.InvokeRPC(component.GetZDO().GetOwner(), "RPC_Heal", new object[2] { amt, true }); } } private int DoBurst(Player p, Art a, ItemData weapon, float s) { //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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00db: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) if (weapon == null) { return 0; } float num = Sv(a.Mag) * s; float num2 = Sv(a.Radius) * Sv(a.Radius); Vector3 position = ((Component)p).transform.position; int num3 = 0; List<Character> allCharacters = Character.GetAllCharacters(); for (int i = 0; i < allCharacters.Count; i++) { Character val = allCharacters[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)p) && !val.IsPlayer() && !val.IsDead() && !val.IsTamed()) { Vector3 val2 = ((Component)val).transform.position - position; if (!(((Vector3)(ref val2)).sqrMagnitude > num2)) { float num4 = (val.IsBoss() ? Sv(_cfgBossFactor) : 1f); HitData val3 = new HitData(); val3.m_damage = weapon.GetDamage(); val3.ApplyModifier(num * num4); val3.SetAttacker((Character)(object)p); val3.m_point = ((Component)val).transform.position; Vector3 val4 = ((Component)val).transform.position - position; val3.m_dir = ((Vector3)(ref val4)).normalized; val.Damage(val3); num3++; } } } return num3; } internal float CooldownLeft(Art a) { if (!_cooldownUntil.TryGetValue(a.Id, out var value)) { return 0f; } return value - Time.time; } internal float ActiveLeft(Art a) { if (!_activeUntil.TryGetValue(a.Id, out var value)) { return 0f; } return value - Time.time; } private void BerserkTick(Player p, float now) { if (!(now >= _berserkUntil) && !(_berserkRegen <= 0f) && !(now < _berserkNextTick)) { _berserkNextTick = now + 1f; ((Character)p).Heal(_berserkRegen, true); Debug("Berserk: +" + FormatTime(_berserkRegen) + " HP, " + FormatTime(_berserkUntil - now) + "s left"); } } internal void MarkExposed(Character c, float fraction, float seconds) { ZDO val = OwnZdo(c); if (val != null && !(fraction <= 0f)) { long num = NowTicks(); float num2 = ((val.GetLong(ZdoExposedUntil, 0L) > num) ? val.GetFloat(ZdoExposed, 0f) : 0f); val.Set(ZdoExposed, Mathf.Max(num2, fraction)); val.Set(ZdoExposedUntil, num + (long)(seconds * 10000000f)); } } internal float ExposedFraction(Character c) { ZDO val = OwnZdo(c); if (val == null || val.GetLong(ZdoExposedUntil, 0L) <= NowTicks()) { return 0f; } return Mathf.Clamp(val.GetFloat(ZdoExposed, 0f), 0f, 1f); } internal int ShotsLeft(Art a) { if (a == null || a.Shots == null || !(ActiveLeft(a) > 0f) || !_shotsLeft.TryGetValue(a.Id, out var value)) { return 0; } return value; } internal void OnLocalShot(ItemData weapon) { Art art = ArtFor(weapon); if (art == null || art.Shots == null || ActiveLeft(art) <= 0f || !_shotsLeft.TryGetValue(art.Id, out var value) || value <= 0) { return; } value--; _shotsLeft[art.Id] = value; Debug(art.Id + ": shot, " + value + " left"); if (value <= 0) { float num = Mathf.Min(ActiveLeft(art), 2.5f); _activeUntil[art.Id] = Time.time + num; ZDO val = OwnZdo((Character)(object)Player.m_localPlayer); if (val != null && val.GetInt(ZdoArt, 0) == art.Hash) { val.Set(ZdoUntil, NowTicks() + (long)(num * 10000000f)); } } } private void BindBleedConfig() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown _cfgBleedSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("05 Bleed", "BleedSeconds", 6f, new ConfigDescription("How long a bleed keeps ticking after the last hit that applied it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), new object[0])); _cfgBleedInterval = ((BaseUnityPlugin)this).Config.Bind<float>("05 Bleed", "TickInterval", 1f, new ConfigDescription("Seconds between bleed ticks.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), new object[0])); } internal void RegisterBleed(Character victim, float dps, ZDOID attacker) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)victim == (Object)null) && !(dps <= 0f)) { Bleed value = default(Bleed); value.Dps = dps; value.Until = Time.time + Sv(_cfgBleedSeconds); value.Attacker = attacker; _bleeds[victim.GetZDOID()] = value; } } private void BleedTick(float now) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_00ce: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (_bleeds.Count == 0 || now < _nextBleedTick) { return; } float num = Mathf.Max(0.25f, _cfgBleedInterval.Value); _nextBleedTick = now + num; _bleedScratch.Clear(); foreach (KeyValuePair<ZDOID, Bleed> bleed in _bleeds) { ZDOID key = bleed.Key; Bleed value = bleed.Value; Character val = ProxyTankChar(key); if ((Object)(object)val == (Object)null || val.IsDead() || now >= value.Until) { _bleedScratch.Add(key); continue; } ZNetView component = ((Component)val).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner()) { HitData val2 = new HitData(); val2.m_damage.m_slash = value.Dps * num; val2.m_attacker = value.Attacker; val2.m_point = ((Component)val).transform.position; val2.m_dir = Vector3.up; s_bleedTick = true; try { val.Damage(val2); } finally { s_bleedTick = false; } } } for (int i = 0; i < _bleedScratch.Count; i++) { _bleeds.Remove(_bleedScratch[i]); } } private void RegisterCommands() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) new ConsoleCommand("weaponarts", "Weapon Arts. 'weaponarts status' - current art and state; 'weaponarts list' - all arts", (ConsoleEvent)delegate(ConsoleEventArgs args) { RunCommand(args); }, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } private static void Say(ConsoleEventArgs args, string text) { if (args != null && (Object)(object)args.Context != (Object)null) { args.Context.AddString(text); } } private void RunCommand(ConsoleEventArgs args) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) try { string text = ((args.Args.Length > 1) ? args.Args[1].ToLowerInvariant() : ""); if (text == "list") { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < _arts.Count; i++) { Art art = _arts[i]; stringBuilder.Append(art.Id).Append(" [").Append(art.Skill) .Append((art.Hand == 1) ? " 1H" : ((art.Hand == 2) ? " 2H" : "")) .Append("]: ") .Append(art.Desc) .Append("\n"); } Say(args, stringBuilder.ToString()); } else if (text == "status") { if (_disabledByErrors) { Say(args, "Weapon Arts is inert after errors."); return; } Player localPlayer = Player.m_localPlayer; Art art2 = CurrentArt(localPlayer); if (art2 == null) { Say(args, "No art for the current weapon."); return; } float num = CooldownLeft(art2); Say(args, art2.Name + " (" + art2.Id + "): " + ((num > 0f) ? ("cooldown " + Mathf.CeilToInt(num) + "s") : "ready") + ". " + art2.Desc); } else { Say(args, "weaponarts status | list"); } } catch (Exception ex) { Say(args, "weaponarts: " + ex.Message); Fail("command", ex); } } internal static string L(string en, string ru) { string text = ((_cfgLanguage != null) ? _cfgLanguage.Value : "Auto"); if (text == "Russian") { return ru; } if (text == "English") { return en; } try { Localization instance = Localization.instance; return (instance != null && instance.GetSelectedLanguage() == "Russian") ? ru : en; } catch { return en; } } private void BindConfig() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Expected O, but got Unknown _cfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("01 General", "Enabled", true, "Master switch."); _cfgDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("01 General", "Debug", false, "Log every activation and applied effect."); _cfgKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("01 General", "AbilityKey", new KeyboardShortcut((KeyCode)99, (KeyCode[])(object)new KeyCode[0]), "Key that triggers the art of the currently equipped weapon."); _cfgShowHud = ((BaseUnityPlugin)this).Config.Bind<bool>("01 General", "ShowHud", true, "Show the current art and its state at the bottom of the screen."); _cfgLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("01 General", "Language", "Auto", new ConfigDescription("Language of the HUD, messages and proxy chat lines. Auto = the game's language (Russian if the game is in Russian, else English). Local, never taken from the server.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Auto", "English", "Russian" }), new object[0])); _cfgGlobalCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("02 Balance", "GlobalCooldown", 30f, new ConfigDescription("Seconds after any activation during which no art can fire (stops weapon-swap spam). Shown in the HUD and on weapon swap.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), new object[0])); _cfgBossFactor = ((BaseUnityPlugin)this).Config.Bind<float>("02 Balance", "BossEffectFactor", 0.5f, new ConfigDescription("Multiplier of art strength against bosses. Crowd control does not apply to bosses regardless (vanilla immunity).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0])); _cfgSkillPowerScale = ((BaseUnityPlugin)this).Config.Bind<float>("02 Balance", "SkillPowerBonus", 0.25f, new ConfigDescription("Extra art strength at weapon skill 100 (0.25 = +25%). The art's Magnitude is the floor (skill 0, weakest weapon).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), new object[0])); _cfgTierPowerScale = ((BaseUnityPlugin)this).Config.Bind<float>("02 Balance", "TierPowerBonus", 0.25f, new ConfigDescription("Extra art strength from a full-tier weapon (see RefWeaponDamage). Adds to SkillPowerBonus.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), new object[0])); _cfgSkillDurationScale = ((BaseUnityPlugin)this).Config.Bind<float>("02 Balance", "SkillDurationScale", 0.5f, new ConfigDescription("Extra art duration from skill+tier, capped at +50% (4s -> max 6s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), new object[0])); _cfgRefWeaponDamage = ((BaseUnityPlugin)this).Config.Bind<float>("02 Balance", "RefWeaponDamage", 100f, new ConfigDescription("Weapon base damage that counts as full tier (tierNorm = weaponDamage / this, capped 1).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 400f), new object[0])); } private float PowerScale(float tierNorm, float skill) { return 1f + Sv(_cfgTierPowerScale) * tierNorm + Sv(_cfgSkillPowerScale) * skill; } private void Awake() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) try { Instance = this; BindConfig(); BindTauntConfig(); BindProxyConfig(); BindSyncConfig(); BindBleedConfig(); BindEffectsConfig(); BindHudConfig(); BindReflection(); BuildArts(); RegisterCommands(); _harmony = new Harmony("j1ga.weaponarts"); _harmony.PatchAll(typeof(WeaponArtsPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Concat("Weapon Arts 0.14.1 loaded. Key: ", _cfgKey.Value, ".")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Awake failed, mod is inert: " + ex)); _disabledByErrors = true; } } private void OnDestroy() { try { ReleaseAllStraight(); if (_harmony != null) { _harmony.UnpatchSelf(); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("OnDestroy: " + ex.Message)); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (_disabledByErrors || !_cfgEnabled.Value) { return; } try { if (_syncDirty) { FlushSync(); } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead()) { if (ShortcutPressed(_cfgKey.Value) && !BlockedByUI()) { TryActivate(localPlayer); } TauntTick(localPlayer, Time.time); BerserkTick(localPlayer, Time.time); GcdOnSwap(localPlayer, Time.time); UpdateProxies(localPlayer, Time.time); BleedTick(Time.time); } } catch (Exception e) { Fail("Update", e); } } internal static long NowTicks() { ZNet instance = ZNet.instance; if (!((Object)(object)instance != (Object)null)) { return DateTime.UtcNow.Ticks; } return instance.GetTime().Ticks; } internal static ZDO OwnZdo(Character c) { if ((Object)(object)c == (Object)null) { return null; } ZNetView component = ((Component)c).GetComponent<ZNetView>(); if (!((Object)(object)component != (Object)null) || !component.IsValid()) { return null; } return component.GetZDO(); } private static bool BlockedByUI() { if ((Object)(object)Chat.instance != (Object)null && Chat.instance.IsChatDialogWindowVisible()) { return true; } if (Console.IsVisible()) { return true; } if (TextInput.IsVisible()) { return true; } if (Menu.IsVisible()) { return true; } if (InventoryGui.IsVisible()) { return true; } if (StoreGui.IsVisible()) { return true; } if ((Object)(object)Minimap.instance != (Object)null && Minimap.IsOpen()) { return true; } return false; } private static bool ShortcutPressed(KeyboardShortcut shortcut) { //IL_0002: 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_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_003c: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return false; } IInputSystem current = UnityInput.Current; if (current == null || !current.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!current.GetKey(modifier)) { return false; } } return true; } internal static string FormatTime(float seconds) { return Mathf.Max(0f, seconds).ToString("0.0", CultureInfo.InvariantCulture); } private void GcdOnSwap(Player p, float now) { ItemData currentWeapon = ((Humanoid)p).GetCurrentWeapon(); string text = ((currentWeapon != null && currentWeapon.m_shared != null) ? currentWeapon.m_shared.m_name : "") + (TauntShieldEquipped(p) ? "+shield" : ""); if (!(text == _lastLoadout)) { _lastLoadout = text; if (now < _gcdUntil) { Message(p, L("Global cooldown: ", "Общий КД: ") + Mathf.CeilToInt(_gcdUntil - now) + L("s", "с")); } } } internal float GcdLeft() { return _gcdUntil - Time.time; } private void Message(Player p, string text) { if ((Object)(object)p != (Object)null) { ((Character)p).Message((MessageType)2, text, 0, (Sprite)null, false); } } private void Debug(string text) { if (_cfgDebug.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)text); } } private void Fail(string where, Exception e) { string text = where + ": " + e.GetType().Name + ": " + e.Message; if (_loggedErrors.Add(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)(text + "\n" + e.StackTrace)); } if (++_errorCount >= 25 && !_disabledByErrors) { _disabledByErrors = true; ((BaseUnityPlugin)this).Logger.LogError((object)"Too many errors, Weapon Arts is now inert until the game restarts."); } } private void BindEffectsConfig() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown _cfgTauntSound = ((BaseUnityPlugin)this).Config.Bind<string>("06 Taunt Effects", "Sound", "Perfect", new ConfigDescription("Sound on taunt: Block (the shield's own block effect), Perfect (perfect-block sparks), None.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Block", "Perfect", "None" }), new object[0])); _cfgTauntVisual = ((BaseUnityPlugin)this).Config.Bind<string>("06 Taunt Effects", "Visual", "GuardianPower", "Visual on taunt, attached to the tank. None; GuardianPower (the forsaken-power activation flash); or a registered prefab name, e.g. fx_eikthyr_stomp, fx_Adrenaline1, fx_guardstone_activate, vfx_perfectblock, fx_gjall_taunt."); _cfgArtSound = ((BaseUnityPlugin)this).Config.Bind<string>("07 Art Effects", "Sound", "Perfect", new ConfigDescription("Sound when a weapon art is activated: Perfect (perfect-block sparks), None.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Perfect", "None" }), new object[0])); _cfgArtVisual = ((BaseUnityPlugin)this).Config.Bind<string>("07 Art Effects", "Visual", "GuardianPower", "Visual when a weapon art is activated, attached to you. None; GuardianPower (the forsaken-power activation flash); or a registered prefab name, e.g. fx_eikthyr_stomp, fx_Adrenaline1, fx_guardstone_activate, vfx_perfectblock, fx_gjall_taunt."); _cfgHealVisual = ((BaseUnityPlugin)this).Config.Bind<string>("07 Art Effects", "HealVisual", "fx_guardstone_activate", "Visual for Rally (sledge heal) instead of the one above: ShamanHeal (the greydwarf shaman heal, green particles) or None; GuardianPower (the forsaken-power activation flash); or a registered prefab name, e.g. fx_eikthyr_stomp, fx_Adrenaline1, fx_guardstone_activate, vfx_perfectblock, fx_gjall_taunt."); _cfgMendVisual = ((BaseUnityPlugin)this).Config.Bind<string>("07 Art Effects", "MendVisual", "ShamanHeal", "Visual for Mend (mace heal): ShamanHeal (the greydwarf shaman heal: green particles around you and on each healed ally), or anything HealVisual takes."); _cfgMendAnimation = ((BaseUnityPlugin)this).Config.Bind<string>("07 Art Effects", "MendAnimation", "StaffShield", "Player animation for Mend: the attack animation of this item prefab (StaffShield = the staff-of-protection cast), a raw animator trigger name, or None."); } private void ResolveShaman() { //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Expected O, but got Unknown if (_shamanResolved || (Object)(object)ZNetScene.instance == (Object)null) { return; } _shamanResolved = true; List<EffectData> list = new List<EffectData>(); GameObject prefab = ZNetScene.instance.GetPrefab("Greydwarf_Shaman"); Humanoid val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Humanoid>() : null); if ((Object)(object)val != (Object)null && val.m_defaultItems != null) { GameObject[] defaultItems = val.m_defaultItems; foreach (GameObject val2 in defaultItems) { ItemDrop val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<ItemDrop>() : null); if ((Object)(object)val3 == (Object)null || ((Object)val2).name.IndexOf("heal", StringComparison.OrdinalIgnoreCase) < 0) { continue; } SharedData shared = val3.m_itemData.m_shared; Attack attack = shared.m_attack; AddEffects(list, shared.m_startEffect); AddEffects(list, shared.m_triggerEffect); if (attack != null) { AddEffects(list, attack.m_startEffect); AddEffects(list, attack.m_triggerEffect); if ((Object)(object)attack.m_spawnOnTrigger != (Object)null && (Object)(object)attack.m_spawnOnTrigger.GetComponent<Aoe>() != (Object)null) { _shamanAoe = attack.m_spawnOnTrigger; } if (attack.m_hitEffect != null && attack.m_hitEffect.HasEffects()) { _shamanHit = attack.m_hitEffect; } } Debug("Shaman heal item " + ((Object)val2).name + ": spawn " + ((attack != null && (Object)(object)attack.m_spawnOnTrigger != (Object)null) ? ((Object)attack.m_spawnOnTrigger).name : "-")); break; } } if ((Object)(object)_shamanAoe == (Object)null) { _shamanAoe = ZNetScene.instance.GetPrefab("shaman_heal_aoe"); } Aoe val4 = (((Object)(object)_shamanAoe != (Object)null) ? _shamanAoe.GetComponent<Aoe>() : null); if ((Object)(object)val4 != (Object)null) { if (_shamanHit == null && val4.m_hitEffects != null && val4.m_hitEffects.HasEffects()) { _shamanHit = val4.m_hitEffects; } } else { _shamanAoe = null; } AddPrefab(list, "vfx_greydwarf_shaman_pray"); AddPrefab(list, "sfx_greydwarf_shaman_heal"); _shamanCast = new EffectList(); _shamanCast.m_effectPrefabs = list.ToArray(); Debug("Shaman heal visual: aoe " + (((Object)(object)_shamanAoe != (Object)null) ? ((Object)_shamanAoe).name : "none") + ", " + list.Count + " cast effects, hit " + (_shamanHit != null)); if ((Object)(object)_shamanAoe == (Object)null && list.Count == 0) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Shaman heal visual not found; heals use HealVisual."); } } private static void AddEffects(List<EffectData> to, EffectList from) { if (from == null || from.m_effectPrefabs == null) { return; } EffectData[] effectPrefabs = from.m_effectPrefabs; foreach (EffectData val in effectPrefabs) { if (val != null && (Object)(object)val.m_prefab != (Object)null && val.m_enabled) { to.Add(val); } } } private static void AddPrefab(List<EffectData> to, string name) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null); if ((Object)(object)val == (Object)null) { return; } foreach (EffectData item in to) { if ((Object)(object)item.m_prefab == (Object)(object)val) { return; } } EffectData val2 = new EffectData(); val2.m_prefab = val; val2.m_enabled = true; val2.m_attach = true; to.Add(val2); } private bool UseShaman(Art a) { if (a == null || a.Kind != ArtKind.AoEHeal) { return false; } string text = ((a.Heal1H ? _cfgMendVisual.Value : _cfgHealVisual.Value) ?? "").Trim(); if (!text.Equals("ShamanHeal", StringComparison.OrdinalIgnoreCase)) { return false; } ResolveShaman(); if (!((Object)(object)_shamanAoe != (Object)null)) { if (_shamanCast != null) { return _shamanCast.HasEffects(); } return false; } return true; } private void SpawnShamanAoe(Vector3 pos, Quaternion rot) { //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) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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) Aoe val = (((Object)(object)_shamanAoe != (Object)null) ? _shamanAoe.GetComponent<Aoe>() : null); if ((Object)(object)val == (Object)null) { return; } bool hitCharacters = val.m_hitCharacters; bool hitProps = val.m_hitProps; bool hitTerrain = val.m_hitTerrain; bool hitOwner = val.m_hitOwner; DamageTypes damage = val.m_damage; string statusEffect = val.m_statusEffect; string statusEffectIfBoss = val.m_statusEffectIfBoss; string statusEffectIfPlayer = val.m_statusEffectIfPlayer; GameObject spawnOnHitTerrain = val.m_spawnOnHitTerrain; GameObject chainObj = val.m_chainObj; float damageSelf = val.m_damageSelf; try { val.m_hitCharacters = false; val.m_hitProps = false; val.m_hitTerrain = false; val.m_hitOwner = false; val.m_damage = default(DamageTypes); val.m_statusEffect = ""; val.m_statusEffectIfBoss = ""; val.m_statusEffectIfPlayer = ""; val.m_spawnOnHitTerrain = null; val.m_chainObj = null; val.m_damageSelf = 0f; Object.Instantiate<GameObject>(_shamanAoe, pos, rot); } finally { val.m_hitCharacters = hitCharacters; val.m_hitProps = hitProps; val.m_hitTerrain = hitTerrain; val.m_hitOwner = hitOwner; val.m_damage = damage; val.m_statusEffect = statusEffect; val.m_statusEffectIfBoss = statusEffectIfBoss; val.m_statusEffectIfPlayer = statusEffectIfPlayer; val.m_spawnOnHitTerrain = spawnOnHitTerrain; val.m_chainObj = chainObj; val.m_damageSelf = damageSelf; } } private void PlayHealHit(Art a, Character target) { //IL_0022: 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_0039: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && UseShaman(a) && _shamanHit != null) { Play(_shamanHit, target.GetCenterPoint(), ((Component)target).transform.rotation, ((Component)target).transform, target.GetZDOID()); } } private void PlayMendAnimation(Humanoid actor, Art a) { if (a == null || !a.Heal1H || (Object)(object)actor != (Object)(object)Player.m_localPlayer) { return; } string text = (_cfgMendAnimation.Value ?? "").Trim(); if (text.Length != 0 && !text.Equals("None", StringComparison.OrdinalIgnoreCase)) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(text) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null && val2.m_itemData.m_shared.m_attack != null) { text = val2.m_itemData.m_shared.m_attack.m_attackAnimation; } ZSyncAnimation val3 = (ZSyncAnimation)((s_zanim != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val3 != (Object)null && !string.IsNullOrEmpty(text)) { val3.SetTrigger(text); } } } private void PlayActivationEffects(Humanoid tank, EffectList blockEffect) { PlayEffects(tank, _cfgTauntSound.Value, _cfgTauntVisual.Value, blockEffect); } private void PlayArtEffects(Humanoid actor, Art a) { //IL_002c: 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_0043: 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_005f: Unknown result type (might be due to invalid IL or missing references) if (a != null) { if (UseShaman(a)) { PlayEffects(actor, _cfgArtSound.Value, "None", null); Play(_shamanCast, ((Character)actor).GetCenterPoint(), ((Component)actor).transform.rotation, ((Component)actor).transform, ((Character)actor).GetZDOID()); SpawnShamanAoe(((Component)actor).transform.position, ((Component)actor).transform.rotation); PlayMendAnimation(actor, a); } else { string visual = ((a.Kind == ArtKind.AoEHeal) ? _cfgHealVisual.Value : _cfgArtVisual.Value); PlayEffects(actor, _cfgArtSound.Value, visual, null); PlayMendAnimation(actor, a); } } } private void PlayEffects(Humanoid actor, string sound, string visual, EffectList blockEffect) { //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) //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_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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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) if (!((Object)(object)actor == (Object)null)) { Vector3 centerPoint = ((Character)actor).GetCenterPoint(); Quaternion rotation = ((Component)actor).transform.rotation; ZDOID zDOID = ((Character)actor).GetZDOID(); sound = sound ?? ""; if (sound.Equals("Block", StringComparison.OrdinalIgnoreCase) && blockEffect != null && blockEffect.HasEffects()) { Play(blockEffect, centerPoint, rotation, null, zDOID); } else if (!sound.Equals("None", StringComparison.OrdinalIgnoreCase)) { Play(actor.m_perfectBlockEffect, centerPoint, rotation, null, zDOID); } visual = (visual ?? "").Trim(); if (visual.Length != 0 && !visual.Equals("None", StringComparison.OrdinalIgnoreCase)) { Play(VisualEffects(visual), centerPoint, rotation, ((Component)actor).transform, zDOID); } } } private static void Play(EffectList list, Vector3 pos, Quaternion rot, Transform parent, ZDOID id) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (list != null && list.HasEffects()) { list.Create(pos, rot, parent, 1f, -1, id); } } private EffectList VisualEffects(string name) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown if (name.Equals("GuardianPower", StringComparison.OrdinalIgnoreCase)) { ObjectDB instance = ObjectDB.instance; StatusEffect val = (((Object)(object)instance != (Object)null) ? instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode("GP_Eikthyr")) : null); if ((Object)(object)val != (Object)null && val.m_startEffects != null && val.m_startEffects.HasEffects()) { return val.m_startEffects; } if (_warnedEffects.Add(name)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"GP_Eikthyr has no start effects in this build; no taunt visual."); } return null; } GameObject val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(name) : null); if ((Object)(object)val2 == (Object)null) { if (_warnedEffects.Add(name)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Visual effect prefab '" + name + "' is not registered; no taunt visual. Try GuardianPower, fx_eikthyr_stomp, fx_Adrenaline1, fx_guardstone_activate, vfx_perfectblock or fx_gjall_taunt.")); } return null; } EffectData val3 = new EffectData(); val3.m_prefab = val2; val3.m_enabled = true; val3.m_attach = true; val3.m_inheritParentRotation = true; EffectList val4 = new EffectList(); val4.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { val3 }; return val4; } private void BindProxyConfig() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown _cfgProxy = ((BaseUnityPlugin)this).Config.Bind<bool>("09 Proxy", "Enabled", false, "Run arts for players WITHOUT the mod near you: they play the trigger emote (or say the trigger word) and this client applies the art of their equipped weapon/shield on their behalf. Players with the mod act for themselves."); _cfgProxyProvider = ((BaseUnityPlugin)this).Config.Bind<string>("09 Proxy", "Provider", "Nearby", new ConfigDescription("Which modded client acts for a modless player. Nearby = of the modded players near enough to own the monsters, the host else the lowest session id (works on a dedicated server). Host = only the hosting player.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Nearby", "Host" }), new object[0])); _cfgProxyEmote = ((BaseUnityPlugin)this).Config.Bind<string>("09 Proxy", "TriggerEmote", "challenge", "Vanilla emote that triggers the art (e.g. /challenge). Empty: off."); _cfgProxyChat = ((BaseUnityPlugin)this).Config.Bind<string>("09 Proxy", "TriggerChat", "art", "Exact chat word that triggers the art for its sender. Empty: off."); _cfgProxyQuery = ((BaseUnityPlugin)this).Config.Bind<string>("09 Proxy", "QueryWord", "art?", "Exact chat word a modless player types to be told their art and its state. Empty: off."); _cfgProxySkill = ((BaseUnityPlugin)this).Config.Bind<float>("09 Proxy", "SkillForModless", 25f, new ConfigDescription("Weapon skill assumed for players without the mod (their real skill is not visible).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[0])); _cfgProxyCooldownFactor = ((BaseUnityPlugin)this).Config.Bind<float>("09 Proxy", "CooldownFactor", 1.5f, new ConfigDescription("Their cooldown is the art's cooldown times this (no stamina/eitr is spent for them).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), new object[0])); _cfgProxyAnnounce = ((BaseUnityPlugin)this).Config.Bind<bool>("09 Proxy", "Announce", true, "Say the result in chat (they have no HUD)."); _cfgProxyAnnounceReady = ((BaseUnityPlugin)this).Config.Bind<bool>("09 Proxy", "AnnounceReady", true, "Say in chat when their art comes off cooldown."); } private bool IsProviderFor(Player p) { long num = ProviderFor(p); if (num != 0) { return num == ZDOMan.GetSessionID(); } return false; } private long ProviderFor(Player p) { //IL_004f: 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_00c5: 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_00d2: Unknown result type (might be due to invalid IL or missing references) ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null || (Object)(object)p == (Object)null) { return 0L; } if (_cfgProxyProvider.Value == "Host") { if (!instance.IsServer()) { return 0L; } return ZDOMan.GetSessionID(); } Player localPlayer = Player.m_localPlayer; Vector3 position = ((Component)p).transform.position; long num = 0L; bool flag = false; List<Player> allPlayers = Player.GetAllPlayers(); for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)p) { continue; } ZNetView component = ((Component)val).GetComponent<ZNetView>(); ZDO val2 = (((Object)(object)component != (Object)null) ? component.GetZDO() : null); if (val2 != null && (!((Object)(object)val != (Object)(object)localPlayer) || HasMod(val2)) && ZNetScene.InActiveArea(position, ZoneSystem.GetZone(((Component)val).transform.position))) { long owner = val2.GetOwner(); bool flag2 = IsHostSession(instance, owner); if (num == 0 || (flag2 && !flag) || (flag2 == flag && owner < num)) { num = owner; flag = flag2; } } } return num; } private static bool IsHostSession(ZNet znet, long uid) { if (znet.IsServer()) { return uid == ZDOMan.GetSessionID(); } ZNetPeer serverPeer = znet.GetServerPeer(); if (serverPeer != null) { return uid == serverPeer.m_uid; } return false; } internal Character ProxyTankChar(ZDOID id) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null || ((ZDOID)(ref id)).IsNone()) { return null; } GameObject val = ZNetScene.instance.FindInstance(id); if (!((Object)(object)val != (Object)null)) { return null; } return val.GetComponent<Character>(); } private void UpdateProxies(Player local, float now) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) MarkSelf(local, now); if (!ProxyOn) { if (_proxies.Count > 0) { _proxies.Clear(); } return; } if (now >= _nextProxyPoll) { _nextProxyPoll = now + 0.25f; PollProxies(local, now); } foreach (Proxy value in _proxies.Values) { if (now < value.TauntUntil && now >= value.NextReapply) { value.NextReapply = now + 0.25f; Character val = ProxyTankChar(value.Id); if ((Object)(object)val != (Object)null && !val.IsDead()) { value.TauntCount = ApplyTauntHold(val, value.TauntUntil, Sv(_cfgTauntRadius), value.SinceMs); } } if (now < value.BerserkUntil && value.BerserkRegen > 0f && now >= value.NextRegen) { value.NextRegen = now + 1f; Character val2 = ProxyTankChar(value.Id); if ((Object)(object)val2 != (Object)null && !val2.IsDead()) { HealChar(val2, value.BerserkRegen); } } if (_cfgProxyAnnounceReady.Value && !value.ReadyAnnounced && value.CooldownUntil > 0f && now >= value.CooldownUntil) { value.ReadyAnnounced = true; Announce(value.Name + ": " + value.ArtName + L(" ready", " готово")); } } _proxyScratch.Clear(); foreach (KeyValuePair<ZDOID, Proxy> proxy in _proxies) { if (now - proxy.Value.LastSeen > 120f) { _proxyScratch.Add(proxy.Key); } } for (int i = 0; i < _proxyScratch.Count; i++) { _proxies.Remove(_proxyScratch[i]); } } private void MarkSelf(Player local, float now) { if (!(now < _nextMark)) { _nextMark = now + 1f; ZDO val = OwnZdo((Character)(object)local); if (val != null && val.GetInt(ModMarkHash, 0) != 1) { val.Set(ModMarkHash, 1, false); } } } private static bool HasMod(ZDO zdo) { if (zdo != null) { return zdo.GetInt(ModMarkHash, 0) != 0; } return false; } private Proxy GetOrAdd(Player p, ZDO zdo, float now) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) ZDOID zDOID = ((Character)p).GetZDOID(); if (!_proxies.TryGetValue(zDOID, out var value)) { value = new Proxy(); value.Id = zDOID; value.Name = p.GetPlayerName(); value.LastEmoteId = zdo.GetInt(ZDOVars.s_emoteID, 0); _proxies[zDOID] = value; } value.LastSeen = now; return value; } private void PollProxies(Player local, float now) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) string text = (_cfgProxyEmote.Value ?? "").Trim(); List<Player> allPlayers = Player.GetAllPlayers(); for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)local) { continue; } ZDO val2 = OwnZdo((Character)(object)val); if (val2 == null || HasMod(val2)) { continue; } bool flag = !_proxies.ContainsKey(((Character)val).GetZDOID()); Proxy orAdd = GetOrAdd(val, val2, now); if (flag || text.Length == 0) { continue; } int num = val2.GetInt(ZDOVars.s_emoteID, 0); if (num != orAdd.LastEmoteId) { orAdd.LastEmoteId = num; string a = val2.GetString(ZDOVars.s_emote, ""); if (string.Equals(a, text, StringComparison.OrdinalIgnoreCase)) { TryActivateProxy(val, val2, orAdd, now, "emote"); } } } } private void OnChat(long senderId, Type type, string text) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (!ProxyOn || (int)type == 3 || text == null) { return; } string a = text.Trim(); string text2 = (_cfgProxyChat.Value ?? "").Trim(); string text3 = (_cfgProxyQuery.Value ?? "").Trim(); bool flag = text2.Length > 0 && string.Equals(a, text2, StringComparison.OrdinalIgnoreCase); bool flag2 = text3.Length > 0 && string.Equals(a, text3, StringComparison.OrdinalIgnoreCase); if (!flag && !flag2) { return; } Player localPlayer = Player.m_localPlayer; List<Player> allPlayers = Player.GetAllPlayers(); for (int i = 0; i < allPlayers.Count; i++) { Player val = allPlayers[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)localPlayer || ((Character)val).GetOwner() != senderId) { continue; } ZDO val2 = OwnZdo((Character)(object)val); if (val2 != null && !HasMod(val2)) { Proxy orAdd = GetOrAdd(val, val2, Time.time); if (flag2) { ReplyQuery(val, val2, orAdd); } else { TryActivateProxy(val, val2, orAdd, Time.time, "chat"); } } break; } } private static ItemData ProtoItem(int hash) { GameObject val = ((hash != 0 && (Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(hash) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 != (Object)null)) { return null; } return val2.m_itemData; } private Art ResolveProxyArt(ZDO zdo, out bool taunt, out ItemData item, out int quality) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 taunt = false; item = null; quality = 1; ItemData val = ProtoItem(zdo.GetInt(ZDOVars.s_leftItem, 0)); if (val != null && val.m_shared != null && (int)val.m_shared.m_itemType == 5) { string text = Ss(_cfgShieldMode); if (text == "None" || text == "AnyShield" || val.m_shared.m_timedBlockBonus <= Sv(_cfgTowerParry)) { taunt = true; item = val; quality = zdo.GetInt(ZDOVars.s_leftItemQuality, 1); return null; } } item = ProtoItem(zdo.GetInt(ZDOVars.s_rightItem, 0)); quality = zdo.GetInt(ZDOVars.s_rightItemQuality, 1); return ArtFor(item); } private void TryActivateProxy(Player p, ZDO zdo, Proxy px, float now, string how) { //IL_030f: Unknown result type (might be due to invalid IL or missing references) if (!IsProviderFor(p)) { Debug("proxy for " + px.Name + " (" + how + "): provider is elsewhere"); return; } if (now < px.CooldownUntil) { Announce(px.Name + L(": cooldown ", ": КД ") + Mathf.CeilToInt(px.CooldownUntil - now) + L("s", "с")); return; } bool taunt; ItemData item; int quality; Art art = ResolveProxyArt(zdo, out taunt, out item, out quality); float num = Mathf.Clamp01(_cfgProxySkill.Value / 100f); if (taunt) { float num2 = ((item != null && item.m_shared != null) ? (item.m_shared.m_blockPower + (float)Mathf.Max(0, quality - 1) * item.m_shared.m_blockPowerPerLevel) : 0f); float num3 = Mathf.Clamp01(num2 / Mathf.Max(1f, Sv(_cfgTauntRefBlock))); float num4 = Mathf.Clamp(num * Sv(_cfgSkillDurationScale) * (0.5f + 0.5f * num3), 0f, 0.5f); px.TauntReduction = Mathf.Clamp(Mathf.Lerp(Sv(_cfgTauntReductionBase), Sv(_cfgTauntReductionBest), 0.8f * num3 + 0.2f * num), 0f, 0.9f); px.TauntUntil = now + Mathf.Max(6f, Sv(_cfgTauntDuration)) * (1f + num4); px.NextReapply = now + 0.25f; px.SinceMs = WorldMs(); px.ArtName = L("Taunt", "Таунт"); px.TauntCount = ApplyTauntHold((Character)(object)p, px.TauntUntil, Sv(_cfgTauntRadius), px.SinceMs); try { PlayActivationEffects((Humanoid)(object)p, (item != null && item.m_shared != null) ? item.m_shared.m_blockEffect : null); } catch (Exception e) { Fail("proxy effects", e); } px.CooldownUntil = now + _cfgTauntCooldown.Value * _cfgProxyCooldownFactor.Value; px.ReadyAnnounced = false; Announce(L("Taunt for ", "Таунт за ") + px.Name + ": " + px.TauntCount + L(" monsters", " мобов")); return; } if (art == null) { Announce(px.Name + L(": no art for this weapon", ": нет активки для оружия")); return; } px.ArtName = art.Name; float num5 = Mathf.Clamp01(TotalDamage(item.GetDamage(quality, 0f)) / Mathf.Max(1f, Sv(_cfgRefWeaponDamage))); float num6 = PowerScale(num5, num); float p2 = 0.5f * num5 + 0.5f * num; if (art.Kind == ArtKind.AoEHeal) { int num7 = DoHeal(p, art, p2); Announce(art.Name + L(" for ", " за ") + px.Name + " (" + num7 + ")"); } else if (art.Kind == ArtKind.AoEBurst) { int num8 = DoBurst(p, art, item, num6); Announce(art.Name + L(" for ", " за ") + px.Name + " (" + num8 + ")"); } else { float num9 = ((art.Kind == ArtKind.DamageMult || art.Kind == ArtKind.Stagger) ? (1f + (Sv(art.Mag) - 1f) * num6) : (Sv(art.Mag) * num6)); float num10 = Mathf.Clamp(num * Sv(_cfgSkillDurationScale) * (0.5f + 0.5f * num5), 0f, 0.5f); float num11 = Mathf.Max(6f, Sv(art.Win)) * (1f + num10); if (art.Shots != null) { num11 = Mathf.Min(num11, 10f); } if (art.Kind == ArtKind.Berserk) { px.BerserkUntil = now + num11; px.BerserkReduction = Mathf.Clamp(num9, 0f, 0.8f); px.BerserkRegen = ((art.Regen != null) ? Sv(art.Regen) : 0f); px.NextRegen = now + 1f; px.ArtHash = 0; } else { px.ArtHash = art.Hash; px.ArtPower = num9; } px.ArtUntil = now + num11; Announce(art.Name + L(" for ", " за ") + px.Name + ": " + num11.ToString("0") + L("s", "с")); } try { PlayArtEffects((Humanoid)(object)p, art); } catch (Exception e2) { Fail("proxy art effects", e2); } px.CooldownUntil = now + art.Cd.Value * _cfgProxyCooldownFactor.Value; px.ReadyAnnounced = false; } private void ReplyQuery(Player p, ZDO zdo, Proxy px) { bool taunt; ItemData item; int quality; Art art = ResolveProxyArt(zdo, out taunt, out item, out quality); string text = (taunt ? L("Taunt", "Таунт") : ((art != null) ? art.Name : L("no art", "нет активки"))); string text2 = (taunt ? L("pull monsters + damage reduction", "стянуть мобов + резист") : ((art != null) ? art.Desc : "")); float time = Time.time; string text3 = ((time < px.TauntUntil || time < px.ArtUntil) ? L("active", "активна") : ((time < px.CooldownUntil) ? (L("cooldown ", "КД ") + Mathf.CeilToInt(px.CooldownUntil - time) + L("s", "с")) : L("ready", "готова"))); Announce(px.Name + ": " + text + " — " + text3 + ((text2.Length > 0) ? (" (" + text2 + ")") : "")); } private void Announce(string text) { if (_cfgProxyAnnounce.Value && !((Object)(object)Chat.instance == (Object)null)) { Chat.instance.SendText((Type)1, text); } } internal bool ProxyWindowArt(Character attacker, out int hash, out float power) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) hash = 0; power = 0f; if ((Object)(object)attacker == (Object)null || _proxies.Count == 0) { return false; } if (!_proxies.TryGetValue(attacker.GetZDOID(), out var value) || value.ArtHash == 0 || Time.time >= value.ArtUntil) { return false; } hash = value.ArtHash; power = value.ArtPower; return true; } private void ReduceProxyHit(Character victim, HitData hit) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)victim == (Object)null || !victim.IsPlayer() || (Object)(object)victim == (Object)(object)Player.m_localPlayer || !_proxies.TryGetValue(victim.GetZDOID(), out var value)) { return; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null) { return; } if (Time.time < value.BerserkUntil && !attacker.IsPlayer() && value.BerserkReduction > 0f) { hit.ApplyModifier(1f - value.BerserkReduction); } if (!(Time.time >= value.TauntUntil) && _tainted.TryGetValue(attacker.GetZDOID(), out var value2) && !(value2.Target != value.Id) && !(Time.time >= value2.Until)) { float num = Mathf.Clamp(value.TauntReduction, 0f, 0.9f); if (num > 0f) { hit.ApplyModifier(1f - num); } } } private void BindSyncConfig() { _cfgSync = ((BaseUnityPlugin)this).Config.Bind<bool>("10 Sync", "SyncConfig", true, "The server sends its balance settings to every client with the mod on connect and on change; the client uses them while connected. Off on the server: everyone uses their own file. No effect on a client. Proxy settings and local pacing are never synced."); ((BaseUnityPlugin)this).Config.SettingChanged += delegate { _syncDirty = true; }; } private static string CompKey(ConfigDefinition d) { return d.Section + "\u0001" + d.Key; } internal float Sv(ConfigEntry<float> e) { if (_serverSynced && _serverByKey.TryGetValue(CompKey(((ConfigEntryBase)e).Definition), out var value) && value is float) { return (float)value; } return e.Value; } internal bool Sb(ConfigEntry<bool> e) { if (_serverSynced && _serverByKey.TryGetValue(CompKey(((ConfigEntryBase)e).Definition), out var value) && value is bool) { return (bool)value; } return e.Value; } internal string Ss(ConfigEntry<string> e) { if (_serverSynced && _serverByKey.TryGetValue(CompKey(((ConfigEntryBase)e).Definition), out var value) && value is string) { return (string)value; } return e.Value; } private void RegisterRpc() { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<ZPackage>("j1ga.weaponarts.config", (Action<long, ZPackage>)OnConfigPacket); } } private void FlushSync() { _syncDirty = false; ZNet instance = ZNet.instance; if (!((Object)(object)instance == (Object)null) && instance.IsServer() && _cfgSync.Value && ZRoutedRpc.instance != null && instance.GetPeers().Count != 0) { SendConfig(0L); Debug("settings sent to " + instance.GetPeers().Count + " peers"); } } private ZPackage BuildPacket() { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown List<ConfigDefinition> list = new List<ConfigDefinition>(); foreach (ConfigDefinition key in ((BaseUnityPlugin)this).Config.Keys) { if (key.Section == null || !key.Section.StartsWith("09 Proxy")) { ConfigEntryBase val = ((BaseUnityPlugin)this).Config[key]; Type settingType = val.SettingType; if (settingType == typeof(float) || settingType == typeof(bool) || settingType == typeof(string)) { list.Add(key); } } } ZPackage val2 = new ZPackage(); val2.Write(1); val2.Write(list.Count); for (int i = 0; i < list.Count; i++) { ConfigDefinition val3 = list[i]; ConfigEntryBase val4 = ((BaseUnityPlugin)this).Config[val3]; Type settingType2 = val4.SettingType; int num = ((settingType2 == typeof(float)) ? 1 : ((settingType2 == typeof(bool)) ? 2 : 3)); val2.Write(num); val2.Write(CompKey(val3)); switch (num) { case 1: val2.Write((float)val4.BoxedValue); break; case 2: val2.Write((bool)val4.BoxedValue); break; default: val2.Write((string)(val4.BoxedValue ?? "")); break; } } return val2; } private void SendConfig(long target) { ZRoutedRpc.instance.InvokeRoutedRPC(target, "j1ga.weaponarts.config", new object[1] { BuildPacket() }); } private void OnPeerInfo(ZNet znet, ZRpc rpc) { if (!znet.IsServer() || !_cfgSync.Value || rpc == null) { return; } foreach (ZNetPeer peer in znet.GetPeers()) { if (peer != null && peer.m_rpc == rpc) { if (peer.m_uid != 0) { ((MonoBehaviour)this).StartCoroutine(SendConfigLater(peer.m_uid)); } break; } } } private IEnumerator SendConfigLater(long uid) { yield return (object)new WaitForSeconds(1f); ZNet znet = ZNet.instance; if ((Object)(object)znet == (Object)null || !znet.IsServer() || ZRoutedRpc.instance == null || !_cfgSync.Value) { yield break; } ZNetPeer peer = znet.GetPeer(uid); if (peer != null) { try { SendConfig(uid); Debug("settings sent to " + peer.m_playerName); } catch (Exception e) { Fail("send config", e); } } } private void OnConfigPacket(long sender, ZPackage pkg) { try { ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null || instance.IsServer() || pkg == null) { return; } ZNetPeer serverPeer = instance.GetServerPeer(); if (serverPeer == null || sender != serverPeer.m_uid) { return; } int num = pkg.ReadInt(); if (num != 1) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Server config packet version " + num + " != " + 1 + "; using local settings.")); return; } int num2 = pkg.ReadInt(); if (num2 < 0 || num2 > 5000) { return; } Dictionary<string, object> dictionary = new Dictionary<string, object>(); for (int i = 0; i < num2; i++) { int num3 = pkg.ReadInt(); string key = pkg.ReadString(); switch (num3) { case 1: dictionary[key] = pkg.ReadSingle(); break; case 2: dictionary[key] = pkg.ReadBool(); break; default: dictionary[key] = pkg.ReadString(); break; } } _serverByKey.Clear(); foreach (KeyValuePair<string, object> item in dictionary) { _serverByKey[item.Key] = item.Value; } _serverSynced = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Balance settings received from the server (" + dictionary.Count + " values).")); } catch (Exception e) { Fail("config packet", e); } } private void ClearServerValues() { _serverSynced = false; _serverByKey.Clear(); } private static long WorldMs() { ZNet instance = ZNet.instance; if (!((Object)(object)instance != (Object)null)) { ret