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 Captain territorial v1.0.87
Captain_territorial.dll
Decompiled a week 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.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Captain_territorial { public static class SimpleVFX { private class AutoCleanup : MonoBehaviour { private float _delay; public static void Schedule(GameObject target, float delay) { if (!((Object)(object)target == (Object)null)) { target.AddComponent<AutoCleanup>()._delay = delay; } } private void Start() { ((MonoBehaviour)this).StartCoroutine(Run()); } private IEnumerator Run() { yield return (object)new WaitForSeconds(_delay); ((Component)this).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)this).gameObject); } } private static GameObject _cachedAuraPrefab; private static bool _initialized; public static void Initialize() { if (!_initialized) { _initialized = true; _cachedAuraPrefab = LoadEmbeddedPrefab("buff_03a_aura"); } } private static GameObject LoadEmbeddedPrefab(string vfxName) { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = null; string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (text2.EndsWith("." + vfxName)) { text = text2; break; } } if (text == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[SimpleVFX] '" + vfxName + "' 리소스 없음")); } return null; } AssetBundle val; using (Stream stream = executingAssembly.GetManifestResourceStream(text)) { if (stream == null) { return null; } val = AssetBundle.LoadFromStream(stream); } GameObject[] array = (((Object)(object)val != (Object)null) ? val.LoadAllAssets<GameObject>() : null); return (array != null && array.Length != 0) ? array[0] : null; } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)("[SimpleVFX] '" + vfxName + "' 로드 실패: " + ex.Message)); } return null; } } public static GameObject PlayAura(Vector3 position, float duration) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cachedAuraPrefab == (Object)null) { return null; } GameObject val = InstantiateWithoutNetworking(_cachedAuraPrefab, position); AutoCleanup.Schedule(val, duration); return val; } public static void PlaySound(string sfxName, Vector3 position, float duration) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PlayZNetScenePrefab(sfxName, position, duration, "sfx"); } public static void PlayVFX(string vfxName, Vector3 position, float duration) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PlayZNetScenePrefab(vfxName, position, duration, "vfx"); } private static void PlayZNetScenePrefab(string prefabName, Vector3 position, float duration, string logTag) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(prefabName) || (Object)(object)ZNetScene.instance == (Object)null) { return; } GameObject prefab = ZNetScene.instance.GetPrefab(prefabName); if ((Object)(object)prefab == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[SimpleVFX] " + logTag + " '" + prefabName + "' 프리팹 없음")); } } else { GameObject target = InstantiateWithoutNetworking(prefab, position); AutoCleanup.Schedule(target, duration); } } private static GameObject InstantiateWithoutNetworking(GameObject prefab, Vector3 position) { //IL_0011: 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) bool activeSelf = prefab.activeSelf; prefab.SetActive(false); GameObject val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity); prefab.SetActive(activeSelf); ZNetView component = val.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } ZSyncTransform component2 = val.GetComponent<ZSyncTransform>(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } val.SetActive(true); return val; } } public static class VFXManager { public static bool VFX_ENABLED = true; private static readonly Vector3[] ConsumeAuraOffsets = (Vector3[])(object)new Vector3[3] { new Vector3(-0.3f, 1.5f, 0f), new Vector3(0f, 1.8f, 0f), new Vector3(0.3f, 1.5f, 0f) }; private const float ConsumeEffectDuration = 3f; private const float UpgradeEffectDuration = 3f; public static void Initialize() { SimpleVFX.Initialize(); } public static void PlayVFXMultiplayer(string vfxName, string soundName, Vector3 position, float destroyAfter = 3f) { //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) if (VFX_ENABLED) { if (!string.IsNullOrEmpty(vfxName)) { SimpleVFX.PlayAura(position, destroyAfter); } if (!string.IsNullOrEmpty(soundName)) { SimpleVFX.PlaySound(soundName, position, destroyAfter); } } } public static void PlayIntrusionAlert(Vector3 position) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (VFX_ENABLED) { SimpleVFX.PlaySound("sfx_morgen_alert", position, 2f); } } public static void PlayWardConsumeEffect(Transform wardTransform) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_004d: Unknown result type (might be due to invalid IL or missing references) if (VFX_ENABLED && !((Object)(object)wardTransform == (Object)null)) { Vector3[] consumeAuraOffsets = ConsumeAuraOffsets; foreach (Vector3 val in consumeAuraOffsets) { SimpleVFX.PlayAura(wardTransform.TransformPoint(val), 3f); } SimpleVFX.PlaySound("sfx_dverger_heal_finish", wardTransform.position, 3f); } } public static void PlayUpgradeEffect(Vector3 position) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (VFX_ENABLED) { SimpleVFX.PlayVFX("vfx_shieldgenerator_refuel", position, 3f); SimpleVFX.PlaySound("sfx_fader_bell", position, 3f); } } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] public static class Patch_Player_TryPlacePiece { private static readonly string[] s_alwaysAllowedPieces = new string[8] { "piece_workbench", "portal_wood", "Cart", "Raft", "Karve", "VikingShip", "VikingShip_Ashlands", "piece_sapcollector" }; private static bool Prefix(Player __instance, ref bool __result) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) GameObject placementGhost = __instance.m_placementGhost; if ((Object)(object)placementGhost == (Object)null) { return true; } Vector3 position = placementGhost.transform.position; string name = ((Object)placementGhost).name; string[] array = s_alwaysAllowedPieces; foreach (string value in array) { if (name.Contains(value)) { return true; } } if (TerritoryWard.IsBasicCampfire(name)) { return true; } if (TerritoryWard.IsTreeSapling(name)) { return true; } if (TerritoryWard.IsInsideDungeon(position)) { return true; } if (name.Contains("territoryward")) { if (!TerritoryConfig.Enabled.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_disabled", 0, (Sprite)null); __result = false; return false; } if (!TerritoryConfig.IsAdminBypassActive() && CountPlayerWards() >= TerritoryConfig.WardLimit.Value) { ((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_limit_reached", 0, (Sprite)null); __result = false; return false; } if (TerritoryWard.IsInsideActiveWard(position)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_no_overlap", 0, (Sprite)null); __result = false; return false; } return true; } if (!TerritoryWard.IsInsideActiveWard(position)) { string text = (TerritoryWard.IsInsideDeactivatedWard(position) ? "$territoryward_must_activate" : "$territoryward_no_build"); ((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null); __result = false; return false; } return true; } private static int CountPlayerWards() { if ((Object)(object)Player.m_localPlayer == (Object)null) { return 0; } long playerID = Player.m_localPlayer.GetPlayerID(); int num = 0; foreach (PrivateArea s_ward in TerritoryWard.s_wards) { if (!((Object)(object)s_ward == (Object)null)) { ZNetView component = ((Component)s_ward).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetLong("creator", 0L) == playerID) { num++; } } } return num; } } [HarmonyPatch(typeof(Player), "RemovePiece")] public static class Patch_Player_RemovePiece_WardCreatorOnly { private static bool Prefix(Player __instance) { //IL_000b: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); if (!Physics.Raycast(((Component)GameCamera.instance).transform.position, ((Component)GameCamera.instance).transform.forward, ref val, 50f, __instance.m_removeRayMask)) { return true; } if (Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)__instance).m_eye.position) >= __instance.m_maxPlaceDistance) { return true; } Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>(); if ((Object)(object)componentInParent == (Object)null || !((Object)((Component)componentInParent).gameObject).name.Contains("territoryward")) { return true; } if (componentInParent.IsCreator()) { return true; } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.LocalPlayerIsAdminOrHost()) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_remove_creator_only", 0, (Sprite)null); return false; } } public static class TerritoryConfig { public struct WardSize { public float Width; public float Depth; } public struct FuelTier { public int Level; public string ItemA; public int AmountA; public string ItemB; public int AmountB; public string ItemC; public int AmountC; public float IntervalSeconds; } public struct UpgradeCostInfo { public string ItemA; public int ItemAAmount; public string ItemB; public int ItemBAmount; public int Coins; } public static ConfigEntry<bool> AdminBypass; public static ConfigEntry<bool> Enabled; public static ConfigEntry<int> WardLimit; public static ConfigEntry<KeyCode> UpgradeKey; public static ConfigEntry<KeyCode> ShieldKey; public static ConfigEntry<KeyCode> RangeRingKey; public static ConfigEntry<KeyCode> FuelStorageKey; public static ConfigEntry<float> Lv1Width; public static ConfigEntry<float> Lv1Depth; public static ConfigEntry<string> Lv1FuelA; public static ConfigEntry<int> Lv1FuelAAmount; public static ConfigEntry<string> Lv1FuelB; public static ConfigEntry<int> Lv1FuelBAmount; public static ConfigEntry<float> Lv1IntervalMinutes; public static ConfigEntry<float> Lv1ShieldMaxHP; public static ConfigEntry<float> Lv2Width; public static ConfigEntry<float> Lv2Depth; public static ConfigEntry<string> Lv2FuelA; public static ConfigEntry<int> Lv2FuelAAmount; public static ConfigEntry<string> Lv2FuelB; public static ConfigEntry<int> Lv2FuelBAmount; public static ConfigEntry<float> Lv2IntervalMinutes; public static ConfigEntry<float> Lv2ShieldMaxHP; public static ConfigEntry<float> Lv3Width; public static ConfigEntry<float> Lv3Depth; public static ConfigEntry<string> Lv3FuelA; public static ConfigEntry<int> Lv3FuelAAmount; public static ConfigEntry<string> Lv3FuelB; public static ConfigEntry<int> Lv3FuelBAmount; public static ConfigEntry<float> Lv3IntervalMinutes; public static ConfigEntry<float> Lv3ShieldMaxHP; public static ConfigEntry<float> Lv4Width; public static ConfigEntry<float> Lv4Depth; public static ConfigEntry<string> Lv4FuelA; public static ConfigEntry<int> Lv4FuelAAmount; public static ConfigEntry<string> Lv4FuelB; public static ConfigEntry<int> Lv4FuelBAmount; public static ConfigEntry<float> Lv4IntervalMinutes; public static ConfigEntry<float> Lv4ShieldMaxHP; public static ConfigEntry<float> Lv5Width; public static ConfigEntry<float> Lv5Depth; public static ConfigEntry<string> Lv5FuelA; public static ConfigEntry<int> Lv5FuelAAmount; public static ConfigEntry<string> Lv5FuelB; public static ConfigEntry<int> Lv5FuelBAmount; public static ConfigEntry<float> Lv5IntervalMinutes; public static ConfigEntry<float> Lv5ShieldMaxHP; public static ConfigEntry<float> Lv6Width; public static ConfigEntry<float> Lv6Depth; public static ConfigEntry<string> Lv6FuelA; public static ConfigEntry<int> Lv6FuelAAmount; public static ConfigEntry<string> Lv6FuelB; public static ConfigEntry<int> Lv6FuelBAmount; public static ConfigEntry<string> Lv6FuelC; public static ConfigEntry<int> Lv6FuelCAmount; public static ConfigEntry<float> Lv6IntervalMinutes; public static ConfigEntry<float> Lv6ShieldMaxHP; public static ConfigEntry<float> Lv7Width; public static ConfigEntry<float> Lv7Depth; public static ConfigEntry<string> Lv7FuelA; public static ConfigEntry<int> Lv7FuelAAmount; public static ConfigEntry<string> Lv7FuelB; public static ConfigEntry<int> Lv7FuelBAmount; public static ConfigEntry<float> Lv7IntervalMinutes; public static ConfigEntry<float> Lv7ShieldMaxHP; public static ConfigEntry<float> Lv8Width; public static ConfigEntry<float> Lv8Depth; public static ConfigEntry<string> Lv8FuelA; public static ConfigEntry<int> Lv8FuelAAmount; public static ConfigEntry<string> Lv8FuelB; public static ConfigEntry<int> Lv8FuelBAmount; public static ConfigEntry<string> Lv8FuelC; public static ConfigEntry<int> Lv8FuelCAmount; public static ConfigEntry<float> Lv8IntervalMinutes; public static ConfigEntry<float> Lv8ShieldMaxHP; public static ConfigEntry<string> Lv2UpgradeItemA; public static ConfigEntry<int> Lv2UpgradeItemAAmount; public static ConfigEntry<string> Lv2UpgradeItemB; public static ConfigEntry<int> Lv2UpgradeItemBAmount; public static ConfigEntry<int> Lv2UpgradeCoins; public static ConfigEntry<string> Lv3UpgradeItemA; public static ConfigEntry<int> Lv3UpgradeItemAAmount; public static ConfigEntry<string> Lv3UpgradeItemB; public static ConfigEntry<int> Lv3UpgradeItemBAmount; public static ConfigEntry<int> Lv3UpgradeCoins; public static ConfigEntry<string> Lv4UpgradeItemA; public static ConfigEntry<int> Lv4UpgradeItemAAmount; public static ConfigEntry<string> Lv4UpgradeItemB; public static ConfigEntry<int> Lv4UpgradeItemBAmount; public static ConfigEntry<int> Lv4UpgradeCoins; public static ConfigEntry<string> Lv5UpgradeItemA; public static ConfigEntry<int> Lv5UpgradeItemAAmount; public static ConfigEntry<string> Lv5UpgradeItemB; public static ConfigEntry<int> Lv5UpgradeItemBAmount; public static ConfigEntry<int> Lv5UpgradeCoins; public static ConfigEntry<string> Lv6UpgradeItemA; public static ConfigEntry<int> Lv6UpgradeItemAAmount; public static ConfigEntry<string> Lv6UpgradeItemB; public static ConfigEntry<int> Lv6UpgradeItemBAmount; public static ConfigEntry<int> Lv6UpgradeCoins; public static ConfigEntry<string> Lv7UpgradeItemA; public static ConfigEntry<int> Lv7UpgradeItemAAmount; public static ConfigEntry<string> Lv7UpgradeItemB; public static ConfigEntry<int> Lv7UpgradeItemBAmount; public static ConfigEntry<int> Lv7UpgradeCoins; public static ConfigEntry<string> Lv8UpgradeItemA; public static ConfigEntry<int> Lv8UpgradeItemAAmount; public static ConfigEntry<string> Lv8UpgradeItemB; public static ConfigEntry<int> Lv8UpgradeItemBAmount; public static ConfigEntry<int> Lv8UpgradeCoins; public static ConfigEntry<bool> DoorAutoCloseEnabled; public static ConfigEntry<float> DoorAutoCloseDelay; public static ConfigEntry<string> ShieldItemName; public static ConfigEntry<bool> PassiveShieldEnabled; public static ConfigEntry<float> PassiveShieldRegenPerMinute; public static ConfigEntry<float> PassiveShieldContactDamagePerSecond; public static ConfigEntry<bool> ShieldDomeVisible; public static void Init(ConfigFile cfg) { AdminBypass = B<bool>("General", "admin_bypass", def: false, "관리자 전용: 켜면 설치 개수 제한·설치 재료비·업그레이드 재료/골드 비용을 모두 무시하고 즉시 설치·업그레이드할 수 있습니다 (연료 유지비는 그대로 적용됩니다).", 200); Enabled = B<bool>("General", "territorial_ward", def: true, "영토 와드 시스템 활성화 여부 (false = 비활성화)", 190); WardLimit = B<int>("General", "ward_limit", 2, "캐릭터 1명당 설치 가능한 영토 와드 수", 180); DoorAutoCloseEnabled = B<bool>("General", "door_auto_close", def: true, "와드 구역 내 문 자동 닫힘 활성화", 170); DoorAutoCloseDelay = B<float>("General", "door_auto_close_delay", 5f, "문 자동 닫힘 대기 시간 (초)", 160); ShieldItemName = B<string>("General", "shield_item", "SurtlingCore", "Lv5+ 데미지 보호 소모 아이템 (프리팹명)", 150); PassiveShieldEnabled = B<bool>("General", "passive_shield_enabled", def: false, "레벨1+ 항상 켜져 있는 패시브 체력형 보호막 기능 전체 활성화 여부 (기본 꺼짐) — 켜면 데미지 흡수, 몬스터 물리 차단, 돔 시각효과, 호버/HUD 수치 표시가 모두 함께 켜집니다. Lv5+ K키 완전무적 실드와는 별개이며 이 설정과 무관하게 항상 사용 가능합니다.", 146); PassiveShieldRegenPerMinute = B<float>("General", "passive_shield_regen_per_minute", 1f, "레벨1+ 패시브 보호막 실제 시간 1분당 회복량", 145); PassiveShieldContactDamagePerSecond = B<float>("General", "passive_shield_contact_damage_per_second", 15f, "몬스터가 보호막에 몸으로 부딪혀 밀쳐질 때 초당 보호막 소모량", 143); ShieldDomeVisible = B<bool>("General", "shield_dome_visible", def: true, "Lv5+ 완전무적/Lv1+ 패시브 보호막 활성 시 돔 시각효과(화면 표시) 표시 여부 — 꺼도 무적/보호막 효과 자체는 그대로 작동합니다", 144); UpgradeKey = B<KeyCode>("General", "upgrade_key", (KeyCode)117, "영토 와드 업그레이드 키", 140); ShieldKey = B<KeyCode>("General", "shield_key", (KeyCode)107, "Lv5+ 영토 보호 실드 활성화/비활성화 키", 130); RangeRingKey = B<KeyCode>("General", "range_ring_key", (KeyCode)114, "범위 링 수동 토글 키", 120); FuelStorageKey = B<KeyCode>("General", "fuel_storage_key", (KeyCode)113, "연료 창고 열기 키", 110); Lv1Width = B<float>("Level 1 - 초원", "width", 16.5f, "레벨 1 가로 크기 (미터)", 100); Lv1Depth = B<float>("Level 1 - 초원", "depth", 16.5f, "레벨 1 세로 크기 (미터)", 99); Lv1FuelA = B<string>("Level 1 - 초원", "fuel_primary", "Wood", "레벨 1 주 연료 — 나무 (프리팹명)", 90); Lv1FuelAAmount = B<int>("Level 1 - 초원", "fuel_primary_amount", 1, "레벨 1 주 연료 소모량", 89); Lv1FuelB = B<string>("Level 1 - 초원", "fuel_secondary", "Resin", "레벨 1 보조 연료 — 수지 (프리팹명)", 88); Lv1FuelBAmount = B<int>("Level 1 - 초원", "fuel_secondary_amount", 0, "레벨 1 보조 연료 소모량", 87); Lv1IntervalMinutes = B<float>("Level 1 - 초원", "fuel_interval_minutes", 5f, "레벨 1 연료 소모 간격 (분)", 80); Lv1ShieldMaxHP = B<float>("Level 1 - 초원", "shield_max_hp", 200f, "레벨 1 패시브 보호막 최대 수치", 75); Lv1Width.SettingChanged += delegate { TerritoryLocalization.RefreshWardDescription(); }; Lv1Depth.SettingChanged += delegate { TerritoryLocalization.RefreshWardDescription(); }; Lv1FuelA.SettingChanged += delegate { TerritoryLocalization.RefreshWardDescription(); }; Lv1FuelAAmount.SettingChanged += delegate { TerritoryLocalization.RefreshWardDescription(); }; Lv1FuelB.SettingChanged += delegate { TerritoryLocalization.RefreshWardDescription(); }; Lv1FuelBAmount.SettingChanged += delegate { TerritoryLocalization.RefreshWardDescription(); }; Lv1IntervalMinutes.SettingChanged += delegate { TerritoryLocalization.RefreshWardDescription(); }; Lv2Width = B<float>("Level 2 - 검은숲", "width", 19.5f, "레벨 2 가로 크기 (미터)", 100); Lv2Depth = B<float>("Level 2 - 검은숲", "depth", 19.5f, "레벨 2 세로 크기 (미터)", 99); Lv2FuelA = B<string>("Level 2 - 검은숲", "fuel_primary", "RoundLog", "레벨 2 주 연료 — 원목 (프리팹명)", 90); Lv2FuelAAmount = B<int>("Level 2 - 검은숲", "fuel_primary_amount", 1, "레벨 2 주 연료 소모량", 89); Lv2FuelB = B<string>("Level 2 - 검은숲", "fuel_secondary", "Resin", "레벨 2 보조 연료 — 수지 (프리팹명)", 88); Lv2FuelBAmount = B<int>("Level 2 - 검은숲", "fuel_secondary_amount", 0, "레벨 2 보조 연료 소모량", 87); Lv2IntervalMinutes = B<float>("Level 2 - 검은숲", "fuel_interval_minutes", 7f, "레벨 2 연료 소모 간격 (분)", 80); Lv2ShieldMaxHP = B<float>("Level 2 - 검은숲", "shield_max_hp", 400f, "레벨 2 패시브 보호막 최대 수치", 75); Lv2UpgradeItemA = B<string>("Level 2 - 검은숲", "upgrade_item_primary", "RoundLog", "Lv2 업그레이드 주 재료 (원목)", 70); Lv2UpgradeItemAAmount = B<int>("Level 2 - 검은숲", "upgrade_item_primary_amount", 10, "Lv2 업그레이드 주 재료 수량", 69); Lv2UpgradeItemB = B<string>("Level 2 - 검은숲", "upgrade_item_secondary", "GreydwarfEye", "Lv2 업그레이드 보조 재료 (그레이드워프 눈)", 68); Lv2UpgradeItemBAmount = B<int>("Level 2 - 검은숲", "upgrade_item_secondary_amount", 5, "Lv2 업그레이드 보조 재료 수량", 67); Lv2UpgradeCoins = B<int>("Level 2 - 검은숲", "upgrade_coins", 0, "Lv2 업그레이드 골드(Coins) 비용", 60); Lv3Width = B<float>("Level 3 - 늪지", "width", 24f, "레벨 3 가로 크기 (미터)", 100); Lv3Depth = B<float>("Level 3 - 늪지", "depth", 24f, "레벨 3 세로 크기 (미터)", 99); Lv3FuelA = B<string>("Level 3 - 늪지", "fuel_primary", "ElderBark", "레벨 3 주 연료 — 고대나무껍질 (프리팹명)", 90); Lv3FuelAAmount = B<int>("Level 3 - 늪지", "fuel_primary_amount", 1, "레벨 3 주 연료 소모량", 89); Lv3FuelB = B<string>("Level 3 - 늪지", "fuel_secondary", "Resin", "레벨 3 보조 연료 — 수지 (프리팹명)", 88); Lv3FuelBAmount = B<int>("Level 3 - 늪지", "fuel_secondary_amount", 0, "레벨 3 보조 연료 소모량", 87); Lv3IntervalMinutes = B<float>("Level 3 - 늪지", "fuel_interval_minutes", 9f, "레벨 3 연료 소모 간격 (분)", 80); Lv3ShieldMaxHP = B<float>("Level 3 - 늪지", "shield_max_hp", 600f, "레벨 3 패시브 보호막 최대 수치", 75); Lv3UpgradeItemA = B<string>("Level 3 - 늪지", "upgrade_item_primary", "ElderBark", "Lv3 업그레이드 주 재료 (고대나무껍질)", 70); Lv3UpgradeItemAAmount = B<int>("Level 3 - 늪지", "upgrade_item_primary_amount", 15, "Lv3 업그레이드 주 재료 수량", 69); Lv3UpgradeItemB = B<string>("Level 3 - 늪지", "upgrade_item_secondary", "Entrails", "Lv3 업그레이드 보조 재료 (창자)", 68); Lv3UpgradeItemBAmount = B<int>("Level 3 - 늪지", "upgrade_item_secondary_amount", 8, "Lv3 업그레이드 보조 재료 수량", 67); Lv3UpgradeCoins = B<int>("Level 3 - 늪지", "upgrade_coins", 1000, "Lv3 업그레이드 골드(Coins) 비용", 60); Lv4Width = B<float>("Level 4 - 산", "width", 27.5f, "레벨 4 가로 크기 (미터)", 100); Lv4Depth = B<float>("Level 4 - 산", "depth", 27.5f, "레벨 4 세로 크기 (미터)", 99); Lv4FuelA = B<string>("Level 4 - 산", "fuel_primary", "Obsidian", "레벨 4 주 연료 — 흑요석 (산에는 지역 나무가 없어 대체) (프리팹명)", 90); Lv4FuelAAmount = B<int>("Level 4 - 산", "fuel_primary_amount", 1, "레벨 4 주 연료 소모량", 89); Lv4FuelB = B<string>("Level 4 - 산", "fuel_secondary", "Resin", "레벨 4 보조 연료 — 수지 (프리팹명)", 88); Lv4FuelBAmount = B<int>("Level 4 - 산", "fuel_secondary_amount", 0, "레벨 4 보조 연료 소모량", 87); Lv4IntervalMinutes = B<float>("Level 4 - 산", "fuel_interval_minutes", 11f, "레벨 4 연료 소모 간격 (분)", 80); Lv4ShieldMaxHP = B<float>("Level 4 - 산", "shield_max_hp", 800f, "레벨 4 패시브 보호막 최대 수치", 75); Lv4UpgradeItemA = B<string>("Level 4 - 산", "upgrade_item_primary", "FreezeGland", "Lv4 업그레이드 주 재료 (얼음 분비선)", 70); Lv4UpgradeItemAAmount = B<int>("Level 4 - 산", "upgrade_item_primary_amount", 20, "Lv4 업그레이드 주 재료 수량", 69); Lv4UpgradeItemB = B<string>("Level 4 - 산", "upgrade_item_secondary", "Obsidian", "Lv4 업그레이드 보조 재료 (흑요석)", 68); Lv4UpgradeItemBAmount = B<int>("Level 4 - 산", "upgrade_item_secondary_amount", 11, "Lv4 업그레이드 보조 재료 수량", 67); Lv4UpgradeCoins = B<int>("Level 4 - 산", "upgrade_coins", 2000, "Lv4 업그레이드 골드(Coins) 비용", 60); Lv5Width = B<float>("Level 5 - 평원", "width", 33f, "레벨 5 가로 크기 (미터)", 100); Lv5Depth = B<float>("Level 5 - 평원", "depth", 33f, "레벨 5 세로 크기 (미터)", 99); Lv5FuelA = B<string>("Level 5 - 평원", "fuel_primary", "Barley", "레벨 5 주 연료 — 보리 (프리팹명)", 90); Lv5FuelAAmount = B<int>("Level 5 - 평원", "fuel_primary_amount", 1, "레벨 5 주 연료 소모량", 89); Lv5FuelB = B<string>("Level 5 - 평원", "fuel_secondary", "Resin", "레벨 5 보조 연료 — 수지 (프리팹명)", 88); Lv5FuelBAmount = B<int>("Level 5 - 평원", "fuel_secondary_amount", 0, "레벨 5 보조 연료 소모량", 87); Lv5IntervalMinutes = B<float>("Level 5 - 평원", "fuel_interval_minutes", 13f, "레벨 5 연료 소모 간격 (분)", 80); Lv5ShieldMaxHP = B<float>("Level 5 - 평원", "shield_max_hp", 1000f, "레벨 5 패시브 보호막 최대 수치", 75); Lv5UpgradeItemA = B<string>("Level 5 - 평원", "upgrade_item_primary", "Barley", "Lv5 업그레이드 주 재료 (보리)", 70); Lv5UpgradeItemAAmount = B<int>("Level 5 - 평원", "upgrade_item_primary_amount", 25, "Lv5 업그레이드 주 재료 수량", 69); Lv5UpgradeItemB = B<string>("Level 5 - 평원", "upgrade_item_secondary", "Tar", "Lv5 업그레이드 보조 재료 (타르)", 68); Lv5UpgradeItemBAmount = B<int>("Level 5 - 평원", "upgrade_item_secondary_amount", 14, "Lv5 업그레이드 보조 재료 수량", 67); Lv5UpgradeCoins = B<int>("Level 5 - 평원", "upgrade_coins", 2500, "Lv5 업그레이드 골드(Coins) 비용", 60); Lv6Width = B<float>("Level 6 - 바다", "width", 37.5f, "레벨 6 가로 크기 (미터)", 100); Lv6Depth = B<float>("Level 6 - 바다", "depth", 37.5f, "레벨 6 세로 크기 (미터)", 99); Lv6FuelA = B<string>("Level 6 - 바다", "fuel_primary", "Wood", "레벨 6 주 연료 — 나무 (바다에는 지역 나무가 없어 나무+원목으로 대체) (프리팹명)", 90); Lv6FuelAAmount = B<int>("Level 6 - 바다", "fuel_primary_amount", 1, "레벨 6 주 연료 소모량", 89); Lv6FuelB = B<string>("Level 6 - 바다", "fuel_secondary", "Resin", "레벨 6 보조 연료 — 수지 (프리팹명)", 88); Lv6FuelBAmount = B<int>("Level 6 - 바다", "fuel_secondary_amount", 0, "레벨 6 보조 연료 소모량", 87); Lv6FuelC = B<string>("Level 6 - 바다", "fuel_tertiary", "RoundLog", "레벨 6 추가 연료 — 원목 (프리팹명, 비워두면 미사용)", 86); Lv6FuelCAmount = B<int>("Level 6 - 바다", "fuel_tertiary_amount", 1, "레벨 6 추가 연료 소모량", 85); Lv6IntervalMinutes = B<float>("Level 6 - 바다", "fuel_interval_minutes", 15f, "레벨 6 연료 소모 간격 (분)", 80); Lv6ShieldMaxHP = B<float>("Level 6 - 바다", "shield_max_hp", 1200f, "레벨 6 패시브 보호막 최대 수치", 75); Lv6UpgradeItemA = B<string>("Level 6 - 바다", "upgrade_item_primary", "Chitin", "Lv6 업그레이드 주 재료 (키틴)", 70); Lv6UpgradeItemAAmount = B<int>("Level 6 - 바다", "upgrade_item_primary_amount", 30, "Lv6 업그레이드 주 재료 수량", 69); Lv6UpgradeItemB = B<string>("Level 6 - 바다", "upgrade_item_secondary", "Ooze", "Lv6 업그레이드 보조 재료 (점액)", 68); Lv6UpgradeItemBAmount = B<int>("Level 6 - 바다", "upgrade_item_secondary_amount", 17, "Lv6 업그레이드 보조 재료 수량", 67); Lv6UpgradeCoins = B<int>("Level 6 - 바다", "upgrade_coins", 3000, "Lv6 업그레이드 골드(Coins) 비용", 60); Lv7Width = B<float>("Level 7 - 미스트랜드", "width", 42f, "레벨 7 가로 크기 (미터)", 100); Lv7Depth = B<float>("Level 7 - 미스트랜드", "depth", 42f, "레벨 7 세로 크기 (미터)", 99); Lv7FuelA = B<string>("Level 7 - 미스트랜드", "fuel_primary", "Wood", "레벨 7 주 연료 — 나무 (프리팹명)", 90); Lv7FuelAAmount = B<int>("Level 7 - 미스트랜드", "fuel_primary_amount", 1, "레벨 7 주 연료 소모량", 89); Lv7FuelB = B<string>("Level 7 - 미스트랜드", "fuel_secondary", "Resin", "레벨 7 보조 연료 — 수지 (프리팹명)", 88); Lv7FuelBAmount = B<int>("Level 7 - 미스트랜드", "fuel_secondary_amount", 0, "레벨 7 보조 연료 소모량", 87); Lv7IntervalMinutes = B<float>("Level 7 - 미스트랜드", "fuel_interval_minutes", 17f, "레벨 7 연료 소모 간격 (분)", 80); Lv7ShieldMaxHP = B<float>("Level 7 - 미스트랜드", "shield_max_hp", 1500f, "레벨 7 패시브 보호막 최대 수치", 75); Lv7UpgradeItemA = B<string>("Level 7 - 미스트랜드", "upgrade_item_primary", "YggdrasilWood", "Lv7 업그레이드 주 재료 (이그드라실 나무)", 70); Lv7UpgradeItemAAmount = B<int>("Level 7 - 미스트랜드", "upgrade_item_primary_amount", 35, "Lv7 업그레이드 주 재료 수량", 69); Lv7UpgradeItemB = B<string>("Level 7 - 미스트랜드", "upgrade_item_secondary", "JotunPuffs", "Lv7 업그레이드 보조 재료 (요툰 버섯)", 68); Lv7UpgradeItemBAmount = B<int>("Level 7 - 미스트랜드", "upgrade_item_secondary_amount", 20, "Lv7 업그레이드 보조 재료 수량", 67); Lv7UpgradeCoins = B<int>("Level 7 - 미스트랜드", "upgrade_coins", 4000, "Lv7 업그레이드 골드(Coins) 비용", 60); Lv8Width = B<float>("Level 8 - 애쉬랜드", "width", 45f, "레벨 8 가로 크기 (미터)", 100); Lv8Depth = B<float>("Level 8 - 애쉬랜드", "depth", 45f, "레벨 8 세로 크기 (미터)", 99); Lv8FuelA = B<string>("Level 8 - 애쉬랜드", "fuel_primary", "Wood", "레벨 8 주 연료 — 나무 (애쉬랜드에는 지역 나무가 없어 나무+이그드라실 나무로 대체) (프리팹명)", 90); Lv8FuelAAmount = B<int>("Level 8 - 애쉬랜드", "fuel_primary_amount", 1, "레벨 8 주 연료 소모량", 89); Lv8FuelB = B<string>("Level 8 - 애쉬랜드", "fuel_secondary", "Resin", "레벨 8 보조 연료 — 수지 (프리팹명)", 88); Lv8FuelBAmount = B<int>("Level 8 - 애쉬랜드", "fuel_secondary_amount", 0, "레벨 8 보조 연료 소모량", 87); Lv8FuelC = B<string>("Level 8 - 애쉬랜드", "fuel_tertiary", "YggdrasilWood", "레벨 8 추가 연료 — 이그드라실 나무 (프리팹명, 비워두면 미사용)", 86); Lv8FuelCAmount = B<int>("Level 8 - 애쉬랜드", "fuel_tertiary_amount", 1, "레벨 8 추가 연료 소모량", 85); Lv8IntervalMinutes = B<float>("Level 8 - 애쉬랜드", "fuel_interval_minutes", 20f, "레벨 8 연료 소모 간격 (분)", 80); Lv8ShieldMaxHP = B<float>("Level 8 - 애쉬랜드", "shield_max_hp", 2000f, "레벨 8 패시브 보호막 최대 수치", 75); Lv8UpgradeItemA = B<string>("Level 8 - 애쉬랜드", "upgrade_item_primary", "CharredBone", "Lv8 업그레이드 주 재료 (불탄 뼈)", 70); Lv8UpgradeItemAAmount = B<int>("Level 8 - 애쉬랜드", "upgrade_item_primary_amount", 40, "Lv8 업그레이드 주 재료 수량", 69); Lv8UpgradeItemB = B<string>("Level 8 - 애쉬랜드", "upgrade_item_secondary", "Grausten", "Lv8 업그레이드 보조 재료 (그라우스텐 돌)", 68); Lv8UpgradeItemBAmount = B<int>("Level 8 - 애쉬랜드", "upgrade_item_secondary_amount", 23, "Lv8 업그레이드 보조 재료 수량", 67); Lv8UpgradeCoins = B<int>("Level 8 - 애쉬랜드", "upgrade_coins", 5000, "Lv8 업그레이드 골드(Coins) 비용", 60); ConfigEntry<T> B<T>(string section, string key, T def, string desc, int order = 0) { //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown return cfg.Bind<T>(section, key, def, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true, Order = order } })); } } public static WardSize GetSize(int level) { return level switch { 2 => new WardSize { Width = Lv2Width.Value, Depth = Lv2Depth.Value }, 3 => new WardSize { Width = Lv3Width.Value, Depth = Lv3Depth.Value }, 4 => new WardSize { Width = Lv4Width.Value, Depth = Lv4Depth.Value }, 5 => new WardSize { Width = Lv5Width.Value, Depth = Lv5Depth.Value }, 6 => new WardSize { Width = Lv6Width.Value, Depth = Lv6Depth.Value }, 7 => new WardSize { Width = Lv7Width.Value, Depth = Lv7Depth.Value }, 8 => new WardSize { Width = Lv8Width.Value, Depth = Lv8Depth.Value }, _ => new WardSize { Width = Lv1Width.Value, Depth = Lv1Depth.Value }, }; } public static float GetShieldMaxHP(int level) { return level switch { 2 => Lv2ShieldMaxHP.Value, 3 => Lv3ShieldMaxHP.Value, 4 => Lv4ShieldMaxHP.Value, 5 => Lv5ShieldMaxHP.Value, 6 => Lv6ShieldMaxHP.Value, 7 => Lv7ShieldMaxHP.Value, 8 => Lv8ShieldMaxHP.Value, _ => Lv1ShieldMaxHP.Value, }; } private static FuelTier GetTier(int level) { return level switch { 2 => new FuelTier { Level = 2, ItemA = Lv2FuelA.Value, AmountA = Lv2FuelAAmount.Value, ItemB = Lv2FuelB.Value, AmountB = Lv2FuelBAmount.Value, IntervalSeconds = Lv2IntervalMinutes.Value * 60f }, 3 => new FuelTier { Level = 3, ItemA = Lv3FuelA.Value, AmountA = Lv3FuelAAmount.Value, ItemB = Lv3FuelB.Value, AmountB = Lv3FuelBAmount.Value, IntervalSeconds = Lv3IntervalMinutes.Value * 60f }, 4 => new FuelTier { Level = 4, ItemA = Lv4FuelA.Value, AmountA = Lv4FuelAAmount.Value, ItemB = Lv4FuelB.Value, AmountB = Lv4FuelBAmount.Value, IntervalSeconds = Lv4IntervalMinutes.Value * 60f }, 5 => new FuelTier { Level = 5, ItemA = Lv5FuelA.Value, AmountA = Lv5FuelAAmount.Value, ItemB = Lv5FuelB.Value, AmountB = Lv5FuelBAmount.Value, IntervalSeconds = Lv5IntervalMinutes.Value * 60f }, 6 => new FuelTier { Level = 6, ItemA = Lv6FuelA.Value, AmountA = Lv6FuelAAmount.Value, ItemB = Lv6FuelB.Value, AmountB = Lv6FuelBAmount.Value, ItemC = Lv6FuelC.Value, AmountC = Lv6FuelCAmount.Value, IntervalSeconds = Lv6IntervalMinutes.Value * 60f }, 7 => new FuelTier { Level = 7, ItemA = Lv7FuelA.Value, AmountA = Lv7FuelAAmount.Value, ItemB = Lv7FuelB.Value, AmountB = Lv7FuelBAmount.Value, IntervalSeconds = Lv7IntervalMinutes.Value * 60f }, 8 => new FuelTier { Level = 8, ItemA = Lv8FuelA.Value, AmountA = Lv8FuelAAmount.Value, ItemB = Lv8FuelB.Value, AmountB = Lv8FuelBAmount.Value, ItemC = Lv8FuelC.Value, AmountC = Lv8FuelCAmount.Value, IntervalSeconds = Lv8IntervalMinutes.Value * 60f }, _ => new FuelTier { Level = 1, ItemA = Lv1FuelA.Value, AmountA = Lv1FuelAAmount.Value, ItemB = Lv1FuelB.Value, AmountB = Lv1FuelBAmount.Value, IntervalSeconds = Lv1IntervalMinutes.Value * 60f }, }; } public static List<FuelTier> GetFuelTiers(int uptoLevel) { List<FuelTier> list = new List<FuelTier>(2) { GetTier(1) }; if (uptoLevel > 1) { list.Add(GetTier(uptoLevel)); } return list; } public static UpgradeCostInfo GetUpgradeCost(int targetLevel) { return targetLevel switch { 2 => new UpgradeCostInfo { ItemA = Lv2UpgradeItemA.Value, ItemAAmount = Lv2UpgradeItemAAmount.Value, ItemB = Lv2UpgradeItemB.Value, ItemBAmount = Lv2UpgradeItemBAmount.Value, Coins = Lv2UpgradeCoins.Value }, 3 => new UpgradeCostInfo { ItemA = Lv3UpgradeItemA.Value, ItemAAmount = Lv3UpgradeItemAAmount.Value, ItemB = Lv3UpgradeItemB.Value, ItemBAmount = Lv3UpgradeItemBAmount.Value, Coins = Lv3UpgradeCoins.Value }, 4 => new UpgradeCostInfo { ItemA = Lv4UpgradeItemA.Value, ItemAAmount = Lv4UpgradeItemAAmount.Value, ItemB = Lv4UpgradeItemB.Value, ItemBAmount = Lv4UpgradeItemBAmount.Value, Coins = Lv4UpgradeCoins.Value }, 5 => new UpgradeCostInfo { ItemA = Lv5UpgradeItemA.Value, ItemAAmount = Lv5UpgradeItemAAmount.Value, ItemB = Lv5UpgradeItemB.Value, ItemBAmount = Lv5UpgradeItemBAmount.Value, Coins = Lv5UpgradeCoins.Value }, 6 => new UpgradeCostInfo { ItemA = Lv6UpgradeItemA.Value, ItemAAmount = Lv6UpgradeItemAAmount.Value, ItemB = Lv6UpgradeItemB.Value, ItemBAmount = Lv6UpgradeItemBAmount.Value, Coins = Lv6UpgradeCoins.Value }, 7 => new UpgradeCostInfo { ItemA = Lv7UpgradeItemA.Value, ItemAAmount = Lv7UpgradeItemAAmount.Value, ItemB = Lv7UpgradeItemB.Value, ItemBAmount = Lv7UpgradeItemBAmount.Value, Coins = Lv7UpgradeCoins.Value }, 8 => new UpgradeCostInfo { ItemA = Lv8UpgradeItemA.Value, ItemAAmount = Lv8UpgradeItemAAmount.Value, ItemB = Lv8UpgradeItemB.Value, ItemBAmount = Lv8UpgradeItemBAmount.Value, Coins = Lv8UpgradeCoins.Value }, _ => default(UpgradeCostInfo), }; } public static bool IsAdminBypassActive() { if (!AdminBypass.Value) { return false; } return (Object)(object)ZNet.instance != (Object)null && ZNet.instance.LocalPlayerIsAdminOrHost(); } } [HarmonyPatch(typeof(DamageText), "AddInworldText")] public static class Patch_DamageText_RichText { internal static readonly HashSet<TMP_Text> SlowRiseFields = new HashSet<TMP_Text>(); private static void Postfix(DamageText __instance, string text) { if (!string.IsNullOrEmpty(text) && text.Contains("<color=") && __instance.m_worldTexts.Count != 0) { WorldTextInstance val = __instance.m_worldTexts[__instance.m_worldTexts.Count - 1]; val.m_textField.richText = true; SlowRiseFields.Add(val.m_textField); } } } [HarmonyPatch(typeof(DamageText), "UpdateWorldTexts")] public static class Patch_DamageText_SlowRise { private const float SpeedFactor = 1f / 3f; private static void Postfix(DamageText __instance, float dt) { if (Patch_DamageText_RichText.SlowRiseFields.Count == 0) { return; } foreach (WorldTextInstance worldText in __instance.m_worldTexts) { if (Patch_DamageText_RichText.SlowRiseFields.Contains(worldText.m_textField)) { worldText.m_worldPos.y -= dt * 0.6666666f; if (worldText.m_timer > __instance.m_textDuration) { Patch_DamageText_RichText.SlowRiseFields.Remove(worldText.m_textField); } } } } } [HarmonyPatch(typeof(Door), "Interact")] public static class Patch_Door_AutoClose { private static void Postfix(Door __instance) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (TerritoryConfig.DoorAutoCloseEnabled.Value && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsOwner() && __instance.m_nview.GetZDO().GetInt("state", 0) != 0 && TerritoryWard.IsInsideActiveWard(((Component)__instance).transform.position)) { ((MonoBehaviour)__instance).StartCoroutine(AutoCloseRoutine(__instance)); } } private static IEnumerator AutoCloseRoutine(Door door) { yield return (object)new WaitForSeconds(TerritoryConfig.DoorAutoCloseDelay.Value); if (!((Object)(object)door == (Object)null) && !((Object)(object)door.m_nview == (Object)null) && door.m_nview.IsValid() && door.m_nview.GetZDO().GetInt("state", 0) != 0 && TerritoryWard.IsInsideActiveWard(((Component)door).transform.position)) { door.m_nview.InvokeRPC(ZNetView.Everybody, "UseDoor", new object[1] { false }); } } } internal static class DoorGuardStoneBypass { internal static void Suppress(Door door, out bool state) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) state = door.m_checkGuardStone; if (TerritoryWard.IsInsideActiveWard(((Component)door).transform.position)) { door.m_checkGuardStone = false; } } internal static void Restore(Door door, bool state) { door.m_checkGuardStone = state; } } [HarmonyPatch(typeof(Door), "Interact")] public static class Patch_Door_GuardStoneBypass { private static void Prefix(Door __instance, out bool __state) { DoorGuardStoneBypass.Suppress(__instance, out __state); } private static void Postfix(Door __instance, bool __state) { DoorGuardStoneBypass.Restore(__instance, __state); } } [HarmonyPatch(typeof(Door), "GetHoverText")] public static class Patch_Door_GuardStoneBypass_HoverText { private static void Prefix(Door __instance, out bool __state) { DoorGuardStoneBypass.Suppress(__instance, out __state); } private static void Postfix(Door __instance, bool __state) { DoorGuardStoneBypass.Restore(__instance, __state); } } [HarmonyPatch(typeof(Door), "UseItem")] public static class Patch_Door_GuardStoneBypass_UseItem { private static void Prefix(Door __instance, out bool __state) { DoorGuardStoneBypass.Suppress(__instance, out __state); } private static void Postfix(Door __instance, bool __state) { DoorGuardStoneBypass.Restore(__instance, __state); } } [HarmonyPatch(typeof(Player), "Interact")] public static class Patch_Player_Interact { private static bool Prefix(Player __instance, GameObject go) { //IL_00d0: 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_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return true; } Container componentInParent = go.GetComponentInParent<Container>(); if ((Object)(object)componentInParent != (Object)null && componentInParent.m_name == "$territoryward_storage") { PrivateArea component = ((Component)componentInParent).GetComponent<PrivateArea>(); if ((Object)(object)component != (Object)null && !component.HaveLocalAccess()) { IntrusionAlert.CheckAndAlert(((Component)componentInParent).transform.position, (Humanoid)(object)__instance); ((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_not_permitted", 0, (Sprite)null); return false; } return true; } if (((Object)((Component)go.transform.root).gameObject).name.Contains("territoryward")) { return true; } if (TerritoryWard.IsInsideDungeon(go.transform.position)) { return true; } bool flag = (Object)(object)go.GetComponentInParent<Door>() != (Object)null; bool flag2 = TerritoryWard.IsBasicCampfire(((Object)((Component)go.transform.root).gameObject).name); Vector3 position = go.transform.position; if (TerritoryWard.IsInsideDeactivatedWard(position)) { if (flag || flag2) { return true; } ((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_off_blocked", 0, (Sprite)null); return false; } if (TerritoryWard.IsInsideActiveWardWithoutAccess(position)) { if (flag || flag2) { return true; } IntrusionAlert.CheckAndAlert(position, (Humanoid)(object)__instance); ((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_not_permitted", 0, (Sprite)null); return false; } return true; } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(int), typeof(int), typeof(int) })] public static class Patch_Inventory_AddItem_MaxStack { private static void Prefix(Inventory __instance, ItemData item, out int __state) { __state = item.m_shared.m_maxStackSize; if (WardInventoryHelper.IsWardStorage(__instance) && WardInventoryHelper.IsWardFuel(item.m_shared.m_name)) { item.m_shared.m_maxStackSize = 999; } } private static void Postfix(ItemData item, int __state) { item.m_shared.m_maxStackSize = __state; } } [HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[] { typeof(ItemData), typeof(int) })] public static class Patch_Inventory_CanAddItem_MaxStack { private static void Prefix(Inventory __instance, ItemData item, out int __state) { __state = item.m_shared.m_maxStackSize; if (WardInventoryHelper.IsWardStorage(__instance) && WardInventoryHelper.IsWardFuel(item.m_shared.m_name)) { item.m_shared.m_maxStackSize = 999; } } private static void Postfix(ItemData item, int __state) { item.m_shared.m_maxStackSize = __state; } } [HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(string), typeof(int), typeof(int), typeof(bool) })] public static class Patch_Inventory_RemoveItem_ProtectWardStorage { private static bool Prefix(Inventory __instance) { if (!WardInventoryHelper.IsWardStorage(__instance)) { return true; } return WardInventoryHelper.IsWithdrawAllowed(__instance); } } [HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })] public static class Patch_Inventory_RemoveItemData_ProtectWardStorage { private static bool Prefix(Inventory __instance) { if (!WardInventoryHelper.IsWardStorage(__instance)) { return true; } return WardInventoryHelper.IsWithdrawAllowed(__instance); } } [HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData), typeof(int) })] public static class Patch_Inventory_RemoveItemDataAmount_ProtectWardStorage { private static bool Prefix(Inventory __instance) { if (!WardInventoryHelper.IsWardStorage(__instance)) { return true; } return WardInventoryHelper.IsWithdrawAllowed(__instance); } } [HarmonyPatch(typeof(Inventory), "RemoveOneItem", new Type[] { typeof(ItemData) })] public static class Patch_Inventory_RemoveOneItem_ProtectWardStorage { private static bool Prefix(Inventory __instance) { if (!WardInventoryHelper.IsWardStorage(__instance)) { return true; } return WardInventoryHelper.IsWithdrawAllowed(__instance); } } [HarmonyPatch(typeof(PrivateArea), "Interact")] public static class Patch_PrivateArea_PermittedToggle { private static bool Prefix(PrivateArea __instance, Humanoid human, bool hold, bool alt) { if (!((Object)((Component)__instance).gameObject).name.Contains("territoryward")) { return true; } if (hold) { return true; } if (alt || Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) { return false; } if (__instance.m_piece.IsCreator()) { return true; } Player val = (Player)(object)((human is Player) ? human : null); if ((Object)(object)val == (Object)null) { return true; } bool flag = __instance.IsPermitted(val.GetPlayerID()); bool flag2 = __instance.IsEnabled(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[Territory] PermittedToggle Interact: player={val.GetPlayerName()}({val.GetPlayerID()}) permitted={flag} wardEnabled={flag2}"); } if (flag) { __instance.m_nview.InvokeRPC("ToggleEnabled", new object[1] { val.GetPlayerID() }); } else if (!flag2) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[Territory] PermittedToggle Interact: sending join RPC for {val.GetPlayerName()}({val.GetPlayerID()})"); } __instance.m_nview.InvokeRPC("TogglePermitted", new object[2] { val.GetPlayerID(), val.GetPlayerName() }); } else { ((Character)Player.m_localPlayer).Message((MessageType)2, "$territoryward_join_blocked_while_active", 0, (Sprite)null); } return false; } } [HarmonyPatch(typeof(PrivateArea), "RPC_ToggleEnabled")] public static class Patch_PrivateArea_RPC_ToggleEnabled { private static bool Prefix(PrivateArea __instance, long uid, long playerID) { if (!((Object)((Component)__instance).gameObject).name.Contains("territoryward")) { return true; } if (!__instance.m_nview.IsOwner()) { return true; } if (__instance.m_piece.GetCreator() == playerID) { return true; } if (!__instance.IsPermitted(playerID)) { return true; } __instance.SetEnabled(!__instance.IsEnabled()); return false; } } [HarmonyPatch(typeof(PrivateArea), "GetHoverText")] public static class Patch_PrivateArea_HoverText { private const string Cyan = "#00FFFF"; private const string Yellow = "yellow"; private const string Gray = "grey"; private static void Postfix(PrivateArea __instance, ref string __result) { //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_064c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)((Component)__instance).gameObject).name.Contains("territoryward")) { return; } TerritoryWardController component = ((Component)__instance).GetComponent<TerritoryWardController>(); ZNetView val = component?.m_nview ?? ((Component)__instance).GetComponent<ZNetView>(); int num = 1; if ((Object)(object)val != (Object)null && val.IsValid()) { num = val.GetZDO().GetInt("tw_level", 1); } bool flag = __instance.IsEnabled(); string arg = (flag ? "<color=green>$territoryward_status_enabled</color>" : "<color=red>$territoryward_status_disabled</color>"); Player localPlayer = Player.m_localPlayer; bool flag2 = (Object)(object)localPlayer != (Object)null && __instance.m_piece.IsCreator(); bool flag3 = (Object)(object)localPlayer != (Object)null && (Object)(object)val != (Object)null && val.IsValid() && __instance.IsPermitted(localPlayer.GetPlayerID()); string text = Localization.instance.Localize("$KEY_Use"); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(string.Format("<size=22><b>[ $territoryward_name <color={0}>Lv{1}</color>({2}) ]</b></size>", "#00FFFF", num, arg)); if ((Object)(object)component != (Object)null) { stringBuilder.Append("\n<color=yellow>$territoryward_fuel_label</color> : " + component.GetFuelInfoText()); } string text2 = (((Object)(object)component != (Object)null) ? $"{component.m_width:0.#}x{component.m_depth:0.#}m" : $"{__instance.m_radius:0}m"); stringBuilder.Append("\n<color=yellow>$territoryward_range_label</color> : " + text2); if ((Object)(object)component != (Object)null && !component.IsShielded() && TerritoryConfig.PassiveShieldEnabled.Value) { float passiveShieldHP = component.GetPassiveShieldHP(); float passiveShieldMaxHP = component.GetPassiveShieldMaxHP(); stringBuilder.Append(string.Format("\n<color={0}>$territoryward_passive_shield_label</color> : {1:0} / {2:0}", "yellow", passiveShieldHP, passiveShieldMaxHP)); } stringBuilder.Append("\n"); object obj; if (val == null) { obj = null; } else { ZDO zDO = val.GetZDO(); obj = ((zDO != null) ? zDO.GetString("creatorName", "???") : null); } if (obj == null) { obj = "???"; } string text3 = (string)obj; string permittedNamesString = GetPermittedNamesString(__instance, val); stringBuilder.Append("\n<color=yellow>$territoryward_owner_label</color> : <color=green>" + text3 + "</color>"); stringBuilder.Append("\n<color=yellow>$territoryward_permitted_label</color> : <color=#4FC3F7>" + permittedNamesString + "</color>"); stringBuilder.Append("\n"); if (flag2 || flag3) { if (flag2) { stringBuilder.Append("\n[<color=yellow><b>Shift+" + text + "</b></color>] $territoryward_member_manage_hint_key"); } stringBuilder.Append("\n[<color=yellow><b>" + text + "</b></color>] $territoryward_toggle_hint_key"); if (flag3 && !flag2) { stringBuilder.Append(string.Format("\n[<color={0}><b>Shift+{1}</b></color>] $territoryward_member_leave_hint_key", "yellow", TerritoryConfig.RangeRingKey.Value)); } } else if (!flag) { stringBuilder.Append("\n[<color=yellow><b>" + text + "</b></color>] $territoryward_member_join_hint_key"); stringBuilder.Append(string.Format("\n[<color={0}><b>Shift+{1}</b></color>] $territoryward_member_leave_hint_key", "yellow", TerritoryConfig.RangeRingKey.Value)); } else { stringBuilder.Append("\n<color=grey>$territoryward_join_blocked_while_active_hint</color>"); } stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] $territoryward_fuel_hint", "yellow", TerritoryConfig.FuelStorageKey.Value)); stringBuilder.Append("\n"); stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] $territoryward_upgrade_hint_key", "yellow", TerritoryConfig.UpgradeKey.Value)); if ((Object)(object)component != (Object)null) { if (num < 8) { TerritoryConfig.WardSize? nextLevelSize = component.GetNextLevelSize(); stringBuilder.Append(string.Format(" <color={0}>Lv{1}</color>→<color={2}><b>Lv{3}</b></color>", "#00FFFF", num, "#00FFFF", num + 1)); stringBuilder.Append("\n<color=yellow>$territoryward_material_label</color> : " + component.GetUpgradeRequirementText()); if (nextLevelSize.HasValue) { stringBuilder.Append(string.Format("\n<color={0}>$territoryward_range_label</color> : {1:0.#}x{2:0.#}m", "yellow", nextLevelSize.Value.Width, nextLevelSize.Value.Depth)); } stringBuilder.Append("\n<color=yellow>$territoryward_fuel_label</color> : " + component.GetNextLevelFuelInfoText()); string nextLevelFullFuelText = component.GetNextLevelFullFuelText(); if (!string.IsNullOrEmpty(nextLevelFullFuelText)) { stringBuilder.Append(string.Format("\n<color={0}>Lv1/Lv{1} $territoryward_fuel_label</color> :", "yellow", num + 1)); stringBuilder.Append("\n" + nextLevelFullFuelText); } } else { stringBuilder.Append(" $territoryward_max_level"); } } if (num >= 5 && (Object)(object)component != (Object)null) { if (component.IsShielded()) { int num2 = Mathf.CeilToInt(component.GetShieldRemainingMinutes()); string text4 = Localization.instance.Localize("$territoryward_shield_active", new string[1] { num2.ToString() }); stringBuilder.Append("\n<color=#00FFFF>[" + text4 + "]</color>"); if (flag2 || flag3) { stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] $territoryward_shield_deactivate_hint_key", "yellow", TerritoryConfig.ShieldKey.Value)); } } else if (flag2 || flag3) { if (!flag) { stringBuilder.Append("\n<color=grey>$territoryward_shield_ward_off_hint</color>"); } else { float shieldBankedRemainingMinutes = component.GetShieldBankedRemainingMinutes(); if (shieldBankedRemainingMinutes > 0f) { int num3 = Mathf.CeilToInt(shieldBankedRemainingMinutes); string arg2 = Localization.instance.Localize("$territoryward_shield_resume_hint", new string[1] { num3.ToString() }); stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] {2}", "yellow", TerritoryConfig.ShieldKey.Value, arg2)); } else { string arg3 = Localization.instance.Localize(TerritoryWardController.Resolve(TerritoryConfig.ShieldItemName.Value) ?? TerritoryConfig.ShieldItemName.Value); stringBuilder.Append(string.Format("\n[<color={0}><b>{1}</b></color>] $territoryward_shield_hint_key ({2} x1)", "yellow", TerritoryConfig.ShieldKey.Value, arg3)); } } } } __result = Localization.instance.Localize(stringBuilder.ToString()); } private static string GetPermittedNamesString(PrivateArea instance, ZNetView nview) { try { if ((Object)(object)nview != (Object)null && nview.IsValid()) { ZDO zDO = nview.GetZDO(); int num = zDO.GetInt("permitted", 0); if (num > 0) { List<string> list = new List<string>(num); for (int i = 0; i < num; i++) { string text = zDO.GetString("pu_name" + i, ""); if (!string.IsNullOrEmpty(text)) { list.Add(text); } } if (list.Count > 0) { return string.Join(", ", list); } } } } catch { } try { FieldInfo[] fields = typeof(PrivateArea).GetFields(BindingFlags.Instance | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.Name.ToLower().Contains("permitted") || !(fieldInfo.GetValue(instance) is IEnumerable enumerable)) { continue; } List<string> list2 = new List<string>(); foreach (object item in enumerable) { if (item != null) { string text2 = item.GetType().GetProperty("Value")?.GetValue(item) as string; if (!string.IsNullOrEmpty(text2)) { list2.Add(text2); } } } if (list2.Count > 0) { return string.Join(", ", list2); } } } catch { } return "$territoryward_none"; } } [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] public static class Patch_Hud_WardHoverTextPosition { private static Vector2? s_basePos; private static Vector2? s_baseSizeDelta; private static TextMeshProUGUI s_rightColumn; private static RectTransform s_dividerRect; private const float OffsetY = 340f; private const float WidthMultiplier = 1.3225f; private const float DividerWidth = 4f; private const float ColumnGap = 12f; private const float MinDividerHeight = 200f; private const float DividerHeightPad = 20f; private static void Postfix(Hud __instance) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) try { object? obj = typeof(Hud).GetField("m_hoverName", BindingFlags.Instance | BindingFlags.Public)?.GetValue(__instance); Component val = (Component)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null) { return; } RectTransform component = val.GetComponent<RectTransform>(); if ((Object)(object)component == (Object)null) { return; } PropertyInfo property = ((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public); if (property == null) { return; } string text = (property.GetValue(val) as string) ?? ""; bool flag = text.Contains("영토 와드") || text.Contains("Territory Ward"); if (!s_basePos.HasValue) { s_basePos = component.anchoredPosition; } if (!s_baseSizeDelta.HasValue) { s_baseSizeDelta = component.sizeDelta; } component.anchoredPosition = s_basePos.Value + (Vector2)(flag ? new Vector2(0f, 340f) : Vector2.zero); if (!flag) { component.sizeDelta = s_baseSizeDelta.Value; if ((Object)(object)s_rightColumn != (Object)null) { ((Component)s_rightColumn).gameObject.SetActive(false); } if ((Object)(object)s_dividerRect != (Object)null) { ((Component)s_dividerRect).gameObject.SetActive(false); } return; } EnsureColumnObjects(val, component); float num = s_baseSizeDelta.Value.x * 1.3225f; component.sizeDelta = new Vector2(num, s_baseSizeDelta.Value.y); string[] array = text.Split(new char[1] { '\n' }); int num2 = Mathf.CeilToInt((float)array.Length / 2f); string value = string.Join("\n", array, 0, num2); string text2 = string.Join("\n", array, num2, array.Length - num2); property.SetValue(val, value); ((TMP_Text)s_rightColumn).text = text2; Vector2 anchoredPosition = component.anchoredPosition; float num3 = num + 12f; float num4 = num + 24f + 4f; RectTransform component2 = ((Component)s_rightColumn).GetComponent<RectTransform>(); component2.sizeDelta = new Vector2(num, s_baseSizeDelta.Value.y); component2.anchoredPosition = anchoredPosition + new Vector2(num4, 0f); ((Component)s_rightColumn).gameObject.SetActive(true); TextMeshProUGUI val2 = (TextMeshProUGUI)(object)((val is TextMeshProUGUI) ? val : null); float num5 = (((Object)(object)val2 != (Object)null) ? ((TMP_Text)val2).preferredHeight : 200f); float preferredHeight = ((TMP_Text)s_rightColumn).preferredHeight; float num6 = Mathf.Max(Mathf.Max(num5, preferredHeight), 200f) + 20f; s_dividerRect.sizeDelta = new Vector2(4f, num6); s_dividerRect.anchoredPosition = anchoredPosition + new Vector2(num3, 0f); ((Component)s_dividerRect).gameObject.SetActive(true); } catch { } } private static void EnsureColumnObjects(Component originalComp, RectTransform originalRt) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_rightColumn == (Object)null) { GameObject val = Object.Instantiate<GameObject>(originalComp.gameObject, ((Transform)originalRt).parent); ((Object)val).name = "TerritoryWard_HoverTextRightColumn"; s_rightColumn = val.GetComponent<TextMeshProUGUI>(); } if ((Object)(object)s_dividerRect == (Object)null) { GameObject val2 = new GameObject("TerritoryWard_HoverTextDivider", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(((Transform)originalRt).parent, false); ((Graphic)val2.GetComponent<Image>()).color = new Color(1f, 1f, 1f, 0.4f); s_dividerRect = val2.GetComponent<RectTransform>(); s_dividerRect.pivot = new Vector2(0.5f, 1f); } } } internal static class WardInventoryHelper { internal static bool IsWardStorage(Inventory inv) { return inv.m_name == "$territoryward_storage"; } internal static bool IsWardFuel(string name) { return name == "$item_wood" || name == "$item_resin"; } internal static bool IsWithdrawAllowed(Inventory inv) { if (TerritoryWardController.IsInternalWithdrawInProgress) { return true; } InventoryGui instance = InventoryGui.instance; return (Object)(object)instance != (Object)null && instance.IsContainerOpen() && instance.m_currentContainer.GetInventory() == inv; } } [HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")] public static class Patch_InventoryGrid_UpdateInventory_ForceRebuild { private static void Prefix(InventoryGrid __instance, Inventory inventory) { if (inventory != null) { int num = inventory.GetWidth() * inventory.GetHeight(); if (__instance.m_elements.Count != num) { __instance.m_width = -1; } } } } [HarmonyPatch(typeof(InventoryGrid), "GetElement")] public static class Patch_InventoryGrid_GetElement_Safety { private static bool Prefix(InventoryGrid __instance, int x, int y, int width, ref Element __result) { int num = y * width + x; if (num >= 0 && num < __instance.m_elements.Count) { return true; } if (__instance.m_elements.Count == 0) { return true; } ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"[Territory] InventoryGrid.GetElement 범위 밖 접근 방어: x={x}, y={y}, width={width}, elements={__instance.m_elements.Count}"); } __result = __instance.m_elements[Mathf.Clamp(num, 0, __instance.m_elements.Count - 1)]; return false; } } [HarmonyPatch(typeof(Container), "Interact")] public static class Patch_Container_Interact_IntrusionAlert { private static void Prefix(Container __instance, Humanoid character) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) IntrusionAlert.CheckAndAlert(((Component)__instance).transform.position, character); } } [HarmonyPatch(typeof(CraftingStation), "Interact")] public static class Patch_CraftingStation_Interact_IntrusionAlert { private static void Prefix(CraftingStation __instance, Humanoid user) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) IntrusionAlert.CheckAndAlert(((Component)__instance).transform.position, user); } } internal static class IntrusionAlert { public static void CheckAndAlert(Vector3 position, Humanoid character) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character != (Object)(object)Player.m_localPlayer) { return; } List<PrivateArea> list = new List<PrivateArea>(); foreach (PrivateArea s_ward in TerritoryWard.s_wards) { if (!((Object)(object)s_ward == (Object)null) && s_ward.IsEnabled() && s_ward.IsInside(position, 0f)) { if (s_ward.HaveLocalAccess()) { return; } list.Add(s_ward); } } foreach (PrivateArea item in list) { ((Component)item).GetComponent<TerritoryWardController>()?.ReportIntrusion(Player.m_localPlayer.GetPlayerName()); } } } internal static class KnownPlayersRegistry { private static readonly Dictionary<long, Dictionary<long, string>> s_byWorld = new Dictionary<long, Dictionary<long, string>>(); private static string s_filePath; private static string FilePath { get { if (s_filePath == null) { s_filePath = Path.Combine(Paths.ConfigPath, "Captain_territorial_known_players.json"); } return s_filePath; } } private static long CurrentWorldUid() { return ZNet.m_world?.m_uid ?? 0; } internal static void Load() { s_byWorld.Clear(); if (!File.Exists(FilePath)) { return; } string text = File.ReadAllText(FilePath, Encoding.UTF8); int num = text.IndexOf('{'); int num2 = text.LastIndexOf('}'); if (num < 0 || num2 < 0 || num2 <= num) { return; } string s = text.Substring(num + 1, num2 - num - 1); foreach (string item in SplitTopLevel(s)) { int num3 = item.IndexOf(':'); if (num3 < 0 || !TryUnquote(item.Substring(0, num3), out var value) || !long.TryParse(value, out var result)) { continue; } string text2 = item.Substring(num3 + 1).Trim(); int num4 = text2.IndexOf('{'); int num5 = text2.LastIndexOf('}'); if (num4 < 0 || num5 < 0 || num5 <= num4) { continue; } Dictionary<long, string> dictionary = new Dictionary<long, string>(); foreach (string item2 in SplitTopLevel(text2.Substring(num4 + 1, num5 - num4 - 1))) { int num6 = item2.IndexOf(':'); if (num6 >= 0 && TryUnquote(item2.Substring(0, num6), out var value2) && TryUnquote(item2.Substring(num6 + 1), out var value3) && long.TryParse(value2, out var result2)) { dictionary[result2] = Unescape(value3); } } if (dictionary.Count > 0) { s_byWorld[result] = dictionary; } } } internal static bool RecordPlayer(long playerID, string name) { long num = CurrentWorldUid(); if (num == 0L || playerID == 0L || string.IsNullOrEmpty(name)) { return false; } if (!s_byWorld.TryGetValue(num, out var value)) { value = new Dictionary<long, string>(); s_byWorld[num] = value; } if (value.TryGetValue(playerID, out var value2) && value2 == name) { return false; } value[playerID] = name; Save(); return true; } internal static void ReplaceAll(Dictionary<long, string> data) { long num = CurrentWorldUid(); if (num != 0) { s_byWorld[num] = new Dictionary<long, string>(data); Save(); } } internal static Dictionary<long, string> GetAll() { long num = CurrentWorldUid(); if (num != 0L && s_byWorld.TryGetValue(num, out var value)) { return new Dictionary<long, string>(value); } return new Dictionary<long, string>(); } private static void Save() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("{\n"); bool flag = true; foreach (KeyValuePair<long, Dictionary<long, string>> item in s_byWorld) { if (item.Value.Count == 0) { continue; } if (!flag) { stringBuilder.Append(",\n"); } flag = false; stringBuilder.Append(" \"").Append(item.Key).Append("\": {\n"); bool flag2 = true; foreach (KeyValuePair<long, string> item2 in item.Value) { if (!flag2) { stringBuilder.Append(",\n"); } flag2 = false; stringBuilder.Append(" \"").Append(item2.Key).Append("\": \"") .Append(Escape(item2.Value)) .Append('"'); } stringBuilder.Append("\n }"); } stringBuilder.Append("\n}\n"); string directoryName = Path.GetDirectoryName(FilePath); if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllText(FilePath, stringBuilder.ToString(), Encoding.UTF8); } private static List<string> SplitTopLevel(string s) { List<string> list = new List<string>(); int num = 0; int num2 = 0; for (int i = 0; i < s.Length; i++) { switch (s[i]) { case '{': num++; break; case '}': num--; break; case ',': if (num == 0) { list.Add(s.Substring(num2, i - num2)); num2 = i + 1; } break; } } string text = s.Substring(num2); if (text.Trim().Length > 0) { list.Add(text); } return list; } private static bool TryUnquote(string raw, out string value) { raw = raw.Trim(); int num = raw.IndexOf('"'); int num2 = raw.LastIndexOf('"'); if (num < 0 || num2 <= num) { value = null; return false; } value = raw.Substring(num + 1, num2 - num - 1); return true; } private static string Escape(string s) { return s.Replace("\\", "\\\\").Replace("\"", "\\\""); } private static string Unescape(string s) { return s.Replace("\\\"", "\"").Replace("\\\\", "\\"); } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class Patch_ZNet_Awake_RegisterKnownPlayersRpc { private static void Postfix() { KnownPlayersSync.RegisterRpcs(); } } internal static class KnownPlayersSync { private const string SyncRpcName = "CaptTerritory_KnownPlayersSync"; private const string RequestRpcName = "CaptTerritory_RequestKnownPlayers"; private static ZRoutedRpc s_registeredOn; internal static void RegisterRpcs() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != s_registeredOn) { instance.Register<ZPackage>("CaptTerritory_KnownPlayersSync", (Action<long, ZPackage>)RPC_ReceiveSync); instance.Register("CaptTerritory_RequestKnownPlayers", (Action<long>)RPC_HandleRequest); s_registeredOn = instance; KnownPlayersRegistry.Load(); if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { RequestFromServer(); } } } internal static void RequestFromServer() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && !((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { instance.InvokeRoutedRPC(instance.GetServerPeerID(), "CaptTerritory_RequestKnownPlayers", Array.Empty<object>()); } } internal static void BroadcastToAll() { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { SendSyncTo(ZRoutedRpc.Everybody); } } private static void RPC_HandleRequest(long sender) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { SendSyncTo(sender); } } private static void SendSyncTo(long target) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown ZRoutedRpc instance = ZRoutedRpc.instance; if (instance == null) { return; } Dictionary<long, string> all = KnownPlayersRegistry.GetAll(); ZPackage val = new ZPackage(); val.Write(all.Count); foreach (KeyValuePair<long, string> item in all) { val.Write(item.Key); val.Write(item.Value); } instance.InvokeRoutedRPC(target, "CaptTerritory_KnownPlayersSync", new object[1] { val }); } private static void RPC_ReceiveSync(long sender, ZPackage pkg) { if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()) { int num = pkg.ReadInt(); Dictionary<long, string> dictionary = new Dictionary<long, string>(num); for (int i = 0; i < num; i++) { long key = pkg.ReadLong(); string value = pkg.ReadString(); dictionary[key] = value; } KnownPlayersRegistry.ReplaceAll(dictionary); } } } public static class TerritoryLocalization { public static void Register() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "Korean"; localization.AddTranslation(ref text, new Dictionary<string, string> { ["territoryward_name"] = "영토 와드", ["territoryward_storage"] = "영토 와드 창고", ["territoryward_no_fuel"] = "연료 부족으로 영토 와드가 비활성화되었습니다!", ["territoryward_off_blocked"] = "비활성화된 영토 와드 구역에서는 사용할 수 없습니다!", ["territoryward_not_permitted"] = "영토 와드의 소유자나 허용된 사람만 사용할 수 있습니다!", ["territoryward_remove_creator_only"] = "영토 와드는 설치자 또는 관리자만 제거할 수 있습니다!", ["territoryward_join_blocked_while_active"] = "활성화된 영토 와드에는 가입할 수 없습니다! 비활성화 상태에서만 가입할 수 있습니다.", ["territoryward_join_blocked_while_active_hint"] = "활성화 중에는 가입할 수 없음 (비활성화 시 가입 가능)", ["territoryward_no_build"] = "영토 와드 구역 안에서만 건설할 수 있습니다!", ["territoryward_must_activate"] = "영토와드를 활성화 해야합니다!", ["territoryward_no_overlap"] = "다른 영토 와드 구역 안에서는 설치할 수 없습니다!", ["territoryward_fuel_hint"] = "연료 창고 열기", ["territoryward_disabled"] = "영토 와드 시스템이 비활성화되어 있습니다!", ["territoryward_limit_reached"] = "영토 와드 설치 한도를 초과했습니다!", ["territoryward_upgrade_hint_key"] = "영토 와드 업그레이드", ["territoryward_range_label"] = "범위", ["territoryward_fuel_label"] = "연료", ["territoryward_fuel_per_minutes"] = "$1분마다", ["territoryward_fuel_or"] = "또는", ["territoryward_upgrade_too_far"] = "영토 와드와 너무 멀리 떨어져 있습니다!", ["territoryward_upgrade_not_creator"] = "영토 와드를 설치한 사람만 업그레이드할 수 있습니다!", ["territoryward_intrusion_alert"] = "$1가 승인없이 영토에 침입했습니다.", ["territoryward_upgrade_success"] = "영토 와드가 업그레이드되었습니다!", ["territoryward_max_level"] = "이미 최대 레벨입니다!", ["territoryward_missing_fuel_suffix"] = " 부족!", ["territoryward_shield_hint_key"] = "영토 보호 활성화", ["territoryward_shield_deactivate_hint_key"] = "영토 보호 비활성화", ["territoryward_shield_active"] = "보호 중 — 남은 $1분", ["territoryward_shield_started"] = "영토 보호가 활성화되었습니다! (1시간)", ["territoryward_shield_stopped"] = "영토 보호가 비활성화되었습니다.", ["territoryward_shield_resumed"] = "남은 시간으로 영토 보호가 재개되었습니다! (아이템 소모 없음)", ["territoryward_shield_resume_hint"] = "재개 (아이템 소모 없음, 남은 $1분)", ["territoryward_shield_no_item"] = "슈트링 코어가 부족합니다!", ["territoryward_shield_ended_no_fuel"] = "슈르트링 코어가 부족하여 영토 보호가 종료되었습니다!", ["territoryward_shield_low_level"] = "Lv5 이상에서만 사용 가능합니다!", ["territoryward_rangering_hint_key"] = "범위 링 토글", ["territoryward_shield_hud"] = "[ 영토 보호 중 — $1분 남음 ]", ["territoryward_shield_hud_paused"] = "[ 영토 보호 일시정지 — 와드 비활성 (보관 $1분) ]", ["territoryward_shield_ward_off_hint"] = "와드가 비활성 상태입니다 (영토 보호 사용 불가)", ["territoryward_passive_shield_label"] = "보호막", ["territoryward_passive_shield_hud"] = "[ 보호막 $1 / $2 ]", ["territoryward_passive_shield_broken"] = "영토 보호막이 파괴되었습니다! 회복까지 기다리세요.", ["territoryward_intrusion_chat"] = "[영토 침입 경고] $1가 승인 없이 영토에 진입했습니다!", ["territoryward_status_enabled"] = "활성화", ["territoryward_status_disabled"] = "비활성화", ["territoryward_owner_label"] = "소유자", ["territoryward_permitted_label"] = "허용됨", ["territoryward_toggle_hint_key"] = "와드 활성화 / 비활성화", ["territoryward_member_leave_hint_key"] = "멤버 탈퇴", ["territoryward_member_join_hint_key"] = "멤버 가입", ["territoryward_material_label"] = "재료", ["territoryward_none"] = "없음", ["territoryward_intruder_label"] = "침입자", ["territoryward_whitelist_title"] = "[ 영토 와드 멤버 관리 ]", ["territoryward_known_members_label"] = "알려진 캐릭터 (클릭해서 추가/추방)", ["territoryward_online_tag"] = " (온라인)", ["territoryward_close_button"] = "닫기", ["territoryward_member_manage_hint_key"] = "온라인 멤버관리" }); text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { ["territoryward_name"] = "Territory Ward", ["territoryward_storage"] = "Territory Ward Storage", ["territoryward_no_fuel"] = "Territory Ward deactivated: out of fuel!", ["territoryward_off_blocked"] = "Cannot use items inside a deactivated Territory Ward!", ["territoryward_not_permitted"] = "Only the owner or permitted members can use this Territory Ward!", ["territoryward_remove_creator_only"] = "Only the creator or an admin can remove this Territory Ward!", ["territoryward_join_blocked_while_active"] = "Cannot join an active Territory Ward! You can only join while it is deactivated.", ["territoryward_join_blocked_while_active_hint"] = "Cannot join while active (join allowed when deactivated)", ["territoryward_no_build"] = "You can only build inside a Territory Ward!", ["territoryward_must_activate"] = "You must activate the Territory Ward!", ["territoryward_no_overlap"] = "Cannot place a Territory Ward inside another Territory Ward!", ["territoryward_fuel_hint"] = "Open Fuel Storage", ["territoryward_disabled"] = "Territory Ward system is disabled!", ["territoryward_limit_reached"] = "Territory Ward placement limit reached!", ["territoryward_upgrade_hint_key"] = "Upgrade Territory Ward", ["territoryward_range_label"] = "Range", ["territoryward_fuel_label"] = "Fuel", ["territoryward_fuel_per_minutes"] = "every $1 min", ["territoryward_fuel_or"] = "or", ["territoryward_upgrade_too_far"] = "You are too far from the Territory Ward!", ["territoryward_upgrade_not_creator"] = "Only the creator of this Territory Ward can upgrade it!", ["territoryward_intrusion_alert"] = "$1 has invaded the territory without permission!", ["territoryward_upgrade_success"] = "Territory Ward upgraded!", ["territoryward_max_level"] = "Already at max level!", ["territoryward_missing_fuel_suffix"] = " is missing!", ["territoryward_shield_hint_key"] = "Activate Territory Shield", ["territoryward_shield_deactivate_hint_key"] = "Deactivate Territory Shield", ["territoryward_shield_active"] = "Shield Active — $1 min remaining", ["territoryward_shield_started"] = "Territory Shield activated! (1 hour)", ["territoryward_shield_stopped"] = "Territory Shield deactivated.", ["territoryward_shield_resumed"] = "Territory Shield resumed with remaining time! (no item consumed)", ["territoryward_shield_resume_hint"] = "Resume (no item needed, $1 min left)", ["territoryward_shield_no_item"] = "Not enough Surtling Core!", ["territoryward_shield_ended_no_fuel"] = "Territory Shield ended: out of Surtling Core!", ["territoryward_shield_low_level"] = "Requires Lv5 or higher!", ["territoryward_rangering_hint_key"] = "Toggle Range Ring", ["territoryward_shield_hud"] = "[ Shield Active — $1 min remaining ]", ["territoryward_shield_hud_paused"] = "[ Shield Paused — Ward Disabled ($1 min banked) ]", ["territoryward_shield_ward_off_hint"] = "Ward is disabled (shield unavailable)", ["territoryward_passive_shield_label"] = "Shield", ["territoryward_passive_shield_hud"] = "[ Shield $1 / $2 ]", ["territoryward_passive_shield_broken"] = "The territory shield has been destroyed! Wait for it to regenerate.", ["territoryward_intrusion_chat"] = "[Intrusion Alert] $1 has entered the territory without permission!", ["territoryward_status_enabled"] = "Enabled", ["territoryward_status_disabled"] = "Disabled", ["territoryward_owner_label"] = "Owner", ["territoryward_permitted_label"] = "Permitted", ["territoryward_toggle_hint_key"] = "Toggle Ward On/Off", ["territoryward_member_leave_hint_key"] = "Leave Membership", ["territoryward_member_join_hint_key"] = "Join Membership", ["territoryward_material_label"] = "Materials", ["territoryward_none"] = "None", ["territoryward_intruder_label"] = "Intruder", ["territoryward_whitelist_title"] = "[ Territory Ward Member Management ]", ["territoryward_known_members_label"] = "Known Characters (click to add/kick)", ["territoryward_online_tag"] = " (Online)", ["territoryward_close_button"] = "Close", ["territoryward_member_manage_hint_key"] = "Manage Online Members" }); } public static void RefreshWardDescription() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = Localization.instance.Localize(TerritoryWardController.Resolve(TerritoryConfig.Lv1FuelA.Value, warnIfMissing: false) ?? "$item_wood"); string text2 = Localization.instance.Localize(TerritoryWardController.Resolve(TerritoryConfig.Lv1FuelB.Value, warnIfMissing: false) ?? "$item_resin"); float value = TerritoryConfig.Lv1Width.Value; float value2 = TerritoryConfig.Lv1Depth.Value; int value3 = TerritoryConfig.Lv1FuelAAmount.Value; int value4 = TerritoryConfig.Lv1FuelBAmount.Value; float value5 = TerritoryConfig.Lv1IntervalMinutes.Value; string text3 = "Korean"; localization.AddTranslation(ref text3, new Dictionary<string, string> { ["territoryward_desc"] = $"{value:0.#}x{value2:0.#}미터의 영토를 설정합니다.\n" + "ON 상태에서만 구역 안에서 건설하고 상호작용할 수 있습니다.\n" + $"연료: {text} {value3}개 + {text2} {value4}개 / {value5:0}분마다" }); text3 = "English"; localization.AddTranslation(ref text3, new Dictionary<string, string> { ["territoryward_desc"] = $"Sets a {value:0.#}x{value2:0.#}m territory.\n" + "Building and interaction only allowed when ON.\n" + $"Fuel: {text} x{value3} + {text2} x{value4} every {value5:0} min" }); } } [HarmonyPatch(typeof(SpawnSystem), "IsSpawnPointGood")] public static class Patch_SpawnSystem_IsSpawnPointGood_NoSpawnInWard { private static void Postfix(ref bool __result, ref Vector3 spawnPoint) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (__result && TerritoryWard.IsInsideActiveWard(spawnPoint)) { __result = false; } } } [HarmonyPatch(typeof(WearNTear), "ApplyDamage")] public static class Patch_WearNTear_ApplyDamage_PassiveShield { private static void Prefix(WearNTear __instance, ref float damage, HitData hitData) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (damage <= 0f) { return; } Character val = ((hitData != null) ? hitData.GetAttacker() : null); if (!((Object)(object)val == (Object)null) && val.IsMonsterFaction(Time.time)) { TerritoryWardController territoryWardController = TerritoryWardController.FindPassiveShieldZoneAt(((Component)__instance).transform.position); if (!((Object)(object)territoryWardController == (Object)null)) { territoryWardController.DrainPassiveShield(damage); damage = 0f; } } } } [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class Patch_Character_ApplyDamage_PassiveShield { private static void Prefix(Character __instance, HitData hit) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!(__instance is Player)) { return; } float totalDamage = hit.GetTotalDamage(); if (totalDamage <= 0f) { return; } Character attacker = hit.GetAttacker(); if (!((Object)(object)attacker == (Object)null) && attacker.IsMonsterFaction(Time.time)) { TerritoryWardController territoryWardController = TerritoryWardController.FindPassiveShieldZoneAt(((Component)__instance).transform.position); if (!((Object)(object)territoryWardController == (Object)null)) { territoryWardController.DrainPassiveShield(totalDamage); ((DamageTypes)(ref hit.m_damage)).Modify(0f); } } } } [HarmonyPatch(typeof(Projectile), "FixedUpdate")] public static class Patch_Projectile_FixedUpdate_PassiveShieldBlock { private static void Postfix(Projectile __instance) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || ((Object)(object)__instance.m_owner != (Object)null && __instance.m_owner.IsPlayer())) { return; } Vector3 position = ((Component)__instance).transform.position; foreach (PrivateArea s_ward in TerritoryWard.s_wards) { if (!s_ward.IsEnabled()) { continue; } TerritoryWardController component = ((Component)s_ward).GetComponent<TerritoryWardController>(); if ((Object)(object)component == (Object)null || (!component.IsShielded() && !component.HasPassiveShield()) || !component.IsPointInside(position) || component.IsPointInside(__instance.m_startPoint)) { continue; } if (!component.IsShielded() && (Object)(object)__instance.m_owner != (Object)null && __instance.m_owner.IsMonsterFaction(Time.time)) { component.DrainPassiveShield(((DamageTypes)(ref __instance.m_damage)).GetTotalDamage()); } __instance.OnHit((Collider)null, position, false, -((Component)__instance).transform.forward); ZNetScene.instance.Destroy(((Component)__instance).gameObject); break; } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] public static class Patch_Humanoid_StartAttack_ShieldSiege { private const float AttackReachMargin = 4f; private static void Postfix(Humanoid __instance, bool __result) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if (!__result || !((Character)__instance).IsMonsterFaction(Time.time) || TerritoryWard.s_wards.Count == 0) { return; } Vector3 position = ((Component)__instance).transform.position; foreach (PrivateArea s_ward in TerritoryWard.s_wards) { if (!s_ward.IsEnabled()) { continue; } TerritoryWardController component = ((Component)s_ward).GetComponent<TerritoryWardController>(); if (!((Object)(object)component == (Object)null) && !component.IsShielded() && component.HasPassiveShield() && !component.IsPointInside(position) && component.IsPointInside(position, 4f)) { ItemData currentWeapon = __instance.GetCurrentWeapon(); float num = ((currentWeapon != null) ? ((DamageTypes)(ref currentWeapon.m_shared.m_damages)).GetTotalDamage() : 0f); if (!(num <= 0f)) { component.DrainPassiveShield(num); break; } } } } } [HarmonyPatch(typeof(PrivateArea), "RPC_TogglePermitted")] public static class Patch_PrivateArea_RPC_TogglePermitted_AllowWhileEnabled { private static bool Prefix(PrivateArea __instance, long uid, long playerID, string name) { TerritoryWardController component = ((Component)__instance).GetComponent<TerritoryWardController>(); if ((Object)(object)component == (Object)null) { return true; } bool flag = __instance.m_nview.IsOwner(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[Territory] RPC_TogglePermitted: target={name}({playerID}) isOwner={flag}"); } if (!flag) { return false; } if (__instance.m_piece.GetCreator() != uid && __instance.IsEnabled()) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[Territory] RPC_TogglePermitted: non-creator self toggle blocked (ward enabled) target={name}({playerID})"); } return false; } if (__instance.IsPermitted(playerID)) { __instance.RemovePermitted(playerID); ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)$"[Territory] RPC_TogglePermitted: removed {name}({playerID})"); } } else { __instance.AddPermitted(playerID, name); ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogInfo((object)$"[Territory] RPC_TogglePermitted: added {name}({playerID})"); } } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { bool flag2 = KnownPlayersRegistry.RecordPlayer(playerID, name); ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)$"[Territory] RPC_TogglePermitted: RecordPlayer({name},{playerID}) recorded={flag2}"); } if (flag2) { KnownPlayersSync.BroadcastToAll(); } } return false; } } [BepInPlugin("KorCaptain_territorial_ward", "Captain Territorial", "1.0.85")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal const string UpgradeButtonName = "TerritorialWardUpgrade"; internal static ButtonConfig UpgradeButton; internal static ButtonConfig ShieldButton; internal static ButtonConfig RangeRingButton; internal static ManualLogSource Log; private readonly Harmony _harmony = new Harmony("KorCaptain.Captain_territorial"); private void Awake() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; TerritoryConfig.Init(((BaseUnityPlugin)this).Config); TerritoryLocalization.Register(); VFXManager.Initialize(); PrefabManager.OnVanillaPrefabsAvailable += TerritoryWard.Create; PrefabManager.OnVanillaPrefabsAvailable += TerritoryLocalization.RefreshWardDescription; UpgradeButton = new ButtonConfig { Name = "TerritorialWardUpgrade", Config = TerritoryConfig.UpgradeKey, HintToken = "$territoryward_upgrade_hint_key" }; InputManager.Instance.AddButton(((BaseUnityPlugin)this).Info.Metadata.GUID, UpgradeButton); ShieldButton = new ButtonConfig { Name = "TerritorialWardShield", Config = TerritoryConfig.ShieldKey, HintToken = "$territoryward_shield_hint_key" }; InputManager.Instance.AddButton(((BaseUnityPlugin)this).Info.Metadata.GUID, ShieldButton); RangeRingButton = new ButtonConfig { Name = "TerritorialWardRangeRing", Config = TerritoryConfig.RangeRingKey, HintToken = "$territoryward_rangering_hint_key" }; InputManager.Instance.AddButton(((BaseUnityPlugin)this).Info.Metadata.GUID, RangeRingButton); SynchronizationManager.OnConfigurationSynchronized += delegate(object _, ConfigurationSynchronizationEventArgs e) { if (e.InitialSynchronization) { TerritoryLocalization.RefreshWardDescription(); } }; _harmony.PatchAll(); ((MonoBehaviour)this).InvokeRepeating("ScanKnownPlayers", 5f, 5f); ((MonoBehaviour)this).InvokeRepeating("UpdateWardMapPins", 5f, 5f); PrintLoadedMessage(); } private void UpdateWardMapPins() { TerritoryWardMapPinManager.Update(); } private void ScanKnownPlayers() { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } bool flag = false; foreach (Player allPlayer in Player.GetAllPlayers()) { long playerID = allPlayer.GetPlayerID(); if (playerID != 0 && KnownPlayersRegistry.RecordPlayer(playerID, allPlayer.GetPlayerName())) { flag = true; } } if (flag) { KnownPlayersSync.BroadcastToAll(); } } private void PrintLoadedMessage() { string text = $"[Captain_territorial] Captain Territorial {((BaseUnityPlugin)this).Info.Metadata.Version} Loaded!"; try { Type type = typeof(BaseUnityPlugin).Assembly.GetType("BepInEx.ConsoleManager"); MethodInfo methodInfo = type?.GetMethod("SetConsoleColor", Binding