Decompiled source of ProtectiveWards v1.2.3
ProtectiveWards.dll
Decompiled 2 months 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.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using ServerSync; using SoftReferenceableAssets; using TMPro; using UnityEngine; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ProtectiveWards")] [assembly: AssemblyDescription("")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyProduct("ProtectiveWards")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f71912b8-9b1c-4181-911a-1550f4ec2889")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyCompany("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace ProtectiveWards { internal class FullProtection { [HarmonyPatch(typeof(Character), "AddFireDamage")] public static class Character_AddFireDamage_IndirectFireDamageProtection { private static void Prefix(Character __instance, ref float damage) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.boarsHensProtection.Value && __instance.IsTamed() && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { damage = 0f; } } } [HarmonyPatch(typeof(Character), "UpdateSmoke")] public static class Character_UpdateSmoke_IndirectSmokeDamageProtection { private static void Prefix(Character __instance, ref float dt) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.boarsHensProtection.Value && __instance.IsTamed() && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { dt = 0f; } } } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] public static class WearNTear_UpdateWear_RainProtection { private static void Prefix(WearNTear __instance, ZNetView ___m_nview, ref bool ___m_noRoofWear, ref bool __state) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.wardRainProtection.Value && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __state = ___m_noRoofWear; ___m_noRoofWear = false; } } private static void Postfix(ref bool ___m_noRoofWear, bool __state) { if (ProtectiveWards.modEnabled.Value && ProtectiveWards.wardRainProtection.Value && __state) { ___m_noRoofWear = __state; } } } [HarmonyPatch(typeof(Ship), "UpdateUpsideDmg")] public static class Ship_UpdateUpsideDmg_PreventShipDamage { private static bool Prefix(Ship __instance) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.modEnabled.Value) { return true; } if (ProtectiveWards.wardShipProtection.Value == ProtectiveWards.ShipDamageType.Off) { return true; } return !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position); } } [HarmonyPatch(typeof(Ship), "UpdateWaterForce")] public static class Ship_UpdateWaterForce_PreventShipDamage { private static void Prefix(Ship __instance, ref float ___m_waterImpactDamage, ref float __state) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.wardShipProtection.Value != 0 && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { __state = ___m_waterImpactDamage; ___m_waterImpactDamage = 0f; } } private static void Postfix(Ship __instance, ref float ___m_waterImpactDamage, float __state) { if (__state != 0f) { ___m_waterImpactDamage = __state; } } } [HarmonyPatch(typeof(Trap), "OnTriggerEnter")] private static class Trap_OnTriggerEnter_TrapProtection { private static bool Prefix(Trap __instance, Collider collider) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.modEnabled.Value) { return true; } if (!ProtectiveWards.wardTrapProtection.Value) { return true; } if ((Object)(object)((Component)collider).GetComponentInParent<Player>() == (Object)null) { return true; } return !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true); } } [HarmonyPatch(typeof(Destructible), "Damage")] public static class Destructible_Damage_PlantProtection { private static void ModifyHitDamage(HitData hit, float value) { ((DamageTypes)(ref hit.m_damage)).Modify(Math.Max(value, 0f)); } private static void Prefix(Destructible __instance, ZNetView ___m_nview, bool ___m_destroyed, HitData hit) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.modEnabled.Value || !ProtectiveWards.wardPlantProtection.Value || !___m_nview.IsValid() || !___m_nview.IsOwner() || ___m_destroyed || (int)__instance.GetDestructibleType() != 1 || __instance.m_health != 1f || !hit.HaveAttacker() || !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, out var area, checkCache: true)) { return; } Pickable val = default(Pickable); if ((Object)(object)((Component)__instance).GetComponent<Plant>() != (Object)null) { ModifyHitDamage(hit, 0f); area.FlashShield(false); } else if (((Component)__instance).TryGetComponent<Pickable>(ref val)) { GameObject itemPrefab = val.m_itemPrefab; SharedData val2 = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData.m_shared); if (ProtectiveWards._wardPlantProtectionList.Contains(val2.m_name.ToLower())) { ModifyHitDamage(hit, 0f); area.FlashShield(false); } } } } } internal class Multipliers { [HarmonyPatch(typeof(SEMan), "ModifyFallDamage")] public static class SEMan_ModifyFallDamage_FallDamageMultiplier { private static void Postfix(Character ___m_character, ZNetView ___m_nview, ref float damage) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && !((Object)(object)___m_nview == (Object)null) && ProtectiveWards.InsideEnabledPlayersArea(((Component)___m_character).transform.position)) { damage *= Math.Max(ProtectiveWards.fallDamageTakenMultiplier.Value, 0f); } } } [HarmonyPatch(typeof(Character), "Damage")] public static class Character_Damage_DamageMultipliers { private static void Prefix(Character __instance, ref HitData hit, ZNetView ___m_nview) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.modEnabled.Value || (Object)(object)___m_nview == (Object)null || !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, out var area) || (hit.HaveAttacker() && hit.GetAttacker().IsBoss())) { return; } if (__instance.IsPlayer()) { ModifyHitDamage(ref hit, ProtectiveWards.playerDamageTakenMultiplier.Value); } else if (__instance.IsTamed()) { ModifyHitDamage(ref hit, ProtectiveWards.tamedDamageTakenMultiplier.Value); if (ProtectiveWards.boarsHensProtection.Value && ProtectiveWards._boarsHensProtectionGroupList.Contains(__instance.m_group.ToLower()) && (!hit.HaveAttacker() || !hit.GetAttacker().IsPlayer())) { if (hit.GetTotalDamage() != hit.m_damage.m_fire) { area.FlashShield(false); } ModifyHitDamage(ref hit, 0f); } } else { ModifyHitDamage(ref hit, ProtectiveWards.playerDamageDealtMultiplier.Value); } } } [HarmonyPatch(typeof(WearNTear), "Damage")] public static class WearNTear_Damage_DamageTakenMultiplier { private static void Prefix(WearNTear __instance, ref HitData hit, ZNetView ___m_nview) { //IL_0026: 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_0055: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 if (ProtectiveWards.modEnabled.Value && !((Object)(object)___m_nview == (Object)null) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { if (ProtectiveWards.fireplaceProtection.Value && (int)hit.m_hitType == 14 && (Object)(object)((Component)__instance).GetComponent<Fireplace>() != (Object)null) { ModifyHitDamage(ref hit, 0f); } else if (ProtectiveWards.wardShipProtection.Value == ProtectiveWards.ShipDamageType.AnyButPlayerDamage && (int)hit.m_hitType != 2 && (Object)(object)((Component)__instance).GetComponent<Ship>() != (Object)null) { ModifyHitDamage(ref hit, 0f); } else if (ProtectiveWards.wardShipProtection.Value == ProtectiveWards.ShipDamageType.AnyDamage && (Object)(object)((Component)__instance).GetComponent<Ship>() != (Object)null) { ModifyHitDamage(ref hit, 0f); } else if ((Object)(object)((Component)__instance).GetComponent<Piece>() != (Object)null && (!hit.HaveAttacker() || !hit.GetAttacker().IsBoss())) { ModifyHitDamage(ref hit, ProtectiveWards.structureDamageTakenMultiplier.Value); } } } } [HarmonyPatch(typeof(Player), "UpdateFood")] public static class Player_UpdateFood_FoodDrainMultiplier { private static void Prefix(Player __instance, float dt, bool forceUpdate) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.modEnabled.Value || ProtectiveWards.foodDrainMultiplier.Value == 1f || (Object)(object)__instance == (Object)null || !(dt + __instance.m_foodUpdateTimer >= 1f || forceUpdate) || !ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { return; } foreach (Food food in __instance.m_foods) { food.m_time += 1f - Math.Max(0f, ProtectiveWards.foodDrainMultiplier.Value); } } } [HarmonyPatch(typeof(Player), "UseStamina")] public static class Player_UseStamina_StaminaDrainMultiplier { private static void Prefix(Player __instance, ref float v) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.staminaDrainMultiplier.Value != 1f && !((Object)(object)__instance == (Object)null) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { v *= Math.Max(0f, ProtectiveWards.staminaDrainMultiplier.Value); } } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] public static class Player_UseStamina_HammerDurabilityDrainMultiplier { private static void Prefix(Player __instance, ref float __state) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.hammerDurabilityDrainMultiplier.Value != 1f && !((Object)(object)__instance == (Object)null) && ((Character)__instance).InPlaceMode() && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { ItemData rightItem = ((Humanoid)__instance).GetRightItem(); __state = rightItem.m_shared.m_useDurabilityDrain; SharedData shared = rightItem.m_shared; shared.m_useDurabilityDrain *= Math.Max(0f, ProtectiveWards.hammerDurabilityDrainMultiplier.Value); } } private static void Postfix(Player __instance, float __state) { if (__state != 0f) { ItemData rightItem = ((Humanoid)__instance).GetRightItem(); rightItem.m_shared.m_useDurabilityDrain = __state; } } } [HarmonyPatch(typeof(Player), "Repair")] public static class Player_Repair_HammerDurabilityDrainMultiplier { private static void Prefix(Player __instance, ItemData toolItem, ref float __state) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.hammerDurabilityDrainMultiplier.Value != 1f && !((Object)(object)__instance == (Object)null) && ((Character)__instance).InPlaceMode() && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position)) { __state = toolItem.m_shared.m_useDurabilityDrain; SharedData shared = toolItem.m_shared; shared.m_useDurabilityDrain *= Math.Max(0f, ProtectiveWards.hammerDurabilityDrainMultiplier.Value); } } private static void Postfix(Player __instance, ItemData toolItem, float __state) { if (__state != 0f) { toolItem.m_shared.m_useDurabilityDrain = __state; } } } [HarmonyPatch(typeof(Skills), "LowerAllSkills")] private static class Skills_OnDeath_SkillDrainMultiplier { private static void Prefix(ref float factor, Player ___m_player) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && !((Object)(object)___m_player == (Object)null) && ProtectiveWards.InsideEnabledPlayersArea(((Component)___m_player).transform.position)) { factor *= Math.Max(0f, ProtectiveWards.skillsDrainMultiplier.Value); } } } [HarmonyPatch(typeof(Fireplace), "GetTimeSinceLastUpdate")] private static class Fireplace_GetTimeSinceLastUpdate_FireplaceDrainMultiplier { private static void Postfix(Fireplace __instance, ref double __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.fireplaceDrainMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, ProtectiveWards.fireplaceDrainMultiplier.Value); } } } [HarmonyPatch(typeof(Smelter), "GetDeltaTime")] private static class Smelter_GetDeltaTime_FireplaceDrainMultiplier_SmeltingSpeedMultiplier { private static void Postfix(Smelter __instance, ref double __result) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value) { float num = ((__instance.m_name == "$piece_bathtub") ? ProtectiveWards.fireplaceDrainMultiplier.Value : ProtectiveWards.smeltingSpeedMultiplier.Value); if (num != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, num); } } } } [HarmonyPatch(typeof(CookingStation), "GetDeltaTime")] private static class CookingStation_GetDeltaTime_CookingSpeedMultiplier { private static void Postfix(Smelter __instance, ref float __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.cookingSpeedMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, ProtectiveWards.cookingSpeedMultiplier.Value); } } } [HarmonyPatch(typeof(CookingStation), "UpdateFuel")] private static class CookingStation_UpdateFuel_FireplaceDrainMultiplier { private static void Prefix(Smelter __instance, ref float dt, ref float __state) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && (ProtectiveWards.fireplaceDrainMultiplier.Value != 1f || ProtectiveWards.cookingSpeedMultiplier.Value != 1f) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __state = dt; dt *= Math.Max(0f, ProtectiveWards.fireplaceDrainMultiplier.Value); if (ProtectiveWards.cookingSpeedMultiplier.Value > 0f) { dt /= ProtectiveWards.cookingSpeedMultiplier.Value; } } } private static void Postfix(Smelter __instance, ref float dt, float __state) { if (__state != 0f) { dt = __state; } } } [HarmonyPatch(typeof(Fermenter), "GetFermentationTime")] private static class Fermenter_GetFermentationTime_FermentingSpeedMultiplier { private static void Postfix(Fermenter __instance, ref double __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.fermentingSpeedMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, ProtectiveWards.fermentingSpeedMultiplier.Value); } } } [HarmonyPatch(typeof(SapCollector), "GetTimeSinceLastUpdate")] private static class SapCollector_GetTimeSinceLastUpdate_SapCollectingSpeedMultiplier { private static void Postfix(SapCollector __instance, ref float __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.sapCollectingSpeedMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __result *= Math.Max(0f, ProtectiveWards.sapCollectingSpeedMultiplier.Value); } } } [HarmonyPatch(typeof(Turret), "IsCoolingDown")] private static class Turret_IsCoolingDown_turretFireRateMultiplier { private static void Prefix(Turret __instance, ref float ___m_attackCooldown, ref float __state) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.turretFireRateMultiplier.Value != 1f && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { __state = ___m_attackCooldown; ___m_attackCooldown *= Math.Max(0f, ProtectiveWards.turretFireRateMultiplier.Value); } } private static void Postfix(ref float ___m_attackCooldown, float __state) { if (ProtectiveWards.modEnabled.Value && __state > 0f) { ___m_attackCooldown = __state; } } } private static void ModifyHitDamage(ref HitData hit, float value) { ((DamageTypes)(ref hit.m_damage)).Modify(Math.Max(value, 0f)); } } internal class RaidProtection { [HarmonyPatch(typeof(Player), "UpdateBaseValue")] public static class Player_UpdateBaseValue_SittingRaidProtection { public static void Postfix(Player __instance, float ___m_baseValueUpdateTimer, ref int ___m_baseValue, ZNetView ___m_nview) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.sittingRaidProtection.Value && ___m_baseValueUpdateTimer == 0f && ___m_baseValue >= 3 && ((Character)__instance).IsSitting() && __instance.m_attached && ((Character)__instance).m_seman.HaveStatusEffect(SEMan.s_statusEffectCampFire) && ProtectiveWards.InsideEnabledPlayersArea(((Component)__instance).transform.position, checkCache: true)) { ___m_baseValue = ProtectiveWards.baseValueProtected; ZNet.instance.m_serverSyncedPlayerData["baseValue"] = ___m_baseValue.ToString(); ___m_nview.GetZDO().Set(ZDOVars.s_baseValue, ___m_baseValue, false); } } } [HarmonyPatch(typeof(RandEventSystem), "CheckBase")] public static class RandEventSystem_CheckBase_SittingRaidProtection { public static void Postfix(PlayerEventData player, ref bool __result) { //IL_0027: 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_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) if (ProtectiveWards.modEnabled.Value && ProtectiveWards.sittingRaidProtection.Value && __result && player.baseValue == ProtectiveWards.baseValueProtected) { ProtectiveWards.LogInfo($"Player at {player.position.x} {player.position.z} is in raid protected state."); __result = false; } } } } internal static class WardOfferings { [HarmonyPatch(typeof(PrivateArea), "UseItem")] public static class PrivateArea_UseItem_Offerings { private static void Postfix(PrivateArea __instance, Humanoid user, ItemData item, ref bool __result) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Invalid comparison between Unknown and I4 //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Invalid comparison between Unknown and I4 if (!__instance.IsEnabled()) { ProtectiveWards.LogInfo("Ward disabled"); return; } if (!__instance.HaveLocalAccess()) { ProtectiveWards.LogInfo("No access"); return; } Player val = (Player)(object)((user is Player) ? user : null); if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer) { ProtectiveWards.LogInfo("UseItem user not a player"); return; } ProtectiveWards.LogInfo($"{val.GetPlayerName()} used {item.m_shared.m_name} on {__instance.m_nview.GetZDO()}"); bool flag = item.m_shared.m_name == "$item_blackcore" && ProtectiveWards.offeringAugmenting.Value; bool flag2 = flag || (item.m_shared.m_name == "$item_surtlingcore" && ProtectiveWards.offeringActiveRepair.Value); bool flag3 = (ProtectiveWards.offeringFood.Value || ProtectiveWards.offeringMead.Value) && (int)item.m_shared.m_itemType == 2; bool flag4 = ProtectiveWards.offeringThundertone.Value && item.m_shared.m_name == "$item_thunderstone"; bool flag5 = ProtectiveWards.offeringTrophy.Value && (int)item.m_shared.m_itemType == 13; bool flag6 = ProtectiveWards.offeringEitr.Value && item.m_shared.m_name == "$item_eitr"; bool flag7 = (ProtectiveWards.offeringYmirRemains.Value && item.m_shared.m_name == "$item_ymirremains") || flag6; bool flag8 = item.m_shared.m_name == "$item_dragonegg" && ZoneSystem.instance.GetGlobalKey((GlobalKeys)33); bool flag9 = ProtectiveWards.offeringTaxi.Value && (item.m_shared.m_name == "$item_coins" || IsBossTrophy(item.m_shared.m_name) || IsItemForHildirTravel(item.m_shared.m_name) || IsItemForBogWitchTravel(item.m_shared.m_name) || item.m_shared.m_name == "$item_chest_hildir1" || item.m_shared.m_name == "$item_chest_hildir2" || item.m_shared.m_name == "$item_chest_hildir3"); if (flag2 || flag3 || flag4 || flag5 || flag7 || flag8 || flag9) { if (flag2) { RepairNearestStructures(flag, __instance, val, item); } if (flag3) { ApplyConsumableEffectToNearestPlayers(__instance, item, val); } if (flag4) { ApplyThunderstrikeOnNearbyEnemies(__instance, item, val); } if (flag5) { ApplyTrophyEffectOnNearbyEnemies(__instance, item, val); } if (flag7) { ApplyInstantGrowthEffectOnNearbyPlants(__instance, item, val, !flag6); } if (flag8) { ApplyModerPowerEffectToNearbyPlayers(__instance, item, val); } if (flag9) { TaxiToLocation(item, val); } __result = true; } } } [HarmonyPatch(typeof(Player), "SetIntro")] public static class Player_SetIntro_Taxi { private static void Postfix(Player __instance) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (ProtectiveWards.modEnabled.Value && !((Character)__instance).InIntro()) { if (ProtectiveWards.taxiReturnBack && ProtectiveWards.canTravel) { ProtectiveWards.isTravelingPlayer = __instance; ((MonoBehaviour)__instance).StartCoroutine(ReturnPlayerToPosition(__instance, ProtectiveWards.taxiPlayerPositionToReturn, 120)); } else { ProtectiveWards.isTravelingPlayer = null; } } } } [HarmonyPatch(typeof(Valkyrie), "Awake")] public static class Valkyrie_Awake_Taxi { private static bool Prefix(Valkyrie __instance) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) if (!ProtectiveWards.modEnabled.Value) { return true; } if (!ProtectiveWards.offeringTaxi.Value) { return true; } if ((Object)(object)ProtectiveWards.isTravelingPlayer == (Object)null) { return true; } Valkyrie.m_instance = __instance; __instance.m_nview = ((Component)__instance).GetComponent<ZNetView>(); __instance.m_animator = ((Component)__instance).GetComponentInChildren<Animator>(); if (!__instance.m_nview.IsOwner()) { ((Behaviour)__instance).enabled = false; return false; } __instance.m_startAltitude = 30f; __instance.m_textDuration = 0f; __instance.m_descentAltitude = 150f; __instance.m_attachOffset = new Vector3(-0.1f, 1.5f, 0.1f); __instance.m_targetPoint = ProtectiveWards.taxiTargetPosition + new Vector3(0f, __instance.m_dropHeight, 0f); Vector3 position = ((Component)ProtectiveWards.isTravelingPlayer).transform.position; position.y += __instance.m_startAltitude; float num = (__instance.m_startDistance = Vector3.Distance(__instance.m_targetPoint, position)); __instance.m_startDescentDistance = Math.Min(200f, num / 5f); __instance.m_speed = Math.Max(Math.Min(num / 90f, Math.Min(30f, ProtectiveWards.maxTaxiSpeed.Value)), 10f); if (__instance.m_speed <= 15f) { EnvMan.instance.m_introEnvironment = EnvMan.instance.m_currentEnv.m_name; } else { EnvMan.instance.m_introEnvironment = "ThunderStorm"; } ProtectiveWards.isTravelingPlayer.m_intro = true; ((Component)__instance).transform.position = position; float num2 = Utils.DistanceXZ(__instance.m_targetPoint, ((Component)__instance).transform.position); float num3 = Math.Max(__instance.m_descentAltitude / num2, Math.Min(__instance.m_descentAltitude * 2f / num2, 0.2f)); __instance.m_descentStart = Vector3.Lerp(__instance.m_targetPoint, ((Component)__instance).transform.position, num3); __instance.m_descentStart.y = __instance.m_descentAltitude; Vector3 val = __instance.m_targetPoint - __instance.m_descentStart; val.y = 0f; ((Vector3)(ref val)).Normalize(); __instance.m_flyAwayPoint = __instance.m_targetPoint + val * __instance.m_startDescentDistance; __instance.m_flyAwayPoint.y += 100f; __instance.SyncPlayer(true); Vector3 val2 = ((Component)__instance).transform.position; string? text = ((object)(Vector3)(ref val2)).ToString(); val2 = ZNet.instance.GetReferencePosition(); ProtectiveWards.LogInfo("Setting up valkyrie " + text + " " + ((object)(Vector3)(ref val2)).ToString()); return false; } } [HarmonyPatch(typeof(Valkyrie), "LateUpdate")] public static class Valkyrie_LateUpdate_Taxi { private static void Prefix(Valkyrie __instance) { if (ProtectiveWards.modEnabled.Value && ProtectiveWards.offeringTaxi.Value && ((ZInput.GetButton("Use") && ZInput.GetButton("AltPlace")) || (ZInput.GetButton("JoyUse") && ZInput.GetButton("JoyAltPlace")))) { __instance.DropPlayer(false); } } } [HarmonyPatch(typeof(Valkyrie), "DropPlayer")] public static class Valkyrie_DropPlayer_Taxi { private static void Postfix() { if (ProtectiveWards.modEnabled.Value && ProtectiveWards.offeringTaxi.Value) { ProtectiveWards.playerDropped = true; if (!((Character)Player.m_localPlayer).m_seman.HaveStatusEffect(slowFallHash)) { ProtectiveWards.castSlowFall = true; ((Character)Player.m_localPlayer).m_seman.AddStatusEffect(slowFallHash, false, 0, 0f); ProtectiveWards.LogInfo("Cast slow fall"); } } } } [HarmonyPatch(typeof(Player), "Update")] public static class Player_Update_Taxi { private static void Postfix(Player __instance) { if (ProtectiveWards.modEnabled.Value && ProtectiveWards.offeringTaxi.Value && !((Object)(object)Player.m_localPlayer != (Object)(object)__instance) && ProtectiveWards.playerDropped && ProtectiveWards.castSlowFall && (((Character)__instance).IsOnGround() || ((Character)__instance).IsSwimming())) { ProtectiveWards.castSlowFall = false; ProtectiveWards.playerDropped = false; if (((Character)__instance).m_seman.HaveStatusEffect(slowFallHash)) { ((Character)__instance).m_seman.RemoveStatusEffect(slowFallHash, true); } ProtectiveWards.LogInfo("Remove slow fall"); } } } [HarmonyPatch(typeof(Valkyrie), "OnDestroy")] public static class Valkyrie_OnDestroy_Taxi { private static void Postfix() { if (ProtectiveWards.modEnabled.Value) { ProtectiveWards.canTravel = true; } } } [HarmonyPatch(typeof(ZoneSystem), "Start")] public static class ZoneSystem_Start_Taxi { private static void Postfix() { if (ProtectiveWards.modEnabled.Value) { RegisterRPCs(); } } } internal static int slowFallHash = StringExtensionMethods.GetStableHashCode("SlowFall"); internal static int moderPowerHash = StringExtensionMethods.GetStableHashCode("GP_Moder"); public static IEnumerator PassiveHealingEffect(PrivateArea ward, float amount, int seconds) { while (true) { if ((Object)(object)ward == (Object)null) { yield break; } if (Game.IsPaused()) { yield return (object)new WaitForSeconds(2f); } if (!ProtectiveWards.wardIsHealing.TryGetValue(ward, out var secondsLeft)) { yield break; } if (secondsLeft <= 0) { break; } ProtectiveWards.wardIsHealing[ward] -= seconds; List<Character> characters = new List<Character>(); CollectionExtensions.Do<PrivateArea>(ProtectiveWards.ConnectedAreas(ward), (Action<PrivateArea>)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Character.GetCharactersInRange(((Component)area).transform.position, area.m_radius, characters); }); CollectionExtensions.DoIf<Character>((IEnumerable<Character>)characters.ToHashSet(), (Func<Character, bool>)((Character character) => character.IsTamed() || character.IsPlayer()), (Action<Character>)delegate(Character character) { character.Heal(amount * (float)seconds, true); }); yield return (object)new WaitForSecondsRealtime((float)seconds); } ProtectiveWards.wardIsHealing.Remove(ward); ProtectiveWards.LogInfo("Passive healing stopped"); } public static IEnumerator LightningStrikeEffect(PrivateArea ward) { if (!((Object)(object)ward == (Object)null)) { List<Player> players = new List<Player>(); CollectionExtensions.Do<PrivateArea>(ProtectiveWards.ConnectedAreas(ward), (Action<PrivateArea>)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Player.GetPlayersInRange(((Component)area).transform.position, area.m_radius, players); }); CollectionExtensions.Do<Player>((IEnumerable<Player>)players.ToHashSet(), (Action<Player>)delegate(Player player) { //IL_000b: 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) ProtectiveWards.preLightning.Create(((Component)player).transform.position, ((Component)player).transform.rotation, (Transform)null, 1f, -1); }); ProtectiveWards.LogInfo("Thor is preparing his strike"); yield return (object)new WaitForSeconds(Random.Range(5f, 7f)); if (Game.IsPaused()) { yield return (object)new WaitForSeconds(1f); } List<Character> characters = new List<Character>(); CollectionExtensions.Do<PrivateArea>(ProtectiveWards.ConnectedAreas(ward), (Action<PrivateArea>)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Character.GetCharactersInRange(((Component)area).transform.position, area.m_radius, characters); }); CollectionExtensions.DoIf<Character>((IEnumerable<Character>)characters.ToHashSet(), (Func<Character, bool>)((Character character) => character.IsMonsterFaction(Time.time)), (Action<Character>)delegate(Character character) { //IL_000b: 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) Object.Instantiate<GameObject>(ProtectiveWards.lightningAOE, ((Component)character).transform.position, ((Component)character).transform.rotation); }); } } public static IEnumerator InstantGrowthEffect(PrivateArea ward, List<Plant> plants) { if ((Object)(object)ward == (Object)null) { yield break; } ProtectiveWards.LogInfo("Instant growth started"); yield return (object)new WaitForSeconds(1f); foreach (Plant plant in plants.ToHashSet()) { if (Object.op_Implicit((Object)(object)plant) && !((Object)(object)plant.m_nview == (Object)null) && plant.m_nview.IsValid() && plant.m_nview.IsOwner()) { if ((int)plant.m_status > 0) { plant.UpdateHealth(0.0); } plant.Grow(); yield return (object)new WaitForSeconds(0.25f); } } ProtectiveWards.LogInfo("Instant growth ended"); } public static IEnumerator ReturnPlayerToPosition(Player player, Vector3 position, int seconds) { //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) if (!((Object)(object)player == (Object)null)) { ProtectiveWards.canTravel = false; ProtectiveWards.LogInfo("Timer of player returnal started"); for (int i = seconds; i >= 0; i--) { ((Character)player).Message((MessageType)((i > 15) ? 1 : 2), Localization.instance.Localize("$pw_msg_travel_back", new string[1] { TimeSpan.FromSeconds(i).ToString("m\\:ss") }), 0, (Sprite)null); yield return (object)new WaitForSeconds(1f); } ProtectiveWards.LogInfo("Timer of player returnal ended"); ((MonoBehaviour)player).StartCoroutine(TaxiToPosition(player, position)); } } private static void RepairNearestStructures(bool augment, PrivateArea ward, Player initiator, ItemData item) { //IL_00a4: 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) int num = 0; int num2 = 0; List<Piece> pieces = new List<Piece>(); CollectionExtensions.Do<PrivateArea>(ProtectiveWards.ConnectedAreas(ward), (Action<PrivateArea>)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Piece.GetAllPiecesInRadius(((Component)area).transform.position, area.m_radius, pieces); }); WearNTear val = default(WearNTear); foreach (Piece item2 in pieces.Where((Piece piece) => piece.IsPlacedByPlayer())) { if (((Component)item2).TryGetComponent<WearNTear>(ref val)) { if (val.Repair()) { num++; item2.m_placeEffect.Create(((Component)item2).transform.position, ((Component)item2).transform.rotation, (Transform)null, 1f, -1); } if (augment && (Object)(object)val.m_nview != (Object)null && val.m_nview.IsValid() && val.m_nview.IsOwner() && val.m_nview.GetZDO().GetFloat(ZDOVars.s_health, val.m_health) < val.m_health * 2f) { val.m_nview.GetZDO().Set(ZDOVars.s_health, val.m_health * 2f); val.m_nview.InvokeRPC(ZNetView.Everybody, "WNTHealthChanged", new object[1] { val.m_health * 2f }); num2++; } } } if (num + num2 > 0) { ((Humanoid)initiator).GetInventory().RemoveOneItem(item); } if (num2 > 0) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_offerdone"), 0, (Sprite)null); if (num > 0) { ((Character)initiator).Message((MessageType)1, Localization.instance.Localize("$msg_repaired", new string[1] { num.ToString() }), 0, (Sprite)null); } } else if (num > 0) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_repaired", new string[1] { num.ToString() }), 0, (Sprite)null); } else if (augment) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_cantoffer"), 0, (Sprite)null); } else { string text = Localization.instance.Localize("$msg_doesnotneedrepair"); ((Character)initiator).Message((MessageType)2, char.ToUpper(text[0]) + text.Substring(1), 0, (Sprite)null); } } private static void GetPlantsInRange(Vector3 point, float radius, List<Plant> plants, bool growableOnly) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 List<SlowUpdate> allInstaces = SlowUpdate.GetAllInstaces(); float num = radius * radius; Plant val = default(Plant); foreach (SlowUpdate item in allInstaces) { if (((Component)item).TryGetComponent<Plant>(ref val) && Utils.DistanceSqr(((Component)item).transform.position, point) < num && val.m_nview.IsOwner() && (!growableOnly || (int)val.m_status == 0)) { plants.Add(val); } } } private static void ApplyTrophyEffectOnNearbyEnemies(PrivateArea ward, ItemData item, Player initiator) { //IL_0093: 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_010c: Unknown result type (might be due to invalid IL or missing references) ProtectiveWards.trophyTargets = ((IEnumerable<Turret>)Resources.FindObjectsOfTypeAll<Turret>()).FirstOrDefault((Func<Turret, bool>)((Turret ws) => ((Object)ws).name == "piece_turret"))?.m_configTargets; if (ProtectiveWards.trophyTargets == null) { return; } bool flag = false; foreach (TrophyTarget item2 in ProtectiveWards.trophyTargets.Where((TrophyTarget configTarget) => item.m_shared.m_name == configTarget.m_item.m_itemData.m_shared.m_name)) { List<Character> characters = new List<Character>(); CollectionExtensions.Do<PrivateArea>(ProtectiveWards.ConnectedAreas(ward), (Action<PrivateArea>)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Character.GetCharactersInRange(((Component)area).transform.position, area.m_radius, characters); }); foreach (Character item3 in from character in characters.ToHashSet() where character.IsMonsterFaction(Time.time) select character) { foreach (Character target in item2.m_targets) { if (item3.m_name == target.m_name) { item3.SetHealth(0f); flag = true; } } } } if (flag) { ((Humanoid)initiator).GetInventory().RemoveOneItem(item); ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_offerdone"), 0, (Sprite)null); } else { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_offerwrong"), 0, (Sprite)null); } } private static void ApplyThunderstrikeOnNearbyEnemies(PrivateArea ward, ItemData item, Player initiator) { Incinerator val = Resources.FindObjectsOfTypeAll<Incinerator>().FirstOrDefault(); ProtectiveWards.lightningAOE = val.m_lightingAOEs; ProtectiveWards.preLightning = val.m_leverEffects; ((MonoBehaviour)ProtectiveWards.instance).StartCoroutine(LightningStrikeEffect(ward)); ((Humanoid)initiator).GetInventory().RemoveOneItem(item); ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$piece_incinerator_conversion"), 0, (Sprite)null); } private static void ApplyConsumableEffectToNearestPlayers(PrivateArea ward, ItemData item, Player initiator) { if (item.m_shared.m_food > 0f) { if (ProtectiveWards.wardIsHealing.ContainsKey(ward)) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_offerwrong"), 0, (Sprite)null); return; } ProtectiveWards.wardIsHealing.Add(ward, 180); ((MonoBehaviour)ProtectiveWards.instance).StartCoroutine(PassiveHealingEffect(ward, item.m_shared.m_foodRegen / 2f, 1)); ProtectiveWards.LogInfo("Passive healing begins"); ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_consumed: " + item.m_shared.m_name), 0, (Sprite)null); ((Humanoid)initiator).GetInventory().RemoveOneItem(item); } else { if (!Object.op_Implicit((Object)(object)item.m_shared.m_consumeStatusEffect)) { return; } ProtectiveWards.LogInfo("Consumable effect offered"); List<Player> players = new List<Player>(); CollectionExtensions.Do<PrivateArea>(ProtectiveWards.ConnectedAreas(ward), (Action<PrivateArea>)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Player.GetPlayersInRange(((Component)area).transform.position, area.m_radius, players); }); bool flag = false; foreach (Player item2 in from player in players.ToHashSet() where ((Humanoid)player).CanConsumeItem(item, false) select player) { ((Character)item2).m_seman.AddStatusEffect(item.m_shared.m_consumeStatusEffect, true, 0, 0f); flag = true; } if (!flag) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_cantoffer"), 0, (Sprite)null); return; } ((Humanoid)initiator).GetInventory().RemoveOneItem(item); ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_offerdone"), 0, (Sprite)null); } } private static void ApplyInstantGrowthEffectOnNearbyPlants(PrivateArea ward, ItemData item, Player initiator, bool growableOnly = true) { List<Plant> plants = new List<Plant>(); CollectionExtensions.Do<PrivateArea>(ProtectiveWards.ConnectedAreas(ward), (Action<PrivateArea>)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) GetPlantsInRange(((Component)area).transform.position, area.m_radius, plants, growableOnly); }); if (plants.Count == 0) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_cantoffer"), 0, (Sprite)null); return; } Inventory inventory = ((Humanoid)initiator).GetInventory(); if (item.m_shared.m_name == "$item_eitr" && inventory.CountItems("$item_eitr", -1, true) < 5) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_incompleteoffering"), 0, (Sprite)null); return; } ((MonoBehaviour)ward).StartCoroutine(InstantGrowthEffect(ward, plants)); if (item.m_shared.m_name == "$item_eitr") { ((Humanoid)initiator).GetInventory().RemoveItem("$item_eitr", 5, -1, true); ProtectiveWards.LogInfo("Offered " + item.m_shared.m_name + " x5"); } else { ((Humanoid)initiator).GetInventory().RemoveOneItem(item); ProtectiveWards.LogInfo("Offered " + item.m_shared.m_name); } ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_offerdone"), 0, (Sprite)null); } private static void ApplyModerPowerEffectToNearbyPlayers(PrivateArea ward, ItemData item, Player initiator) { ProtectiveWards.LogInfo("Dragon egg offered"); List<Player> players = new List<Player>(); CollectionExtensions.Do<PrivateArea>(ProtectiveWards.ConnectedAreas(ward), (Action<PrivateArea>)delegate(PrivateArea area) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Player.GetPlayersInRange(((Component)area).transform.position, area.m_radius, players); }); foreach (Player item2 in players.ToHashSet()) { StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect(moderPowerHash); ((Character)item2).GetSEMan().AddStatusEffect(statusEffect.NameHash(), true, 0, 0f); } ((Humanoid)initiator).GetInventory().RemoveOneItem(item); } private static void TaxiToLocation(ItemData item, Player initiator) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_01e3: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) if (((Character)initiator).IsEncumbered()) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$se_encumbered_start"), 0, (Sprite)null); return; } if (!IsTeleportable(initiator)) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$pw_msg_notravel"), 0, (Sprite)null); return; } if (!ProtectiveWards.canTravel) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$pw_msg_canttravel"), 0, (Sprite)null); return; } Vector3 target = Vector3.zero; int stack = 0; string text; bool flag; if (IsBossTrophy(item.m_shared.m_name)) { text = "StartTemple"; flag = TryGetFoundLocation(text, ((Component)initiator).transform.position, ref target); } else if (item.m_shared.m_name == "$item_coins") { text = "Vendor_BlackForest"; flag = TryGetFoundLocation(text, ((Component)initiator).transform.position, ref target); stack = (flag ? ProtectiveWards.offeringTaxiPriceHaldorDiscovered.Value : ProtectiveWards.offeringTaxiPriceHaldorUndiscovered.Value); } else if (IsItemForHildirTravel(item.m_shared.m_name) || item.m_shared.m_name == "$item_chest_hildir1" || item.m_shared.m_name == "$item_chest_hildir2" || item.m_shared.m_name == "$item_chest_hildir3") { text = "Hildir_camp"; flag = TryGetFoundLocation(text, ((Component)initiator).transform.position, ref target); stack = 1; } else { if (!IsItemForBogWitchTravel(item.m_shared.m_name)) { return; } text = "BogWitch_Camp"; flag = TryGetFoundLocation(text, ((Component)initiator).transform.position, ref target); stack = ProtectiveWards.offeringTaxiPriceBogWitchAmount.Value; } if (flag) { StartTaxi(initiator, target, item.m_shared.m_name, stack); } else if (!ZNet.instance.IsServer()) { ClosestLocationRequest(text, ((Component)initiator).transform.position, item.m_shared.m_name, stack); } else { ProtectiveWards.LogInfo("Location " + text + " is not found"); } } internal static void RegisterRPCs() { if (ZNet.instance.IsServer()) { ZRoutedRpc.instance.Register<ZPackage>("ClosestLocationRequest", (Action<long, ZPackage>)RPC_ClosestLocationRequest); } else { ZRoutedRpc.instance.Register<ZPackage>("StartTaxi", (Action<long, ZPackage>)RPC_StartTaxi); } } public static void ClosestLocationRequest(string name, Vector3 position, string itemName, int stack) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) ProtectiveWards.LogInfo(name + " closest location request"); ZPackage val = new ZPackage(); val.Write(name); val.Write(position); val.Write(itemName); val.Write(stack); ZRoutedRpc.instance.InvokeRoutedRPC("ClosestLocationRequest", new object[1] { val }); } public static void RPC_ClosestLocationRequest(long sender, ZPackage pkg) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) string text = pkg.ReadString(); Vector3 position = pkg.ReadVector3(); string text2 = pkg.ReadString(); int num = pkg.ReadInt(); Vector3 target = Vector3.zero; if (!TryGetFoundLocation(text, position, ref target)) { ProtectiveWards.LogInfo("Location " + text + " is not found"); return; } ZPackage val = new ZPackage(); val.Write(target); val.Write(text2); val.Write(num); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "StartTaxi", new object[1] { val }); } public static void RPC_StartTaxi(long sender, ZPackage pkg) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Vector3 position = pkg.ReadVector3(); string itemName = pkg.ReadString(); int stack = pkg.ReadInt(); ProtectiveWards.LogInfo("Server responded with closest location"); StartTaxi(Player.m_localPlayer, position, itemName, stack); } internal static void StartTaxi(Player initiator, Vector3 position, string itemName, int stack) { //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_00a7: Unknown result type (might be due to invalid IL or missing references) if (Utils.DistanceXZ(((Component)initiator).transform.position, position) < 300f) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$pw_msg_tooclose"), 0, (Sprite)null); return; } if (stack > 0 && (IsItemForHildirTravel(itemName) || IsItemForBogWitchTravel(itemName) || itemName == "$item_coins")) { if (((Humanoid)initiator).GetInventory().CountItems(itemName, -1, true) < stack) { ((Character)initiator).Message((MessageType)2, Localization.instance.Localize("$msg_incompleteoffering"), 0, (Sprite)null); return; } ((Humanoid)initiator).GetInventory().RemoveItem(itemName, stack, -1, true); } ((MonoBehaviour)initiator).StartCoroutine(TaxiToPosition(initiator, position, returnBack: true, 10)); } internal static bool TryGetFoundLocation(string name, Vector3 position, ref Vector3 target) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) ZoneSystem.instance.tempIconList.Clear(); ZoneSystem.instance.GetLocationIcons(ZoneSystem.instance.tempIconList); foreach (KeyValuePair<Vector3, string> tempIcon in ZoneSystem.instance.tempIconList) { if (tempIcon.Value == name) { target = tempIcon.Key; ProtectiveWards.LogInfo("Found closest " + name + " in icon list"); return true; } } LocationInstance val = default(LocationInstance); if (ZoneSystem.instance.FindClosestLocation(name, position, ref val)) { target = val.m_position; ProtectiveWards.LogInfo("Found closest " + name + " in location list"); return true; } return false; } internal static bool IsItemForHildirTravel(string itemName) { return ProtectiveWards.offeringTaxiPriceHildirItem.Value != "" && itemName == ProtectiveWards.offeringTaxiPriceHildirItem.Value; } internal static bool IsItemForBogWitchTravel(string itemName) { return ProtectiveWards.offeringTaxiPriceBogWitchItem.Value != "" && itemName == ProtectiveWards.offeringTaxiPriceBogWitchItem.Value; } internal static bool IsBossTrophy(string itemName) { int result; switch (itemName) { default: result = ((itemName == "$item_trophy_fader") ? 1 : 0); break; case "$item_trophy_eikthyr": case "$item_trophy_elder": case "$item_trophy_bonemass": case "$item_trophy_dragonqueen": case "$item_trophy_goblinking": case "$item_trophy_seekerqueen": result = 1; break; } return (byte)result != 0; } public static bool IsTeleportable(Player player) { if (((Humanoid)player).IsTeleportable()) { return true; } foreach (ItemData item in ((Humanoid)player).GetInventory().m_inventory) { if (item.m_shared.m_name == "$item_chest_hildir1" || item.m_shared.m_name == "$item_chest_hildir2" || item.m_shared.m_name == "$item_chest_hildir3" || item.m_shared.m_teleportable) { continue; } return false; } return true; } private static IEnumerator TaxiToPosition(Player player, Vector3 position, bool returnBack = false, int waitSeconds = 0) { //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) ProtectiveWards.canTravel = false; ProtectiveWards.isTravelingPlayer = player; if (waitSeconds > 0) { for (int i = waitSeconds; i > 0; i--) { ((Character)player).Message((MessageType)2, Localization.instance.Localize("$pw_msg_travel_starting", new string[1] { TimeSpan.FromSeconds(i).ToString("m\\:ss") }), 0, (Sprite)null); yield return (object)new WaitForSeconds(1f); } } DateTime flightInitiated = DateTime.Now; if ((Object)(object)Valkyrie.m_instance == (Object)null) { bool playerShouldExit = ((Character)player).IsAttachedToShip() || ((Character)player).IsAttached() || ((Character)player).IsDead() || ((Character)player).IsRiding() || player.IsSleeping() || ((Character)player).IsTeleporting() || ((Character)player).InPlaceMode() || ((Character)player).InBed() || ((Character)player).InCutscene() || ((Character)player).InInterior(); while (playerShouldExit || ((Character)player).IsEncumbered() || !((Humanoid)player).IsTeleportable()) { string timeSpent = (DateTime.Now - flightInitiated).ToString("m\\:ss"); if (playerShouldExit) { ((Character)player).Message((MessageType)1, Localization.instance.Localize("$pw_msg_travel_inside", new string[1] { timeSpent }), 0, (Sprite)null); } else { ((Character)player).Message((MessageType)2, Localization.instance.Localize("$pw_msg_travel_blocked", new string[1] { timeSpent }) + Localization.instance.Localize(((Character)player).IsEncumbered() ? " $se_encumbered_start" : " $msg_noteleport"), 0, (Sprite)null); } yield return (object)new WaitForSeconds(1f); playerShouldExit = ((Character)player).IsAttachedToShip() || ((Character)player).IsAttached() || ((Character)player).IsDead() || ((Character)player).IsRiding() || player.IsSleeping() || ((Character)player).IsTeleporting() || ((Character)player).InPlaceMode() || ((Character)player).InBed() || ((Character)player).InCutscene() || ((Character)player).InInterior(); } ((Character)player).Message((MessageType)2, Localization.instance.Localize("$pw_msg_travel_start"), 0, (Sprite)null); ProtectiveWards.taxiTargetPosition = position; ProtectiveWards.taxiReturnBack = returnBack; ProtectiveWards.taxiPlayerPositionToReturn = ((Component)player).transform.position; ProtectiveWards.playerDropped = false; Player.m_localPlayer.m_valkyrie.Load(); GameObject valkyrie = Object.Instantiate<GameObject>(Player.m_localPlayer.m_valkyrie.Asset, ((Component)player).transform.position, Quaternion.identity); valkyrie.GetComponent<ZNetView>().HoldReferenceTo((IReferenceCounted)(object)Player.m_localPlayer.m_valkyrie); Player.m_localPlayer.m_valkyrie.Release(); } ProtectiveWards.canTravel = true; } } [BepInPlugin("shudnal.ProtectiveWards", "Protective Wards", "1.2.3")] public class ProtectiveWards : BaseUnityPlugin { public enum ShipDamageType { Off, WaterDamage, AnyButPlayerDamage, AnyDamage } [HarmonyPatch(typeof(CircleProjector), "CreateSegments")] public static class CircleProjector_CreateSegments_InitState { public static void Prefix(CircleProjector __instance, ref bool __state) { if (modEnabled.Value && wardAreaMarkerPatch.Value) { __instance.m_nrOfSegments = (int)(80f * (wardAreaMarkerPatch.Value ? wardAreaMarkerAmount.Value : 1f) * (__instance.m_radius / 32f)); __state = (!__instance.m_sliceLines && __instance.m_segments.Count == __instance.m_nrOfSegments) || (__instance.m_sliceLines && __instance.m_calcStart == __instance.m_start && __instance.m_calcTurns == __instance.m_turns); } } public static void Postfix(CircleProjector __instance, bool __state) { if (!modEnabled.Value || !wardAreaMarkerPatch.Value || __state) { return; } ZNetView componentInParent = ((Component)__instance).GetComponentInParent<ZNetView>(); if (Object.op_Implicit((Object)(object)componentInParent) && componentInParent.IsValid()) { ZDO zDO = componentInParent.GetZDO(); if (zDO != null) { InitCircleProjectorState(__instance, componentInParent); } } } } [HarmonyPatch(typeof(Door), "Interact")] public static class Door_SetState_AutoClose { public static void Postfix(Door __instance, ZNetView ___m_nview, bool __result) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled.Value || autoCloseDoorsTime.Value == 0 || !___m_nview.IsValid() || !__result || !InsideEnabledPlayersArea(((Component)__instance).transform.position, out var area, checkCache: true)) { return; } if (!doorsToClose.TryGetValue(area, out var value)) { value = new List<Door>(); } int @int = ___m_nview.GetZDO().GetInt(ZDOVars.s_state, 0); if (@int == 0) { value.Remove(__instance); } else if (!value.Contains(__instance)) { value.Add(__instance); } if (value.Count == 0) { wardIsClosing.Remove(area); doorsToClose.Remove(area); } else if (@int != 0) { doorsToClose[area] = value; LogInfo(value.Count); if (wardIsClosing.ContainsKey(area)) { wardIsClosing[area] = Math.Max(autoCloseDoorsTime.Value, 2); LogInfo($"Doors closing reset to {wardIsClosing[area]} seconds"); } else { wardIsClosing[area] = Math.Max(autoCloseDoorsTime.Value, 2); ((MonoBehaviour)area).StartCoroutine(AutoClosingDoors(area)); LogInfo("Doors closing started"); } } } } [HarmonyPatch(typeof(PrivateArea), "OnDestroy")] public static class PrivateArea_OnDestroy_ClearStatus { public static void Prefix(PrivateArea __instance) { if (modEnabled.Value) { areaCache.Clear(); wardIsHealing.Remove(__instance); wardIsRepairing.Remove(__instance); wardIsClosing.Remove(__instance); } } } [HarmonyPatch(typeof(PrivateArea), "HideMarker")] public static class PrivateArea_HideMarker_ShowAreaMarker { public static bool Prefix() { if (!modEnabled.Value) { return true; } return !showAreaMarker.Value; } } [HarmonyPatch(typeof(PrivateArea), "AddUserList")] public static class PrivateArea_AddUserList_WardAltActionCaption { public static void Prefix(PrivateArea __instance, StringBuilder text) { if (!modEnabled.Value || !__instance.HaveLocalAccess()) { return; } bool flag = __instance.IsEnabled(); if (!flag && !__instance.m_piece.IsCreator()) { return; } if (!flag) { if (!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) { text.Append("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $pw_ward_apply_settings"); } else { text.Append("\n[<color=yellow><b>$KEY_JoyAltKeys + $KEY_Use</b></color>] $pw_ward_apply_settings"); } return; } List<string> list = new List<string>(); if (wardIsRepairing.TryGetValue(__instance, out var value)) { list.Add($"$hud_repair {value}"); } else if (wardPassiveRepair.Value) { if (!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) { text.Append("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $pw_ward_start_repair"); } else { text.Append("\n[<color=yellow><b>$KEY_JoyAltKeys + $KEY_Use</b></color>] $pw_ward_start_repair"); } } if (wardIsHealing.TryGetValue(__instance, out var value2)) { list.Add("$item_food_regen " + TimeSpan.FromSeconds(value2).ToString("m\\:ss")); } if (list.Count > 0) { text.Append("\n$guardianstone_hook_power_activate: "); text.Append(string.Join(", ", list.ToArray())); } if (offeringsTimer < showOfferingsInHoverAfterSeconds.Value + 0.5f) { offeringsTimer += Time.fixedDeltaTime * 2f; } if (!showOfferingsInHover.Value || !(offeringsTimer > showOfferingsInHoverAfterSeconds.Value)) { return; } List<string> list2 = new List<string>(); if (offeringActiveRepair.Value && (Player.m_localPlayer.IsMaterialKnown("$item_surtlingcore") || Player.m_localPlayer.NoCostCheat())) { list2.Add("$item_surtlingcore - $pw_ward_offering_surtlingcore_description"); } if (offeringAugmenting.Value && (Player.m_localPlayer.IsMaterialKnown("$item_blackcore") || Player.m_localPlayer.NoCostCheat())) { list2.Add("$item_blackcore - $pw_ward_offering_blackcore_description"); } if (offeringFood.Value) { list2.Add("$item_food - $pw_ward_offering_food_description"); } if (offeringMead.Value) { list2.Add("$se_mead_name - $pw_ward_offering_mead_description"); } if (offeringThundertone.Value && (Player.m_localPlayer.IsMaterialKnown("$item_thunderstone") || Player.m_localPlayer.NoCostCheat())) { list2.Add("$item_thunderstone - $pw_ward_offering_thunderstone_description"); } if (offeringTrophy.Value) { list2.Add("$inventory_trophies - $pw_ward_offering_trophies_description"); list2.Add("$pw_ward_offering_bosstrophies - $pw_ward_offering_bosstrophies_description"); } if (offeringYmirRemains.Value && (Player.m_localPlayer.IsMaterialKnown("$item_ymirremains") || Player.m_localPlayer.NoCostCheat())) { list2.Add("$item_ymirremains - $pw_ward_offering_ymirremains_description"); } if (offeringEitr.Value && (Player.m_localPlayer.IsMaterialKnown("$item_eitr") || Player.m_localPlayer.NoCostCheat())) { list2.Add("$item_eitr - $pw_ward_offering_eitr_description"); } if (offeringDragonEgg.Value && ((Player.m_localPlayer.IsMaterialKnown("$item_dragonegg") && ZoneSystem.instance.GetGlobalKey((GlobalKeys)33)) || Player.m_localPlayer.NoCostCheat())) { list2.Add("$item_dragonegg - $pw_ward_offering_dragonegg_description"); } if (offeringTaxi.Value) { if (Player.m_localPlayer.IsMaterialKnown("$item_coins") || Player.m_localPlayer.NoCostCheat()) { ZoneSystem.instance.tempIconList.Clear(); ZoneSystem.instance.GetLocationIcons(ZoneSystem.instance.tempIconList); int num = (ZoneSystem.instance.tempIconList.Any((KeyValuePair<Vector3, string> icon) => icon.Value == "Vendor_BlackForest") ? offeringTaxiPriceHaldorDiscovered.Value : offeringTaxiPriceHaldorUndiscovered.Value); list2.Add($"$item_coins: {num} - $pw_ward_offering_coins_description"); } if (!Utility.IsNullOrWhiteSpace(offeringTaxiPriceHildirItem.Value) && (Player.m_localPlayer.IsMaterialKnown(offeringTaxiPriceHildirItem.Value) || Player.m_localPlayer.NoCostCheat())) { list2.Add(offeringTaxiPriceHildirItem.Value + " - $pw_ward_offering_hildiritem_description"); } if (Player.m_localPlayer.IsMaterialKnown("$item_chest_hildir1") || Player.m_localPlayer.IsMaterialKnown("$item_chest_hildir2") || Player.m_localPlayer.IsMaterialKnown("$item_chest_hildir3") || Player.m_localPlayer.NoCostCheat()) { list2.Add("$pw_ward_offering_hildirchest - $pw_ward_offering_hildirchest_description"); } if (!Utility.IsNullOrWhiteSpace(offeringTaxiPriceBogWitchItem.Value) && (Player.m_localPlayer.IsMaterialKnown(offeringTaxiPriceBogWitchItem.Value) || Player.m_localPlayer.NoCostCheat())) { list2.Add(offeringTaxiPriceBogWitchItem.Value + " " + ((offeringTaxiPriceBogWitchAmount.Value > 0) ? $"x{offeringTaxiPriceBogWitchAmount.Value}" : "") + " - $pw_ward_offering_bogwitchitem_description"); } } if (list2.Count > 0) { text.Append("\n[<color=yellow><b>1-8</b></color>] $piece_offerbowl_offeritem:\n"); text.Append(string.Join("\n", list2)); text.Append('\n'); } } } [HarmonyPatch(typeof(PrivateArea), "IsPermitted")] public static class PrivateArea_AddUserList_PermittanceToEveryone { public static bool Prefix(ref bool __result) { if (!modEnabled.Value) { return true; } if (!permitEveryone.Value) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(PrivateArea), "Interact")] public static class PrivateArea_Interact_PassiveEffectWardRepair { private static bool Prefix(PrivateArea __instance, Humanoid human, bool hold, bool alt, Faction ___m_ownerFaction, ref bool __result) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled.Value) { return true; } if (hold) { return true; } if (!alt) { return true; } if ((int)___m_ownerFaction > 0) { return true; } if (!__instance.HaveLocalAccess()) { return true; } areaCache.Clear(); if (__instance.IsEnabled() && wardPassiveRepair.Value) { __result = true; if (wardIsRepairing.ContainsKey(__instance)) { return false; } LogInfo("Passive repairing begins"); ((MonoBehaviour)instance).StartCoroutine(PassiveRepairEffect(__instance, (Player)(object)((human is Player) ? human : null))); return false; } if (!__instance.IsEnabled() && __instance.m_piece.IsCreator()) { ZDO zDO = __instance.m_nview.GetZDO(); if (zDO == null) { return false; } __result = true; zDO.Set(s_bubbleEnabled, wardBubbleShow.Value); if (wardBubbleShow.Value) { zDO.Set(s_bubbleRefractionIntensity, wardBubbleRefractionIntensity.Value); zDO.Set(s_bubbleWaveVel, wardBubbleWaveIntensity.Value); zDO.Set(s_bubbleColor, new Vector3(wardBubbleColor.Value.r, wardBubbleColor.Value.g, wardBubbleColor.Value.b)); zDO.Set(s_bubbleColorAlpha, wardBubbleColor.Value.a); zDO.Set(s_bubbleGlossiness, wardBubbleGlossiness.Value); zDO.Set(s_bubbleMetallic, wardBubbleMetallic.Value); zDO.Set(s_bubbleNormalScale, wardBubbleNormalScale.Value); zDO.Set(s_bubbleDepthFade, wardBubbleDepthFade.Value); } zDO.Set(s_customRange, setWardRange.Value); if (setWardRange.Value) { zDO.Set(s_range, wardRange.Value); } zDO.Set(s_customColor, wardEmissionColorEnabled.Value); if (wardEmissionColorEnabled.Value) { zDO.Set(s_color, new Vector3(wardEmissionColor.Value.r * wardEmissionColorMultiplier.Value, wardEmissionColor.Value.g * wardEmissionColorMultiplier.Value, wardEmissionColor.Value.b * wardEmissionColorMultiplier.Value)); } zDO.Set(s_circleEnabled, wardAreaMarkerPatch.Value); if (wardAreaMarkerPatch.Value) { zDO.Set(s_circleStartColor, ColorUtility.ToHtmlStringRGBA(wardAreaMarkerStartColor.Value)); zDO.Set(s_circleEndColor, ColorUtility.ToHtmlStringRGBA(wardAreaMarkerEndColor.Value)); zDO.Set(s_circleSpeed, wardAreaMarkerSpeed.Value); zDO.Set(s_circleLength, wardAreaMarkerLength.Value); zDO.Set(s_circleWidth, wardAreaMarkerWidth.Value); zDO.Set(s_circleAmount, wardAreaMarkerAmount.Value); } __instance.m_addPermittedEffect.Create(((Component)__instance).transform.position, ((Component)__instance).transform.rotation, (Transform)null, 1f, -1); LogInfo($"Ward settings applied for {zDO}"); return false; } return true; } } [HarmonyPatch(typeof(PrivateArea), "Awake")] public static class PrivateArea_Awake_SetWardRange { private static void Postfix(PrivateArea __instance, ZNetView ___m_nview) { if (modEnabled.Value && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid()) { PatchRange(__instance); if (showAreaMarker.Value) { ((Component)__instance.m_areaMarker).gameObject.SetActive(true); } if ((Object)(object)forceField != (Object)null) { GameObject val = Object.Instantiate<GameObject>(forceField, ((Component)__instance).transform); ((Object)val).name = "ForceField"; InitBubbleState(__instance, val, ___m_nview); } if ((Object)(object)forceFieldDemister != (Object)null) { GameObject val2 = Object.Instantiate<GameObject>(forceFieldDemister, ((Component)__instance).transform); ((Object)val2).name = "Particle System Force Field"; InitDemisterState(__instance, val2, ___m_nview); } InitEmissionColor(__instance); } } } [HarmonyPatch(typeof(PrivateArea), "RPC_FlashShield")] public static class PrivateArea_RPC_FlashShield_StopFlashShield { private static bool Prefix(PrivateArea __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 if (!modEnabled.Value) { return true; } if ((int)__instance.m_ownerFaction == 0) { return !disableFlash.Value; } return true; } } [HarmonyPatch(typeof(ZoneSystem), "Start")] public static class ZoneSystem_Start_InitWardBubble { private static void Postfix(ZoneSystem __instance) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown ZoneLocation val = __instance.m_locations.Find((ZoneLocation loc) => loc.m_prefabName == "Vendor_BlackForest"); if (val != null && val.m_prefab.IsValid) { val.m_prefab.Load(); Transform obj = val.m_prefab.Asset.transform.Find("ForceField"); forceField = Object.Instantiate<GameObject>((obj != null) ? ((Component)obj).gameObject : null); ((Object)forceField).name = "ProtectiveWards_bubble"; MeshRenderer component = forceField.GetComponent<MeshRenderer>(); ((Renderer)component).sharedMaterial = new Material(((Renderer)component).sharedMaterial); Material sharedMaterial = ((Renderer)component).sharedMaterial; int renderQueue = sharedMaterial.renderQueue; sharedMaterial.renderQueue = renderQueue + 1; val.m_prefab.Release(); } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ZNetScene_Awake_DemisterForceField { private static void Postfix(ZNetScene __instance) { GameObject prefab = __instance.GetPrefab("Demister"); object forceFieldDemister; if (prefab == null) { forceFieldDemister = null; } else { Transform obj = prefab.transform.Find("Particle System Force Field"); forceFieldDemister = ((obj != null) ? ((Component)obj).gameObject : null); } ProtectiveWards.forceFieldDemister = (GameObject)forceFieldDemister; } } [HarmonyPatch(typeof(PrivateArea), "RPC_ToggleEnabled")] public static class PrivateArea_RPC_ToggleEnabled_InitWardBubble { private static void Postfix(PrivateArea __instance, ZNetView ___m_nview, Piece ___m_piece) { if (!((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid()) { PatchRange(__instance); InitEmissionColor(__instance); Transform obj = ((Component)__instance).transform.Find("ForceField"); InitBubbleState(__instance, (obj != null) ? ((Component)obj).gameObject : null, ___m_nview); Transform obj2 = ((Component)__instance).transform.Find("Particle System Force Field"); InitDemisterState(__instance, (obj2 != null) ? ((Component)obj2).gameObject : null, ___m_nview); InitCircleProjectorState(__instance.m_areaMarker, ___m_nview); } } } private const string pluginID = "shudnal.ProtectiveWards"; private const string pluginName = "Protective Wards"; private const string pluginVersion = "1.2.3"; private Harmony _harmony; internal static readonly ConfigSync configSync = new ConfigSync("shudnal.ProtectiveWards") { DisplayName = "Protective Wards", CurrentVersion = "1.2.3", MinimumRequiredVersion = "1.2.3" }; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> configLocked; public static ConfigEntry<bool> disableFlash; public static ConfigEntry<bool> showAreaMarker; public static ConfigEntry<bool> loggingEnabled; public static ConfigEntry<int> refreshingTime; public static ConfigEntry<bool> showOfferingsInHover; public static ConfigEntry<float> showOfferingsInHoverAfterSeconds; public static ConfigEntry<float> maxTaxiSpeed; public static ConfigEntry<bool> offeringActiveRepair; public static ConfigEntry<bool> offeringAugmenting; public static ConfigEntry<bool> offeringFood; public static ConfigEntry<bool> offeringMead; public static ConfigEntry<bool> offeringThundertone; public static ConfigEntry<bool> offeringTrophy; public static ConfigEntry<bool> offeringYmirRemains; public static ConfigEntry<bool> offeringEitr; public static ConfigEntry<bool> offeringDragonEgg; public static ConfigEntry<bool> offeringTaxi; public static ConfigEntry<int> offeringTaxiPriceHaldorUndiscovered; public static ConfigEntry<int> offeringTaxiPriceHaldorDiscovered; public static ConfigEntry<string> offeringTaxiPriceHildirItem; public static ConfigEntry<string> offeringTaxiPriceBogWitchItem; public static ConfigEntry<int> offeringTaxiPriceBogWitchAmount; public static ConfigEntry<bool> wardPassiveRepair; public static ConfigEntry<int> autoCloseDoorsTime; public static ConfigEntry<string> wardPrefabNameToChangeRange; public static ConfigEntry<bool> setWardRange; public static ConfigEntry<float> wardRange; public static ConfigEntry<bool> supressSpawnInRange; public static ConfigEntry<bool> permitEveryone; public static ConfigEntry<float> playerDamageDealtMultiplier; public static ConfigEntry<float> playerDamageTakenMultiplier; public static ConfigEntry<float> tamedDamageTakenMultiplier; public static ConfigEntry<float> structureDamageTakenMultiplier; public static ConfigEntry<float> fallDamageTakenMultiplier; public static ConfigEntry<float> turretFireRateMultiplier; public static ConfigEntry<float> foodDrainMultiplier; public static ConfigEntry<float> staminaDrainMultiplier; public static ConfigEntry<float> skillsDrainMultiplier; public static ConfigEntry<float> fireplaceDrainMultiplier; public static ConfigEntry<float> hammerDurabilityDrainMultiplier; public static ConfigEntry<float> smeltingSpeedMultiplier; public static ConfigEntry<float> cookingSpeedMultiplier; public static ConfigEntry<float> fermentingSpeedMultiplier; public static ConfigEntry<float> sapCollectingSpeedMultiplier; public static ConfigEntry<bool> wardBubbleShow; public static ConfigEntry<Color> wardBubbleColor; public static ConfigEntry<float> wardBubbleRefractionIntensity; public static ConfigEntry<float> wardBubbleWaveIntensity; public static ConfigEntry<float> wardBubbleGlossiness; public static ConfigEntry<float> wardBubbleMetallic; public static ConfigEntry<float> wardBubbleNormalScale; public static ConfigEntry<float> wardBubbleDepthFade; public static ConfigEntry<bool> wardAreaMarkerPatch; public static ConfigEntry<float> wardAreaMarkerSpeed; public static ConfigEntry<Color> wardAreaMarkerStartColor; public static ConfigEntry<Color> wardAreaMarkerEndColor; public static ConfigEntry<float> wardAreaMarkerLength; public static ConfigEntry<float> wardAreaMarkerWidth; public static ConfigEntry<float> wardAreaMarkerAmount; public static ConfigEntry<bool> wardEmissionColorEnabled; public static ConfigEntry<Color> wardEmissionColor; public static ConfigEntry<float> wardEmissionColorMultiplier; public static ConfigEntry<bool> wardLightColorEnabled; public static ConfigEntry<bool> wardDemisterEnabled; public static ConfigEntry<bool> boarsHensProtection; public static ConfigEntry<bool> wardRainProtection; public static ConfigEntry<ShipDamageType> wardShipProtection; public static ConfigEntry<bool> wardPlantProtection; public static ConfigEntry<bool> fireplaceProtection; public static ConfigEntry<bool> sittingRaidProtection; public static ConfigEntry<bool> wardTrapProtection; public static ConfigEntry<string> wardPlantProtectionList; public static ConfigEntry<string> boarsHensProtectionGroupList; internal static ProtectiveWards instance; internal static long startTimeCached; internal static Dictionary<Vector3, PrivateArea> areaCache = new Dictionary<Vector3, PrivateArea>(); internal static Dictionary<PrivateArea, int> wardIsRepairing = new Dictionary<PrivateArea, int>(); internal static Dictionary<PrivateArea, int> wardIsHealing = new Dictionary<PrivateArea, int>(); internal static Dictionary<PrivateArea, int> wardIsClosing = new Dictionary<PrivateArea, int>(); internal static Dictionary<PrivateArea, List<Door>> doorsToClose = new Dictionary<PrivateArea, List<Door>>(); internal static GameObject lightningAOE; internal static EffectList preLightning; internal static List<TrophyTarget> trophyTargets; internal static int baseValueProtected = 999; internal static GameObject forceField; internal const string forceFieldName = "ForceField"; internal static GameObject forceFieldDemister; internal const string forceFieldDemisterName = "Particle System Force Field"; internal static bool taxiReturnBack = false; internal static Vector3 taxiPlayerPositionToReturn; internal static Vector3 taxiTargetPosition; internal static bool canTravel = true; internal static Player isTravelingPlayer; internal static bool playerDropped = false; internal static bool castSlowFall; internal static HashSet<string> _wardPlantProtectionList; internal static HashSet<string> _boarsHensProtectionGroupList; public static readonly int s_customRange = StringExtensionMethods.GetStableHashCode("ward_useRange"); public static readonly int s_range = StringExtensionMethods.GetStableHashCode("ward_range"); public static readonly int s_customColor = StringExtensionMethods.GetStableHashCode("ward_useColor"); public static readonly int s_color = StringExtensionMethods.GetStableHashCode("ward_color"); public static readonly int s_circleEnabled = StringExtensionMethods.GetStableHashCode("circle_enabled"); public static readonly int s_circleStartColor = StringExtensionMethods.GetStableHashCode("circle_startColor"); public static readonly int s_circleEndColor = StringExtensionMethods.GetStableHashCode("circle_endColor"); public static readonly int s_circleSpeed = StringExtensionMethods.GetStableHashCode("circle_speed"); public static readonly int s_circleLength = StringExtensionMethods.GetStableHashCode("circle_length"); public static readonly int s_circleWidth = StringExtensionMethods.GetStableHashCode("circle_width"); public static readonly int s_circleAmount = StringExtensionMethods.GetStableHashCode("circle_amount"); public static readonly int s_bubbleEnabled = StringExtensionMethods.GetStableHashCode("bubble_enabled"); public static readonly int s_bubbleColor = StringExtensionMethods.GetStableHashCode("bubble_color"); public static readonly int s_bubbleColorAlpha = StringExtensionMethods.GetStableHashCode("bubble_color_alpha"); public static readonly int s_bubbleWaveVel = StringExtensionMethods.GetStableHashCode("bubble_wave"); public static readonly int s_bubbleRefractionIntensity = StringExtensionMethods.GetStableHashCode("bubble_refraction"); public static readonly int s_bubbleGlossiness = StringExtensionMethods.GetStableHashCode("bubble_glossiness"); public static readonly int s_bubbleMetallic = StringExtensionMethods.GetStableHashCode("bubble_metallic"); public static readonly int s_bubbleNormalScale = StringExtensionMethods.GetStableHashCode("bubble_normalscale"); public static readonly int s_bubbleDepthFade = StringExtensionMethods.GetStableHashCode("bubble_depthfade"); private static readonly MaterialPropertyBlock s_matBlock = new MaterialPropertyBlock(); private static float offeringsTimer = 0f; private void Awake() { _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "shudnal.ProtectiveWards"); instance = this; ConfigInit(); configSync.AddLockingConfigEntry<bool>(configLocked); Localizer.Load(); } private void FixedUpdate() { if (offeringsTimer > 0f) { offeringsTimer -= Time.fixedDeltaTime; } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } public static void LogInfo(object data) { if (loggingEnabled.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo(data); } } private void ConfigInit() { //IL_05aa: Unknown result type (might be due to invalid IL or missing references) //IL_06f1: Unknown result type (might be due to invalid IL or missing references) //IL_0711: Unknown result type (might be due to invalid IL or missing references) //IL_0880: Unknown result type (might be due to invalid IL or missing references) config("General", "NexusID", 2450, "Nexus mod ID for updates", synchronizedSetting: false); modEnabled = config("General", "Enabled", defaultValue: true, "Enable the mod. Every option requires being in the zone of the active Ward."); configLocked = config("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only."); disableFlash = config("Misc", "Disable flash", defaultValue: false, "Disable flash on hit [Not Synced with Server]", synchronizedSetting: false); showAreaMarker = config("Misc", "Always show radius", defaultValue: false, "Always show ward radius. Hover the ward for changes to take effect. [Not Synced with Server]", synchronizedSetting: false); refreshingTime = config("Misc", "Ward protected status check time", 30, "Set how many seconds the \"inside the protected zone\" status is reset. [Not Synced with Server]\nSetting more seconds can be helpful for fps for base with many objects and static untoggled wards. \nDoesn't affect moving objects.", synchronizedSetting: false); loggingEnabled = config("Misc", "Enable logging", defaultValue: false, "Enable logging for ward events. [Not Synced with Server]", synchronizedSetting: false); showOfferingsInHover = config("Misc", "Show offerings in hover", defaultValue: true, "Show offerings list in hover text. [Not Synced with Server]", synchronizedSetting: false); showOfferingsInHoverAfterSeconds = config("Misc", "Show offerings in hover after seconds", 10f, "Show offerings list after set amount of seconds. [Not Synced with Server]", synchronizedSetting: false); maxTaxiSpeed = config("Misc", "Maximum taxi speed", 30f, "Reduce maximum taxi speed if it is laggy. [Not Synced with Server]", synchronizedSetting: false); playerDamageDealtMultiplier = config("Modifiers damage", "Creatures damage taken multiplier", 1f, "Basically it means damage dealt by any creatures (players and tames included) to any creatures (players and tames excluded)"); playerDamageTakenMultiplier = config("Modifiers damage", "Player damage taken multiplier", 1f, "Damage taken by players from creatures"); fallDamageTakenMultiplier = config("Modifiers damage", "Player fall damage taken multiplier", 1f, "Player fall damage taken"); structureDamageTakenMultiplier = config("Modifiers damage", "Structure damage taken multiplier", 1f, "Structures (and ships) damage taken"); tamedDamageTakenMultiplier = config("Modifiers damage", "Tamed damage taken multiplier", 1f, "Damage taken by tamed from creatures (players included)"); turretFireRateMultiplier = config("Modifiers damage", "Turret fire rate multiplier", 1f, "Basically time between shots"); foodDrainMultiplier = config("Modifiers drain", "Food drain multiplier", 1f, "Speed of food drain, more - faster, less - slower"); staminaDrainMultiplier = config("Modifiers drain", "Stamina drain multiplier", 1f, "Multiplier of stamina needed for actions"); skillsDrainMultiplier = config("Modifiers drain", "Skills drain on death multiplier", 1f, "Multiplier of how much skill points you lose on death. Accumulated scale will be lost anyway"); fireplaceDrainMultiplier = config("Modifiers drain", "Fireplace fuel drain multiplier", 1f, "Speed of fuel spent for fireplaces (including bathtub, torches and braziers)"); hammerDurabilityDrainMultiplier = config("Modifiers drain", "Hammer durability drain multiplier", 1f, "Multiplier of how much hammer's durability will be spent on building and repairing"); smeltingSpeedMultiplier = config("Modifiers speed", "Smelting speed multiplier", 1f, "Speed of smelting for all smelting stations (excluding bathtub)"); cookingSpeedMultiplier = config("Modifiers speed", "Cooking speed multiplier", 1f, "Speed of cooking for all cooking stations (that also means faster burn)"); fermentingSpeedMultiplier = config("Modifiers speed", "Fermenting speed multiplier", 1f, "Speed of fermenting"); sapCollectingSpeedMultiplier = config("Modifiers speed", "Sap collecting speed multiplier", 1f, "Speed of sap collecting"); offeringActiveRepair = config("Offerings", "1 - Repair all pieces by surtling core offering", defaultValue: true, "Offer surtling core to ward to instantly repair all pieces in all connected areas\nCore will NOT be wasted if there is no piece to repair"); offeringAugmenting = config("Offerings", "2 - Augment all pieces by black core offering", defaultValue: true, "Offer black core to ward to double the health of every structural piece in all connected areas\nCore will NOT be wasted if there is no piece to repair"); offeringFood = config("Offerings", "3 - Heal all allies for 3 min by food offering", defaultValue: true, "Offer food to ward to activate healing for 3 minutes in all connected areas. Better food means better heal.\nYou can offer one food to one ward until 3 minutes are gone. But nothing stops you from offering food to several wards."); offeringMead = config("Offerings", "4 - Share mead effect to all players by mead offering", defaultValue: true, "Offer mead to ward to share the effect to all players in all connected areas. \nMead will NOT be wasted if no one can have effect."); offeringThundertone = config("Offerings", "5 - Call the wrath of the Thor upon your enemies by thunderstone offering", defaultValue: true, "Offer thunderstone to ward to call the Thor's wrath upon your enemies in all connected areas\nThunderstone WILL be wasted even if no one gets hurt"); offeringTrophy = config("Offerings", "6 - Kill all enemies of the same type by trophy offering", defaultValue: true, "Offer trophy to ward to kill all enemies with type of the offered trophy in all connected areas\nTrophy will NOT be wasted if no one gets hurt"); offeringYmirRemains = config("Offerings", "7 - Grow all plants by Ymir flesh offering", defaultValue: true, "Offer Ymir flesh to instantly grow every plant in all connected areas\nYmir flesh will NOT be wasted if there is no plant to grow"); offeringEitr = config("Offerings", "8 - Grow all plants regardless the requirements by Eitr x5 offering", defaultValue: true, "Offer 5 Eitr to instantly grow every plant regardless the requirements in all connected areas\nEitr will NOT be wasted if there is no plant to grow"); offeringDragonEgg = config("Offerings", "9 - Activate Moder power by dragon egg offering", defaultValue: true, "Offer dragon egg to activate Moder power on all players in all connected areas."); offeringTaxi = config("Offerings", "10 - Fly back and forth to distant point by different items offering", defaultValue: true, "Offer boss trophy to travel to Sacrificial Stones (initial spawn point). Boss trophy will NOT be consumed.\nOffer coins to travel to Haldor (x2000 if you didn't find him yet. x500 otherwise). Coins will be consumed.\nOffer Hildir's chest to travel to Hildir for free. Chest will NOT be consumed. Totem WILL be consumed.\nOffer Fuling totem to travel to Hildir. Totem WILL be consumed."); offeringTaxiPriceHaldorUndiscovered = config("Offerings - Taxi", "Price to undiscovered Haldor", 2000, "Coins amount that must be paid to discover and travel to nearest Haldor."); offeringTaxiPriceHaldorDiscovered = config("Offerings - Taxi", "Price to discovered Haldor", 500, "Coins amount that must be paid to travel to already discovered Haldor."); offeringTaxiPriceHildirItem = config("Offerings - Taxi", "Item to travel to Hildir", "$item_goblintotem", "An item that must be paid to travel to Hildir."); offeringTaxiPriceBogWitchItem = config("Offerings - Taxi", "Item to travel to Bog Witch", "$item_pukeberries", "An item that must be paid to travel to Bog Witch."); offeringTaxiPriceBogWitchAmount = config("Offerings - Taxi", "Item to travel to Bog Witch amount", 20, "An amount of items that must be paid to travel to Bog Witch."); wardPassiveRepair = config("Passive", "Activatable passive repair", defaultValue: true, "Interact with a ward to start passive repair process of all pieces in all connected areas\nWard will repair one piece every 10 seconds until all pieces are healthy. Then the process will stop."); autoCloseDoorsTime = config("Passive", "Auto close doors after", 0, "Automatically close doors after a specified number of seconds. 0 to disable. 5 recommended"); wardPrefabNameToChangeRange = config("Range", "Ward prefab names to control range", "guard_stone", "Prefab name of ward to control range in case."); setWardRange = config("Range", "Change Ward range", defaultValue: false, "Change ward range."); wardRange = config("Range", "Ward range", 10f, "Ward range. Toggle ward protection for changes to take effect"); supressSpawnInRange = config("Range", "Supress spawn in ward area", defaultValue: true, "Vanilla behavior is true. Set false if you want creatures and raids spawn in ward radius. Toggle ward protection for changes to take effect"); permitEveryone = config("Range", "Grant permittance to everyone", defaultValue: false, "Grant permittance to every player. There still will be permittance list on ward but it won't take any effect."); wardBubbleShow = config("Ward Bubble", "Show bubble", defaultValue: false, "Show ward bubble like trader's one [Not Synced with Server]", synchronizedSetting: false); wardBubbleColor = config<Color>("Ward Bubble", "Bubble color", Color.black, "Bubble color. Toggle ward protection to change color [Not Synced with Server]", synchronizedSetting: false); wardBubbleRefractionIntensity = config("Ward Bubble", "Refraction intensity", 0.005f, "Intensity of light refraction caused by bubble. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardBubbleWaveIntensity = config("Ward Bubble", "Wave intensity", 40f, "Bubble light distortion speed. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardBubbleGlossiness = config("Ward Bubble", "Glossiness", 0f, "Bubble glossiness. 1 to soap bubble effect. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardBubbleMetallic = config("Ward Bubble", "Metallic", 1f, "Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardBubbleNormalScale = config("Ward Bubble", "Normal scale", 15f, "Density of distortion effect. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardBubbleDepthFade = config("Ward Bubble", "Depth fade", 1f, "Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardDemisterEnabled = config("Ward Demister", "Enable demister", defaultValue: false, "Ward will push out the mist"); wardAreaMarkerPatch = config("Ward Circle", "Patch circle", defaultValue: false, "Change area marker circle projector parameters. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardAreaMarkerSpeed = config("Ward Circle", "Speed", 0.1f, "Speed of lines movement. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardAreaMarkerStartColor = config<Color>("Ward Circle", "Color start", new Color(0.8f, 0.8f, 0.8f), "Starting color. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardAreaMarkerEndColor = config<Color>("Ward Circle", "Color end", Color.clear, "End color (if set color of lines will change gradually). Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardAreaMarkerLength = config("Ward Circle", "Length multiplier", 1f, "Change area marker circle projector parameters. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardAreaMarkerWidth = config("Ward Circle", "Width multiplier", 1f, "Change area marker circle projector parameters. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); wardAreaMarkerAmount = config("Ward Circle", "Lines amount multiplier", 1f, "Change area marker circle projector parameters. Toggle ward protection for changes to take effect [Not Synced with Server]", synchronizedSetting: false); boarsHensProtection = config("Ward protects", "Boars and hens from damage", defaultValue: true, "Set whether an active Ward will protect nearby boars and hens from taken damage (players excluded)"); wardRainProtection = config("Ward protects", "Struc