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 Bifrost Breakout v0.3.21
BepInEx/plugins/Bifrost-Breakout/BifrostBreakout.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using SoftReferenceableAssets; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Bifrost Breakout")] [assembly: AssemblyDescription("Roaming monsters, migrating wildlife, warbands, unexpected encounters, and a world whose ecology changes as you progress.")] [assembly: AssemblyCompany("ChorusReef")] [assembly: AssemblyProduct("Bifrost Breakout")] [assembly: AssemblyFileVersion("0.3.21.0")] [assembly: AssemblyVersion("0.3.21.0")] namespace ChorusReef.BifrostBreakout; internal static class AmbientEncounterSystem { internal const string GhostCooldownKey = "bifrost_ghost_ship_next_spawn"; internal const string MeteorCooldownKey = "bifrost_meteor_next_spawn"; internal const double GhostCooldownSeconds = 3600.0; internal const double MeteorCooldownSeconds = 1800.0; private const double AttemptIntervalSeconds = 300.0; private const float GhostChance = 20f; private const float MeteorChance = 25f; private static MonoBehaviour _host; private static Coroutine _loop; private static ConfigEntry<bool> _ghostEnabled; private static ConfigEntry<bool> _meteorEnabled; internal static ManualLogSource Log; internal static bool ServerReady { get { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && (Object)(object)ZoneSystem.instance != (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { return (Object)(object)ObjectDB.instance != (Object)null; } return false; } } internal static void Initialize(MonoBehaviour host, ManualLogSource log, ConfigFile config) { _host = host; Log = log; _ghostEnabled = config.Bind<bool>("Ghost Ships", "Enabled", true, "Rare deep-Ocean Karves with three Wraiths and randomized cargo."); _meteorEnabled = config.Bind<bool>("Meteor Trolls", "Enabled", true, "Rare wilderness Trollstav impacts after Moder, outside PlayerBase coverage."); _loop = host.StartCoroutine(Run()); } internal static void Shutdown() { if ((Object)(object)_host != (Object)null && _loop != null) { _host.StopCoroutine(_loop); } _loop = null; _host = null; } private static IEnumerator Run() { ZoneSystem world = null; double nextAttempt = 0.0; while (true) { yield return (object)new WaitForSeconds(10f); if (!ServerReady) { continue; } double timeSeconds = ZNet.instance.GetTimeSeconds(); if ((Object)(object)world != (Object)(object)ZoneSystem.instance) { world = ZoneSystem.instance; nextAttempt = timeSeconds + 300.0; } if (timeSeconds < nextAttempt) { continue; } nextAttempt = timeSeconds + 300.0; try { List<Player> list = new List<Player>(); List<Player> list2 = new List<Player>(); foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null) && !((Character)allPlayer).IsDead() && !((Character)allPlayer).InInterior() && !((Character)allPlayer).IsTeleporting()) { if (DeepOcean(((Component)allPlayer).transform.position, out var _)) { list.Add(allPlayer); } if (!DeepNorth(((Component)allPlayer).transform.position) && !MeteorEncounter.Protected(((Component)allPlayer).transform.position, 0.25f)) { list2.Add(allPlayer); } } } if (_ghostEnabled.Value && list.Count > 0 && CooldownReady("bifrost_ghost_ship_next_spawn", timeSeconds) && Random.Range(0f, 100f) < 20f) { GhostShipEncounter.TrySpawn(list[Random.Range(0, list.Count)]); } if (_meteorEnabled.Value && list2.Count > 0 && world.GetGlobalKey("defeated_dragon") && CooldownReady("bifrost_meteor_next_spawn", timeSeconds) && Random.Range(0f, 100f) < 25f) { MeteorEncounter.TryStart(_host, list2[Random.Range(0, list2.Count)]); } } catch (Exception ex) { Log.LogError((object)("Ambient encounter attempt failed safely: " + ex)); } } } internal static bool CooldownReady(string key, double now) { string s = default(string); if (!ZoneSystem.instance.GetGlobalKey(key, ref s)) { return true; } if (double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return now >= result; } return false; } internal static void BeginCooldown(string key, double seconds) { long num = (long)Math.Ceiling(ZNet.instance.GetTimeSeconds() + seconds); ZoneSystem.instance.SetGlobalKey(key + " " + num.ToString(CultureInfo.InvariantCulture)); } internal static bool DeepOcean(Vector3 point, out float surface) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_002b: 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) surface = 0f; ZoneSystem instance = ZoneSystem.instance; if (!instance.IsZoneLoaded(point) || (int)WorldGenerator.instance.GetBiome(point) != 256) { return false; } float num = default(float); if (!instance.GetGroundHeight(point, ref num) || instance.m_waterLevel - num < 5f) { return false; } point.y = instance.m_waterLevel; surface = Floating.GetLiquidLevel(point, 1f, (LiquidType)0); if (surface > -1000f) { return surface - num >= 5f; } return false; } internal static bool DeepNorth(Vector3 point) { //IL_000c: 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_0014: Invalid comparison between Unknown and I4 if (WorldGenerator.instance != null) { return (int)WorldGenerator.instance.GetBiome(point) == 64; } return false; } internal static bool AwayFromPlayers(Vector3 point, float minimumDistance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer != (Object)null && Vector3.Distance(((Component)allPlayer).transform.position, point) < minimumDistance) { return false; } } return true; } } internal sealed class AquaticZdoTracker { private readonly string[] _prefabNames; private readonly int _ownershipMarkerKey; private readonly HashSet<ZDOID> _trackedIds = new HashSet<ZDOID>(); private readonly List<ZDO> _recoveryBuffer = new List<ZDO>(); private readonly List<ZDOID> _staleIds = new List<ZDOID>(); private int _recoveryPrefabIndex; private int _recoverySectorIndex; private bool _recoveryComplete; internal bool RecoveryComplete => _recoveryComplete; internal AquaticZdoTracker(int ownershipMarkerKey, params string[] prefabNames) { if (prefabNames == null || prefabNames.Length == 0) { throw new ArgumentException("At least one aquatic prefab name is required.", "prefabNames"); } _ownershipMarkerKey = ownershipMarkerKey; _prefabNames = prefabNames; } internal void Reset() { _trackedIds.Clear(); _recoveryBuffer.Clear(); _recoveryPrefabIndex = 0; _recoverySectorIndex = 0; _recoveryComplete = false; } internal bool RecoverStep(out int recovered) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) recovered = 0; if (_recoveryComplete) { return true; } if (ZDOMan.instance == null) { return false; } if (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(_prefabNames[_recoveryPrefabIndex], _recoveryBuffer, ref _recoverySectorIndex)) { return false; } for (int i = 0; i < _recoveryBuffer.Count; i++) { ZDO val = _recoveryBuffer[i]; if (val != null && val.GetBool(_ownershipMarkerKey, false) && _trackedIds.Add(val.m_uid)) { recovered++; } } _recoveryBuffer.Clear(); _recoverySectorIndex = 0; _recoveryPrefabIndex++; _recoveryComplete = _recoveryPrefabIndex >= _prefabNames.Length; return _recoveryComplete; } internal void Track(ZDO zdo) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (zdo != null && zdo.GetBool(_ownershipMarkerKey, false)) { _trackedIds.Add(zdo.m_uid); } } internal void Untrack(ZDO zdo) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (zdo != null) { _trackedIds.Remove(zdo.m_uid); } } internal void ResolveTracked(List<ZDO> result) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) result.Clear(); _staleIds.Clear(); ZDOMan instance = ZDOMan.instance; if (instance == null) { return; } foreach (ZDOID trackedId in _trackedIds) { ZDO zDO = instance.GetZDO(trackedId); if (zDO == null || !zDO.GetBool(_ownershipMarkerKey, false)) { _staleIds.Add(trackedId); } else { result.Add(zDO); } } for (int i = 0; i < _staleIds.Count; i++) { _trackedIds.Remove(_staleIds[i]); } } internal bool Destroy(ZDO zdo) { if (zdo == null) { return false; } Untrack(zdo); ZNetView val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(zdo) : null); if ((Object)(object)val != (Object)null && val.IsValid()) { if (!val.IsOwner()) { val.ClaimOwnership(); } ZNetScene.instance.Destroy(((Component)val).gameObject); return true; } if (ZDOMan.instance != null) { ZDOMan.instance.DestroyZDO(zdo); } return false; } } internal static class DraugrVillageRitualSystem { internal const string WardPrefabName = "dverger_guardstone"; internal const string DemisterPrefabName = "dverger_demister_large"; internal const string AbominationPrefabName = "Abomination"; internal const string GreenTorchPrefabName = "CastleKit_groundtorch_green"; internal const string WardMarkerKey = "Bifrost.DraugrVillageWard"; internal const string DemisterMarkerKey = "Bifrost.DraugrVillageDemister"; internal const string AbominationMarkerKey = "Bifrost.DraugrVillageAbomination"; internal const string SpawnerMarkerKey = "Bifrost.DraugrVillageProtectedSpawner"; internal const string DecorationMarkerKey = "Bifrost.DraugrVillageDecoration"; internal const string RitualAltarPrefabName = "altar"; internal const string MistAnchorMarkerKey = "Bifrost.DraugrVillageMistAnchor"; internal const float RitualRadius = 35f; internal const float RitualWardHealth = 100f; internal const float ActivationRange = 150f; private const float UpdateSeconds = 5f; private const float VillageScanRadius = 80f; internal const float MistRadius = 68f; internal const float MistHeight = 32f; private const double MistAfterWardSeconds = 600.0; private const double MistAfterCompletionSeconds = 90.0; private static readonly string[] MistPrefabCandidates = new string[3] { "MistArea", "MistArea_small", "MistArea_edge" }; private static readonly string[] VillagePrefabs = new string[2] { "WoodVillage1", "WoodVillage2" }; private static readonly HashSet<string> WaitingLogged = new HashSet<string>(StringComparer.Ordinal); private static readonly HashSet<string> FallbackLogged = new HashSet<string>(StringComparer.Ordinal); private static MonoBehaviour _host; private static ManualLogSource _log; private static Coroutine _loop; private static ZoneSystem _world; internal static void Initialize(MonoBehaviour host, ManualLogSource log) { _host = host; _log = log; _loop = host.StartCoroutine(Run()); } internal static void Shutdown() { if ((Object)(object)_host != (Object)null && _loop != null) { _host.StopCoroutine(_loop); } _loop = null; _host = null; _log = null; _world = null; WaitingLogged.Clear(); FallbackLogged.Clear(); } private static IEnumerator Run() { while (true) { yield return (object)new WaitForSeconds(5f); if (!ServerReady()) { continue; } try { if ((Object)(object)_world != (Object)(object)ZoneSystem.instance) { _world = ZoneSystem.instance; WaitingLogged.Clear(); FallbackLogged.Clear(); } List<Vector3> list = new List<Vector3>(); foreach (LocationInstance location in _world.GetLocationList()) { if (IsVillage(location) && HasPlayerNear(location.m_position)) { list.Add(location.m_position); MaintainOrAugment(location.m_position); } } MaintainLoadedVillageFallback(list); } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogError((object)("Draugr-village ritual update failed safely: " + ex)); } } } } private static void MaintainOrAugment(Vector3 villageCenter) { //IL_0000: 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_0033: 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_0047: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) string token = Token(villageCenter); if (_world.GetGlobalKey(CompletedKey(token))) { CleanupLoadedEncounter(token, keepMist: false); return; } if (!_world.GetGlobalKey(AugmentedKey(token))) { TryAugment(villageCenter); return; } if (TryFindHeart(villageCenter, out var heart, out var bounds) && TryFindRitualCenter(heart, bounds, out var center, out var rotation)) { MigrateRitualObjects(token, villageCenter, center, rotation); EnsureMistAnchor(center, token); OpenVillageDoorsOnce(token, villageCenter, center); } if (HasPlayerNear(villageCenter, 55f)) { RecoverLegacyAbominationDeath(token); } TryComplete(token); } private static void MaintainLoadedVillageFallback(List<Vector3> naturalCenters) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) Room[] array = Object.FindObjectsByType<Room>((FindObjectsInactive)1, (FindObjectsSortMode)0); List<Vector3> list = new List<Vector3>(); foreach (Room val in array) { if ((Object)(object)val == (Object)null || !IsVillageHeartName(((Object)val).name) || !HasPlayerNear(((Component)val).transform.position)) { continue; } Vector3 position = ((Component)val).transform.position; if (NearAny(position, naturalCenters, 80f) || NearAny(position, list, 80f) || FindDraugrSpawners(position).Count == 0) { continue; } list.Add(position); string text = Token(position); if (FallbackLogged.Add(text)) { ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("The Village discovered loaded Draugr-village fallback " + text + " from room '" + ((Object)val).name + "' because no ZoneSystem LocationInstance was available.")); } } MaintainOrAugment(position); } } private static bool IsVillageHeartName(string value) { if (string.IsNullOrEmpty(value)) { return false; } string text = value.ToLowerInvariant(); if (!text.Contains("meadowsvillage_greathall")) { return text.Contains("meadowsvillage_longhouse"); } return true; } private static bool NearAny(Vector3 point, List<Vector3> centers, float range) { //IL_000a: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) float num = range * range; for (int i = 0; i < centers.Count; i++) { Vector3 val = centers[i] - point; if (((Vector3)(ref val)).sqrMagnitude <= num) { return true; } } return false; } private static bool ServerReady() { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && (Object)(object)ZoneSystem.instance != (Object)null) { return (Object)(object)ZNetScene.instance != (Object)null; } return false; } private static bool IsVillage(LocationInstance location) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!location.m_placed || location.m_location == null) { return false; } string prefabName = location.m_location.m_prefabName; for (int i = 0; i < VillagePrefabs.Length; i++) { if (string.Equals(prefabName, VillagePrefabs[i], StringComparison.Ordinal)) { return true; } } return false; } private static bool HasPlayerNear(Vector3 center) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return HasPlayerNear(center, 150f); } private static bool HasPlayerNear(Vector3 center, float range) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) float num = range * range; foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer != (Object)null && !((Character)allPlayer).IsDead()) { Vector3 val = ((Component)allPlayer).transform.position - center; if (((Vector3)(ref val)).sqrMagnitude <= num) { return true; } } } return false; } private static void TryAugment(Vector3 villageCenter) { //IL_0000: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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) string text = Token(villageCenter); List<CreatureSpawner> list = FindDraugrSpawners(villageCenter); if (list.Count == 0) { return; } if (!TryFindHeart(villageCenter, out var heart, out var bounds)) { if (WaitingLogged.Add(text)) { ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Draugr village " + text + " has loaded spawners but is waiting for its generated greathall/longhouse room hierarchy.")); } } } else { if (!TryFindRitualCenter(heart, bounds, out var center, out var rotation)) { return; } CreatureSpawner val = FindClosestSpawner(list, center); bool flag = MarkProtectedSpawner(val, text); bool num = EnsureWard(center, rotation, text); bool flag2 = EnsureDemister(center, text); bool flag3 = EnsureMistAnchor(center, text); bool flag4 = EnsureAbomination(center, villageCenter, ((Component)heart).transform.forward, text); EnsureRitualAltar(center, rotation, text); EnsureGreenTorches(center, rotation, text); OpenVillageDoorsOnce(text, villageCenter, center); if (num && flag4 && flag) { _world.SetGlobalKey(AugmentedKey(text)); WaitingLogged.Remove(text); ManualLogSource log2 = _log; if (log2 != null) { log2.LogInfo((object)("Augmented The Village " + text + " using room '" + ((Object)heart).name + "' at " + Format(center) + ": ground-level protected Undead ritual ward, dormant unstarred Abomination, and Draugr spawner '" + ((Object)val).name + "'. Optional demister=" + flag2 + ", visible mist=" + flag3 + ".")); } } } } private static List<CreatureSpawner> FindDraugrSpawners(Vector3 center) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) List<CreatureSpawner> list = new List<CreatureSpawner>(); float num = 6400f; CreatureSpawner[] array = Object.FindObjectsByType<CreatureSpawner>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (CreatureSpawner val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.m_creaturePrefab == (Object)null)) { Vector3 val2 = ((Component)val).transform.position - center; if (!(((Vector3)(ref val2)).sqrMagnitude > num) && ((Object)val.m_creaturePrefab).name.IndexOf("Draugr", StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(val); } } } return list; } private static bool TryFindHeart(Vector3 center, out Room heart, out Bounds bounds) { //IL_0004: 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_000a: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) heart = null; bounds = new Bounds(center, Vector3.zero); float num = float.MinValue; float num2 = 6400f; Room[] array = Object.FindObjectsByType<Room>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (Room val in array) { if ((Object)(object)val == (Object)null) { continue; } Vector3 val2 = ((Component)val).transform.position - center; if (((Vector3)(ref val2)).sqrMagnitude > num2) { continue; } string text = ((Object)val).name.ToLowerInvariant(); bool flag = text.Contains("meadowsvillage_greathall"); bool flag2 = text.Contains("meadowsvillage_longhouse"); if ((flag || flag2) && TryGetBounds(((Component)val).gameObject, out var bounds2)) { float num3 = ((Bounds)(ref bounds2)).size.x * ((Bounds)(ref bounds2)).size.z + (flag ? 10000f : 5000f) - (text.Contains("ruin") ? 2500f : 0f); if (!(num3 <= num)) { num = num3; heart = val; bounds = bounds2; } } } return (Object)(object)heart != (Object)null; } private static bool TryGetBounds(GameObject root, out Bounds bounds) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) bounds = new Bounds(root.transform.position, Vector3.zero); bool flag = false; Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && val.enabled) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } if (flag) { return true; } Renderer[] componentsInChildren2 = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && val2.enabled) { if (!flag) { bounds = val2.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2.bounds); } } } return flag; } private static bool TryFindRitualCenter(Room heart, Bounds heartBounds, out Vector3 center, out Quaternion rotation) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) center = ((Bounds)(ref heartBounds)).center; Vector3 val = ((Component)heart).transform.forward; val.y = 0f; Door[] componentsInChildren = ((Component)heart).GetComponentsInChildren<Door>(true); float num = 0f; for (int i = 0; i < componentsInChildren.Length; i++) { Vector3 val2 = ((Component)componentsInChildren[i]).transform.position - ((Bounds)(ref heartBounds)).center; val2.y = 0f; if (!(((Vector3)(ref val2)).sqrMagnitude <= num)) { num = ((Vector3)(ref val2)).sqrMagnitude; val = val2; } } if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Vector3.forward; } ((Vector3)(ref val)).Normalize(); float num2 = Mathf.Abs(val.x) * ((Bounds)(ref heartBounds)).extents.x + Mathf.Abs(val.z) * ((Bounds)(ref heartBounds)).extents.z; center = ((Bounds)(ref heartBounds)).center + val * (num2 + 3f); if (!TryTerrainGround(center, out center)) { rotation = ((Component)heart).transform.rotation; return false; } rotation = Quaternion.LookRotation(val, Vector3.up); return true; } private static bool TryTerrainGround(Vector3 horizontal, out Vector3 grounded) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) grounded = horizontal; float num = default(float); if (!_world.GetGroundHeight(horizontal, ref num)) { return false; } grounded.y = num + 0.05f; return true; } private static bool TryGround(Vector3 horizontal, float rayStart, out Vector3 grounded) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) grounded = horizontal; float num = default(float); if (!_world.GetGroundHeight(horizontal, ref num)) { return false; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(horizontal.x, Mathf.Max(rayStart, num + 15f), horizontal.z); RaycastHit[] array = Physics.RaycastAll(val, Vector3.down, 60f, -5, (QueryTriggerInteraction)1); float num2 = float.MinValue; for (int i = 0; i < array.Length; i++) { RaycastHit val2 = array[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Character>() != (Object)null) && !(((RaycastHit)(ref val2)).point.y < num - 1f) && !(((RaycastHit)(ref val2)).point.y > val.y) && !(((RaycastHit)(ref val2)).point.y <= num2)) { num2 = ((RaycastHit)(ref val2)).point.y; } } grounded.y = ((num2 > float.MinValue) ? num2 : num); return true; } private static CreatureSpawner FindClosestSpawner(List<CreatureSpawner> spawners, Vector3 anchor) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_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) CreatureSpawner result = null; float num = float.MaxValue; for (int i = 0; i < spawners.Count; i++) { Vector3 val = ((Component)spawners[i]).transform.position - anchor; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (!(sqrMagnitude >= num)) { num = sqrMagnitude; result = spawners[i]; } } return result; } private static bool MarkProtectedSpawner(CreatureSpawner spawner, string token) { if ((Object)(object)spawner == (Object)null) { return false; } Destructible component = ((Component)spawner).GetComponent<Destructible>(); if ((Object)(object)component == (Object)null) { ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Draugr village " + token + " spawner '" + ((Object)spawner).name + "' is not destructible and needs no friendly-fire protection.")); } return true; } ZNetView val = (((Object)(object)component != (Object)null) ? ((Component)component).GetComponent<ZNetView>() : null); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); if (val2 == null) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("Draugr village " + token + " destructible spawner '" + ((Object)spawner).name + "' lacks a persistent ZNetView; the encounter will continue without marking it.")); } return true; } val2.Set("Bifrost.DraugrVillageProtectedSpawner", token); return true; } private static bool EnsureWard(Vector3 position, Quaternion rotation, string token) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (_world.GetGlobalKey(WardCreatedKey(token))) { return true; } GameObject prefab = ZNetScene.instance.GetPrefab("dverger_guardstone"); if ((Object)(object)prefab == (Object)null) { return false; } GameObject val = Object.Instantiate<GameObject>(prefab, position, rotation); ZNetView component = val.GetComponent<ZNetView>(); ZDO val2 = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val2 == null) { Object.Destroy((Object)(object)val); return false; } val2.Set("Bifrost.DraugrVillageWard", token); ConfigureWard(val.GetComponent<PrivateArea>()); _world.SetGlobalKey(WardCreatedKey(token)); return true; } private static void ConfigureWard(PrivateArea area) { //IL_0065: 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)area == (Object)null) { return; } ZNetView component = ((Component)area).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val == null || string.IsNullOrEmpty(val.GetString("Bifrost.DraugrVillageWard", string.Empty))) { return; } string token = val.GetString("Bifrost.DraugrVillageWard", string.Empty); area.m_radius = 35f; area.m_ownerFaction = (Faction)3; if ((Object)(object)area.m_areaMarker != (Object)null) { area.m_areaMarker.m_radius = 35f; } EffectArea[] componentsInChildren = ((Component)area).GetComponentsInChildren<EffectArea>(true); foreach (EffectArea val2 in componentsInChildren) { if ((val2.m_type & 4) != 0) { ((Component)val2).gameObject.SetActive(true); } } ApplyCursedWardAppearance(((Component)area).gameObject); WearNTear component2 = ((Component)area).GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { component2.m_health = 100f; if (component.IsOwner()) { if (val.GetFloat(ZDOVars.s_health, 100f) > 100f) { val.Set(ZDOVars.s_health, 100f); } val.Set(ZDOVars.s_maxHealth, 100f); } } DraugrVillageContainment draugrVillageContainment = ((Component)area).GetComponent<DraugrVillageContainment>(); if ((Object)(object)draugrVillageContainment == (Object)null) { draugrVillageContainment = ((Component)area).gameObject.AddComponent<DraugrVillageContainment>(); } draugrVillageContainment.Configure(token, 35f); } private static void MigrateRitualObjects(string token, Vector3 villageCenter, Vector3 anchor, Quaternion rotation) { //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: 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_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) if (_world.GetGlobalKey(WardDestroyedKey(token))) { return; } ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsInactive)1, (FindObjectsSortMode)0); List<ZNetView> list = new List<ZNetView>(); foreach (ZNetView val in array) { ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); if (val2 == null) { continue; } if (string.Equals(val2.GetString("Bifrost.DraugrVillageWard", string.Empty), token, StringComparison.Ordinal)) { MovePersistentObject(val, anchor, rotation); } else if (string.Equals(val2.GetString("Bifrost.DraugrVillageDemister", string.Empty), token, StringComparison.Ordinal)) { MovePersistentObject(val, anchor + Vector3.down * 0.15f, Quaternion.identity); } else if (string.Equals(val2.GetString("Bifrost.DraugrVillageDecoration", string.Empty), token, StringComparison.Ordinal) && ((Object)((Component)val).gameObject).name.IndexOf("groundtorch_green", StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(val); } else { if (_world.GetGlobalKey(AbominationCenteredKey(token)) || !string.Equals(val2.GetString("Bifrost.DraugrVillageAbomination", string.Empty), token, StringComparison.Ordinal)) { continue; } Vector3 grounded = villageCenter; if (TryTerrainGround(grounded, out grounded)) { Vector3 val3 = anchor - grounded; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = rotation * Vector3.forward; } ((Vector3)(ref val3)).Normalize(); MovePersistentObject(val, grounded, Quaternion.LookRotation(val3, Vector3.up)); _world.SetGlobalKey(AbominationCenteredKey(token)); } } } list.Sort(delegate(ZNetView left, ZNetView right) { ZDO val4 = (((Object)(object)left != (Object)null && left.IsValid()) ? left.GetZDO() : null); ZDO val5 = (((Object)(object)right != (Object)null && right.IsValid()) ? right.GetZDO() : null); string strA = ((val4 != null) ? ((object)Unsafe.As<ZDOID, ZDOID>(ref val4.m_uid)/*cast due to .constrained prefix*/).ToString() : string.Empty); string strB = ((val5 != null) ? ((object)Unsafe.As<ZDOID, ZDOID>(ref val5.m_uid)/*cast due to .constrained prefix*/).ToString() : string.Empty); return string.CompareOrdinal(strA, strB); }); Vector3[] array2 = RitualTorchOffsets(); int num = Mathf.Min(list.Count, array2.Length); for (int num2 = 0; num2 < num; num2++) { Vector3 grounded2 = anchor + rotation * array2[num2]; if (TryTerrainGround(grounded2, out grounded2)) { MovePersistentObject(list[num2], grounded2, rotation); } } } private static void MovePersistentObject(ZNetView view, Vector3 position, Quaternion rotation) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)view == (Object)null || !view.IsValid()) { return; } Vector3 val = ((Component)view).transform.position - position; if (!(((Vector3)(ref val)).sqrMagnitude < 0.04f) || !(Quaternion.Angle(((Component)view).transform.rotation, rotation) < 2f)) { if (!view.IsOwner()) { view.ClaimOwnership(); } ((Component)view).transform.SetPositionAndRotation(position, rotation); ZDO zDO = view.GetZDO(); if (zDO != null) { zDO.SetPosition(position); zDO.SetRotation(rotation); } ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("The Village moved persistent ritual object '" + ((Object)((Component)view).gameObject).name + "' to ground-level objective at " + Format(position) + ".")); } } } internal static void ApplyCursedWardAppearance(GameObject ward) { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ward == (Object)null) { return; } ZNetView component = ward.GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); bool num = val != null && !string.IsNullOrEmpty(val.GetString("Bifrost.DraugrVillageWard", string.Empty)); bool flag = val != null && !string.IsNullOrEmpty(val.GetString(1888340365, string.Empty)); if (!num && !flag) { return; } Color val2 = default(Color); ((Color)(ref val2))..ctor(0.085f, 0.035f, 0.025f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.03f, 0.18f, 0.045f, 1f); Renderer[] componentsInChildren = ward.GetComponentsInChildren<Renderer>(true); foreach (Renderer val4 in componentsInChildren) { if ((Object)(object)val4 == (Object)null) { continue; } Material[] materials = val4.materials; foreach (Material val5 in materials) { if (!((Object)(object)val5 == (Object)null)) { if (val5.HasProperty("_Color")) { Color color = val5.color; Color color2 = Color.Lerp(color, val2, 0.78f); color2.a = color.a; val5.color = color2; } if (val5.HasProperty("_BaseColor")) { Color color3 = val5.GetColor("_BaseColor"); Color val6 = Color.Lerp(color3, val2, 0.78f); val6.a = color3.a; val5.SetColor("_BaseColor", val6); } string text = (((Object)val4).name + " " + ((Object)val5).name).ToLowerInvariant(); bool flag2 = text.Contains("rune") || text.Contains("glow") || text.Contains("active"); if (val5.HasProperty("_EmissionColor")) { val5.SetColor("_EmissionColor", flag2 ? val3 : Color.black); } } } } } private static bool EnsureDemister(Vector3 position, string token) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (_world.GetGlobalKey(DemisterCreatedKey(token))) { return true; } GameObject prefab = ZNetScene.instance.GetPrefab("dverger_demister_large"); if ((Object)(object)prefab == (Object)null) { return false; } GameObject val = Object.Instantiate<GameObject>(prefab, position + Vector3.down * 0.15f, Quaternion.identity); ZNetView component = val.GetComponent<ZNetView>(); ZDO val2 = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val2 == null) { Object.Destroy((Object)(object)val); return false; } val2.Set("Bifrost.DraugrVillageDemister", token); ConfigureDemister(val); _world.SetGlobalKey(DemisterCreatedKey(token)); return true; } private static void ConfigureDemister(GameObject demister) { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)demister == (Object)null) { return; } ZNetView component = demister.GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); string text = ((val != null) ? val.GetString("Bifrost.DraugrVillageDemister", string.Empty) : string.Empty); if (string.IsNullOrEmpty(text)) { return; } if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey(WardDestroyedKey(text))) { if (component.IsOwner()) { ZNetScene.instance.Destroy(demister); } return; } WearNTear component2 = demister.GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { component2.m_triggerPrivateArea = false; } MeshRenderer[] componentsInChildren = demister.GetComponentsInChildren<MeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Renderer)componentsInChildren[i]).enabled = false; } Collider[] componentsInChildren2 = demister.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } ParticleSystemForceField[] componentsInChildren3 = demister.GetComponentsInChildren<ParticleSystemForceField>(true); foreach (ParticleSystemForceField obj in componentsInChildren3) { Transform parent = ((Component)obj).transform.parent; Vector3 val2 = (((Object)(object)parent != (Object)null) ? parent.lossyScale : Vector3.one); ((Component)obj).transform.localScale = new Vector3(1f / Mathf.Max(0.01f, val2.x), 1f / Mathf.Max(0.01f, val2.y), 1f / Mathf.Max(0.01f, val2.z)); obj.endRange = 35f; } } private static bool EnsureMistAnchor(Vector3 position, string token) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (_world.GetGlobalKey(MistCreatedKey(token))) { return true; } if (!DraugrVillageMistVisual.HasVerifiedSource()) { return false; } GameObject prefab = ZNetScene.instance.GetPrefab("dverger_demister_large"); if ((Object)(object)prefab == (Object)null) { return false; } GameObject val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity); ZNetView component = val.GetComponent<ZNetView>(); ZDO val2 = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val2 == null) { Object.Destroy((Object)(object)val); return false; } val2.Set("Bifrost.DraugrVillageMistAnchor", token); ConfigureMistAnchor(val); _world.SetGlobalKey(MistCreatedKey(token)); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Draugr village " + token + " created a Bifrost-owned 68m temporary mist volume from " + DraugrVillageMistVisual.VerifiedSourceName + ".")); } return true; } private static void ConfigureMistAnchor(GameObject anchor) { if ((Object)(object)anchor == (Object)null) { return; } ZNetView component = anchor.GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); string text = ((val != null) ? val.GetString("Bifrost.DraugrVillageMistAnchor", string.Empty) : string.Empty); if (!string.IsNullOrEmpty(text)) { Demister[] componentsInChildren = anchor.GetComponentsInChildren<Demister>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } ParticleSystemForceField[] componentsInChildren2 = anchor.GetComponentsInChildren<ParticleSystemForceField>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Component)componentsInChildren2[i]).gameObject.SetActive(false); } MeshRenderer[] componentsInChildren3 = anchor.GetComponentsInChildren<MeshRenderer>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Renderer)componentsInChildren3[i]).enabled = false; } Collider[] componentsInChildren4 = anchor.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { componentsInChildren4[i].enabled = false; } WearNTear component2 = anchor.GetComponent<WearNTear>(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } DraugrVillageMistVisual draugrVillageMistVisual = anchor.GetComponent<DraugrVillageMistVisual>(); if ((Object)(object)draugrVillageMistVisual == (Object)null) { draugrVillageMistVisual = anchor.AddComponent<DraugrVillageMistVisual>(); } draugrVillageMistVisual.Configure(text); } } private static bool EnsureAbomination(Vector3 anchor, Vector3 villageCenter, Vector3 fallbackDirection, string token) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (_world.GetGlobalKey(AbominationCreatedKey(token))) { return true; } GameObject prefab = ZNetScene.instance.GetPrefab("Abomination"); if ((Object)(object)prefab == (Object)null) { return false; } Vector3 val = villageCenter; float num = default(float); if (!_world.GetGroundHeight(val, ref num)) { return false; } val.y = num + 0.2f; Vector3 val2 = anchor - val; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.1f) { val2 = fallbackDirection; val2.y = 0f; } ((Vector3)(ref val2)).Normalize(); GameObject val3 = Object.Instantiate<GameObject>(prefab, val, Quaternion.LookRotation(val2, Vector3.up)); ZNetView component = val3.GetComponent<ZNetView>(); ZDO val4 = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); Character component2 = val3.GetComponent<Character>(); if (val4 == null || (Object)(object)component2 == (Object)null) { Object.Destroy((Object)(object)val3); return false; } val4.Set("Bifrost.DraugrVillageAbomination", token); val4.Set(-841210880, true); component2.SetLevel(1); _world.SetGlobalKey(AbominationCreatedKey(token)); _world.SetGlobalKey(AbominationCenteredKey(token)); return true; } private static void OpenVillageDoorsOnce(string token, Vector3 villageCenter, Vector3 ritualCenter) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if (_world.GetGlobalKey(DoorsOpenedKey(token)) || !HasPlayerNear(ritualCenter, 34f)) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(Door), "SetState", new Type[1] { typeof(int) }, (Type[])null); if (methodInfo == null) { return; } Door[] array = Object.FindObjectsByType<Door>((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = 0; int num2 = 0; float num3 = 6400f; foreach (Door val in array) { if ((Object)(object)val == (Object)null) { continue; } Vector3 val2 = ((Component)val).transform.position - villageCenter; if (((Vector3)(ref val2)).sqrMagnitude > num3) { continue; } ZNetView component = ((Component)val).GetComponent<ZNetView>(); ZDO val3 = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val3 == null) { continue; } num++; if (val3.GetInt(ZDOVars.s_state, 0) == 0) { if (!component.IsOwner()) { component.ClaimOwnership(); } methodInfo.Invoke(val, new object[1] { 1 }); num2++; } } if (num != 0) { _world.SetGlobalKey(DoorsOpenedKey(token)); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("The Village trap " + token + " opened " + num2 + " of " + num + " loaded door(s) in one networked activation.")); } } } private static void EnsureRitualAltar(Vector3 anchor, Quaternion rotation, string token) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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) if (_world.GetGlobalKey(AltarCreatedKey(token))) { return; } GameObject prefab = ZNetScene.instance.GetPrefab("altar"); if ((Object)(object)prefab == (Object)null) { ManualLogSource log = _log; if (log != null) { log.LogInfo((object)"Optional ritual prefab altar is not a runtime network prefab; The Village altar was deferred."); } _world.SetGlobalKey(AltarCreatedKey(token)); return; } Vector3 grounded = anchor + rotation * new Vector3(0f, 0f, -2.2f); if (!TryGround(grounded, anchor.y + 8f, out grounded)) { ManualLogSource log2 = _log; if (log2 != null) { log2.LogWarning((object)("The Village " + token + " could not ground its optional ritual altar.")); } _world.SetGlobalKey(AltarCreatedKey(token)); return; } GameObject val = Object.Instantiate<GameObject>(prefab, grounded, rotation); ZNetView component = val.GetComponent<ZNetView>(); ZDO val2 = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val2 == null) { Object.Destroy((Object)(object)val); ManualLogSource log3 = _log; if (log3 != null) { log3.LogInfo((object)"Optional ritual prefab altar lacks a persistent ZNetView; The Village altar was deferred."); } _world.SetGlobalKey(AltarCreatedKey(token)); return; } val2.Set("Bifrost.DraugrVillageDecoration", token); _world.SetGlobalKey(AltarCreatedKey(token)); ManualLogSource log4 = _log; if (log4 != null) { log4.LogInfo((object)("The Village " + token + " placed optional ritual altar 'altar' at " + Format(grounded) + ".")); } } private static void EnsureGreenTorches(Vector3 anchor, Quaternion rotation, string token) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (_world.GetGlobalKey(DecorationsCreatedKey(token))) { return; } GameObject prefab = ZNetScene.instance.GetPrefab("CastleKit_groundtorch_green"); if ((Object)(object)prefab == (Object)null) { ManualLogSource log = _log; if (log != null) { log.LogInfo((object)"Optional ritual prefab CastleKit_groundtorch_green is not a runtime network prefab; green torches were deferred."); } _world.SetGlobalKey(DecorationsCreatedKey(token)); return; } Vector3[] array = RitualTorchOffsets(); int num = 0; for (int i = 0; i < array.Length; i++) { Vector3 grounded = anchor + rotation * array[i]; if (TryTerrainGround(grounded, out grounded)) { GameObject val = Object.Instantiate<GameObject>(prefab, grounded, rotation); ZNetView component = val.GetComponent<ZNetView>(); ZDO val2 = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val2 != null) { val2.Set("Bifrost.DraugrVillageDecoration", token); num++; } else { Object.Destroy((Object)(object)val); } } } _world.SetGlobalKey(DecorationsCreatedKey(token)); ManualLogSource log2 = _log; if (log2 != null) { log2.LogInfo((object)("Draugr village " + token + " placed " + num + " optional green ritual torch(es).")); } } private static Vector3[] RitualTorchOffsets() { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) return (Vector3[])(object)new Vector3[4] { new Vector3(3f, 0f, 3f), new Vector3(-3f, 0f, 3f), new Vector3(3f, 0f, -3f), new Vector3(-3f, 0f, -3f) }; } internal static bool IgnoreUndeadSpawnerDamage(Destructible destructible, HitData hit) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 if ((Object)(object)destructible == (Object)null || hit == null) { return false; } ZNetView component = ((Component)destructible).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val == null || string.IsNullOrEmpty(val.GetString("Bifrost.DraugrVillageProtectedSpawner", string.Empty))) { return false; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker != (Object)null) { return (int)attacker.GetFaction() == 3; } return false; } internal static bool IgnoreUndeadWardDamage(WearNTear wear, HitData hit) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 if ((Object)(object)wear == (Object)null || hit == null) { return false; } ZNetView component = ((Component)wear).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val == null || string.IsNullOrEmpty(val.GetString("Bifrost.DraugrVillageWard", string.Empty))) { return false; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker != (Object)null) { return (int)attacker.GetFaction() == 3; } return false; } internal static void ConfigureLoadedObject(GameObject gameObject) { if ((Object)(object)gameObject == (Object)null) { return; } ZNetView component = gameObject.GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val != null) { if (!string.IsNullOrEmpty(val.GetString("Bifrost.DraugrVillageWard", string.Empty))) { ConfigureWard(gameObject.GetComponent<PrivateArea>()); } if (!string.IsNullOrEmpty(val.GetString("Bifrost.DraugrVillageDemister", string.Empty))) { ConfigureDemister(gameObject); } if (!string.IsNullOrEmpty(val.GetString("Bifrost.DraugrVillageMistAnchor", string.Empty))) { ConfigureMistAnchor(gameObject); } string text = FirstMarker(val, "Bifrost.DraugrVillageWard", "Bifrost.DraugrVillageDemister", "Bifrost.DraugrVillageAbomination", "Bifrost.DraugrVillageDecoration", "Bifrost.DraugrVillageProtectedSpawner"); if (!string.IsNullOrEmpty(text) && (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey(CompletedKey(text))) { CleanupLoadedObject(gameObject, val, text, keepMist: false); } } } internal static void OnCharacterDeath(Character character) { if (!ServerReady() || (Object)(object)character == (Object)null) { return; } ZNetView component = ((Component)character).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); string text = ((val != null) ? val.GetString("Bifrost.DraugrVillageAbomination", string.Empty) : string.Empty); if (!string.IsNullOrEmpty(text)) { _world.SetGlobalKey(AbominationDeadKey(text)); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Draugr village ritual Abomination " + text + " was killed.")); } TryComplete(text); } } internal static void OnWearNTearDestroyed(WearNTear wear) { if (!ServerReady() || (Object)(object)wear == (Object)null) { return; } ZNetView component = ((Component)wear).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); string text = ((val != null) ? val.GetString("Bifrost.DraugrVillageWard", string.Empty) : string.Empty); if (string.IsNullOrEmpty(text)) { return; } ZoneSystem.instance.SetGlobalKey(WardDestroyedKey(text)); SetMistCleanupDeadline(text, 600.0, onlyShorten: false); Demister[] array = Object.FindObjectsByType<Demister>((FindObjectsInactive)1, (FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { ZNetView componentInParent = ((Component)array[i]).GetComponentInParent<ZNetView>(); ZDO val2 = (((Object)(object)componentInParent != (Object)null && componentInParent.IsValid()) ? componentInParent.GetZDO() : null); if (val2 != null && string.Equals(val2.GetString("Bifrost.DraugrVillageDemister", string.Empty), text, StringComparison.Ordinal)) { if (!componentInParent.IsOwner()) { componentInParent.ClaimOwnership(); } ZNetScene.instance.Destroy(((Component)componentInParent).gameObject); } } ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Draugr village ritual Ward " + text + " was destroyed; its 35m demister was removed and the mist will close in for at most 10 minutes.")); } TryComplete(text); } private static void RecoverLegacyAbominationDeath(string token) { if (!_world.GetGlobalKey(AbominationCreatedKey(token)) || _world.GetGlobalKey(AbominationDeadKey(token))) { return; } Character[] array = Object.FindObjectsByType<Character>((FindObjectsInactive)1, (FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { ZNetView component = ((Component)array[i]).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val != null && string.Equals(val.GetString("Bifrost.DraugrVillageAbomination", string.Empty), token, StringComparison.Ordinal)) { return; } } _world.SetGlobalKey(AbominationDeadKey(token)); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Recovered completed ritual Abomination state for existing Draugr village " + token + ".")); } } private static void TryComplete(string token) { if (!((Object)(object)_world == (Object)null) && !_world.GetGlobalKey(CompletedKey(token)) && _world.GetGlobalKey(WardDestroyedKey(token)) && _world.GetGlobalKey(AbominationDeadKey(token))) { _world.SetGlobalKey(CompletedKey(token)); SetMistCleanupDeadline(token, 90.0, onlyShorten: true); CleanupLoadedEncounter(token, keepMist: true); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Draugr village ritual " + token + " completed permanently: Ward and ritual Abomination are dead. Decorations were retired and the closing mist will clear in 90 seconds.")); } } } private static void SetMistCleanupDeadline(string token, double seconds, bool onlyShorten) { if (!((Object)(object)ZNet.instance == (Object)null) && !((Object)(object)ZoneSystem.instance == (Object)null)) { double num = ZNet.instance.GetTimeSeconds() + seconds; string s = default(string); if (!onlyShorten || !ZoneSystem.instance.GetGlobalKey(MistCleanupKey(token), ref s) || !double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !(result <= num)) { ZoneSystem.instance.SetGlobalKey(MistCleanupKey(token) + " " + Math.Ceiling(num).ToString(CultureInfo.InvariantCulture)); } } } internal static bool MistExpired(string token) { if ((Object)(object)ZoneSystem.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return false; } string s = default(string); if (ZoneSystem.instance.GetGlobalKey(MistCleanupKey(token), ref s) && double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return ZNet.instance.GetTimeSeconds() >= result; } return false; } private static void CleanupLoadedEncounter(string token, bool keepMist) { ZNetView[] array = Object.FindObjectsByType<ZNetView>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (ZNetView val in array) { ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); if (val2 != null) { CleanupLoadedObject(((Component)val).gameObject, val2, token, keepMist); } } } private static void CleanupLoadedObject(GameObject gameObject, ZDO zdo, string token, bool keepMist) { if (string.Equals(zdo.GetString("Bifrost.DraugrVillageProtectedSpawner", string.Empty), token, StringComparison.Ordinal)) { zdo.Set("Bifrost.DraugrVillageProtectedSpawner", string.Empty); } bool flag = string.Equals(zdo.GetString("Bifrost.DraugrVillageMistAnchor", string.Empty), token, StringComparison.Ordinal); if ((!string.Equals(zdo.GetString("Bifrost.DraugrVillageDemister", string.Empty), token, StringComparison.Ordinal) && !string.Equals(zdo.GetString("Bifrost.DraugrVillageDecoration", string.Empty), token, StringComparison.Ordinal) && (!flag || keepMist || !MistExpired(token))) || (Object)(object)ZNetScene.instance == (Object)null) { return; } ZNetView component = gameObject.GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { if (!component.IsOwner()) { component.ClaimOwnership(); } ZNetScene.instance.Destroy(gameObject); } } private static string FirstMarker(ZDO zdo, params string[] keys) { for (int i = 0; i < keys.Length; i++) { string text = zdo.GetString(keys[i], string.Empty); if (!string.IsNullOrEmpty(text)) { return text; } } return string.Empty; } private static string Token(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Vector2s zone = ZoneSystem.GetZone(position); return zone.x + ":" + zone.y; } private static string StateKey(string prefix, string token) { return prefix + token.Replace(':', '_'); } private static string AugmentedKey(string token) { return StateKey("bifrost_draugr_village_augmented_", token); } private static string WardCreatedKey(string token) { return StateKey("bifrost_draugr_village_ward_created_", token); } private static string WardDestroyedKey(string token) { return StateKey("bifrost_draugr_village_ward_destroyed_", token); } private static string DemisterCreatedKey(string token) { return StateKey("bifrost_draugr_village_demister_created_", token); } private static string AbominationCreatedKey(string token) { return StateKey("bifrost_draugr_village_abomination_created_", token); } private static string AbominationCenteredKey(string token) { return StateKey("bifrost_draugr_village_abomination_centered_", token); } private static string AltarCreatedKey(string token) { return StateKey("bifrost_draugr_village_altar_created_", token); } private static string DecorationsCreatedKey(string token) { return StateKey("bifrost_draugr_village_decorations_created_", token); } private static string DoorsOpenedKey(string token) { return StateKey("bifrost_draugr_village_doors_opened_", token); } private static string MistCreatedKey(string token) { return StateKey("bifrost_draugr_village_mist_created_", token); } private static string MistCleanupKey(string token) { return StateKey("bifrost_draugr_village_mist_cleanup_", token); } private static string AbominationDeadKey(string token) { return StateKey("bifrost_draugr_village_abomination_dead_", token); } private static string CompletedKey(string token) { return StateKey("bifrost_draugr_village_completed_", token); } private static string Format(Vector3 value) { return value.x.ToString("0.0") + "," + value.y.ToString("0.0") + "," + value.z.ToString("0.0"); } internal static GameObject FindVerifiedMistSource() { if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null) { return null; } for (int i = 0; i < MistPrefabCandidates.Length; i++) { GameObject prefab = ZNetScene.instance.GetPrefab(MistPrefabCandidates[i]); if (IsVerifiedMistSource(prefab)) { return prefab; } } for (int j = 0; j < MistPrefabCandidates.Length; j++) { for (int k = 0; k < ZoneSystem.instance.m_vegetation.Count; k++) { GameObject prefab2 = ZoneSystem.instance.m_vegetation[k].m_prefab; if ((Object)(object)prefab2 != (Object)null && string.Equals(((Object)prefab2).name, MistPrefabCandidates[j], StringComparison.Ordinal) && IsVerifiedMistSource(prefab2)) { return prefab2; } } } return null; } private static bool IsVerifiedMistSource(GameObject source) { if ((Object)(object)source == (Object)null || (Object)(object)source.GetComponentInChildren<Mister>(true) == (Object)null || (Object)(object)source.GetComponentInChildren<MistEmitter>(true) == (Object)null || (Object)(object)source.GetComponentInChildren<ZNetView>(true) != (Object)null) { return false; } MistEmitter[] componentsInChildren = source.GetComponentsInChildren<MistEmitter>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i].m_psystem != (Object)null) { return true; } } return false; } } internal sealed class DraugrVillageMistVisual : MonoBehaviour { private static GameObject _verifiedSource; private static bool _sourceChecked; private static bool _missingLogged; private string _token; private GameObject _visual; private float _nextCheck; internal static string VerifiedSourceName { get { if (!((Object)(object)_verifiedSource != (Object)null)) { return "none"; } return ((Object)_verifiedSource).name; } } internal static bool HasVerifiedSource() { if (!_sourceChecked || (Object)(object)_verifiedSource == (Object)null) { _sourceChecked = true; _verifiedSource = DraugrVillageRitualSystem.FindVerifiedMistSource(); } if ((Object)(object)_verifiedSource == (Object)null && !_missingLogged) { _missingLogged = true; Debug.LogWarning((object)"Bifrost Breakout: none of MistArea, MistArea_small, or MistArea_edge was a safe runtime prefab with Mister, configured MistEmitter particles, and no ZNetView. The Village will continue without optional mist dressing."); } return (Object)(object)_verifiedSource != (Object)null; } internal void Configure(string token) { _token = token; EnsureVisual(); } private void Update() { if (Time.time < _nextCheck) { return; } _nextCheck = Time.time + 2f; if (string.IsNullOrEmpty(_token)) { return; } if (DraugrVillageRitualSystem.MistExpired(_token)) { if ((Object)(object)_visual != (Object)null) { Object.Destroy((Object)(object)_visual); } _visual = null; ZNetView component = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner() && (Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(((Component)this).gameObject); } } else { EnsureVisual(); } } private void EnsureVisual() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_visual != (Object)null) && HasVerifiedSource()) { _visual = Object.Instantiate<GameObject>(_verifiedSource, ((Component)this).transform.position, Quaternion.identity, ((Component)this).transform); ((Object)_visual).name = "Bifrost_DraugrVillageTemporaryMist"; Mister[] componentsInChildren = _visual.GetComponentsInChildren<Mister>(true); foreach (Mister obj in componentsInChildren) { obj.m_radius = 68f; obj.m_height = 32f; } MistEmitter[] componentsInChildren2 = _visual.GetComponentsInChildren<MistEmitter>(true); foreach (MistEmitter obj2 in componentsInChildren2) { obj2.m_totalRadius = 68f; obj2.SetEmit(true); } Debug.Log((object)("Bifrost Breakout: Draugr village " + _token + " activated local temporary mist from verified vanilla prefab " + VerifiedSourceName + " (68m radius, 32m height).")); } } } internal sealed class DraugrVillageContainment : MonoBehaviour { private const float ArmMargin = 1f; private const float BoundaryInset = 0.75f; private const float TeleportEscapeMargin = 5f; private string _token; private float _radius; private bool _armed; internal void Configure(string token, float radius) { _token = token; _radius = radius; } private void FixedUpdate() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(_token) || _radius <= 0f) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { _armed = false; return; } Vector3 position = ((Component)localPlayer).transform.position; Vector3 val = position - ((Component)this).transform.position; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (!_armed) { if (magnitude <= _radius - 1f) { _armed = true; } } else { if (magnitude <= _radius) { return; } if (magnitude > _radius + 5f) { _armed = false; return; } Vector3 val2 = ((((Vector3)(ref val)).sqrMagnitude > 0.001f) ? ((Vector3)(ref val)).normalized : Vector3.forward); Vector3 position2 = ((Component)this).transform.position + val2 * (_radius - 0.75f); position2.y = position.y; ((Component)localPlayer).transform.position = position2; Vector3 velocity = ((Character)localPlayer).GetVelocity(); float num = Vector3.Dot(velocity, val2); if (num > 0f) { ((Character)localPlayer).SetVelocity(velocity - val2 * num); } } } } [HarmonyPatch(typeof(ZNetScene), "CreateObject")] internal static class DraugrVillageRitualCreateObjectPatch { [HarmonyPostfix] private static void Postfix(GameObject __result) { DraugrVillageRitualSystem.ConfigureLoadedObject(__result); } } [HarmonyPatch(typeof(Destructible), "RPC_Damage")] internal static class DraugrVillageSpawnerFriendlyFirePatch { [HarmonyPrefix] private static bool Prefix(Destructible __instance, HitData hit) { return !DraugrVillageRitualSystem.IgnoreUndeadSpawnerDamage(__instance, hit); } } [HarmonyPatch(typeof(WearNTear), "Destroy")] internal static class DraugrVillageWardDestroyedPatch { [HarmonyPrefix] private static void Prefix(WearNTear __instance) { DraugrVillageRitualSystem.OnWearNTearDestroyed(__instance); } } [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] internal static class DraugrVillageWardFriendlyFirePatch { [HarmonyPrefix] private static bool Prefix(WearNTear __instance, HitData hit) { return !DraugrVillageRitualSystem.IgnoreUndeadWardDamage(__instance, hit); } } internal static class FortressSortieSystem { private sealed class FortressState { internal readonly string Token; internal Vector3 Center; internal FortressState(string token, Vector3 center) { //IL_000e: 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) Token = token; Center = center; } } internal const string FortressPrefabName = "CharredFortress"; internal const string CommanderPrefabName = "Charred_Mage"; internal const string ExteriorGatePrefabName = "Ashlands_Fortress_Gate_Door"; internal const string WardPrefabName = "dverger_guardstone"; internal const int CommanderMarkerKey = 694315693; internal const int WardMarkerKey = 1888340365; internal const int GateFortressMarkerKey = 470325472; internal const int GateOpenMarkerKey = 2050492924; internal const int GateCloseTimeKey = -55907439; internal const int GatePhaseKey = 778750144; internal const int WardLayoutVersionKey = -1203120781; internal const int SortieThreshold = 8; internal const float PlayerActivationRange = 100f; internal const float GateOpenSeconds = 30f; internal const float FortressWardRadius = 65f; private const float UpdateIntervalSeconds = 5f; private const float CentralCommanderRadius = 6f; private const float CentralCommanderMinimumHeight = 8f; private const float ExteriorGateRadiusMin = 14f; private const float ExteriorGateRadiusMax = 24f; private const float CourtyardWardOffset = 8f; private const float WardGroundRayStart = 20f; private const float WardGroundRayDistance = 50f; private const int CurrentWardLayoutVersion = 1; private const float InteriorHalfExtent = 18.5f; private const int InitialSortiePhase = 0; private const int WaitingForPopulationDropPhase = 1; private const int WaitingForRefillPhase = 2; private static readonly HashSet<string> DefenderPrefabs = new HashSet<string>(StringComparer.Ordinal) { "Charred_Archer", "Charred_Mage", "Charred_Melee", "Charred_Melee_Dyrnwyn", "Charred_Twitcher" }; private static readonly MethodInfo WakeupMethod = AccessTools.Method(typeof(MonsterAI), "Wakeup", (Type[])null, (Type[])null); private static readonly MethodInfo SetTargetMethod = AccessTools.Method(typeof(MonsterAI), "SetTarget", new Type[1] { typeof(Character) }, (Type[])null); private static readonly MethodInfo SetAlertedMethod = AccessTools.Method(typeof(MonsterAI), "SetAlerted", new Type[1] { typeof(bool) }, (Type[])null); private static readonly FieldInfo TargetCreatureField = AccessTools.Field(typeof(MonsterAI), "m_targetCreature"); private static readonly Dictionary<string, FortressState> Fortresses = new Dictionary<string, FortressState>(StringComparer.Ordinal); private static readonly List<FortressGateRuntime> Gates = new List<FortressGateRuntime>(); private static readonly List<FortressWardRuntime> Wards = new List<FortressWardRuntime>(); private static readonly List<Character> Defenders = new List<Character>(); private static readonly List<FortressGateRuntime> ExteriorGates = new List<FortressGateRuntime>(); private static readonly RaycastHit[] WardGroundHits = (RaycastHit[])(object)new RaycastHit[32]; private static MonoBehaviour _host; private static ManualLogSource _log; private static Coroutine _loop; private static ZoneSystem _world; internal static void Initialize(MonoBehaviour host, ManualLogSource log) { _host = host; _log = log; _loop = host.StartCoroutine(Run()); } internal static void Shutdown() { if ((Object)(object)_host != (Object)null && _loop != null) { _host.StopCoroutine(_loop); } _loop = null; _host = null; _world = null; _log = null; Fortresses.Clear(); Gates.Clear(); Wards.Clear(); Defenders.Clear(); ExteriorGates.Clear(); } private static IEnumerator Run() { while (true) { yield return (object)new WaitForSeconds(5f); if (!ServerReady()) { continue; } try { if ((Object)(object)_world != (Object)(object)ZoneSystem.instance) { _world = ZoneSystem.instance; Fortresses.Clear(); } RefreshFortresses(); foreach (FortressState value in Fortresses.Values) { Player val = FindNearbyPlayer(value.Center); if ((Object)(object)val != (Object)null) { UpdateFortress(value, val); } } } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogError((object)("Fortress sortie update failed safely: " + ex)); } } } } private static bool ServerReady() { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && (Object)(object)ZoneSystem.instance != (Object)null) { return (Object)(object)ZNetScene.instance != (Object)null; } return false; } private static void RefreshFortresses() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) foreach (LocationInstance location in _world.GetLocationList()) { if (location.m_placed && location.m_location != null && string.Equals(location.m_location.m_prefabName, "CharredFortress", StringComparison.Ordinal)) { string text = FortressToken(location.m_position); if (Fortresses.TryGetValue(text, out var value)) { value.Center = location.m_position; } else { Fortresses.Add(text, new FortressState(text, location.m_position)); } } } } private static Player FindNearbyPlayer(Vector3 center) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) Player result = null; float num = 100f; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null) && !((Character)allPlayer).IsDead() && !((Character)allPlayer).InInterior() && !((Character)allPlayer).IsTeleporting()) { float num2 = DistanceXZ(((Component)allPlayer).transform.position, center); if (num2 <= num) { result = allPlayer; num = num2; } } } return result; } private static void UpdateFortress(FortressState fortress, Player player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) FindExteriorGates(fortress.Center, ExteriorGates); EnsureWard(fortress, ExteriorGates); EnsureCommander(fortress); if (ExteriorGates.Count != 2) { return; } double timeSeconds = ZNet.instance.GetTimeSeconds(); CloseExpiredGates(ExteriorGates, timeSeconds); string text = CommanderDeadKey(fortress.Token); if (!_world.GetGlobalKey(text) && !((Object)(object)FindCommander(fortress.Token) == (Object)null)) { FindInsideDefenders(fortress, ExteriorGates, Defenders); int num = ReadSortiePhase(ExteriorGates); if (num == 1 && Defenders.Count < 8) { WriteSortiePhase(ExteriorGates, 2); num = 2; } if (!AnyGateOpen(ExteriorGates) && Defenders.Count >= 8 && num != 1) { BeginSortie(fortress, ExteriorGates, Defenders, player, timeSeconds); } } } private static void EnsureCommander(FortressState fortress) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (_world.GetGlobalKey(CommanderDeadKey(fortress.Token))) { return; } Character val = FindCommander(fortress.Token); if ((Object)(object)val != (Object)null) { SetCommanderLevel(val); } else if (!_world.GetGlobalKey(CommanderAssignedKey(fortress.Token))) { Character val2 = FindCentralCommanderCandidate(fortress.Center); if ((Object)(object)val2 != (Object)null) { AssignCommander(val2, fortress.Token); } } } private static Character FindCentralCommanderCandidate(Vector3 center) { //IL_0046: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) Character result = null; float num = 6f; foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsDead() && IsPrefab(((Component)allCharacter).gameObject, "Charred_Mage") && !(((Component)allCharacter).transform.position.y < center.y + 8f)) { float num2 = DistanceXZ(((Component)allCharacter).transform.position, center); if (num2 <= num) { result = allCharacter; num = num2; } } } return result; } private static Character FindCommander(string token) { foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsDead()) { ZNetView component = ((Component)allCharacter).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); if (val != null && string.Equals(val.GetString(694315693, string.Empty), token, StringComparison.Ordinal)) { return allCharacter; } } } return null; } private static void AssignCommander(Character character, string token) { ZNetView component = ((Component)character).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { if (!component.IsOwner()) { component.ClaimOwnership(); } component.GetZDO().Set(694315693, token); SetCommanderLevel(character); _world.SetGlobalKey(CommanderAssignedKey(token)); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Assigned the central Charred_Mage as the two-star commander of fortress " + token + ".")); } } } private static void SetCommanderLevel(Character commander) { if (commander.GetLevel() == 3) { return; } ZNetView component = ((Component)commander).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { if (!component.IsOwner()) { component.ClaimOwnership(); } commander.SetLevel(3); } } internal static void TryInitializeCharacter(Character character) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null) { return; } try { ZNetView component = ((Component)character).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { return; } if (!string.IsNullOrEmpty(component.GetZDO().GetString(694315693, string.Empty))) { SetCommanderLevel(character); } else { if (!IsPrefab(((Component)character).gameObject, "Charred_Mage")) { return; } { foreach (LocationInstance location in ZoneSystem.instance.GetLocationList()) { if (location.m_placed && location.m_location != null && string.Equals(location.m_location.m_prefabName, "CharredFortress", StringComparison.Ordinal) && !(DistanceXZ(((Component)character).transform.position, location.m_position) > 6f) && !(((Component)character).transform.position.y < location.m_position.y + 8f)) { string token = FortressToken(location.m_position); if (!ZoneSystem.instance.GetGlobalKey(CommanderDeadKey(token)) && !ZoneSystem.instance.GetGlobalKey(CommanderAssignedKey(token))) { AssignCommander(character, token); } break; } } return; } } } catch (Exception ex) { ManualLogSource log = _log; if (log != null) { log.LogError((object)("Fortress commander initialization failed safely: " + ex)); } } } internal static void OnCharacterDeath(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null) { return; } ZNetView component = ((Component)character).GetComponent<ZNetView>(); ZDO val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null); string text = ((val != null) ? val.GetString(694315693, string.Empty) : string.Empty); if (!string.IsNullOrEmpty(text)) { ZoneSystem.instance.SetGlobalKey(CommanderDeadKey(text)); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Fortress commander " + text + " was killed; its automatic sorties are permanently disabled.")); } } } private static void FindExteriorGates(Vector3 center, List<FortressGateRuntime> result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) result.Clear(); for (int num = Gates.Count - 1; num >= 0; num--) { FortressGateRuntime fortressGateRuntime = Gates[num]; if ((Object)(object)fortressGateRuntime == (Object)null) { Gates.RemoveAt(num); } else { float num2 = DistanceXZ(((Component)fortre