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 ExtendedBosses v0.8.6
ExtendedBosses.dll
Decompiled 3 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.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.UI; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("0.0.0.0")] namespace ExtendedBosses; internal enum ActKind { Wave, Lieutenant, Nest, Totem, Marks, Charge, Shield, Resist, Cycle, Fusion, Seeds, HitEffect, Fixate, Cocoon, Hazard } internal class CycleVariant { public string Id; public string Say; public Dictionary<DamageType, float> Mods; public float Other = 1f; public bool Back; public float MeleeFactor = 1f; public float MeleeRange = 5f; public float Retaliate; public DamageType RetaliateType = (DamageType)256; public float RangedFactor = 1f; public bool GroundedOnly; public float ThornsPercent; public float ThornsMin; public float RegenPercent; public DamageType RegenStopType = (DamageType)64; public float RegenStopSeconds = 3f; public bool Adapt; public float AdaptFactor = 0.6f; public float AdaptOthers = 1.1f; public float Lifesteal; public string EndKey; } internal class Act { public ActKind Kind; public string[] Prefabs; public string[] NightPrefabs; public string Fallback = "BonePileSpawner"; public float Count = 1f; public int ExtraFrom; public int Level = 1; public float HpMul = 1f; public int Role; public float Lifetime; public bool InWater; public string Prop; public float Interval = 12f; public int MaxAlive = 3; public float Damage; public DamageType DamageType = (DamageType)128; public string MarkKey; public string Creature; public int CreatureCount = 4; public float RingRadius = 3f; public float Duration; public Dictionary<DamageType, float> Mods; public float CooldownMin; public float CooldownMax; public float Delay; public List<CycleVariant> Variants; public string EndKey; public float Heal; public string Gate; public bool AnyProp; public bool ScaleAsAdds; public float Chance; public string Effect; public bool Land; } internal class PhaseDef { public float Pct; public string Say; public List<Act> Acts = new List<Act>(); } internal class Loot { public string Prefab; public int Min; public int Max; public bool PerPlayer; public Loot(string prefab, int min, int max, bool perPlayer) { Prefab = prefab; Min = min; Max = max; PerPlayer = perPlayer; } } internal class RewardDef { public List<Loot> Valuables = new List<Loot>(); public List<Loot> NextBiome = new List<Loot>(); public string[] Gear = new string[0]; public string[] NextGear = new string[0]; } internal class BossDef { public string Prefab; public int Hash; public string Section; public List<PhaseDef> Phases = new List<PhaseDef>(); public RewardDef Reward = new RewardDef(); public ConfigEntry<string> CfgMode; public ConfigEntry<string> CfgProfile; public Action<ExtendedBossesPlugin, BossDef> BindExtra; public ConfigEntry<string> CfgTotemPrefab; public ConfigEntry<string> CfgNestPrefab; public ConfigEntry<string> CfgMarkPrefab; public ConfigEntry<string> CfgMarkEffect; public ConfigEntry<string> CfgMarkCreature; public ConfigEntry<float> CfgMarkDamage; public ConfigEntry<float> CfgChargeInterval; public ConfigEntry<float> CfgChargeSpeed; public ConfigEntry<float> CfgChargeDuration; public ConfigEntry<string> CfgCycleVariant; public ConfigEntry<float> CfgCycleDuration; public ConfigEntry<float> CfgCycleCdMin; public ConfigEntry<float> CfgCycleCdMax; public ConfigEntry<float> CfgCycleDelay; public ConfigEntry<float> CfgBackArc; public ConfigEntry<float> CfgCycleMelee; public ConfigEntry<float> CfgCycleRetaliate; public ConfigEntry<float> CfgCycleRanged; public ConfigEntry<float> CfgCycleThorns; public ConfigEntry<float> CfgRegen; public ConfigEntry<float> CfgAdaptFactor; public ConfigEntry<float> CfgAdaptOthers; public ConfigEntry<float> CfgLifesteal; public readonly Dictionary<string, ConfigEntry<bool>> Gates = new Dictionary<string, ConfigEntry<bool>>(); public ConfigEntry<float> CfgFusionInterval; public ConfigEntry<float> CfgFusionHeal; } [BepInPlugin("j1ga.extendedbosses", "Extended Bosses", "0.8.6")] public class ExtendedBossesPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(SpawnArea), "SpawnOne")] private static class SpawnArea_SpawnOne_Patch { private static bool Prefix(SpawnArea __instance, ref bool __result) { ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.Active || (Object)(object)__instance == (Object)null) { return true; } try { if (instance.NestMaySpawn(__instance)) { return true; } __result = false; return false; } catch (Exception e) { instance.Fail("SpawnArea.SpawnOne", e); return true; } } } [HarmonyPatch(typeof(Projectile), "OnHit")] private static class Projectile_OnHit_Patch { private static void Postfix(Projectile __instance, Vector3 hitPoint) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.Active || (Object)(object)__instance == (Object)null || instance._fights.Count == 0) { return; } try { instance.OnProjectileHit(__instance, hitPoint); } catch (Exception e) { instance.Fail("Projectile.OnHit", e); } } } private class Strike { public ZDOID Target; public float At; public Act Act; } private class FightRt { public ZDOID BossId; public BossDef Def; public Character Boss; public bool Seen; public float NextMark; public readonly List<Strike> Strikes = new List<Strike>(); public float NextCharge; public float ChargeEnd; public bool Charging; public float BaseSpeed; public float BaseRun; public readonly Dictionary<int, float> TotemNext = new Dictionary<int, float>(); public float NoPlayersSince = -1f; public bool CleanedForVanilla; public bool ShieldActive; public bool WindowActive; public Act ResistAct; public Act CycleAct; public CycleVariant CycleVar; public float NextFusion; public readonly Dictionary<ZDOID, float> RetaliateAt = new Dictionary<ZDOID, float>(); public readonly Dictionary<DamageType, float> TypeDmg = new Dictionary<DamageType, float>(); public readonly Dictionary<DamageType, float> LastHitBy = new Dictionary<DamageType, float>(); public DamageType AdaptType; public int TotemsAlive; public int Healers; public int Guards; public float NextFix; public float FixUntil; public ZDOID FixTarget = ZDOID.None; public float NextHazard; public float NextSeed; public float CocoonUntil; public float CocoonReady; public bool CocoonActive; public Vector3 LastPos; public bool HasLastPos; public readonly Dictionary<ZDOID, float> Threat = new Dictionary<ZDOID, float>(); public ZDOID ThreatTarget = ZDOID.None; public float ThreatSince; } [HarmonyPatch(typeof(Character), "RPC_Damage")] private static class Character_RPC_Damage_Patch { private static void Prefix(Character __instance, HitData hit, out float __state) { __state = -1f; ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.Active || (Object)(object)__instance == (Object)null || hit == null) { return; } try { if (__instance.IsPlayer() || !IsOwner((Component)(object)__instance)) { return; } ZDO val = Zdo((Component)(object)__instance); if (val == null) { return; } float num = 1f; if (__instance.IsBoss()) { BossDef bossDef = instance.BossOf(val); if (bossDef != null && instance.IsModMode(bossDef)) { instance.RecordHit(__instance, hit); float totalDamage = hit.GetTotalDamage(); instance.ApplyResist(__instance, hit); instance.ApplyCycle(__instance, hit); hit.ApplyModifier(instance.MechFactor(__instance, bossDef)); float totalDamage2 = hit.GetTotalDamage(); float num2 = instance.Sv(instance._cfgMinDamage); if (totalDamage > 0.01f && totalDamage2 > 0.0001f && totalDamage2 < totalDamage * num2) { hit.ApplyModifier(totalDamage * num2 / totalDamage2); } num *= instance.ScaleFactor(__instance, bossDef); __state = __instance.GetHealth(); } } float num3 = val.GetFloat(KHpMul, 1f); if (num3 > 0.01f && Mathf.Abs(num3 - 1f) > 0.001f) { num /= num3; } if (Mathf.Abs(num - 1f) > 0.001f) { hit.ApplyModifier(num); } } catch (Exception e) { instance.Fail("RPC_Damage", e); } } private static void Postfix(Character __instance, HitData hit, float __state) { if (__state < 0f) { return; } ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || (Object)(object)__instance == (Object)null || hit == null) { return; } try { instance.AddThreat(__instance, hit.GetAttacker(), __state - __instance.GetHealth()); } catch (Exception e) { instance.Fail("RPC_Damage threat", e); } } } [HarmonyPatch(typeof(Character), "Damage")] private static class Character_Damage_Patch { private static void Prefix(Character __instance, HitData hit) { ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.Active || (Object)(object)__instance == (Object)null || hit == null || instance._fights.Count == 0) { return; } try { if (__instance.IsPlayer()) { Character attacker = hit.GetAttacker(); if (!((Object)(object)attacker == (Object)null) && attacker.IsBoss() && IsOwner((Component)(object)attacker)) { instance.ApplyHitEffect(attacker, hit); instance.Lifesteal(attacker, hit); } } } catch (Exception e) { instance.Fail("Character.Damage", e); } } } [HarmonyPatch(typeof(Character), "Awake")] private static class Character_Awake_Patch { private static void Postfix(Character __instance) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || instance._disabledByErrors || (Object)(object)__instance == (Object)null) { return; } try { ZDO val = Zdo((Component)(object)__instance); if (val != null && val.GetZDOID("j1ga.extendedbosses.boss") != ZDOID.None) { __instance.m_group = "extendedbosses"; } } catch (Exception e) { instance.Fail("Character.Awake", e); } } } [HarmonyPatch(typeof(Character), "OnDeath")] private static class Character_OnDeath_Patch { private static void Prefix(Character __instance) { ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.Active || (Object)(object)__instance == (Object)null || !__instance.IsBoss()) { return; } try { if (!IsOwner((Component)(object)__instance)) { return; } BossDef bossDef = instance.BossOf(Zdo((Component)(object)__instance)); if (bossDef != null && instance.IsModMode(bossDef)) { FightRt fightRt = instance.RtIfRunning(__instance); if (fightRt != null) { instance.StopCharge(fightRt); } instance.DropRewards(__instance, bossDef); if (instance.Sb(instance._cfgCleanupOnDeath)) { int num = instance.Cleanup(__instance); instance.Debug(bossDef.Prefab + " died: removed " + num + " add(s)/nest(s)"); } } } catch (Exception e) { instance.Fail("OnDeath", e); } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Patch { private static void Postfix() { ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || instance._disabledByErrors) { return; } try { instance.SelfCheck(); } catch (Exception e) { instance.Fail("self-check", e); } } } private enum Need { Creature, Nest, Totem, Prop, Aoe, Effect, Item, Status } private class Circle { public GameObject Go; public LineRenderer Line; public Transform Follow; public Vector3 Pos; public float Radius; public float Until; } [HarmonyPatch(typeof(ZNet), "Disconnect")] private static class ZNet_Disconnect_Patch { private static void Postfix(ZNetPeer peer) { ExtendedBossesPlugin instance = Instance; if (!((Object)(object)instance == (Object)null) && peer != null) { instance._moddedPeers.Remove(peer.m_uid); } } } [HarmonyPatch(typeof(ZNet), "Awake")] private static class ZNet_Awake_Patch { private static void Postfix() { ExtendedBossesPlugin 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) { ExtendedBossesPlugin 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() { ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null) { return; } try { ((MonoBehaviour)instance).StopAllCoroutines(); instance.ClearServerValues(); instance.RestoreAllCharges(); instance._fights.Clear(); instance.ClearCircles(); instance._helloSent = false; instance._moddedPeers.Clear(); } catch (Exception e) { instance.Fail("ZNet.OnDestroy", e); } } } [HarmonyPatch(typeof(MonsterAI), "UpdateTarget")] private static class MonsterAI_UpdateTarget_Patch { [HarmonyPriority(800)] private static void Postfix(MonsterAI __instance) { ExtendedBossesPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.Active || (Object)(object)__instance == (Object)null || instance._fights.Count == 0) { return; } try { Character component = ((Component)__instance).GetComponent<Character>(); if (!((Object)(object)component == (Object)null) && component.IsBoss()) { instance.PickThreatTarget(__instance, component); } } catch (Exception e) { instance.Fail("UpdateTarget", e); } } } internal const int RoleHealer = 1; internal const int RoleFuse = 2; internal const int RoleGuard = 3; internal const string CycleRandom = "Random"; internal const string CycleAuto = "Auto"; internal const string ProfileLight = "Light"; internal const string ProfileRaid = "Raid"; internal const string ProfileHard = "Hard"; internal const string ProfileDefault = "Default"; internal const string ModeMod = "Mod"; internal const string ModeVanilla = "Vanilla"; private const int CurrentConfigVersion = 2; private const float ReloadDebounce = 1f; public const string Guid = "j1ga.extendedbosses"; public const string Name = "Extended Bosses"; public const string Version = "0.8.6"; internal const string RaidGroup = "extendedbosses"; private const int MaxErrors = 25; private const float TickInterval = 0.25f; internal const string KBoss = "j1ga.extendedbosses.boss"; private const int NestCode = -1; private const int SeedCode = -2; private const float FuseReach = 3.5f; private const string FxRpc = "j1ga.extendedbosses.fx"; internal const int FxMark = 1; internal const int FxStrike = 2; private const int CircleSegments = 48; private const string HelloRpc = "j1ga.extendedbosses.hello"; private const string AnnounceRpc = "j1ga.extendedbosses.announce"; private const string MessageRpc = "j1ga.extendedbosses.msg"; private const float VanillaCenterFade = 4f; private const string SyncRpc = "j1ga.extendedbosses.config"; private const int SyncVersion = 1; private readonly List<BossDef> _bosses = new List<BossDef>(); private readonly Dictionary<int, BossDef> _bossByHash = new Dictionary<int, BossDef>(); private ConfigEntry<int> _cfgCapBase; private ConfigEntry<int> _cfgCapPerPlayer; private ConfigEntry<float> _cfgCapRadius; private ConfigEntry<bool> _cfgEnabled; private ConfigEntry<bool> _cfgDebug; private ConfigEntry<string> _cfgProfile; private ConfigEntry<string> _cfgAnnounce; private ConfigEntry<float> _cfgScalingRange; private ConfigEntry<float> _cfgHealthPerPlayer; private ConfigEntry<int> _cfgMaxScalingPlayers; private ConfigEntry<float> _cfgBaseHealth; private ConfigEntry<float> _cfgHardHealth; private ConfigEntry<float> _cfgSoloAdds; private ConfigEntry<float> _cfgAddsPerPlayer; private ConfigEntry<float> _cfgHardAdds; private ConfigEntry<int> _cfgLieutenantStarPlayers; private ConfigEntry<int> _cfgAddStarPlayers; private ConfigEntry<float> _cfgSoloHealth; private ConfigEntry<float> _cfgSoloLieutenant; private ConfigEntry<bool> _cfgWaves; private ConfigEntry<bool> _cfgNests; private ConfigEntry<bool> _cfgLieutenants; private ConfigEntry<bool> _cfgMarks; private ConfigEntry<bool> _cfgSpecials; private ConfigEntry<bool> _cfgShield; private ConfigEntry<bool> _cfgHealers; private ConfigEntry<bool> _cfgResist; private ConfigEntry<bool> _cfgThreat; private ConfigEntry<bool> _cfgCleanupOnDeath; private ConfigEntry<bool> _cfgCleanupOnDisable; private ConfigEntry<float> _cfgSpawnRadiusMin; private ConfigEntry<float> _cfgSpawnRadiusMax; private ConfigEntry<float> _cfgMarkDelay; private ConfigEntry<float> _cfgMarkInterval; private ConfigEntry<float> _cfgMarkDamage; private ConfigEntry<bool> _cfgRewards; private ConfigEntry<int> _cfgQualityMin; private ConfigEntry<int> _cfgQualityMax; private ConfigEntry<float> _cfgPlayersPerItem; private ConfigEntry<float> _cfgNextBiomeChance; private ConfigEntry<float> _cfgValuables; private ConfigEntry<bool> _cfgReset; private ConfigEntry<float> _cfgResetRadius; private ConfigEntry<float> _cfgResetSeconds; private ConfigEntry<bool> _cfgShowCircles; private ConfigEntry<float> _cfgMessageDuration; private ConfigEntry<float> _cfgShieldFactor; private ConfigEntry<float> _cfgHardShieldFactor; private ConfigEntry<float> _cfgWindowSeconds; private ConfigEntry<float> _cfgWindowMultiplier; private ConfigEntry<float> _cfgHealPercent; private ConfigEntry<float> _cfgHealRange; private ConfigEntry<float> _cfgLeash; private ConfigEntry<float> _cfgSwitchMargin; private ConfigEntry<float> _cfgHoldSeconds; private ConfigEntry<float> _cfgThreatDecay; private ConfigEntry<float> _cfgOutOfLeashHalfLife; private ConfigEntry<float> _cfgShieldMax; private ConfigEntry<float> _cfgMinDamage; private ConfigEntry<int> _cfgConfigVersion; private static readonly string[] Profiles = new string[3] { "Light", "Raid", "Hard" }; private static readonly string[] BossProfiles = new string[4] { "Default", "Light", "Raid", "Hard" }; private static readonly string[] Modes = new string[2] { "Mod", "Vanilla" }; private ConfigEntry<bool> _cfgWatchFile; private FileSystemWatcher _watcher; private volatile bool _fileChanged; private float _reloadAt; private float _lastSettingChange = -100f; private bool _reloading; public static ExtendedBossesPlugin Instance; private Harmony _harmony; private int _errorCount; private bool _disabledByErrors; private readonly HashSet<string> _loggedErrors = new HashSet<string>(); private float _nextTick; private float _nextOrphanScan; private static FieldInfo _fiProjectileOwner; internal static readonly int KPhase = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.phase"); internal static readonly int KTotems = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.totems"); internal static readonly int KShieldAct = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.shield"); internal static readonly int KResistAct = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.resist"); internal static readonly int KResistUntil = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.resistuntil"); internal static readonly int KWindowUntil = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.window"); internal static readonly int KShieldSince = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.shieldsince"); internal static readonly int KCycleAct = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.cycle"); internal static readonly int KCycleStartAt = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.cyclestart"); internal static readonly int KCycleStarted = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.cycleon"); internal static readonly int KCycleUntil = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.cycleuntil"); internal static readonly int KCycleNext = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.cyclenext"); internal static readonly int KCycleAdapt = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.cycleadapt"); internal static readonly int KCycleKind = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.cyclekind"); internal static readonly int KHpMul = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.hpmul"); internal static readonly int KSrc = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.src"); internal static readonly int KRole = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.role"); internal static readonly int KExpire = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.expire"); internal static readonly int KFuseHeal = StringExtensionMethods.GetStableHashCode("j1ga.extendedbosses.fuseheal"); private readonly Dictionary<ZDOID, FightRt> _fights = new Dictionary<ZDOID, FightRt>(); private readonly List<Character> _tmpBosses = new List<Character>(); private readonly List<ZDOID> _tmpIds = new List<ZDOID>(); private int _forcePlayers; private readonly List<GameObject> _tmpExpired = new List<GameObject>(); private FieldInfo _instancesField; private int _checkOk; private List<string> _checkProblems = new List<string>(); private readonly List<Circle> _circles = new List<Circle>(); private Material _circleMat; private static readonly Dictionary<string, string[]> Texts = new Dictionary<string, string[]> { { "eikthyr.80", new string[2] { "{0}: Herd, to me!", "{0}: Стадо, ко мне!" } }, { "eikthyr.60", new string[2] { "{0} lowers the antlers - beware the charge!", "{0} пригибает рога — берегитесь рывка!" } }, { "eikthyr.50", new string[2] { "{0}: Rise, bones! (smash the skull pile)", "{0}: Кости, встаньте! (разбейте груду черепов)" } }, { "eikthyr.30", new string[2] { "{0}: The sky answers me! (the marked one - move away from the others)", "{0}: Небо, ответь мне! (отмеченный — отойди от остальных)" } }, { "eikthyr.15", new string[2] { "{0} calls the leader of the herd!", "{0} призывает вожака стада!" } }, { "eikthyr.mark", new string[2] { "{0} marks {1} for lightning - spread out!", "{0} метит молнией: {1} — разойдитесь!" } }, { "elder.85", new string[2] { "{0}: Forest, hear me! (destroy the nest)", "{0}: Лес, услышь меня! (разрушьте гнездо)" } }, { "elder.70", new string[2] { "{0}: More of my children! (nests - and roots stir underfoot)", "{0}: Ещё мои дети! (гнёзда — и корни под ногами)" } }, { "elder.55", new string[2] { "{0}: My nests shield me! (destroy them all)", "{0}: Гнёзда укроют меня! (разрушьте их все)" } }, { "elder.bark.sap", new string[2] { "{0}: the bark swells with sap - fire is useless, chop with axes!", "{0}: кора набухла соком — огонь бесполезен, рубите топорами!" } }, { "elder.bark.back", new string[2] { "{0} is covered in living bark - only blows to the back hurt! Tank, hold it facing you!", "{0}: живая кора — ранят только удары в спину! Танк, держите босса лицом к себе!" } }, { "elder.bark.end", new string[2] { "{0}: the bark cracks - hit with anything!", "{0}: кора трескается — бейте чем угодно!" } }, { "elder.45", new string[2] { "{0} calls a troll!", "{0} призывает тролля!" } }, { "elder.30", new string[2] { "{0} wakes a bear!", "{0} будит медведя!" } }, { "elder.20", new string[2] { "{0} calls the elite - kill the shamans first, they heal the boss!", "{0} зовёт элиту — сначала убейте шаманов, они лечат босса!" } }, { "elder.10", new string[2] { "{0}: Dead of the barrows, rise!", "{0}: Мёртвые курганов, встаньте!" } }, { "elder.mark", new string[2] { "Roots stir under {1} - get out!", "Корни шевелятся под игроком {1} — выбирайтесь!" } }, { "elder.seed", new string[2] { "A seed of {0} takes root - a new nest!", "Семя ({0}) пустило корни — новое гнездо!" } }, { "bonemass.85", new string[2] { "{0}: The swamp remembers its dead! (destroy the bone pile)", "{0}: Болото помнит своих мертвецов! (разрушьте кучу костей)" } }, { "bonemass.70", new string[2] { "{0}: More bones! (piles - poison underfoot - leeches in the water)", "{0}: Больше костей! (кучи — яд под ногами — пиявки в воде)" } }, { "bonemass.55", new string[2] { "{0}: The bones shield me! (destroy all the piles)", "{0}: Кости укроют меня! (разрушьте все кучи)" } }, { "bonemass.harden", new string[2] { "{0}: the bones harden - blunt is useless, burn it!", "{0}: кости затвердели — дробящее бесполезно, жгите!" } }, { "bonemass.harden.end", new string[2] { "{0}: the bones soften again", "{0}: кости снова размякли" } }, { "bonemass.rot", new string[2] { "{0}: rotten steam - close blows sink in and poison you, strike from afar!", "{0}: гнилостный пар — удары вблизи вязнут и травят, бейте издалека!" } }, { "bonemass.rot.end", new string[2] { "{0}: the steam clears", "{0}: пар рассеялся" } }, { "bonemass.45", new string[2] { "{0} raises an abomination! Slime will crawl to the boss - kill it before it merges!", "{0} поднимает мерзость! К боссу поползёт слизь — убейте её, пока не слилась!" } }, { "bonemass.fusion", new string[2] { "{0} calls the slime - intercept it!", "{0} зовёт слизь — перехватите её!" } }, { "bonemass.40", new string[2] { "{0}: Writhans, to me!", "{0}: Скручни, ко мне!" } }, { "bonemass.35", new string[2] { "{0}: Fire of the swamp, come! (surtlings)", "{0}: Огонь болот, ко мне! (суртлинги)" } }, { "bonemass.25", new string[2] { "{0} raises the elite dead!", "{0} поднимает элитных драугров!" } }, { "bonemass.15", new string[2] { "{0}: Spirits of the swamp, feast!", "{0}: Духи болота, пируйте!" } }, { "bonemass.mark", new string[2] { "{0} spits poison under {1} - spread out!", "{0} плюёт ядом под игрока {1} — разойдитесь!" } }, { "moder.85", new string[2] { "{0}: The ice will bear my brood! (break the ice spike) - the pack is coming!", "{0}: Лёд выносит моё потомство! (разбейте ледяной сталагмит) — идёт стая!" } }, { "moder.70", new string[2] { "{0}: More ice, more young! (spikes - frost flashes under your feet)", "{0}: Больше льда — больше детёнышей! (сталагмиты — ледяные вспышки под ногами)" } }, { "moder.55", new string[2] { "{0}: The ice shields me! (break every spike)", "{0}: Лёд укроет меня! (разбейте все сталагмиты)" } }, { "moder.ice", new string[2] { "{0}: ice armor - arrows bounce off while she is on the ground, fight up close!", "{0}: ледяная броня — пока она на земле, стрелы отскакивают, бейте вблизи!" } }, { "moder.ice.end", new string[2] { "{0}: the ice armor melts", "{0}: ледяная броня тает" } }, { "moder.thorns", new string[2] { "{0}: ice thorns - every blow is paid back with frost, hit with care!", "{0}: ледяные шипы — каждый удар возвращается морозом, бейте с умом!" } }, { "moder.thorns.end", new string[2] { "{0}: the thorns break off", "{0}: шипы обламываются" } }, { "moder.45", new string[2] { "{0} calls the cultists - their fire burns her ice too!", "{0} зовёт культистов — их огонь жжёт и её лёд!" } }, { "moder.35", new string[2] { "{0} wakes the stone golem!", "{0} будит каменного голема!" } }, { "moder.20", new string[2] { "{0}: All my brood, to me!", "{0}: Всё моё потомство — ко мне!" } }, { "moder.mark", new string[2] { "{0} breathes frost under {1} - spread out!", "{0} дышит морозом под игрока {1} — разойдитесь!" } }, { "moder.breath", new string[2] { "{0} lands and fixes her eyes on {1} - the rest, stay out of her breath!", "{0} садится и смотрит на игрока {1} — остальные, не стойте под её дыханием!" } }, { "yagluth.85", new string[2] { "{0}: My tribe, rise! (break the fuling totem)", "{0}: Моё племя, встань! (сломайте тотем фулингов)" } }, { "yagluth.70", new string[2] { "{0}: Burn! (more totems - meteors fall on the marked)", "{0}: Горите! (ещё тотемы — метеоры падают на отмеченных)" } }, { "yagluth.55", new string[2] { "{0}: The totems shield me, the shamans mend me! (break the totems, kill the shamans)", "{0}: Тотемы укроют, шаманы исцелят! (сломайте тотемы, убейте шаманов)" } }, { "yagluth.regen", new string[2] { "{0} feeds on fire - he heals unless chilled! Hit with frost!", "{0} питается огнём — он лечится, пока его не остудят! Бейте морозом!" } }, { "yagluth.regen.end", new string[2] { "{0}: the fire inside dims", "{0}: огонь внутри угасает" } }, { "yagluth.adapt", new string[2] { "{0} adapts: {1} hurts him less - switch weapons!", "{0} приспособился: урон «{1}» проходит слабее — смените оружие!" } }, { "yagluth.adapt.end", new string[2] { "{0} loses the adaptation", "{0}: приспособление прошло" } }, { "yagluth.45", new string[2] { "{0} calls the brutes!", "{0} зовёт брютов!" } }, { "yagluth.30", new string[2] { "{0} wakes the Unbjorn!", "{0} будит анбьёрна!" } }, { "yagluth.20", new string[2] { "{0}: Bones of my servants, rise!", "{0}: Кости моих слуг, встаньте!" } }, { "yagluth.15", new string[2] { "{0}: Swarm, drink their blood!", "{0}: Рой, пей их кровь!" } }, { "yagluth.10", new string[2] { "{0} calls an echo of the dragon queen!", "{0} призывает эхо королевы драконов!" } }, { "yagluth.mark", new string[2] { "{0} calls meteors on {1} - run!", "{0} зовёт метеоры на игрока {1} — бегите!" } }, { "yagluth.beam", new string[2] { "{0} locks his gaze on {1} - break line of sight!", "{0} не сводит глаз с игрока {1} — укройтесь от луча!" } }, { "queen.85", new string[2] { "{0} lays a clutch! (smash the eggs before they hatch)", "{0} откладывает кладку! (разбейте яйца, пока не вылупились)" } }, { "queen.70", new string[2] { "{0}: More children! (eggs - acid falls on the marked)", "{0}: Больше детей! (яйца — кислота на отмеченных)" } }, { "queen.55", new string[2] { "{0}: My brood shields me! (smash every egg)", "{0}: Выводок укроет меня! (разбейте все яйца)" } }, { "queen.blood", new string[2] { "{0} thirsts - her blows heal her! Dodge, block, keep away!", "{0} жаждет крови — её удары лечат её! Уклоняйтесь, блокируйте, не подставляйтесь!" } }, { "queen.blood.end", new string[2] { "{0}: the thirst fades", "{0}: жажда утихает" } }, { "queen.acid", new string[2] { "{0}: acid thorns - every blow is paid back with poison, hit with care!", "{0}: кислотные шипы — каждый удар возвращается ядом, бейте с умом!" } }, { "queen.acid.end", new string[2] { "{0}: the acid dries up", "{0}: кислота высыхает" } }, { "queen.45", new string[2] { "{0} calls her guards!", "{0} зовёт стражей!" } }, { "queen.30", new string[2] { "{0} calls a gjall from the mist!", "{0} призывает гьялля из тумана!" } }, { "queen.20", new string[2] { "{0}: All my brood, devour them!", "{0}: Весь выводок — пожрите их!" } }, { "queen.mark", new string[2] { "{0} spits acid at {1} - spread out!", "{0} плюёт кислотой в игрока {1} — разойдитесь!" } }, { "queen.cocoon", new string[2] { "{0} hides behind her guards - kill them to reach her!", "{0} укрылась за стражами — убейте их, чтобы добраться до неё!" } }, { "fader.85", new string[2] { "{0}: Rise, charred! (break the spawner stone)", "{0}: Встаньте, обугленные! (разбейте камень-спавнер)" } }, { "fader.70", new string[2] { "{0}: The sky burns! (more stones - meteors fall on the marked)", "{0}: Небо горит! (ещё камни — метеоры падают на отмеченных)" } }, { "fader.55", new string[2] { "{0}: The stones shield me! (break them all)", "{0}: Камни укроют меня! (разбейте их все)" } }, { "fader.molten", new string[2] { "{0}: molten armor - close blows sink in and burn you, strike from afar!", "{0}: раскалённая броня — удары вблизи вязнут и обжигают, бейте издалека!" } }, { "fader.molten.end", new string[2] { "{0}: the armor cools", "{0}: броня остывает" } }, { "fader.ash", new string[2] { "{0}: ash veil - arrows and spells get lost, fight up close!", "{0}: пепельная завеса — стрелы и заклинания теряются, бейте вблизи!" } }, { "fader.ash.end", new string[2] { "{0}: the ash settles", "{0}: пепел оседает" } }, { "fader.45", new string[2] { "{0} wakes a morgen!", "{0} будит моргена!" } }, { "fader.30", new string[2] { "{0} calls a fallen valkyrie!", "{0} призывает падшую валькирию!" } }, { "fader.20", new string[2] { "{0} calls Lord Reto!", "{0} призывает лорда Рето!" } }, { "fader.10", new string[2] { "{0}: Ashlands, devour them!", "{0}: Пепельные земли, пожрите их!" } }, { "fader.mark", new string[2] { "{0} calls meteors on {1} - run!", "{0} зовёт метеоры на игрока {1} — бегите!" } }, { "fader.wall", new string[2] { "{0} raises a wall of fire - split up!", "{0} поднимает стену огня — разделитесь!" } }, { "window", new string[2] { "{0}: the shield has fallen - strike now!", "{0}: защита пала — бейте!" } }, { "shield.fade", new string[2] { "{0}: the shield crumbles by itself", "{0}: щит рассыпается сам" } }, { "reset", new string[2] { "{0} regains strength...", "{0} восстанавливает силы…" } }, { "cmd.help", new string[2] { "eb status | check | phase <n> | reset | probe <prefab> | players <n|0>", "eb status | check | phase <n> | reset | probe <префаб> | players <n|0>" } }, { "cmd.noboss", new string[2] { "No boss owned by this client nearby (the mechanics run on the owner).", "Рядом нет босса, которым владеет этот клиент (механики работают у владельца)." } }, { "cmd.reset", new string[2] { "{0}: fight reset.", "{0}: бой сброшен." } }, { "cmd.phase", new string[2] { "{0}: phase {1} ({2}%) forced.", "{0}: фаза {1} ({2} %) запущена." } }, { "cmd.phaseusage", new string[2] { "eb phase <0..{0}>", "eb phase <0..{0}>" } }, { "cmd.players", new string[2] { "eb players <n> (0 = count real players)", "eb players <n> (0 — считать реальных игроков)" } }, { "cmd.playerscount", new string[2] { "Group size: counted.", "Размер группы: считается по игрокам." } }, { "cmd.playersforced", new string[2] { "Group size forced to {0} (this client only).", "Размер группы принудительно {0} (только на этом клиенте)." } }, { "cmd.inert", new string[2] { "{0} is inert after errors (see the log).", "{0} отключился после ошибок (см. лог)." } }, { "cmd.noworld", new string[2] { "Not in a world.", "Не в мире." } }, { "cmd.nobosses", new string[2] { "No known boss loaded nearby.", "Рядом нет загруженных боссов мода." } }, { "cmd.status", new string[2] { "{0}: {1}/{2}, HP {3}%, phases {4}/{5}, {6}, group {7}, damage x{8}, adds {9}, nests {10}{11}", "{0}: {1}/{2}, HP {3} %, фазы {4}/{5}, {6}, группа {7}, урон x{8}, адды {9}, гнёзда {10}{11}" } }, { "cmd.ownedhere", new string[2] { "owned here", "владелец — этот клиент" } }, { "cmd.ownedother", new string[2] { "owned by another client", "владелец — другой клиент" } }, { "cmd.shield", new string[2] { ", SHIELD", ", ЩИТ" } }, { "cmd.window", new string[2] { ", WINDOW", ", ОКНО" } }, { "cmd.cocoon", new string[2] { ", COCOON", ", КОКОН" } }, { "cmd.fixate", new string[2] { ", FIXATED", ", ФИКСАЦИЯ" } }, { "cmd.resist", new string[2] { ", RESIST", ", СОПРОТИВЛЕНИЕ" } }, { "cmd.cycle.sap", new string[2] { ", BARK (sap)", ", КОРА (сок)" } }, { "cmd.cycle.back", new string[2] { ", BARK (back)", ", КОРА (спина)" } }, { "cmd.cycle.harden", new string[2] { ", HARDENED", ", ЗАТВЕРДЕЛ" } }, { "cmd.cycle.rot", new string[2] { ", ROTTEN STEAM", ", ГНИЛОСТНЫЙ ПАР" } }, { "cmd.cycle.icearmor", new string[2] { ", ICE ARMOR", ", ЛЕДЯНАЯ БРОНЯ" } }, { "cmd.cycle.thorns", new string[2] { ", ICE THORNS", ", ЛЕДЯНЫЕ ШИПЫ" } }, { "cmd.cycle.regen", new string[2] { ", REGENERATION", ", РЕГЕНЕРАЦИЯ" } }, { "cmd.cycle.adapt", new string[2] { ", ADAPTED", ", АДАПТАЦИЯ" } }, { "cmd.cycle.bloodthirst", new string[2] { ", BLOODTHIRST", ", КРОВОЖАДНОСТЬ" } }, { "cmd.cycle.acidthorns", new string[2] { ", ACID THORNS", ", КИСЛОТНЫЕ ШИПЫ" } }, { "cmd.cycle.molten", new string[2] { ", MOLTEN ARMOR", ", РАСКАЛЁННАЯ БРОНЯ" } }, { "cmd.cycle.ashveil", new string[2] { ", ASH VEIL", ", ПЕПЕЛЬНАЯ ЗАВЕСА" } }, { "cmd.checkdone", new string[2] { "Self-check: {0} prefab(s) OK, {1} problem(s) - details in the log.", "Самопроверка: {0} префаб(ов) в порядке, проблем: {1} — подробности в логе." } } }; private ConfigEntry<string> _cfgGuestLanguage; private readonly HashSet<long> _moddedPeers = new HashSet<long>(); private bool _helloSent; private ConfigEntry<bool> _cfgSync; private bool _syncDirty; private bool _serverSynced; private readonly Dictionary<string, object> _serverByKey = new Dictionary<string, object>(); private static MethodInfo _miSetTarget; private readonly List<ZDOID> _tmpThreatIds = new List<ZDOID>(); internal bool Active { get { if (!_disabledByErrors && Sb(_cfgEnabled) && (Object)(object)ZNet.instance != (Object)null) { return (Object)(object)ZNetScene.instance != (Object)null; } return false; } } internal BossDef BossOf(ZDO zdo) { if (zdo == null || !_bossByHash.TryGetValue(zdo.GetPrefab(), out var value)) { return null; } return value; } private void AddBoss(BossDef b) { b.Hash = StringExtensionMethods.GetStableHashCode(b.Prefab); _bosses.Add(b); _bossByHash[b.Hash] = b; } private void BuildBosses() { AddBoss(Eikthyr()); AddBoss(Elder()); AddBoss(Bonemass()); AddBoss(Moder()); AddBoss(Yagluth()); AddBoss(Queen()); AddBoss(Fader()); } private static PhaseDef Phase(BossDef b, float pct, string say) { PhaseDef phaseDef = new PhaseDef(); phaseDef.Pct = pct; phaseDef.Say = say; PhaseDef phaseDef2 = phaseDef; b.Phases.Add(phaseDef2); return phaseDef2; } private static Dictionary<DamageType, float> Mods(params object[] pairs) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) Dictionary<DamageType, float> dictionary = new Dictionary<DamageType, float>(); for (int i = 0; i + 1 < pairs.Length; i += 2) { dictionary[(DamageType)pairs[i]] = (float)pairs[i + 1]; } return dictionary; } private void BindCycle(BossDef d, string prefix, string whatEn, string whatRu, params string[] variantIds) { if (variantIds != null && variantIds.Length > 1) { List<string> list = new List<string>(); list.Add("Random"); list.AddRange(variantIds); list.Add("Auto"); d.CfgCycleVariant = S(d.Section, prefix + "Variant", "Random", "Which variant (" + whatEn + ") comes: Random (chosen anew each time), a variant name to pin it, or Auto (positional variant for a group of 3+). A single player never gets a positional variant.", "Какой вариант (" + whatRu + "): Random — заново каждый раз, имя варианта — всегда он, Auto — позиционный для группы от 3 игроков. Одному игроку позиционный вариант не выпадает никогда.", list.ToArray()); } d.CfgCycleDuration = F(d.Section, prefix + "Duration", 30f, 5f, 120f, "Seconds each " + whatEn + " lasts.", "Длительность (" + whatRu + "), секунд."); d.CfgCycleCdMin = F(d.Section, prefix + "CooldownMin", 50f, 5f, 300f, "Cooldown between: from...", "Перерыв между: от…"); d.CfgCycleCdMax = F(d.Section, prefix + "CooldownMax", 70f, 5f, 300f, "...to (random each time).", "…до (случайно каждый раз)."); d.CfgCycleDelay = F(d.Section, prefix + "StartDelay", 60f, 0f, 300f, "The first one comes when the stagger after the fallen shield ends; if the shield still stands this long after 55%, it starts anyway.", "Первый раз — когда кончается оглушение после падения щита; если щит стоит дольше этого после 55 %, начинается всё равно."); } private static BossDef Eikthyr() { //IL_0193: Unknown result type (might be due to invalid IL or missing references) BossDef bossDef = new BossDef(); bossDef.Prefab = "Eikthyr"; bossDef.Section = "10 Eikthyr"; BossDef bossDef2 = bossDef; Phase(bossDef2, 80f, "eikthyr.80").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[2] { "Boar", "Neck" }, Count = 2f }); Phase(bossDef2, 60f, "eikthyr.60").Acts.Add(new Act { Kind = ActKind.Charge }); Phase(bossDef2, 50f, "eikthyr.50").Acts.Add(new Act { Kind = ActKind.Totem, Prop = "skull_pile", Count = 1f, Prefabs = new string[3] { "Skeleton_Meadows_noarcher", "Skeleton_Meadows_noarcher", "Skeleton_Meadows" }, Interval = 12f, MaxAlive = 3 }); Phase(bossDef2, 30f, "eikthyr.30").Acts.Add(new Act { Kind = ActKind.Marks, Prefabs = new string[1] { "lightningAOE" }, Prop = "vfx_prespawn", MarkKey = "eikthyr.mark", Count = 1f, Damage = 15f, DamageType = (DamageType)128 }); Phase(bossDef2, 15f, "eikthyr.15").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Boar" }, Level = 3, HpMul = 3f }); bossDef2.Reward.Valuables.Add(new Loot("Coins", 60, 90, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("Amber", 3, 3, perPlayer: true)); bossDef2.Reward.NextBiome.Add(new Loot("CopperOre", 2, 4, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("TinOre", 2, 4, perPlayer: false)); bossDef2.Reward.Gear = new string[10] { "AxeFlint", "SpearFlint", "KnifeFlint", "Club", "Bow", "ShieldWood", "ArmorLeatherChest", "ArmorLeatherLegs", "HelmetLeather", "CapeDeerHide" }; bossDef2.Reward.NextGear = new string[9] { "AxeBronze", "MaceBronze", "SwordBronze", "SpearBronze", "AtgeirBronze", "ArmorBronzeChest", "ArmorBronzeLegs", "HelmetBronze", "ShieldBronzeBuckler" }; bossDef2.BindExtra = delegate(ExtendedBossesPlugin pl, BossDef d) { d.CfgTotemPrefab = pl.S(d.Section, "TotemPrefab", "skull_pile", "Destructible vanilla object used as the skeleton totem at 50%. Must be networked and destructible (see the self-check in the log). Fallback: BonePileSpawner.", "Разрушаемый ванильный объект — тотем со скелетами на 50 %. Должен быть сетевым и разрушаемым (см. самопроверку в логе). Запасной — BonePileSpawner."); d.CfgMarkPrefab = pl.S(d.Section, "MarkPrefab", "lightningAOE", "Vanilla AoE prefab of the lightning strike at 30%.", "Ванильный AoE-префаб удара молнии на 30 %."); d.CfgMarkEffect = pl.S(d.Section, "MarkEffect", "vfx_prespawn", "Vanilla effect on the marked player before the strike (players with the mod).", "Ванильный эффект на отмеченном игроке до удара (у игроков с модом)."); d.CfgMarkDamage = pl.F(d.Section, "MarkDamage", 15f, 0f, 500f, "Lightning damage of the strike (before 04 Marks DamageMultiplier).", "Урон молнией (до множителя из 04 Marks)."); d.CfgChargeInterval = pl.F(d.Section, "ChargeInterval", 20f, 5f, 120f, "Seconds between charges from 60%.", "Секунд между рывками с 60 %."); d.CfgChargeSpeed = pl.F(d.Section, "ChargeSpeed", 2f, 1f, 4f, "Speed multiplier during a charge.", "Множитель скорости во время рывка."); d.CfgChargeDuration = pl.F(d.Section, "ChargeDuration", 2.5f, 0.5f, 8f, "Seconds a charge lasts.", "Длительность рывка, секунд."); }; return bossDef2; } private static BossDef Elder() { BossDef bossDef = new BossDef(); bossDef.Prefab = "gd_king"; bossDef.Section = "11 Elder"; BossDef bossDef2 = bossDef; Phase(bossDef2, 85f, "elder.85").Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_GreydwarfNest" }, Count = 1f }); PhaseDef phaseDef = Phase(bossDef2, 70f, "elder.70"); phaseDef.Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_GreydwarfNest" }, Count = 2f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Marks, Creature = "TentaRoot", CreatureCount = 4, RingRadius = 3f, Lifetime = 15f, Prop = "vfx_prespawn", MarkKey = "elder.mark", Count = 1f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Seeds, Prefabs = new string[1] { "Spawner_GreydwarfNest" }, Chance = 0.05f, Interval = 20f, MaxAlive = 2, MarkKey = "elder.seed" }); phaseDef = Phase(bossDef2, 55f, "elder.55"); phaseDef.Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_GreydwarfNest" }, Count = 3f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Shield }); phaseDef.Acts.Add(new Act { Kind = ActKind.Cycle, Duration = 30f, CooldownMin = 50f, CooldownMax = 70f, Delay = 60f, EndKey = "elder.bark.end", Variants = new List<CycleVariant> { new CycleVariant { Id = "Sap", Say = "elder.bark.sap", Other = 0.25f, Mods = Mods((object)(DamageType)2, 1.25f, (object)(DamageType)32, 0.25f) }, new CycleVariant { Id = "Back", Say = "elder.bark.back", Other = 0.25f, Back = true } } }); Phase(bossDef2, 45f, "elder.45").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Troll" }, ExtraFrom = 3 }); Phase(bossDef2, 30f, "elder.30").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Bjorn" } }); phaseDef = Phase(bossDef2, 20f, "elder.20"); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Greydwarf_Elite" }, Count = 2f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Greydwarf_Shaman" }, Count = 1f, Role = 1 }); Phase(bossDef2, 10f, "elder.10").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[2] { "Skeleton", "Ghost" }, Count = 1f }); bossDef2.Reward.Valuables.Add(new Loot("Coins", 120, 180, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("Amber", 3, 6, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("Ruby", 1, 1, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("CopperOre", 4, 8, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("TinOre", 4, 8, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("IronScrap", 2, 4, perPlayer: false)); bossDef2.Reward.Gear = new string[15] { "AxeBronze", "MaceBronze", "SwordBronze", "SpearBronze", "AtgeirBronze", "KnifeCopper", "BowFineWood", "ArmorBronzeChest", "ArmorBronzeLegs", "HelmetBronze", "ShieldBronzeBuckler", "ArmorTrollLeatherChest", "ArmorTrollLeatherLegs", "HelmetTrollLeather", "CapeTrollHide" }; bossDef2.Reward.NextGear = new string[9] { "SwordIron", "MaceIron", "AxeIron", "SpearElderbark", "AtgeirIron", "ArmorIronChest", "ArmorIronLegs", "HelmetIron", "ShieldBanded" }; bossDef2.BindExtra = delegate(ExtendedBossesPlugin pl, BossDef d) { d.CfgNestPrefab = pl.S(d.Section, "NestPrefab", "Spawner_GreydwarfNest", "Vanilla destructible spawner placed at 85/70/55%.", "Ванильный разрушаемый спавнер на 85/70/55 %."); d.CfgMarkCreature = pl.S(d.Section, "RootsCreature", "TentaRoot", "Creature summoned in a ring around the marked player from 70%.", "Существо, которое появляется кольцом вокруг отмеченного игрока с 70 %."); d.CfgMarkEffect = pl.S(d.Section, "MarkEffect", "vfx_prespawn", "Vanilla effect on the marked player before the roots (players with the mod).", "Ванильный эффект на отмеченном игроке до корней (у игроков с модом)."); pl.BindCycle(d, "Bark", "living bark - Sap: fire x0.25, slash x1.25, the rest x0.25; Back: x0.25 from the front, full from behind", "живая кора: Sap — огонь ×0.25, рубящий ×1.25, остальное ×0.25; Back — спереди ×0.25, в спину полный", "Sap", "Back"); d.CfgBackArc = pl.F(d.Section, "BackArc", 120f, 30f, 270f, "Back variant: width of the arc behind the Elder that counts as 'the back', degrees.", "Вариант Back: ширина дуги позади Древнего, которая считается спиной, градусов."); }; return bossDef2; } private static BossDef Bonemass() { //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) BossDef bossDef = new BossDef(); bossDef.Prefab = "Bonemass"; bossDef.Section = "12 Bonemass"; BossDef bossDef2 = bossDef; Phase(bossDef2, 85f, "bonemass.85").Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_DraugrPile" }, Count = 1f }); PhaseDef phaseDef = Phase(bossDef2, 70f, "bonemass.70"); phaseDef.Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_DraugrPile" }, Count = 2f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Leech" }, Count = 2f, InWater = true }); phaseDef.Acts.Add(new Act { Kind = ActKind.Marks, Prefabs = new string[1] { "bonemass_aoe" }, Prop = "vfx_prespawn", MarkKey = "bonemass.mark", Count = 1f, Damage = 25f, DamageType = (DamageType)256 }); phaseDef.Acts.Add(new Act { Kind = ActKind.HitEffect, Effect = "Wet" }); phaseDef = Phase(bossDef2, 55f, "bonemass.55"); phaseDef.Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_DraugrPile" }, Count = 3f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Shield }); phaseDef.Acts.Add(new Act { Kind = ActKind.Cycle, Duration = 30f, CooldownMin = 50f, CooldownMax = 70f, Delay = 60f, Variants = new List<CycleVariant> { new CycleVariant { Id = "Harden", Say = "bonemass.harden", EndKey = "bonemass.harden.end", Other = 1f, Mods = Mods((object)(DamageType)1, 0.25f, (object)(DamageType)32, 2f) }, new CycleVariant { Id = "Rot", Say = "bonemass.rot", EndKey = "bonemass.rot.end", Other = 1f, MeleeFactor = 0.5f, MeleeRange = 5f, Retaliate = 12f, RetaliateType = (DamageType)256 } } }); phaseDef = Phase(bossDef2, 45f, "bonemass.45"); phaseDef.Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Abomination" } }); phaseDef.Acts.Add(new Act { Kind = ActKind.Fusion, Prefabs = new string[3] { "Blob", "Blob", "BlobElite" }, Count = 2f, Interval = 25f, Heal = 6f, MarkKey = "bonemass.fusion" }); Phase(bossDef2, 40f, "bonemass.40").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Writhan" }, Count = 1f }); phaseDef = Phase(bossDef2, 35f, "bonemass.35"); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Surtling" }, Count = 2f }); phaseDef.Acts.Add(new Act { Kind = ActKind.HitEffect, Effect = "Tared" }); Phase(bossDef2, 25f, "bonemass.25").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Draugr_Elite" }, Count = 1f }); Phase(bossDef2, 15f, "bonemass.15").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[3] { "Wraith", "Bat_Swamp", "Bat_Swamp" }, Count = 1f }); bossDef2.Reward.Valuables.Add(new Loot("Coins", 180, 270, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("Ruby", 1, 2, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("AmberPearl", 1, 1, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("IronScrap", 6, 10, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("SilverOre", 2, 4, perPlayer: false)); bossDef2.Reward.Gear = new string[14] { "SwordIron", "MaceIron", "AxeIron", "AtgeirIron", "SpearElderbark", "BowHuntsman", "ArmorIronChest", "ArmorIronLegs", "HelmetIron", "ShieldBanded", "ShieldIronTower", "ArmorRootChest", "ArmorRootLegs", "HelmetRoot" }; bossDef2.Reward.NextGear = new string[10] { "SwordSilver", "MaceSilver", "SpearWolfFang", "KnifeSilver", "BowDraugrFang", "ArmorWolfChest", "ArmorWolfLegs", "HelmetDrake", "CapeWolf", "ShieldSilver" }; bossDef2.BindExtra = delegate(ExtendedBossesPlugin pl, BossDef d) { d.CfgNestPrefab = pl.S(d.Section, "NestPrefab", "Spawner_DraugrPile", "Vanilla destructible spawner placed at 85/70/55% (bone pile). Alternative: BonePileSpawner_swamp.", "Ванильный разрушаемый спавнер на 85/70/55 % (куча костей). Альтернатива — BonePileSpawner_swamp."); d.CfgMarkPrefab = pl.S(d.Section, "MarkPrefab", "bonemass_aoe", "Vanilla AoE prefab of the poison puddle under a marked player from 70%.", "Ванильный AoE-префаб ядовитой лужи под отмеченным игроком с 70 %."); d.CfgMarkEffect = pl.S(d.Section, "MarkEffect", "vfx_prespawn", "Vanilla effect on the marked player before the puddle (players with the mod).", "Ванильный эффект на отмеченном игроке до лужи (у игроков с модом)."); d.CfgMarkDamage = pl.F(d.Section, "MarkDamage", 25f, 0f, 500f, "Poison damage of the puddle (before 04 Marks DamageMultiplier).", "Урон ядом лужи (до множителя из 04 Marks)."); pl.BindCycle(d, "Cycle", "Harden: blunt x0.25, fire x2; Rot: close hits x0.5 and poison the attacker, ranged full", "Harden — затвердевание: дробящий ×0.25, огонь ×2; Rot — гнилостный пар: удары вблизи ×0.5 и травят атакующего, издалека полный", "Harden", "Rot"); d.CfgCycleMelee = pl.F(d.Section, "RotMeleeFactor", 0.5f, 0f, 1f, "Rotten steam: damage of hits from within 5 m (x).", "Гнилостный пар: урон ударов ближе 5 м (×)."); d.CfgCycleRetaliate = pl.F(d.Section, "RotPoisonDamage", 12f, 0f, 200f, "Rotten steam: poison dealt back to a close attacker per hit (at most once a second per player).", "Гнилостный пар: яд, который получает атакующий вблизи за удар (не чаще раза в секунду на игрока)."); d.CfgFusionInterval = pl.F(d.Section, "SlimeInterval", 25f, 5f, 180f, "From 45%: seconds between slime waves crawling to Bonemass.", "С 45 %: секунд между волнами слизи, ползущей к Массивному."); d.CfgFusionHeal = pl.F(d.Section, "SlimeWaveHealPercent", 6f, 0f, 50f, "% of max HP one slime wave can heal Bonemass in total, shared among its slimes (a bigger wave does not heal more).", "Сколько % макс. HP может вылечить Массивному одна волна слизи в сумме, поровну на её капли (большая волна не лечит больше)."); }; return bossDef2; } private static BossDef Moder() { //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) BossDef bossDef = new BossDef(); bossDef.Prefab = "Dragon"; bossDef.Section = "13 Moder"; BossDef bossDef2 = bossDef; string[] prefabs = new string[1] { "Hatchling" }; PhaseDef phaseDef = Phase(bossDef2, 85f, "moder.85"); phaseDef.Acts.Add(new Act { Kind = ActKind.Totem, Prop = "caverock_ice_stalagmite", Count = 1f, Prefabs = prefabs, Interval = 15f, MaxAlive = 2, Fallback = null }); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Wolf" }, NightPrefabs = new string[1] { "Ulv" }, Count = 2f }); phaseDef = Phase(bossDef2, 70f, "moder.70"); phaseDef.Acts.Add(new Act { Kind = ActKind.Totem, Prop = "caverock_ice_stalagmite", Count = 2f, Prefabs = prefabs, Interval = 15f, MaxAlive = 2, Fallback = null }); phaseDef.Acts.Add(new Act { Kind = ActKind.Marks, Prefabs = new string[1] { "FenringIceNova_aoe" }, Prop = "vfx_prespawn", MarkKey = "moder.mark", Count = 1f, Damage = 25f, DamageType = (DamageType)64 }); phaseDef = Phase(bossDef2, 55f, "moder.55"); phaseDef.Acts.Add(new Act { Kind = ActKind.Totem, Prop = "caverock_ice_stalagmite", Count = 3f, Prefabs = prefabs, Interval = 15f, MaxAlive = 2, Fallback = null }); phaseDef.Acts.Add(new Act { Kind = ActKind.Shield }); phaseDef.Acts.Add(new Act { Kind = ActKind.Cycle, Duration = 30f, CooldownMin = 50f, CooldownMax = 70f, Delay = 60f, Variants = new List<CycleVariant> { new CycleVariant { Id = "IceArmor", Say = "moder.ice", EndKey = "moder.ice.end", Other = 1f, MeleeRange = 6f, RangedFactor = 0.25f, GroundedOnly = true }, new CycleVariant { Id = "Thorns", Say = "moder.thorns", EndKey = "moder.thorns.end", Other = 1f, ThornsPercent = 12f, ThornsMin = 5f, RetaliateType = (DamageType)64 } } }); phaseDef = Phase(bossDef2, 45f, "moder.45"); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Fenring_Cultist" }, Count = 1f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Fixate, Land = true, Interval = 35f, Duration = 8f, MarkKey = "moder.breath" }); Phase(bossDef2, 35f, "moder.35").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "StoneGolem" } }); phaseDef = Phase(bossDef2, 20f, "moder.20"); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Fenring" }, Count = 1f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = prefabs, Count = 2f }); bossDef2.Reward.Valuables.Add(new Loot("Coins", 240, 360, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("Ruby", 1, 2, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("SilverNecklace", 1, 1, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("SilverOre", 6, 10, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("Obsidian", 4, 8, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("Crystal", 2, 4, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("BlackMetalScrap", 2, 4, perPlayer: false)); bossDef2.Reward.Gear = new string[13] { "SwordSilver", "MaceSilver", "SpearWolfFang", "KnifeSilver", "BowDraugrFang", "ShieldSilver", "ArmorWolfChest", "ArmorWolfLegs", "HelmetDrake", "CapeWolf", "ArmorFenringChest", "ArmorFenringLegs", "HelmetFenring" }; bossDef2.Reward.NextGear = new string[10] { "SwordBlackmetal", "AxeBlackMetal", "AtgeirBlackmetal", "KnifeBlackMetal", "MaceNeedle", "ShieldBlackmetal", "ArmorPaddedCuirass", "ArmorPaddedGreaves", "HelmetPadded", "CapeLinen" }; bossDef2.BindExtra = delegate(ExtendedBossesPlugin pl, BossDef d) { d.CfgTotemPrefab = pl.S(d.Section, "TotemPrefab", "caverock_ice_stalagmite", "Destructible vanilla object that hatches drakes at 85/70/55% and holds the shield. Must be networked and destructible (see the self-check).", "Разрушаемый ванильный объект, из которого вылупляются дрейки на 85/70/55 % и который держит щит. Должен быть сетевым и разрушаемым (см. самопроверку)."); d.CfgMarkPrefab = pl.S(d.Section, "MarkPrefab", "FenringIceNova_aoe", "Vanilla AoE prefab of the ice flash under a marked player from 70%.", "Ванильный AoE-префаб ледяной вспышки под отмеченным игроком с 70 %."); d.CfgMarkEffect = pl.S(d.Section, "MarkEffect", "vfx_prespawn", "Vanilla effect on the marked player before the flash (players with the mod).", "Ванильный эффект на отмеченном игроке до вспышки (у игроков с модом)."); d.CfgMarkDamage = pl.F(d.Section, "MarkDamage", 25f, 0f, 500f, "Frost damage of the flash (before 04 Marks DamageMultiplier); frost also slows.", "Урон морозом вспышки (до множителя из 04 Marks); мороз ещё и замедляет."); pl.BindCycle(d, "Cycle", "IceArmor: hits from afar x0.25 while she is on the ground; Thorns: every hit is paid back with frost", "IceArmor — ледяная броня: удары издалека ×0.25, пока она на земле; Thorns — ледяные шипы: каждый удар возвращается морозом", "IceArmor", "Thorns"); d.CfgCycleRanged = pl.F(d.Section, "IceArmorRangedFactor", 0.25f, 0f, 1f, "Ice armor: damage of hits from farther than 6 m (x), only while Moder is on the ground.", "Ледяная броня: урон ударов дальше 6 м (×), только пока Модер на земле."); d.CfgCycleThorns = pl.F(d.Section, "ThornsPercent", 12f, 0f, 100f, "Ice thorns: % of each hit's damage dealt back as frost to the attacker (at least 5, at most once a second per player).", "Ледяные шипы: % урона удара, который возвращается атакующему морозом (не меньше 5, не чаще раза в секунду на игрока)."); }; return bossDef2; } private static BossDef Yagluth() { //IL_02c8: Unknown result type (might be due to invalid IL or missing references) BossDef bossDef = new BossDef(); bossDef.Prefab = "GoblinKing"; bossDef.Section = "14 Yagluth"; BossDef bossDef2 = bossDef; string[] prefabs = new string[3] { "Goblin", "Goblin", "GoblinArcher" }; Phase(bossDef2, 85f, "yagluth.85").Acts.Add(new Act { Kind = ActKind.Totem, Prop = "goblin_totempole", Count = 1f, Prefabs = prefabs, Interval = 12f, MaxAlive = 3, Fallback = null }); PhaseDef phaseDef = Phase(bossDef2, 70f, "yagluth.70"); phaseDef.Acts.Add(new Act { Kind = ActKind.Totem, Prop = "goblin_totempole", Count = 2f, Prefabs = prefabs, Interval = 12f, MaxAlive = 3, Fallback = null }); phaseDef.Acts.Add(new Act { Kind = ActKind.Marks, Prefabs = new string[1] { "spawn_meteors" }, Prop = "vfx_prespawn", MarkKey = "yagluth.mark", Count = 1f }); phaseDef = Phase(bossDef2, 55f, "yagluth.55"); phaseDef.Acts.Add(new Act { Kind = ActKind.Totem, Prop = "goblin_totempole", Count = 3f, Prefabs = prefabs, Interval = 12f, MaxAlive = 3, Fallback = null }); phaseDef.Acts.Add(new Act { Kind = ActKind.Shield }); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "GoblinShaman" }, Count = 1f, Role = 1 }); phaseDef.Acts.Add(new Act { Kind = ActKind.Cycle, Duration = 30f, CooldownMin = 50f, CooldownMax = 70f, Delay = 60f, Variants = new List<CycleVariant> { new CycleVariant { Id = "Regen", Say = "yagluth.regen", EndKey = "yagluth.regen.end", RegenPercent = 0.3f, RegenStopType = (DamageType)64, RegenStopSeconds = 3f }, new CycleVariant { Id = "Adapt", Say = "yagluth.adapt", EndKey = "yagluth.adapt.end", Adapt = true, AdaptFactor = 0.6f, AdaptOthers = 1.1f } } }); phaseDef = Phase(bossDef2, 45f, "yagluth.45"); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "GoblinBrute" }, Count = 1f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Fixate, Interval = 30f, Duration = 8f, MarkKey = "yagluth.beam" }); phaseDef.Acts.Add(new Act { Kind = ActKind.HitEffect, Effect = "Tared" }); Phase(bossDef2, 30f, "yagluth.30").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Unbjorn" } }); Phase(bossDef2, 20f, "yagluth.20").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[3] { "Skeleton_NoArcher", "Skeleton", "Skeleton_Poison" }, Count = 1f }); Phase(bossDef2, 15f, "yagluth.15").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "Deathsquito" }, Count = 1f }); Phase(bossDef2, 10f, "yagluth.10").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Aspect_Moder" }, HpMul = 0.5f, Gate = "EchoOfModer" }); bossDef2.Reward.Valuables.Add(new Loot("Coins", 300, 450, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("SilverNecklace", 1, 2, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("Ruby", 2, 3, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("BlackMetalScrap", 8, 14, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("Softtissue", 2, 4, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("BlackCore", 1, 1, perPlayer: false)); bossDef2.Reward.Gear = new string[12] { "SwordBlackmetal", "AxeBlackMetal", "AtgeirBlackmetal", "KnifeBlackMetal", "MaceNeedle", "ShieldBlackmetal", "ShieldBlackmetalTower", "ArmorPaddedCuirass", "ArmorPaddedGreaves", "HelmetPadded", "CapeLinen", "CapeLox" }; bossDef2.Reward.NextGear = new string[18] { "SwordMistwalker", "AxeJotunBane", "THSwordKrom", "KnifeSkollAndHati", "SpearCarapace", "AtgeirHimminAfl", "MaceEldner", "BowSpineSnap", "CrossbowArbalest", "ShieldCarapace", "ArmorCarapaceChest", "ArmorCarapaceLegs", "HelmetCarapace", "ArmorMageChest", "ArmorMageLegs", "HelmetMage", "StaffFireball", "StaffIceShards" }; bossDef2.BindExtra = delegate(ExtendedBossesPlugin pl, BossDef d) { d.CfgTotemPrefab = pl.S(d.Section, "TotemPrefab", "goblin_totempole", "Destructible vanilla object that spawns fulings at 85/70/55% and holds the shield. Must be networked and destructible (see the self-check).", "Разрушаемый ванильный объект, из которого идут фулинги на 85/70/55 % и который держит щит. Должен быть сетевым и разрушаемым (см. самопроверку)."); d.CfgMarkPrefab = pl.S(d.Section, "MarkPrefab", "spawn_meteors", "Vanilla prefab dropped at a marked player from 70%: spawn_meteors (his meteor shower, its own damage) or an AoE such as aoe_nova.", "Ванильный префаб под отмеченным игроком с 70 %: spawn_meteors (его метеоритный дождь, урон свой) или AoE, например aoe_nova."); d.CfgMarkEffect = pl.S(d.Section, "MarkEffect", "vfx_prespawn", "Vanilla effect on the marked player before the meteors (players with the mod).", "Ванильный эффект на отмеченном игроке до метеоров (у игроков с модом)."); pl.BindCycle(d, "Cycle", "Regen: heals unless hit by frost within 3 s; Adapt: the most used damage type x0.6, the rest x1.1", "Regen — регенерация: лечится, если 3 с не получал мороза; Adapt — адаптация: самый частый тип урона ×0.6, остальные ×1.1", "Regen", "Adapt"); d.CfgRegen = pl.F(d.Section, "RegenPercentPerSecond", 0.3f, 0f, 5f, "Regeneration: % of max HP healed per second while no frost hit him for 3 s.", "Регенерация: % макс. HP в секунду, пока его 3 с не били морозом."); d.CfgAdaptFactor = pl.F(d.Section, "AdaptFactor", 0.6f, 0.1f, 1f, "Adaptation: damage of the type he adapted to (x).", "Адаптация: урон того типа, к которому он приспособился (×)."); d.CfgAdaptOthers = pl.F(d.Section, "AdaptOthers", 1.1f, 1f, 2f, "Adaptation: damage of every other type (x).", "Адаптация: урон всех остальных типов (×)."); d.Gates["EchoOfModer"] = pl.B(d.Section, "EchoOfModer", def: false, "Experiment: at 10% Yagluth calls the echo of Moder (Aspect_Moder, half HP). Off by default.", "Эксперимент: на 10 % Яглут призывает эхо Модер (Aspect_Moder, половина HP). По умолчанию выкл."); }; return bossDef2; } private static BossDef Queen() { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) BossDef bossDef = new BossDef(); bossDef.Prefab = "SeekerQueen"; bossDef.Section = "15 Queen"; BossDef bossDef2 = bossDef; Phase(bossDef2, 85f, "queen.85").Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "SeekerEgg_alwayshatch" }, Count = 2f, AnyProp = true }); PhaseDef phaseDef = Phase(bossDef2, 70f, "queen.70"); phaseDef.Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "SeekerEgg_alwayshatch" }, Count = 2f, AnyProp = true }); phaseDef.Acts.Add(new Act { Kind = ActKind.Marks, Prefabs = new string[1] { "SeekerQueen_spithit" }, Prop = "vfx_prespawn", MarkKey = "queen.mark", Count = 1f, Damage = 30f, DamageType = (DamageType)256 }); phaseDef = Phase(bossDef2, 55f, "queen.55"); phaseDef.Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "SeekerEgg_alwayshatch" }, Count = 3f, AnyProp = true }); phaseDef.Acts.Add(new Act { Kind = ActKind.Shield }); phaseDef.Acts.Add(new Act { Kind = ActKind.Cycle, Duration = 30f, CooldownMin = 50f, CooldownMax = 70f, Delay = 60f, Variants = new List<CycleVariant> { new CycleVariant { Id = "Bloodthirst", Say = "queen.blood", EndKey = "queen.blood.end", Lifesteal = 40f }, new CycleVariant { Id = "AcidThorns", Say = "queen.acid", EndKey = "queen.acid.end", ThornsPercent = 10f, ThornsMin = 5f, RetaliateType = (DamageType)256 } } }); phaseDef = Phase(bossDef2, 45f, "queen.45"); phaseDef.Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[1] { "SeekerBrute" }, Count = 1f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Cocoon, Prefabs = new string[2] { "Seeker", "SeekerBrood" }, Count = 1f, Duration = 20f, Interval = 30f, MarkKey = "queen.cocoon" }); Phase(bossDef2, 30f, "queen.30").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Gjall" } }); Phase(bossDef2, 20f, "queen.20").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[2] { "Tick", "SeekerBrood" }, Count = 2f }); bossDef2.Reward.Valuables.Add(new Loot("Coins", 360, 540, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("Ruby", 2, 3, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("Softtissue", 4, 8, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("BlackCore", 1, 2, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("Eitr", 2, 4, perPlayer: true)); bossDef2.Reward.NextBiome.Add(new Loot("FlametalOreNew", 2, 4, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("GemstoneRed", 1, 1, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("GemstoneGreen", 1, 1, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("GemstoneBlue", 1, 1, perPlayer: false)); bossDef2.Reward.Gear = new string[18] { "SwordMistwalker", "AxeJotunBane", "THSwordKrom", "KnifeSkollAndHati", "SpearCarapace", "AtgeirHimminAfl", "MaceEldner", "BowSpineSnap", "CrossbowArbalest", "ShieldCarapace", "ArmorCarapaceChest", "ArmorCarapaceLegs", "HelmetCarapace", "ArmorMageChest", "ArmorMageLegs", "HelmetMage", "StaffFireball", "StaffIceShards" }; bossDef2.Reward.NextGear = new string[11] { "SwordNiedhogg", "AxeBerzerkr", "THSwordSlayer", "SpearSplitner", "SledgeDemolisher", "BowAshlands", "CrossbowRipper", "ShieldFlametal", "ArmorFlametalChest", "ArmorFlametalLegs", "HelmetFlametal" }; bossDef2.BindExtra = delegate(ExtendedBossesPlugin pl, BossDef d) { d.CfgNestPrefab = pl.S(d.Section, "EggPrefab", "SeekerEgg_alwayshatch", "Vanilla egg laid in clutches at 85/70/55%: they hatch seekers on their own and hold her shield until smashed or hatched.", "Ванильное яйцо, кладки на 85/70/55 %: сами вылупляются ищущими и держат её щит, пока не разбиты или не вылупились."); d.CfgMarkPrefab = pl.S(d.Section, "MarkPrefab", "SeekerQueen_spithit", "Vanilla AoE prefab of the acid splash under a marked player from 70%.", "Ванильный AoE-префаб кислотного всплеска под отмеченным игроком с 70 %."); d.CfgMarkEffect = pl.S(d.Section, "MarkEffect", "vfx_prespawn", "Vanilla effect on the marked player before the acid (players with the mod).", "Ванильный эффект на отмеченном игроке до кислоты (у игроков с модом)."); d.CfgMarkDamage = pl.F(d.Section, "MarkDamage", 30f, 0f, 500f, "Poison damage of the acid splash (before 04 Marks DamageMultiplier).", "Урон ядом кислотного всплеска (до множителя из 04 Marks)."); pl.BindCycle(d, "Cycle", "Bloodthirst: her hits on players heal her; AcidThorns: every hit on her is paid back with poison", "Bloodthirst — кровожадность: её удары по игрокам лечат её; AcidThorns — кислотные шипы: каждый удар по ней возвращается ядом", "Bloodthirst", "AcidThorns"); d.CfgLifesteal = pl.F(d.Section, "BloodthirstPercent", 40f, 0f, 200f, "Bloodthirst: % of the raw damage of her hits on players she heals (before armor and block).", "Кровожадность: сколько % сырого урона её ударов по игрокам она лечит (до брони и блока)."); d.CfgCycleThorns = pl.F(d.Section, "AcidThornsPercent", 10f, 0f, 100f, "Acid thorns: % of each hit's damage dealt back as poison to the attacker (at least 5, at most once a second per player).", "Кислотные шипы: % урона удара, который возвращается атакующему ядом (не меньше 5, не чаще раза в секунду на игрока)."); }; return bossDef2; } private static BossDef Fader() { //IL_0229: Unknown result type (might be due to invalid IL or missing references) BossDef bossDef = new BossDef(); bossDef.Prefab = "Fader"; bossDef.Section = "16 Fader"; BossDef bossDef2 = bossDef; Phase(bossDef2, 85f, "fader.85").Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_CharredStone" }, Count = 1f }); PhaseDef phaseDef = Phase(bossDef2, 70f, "fader.70"); phaseDef.Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_CharredStone" }, Count = 2f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Marks, Prefabs = new string[1] { "spawn_fader_meteors" }, Prop = "vfx_prespawn", MarkKey = "fader.mark", Count = 1f }); phaseDef = Phase(bossDef2, 55f, "fader.55"); phaseDef.Acts.Add(new Act { Kind = ActKind.Nest, Prefabs = new string[1] { "Spawner_CharredStone" }, Count = 3f }); phaseDef.Acts.Add(new Act { Kind = ActKind.Shield }); phaseDef.Acts.Add(new Act { Kind = ActKind.Cycle, Duration = 30f, CooldownMin = 50f, CooldownMax = 70f, Delay = 60f, Variants = new List<CycleVariant> { new CycleVariant { Id = "Molten", Say = "fader.molten", EndKey = "fader.molten.end", MeleeFactor = 0.5f, MeleeRange = 6f, Retaliate = 15f, RetaliateType = (DamageType)32 }, new CycleVariant { Id = "AshVeil", Say = "fader.ash", EndKey = "fader.ash.end", MeleeRange = 6f, RangedFactor = 0.25f } } }); phaseDef = Phase(bossDef2, 45f, "fader.45"); phaseDef.Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Morgen" } }); phaseDef.Acts.Add(new Act { Kind = ActKind.Hazard, Prefabs = new string[1] { "Fader_WallOfFire_Spawn" }, Interval = 45f, MarkKey = "fader.wall" }); Phase(bossDef2, 30f, "fader.30").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "FallenValkyrie" } }); Phase(bossDef2, 20f, "fader.20").Acts.Add(new Act { Kind = ActKind.Lieutenant, Prefabs = new string[1] { "Charred_Melee_Dyrnwyn" } }); Phase(bossDef2, 10f, "fader.10").Acts.Add(new Act { Kind = ActKind.Wave, Prefabs = new string[2] { "Asksvin", "BlobLava" }, Count = 1f }); bossDef2.Reward.Valuables.Add(new Loot("Coins", 450, 750, perPlayer: true)); bossDef2.Reward.Valuables.Add(new Loot("GemstoneRed", 1, 2, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("GemstoneGreen", 1, 2, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("GemstoneBlue", 1, 2, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("FlametalOreNew", 6, 12, perPlayer: false)); bossDef2.Reward.Valuables.Add(new Loot("MoltenCore", 1, 2, perPlayer: false)); bossDef2.Reward.NextBiome.Add(new Loot("FrostCore", 1, 2, perPlayer: false)); bossDef2.Reward.Gear = new string[13] { "SwordNiedhogg", "AxeBerzerkr", "THSwordSlayer", "SpearSplitner", "SledgeDemolisher", "BowAshlands", "CrossbowRipper", "ShieldFlametal", "ShieldFlametalTower", "ArmorFlametalChest", "ArmorFlametalLegs", "HelmetFlametal", "StaffGreenRoots" }; bossDef2.BindExtra = delegate(ExtendedBossesPlugin pl, BossDef d) { d.CfgNestPrefab = pl.S(d.Section, "NestPrefab", "Spawner_CharredStone", "Vanilla destructible spawner of charred at 85/70/55%. Alternative: Spawner_CharredCross.", "Ванильный разрушаемый спавнер обугленных на 85/70/55 %. Альтернатива — Spawner_CharredCross."); d.CfgMarkPrefab = pl.S(d.Section, "MarkPrefab", "spawn_fader_meteors", "Vanilla prefab dropped at a marked player from 70%: spawn_fader_meteors (his meteors, own damage) or an AoE.", "Ванильный префаб под отмеченным игроком с 70 %: spawn_fader_meteors (его метеоры, урон свой) или AoE."); d.CfgMarkEffect = pl.S(d.Section, "MarkEffect", "vfx_prespawn", "Vanilla effect on the marked player before the meteors (players with the mod).", "Ванильный эффект на отмеченном игроке до метеоров (у игроков с модом)."); pl.BindCycle(d, "Cycle", "Molten: close hits x0.5 and burn the attacker; AshVeil: hits from afar x0.25", "Molten — раскалённая броня: удары вблизи ×0.5 и обжигают атакующего; AshVeil — пепельная завеса: удары издалека ×0.25", "Molten", "AshVeil"); d.CfgCycleMelee = pl.F(d.Section, "MoltenMeleeFactor", 0.5f, 0f, 1f, "Molten armor: damage of hits from within 6 m (x).", "Раскалённая броня: урон ударов ближе 6 м (×)."); d.CfgCycleRetaliate = pl.F(d.Section, "MoltenFireDamage", 15f, 0f, 200f, "Molten armor: fire dealt back to a close attacker per hit (at most once a second per player).", "Раскалённая броня: огонь, который получает атакующий вблизи за удар (не чаще раза в секунду на игрока)."); d.CfgCycleRanged = pl.F(d.Section, "AshVeilRangedFactor", 0.25f, 0f, 1f, "Ash veil: damage of hits from farther than 6 m (x).", "Пепельная завеса: урон ударов дальше 6 м (×)."); }; return bossDef2; } private void BindCapConfig() { _cfgCapBase = I("09 Raid", "AddsCapSolo", 8, 1, 100, "At most this many monsters around a boss for a single player (nests, totems, waves and slime stop at it).", "Не больше стольких монстров вокруг босса для одного игрока (гнёзда, тотемы, волны и слизь на этом останавливаются)."); _cfgCapPerPlayer = I("09 Raid", "AddsCapPerPlayer", 3, 0, 50, "The cap grows by this for every player beyond the first.", "Лимит растёт на столько за каждого игрока сверх первого."); _cfgCapRadius = F("09 Raid", "AddsCapRadius", 50f, 10f, 150f, "Monsters within this distance of the boss count towards the cap.", "Монстры ближе этого расстояния к боссу считаются в лимит."); } internal int AddsCap(Character boss) { return Si(_cfgCapBase) + Si(_cfgCapPerPlayer) * (GroupSize(boss) - 1); } internal int MonstersNear(Character boss) { //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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) float num = Sv(_cfgCapRadius); Vector3 position = ((Component)boss).transform.position; int num2 = 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)boss) && !val.IsPlayer() && !val.IsDead() && !val.IsTamed() && !val.IsBoss() && !((Object)(object)val.GetBaseAI() == (Object)null) && Flat(((Component)val).transform.position - position) <= num) { num2++; } } return num2; } internal bool AtCap(Character boss) { return MonstersNear(boss) >= AddsCap(boss); } private bool NestMaySpawn(SpawnArea area) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) ZDO val = Zdo((Component)(object)area); if (val == null) { return true; } ZDOID zDOID = val.GetZDOID("j1ga.extendedbosses.boss"); if (zDOID == ZDOID.None) { return true; } GameObject val2 = ZNetScene.instance.FindInstance(zDOID); Character val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<Character>() : null); if ((Object)(object)val3 == (Object)null || val3.IsDead()) { return true; } BossDef bossDef = BossOf(Zdo((Component)(object)val3)); if (bossDef == null || !IsModMode(bossDef)) { return true; } return !AtCap(val3); } 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("eb", "Extended Bosses: eb status | check | phase <n> | reset | probe <prefab> | players <n|0>", (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) { try { string text = ((args.Args.Length > 1) ? args.Args[1].ToLowerInvariant() : ""); string text2 = ((args.Args.Length > 2) ? args.Args[2] : ""); switch (text) { case "status": Say(args, Status()); break; case "probe": Say(args, Probe(text2)); break; case "check": { if ((Object)(object)ZNetScene.instance == (Object)null) { Say(args, L("cmd.noworld")); break; } SelfCheck(); Say(args, L("cmd.checkdone", _checkOk.ToString(), _checkProblems.Count.ToString())); for (int i = 0; i < _checkProblems.Count; i++) { Say(args, " " + _checkProblems[i]); } break; } case "players": { if (!int.TryParse(text2, out var result2) || result2 < 0) { Say(args, L("cmd.players")); break; } _forcePlayers = result2; Say(args, (result2 == 0) ? L("cmd.playerscount") : L("cmd.playersforced", result2.ToString())); break; } case "phase": case "reset": { Character val = NearestOwnedBoss(); if ((Object)(object)val == (Object)null) { Say(args, L("cmd.noboss")); break; } BossDef bossDef = BossOf(Zdo((Component)(object)val)); FightRt rt = Rt(val, bossDef); if (text == "reset") { ResetFight(val, rt); Say(args, L("cmd.reset", bossDef.Prefab)); break; } if (!int.TryParse(text2, out var result) || result < 0 || result >= bossDef.Phases.Count) { Say(args, L("cmd.phaseusage", (bossDef.Phases.Count - 1).ToString())); break; } ZDO val2 = Zdo((Component)(object)val); val2.Set(KPhase, val2.GetInt(KPhase, 0) | (1 << result), false); RunPhase(val, rt, result, GroupSize(val), Time.time); Say(args, L("cmd.phase", bossDef.Prefab, result.ToString(), bossDef.Phases[result].Pct.ToString())); break; } default: Say(args, L("cmd.help")); break; } } catch (Exception ex) { Say(args, "eb: " + ex.Message); Fail("command", ex); } } private Character NearestOwnedBoss() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Vector3 val = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).transform.position : Vector3.zero); Character result = null; float num = float.MaxValue; List<Character> allCharacters = Character.GetAllCharacters(); for (int i = 0; i < allCharacters.Count; i++) { Character val2 = allCharacters[i]; if (!((Object)(object)val2 == (Object)null) && val2.IsBoss() && !val2.IsDead() && IsOwner((Component)(object)val2) && BossOf(Zdo((Component)(object)val2)) != null) { float num2 = Vector3.Distance(val, ((Component)val2).transform.position); if (num2 < num) { num = num2; result = val2; } } } return result; } private string Status() { //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) if (_disabledByErrors) { return L("cmd.inert", "Extended Bosses"); } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("Extended Bosses").Append(" ").Append("0.8.6") .Append(Sb(_cfgEnabled) ? "" : " (disabled)") .Append(", profile ") .Append(Ss(_cfgProfile)) .Append(_serverSynced ? ", server settings" : ", local settings"); if (_forcePlayers > 0) { stringBuilder.Append(", players = ").Append(_forcePlayers); } stringBuilder.Append("\n"); int num = 0; List<Character> allCharacters = Character.GetAllCharacters(); for (int i = 0; i < allCharacters.Count; i++) { Character val = allCharacters[i]; if ((Object)(object)val == (Object)null || !val.IsBoss()) { continue; } ZDO val2 = Zdo((Component)(object)val); BossDef bossDef = BossOf(val2); if (bossDef == null) { continue; } num++; int num2 = val2.GetInt(KPhase, 0); int num3 = 0; for (int j = 0; j < bossDef.Phases.Count; j++) { if ((num2 & (1 << j)) != 0) { num3++; } } FightRt fightRt = RtIfRunning(val); string text = ""; if (fightRt != null && fightRt.ShieldActive) { text += L("cmd.shield"); } if (fightRt != null && fightRt.WindowActive) { text += L("cmd.window"); } if (fightRt != null && fightRt.CocoonActive) { text += L("cmd.cocoon"); } if (fightRt != null && fightRt.FixTarget != ZDOID.None && Time.time < fightRt.FixUntil) { text += L("cmd.fixate"); } if (fightRt != null && fightRt.ResistAct != null) { text += L("cmd.resist"); } if (fightRt != null && fightRt.CycleAct != null && fightRt.CycleVar != null) { text += L("cmd.cycle." + fightRt.CycleVar.Id.ToLowerInvariant()); } stringBuilder.Append(L("cmd.status", bossDef.Prefab, Ss(bossDef.CfgMode), ProfileOf(bossDef), F1(val.GetHealthPercentage() * 100f), num3.ToString(), bossDef.Phases.Count.ToString(), IsOwner((Component)(object)val) ? L("cmd.ownedhere") : L("cmd.ownedother"), GroupSize(val).ToString(), F2(IsModMode(bossDef) ? BossDamageFactor(val, bossDef) : 1f), CountAdds(val.GetZDOID(), 0).ToString(), (fightRt?.TotemsAlive ?? val2.GetInt(KTotems, 0)).ToString(), text)).Append("\n"); } if (num == 0) { stringBuilder.Append(L("cmd.nobosses")); } return stringBuilder.ToString().TrimEnd(); } private static string Probe(string prefab) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(prefab)) { return "eb probe <prefab>"; } if ((Object)(object)ZNetScene.instance == (Object)null) { return L("cmd.noworld"); } GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); if ((Object)(object)prefab2 == (Object)null) { return "Prefab '" + prefab + "' not found."; } StringBuilder stringBuilder = new StringBuilder(); ZNetView component = prefab2.GetComponent<ZNetView>(); stringBuilder.Append(prefab).Append(": ").Append(((Object)(object)component != (Object)null) ? ("networked" + (component.m_persistent ? ", persistent" : ", not persistent")) : "LOCAL ONLY (no ZNetView)") .Append("\n"); Character component2 = prefab2.GetComponent<Character>(); if ((Object)(object)component2 != (Object)null) { stringBuilder.Append(" Character '").Append(component2.m_name).Append("' hp ") .Append(component2.m_health) .Append(" faction ") .Append(component2.m_faction) .Append(" group '") .Append(component2.m_group) .Append("' boss ") .Append(component2.m_boss) .Append("\n"); } if ((Object)(object)component2 != (Object)null) { DamageModifiers damageModifiers = component2.m_damageModifiers; stringBuilder.Append(" resist: blunt ").Append(damageModifiers.m_blunt).Append(", slash ") .Append(damageModifiers.m_slash) .Append(", pierce ") .Append(damageModifiers.m_pierce) .Append(", chop ") .Append(damageModifiers.m_chop) .Append(", fire ") .Append(damageModifiers.m_fire) .Append(", frost ") .Append(damageModifiers.m_frost) .Append(", lightning ") .Append(damageModifiers.m_lightning) .Append(", poison ") .Append(damageModifiers.m_poison) .Append(", spirit ") .Append(damageModifiers.m_spirit) .Append("\n"); } Humanoid component3 = prefab2.GetComponent<Humanoid>(); if ((Object)(object)component3 != (Object)null && component3.m_defaultItems != null) { stringBuilder.Append(" default items:"); for (int i = 0; i < component3.m_defaultItems.Length; i++) { if ((Object)(object)component3.m_defaultItems[i] != (Object)null) { stringBuilder.Append(" ").Append(((Object)component3.m_defaultItems[i]).name); } } stringBuilder.Append("\n"); } Destructible componentInChildren = prefab2.GetComponentInChildren<Destructible>(true); if ((Object)(object)componentInChildren != (Object)null) { stringBuilder.Append(" Destructible hp ").Append(componentInChildren.m_health).Append("\n"); } WearNTear componentInChildren2 = prefab2.GetComponentInChildren<WearNTear>(true); if ((Object)(object)componentInChildren2 != (Object)null) { stringBuilder.Append(" WearNTear hp ").Append(componentInChildren2.m_health).Append("\n"); } SpawnArea componentInChildren3 = prefab2.GetComponentInChildren<SpawnArea>(true); if ((Object)(object)componentInChildren3 != (Object)null) { stringBuilder.Append(" SpawnArea every ").Append(componentInChildren3.m_spawnIntervalSec).Append("s, max near ") .Append(componentInChildren3.m_maxNear) .Append(":"); for (int j = 0; j < componentInChildren3.m_prefabs.Count; j++) { if ((Object)(object)componentInChildren3.m_prefabs[j].m_prefab != (Object)null) { stringBuilder.Append(" ").Append(((Object)componentInChildren3.m_prefabs[j].m_prefab).name); } } stringBuilder.Append("\n"); } Aoe[] componentsInChildren = prefab2.GetComponentsInChildren<Aoe>(true); for (int k = 0; k < componentsInChildren.Length; k++) { stringBuilder.Append(" Aoe radius ").Append(componentsInChildren[k].m_radius).Append(" damage ") .Append(((DamageTypes)(ref componentsInChildren[k].m_damage)).GetTotalDamage()) .Append(" ttl ") .Append(componentsInChildren[k].m_ttl) .Append("\n"); } ItemDrop component4 = prefab2.GetComponent<ItemDrop>(); if ((Object)(object)component4 != (Object)null) { stringBuilder.Append(" Item '").Append(component4.m_itemData.m_shared.m_name).Append("' max quality ") .Append(component4.m_itemData.m_shared.m_maxQuality) .Append(" stack ") .Append(component4.m_itemData.m_shared.m_maxStackSize) .Append("\n"); } return stringBuilder.ToString().TrimEnd(); } internal static string D(string en, string ru) { return en + "\n" + ru; } private ConfigEntry<float> F(string section, string key, float def, float min, float max, string en, string ru) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<float>(section, key, def, new ConfigDescription(D(en, ru), (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), new object[0])); } private ConfigEntry<int> I(string section, string key, int def, int min, int max, string en, string ru) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<int>(section, key, def, new ConfigDescription(D(en, ru), (AcceptableValueBase)(object)new AcceptableValueRange<int>(min, max), new object[0])); } private ConfigEntry<bool> B(string section, string key, bool def, string en, string ru) { return ((BaseUnityPlugin)this).Config.Bind<bool>(section, key, def, D(en, ru)); } private ConfigEntry<string> S(string section, string key, string def, string en, string ru, params string[] allowed) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown if (allowed == null || allowed.Length <= 0) { return ((BaseUnityPlugin)this).Config.Bind<string>(section, key, def, D(en, ru)); } return ((BaseUnityPlugin)this).Config.Bind<string>(section, key, def, new ConfigDescription(D(en, ru), (AcceptableValueBase)(object)new AcceptableValueList<string>(allowed), new object[0])); } private void BindConfig() { _cfgEnabled = B("01 General", "Enabled", def: true, "Master switch. Off: every boss is vanilla.", "Главный выключатель. Выкл — все боссы ванильные."); _cfgDebug = B("01 General", "Debug", def: false, "Log phases, spaw