Decompiled source of WKCinema v0.2.4
BepInEx/plugins/WKCinema/WKCinema.dll
Decompiled 8 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 BepInEx; using BepInEx.Configuration; using HarmonyLib; using Steamworks; using UnityEngine; using UnityEngine.SceneManagement; using WKModUI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("WK Cinema")] [assembly: AssemblyDescription("Independent camera and filming tools for White Knuckle")] [assembly: AssemblyCompany("Ilylllk1n5")] [assembly: AssemblyFileVersion("0.2.4.0")] [assembly: AssemblyVersion("0.2.4.0")] namespace WKModUI { internal static class SharedLanguage { internal const string Protocol = "ilya.whiteknuckle.shared-language.v1"; private static Dictionary<string, object> State => AppDomain.CurrentDomain.GetData("ilya.whiteknuckle.shared-language.v1") as Dictionary<string, object>; internal static string Current { get { Dictionary<string, object> state = State; if (state != null) { return (string)state["resolved"]; } return "en"; } } internal static string Label { get { if (!(Current == "ru")) { return "ENG"; } return "RU"; } } private static SortedDictionary<string, object[]> Clients(Dictionary<string, object> state) { return (SortedDictionary<string, object[]>)state["clients"]; } internal static string Normalize(string language) { language = (language ?? "").Trim().ToLowerInvariant().Replace('_', '-'); switch (language) { default: if (!language.StartsWith("ru-", StringComparison.Ordinal)) { return "en"; } break; case "ru": case "russian": case "русский": break; } return "ru"; } private static string Choice(string value) { if (!(value == "ru") && !(value == "en")) { return "auto"; } return value; } internal static void Connect(string id, Action<string> apply, Func<bool> visible, string automatic, string legacy, Func<object[]> settings, Action<Exception> error) { Dictionary<string, object> dictionary = State; if (dictionary == null) { object[] array = settings(); dictionary = new Dictionary<string, object>(StringComparer.Ordinal) { { "clients", new SortedDictionary<string, object[]>(StringComparer.Ordinal) }, { "read", array[1] }, { "write", array[2] }, { "choice", Choice(((Func<string>)array[1])()) }, { "allowLegacy", !(bool)array[0] }, { "resolved", "en" } }; AppDomain.CurrentDomain.SetData("ilya.whiteknuckle.shared-language.v1", dictionary); } Clients(dictionary)[id] = new object[4] { apply, visible, Normalize(automatic), error }; if ((bool)dictionary["allowLegacy"] && (legacy == "ru" || legacy == "en")) { SetChoice(legacy); } Refresh(dictionary); Apply(Clients(dictionary)[id], (string)dictionary["resolved"]); } internal static void Disconnect(string id) { Dictionary<string, object> state = State; if (state != null) { Clients(state).Remove(id); Refresh(state); } } internal static void Automatic(string id, string language) { Dictionary<string, object> state = State; if (state != null && Clients(state).TryGetValue(id, out var value)) { value[2] = Normalize(language); state["choice"] = Choice(((Func<string>)state["read"])()); Refresh(state); } } internal static void Toggle() { SetChoice((Current == "ru") ? "en" : "ru"); } internal static void SetChoice(string choice) { if (choice != "auto" && choice != "ru" && choice != "en") { throw new ArgumentException("Expected auto, ru or en.", "choice"); } Dictionary<string, object> state = State; if (state == null) { return; } state["allowLegacy"] = false; state["choice"] = choice; try { ((Action<string>)state["write"])(choice); } catch (Exception exception) { foreach (object[] value in Clients(state).Values) { Report(value, exception); } } Refresh(state); } internal static bool OwnsButton(string id) { Dictionary<string, object> state = State; if (state == null) { return false; } foreach (KeyValuePair<string, object[]> item in Clients(state)) { bool flag = false; try { flag = ((Func<bool>)item.Value[1])(); } catch (Exception exception) { Report(item.Value, exception); } if (flag) { return item.Key == id; } } return false; } private static void Refresh(Dictionary<string, object> state) { string text = (string)state["choice"]; if (text == "auto") { text = "en"; using SortedDictionary<string, object[]>.ValueCollection.Enumerator enumerator = Clients(state).Values.GetEnumerator(); if (enumerator.MoveNext()) { text = (string)enumerator.Current[2]; } } if ((string)state["resolved"] == text) { return; } state["resolved"] = text; foreach (object[] item in new List<object[]>(Clients(state).Values)) { Apply(item, text); } } private static void Apply(object[] client, string language) { try { ((Action<string>)client[0])(language); } catch (Exception exception) { Report(client, exception); } } private static void Report(object[] client, Exception exception) { if (client[3] is Action<Exception> action) { try { action(exception); } catch (Exception) { } } } } internal static class SharedLanguageConfig { internal const string Filename = "ilya.whiteknuckle.shared-language.cfg"; internal static object[] Open(string directory) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown string text = Path.Combine(directory, "ilya.whiteknuckle.shared-language.cfg"); bool flag = File.Exists(text); ConfigFile file = new ConfigFile(text, false) { SaveOnConfigSet = false }; ConfigEntry<string> choice = file.Bind<string>("General", "Language", "auto", new ConfigDescription("Language for all compatible Ilyushkins WK mods. RU/ENG switches every connected mod. auto follows the game; ru = Russian; en = English. / Язык всех совместимых WK-модов Илюшкинса. RU/ENG переключает все подключённые моды. auto = язык игры; ru = русский; en = английский.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "auto", "ru", "en" }), Array.Empty<object>())); if (!flag) { file.Save(); } return new object[3] { flag, (Func<string>)(() => choice.Value), (Action<string>)delegate(string value) { choice.Value = value; file.Save(); } }; } } } namespace WhiteKnuckle.Cinema { internal static class CameraMath { internal static bool Finite(double v) { if (!double.IsNaN(v)) { return !double.IsInfinity(v); } return false; } internal static double Clamp(double v, double lo, double hi) { return Math.Max(lo, Math.Min(hi, v)); } internal static double Smooth(double t) { t = Clamp(t, 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } internal static double Progress(int frame, int frames) { return Clamp((double)frame / (double)Math.Max(1, frames), 0.0, 1.0); } internal static double Curve(double a, double b, double c, double d, double t) { return 0.5 * (2.0 * b + (0.0 - a + c) * t + (2.0 * a - 5.0 * b + 4.0 * c - d) * t * t + (0.0 - a + 3.0 * b - 3.0 * c + d) * t * t * t); } internal static double Angle(double start, double speed, double seconds, bool clockwise) { return Wrap(start + speed * seconds * (double)(clockwise ? 1 : (-1))); } internal static double Wrap(double angle) { return (angle % 360.0 + 360.0) % 360.0; } internal static void Orbit(double radius, double height, double angle, out double x, out double y, out double z) { if (!Finite(radius) || radius < 0.25 || !Finite(height) || !Finite(angle)) { throw new ArgumentOutOfRangeException("radius", "Invalid orbit coordinates"); } double num = Wrap(angle) * Math.PI / 180.0; x = radius * Math.Sin(num); y = height; z = radius * Math.Cos(num); } } internal sealed class CameraOrbit { private readonly CinemaPlugin p; private readonly TakeClock clock = new TakeClock(); private Camera camera; private double radius; private double height; private double speed; private double start; private bool clockwise; private bool loop; private float fov; internal bool Paused; internal bool HasCenter { get; private set; } internal Vector3 Center { get; private set; } internal int Revision { get; private set; } internal bool Playing { get; private set; } internal CameraOrbit(CinemaPlugin plugin) { p = plugin; } internal void SetCenter(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!CameraRoute.ValidPosition(point)) { p.Status = Loc.Text("Центр должен иметь конечные координаты в пределах ±1000000.", "Center coordinates must be finite and within ±1000000."); return; } p.StopTakes(); Center = point; HasCenter = true; Revision++; p.Status = Loc.Text("Центр облёта сохранён. Настрой радиус и скорость, затем запускай.", "Orbit center saved. Set the radius and speed, then start."); } internal void CaptureHere() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) Camera viewCamera = CinemaPlugin.ViewCamera; if (!CL_GameManager.IsInGame() || (Object)(object)viewCamera == (Object)null) { p.Status = Loc.Text("Сначала начни забег.", "Start a run first."); } else { SetCenter(((Component)viewCamera).transform.position); } } internal void CaptureLookedAt() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) Camera viewCamera = CinemaPlugin.ViewCamera; if (!CL_GameManager.IsInGame() || (Object)(object)viewCamera == (Object)null) { p.Status = Loc.Text("Сначала начни забег.", "Start a run first."); return; } RaycastHit[] array = Physics.RaycastAll(((Component)viewCamera).transform.position, ((Component)viewCamera).transform.forward, 10000f, -1, (QueryTriggerInteraction)1); RaycastHit? val = null; ENT_Player playerObject = ENT_Player.playerObject; RaycastHit[] array2 = array; RaycastHit value2; for (int i = 0; i < array2.Length; i++) { RaycastHit value = array2[i]; if ((Object)(object)playerObject != (Object)null && (Object)(object)((RaycastHit)(ref value)).transform != (Object)null && ((RaycastHit)(ref value)).transform.IsChildOf(((Component)playerObject).transform)) { continue; } if (val.HasValue) { float distance = ((RaycastHit)(ref value)).distance; value2 = val.Value; if (!(distance < ((RaycastHit)(ref value2)).distance)) { continue; } } val = value; } if (!val.HasValue) { p.Status = Loc.Text("Под взглядом нет поверхности. Подлети к центру и выбери «Центр здесь» или введи XYZ.", "No surface under the crosshair. Fly to the center and choose 'Center at camera', or enter XYZ."); return; } value2 = val.Value; SetCenter(((RaycastHit)(ref value2)).point); FitToCamera(); p.Status = Loc.Text("Центр выбран на поверхности объекта под взглядом. Его можно уточнить по XYZ.", "Center placed on the surface under the crosshair. Adjust its XYZ coordinates if needed."); } internal void FitToCamera() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) Camera viewCamera = CinemaPlugin.ViewCamera; if (!HasCenter || (Object)(object)viewCamera == (Object)null) { p.Status = Loc.Text("Сначала выбери центр облёта.", "Choose an orbit center first."); return; } p.StopTakes(); Vector3 val = ((Component)viewCamera).transform.position - Center; float num = Mathf.Sqrt(val.x * val.x + val.z * val.z); p.OrbitRadius.Value = Mathf.Clamp(num, 0.25f, 10000f); p.OrbitHeight.Value = Mathf.Clamp(val.y, -10000f, 10000f); if (num >= 0.25f) { p.OrbitStartAngle.Value = (float)CameraMath.Wrap(Math.Atan2(val.x, val.z) * 180.0 / Math.PI); } p.Status = Loc.Text("Радиус, высота и начальная сторона взяты по текущей камере.", "Radius, height and start angle copied from the current camera view."); } private bool Prepare() { if (!HasCenter) { p.Status = Loc.Text("Сначала выбери центр облёта.", "Choose an orbit center first."); return false; } if (!p.EnsureFreecam()) { return false; } p.StopTakes(); camera = CameraTools.FreeCamera; radius = p.OrbitRadius.Value; height = p.OrbitHeight.Value; speed = p.OrbitSpeed.Value; start = p.OrbitStartAngle.Value; clockwise = p.OrbitClockwise.Value; loop = p.OrbitLoop.Value; fov = camera.fieldOfView; return true; } internal void Preview() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (Prepare()) { Apply(0.0); camera = null; p.Menu.Close(resume: true); p.Status = Loc.Text("Камера в начале круга. {0} — запустить облёт.", "Camera at the orbit start. {0} — start orbit.", p.OrbitPlayKey.Value); } } internal void Play() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (Prepare()) { clock.Start(p.StartDelay.Value); Playing = true; Paused = false; Apply(0.0); p.Menu.Close(resume: true); p.Status = Loc.Text("Облёт запущен. Камера смотрит в центр. {0} — остановить.", "Orbit started. The camera faces the center. {0} — stop.", p.OrbitPlayKey.Value); } } internal void Tick() { if (!Playing) { return; } if ((Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)CameraTools.FreeCamera) { Stop(); return; } clock.Maintain(); if (!p.HoldTake && !Paused) { double num = clock.Seconds; if (!loop) { num = Math.Min(num, 360.0 / speed); } Apply(num); if (!loop && num >= 360.0 / speed) { Stop(); p.Status = Loc.Text("Полный круг завершён. Камера осталась в начальном ракурсе.", "Full orbit complete. The camera is at the starting view."); } else { clock.Advance(); } } } private void Apply(double seconds) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) CameraMath.Orbit(radius, height, CameraMath.Angle(start, speed, seconds, clockwise), out var x, out var y, out var z); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor((float)x, (float)y, (float)z); CameraTools.ApplyPose(camera, Center + val, Quaternion.LookRotation(-val, Vector3.up), fov); } internal void Stop() { Playing = false; Paused = false; clock.Stop(); camera = null; } internal void Clear() { Stop(); HasCenter = false; Revision++; } internal void Offset(float amount) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (HasCenter) { Center += Vector3.up * amount; Revision++; } } } internal struct CameraMark { internal Vector3 Position; internal Quaternion Rotation; internal float Fov; } internal sealed class CameraRoute { private readonly List<CameraMark> marks = new List<CameraMark>(); private readonly List<CameraMark[]> history = new List<CameraMark[]>(); private readonly CinemaPlugin p; private readonly TakeClock clock = new TakeClock(); private Camera camera; private float duration; internal bool Paused; internal bool Playing { get; private set; } internal int Revision { get; private set; } internal int Count => marks.Count; internal bool CanUndo => history.Count > 0; internal double Progress => CameraMath.Clamp(clock.Seconds / (double)Math.Max(1f, duration), 0.0, 1.0); internal CameraRoute(CinemaPlugin plugin) { p = plugin; } private bool Valid(int i) { if (i >= 0) { return i < marks.Count; } return false; } internal CameraMark At(int i) { return marks[i]; } private void Remember() { p.StopTakes(); if (history.Count == 20) { history.RemoveAt(0); } history.Add(marks.ToArray()); Revision++; } internal void Add() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (marks.Count >= 100) { p.Status = Loc.Text("Максимум 100 точек в маршруте.", "A path can contain up to 100 points."); } else if (p.EnsureFreecam()) { Camera freeCamera = CameraTools.FreeCamera; Remember(); marks.Add(new CameraMark { Position = ((Component)freeCamera).transform.position, Rotation = ((Component)freeCamera).transform.rotation, Fov = freeCamera.fieldOfView }); p.Status = Loc.Text("Точка {0} добавлена: координаты, взгляд и угол обзора.", "Point {0} added: position, rotation and field of view.", Count); } } internal void Undo() { if (CanUndo) { p.StopTakes(); CameraMark[] collection = history[history.Count - 1]; history.RemoveAt(history.Count - 1); marks.Clear(); marks.AddRange(collection); Revision++; p.Status = Loc.Text("Последнее изменение маршрута отменено.", "Last path edit undone."); } } internal void Remove(int i) { if (Valid(i)) { Remember(); marks.RemoveAt(i); p.Status = Loc.Text("Точка удалена. Можно отменить.", "Point deleted. You can undo this change."); } } internal void Move(int i, int direction) { int num = i + direction; if (Valid(i) && Valid(num)) { Remember(); CameraMark value = marks[i]; marks[i] = marks[num]; marks[num] = value; p.Status = Loc.Text("Порядок точек изменён.", "Point order changed."); } } internal static bool ValidPosition(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (CameraMath.Finite(pos.x) && CameraMath.Finite(pos.y) && CameraMath.Finite(pos.z) && Math.Abs(pos.x) <= 1000000f && Math.Abs(pos.y) <= 1000000f) { return Math.Abs(pos.z) <= 1000000f; } return false; } internal void Edit(int i, Vector3 position, Vector3 angles, float fov) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (Valid(i)) { if (!ValidPosition(position) || !ValidPosition(angles) || !CameraMath.Finite(fov) || fov < 10f || fov > 140f) { p.Status = Loc.Text("Проверь координаты и углы. Угол обзора: от 10 до 140°.", "Check the coordinates and angles. Field of view must be 10–140°."); return; } Remember(); marks[i] = new CameraMark { Position = position, Rotation = Quaternion.Euler(angles), Fov = fov }; p.Status = Loc.Text("Точка {0} сохранена.", "Point {0} saved.", i + 1); } } internal void ReplaceFromCamera(int i) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (Valid(i) && p.EnsureFreecam()) { Camera freeCamera = CameraTools.FreeCamera; Remember(); marks[i] = new CameraMark { Position = ((Component)freeCamera).transform.position, Rotation = ((Component)freeCamera).transform.rotation, Fov = freeCamera.fieldOfView }; p.Status = Loc.Text("Точка {0} заменена текущим ракурсом.", "Point {0} replaced with the current view.", i + 1); } } internal void GoTo(int i) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (Valid(i) && p.EnsureFreecam()) { p.StopTakes(); CameraMark cameraMark = marks[i]; CameraTools.ApplyPose(CameraTools.FreeCamera, cameraMark.Position, cameraMark.Rotation, cameraMark.Fov); p.Status = Loc.Text("Камера в точке {0}. Закрой меню для уточнения ракурса.", "Camera at point {0}. Close the menu to adjust the view.", i + 1); } } internal void ClearEditable() { if (marks.Count != 0) { Remember(); marks.Clear(); p.Status = Loc.Text("Маршрут очищен. Очистку можно отменить.", "Path cleared. You can undo this change."); } } internal void Clear() { Stop(); marks.Clear(); history.Clear(); Revision++; } internal void Play() { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if (marks.Count < 2) { p.Status = Loc.Text("Для маршрута нужны хотя бы две точки.", "A path needs at least two points."); } else if (p.EnsureFreecam()) { p.StopTakes(); camera = CameraTools.FreeCamera; duration = p.RouteDuration.Value; clock.Start(p.StartDelay.Value); Playing = true; Paused = false; Apply(0.0); p.Menu.Close(resume: true); p.Status = Loc.Text("Проезд запущен. {0} — остановить.", "Path started. {0} — stop.", p.RoutePlayKey.Value); } } internal void Tick() { if (!Playing) { return; } if ((Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)CameraTools.FreeCamera) { Stop(); return; } clock.Maintain(); if (!p.HoldTake && !Paused) { double progress = Progress; Apply(progress); if (progress >= 1.0) { Stop(); p.Status = Loc.Text("Проезд завершён. Повтор запускается с той же точки.", "Path complete. Replaying starts from the same point."); } else { clock.Advance(); } } } private void Apply(double progress) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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) double num = CameraMath.Smooth(progress) * (double)(Count - 1); int num2 = Math.Min(Count - 2, (int)num); float num3 = (float)(num - (double)num2); CameraMark cameraMark = marks[Math.Max(0, num2 - 1)]; CameraMark cameraMark2 = marks[num2]; CameraMark cameraMark3 = marks[num2 + 1]; CameraMark cameraMark4 = marks[Math.Min(Count - 1, num2 + 2)]; Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor((float)CameraMath.Curve(cameraMark.Position.x, cameraMark2.Position.x, cameraMark3.Position.x, cameraMark4.Position.x, num3), (float)CameraMath.Curve(cameraMark.Position.y, cameraMark2.Position.y, cameraMark3.Position.y, cameraMark4.Position.y, num3), (float)CameraMath.Curve(cameraMark.Position.z, cameraMark2.Position.z, cameraMark3.Position.z, cameraMark4.Position.z, num3)); CameraTools.ApplyPose(camera, position, Quaternion.Slerp(cameraMark2.Rotation, cameraMark3.Rotation, num3), Mathf.Lerp(cameraMark2.Fov, cameraMark3.Fov, num3)); } internal void Stop() { Playing = false; Paused = false; clock.Stop(); camera = null; } internal void Offset(float amount) { Revision++; foreach (CameraMark[] item in history) { for (int i = 0; i < item.Length; i++) { CameraMark cameraMark = item[i]; cameraMark.Position.y += amount; item[i] = cameraMark; } } for (int j = 0; j < Count; j++) { CameraMark value = marks[j]; value.Position.y += amount; marks[j] = value; } } } internal sealed class CameraTools { private GameObject hiddenCrosshair; private bool originalActive; private DebugCameraController settingsOwner; private float oldFov; private float oldSpeed; private float oldTurn; private float oldSmooth; internal static bool Freecam { get { if ((Object)(object)CL_GameManager.gMan != (Object)null) { return CL_GameManager.gMan.freecam; } return false; } } internal static Camera FreeCamera { get { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!Freecam) { return null; } DebugCameraController val = FreecamMemory.Controller; if ((Object)(object)val == (Object)null) { DebugCameraController[] array = Resources.FindObjectsOfTypeAll<DebugCameraController>(); foreach (DebugCameraController val2 in array) { Scene scene = ((Component)val2).gameObject.scene; if (((Scene)(ref scene)).IsValid() && ((Behaviour)val2).isActiveAndEnabled) { FreecamMemory.Validate(val2); val = val2; break; } } } Camera val3 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Camera>() : null); if (!((Object)(object)val3 != (Object)null) || !((Behaviour)val3).isActiveAndEnabled) { return null; } return val3; } } internal void Tick() { CL_UIManager instance = CL_UIManager.instance; GameObject val = (((Object)(object)instance != (Object)null && (Object)(object)instance.crosshairController != (Object)null && (Object)(object)instance.crosshairController.crosshairRoot != (Object)null) ? ((Component)instance.crosshairController.crosshairRoot).gameObject : null); if (!Freecam || (Object)(object)val != (Object)(object)hiddenCrosshair || !CinemaPlugin.Instance.HideCrosshair.Value) { Restore(); } if (Freecam && !((Object)(object)val == (Object)null) && CinemaPlugin.Instance.HideCrosshair.Value) { if ((Object)(object)hiddenCrosshair == (Object)null) { hiddenCrosshair = val; originalActive = val.activeSelf; } val.SetActive(false); } } internal void Restore() { if ((Object)(object)hiddenCrosshair != (Object)null) { hiddenCrosshair.SetActive(originalActive); } hiddenCrosshair = null; } internal void TrackSettings() { DebugCameraController controller = FreecamMemory.Controller; if (!((Object)(object)controller == (Object)null) && !((Object)(object)controller == (Object)(object)settingsOwner)) { settingsOwner = controller; oldFov = ((Component)controller).GetComponent<Camera>().fieldOfView; oldSpeed = ReadNative("speed"); oldTurn = ReadNative("turnSpeed"); oldSmooth = ReadNative("smoothMovement"); } } internal static float ReadNative(string field) { DebugCameraController controller = FreecamMemory.Controller; if (!((Object)(object)controller == (Object)null)) { return Traverse.Create((object)controller).Field(field).GetValue<float>(); } return 0f; } internal void SetNative(string field, float value) { if (!((Object)(object)FreecamMemory.Controller == (Object)null) && CameraMath.Finite(value)) { TrackSettings(); Traverse.Create((object)FreecamMemory.Controller).Field(field).SetValue((object)value); } } internal void RestoreSettings() { if ((Object)(object)settingsOwner != (Object)null) { ((Component)settingsOwner).GetComponent<Camera>().fieldOfView = oldFov; Traverse obj = Traverse.Create((object)settingsOwner); obj.Field("speed").SetValue((object)oldSpeed); obj.Field("turnSpeed").SetValue((object)oldTurn); obj.Field("smoothMovement").SetValue((object)oldSmooth); } settingsOwner = null; } internal static void ApplyPose(Camera camera, Vector3 position, Quaternion rotation, float fov) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) CinemaPlugin.Instance.CameraTools.TrackSettings(); ((Component)camera).transform.SetPositionAndRotation(position, rotation); camera.fieldOfView = Mathf.Clamp(fov, 10f, 140f); FreecamMemory.SyncLook(rotation); DebugCameraController controller = FreecamMemory.Controller; if ((Object)(object)controller != (Object)null) { Traverse.Create((object)controller).Field("targetMovement").SetValue((object)Vector3.zero); Traverse.Create((object)controller).Field("targetRotation").SetValue((object)FreecamMemory.LookAngles); } FreecamMemory.Position = position; FreecamMemory.Rotation = rotation; FreecamMemory.Fov = camera.fieldOfView; FreecamMemory.Saved = true; } internal static void DrawFrame() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) float num = Screen.height; float num2 = Mathf.Min((float)Screen.width, num * 9f / 16f); num = num2 * 16f / 9f; float num3 = ((float)Screen.width - num2) / 2f; float num4 = ((float)Screen.height - num) / 2f; Color color = GUI.color; int depth = GUI.depth; Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.identity; GUI.depth = -9000; try { GUI.color = new Color(0f, 0f, 0f, 0.55f); GUI.DrawTexture(new Rect(0f, 0f, num3, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num3 + num2, 0f, num3, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num3, 0f, num2, num4), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num3, num4 + num, num2, num4), (Texture)(object)Texture2D.whiteTexture); GUI.color = new Color(0.6f, 0.95f, 1f, 0.9f); GUI.DrawTexture(new Rect(num3, num4, 2f, num), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num3 + num2 - 2f, num4, 2f, num), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num3, num4, num2, 2f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num3, num4 + num - 2f, num2, 2f), (Texture)(object)Texture2D.whiteTexture); } finally { GUI.color = color; GUI.depth = depth; GUI.matrix = matrix; } } } internal static class FreecamMemory { internal static DebugCameraController Controller; internal static Vector3 Position; internal static Quaternion Rotation; internal static bool Saved; internal static float Fov = 90f; internal static float Roll; internal static Vector3 LookAngles; private static int scene; internal static void Validate(DebugCameraController camera) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); int num = SceneHandle.op_Implicit(((Scene)(ref activeScene)).handle); if ((Object)(object)Controller != (Object)(object)camera || scene != num) { Saved = false; LookAngles = ((Component)camera).transform.eulerAngles; Roll = LookAngles.z; } Controller = camera; scene = num; } internal static void Clear() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Controller = null; Saved = false; Roll = 0f; LookAngles = Vector3.zero; } internal static void SyncLook(Quaternion rotation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (Quaternion.Angle(Quaternion.Euler(LookAngles), rotation) > 0.01f) { LookAngles = ((Quaternion)(ref rotation)).eulerAngles; } Roll = LookAngles.z; } internal static void Offset(float amount) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (Saved) { Position += Vector3.up * amount; } } internal static void ResetToPlayer() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null || (Object)(object)playerObject.cam == (Object)null) { CinemaPlugin.Instance.Status = Loc.Text("Сначала начни забег.", "Start a run first."); return; } if ((Object)(object)Controller == (Object)null) { Saved = false; CinemaPlugin.Instance.Status = Loc.Text("При включении фрикам появится у игрока.", "Freecam will start at the player when enabled."); return; } Validate(Controller); Position = ((Component)playerObject.cam).transform.position; Rotation = ((Component)playerObject.cam).transform.rotation; Fov = playerObject.cam.fieldOfView; Saved = true; CameraTools.ApplyPose(((Component)Controller).GetComponent<Camera>(), Position, Rotation, Fov); Traverse.Create((object)Controller).Field("targetMovement").SetValue((object)Vector3.zero); CinemaPlugin.Instance.Status = Loc.Text("Фрикам возвращён к игроку. Ракурс сброшен.", "Freecam returned to the player. Saved view reset."); } } [HarmonyPatch(typeof(DebugCameraController), "ToggleActive")] internal static class FreecamPositionPatch { private static void Prefix(DebugCameraController __instance, bool ___active) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) FreecamMemory.Validate(__instance); if (___active) { FreecamMemory.Position = ((Component)__instance).transform.position; FreecamMemory.Rotation = ((Component)__instance).transform.rotation; FreecamMemory.Fov = ((Component)__instance).GetComponent<Camera>().fieldOfView; FreecamMemory.Saved = true; } } private static void Postfix(DebugCameraController __instance, bool ___active, ref Vector3 ___targetMovement, ref Vector3 ___targetRotation) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!___active) { if ((Object)(object)CinemaPlugin.Instance != (Object)null) { CinemaPlugin.Instance.StopTakes(); } return; } if (FreecamMemory.Saved) { CameraTools.ApplyPose(((Component)__instance).GetComponent<Camera>(), FreecamMemory.Position, FreecamMemory.Rotation, FreecamMemory.Fov); } FreecamMemory.SyncLook(((Component)__instance).transform.rotation); ___targetMovement = Vector3.zero; ___targetRotation = FreecamMemory.LookAngles; } } [HarmonyPatch(typeof(DebugCameraController), "Update")] internal static class FreecamMenuPatch { private static bool Prefix(DebugCameraController __instance, bool ___active, ref Vector3 ___targetMovement, ref Vector3 ___targetRotation, out bool __state) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) __state = false; CinemaPlugin instance = CinemaPlugin.Instance; if ((Object)(object)instance == (Object)null || instance.Menu == null || !___active) { return true; } FreecamMemory.Validate(__instance); if (!instance.BlockCameraFrame && !instance.HoldTake && !instance.Automated && !CinemaShortcuts.Pressed(instance.MenuKey.Value) && !CinemaShortcuts.Pressed(instance.RoutePlayKey.Value) && !CinemaShortcuts.Pressed(instance.OrbitPlayKey.Value)) { __state = true; return true; } ___targetMovement = Vector3.zero; ___targetRotation = FreecamMemory.LookAngles; return false; } private static void Postfix(DebugCameraController __instance, ref Vector3 ___targetRotation, bool __state, bool __runOriginal) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) CinemaPlugin instance = CinemaPlugin.Instance; if (__state && __runOriginal && !((Object)(object)instance == (Object)null) && CameraTools.Freecam && ((Behaviour)__instance).isActiveAndEnabled) { ((Component)__instance).transform.rotation = FreecamLook.Step(ref ___targetRotation, ref FreecamMemory.LookAngles, FreecamMemory.Roll, instance.LookSmoothing.Value, Time.unscaledDeltaTime); } } } internal sealed class CinemaMenu { private readonly CinemaPlugin p; private CL_GameManager manager; private bool ownsPause; private bool hidPauseMenu; private bool oldShowCursor; private bool pauseContext; private CursorLockMode oldLock; private int scene; private int tab; private Vector2 scroll; private GUIStyle label; private GUIStyle title; private GUIStyle button; private GUIStyle field; private GUIStyle heading; private GUIStyle toggle; private Action pending; private readonly Dictionary<string, string> inputs = new Dictionary<string, string>(); private int selected = -1; private int routeRevision = -1; private int orbitRevision = -1; private readonly string[] routeFields = new string[7]; private readonly string[] centerFields = new string[3]; internal bool Visible { get; private set; } internal CinemaMenu(CinemaPlugin plugin) { p = plugin; } internal void Open() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) if (Visible || ((Object)(object)CL_GameManager.gMan != (Object)null && CL_GameManager.IsLoading())) { return; } if (CompanionMenus.AnyOpen) { p.Status = Loc.Text("Сначала закрой открытое меню другого мода.", "Close the other mod's menu first."); return; } manager = CL_GameManager.gMan; Scene activeScene = SceneManager.GetActiveScene(); scene = SceneHandle.op_Implicit(((Scene)(ref activeScene)).handle); oldShowCursor = CL_GameManager.showCursor; oldLock = Cursor.lockState; ownsPause = false; hidPauseMenu = false; pauseContext = CL_GameManager.IsInGame() && (Object)(object)manager != (Object)null; if (pauseContext) { if (!manager.isPaused && !manager.canPause) { p.Status = Loc.Text("Сейчас игра не может встать на паузу.", "The game cannot be paused right now."); return; } ownsPause = !manager.isPaused; if (ownsPause) { manager.Pause(); } if ((Object)(object)manager.pauseMenu != (Object)null && manager.pauseMenu.activeSelf) { manager.pauseMenu.SetActive(false); hidPauseMenu = true; } } Cursor.lockState = (CursorLockMode)0; CL_GameManager.showCursor = true; Cursor.visible = true; inputs.Clear(); Visible = true; } internal void Tick() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (pending != null) { Action action = pending; pending = null; p.Guard(action); } if (Visible) { SceneHandle val = SceneHandle.op_Implicit(scene); Scene activeScene = SceneManager.GetActiveScene(); if (val != ((Scene)(ref activeScene)).handle || (pauseContext && (Object)(object)manager != (Object)null && !manager.isPaused)) { Close(resume: false); } else if (Input.GetKeyDown((KeyCode)27)) { p.BlockCameraFrame = true; Close(resume: true); } } } internal void Close(bool resume) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (!Visible) { return; } Visible = false; p.BlockCameraFrame = true; SceneHandle val = SceneHandle.op_Implicit(scene); Scene activeScene = SceneManager.GetActiveScene(); if (val == ((Scene)(ref activeScene)).handle) { if (pauseContext && (Object)(object)manager != (Object)null && (Object)(object)manager == (Object)(object)CL_GameManager.gMan) { if (ownsPause && resume && manager.isPaused) { manager.UnPause(); } else if (manager.isPaused && hidPauseMenu && (Object)(object)manager.pauseMenu != (Object)null) { manager.pauseMenu.SetActive(true); } CL_GameManager.showCursor = manager.isPaused; Cursor.lockState = (CursorLockMode)(!manager.isPaused); Cursor.visible = manager.isPaused; } else { CL_GameManager.showCursor = oldShowCursor; Cursor.lockState = oldLock; Cursor.visible = oldShowCursor; } } manager = null; ownsPause = false; hidPauseMenu = false; } private void Styles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0069: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00b4: Expected O, but got Unknown //IL_00b9: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) if (label == null) { label = new GUIStyle(GUI.skin.label) { fontSize = 18, wordWrap = true }; label.normal.textColor = Color.white; title = new GUIStyle(label) { fontSize = 27, fontStyle = (FontStyle)1 }; heading = new GUIStyle(label) { fontSize = 21, fontStyle = (FontStyle)1 }; button = new GUIStyle(GUI.skin.button) { fontSize = 18, wordWrap = true, padding = new RectOffset(10, 10, 10, 10) }; field = new GUIStyle(GUI.skin.textField) { fontSize = 20 }; toggle = new GUIStyle(GUI.skin.toggle) { fontSize = 18, wordWrap = true }; toggle.normal.textColor = Color.white; } } internal void Draw() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) Styles(); Matrix4x4 matrix = GUI.matrix; int depth = GUI.depth; Color color = GUI.color; float num = Mathf.Min(1.25f, Mathf.Min((float)Screen.width / 1000f, (float)Screen.height / 820f)); float num2 = ((float)Screen.width / num - 960f) / 2f; float num3 = ((float)Screen.height / num - 780f) / 2f; GUI.matrix = Matrix4x4.Scale(Vector3.one * num); GUI.depth = -10000; try { GUI.color = new Color(0.055f, 0.068f, 0.09f, 1f); GUI.DrawTexture(new Rect(num2, num3, 960f, 780f), (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; GUILayout.BeginArea(new Rect(num2 + 24f, num3 + 18f, 912f, 744f)); Row(delegate { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label((string)Loc.Text("WK Cinema · Съёмка", "WK Cinema · Filming"), title, Array.Empty<GUILayoutOption>()); Btn(string.Concat(Loc.Text("Закрыть · ", "Close · "), ((object)p.MenuKey.Value/*cast due to .constrained prefix*/).ToString()), delegate { Close(resume: true); }); if (GameLanguage.OwnsButton && GUILayout.Button(GameLanguage.ButtonLabel, button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(78f) })) { GameLanguage.Toggle(); } }); GUILayout.Label((string)Loc.Text("Меню ставит съёмку на паузу. Клавиши и сочетания можно менять в конфиге WKCinema через r2modman.", "The menu pauses filming. Change shortcuts in the WKCinema config through r2modman."), label, Array.Empty<GUILayoutOption>()); Row(delegate { Tab(Loc.Text("Камера", "Camera"), 0); Tab(Loc.Text("Маршрут", "Path"), 1); Tab(Loc.Text("Облёт", "Orbit"), 2); Tab(Loc.Text("Мир и место", "World and location"), 3); }); GUILayout.Space(10f); scroll = GUILayout.BeginScrollView(scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(525f) }); if (tab == 0) { CameraPage(); } else if (tab == 1) { RoutePage(); } else if (tab == 2) { OrbitPage(); } else { SessionPage(); } GUILayout.EndScrollView(); GUILayout.Space(8f); GUILayout.Label((string)p.Status, label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(65f) }); GUILayout.Label("WK Cinema 0.2.4" + Loc.Text(" · Изменения полей подтверждаются кнопкой «Применить».", " · Confirm field edits with Apply."), label, Array.Empty<GUILayoutOption>()); GUILayout.EndArea(); } finally { GUI.matrix = matrix; GUI.depth = depth; GUI.color = color; } } private void Tab(string text, int index) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) Color backgroundColor = GUI.backgroundColor; if (tab == index) { GUI.backgroundColor = new Color(0.35f, 0.8f, 1f); } if (GUILayout.Button(text, button, Array.Empty<GUILayoutOption>())) { tab = index; scroll = Vector2.zero; } GUI.backgroundColor = backgroundColor; } internal void DrawMainMenuLanguage() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) Styles(); Matrix4x4 matrix = GUI.matrix; int depth = GUI.depth; Color color = GUI.color; Color backgroundColor = GUI.backgroundColor; bool enabled = GUI.enabled; float num = Mathf.Min(1.25f, Mathf.Min((float)Screen.width / 1000f, (float)Screen.height / 820f)); GUI.matrix = Matrix4x4.Scale(Vector3.one * num); GUI.depth = -10000; GUI.color = Color.white; GUI.backgroundColor = Color.white; GUI.enabled = true; try { GUILayout.BeginArea(new Rect((float)Screen.width / num - 278f, 18f, 260f, 58f)); Row(delegate { GUILayout.Label((string)Loc.Text("Язык модов", "Mod language"), label, Array.Empty<GUILayoutOption>()); if (GUILayout.Button(GameLanguage.ButtonLabel, button, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(78f), GUILayout.MinHeight(42f) })) { GameLanguage.Toggle(); } }); GUILayout.EndArea(); } finally { GUI.matrix = matrix; GUI.depth = depth; GUI.color = color; GUI.backgroundColor = backgroundColor; GUI.enabled = enabled; } } private void CameraPage() { GUILayout.Label((string)(CameraTools.Freecam ? Loc.Text("Сейчас: свободная камера", "Current mode: free camera") : Loc.Text("Сейчас: управление игроком", "Current mode: player control")), heading, Array.Empty<GUILayoutOption>()); Row(delegate { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) Btn(string.Concat(CameraTools.Freecam ? Loc.Text("Вернуться к игроку", "Return to player") : Loc.Text("Включить фрикам", "Enable freecam"), " · ", ((object)p.FreecamKey.Value/*cast due to .constrained prefix*/).ToString()), delegate { p.ToggleFreecam(); Close(resume: true); }); Btn(Loc.Text("Вернуть камеру к игроку", "Reset camera to player"), delegate { p.ResetCamera(); Close(resume: true); }); }); GUILayout.Label((string)Loc.Text("Положение фрикама сохраняется при переключении на игрока и обратно.", "The freecam view is remembered when switching to the player and back."), label, Array.Empty<GUILayoutOption>()); GUILayout.Label((string)Loc.Text("Фрикам сам включает необходимые читы. Игра отключает статистику этого забега.", "Freecam enables the required cheats automatically. The game disables statistics for this run."), label, Array.Empty<GUILayoutOption>()); Row(delegate { Btn(Loc.Text("Включить читы + бессмертие + ноуклип", "Enable cheats + godmode + noclip"), p.EnableFilmingCheats); Btn(Loc.Text("Отключить ноуклип", "Disable noclip"), p.DisableNoclip); }); p.ShortsFrame.Value = GUILayout.Toggle(p.ShortsFrame.Value, (string)Loc.Text(" Разметка Shorts 9:16", " Shorts guide 9:16"), toggle, Array.Empty<GUILayoutOption>()); p.HideCrosshair.Value = GUILayout.Toggle(p.HideCrosshair.Value, (string)Loc.Text(" Скрыть прицел во фрикаме", " Hide crosshair in freecam"), toggle, Array.Empty<GUILayoutOption>()); Camera c = CameraTools.FreeCamera; if ((Object)(object)c != (Object)null) { GUILayout.Space(10f); GUILayout.Label((string)Loc.Text("Настройка ракурса", "Camera settings"), heading, Array.Empty<GUILayoutOption>()); LiveNumber("fov", Loc.Text("Угол обзора, °", "Field of view, °"), c.fieldOfView, 10f, 140f, 140f, delegate(float v) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) p.StopTakes(); CameraTools.ApplyPose(c, ((Component)c).transform.position, ((Component)c).transform.rotation, v); }); LiveNumber("speed", Loc.Text("Скорость свободного полёта", "Freecam movement speed"), CameraTools.ReadNative("speed"), 0.1f, 1000f, 50f, delegate(float v) { p.CameraTools.SetNative("speed", v); }); LiveNumber("turn", Loc.Text("Скорость поворота", "Turn speed"), CameraTools.ReadNative("turnSpeed"), 0.05f, 100f, 5f, delegate(float v) { p.CameraTools.SetNative("turnSpeed", v); }); LiveNumber("smooth", Loc.Text("Плавность перемещения", "Movement smoothing"), CameraTools.ReadNative("smoothMovement"), 0.01f, 10f, 5f, delegate(float v) { p.CameraTools.SetNative("smoothMovement", v); }); Number("lookSmooth", Loc.Text("Сглаживание поворота, сек. (0 — выкл.)", "Look smoothing, seconds (0 = off)"), p.LookSmoothing, 0f, 2f, 2f); } Number("delay", Loc.Text("Пауза перед дублем, сек.", "Delay before take, seconds"), p.StartDelay, 0f, 10f, 5f); GUILayout.Label((string)Loc.Text("Полёт: WASD; вверх/вниз — Space/F; Q — точная подстройка. Колесо — скорость, Shift + колесо — угол обзора, Alt + колесо — скорость поворота. Разметка включается в этом меню.", "Fly: WASD; up/down: Space/F; precision: Q. Wheel: speed; Shift + wheel: field of view; Alt + wheel: turn speed. Toggle the guide in this menu."), label, Array.Empty<GUILayoutOption>()); } private void SessionPage() { WorldSession s = p.Session; GUILayout.Label((string)Loc.Text("Один мир · одно место съёмки", "Same world · same filming location"), heading, Array.Empty<GUILayoutOption>()); GUILayout.Label((string)Loc.Text("Красный закрытый замок — закреплено. Зелёный открытый — свободно. Настройки сохраняются после выхода из игры.", "Red closed lock: fixed. Green open lock: unlocked. Settings persist after leaving the game."), label, Array.Empty<GUILayoutOption>()); GUILayout.Space(6f); if (!inputs.ContainsKey("worldSeed")) { inputs["worldSeed"] = (s.SeedLocked.Value ? s.Seed.Value : s.CurrentSeed).ToString(CultureInfo.InvariantCulture); } if (!inputs.ContainsKey("worldHeight")) { inputs["worldHeight"] = Format((s.HeightLocked.Value || s.HasAnchor) ? s.Height.Value : s.CurrentHeight); } Row(delegate { GUILayout.Label((string)Loc.Text("Сид мира", "World seed"), label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }); inputs["worldSeed"] = GUILayout.TextField(inputs["worldSeed"], field, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(330f) }); string value = inputs["worldSeed"]; LockButton(s.SeedLocked.Value, s.SeedLocked.Value ? Loc.Text("Закреплён", "Fixed") : Loc.Text("Случайный", "Random"), delegate { if (s.SeedLocked.Value) { s.ApplySeed(s.Seed.Value.ToString(CultureInfo.InvariantCulture), locked: false); } else { s.ApplySeed(value, locked: true); } }); }); Row(delegate { Btn(Loc.Text("Взять текущий сид", "Use current seed"), delegate { s.UseCurrentSeed(); inputs["worldSeed"] = s.Seed.Value.ToString(CultureInfo.InvariantCulture); }); string value = inputs["worldSeed"]; Btn(Loc.Text("Применить сид", "Apply seed"), delegate { s.ApplySeed(value, s.SeedLocked.Value); }); }); GUILayout.Label(string.Concat(Loc.Text("Сейчас: ", "Current: "), s.CurrentSeed.ToString(), Loc.Text(". Закрепляется стартовый сид забега. Изменение вступит в силу при новом запуске уровня.", ". Locks the run's starting seed. Changes apply on a new run.")), label, Array.Empty<GUILayoutOption>()); GUILayout.Space(12f); Row(delegate { GUILayout.Label((string)Loc.Text("Высота игрока, м", "Player height, m"), label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) }); inputs["worldHeight"] = GUILayout.TextField(inputs["worldHeight"], field, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(330f) }); string value = inputs["worldHeight"]; LockButton(s.HeightLocked.Value, s.HeightLocked.Value ? Loc.Text("Возврат включён", "Return enabled") : Loc.Text("Обычный старт", "Normal start"), delegate { if (s.HeightLocked.Value) { s.ApplyHeight(Format(s.Height.Value), locked: false); } else { s.ApplyHeight(value, locked: true); } }); }); Row(delegate { Btn(Loc.Text("Взять текущую высоту", "Use current height"), delegate { inputs["worldHeight"] = Format(s.CurrentHeight); s.ApplyHeight(inputs["worldHeight"], s.HeightLocked.Value); }); string value = inputs["worldHeight"]; Btn(Loc.Text("Применить высоту", "Apply height"), delegate { s.ApplyHeight(value, s.HeightLocked.Value); }); }); GUILayout.Label(string.Concat(Loc.Text("Сейчас: ", "Current: "), s.CurrentHeight.ToString("0.00"), Loc.Text(" м. ", " m. "), s.PlaceName), label, Array.Empty<GUILayoutOption>()); Btn(Loc.Text("Запомнить это место и закрепить оба замка", "Save this location and lock both settings"), delegate { if (s.Capture(lockBoth: true)) { inputs["worldSeed"] = s.Seed.Value.ToString(CultureInfo.InvariantCulture); inputs["worldHeight"] = Format(s.Height.Value); } }); GUILayout.Label((string)Loc.Text("Сохраняются участок мира, точная позиция и взгляд игрока. При включённом фрикаме сохраняется и его ракурс. Ручное изменение высоты выбирает новую высоту вместо точной точки.", "Saves the world section, exact player position and view. Active freecam view is saved too. Editing the height replaces the exact location with an altitude."), label, Array.Empty<GUILayoutOption>()); GUILayout.Label((string)Loc.Text("Возврат включает съёмочные читы, бессмертие и ноуклип, чтобы не упасть при загрузке. Поддерживается основной мир в том же режиме игры; новые забеги получают выбранные настройки.", "Returning enables filming cheats, godmode and noclip to prevent falling on load. Supports the main world in the same game mode. Settings apply to new runs."), label, Array.Empty<GUILayoutOption>()); Row(delegate { Btn(Loc.Text("Вернуться сейчас", "Return now"), s.ReturnNow); Btn(Loc.Text("Перезапустить с этими настройками", "Restart with these settings"), s.Restart); }); if (s.Restoring) { Btn(Loc.Text("Отменить возврат", "Cancel return"), delegate { s.Cancel(); }); } GUILayout.Label((string)Loc.Text("Случайный сид + закреплённая высота = та же высота в другом мире. Оба красных замка + сохранённое место = повторная съёмка той же локации.", "Random seed + locked height: same altitude in a different world. Both red locks + a saved location: film the same place again."), label, Array.Empty<GUILayoutOption>()); } private void LockButton(bool locked, string text, Action action) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Invalid comparison between Unknown and I4 //IL_0091: 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) //IL_00a8: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = (locked ? new Color(1f, 0.25f, 0.25f) : new Color(0.2f, 1f, 0.4f)); if (GUILayout.Button(" " + text, button, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(300f), GUILayout.Height(46f) })) { pending = action; } Rect lastRect = GUILayoutUtility.GetLastRect(); GUI.backgroundColor = backgroundColor; if ((int)Event.current.type == 7) { Color color = GUI.color; GUI.color = (locked ? new Color(1f, 0.35f, 0.35f) : new Color(0.25f, 1f, 0.45f)); float num = ((Rect)(ref lastRect)).x + 14f; float num2 = ((Rect)(ref lastRect)).y + 8f; GUI.DrawTexture(new Rect(num, num2 + 14f, 22f, 16f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num + 3f, num2 + 3f, 4f, (float)(locked ? 14 : 9)), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num + 3f, num2, 16f, 4f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(num + 15f, num2 + 3f, 4f, 14f), (Texture)(object)Texture2D.whiteTexture); GUI.color = new Color(0.06f, 0.07f, 0.09f); GUI.DrawTexture(new Rect(num + 9f, num2 + 19f, 4f, 7f), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; } } private void Select(int i) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) selected = ((p.Route.Count == 0) ? (-1) : Mathf.Clamp(i, 0, p.Route.Count - 1)); routeRevision = p.Route.Revision; if (selected >= 0) { CameraMark cameraMark = p.Route.At(selected); Vector3 eulerAngles = ((Quaternion)(ref cameraMark.Rotation)).eulerAngles; float[] array = new float[7] { cameraMark.Position.x, cameraMark.Position.y, cameraMark.Position.z, eulerAngles.x, eulerAngles.y, eulerAngles.z, cameraMark.Fov }; for (int j = 0; j < array.Length; j++) { routeFields[j] = Format(array[j]); } } } private void ApplyPoint() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) float[] array = new float[7]; for (int i = 0; i < 7; i++) { if (!Parse(routeFields[i], out array[i])) { p.Status = Loc.Text("Введи координаты, углы и обзор числами.", "Enter numeric coordinates, angles and field of view."); return; } } p.Route.Edit(selected, new Vector3(array[0], array[1], array[2]), new Vector3(array[3], array[4], array[5]), array[6]); } private void RoutePage() { //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) if (routeRevision != p.Route.Revision) { Select(selected); } GUILayout.Label(string.Concat(Loc.Text("Проезд по точкам · ", "Camera path · "), p.Route.Count.ToString(), " / 100"), heading, Array.Empty<GUILayoutOption>()); GUILayout.Label((string)Loc.Text("Выбери ракурс, добавь точку, перелети дальше и добавь следующую. Каждая точка хранит позицию, направление взгляда и угол обзора.", "Choose a view, add a point, fly to another view and add the next. Each point stores position, rotation and field of view."), label, Array.Empty<GUILayoutOption>()); Row(delegate { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Btn(string.Concat(Loc.Text("Добавить · ", "Add · "), ((object)p.RoutePointKey.Value/*cast due to .constrained prefix*/).ToString()), delegate { p.Route.Add(); Select(p.Route.Count - 1); }); bool enabled = GUI.enabled; GUI.enabled = enabled && p.Route.CanUndo; Btn(Loc.Text("Отменить правку", "Undo edit"), p.Route.Undo); GUI.enabled = enabled; Btn(Loc.Text("Очистить маршрут", "Clear path"), p.Route.ClearEditable); }); Number("routeTime", Loc.Text("Длительность проезда, сек.", "Path duration, seconds"), p.RouteDuration, 1f, 600f, 60f); Row(delegate { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Btn(p.Route.Playing ? ((string)Loc.Text("Повторить с начала", "Restart from beginning")) : string.Concat(Loc.Text("Запустить · ", "Start · "), ((object)p.RoutePlayKey.Value/*cast due to .constrained prefix*/).ToString()), p.Route.Play); Btn(p.Route.Paused ? Loc.Text("Продолжить", "Resume") : Loc.Text("Пауза", "Pause"), delegate { if (p.Route.Playing) { p.Route.Paused = !p.Route.Paused; Close(resume: true); } }); Btn(Loc.Text("Остановить", "Stop"), p.StopTakes); }); if (selected >= 0 && selected < p.Route.Count) { GUILayout.Space(8f); GUILayout.Label(string.Concat(Loc.Text("Точка ", "Point "), (selected + 1).ToString()), heading, Array.Empty<GUILayoutOption>()); Row(delegate { Field("X", routeFields, 0); Field(Loc.Text("Y (высота)", "Y (height)"), routeFields, 1); Field("Z", routeFields, 2); }); Row(delegate { Field(Loc.Text("Наклон °", "Pitch °"), routeFields, 3); Field(Loc.Text("Поворот °", "Yaw °"), routeFields, 4); Field(Loc.Text("Крен °", "Roll °"), routeFields, 5); }); Row(delegate { Field(Loc.Text("Обзор °", "FOV °"), routeFields, 6); Btn(Loc.Text("Применить", "Apply"), ApplyPoint); Btn(Loc.Text("Сбросить ввод", "Reset input"), delegate { Select(selected); }); }); Row(delegate { Btn(Loc.Text("Показать этот ракурс", "Preview this point"), delegate { p.Route.GoTo(selected); Close(resume: true); }); Btn(Loc.Text("Заменить текущим ракурсом", "Replace with current view"), delegate { p.Route.ReplaceFromCamera(selected); }); }); Row(delegate { Btn(Loc.Text("Раньше", "Move earlier"), delegate { if (selected > 0) { p.Route.Move(selected, -1); Select(selected - 1); } }); Btn(Loc.Text("Позже", "Move later"), delegate { if (selected < p.Route.Count - 1) { p.Route.Move(selected, 1); Select(selected + 1); } }); Btn(Loc.Text("Удалить точку", "Delete point"), delegate { p.Route.Remove(selected); }); }); } GUILayout.Space(8f); GUILayout.Label((string)Loc.Text("Выбери точку для редактирования", "Select a point to edit"), heading, Array.Empty<GUILayoutOption>()); for (int num = 0; num < p.Route.Count; num++) { int index = num; Vector3 position = p.Route.At(num).Position; Btn(string.Concat((selected == num) ? "▶ " : "", Loc.Text("Точка ", "Point "), (num + 1).ToString(), " X ", position.x.ToString("0.##"), " Y ", position.y.ToString("0.##"), " Z ", position.z.ToString("0.##")), delegate { Select(index); }); } GUILayout.Label((string)Loc.Text("Повторный запуск воспроизводит тот же путь при 60 кадрах/с. Доступна отмена 20 правок, включая очистку. Точки хранятся в текущем уровне.", "Replay follows the same path at 60 steps per second. Undo supports 20 edits, including clearing. Points last for the current level session."), label, Array.Empty<GUILayoutOption>()); } private void SyncCenter() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) orbitRevision = p.Orbit.Revision; Vector3 center = p.Orbit.Center; centerFields[0] = Format(center.x); centerFields[1] = Format(center.y); centerFields[2] = Format(center.z); } private void ApplyCenter() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!Parse(centerFields[0], out var value) || !Parse(centerFields[1], out var value2) || !Parse(centerFields[2], out var value3)) { p.Status = Loc.Text("Введи X, Y и Z числами.", "Enter numeric X, Y and Z coordinates."); } else { p.Orbit.SetCenter(new Vector3(value, value2, value3)); } } private void OrbitPage() { if (orbitRevision != p.Orbit.Revision) { SyncCenter(); } GUILayout.Label((string)Loc.Text("1. Выбери центр", "1. Choose a center"), heading, Array.Empty<GUILayoutOption>()); Row(delegate { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Btn(string.Concat(Loc.Text("Объект под взглядом · ", "Surface under crosshair · "), ((object)p.OrbitCenterKey.Value/*cast due to .constrained prefix*/).ToString()), delegate { p.Orbit.CaptureLookedAt(); inputs.Clear(); }); Btn(Loc.Text("Центр здесь, по камере", "Center at camera"), p.Orbit.CaptureHere); }); GUILayout.Label((string)Loc.Text("Первый вариант выбирает точку на поверхности объекта. Второй — точную позицию камеры, в том числе внутри объекта. Центр остаётся неподвижным.", "The first option picks a surface point. The second uses the exact camera position, even inside an object. The center stays fixed."), label, Array.Empty<GUILayoutOption>()); Row(delegate { Field("X", centerFields, 0); Field("Y", centerFields, 1); Field("Z", centerFields, 2); }); Row(delegate { Btn(Loc.Text("Применить центр", "Apply center"), ApplyCenter); Btn(Loc.Text("Сбросить ввод", "Reset input"), SyncCenter); }); GUILayout.Label((string)(p.Orbit.HasCenter ? Loc.Text("Центр задан.", "Center selected.") : Loc.Text("Центр пока не задан.", "No center selected yet.")), label, Array.Empty<GUILayoutOption>()); GUILayout.Space(8f); GUILayout.Label((string)Loc.Text("2. Настрой круг", "2. Configure the orbit"), heading, Array.Empty<GUILayoutOption>()); Number("radius", Loc.Text("Радиус круга", "Orbit radius"), p.OrbitRadius, 0.25f, 10000f, 50f); Number("height", Loc.Text("Высота камеры над центром", "Camera height above center"), p.OrbitHeight, -10000f, 10000f, 30f, -30f); Number("orbitSpeed", Loc.Text("Скорость вращения, °/сек.", "Orbit speed, °/second"), p.OrbitSpeed, 0.1f, 180f, 90f); Number("startAngle", Loc.Text("Начальный угол, °", "Start angle, °"), p.OrbitStartAngle, 0f, 360f, 360f); GUILayout.Label(string.Concat(Loc.Text("Полный круг: ", "Full orbit: "), (360f / p.OrbitSpeed.Value).ToString("0.0"), Loc.Text(" сек. Камера всегда направлена в выбранный центр.", " seconds. The camera always faces the selected center.")), label, Array.Empty<GUILayoutOption>()); GUILayout.Label((string)Loc.Text("Направление (вид сверху)", "Direction (viewed from above)"), label, Array.Empty<GUILayoutOption>()); Row(delegate { OrbitDirection(clockwise: true, Loc.Text("По часовой", "Clockwise")); OrbitDirection(clockwise: false, Loc.Text("Против часовой", "Counterclockwise")); }); bool flag = GUILayout.Toggle(p.OrbitLoop.Value, (string)Loc.Text(" Крутиться непрерывно; без галочки — один круг", " Loop continuously; uncheck for one full orbit"), toggle, Array.Empty<GUILayoutOption>()); if (flag != p.OrbitLoop.Value) { p.StopTakes(); p.OrbitLoop.Value = flag; } Btn(Loc.Text("Взять радиус, высоту и начальный угол по камере", "Fit radius, height and start angle to camera"), delegate { p.Orbit.FitToCamera(); inputs.Clear(); }); GUILayout.Space(8f); GUILayout.Label((string)Loc.Text("3. Сними дубль", "3. Record a take"), heading, Array.Empty<GUILayoutOption>()); Row(delegate { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) Btn(Loc.Text("Показать начальный ракурс", "Preview starting view"), p.Orbit.Preview); Btn(p.Orbit.Playing ? ((string)Loc.Text("Повторить с начала", "Restart from beginning")) : string.Concat(Loc.Text("Запустить · ", "Start · "), ((object)p.OrbitPlayKey.Value/*cast due to .constrained prefix*/).ToString()), p.Orbit.Play); }); Row(delegate { Btn(p.Orbit.Paused ? Loc.Text("Продолжить", "Resume") : Loc.Text("Пауза", "Pause"), delegate { if (p.Orbit.Playing) { p.Orbit.Paused = !p.Orbit.Paused; Close(resume: true); } }); Btn(Loc.Text("Остановить облёт", "Stop orbit"), p.StopTakes); }); GUILayout.Label((string)Loc.Text("Дубль начинается после заданной паузы. Изменение параметров останавливает движение; снова нажми «Запустить». Радиус считается по горизонтали, высота задаётся отдельно. Камера проходит сквозь стены.", "The take starts after the selected delay. Editing settings stops movement; press Start again. Radius is horizontal; height is separate. The camera passes through walls."), label, Array.Empty<GUILayoutOption>()); } private void OrbitDirection(bool clockwise, string text) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) Color backgroundColor = GUI.backgroundColor; bool flag = p.OrbitClockwise.Value == clockwise; if (flag) { GUI.backgroundColor = new Color(0.35f, 0.8f, 1f); } Btn((flag ? "● " : "○ ") + text, delegate { if (p.OrbitClockwise.Value != clockwise) { p.StopTakes(); p.OrbitClockwise.Value = clockwise; } }); GUI.backgroundColor = backgroundColor; } private static string Format(float value) { return value.ToString("R", CultureInfo.InvariantCulture); } private static bool Parse(string s, out float value) { if (float.TryParse((s ?? "").Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { return CameraMath.Finite(value); } return false; } private void Field(string name, string[] values, int index) { GUILayout.Label(name, label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(92f) }); values[index] = GUILayout.TextField(values[index] ?? "", field, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(175f) }); } private void Number(string id, LocalizedText name, ConfigEntry<float> setting, float min, float max, float sliderMax, float? sliderMin = null) { LiveNumber(id, name, setting.Value, min, max, sliderMax, delegate(float v) { p.StopTakes(); setting.Value = v; }, sliderMin); } private void LiveNumber(string id, LocalizedText name, float current, float min, float max, float sliderMax, Action<float> apply, float? sliderMin = null) { if (!inputs.ContainsKey(id)) { inputs[id] = Format(current); } Row(delegate { GUILayout.Label((string)name, label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(360f) }); inputs[id] = GUILayout.TextField(inputs[id], field, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) }); Btn(Loc.Text("Применить", "Apply"), delegate { if (!Parse(inputs[id], out var value) || value < min || value > max) { p.Status = Loc.Text("Допустимые значения: {0} … {1}", "Allowed range: {0} … {1}", min, max); } else { apply(value); p.Status = Loc.Text("{0}: {1}", "{0}: {1}", name, Format(value)); } }); }); float valueOrDefault = sliderMin.GetValueOrDefault(min); float num = Mathf.Clamp(current, valueOrDefault, sliderMax); float num2 = GUILayout.HorizontalSlider(num, valueOrDefault, sliderMax, Array.Empty<GUILayoutOption>()); if (Math.Abs(num2 - num) > 0.0001f) { apply(num2); inputs[id] = Format(num2); } } private void Row(Action action) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); action(); GUILayout.EndHorizontal(); } private void Btn(string text, Action action) { if (GUILayout.Button(text, button, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinHeight(42f) })) { pending = action; } } } [BepInPlugin("ilya.whiteknuckle.cinema", "WK Cinema", "0.2.4")] [DefaultExecutionOrder(950)] public sealed class CinemaPlugin : BaseUnityPlugin { public const string Id = "ilya.whiteknuckle.cinema"; public const string Version = "0.2.4"; internal static CinemaPlugin Instance; internal CinemaMenu Menu; internal CameraRoute Route; internal CameraOrbit Orbit; internal WorldSession Session; internal readonly CameraTools CameraTools = new CameraTools(); internal ConfigEntry<KeyboardShortcut> MenuKey; internal ConfigEntry<KeyboardShortcut> FreecamKey; internal ConfigEntry<KeyboardShortcut> RoutePointKey; internal ConfigEntry<KeyboardShortcut> RoutePlayKey; internal ConfigEntry<KeyboardShortcut> OrbitCenterKey; internal ConfigEntry<KeyboardShortcut> OrbitPlayKey; internal ConfigEntry<float> RouteDuration; internal ConfigEntry<float> StartDelay; internal ConfigEntry<float> OrbitRadius; internal ConfigEntry<float> OrbitHeight; internal ConfigEntry<float> OrbitSpeed; internal ConfigEntry<float> OrbitStartAngle; internal ConfigEntry<float> LookSmoothing; internal ConfigEntry<bool> ShortsFrame; internal ConfigEntry<bool> OrbitClockwise; internal ConfigEntry<bool> OrbitLoop; internal ConfigEntry<bool> HideCrosshair; internal LocalizedText Status; internal bool BlockCameraFrame; private bool initialized; private bool ownsFreecam; private Harmony harmony; private int scene; public static bool MenuOpen { get { if ((Object)(object)Instance != (Object)null && Instance.Menu != null) { return Instance.Menu.Visible; } return false; } } internal bool Automated { get { if (!Route.Playing) { return Orbit.Playing; } return true; } } internal bool HoldTake { get { if (!Menu.Visible && !CompanionMenus.AnyOpen && Application.isFocused && !CommandConsole.IsConsoleVisible()) { if ((Object)(object)CL_GameManager.gMan != (Object)null) { return CL_GameManager.gMan.isPaused; } return false; } return true; } } internal static Camera ViewCamera { get { Camera freeCamera = CameraTools.FreeCamera; if ((Object)(object)freeCamera != (Object)null) { return freeCamera; } ENT_Player playerObject = ENT_Player.playerObject; if (!((Object)(object)playerObject != (Object)null) || !((Object)(object)playerObject.cam != (Object)null)) { return Camera.main; } return playerObject.cam; } } private void Awake() { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) GameLanguage.Refresh(force: true); MenuKey = Key("Menu", (KeyCode)292, Loc.Text("Меню съёмки", "Filming menu")); FreecamKey = Key("Freecam", (KeyCode)284, Loc.Text("Переключить игрока / свободную камеру", "Switch player / free camera")); RoutePointKey = Key("RouteAdd", (KeyCode)285, Loc.Text("Добавить точку маршрута", "Add a path point")); RoutePlayKey = Key("RoutePlay", (KeyCode)284, Loc.Text("Запустить / остановить маршрут", "Start / stop path"), (KeyCode)304); OrbitCenterKey = Key("OrbitCenter", (KeyCode)285, Loc.Text("Центр облёта в точке под взглядом", "Set orbit center under crosshair"), (KeyCode)304); OrbitPlayKey = Key("OrbitPlay", (KeyCode)284, Loc.Text("Запустить / остановить облёт", "Start / stop orbit"), (KeyCode)306); ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "ShortsGuide", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), Loc.Config("Не используется: разметка 9:16 переключается в меню камеры.", "Unused: toggle the 9:16 guide in the camera menu.")).Value = new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()); CinemaShortcuts.Migrate(((BaseUnityPlugin)this).Config, MenuKey, RoutePlayKey, OrbitCenterKey, OrbitPlayKey); Status = Loc.Text("{0} — меню съёмки. {1} — игрок / фрикам.", "{0} — filming menu. {1} — player / freecam.", MenuKey.Value, FreecamKey.Value); RouteDuration = Number("Route", "DurationSeconds", 8f, 1f, 600f, Loc.Text("Длительность маршрута", "Path duration")); StartDelay = Number("Camera", "StartDelaySeconds", 2f, 0f, 10f, Loc.Text("Пауза в начальной точке перед дублем", "Delay at the starting point before a take")); LookSmoothing = Number("Camera", "LookSmoothingSeconds", 0f, 0f, 2f, Loc.Text("Сглаживание поворота, секунды. 0 — прямой отклик мыши.", "Look smoothing, seconds. 0 means direct mouse response.")); OrbitRadius = Number("Orbit", "Radius", 5f, 0.25f, 10000f, Loc.Text("Радиус горизонтального круга", "Horizontal orbit radius")); OrbitHeight = Number("Orbit", "Height", 1f, -10000f, 10000f, Loc.Text("Высота камеры над центром (может быть отрицательной)", "Camera height above center (can be negative)")); OrbitSpeed = Number("Orbit", "SpeedDegreesPerSecond", 20f, 0.1f, 180f, Loc.Text("Угловая скорость, градусов в секунду", "Angular speed, degrees per second")); OrbitStartAngle = Number("Orbit", "StartAngle", 0f, 0f, 360f, Loc.Text("Начальный угол круга, в градусах", "Orbit start angle, degrees")); OrbitClockwise = ((BaseUnityPlugin)this).Config.Bind<bool>("Orbit", "Clockwise", true, Loc.Config("По часовой стрелке, если смотреть сверху", "Clockwise when viewed from above")); OrbitLoop = ((BaseUnityPlugin)this).Config.Bind<bool>("Orbit", "Loop", true, Loc.Config("Повторять круги до остановки", "Repeat orbits until stopped")); ShortsFrame = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "ShortsGuide", false, Loc.Config("Разметка 9:16 во фрикаме", "9:16 guide in freecam")); HideCrosshair = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "HideCrosshair", true, Loc.Config("Скрыть прицел во фрикаме", "Hide crosshair in freecam")); Route = new CameraRoute(this); Orbit = new CameraOrbit(this); Menu = new CinemaMenu(this); Session = new WorldSession(this); Scene activeScene = SceneManager.GetActiveScene(); scene = SceneHandle.op_Implicit(((Scene)(ref activeScene)).handle); initialized = true; } private ConfigEntry<KeyboardShortcut> Key(string name, KeyCode key, LocalizedText description, params KeyCode[] modifiers) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", name, new KeyboardShortcut(key, modifiers), description.Bilingual + Loc.Config(". Можно задать сочетание, например F3 + LeftShift. None отключает клавишу.", ". Shortcuts support modifiers, e.g. F3 + LeftShift. None disables a shortcut.")); } private ConfigEntry<float> Number(string section, string name, float value, float min, float max, LocalizedText description) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown ConfigEntry<float> val = ((BaseUnityPlugin)this).Config.Bind<float>(section, name, value, new ConfigDescription(description.Bilingual, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>())); if (!CameraMath.Finite(val.Value)) { val.Value = value; } return val; } private void OnEnable() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (!initialized || harmony != null) { return; } Instance = this; try { GameLanguage.Connect(Paths.ConfigPath, () => ((Behaviour)this).isActiveAndEnabled && Menu != null && (Menu.Visible || MainMenuLanguage.Visible), delegate(Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)ex2); }); harmony = new Harmony("ilya.whiteknuckle.cinema"); harmony.PatchAll(typeof(CinemaPlugin).Assembly); DarkMachineFunctions.offsetAction = (Action<float>)Delegate.Combine(DarkMachineFunctions.offsetAction, new Action<float>(OffsetWorld)); ((BaseUnityPlugin)this).Logger.LogInfo((object)("WK Cinema 0.2.4 loaded. " + ((object)MenuKey.Value/*cast due to .constrained p