mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-01-25 15:35:22 +00:00
commit
94e746b0e9
Binary file not shown.
@ -1,24 +1,24 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 3469869292
|
||||
CRC: 1518538429
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 55d90dfc169d4fd552679840c1474222
|
||||
Hash: cda9c91e090f27b94734bfca3a7cb9e2
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 6ce89620af51ba381c9e4f226a2ebb1b
|
||||
Hash: 90db08ff16f71e0f4005d38a4650eff2
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
Script: {instanceID: 0}
|
||||
- Class: 114
|
||||
Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -900027084, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
Script: {fileID: 11500000, guid: e19747de3f5aca642ab2be37e372fb86, type: 3}
|
||||
- Class: 115
|
||||
Script: {instanceID: 0}
|
||||
- Class: 222
|
||||
@ -27,6 +27,7 @@ ClassTypes:
|
||||
Script: {instanceID: 0}
|
||||
- Class: 224
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/DialogueBubble.prefab
|
||||
Dependencies: []
|
||||
|
Binary file not shown.
@ -1,26 +1,34 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 2815158869
|
||||
CRC: 3009665417
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 5677b7876f2afae05c0920067ef29e8a
|
||||
Hash: dbc913ca95e649d2e00d188ff573830e
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 4d6a73cb377370ba69c96eb5da1b5028
|
||||
Hash: b2ece8ae09df261ff59d764d08696641
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
Script: {instanceID: 0}
|
||||
- Class: 4
|
||||
Script: {instanceID: 0}
|
||||
- Class: 21
|
||||
Script: {instanceID: 0}
|
||||
- Class: 23
|
||||
Script: {instanceID: 0}
|
||||
- Class: 28
|
||||
Script: {instanceID: 0}
|
||||
- Class: 33
|
||||
Script: {instanceID: 0}
|
||||
- Class: 43
|
||||
Script: {instanceID: 0}
|
||||
- Class: 48
|
||||
Script: {instanceID: 0}
|
||||
- Class: 114
|
||||
Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
|
||||
- Class: 115
|
||||
Script: {instanceID: 0}
|
||||
- Class: 128
|
||||
@ -31,6 +39,11 @@ ClassTypes:
|
||||
Script: {instanceID: 0}
|
||||
- Class: 224
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/Cube.prefab
|
||||
- Assets/Capsule.prefab
|
||||
- Assets/DebugVis.mat
|
||||
- Assets/LogCanvas.prefab
|
||||
- Assets/Sphere.prefab
|
||||
Dependencies: []
|
||||
|
Binary file not shown.
@ -1,12 +1,12 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 3621554448
|
||||
CRC: 1991351671
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: c9002a0b83220186e94179a065236b5c
|
||||
Hash: 494875ba5d9a67b7d87421e95e386357
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 8b6abf066340f652e25eed06e6b72102
|
||||
Hash: 6968c5d2bbef57a79632abd61ea01bb3
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
@ -14,13 +14,14 @@ ClassTypes:
|
||||
- Class: 4
|
||||
Script: {instanceID: 0}
|
||||
- Class: 114
|
||||
Script: {fileID: 372142912, guid: dc443db3e92b4983b9738c1131f555cb, type: 3}
|
||||
Script: {fileID: 372142912, guid: 93b08009869340045a8e7321508b6355, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -1768714887, guid: dc443db3e92b4983b9738c1131f555cb, type: 3}
|
||||
Script: {fileID: -1768714887, guid: 93b08009869340045a8e7321508b6355, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: -1267208747, guid: dc443db3e92b4983b9738c1131f555cb, type: 3}
|
||||
Script: {fileID: -1267208747, guid: 93b08009869340045a8e7321508b6355, type: 3}
|
||||
- Class: 115
|
||||
Script: {instanceID: 0}
|
||||
SerializeReferenceClassIdentifiers: []
|
||||
Assets:
|
||||
- Assets/NetworkProbe.prefab
|
||||
- Assets/NETWORK_Player_Body.prefab
|
||||
|
@ -12,7 +12,7 @@ namespace QSB.Animation.NPC
|
||||
QSBWorldSync.Init<QSBCharacterAnimController, CharacterAnimController>();
|
||||
QSBWorldSync.Init<QSBTravelerController, TravelerController>();
|
||||
|
||||
//TODO : this is the wrong place to put this... move it to Conversations?
|
||||
//MOVE : this is the wrong place to put this... move it to Conversations?
|
||||
QSBWorldSync.OldDialogueTrees.Clear();
|
||||
QSBWorldSync.OldDialogueTrees = Resources.FindObjectsOfTypeAll<CharacterDialogueTree>().ToList();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using QSB.Animation.NPC.WorldObjects;
|
||||
using QSB.ConversationSync;
|
||||
using QSB.Events;
|
||||
@ -12,22 +13,14 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.NPC.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class CharacterAnimationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(CharacterAnimController_OnAnimatorIK));
|
||||
Prefix(nameof(CharacterAnimController_OnZoneEntry));
|
||||
Prefix(nameof(CharacterAnimController_OnZoneExit));
|
||||
Prefix(nameof(FacePlayerWhenTalking_OnStartConversation));
|
||||
Prefix(nameof(CharacterDialogueTree_StartConversation));
|
||||
Prefix(nameof(CharacterDialogueTree_EndConversation));
|
||||
Prefix(nameof(KidRockController_Update));
|
||||
}
|
||||
|
||||
public static bool CharacterAnimController_OnAnimatorIK(
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnAnimatorIK))]
|
||||
public static bool AnimatorIKReplacement(
|
||||
CharacterAnimController __instance,
|
||||
float ___headTrackingWeight,
|
||||
bool ___lookOnlyWhenTalking,
|
||||
@ -39,14 +32,14 @@ namespace QSB.Animation.NPC.Patches
|
||||
Animator ____animator,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
if (!WorldObjectManager.AllReady || ConversationManager.Instance == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var playerId = ConversationManager.Instance.GetPlayerTalkingToTree(____dialogueTree);
|
||||
var player = QSBPlayerManager.GetPlayer(playerId);
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance); // TODO : maybe cache this somewhere... or assess how slow this is
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance); // OPTIMIZE : maybe cache this somewhere... or assess how slow this is
|
||||
|
||||
PlayerInfo playerToUse = null;
|
||||
if (____inConversation)
|
||||
@ -63,7 +56,7 @@ namespace QSB.Animation.NPC.Patches
|
||||
: player;
|
||||
}
|
||||
}
|
||||
else if (!___lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0) // TODO : maybe this would be more fun if characters looked between players at random times? :P
|
||||
else if (!___lookOnlyWhenTalking && qsbObj.GetPlayersInHeadZone().Count != 0) // IDEA : maybe this would be more fun if characters looked between players at random times? :P
|
||||
{
|
||||
playerToUse = QSBPlayerManager.GetClosestPlayerToWorldPoint(qsbObj.GetPlayersInHeadZone(), __instance.transform.position);
|
||||
}
|
||||
@ -103,21 +96,27 @@ namespace QSB.Animation.NPC.Patches
|
||||
|
||||
}
|
||||
|
||||
public static bool CharacterAnimController_OnZoneExit(CharacterAnimController __instance)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnZoneExit))]
|
||||
public static bool HeadZoneExit(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBExitHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CharacterAnimController_OnZoneEntry(CharacterAnimController __instance)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterAnimController), nameof(CharacterAnimController.OnZoneEntry))]
|
||||
public static bool HeadZoneEntry(CharacterAnimController __instance)
|
||||
{
|
||||
var qsbObj = QSBWorldSync.GetWorldFromUnity<QSBCharacterAnimController, CharacterAnimController>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBEnterHeadZone, qsbObj.ObjectId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool FacePlayerWhenTalking_OnStartConversation(
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(FacePlayerWhenTalking), nameof(FacePlayerWhenTalking.OnStartConversation))]
|
||||
public static bool OnStartConversation(
|
||||
FacePlayerWhenTalking __instance,
|
||||
CharacterDialogueTree ____dialogueTree)
|
||||
{
|
||||
@ -140,7 +139,9 @@ namespace QSB.Animation.NPC.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CharacterDialogueTree_StartConversation(CharacterDialogueTree __instance)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.StartConversation))]
|
||||
public static bool StartConversation(CharacterDialogueTree __instance)
|
||||
{
|
||||
var allNpcAnimControllers = QSBWorldSync.GetWorldObjects<INpcAnimController>();
|
||||
var ownerOfThis = allNpcAnimControllers.FirstOrDefault(x => x.GetDialogueTree() == __instance);
|
||||
@ -154,7 +155,9 @@ namespace QSB.Animation.NPC.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CharacterDialogueTree_EndConversation(CharacterDialogueTree __instance)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.EndConversation))]
|
||||
public static bool EndConversation(CharacterDialogueTree __instance)
|
||||
{
|
||||
var allNpcAnimControllers = QSBWorldSync.GetWorldObjects<INpcAnimController>();
|
||||
var ownerOfThis = allNpcAnimControllers.FirstOrDefault(x => x.GetDialogueTree() == __instance);
|
||||
@ -168,7 +171,9 @@ namespace QSB.Animation.NPC.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool KidRockController_Update(
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(KidRockController), nameof(KidRockController.Update))]
|
||||
public static bool UpdateReplacement(
|
||||
KidRockController __instance,
|
||||
bool ____throwingRock,
|
||||
CharacterDialogueTree ____dialogueTree,
|
||||
|
@ -41,7 +41,7 @@ namespace QSB.Animation.Player
|
||||
return;
|
||||
}
|
||||
|
||||
var jumpChargeFraction = _playerController.GetJumpChargeFraction();
|
||||
var jumpChargeFraction = _playerController.GetJumpCrouchFraction();
|
||||
_crouchValue = jumpChargeFraction;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using QSB.Events;
|
||||
using HarmonyLib;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
@ -6,27 +7,27 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.Animation.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class PlayerAnimationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
=> Prefix(nameof(PlayerAnimController_LateUpdate));
|
||||
|
||||
public static bool PlayerAnimController_LateUpdate(
|
||||
PlayerAnimController __instance,
|
||||
PlayerCharacterController ____playerController,
|
||||
ThrusterModel ____playerJetpack,
|
||||
ref float ____ungroundedTime,
|
||||
Animator ____animator,
|
||||
ref bool ____justBecameGrounded,
|
||||
ref bool ____justTookFallDamage,
|
||||
ref bool ____leftFootGrounded,
|
||||
ref bool ____rightFootGrounded,
|
||||
ref bool ____rightArmHidden,
|
||||
GameObject[] ____rightArmObjects,
|
||||
int ____defaultLayer,
|
||||
int ____probeOnlyLayer)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerAnimController), nameof(PlayerAnimController.LateUpdate))]
|
||||
public static bool LateUpdateReplacement(
|
||||
PlayerAnimController __instance,
|
||||
PlayerCharacterController ____playerController,
|
||||
ThrusterModel ____playerJetpack,
|
||||
ref float ____ungroundedTime,
|
||||
Animator ____animator,
|
||||
ref bool ____justBecameGrounded,
|
||||
ref bool ____justTookFallDamage,
|
||||
ref bool ____leftFootGrounded,
|
||||
ref bool ____rightFootGrounded,
|
||||
ref bool ____rightArmHidden,
|
||||
GameObject[] ____rightArmObjects,
|
||||
int ____defaultLayer,
|
||||
int ____probeOnlyLayer)
|
||||
{
|
||||
var isGrounded = ____playerController.IsGrounded();
|
||||
var isAttached = PlayerState.IsAttached();
|
||||
@ -66,7 +67,7 @@ namespace QSB.Animation.Patches
|
||||
____animator.SetFloat("RunSpeedY", movementVector.z / 3f);
|
||||
____animator.SetFloat("TurnSpeed", ____playerController.GetTurning());
|
||||
____animator.SetBool("Grounded", isGrounded || isAttached || PlayerState.IsRecentlyDetached());
|
||||
____animator.SetLayerWeight(1, ____playerController.GetJumpChargeFraction());
|
||||
____animator.SetLayerWeight(1, ____playerController.GetJumpCrouchFraction());
|
||||
____animator.SetFloat("FreefallSpeed", freefallMagnitude / 15f * (timeInFreefall / 3f));
|
||||
____animator.SetBool("InZeroG", isInZeroG || isFlying);
|
||||
____animator.SetBool("UsingJetpack", isInZeroG && PlayerState.IsWearingSuit());
|
||||
|
@ -1,20 +1,22 @@
|
||||
using QSB.CampfireSync.WorldObjects;
|
||||
using HarmonyLib;
|
||||
using QSB.CampfireSync.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.WorldSync;
|
||||
|
||||
namespace QSB.CampfireSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class CampfirePatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches() => Prefix(nameof(Campfire_OnPressInteract));
|
||||
|
||||
public static bool Campfire_OnPressInteract(Campfire __instance, Campfire.State ____state)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Campfire), nameof(Campfire.OnPressInteract))]
|
||||
public static bool LightCampfireEvent(Campfire __instance)
|
||||
{
|
||||
var qsbCampfire = QSBWorldSync.GetWorldFromUnity<QSBCampfire, Campfire>(__instance);
|
||||
if (____state == Campfire.State.LIT)
|
||||
if (__instance._state == Campfire.State.LIT)
|
||||
{
|
||||
qsbCampfire.StartRoasting();
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
DeadInSolarSystem,
|
||||
AliveInEye,
|
||||
WaitingForOthersToDieInSolarSystem,
|
||||
WaitingForOthersToReadyInSolarSystem
|
||||
WaitingForOthersToReadyInSolarSystem,
|
||||
WatchingLongCredits,
|
||||
WatchingShortCredits
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace QSB.ClientServerStateSync
|
||||
public event ChangeStateEvent OnChangeState;
|
||||
public delegate void ChangeStateEvent(ClientState newState);
|
||||
|
||||
private void Awake()
|
||||
private void Awake()
|
||||
=> Instance = this;
|
||||
|
||||
private void Start()
|
||||
@ -28,6 +28,7 @@ namespace QSB.ClientServerStateSync
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"CHANGE CLIENT STATE FROM {QSBPlayerManager.LocalPlayer.State} to {newState}");
|
||||
QSBPlayerManager.LocalPlayer.State = newState;
|
||||
OnChangeState?.Invoke(newState);
|
||||
@ -37,48 +38,99 @@ namespace QSB.ClientServerStateSync
|
||||
{
|
||||
var serverState = ServerStateManager.Instance.GetServerState();
|
||||
|
||||
ClientState newState;
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
if (newScene == OWScene.SolarSystem && oldScene != OWScene.SolarSystem)
|
||||
{
|
||||
DebugLog.DebugWrite($"Server is loading SolarSystem just after creating server.");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
|
||||
}
|
||||
|
||||
if (newScene == OWScene.SolarSystem && oldScene == OWScene.SolarSystem)
|
||||
switch (newScene)
|
||||
{
|
||||
DebugLog.DebugWrite($"Server is reloading SolarSystem");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.WaitingForOthersToReadyInSolarSystem);
|
||||
}
|
||||
|
||||
if (newScene == OWScene.TitleScreen)
|
||||
{
|
||||
DebugLog.DebugWrite($"Server has gone back to title screen");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.InTitleScreen);
|
||||
case OWScene.TitleScreen:
|
||||
DebugLog.DebugWrite($"SERVER LOAD TITLESCREEN");
|
||||
newState = ClientState.InTitleScreen;
|
||||
break;
|
||||
case OWScene.Credits_Fast:
|
||||
DebugLog.DebugWrite($"SERVER LOAD SHORT CREDITS");
|
||||
newState = ClientState.WatchingShortCredits;
|
||||
break;
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
DebugLog.DebugWrite($"SERVER LOAD LONG CREDITS");
|
||||
newState = ClientState.WatchingLongCredits;
|
||||
break;
|
||||
case OWScene.SolarSystem:
|
||||
if (oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
// reloading scene
|
||||
DebugLog.DebugWrite($"SERVER RELOAD SOLARSYSTEM");
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
// loading in from title screen
|
||||
DebugLog.DebugWrite($"SERVER LOAD SOLARSYSTEM");
|
||||
newState = ClientState.AliveInSolarSystem;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
newState = ClientState.NotLoaded;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (newScene == OWScene.SolarSystem && oldScene != OWScene.SolarSystem && serverState != ServerState.AwaitingPlayConfirmation)
|
||||
switch (newScene)
|
||||
{
|
||||
DebugLog.DebugWrite($"Client is loading SolarSystem just after connecting.");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
|
||||
}
|
||||
case OWScene.TitleScreen:
|
||||
DebugLog.DebugWrite($"CLIENT LOAD TITLESCREEN");
|
||||
newState = ClientState.InTitleScreen;
|
||||
break;
|
||||
case OWScene.Credits_Fast:
|
||||
DebugLog.DebugWrite($"CLIENT LOAD SHORT CREDITS");
|
||||
newState = ClientState.WatchingShortCredits;
|
||||
break;
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
DebugLog.DebugWrite($"CLIENT LOAD LONG CREDITS");
|
||||
newState = ClientState.WatchingLongCredits;
|
||||
break;
|
||||
case OWScene.SolarSystem:
|
||||
if (serverState == ServerState.WaitingForAllPlayersToDie)
|
||||
{
|
||||
DebugLog.DebugWrite($"SEVER IN DEATH PHASE - WAIT");
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
break;
|
||||
}
|
||||
|
||||
if (newScene == OWScene.SolarSystem && oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
DebugLog.DebugWrite($"Client is reloading SolarSystem");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.WaitingForOthersToReadyInSolarSystem);
|
||||
}
|
||||
|
||||
if (serverState == ServerState.WaitingForDeath)
|
||||
{
|
||||
DebugLog.DebugWrite($"Client loaded new scene while server is waiting for all players to die");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.WaitingForOthersToReadyInSolarSystem);
|
||||
if (oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
// reloading scene
|
||||
DebugLog.DebugWrite($"CLIENT RELOAD SOLARSYSTEM");
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
// loading in from title screen
|
||||
DebugLog.DebugWrite($"CLIENT LOAD SOLARSYSTEM");
|
||||
if (serverState == ServerState.WaitingForAllPlayersToReady)
|
||||
{
|
||||
newState = ClientState.WaitingForOthersToReadyInSolarSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
newState = ClientState.AliveInSolarSystem;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
newState = ClientState.NotLoaded;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, newState);
|
||||
}
|
||||
|
||||
|
||||
public void OnDeath()
|
||||
{
|
||||
var currentScene = QSBSceneManager.CurrentScene;
|
||||
@ -97,29 +149,48 @@ namespace QSB.ClientServerStateSync
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRespawn()
|
||||
{
|
||||
var currentScene = QSBSceneManager.CurrentScene;
|
||||
if (currentScene == OWScene.SolarSystem)
|
||||
{
|
||||
DebugLog.DebugWrite($"RESPAWN!");
|
||||
QSBEventManager.FireEvent(EventNames.QSBClientState, ClientState.AliveInSolarSystem);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Player tried to respawn in scene {currentScene}", OWML.Common.MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private ClientState ForceGetCurrentState()
|
||||
{
|
||||
DebugLog.DebugWrite($"ForceGetCurrentState");
|
||||
var currentScene = LoadManager.GetCurrentScene();
|
||||
var lastScene = LoadManager.GetPreviousScene();
|
||||
|
||||
if (currentScene == OWScene.TitleScreen || currentScene == OWScene.Credits_Fast || currentScene == OWScene.Credits_Final)
|
||||
switch (currentScene)
|
||||
{
|
||||
return ClientState.InTitleScreen;
|
||||
case OWScene.TitleScreen:
|
||||
DebugLog.DebugWrite($"- TitleScreen");
|
||||
return ClientState.InTitleScreen;
|
||||
case OWScene.Credits_Fast:
|
||||
DebugLog.DebugWrite($"- Short Credits");
|
||||
return ClientState.WatchingShortCredits;
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
DebugLog.DebugWrite($"- Long Credits");
|
||||
return ClientState.WatchingLongCredits;
|
||||
case OWScene.SolarSystem:
|
||||
DebugLog.DebugWrite($"- SolarSystem");
|
||||
return ClientState.AliveInSolarSystem;
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
DebugLog.DebugWrite($"- Eye");
|
||||
return ClientState.AliveInEye;
|
||||
default:
|
||||
DebugLog.DebugWrite($"- Not Loaded");
|
||||
return ClientState.NotLoaded;
|
||||
}
|
||||
|
||||
// cant join while dead...
|
||||
|
||||
if (currentScene == OWScene.SolarSystem)
|
||||
{
|
||||
return ClientState.AliveInSolarSystem;
|
||||
}
|
||||
|
||||
if (currentScene == OWScene.EyeOfTheUniverse)
|
||||
{
|
||||
return ClientState.AliveInEye;
|
||||
}
|
||||
|
||||
return ClientState.NotLoaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ namespace QSB.ClientServerStateSync.Events
|
||||
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<ClientState> message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Remote receive id:{message.AboutId} state:{message.EnumValue}");
|
||||
if (message.AboutId == uint.MaxValue)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - ID is uint.MaxValue!", OWML.Common.MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
player.State = message.EnumValue;
|
||||
}
|
||||
|
@ -21,10 +21,10 @@ namespace QSB.ClientServerStateSync.Events
|
||||
EnumValue = state
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, EnumMessage<ServerState> message)
|
||||
public override void OnReceiveLocal(bool server, EnumMessage<ServerState> message)
|
||||
=> OnReceiveRemote(server, message);
|
||||
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<ServerState> message)
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<ServerState> message)
|
||||
=> ServerStateManager.Instance.ChangeServerState(message.EnumValue);
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,10 @@
|
||||
InEye,
|
||||
|
||||
// At end of loop, waiting for everyone to be ready to reload the scene
|
||||
WaitingForDeath,
|
||||
WaitingForAllPlayersToDie,
|
||||
|
||||
// At start of loop, waiting for everybody to be ready to start playing
|
||||
AwaitingPlayConfirmation,
|
||||
WaitingForAllPlayersToReady,
|
||||
|
||||
// When the statue has been activated
|
||||
InStatueCutscene
|
||||
|
@ -16,7 +16,7 @@ namespace QSB.ClientServerStateSync
|
||||
|
||||
private ServerState _currentState;
|
||||
|
||||
private void Awake()
|
||||
private void Awake()
|
||||
=> Instance = this;
|
||||
|
||||
private void Start()
|
||||
@ -25,6 +25,7 @@ namespace QSB.ClientServerStateSync
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
GlobalMessenger.AddListener("TriggerSupernova", OnTriggerSupernova);
|
||||
|
||||
@ -37,12 +38,12 @@ namespace QSB.ClientServerStateSync
|
||||
{
|
||||
return;
|
||||
}
|
||||
DebugLog.DebugWrite($"CHANGE SERVER STATE FROM {_currentState} to {newState}");
|
||||
|
||||
_currentState = newState;
|
||||
OnChangeState?.Invoke(newState);
|
||||
}
|
||||
|
||||
public ServerState GetServerState()
|
||||
public ServerState GetServerState()
|
||||
=> _currentState;
|
||||
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool inUniverse)
|
||||
@ -52,26 +53,31 @@ namespace QSB.ClientServerStateSync
|
||||
case OWScene.Credits_Fast:
|
||||
case OWScene.Credits_Final:
|
||||
case OWScene.PostCreditsScene:
|
||||
DebugLog.DebugWrite($"SERVER LOAD CREDITS");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.Credits);
|
||||
break;
|
||||
|
||||
case OWScene.TitleScreen:
|
||||
DebugLog.DebugWrite($"SERVER LOAD TITLE SCREEN");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.NotLoaded);
|
||||
break;
|
||||
|
||||
case OWScene.SolarSystem:
|
||||
DebugLog.DebugWrite($"SERVER LOAD SOLARSYSTEM");
|
||||
if (oldScene == OWScene.SolarSystem)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.AwaitingPlayConfirmation);
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForAllPlayersToReady);
|
||||
}
|
||||
else
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InSolarSystem);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.AwaitingPlayConfirmation);
|
||||
DebugLog.DebugWrite($"EYE");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForAllPlayersToReady);
|
||||
break;
|
||||
|
||||
case OWScene.None:
|
||||
@ -86,21 +92,26 @@ namespace QSB.ClientServerStateSync
|
||||
private void OnTriggerSupernova()
|
||||
{
|
||||
DebugLog.DebugWrite($"TriggerSupernova");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForDeath);
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForAllPlayersToDie);
|
||||
}
|
||||
|
||||
private ServerState ForceGetCurrentState()
|
||||
{
|
||||
DebugLog.DebugWrite($"ForceGetCurrentState");
|
||||
|
||||
var currentScene = LoadManager.GetCurrentScene();
|
||||
var lastScene = LoadManager.GetPreviousScene();
|
||||
|
||||
switch (currentScene)
|
||||
{
|
||||
case OWScene.SolarSystem:
|
||||
DebugLog.DebugWrite($"- SolarSystem");
|
||||
return ServerState.InSolarSystem;
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
DebugLog.DebugWrite($"- Eye");
|
||||
return ServerState.InEye;
|
||||
default:
|
||||
DebugLog.DebugWrite($"- Not Loaded");
|
||||
return ServerState.NotLoaded;
|
||||
}
|
||||
}
|
||||
@ -112,7 +123,7 @@ namespace QSB.ClientServerStateSync
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentState == ServerState.AwaitingPlayConfirmation)
|
||||
if (_currentState == ServerState.WaitingForAllPlayersToReady)
|
||||
{
|
||||
if (QSBPlayerManager.PlayerList.All(x => x.State == ClientState.WaitingForOthersToReadyInSolarSystem))
|
||||
{
|
||||
|
30
QSB/ConversationSync/CameraFacingBillboard.cs
Normal file
30
QSB/ConversationSync/CameraFacingBillboard.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class CameraFacingBillboard : MonoBehaviour
|
||||
{
|
||||
private OWCamera _activeCam;
|
||||
|
||||
private void Awake()
|
||||
=> GlobalMessenger<OWCamera>.AddListener("SwitchActiveCamera", OnSwitchActiveCamera);
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_activeCam = Locator.GetActiveCamera();
|
||||
UpdateRotation();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
=> GlobalMessenger<OWCamera>.RemoveListener("SwitchActiveCamera", OnSwitchActiveCamera);
|
||||
|
||||
private void OnSwitchActiveCamera(OWCamera activeCamera)
|
||||
{
|
||||
_activeCam = activeCamera;
|
||||
UpdateRotation();
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
=> UpdateRotation();
|
||||
|
||||
private void UpdateRotation()
|
||||
=> transform.LookAt(transform.position + (_activeCam.transform.rotation * Vector3.forward), _activeCam.transform.rotation * Vector3.up);
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Events;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
@ -23,7 +22,7 @@ namespace QSB.ConversationSync
|
||||
Instance = this;
|
||||
|
||||
_boxPrefab = QSBCore.ConversationAssetBundle.LoadAsset<GameObject>("assets/dialoguebubble.prefab");
|
||||
// TODO : make dynamic so it can be different sizes!
|
||||
// BUG : make dynamic so it can be different sizes!
|
||||
// the dynamic font seems to be super lo-res at this size...?
|
||||
var font = (Font)Resources.Load(@"fonts\english - latin\spacemono-bold");
|
||||
if (font == null)
|
||||
@ -91,7 +90,7 @@ namespace QSB.ConversationSync
|
||||
Destroy(playerBox);
|
||||
}
|
||||
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentDialogueBox = CreateBox(player.Body.transform, 25, text);
|
||||
QSBPlayerManager.GetPlayer(playerId).CurrentDialogueBox = CreateBox(player.Body.transform, 2, text);
|
||||
}
|
||||
|
||||
public void DisplayCharacterConversationBox(int index, string text)
|
||||
@ -120,10 +119,7 @@ namespace QSB.ConversationSync
|
||||
newBox.transform.SetParent(parent);
|
||||
newBox.transform.localPosition = new Vector3(0, vertOffset, 0);
|
||||
newBox.transform.rotation = parent.rotation;
|
||||
var lookAt = newBox.AddComponent<FaceActiveCamera>();
|
||||
lookAt.SetValue("_useLookAt", false);
|
||||
lookAt.SetValue("_localFacingVector", Vector3.back);
|
||||
lookAt.SetValue("_localRotationAxis", Vector3.up);
|
||||
newBox.AddComponent<CameraFacingBillboard>();
|
||||
newBox.GetComponent<Text>().text = text;
|
||||
newBox.AddComponent<ZOverride>();
|
||||
newBox.SetActive(true);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
@ -7,18 +8,13 @@ using System.Collections.Generic;
|
||||
|
||||
namespace QSB.ConversationSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class ConversationPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Postfix(nameof(DialogueNode_GetNextPage));
|
||||
Prefix(nameof(CharacterDialogueTree_InputDialogueOption));
|
||||
Prefix(nameof(CharacterDialogueTree_StartConversation));
|
||||
Prefix(nameof(CharacterDialogueTree_EndConversation));
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.StartConversation))]
|
||||
public static void CharacterDialogueTree_StartConversation(CharacterDialogueTree __instance)
|
||||
{
|
||||
var index = QSBWorldSync.OldDialogueTrees.FindIndex(x => x == __instance);
|
||||
@ -31,6 +27,8 @@ namespace QSB.ConversationSync.Patches
|
||||
ConversationManager.Instance.SendConvState(index, true);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.EndConversation))]
|
||||
public static bool CharacterDialogueTree_EndConversation(CharacterDialogueTree __instance)
|
||||
{
|
||||
if (!__instance.enabled)
|
||||
@ -51,6 +49,8 @@ namespace QSB.ConversationSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CharacterDialogueTree), nameof(CharacterDialogueTree.InputDialogueOption))]
|
||||
public static bool CharacterDialogueTree_InputDialogueOption(int optionIndex, DialogueBoxVer2 ____currentDialogueBox)
|
||||
{
|
||||
if (optionIndex < 0)
|
||||
@ -65,6 +65,8 @@ namespace QSB.ConversationSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(DialogueNode), nameof(DialogueNode.GetNextPage))]
|
||||
public static void DialogueNode_GetNextPage(string ____name, List<string> ____listPagesToDisplay, int ____currentPage)
|
||||
{
|
||||
var key = ____name + ____listPagesToDisplay[____currentPage];
|
||||
|
@ -20,20 +20,21 @@ namespace QSB.DeathSync.Events
|
||||
EnumValue = type
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool server, EnumMessage<EndLoopReason> message)
|
||||
public override void OnReceiveLocal(bool server, EnumMessage<EndLoopReason> message)
|
||||
=> OnReceiveRemote(server, message);
|
||||
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<EndLoopReason> message)
|
||||
{
|
||||
DebugLog.DebugWrite($" ~~~~ END LOOP - Reason:{message.EnumValue} ~~~~ ");
|
||||
switch (message.EnumValue)
|
||||
{
|
||||
case EndLoopReason.AllPlayersDead:
|
||||
DebugLog.DebugWrite($"all players dead");
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForDeath);
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.WaitingForAllPlayersToDie);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ namespace QSB.DeathSync.Events
|
||||
|
||||
public override void OnReceiveLocal(bool server, PlayerDeathMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"RECEIVE LOCAL PLAYER DEATH");
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
RespawnManager.Instance.OnPlayerDeath(player);
|
||||
ClientStateManager.Instance.OnDeath();
|
||||
@ -31,7 +30,6 @@ namespace QSB.DeathSync.Events
|
||||
|
||||
public override void OnReceiveRemote(bool server, PlayerDeathMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"RECEIVE REMOTE PLAYER DEATH");
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
var playerName = player.Name;
|
||||
var deathMessage = Necronomicon.GetPhrase(message.EnumValue, message.NecronomiconIndex);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using QSB.Events;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Events;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
@ -29,6 +30,7 @@ namespace QSB.DeathSync.Events
|
||||
if (message.AboutId == LocalPlayerId)
|
||||
{
|
||||
RespawnManager.Instance.Respawn();
|
||||
ClientStateManager.Instance.OnRespawn();
|
||||
}
|
||||
|
||||
RespawnManager.Instance.OnPlayerRespawn(QSBPlayerManager.GetPlayer(message.AboutId));
|
||||
|
@ -1,46 +1,45 @@
|
||||
using Harmony;
|
||||
using HarmonyLib;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.ShipSync;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.DeathSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class DeathPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(DeathManager_KillPlayer_Prefix));
|
||||
Postfix(nameof(DeathManager_KillPlayer_Postfix));
|
||||
Prefix(nameof(ShipDetachableLeg_Detach));
|
||||
Prefix(nameof(ShipDetachableModule_Detach));
|
||||
Empty("ShipEjectionSystem_OnPressInteract");
|
||||
Postfix(nameof(ShipDamageController_Awake));
|
||||
Prefix(nameof(DestructionVolume_VanishShip));
|
||||
Prefix(nameof(HighSpeedImpactSensor_FixedUpdate));
|
||||
Prefix(nameof(PlayerResources_OnImpact));
|
||||
}
|
||||
// TODO : Remove with future functionality.
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipEjectionSystem), nameof(ShipEjectionSystem.OnPressInteract))]
|
||||
public static bool DisableEjection()
|
||||
=> false;
|
||||
|
||||
// TODO : Remove with future functionality.
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipDetachableLeg), nameof(ShipDetachableLeg.Detach))]
|
||||
public static bool ShipDetachableLeg_Detach(ref OWRigidbody __result)
|
||||
{
|
||||
__result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : Remove with future functionality.
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipDetachableModule), nameof(ShipDetachableModule.Detach))]
|
||||
public static bool ShipDetachableModule_Detach(ref OWRigidbody __result)
|
||||
{
|
||||
__result = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerResources), nameof(PlayerResources.OnImpact))]
|
||||
public static bool PlayerResources_OnImpact(ImpactData impact, PlayerResources __instance, float ____currentHealth)
|
||||
{
|
||||
if (PlayerState.IsInsideShip())
|
||||
@ -66,6 +65,8 @@ namespace QSB.DeathSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(HighSpeedImpactSensor), nameof(HighSpeedImpactSensor.FixedUpdate))]
|
||||
public static bool HighSpeedImpactSensor_FixedUpdate(
|
||||
HighSpeedImpactSensor __instance,
|
||||
bool ____isPlayer,
|
||||
@ -186,9 +187,10 @@ namespace QSB.DeathSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.KillPlayer))]
|
||||
public static bool DeathManager_KillPlayer_Prefix(DeathType deathType)
|
||||
{
|
||||
DebugLog.DebugWrite($"KILL PLAYER PREFIX stacetrace : \r\n {Environment.StackTrace}");
|
||||
if (RespawnOnDeath.Instance == null)
|
||||
{
|
||||
return true;
|
||||
@ -205,21 +207,20 @@ namespace QSB.DeathSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(DeathManager), nameof(DeathManager.KillPlayer))]
|
||||
public static void DeathManager_KillPlayer_Postfix(DeathType deathType)
|
||||
{
|
||||
DebugLog.DebugWrite($"KILL PLAYER POSTFIX");
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerDeath, deathType);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(ShipDamageController), nameof(ShipDamageController.Awake))]
|
||||
public static void ShipDamageController_Awake(ref bool ____exploded)
|
||||
=> ____exploded = true;
|
||||
|
||||
public static IEnumerable<CodeInstruction> ReturnNull(IEnumerable<CodeInstruction> instructions) => new List<CodeInstruction>
|
||||
{
|
||||
new CodeInstruction(OpCodes.Ldnull),
|
||||
new CodeInstruction(OpCodes.Ret)
|
||||
};
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(DestructionVolume), nameof(DestructionVolume.VanishShip))]
|
||||
public static bool DestructionVolume_VanishShip(DeathType ____deathType)
|
||||
{
|
||||
if (RespawnOnDeath.Instance == null)
|
||||
|
@ -7,11 +7,11 @@ namespace QSB.DeathSync.Patches
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.RespawnTime;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(MapController_LateUpdate));
|
||||
Prefix(nameof(MapController_EnterMapView));
|
||||
}
|
||||
//public override void DoPatches()
|
||||
//{
|
||||
// Prefix<MapController>(nameof(MapController.LateUpdate), nameof(MapController_LateUpdate));
|
||||
// Prefix<MapController>(nameof(MapController.EnterMapView), nameof(MapController_EnterMapView));
|
||||
//}
|
||||
|
||||
public static bool MapController_EnterMapView(
|
||||
MapController __instance,
|
||||
@ -164,9 +164,9 @@ namespace QSB.DeathSync.Patches
|
||||
var zoomInput = 0f;
|
||||
if (canInteractWith)
|
||||
{
|
||||
XZinput = OWInput.GetValue(InputLibrary.moveXZ, InputMode.All);
|
||||
lookInput = InputLibrary.look.GetValue(false);
|
||||
zoomInput = OWInput.GetValue(InputLibrary.mapZoom, InputMode.All);
|
||||
XZinput = OWInput.GetAxisValue(InputLibrary.moveXZ, InputMode.All);
|
||||
lookInput = InputLibrary.look.GetAxisValue(false);
|
||||
zoomInput = OWInput.GetValue(InputLibrary.mapZoomIn, InputMode.All) - OWInput.GetValue(InputLibrary.mapZoomOut, InputMode.All);
|
||||
lookInput.y *= -1f;
|
||||
zoomInput *= -1f;
|
||||
}
|
||||
|
@ -1,18 +1,22 @@
|
||||
using OWML.Utils;
|
||||
using HarmonyLib;
|
||||
using OWML.Utils;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.DeathSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class RespawnPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(PlayerRecoveryPoint_OnGainFocus));
|
||||
Prefix(nameof(PlayerRecoveryPoint_OnPressInteract));
|
||||
}
|
||||
//public override void DoPatches()
|
||||
//{
|
||||
// Prefix<PlayerRecoveryPoint>(nameof(PlayerRecoveryPoint.OnGainFocus), nameof(PlayerRecoveryPoint_OnGainFocus));
|
||||
// Prefix<PlayerRecoveryPoint>(nameof(PlayerRecoveryPoint.OnPressInteract), nameof(PlayerRecoveryPoint_OnPressInteract));
|
||||
//}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerRecoveryPoint), nameof(PlayerRecoveryPoint.OnGainFocus))]
|
||||
public static bool PlayerRecoveryPoint_OnGainFocus(
|
||||
PlayerResources ____playerResources,
|
||||
bool ____refuelsPlayer,
|
||||
@ -100,6 +104,8 @@ namespace QSB.DeathSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerRecoveryPoint), nameof(PlayerRecoveryPoint.OnPressInteract))]
|
||||
public static bool PlayerRecoveryPoint_OnPressInteract(
|
||||
PlayerRecoveryPoint __instance,
|
||||
PlayerResources ____playerResources,
|
||||
|
@ -28,7 +28,7 @@ namespace QSB.DeathSync
|
||||
private Vector3 _deathPositionRelative;
|
||||
|
||||
public Transform DeathClosestAstroObject { get; private set; }
|
||||
public Vector3 DeathPositionWorld
|
||||
public Vector3 DeathPositionWorld
|
||||
=> DeathClosestAstroObject == null
|
||||
? Vector3.zero
|
||||
: DeathClosestAstroObject.TransformPoint(_deathPositionRelative);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Utils;
|
||||
using HarmonyLib;
|
||||
using OWML.Utils;
|
||||
using QSB.ElevatorSync.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
@ -6,18 +7,18 @@ using QSB.WorldSync;
|
||||
|
||||
namespace QSB.ElevatorSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class ElevatorPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(Elevator), nameof(Elevator.StartLift))]
|
||||
public static void Elevator_StartLift(Elevator __instance)
|
||||
{
|
||||
var isGoingUp = __instance.GetValue<bool>("_goingToTheEnd");
|
||||
var id = QSBWorldSync.GetIdFromUnity<QSBElevator, Elevator>(__instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBStartLift, id, isGoingUp);
|
||||
}
|
||||
|
||||
public override void DoPatches()
|
||||
=> Postfix(nameof(Elevator_StartLift));
|
||||
}
|
||||
}
|
@ -1,22 +1,22 @@
|
||||
using QSB.Events;
|
||||
using HarmonyLib;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.FrequencySync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class FrequencyPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Postfix(nameof(AudioSignal_IdentifyFrequency));
|
||||
Postfix(nameof(AudioSignal_IdentifySignal));
|
||||
}
|
||||
|
||||
public static void AudioSignal_IdentifyFrequency(SignalFrequency ____frequency)
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(AudioSignal), nameof(AudioSignal.IdentifyFrequency))]
|
||||
static void IdentifyFrequencyEvent(SignalFrequency ____frequency)
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBIdentifyFrequency, ____frequency);
|
||||
|
||||
public static void AudioSignal_IdentifySignal(SignalName ____name)
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(AudioSignal), nameof(AudioSignal.IdentifySignal))]
|
||||
static void IdentifySignalEvent(SignalName ____name)
|
||||
=> QSBEventManager.FireEvent(EventNames.QSBIdentifySignal, ____name);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,16 @@
|
||||
using QSB.Patches;
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.GeyserSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class GeyserPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnNonServerClientConnect;
|
||||
|
||||
public override void DoPatches() => Empty("GeyserController_Update");
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GeyserController), nameof(GeyserController.Update))]
|
||||
public static bool Empty()
|
||||
=> false;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
using QSB.Patches;
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.Inputs.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class InputPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
=> Prefix(nameof(OWInput_Update));
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(OWInput), nameof(OWInput.Update))]
|
||||
public static bool OWInput_Update()
|
||||
=> QSBInputManager.Instance.InputsEnabled;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ namespace QSB.Instruments.QSBCamera
|
||||
|
||||
private void UpdateInput()
|
||||
{
|
||||
var input = OWInput.GetValue(InputLibrary.look, false);
|
||||
var input = InputLibrary.look.GetAxisValue(false);
|
||||
_degreesX += input.x * 180f * Time.fixedDeltaTime;
|
||||
_degreesY += input.y * 180f * Time.fixedDeltaTime;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace QSB.ItemSync
|
||||
{
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
DebugLog.DebugWrite("Rebuilding OWItems...", MessageType.Warning);
|
||||
DebugLog.DebugWrite("Rebuilding OWItems...", MessageType.Info);
|
||||
QSBWorldSync.Init<QSBScrollSocket, ScrollSocket>();
|
||||
QSBWorldSync.Init<QSBScrollItem, ScrollItem>();
|
||||
QSBWorldSync.Init<QSBSharedStoneSocket, SharedStoneSocket>();
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Utility;
|
||||
@ -7,19 +8,13 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.ItemSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class ItemPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(ItemTool_MoveItemToCarrySocket));
|
||||
Prefix(nameof(ItemTool_SocketItem));
|
||||
Prefix(nameof(ItemTool_StartUnsocketItem));
|
||||
Prefix(nameof(ItemTool_CompleteUnsocketItem));
|
||||
Prefix(nameof(ItemTool_DropItem));
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.MoveItemToCarrySocket))]
|
||||
public static bool ItemTool_MoveItemToCarrySocket(OWItem item)
|
||||
{
|
||||
var itemId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(item));
|
||||
@ -27,6 +22,8 @@ namespace QSB.ItemSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.SocketItem))]
|
||||
public static bool ItemTool_SocketItem(OWItem ____heldItem, OWItemSocket socket)
|
||||
{
|
||||
var socketId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(socket));
|
||||
@ -35,6 +32,8 @@ namespace QSB.ItemSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.StartUnsocketItem))]
|
||||
public static bool ItemTool_StartUnsocketItem(OWItemSocket socket)
|
||||
{
|
||||
var socketId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(socket));
|
||||
@ -42,6 +41,8 @@ namespace QSB.ItemSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.CompleteUnsocketItem))]
|
||||
public static bool ItemTool_CompleteUnsocketItem(OWItem ____heldItem)
|
||||
{
|
||||
var itemId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
|
||||
@ -49,7 +50,9 @@ namespace QSB.ItemSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ItemTool_DropItem(RaycastHit hit, OWRigidbody targetRigidbody, DetachableFragment detachableFragment, ref OWItem ____heldItem)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ItemTool), nameof(ItemTool.DropItem))]
|
||||
public static bool ItemTool_DropItem(RaycastHit hit, OWRigidbody targetRigidbody, IItemDropTarget customDropTarget, ref OWItem ____heldItem)
|
||||
{
|
||||
Locator.GetPlayerAudioController().PlayDropItem(____heldItem.GetItemType());
|
||||
var hitGameObject = hit.collider.gameObject;
|
||||
@ -65,13 +68,21 @@ namespace QSB.ItemSync.Patches
|
||||
if (sectorGroup != null)
|
||||
{
|
||||
sector = sectorGroup.GetSector();
|
||||
if (sector == null && sectorGroup is SectorCullGroup)
|
||||
{
|
||||
SectorProxy controllingProxy = (sectorGroup as SectorCullGroup).GetControllingProxy();
|
||||
if (controllingProxy != null)
|
||||
{
|
||||
sector = controllingProxy.GetSector();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var parent = (detachableFragment != null)
|
||||
? detachableFragment.transform
|
||||
: targetRigidbody.transform;
|
||||
var parent = (customDropTarget == null)
|
||||
? targetRigidbody.transform
|
||||
: customDropTarget.GetItemDropTargetTransform(hit.collider.gameObject);
|
||||
var objectId = QSBWorldSync.GetIdFromTypeSubset(ItemManager.GetObject(____heldItem));
|
||||
____heldItem.DropItem(hit.point, hit.normal, parent, sector, detachableFragment);
|
||||
____heldItem.DropItem(hit.point, hit.normal, parent, sector, customDropTarget);
|
||||
____heldItem = null;
|
||||
Locator.GetToolModeSwapper().UnequipTool();
|
||||
var parentSector = parent.GetComponentInChildren<Sector>();
|
||||
|
@ -1,12 +1,16 @@
|
||||
using QSB.Events;
|
||||
using HarmonyLib;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.LogSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class LogPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(ShipLogManager), nameof(ShipLogManager.RevealFact))]
|
||||
public static void ShipLogManager_RevealFact(string id, bool saveGame, bool showNotification, bool __result)
|
||||
{
|
||||
if (!__result)
|
||||
@ -16,7 +20,5 @@ namespace QSB.LogSync.Patches
|
||||
|
||||
QSBEventManager.FireEvent(EventNames.QSBRevealFact, id, saveGame, showNotification);
|
||||
}
|
||||
|
||||
public override void DoPatches() => Postfix(nameof(ShipLogManager_RevealFact));
|
||||
}
|
||||
}
|
22
QSB/Menus/IMenuAPI.cs
Normal file
22
QSB/Menus/IMenuAPI.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace QSB.Menus
|
||||
{
|
||||
public interface IMenuAPI
|
||||
{
|
||||
// Title screen
|
||||
GameObject TitleScreen_MakeMenuOpenButton(string name, Menu menuToOpen);
|
||||
GameObject TitleScreen_MakeSceneLoadButton(string name, SubmitActionLoadScene.LoadableScenes sceneToLoad, PopupMenu confirmPopup = null);
|
||||
Button TitleScreen_MakeSimpleButton(string name);
|
||||
// Pause menu
|
||||
GameObject PauseMenu_MakeMenuOpenButton(string name, Menu menuToOpen, Menu customMenu = null);
|
||||
GameObject PauseMenu_MakeSceneLoadButton(string name, SubmitActionLoadScene.LoadableScenes sceneToLoad, PopupMenu confirmPopup = null, Menu customMenu = null);
|
||||
Button PauseMenu_MakeSimpleButton(string name, Menu customMenu = null);
|
||||
Menu PauseMenu_MakePauseListMenu(string title);
|
||||
// Misc
|
||||
PopupMenu MakeTwoChoicePopup(string message, string confirmText, string cancelText);
|
||||
PopupInputMenu MakeInputFieldPopup(string message, string placeholderMessage, string confirmText, string cancelText);
|
||||
PopupMenu MakeInfoPopup(string message, string continueButtonText);
|
||||
}
|
||||
}
|
251
QSB/Menus/MenuManager.cs
Normal file
251
QSB/Menus/MenuManager.cs
Normal file
@ -0,0 +1,251 @@
|
||||
using QSB.Player;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace QSB.Menus
|
||||
{
|
||||
class MenuManager : MonoBehaviour
|
||||
{
|
||||
public static MenuManager Instance;
|
||||
|
||||
private IMenuAPI MenuApi => QSBCore.MenuApi;
|
||||
private PopupMenu PopupMenu;
|
||||
private Button HostButton;
|
||||
private GameObject ClientButton;
|
||||
private Button DisconnectButton;
|
||||
private PopupMenu InfoPopup;
|
||||
private bool _addedPauseLock;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Instance = this;
|
||||
MakeTitleMenus();
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
QSBNetworkManager.Instance.OnClientConnected += OnConnected;
|
||||
QSBNetworkManager.Instance.OnClientDisconnected += OnDisconnected;
|
||||
QSBNetworkManager.Instance.OnClientErrorThrown += OnClientError;
|
||||
}
|
||||
|
||||
void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isUniverse)
|
||||
{
|
||||
if (isUniverse)
|
||||
{
|
||||
InitPauseMenus();
|
||||
return;
|
||||
}
|
||||
|
||||
if (newScene == OWScene.TitleScreen)
|
||||
{
|
||||
MakeTitleMenus();
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenInfoPopup(string message, string buttonText)
|
||||
{
|
||||
InfoPopup.SetUpPopup(message, InputLibrary.menuConfirm, InputLibrary.cancel, new ScreenPrompt(buttonText), null, true, false);
|
||||
|
||||
OWTime.Pause(OWTime.PauseType.System);
|
||||
OWInput.ChangeInputMode(InputMode.Menu);
|
||||
|
||||
var pauseCommandListener = Locator.GetPauseCommandListener();
|
||||
if (pauseCommandListener != null)
|
||||
{
|
||||
pauseCommandListener.AddPauseCommandLock();
|
||||
_addedPauseLock = true;
|
||||
}
|
||||
|
||||
InfoPopup.EnableMenu(true);
|
||||
}
|
||||
|
||||
private void OnCloseInfoPopup()
|
||||
{
|
||||
var pauseCommandListener = Locator.GetPauseCommandListener();
|
||||
if (pauseCommandListener != null && _addedPauseLock)
|
||||
{
|
||||
pauseCommandListener.RemovePauseCommandLock();
|
||||
_addedPauseLock = false;
|
||||
}
|
||||
OWTime.Unpause(OWTime.PauseType.System);
|
||||
OWInput.RestorePreviousInputs();
|
||||
}
|
||||
|
||||
private void CreateCommonPopups()
|
||||
{
|
||||
PopupMenu = MenuApi.MakeInputFieldPopup("IP Address", "IP Address", "Connect", "Cancel");
|
||||
PopupMenu.OnPopupConfirm += Connect;
|
||||
|
||||
InfoPopup = MenuApi.MakeInfoPopup("", "");
|
||||
InfoPopup.OnDeactivateMenu += OnCloseInfoPopup;
|
||||
}
|
||||
|
||||
private void InitPauseMenus()
|
||||
{
|
||||
CreateCommonPopups();
|
||||
|
||||
HostButton = MenuApi.PauseMenu_MakeSimpleButton("MULTIPLAYER (HOST)");
|
||||
HostButton.onClick.AddListener(Host);
|
||||
|
||||
ClientButton = MenuApi.PauseMenu_MakeMenuOpenButton("MULTIPLAYER (CONNECT)", PopupMenu);
|
||||
|
||||
DisconnectButton = MenuApi.PauseMenu_MakeSimpleButton("DISCONNECT");
|
||||
DisconnectButton.onClick.AddListener(Disconnect);
|
||||
|
||||
|
||||
if (QSBCore.IsInMultiplayer)
|
||||
{
|
||||
ClientButton.SetActive(false);
|
||||
HostButton.gameObject.SetActive(false);
|
||||
DisconnectButton.gameObject.SetActive(true);
|
||||
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisconnectButton.gameObject.SetActive(false);
|
||||
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
|
||||
}
|
||||
|
||||
OnConnected();
|
||||
}
|
||||
|
||||
private void MakeTitleMenus()
|
||||
{
|
||||
CreateCommonPopups();
|
||||
|
||||
HostButton = MenuApi.TitleScreen_MakeSimpleButton("MULTIPLAYER (HOST)");
|
||||
HostButton.onClick.AddListener(Host);
|
||||
|
||||
ClientButton = MenuApi.TitleScreen_MakeMenuOpenButton("MULTIPLAYER (CONNECT)", PopupMenu);
|
||||
|
||||
DisconnectButton = MenuApi.TitleScreen_MakeSimpleButton("DISCONNECT");
|
||||
DisconnectButton.onClick.AddListener(Disconnect);
|
||||
|
||||
if (QSBCore.IsInMultiplayer)
|
||||
{
|
||||
ClientButton.SetActive(false);
|
||||
HostButton.gameObject.SetActive(false);
|
||||
DisconnectButton.gameObject.SetActive(true);
|
||||
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisconnectButton.gameObject.SetActive(false);
|
||||
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
|
||||
}
|
||||
|
||||
OnConnected();
|
||||
}
|
||||
|
||||
private void Disconnect()
|
||||
{
|
||||
QSBNetworkManager.Instance.StopHost();
|
||||
DisconnectButton.gameObject.SetActive(false);
|
||||
ClientButton.SetActive(true);
|
||||
HostButton.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
private void Host()
|
||||
{
|
||||
QSBNetworkManager.Instance.StartHost();
|
||||
DisconnectButton.gameObject.SetActive(true);
|
||||
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
|
||||
ClientButton.SetActive(false);
|
||||
HostButton.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void Connect()
|
||||
{
|
||||
QSBNetworkManager.Instance.networkAddress = (PopupMenu as PopupInputMenu).GetInputText();
|
||||
QSBNetworkManager.Instance.StartClient();
|
||||
DisconnectButton.transform.GetChild(0).GetChild(1).GetComponent<Text>().text = "CONNECTING... (STOP)";
|
||||
DisconnectButton.gameObject.SetActive(true);
|
||||
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
|
||||
ClientButton.SetActive(false);
|
||||
HostButton.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void OnConnected()
|
||||
{
|
||||
var text = QSBCore.IsHost
|
||||
? "STOP HOSTING"
|
||||
: "DISCONNECT";
|
||||
DisconnectButton.transform.GetChild(0).GetChild(1).GetComponent<Text>().text = text;
|
||||
}
|
||||
|
||||
public void OnKicked(KickReason reason)
|
||||
{
|
||||
string text;
|
||||
switch (reason)
|
||||
{
|
||||
case KickReason.QSBVersionNotMatching:
|
||||
text = "Server refused connection as QSB version does not match.";
|
||||
break;
|
||||
case KickReason.GameVersionNotMatching:
|
||||
text = "Server refused connection as Outer Wilds version does not match.";
|
||||
break;
|
||||
case KickReason.None:
|
||||
text = "Kicked from server. No reason given.";
|
||||
break;
|
||||
default:
|
||||
text = $"Kicked from server. KickReason:{reason}";
|
||||
break;
|
||||
}
|
||||
|
||||
OpenInfoPopup(text, "OK");
|
||||
|
||||
DisconnectButton.gameObject.SetActive(false);
|
||||
ClientButton.SetActive(true);
|
||||
HostButton.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
private void OnDisconnected(NetworkError error)
|
||||
{
|
||||
if (error == NetworkError.Ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string text;
|
||||
switch (error)
|
||||
{
|
||||
case NetworkError.Timeout:
|
||||
text = "Client disconnected with error!\r\nConnection timed out.";
|
||||
break;
|
||||
default:
|
||||
text = $"Client disconnected with error!\r\nNetworkError:{error}";
|
||||
break;
|
||||
}
|
||||
|
||||
OpenInfoPopup(text, "OK");
|
||||
|
||||
DisconnectButton.gameObject.SetActive(false);
|
||||
ClientButton.SetActive(true);
|
||||
HostButton.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
private void OnClientError(NetworkError error)
|
||||
{
|
||||
if (error == NetworkError.Ok)
|
||||
{
|
||||
// lol wut
|
||||
return;
|
||||
}
|
||||
|
||||
string text;
|
||||
switch (error)
|
||||
{
|
||||
case NetworkError.DNSFailure:
|
||||
text = "Internal QNet client error!\r\nDNS Faliure. Address was invalid or could not be resolved.";
|
||||
DisconnectButton.gameObject.SetActive(false);
|
||||
ClientButton.SetActive(true);
|
||||
HostButton.gameObject.SetActive(true);
|
||||
break;
|
||||
default:
|
||||
text = $"Internal QNet client error!\n\nNetworkError:{error}";
|
||||
break;
|
||||
}
|
||||
|
||||
OpenInfoPopup(text, "OK");
|
||||
}
|
||||
}
|
||||
}
|
@ -84,9 +84,17 @@ namespace QSB.OrbSync.Events
|
||||
return;
|
||||
}
|
||||
|
||||
if (orbIdentity.ClientAuthorityOwner != null && orbIdentity.ClientAuthorityOwner != fromPlayer)
|
||||
var currentOwner = orbIdentity.ClientAuthorityOwner;
|
||||
var newOwner = fromPlayer;
|
||||
|
||||
if (currentOwner == newOwner)
|
||||
{
|
||||
orbIdentity.RemoveClientAuthority(orbIdentity.ClientAuthorityOwner);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentOwner != null && currentOwner != fromPlayer)
|
||||
{
|
||||
orbIdentity.RemoveClientAuthority(currentOwner);
|
||||
}
|
||||
|
||||
orbIdentity.AssignClientAuthority(fromPlayer);
|
||||
|
@ -26,7 +26,10 @@ namespace QSB.OrbSync
|
||||
{
|
||||
NomaiOrbTransformSync.OrbTransformSyncs.ForEach(x => QNetworkServer.Destroy(x.gameObject));
|
||||
NomaiOrbTransformSync.OrbTransformSyncs.Clear();
|
||||
QSBWorldSync.OldOrbList.ForEach(x => QNetworkServer.Spawn(Instantiate(QSBNetworkManager.Instance.OrbPrefab)));
|
||||
foreach (var orb in QSBWorldSync.OldOrbList)
|
||||
{
|
||||
Instantiate(QSBNetworkManager.Instance.OrbPrefab).SpawnWithServerAuthority();
|
||||
}
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"Finished orb build with {QSBWorldSync.OldOrbList.Count} orbs.", MessageType.Success);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using QSB.Events;
|
||||
using HarmonyLib;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
@ -6,10 +7,13 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.OrbSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class OrbPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(NomaiInterfaceOrb), nameof(NomaiInterfaceOrb.StartDragFromPosition))]
|
||||
public static void NomaiInterfaceOrb_StartDragFromPosition(bool __result, NomaiInterfaceOrb __instance)
|
||||
{
|
||||
if (__result)
|
||||
@ -18,6 +22,8 @@ namespace QSB.OrbSync.Patches
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiInterfaceSlot), nameof(NomaiInterfaceSlot.CheckOrbCollision))]
|
||||
public static bool NomaiInterfaceSlot_CheckOrbCollision(ref bool __result, NomaiInterfaceSlot __instance, NomaiInterfaceOrb orb,
|
||||
bool ____ignoreDraggedOrbs, float ____radius, float ____exitRadius, ref NomaiInterfaceOrb ____occupyingOrb)
|
||||
{
|
||||
@ -60,11 +66,5 @@ namespace QSB.OrbSync.Patches
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Postfix(nameof(NomaiInterfaceOrb_StartDragFromPosition));
|
||||
Prefix(nameof(NomaiInterfaceSlot_CheckOrbCollision));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using QSB.Syncs.TransformSync;
|
||||
using QSB.Syncs.Unsectored.Transforms;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
@ -6,7 +6,7 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.OrbSync.TransformSync
|
||||
{
|
||||
internal class NomaiOrbTransformSync : UnparentedBaseTransformSync
|
||||
internal class NomaiOrbTransformSync : UnsectoredTransformSync
|
||||
{
|
||||
public static List<NomaiOrbTransformSync> OrbTransformSyncs = new List<NomaiOrbTransformSync>();
|
||||
|
||||
@ -17,7 +17,7 @@ namespace QSB.OrbSync.TransformSync
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
OrbTransformSyncs.Remove(this);
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
@ -59,6 +59,7 @@ namespace QSB.OrbSync.TransformSync
|
||||
protected override Component InitLocalTransform() => GetTransform();
|
||||
protected override Component InitRemoteTransform() => GetTransform();
|
||||
|
||||
protected override float DistanceLeeway => 1f;
|
||||
public override bool IsReady => QSBCore.WorldObjectsReady;
|
||||
public override bool UseInterpolation => false;
|
||||
}
|
||||
|
@ -1,119 +1,14 @@
|
||||
using Harmony;
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace QSB.Patches
|
||||
{
|
||||
public abstract class QSBPatch
|
||||
{
|
||||
public abstract QSBPatchTypes Type { get; }
|
||||
public abstract void DoPatches();
|
||||
|
||||
public void DoUnpatches()
|
||||
public void DoPatches(Harmony instance)
|
||||
{
|
||||
foreach (var item in _patchedMethods)
|
||||
{
|
||||
//DebugLog.DebugWrite($"[Unpatch] {item.DeclaringType}.{item.Name}", MessageType.Info);
|
||||
Unpatch(item);
|
||||
}
|
||||
|
||||
_patchedMethods.Clear();
|
||||
}
|
||||
|
||||
private List<MethodInfo> _patchedMethods = new List<MethodInfo>();
|
||||
|
||||
public void Empty(string patchName)
|
||||
{
|
||||
//DebugLog.DebugWrite($"[Empty] {patchName}", MessageType.Success);
|
||||
var method = GetMethodInfo(patchName);
|
||||
QSBCore.Helper.HarmonyHelper.EmptyMethod(method);
|
||||
_patchedMethods.Add(method);
|
||||
}
|
||||
|
||||
public void Prefix(string patchName)
|
||||
=> DoPrefixPostfix(true, patchName);
|
||||
|
||||
public void Postfix(string patchName)
|
||||
=> DoPrefixPostfix(false, patchName);
|
||||
|
||||
private void DoPrefixPostfix(bool isPrefix, string patchName)
|
||||
{
|
||||
var method = GetMethodInfo(patchName);
|
||||
|
||||
if (method != null)
|
||||
{
|
||||
if (isPrefix)
|
||||
{
|
||||
QSBCore.Helper.HarmonyHelper.AddPrefix(method, GetType(), patchName);
|
||||
}
|
||||
else
|
||||
{
|
||||
QSBCore.Helper.HarmonyHelper.AddPostfix(method, GetType(), patchName);
|
||||
}
|
||||
|
||||
_patchedMethods.Add(method);
|
||||
}
|
||||
|
||||
//DebugLog.DebugWrite($"{(isPrefix ? "[Prefix]" : "[Postfix]")} {patchName}", method == null ? MessageType.Error : MessageType.Success);
|
||||
}
|
||||
|
||||
private MethodInfo GetMethodInfo(string patchName)
|
||||
{
|
||||
var splitName = patchName.Split('_');
|
||||
var typeName = splitName[0];
|
||||
var methodName = splitName[1];
|
||||
|
||||
var type = GetFirstTypeByName(typeName);
|
||||
if (type == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Couldn't find type for patch name {patchName}!", MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
|
||||
var method = type.GetAnyMethod(methodName);
|
||||
if (method == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Couldn't find method for patch name {patchName}!", MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
private Type GetFirstTypeByName(string typeName)
|
||||
{
|
||||
var a = typeof(OWRigidbody).Assembly;
|
||||
var assemblyTypes = a.GetTypes();
|
||||
for (var j = 0; j < assemblyTypes.Length; j++)
|
||||
{
|
||||
if (assemblyTypes[j].Name == typeName)
|
||||
{
|
||||
return assemblyTypes[j];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void Unpatch(MethodInfo method)
|
||||
{
|
||||
var dictionary = typeof(HarmonySharedState).Invoke<Dictionary<MethodBase, byte[]>>("GetState", new object[0]);
|
||||
var methodBase = dictionary.Keys.First(m =>
|
||||
m.DeclaringType == method.DeclaringType
|
||||
&& m.Name == method.Name);
|
||||
|
||||
var patchInfo = PatchInfoSerialization.Deserialize(dictionary.GetValueSafe(methodBase));
|
||||
patchInfo.RemovePostfix(QSBCore.Helper.Manifest.UniqueName);
|
||||
patchInfo.RemovePrefix(QSBCore.Helper.Manifest.UniqueName);
|
||||
patchInfo.RemoveTranspiler(QSBCore.Helper.Manifest.UniqueName);
|
||||
|
||||
PatchFunctions.UpdateWrapper(methodBase, patchInfo, QSBCore.Helper.Manifest.UniqueName);
|
||||
dictionary[methodBase] = patchInfo.Serialize();
|
||||
instance.PatchAll(GetType());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
using OWML.Common;
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.NPC.Patches;
|
||||
using QSB.Animation.Patches;
|
||||
using QSB.CampfireSync.Patches;
|
||||
@ -34,6 +36,8 @@ namespace QSB.Patches
|
||||
|
||||
private static List<QSBPatch> _patchList = new List<QSBPatch>();
|
||||
|
||||
public static Dictionary<QSBPatchTypes, Harmony> TypeToInstance = new Dictionary<QSBPatchTypes, Harmony>();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
_patchList = new List<QSBPatch>
|
||||
@ -66,6 +70,14 @@ namespace QSB.Patches
|
||||
new LauncherPatches()
|
||||
};
|
||||
|
||||
TypeToInstance = new Dictionary<QSBPatchTypes, Harmony>
|
||||
{
|
||||
{ QSBPatchTypes.OnClientConnect, new Harmony("QSB.Client") },
|
||||
{ QSBPatchTypes.OnServerClientConnect, new Harmony("QSB.Server") },
|
||||
{ QSBPatchTypes.OnNonServerClientConnect, new Harmony("QSB.NonServer") },
|
||||
{ QSBPatchTypes.RespawnTime, new Harmony("QSB.Death") }
|
||||
};
|
||||
|
||||
DebugLog.DebugWrite("Patch Manager ready.", MessageType.Success);
|
||||
}
|
||||
|
||||
@ -76,7 +88,14 @@ namespace QSB.Patches
|
||||
foreach (var patch in _patchList.Where(x => x.Type == type))
|
||||
{
|
||||
//DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info);
|
||||
patch.DoPatches();
|
||||
try
|
||||
{
|
||||
patch.DoPatches(TypeToInstance[type]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error while patching {patch.GetType().Name} :\r\n{ex}", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,11 +103,7 @@ namespace QSB.Patches
|
||||
{
|
||||
OnUnpatchType?.SafeInvoke(type);
|
||||
//DebugLog.DebugWrite($"Unpatch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info);
|
||||
foreach (var patch in _patchList.Where(x => x.Type == type))
|
||||
{
|
||||
//DebugLog.DebugWrite($" - Unpatching in {patch.GetType().Name}", MessageType.Info);
|
||||
patch.DoUnpatches();
|
||||
}
|
||||
TypeToInstance[type].UnpatchSelf();
|
||||
}
|
||||
}
|
||||
}
|
@ -49,7 +49,6 @@ namespace QSB.Player.Events
|
||||
public override void OnReceiveRemote(bool server, EnumWorldObjectMessage<EnterLeaveType> message)
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(message.FromId);
|
||||
DebugLog.DebugWrite($"{message.FromId} {message.EnumValue}", OWML.Common.MessageType.Info);
|
||||
switch (message.EnumValue)
|
||||
{
|
||||
case EnterLeaveType.EnterMoon:
|
||||
|
@ -17,22 +17,38 @@ namespace QSB.Player.Events
|
||||
{
|
||||
AboutId = LocalPlayerId,
|
||||
PlayerName = name,
|
||||
QSBVersion = QSBCore.QSBVersion
|
||||
QSBVersion = QSBCore.QSBVersion,
|
||||
GameVersion = QSBCore.GameVersion
|
||||
};
|
||||
|
||||
public override void OnReceiveRemote(bool server, PlayerJoinMessage message)
|
||||
{
|
||||
if (server && (message.QSBVersion != QSBCore.QSBVersion))
|
||||
if (message.QSBVersion != QSBCore.QSBVersion)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Client {message.PlayerName} connecting with wrong version. (Client:{message.QSBVersion}, Server:{QSBCore.QSBVersion})", MessageType.Error);
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerKick, message.AboutId, KickReason.VersionNotMatching);
|
||||
if (server)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Client {message.PlayerName} connecting with wrong QSB version. (Client:{message.QSBVersion}, Server:{QSBCore.QSBVersion})", MessageType.Error);
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerKick, message.AboutId, KickReason.QSBVersionNotMatching);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.GameVersion != QSBCore.GameVersion)
|
||||
{
|
||||
if (server)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Client {message.PlayerName} connecting with wrong game version. (Client:{message.GameVersion}, Server:{QSBCore.GameVersion})", MessageType.Error);
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerKick, message.AboutId, KickReason.GameVersionNotMatching);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
player.Name = message.PlayerName;
|
||||
DebugLog.ToAll($"{player.Name} joined!", MessageType.Info);
|
||||
DebugLog.DebugWrite($"{player.Name} joined as id {player.PlayerId}", MessageType.Info);
|
||||
DebugLog.DebugWrite($"{player.Name} joined. id:{player.PlayerId}, qsbVersion:{message.QSBVersion}, gameVersion:{message.GameVersion}", MessageType.Info);
|
||||
}
|
||||
|
||||
public override void OnReceiveLocal(bool server, PlayerJoinMessage message)
|
||||
|
@ -7,12 +7,14 @@ namespace QSB.Player.Events
|
||||
{
|
||||
public string PlayerName { get; set; }
|
||||
public string QSBVersion { get; set; }
|
||||
public string GameVersion { get; set; }
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
PlayerName = reader.ReadString();
|
||||
QSBVersion = reader.ReadString();
|
||||
GameVersion = reader.ReadString();
|
||||
}
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
@ -20,6 +22,7 @@ namespace QSB.Player.Events
|
||||
base.Serialize(writer);
|
||||
writer.Write(PlayerName);
|
||||
writer.Write(QSBVersion);
|
||||
writer.Write(GameVersion);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using QSB.Events;
|
||||
using QSB.Menus;
|
||||
using QSB.Messaging;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET;
|
||||
@ -49,6 +50,7 @@ namespace QSB.Player.Events
|
||||
}
|
||||
|
||||
DebugLog.ToAll($"Kicked from server. Reason : {message.EnumValue}");
|
||||
MenuManager.Instance.OnKicked(message.EnumValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,7 @@ namespace QSB.Player.Events
|
||||
public override void SetupListener() => GlobalMessenger.AddListener(EventNames.QSBRequestStateResync, Handler);
|
||||
public override void CloseListener() => GlobalMessenger.RemoveListener(EventNames.QSBRequestStateResync, Handler);
|
||||
|
||||
private void Handler()
|
||||
{
|
||||
DebugLog.DebugWrite($"Sending QSBRequestStateResync");
|
||||
SendEvent(CreateMessage());
|
||||
}
|
||||
private void Handler() => SendEvent(CreateMessage());
|
||||
|
||||
private PlayerMessage CreateMessage() => new PlayerMessage
|
||||
{
|
||||
@ -33,16 +29,11 @@ namespace QSB.Player.Events
|
||||
|
||||
public override void OnReceiveRemote(bool isHost, PlayerMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"OnReceiveRemote RequestStateResyncEvent");
|
||||
|
||||
// if host, send worldobject and server states
|
||||
|
||||
if (isHost)
|
||||
{
|
||||
DebugLog.DebugWrite($"SENDING SERVER STATE");
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerStateManager.Instance.GetServerState());
|
||||
|
||||
DebugLog.DebugWrite($"SENDING PLAYER INFORMATION");
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation);
|
||||
|
||||
SendWorldObjectInfo();
|
||||
@ -51,15 +42,11 @@ namespace QSB.Player.Events
|
||||
}
|
||||
|
||||
// if client, send player and client states
|
||||
|
||||
DebugLog.DebugWrite($"SENDING PLAYER INFORMATION");
|
||||
QSBEventManager.FireEvent(EventNames.QSBPlayerInformation);
|
||||
}
|
||||
|
||||
private void SendWorldObjectInfo()
|
||||
{
|
||||
DebugLog.DebugWrite($"SENDING WORLDOBJECT INFORMATION");
|
||||
|
||||
QSBWorldSync.DialogueConditions.ForEach(condition
|
||||
=> QSBEventManager.FireEvent(EventNames.DialogueCondition, condition.Key, condition.Value));
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
{
|
||||
public enum KickReason
|
||||
{
|
||||
VersionNotMatching
|
||||
None,
|
||||
QSBVersionNotMatching,
|
||||
GameVersionNotMatching
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,15 @@
|
||||
using QSB.Patches;
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.Player.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class PlayerPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(PlayerCrushedController_CrushPlayer));
|
||||
Prefix(nameof(PauseMenuManager_OnExitToMainMenu));
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerCrushedController), nameof(PlayerCrushedController.CrushPlayer))]
|
||||
public static bool PlayerCrushedController_CrushPlayer()
|
||||
{
|
||||
// #CrushIt https://www.twitch.tv/videos/846916781?t=00h03m51s
|
||||
@ -20,6 +18,9 @@ namespace QSB.Player.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void PauseMenuManager_OnExitToMainMenu() => QSBPlayerManager.LocalPlayer.PlayerStates.IsReady = false;
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PauseMenuManager), nameof(PauseMenuManager.OnExitToMainMenu))]
|
||||
public static void PauseMenuManager_OnExitToMainMenu()
|
||||
=> QSBPlayerManager.LocalPlayer.PlayerStates.IsReady = false;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace QSB.Player
|
||||
private bool _needsInitializing;
|
||||
private bool _isReady;
|
||||
|
||||
protected override void InitCanvasMarker()
|
||||
public override void InitCanvasMarker()
|
||||
{
|
||||
_markerRadius = 2f;
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace QSB.Player
|
||||
// Tools
|
||||
public GameObject ProbeBody { get; set; }
|
||||
public QSBProbe Probe { get; set; }
|
||||
public QSBFlashlight FlashLight
|
||||
public QSBFlashlight FlashLight
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -66,8 +66,8 @@ namespace QSB.Player
|
||||
public JetpackAccelerationSync JetpackAcceleration { get; set; }
|
||||
|
||||
// Misc
|
||||
public bool IsInMoon; // TODO : move into PlayerStates?
|
||||
public bool IsInShrine; // TODO : move into PlayerStates?
|
||||
public bool IsInMoon; // MOVE : move into PlayerStates?
|
||||
public bool IsInShrine; // MOVE : move into PlayerStates?
|
||||
public IQSBQuantumObject EntangledObject;
|
||||
public bool IsDead { get; set; }
|
||||
public ClientState State { get; set; }
|
||||
@ -87,7 +87,7 @@ namespace QSB.Player
|
||||
}
|
||||
}
|
||||
|
||||
public Flashlight LocalFlashlight
|
||||
public Flashlight LocalFlashlight
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -129,7 +129,6 @@ namespace QSB.Player
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public PlayerInfo(uint id)
|
||||
{
|
||||
PlayerId = id;
|
||||
|
@ -35,6 +35,7 @@ namespace QSB.Player
|
||||
}
|
||||
|
||||
public static Action<uint> OnRemovePlayer;
|
||||
public static Action<uint> OnAddPlayer;
|
||||
|
||||
public static PlayerInfo LocalPlayer => GetPlayer(LocalPlayerId);
|
||||
public static List<PlayerInfo> PlayerList { get; } = new List<PlayerInfo>();
|
||||
@ -43,12 +44,6 @@ namespace QSB.Player
|
||||
|
||||
public static PlayerInfo GetPlayer(uint id)
|
||||
{
|
||||
if (!QSBNetworkManager.Instance.IsReady)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - GetPlayer() (id<{id}>) called when Network Manager not ready! Is a Player Sync Object still active? " +
|
||||
$"{Environment.NewLine} Stacktrace :\r\n{Environment.StackTrace}", MessageType.Warning);
|
||||
}
|
||||
|
||||
if (id == uint.MaxValue || id == 0U)
|
||||
{
|
||||
return default;
|
||||
@ -69,6 +64,7 @@ namespace QSB.Player
|
||||
DebugLog.DebugWrite($"Create Player : id<{id}> Stacktrace :\r\n{Environment.StackTrace}", MessageType.Info);
|
||||
player = new PlayerInfo(id);
|
||||
PlayerList.Add(player);
|
||||
OnAddPlayer?.Invoke(id);
|
||||
return player;
|
||||
}
|
||||
|
||||
@ -83,7 +79,6 @@ namespace QSB.Player
|
||||
|
||||
public static void HandleFullStateMessage(PlayerInformationMessage message)
|
||||
{
|
||||
DebugLog.DebugWrite($"Handle full state message of {message.AboutId}");
|
||||
var player = GetPlayer(message.AboutId);
|
||||
player.Name = message.PlayerName;
|
||||
player.PlayerStates = message.PlayerState;
|
||||
@ -91,6 +86,7 @@ namespace QSB.Player
|
||||
{
|
||||
player.UpdateStateObjects();
|
||||
}
|
||||
|
||||
player.State = message.ClientState;
|
||||
}
|
||||
|
||||
@ -116,6 +112,16 @@ namespace QSB.Player
|
||||
{
|
||||
cameraList.Add(LocalPlayer);
|
||||
}
|
||||
else if (includeLocalCamera && (LocalPlayer == default || LocalPlayer.Camera == null))
|
||||
{
|
||||
if (LocalPlayer == default)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - LocalPlayer is null.", MessageType.Error);
|
||||
return cameraList;
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"Error - LocalPlayer.Camera is null.", MessageType.Error);
|
||||
}
|
||||
|
||||
return cameraList;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ using QSB.Events;
|
||||
using QSB.Instruments;
|
||||
using QSB.RoastingSync;
|
||||
using QSB.SectorSync;
|
||||
using QSB.Syncs.TransformSync;
|
||||
using QSB.Syncs.Sectored.Transforms;
|
||||
using QSB.Tools;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
@ -86,7 +86,7 @@ namespace QSB.Player.TransformSync
|
||||
|
||||
protected override Component InitLocalTransform()
|
||||
{
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetPlayerSectorDetector(), this));
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetPlayerSectorDetector(), TargetType.Player));
|
||||
|
||||
// player body
|
||||
var player = Locator.GetPlayerTransform();
|
||||
@ -108,7 +108,6 @@ namespace QSB.Player.TransformSync
|
||||
_visibleStickPivot = pivot;
|
||||
_visibleStickTip = pivot.Find("Stick_Tip");
|
||||
|
||||
DebugLog.DebugWrite("PlayerTransformSync init done - Request state!");
|
||||
QSBEventManager.FireEvent(EventNames.QSBRequestStateResync);
|
||||
|
||||
return player;
|
||||
@ -275,7 +274,5 @@ namespace QSB.Player.TransformSync
|
||||
public static PlayerTransformSync LocalInstance { get; private set; }
|
||||
|
||||
public override bool UseInterpolation => true;
|
||||
|
||||
public override TargetType Type => TargetType.Player;
|
||||
}
|
||||
}
|
@ -360,7 +360,8 @@ namespace QSB.PoolSync
|
||||
continue;
|
||||
}
|
||||
|
||||
var hologram = item.Value.transform.GetChild(0);
|
||||
//var hologram = item.Value.transform.GetChild(0);
|
||||
var hologram = item.Value.transform;
|
||||
hologram.position = TransformPoint(item.Key.Body.transform.position, this, _slavePlatform);
|
||||
hologram.rotation = TransformRotation(item.Key.Body.transform.rotation, this, _slavePlatform);
|
||||
}
|
||||
@ -719,7 +720,7 @@ namespace QSB.PoolSync
|
||||
hologramCopy.GetChild(0).Find("player_mesh_noSuit:Traveller_HEA_Player/player_mesh_noSuit:Player_Head").gameObject.layer = 0;
|
||||
hologramCopy.GetChild(0).Find("Traveller_Mesh_v01:Traveller_Geo/Traveller_Mesh_v01:PlayerSuit_Helmet").gameObject.layer = 0;
|
||||
|
||||
// TODO : Look at this again... probably need to sync head rotation to something else
|
||||
// BUG : Look at this again... probably need to sync head rotation to something else
|
||||
//var ikSync = hologramCopy.GetChild(0).gameObject.AddComponent<PlayerHeadRotationSync>();
|
||||
//ikSync.Init(player.CameraBody.transform);
|
||||
|
||||
|
@ -13,7 +13,7 @@ namespace QSB.PoolSync
|
||||
private NomaiRemoteCameraStreaming _oldStreaming;
|
||||
private bool _hasLoadedAssets;
|
||||
|
||||
protected override void Awake()
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_oldStreaming = GetComponent<NomaiRemoteCameraStreaming>();
|
||||
@ -48,7 +48,7 @@ namespace QSB.PoolSync
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnSectorOccupantAdded(SectorDetector sectorDetector)
|
||||
public override void OnSectorOccupantAdded(SectorDetector sectorDetector)
|
||||
{
|
||||
if (sectorDetector.GetOccupantType() == DynamicOccupant.Player && StreamingManager.isStreamingEnabled)
|
||||
{
|
||||
@ -56,7 +56,7 @@ namespace QSB.PoolSync
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnSectorOccupantRemoved(SectorDetector sectorDetector)
|
||||
public override void OnSectorOccupantRemoved(SectorDetector sectorDetector)
|
||||
{
|
||||
if (sectorDetector.GetOccupantType() == DynamicOccupant.Player)
|
||||
{
|
||||
|
@ -1,34 +1,51 @@
|
||||
using QSB.Patches;
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.PoolSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class PoolPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(NomaiRemoteCameraPlatform_Awake));
|
||||
Prefix(nameof(NomaiRemoteCameraPlatform_Update));
|
||||
Prefix(nameof(NomaiRemoteCameraPlatform_OnSocketableRemoved));
|
||||
Prefix(nameof(NomaiRemoteCameraPlatform_OnSocketableDonePlacing));
|
||||
Prefix(nameof(NomaiRemoteCameraPlatform_OnPedestalContact));
|
||||
Prefix(nameof(NomaiRemoteCameraStreaming_FixedUpdate));
|
||||
Prefix(nameof(NomaiRemoteCameraStreaming_OnSectorOccupantAdded));
|
||||
Prefix(nameof(NomaiRemoteCameraStreaming_OnSectorOccupantRemoved));
|
||||
Prefix(nameof(NomaiRemoteCameraStreaming_OnEntry));
|
||||
Prefix(nameof(NomaiRemoteCameraStreaming_OnExit));
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraPlatform), nameof(NomaiRemoteCameraPlatform.Awake))]
|
||||
public static bool NomaiRemoteCameraPlatform_Awake() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraPlatform), nameof(NomaiRemoteCameraPlatform.Update))]
|
||||
public static bool NomaiRemoteCameraPlatform_Update() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraPlatform), nameof(NomaiRemoteCameraPlatform.OnSocketableRemoved))]
|
||||
public static bool NomaiRemoteCameraPlatform_OnSocketableRemoved() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraPlatform), nameof(NomaiRemoteCameraPlatform.OnSocketableDonePlacing))]
|
||||
public static bool NomaiRemoteCameraPlatform_OnSocketableDonePlacing() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraPlatform), nameof(NomaiRemoteCameraPlatform.OnPedestalContact))]
|
||||
public static bool NomaiRemoteCameraPlatform_OnPedestalContact() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraStreaming), nameof(NomaiRemoteCameraStreaming.FixedUpdate))]
|
||||
public static bool NomaiRemoteCameraStreaming_FixedUpdate() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraStreaming), nameof(NomaiRemoteCameraStreaming.OnSectorOccupantAdded))]
|
||||
public static bool NomaiRemoteCameraStreaming_OnSectorOccupantAdded() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraStreaming), nameof(NomaiRemoteCameraStreaming.OnSectorOccupantRemoved))]
|
||||
public static bool NomaiRemoteCameraStreaming_OnSectorOccupantRemoved() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraStreaming), nameof(NomaiRemoteCameraStreaming.OnEntry))]
|
||||
public static bool NomaiRemoteCameraStreaming_OnEntry() => false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(NomaiRemoteCameraStreaming), nameof(NomaiRemoteCameraStreaming.OnExit))]
|
||||
public static bool NomaiRemoteCameraStreaming_OnExit() => false;
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,11 @@ namespace QSB.ProbeSync.Events
|
||||
public override void OnReceiveRemote(bool server, EnumMessage<ProbeEvent> message)
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
if (!player.PlayerStates.IsReady || player.Probe == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var probe = player.Probe;
|
||||
|
||||
probe.HandleEvent(message.EnumValue);
|
||||
|
@ -25,6 +25,11 @@ namespace QSB.ProbeSync.Events
|
||||
public override void OnReceiveRemote(bool server, FloatMessage message)
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(message.AboutId);
|
||||
if (!player.PlayerStates.IsReady || player.Probe == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var probe = player.Probe;
|
||||
probe.OnStartRetrieve(message.Value);
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ namespace QSB.ProbeSync
|
||||
public OWAudioSource _flightLoopAudio;
|
||||
public OWAudioSource _anchorAudio;
|
||||
public ParticleSystem _anchorParticles;
|
||||
public ParticleSystem _underwaterAnchorParticles;
|
||||
|
||||
private QSBProbe _probe;
|
||||
|
||||
|
@ -12,7 +12,6 @@ namespace QSB.ProbeSync
|
||||
|
||||
private QSBProbe _probe;
|
||||
private OWLight2 _light;
|
||||
private bool _inFlight;
|
||||
private float _timer;
|
||||
|
||||
private void Awake()
|
||||
@ -64,15 +63,12 @@ namespace QSB.ProbeSync
|
||||
{
|
||||
StartFadeIn();
|
||||
}
|
||||
|
||||
_inFlight = true;
|
||||
}
|
||||
|
||||
private void OnAnchorOrRetrieve()
|
||||
{
|
||||
_light.GetLight().enabled = false;
|
||||
enabled = false;
|
||||
_inFlight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.SectorSync;
|
||||
using QSB.Syncs.TransformSync;
|
||||
using QSB.Syncs.Sectored.Transforms;
|
||||
using QSB.Tools;
|
||||
using QSB.Tools.ProbeLauncherTool;
|
||||
using QSB.Utility;
|
||||
@ -14,7 +14,6 @@ namespace QSB.ProbeSync.TransformSync
|
||||
{
|
||||
protected override float DistanceLeeway => 10f;
|
||||
public override bool UseInterpolation => true;
|
||||
public override TargetType Type => TargetType.Probe;
|
||||
public override bool IgnoreDisabledAttachedObject => true;
|
||||
|
||||
public static PlayerProbeSync LocalInstance { get; private set; }
|
||||
@ -23,7 +22,7 @@ namespace QSB.ProbeSync.TransformSync
|
||||
|
||||
protected override Component InitLocalTransform()
|
||||
{
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetProbe().GetSectorDetector(), this));
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetProbe().GetSectorDetector(), TargetType.Probe));
|
||||
|
||||
var body = Locator.GetProbe().transform;
|
||||
Player.ProbeBody = body.gameObject;
|
||||
@ -53,8 +52,8 @@ namespace QSB.ProbeSync.TransformSync
|
||||
return default;
|
||||
}
|
||||
|
||||
var body = probe.gameObject.activeSelf
|
||||
? probe.InstantiateInactive()
|
||||
var body = probe.gameObject.activeSelf
|
||||
? probe.InstantiateInactive()
|
||||
: Instantiate(probe);
|
||||
|
||||
body.name = "RemoteProbeTransform";
|
||||
@ -89,8 +88,16 @@ namespace QSB.ProbeSync.TransformSync
|
||||
probeOWRigidbody.SetPosition(launcherTransform.position);
|
||||
probeOWRigidbody.SetRotation(launcherTransform.rotation);
|
||||
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
if (ReferenceTransform != null)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
_intermediaryTransform.SetPosition(Vector3.zero);
|
||||
_intermediaryTransform.SetRotation(Quaternion.identity);
|
||||
}
|
||||
|
||||
var currentReferenceSector = ReferenceSector;
|
||||
var playerReferenceSector = Player.TransformSync.ReferenceSector;
|
||||
|
183
QSB/QSB.csproj
183
QSB/QSB.csproj
@ -9,9 +9,10 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>QSB</RootNamespace>
|
||||
<AssemblyName>QSB</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@ -21,6 +22,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@ -33,77 +35,6 @@
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\Assembly-CSharp.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="UnityEngine, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.AnimationModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.AudioModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Networking">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.Networking.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.UI.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.UIModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UNETModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.UNETModule.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Animation\NPC\AnimationEvent.cs" />
|
||||
<Compile Include="Animation\NPC\CharacterAnimManager.cs" />
|
||||
@ -134,6 +65,7 @@
|
||||
<Compile Include="CampfireSync\WorldObjects\QSBCampfire.cs" />
|
||||
<Compile Include="ClientServerStateSync\ClientStateManager.cs" />
|
||||
<Compile Include="ClientServerStateSync\Events\ClientStateEvent.cs" />
|
||||
<Compile Include="ConversationSync\CameraFacingBillboard.cs" />
|
||||
<Compile Include="ConversationSync\Events\DialogueConditionEvent.cs" />
|
||||
<Compile Include="ConversationSync\Events\DialogueConditionMessage.cs" />
|
||||
<Compile Include="ConversationSync\Events\ConversationEvent.cs" />
|
||||
@ -170,6 +102,8 @@
|
||||
<Compile Include="Instruments\QSBCamera\CameraManager.cs" />
|
||||
<Compile Include="Instruments\QSBCamera\CameraMode.cs" />
|
||||
<Compile Include="Instruments\InstrumentsManager.cs" />
|
||||
<Compile Include="Menus\IMenuAPI.cs" />
|
||||
<Compile Include="Menus\MenuManager.cs" />
|
||||
<Compile Include="Messaging\BoolMessage.cs" />
|
||||
<Compile Include="OrbSync\TransformSync\NomaiOrbTransformSync.cs" />
|
||||
<Compile Include="Player\Events\PlayerInformationEvent.cs" />
|
||||
@ -228,7 +162,6 @@
|
||||
<Compile Include="ProbeSync\QSBProbeEffects.cs" />
|
||||
<Compile Include="ProbeSync\QSBProbeLantern.cs" />
|
||||
<Compile Include="ProbeSync\QSBProbeSpotlight.cs" />
|
||||
<Compile Include="QSBNetworkLobby.cs" />
|
||||
<Compile Include="Patches\QSBPatch.cs" />
|
||||
<Compile Include="Patches\QSBPatchTypes.cs" />
|
||||
<Compile Include="QSBSceneManager.cs" />
|
||||
@ -278,10 +211,13 @@
|
||||
<Compile Include="ShipSync\Events\RepairTickMessage.cs" />
|
||||
<Compile Include="ShipSync\WorldObjects\QSBShipComponent.cs" />
|
||||
<Compile Include="ShipSync\WorldObjects\QSBShipHull.cs" />
|
||||
<Compile Include="Syncs\ISectoredSync.cs" />
|
||||
<Compile Include="Syncs\RigidbodySync\UnparentedBaseRigidbodySync.cs" />
|
||||
<Compile Include="Syncs\RigidbodySync\SectoredRigidbodySync.cs" />
|
||||
<Compile Include="Syncs\Sectored\BaseSectoredSync.cs" />
|
||||
<Compile Include="Syncs\Sectored\Rigidbodies\SectoredRigidbodySync.cs" />
|
||||
<Compile Include="Syncs\Sectored\Transforms\SectoredTransformSync.cs" />
|
||||
<Compile Include="Syncs\SyncBase.cs" />
|
||||
<Compile Include="Syncs\Unsectored\BaseUnsectoredSync.cs" />
|
||||
<Compile Include="Syncs\Unsectored\Rigidbodies\UnsectoredRigidbodySync.cs" />
|
||||
<Compile Include="Syncs\Unsectored\Transforms\UnsectoredTransformSync.cs" />
|
||||
<Compile Include="TimeSync\FastForwardReason.cs" />
|
||||
<Compile Include="TimeSync\Patches\TimePatches.cs" />
|
||||
<Compile Include="TimeSync\PauseReason.cs" />
|
||||
@ -309,10 +245,7 @@
|
||||
<Compile Include="StatueSync\Events\StartStatueMessage.cs" />
|
||||
<Compile Include="StatueSync\Patches\StatuePatches.cs" />
|
||||
<Compile Include="StatueSync\StatueManager.cs" />
|
||||
<Compile Include="Syncs\TransformSync\BaseTransformSync.cs" />
|
||||
<Compile Include="Syncs\IntermediaryTransform.cs" />
|
||||
<Compile Include="Syncs\TransformSync\SectoredTransformSync.cs" />
|
||||
<Compile Include="Syncs\TransformSync\UnparentedBaseTransformSync.cs" />
|
||||
<Compile Include="TranslationSync\Events\SetAsTranslatedEvent.cs" />
|
||||
<Compile Include="TranslationSync\Events\SetAsTranslatedMessage.cs" />
|
||||
<Compile Include="TranslationSync\NomaiTextType.cs" />
|
||||
@ -359,7 +292,6 @@
|
||||
<Compile Include="Utility\Popcron.Gizmos\Drawers\PolygonDrawer.cs" />
|
||||
<Compile Include="Utility\Popcron.Gizmos\Drawers\SquareDrawer.cs" />
|
||||
<Compile Include="Utility\RepeatingManager.cs" />
|
||||
<Compile Include="Utility\Tuple.cs" />
|
||||
<Compile Include="Utility\UnitTestDetector.cs" />
|
||||
<Compile Include="WorldSync\Events\BoolWorldObjectMessage.cs" />
|
||||
<Compile Include="WorldSync\Events\EnumWorldObjectMessage.cs" />
|
||||
@ -399,6 +331,7 @@
|
||||
<Compile Include="WorldSync\WorldObjectManager.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="default-config.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
@ -406,18 +339,89 @@
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Assembly-CSharp_publicized">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\publicized_assemblies\Assembly-CSharp_publicized.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp-firstpass">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="netstandard">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\netstandard.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System">
|
||||
<HintPath>..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Unity.InputSystem, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\Unity.InputSystem.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.AnimationModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AssetBundleModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.AssetBundleModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AudioModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.AudioModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.IMGUIModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.IMGUIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.InputModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.Networking">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.Networking.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextCoreModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.TextCoreModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.TextRenderingModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.TextRenderingModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UI">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UIModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.UIModule.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.UNETModule">
|
||||
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.UNETModule.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\QuantumUNET\QuantumUNET.csproj">
|
||||
<Project>{C8C53004-1508-4F86-A419-4292C188DC2A}</Project>
|
||||
<Project>{c8c53004-1508-4f86-a419-4292c188dc2a}</Project>
|
||||
<Name>QuantumUNET</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="lib\UnityEngine.Networking.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HarmonyX">
|
||||
<Version>2.5.5</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="OWML">
|
||||
<Version>1.1.8</Version>
|
||||
<Version>2.0.0</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>md "$(OwmlDir)\Mods\$(ProjectName)"
|
||||
@ -425,11 +429,18 @@ md "$(OwmlDir)\Mods\$(ProjectName)\assets"
|
||||
del "$(OwmlDir)\Mods\$(ProjectName)\config.json"
|
||||
|
||||
copy /y "$(ProjectDir)\default-config.json" "$(OwmlDir)\Mods\$(ProjectName)"
|
||||
copy /y "$(SolutionDir)\AssetBundles" "$(OwmlDir)\Mods\$(ProjectName)\assets
|
||||
copy /y "$(SolutionDir)\AssetBundles" "$(OwmlDir)\Mods\$(ProjectName)\assets"
|
||||
copy /y "$(ProjectDir)\manifest.json" "$(OwmlDir)\Mods\$(ProjectName)"
|
||||
|
||||
"$(SolutionDir)\QNetWeaver\bin\Debug\QNetWeaver.exe" "$(GameDir)\OuterWilds_Data\Managed\UnityEngine.CoreModule.dll" "$(OwmlDir)\Mods\$(ProjectName)\QuantumUNET.dll" "$(GameDir)\OuterWilds_Data\Managed\UnityEngine.Networking.dll" "$(SolutionDir)\WeavedFiles" "$(TargetPath)"
|
||||
"$(SolutionDir)\QNetWeaver\bin\Debug\QNetWeaver.exe" "$(GameDir)\OuterWilds_Data\Managed\UnityEngine.CoreModule.dll" "$(OwmlDir)\Mods\$(ProjectName)\QuantumUNET.dll" "$(ProjectDir)\lib\UnityEngine.Networking.dll" "$(SolutionDir)\WeavedFiles" "$(TargetPath)"
|
||||
|
||||
copy /y "$(SolutionDir)\WeavedFiles\QSB.dll" "$(OwmlDir)\Mods\$(ProjectName)"</PostBuildEvent>
|
||||
copy /y "$(SolutionDir)\WeavedFiles\QSB.dll" "$(OwmlDir)\Mods\$(ProjectName)"
|
||||
|
||||
xcopy /y "$(ProjectDir)\lib" "$(OwmlDir)\Mods\$(ProjectName)"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties manifest_1json__JsonSchema="" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<GameDir>E:\Epic\Epic Games\OuterWilds</GameDir>
|
||||
<GameDir>D:\EpicGames\OuterWilds</GameDir>
|
||||
<OwmlDir>C:\Users\Henry\AppData\Roaming\OuterWildsModManager\OWML</OwmlDir>
|
||||
<ProjectView>ShowAllFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
|
@ -1,7 +1,6 @@
|
||||
using OWML.Common;
|
||||
using OWML.ModHelper;
|
||||
using OWML.ModHelper.Input;
|
||||
using OWML.Utils;
|
||||
using QSB.Animation.NPC;
|
||||
using QSB.CampfireSync;
|
||||
using QSB.ConversationSync;
|
||||
@ -10,6 +9,7 @@ using QSB.ElevatorSync;
|
||||
using QSB.GeyserSync;
|
||||
using QSB.Inputs;
|
||||
using QSB.ItemSync;
|
||||
using QSB.Menus;
|
||||
using QSB.OrbSync;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
@ -59,14 +59,17 @@ namespace QSB
|
||||
public static AssetBundle NetworkAssetBundle { get; private set; }
|
||||
public static AssetBundle InstrumentAssetBundle { get; private set; }
|
||||
public static AssetBundle ConversationAssetBundle { get; private set; }
|
||||
public static AssetBundle DebugAssetBundle { get; private set; }
|
||||
public static bool WorldObjectsReady => WorldObjectManager.AllReady && IsInMultiplayer && PlayerTransformSync.LocalInstance != null;
|
||||
public static bool IsHost => QNetworkServer.active;
|
||||
public static bool IsInMultiplayer => QNetworkManager.singleton.isNetworkActive;
|
||||
public static string QSBVersion => Helper.Manifest.Version;
|
||||
public static string GameVersion => Application.version;
|
||||
public static IMenuAPI MenuApi { get; private set; }
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
var instance = TextTranslation.Get().GetValue<TextTranslation.TranslationTable>("m_table");
|
||||
var instance = TextTranslation.Get().m_table;
|
||||
instance.theUITable[(int)UITextType.PleaseUseController] =
|
||||
"<color=orange>Quantum Space Buddies</color> is best experienced with friends...";
|
||||
}
|
||||
@ -76,14 +79,16 @@ namespace QSB
|
||||
Helper = ModHelper;
|
||||
DebugLog.ToConsole($"* Start of QSB version {QSBVersion} - authored by {Helper.Manifest.Author}", MessageType.Info);
|
||||
|
||||
MenuApi = ModHelper.Interaction.GetModApi<IMenuAPI>("_nebula.MenuFramework");
|
||||
|
||||
NetworkAssetBundle = Helper.Assets.LoadBundle("assets/network");
|
||||
InstrumentAssetBundle = Helper.Assets.LoadBundle("assets/instruments");
|
||||
ConversationAssetBundle = Helper.Assets.LoadBundle("assets/conversation");
|
||||
DebugAssetBundle = Helper.Assets.LoadBundle("assets/debug");
|
||||
|
||||
QSBPatchManager.Init();
|
||||
|
||||
gameObject.AddComponent<QSBNetworkManager>();
|
||||
gameObject.AddComponent<QNetworkManagerHUD>();
|
||||
gameObject.AddComponent<DebugActions>();
|
||||
gameObject.AddComponent<ConversationManager>();
|
||||
gameObject.AddComponent<QSBInputManager>();
|
||||
@ -91,6 +96,7 @@ namespace QSB
|
||||
gameObject.AddComponent<RepeatingManager>();
|
||||
gameObject.AddComponent<PlayerEntanglementWatcher>();
|
||||
gameObject.AddComponent<DebugGUI>();
|
||||
gameObject.AddComponent<MenuManager>();
|
||||
gameObject.AddComponent<RespawnManager>();
|
||||
|
||||
// WorldObject managers
|
||||
@ -112,9 +118,6 @@ namespace QSB
|
||||
|
||||
Helper.HarmonyHelper.EmptyMethod<ModCommandListener>("Update");
|
||||
|
||||
// Stop players being able to pause
|
||||
Helper.HarmonyHelper.EmptyMethod(typeof(OWTime).GetMethod("Pause"));
|
||||
|
||||
QSBPatchManager.OnPatchType += OnPatchType;
|
||||
QSBPatchManager.OnUnpatchType += OnUnpatchType;
|
||||
}
|
||||
@ -177,4 +180,5 @@ namespace QSB
|
||||
* Teleskärm
|
||||
* Daft Punk
|
||||
* Natalie Holt
|
||||
* WMD
|
||||
*/
|
@ -1,71 +0,0 @@
|
||||
using OWML.Utils;
|
||||
using QuantumUNET;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB
|
||||
{
|
||||
public class QSBNetworkLobby : QNetworkBehaviour
|
||||
{
|
||||
public bool CanEditName { get; set; }
|
||||
public string PlayerName { get; private set; }
|
||||
|
||||
// TODO : Could delete a lot of this - shouldnt be possible to not have a profile and still play
|
||||
|
||||
private readonly string[] _defaultNames = {
|
||||
"Arkose",
|
||||
"Chert",
|
||||
"Esker",
|
||||
"Hal",
|
||||
"Hornfels",
|
||||
"Feldspar",
|
||||
"Gabbro",
|
||||
"Galena",
|
||||
"Gneiss",
|
||||
"Gossan",
|
||||
"Marl",
|
||||
"Mica",
|
||||
"Moraine",
|
||||
"Porphy",
|
||||
"Riebeck",
|
||||
"Rutile",
|
||||
"Slate",
|
||||
"Spinel",
|
||||
"Tektite",
|
||||
"Tephra",
|
||||
"Tuff",
|
||||
"Jinha"
|
||||
};
|
||||
|
||||
public void Awake()
|
||||
{
|
||||
PlayerName = GetPlayerName();
|
||||
CanEditName = true;
|
||||
}
|
||||
|
||||
private string GetPlayerName()
|
||||
{
|
||||
var profileManager = StandaloneProfileManager.SharedInstance;
|
||||
profileManager.Initialize();
|
||||
var profile = profileManager.GetValue<StandaloneProfileManager.ProfileData>("_currentProfile");
|
||||
var profileName = profile?.profileName;
|
||||
return !string.IsNullOrEmpty(profileName)
|
||||
? profileName
|
||||
: _defaultNames.OrderBy(x => Guid.NewGuid()).First();
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
GUI.Label(new Rect(10, 10, 200f, 20f), "Name:");
|
||||
if (CanEditName)
|
||||
{
|
||||
PlayerName = GUI.TextField(new Rect(60, 10, 145, 20f), PlayerName);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.Label(new Rect(60, 10, 145, 20f), PlayerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -30,15 +30,18 @@ namespace QSB
|
||||
public static QSBNetworkManager Instance { get; private set; }
|
||||
|
||||
public event Action OnNetworkManagerReady;
|
||||
public event Action OnClientConnected;
|
||||
public event Action<NetworkError> OnClientDisconnected;
|
||||
public event Action<NetworkError> OnClientErrorThrown;
|
||||
|
||||
public bool IsReady { get; private set; }
|
||||
public GameObject OrbPrefab { get; private set; }
|
||||
public GameObject ShipPrefab { get; private set; }
|
||||
public string PlayerName { get; private set; }
|
||||
|
||||
private const int MaxConnections = 128;
|
||||
private const int MaxBufferedPackets = 64;
|
||||
|
||||
private QSBNetworkLobby _lobby;
|
||||
private AssetBundle _assetBundle;
|
||||
private GameObject _probePrefab;
|
||||
private bool _everConnected;
|
||||
@ -48,11 +51,11 @@ namespace QSB
|
||||
base.Awake();
|
||||
Instance = this;
|
||||
|
||||
_lobby = gameObject.AddComponent<QSBNetworkLobby>();
|
||||
PlayerName = GetPlayerName();
|
||||
_assetBundle = QSBCore.NetworkAssetBundle;
|
||||
|
||||
playerPrefab = _assetBundle.LoadAsset<GameObject>("assets/NETWORK_Player_Body.prefab");
|
||||
SetupNetworkId(playerPrefab);
|
||||
SetupNetworkId(playerPrefab, 1);
|
||||
SetupNetworkTransform(playerPrefab);
|
||||
playerPrefab.AddComponent<PlayerTransformSync>();
|
||||
playerPrefab.AddComponent<AnimationSync>();
|
||||
@ -62,19 +65,19 @@ namespace QSB
|
||||
playerPrefab.AddComponent<InstrumentsManager>();
|
||||
|
||||
ShipPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkship.prefab");
|
||||
SetupNetworkId(ShipPrefab);
|
||||
SetupNetworkId(ShipPrefab, 2);
|
||||
SetupNetworkTransform(ShipPrefab);
|
||||
ShipPrefab.AddComponent<ShipTransformSync>();
|
||||
spawnPrefabs.Add(ShipPrefab);
|
||||
|
||||
_probePrefab = _assetBundle.LoadAsset<GameObject>("assets/networkprobe.prefab");
|
||||
SetupNetworkId(_probePrefab);
|
||||
SetupNetworkId(_probePrefab, 3);
|
||||
SetupNetworkTransform(_probePrefab);
|
||||
_probePrefab.AddComponent<PlayerProbeSync>();
|
||||
spawnPrefabs.Add(_probePrefab);
|
||||
|
||||
OrbPrefab = _assetBundle.LoadAsset<GameObject>("assets/networkorb.prefab");
|
||||
SetupNetworkId(OrbPrefab);
|
||||
SetupNetworkId(OrbPrefab, 4);
|
||||
SetupNetworkTransform(OrbPrefab);
|
||||
OrbPrefab.AddComponent<NomaiOrbTransformSync>();
|
||||
spawnPrefabs.Add(OrbPrefab);
|
||||
@ -82,12 +85,22 @@ namespace QSB
|
||||
ConfigureNetworkManager();
|
||||
}
|
||||
|
||||
private void SetupNetworkId(GameObject go)
|
||||
private string GetPlayerName()
|
||||
{
|
||||
var profileManager = StandaloneProfileManager.SharedInstance;
|
||||
profileManager.Initialize();
|
||||
var profile = profileManager.GetValue<StandaloneProfileManager.ProfileData>("_currentProfile");
|
||||
var profileName = profile.profileName;
|
||||
return profileName;
|
||||
}
|
||||
|
||||
private void SetupNetworkId(GameObject go, int assetId)
|
||||
{
|
||||
var ident = go.AddComponent<QNetworkIdentity>();
|
||||
ident.LocalPlayerAuthority = true;
|
||||
ident.SetValue("m_AssetId", go.GetComponent<NetworkIdentity>().assetId);
|
||||
ident.SetValue("m_SceneId", go.GetComponent<NetworkIdentity>().sceneId);
|
||||
var networkIdentity = go.GetComponent<NetworkIdentity>();
|
||||
ident.SetValue("m_AssetId", assetId);
|
||||
ident.SetValue("m_SceneId", networkIdentity.GetComponent<NetworkIdentity>().sceneId);
|
||||
}
|
||||
|
||||
private void SetupNetworkTransform(GameObject go)
|
||||
@ -138,17 +151,21 @@ namespace QSB
|
||||
|
||||
public override void OnStartClient(QNetworkClient _)
|
||||
{
|
||||
DebugLog.DebugWrite($"Setting defaultServerIP to {networkAddress}");
|
||||
var config = QSBCore.Helper.Config;
|
||||
config.SetSettingsValue("defaultServerIP", networkAddress);
|
||||
QSBCore.Helper.Storage.Save(config, Constants.ModConfigFileName);
|
||||
}
|
||||
|
||||
public override void OnClientError(QNetworkConnection conn, int errorCode)
|
||||
=> OnClientErrorThrown?.SafeInvoke((NetworkError)errorCode);
|
||||
|
||||
public override void OnClientConnect(QNetworkConnection connection) // Called on the client when connecting to a server
|
||||
{
|
||||
DebugLog.DebugWrite("OnClientConnect", MessageType.Info);
|
||||
base.OnClientConnect(connection);
|
||||
|
||||
OnClientConnected?.SafeInvoke();
|
||||
|
||||
QSBEventManager.Init();
|
||||
|
||||
gameObject.AddComponent<RespawnOnDeath>();
|
||||
@ -164,13 +181,11 @@ namespace QSB
|
||||
QSBPatchManager.DoPatchType(specificType);
|
||||
QSBPatchManager.DoPatchType(QSBPatchTypes.OnClientConnect);
|
||||
|
||||
_lobby.CanEditName = false;
|
||||
|
||||
OnNetworkManagerReady?.SafeInvoke();
|
||||
IsReady = true;
|
||||
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBEventManager.Ready && PlayerTransformSync.LocalInstance != null,
|
||||
() => QSBEventManager.FireEvent(EventNames.QSBPlayerJoin, _lobby.PlayerName));
|
||||
() => QSBEventManager.FireEvent(EventNames.QSBPlayerJoin, PlayerName));
|
||||
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
@ -202,12 +217,16 @@ namespace QSB
|
||||
QSBPatchManager.DoUnpatchType(QSBPatchTypes.OnClientConnect);
|
||||
}
|
||||
|
||||
_lobby.CanEditName = true;
|
||||
|
||||
IsReady = false;
|
||||
_everConnected = false;
|
||||
}
|
||||
|
||||
public override void OnClientDisconnect(QNetworkConnection conn)
|
||||
{
|
||||
base.OnClientDisconnect(conn);
|
||||
OnClientDisconnected?.SafeInvoke(conn.LastError);
|
||||
}
|
||||
|
||||
public override void OnServerDisconnect(QNetworkConnection connection) // Called on the server when any client disconnects
|
||||
{
|
||||
base.OnServerDisconnect(connection);
|
||||
|
@ -1,21 +1,21 @@
|
||||
using QSB.Patches;
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
using System.Reflection;
|
||||
|
||||
namespace QSB.QuantumSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class ClientQuantumPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnNonServerClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(QuantumMoon_ChangeQuantumState));
|
||||
Postfix(nameof(QuantumMoon_Start));
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(QuantumMoon), nameof(QuantumMoon.Start))]
|
||||
public static void QuantumMoon_Start(QuantumMoon __instance)
|
||||
=> __instance.GetType().GetMethod("SetSurfaceState", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { -1 });
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumMoon), nameof(QuantumMoon.ChangeQuantumState))]
|
||||
public static bool QuantumMoon_ChangeQuantumState()
|
||||
=> false;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
@ -12,26 +13,13 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.QuantumSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class QuantumPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(SocketedQuantumObject_ChangeQuantumState));
|
||||
Postfix(nameof(SocketedQuantumObject_MoveToSocket));
|
||||
Prefix(nameof(QuantumShuffleObject_ChangeQuantumState));
|
||||
Prefix(nameof(MultiStateQuantumObject_ChangeQuantumState));
|
||||
Postfix(nameof(QuantumState_SetVisible));
|
||||
Prefix(nameof(QuantumShrine_IsPlayerInDarkness));
|
||||
Prefix(nameof(QuantumShrine_ChangeQuantumState));
|
||||
Prefix(nameof(QuantumShrine_OnEntry));
|
||||
Prefix(nameof(QuantumShrine_OnExit));
|
||||
Prefix(nameof(QuantumMoon_CheckPlayerFogProximity));
|
||||
Prefix(nameof(QuantumObject_IsLockedByPlayerContact));
|
||||
Prefix(nameof(MultiStateQuantumObject_Start));
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumObject), nameof(QuantumObject.IsLockedByPlayerContact))]
|
||||
public static bool QuantumObject_IsLockedByPlayerContact(ref bool __result, QuantumObject __instance)
|
||||
{
|
||||
var playersEntangled = QuantumManager.GetEntangledPlayers(__instance);
|
||||
@ -39,6 +27,8 @@ namespace QSB.QuantumSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SocketedQuantumObject), nameof(SocketedQuantumObject.ChangeQuantumState))]
|
||||
public static bool SocketedQuantumObject_ChangeQuantumState(
|
||||
SocketedQuantumObject __instance,
|
||||
ref bool __result,
|
||||
@ -149,6 +139,8 @@ namespace QSB.QuantumSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(SocketedQuantumObject), nameof(SocketedQuantumObject.MoveToSocket))]
|
||||
public static void SocketedQuantumObject_MoveToSocket(SocketedQuantumObject __instance, QuantumSocket socket)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
@ -183,6 +175,8 @@ namespace QSB.QuantumSync.Patches
|
||||
__instance.transform.localRotation);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumShuffleObject), nameof(QuantumShuffleObject.ChangeQuantumState))]
|
||||
public static bool QuantumShuffleObject_ChangeQuantumState(
|
||||
QuantumShuffleObject __instance,
|
||||
ref List<int> ____indexList,
|
||||
@ -227,6 +221,8 @@ namespace QSB.QuantumSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(MultiStateQuantumObject), nameof(MultiStateQuantumObject.Start))]
|
||||
public static bool MultiStateQuantumObject_Start(MultiStateQuantumObject __instance, Sector ____sector, bool ____collapseOnStart)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
@ -250,17 +246,19 @@ namespace QSB.QuantumSync.Patches
|
||||
|
||||
if (____sector == null)
|
||||
{
|
||||
__instance.GetType().GetMethod("CheckEnabled", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null);
|
||||
__instance.CheckEnabled();
|
||||
}
|
||||
|
||||
if (____collapseOnStart)
|
||||
{
|
||||
__instance.GetType().GetMethod("Collapse", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { true });
|
||||
__instance.Collapse(true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(MultiStateQuantumObject), nameof(MultiStateQuantumObject.ChangeQuantumState))]
|
||||
public static bool MultiStateQuantumObject_ChangeQuantumState(MultiStateQuantumObject __instance)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
@ -278,6 +276,8 @@ namespace QSB.QuantumSync.Patches
|
||||
return isInControl;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(QuantumState), nameof(QuantumState.SetVisible))]
|
||||
public static void QuantumState_SetVisible(QuantumState __instance, bool visible)
|
||||
{
|
||||
if (!WorldObjectManager.AllReady)
|
||||
@ -292,7 +292,13 @@ namespace QSB.QuantumSync.Patches
|
||||
|
||||
var allMultiStates = QSBWorldSync.GetWorldObjects<QSBMultiStateQuantumObject>();
|
||||
var stateObject = QSBWorldSync.GetWorldFromUnity<QSBQuantumState, QuantumState>(__instance);
|
||||
var owner = allMultiStates.First(x => x.QuantumStates.Contains(stateObject));
|
||||
var owner = allMultiStates.FirstOrDefault(x => x.QuantumStates.Contains(stateObject));
|
||||
if (owner == default)
|
||||
{
|
||||
DebugLog.DebugWrite($"Error - Could not find QSBMultiStateQuantumObject for state {__instance.name}", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (owner.ControllingPlayer != QSBPlayerManager.LocalPlayerId)
|
||||
{
|
||||
return;
|
||||
@ -305,6 +311,8 @@ namespace QSB.QuantumSync.Patches
|
||||
stateIndex);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.IsPlayerInDarkness))]
|
||||
public static bool QuantumShrine_IsPlayerInDarkness(ref bool __result, Light[] ____lamps, float ____fadeFraction, bool ____isProbeInside, NomaiGateway ____gate)
|
||||
{
|
||||
foreach (var lamp in ____lamps)
|
||||
@ -344,13 +352,15 @@ namespace QSB.QuantumSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : make this *really* check for all players - check other probes and other jetpacks!
|
||||
// BUG : make this *really* check for all players - check other probes and other jetpacks!
|
||||
__result = ____gate.GetOpenFraction() == 0f
|
||||
&& !____isProbeInside
|
||||
&& Locator.GetThrusterLightTracker().GetLightRange() <= 0f;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.ChangeQuantumState))]
|
||||
public static bool QuantumShrine_ChangeQuantumState(QuantumShrine __instance)
|
||||
{
|
||||
var shrineWorldObject = QSBWorldSync.GetWorldFromUnity<QSBSocketedQuantumObject, SocketedQuantumObject>(__instance);
|
||||
@ -358,6 +368,8 @@ namespace QSB.QuantumSync.Patches
|
||||
return isInControl;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.OnEntry))]
|
||||
public static bool QuantumShrine_OnEntry(
|
||||
GameObject hitObj,
|
||||
ref bool ____isPlayerInside,
|
||||
@ -380,6 +392,8 @@ namespace QSB.QuantumSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumShrine), nameof(QuantumShrine.OnExit))]
|
||||
public static bool QuantumShrine_OnExit(
|
||||
GameObject hitObj,
|
||||
ref bool ____isPlayerInside,
|
||||
@ -402,6 +416,8 @@ namespace QSB.QuantumSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumMoon), nameof(QuantumMoon.CheckPlayerFogProximity))]
|
||||
public static bool QuantumMoon_CheckPlayerFogProximity(
|
||||
QuantumMoon __instance,
|
||||
int ____stateIndex,
|
||||
@ -429,7 +445,7 @@ namespace QSB.QuantumSync.Patches
|
||||
fogAlpha = Mathf.InverseLerp(____fogThickness + ____fogRolloffDistance, ____fogThickness, distanceFromFog);
|
||||
if (distanceFromFog < 0f)
|
||||
{
|
||||
if ((bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) || QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true).First)
|
||||
if ((bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) || QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true).Item1)
|
||||
{
|
||||
____isPlayerInside = true;
|
||||
__instance.GetType().GetMethod("SetSurfaceState", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { ____stateIndex });
|
||||
@ -450,7 +466,7 @@ namespace QSB.QuantumSync.Patches
|
||||
if (____stateIndex != 5)
|
||||
{
|
||||
____isPlayerInside = false;
|
||||
if (!(bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) && !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true).First)
|
||||
if (!(bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) && !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true).Item1)
|
||||
{
|
||||
__instance.GetType().GetMethod("Collapse", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { true });
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using QSB.Patches;
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
@ -7,34 +8,33 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.QuantumSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class QuantumVisibilityPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(ShapeVisibilityTracker_IsVisibleUsingCameraFrustum));
|
||||
Prefix(nameof(ShapeVisibilityTracker_IsVisible));
|
||||
Prefix(nameof(RendererVisibilityTracker_IsVisibleUsingCameraFrustum));
|
||||
Prefix(nameof(VisibilityObject_CheckIllumination));
|
||||
Postfix(nameof(Shape_OnEnable));
|
||||
Postfix(nameof(Shape_OnDisable));
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(Shape), nameof(Shape.OnEnable))]
|
||||
public static void Shape_OnEnable(Shape __instance)
|
||||
=> __instance.RaiseEvent("OnShapeActivated", __instance);
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(Shape), nameof(Shape.OnDisable))]
|
||||
public static void Shape_OnDisable(Shape __instance)
|
||||
=> __instance.RaiseEvent("OnShapeDeactivated", __instance);
|
||||
|
||||
// ShapeVisibilityTracker patches
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShapeVisibilityTracker), nameof(ShapeVisibilityTracker.IsVisibleUsingCameraFrustum))]
|
||||
public static bool ShapeVisibilityTracker_IsVisibleUsingCameraFrustum(ShapeVisibilityTracker __instance, ref bool __result)
|
||||
{
|
||||
__result = QuantumManager.IsVisibleUsingCameraFrustum(__instance, false).First;
|
||||
__result = QuantumManager.IsVisibleUsingCameraFrustum(__instance, false).Item1;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShapeVisibilityTracker), nameof(ShapeVisibilityTracker.IsVisible))]
|
||||
public static bool ShapeVisibilityTracker_IsVisible(ShapeVisibilityTracker __instance, ref bool __result)
|
||||
{
|
||||
__result = QuantumManager.IsVisible(__instance, false);
|
||||
@ -43,6 +43,8 @@ namespace QSB.QuantumSync.Patches
|
||||
|
||||
// RendererVisibilityTracker patches - probably not needed as i don't think RendererVisibilityTracker is ever used?
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(RendererVisibilityTracker), nameof(RendererVisibilityTracker.IsVisibleUsingCameraFrustum))]
|
||||
public static bool RendererVisibilityTracker_IsVisibleUsingCameraFrustum(RendererVisibilityTracker __instance, ref bool __result, Renderer ____renderer, bool ____checkFrustumOcclusion)
|
||||
{
|
||||
__result = QSBPlayerManager.GetPlayersWithCameras()
|
||||
@ -56,6 +58,8 @@ namespace QSB.QuantumSync.Patches
|
||||
|
||||
// VisibilityObject
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(VisibilityObject), nameof(VisibilityObject.CheckIllumination))]
|
||||
public static bool VisibilityObject_CheckIllumination(VisibilityObject __instance, ref bool __result, bool ____checkIllumination, Vector3 ____localIlluminationOffset, float ____illuminationRadius, Light[] ____lightSources)
|
||||
{
|
||||
if (!____checkIllumination)
|
||||
@ -66,8 +70,8 @@ namespace QSB.QuantumSync.Patches
|
||||
|
||||
var point = __instance.transform.TransformPoint(____localIlluminationOffset);
|
||||
var tupleFlashlights = QSBPlayerManager.GetPlayerFlashlights();
|
||||
var localFlashlight = tupleFlashlights.First;
|
||||
var playerFlashlights = tupleFlashlights.Second;
|
||||
var localFlashlight = tupleFlashlights.Item1;
|
||||
var playerFlashlights = tupleFlashlights.Item2;
|
||||
|
||||
// local player flashlight
|
||||
if (localFlashlight.CheckIlluminationAtPoint(point, ____illuminationRadius))
|
||||
@ -83,14 +87,14 @@ namespace QSB.QuantumSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : Implement checking for other probes!
|
||||
// BUG : Implement checking for other probes!
|
||||
if (Locator.GetProbe() != null && Locator.GetProbe().IsLaunched() && Locator.GetProbe().CheckIlluminationAtPoint(point, ____illuminationRadius))
|
||||
{
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : Implement checking for other player's thrusters!
|
||||
// BUG : Implement checking for other player's thrusters!
|
||||
if (Locator.GetThrusterLightTracker().CheckIlluminationAtPoint(point, ____illuminationRadius))
|
||||
{
|
||||
__result = true;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using HarmonyLib;
|
||||
using OWML.Common;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
@ -9,13 +10,13 @@ using UnityEngine;
|
||||
|
||||
namespace QSB.QuantumSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public class ServerQuantumPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnServerClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
=> Prefix(nameof(QuantumMoon_ChangeQuantumState));
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuantumMoon), nameof(QuantumMoon.ChangeQuantumState))]
|
||||
public static bool QuantumMoon_ChangeQuantumState(
|
||||
QuantumMoon __instance,
|
||||
ref bool __result,
|
||||
@ -38,9 +39,14 @@ namespace QSB.QuantumSync.Patches
|
||||
GameObject[] ____deactivateAtEye
|
||||
)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var isVisibleOutput = QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck);
|
||||
//var moonVisible = isVisibleOutput.First;
|
||||
var moonVisiblePlayers = isVisibleOutput.Second;
|
||||
var moonVisiblePlayers = isVisibleOutput.Item2;
|
||||
var inMoonPlayers = QSBPlayerManager.PlayerList.Where(x => x.IsInMoon);
|
||||
if (inMoonPlayers == null)
|
||||
{
|
||||
@ -148,7 +154,7 @@ namespace QSB.QuantumSync.Patches
|
||||
Physics.SyncTransforms();
|
||||
}
|
||||
|
||||
if (__instance.IsPlayerEntangled() || !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck).First)
|
||||
if (__instance.IsPlayerEntangled() || !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck).Item1)
|
||||
{
|
||||
____moonBody.transform.position = position;
|
||||
if (!Physics.autoSyncTransforms)
|
||||
|
@ -4,6 +4,7 @@ using QSB.Player;
|
||||
using QSB.QuantumSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@ -31,7 +32,7 @@ namespace QSB.QuantumSync
|
||||
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
DebugLog.DebugWrite("Rebuilding quantum objects...", MessageType.Warning);
|
||||
DebugLog.DebugWrite("Rebuilding quantum objects...", MessageType.Info);
|
||||
QSBWorldSync.Init<QSBQuantumState, QuantumState>();
|
||||
QSBWorldSync.Init<QSBSocketedQuantumObject, SocketedQuantumObject>();
|
||||
QSBWorldSync.Init<QSBMultiStateQuantumObject, MultiStateQuantumObject>();
|
||||
@ -87,7 +88,7 @@ namespace QSB.QuantumSync
|
||||
var playersWithCameras = QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera);
|
||||
if (playersWithCameras.Count == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Trying to run IsVisibleUsingCameraFrustum when there are no players!", MessageType.Warning);
|
||||
DebugLog.ToConsole($"Warning - Could not find any players with cameras!", MessageType.Warning);
|
||||
return new Tuple<bool, List<PlayerInfo>>(false, new List<PlayerInfo>());
|
||||
}
|
||||
|
||||
@ -120,7 +121,7 @@ namespace QSB.QuantumSync
|
||||
}
|
||||
|
||||
public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera) => tracker.gameObject.activeInHierarchy
|
||||
&& IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera).First
|
||||
&& IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera).Item1
|
||||
&& QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera)
|
||||
.Any(x => VisibilityOccluder.CanYouSee(tracker, x.Camera.mainCamera.transform.position));
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
public List<QSBQuantumState> QuantumStates { get; private set; }
|
||||
public Text DebugBoxText;
|
||||
public int CurrentState => AttachedObject.GetValue<int>("_stateIndex");
|
||||
public int CurrentState => AttachedObject._stateIndex;
|
||||
|
||||
public override void OnRemoval()
|
||||
{
|
||||
@ -26,15 +26,25 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
ObjectId = id;
|
||||
AttachedObject = attachedObject;
|
||||
QuantumStates = AttachedObject.GetValue<QuantumState[]>("_states").ToList().Select(x => QSBWorldSync.GetWorldFromUnity<QSBQuantumState, QuantumState>(x)).ToList();
|
||||
|
||||
if (QSBCore.DebugMode)
|
||||
{
|
||||
DebugBoxText = DebugBoxManager.CreateBox(AttachedObject.transform, 0, CurrentState.ToString()).GetComponent<Text>();
|
||||
DebugBoxText = DebugBoxManager.CreateBox(AttachedObject.transform, 0, $"Multistate\r\nid:{id}\r\nstate:{CurrentState}").GetComponent<Text>();
|
||||
}
|
||||
|
||||
base.Init(attachedObject, id);
|
||||
}
|
||||
|
||||
public override void PostInit()
|
||||
{
|
||||
QuantumStates = AttachedObject._states.ToList().Select(x => QSBWorldSync.GetWorldFromUnity<QSBQuantumState, QuantumState>(x)).ToList();
|
||||
|
||||
if (QuantumStates.Any(x => x == null))
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {AttachedObject.name} has one or more null QSBQuantumStates assigned!", OWML.Common.MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeState(int newStateIndex)
|
||||
{
|
||||
if (CurrentState != -1)
|
||||
@ -43,10 +53,10 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
}
|
||||
|
||||
QuantumStates[newStateIndex].SetVisible(true);
|
||||
AttachedObject.SetValue("_stateIndex", newStateIndex);
|
||||
AttachedObject._stateIndex = newStateIndex;
|
||||
if (QSBCore.DebugMode)
|
||||
{
|
||||
DebugBoxText.text = newStateIndex.ToString();
|
||||
DebugBoxText.text = $"Multistate\r\nid:{ObjectId}\r\nstate:{CurrentState}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.QuantumSync.WorldObjects
|
||||
{
|
||||
@ -29,6 +30,26 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
|
||||
public override void Init(T attachedObject, int id)
|
||||
{
|
||||
var debugBundle = QSBCore.DebugAssetBundle;
|
||||
var sphere = debugBundle.LoadAsset<GameObject>("Assets/Sphere.prefab");
|
||||
var cube = debugBundle.LoadAsset<GameObject>("Assets/Cube.prefab");
|
||||
var capsule = debugBundle.LoadAsset<GameObject>("Assets/Capsule.prefab");
|
||||
|
||||
if (cube == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"CUBE IS NULL");
|
||||
}
|
||||
|
||||
if (sphere == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"SPHERE IS NULL");
|
||||
}
|
||||
|
||||
if (capsule == null)
|
||||
{
|
||||
DebugLog.DebugWrite($"CAPSULE IS NULL");
|
||||
}
|
||||
|
||||
foreach (var shape in GetAttachedShapes())
|
||||
{
|
||||
if (shape == null)
|
||||
@ -42,6 +63,31 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
|
||||
shape.OnShapeDeactivated += (Shape s)
|
||||
=> QSBCore.UnityEvents.FireOnNextUpdate(() => OnDisable(s));
|
||||
|
||||
if (shape is BoxShape boxShape)
|
||||
{
|
||||
var newCube = UnityEngine.Object.Instantiate(cube);
|
||||
newCube.transform.parent = shape.transform;
|
||||
newCube.transform.localPosition = Vector3.zero;
|
||||
newCube.transform.localRotation = Quaternion.Euler(0, 0, 0);
|
||||
newCube.transform.localScale = boxShape.size;
|
||||
}
|
||||
else if (shape is SphereShape sphereShape)
|
||||
{
|
||||
var newSphere = UnityEngine.Object.Instantiate(sphere);
|
||||
newSphere.transform.parent = shape.transform;
|
||||
newSphere.transform.localPosition = Vector3.zero;
|
||||
newSphere.transform.localRotation = Quaternion.Euler(0, 0, 0);
|
||||
newSphere.transform.localScale = Vector3.one * (sphereShape.radius * 2);
|
||||
}
|
||||
else if (shape is CapsuleShape capsuleShape)
|
||||
{
|
||||
var newCapsule = Object.Instantiate(capsule);
|
||||
newCapsule.transform.parent = shape.transform;
|
||||
newCapsule.transform.localPosition = Vector3.zero;
|
||||
newCapsule.transform.localRotation = Quaternion.Euler(0, 0, 0);
|
||||
newCapsule.transform.localScale = new Vector3(capsuleShape.radius * 2, capsuleShape.height, capsuleShape.radius * 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetAttachedShapes().Any(x => !x.enabled || !x.active))
|
||||
|
@ -20,7 +20,7 @@ namespace QSB.QuantumSync.WorldObjects
|
||||
base.Init(quantumObject, id);
|
||||
if (QSBCore.DebugMode)
|
||||
{
|
||||
DebugBoxText = DebugBoxManager.CreateBox(AttachedObject.transform, 0, ObjectId.ToString()).GetComponent<Text>();
|
||||
DebugBoxText = DebugBoxManager.CreateBox(AttachedObject.transform, 0, $"Socketed\r\nid:{ObjectId}").GetComponent<Text>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,28 +1,34 @@
|
||||
using QSB.Events;
|
||||
using HarmonyLib;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.RoastingSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class RoastingPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(RoastingStickController_UpdateMarshmallowInput));
|
||||
Prefix(nameof(Marshmallow_Burn));
|
||||
Prefix(nameof(Marshmallow_Shrivel));
|
||||
Prefix(nameof(Marshmallow_RemoveMallow));
|
||||
Prefix(nameof(Marshmallow_SpawnMallow));
|
||||
}
|
||||
//public override void DoPatches()
|
||||
//{
|
||||
// Prefix<RoastingStickController>(nameof(RoastingStickController.UpdateMarshmallowInput), nameof(RoastingStickController_UpdateMarshmallowInput));
|
||||
// Prefix<Marshmallow>(nameof(Marshmallow.Burn), nameof(Marshmallow_Burn));
|
||||
// Prefix<Marshmallow>(nameof(Marshmallow.Shrivel), nameof(Marshmallow_Shrivel));
|
||||
// Prefix<Marshmallow>(nameof(Marshmallow.RemoveMallow), nameof(Marshmallow_RemoveMallow));
|
||||
// Prefix<Marshmallow>(nameof(Marshmallow.SpawnMallow), nameof(Marshmallow_SpawnMallow));
|
||||
//}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Marshmallow), nameof(Marshmallow.SpawnMallow))]
|
||||
public static bool Marshmallow_SpawnMallow()
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBMarshmallowEvent, MarshmallowEventType.Replace);
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Marshmallow), nameof(Marshmallow.Burn))]
|
||||
public static bool Marshmallow_Burn(
|
||||
ref Marshmallow.MallowState ____mallowState,
|
||||
MeshRenderer ____fireRenderer,
|
||||
@ -43,6 +49,8 @@ namespace QSB.RoastingSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Marshmallow), nameof(Marshmallow.Shrivel))]
|
||||
public static bool Marshmallow_Shrivel(
|
||||
ref Marshmallow.MallowState ____mallowState,
|
||||
ref float ____initShrivelTime)
|
||||
@ -57,6 +65,8 @@ namespace QSB.RoastingSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(Marshmallow), nameof(Marshmallow.RemoveMallow))]
|
||||
public static bool Marshmallow_RemoveMallow(
|
||||
ParticleSystem ____smokeParticles,
|
||||
MeshRenderer ____fireRenderer,
|
||||
@ -73,6 +83,8 @@ namespace QSB.RoastingSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(RoastingStickController), nameof(RoastingStickController.UpdateMarshmallowInput))]
|
||||
public static bool RoastingStickController_UpdateMarshmallowInput(
|
||||
float ____extendFraction,
|
||||
Marshmallow ____marshmallow,
|
||||
@ -96,7 +108,7 @@ namespace QSB.RoastingSync.Patches
|
||||
if (____marshmallow.IsBurned())
|
||||
{
|
||||
showRemovePrompt = true;
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.cancel, true, InputMode.Roasting))
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.cancel, InputMode.Roasting))
|
||||
{
|
||||
____marshmallow.Remove();
|
||||
Locator.GetPlayerAudioController().PlayMarshmallowToss();
|
||||
|
@ -4,6 +4,6 @@
|
||||
{
|
||||
public Sector AttachedSector;
|
||||
|
||||
protected override void Awake() { }
|
||||
public override void Awake() { }
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
using OWML.Common;
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
using QSB.Syncs;
|
||||
using QSB.Syncs.Sectored;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System.Collections.Generic;
|
||||
@ -18,8 +18,7 @@ namespace QSB.SectorSync
|
||||
private void OnEnable() => RepeatingManager.Repeatings.Add(this);
|
||||
private void OnDisable() => RepeatingManager.Repeatings.Remove(this);
|
||||
|
||||
public List<SyncBase> SectoredTransformSyncs = new List<SyncBase>();
|
||||
public List<SyncBase> SectoredRigidbodySyncs = new List<SyncBase>();
|
||||
public List<BaseSectoredSync> SectoredSyncs = new List<BaseSectoredSync>();
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
@ -28,7 +27,7 @@ namespace QSB.SectorSync
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var sync in SectoredTransformSyncs)
|
||||
foreach (var sync in SectoredSyncs)
|
||||
{
|
||||
if (sync.AttachedObject == null)
|
||||
{
|
||||
@ -37,24 +36,10 @@ namespace QSB.SectorSync
|
||||
|
||||
if (sync.HasAuthority
|
||||
&& sync.AttachedObject.gameObject.activeInHierarchy
|
||||
&& sync.IsReady)
|
||||
&& sync.IsReady
|
||||
&& sync.SectorSync.IsReady)
|
||||
{
|
||||
CheckTransformSyncSector(sync as ISectoredSync<Transform>);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var sync in SectoredRigidbodySyncs)
|
||||
{
|
||||
if (sync.AttachedObject == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sync.HasAuthority
|
||||
&& sync.AttachedObject.gameObject.activeInHierarchy
|
||||
&& sync.IsReady)
|
||||
{
|
||||
CheckTransformSyncSector(sync as ISectoredSync<OWRigidbody>);
|
||||
CheckTransformSyncSector(sync);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,7 +53,7 @@ namespace QSB.SectorSync
|
||||
|
||||
protected override void RebuildWorldObjects(OWScene scene)
|
||||
{
|
||||
DebugLog.DebugWrite("Rebuilding sectors...", MessageType.Warning);
|
||||
DebugLog.DebugWrite("Rebuilding sectors...", MessageType.Info);
|
||||
if (QSBSceneManager.CurrentScene == OWScene.SolarSystem)
|
||||
{
|
||||
var timeLoopRing = GameObject.Find("TimeLoopRing_Body");
|
||||
@ -89,10 +74,9 @@ namespace QSB.SectorSync
|
||||
IsReady = QSBWorldSync.GetWorldObjects<QSBSector>().Any();
|
||||
}
|
||||
|
||||
private void CheckTransformSyncSector<T>(ISectoredSync<T> transformSync)
|
||||
where T : Component
|
||||
private void CheckTransformSyncSector(BaseSectoredSync transformSync)
|
||||
{
|
||||
var attachedObject = (transformSync as SyncBase).AttachedObject;
|
||||
var attachedObject = transformSync.AttachedObject;
|
||||
var closestSector = transformSync.SectorSync.GetClosestSector(attachedObject.transform);
|
||||
if (closestSector == default(QSBSector))
|
||||
{
|
||||
|
@ -1,9 +1,9 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
using QSB.Syncs;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@ -12,12 +12,12 @@ namespace QSB.SectorSync
|
||||
{
|
||||
public class SectorSync : MonoBehaviour
|
||||
{
|
||||
public bool IsReady { get; private set; }
|
||||
public List<QSBSector> SectorList = new List<QSBSector>();
|
||||
|
||||
private OWRigidbody _attachedOWRigidbody;
|
||||
private SectorDetector _sectorDetector;
|
||||
private TargetType _targetType;
|
||||
private bool _isReady;
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
@ -26,10 +26,11 @@ namespace QSB.SectorSync
|
||||
_sectorDetector.OnEnterSector -= AddSector;
|
||||
_sectorDetector.OnExitSector -= RemoveSector;
|
||||
}
|
||||
_isReady = false;
|
||||
|
||||
IsReady = false;
|
||||
}
|
||||
|
||||
public void Init<T>(SectorDetector detector, ISectoredSync<T> sectoredSync)
|
||||
public void Init(SectorDetector detector, TargetType type)
|
||||
{
|
||||
if (_sectorDetector != null)
|
||||
{
|
||||
@ -55,8 +56,8 @@ namespace QSB.SectorSync
|
||||
|
||||
PopulateSectorList();
|
||||
|
||||
_targetType = sectoredSync.Type;
|
||||
_isReady = true;
|
||||
_targetType = type;
|
||||
IsReady = true;
|
||||
}
|
||||
|
||||
private void PopulateSectorList()
|
||||
@ -117,15 +118,15 @@ namespace QSB.SectorSync
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_isReady)
|
||||
if (!IsReady)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to use GetClosestSector before it was initialized. Transform:{trans.name}", MessageType.Warning);
|
||||
DebugLog.ToConsole($"Warning - Tried to use GetClosestSector() before this SectorSync is ready. Transform:{trans.name} Stacktrace:\r\n{Environment.StackTrace}", MessageType.Warning);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_sectorDetector == null || _attachedOWRigidbody == null || _targetType == TargetType.None)
|
||||
{
|
||||
_isReady = false;
|
||||
IsReady = false;
|
||||
DebugLog.ToConsole($"Error - SectorSync is no longer ready. Detector Null : {_sectorDetector == null}, OWRigidbody Null : {_attachedOWRigidbody == null}, None TargetType : {_targetType == TargetType.None}", MessageType.Error);
|
||||
return null;
|
||||
}
|
||||
|
@ -1,30 +1,20 @@
|
||||
using OWML.Utils;
|
||||
using HarmonyLib;
|
||||
using OWML.Utils;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ShipSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class ShipPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
{
|
||||
Prefix(nameof(HatchController_OnPressInteract));
|
||||
Prefix(nameof(HatchController_OnEntry));
|
||||
Prefix(nameof(ShipTractorBeamSwitch_OnTriggerExit));
|
||||
Prefix(nameof(InteractZone_UpdateInteractVolume));
|
||||
Prefix(nameof(ShipElectricalComponent_OnEnterShip));
|
||||
Prefix(nameof(ShipElectricalComponent_OnExitShip));
|
||||
Prefix(nameof(ShipComponent_SetDamaged));
|
||||
Prefix(nameof(ShipHull_FixedUpdate));
|
||||
Prefix(nameof(ShipDamageController_OnImpact));
|
||||
Postfix(nameof(ShipComponent_RepairTick));
|
||||
Prefix(nameof(ShipHull_RepairTick));
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(HatchController), nameof(HatchController.OnPressInteract))]
|
||||
public static bool HatchController_OnPressInteract()
|
||||
{
|
||||
if (!PlayerState.IsInsideShip())
|
||||
@ -37,6 +27,8 @@ namespace QSB.ShipSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(HatchController), nameof(HatchController.OnEntry))]
|
||||
public static bool HatchController_OnEntry(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
@ -47,9 +39,11 @@ namespace QSB.ShipSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ShipTractorBeamSwitch_OnTriggerExit(Collider hitCollider, bool ____isPlayerInShip, bool ____functional)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipTractorBeamSwitch), nameof(ShipTractorBeamSwitch.OnTriggerExit))]
|
||||
public static bool ShipTractorBeamSwitch_OnTriggerExit(ShipTractorBeamSwitch __instance, Collider hitCollider)
|
||||
{
|
||||
if (!____isPlayerInShip && ____functional && hitCollider.CompareTag("PlayerDetector") && !ShipManager.Instance.HatchController.GetValue<GameObject>("_hatchObject").activeSelf)
|
||||
if (!__instance._isPlayerInShip && __instance._functional && hitCollider.CompareTag("PlayerDetector") && !ShipManager.Instance.HatchController._hatchObject.activeSelf)
|
||||
{
|
||||
ShipManager.Instance.HatchController.Invoke("CloseHatch");
|
||||
ShipManager.Instance.ShipTractorBeam.DeactivateTractorBeam();
|
||||
@ -59,7 +53,16 @@ namespace QSB.ShipSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool InteractZone_UpdateInteractVolume(InteractZone __instance, OWCamera ____playerCam, ref bool ____focused)
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(SingleInteractionVolume), nameof(SingleInteractionVolume.UpdateInteractVolume))]
|
||||
public static void SingleInteractionVolume_UpdateInteractVolume_Stub(object instance)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(InteractZone), nameof(InteractZone.UpdateInteractVolume))]
|
||||
public static bool InteractZone_UpdateInteractVolume(InteractZone __instance)
|
||||
{
|
||||
/* Angle for interaction with the ship hatch
|
||||
*
|
||||
@ -78,64 +81,86 @@ namespace QSB.ShipSync.Patches
|
||||
return true;
|
||||
}
|
||||
|
||||
var angle = 2f * Vector3.Angle(____playerCam.transform.forward, __instance.transform.forward);
|
||||
var angle = 2f * Vector3.Angle(__instance._playerCam.transform.forward, __instance.transform.forward);
|
||||
|
||||
____focused = PlayerState.IsInsideShip()
|
||||
__instance._focused = PlayerState.IsInsideShip()
|
||||
? angle <= 80
|
||||
: angle >= 280;
|
||||
|
||||
__instance.CallBase<InteractZone, SingleInteractionVolume>("UpdateInteractVolume");
|
||||
SingleInteractionVolume_UpdateInteractVolume_Stub(__instance as SingleInteractionVolume);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ShipElectricalComponent_OnEnterShip(ShipElectricalComponent __instance, bool ____damaged, ElectricalSystem ____electricalSystem)
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(ShipComponent), nameof(ShipComponent.OnEnterShip))]
|
||||
public static void ShipComponent_OnEnterShip_Stub(object instance)
|
||||
{
|
||||
__instance.CallBase<ShipElectricalComponent, ShipComponent>("OnEnterShip");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipElectricalComponent), nameof(ShipElectricalComponent.OnEnterShip))]
|
||||
public static bool ShipElectricalComponent_OnEnterShip(ShipElectricalComponent __instance)
|
||||
{
|
||||
ShipComponent_OnEnterShip_Stub(__instance as ShipComponent);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ShipElectricalComponent_OnExitShip(ShipElectricalComponent __instance, bool ____damaged, ElectricalSystem ____electricalSystem)
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(ShipComponent), nameof(ShipComponent.OnExitShip))]
|
||||
public static void ShipComponent_OnExitShip_Stub(object instance)
|
||||
{
|
||||
__instance.CallBase<ShipElectricalComponent, ShipComponent>("OnExitShip");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipElectricalComponent), nameof(ShipElectricalComponent.OnExitShip))]
|
||||
public static bool ShipElectricalComponent_OnExitShip(ShipElectricalComponent __instance)
|
||||
{
|
||||
ShipComponent_OnExitShip_Stub(__instance as ShipComponent);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ShipComponent_SetDamaged(ShipComponent __instance, bool damaged, ref bool ____damaged, ref float ____repairFraction, DamageEffect ____damageEffect)
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipComponent), nameof(ShipComponent.SetDamaged))]
|
||||
public static bool ShipComponent_SetDamaged(ShipComponent __instance, bool damaged)
|
||||
{
|
||||
if (____damaged == damaged)
|
||||
if (__instance._damaged == damaged)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (damaged)
|
||||
{
|
||||
____damaged = true;
|
||||
____repairFraction = 0f;
|
||||
__instance._damaged = true;
|
||||
__instance._repairFraction = 0f;
|
||||
__instance.GetType().GetAnyMethod("OnComponentDamaged").Invoke(__instance, null);
|
||||
__instance.RaiseEvent("OnDamaged", __instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBComponentDamaged, __instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
____damaged = false;
|
||||
____repairFraction = 1f;
|
||||
__instance._damaged = false;
|
||||
__instance._repairFraction = 1f;
|
||||
__instance.GetType().GetAnyMethod("OnComponentRepaired").Invoke(__instance, null);
|
||||
__instance.RaiseEvent("OnRepaired", __instance);
|
||||
QSBEventManager.FireEvent(EventNames.QSBComponentRepaired, __instance);
|
||||
}
|
||||
|
||||
__instance.GetType().GetAnyMethod("UpdateColliderState").Invoke(__instance, null);
|
||||
if (____damageEffect)
|
||||
if (__instance._damageEffect)
|
||||
{
|
||||
____damageEffect.SetEffectBlend(1f - ____repairFraction);
|
||||
__instance._damageEffect.SetEffectBlend(1f - __instance._repairFraction);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipHull), nameof(ShipHull.FixedUpdate))]
|
||||
public static bool ShipHull_FixedUpdate(ShipHull __instance, ref ImpactData ____dominantImpact, ref float ____integrity, ref bool ____damaged, DamageEffect ____damageEffect, ShipComponent[] ____components)
|
||||
{
|
||||
if (____dominantImpact != null)
|
||||
@ -186,15 +211,21 @@ namespace QSB.ShipSync.Patches
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipDamageController), nameof(ShipDamageController.OnImpact))]
|
||||
public static bool ShipDamageController_OnImpact()
|
||||
=> ShipManager.Instance.HasAuthority;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(ShipComponent), nameof(ShipComponent.RepairTick))]
|
||||
public static void ShipComponent_RepairTick(ShipComponent __instance, float ____repairFraction)
|
||||
{
|
||||
QSBEventManager.FireEvent(EventNames.QSBComponentRepairTick, __instance, ____repairFraction);
|
||||
return;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ShipHull), nameof(ShipHull.RepairTick))]
|
||||
public static bool ShipHull_RepairTick(ShipHull __instance, ref float ____integrity, ref bool ____damaged, DamageEffect ____damageEffect, float ____repairTime)
|
||||
{
|
||||
if (!____damaged)
|
||||
|
@ -78,6 +78,7 @@ namespace QSB.ShipSync
|
||||
DebugLog.ToConsole($"Warning - ShipTransformSync's LocalInstance is not null, but it's gameobject is null!", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkServer.Destroy(ShipTransformSync.LocalInstance.gameObject);
|
||||
}
|
||||
|
||||
@ -85,7 +86,8 @@ namespace QSB.ShipSync
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Tried to spawn ship, but LocalPlayer's TransformSync is null!", MessageType.Error);
|
||||
}
|
||||
QNetworkServer.SpawnWithClientAuthority(Instantiate(QSBNetworkManager.Instance.ShipPrefab), QSBPlayerManager.LocalPlayer.TransformSync.gameObject);
|
||||
|
||||
Instantiate(QSBNetworkManager.Instance.ShipPrefab).SpawnWithServerAuthority();
|
||||
}
|
||||
|
||||
QSBWorldSync.Init<QSBShipComponent, ShipComponent>();
|
||||
@ -106,6 +108,9 @@ namespace QSB.ShipSync
|
||||
UpdateElectricalComponent();
|
||||
}
|
||||
|
||||
public bool IsPlayerInShip(PlayerInfo player)
|
||||
=> _playersInShip.Contains(player);
|
||||
|
||||
private void UpdateElectricalComponent()
|
||||
{
|
||||
var electricalSystem = ShipElectricalComponent.GetValue<ElectricalSystem>("_electricalSystem");
|
||||
|
@ -1,9 +1,6 @@
|
||||
using QSB.Player;
|
||||
using QSB.SectorSync;
|
||||
using QSB.Syncs.RigidbodySync;
|
||||
using QSB.Utility;
|
||||
using QSB.Syncs.Sectored.Rigidbodies;
|
||||
using QSB.WorldSync;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.ShipSync.TransformSync
|
||||
{
|
||||
@ -11,6 +8,9 @@ namespace QSB.ShipSync.TransformSync
|
||||
{
|
||||
public static ShipTransformSync LocalInstance { get; private set; }
|
||||
|
||||
private const int ForcePositionAfterUpdates = 50;
|
||||
private int _updateCount;
|
||||
|
||||
public override bool IsReady
|
||||
=> Locator.GetShipBody() != null;
|
||||
|
||||
@ -20,34 +20,65 @@ namespace QSB.ShipSync.TransformSync
|
||||
LocalInstance = this;
|
||||
}
|
||||
|
||||
protected override Component InitLocalTransform() => throw new System.NotImplementedException();
|
||||
protected override Component InitRemoteTransform() => throw new System.NotImplementedException();
|
||||
|
||||
protected override OWRigidbody GetRigidbody()
|
||||
{
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetShipDetector().GetComponent<SectorDetector>(), this));
|
||||
QSBCore.UnityEvents.RunWhen(() => WorldObjectManager.AllReady, () => SectorSync.Init(Locator.GetShipDetector().GetComponent<SectorDetector>(), TargetType.Ship));
|
||||
return Locator.GetShipBody();
|
||||
}
|
||||
|
||||
private void ForcePosition()
|
||||
{
|
||||
if (ReferenceTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_Unparented();
|
||||
var targetRot = _intermediaryTransform.GetTargetRotation_Unparented();
|
||||
|
||||
(AttachedObject as OWRigidbody).SetPosition(targetPos);
|
||||
(AttachedObject as OWRigidbody).SetRotation(targetRot);
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (HasAuthority && ShipManager.Instance.CurrentFlyer != QSBPlayerManager.LocalPlayerId && ShipManager.Instance.CurrentFlyer != uint.MaxValue)
|
||||
if (!UpdateSectors())
|
||||
{
|
||||
DebugLog.ToConsole("Warning - Has authority, but is not current flyer!", OWML.Common.MessageType.Warning);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasAuthority && ShipManager.Instance.CurrentFlyer == QSBPlayerManager.LocalPlayerId)
|
||||
// Dont do base... this is a replacement!
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Doesn't have authority, but is current flyer!", OWML.Common.MessageType.Warning);
|
||||
return false;
|
||||
SetValuesToSync();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.UpdateTransform();
|
||||
_updateCount++;
|
||||
|
||||
if (_updateCount >= ForcePositionAfterUpdates)
|
||||
{
|
||||
_updateCount = 0;
|
||||
ForcePosition();
|
||||
}
|
||||
|
||||
if (ReferenceTransform == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_Unparented();
|
||||
|
||||
var targetVelocity = ReferenceTransform.GetAttachedOWRigidbody().GetPointVelocity(targetPos) + _relativeVelocity;
|
||||
var targetAngularVelocity = ReferenceTransform.GetAttachedOWRigidbody().GetAngularVelocity() + _relativeAngularVelocity;
|
||||
|
||||
SetVelocity(AttachedObject as OWRigidbody, targetVelocity);
|
||||
(AttachedObject as OWRigidbody).SetAngularVelocity(targetAngularVelocity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override TargetType Type => TargetType.Ship;
|
||||
|
||||
public override bool UseInterpolation => true;
|
||||
protected override float DistanceLeeway => 20f;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ namespace QSB.StatueSync.Events
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QSBEventManager.FireEvent(EventNames.QSBServerState, ServerState.InStatueCutscene);
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,18 @@
|
||||
using QSB.Events;
|
||||
using HarmonyLib;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.StatueSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class StatuePatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
=> Prefix(nameof(MemoryUplinkTrigger_Update));
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(MemoryUplinkTrigger), nameof(MemoryUplinkTrigger.Update))]
|
||||
public static bool MemoryUplinkTrigger_Update(bool ____waitForPlayerGrounded)
|
||||
{
|
||||
if (StatueManager.Instance.HasStartedStatueLocally)
|
||||
|
@ -1,14 +0,0 @@
|
||||
using QSB.SectorSync;
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
|
||||
namespace QSB.Syncs
|
||||
{
|
||||
public interface ISectoredSync<T>
|
||||
{
|
||||
SectorSync.SectorSync SectorSync { get; }
|
||||
QSBSector ReferenceSector { get; }
|
||||
TargetType Type { get; }
|
||||
|
||||
void SetReferenceSector(QSBSector sector);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using OWML.Common;
|
||||
using QSB.Utility;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs
|
||||
@ -58,7 +58,7 @@ namespace QSB.Syncs
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} ({MethodBase.GetCurrentMethod().Name})", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} \r\n{Environment.StackTrace}", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ namespace QSB.Syncs
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} ({MethodBase.GetCurrentMethod().Name})", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} \r\n{Environment.StackTrace}", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ namespace QSB.Syncs
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} ({MethodBase.GetCurrentMethod().Name})", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} \r\n{Environment.StackTrace}", MessageType.Error);
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ namespace QSB.Syncs
|
||||
{
|
||||
if (_referenceTransform == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} ({MethodBase.GetCurrentMethod().Name})", MessageType.Error);
|
||||
DebugLog.ToConsole($"Error - _referenceTransform has not been set for {_attachedTransform.name} \r\n{Environment.StackTrace}", MessageType.Error);
|
||||
return Quaternion.identity;
|
||||
}
|
||||
|
||||
|
@ -1,120 +0,0 @@
|
||||
using QSB.SectorSync;
|
||||
using QSB.SectorSync.WorldObjects;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.Syncs.RigidbodySync
|
||||
{
|
||||
public abstract class SectoredRigidbodySync : UnparentedBaseRigidbodySync, ISectoredSync<OWRigidbody>
|
||||
{
|
||||
public QSBSector ReferenceSector { get; set; }
|
||||
public SectorSync.SectorSync SectorSync { get; private set; }
|
||||
public abstract TargetType Type { get; }
|
||||
|
||||
public override bool IgnoreDisabledAttachedObject => false;
|
||||
public override bool IgnoreNullReferenceTransform => true;
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
|
||||
QSBSectorManager.Instance.SectoredRigidbodySyncs.Add(this);
|
||||
base.Start();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
QSBSectorManager.Instance.SectoredRigidbodySyncs.Remove(this);
|
||||
if (SectorSync != null)
|
||||
{
|
||||
Destroy(SectorSync);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
base.Init();
|
||||
if (!QSBSectorManager.Instance.IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
{
|
||||
SetReferenceTransform(closestSector.Transform);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
if (ReferenceSector != null)
|
||||
{
|
||||
writer.Write(ReferenceSector.ObjectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(-1);
|
||||
}
|
||||
|
||||
base.SerializeTransform(writer, initialState);
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
reader.ReadInt32();
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var sectorId = reader.ReadInt32();
|
||||
var sector = sectorId == -1
|
||||
? null
|
||||
: QSBWorldSync.GetWorldFromId<QSBSector>(sectorId);
|
||||
|
||||
if (sector != ReferenceSector)
|
||||
{
|
||||
SetReferenceSector(sector);
|
||||
}
|
||||
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if ((ReferenceTransform == null || ReferenceSector == null || _intermediaryTransform.GetReferenceTransform() == null) && QSBSectorManager.Instance.IsReady && HasAuthority)
|
||||
{
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
{
|
||||
SetReferenceTransform(closestSector.Transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return base.UpdateTransform();
|
||||
}
|
||||
|
||||
public void SetReferenceSector(QSBSector sector)
|
||||
{
|
||||
ReferenceSector = sector;
|
||||
SetReferenceTransform(sector?.Transform);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,32 +4,30 @@ using QSB.SectorSync.WorldObjects;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Transport;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.TransformSync
|
||||
namespace QSB.Syncs.Sectored
|
||||
{
|
||||
public abstract class SectoredTransformSync : BaseTransformSync, ISectoredSync<Transform>
|
||||
public abstract class BaseSectoredSync : SyncBase
|
||||
{
|
||||
public override bool IgnoreDisabledAttachedObject => false;
|
||||
public override bool IgnoreNullReferenceTransform => true;
|
||||
|
||||
public QSBSector ReferenceSector { get; set; }
|
||||
public SectorSync.SectorSync SectorSync { get; private set; }
|
||||
public abstract TargetType Type { get; }
|
||||
|
||||
public override bool IgnoreNullReferenceTransform => true;
|
||||
public override bool IgnoreDisabledAttachedObject => false;
|
||||
|
||||
private int _sectorIdWaitingSlot = int.MinValue;
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
|
||||
QSBSectorManager.Instance.SectoredTransformSyncs.Add(this);
|
||||
QSBSectorManager.Instance.SectoredSyncs.Add(this);
|
||||
base.Start();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
QSBSectorManager.Instance.SectoredTransformSyncs.Remove(this);
|
||||
QSBSectorManager.Instance.SectoredSyncs.Remove(this);
|
||||
if (SectorSync != null)
|
||||
{
|
||||
Destroy(SectorSync);
|
||||
@ -49,6 +47,11 @@ namespace QSB.Syncs.TransformSync
|
||||
return;
|
||||
}
|
||||
|
||||
QSBCore.UnityEvents.RunWhen(() => SectorSync.IsReady, InitSector);
|
||||
}
|
||||
|
||||
private void InitSector()
|
||||
{
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
{
|
||||
@ -56,7 +59,7 @@ namespace QSB.Syncs.TransformSync
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"INIT - {PlayerId}.{GetType().Name}'s closest sector is null!");
|
||||
DebugLog.ToConsole($"Warning - {_logName}'s initial sector was null.", OWML.Common.MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,26 +107,25 @@ namespace QSB.Syncs.TransformSync
|
||||
|
||||
if (!QSBPlayerManager.PlayerExists(PlayerId))
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to serialize {_logName} before the right player exists.", OWML.Common.MessageType.Warning);
|
||||
writer.Write(-1);
|
||||
}
|
||||
else if (!Player.PlayerStates.IsReady)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Tried to serialize {_logName} before the player was ready.", OWML.Common.MessageType.Warning);
|
||||
writer.Write(-1);
|
||||
}
|
||||
|
||||
if (ReferenceSector != null)
|
||||
else if (ReferenceSector != null)
|
||||
{
|
||||
writer.Write(ReferenceSector.ObjectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - ReferenceSector of {PlayerId}.{GetType().Name} is null.", OWML.Common.MessageType.Warning);
|
||||
if (_isInitialized)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - ReferenceSector of {PlayerId}.{GetType().Name} is null.", OWML.Common.MessageType.Warning);
|
||||
}
|
||||
|
||||
writer.Write(-1);
|
||||
}
|
||||
|
||||
base.SerializeTransform(writer, initialState);
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
@ -134,11 +136,10 @@ namespace QSB.Syncs.TransformSync
|
||||
sectorId = reader.ReadInt32();
|
||||
if (initialState && sectorId != -1)
|
||||
{
|
||||
DebugLog.DebugWrite($"SET WAITING FOR SECTOR SET - id {sectorId}");
|
||||
DebugLog.DebugWrite($"{_logName} set waiting sector id:{sectorId}");
|
||||
_sectorIdWaitingSlot = sectorId;
|
||||
}
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -152,17 +153,14 @@ namespace QSB.Syncs.TransformSync
|
||||
if (sector == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {PlayerId}.{GetType().Name} got sector of ID -1.", OWML.Common.MessageType.Error);
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
return;
|
||||
}
|
||||
|
||||
SetReferenceSector(sector);
|
||||
}
|
||||
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
protected bool UpdateSectors()
|
||||
{
|
||||
var referenceNull = ReferenceTransform == null || ReferenceSector == null || _intermediaryTransform.GetReferenceTransform() == null;
|
||||
var sectorManagerReady = QSBSectorManager.Instance.IsReady;
|
||||
@ -175,31 +173,44 @@ namespace QSB.Syncs.TransformSync
|
||||
$"Transform:{ReferenceTransform == null}, Sector:{ReferenceSector == null}, Intermediary:{_intermediaryTransform.GetReferenceTransform() == null}",
|
||||
OWML.Common.MessageType.Warning);
|
||||
}
|
||||
return base.UpdateTransform();
|
||||
|
||||
DebugLog.DebugWrite($"{_logName} : Sector Manager not ready.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasAuthority)
|
||||
{
|
||||
return base.UpdateTransform();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (referenceNull)
|
||||
{
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
if (SectorSync.IsReady)
|
||||
{
|
||||
SetReferenceTransform(closestSector.Transform);
|
||||
var closestSector = SectorSync.GetClosestSector(AttachedObject.transform);
|
||||
if (closestSector != null)
|
||||
{
|
||||
SetReferenceTransform(closestSector.Transform);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No closest sector found to {PlayerId}.{GetType().Name}!", OWML.Common.MessageType.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.ToConsole($"Error - No closest sector found to {PlayerId}.{GetType().Name}!", OWML.Common.MessageType.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return base.UpdateTransform();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
=> UpdateSectors();
|
||||
|
||||
public void SetReferenceSector(QSBSector sector)
|
||||
{
|
||||
ReferenceSector = sector;
|
@ -1,63 +1,46 @@
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Transport;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.RigidbodySync
|
||||
namespace QSB.Syncs.Sectored.Rigidbodies
|
||||
{
|
||||
public abstract class UnparentedBaseRigidbodySync : SyncBase
|
||||
public abstract class SectoredRigidbodySync : BaseSectoredSync
|
||||
{
|
||||
public override bool ShouldReparentAttachedObject => false;
|
||||
|
||||
public const float PositionMovedThreshold = 0.05f;
|
||||
public const float AngleRotatedThreshold = 0.05f;
|
||||
public const float VelocityChangeThreshold = 0.05f;
|
||||
public const float AngVelocityChangeThreshold = 0.05f;
|
||||
|
||||
protected Vector3 _relativeVelocity;
|
||||
protected Vector3 _relativeAngularVelocity;
|
||||
protected Vector3 _prevVelocity;
|
||||
protected Vector3 _prevAngularVelocity;
|
||||
|
||||
/// <summary>
|
||||
/// The previous position of the VISIBLE object, as if parented to the reference.
|
||||
/// </summary>
|
||||
protected Vector3 _localPrevPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The previous rotation of the VISIBLE object, as if parented to the reference.
|
||||
/// </summary>
|
||||
protected Quaternion _localPrevRotation;
|
||||
|
||||
protected Vector3 _localPrevVelocity;
|
||||
protected Vector3 _localPrevAngularVelocity;
|
||||
|
||||
protected abstract OWRigidbody GetRigidbody();
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
|
||||
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
|
||||
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy() => QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
|
||||
private void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isInUniverse)
|
||||
=> _isInitialized = false;
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
if (!QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {_logName} is being init-ed when not in the universe!", MessageType.Error);
|
||||
}
|
||||
|
||||
AttachedObject = GetRigidbody();
|
||||
_isInitialized = true;
|
||||
}
|
||||
protected override Component SetAttachedObject()
|
||||
=> GetRigidbody();
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
/* We need to send :
|
||||
* - Position
|
||||
* - Rotation
|
||||
* - Velocity
|
||||
* - Angular velocity
|
||||
* We can't store the last two on the IntermediaryTransform, so they come from fields.
|
||||
*/
|
||||
base.SerializeTransform(writer, initialState);
|
||||
|
||||
var worldPos = _intermediaryTransform.GetPosition();
|
||||
var worldRot = _intermediaryTransform.GetRotation();
|
||||
@ -77,6 +60,8 @@ namespace QSB.Syncs.RigidbodySync
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
reader.ReadVector3();
|
||||
@ -112,14 +97,24 @@ namespace QSB.Syncs.RigidbodySync
|
||||
}
|
||||
}
|
||||
|
||||
protected void SetValuesToSync()
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
_relativeVelocity = GetRelativeVelocity();
|
||||
_relativeAngularVelocity = (AttachedObject as OWRigidbody).GetRelativeAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody());
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (!base.UpdateTransform())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
_relativeVelocity = GetRelativeVelocity();
|
||||
_relativeAngularVelocity = (AttachedObject as OWRigidbody).GetRelativeAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody());
|
||||
SetValuesToSync();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -131,28 +126,101 @@ namespace QSB.Syncs.RigidbodySync
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3 positionToSet = targetPos;
|
||||
Quaternion rotationToSet = targetRot;
|
||||
|
||||
if (UseInterpolation)
|
||||
{
|
||||
(AttachedObject as OWRigidbody).SetPosition(SmartSmoothDamp(AttachedObject.transform.position, targetPos));
|
||||
(AttachedObject as OWRigidbody).SetRotation(QuaternionHelper.SmoothDamp(AttachedObject.transform.rotation, targetRot, ref _rotationSmoothVelocity, SmoothTime));
|
||||
positionToSet = SmartSmoothDamp(AttachedObject.transform.position, targetPos);
|
||||
rotationToSet = QuaternionHelper.SmoothDamp(AttachedObject.transform.rotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
else
|
||||
|
||||
var hasMoved = CustomHasMoved(
|
||||
_intermediaryTransform.GetTargetPosition_ParentedToReference(),
|
||||
_localPrevPosition,
|
||||
_intermediaryTransform.GetTargetRotation_ParentedToReference(),
|
||||
_localPrevRotation,
|
||||
_relativeVelocity,
|
||||
_localPrevVelocity,
|
||||
_relativeAngularVelocity,
|
||||
_localPrevAngularVelocity);
|
||||
|
||||
_localPrevPosition = _intermediaryTransform.GetTargetPosition_ParentedToReference();
|
||||
_localPrevRotation = _intermediaryTransform.GetTargetRotation_ParentedToReference();
|
||||
_localPrevVelocity = _relativeVelocity;
|
||||
_localPrevAngularVelocity = _relativeAngularVelocity;
|
||||
|
||||
if (!hasMoved)
|
||||
{
|
||||
(AttachedObject as OWRigidbody).SetPosition(targetPos);
|
||||
(AttachedObject as OWRigidbody).SetRotation(targetRot);
|
||||
return true;
|
||||
}
|
||||
|
||||
var currentVelocity = GetRelativeVelocity();
|
||||
var targetVelocity = ReferenceTransform.GetAttachedOWRigidbody().GetPointVelocity(targetPos) + _relativeVelocity;
|
||||
var adjustedTarget = targetVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameWorldVelocity();
|
||||
//(AttachedObject as OWRigidbody).SetPosition(positionToSet);
|
||||
//(AttachedObject as OWRigidbody).SetRotation(rotationToSet);
|
||||
|
||||
SetVelocity((AttachedObject as OWRigidbody), targetVelocity);
|
||||
(AttachedObject as OWRigidbody).SetAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody().GetAngularVelocity() + _relativeAngularVelocity);
|
||||
(AttachedObject as OWRigidbody).MoveToPosition(positionToSet);
|
||||
(AttachedObject as OWRigidbody).MoveToRotation(rotationToSet);
|
||||
|
||||
var targetVelocity = ReferenceTransform.GetAttachedOWRigidbody().GetPointVelocity(targetPos) + _relativeVelocity;
|
||||
var targetAngularVelocity = ReferenceTransform.GetAttachedOWRigidbody().GetAngularVelocity() + _relativeAngularVelocity;
|
||||
|
||||
SetVelocity(AttachedObject as OWRigidbody, targetVelocity);
|
||||
(AttachedObject as OWRigidbody).SetAngularVelocity(targetAngularVelocity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetVelocity(OWRigidbody rigidbody, Vector3 relativeVelocity)
|
||||
public override bool HasMoved()
|
||||
=> CustomHasMoved(
|
||||
_intermediaryTransform.GetPosition(),
|
||||
_prevPosition,
|
||||
_intermediaryTransform.GetRotation(),
|
||||
_prevRotation,
|
||||
_relativeVelocity,
|
||||
_prevVelocity,
|
||||
_relativeAngularVelocity,
|
||||
_prevAngularVelocity);
|
||||
|
||||
// OPTIMIZE : optimize by using sqrMagnitude
|
||||
private bool CustomHasMoved(
|
||||
Vector3 newPosition,
|
||||
Vector3 prevPosition,
|
||||
Quaternion newRotation,
|
||||
Quaternion prevRotation,
|
||||
Vector3 newVelocity,
|
||||
Vector3 prevVelocity,
|
||||
Vector3 newAngVelocity,
|
||||
Vector3 prevAngVelocity)
|
||||
{
|
||||
var displacementMagnitude = (newPosition - prevPosition).magnitude;
|
||||
|
||||
if (displacementMagnitude > PositionMovedThreshold)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Quaternion.Angle(newRotation, prevRotation) > AngleRotatedThreshold)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var velocityChangeMagnitude = (newVelocity - prevVelocity).magnitude;
|
||||
var angularVelocityChangeMagnitude = (newAngVelocity - prevAngVelocity).magnitude;
|
||||
if (velocityChangeMagnitude > VelocityChangeThreshold)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (angularVelocityChangeMagnitude > AngVelocityChangeThreshold)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : why? isn't owrigidbody.setvelocity the same...? :P
|
||||
protected void SetVelocity(OWRigidbody rigidbody, Vector3 relativeVelocity)
|
||||
{
|
||||
var isRunningKinematic = rigidbody.RunningKinematicSimulation();
|
||||
var currentVelocity = rigidbody.GetValue<Vector3>("_currentVelocity");
|
||||
@ -160,65 +228,18 @@ namespace QSB.Syncs.RigidbodySync
|
||||
if (isRunningKinematic)
|
||||
{
|
||||
var kinematicRigidbody = rigidbody.GetValue<KinematicRigidbody>("_kinematicRigidbody");
|
||||
kinematicRigidbody.velocity = relativeVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameWorldVelocity();
|
||||
kinematicRigidbody.velocity = relativeVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameVelocity_Internal();
|
||||
}
|
||||
else
|
||||
{
|
||||
var normalRigidbody = rigidbody.GetValue<Rigidbody>("_rigidbody");
|
||||
normalRigidbody.velocity = relativeVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameWorldVelocity();
|
||||
normalRigidbody.velocity = relativeVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameVelocity_Internal();
|
||||
}
|
||||
|
||||
rigidbody.SetValue("_lastVelocity", currentVelocity);
|
||||
rigidbody.SetValue("_currentVelocity", relativeVelocity);
|
||||
}
|
||||
|
||||
public void SetReferenceTransform(Transform transform)
|
||||
{
|
||||
if (ReferenceTransform == transform)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReferenceTransform = transform;
|
||||
_intermediaryTransform.SetReferenceTransform(transform);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : optimize by using sqrMagnitude
|
||||
public override bool HasMoved()
|
||||
{
|
||||
var displacementMagnitude = (_intermediaryTransform.GetPosition() - _prevPosition).magnitude;
|
||||
|
||||
if (displacementMagnitude > 1E-03f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Quaternion.Angle(_intermediaryTransform.GetRotation(), _prevRotation) > 1E-03f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var velocityChangeMagnitude = (_relativeVelocity - _prevVelocity).magnitude;
|
||||
var angularVelocityChangeMagnitude = (_relativeAngularVelocity - _prevAngularVelocity).magnitude;
|
||||
if (velocityChangeMagnitude > 1E-03f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (angularVelocityChangeMagnitude > 1E-03f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public float GetVelocityChangeMagnitude()
|
||||
=> (_relativeVelocity - _prevVelocity).magnitude;
|
||||
|
||||
@ -247,4 +268,4 @@ namespace QSB.Syncs.RigidbodySync
|
||||
return (AttachedObject as OWRigidbody).GetVelocity() - pointVelocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
105
QSB/Syncs/Sectored/Transforms/SectoredTransformSync.cs
Normal file
105
QSB/Syncs/Sectored/Transforms/SectoredTransformSync.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using OWML.Common;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Transport;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.Sectored.Transforms
|
||||
{
|
||||
public abstract class SectoredTransformSync : BaseSectoredSync
|
||||
{
|
||||
public override bool ShouldReparentAttachedObject => true;
|
||||
|
||||
protected abstract Component InitLocalTransform();
|
||||
protected abstract Component InitRemoteTransform();
|
||||
|
||||
protected override Component SetAttachedObject()
|
||||
=> HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
base.SerializeTransform(writer, initialState);
|
||||
|
||||
var worldPos = _intermediaryTransform.GetPosition();
|
||||
var worldRot = _intermediaryTransform.GetRotation();
|
||||
writer.Write(worldPos);
|
||||
SerializeRotation(writer, worldRot);
|
||||
_prevPosition = worldPos;
|
||||
_prevRotation = worldRot;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
base.DeserializeTransform(reader, initialState);
|
||||
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var pos = reader.ReadVector3();
|
||||
var rot = DeserializeRotation(reader);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
_intermediaryTransform.SetPosition(pos);
|
||||
_intermediaryTransform.SetRotation(rot);
|
||||
|
||||
if (_intermediaryTransform.GetPosition() == Vector3.zero)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {_logName} at (0,0,0)! - Given position was {pos}", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (!base.UpdateTransform())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
if (ReferenceTransform != null)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
_intermediaryTransform.SetPosition(Vector3.zero);
|
||||
_intermediaryTransform.SetRotation(Quaternion.identity);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_ParentedToReference();
|
||||
var targetRot = _intermediaryTransform.GetTargetRotation_ParentedToReference();
|
||||
if (targetPos != Vector3.zero && _intermediaryTransform.GetTargetPosition_Unparented() != Vector3.zero)
|
||||
{
|
||||
if (UseInterpolation)
|
||||
{
|
||||
AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, targetPos);
|
||||
AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedObject.transform.localPosition = targetPos;
|
||||
AttachedObject.transform.localRotation = targetRot;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,45 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET.Components;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs
|
||||
{
|
||||
/*
|
||||
* Rewrite number : 9
|
||||
* God has cursed me for my hubris, and my work is never finished.
|
||||
*/
|
||||
|
||||
public abstract class SyncBase : QNetworkTransform
|
||||
{
|
||||
private static readonly Dictionary<uint, Dictionary<Type, SyncBase>> _storedTransformSyncs = new Dictionary<uint, Dictionary<Type, SyncBase>>();
|
||||
|
||||
public static T GetPlayers<T>(PlayerInfo player)
|
||||
where T : SyncBase
|
||||
{
|
||||
var dictOfOwnedSyncs = _storedTransformSyncs[player.PlayerId];
|
||||
var wantedSync = dictOfOwnedSyncs[typeof(T)];
|
||||
if (wantedSync == default)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - _storedTransformSyncs does not contain type:{typeof(T)} under player {player.PlayerId}. Attempting to find manually...", MessageType.Error);
|
||||
var allSyncs = Resources.FindObjectsOfTypeAll<T>();
|
||||
wantedSync = allSyncs.First(x => x.Player == player);
|
||||
if (wantedSync == default)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Could not find type:{typeof(T)} for player {player.PlayerId} manually!", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
return (T)wantedSync;
|
||||
}
|
||||
|
||||
public uint AttachedNetId
|
||||
{
|
||||
get
|
||||
@ -50,6 +81,7 @@ namespace QSB.Syncs
|
||||
public abstract bool UseInterpolation { get; }
|
||||
public abstract bool IgnoreDisabledAttachedObject { get; }
|
||||
public abstract bool IgnoreNullReferenceTransform { get; }
|
||||
public abstract bool ShouldReparentAttachedObject { get; }
|
||||
|
||||
public Component AttachedObject { get; set; }
|
||||
public Transform ReferenceTransform { get; set; }
|
||||
@ -63,22 +95,78 @@ namespace QSB.Syncs
|
||||
protected IntermediaryTransform _intermediaryTransform;
|
||||
protected bool _isInitialized;
|
||||
|
||||
protected abstract Component InitLocalTransform();
|
||||
protected abstract Component InitRemoteTransform();
|
||||
protected abstract Component SetAttachedObject();
|
||||
protected abstract bool UpdateTransform();
|
||||
protected abstract void Init();
|
||||
|
||||
protected Vector3 SmartSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
|
||||
public virtual void Start()
|
||||
{
|
||||
var distance = Vector3.Distance(currentPosition, targetPosition);
|
||||
if (distance > _previousDistance + DistanceLeeway)
|
||||
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
|
||||
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
|
||||
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
|
||||
if (Player == null)
|
||||
{
|
||||
_previousDistance = distance;
|
||||
return targetPosition;
|
||||
DebugLog.ToConsole($"Error - Player in start of {_logName} was null!", MessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
_previousDistance = distance;
|
||||
return Vector3.SmoothDamp(currentPosition, targetPosition, ref _positionSmoothVelocity, SmoothTime);
|
||||
if (!_storedTransformSyncs.ContainsKey(PlayerId))
|
||||
{
|
||||
_storedTransformSyncs.Add(PlayerId, new Dictionary<Type, SyncBase>());
|
||||
}
|
||||
|
||||
var playerDict = _storedTransformSyncs[PlayerId];
|
||||
playerDict[GetType()] = this;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (ShouldReparentAttachedObject)
|
||||
{
|
||||
if (!HasAuthority && AttachedObject != null)
|
||||
{
|
||||
Destroy(AttachedObject.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
|
||||
if (!QSBPlayerManager.PlayerExists(PlayerId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var playerDict = _storedTransformSyncs[PlayerId];
|
||||
playerDict.Remove(GetType());
|
||||
}
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
if (!QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {_logName} is being init-ed when not in the universe!", MessageType.Error);
|
||||
}
|
||||
|
||||
// TODO : maybe make it's own option
|
||||
if (ShouldReparentAttachedObject)
|
||||
{
|
||||
if (!HasAuthority && AttachedObject != null)
|
||||
{
|
||||
Destroy(AttachedObject.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
AttachedObject = SetAttachedObject();
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
protected virtual void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isInUniverse)
|
||||
{
|
||||
_isInitialized = false;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
@ -135,30 +223,72 @@ namespace QSB.Syncs
|
||||
return;
|
||||
}
|
||||
|
||||
var state = UpdateTransform();
|
||||
if (!state)
|
||||
UpdateTransform();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
protected Vector3 SmartSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
|
||||
{
|
||||
var distance = Vector3.Distance(currentPosition, targetPosition);
|
||||
if (distance > _previousDistance + DistanceLeeway)
|
||||
{
|
||||
/*
|
||||
DebugLog.DebugWrite($"{_logName} moved too far!" +
|
||||
$"\r\n CurrentPosition:{currentPosition}," +
|
||||
$"\r\n TargetPosition:{targetPosition}");
|
||||
*/
|
||||
_previousDistance = distance;
|
||||
return targetPosition;
|
||||
}
|
||||
|
||||
_previousDistance = distance;
|
||||
return Vector3.SmoothDamp(currentPosition, targetPosition, ref _positionSmoothVelocity, SmoothTime);
|
||||
}
|
||||
|
||||
public void SetReferenceTransform(Transform transform)
|
||||
{
|
||||
if (ReferenceTransform == transform)
|
||||
{
|
||||
DebugLog.ToConsole($"{_logName} UpdateTransform() fail.", MessageType.Error);
|
||||
base.Update();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
var expectedPosition = _intermediaryTransform.GetTargetPosition_Unparented();
|
||||
var actualPosition = AttachedObject.transform.position;
|
||||
var distance = Vector3.Distance(expectedPosition, actualPosition);
|
||||
if (distance > 20)
|
||||
{
|
||||
var intermediaryReference = _intermediaryTransform.GetReferenceTransform();
|
||||
DebugLog.ToConsole($"Warning - {_logName}'s AttachedObject ({AttachedObject?.name}) is far away from it's expected position! Info:" +
|
||||
$"\r\n AttachedObject's parent : {AttachedObject?.transform.parent?.name}" +
|
||||
$"\r\n Distance : {distance}" +
|
||||
$"\r\n ReferenceTransform : {(ReferenceTransform == null ? "NULL" : ReferenceTransform.name)}" +
|
||||
$"\r\n Intermediary's ReferenceTransform : {(intermediaryReference == null ? "NULL" : intermediaryReference.name)}", MessageType.Warning);
|
||||
}
|
||||
*/
|
||||
ReferenceTransform = transform;
|
||||
_intermediaryTransform.SetReferenceTransform(transform);
|
||||
|
||||
base.Update();
|
||||
if (ShouldReparentAttachedObject)
|
||||
{
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - AttachedObject was null for {_logName} when trying to set reference transform to {transform?.name}. Waiting until not null...", MessageType.Warning);
|
||||
QSBCore.UnityEvents.RunWhen(
|
||||
() => AttachedObject != null,
|
||||
() => ReparentAttachedObject(transform));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasAuthority)
|
||||
{
|
||||
ReparentAttachedObject(transform);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReparentAttachedObject(Transform newParent)
|
||||
{
|
||||
if (AttachedObject.transform.parent != null && AttachedObject.transform.parent.GetComponent<Sector>() == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Trying to reparent AttachedObject {AttachedObject.name} which wasnt attached to sector!", MessageType.Warning);
|
||||
}
|
||||
|
||||
AttachedObject.transform.SetParent(newParent, true);
|
||||
AttachedObject.transform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
protected virtual void OnRenderObject()
|
||||
|
@ -1,258 +0,0 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET;
|
||||
using QuantumUNET.Transport;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.TransformSync
|
||||
{
|
||||
/*
|
||||
* Rewrite number : 7
|
||||
* God has cursed me for my hubris, and my work is never finished.
|
||||
*/
|
||||
|
||||
public abstract class BaseTransformSync : SyncBase
|
||||
{
|
||||
private static readonly Dictionary<PlayerInfo, Dictionary<Type, BaseTransformSync>> _storedTransformSyncs = new Dictionary<PlayerInfo, Dictionary<Type, BaseTransformSync>>();
|
||||
|
||||
public static T GetPlayers<T>(PlayerInfo player)
|
||||
where T : BaseTransformSync
|
||||
{
|
||||
var dictOfOwnedSyncs = _storedTransformSyncs[player];
|
||||
var wantedSync = dictOfOwnedSyncs[typeof(T)];
|
||||
if (wantedSync == default)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - _storedTransformSyncs does not contain type:{typeof(T)} under player {player.PlayerId}. Attempting to find manually...", MessageType.Error);
|
||||
var allSyncs = Resources.FindObjectsOfTypeAll<T>();
|
||||
wantedSync = allSyncs.First(x => x.Player == player);
|
||||
if (wantedSync == default)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - Could not find type:{typeof(T)} for player {player.PlayerId} manually!", MessageType.Error);
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
return (T)wantedSync;
|
||||
}
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
|
||||
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
|
||||
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
|
||||
if (!_storedTransformSyncs.ContainsKey(Player))
|
||||
{
|
||||
_storedTransformSyncs.Add(Player, new Dictionary<Type, BaseTransformSync>());
|
||||
}
|
||||
|
||||
var playerDict = _storedTransformSyncs[Player];
|
||||
playerDict[GetType()] = this;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (!HasAuthority && AttachedObject != null)
|
||||
{
|
||||
Destroy(AttachedObject.gameObject);
|
||||
}
|
||||
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
|
||||
if (!QSBPlayerManager.PlayerExists(PlayerId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var playerDict = _storedTransformSyncs[Player];
|
||||
playerDict.Remove(GetType());
|
||||
}
|
||||
|
||||
protected virtual void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isInUniverse)
|
||||
=> _isInitialized = false;
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
if (!QSBSceneManager.IsInUniverse)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - {_logName} is being init-ed when not in the universe!", MessageType.Error);
|
||||
}
|
||||
|
||||
if (!HasAuthority && AttachedObject != null)
|
||||
{
|
||||
Destroy(AttachedObject.gameObject);
|
||||
}
|
||||
|
||||
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
_isInitialized = true;
|
||||
|
||||
if (QSBCore.DebugMode)
|
||||
{
|
||||
DebugBoxManager.CreateBox(AttachedObject.transform, 0, _logName);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnSerialize(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (!initialState)
|
||||
{
|
||||
if (SyncVarDirtyBits == 0U)
|
||||
{
|
||||
writer.WritePackedUInt32(0U);
|
||||
return false;
|
||||
}
|
||||
|
||||
writer.WritePackedUInt32(1U);
|
||||
}
|
||||
|
||||
SerializeTransform(writer, initialState);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDeserialize(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!IsServer || !QNetworkServer.localClientActive)
|
||||
{
|
||||
if (!initialState)
|
||||
{
|
||||
if (reader.ReadPackedUInt32() == 0U)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DeserializeTransform(reader, initialState);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
var worldPos = _intermediaryTransform.GetPosition();
|
||||
var worldRot = _intermediaryTransform.GetRotation();
|
||||
writer.Write(worldPos);
|
||||
SerializeRotation(writer, worldRot);
|
||||
_prevPosition = worldPos;
|
||||
_prevRotation = worldRot;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var pos = reader.ReadVector3();
|
||||
var rot = DeserializeRotation(reader);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
_intermediaryTransform.SetPosition(pos);
|
||||
_intermediaryTransform.SetRotation(rot);
|
||||
|
||||
if (_intermediaryTransform.GetPosition() == Vector3.zero)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {_logName} at (0,0,0)! - Given position was {pos}", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_ParentedToReference();
|
||||
var targetRot = _intermediaryTransform.GetTargetRotation_ParentedToReference();
|
||||
if (targetPos != Vector3.zero && _intermediaryTransform.GetTargetPosition_Unparented() != Vector3.zero)
|
||||
{
|
||||
if (UseInterpolation)
|
||||
{
|
||||
AttachedObject.transform.localPosition = SmartSmoothDamp(AttachedObject.transform.localPosition, targetPos);
|
||||
AttachedObject.transform.localRotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.localRotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedObject.transform.localPosition = targetPos;
|
||||
AttachedObject.transform.localRotation = targetRot;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool HasMoved()
|
||||
{
|
||||
var displacementMagnitude = (_intermediaryTransform.GetPosition() - _prevPosition).magnitude;
|
||||
return displacementMagnitude > 1E-03f
|
||||
|| Quaternion.Angle(_intermediaryTransform.GetRotation(), _prevRotation) > 1E-03f;
|
||||
}
|
||||
|
||||
public void SetReferenceTransform(Transform transform)
|
||||
{
|
||||
if (ReferenceTransform == transform)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReferenceTransform = transform;
|
||||
_intermediaryTransform.SetReferenceTransform(transform);
|
||||
if (AttachedObject == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - AttachedObject was null for {_logName} when trying to set reference transform to {transform?.name}. Waiting until not null...", MessageType.Warning);
|
||||
QSBCore.UnityEvents.RunWhen(
|
||||
() => AttachedObject != null,
|
||||
() => ReparentAttachedObject(transform));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasAuthority)
|
||||
{
|
||||
ReparentAttachedObject(transform);
|
||||
}
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReparentAttachedObject(Transform newParent)
|
||||
{
|
||||
if (AttachedObject.transform.parent != null && AttachedObject.transform.parent.GetComponent<Sector>() == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Trying to reparent AttachedObject {AttachedObject.name} which wasnt attached to sector!", MessageType.Warning);
|
||||
}
|
||||
|
||||
AttachedObject.transform.SetParent(newParent, true);
|
||||
AttachedObject.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
using OWML.Common;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Transport;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.TransformSync
|
||||
{
|
||||
public abstract class UnparentedBaseTransformSync : SyncBase
|
||||
{
|
||||
public override bool IgnoreDisabledAttachedObject => false;
|
||||
public override bool IgnoreNullReferenceTransform => false;
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
var lowestBound = Resources.FindObjectsOfTypeAll<PlayerTransformSync>()
|
||||
.Where(x => x.NetId.Value <= NetId.Value).OrderBy(x => x.NetId.Value).Last();
|
||||
NetIdentity.SetRootIdentity(lowestBound.NetIdentity);
|
||||
|
||||
DontDestroyOnLoad(gameObject);
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
DebugLog.DebugWrite($"OnDestroy {_logName}");
|
||||
if (!HasAuthority && AttachedObject != null)
|
||||
{
|
||||
Destroy(AttachedObject.gameObject);
|
||||
}
|
||||
|
||||
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
|
||||
}
|
||||
|
||||
protected void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isInUniverse) =>
|
||||
_isInitialized = false;
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
var worldPos = _intermediaryTransform.GetPosition();
|
||||
var worldRot = _intermediaryTransform.GetRotation();
|
||||
writer.Write(worldPos);
|
||||
SerializeRotation(writer, worldRot);
|
||||
_prevPosition = worldPos;
|
||||
_prevRotation = worldRot;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var pos = reader.ReadVector3();
|
||||
var rot = DeserializeRotation(reader);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
_intermediaryTransform.SetPosition(pos);
|
||||
_intermediaryTransform.SetRotation(rot);
|
||||
|
||||
if (_intermediaryTransform.GetPosition() == Vector3.zero)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - {PlayerId}.{GetType().Name} at (0,0,0)! - Given position was {pos}", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_Unparented();
|
||||
var targetRot = _intermediaryTransform.GetTargetRotation_Unparented();
|
||||
if (targetPos != Vector3.zero && _intermediaryTransform.GetTargetPosition_ParentedToReference() != Vector3.zero)
|
||||
{
|
||||
if (UseInterpolation)
|
||||
{
|
||||
AttachedObject.transform.position = SmartSmoothDamp(AttachedObject.transform.position, targetPos);
|
||||
AttachedObject.transform.rotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.rotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedObject.transform.position = targetPos;
|
||||
AttachedObject.transform.rotation = targetRot;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool HasMoved()
|
||||
{
|
||||
var displacementMagnitude = (_intermediaryTransform.GetPosition() - _prevPosition).magnitude;
|
||||
return displacementMagnitude > 1E-03f
|
||||
|| Quaternion.Angle(_intermediaryTransform.GetRotation(), _prevRotation) > 1E-03f;
|
||||
}
|
||||
|
||||
public void SetReferenceTransform(Transform transform)
|
||||
{
|
||||
if (ReferenceTransform == transform)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReferenceTransform = transform;
|
||||
_intermediaryTransform.SetReferenceTransform(transform);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
QSB/Syncs/Unsectored/BaseUnsectoredSync.cs
Normal file
19
QSB/Syncs/Unsectored/BaseUnsectoredSync.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.Syncs.Unsectored
|
||||
{
|
||||
public abstract class BaseUnsectoredSync : SyncBase
|
||||
{
|
||||
public override bool IgnoreDisabledAttachedObject => false;
|
||||
public override bool IgnoreNullReferenceTransform => false;
|
||||
public override bool ShouldReparentAttachedObject => false;
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
QSB/Syncs/Unsectored/Rigidbodies/UnsectoredRigidbodySync.cs
Normal file
13
QSB/Syncs/Unsectored/Rigidbodies/UnsectoredRigidbodySync.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.Unsectored.Rigidbodies
|
||||
{
|
||||
public abstract class UnsectoredRigidbodySync : BaseUnsectoredSync
|
||||
{
|
||||
protected abstract OWRigidbody GetRigidbody();
|
||||
|
||||
protected override Component SetAttachedObject()
|
||||
=> throw new NotImplementedException();
|
||||
}
|
||||
}
|
91
QSB/Syncs/Unsectored/Transforms/UnsectoredTransformSync.cs
Normal file
91
QSB/Syncs/Unsectored/Transforms/UnsectoredTransformSync.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using OWML.Common;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Transport;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Syncs.Unsectored.Transforms
|
||||
{
|
||||
public abstract class UnsectoredTransformSync : BaseUnsectoredSync
|
||||
{
|
||||
protected abstract Component InitLocalTransform();
|
||||
protected abstract Component InitRemoteTransform();
|
||||
|
||||
protected override Component SetAttachedObject()
|
||||
=> HasAuthority ? InitLocalTransform() : InitRemoteTransform();
|
||||
|
||||
public override void SerializeTransform(QNetworkWriter writer, bool initialState)
|
||||
{
|
||||
base.SerializeTransform(writer, initialState);
|
||||
|
||||
var worldPos = _intermediaryTransform.GetPosition();
|
||||
var worldRot = _intermediaryTransform.GetRotation();
|
||||
writer.Write(worldPos);
|
||||
SerializeRotation(writer, worldRot);
|
||||
_prevPosition = worldPos;
|
||||
_prevRotation = worldRot;
|
||||
}
|
||||
|
||||
public override void DeserializeTransform(QNetworkReader reader, bool initialState)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
reader.ReadVector3();
|
||||
DeserializeRotation(reader);
|
||||
return;
|
||||
}
|
||||
|
||||
var pos = reader.ReadVector3();
|
||||
var rot = DeserializeRotation(reader);
|
||||
|
||||
if (HasAuthority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_intermediaryTransform == null)
|
||||
{
|
||||
_intermediaryTransform = new IntermediaryTransform(transform);
|
||||
}
|
||||
|
||||
_intermediaryTransform.SetPosition(pos);
|
||||
_intermediaryTransform.SetRotation(rot);
|
||||
|
||||
if (_intermediaryTransform.GetPosition() == Vector3.zero)
|
||||
{
|
||||
//DebugLog.ToConsole($"Warning - {_logName} at (0,0,0)! - Given position was {pos}", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool UpdateTransform()
|
||||
{
|
||||
if (HasAuthority)
|
||||
{
|
||||
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
|
||||
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
|
||||
return true;
|
||||
}
|
||||
|
||||
var targetPos = _intermediaryTransform.GetTargetPosition_Unparented();
|
||||
var targetRot = _intermediaryTransform.GetTargetRotation_Unparented();
|
||||
if (targetPos != Vector3.zero && _intermediaryTransform.GetTargetPosition_Unparented() != Vector3.zero)
|
||||
{
|
||||
if (UseInterpolation)
|
||||
{
|
||||
AttachedObject.transform.position = SmartSmoothDamp(AttachedObject.transform.position, targetPos);
|
||||
AttachedObject.transform.rotation = QuaternionHelper.SmoothDamp(AttachedObject.transform.rotation, targetRot, ref _rotationSmoothVelocity, SmoothTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachedObject.transform.position = targetPos;
|
||||
AttachedObject.transform.rotation = targetRot;
|
||||
}
|
||||
}
|
||||
else if (targetPos == Vector3.zero)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - TargetPos for {_logName} was (0,0,0).", MessageType.Warning);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
{
|
||||
public enum FastForwardReason
|
||||
{
|
||||
None,
|
||||
TooFarBehind
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,26 @@
|
||||
using QSB.Patches;
|
||||
using HarmonyLib;
|
||||
using QSB.Patches;
|
||||
|
||||
namespace QSB.TimeSync.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
internal class TimePatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
public override void DoPatches()
|
||||
=> Prefix(nameof(PlayerCameraEffectController_OnStartOfTimeLoop));
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerCameraEffectController), nameof(PlayerCameraEffectController.OnStartOfTimeLoop))]
|
||||
public static bool PlayerCameraEffectController_OnStartOfTimeLoop()
|
||||
=> false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(OWTime), nameof(OWTime.Pause))]
|
||||
public static bool StopPausing()
|
||||
=> false;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(SubmitActionSkipToNextLoop), nameof(SubmitActionSkipToNextLoop.AdvanceToNewTimeLoop))]
|
||||
public static bool StopMeditation()
|
||||
=> false;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
{
|
||||
public enum PauseReason
|
||||
{
|
||||
None,
|
||||
TooFarAhead,
|
||||
ServerNotStarted,
|
||||
WaitingForAllPlayersToDie,
|
||||
|
@ -7,7 +7,8 @@ namespace QSB.TimeSync
|
||||
{
|
||||
public void Start()
|
||||
{
|
||||
QSBCore.Helper.Menus.PauseMenu.GetTitleButton("Button-EndCurrentLoop").Hide(); // Remove the meditation button
|
||||
// BUG : Get this working for the new menu system. Can't use OWML's anymore.
|
||||
//QSBCore.Helper.Menus.PauseMenu.GetTitleButton("Button-EndCurrentLoop").Hide(); // Remove the meditation button
|
||||
|
||||
// Allow server to sleep at campfires
|
||||
if (IsServer)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user