Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of WorldControl v3.0.0
plugins/WorldControl.dll
Decompiled 11 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("WorldControl")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("3.0.0.0")] [assembly: AssemblyInformationalVersion("3.0.0+5006c83861da9b211cb31e8b1d53944e6c845180")] [assembly: AssemblyProduct("WorldControl")] [assembly: AssemblyTitle("WorldControl")] [assembly: AssemblyVersion("3.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WorldControl { [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInPlugin("dezzycode.valheim.windcontrol", "World Control", "3.0.0")] [BepInDependency("com.jotunn.jotunn", "2.30.0")] public sealed class Plugin : BaseUnityPlugin { private struct EitrAttackContextState { public int Depth; public bool Secondary; public bool Changed; } private struct EitrReloadCostState { public Attack Attack; public float Value; public bool Changed; } private struct EitrRepairCostState { public Attack Attack; public float Value; public bool Changed; } [HarmonyPatch(typeof(Humanoid), "StartAttack", new Type[] { typeof(Character), typeof(bool) })] private static class EitrAttackContextPatch { private static void Prefix(Humanoid __instance, bool __1, ref EitrAttackContextState __state) { __state = new EitrAttackContextState { Depth = eitrAttackContextDepth, Secondary = eitrAttackContextSecondary, Changed = false }; if (CanScaleLocalEitr((Character)(object)((__instance is Player) ? __instance : null))) { eitrAttackContextDepth++; eitrAttackContextSecondary = __1; __state.Changed = true; } } private static Exception Finalizer(Exception __exception, ref EitrAttackContextState __state) { RestoreEitrAttackContext(ref __state); return __exception; } } [HarmonyPatch(typeof(Attack), "GetAttackEitr", new Type[] { })] private static class EitrAttackCostPatch { private static void Postfix(Attack __instance, Humanoid ___m_character, ref float __result) { if (CanScaleLocalEitr((Character)(object)___m_character) && !(__result <= 0f)) { bool flag; if (eitrAttackContextDepth <= 0) { flag = __instance == eitrActiveAttack && eitrActiveAttackSecondary; } else { flag = eitrAttackContextSecondary; eitrActiveAttack = __instance; eitrActiveAttackSecondary = flag; } float num = (flag ? instance.playerRules.SecondaryEitr : instance.playerRules.PrimaryEitr); if (num != 1f) { __result *= num; } } } } [HarmonyPatch(typeof(ItemData), "GetDrawEitrDrain")] private static class EitrDrawCostPatch { private static void Postfix(ItemData __instance, ref float __result) { Plugin instance = Plugin.instance; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)instance == (Object)null) && instance.playerRulesSynced && !((Object)(object)localPlayer == (Object)null) && __instance != null && !(__result <= 0f)) { float drawEitr = instance.playerRules.DrawEitr; if (drawEitr != 1f && ((Humanoid)localPlayer).GetCurrentWeapon() == __instance) { __result *= drawEitr; } } } } [HarmonyPatch(typeof(Player), "UpdateWeaponLoading", new Type[] { typeof(ItemData), typeof(float) })] private static class EitrReloadCostPatch { private static void Prefix(Player __instance, ItemData __0, ref EitrReloadCostState __state) { __state = ScaleReloadEitrTemporarily(__instance, __0); } private static Exception Finalizer(Exception __exception, ref EitrReloadCostState __state) { RestoreReloadEitr(ref __state); return __exception; } } [HarmonyPatch(typeof(Player), "Repair", new Type[] { typeof(ItemData), typeof(Piece) })] private static class EitrRepairCostPatch { private static void Prefix(Player __instance, ItemData __0, ref EitrRepairCostState __state) { __state = ScaleRepairEitrTemporarily(__instance, __0); } private static Exception Finalizer(Exception __exception, ref EitrRepairCostState __state) { RestoreRepairEitr(ref __state); return __exception; } } private struct RegenTickState { public float Stamina; public float Eitr; public bool Changed; } [HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })] private static class PlayerRegenCalculationPatch { private static void Prefix(Player __instance, ref RegenTickState __state) { __state = default(RegenTickState); Plugin instance = Plugin.instance; if ((Object)(object)instance == (Object)null || !instance.playerVitalsSynced || (Object)(object)__instance == (Object)null || __instance != Player.m_localPlayer) { return; } float staminaRegen = instance.playerVitals.StaminaRegen; float eitrRegen = instance.playerVitals.EitrRegen; if (staminaRegen != 1f || eitrRegen != 1f) { __state.Stamina = __instance.m_staminaRegen; __state.Eitr = __instance.m_eiterRegen; __state.Changed = true; if (staminaRegen != 1f) { __instance.m_staminaRegen = __state.Stamina * staminaRegen; } if (eitrRegen != 1f) { __instance.m_eiterRegen = __state.Eitr * eitrRegen; } } } private static Exception Finalizer(Exception __exception, Player __instance, ref RegenTickState __state) { RestoreRegenTick(__instance, ref __state); return __exception; } } [HarmonyPatch(typeof(Plugin), "BuildPlayerVitals")] private static class EitrRegenVitalsUiPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance, Transform parent) { if ((Object)(object)__instance != (Object)null) { __instance.AddEitrRegenSlider(parent); } } } [HarmonyPatch(typeof(Plugin), "DestroyUI")] private static class EitrRegenUiDestroyPatch { [HarmonyPriority(800)] private static void Prefix(Plugin __instance) { if ((Object)(object)__instance != (Object)null) { __instance.eitrRegenUiAdded = false; } } } [HarmonyPatch(typeof(EnvMan), "FixedUpdate")] private static class EnvironmentPatch { private static void Prefix(EnvMan __instance) { Plugin instance = Plugin.instance; if ((Object)(object)instance == (Object)null || instance.session == null || !instance.session.Synced || instance.session.State.Revision == 0L) { return; } if ((Object)(object)instance.controlledEnvironment != (Object)(object)__instance) { instance.RestoreEnvironment(); instance.controlledEnvironment = __instance; instance.savedWeather = __instance.m_debugEnv; instance.savedTimeEnabled = __instance.m_debugTimeOfDay; instance.savedTime = __instance.m_debugTime; instance.savedWindEnabled = __instance.m_debugWind; instance.savedWindAngle = __instance.m_debugWindAngle; instance.savedWindStrength = __instance.m_debugWindIntensity; instance.controlledEnvironmentRevision = -1L; } long revision = instance.session.State.Revision; if (instance.controlledEnvironmentRevision != revision) { Request settings = instance.session.State.Settings; __instance.m_debugEnv = settings.Weather; if (settings.WindOn) { __instance.SetDebugWind(settings.Angle, settings.Strength); } else { __instance.ResetDebugWind(); } if (settings.TimeMode == 1) { instance.ownedTime = true; __instance.m_debugTimeOfDay = false; } else if (instance.ownedTime) { __instance.m_debugTimeOfDay = false; instance.ownedTime = false; } instance.controlledEnvironmentRevision = revision; } } } [HarmonyPatch(typeof(EnvMan), "RescaleDayFraction")] private static class HeldDayTargetPatch { private static void Postfix(EnvMan __instance, ref float __result) { Plugin instance = Plugin.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.controlledEnvironment == (Object)(object)__instance && instance.session != null && instance.session.Synced && instance.session.State.Settings.TimeMode == 1) { __result = instance.session.State.Settings.Hour / 24f; } } } [HarmonyPatch(typeof(Plugin), "PlayerRule")] private static class PlayerRuleFiveMaxPatch { private static void Postfix(float value, ref bool __result) { __result = !float.IsNaN(value) && !float.IsInfinity(value) && value >= 0f && value <= 5f; } } [HarmonyPatch(typeof(Plugin), "ValidPlayerRules")] private static class PlayerRulesBuffOnlyValidationPatch { [HarmonyPriority(0)] private static void Postfix(PlayerResourceRules r, ref bool __result) { if (__result) { __result = BuffOnlyPlayerRules(r); } } } [HarmonyPatch(typeof(Plugin), "BuildStaminaRules")] private static class StaminaBuffOnlyUiPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance, Transform parent) { SetAllPlayerSliderRanges(parent, 0f, 1f); __instance?.ReplacePlayerRuleFooter(parent, "1.00× = Vanilla · lower = less stamina used · 0.00× = no stamina cost.", "1,00× = Vanilla · niedriger = weniger Ausdauerverbrauch · 0,00× = kein Ausdauerverbrauch."); } } [HarmonyPatch(typeof(Plugin), "BuildEitrRules")] private static class EitrBuffOnlyUiPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance, Transform parent) { SetAllPlayerSliderRanges(parent, 0f, 1f); __instance?.ReplacePlayerRuleFooter(parent, "1.00× = Vanilla · lower = less Eitr used · 0.00× = no Eitr cost.", "1,00× = Vanilla · niedriger = weniger Eitr-Verbrauch · 0,00× = kein Eitr-Verbrauch."); } } [HarmonyPatch(typeof(Plugin), "BuildAdrenalineRules")] private static class AdrenalineBuffOnlyUiPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance, Transform parent) { SetAdrenalineSliderRanges(parent); __instance?.ReplacePlayerRuleFooter(parent, "Gains: 1.00× = Vanilla, higher = more. Penalties: 1.00× = Vanilla, lower = less loss.", "Gewinn: 1,00× = Vanilla, höher = mehr. Verluste: 1,00× = Vanilla, niedriger = weniger Verlust."); } } [HarmonyPatch(typeof(Plugin), "LayoutPlayerTabs")] private static class PlayerResetButtonHookPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance) { if ((Object)(object)__instance != (Object)null) { __instance.EnsurePlayerResetConfirmationHook(); } } } [HarmonyPatch(typeof(Plugin), "DestroyUI")] private static class PlayerResetConfirmationDestroyPatch { [HarmonyPriority(800)] private static void Prefix(Plugin __instance) { if ((Object)(object)__instance != (Object)null) { __instance.ResetPlayerConfirmationReferences(); } } } private sealed class AttackBaseline { public float AttackAdrenaline; } private sealed class ShieldBaseline { public float Block; public float Parry; } [HarmonyPatch(typeof(Plugin), "OpenWindow")] private static class PlayerRulesOpenPatch { private static void Postfix(Plugin __instance) { if (!((Object)(object)__instance == (Object)null)) { if (!__instance.playerRulesDraftDirty) { __instance.playerRulesDraft = __instance.playerRules; } __instance.EnsurePlayerRulesUI(); } } } [HarmonyPatch(typeof(Plugin), "EnsureUI")] private static class PlayerRulesUiPatch { private static void Postfix(Plugin __instance, bool __result) { if (__result && (Object)(object)__instance != (Object)null) { __instance.EnsurePlayerRulesUI(); } } } [HarmonyPatch(typeof(Player), "GetBuildStamina")] private static class PlayerRulesHomeStaminaPatch { private static void Postfix(Player __instance, ref float __result) { Plugin instance = Plugin.instance; if (!((Object)(object)instance == (Object)null) && instance.playerRulesSynced && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { __result *= instance.playerRules.HomeStamina; } } } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] private static class PlayerVitalMaximumPatch { private static void Postfix(Player __instance, ref float __0, ref float __1, ref float __2) { Plugin instance = Plugin.instance; if (!((Object)(object)instance == (Object)null) && instance.playerVitalsSynced && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { __0 *= instance.playerVitals.MaxHealth; __1 *= instance.playerVitals.MaxStamina; __2 *= instance.playerVitals.MaxEitr; } } } [HarmonyPatch(typeof(Plugin), "EnsureUI")] private static class PlayerVitalsUiPatch { private static void Postfix(Plugin __instance, bool __result) { if (__result && (Object)(object)__instance != (Object)null) { __instance.EnsurePlayerVitalsUI(); } } } [HarmonyPatch(typeof(Plugin), "OpenWindow")] private static class PlayerVitalsOpenPatch { private static void Postfix(Plugin __instance) { if (!((Object)(object)__instance == (Object)null)) { if (!__instance.playerVitalsDraftDirty) { __instance.playerVitalsDraft = __instance.playerVitals; } __instance.EnsurePlayerVitalsUI(); } } } [HarmonyPatch(typeof(Plugin), "EndSession")] private static class PlayerVitalsSessionEndPatch { private static void Prefix(Plugin __instance) { if ((Object)(object)__instance != (Object)null) { __instance.RestorePlayerVitalsLocal(); } } } [HarmonyPatch(typeof(Plugin), "VitalSlider")] private static class PlayerVitalsSliderRangePatch { private static void Prefix(ref float __4, ref float __5) { __4 = 1f; __5 = 5f; } } [HarmonyPatch(typeof(Plugin), "ValidVitalMax")] private static class PlayerVitalsMaxValidationPatch { private static void Postfix(float value, ref bool __result) { __result = !float.IsNaN(value) && !float.IsInfinity(value) && value >= 1f && value <= 5f; } } [HarmonyPatch(typeof(Plugin), "ValidVitalRegen")] private static class PlayerVitalsRegenValidationPatch { private static void Postfix(float value, ref bool __result) { __result = !float.IsNaN(value) && !float.IsInfinity(value) && value >= 1f && value <= 5f; } } [HarmonyPatch(typeof(RandEventSystem), "UpdateRandomEvent")] private static class EventPausePatch { private static bool Prefix() { if (!((Object)(object)instance == (Object)null) && instance.session != null && instance.session.Server) { return !instance.session.State.Settings.EventsPaused; } return true; } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] private static class SessionEndPatch { private static void Prefix(ZNet __instance) { if ((Object)(object)instance != (Object)null && instance.network == __instance) { instance.EndSession(); } } } private struct RainWetState { public bool Original; public bool Changed; } [HarmonyPatch(typeof(Plugin), "BuildWeather")] private static class RainDamageWeatherUiPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance, Transform parent) { if ((Object)(object)__instance != (Object)null) { __instance.AddRainDamageToggle(parent); } } } [HarmonyPatch(typeof(WearNTear), "IsWet")] private static class RainDamageWearPatch { private static void Prefix(WearNTear __instance, ref RainWetState __state) { __state = default(RainWetState); Plugin instance = Plugin.instance; if ((Object)(object)instance == (Object)null || instance.session == null || !instance.session.Synced || !instance.session.State.Settings.NoRainDamage || (Object)(object)__instance == (Object)null || !TryGetRainWetField()) { return; } try { ref bool reference = ref rainWetField.Invoke(__instance); __state.Original = reference; __state.Changed = true; reference = false; } catch { } } private static Exception Finalizer(Exception __exception, WearNTear __instance, ref RainWetState __state) { RestoreRainWet(__instance, ref __state); return __exception; } } [HarmonyPatch(typeof(Plugin), "Remember")] private static class RainDamageRememberPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance) { if ((Object)(object)__instance != (Object)null) { __instance.RememberRainDamageSetting(); } } } [HarmonyPatch(typeof(Plugin), "Recall")] private static class RainDamageRecallPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance) { if ((Object)(object)__instance != (Object)null) { __instance.RecallRainDamageSetting(); } } } [HarmonyPatch(typeof(Plugin), "Players")] private static class PlayerListFrameCache { private static bool Prefix(ref List<PlayerInfo> __result) { if (playersCachedFrame != Time.frameCount) { return true; } __result = PlayerBuffer; return false; } private static void Postfix(ref List<PlayerInfo> __result) { playersCachedFrame = Time.frameCount; __result = PlayerBuffer; } } private struct StaminaAttackContextState { public int Depth; public bool Secondary; public bool Changed; } private struct StaminaReloadState { public Attack Attack; public float Value; public bool Changed; } private struct BlockStaminaState { public float Normal; public float Perfect; public bool Changed; } [HarmonyPatch(typeof(Humanoid), "StartAttack", new Type[] { typeof(Character), typeof(bool) })] private static class StaminaAttackContextPatch { private static void Prefix(Humanoid __instance, bool __1, ref StaminaAttackContextState __state) { __state = new StaminaAttackContextState { Depth = staminaAttackContextDepth, Secondary = staminaAttackContextSecondary, Changed = false }; if (CanScaleLocalStamina((Character)(object)((__instance is Player) ? __instance : null))) { staminaAttackContextDepth++; staminaAttackContextSecondary = __1; __state.Changed = true; } } private static Exception Finalizer(Exception __exception, ref StaminaAttackContextState __state) { RestoreStaminaAttackContext(ref __state); return __exception; } } [HarmonyPatch(typeof(Attack), "GetAttackStamina", new Type[] { })] private static class StaminaAttackCostPatch { private static void Postfix(Attack __instance, Humanoid ___m_character, ref float __result) { Plugin instance = Plugin.instance; if (!((Object)(object)instance == (Object)null) && instance.playerRulesSynced && CanScaleLocalStamina((Character)(object)___m_character) && !(__result <= 0f) && (__instance == null || !__instance.m_isHomeItem)) { bool flag; if (staminaAttackContextDepth <= 0) { flag = __instance == staminaActiveAttack && staminaActiveAttackSecondary; } else { flag = staminaAttackContextSecondary; staminaActiveAttack = __instance; staminaActiveAttackSecondary = flag; } float num = (flag ? instance.playerRules.SecondaryStamina : instance.playerRules.PrimaryStamina); if (num != 1f) { __result *= num; } } } } [HarmonyPatch(typeof(ItemData), "GetDrawStaminaDrain")] private static class StaminaDrawCostPatch { private static void Postfix(ItemData __instance, ref float __result) { Plugin instance = Plugin.instance; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)instance == (Object)null) && instance.playerRulesSynced && !((Object)(object)localPlayer == (Object)null) && __instance != null && !(__result <= 0f)) { float drawStamina = instance.playerRules.DrawStamina; if (drawStamina != 1f && ((Humanoid)localPlayer).GetCurrentWeapon() == __instance) { __result *= drawStamina; } } } } [HarmonyPatch(typeof(Player), "UpdateWeaponLoading", new Type[] { typeof(ItemData), typeof(float) })] private static class StaminaReloadCostPatch { private static void Prefix(Player __instance, ItemData __0, ref StaminaReloadState __state) { __state = default(StaminaReloadState); if (CanScaleLocalStamina((Character)(object)__instance) && __0 != null && __0.m_shared != null && __0.m_shared.m_attack != null) { float reloadStamina = instance.playerRules.ReloadStamina; if (reloadStamina != 1f) { Attack val = (__state.Attack = __0.m_shared.m_attack); __state.Value = val.m_reloadStaminaDrain; __state.Changed = true; val.m_reloadStaminaDrain = __state.Value * reloadStamina; } } } private static Exception Finalizer(Exception __exception, ref StaminaReloadState __state) { RestoreStaminaReload(ref __state); return __exception; } } [HarmonyPatch(typeof(Humanoid), "BlockAttack", new Type[] { typeof(HitData), typeof(Character) })] private static class BlockStaminaCostPatch { private static void Prefix(Humanoid __instance, ref BlockStaminaState __state) { __state = default(BlockStaminaState); if (CanScaleLocalStamina((Character)(object)((__instance is Player) ? __instance : null))) { float block = instance.playerRules.Block; if (block != 1f) { __state.Normal = __instance.m_blockStaminaDrain; __state.Perfect = __instance.m_perfectBlockStaminaDrain; __state.Changed = true; __instance.m_blockStaminaDrain = __state.Normal * block; __instance.m_perfectBlockStaminaDrain = __state.Perfect * block; } } } private static Exception Finalizer(Exception __exception, Humanoid __instance, ref BlockStaminaState __state) { RestoreBlockStamina(__instance, ref __state); return __exception; } } private sealed class TerrainOpSnapshot { private readonly TerrainOp op; private readonly float level; private readonly float raise; private readonly float smooth; private readonly float paint; public TerrainOpSnapshot(TerrainOp value) { op = value; Settings settings = value.m_settings; level = settings.m_levelRadius; raise = settings.m_raiseRadius; smooth = settings.m_smoothRadius; paint = settings.m_paintRadius; } public void Restore() { if (!((Object)(object)op == (Object)null) && op.m_settings != null) { op.m_settings.m_levelRadius = level; op.m_settings.m_raiseRadius = raise; op.m_settings.m_smoothRadius = smooth; op.m_settings.m_paintRadius = paint; } } } private sealed class TerrainModifierSnapshot { private readonly TerrainModifier modifier; private readonly float level; private readonly float smooth; public TerrainModifierSnapshot(TerrainModifier value) { modifier = value; level = value.m_levelRadius; smooth = value.m_smoothRadius; } public void Restore() { if (!((Object)(object)modifier == (Object)null)) { modifier.m_levelRadius = level; modifier.m_smoothRadius = smooth; } } } private sealed class PlacementRadiusScope { public readonly HashSet<int> Seen = new HashSet<int>(); public readonly List<TerrainOpSnapshot> Ops = new List<TerrainOpSnapshot>(); public readonly List<TerrainModifierSnapshot> Modifiers = new List<TerrainModifierSnapshot>(); public void Restore() { foreach (TerrainOpSnapshot op in Ops) { op.Restore(); } foreach (TerrainModifierSnapshot modifier in Modifiers) { modifier.Restore(); } } } [HarmonyPatch] private static class TerrainPlacementPatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!(methodInfo.Name != "TryPlacePiece") && !(methodInfo.ReturnType != typeof(bool))) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(Piece)) { yield return methodInfo; } } } } [HarmonyPriority(800)] private static bool Prefix(Player __instance, Piece piece, ref bool __result) { RestoreTerrainRadiusScope(); Plugin instance = Plugin.instance; if ((Object)(object)instance == (Object)null || instance.terrainEnabled == null || !instance.terrainEnabled.Value || !instance.CanEdit || (Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || (Object)(object)piece == (Object)null) { return true; } if (instance.IsTerrainRampPiece(piece)) { __result = instance.ApplyRamp(__instance); return false; } if (instance.IsTerrainRevertPiece(piece)) { __result = instance.ApplyRevert(__instance); return false; } if (instance.terrainToolRadiusEnabled == null || !instance.terrainToolRadiusEnabled.Value) { return true; } TerrainToolKind terrainToolKind = GetTerrainToolKind(((Humanoid)__instance).GetCurrentWeapon()); if (terrainToolKind == TerrainToolKind.None) { return true; } float configuredTerrainRadius = instance.GetConfiguredTerrainRadius(terrainToolKind); PlacementRadiusScope placementRadiusScope = new PlacementRadiusScope(); try { ScaleTerrainComponents(((Component)piece).gameObject, configuredTerrainRadius, placementRadiusScope); Piece val = null; try { val = __instance.GetSelectedPiece(); } catch { } if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)piece) { ScaleTerrainComponents(((Component)val).gameObject, configuredTerrainRadius, placementRadiusScope); } if (placementRadiusScope.Ops.Count == 0 && placementRadiusScope.Modifiers.Count == 0) { placementRadiusScope.Restore(); return true; } terrainActiveRadiusScope = placementRadiusScope; } catch { placementRadiusScope.Restore(); throw; } return true; } private static Exception Finalizer(Exception __exception) { RestoreTerrainRadiusScope(); return __exception; } } [HarmonyPatch] private static class TerrainGridMovementPatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "SetControls") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); foreach (ParameterInfo parameterInfo in parameters) { if (parameterInfo.Name == "movedir" && parameterInfo.ParameterType == typeof(Vector3)) { yield return methodInfo; break; } } } } private static void Prefix(Player __instance, ref Vector3 movedir) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) Plugin instance = Plugin.instance; if ((Object)(object)instance == (Object)null || instance.terrainEnabled == null || !instance.terrainEnabled.Value || instance.terrainGridMovement == null || !instance.terrainGridMovement.Value || !instance.CanEdit || instance.windowOpen || (Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !IsTerrainPickaxe(((Humanoid)__instance).GetCurrentWeapon()) || instance.terrainFlattenHold == null || !ShortcutHeld(instance.terrainFlattenHold.Value)) { return; } Vector2 val = new Vector2(movedir.x, movedir.z); float num = Mathf.Clamp01(((Vector2)(ref val)).magnitude); if (!(num < 0.001f)) { Vector3 val2 = ((Character)__instance).GetLookDir(); val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.001f) { val2 = ((Component)__instance).transform.forward; val2.y = 0f; } ((Vector3)(ref val2)).Normalize(); Vector3 val3 = Vector3.Cross(Vector3.up, val2); Vector3 normalized = ((Vector3)(ref val3)).normalized; Vector3 val4 = val2 * movedir.z + normalized * movedir.x; val4.y = 0f; if (!(((Vector3)(ref val4)).sqrMagnitude < 0.001f)) { ((Vector3)(ref val4)).Normalize(); float num2 = Mathf.Round(Mathf.Atan2(val4.x, val4.z) * 57.29578f / 45f) * 45f * ((float)Math.PI / 180f); Vector3 val5 = new Vector3(Mathf.Sin(num2), 0f, Mathf.Cos(num2)) * num; movedir.x = Vector3.Dot(val5, normalized); movedir.z = Vector3.Dot(val5, val2); movedir.y = 0f; } } } } [HarmonyPatch(typeof(Plugin), "CreateTerrainActionPiece")] private static class TerrainActionPieceUsagePatch { [HarmonyPriority(0)] private static void Postfix(PieceTable table, GameObject __result) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)table == (Object)null || (Object)(object)__result == (Object)null) { return; } Piece component = __result.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { return; } int num = FindHoeGroundIndex(table); if (num >= 0 && num < table.m_pieces.Count && (Object)(object)table.m_pieces[num] != (Object)null) { Piece component2 = table.m_pieces[num].GetComponent<Piece>(); if ((Object)(object)component2 != (Object)null) { component.m_category = component2.m_category; component.m_usage = (UsageTagFlags)(((int)component2.m_usage == 0) ? 1 : ((int)component2.m_usage)); return; } } if ((int)component.m_usage == 0) { component.m_usage = (UsageTagFlags)1; } } } [HarmonyPatch(typeof(Plugin), "DestroyUI")] private static class DynamicUiDestroyPatch { [HarmonyPriority(800)] private static void Prefix(Plugin __instance) { if ((Object)(object)__instance != (Object)null) { __instance.ResetDynamicUiReferences(); } } } [HarmonyPatch(typeof(Plugin), "EnsureUI")] private static class PlayerLayoutCreationPatch { [HarmonyPriority(0)] private static void Postfix(Plugin __instance, bool __result) { if (__result && !((Object)(object)__instance == (Object)null)) { __instance.EnsurePlayerPageLayout(); __instance.PolishMainWindow(); } } } [HarmonyPatch(typeof(ZCursor), "set_LockState")] private static class PointerLockGuard { [HarmonyPriority(0)] private static bool Prefix(ref CursorLockMode value) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 if (!OwnsPointer) { return true; } if (value) { instance.preventedCursorLocks++; } value = (CursorLockMode)0; return (int)Cursor.lockState > 0; } } [HarmonyPatch(typeof(ZCursor), "Hide")] private static class PointerVisibilityGuard { private static bool Prefix() { return !OwnsPointer; } } [HarmonyPatch(typeof(Menu), "Update")] private static class EscapePatch { private static bool Prefix() { return !BlockInput; } } private static int eitrAttackContextDepth; private static bool eitrAttackContextSecondary; private static Attack eitrActiveAttack; private static bool eitrActiveAttackSecondary; private bool eitrRegenUiAdded; private EnvMan controlledEnvironment; private string savedWeather; private float savedTime; private float savedWindAngle; private float savedWindStrength; private bool savedTimeEnabled; private bool savedWindEnabled; private bool ownedTime; private long controlledEnvironmentRevision = -1L; private const float PlayerReductionMin = 0f; private const float PlayerReductionMax = 1f; private const float PlayerBoostMin = 1f; private const float PlayerBoostMax = 5f; private Button playerResetHookedButton; private GameObject playerResetConfirmOverlay; private const int PlayerRulesWireVersion = 1; private const string PlayerRulesRequestRpc = "DezzyCode.WorldControl.PlayerRules.Request.v1"; private const string PlayerRulesStateRpc = "DezzyCode.WorldControl.PlayerRules.State.v1"; private const float PlayerRuleMin = 0f; private const float PlayerRuleMax = 3f; private readonly HashSet<ZRpc> playerRulesRegistered = new HashSet<ZRpc>(); private readonly Dictionary<ZRpc, float> playerRulesRequests = new Dictionary<ZRpc, float>(); private readonly Dictionary<ZRpc, float> playerRulesEdits = new Dictionary<ZRpc, float>(); private readonly List<ZRpc> playerRulesStale = new List<ZRpc>(); private ConfigEntry<string> playerRulesStored; private bool playerRulesConfigReady; private bool playerRulesLoadedForServer; private bool playerRulesSynced; private bool playerRulesDraftDirty; private long playerRulesRevision; private float nextPlayerRulesQuery; private ZNet playerRulesNetwork; private PlayerResourceRules playerRules = PlayerResourceRules.Vanilla; private PlayerResourceRules playerRulesDraft = PlayerResourceRules.Vanilla; private int playerPageMode = 4; private GameObject playerStaminaPanel; private GameObject playerEitrPanel; private GameObject playerAdrenalinePanel; private Text playerRulesStatus; private Player playerRulesAppliedPlayer; private readonly Dictionary<string, float> playerFieldBaselines = new Dictionary<string, float>(); private ObjectDB playerRulesObjectDb; private long playerRulesAppliedRevision = -1L; private readonly Dictionary<Attack, AttackBaseline> attackBaselines = new Dictionary<Attack, AttackBaseline>(); private readonly Dictionary<Projectile, float> projectileBaselines = new Dictionary<Projectile, float>(); private readonly Dictionary<SharedData, ShieldBaseline> shieldBaselines = new Dictionary<SharedData, ShieldBaseline>(); private const int PlayerVitalsWireVersion = 2; private const string PlayerVitalsRequestRpc = "DezzyCode.WorldControl.PlayerVitals.Request.v1"; private const string PlayerVitalsStateRpc = "DezzyCode.WorldControl.PlayerVitals.State.v1"; private const float VitalMaxMin = 0.1f; private const float VitalMaxMax = 3f; private const float VitalRegenMin = 0f; private const float VitalRegenMax = 3f; private readonly HashSet<ZRpc> playerVitalsRegistered = new HashSet<ZRpc>(); private readonly Dictionary<ZRpc, float> playerVitalsRequests = new Dictionary<ZRpc, float>(); private readonly Dictionary<ZRpc, float> playerVitalsEdits = new Dictionary<ZRpc, float>(); private readonly List<ZRpc> playerVitalsStale = new List<ZRpc>(); private ConfigEntry<string> playerVitalsStored; private bool playerVitalsConfigReady; private bool playerVitalsLoadedForServer; private bool playerVitalsSynced; private bool playerVitalsDraftDirty; private long playerVitalsRevision; private long playerVitalsAppliedRevision = -1L; private float nextPlayerVitalsQuery; private float nextPlayerVitalsMaintenance; private ZNet playerVitalsNetwork; private PlayerVitalRules playerVitals = PlayerVitalRules.Vanilla; private PlayerVitalRules playerVitalsDraft = PlayerVitalRules.Vanilla; private Player playerVitalsAppliedPlayer; private bool playerVitalsUpdateFoodWarned; private GameObject playerVitalsPanel; private Button playerVitalsTabButton; private Text playerVitalsInfo; private static MethodInfo PlayerUpdateFoodMethod; private static bool playerUpdateFoodResolved; private const float VitalBoostMin = 1f; private const float VitalBoostMax = 5f; public const string PluginGuid = "dezzycode.valheim.windcontrol"; private const string RequestRpc = "DezzyCode.WorldControl.Request.v3"; private const string StateRpc = "DezzyCode.WorldControl.State.v3"; private const string TeleportRpc = "DezzyCode.WorldControl.Teleport.v1"; private const string SayRpc = "DezzyCode.WorldControl.Say.v1"; private static Plugin instance; private Harmony harmony; private ZNet network; private Session session; private readonly HashSet<ZRpc> registered = new HashSet<ZRpc>(); private readonly HashSet<ZRpc> participants = new HashSet<ZRpc>(); private readonly List<ZRpc> stale = new List<ZRpc>(); private readonly Dictionary<ZRpc, ZNetPeer> peersByRpc = new Dictionary<ZRpc, ZNetPeer>(); private readonly Dictionary<ZRpc, float> edits = new Dictionary<ZRpc, float>(); private readonly Dictionary<ZRpc, float> queries = new Dictionary<ZRpc, float>(); private InitialSync initialSync = new InitialSync(); private ZRpc serverConnection; private bool openWhenSynced; private float nextManualQuery; private float nextPeerMaintenance; private int knownPeerCount = -1; private ConfigEntry<KeyCode> toggleKey; private ConfigEntry<UiLanguage> language; private readonly ConfigEntry<string>[] presets = new ConfigEntry<string>[3]; private readonly ConfigEntry<string>[] places = new ConfigEntry<string>[3]; private ConfigEntry<string> stored; private bool recalled; private UiLanguage builtFor; private bool windowOpen; private int blockThroughFrame = -1; private string statusKey = "status.checking"; private Request draft = Protocol.Defaults; private static FieldRef<RandEventSystem, RandomEvent> randomEventField; private static bool randomEventTried; private static FieldRef<WearNTear, bool> rainWetField; private static bool rainWetFieldTried; private float nextPlayerRulesMaintenance; private float nextPlayerVitalsTickOptimized; private static int playersCachedFrame = -1; private static int staminaAttackContextDepth; private static bool staminaAttackContextSecondary; private static Attack staminaActiveAttack; private static bool staminaActiveAttackSecondary; private ConfigEntry<bool> terrainEnabled; private ConfigEntry<float> terrainFlattenSize; private ConfigEntry<float> terrainFlattenSmoothness; private ConfigEntry<TerrainFlattenShape> terrainFlattenShape; private ConfigEntry<TerrainGroundTexture> terrainGroundTexture; private ConfigEntry<KeyboardShortcut> terrainFlattenHold; private ConfigEntry<bool> terrainGridMovement; private ConfigEntry<bool> terrainToolRadiusEnabled; private ConfigEntry<float> terrainHoeRadius; private ConfigEntry<float> terrainCultivatorRadius; private ConfigEntry<KeyboardShortcut> terrainRadiusIncrease; private ConfigEntry<KeyboardShortcut> terrainRadiusDecrease; private ConfigEntry<float> terrainRampThickness; private ConfigEntry<float> terrainRevertRadius; private bool terrainHolding; private Vector3 terrainLastCenter = new Vector3(100000f, 100000f, 100000f); private float terrainLastSize = -1f; private float terrainLastSmooth = -1f; private float terrainLastApply = -10f; private TerrainFlattenShape terrainLastShape; private TerrainGroundTexture terrainLastTexture; private bool terrainBackendWarned; private GameObject terrainPreviewRoot; private LineRenderer flattenPreview; private LineRenderer radiusPreview; private LineRenderer rampOutlinePreview; private LineRenderer rampCenterPreview; private LineRenderer revertPreview; private Material flattenPreviewMaterial; private Material radiusPreviewMaterial; private Material rampPreviewMaterial; private Material revertPreviewMaterial; private PieceTable terrainHoeTable; private GameObject terrainRampPrefab; private GameObject terrainRevertPrefab; private Texture2D terrainRampIconTexture; private Texture2D terrainRevertIconTexture; private Sprite terrainRampIcon; private Sprite terrainRevertIcon; private static MethodInfo terrainUpdatePiecesMethod; private static FieldInfo terrainHmapField; private static FieldInfo terrainLevelDeltaField; private static FieldInfo terrainSmoothDeltaField; private static FieldInfo terrainModifiedHeightField; private static FieldInfo terrainPaintMaskField; private static FieldInfo terrainModifiedPaintField; private static FieldInfo terrainNviewField; private static MethodInfo terrainSaveMethod; private static PlacementRadiusScope terrainActiveRadiusScope; private static readonly RaycastHit[] TerrainRaycastBuffer = (RaycastHit[])(object)new RaycastHit[256]; private static readonly HashSet<TerrainComp> TerrainCompilerBuffer = new HashSet<TerrainComp>(); private static readonly object[] TerrainSaveArguments = new object[1] { false }; private static bool terrainFastAccessTried; private static FieldRef<TerrainComp, Heightmap> terrainHmapFastRef; private static FieldRef<TerrainComp, float[]> terrainLevelDeltaFastRef; private static FieldRef<TerrainComp, float[]> terrainSmoothDeltaFastRef; private static FieldRef<TerrainComp, bool[]> terrainModifiedHeightFastRef; private static FieldRef<TerrainComp, Color[]> terrainPaintMaskFastRef; private static FieldRef<TerrainComp, bool[]> terrainModifiedPaintFastRef; private static FieldRef<TerrainComp, ZNetView> terrainNviewFastRef; private static Action<TerrainComp, bool> terrainSaveFast; private float terrainNextPreviewUpdate; private float terrainNextPieceCheck; private bool terrainPieceTextReady; private bool terrainPieceTextGerman; private GameObject playerLayoutPanel; private GameObject playerLayoutStamina; private GameObject playerLayoutEitr; private GameObject playerLayoutAdrenaline; private GameObject playerLayoutVitals; private GameObject polishedMainPanel; private Button playerSharedResetButton; internal const float UiWindowWidth = 1480f; internal const float UiWindowHeight = 760f; internal const float UiContentX = 230f; internal const float UiContentY = 150f; internal const float UiContentWidth = 1220f; internal const float UiContentHeight = 420f; private const int PageTime = 0; private const int PageWeather = 1; private const int PageWind = 2; private const int PageEvents = 3; private const int PagePresets = 4; private const int PagePlayers = 5; private const int PagePlaces = 6; private const int PageSay = 7; private const int PagePlayerValues = 8; private const int PageTerrain = 9; private const int PageCount = 10; private static readonly string[] TabKeys = new string[10] { "tab.time", "tab.weather", "tab.wind", "tab.events", "tab.presets", "tab.players", "tab.places", "tab.say", "tab.values", "tab.terrain" }; private GameObject panel; private readonly GameObject[] pages = (GameObject[])(object)new GameObject[10]; private InputField _message; private InputField _placeName; private int eventPage; private int playerPage; private static List<string> eventNames; private readonly List<Action> refresh = new List<Action>(); private Text clockText; private Text statusText; private Button applyButton; private Button resetButton; private bool uiInputBlocked; private bool controlsDirty; private int preventedCursorLocks; private int recoveredCursorLocks; private static Sprite mark; private static bool markMissing; private int tab; private float nextUiRequest; private float nextUiRefresh; private const int EventsPerPage = 5; private static readonly Dictionary<string, string> EventTitles = new Dictionary<string, string>(); private static readonly Biome[] SingleBiomes; private const int PlayersPerPage = 5; private static readonly List<PlayerInfo> PlayerBuffer; private static readonly CultureInfo Culture; private static readonly float[] Holds; private bool HasState { get { if (session == null || !session.Synced || (Object)(object)network == (Object)null) { return false; } if (session.Server) { return true; } ZNetPeer serverPeer = network.GetServerPeer(); if (serverPeer != null && serverConnection != null && serverPeer.m_rpc == serverConnection) { return serverConnection.IsConnected(); } return false; } } private bool CanEdit { get { if (HasState) { if (!session.Server) { return session.State.CanEdit; } return true; } return false; } } private static bool BlockInput { get { if ((Object)(object)instance != (Object)null) { if (!instance.windowOpen) { return Time.frameCount <= instance.blockThroughFrame; } return true; } return false; } } private static bool OwnsPointer { get { if ((Object)(object)instance != (Object)null && instance.windowOpen) { return Application.isFocused; } return false; } } private static bool CanScaleLocalEitr(Character character) { Plugin plugin = instance; if ((Object)(object)plugin != (Object)null && plugin.playerRulesSynced && (Object)(object)character != (Object)null) { return (object)character == Player.m_localPlayer; } return false; } private static EitrReloadCostState ScaleReloadEitrTemporarily(Player player, ItemData weapon) { EitrReloadCostState result = default(EitrReloadCostState); if (!CanScaleLocalEitr((Character)(object)player) || weapon == null || weapon.m_shared == null || weapon.m_shared.m_attack == null) { return result; } float reloadEitr = instance.playerRules.ReloadEitr; if (reloadEitr == 1f) { return result; } Attack val = (result.Attack = weapon.m_shared.m_attack); result.Value = val.m_reloadEitrDrain; result.Changed = true; val.m_reloadEitrDrain = result.Value * reloadEitr; return result; } private static void RestoreReloadEitr(ref EitrReloadCostState state) { if (state.Changed) { if (state.Attack != null) { state.Attack.m_reloadEitrDrain = state.Value; } state.Changed = false; } } private static EitrRepairCostState ScaleRepairEitrTemporarily(Player player, ItemData tool) { EitrRepairCostState result = default(EitrRepairCostState); if (!CanScaleLocalEitr((Character)(object)player) || tool == null || tool.m_shared == null || tool.m_shared.m_attack == null) { return result; } float primaryEitr = instance.playerRules.PrimaryEitr; if (primaryEitr == 1f) { return result; } Attack val = (result.Attack = tool.m_shared.m_attack); result.Value = val.m_attackEitr; result.Changed = true; val.m_attackEitr = result.Value * primaryEitr; return result; } private static void RestoreRepairEitr(ref EitrRepairCostState state) { if (state.Changed) { if (state.Attack != null) { state.Attack.m_attackEitr = state.Value; } state.Changed = false; } } private static void RestoreEitrAttackContext(ref EitrAttackContextState state) { if (state.Changed) { eitrAttackContextDepth = state.Depth; eitrAttackContextSecondary = state.Secondary; state.Changed = false; } } private static void RestoreRegenTick(Player player, ref RegenTickState state) { if (state.Changed) { if ((Object)(object)player != (Object)null) { player.m_staminaRegen = state.Stamina; player.m_eiterRegen = state.Eitr; } state.Changed = false; } } private void AddEitrRegenSlider(Transform parent) { if (!((Object)(object)parent == (Object)null) && !eitrRegenUiAdded) { eitrRegenUiAdded = true; VitalSlider(parent, 0f, 246f, 650f, 0f, 3f, "Eitr regeneration", "Eitr-Regeneration", () => playerVitalsDraft.EitrRegen, delegate(float v) { playerVitalsDraft.EitrRegen = v; }); if ((Object)(object)playerVitalsInfo != (Object)null) { Position(((Component)playerVitalsInfo).gameObject, 6f, 322f, 1318f, 54f); } } } private void RestoreEnvironment() { if ((Object)(object)controlledEnvironment != (Object)null) { controlledEnvironment.m_debugEnv = savedWeather; controlledEnvironment.m_debugTimeOfDay = savedTimeEnabled; controlledEnvironment.m_debugTime = savedTime; if (savedWindEnabled) { controlledEnvironment.SetDebugWind(savedWindAngle, savedWindStrength); } else { controlledEnvironment.ResetDebugWind(); } } controlledEnvironment = null; ownedTime = false; controlledEnvironmentRevision = -1L; } private static bool InRange(float value, float min, float max) { if (!float.IsNaN(value) && !float.IsInfinity(value) && value >= min) { return value <= max; } return false; } private static bool BuffOnlyPlayerRules(PlayerResourceRules r) { if (!InRange(r.Run, 0f, 1f) || !InRange(r.Jump, 0f, 1f) || !InRange(r.Dodge, 0f, 1f) || !InRange(r.Swim, 0f, 1f) || !InRange(r.Sneak, 0f, 1f) || !InRange(r.Encumbered, 0f, 1f) || !InRange(r.Block, 0f, 1f) || !InRange(r.Grapple, 0f, 1f) || !InRange(r.PrimaryStamina, 0f, 1f) || !InRange(r.SecondaryStamina, 0f, 1f) || !InRange(r.DrawStamina, 0f, 1f) || !InRange(r.ReloadStamina, 0f, 1f) || !InRange(r.HomeStamina, 0f, 1f) || !InRange(r.PrimaryEitr, 0f, 1f) || !InRange(r.SecondaryEitr, 0f, 1f) || !InRange(r.DrawEitr, 0f, 1f) || !InRange(r.ReloadEitr, 0f, 1f)) { return false; } if (!InRange(r.PrimaryAdrenaline, 1f, 5f) || !InRange(r.SecondaryAdrenaline, 1f, 5f) || !InRange(r.ProjectileAdrenaline, 1f, 5f) || !InRange(r.BlockAdrenaline, 1f, 5f) || !InRange(r.ParryAdrenaline, 1f, 5f) || !InRange(r.PerfectDodgeAdrenaline, 1f, 5f) || !InRange(r.StaggerAdrenaline, 1f, 5f) || !InRange(r.GuardianAdrenaline, 1f, 5f)) { return false; } if (InRange(r.MissAdrenaline, 0f, 1f)) { return InRange(r.DamageAdrenaline, 0f, 1f); } return false; } private static void SetAllPlayerSliderRanges(Transform parent, float min, float max) { if ((Object)(object)parent == (Object)null) { return; } Slider[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Slider>(true); foreach (Slider val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { val.minValue = min; val.maxValue = max; val.SetValueWithoutNotify(Mathf.Clamp(val.value, min, max)); } } } private static void SetAdrenalineSliderRanges(Transform parent) { if ((Object)(object)parent == (Object)null) { return; } Slider[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Slider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Slider val = componentsInChildren[i]; if (!((Object)(object)val == (Object)null)) { bool flag = i == 7 || i == 8; val.minValue = (flag ? 0f : 1f); val.maxValue = (flag ? 1f : 5f); val.SetValueWithoutNotify(Mathf.Clamp(val.value, val.minValue, val.maxValue)); } } } private void ReplacePlayerRuleFooter(Transform parent, string english, string german) { if ((Object)(object)parent == (Object)null) { return; } string text = PR(english, german); Text[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Text>(true); foreach (Text val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(val.text) && (val.text.Contains("1.00×") || val.text.Contains("1,00×"))) { val.text = text; break; } } } private void EnsurePlayerResetConfirmationHook() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown if (!((Object)(object)playerSharedResetButton == (Object)null) && playerResetHookedButton != playerSharedResetButton) { playerResetHookedButton = playerSharedResetButton; ((UnityEventBase)playerSharedResetButton.onClick).RemoveAllListeners(); ((UnityEvent)playerSharedResetButton.onClick).AddListener((UnityAction)delegate { ShowPlayerResetConfirmation(); controlsDirty = true; }); } } private void ShowPlayerResetConfirmation() { if (!((Object)(object)pages[8] == (Object)null)) { if ((Object)(object)playerResetConfirmOverlay == (Object)null) { BuildPlayerResetConfirmation(); } if (!((Object)(object)playerResetConfirmOverlay == (Object)null)) { playerResetConfirmOverlay.transform.SetAsLastSibling(); playerResetConfirmOverlay.SetActive(true); } } } private void BuildPlayerResetConfirmation() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) GameObject val = pages[8]; if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("PlayerResetConfirmation", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(val.transform, false); Position(val2, 0f, 0f, 1220f, 420f); Image component = val2.GetComponent<Image>(); ((Graphic)component).color = new Color(0f, 0f, 0f, 0.58f); ((Graphic)component).raycastTarget = true; GameObject val3 = GUIManager.Instance.CreateWoodpanel(val2.transform, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, 640f, 220f, false); ((Object)val3).name = "PlayerResetConfirmationBox"; Position(val3, 290f, 88f, 640f, 220f); Label(val3.transform, 28f, 22f, 584f, PR("Reset player values?", "Spielerwerte zurücksetzen?"), 24, 38f); Label(val3.transform, 28f, 70f, 584f, PR("Are you sure you want to reset all player values to Vanilla?", "Bist du sicher, dass du alle Spielerwerte auf Vanilla zurücksetzen willst?"), 16, 58f); Button(val3.transform, 28f, 154f, 278f, 40f, PR("Yes, reset", "Ja, zurücksetzen"), delegate { ResetAllPlayerDrafts(); HidePlayerResetConfirmation(); }); Button(val3.transform, 334f, 154f, 278f, 40f, PR("Cancel", "Abbrechen"), HidePlayerResetConfirmation); playerResetConfirmOverlay = val2; playerResetConfirmOverlay.SetActive(false); } } private void HidePlayerResetConfirmation() { if ((Object)(object)playerResetConfirmOverlay != (Object)null) { playerResetConfirmOverlay.SetActive(false); } } private void ResetPlayerConfirmationReferences() { playerResetHookedButton = null; playerResetConfirmOverlay = null; } private void EnsurePlayerRulesConfig() { if (!playerRulesConfigReady) { playerRulesConfigReady = true; playerRulesStored = ((BaseUnityPlugin)this).Config.Bind<string>("Server - Player Rules", "State", "", "Written by the World Control server. Server-authoritative stamina, eitr and adrenaline multipliers."); } } private static bool PlayerRule(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value) && value >= 0f) { return value <= 3f; } return false; } private static bool ValidPlayerRules(PlayerResourceRules r) { if (PlayerRule(r.Run) && PlayerRule(r.Jump) && PlayerRule(r.Dodge) && PlayerRule(r.Swim) && PlayerRule(r.Sneak) && PlayerRule(r.Encumbered) && PlayerRule(r.Block) && PlayerRule(r.Grapple) && PlayerRule(r.PrimaryStamina) && PlayerRule(r.SecondaryStamina) && PlayerRule(r.DrawStamina) && PlayerRule(r.ReloadStamina) && PlayerRule(r.HomeStamina) && PlayerRule(r.PrimaryEitr) && PlayerRule(r.SecondaryEitr) && PlayerRule(r.DrawEitr) && PlayerRule(r.ReloadEitr) && PlayerRule(r.PrimaryAdrenaline) && PlayerRule(r.SecondaryAdrenaline) && PlayerRule(r.ProjectileAdrenaline) && PlayerRule(r.BlockAdrenaline) && PlayerRule(r.ParryAdrenaline) && PlayerRule(r.PerfectDodgeAdrenaline) && PlayerRule(r.StaggerAdrenaline) && PlayerRule(r.MissAdrenaline) && PlayerRule(r.DamageAdrenaline)) { return PlayerRule(r.GuardianAdrenaline); } return false; } private static void WritePlayerRules(BinaryWriter w, PlayerResourceRules r) { w.Write(r.Run); w.Write(r.Jump); w.Write(r.Dodge); w.Write(r.Swim); w.Write(r.Sneak); w.Write(r.Encumbered); w.Write(r.Block); w.Write(r.Grapple); w.Write(r.PrimaryStamina); w.Write(r.SecondaryStamina); w.Write(r.DrawStamina); w.Write(r.ReloadStamina); w.Write(r.HomeStamina); w.Write(r.PrimaryEitr); w.Write(r.SecondaryEitr); w.Write(r.DrawEitr); w.Write(r.ReloadEitr); w.Write(r.PrimaryAdrenaline); w.Write(r.SecondaryAdrenaline); w.Write(r.ProjectileAdrenaline); w.Write(r.BlockAdrenaline); w.Write(r.ParryAdrenaline); w.Write(r.PerfectDodgeAdrenaline); w.Write(r.StaggerAdrenaline); w.Write(r.MissAdrenaline); w.Write(r.DamageAdrenaline); w.Write(r.GuardianAdrenaline); } private static PlayerResourceRules ReadPlayerRules(BinaryReader r) { return new PlayerResourceRules { Run = r.ReadSingle(), Jump = r.ReadSingle(), Dodge = r.ReadSingle(), Swim = r.ReadSingle(), Sneak = r.ReadSingle(), Encumbered = r.ReadSingle(), Block = r.ReadSingle(), Grapple = r.ReadSingle(), PrimaryStamina = r.ReadSingle(), SecondaryStamina = r.ReadSingle(), DrawStamina = r.ReadSingle(), ReloadStamina = r.ReadSingle(), HomeStamina = r.ReadSingle(), PrimaryEitr = r.ReadSingle(), SecondaryEitr = r.ReadSingle(), DrawEitr = r.ReadSingle(), ReloadEitr = r.ReadSingle(), PrimaryAdrenaline = r.ReadSingle(), SecondaryAdrenaline = r.ReadSingle(), ProjectileAdrenaline = r.ReadSingle(), BlockAdrenaline = r.ReadSingle(), ParryAdrenaline = r.ReadSingle(), PerfectDodgeAdrenaline = r.ReadSingle(), StaggerAdrenaline = r.ReadSingle(), MissAdrenaline = r.ReadSingle(), DamageAdrenaline = r.ReadSingle(), GuardianAdrenaline = r.ReadSingle() }; } private static byte[] EncodePlayerRulesRequest(bool apply, PlayerResourceRules rules) { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(1); binaryWriter.Write(apply ? ((byte)1) : ((byte)0)); if (apply) { WritePlayerRules(binaryWriter, rules); } return memoryStream.ToArray(); } private static bool DecodePlayerRulesRequest(byte[] bytes, out bool apply, out PlayerResourceRules rules) { apply = false; rules = PlayerResourceRules.Vanilla; if (bytes == null || bytes.Length > 256) { return false; } try { using BinaryReader binaryReader = new BinaryReader(new MemoryStream(bytes)); if (binaryReader.ReadInt32() != 1) { return false; } byte b = binaryReader.ReadByte(); if (b > 1) { return false; } apply = b == 1; if (apply) { rules = ReadPlayerRules(binaryReader); } return binaryReader.BaseStream.Position == binaryReader.BaseStream.Length && (!apply || ValidPlayerRules(rules)); } catch (Exception ex) when (ex is IOException || ex is EndOfStreamException || ex is ArgumentException) { return false; } } private static byte[] EncodePlayerRulesState(long revision, PlayerResourceRules rules) { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(1); binaryWriter.Write(revision); WritePlayerRules(binaryWriter, rules); return memoryStream.ToArray(); } private static bool DecodePlayerRulesState(byte[] bytes, out long revision, out PlayerResourceRules rules) { revision = 0L; rules = PlayerResourceRules.Vanilla; if (bytes == null || bytes.Length > 256) { return false; } try { using BinaryReader binaryReader = new BinaryReader(new MemoryStream(bytes)); if (binaryReader.ReadInt32() != 1) { return false; } revision = binaryReader.ReadInt64(); rules = ReadPlayerRules(binaryReader); return binaryReader.BaseStream.Position == binaryReader.BaseStream.Length && revision >= 0 && ValidPlayerRules(rules); } catch (Exception ex) when (ex is IOException || ex is EndOfStreamException || ex is ArgumentException) { return false; } } private void LoadPlayerRules() { EnsurePlayerRulesConfig(); playerRules = PlayerResourceRules.Vanilla; playerRulesRevision = 1L; string text = ((playerRulesStored != null) ? playerRulesStored.Value : ""); if (string.IsNullOrEmpty(text)) { return; } try { if (DecodePlayerRulesState(Convert.FromBase64String(text), out var revision, out var rules)) { playerRules = rules; playerRulesRevision = Math.Max(1L, revision); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not read stored player rules: " + ex.Message)); } } private void SavePlayerRules() { EnsurePlayerRulesConfig(); if (playerRulesStored != null) { playerRulesStored.Value = Convert.ToBase64String(EncodePlayerRulesState(playerRulesRevision, playerRules)); } } private void ResetPlayerRulesNetwork() { foreach (ZRpc item in playerRulesRegistered) { try { item.Unregister("DezzyCode.WorldControl.PlayerRules.Request.v1"); item.Unregister("DezzyCode.WorldControl.PlayerRules.State.v1"); } catch { } } playerRulesRegistered.Clear(); playerRulesRequests.Clear(); playerRulesEdits.Clear(); playerRulesNetwork = network; playerRulesLoadedForServer = false; nextPlayerRulesQuery = 0f; playerRulesSynced = session != null && session.Server; playerRulesRevision = 0L; if (session == null || !session.Server) { playerRules = PlayerResourceRules.Vanilla; } playerRulesDraft = playerRules; playerRulesDraftDirty = false; RestorePlayerRuleTuning(); } private void PlayerRulesTick() { //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Expected O, but got Unknown EnsurePlayerRulesConfig(); if (playerRulesNetwork != network) { ResetPlayerRulesNetwork(); } if ((Object)(object)network == (Object)null || session == null) { return; } if (session.Server && !playerRulesLoadedForServer) { playerRulesLoadedForServer = true; LoadPlayerRules(); playerRulesSynced = true; playerRulesDraft = playerRules; } foreach (ZNetPeer peer in network.GetPeers()) { if (peer != null && peer.m_rpc != null && playerRulesRegistered.Add(peer.m_rpc)) { peer.m_rpc.Register<ZPackage>("DezzyCode.WorldControl.PlayerRules.Request.v1", (Action<ZRpc, ZPackage>)OnPlayerRulesRequest); peer.m_rpc.Register<ZPackage>("DezzyCode.WorldControl.PlayerRules.State.v1", (Action<ZRpc, ZPackage>)OnPlayerRulesState); if (session.Server && peer.IsReady() && peer.m_rpc.IsConnected()) { SendPlayerRulesState(peer.m_rpc); } } } playerRulesStale.Clear(); foreach (ZRpc item in playerRulesRegistered) { if (item == null || !item.IsConnected()) { playerRulesStale.Add(item); } } foreach (ZRpc item2 in playerRulesStale) { playerRulesRegistered.Remove(item2); playerRulesRequests.Remove(item2); playerRulesEdits.Remove(item2); try { item2.Unregister("DezzyCode.WorldControl.PlayerRules.Request.v1"); item2.Unregister("DezzyCode.WorldControl.PlayerRules.State.v1"); } catch { } } if (!session.Server && !playerRulesSynced && Time.unscaledTime >= nextPlayerRulesQuery) { ZNetPeer serverPeer = network.GetServerPeer(); if (serverPeer != null && serverPeer.IsReady() && serverPeer.m_rpc != null && serverPeer.m_rpc.IsConnected()) { nextPlayerRulesQuery = Time.unscaledTime + 1f; serverPeer.m_rpc.Invoke("DezzyCode.WorldControl.PlayerRules.Request.v1", new object[1] { (object)new ZPackage(EncodePlayerRulesRequest(apply: false, PlayerResourceRules.Vanilla)) }); } } if (playerRulesSynced) { ApplyPlayerRuleTuning(); } } private void OnPlayerRulesRequest(ZRpc rpc, ZPackage package) { ZNetPeer val = ReadyPeer(rpc); if (session == null || !session.Server || rpc == null || val == null || package == null || package.Size() > 256 || !DecodePlayerRulesRequest(package.GetArray(), out var apply, out var rules)) { return; } Dictionary<ZRpc, float> dictionary = (apply ? playerRulesEdits : playerRulesRequests); if (!dictionary.TryGetValue(rpc, out var value) || !(Time.unscaledTime < value)) { dictionary[rpc] = Time.unscaledTime + (apply ? 0.35f : 0.75f); if (apply && IsAdmin(rpc)) { playerRules = rules; playerRulesRevision = Math.Max(1L, playerRulesRevision + 1); SavePlayerRules(); playerRulesDraft = playerRules; playerRulesDraftDirty = false; BroadcastPlayerRules(); controlsDirty = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Player resource rules changed by admin " + val.m_playerName + ".")); } else { SendPlayerRulesState(rpc); } } } private void OnPlayerRulesState(ZRpc rpc, ZPackage package) { if (session != null && !session.Server && rpc != null && package != null && package.Size() <= 256 && serverConnection != null && rpc == serverConnection && DecodePlayerRulesState(package.GetArray(), out var revision, out var rules) && (!playerRulesSynced || revision >= playerRulesRevision)) { playerRulesRevision = revision; playerRules = rules; playerRulesSynced = true; if (!playerRulesDraftDirty) { playerRulesDraft = rules; } controlsDirty = true; } } private void SendPlayerRulesState(ZRpc rpc) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (rpc != null && rpc.IsConnected()) { rpc.Invoke("DezzyCode.WorldControl.PlayerRules.State.v1", new object[1] { (object)new ZPackage(EncodePlayerRulesState(playerRulesRevision, playerRules)) }); } } private void BroadcastPlayerRules() { foreach (ZNetPeer peer in network.GetPeers()) { if (peer != null && peer.IsReady() && peer.m_rpc != null && peer.m_rpc.IsConnected() && playerRulesRegistered.Contains(peer.m_rpc)) { SendPlayerRulesState(peer.m_rpc); } } ApplyPlayerRuleTuning(); } private void SubmitPlayerRules() { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown if (!CanEdit || !ValidPlayerRules(playerRulesDraft)) { return; } if (session != null && session.Server) { playerRules = playerRulesDraft; playerRulesRevision = Math.Max(1L, playerRulesRevision + 1); playerRulesSynced = true; playerRulesDraftDirty = false; SavePlayerRules(); BroadcastPlayerRules(); controlsDirty = true; } else { ZNetPeer val = (((Object)(object)network != (Object)null) ? network.GetServerPeer() : null); if (val != null && val.IsReady() && val.m_rpc != null && val.m_rpc.IsConnected()) { val.m_rpc.Invoke("DezzyCode.WorldControl.PlayerRules.Request.v1", new object[1] { (object)new ZPackage(EncodePlayerRulesRequest(apply: true, playerRulesDraft)) }); } } } private static FieldInfo PlayerRuleField(string name) { Type type = typeof(Player); while (type != null) { FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(float)) { return field; } type = type.BaseType; } return null; } private void ApplyPlayerFloat(Player player, string fieldName, float multiplier) { FieldInfo fieldInfo = PlayerRuleField(fieldName); if (fieldInfo == null || (Object)(object)player == (Object)null) { return; } if (!playerFieldBaselines.TryGetValue(fieldName, out var value)) { try { value = (float)fieldInfo.GetValue(player); playerFieldBaselines[fieldName] = value; } catch { return; } } try { fieldInfo.SetValue(player, value * multiplier); } catch { } } private void ApplyPlayerRuleTuning() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { bool flag = playerRulesAppliedPlayer != localPlayer; bool flag2 = playerRulesObjectDb != ObjectDB.instance; if (flag) { RestorePlayerFields(); playerRulesAppliedPlayer = localPlayer; playerFieldBaselines.Clear(); playerRulesAppliedRevision = -1L; } if (flag2) { RestoreItemRules(); playerRulesObjectDb = ObjectDB.instance; attackBaselines.Clear(); projectileBaselines.Clear(); shieldBaselines.Clear(); playerRulesAppliedRevision = -1L; } if (playerRulesAppliedRevision != playerRulesRevision || flag || flag2) { ApplyPlayerFloat(localPlayer, "m_runStaminaDrain", playerRules.Run); ApplyPlayerFloat(localPlayer, "m_jumpStaminaUsage", playerRules.Jump); ApplyPlayerFloat(localPlayer, "m_dodgeStaminaUsage", playerRules.Dodge); ApplyPlayerFloat(localPlayer, "m_swimStaminaDrainMinSkill", playerRules.Swim); ApplyPlayerFloat(localPlayer, "m_swimStaminaDrainMaxSkill", playerRules.Swim); ApplyPlayerFloat(localPlayer, "m_sneakStaminaDrain", playerRules.Sneak); ApplyPlayerFloat(localPlayer, "m_encumberedStaminaDrain", playerRules.Encumbered); ApplyPlayerFloat(localPlayer, "m_grapplingStaminaDrain", playerRules.Grapple); ApplyPlayerFloat(localPlayer, "m_perfectDodgeAdrenaline", playerRules.PerfectDodgeAdrenaline); ApplyPlayerFloat(localPlayer, "m_staggerEnemyAdrenaline", playerRules.StaggerAdrenaline); ApplyPlayerFloat(localPlayer, "m_attackMissAdrenaline", playerRules.MissAdrenaline); ApplyPlayerFloat(localPlayer, "m_nonBlockDamageAdrenaline", playerRules.DamageAdrenaline); ApplyPlayerFloat(localPlayer, "m_adrenalineGuardianPower", playerRules.GuardianAdrenaline); TuneItemRules(); playerRulesAppliedRevision = playerRulesRevision; } } } private void TuneItemRules() { ObjectDB val = ObjectDB.instance; if ((Object)(object)val == (Object)null || val.m_items == null) { return; } foreach (GameObject item in val.m_items) { if (!((Object)(object)item == (Object)null)) { ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null) { SharedData shared = component.m_itemData.m_shared; TuneAttack(shared.m_attack, primary: true); TuneAttack(shared.m_secondaryAttack, primary: false); TuneShield(shared); } } } } private void TuneAttack(Attack attack, bool primary) { if (attack == null) { return; } if (!attackBaselines.TryGetValue(attack, out var value)) { value = new AttackBaseline { AttackAdrenaline = attack.m_attackAdrenaline }; attackBaselines[attack] = value; } float num = (primary ? playerRules.PrimaryAdrenaline : playerRules.SecondaryAdrenaline); attack.m_attackAdrenaline = value.AttackAdrenaline * num; if (!((Object)(object)attack.m_attackProjectile != (Object)null)) { return; } Projectile component = attack.m_attackProjectile.GetComponent<Projectile>(); if ((Object)(object)component != (Object)null) { if (!projectileBaselines.TryGetValue(component, out var value2)) { value2 = component.m_adrenaline; projectileBaselines[component] = value2; } component.m_adrenaline = value2 * playerRules.ProjectileAdrenaline; } } private void TuneShield(SharedData shared) { if (shared != null) { if (!shieldBaselines.TryGetValue(shared, out var value)) { value = new ShieldBaseline { Block = shared.m_blockAdrenaline, Parry = shared.m_perfectBlockAdrenaline }; shieldBaselines[shared] = value; } shared.m_blockAdrenaline = value.Block * playerRules.BlockAdrenaline; shared.m_perfectBlockAdrenaline = value.Parry * playerRules.ParryAdrenaline; } } private void RestorePlayerFields() { Player val = playerRulesAppliedPlayer; if ((Object)(object)val == (Object)null) { return; } foreach (KeyValuePair<string, float> playerFieldBaseline in playerFieldBaselines) { FieldInfo fieldInfo = PlayerRuleField(playerFieldBaseline.Key); if (!(fieldInfo == null)) { try { fieldInfo.SetValue(val, playerFieldBaseline.Value); } catch { } } } } private void RestoreItemRules() { foreach (KeyValuePair<Attack, AttackBaseline> attackBaseline in attackBaselines) { Attack key = attackBaseline.Key; AttackBaseline value = attackBaseline.Value; if (key != null && value != null) { key.m_attackAdrenaline = value.AttackAdrenaline; } } foreach (KeyValuePair<Projectile, float> projectileBaseline in projectileBaselines) { if ((Object)(object)projectileBaseline.Key != (Object)null) { projectileBaseline.Key.m_adrenaline = projectileBaseline.Value; } } foreach (KeyValuePair<SharedData, ShieldBaseline> shieldBaseline in shieldBaselines) { if (shieldBaseline.Key != null && shieldBaseline.Value != null) { shieldBaseline.Key.m_blockAdrenaline = shieldBaseline.Value.Block; shieldBaseline.Key.m_perfectBlockAdrenaline = shieldBaseline.Value.Parry; } } } private void RestorePlayerRuleTuning() { RestorePlayerFields(); RestoreItemRules(); playerRulesAppliedPlayer = null; playerFieldBaselines.Clear(); playerRulesObjectDb = null; attackBaselines.Clear(); projectileBaselines.Clear(); shieldBaselines.Clear(); playerRulesAppliedRevision = -1L; } private static string PR(string english, string german) { if (!Words.IsGerman) { return english; } return german; } private void EnsurePlayerRulesUI() { if ((Object)(object)panel == (Object)null || (Object)(object)pages[8] == (Object)null || (Object)(object)playerStaminaPanel != (Object)null) { return; } GameObject val = pages[8]; Position(val, 210f, 158f, 1350f, 470f); playerStaminaPanel = PlayerRulePanel(val.transform, "PlayerStamina", 0f, 52f, 1350f, 410f); playerEitrPanel = PlayerRulePanel(val.transform, "PlayerEitr", 0f, 52f, 1350f, 410f); playerAdrenalinePanel = PlayerRulePanel(val.transform, "PlayerAdrenaline", 0f, 52f, 1350f, 410f); Choice(val.transform, 250f, 0f, 240f, () => PR("Stamina", "Ausdauer"), () => playerPageMode == 1, delegate { playerPageMode = 1; }); Choice(val.transform, 500f, 0f, 240f, () => PR("Eitr", "Eitr"), () => playerPageMode == 2, delegate { playerPageMode = 2; }); Choice(val.transform, 750f, 0f, 240f, () => PR("Adrenaline", "Adrenalin"), () => playerPageMode == 3, delegate { playerPageMode = 3; }); BuildStaminaRules(playerStaminaPanel.transform); BuildEitrRules(playerEitrPanel.transform); BuildAdrenalineRules(playerAdrenalinePanel.transform); playerRulesStatus = Label(val.transform, 1010f, 2f, 330f, "", 13, 36f); refresh.Add(delegate { if ((Object)(object)playerStaminaPanel != (Object)null) { playerStaminaPanel.SetActive(playerPageMode == 1); } if ((Object)(object)playerEitrPanel != (Object)null) { playerEitrPanel.SetActive(playerPageMode == 2); } if ((Object)(object)playerAdrenalinePanel != (Object)null) { playerAdrenalinePanel.SetActive(playerPageMode == 3); } if ((Object)(object)playerRulesStatus != (Object)null) { playerRulesStatus.text = (playerRulesDraftDirty ? PR("Local changes · not applied", "Lokale Änderungen · nicht übernommen") : (playerRulesSynced ? PR("Server rules synchronized", "Serverregeln synchronisiert") : PR("Waiting for server rules ...", "Warte auf Serverregeln ..."))); } }); } private GameObject PlayerRulePanel(Transform parent, string name, float x, float y, float width, float height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0034: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); Position(val, x, y, width, height); return val; } private void PlayerRuleSlider(Transform parent, float x, float y, float width, string label, Func<float> read, Action<float> write) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) Text text = Label(parent, x + 6f, y, width - 12f, "", 14, 22f); GameObject val = DefaultControls.CreateSlider(GUIManager.Instance.ValheimControlResources); val.transform.SetParent(parent, false); Position(val, x + 8f, y + 23f, width - 16f, 20f); Slider slider = val.GetComponent<Slider>(); GUIManager.Instance.ApplySliderStyle(slider, new Vector2(18f, 20f)); slider.minValue = 0f; slider.maxValue = 3f; slider.wholeNumbers = false; slider.SetValueWithoutNotify(read()); ((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float value) { float num = Mathf.Round(value * 20f) / 20f; write(num); slider.SetValueWithoutNotify(num); playerRulesDraftDirty = true; controlsDirty = true; }); Slider obj = slider; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)obj).navigation = navigation; refresh.Add(delegate { float num = read(); text.text = label + " " + num.ToString("0.00", CultureInfo.InvariantCulture) + "×"; if (!Mathf.Approximately(slider.value, num)) { slider.SetValueWithoutNotify(num); } ((Selectable)slider).interactable = CanEdit && playerRulesSynced; }); } private void PlayerRuleFooter(Transform parent, string resetWhat) { Button apply = Button(parent, 0f, 366f, 280f, 36f, PR("Apply to server", "Auf Server übernehmen"), SubmitPlayerRules); Button(parent, 294f, 366f, 280f, 36f, PR("Reset all to Vanilla", "Alles auf Vanilla"), delegate { playerRulesDraft = PlayerResourceRules.Vanilla; playerRulesDraftDirty = true; controlsDirty = true; }); Label(parent, 590f, 364f, 740f, PR("1.00× = Vanilla · 0.50× = half · 0.00× = free / no gain · 2.00× = double. ", "1,00× = Vanilla · 0,50× = Hälfte · 0,00× = kostenlos / kein Gewinn · 2,00× = doppelt. ") + resetWhat, 13); refresh.Add(delegate { ((Selectable)apply).interactable = CanEdit && playerRulesSynced && playerRulesDraftDirty; }); } private void BuildStaminaRules(Transform parent) { Label(parent, 6f, 0f, 1320f, PR("Stamina consumption", "Ausdauerverbrauch"), 19, 26f); float x = 0f; float x2 = 675f; float width = 650f; float num = 34f; float num2 = 47f; PlayerRuleSlider(parent, x, num, width, PR("Run", "Rennen"), () => playerRulesDraft.Run, delegate(float v) { playerRulesDraft.Run = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Jump", "Springen"), () => playerRulesDraft.Jump, delegate(float v) { playerRulesDraft.Jump = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Dodge roll", "Ausweichen / Rollen"), () => playerRulesDraft.Dodge, delegate(float v) { playerRulesDraft.Dodge = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Swim", "Schwimmen"), () => playerRulesDraft.Swim, delegate(float v) { playerRulesDraft.Swim = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Sneak", "Schleichen"), () => playerRulesDraft.Sneak, delegate(float v) { playerRulesDraft.Sneak = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Encumbered", "Überladen"), () => playerRulesDraft.Encumbered, delegate(float v) { playerRulesDraft.Encumbered = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Block", "Blocken"), () => playerRulesDraft.Block, delegate(float v) { playerRulesDraft.Block = v; }); num = 34f; PlayerRuleSlider(parent, x2, num, width, PR("Primary attack", "Primärangriff"), () => playerRulesDraft.PrimaryStamina, delegate(float v) { playerRulesDraft.PrimaryStamina = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Secondary attack", "Sekundärangriff"), () => playerRulesDraft.SecondaryStamina, delegate(float v) { playerRulesDraft.SecondaryStamina = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Draw / charge", "Spannen / Aufladen"), () => playerRulesDraft.DrawStamina, delegate(float v) { playerRulesDraft.DrawStamina = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Reload", "Nachladen"), () => playerRulesDraft.ReloadStamina, delegate(float v) { playerRulesDraft.ReloadStamina = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Building / home tools", "Bauen / Heimwerkzeuge"), () => playerRulesDraft.HomeStamina, delegate(float v) { playerRulesDraft.HomeStamina = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Grappling", "Grappling"), () => playerRulesDraft.Grapple, delegate(float v) { playerRulesDraft.Grapple = v; }); PlayerRuleFooter(parent, PR("Movement and attack values are independent.", "Bewegungs- und Angriffswerte sind unabhängig.")); } private void BuildEitrRules(Transform parent) { Label(parent, 6f, 0f, 1320f, PR("Eitr consumption", "Eitr-Verbrauch"), 19, 26f); float x = 0f; float x2 = 675f; float width = 650f; float num = 48f; float num2 = 68f; PlayerRuleSlider(parent, x, num, width, PR("Primary attack / spell", "Primärangriff / Zauber"), () => playerRulesDraft.PrimaryEitr, delegate(float v) { playerRulesDraft.PrimaryEitr = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Secondary attack / spell", "Sekundärangriff / Zauber"), () => playerRulesDraft.SecondaryEitr, delegate(float v) { playerRulesDraft.SecondaryEitr = v; }); num = 48f; PlayerRuleSlider(parent, x2, num, width, PR("Draw / channel", "Spannen / Kanalisieren"), () => playerRulesDraft.DrawEitr, delegate(float v) { playerRulesDraft.DrawEitr = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Reload / repeated cast", "Nachladen / Wiederholung"), () => playerRulesDraft.ReloadEitr, delegate(float v) { playerRulesDraft.ReloadEitr = v; }); Label(parent, 6f, 212f, 1320f, PR("These multiply the Eitr values stored on the actual vanilla attack. Modded attacks using the same Valheim fields are covered too.", "Diese Werte multiplizieren die Eitr-Kosten des tatsächlichen Valheim-Angriffs. Mod-Angriffe mit denselben Vanilla-Feldern werden ebenfalls erfasst."), 14, 60f); PlayerRuleFooter(parent, ""); } private void BuildAdrenalineRules(Transform parent) { Label(parent, 6f, 0f, 1320f, PR("Adrenaline gain / loss", "Adrenalin-Gewinn / Verlust"), 19, 26f); float x = 0f; float x2 = 675f; float width = 650f; float num = 34f; float num2 = 54f; PlayerRuleSlider(parent, x, num, width, PR("Primary attack", "Primärangriff"), () => playerRulesDraft.PrimaryAdrenaline, delegate(float v) { playerRulesDraft.PrimaryAdrenaline = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Secondary attack", "Sekundärangriff"), () => playerRulesDraft.SecondaryAdrenaline, delegate(float v) { playerRulesDraft.SecondaryAdrenaline = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Projectile hit", "Projektiltreffer"), () => playerRulesDraft.ProjectileAdrenaline, delegate(float v) { playerRulesDraft.ProjectileAdrenaline = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Block", "Blocken"), () => playerRulesDraft.BlockAdrenaline, delegate(float v) { playerRulesDraft.BlockAdrenaline = v; }); num += num2; PlayerRuleSlider(parent, x, num, width, PR("Perfect block / parry", "Perfekter Block / Parieren"), () => playerRulesDraft.ParryAdrenaline, delegate(float v) { playerRulesDraft.ParryAdrenaline = v; }); num = 34f; PlayerRuleSlider(parent, x2, num, width, PR("Perfect dodge", "Perfektes Ausweichen"), () => playerRulesDraft.PerfectDodgeAdrenaline, delegate(float v) { playerRulesDraft.PerfectDodgeAdrenaline = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Stagger enemy", "Gegner taumeln lassen"), () => playerRulesDraft.StaggerAdrenaline, delegate(float v) { playerRulesDraft.StaggerAdrenaline = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Miss penalty", "Fehlschlag-Verlust"), () => playerRulesDraft.MissAdrenaline, delegate(float v) { playerRulesDraft.MissAdrenaline = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Unblocked damage penalty", "Ungeblockter Schaden-Verlust"), () => playerRulesDraft.DamageAdrenaline, delegate(float v) { playerRulesDraft.DamageAdrenaline = v; }); num += num2; PlayerRuleSlider(parent, x2, num, width, PR("Guardian power gain", "Bosskraft-Gewinn"), () => playerRulesDraft.GuardianAdrenaline, delegate(float v) { playerRulesDraft.GuardianAdrenaline = v; }); PlayerRuleFooter(parent, PR("Negative vanilla adrenaline values stay negative; the slider scales their size.", "Negative Vanilla-Adrenalinwerte bleiben negativ; der Regler skaliert ihre Stärke.")); } private void EnsurePlayerVitalsConfig() { if (!playerVitalsConfigReady) { playerVitalsConfigReady = true; playerVitalsStored = ((BaseUnityPlugin)this).Config.Bind<string>("Server - Player Vitals", "State", "", "Written by the World Control server. Server-authoritative health, stamina, eitr, stamina regeneration and eitr regeneration multipliers."); } } private static bool ValidVitalMax(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value) && value >= 0.1f) { return value <= 3f; } return false; } private static bool ValidVitalRegen(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value) && value >= 0f) { return value <= 3f; } return false; } private static bool ValidPlayerVitals(PlayerVitalRules rules) { if (ValidVitalMax(rules.MaxHealth) && ValidVitalMax(rules.MaxStamina) && ValidVitalMax(rules.MaxEitr) && ValidVitalRegen(rules.StaminaRegen)) { return ValidVitalRegen(rules.EitrRegen); } return false; } private static void WritePlayerVitals(BinaryWriter writer, PlayerVitalRules rules) { writer.Write(rules.MaxHealth); writer.Write(rules.MaxStamina); writer.Write(rules.MaxEitr); writer.Write(rules.StaminaRegen); writer.Write(rules.EitrRegen); } private static PlayerVitalRules ReadPlayerVitals(BinaryReader reader, int version) { return new PlayerVitalRules { MaxHealth = reader.ReadSingle(), MaxStamina = reader.ReadSingle(), MaxEitr = reader.ReadSingle(), StaminaRegen = reader.ReadSingle(), EitrRegen = ((version >= 2) ? reader.ReadSingle() : 1f) }; } private static byte[] EncodePlayerVitalsRequest(bool apply, PlayerVitalRules rules) { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(2); binaryWriter.Write(apply ? ((byte)1) : ((byte)0)); if (apply) { WritePlayerVitals(binaryWriter, rules); } return memoryStream.ToArray(); } private static bool DecodePlayerVitalsRequest(byte[] bytes, out bool apply, out PlayerVitalRules rules) { apply = false; rules = PlayerVitalRules.Vanilla; if (bytes == null || bytes.Length > 96) { return false; } try { using BinaryReader binaryReader = new BinaryReader(new MemoryStream(bytes)); int num = binaryReader.ReadInt32(); if (num < 1 || num > 2) { return false; } byte b = binaryReader.ReadByte(); if (b > 1) { return false; } apply = b == 1; if (apply) { rules = ReadPlayerVitals(binaryReader, num); } return binaryReader.BaseStream.Position == binaryReader.BaseStream.Length && (!apply || ValidPlayerVitals(rules)); } catch (Exception ex) when (ex is IOException || ex is EndOfStreamException || ex is ArgumentException) { return false; } } private static byte[] EncodePlayerVitalsState(long revision, PlayerVitalRules rules) { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(2); binaryWriter.Write(revision); WritePlayerVitals(binaryWriter, rules); return memoryStream.ToArray(); } private static bool DecodePlayerVitalsState(byte[] bytes, out long revision, out PlayerVitalRules rules) { revision = 0L; rules = PlayerVitalRules.Vanilla; if (bytes == null || bytes.Length > 96) { return false; } try { using BinaryReader binaryReader = new BinaryReader(new MemoryStream(bytes)); int num = binaryReader.ReadInt32(); if (num < 1 || num > 2) { return false; } revision = binaryReader.ReadInt64(); rules = ReadPlayerVitals(binaryReader, num); return binaryReader.BaseStream.Position == binaryReader.BaseStream.Length && revision >= 0 && ValidPlayerVitals(rules); } catch (Exception ex) when (ex is IOException || ex is EndOfStreamException || ex is ArgumentException) { return false; } } private void LoadPlayerVitals() { EnsurePlayerVitalsConfig(); playerVitals = PlayerVitalRules.Vanilla; playerVitalsRevision = 1L; string text = ((playerVitalsStored != null) ? playerVitalsStored.Value : ""); if (string.IsNullOrEmpty(text)) { return; } try { if (DecodePlayerVitalsState(Convert.FromBase64String(text), out var revision, out var rules)) { playerVitals = rules; playerVitalsRevision = Math.Max(1L, revision); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not read stored player vitals: " + ex.Message)); } } private void SavePlayerVitals() { EnsurePlayerVitalsConfig(); if (playerVitalsStored != null) { playerVitalsStored.Value = Convert.ToBase64String(EncodePlayerVitalsState(playerVitalsRevision, playerVitals)); } } private void ResetPlayerVitalsNetwork() { foreach (ZRpc item in playerVitalsRegistered) { try { item.Unregister("DezzyCode.WorldControl.PlayerVitals.Request.v1"); item.Unregister("DezzyCode.WorldControl.PlayerVitals.State.v1"); } catch { } } playerVitalsRegistered.Clear(); playerVitalsRequests.Clear(); playerVitalsEdits.Clear(); playerVitalsNetwork = network; playerVitalsLoadedForServer = false; nextPlayerVitalsQuery = 0f; nextPlayerVitalsMaintenance = 0f; playerVitalsSynced = session != null && session.Server; playerVitalsRevision = 0L; if (session == null || !session.Server) { playerVitals = PlayerVitalRules.Vanilla; } playerVitalsDraft = playerVitals; playerVitalsDraftDirty = false; RestorePlayerVitalsLocal(); } private void PlayerVitalsTick() { //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Expected O, but got Unknown EnsurePlayerVitalsConfig(); if (playerVitalsNetwork != network) { ResetPlayerVitalsNetwork(); } if ((Object)(object)network == (Object)null || session == null) { return; } if (session.Server && !playerVitalsLoadedForServer) { playerVitalsLoadedForServer = true; LoadPlayerVitals(); playerVitalsSynced = true; playerVitalsDraft = playerVitals; playerVitalsAppliedRevision = -1L; } if (playerVitalsSynced) { ApplyPlayerVitalsLocal(); } if (Time.unscaledTime < nextPlayerVitalsMaintenance) { return; } nextPlayerVitalsMaintenance = Time.unscaledTime + 0.25f; foreach (ZNetPeer peer in network.GetPeers()) { if (peer != null && peer.m_rpc != null && playerVitalsRegistered.Add(peer.m_rpc)) { peer.m_rpc.Register<ZPackage>("DezzyCode.WorldControl.PlayerVitals.Request.v1", (Action<ZRpc, ZPackage>)OnPlayerVitalsRequest); peer.m_rpc.Register<ZPackage>("DezzyCode.WorldControl.PlayerVitals.State.v1", (Action<ZRpc, ZPackage>)OnPlayerVitalsState); if (session.Server && peer.IsReady() && peer.m_rpc.IsConnected()) { SendPlayerVitalsState(peer.m_rpc); } } } playerVitalsStale.Clear(); foreach (ZRpc item in playerVitalsRegistered) { if (item == null || !item.IsConnected()) { playerVitalsStale.Add(item); } } foreach (ZRpc item2 in playerVitalsStale) { playerVitalsRegistered.Remove(item2); playerVitalsRequests.Remove(item2); playerVitalsEdits.Remove(item2); try { item2.Unregister("DezzyCode.WorldControl.PlayerVitals.Request.v1"); item2.Unregister("DezzyCode.WorldControl.PlayerVitals.State.v1"); } catch { } } if (!session.Server && !playerVitalsSynced && Time.unscaledTime >= nextPlayerVitalsQuery) { ZNetPeer serverPeer = network.GetServerPeer(); if (serverPeer != null && serverPeer.IsReady() && serverPeer.m_rpc != null && serverPeer.m_rpc.IsConnected()) { nextPlayerVitalsQuery = Time.unscaledTime + 1f; serverPeer.m_rpc.Invoke("DezzyCode.WorldControl.PlayerVitals.Request.v1", new object[1] { (object)new ZPackage(EncodePlayerVitalsRequest(apply: false, PlayerVitalRules.Vanilla)) }); } } } private void OnPlayerVitalsRequest(ZRpc rpc, ZPackage package) { ZNetPeer val = ReadyPeer(rpc); if (session == null || !session.Server || rpc == null || val == null || package == null || package.Size() > 96 || !DecodePlayerVitalsRequest(package.GetArray(), out var apply, out var rules)) { return; } Dictionary<ZRpc, float> dictionary = (apply ? playerVitalsEdits : playerVitalsRequests); if (!dictionary.TryGetValue(rpc, out var value) || !(Time.unscaledTime < value)) { dictionary[rpc] = Time.unscaledTime + (apply ? 0.35f : 0.75f); if (apply && IsAdmin(rpc)) { playerVitals = rules; playerVitalsRevision = Math.Max(1L, playerVitalsRevision + 1); playerVitalsAppliedRevision = -1L; SavePlayerVitals(); playerVitalsDraft = playerVitals; playerVitalsDraftDirty = false; BroadcastPlayerVitals(); controlsDirty = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Player vital rules changed by admin " + val.m_playerName + ".")); } else { SendPlayerVitalsState(rpc); } } } private void OnPlayerVitalsState(ZRpc rpc, ZPackage package) { if (session != null && !session.Server && rpc != null && package != null && package.Size() <= 96 && serverConnection != null && rpc == serverConnection && DecodePlayerVitalsState(package.GetArray(), out var revision, out var rules) && (!playerVitalsSynced || revision >= playerVitalsRevision)) { playerVitalsRevision = revision; playerVitals = rules; playerVitalsSynced = true; playerVitalsAppliedRevision = -1L; if (!playerVitalsDraftDirty) { playerVitalsDraft = rules; } ApplyPlayerVitalsLocal(); controlsDirty = true; } } private void SendPlayerVitalsState(ZRpc rpc) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (rpc != null && rpc.IsConnected()) { rpc.Invoke("DezzyCode.WorldControl.PlayerVitals.State.v1", new object[1] { (object)new ZPackage(EncodePlayerVitalsState(playerVitalsRevision, playerVitals)) }); } } private void BroadcastPlayerVitals() { foreach (ZNetPeer peer in network.GetPeers()) { if (peer != null && peer.IsReady() && peer.m_rpc != null && peer.m_rpc.IsConnected() && playerVitalsRegistered.Contains(peer.m_rpc)) { SendPlayerVitalsState(peer.m_rpc); } } ApplyPlayerVitalsLocal(); } private void SubmitPlayerVitals() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown if (!playerVitalsDraftDirty || !CanEdit || !playerVitalsSynced || !ValidPlayerVitals(playerVitalsDraft)) { return; } if (session != null && session.Server) { playerVitals = playerVitalsDraft; playerVitalsRevision = Math.Max(1L, playerVitalsRevision + 1); playerVitalsAppliedRevision = -1L; playerVitalsDraftDirty = false; SavePlayerVitals(); BroadcastPlayerVitals(); c