using System.Collections.Generic; using System.Reflection; using HarmonyLib; using NitroxClient.GameLogic; using NitroxModel.Helper; using NitroxPatcher.PatternMatching; using UnityEngine; using static System.Reflection.Emit.OpCodes; namespace NitroxPatcher.Patches.Dynamic; /// /// Prevent uSkyManager from "freezing" the clouds when FreezeTime is active (game paused). /// Also sets skybox's rotation depending on the real server time. /// public sealed partial class uSkyManager_SetVaryingMaterialProperties_Patch : NitroxPatch, IDynamicPatch { public static readonly MethodInfo TARGET_METHOD = Reflect.Method((uSkyManager t) => t.SetVaryingMaterialProperties(default)); /// /// This pattern detects the property in the following line /// and replaces the property call target to : /// Quaternion q = Quaternion.AngleAxis(cloudsRotateSpeed * Time.time, Vector3.up); /// public static readonly InstructionsPattern ModifyInstructionPattern = new() { Ldarg_0, Ldfld, { Reflect.Property(() => Time.time).GetMethod, "Modify" }, Mul }; /// /// Intermediate time property to simplify the dependency resolving for the transpiler. /// private static double CurrentTime => Resolve().CurrentTime; /// /// Replaces Time.time call to Time.realtimeSinceStartup so that it doesn't take Time.timeScale into account /// public static IEnumerable Transpiler(MethodBase original, IEnumerable instructions) => instructions .ChangeAtMarker(ModifyInstructionPattern, "Modify", instruction => instruction.operand = Reflect.Property(() => CurrentTime).GetMethod); }