diff --git a/QNetWeaver/QNetWeaver.csproj b/QNetWeaver/QNetWeaver.csproj
index be1b5de5..b60b466a 100644
--- a/QNetWeaver/QNetWeaver.csproj
+++ b/QNetWeaver/QNetWeaver.csproj
@@ -52,8 +52,9 @@
..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.Cecil.Pdb.dll
-
- ..\..\..\..\..\..\Program Files\Unity\Hub\Editor\2017.4.33f1\Editor\Data\Managed\Unity.UNetWeaver.dll
+
+ False
+ lib\Unity.UNetWeaver.dll
@@ -68,5 +69,8 @@
+
+
+
\ No newline at end of file
diff --git a/QNetWeaver/lib/Unity.UNetWeaver.dll b/QNetWeaver/lib/Unity.UNetWeaver.dll
new file mode 100644
index 00000000..84c5baec
Binary files /dev/null and b/QNetWeaver/lib/Unity.UNetWeaver.dll differ
diff --git a/QSB/Events/EventNames.cs b/QSB/Events/EventNames.cs
index 81a70cc2..39a06366 100644
--- a/QSB/Events/EventNames.cs
+++ b/QSB/Events/EventNames.cs
@@ -89,5 +89,8 @@
public static string QSBDebugEvent = "QSBDebugEvent";
public static string QSBEnterNomaiHeadZone = "QSBEnterNomaiHeadZone";
public static string QSBExitNomaiHeadZone = "QSBExitNomaiHeadZone";
+ public static string QSBEnterSatelliteCamera = "QSBEnterSatelliteCamera";
+ public static string QSBExitSatelliteCamera = "QSBExitSatelliteCamera";
+ public static string QSBSatelliteSnapshot = "QSBSatelliteSnapshot";
}
}
\ No newline at end of file
diff --git a/QSB/Events/EventType.cs b/QSB/Events/EventType.cs
index be7a01f7..4553f923 100644
--- a/QSB/Events/EventType.cs
+++ b/QSB/Events/EventType.cs
@@ -6,6 +6,8 @@
* MISC.
*/
DebugEvent,
+ SatelliteProjector,
+ SatelliteProjectorSnapshot,
/*
* SERVER EVENTS
diff --git a/QSB/Events/QSBEventManager.cs b/QSB/Events/QSBEventManager.cs
index 68029535..d6780875 100644
--- a/QSB/Events/QSBEventManager.cs
+++ b/QSB/Events/QSBEventManager.cs
@@ -15,6 +15,7 @@ using QSB.Player.Events;
using QSB.ProbeSync.Events;
using QSB.QuantumSync.Events;
using QSB.RoastingSync.Events;
+using QSB.SatelliteSync.Events;
using QSB.ShipSync.Events;
using QSB.ShipSync.Events.Component;
using QSB.ShipSync.Events.Hull;
@@ -69,6 +70,8 @@ namespace QSB.Events
new ServerStateEvent(),
new ClientStateEvent(),
new DebugEvent(),
+ new SatelliteProjectorEvent(),
+ new SatelliteProjectorSnapshotEvent(),
// World Objects
new ElevatorEvent(),
new GeyserEvent(),
diff --git a/QSB/Patches/QSBPatchManager.cs b/QSB/Patches/QSBPatchManager.cs
index bf71ee58..d9f082c4 100644
--- a/QSB/Patches/QSBPatchManager.cs
+++ b/QSB/Patches/QSBPatchManager.cs
@@ -16,6 +16,7 @@ using QSB.Player.Patches;
using QSB.PoolSync.Patches;
using QSB.QuantumSync.Patches;
using QSB.RoastingSync.Patches;
+using QSB.SatelliteSync.Patches;
using QSB.ShipSync.Patches;
using QSB.StatueSync.Patches;
using QSB.TimeSync.Patches;
@@ -67,7 +68,8 @@ namespace QSB.Patches
new MapPatches(),
new RespawnPatches(),
new LauncherPatches(),
- new SolanumPatches()
+ new SolanumPatches(),
+ new SatelliteProjectorPatches()
};
TypeToInstance = new Dictionary
diff --git a/QSB/QSB.csproj b/QSB/QSB.csproj
index 79e1b2b9..f65b9fd1 100644
--- a/QSB/QSB.csproj
+++ b/QSB/QSB.csproj
@@ -200,6 +200,10 @@
+
+
+
+
diff --git a/QSB/QSBCore.cs b/QSB/QSBCore.cs
index ef1c7bc0..c72b4687 100644
--- a/QSB/QSBCore.cs
+++ b/QSB/QSBCore.cs
@@ -16,6 +16,7 @@ using QSB.Player;
using QSB.Player.TransformSync;
using QSB.PoolSync;
using QSB.QuantumSync;
+using QSB.SatelliteSync;
using QSB.SectorSync;
using QSB.ShipSync;
using QSB.StatueSync;
@@ -102,6 +103,7 @@ namespace QSB
gameObject.AddComponent();
gameObject.AddComponent();
gameObject.AddComponent();
+ gameObject.AddComponent();
// WorldObject managers
gameObject.AddComponent();
diff --git a/QSB/SatelliteSync/Events/SatelliteProjectorEvent.cs b/QSB/SatelliteSync/Events/SatelliteProjectorEvent.cs
new file mode 100644
index 00000000..b2d8356e
--- /dev/null
+++ b/QSB/SatelliteSync/Events/SatelliteProjectorEvent.cs
@@ -0,0 +1,42 @@
+using QSB.Events;
+using QSB.Messaging;
+
+namespace QSB.SatelliteSync.Events
+{
+ class SatelliteProjectorEvent : QSBEvent
+ {
+ public override EventType Type => EventType.SatelliteProjector;
+
+ public override void SetupListener()
+ {
+ GlobalMessenger.AddListener(EventNames.QSBEnterSatelliteCamera, () => Handler(true));
+ GlobalMessenger.AddListener(EventNames.QSBExitSatelliteCamera, () => Handler(false));
+ }
+
+ public override void CloseListener()
+ {
+ GlobalMessenger.RemoveListener(EventNames.QSBEnterSatelliteCamera, () => Handler(true));
+ GlobalMessenger.RemoveListener(EventNames.QSBExitSatelliteCamera, () => Handler(false));
+ }
+
+ private void Handler(bool usingProjector) => SendEvent(CreateMessage(usingProjector));
+
+ private BoolMessage CreateMessage(bool usingProjector) => new BoolMessage
+ {
+ AboutId = LocalPlayerId,
+ Value = usingProjector
+ };
+
+ public override void OnReceiveRemote(bool isHost, BoolMessage message)
+ {
+ if (message.Value)
+ {
+ SatelliteProjectorManager.Instance.RemoteEnter();
+ }
+ else
+ {
+ SatelliteProjectorManager.Instance.RemoteExit();
+ }
+ }
+ }
+}
diff --git a/QSB/SatelliteSync/Events/SatelliteProjectorSnapshotEvent.cs b/QSB/SatelliteSync/Events/SatelliteProjectorSnapshotEvent.cs
new file mode 100644
index 00000000..5dbba575
--- /dev/null
+++ b/QSB/SatelliteSync/Events/SatelliteProjectorSnapshotEvent.cs
@@ -0,0 +1,34 @@
+using QSB.Events;
+using QSB.Messaging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace QSB.SatelliteSync.Events
+{
+ class SatelliteProjectorSnapshotEvent : QSBEvent
+ {
+ public override EventType Type => EventType.SatelliteProjectorSnapshot;
+
+ public override void SetupListener()
+ {
+ GlobalMessenger.AddListener(EventNames.QSBSatelliteSnapshot, (bool forward) => Handler(forward));
+ }
+
+ public override void CloseListener()
+ {
+ GlobalMessenger.RemoveListener(EventNames.QSBSatelliteSnapshot, (bool forward) => Handler(forward));
+ }
+
+ private void Handler(bool forward) => SendEvent(CreateMessage(forward));
+
+ private BoolMessage CreateMessage(bool forward) => new BoolMessage
+ {
+ AboutId = LocalPlayerId,
+ Value = forward
+ };
+
+ public override void OnReceiveRemote(bool isHost, BoolMessage message) => SatelliteProjectorManager.Instance.RemoteTakeSnapshot(message.Value);
+ }
+}
diff --git a/QSB/SatelliteSync/Patches/SatelliteProjectorPatches.cs b/QSB/SatelliteSync/Patches/SatelliteProjectorPatches.cs
new file mode 100644
index 00000000..5f8c9f14
--- /dev/null
+++ b/QSB/SatelliteSync/Patches/SatelliteProjectorPatches.cs
@@ -0,0 +1,62 @@
+using HarmonyLib;
+using QSB.Events;
+using QSB.Patches;
+using UnityEngine;
+
+namespace QSB.SatelliteSync.Patches
+{
+ [HarmonyPatch]
+ class SatelliteProjectorPatches : QSBPatch
+ {
+ public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(SatelliteSnapshotController), nameof(SatelliteSnapshotController.OnPressInteract))]
+ public static bool UseProjector()
+ {
+ QSBEventManager.FireEvent(EventNames.QSBEnterSatelliteCamera);
+ return true;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(SatelliteSnapshotController), nameof(SatelliteSnapshotController.TurnOffProjector))]
+ public static bool LeaveProjector()
+ {
+ QSBEventManager.FireEvent(EventNames.QSBExitSatelliteCamera);
+ return true;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(SatelliteSnapshotController), nameof(SatelliteSnapshotController.Update))]
+ public static bool UpdateReplacement(SatelliteSnapshotController __instance)
+ {
+ if (!OWInput.IsInputMode(InputMode.SatelliteCam))
+ {
+ return false;
+ }
+
+ if (OWInput.IsNewlyPressed(InputLibrary.toolActionPrimary, InputMode.All))
+ {
+ QSBEventManager.FireEvent(EventNames.QSBSatelliteSnapshot, true);
+ __instance._satelliteCamera.transform.localEulerAngles = __instance._initCamLocalRot;
+ __instance.RenderSnapshot();
+ return false;
+ }
+
+ if (__instance._allowRearview && OWInput.IsNewlyPressed(InputLibrary.toolActionSecondary, InputMode.All))
+ {
+ QSBEventManager.FireEvent(EventNames.QSBSatelliteSnapshot, false);
+ __instance._satelliteCamera.transform.localEulerAngles = __instance._initCamLocalRot + new Vector3(0f, 180f, 0f);
+ __instance.RenderSnapshot();
+ return false;
+ }
+
+ if (OWInput.IsNewlyPressed(InputLibrary.cancel, InputMode.All))
+ {
+ __instance.TurnOffProjector();
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/QSB/SatelliteSync/SatelliteProjectorManager.cs b/QSB/SatelliteSync/SatelliteProjectorManager.cs
new file mode 100644
index 00000000..2d49cf05
--- /dev/null
+++ b/QSB/SatelliteSync/SatelliteProjectorManager.cs
@@ -0,0 +1,86 @@
+using QSB.Utility;
+using System.Linq;
+using UnityEngine;
+
+namespace QSB.SatelliteSync
+{
+ class SatelliteProjectorManager : MonoBehaviour
+ {
+ public static SatelliteProjectorManager Instance { get; private set; }
+
+ public SatelliteSnapshotController Projector { get; private set; }
+
+ public void Start()
+ {
+ Instance = this;
+ QSBSceneManager.OnUniverseSceneLoaded += OnSceneLoaded;
+ }
+
+ public void OnDestroy()
+ {
+ QSBSceneManager.OnUniverseSceneLoaded -= OnSceneLoaded;
+ }
+
+ private void OnSceneLoaded(OWScene oldScene, OWScene newScene)
+ {
+ if (newScene == OWScene.SolarSystem)
+ {
+ Projector = Resources.FindObjectsOfTypeAll().First();
+ Projector._loopingSource.spatialBlend = 1f;
+ Projector._oneShotSource.spatialBlend = 1f;
+ }
+ }
+
+ public void RemoteEnter()
+ {
+ Projector.enabled = true;
+ Projector._interactVolume.DisableInteraction();
+
+ if (Projector._showSplashTexture)
+ {
+ Projector._splashObject.SetActive(false);
+ Projector._diagramObject.SetActive(true);
+ Projector._projectionScreen.gameObject.SetActive(false);
+ }
+
+ if (Projector._fadeLight != null)
+ {
+ Projector._fadeLight.StartFade(0f, 2f, 0f);
+ }
+
+ var audioClip = Projector._oneShotSource.PlayOneShot(AudioType.TH_ProjectorActivate, 1f);
+ Projector._loopingSource.FadeIn(audioClip.length, false, false, 1f);
+ }
+
+ public void RemoteExit()
+ {
+ Projector.enabled = false;
+ Projector._interactVolume.EnableInteraction();
+ Projector._interactVolume.ResetInteraction();
+
+ if (Projector._showSplashTexture)
+ {
+ Projector._splashObject.SetActive(true);
+ Projector._diagramObject.SetActive(false);
+ Projector._projectionScreen.gameObject.SetActive(false);
+ }
+
+ if (Projector._fadeLight != null)
+ {
+ Projector._fadeLight.StartFade(Projector._initLightIntensity, 2f, 0f);
+ }
+
+ var audioClip = Projector._oneShotSource.PlayOneShot(AudioType.TH_ProjectorStop, 1f);
+ Projector._loopingSource.FadeOut(audioClip.length, OWAudioSource.FadeOutCompleteAction.STOP, 0f);
+ }
+
+ public void RemoteTakeSnapshot(bool forward)
+ {
+ Projector._satelliteCamera.transform.localEulerAngles = forward
+ ? Projector._initCamLocalRot
+ : Projector._initCamLocalRot + new Vector3(0f, 180f, 0f);
+
+ Projector.RenderSnapshot();
+ }
+ }
+}
diff --git a/QSB/Tools/ProbeLauncherTool/Patches/LauncherPatches.cs b/QSB/Tools/ProbeLauncherTool/Patches/LauncherPatches.cs
index c96b8506..ae9e0fcf 100644
--- a/QSB/Tools/ProbeLauncherTool/Patches/LauncherPatches.cs
+++ b/QSB/Tools/ProbeLauncherTool/Patches/LauncherPatches.cs
@@ -71,12 +71,20 @@ namespace QSB.Tools.ProbeLauncherTool.Patches
// TODO : ehhhh idk about this. maybe copy each sound source so we have a 2d version (for local) and a 3d version (for remote)?
// this would probably be a whole qsb version on it's own
- [HarmonyPostfix]
+ [HarmonyPrefix]
[HarmonyPatch(typeof(ProbeLauncherEffects), nameof(ProbeLauncherEffects.PlayRetrievalClip))]
- public static void ProbeLauncherEffects_PlayRetrievalClip(OWAudioSource ____owAudioSource) => ____owAudioSource.GetAudioSource().spatialBlend = 1f;
+ public static bool ProbeLauncherEffects_PlayRetrievalClip(OWAudioSource ____owAudioSource)
+ {
+ ____owAudioSource.GetAudioSource().spatialBlend = 1f;
+ return true;
+ }
- [HarmonyPostfix]
+ [HarmonyPrefix]
[HarmonyPatch(typeof(ProbeLauncherEffects), nameof(ProbeLauncherEffects.PlayLaunchClip))]
- public static void ProbeLauncherEffects_PlayLaunchClip(OWAudioSource ____owAudioSource) => ____owAudioSource.GetAudioSource().spatialBlend = 1f;
+ public static bool ProbeLauncherEffects_PlayLaunchClip(OWAudioSource ____owAudioSource)
+ {
+ ____owAudioSource.GetAudioSource().spatialBlend = 1f;
+ return true;
+ }
}
}
diff --git a/QSB/default-config.json b/QSB/default-config.json
index ffe88285..fedee1d0 100644
--- a/QSB/default-config.json
+++ b/QSB/default-config.json
@@ -3,7 +3,7 @@
"settings": {
"defaultServerIP": "localhost",
"port": 7777,
- "debugMode": false,
+ "debugMode": true,
"showLinesInDebug": false
}
}
\ No newline at end of file
diff --git a/QSBTests/PatchTests.cs b/QSBTests/PatchTests.cs
index 26ece311..29d3ebdd 100644
--- a/QSBTests/PatchTests.cs
+++ b/QSBTests/PatchTests.cs
@@ -1,36 +1,41 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using QSB.Patches;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
namespace QSBTests
{
[TestClass]
public class PatchTests
{
- //[TestMethod]
- //public void CheckUnreferencedPatches()
- //{
- // var qsbAssembly = Assembly.Load("QSB");
- // var allPatchTypes = qsbAssembly
- // .GetTypes()
- // .Where(x => typeof(QSBPatch).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract);
+ [TestMethod]
+ public void CheckUnreferencedPatches()
+ {
+ var qsbAssembly = Assembly.Load("QSB");
+ var allPatchTypes = qsbAssembly
+ .GetTypes()
+ .Where(x => typeof(QSBPatch).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract);
- // QSBPatchManager.Init();
- // var patchInstances = (List)typeof(QSBPatchManager)
- // .GetField("_patchList", BindingFlags.NonPublic | BindingFlags.Static)
- // .GetValue(typeof(QSBPatchManager));
+ QSBPatchManager.Init();
+ var patchInstances = (List)typeof(QSBPatchManager)
+ .GetField("_patchList", BindingFlags.NonPublic | BindingFlags.Static)
+ .GetValue(typeof(QSBPatchManager));
- // var failedTypes = new List();
- // foreach (var type in allPatchTypes)
- // {
- // if (!patchInstances.Any(x => x.GetType() == type))
- // {
- // failedTypes.Add(type);
- // }
- // }
+ var failedTypes = new List();
+ foreach (var type in allPatchTypes)
+ {
+ if (!patchInstances.Any(x => x.GetType() == type))
+ {
+ failedTypes.Add(type);
+ }
+ }
- // if (failedTypes.Count > 0)
- // {
- // Assert.Fail(string.Join(", ", failedTypes.Select(x => x.Name)));
- // }
- //}
+ if (failedTypes.Count > 0)
+ {
+ Assert.Fail(string.Join(", ", failedTypes.Select(x => x.Name)));
+ }
+ }
}
}
diff --git a/QuantumUNET/QuantumUNET.csproj b/QuantumUNET/QuantumUNET.csproj
index 74f0f29a..f7f44bb5 100644
--- a/QuantumUNET/QuantumUNET.csproj
+++ b/QuantumUNET/QuantumUNET.csproj
@@ -52,8 +52,9 @@
$(GameDir)\OuterWilds_Data\Managed\UnityEngine.IMGUIModule.dll
-
- $(GameDir)\OuterWilds_Data\Managed\UnityEngine.Networking.dll
+
+ False
+ ..\QSB\lib\UnityEngine.Networking.dll
False
diff --git a/README.md b/README.md
index 8a16bd69..c3a6ab7b 100644
--- a/README.md
+++ b/README.md
@@ -91,10 +91,10 @@ QSB relies on exact orders of objects found using Resources.FindObjectsOfTypeAll
| Quantum objects | Yes |
| Repairing ship parts | Yes |
| Repairing "satellite" parts | No |
-| Ship | Kinda of |
+| Ship | Yes |
| Ship log | Yes |
-| Solanum | No |
-| Timber Hearth satellite | No |
+| Solanum | Yes |
+| Timber Hearth satellite | Yes |
| Tornadoes | No |
QSB also changes some mechanics of the base game, to better fit a multiplayer experience. These include :
@@ -137,19 +137,15 @@ Note - _nebula has no idea how Hamachi works and has never used it, so don't ask
## Playing as a client
- Run the game.
-- You'll see some new buttons on the top left.
-- Replace `localhost` with the server's public IP address.
-- Press "Connect". You can join servers in the menu or in-game, but it is recommended to join in the main menu.
-- If you see "Stop", you are connected.
-- If it stops at "Connecting to..." then you or the host has issues with their firewall/router/other.
+- On the title/pause menu, select "MULTIPLAYER (CONNECT)".
+- Enter the public IP address of the host.
+- Hit connect, and pray.
## Playing as a host
- Open port `7777` on your router.
- Run the game.
-- You'll see some new buttons on the top left.
-- Press "Host". This can be done in-game or in the menu, but it is recommened to start servers in the menu.
-- If you now see the "Stop" button, you are hosting.
+- On the title/pause menu, select "MULTIPLAYER (HOST)".
- Give your external IPv4 address to your clients ([like what you see here](http://whatismyip.host/)).
## Development Setup
@@ -160,10 +156,10 @@ Note - _nebula has no idea how Hamachi works and has never used it, so don't ask
- Open the file `QSB/QSB.csproj.user` in your favorite text editor
- Edit the entry `` to point to the directory where Outer Wilds is installed
- Edit the entry `` to point to your OWML directory (it is installed inside the Mod Manager directory)
-- Do the same for QuantumUNET/QuantumUNET.csproj.user
+- Do the same for `QuantumUNET/QuantumUNET.csproj.user` and `QSBTests/QSBTests.csproj.user`
- Open the project solution file `QSB.sln` in Visual Studio
- If needed, right click `References` in the Solution Explorer > Manage NuGet Packages > Update OWML to fix missing references
-- Run this to stop tracking QSB.csproj.user: ```git update-index --skip-worktree QSB/QSB.csproj.user```
+- Run this to stop tracking QSB.csproj.user: ```git update-index --skip-worktree QSB/QSB.csproj.user``` (and do the same for the other .user files)
To fix the references, right click "References" in the Solution Explorer > "Add Reference", and add all the missing DLLs (references with yellow warning icon). You can find these DLLs in the game's directory (`OuterWilds\OuterWilds_Data\Managed`);
diff --git a/UnityEngine.Networking.dll b/UnityEngine.Networking.dll
deleted file mode 100644
index 4db9ce9d..00000000
Binary files a/UnityEngine.Networking.dll and /dev/null differ