diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..a7fb7ac --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +patreon: xen42 +custom: ["https://paypal.me/xen42"] \ No newline at end of file diff --git a/DredgeVR/DredgeVR.csproj b/DredgeVR/DredgeVR.csproj index c748f4c..281d114 100644 --- a/DredgeVR/DredgeVR.csproj +++ b/DredgeVR/DredgeVR.csproj @@ -12,7 +12,7 @@ false x86 net48 - default + latest true false false @@ -25,11 +25,14 @@ Always + + Always + - + @@ -37,11 +40,4 @@ - - - - - - - diff --git a/DredgeVR/Helpers/DLCHelper.cs b/DredgeVR/Helpers/DLCHelper.cs new file mode 100644 index 0000000..04b247a --- /dev/null +++ b/DredgeVR/Helpers/DLCHelper.cs @@ -0,0 +1,6 @@ +namespace DredgeVR.Helpers; + +public static class DLCHelper +{ + public static bool OwnsThePaleReach() => GameManager.Instance.EntitlementManager.GetHasEntitlement(Entitlement.DLC_1); +} diff --git a/DredgeVR/Helpers/FileHelper.cs b/DredgeVR/Helpers/FileHelper.cs new file mode 100644 index 0000000..3ed6d56 --- /dev/null +++ b/DredgeVR/Helpers/FileHelper.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; + +namespace DredgeVR.Helpers; + +public static class FileHelper +{ + public static void Copy(string sourceDirectory, string targetDirectory) + { + DirectoryInfo diSource = new DirectoryInfo(sourceDirectory); + DirectoryInfo diTarget = new DirectoryInfo(targetDirectory); + + CopyAll(diSource, diTarget); + } + + public static void CopyAll(DirectoryInfo source, DirectoryInfo target) + { + Directory.CreateDirectory(target.FullName); + + // Copy each file into the new directory. + foreach (FileInfo fi in source.GetFiles()) + { + Console.WriteLine(@"Copying {0}\{1}", target.FullName, fi.Name); + fi.CopyTo(Path.Combine(target.FullName, fi.Name), true); + } + + // Copy each subdirectory using recursion. + foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) + { + DirectoryInfo nextTargetSubDir = + target.CreateSubdirectory(diSourceSubDir.Name); + CopyAll(diSourceSubDir, nextTargetSubDir); + } + } +} diff --git a/DredgeVR/Loader.cs b/DredgeVR/Loader.cs index 5418d4f..a3f2809 100644 --- a/DredgeVR/Loader.cs +++ b/DredgeVR/Loader.cs @@ -8,11 +8,20 @@ using UnityEngine; using UnityEngine.XR.Management; using Valve.VR; +using System.Runtime.CompilerServices; namespace DredgeVR { public class Loader { + // Confuses me that the mod dll counts as the executing assembly + // Might change if we were using a different mod loader + // Should update Winch to provide these paths if it doesn't already + public static string DredgeVRFolder => Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName; + + // Bit hacky but eh + public static string DredgeFolder => Directory.GetParent(Assembly.GetExecutingAssembly().Location).Parent.Parent.FullName; + public static void Initialize() { OptionsManager.Load(); @@ -26,6 +35,14 @@ public static void Initialize() new Harmony("DredgeVR").PatchAll(); } + /// + /// This runs when the assembly is loaded + /// + public static void Preload() + { + FileHelper.Copy(Path.Combine(DredgeVRFolder, "CopyToGame"), Path.Combine(DredgeFolder, "DREDGE_Data")); + } + private static void SetUpXr() { SteamVR_Actions.PreInitialize(); @@ -54,8 +71,7 @@ private static void SetUpXr() // SteamVR_Settings.instance.pauseGameWhenDashboardVisible = true; // Makes it so that Dredge appears as a VR game in your Steam Home - var dredgeFolder = Directory.GetParent(Assembly.GetExecutingAssembly().Location).Parent.Parent.FullName; - var manifestPath = Path.Combine(dredgeFolder, @"DREDGE_Data\StreamingAssets\dredge.vrmanifest"); + var manifestPath = Path.Combine(DredgeFolder, @"DREDGE_Data\StreamingAssets\dredge.vrmanifest"); ApplicationManifestHelper.UpdateManifest(manifestPath, "steam.app.1562430", "https://steamcdn-a.akamaihd.net/steam/apps/1562430/header.jpg", diff --git a/DredgeVR/VRCamera/VRCameraManager.cs b/DredgeVR/VRCamera/VRCameraManager.cs index 0eda142..72ee98b 100644 --- a/DredgeVR/VRCamera/VRCameraManager.cs +++ b/DredgeVR/VRCamera/VRCameraManager.cs @@ -130,12 +130,22 @@ private void OnSceneStart(string _) private void OnTitleSceneStart() { - // Make the player look towards the lighthouse - var lightHouse = GameObject.Find("TheMarrows/Islands/LittleMarrow").transform; - var worldPos = new Vector3(lightHouse.position.x, 0.5f, lightHouse.position.z); + if (DLCHelper.OwnsThePaleReach()) + { + var camLookAt = GameObject.Find("DLC1Positions/DLC1CamLookAt").transform.position.ProjectOntoPlane(Vector3.up); + + AnchorTransform.position = new Vector3(-90.6f, 1f, -1337.3f); + AnchorTransform.LookAt(camLookAt); + } + else + { + // Make the player look towards the lighthouse + var lightHouse = GameObject.Find("TheMarrows/Islands/LittleMarrow").transform; + var worldPos = new Vector3(lightHouse.position.x, 0.5f, lightHouse.position.z); - AnchorTransform.position = new Vector3(-6.5f, 0.5f, 0); - AnchorTransform.LookAt(worldPos); + AnchorTransform.position = new Vector3(-6.5f, 0.5f, 0); + AnchorTransform.LookAt(worldPos); + } } private void OnPlayerSpawned() diff --git a/DredgeVR/VRInput/VRInputManager.cs b/DredgeVR/VRInput/VRInputManager.cs index 9a3baaa..be5a09c 100644 --- a/DredgeVR/VRInput/VRInputManager.cs +++ b/DredgeVR/VRInput/VRInputManager.cs @@ -89,9 +89,25 @@ public static void InitControls() AddNewBinding(GameManager.Instance.Input.Controls.TabLeft, SteamVR_Actions._default.TabLeft); AddNewBinding(GameManager.Instance.Input.Controls.TabRight, SteamVR_Actions._default.TabRight); + // These bindings are only really used by the tutorial manager to check if the player is moving + AddNewBinding(GameManager.Instance.Input.controls.MoveForward, SteamVR_Actions._default.Move, Vector2.up); + AddNewBinding(GameManager.Instance.Input.controls.MoveBack, SteamVR_Actions._default.Move, Vector2.down); + AddNewBinding(GameManager.Instance.Input.controls.MoveLeft, SteamVR_Actions._default.Move, Vector2.left); + AddNewBinding(GameManager.Instance.Input.controls.MoveRight, SteamVR_Actions._default.Move, Vector2.right); + new CustomControl(SteamVR_Actions._default.RecenterCamera, VRCameraManager.Instance.RecenterCamera); } + private static void AddNewBinding(PlayerAction action, SteamVR_Action_Vector2 vrAction, Vector2 direction) + { + var vrBindingSource = new VRVector2BindingSource(vrAction, direction); + + action.AddDefaultBinding(vrBindingSource); + action.AddBinding(vrBindingSource); + + DredgeVRLogger.Debug($"Added new binding for {action.Name} - {vrAction.GetShortName()}"); + } + private static void AddNewBinding(PlayerAction action, SteamVR_Action_Boolean vrAction) { var vrBindingSource = new VRBindingSource(vrAction); diff --git a/DredgeVR/VRInput/VRVector2BindingSource.cs b/DredgeVR/VRInput/VRVector2BindingSource.cs new file mode 100644 index 0000000..f513ca2 --- /dev/null +++ b/DredgeVR/VRInput/VRVector2BindingSource.cs @@ -0,0 +1,64 @@ +using InControl; +using System.IO; +using UnityEngine; +using Valve.VR; + +namespace DredgeVR.VRInput; + +public class VRVector2BindingSource : BindingSource +{ + public SteamVR_Action_Vector2 action; + private Vector2 _direction; + + public string GetButtonName() + { + // Keep these localized because they will appear in text strings + var button = action.GetLocalizedOriginPart(SteamVR_Input_Sources.Any, EVRInputStringBits.VRInputString_InputSource); + var hand = action.GetLocalizedOriginPart(SteamVR_Input_Sources.Any, EVRInputStringBits.VRInputString_Hand); + + return $"{button} ({hand})"; + } + + public VRVector2BindingSource(SteamVR_Action_Vector2 action, Vector2 direction) + { + this.action = action; + this._direction = direction; + } + + public override string Name => $"{action.GetShortName()} - {action.GetLocalizedOrigin(SteamVR_Input_Sources.Any)}"; + + public override string DeviceName => "VR"; + + public override InputDeviceClass DeviceClass => InputDeviceClass.Controller; + + public override InputDeviceStyle DeviceStyle => InputDeviceStyle.Oculus; + + public static BindingSourceType Source = BindingSourceType.UnknownDeviceBindingSource; + public override BindingSourceType BindingSourceType => Source; + + public override bool Equals(BindingSource other) + { + return other is VRBindingSource otherVR && otherVR.action.Equals(action); + } + + public override bool GetState(InputDevice inputDevice) + { + // Dot product greater than zero means that some part of this movement is in the direction specified + return Vector2.Dot(action.axis, _direction) > 0; + } + + public override float GetValue(InputDevice inputDevice) + { + return GetState(inputDevice) ? 1f : 0f; + } + + public override void Load(BinaryReader reader, ushort dataFormatVersion) + { + + } + + public override void Save(BinaryWriter writer) + { + + } +} diff --git a/DredgeVR/VRUI/LoadScene/SceneLoadFade.cs b/DredgeVR/VRUI/LoadScene/SceneLoadFade.cs index b8b44ae..e10d0af 100644 --- a/DredgeVR/VRUI/LoadScene/SceneLoadFade.cs +++ b/DredgeVR/VRUI/LoadScene/SceneLoadFade.cs @@ -9,7 +9,6 @@ namespace DredgeVR.VRUI; [HarmonyPatch] public class VRLoadingScene : MonoBehaviour { - private MeshRenderer _meshRenderer; private int _cameraLayerCache; private bool _isInLoadingScreen; @@ -74,8 +73,6 @@ public void ShowLoadScreen() VRCameraManager.LeftEye.Camera.clearFlags = CameraClearFlags.Depth; VRCameraManager.RightEye.Camera.clearFlags = CameraClearFlags.Depth; - - _meshRenderer.forceRenderingOff = false; } } @@ -89,8 +86,6 @@ public void HideLoadScreen() VRCameraManager.LeftEye.Camera.clearFlags = CameraClearFlags.Skybox; VRCameraManager.RightEye.Camera.clearFlags = CameraClearFlags.Skybox; - - _meshRenderer.forceRenderingOff = true; } } } diff --git a/DredgeVR/VRUI/VRUIManager.cs b/DredgeVR/VRUI/VRUIManager.cs index 14e31ac..31b0be7 100644 --- a/DredgeVR/VRUI/VRUIManager.cs +++ b/DredgeVR/VRUI/VRUIManager.cs @@ -123,8 +123,17 @@ private void OnTitleSceneStart() // We place the title screen canvas on the beach var canvas = GameObject.Find("Canvases"); - canvas.transform.position = new Vector3(-5.3f, 0.45f, 2f); - canvas.transform.rotation = Quaternion.Euler(0, 70, 0); + if (DLCHelper.OwnsThePaleReach()) + { + canvas.transform.position = new Vector3(-91.1f, 1f, -1339.2f); + canvas.transform.rotation = Quaternion.Euler(0, 230, 0); + } + else + { + canvas.transform.position = new Vector3(-5.3f, 0.45f, 2f); + canvas.transform.rotation = Quaternion.Euler(0, 70, 0); + } + canvas.transform.localScale = Vector3.one * 0.002f; // Remove controls tab for now since it doesnt work diff --git a/DredgeVR/World/Patches/DepthFixer.cs b/DredgeVR/World/Patches/DepthFixer.cs index fcdde2b..3210cda 100644 --- a/DredgeVR/World/Patches/DepthFixer.cs +++ b/DredgeVR/World/Patches/DepthFixer.cs @@ -27,10 +27,18 @@ private static void UpdateDepth(WaterController __instance) if (GameManager.Instance.Player != null) { - var t = Mathf.Clamp01(Mathf.InverseLerp(5, 30, GameManager.Instance.Player.PlayerDepthMonitor.currentDepth * 100)); + var depth = GameManager.Instance.Player.PlayerDepthMonitor.currentDepth * 100; // m + + var t = Mathf.Clamp01(Mathf.InverseLerp(5, 30, depth)); // High "depth" is clearer than low "depth" var realDepth = currentDepth * Mathf.Lerp(1200, 400, t*t); + // In the middle of the ocean just make the water clear since theres no bottom anyway + if (depth >= 100) + { + realDepth = currentDepth * 1000f; + } + float depthToUse; if (_previousDepth == -1f) diff --git a/DredgeVR/World/WorldManager.cs b/DredgeVR/World/WorldManager.cs index aa6ff98..ffc2556 100644 --- a/DredgeVR/World/WorldManager.cs +++ b/DredgeVR/World/WorldManager.cs @@ -93,6 +93,15 @@ private void OnGameSceneStart() // OnDestroy breaks the reference to the culling brain so we reconnect it so other scripts don't NRE GameManager.Instance.CullingBrain = cullingBrain; } + + if (DLCHelper.OwnsThePaleReach()) + { + foreach (var meshRenderer in GameObject.FindObjectsOfType().Where(x => x.material.shader.name.Contains("DLC1TransparentIceShader"))) + { + // Since we break depth textures we have to fix this shader + meshRenderer.material.SetFloat("_IceDepth", 0.00025f); + } + } } public void OnPlayerSpawned() diff --git a/DredgeVR/mod_meta.json b/DredgeVR/mod_meta.json index 7dde0f3..46662e7 100644 --- a/DredgeVR/mod_meta.json +++ b/DredgeVR/mod_meta.json @@ -1,8 +1,9 @@ { "Name": "DredgeVR", "ModGUID": "xen.DredgeVR", - "Version": "0.1.6", + "Version": "0.2.0", "ModAssembly": "DredgeVR.dll", - "MinWinchVersion": "0.2.3", - "Entrypoint": "DredgeVR.Loader/Initialize" + "MinWinchVersion": "0.3.0", + "Entrypoint": "DredgeVR.Loader/Initialize", + "Preload": "DredgeVR.Loader/Preload" }