Merge pull request #294 from misternebula/so-many-fixes

So many fixes
This commit is contained in:
_nebula 2021-05-26 20:44:45 +01:00 committed by GitHub
commit ef8b23935f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 477 additions and 94 deletions

View File

@ -21,11 +21,11 @@ namespace QSB.Animation.Player.Events
public override void OnReceiveRemote(bool server, AnimationTriggerMessage message)
{
if (!QSBCore.WorldObjectsReady)
var animationSync = QSBPlayerManager.GetSyncObject<AnimationSync>(message.AttachedNetId);
if (!QSBCore.WorldObjectsReady || animationSync != null)
{
return;
}
var animationSync = QSBPlayerManager.GetSyncObject<AnimationSync>(message.AttachedNetId);
animationSync.VisibleAnimator.SetTrigger(message.Name);
}
}

View File

@ -1,9 +1,11 @@
using Harmony;
using QSB.Events;
using QSB.Patches;
using QSB.Utility;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using UnityEngine;
namespace QSB.DeathSync.Patches
{
@ -20,6 +22,8 @@ namespace QSB.DeathSync.Patches
QSBCore.HarmonyHelper.EmptyMethod<ShipEjectionSystem>("OnPressInteract");
QSBCore.HarmonyHelper.AddPostfix<ShipDamageController>("Awake", typeof(DeathPatches), nameof(DamageController_Exploded));
QSBCore.HarmonyHelper.AddPrefix<DestructionVolume>("VanishShip", typeof(DeathPatches), nameof(DestructionVolume_VanishShip));
QSBCore.HarmonyHelper.AddPrefix<HighSpeedImpactSensor>("FixedUpdate", typeof(DeathPatches), nameof(HighSpeedImpactSensor_FixedUpdate));
QSBCore.HarmonyHelper.AddPrefix<PlayerResources>("OnImpact", typeof(DeathPatches), nameof(PlayerResources_OnImpact));
}
public override void DoUnpatches()
@ -30,6 +34,150 @@ namespace QSB.DeathSync.Patches
QSBCore.HarmonyHelper.Unpatch<ShipEjectionSystem>("OnPressInteract");
QSBCore.HarmonyHelper.Unpatch<ShipDamageController>("Awake");
QSBCore.HarmonyHelper.Unpatch<DestructionVolume>("VanishShip");
QSBCore.HarmonyHelper.Unpatch<HighSpeedImpactSensor>("FixedUpdate");
QSBCore.HarmonyHelper.Unpatch<PlayerResources>("OnImpact");
}
public static bool PlayerResources_OnImpact(ImpactData impact, PlayerResources __instance, float ____currentHealth)
{
if (PlayerState.IsInsideShip())
{
return false;
}
var speed = Mathf.Clamp01((impact.speed - __instance.GetMinImpactSpeed()) / (__instance.GetMaxImpactSpeed() - __instance.GetMinImpactSpeed()));
var tookDamage = __instance.ApplyInstantDamage(100f * speed, InstantDamageType.Impact);
if (tookDamage && ____currentHealth <= 0f && !PlayerState.IsDead())
{
Locator.GetDeathManager().SetImpactDeathSpeed(impact.speed);
Locator.GetDeathManager().KillPlayer(DeathType.Impact);
DebugLog.DebugWrite(string.Concat(new object[]
{
"Player killed from impact with ",
impact.otherCollider,
" attached to ",
impact.otherCollider.attachedRigidbody.gameObject.name
}));
}
return false;
}
public static bool HighSpeedImpactSensor_FixedUpdate(
HighSpeedImpactSensor __instance,
bool ____isPlayer,
ref bool ____dead,
ref bool ____dieNextUpdate,
OWRigidbody ____body,
ref float ____impactSpeed,
float ____sqrCheckSpeedThreshold,
RaycastHit[] ____raycastHits,
SectorDetector ____sectorDetector,
float ____radius,
Vector3 ____localOffset
)
{
if (____isPlayer && (PlayerState.IsAttached() || PlayerState.IsInsideShuttle() || PlayerState.UsingNomaiRemoteCamera()))
{
return false;
}
if (____dieNextUpdate && !____dead)
{
____dead = true;
____dieNextUpdate = false;
if (__instance.gameObject.CompareTag("Player"))
{
Locator.GetDeathManager().SetImpactDeathSpeed(____impactSpeed);
Locator.GetDeathManager().KillPlayer(DeathType.Impact);
}
else if (__instance.gameObject.CompareTag("Ship"))
{
__instance.GetComponent<ShipDamageController>().Explode(false);
}
}
if (____isPlayer && PlayerState.IsInsideShip())
{
var shipCenter = Locator.GetShipTransform().position + (Locator.GetShipTransform().up * 2f);
var distanceFromShip = Vector3.Distance(____body.GetPosition(), shipCenter);
if (distanceFromShip > 8f)
{
____body.SetPosition(shipCenter);
DebugLog.DebugWrite("MOVE PLAYER BACK TO SHIP CENTER");
}
if (!____dead)
{
var a = ____body.GetVelocity() - Locator.GetShipBody().GetPointVelocity(____body.GetPosition());
if (a.sqrMagnitude > ____sqrCheckSpeedThreshold)
{
____impactSpeed = a.magnitude;
____body.AddVelocityChange(-a);
DebugLog.DebugWrite("Would have killed player...");
//____dieNextUpdate = true;
DebugLog.DebugWrite(string.Concat(new object[]
{
"HIGH SPEED IMPACT: ",
__instance.name,
" hit the Ship at ",
____impactSpeed,
"m/s Dist from ship: ",
distanceFromShip
}));
}
}
return false;
}
var passiveReferenceFrame = ____sectorDetector.GetPassiveReferenceFrame();
if (!____dead && passiveReferenceFrame != null)
{
var relativeVelocity = ____body.GetVelocity() - passiveReferenceFrame.GetOWRigidBody().GetPointVelocity(____body.GetPosition());
if (relativeVelocity.sqrMagnitude > ____sqrCheckSpeedThreshold)
{
var hitCount = Physics.RaycastNonAlloc(__instance.transform.TransformPoint(____localOffset), relativeVelocity, ____raycastHits, (relativeVelocity.magnitude * Time.deltaTime) + ____radius, OWLayerMask.physicalMask, QueryTriggerInteraction.Ignore);
for (var i = 0; i < hitCount; i++)
{
if (____raycastHits[i].rigidbody.mass > 10f && !____raycastHits[i].rigidbody.Equals(____body.GetRigidbody()))
{
var owRigidbody = ____raycastHits[i].rigidbody.GetComponent<OWRigidbody>();
if (owRigidbody == null)
{
DebugLog.ToConsole("Rigidbody does not have attached OWRigidbody!!!", OWML.Common.MessageType.Error);
Debug.Break();
}
else
{
relativeVelocity = ____body.GetVelocity() - owRigidbody.GetPointVelocity(____body.GetPosition());
var a2 = Vector3.Project(relativeVelocity, ____raycastHits[i].normal);
if (a2.sqrMagnitude > ____sqrCheckSpeedThreshold)
{
____body.AddVelocityChange(-a2);
____impactSpeed = a2.magnitude;
if (!PlayerState.IsInsideTheEye())
{
____dieNextUpdate = true;
}
DebugLog.DebugWrite(string.Concat(new object[]
{
"HIGH SPEED IMPACT: ",
__instance.name,
" hit ",
____raycastHits[i].rigidbody.name,
" at ",
____impactSpeed,
"m/s RF: ",
passiveReferenceFrame.GetOWRigidBody().name
}));
break;
}
}
}
}
}
}
return false;
}
public static bool PreFinishDeathSequence(DeathType deathType)

View File

@ -30,6 +30,7 @@ namespace QSB.DeathSync
private ShipCockpitController _cockpitController;
private PlayerSpacesuit _spaceSuit;
private ShipTractorBeamSwitch _shipTractorBeam;
private SuitPickupVolume[] _suitPickupVolumes;
public void Awake() => Instance = this;
@ -40,6 +41,8 @@ namespace QSB.DeathSync
_spaceSuit = Locator.GetPlayerSuit();
_playerSpawner = FindObjectOfType<PlayerSpawner>();
_shipTractorBeam = FindObjectOfType<ShipTractorBeamSwitch>();
_suitPickupVolumes = FindObjectsOfType<SuitPickupVolume>();
_fluidDetector = Locator.GetPlayerCamera().GetComponentInChildren<FluidDetector>();
_playerSpawnPoint = GetSpawnPoint();
@ -88,6 +91,33 @@ namespace QSB.DeathSync
_playerResources.SetValue("_isSuffocating", false);
_playerResources.DebugRefillResources();
_spaceSuit.RemoveSuit(true);
foreach (var pickupVolume in _suitPickupVolumes)
{
var containsSuit = pickupVolume.GetValue<bool>("_containsSuit");
var allowReturn = pickupVolume.GetValue<bool>("_allowSuitReturn");
if (!containsSuit && allowReturn)
{
var interactVolume = pickupVolume.GetValue<MultipleInteractionVolume>("_interactVolume");
var pickupSuitIndex = pickupVolume.GetValue<int>("_pickupSuitCommandIndex");
pickupVolume.SetValue("_containsSuit", true);
interactVolume.ChangePrompt(UITextType.SuitUpPrompt, pickupSuitIndex);
var suitGeometry = pickupVolume.GetValue<GameObject>("_suitGeometry");
var suitCollider = pickupVolume.GetValue<OWCollider>("_suitOWCollider");
var toolGeometries = pickupVolume.GetValue<GameObject[]>("_toolGeometry");
suitGeometry.SetActive(true);
suitCollider.SetActivation(true);
foreach (var geo in toolGeometries)
{
geo.SetActive(true);
}
}
}
}
public void ResetShip()

View File

@ -11,17 +11,11 @@ namespace QSB.OrbSync.TransformSync
public static List<NomaiOrbTransformSync> OrbTransformSyncs = new List<NomaiOrbTransformSync>();
private int _index => OrbTransformSyncs.IndexOf(this);
private bool _isReady;
public override void OnStartClient()
{
QSBSceneManager.OnSceneLoaded += (OWScene scene, bool inUniverse) => _isReady = false;
OrbTransformSyncs.Add(this);
}
public override void OnStartClient() => OrbTransformSyncs.Add(this);
protected override void OnDestroy()
{
QSBSceneManager.OnSceneLoaded -= (OWScene scene, bool inUniverse) => _isReady = false;
OrbTransformSyncs.Remove(this);
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
}
@ -34,6 +28,11 @@ namespace QSB.OrbSync.TransformSync
private GameObject GetTransform()
{
if (_index == -1)
{
DebugLog.ToConsole($"Error - Index cannot be found.", OWML.Common.MessageType.Error);
return null;
}
if (QSBWorldSync.OldOrbList == null || QSBWorldSync.OldOrbList.Count <= _index)
{
DebugLog.ToConsole($"Error - OldOrbList is null or does not contain index {_index}.", OWML.Common.MessageType.Error);

View File

@ -20,7 +20,9 @@ namespace QSB.Player
var localInstance = PlayerTransformSync.LocalInstance;
if (localInstance == null)
{
DebugLog.ToConsole($"Error - Trying to get LocalPlayerId when the local PlayerTransformSync instance is null.", MessageType.Error);
var method = new StackTrace().GetFrame(1).GetMethod();
DebugLog.ToConsole($"Error - Trying to get LocalPlayerId when the local PlayerTransformSync instance is null." +
$"{Environment.NewLine} Called from {method.DeclaringType.Name}.{method.Name} ", MessageType.Error);
return uint.MaxValue;
}
if (localInstance.NetIdentity == null)

View File

@ -64,7 +64,7 @@ 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 bool WorldObjectsReady => WorldObjectManager.AllReady;
public static bool WorldObjectsReady => WorldObjectManager.AllReady && IsInMultiplayer && PlayerTransformSync.LocalInstance != null;
public static bool IsServer => QNetworkServer.active;
public static bool IsInMultiplayer => QNetworkManager.singleton.isNetworkActive;
public static string QSBVersion => Helper.Manifest.Version;
@ -176,15 +176,23 @@ namespace QSB
{
GUI.Label(new Rect(420, offset3, 200f, 20f), $"In control of ship? : {ship.HasAuthority}");
offset3 += _debugLineSpacing;
GUI.Label(new Rect(420, offset3, 200f, 20f), $"Ship sector : {(ship.ReferenceSector == null ? "NULL" : ship.ReferenceSector.Name)}");
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Ship sector : {(ship.ReferenceSector == null ? "NULL" : ship.ReferenceSector.Name)}");
offset3 += _debugLineSpacing;
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Ship relative velocity : {ship.AttachedObject.GetRelativeVelocity(ship.ReferenceTransform.GetAttachedOWRigidbody())}");
offset3 += _debugLineSpacing;
offset3 += _debugLineSpacing;
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Ship velocity mag. : {ship.GetVelocityChangeMagnitude()}");
if (ship.ReferenceTransform != null)
{
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Ship relative velocity : {ship.GetRelativeVelocity()}");
offset3 += _debugLineSpacing;
GUI.Label(new Rect(420, offset3, 400f, 20f), $"Ship velocity mag. : {ship.GetVelocityChangeMagnitude()}");
offset3 += _debugLineSpacing;
}
GUI.Label(new Rect(420, offset3, 200f, 20f), $"Ship sectors :");
offset3 += _debugLineSpacing;
foreach (var sector in ship.SectorSync.SectorList)
{
GUI.Label(new Rect(420, offset3, 400f, 20f), $"- {sector.Name}");
offset3 += _debugLineSpacing;
}
}
var offset2 = 10f;
@ -217,6 +225,16 @@ namespace QSB
GUI.Label(new Rect(220, offset, 400f, 20f), $"- Thrusting : {player.JetpackAcceleration?.IsThrusting}");
offset += _debugLineSpacing;
}
GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Illuminated : {Locator.GetQuantumMoon().IsIlluminated()}");
offset += _debugLineSpacing;
GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Visible by :");
offset += _debugLineSpacing;
var tracker = Locator.GetQuantumMoon().GetValue<ShapeVisibilityTracker>("_visibilityTracker");
foreach (var player in QSBPlayerManager.GetPlayersWithCameras())
{
GUI.Label(new Rect(220, offset, 200f, 20f), $" - {player.PlayerId} : {tracker.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(tracker, new object[] { player.Camera.GetFrustumPlanes() })}");
offset += _debugLineSpacing;
}
if (SocketedObjToDebug == -1)
{

View File

@ -11,6 +11,8 @@ namespace QSB
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",

View File

@ -435,7 +435,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))
if ((bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) || QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true).First)
{
____isPlayerInside = true;
__instance.GetType().GetMethod("SetSurfaceState", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { ____stateIndex });
@ -456,7 +456,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))
if (!(bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) && !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true).First)
{
__instance.GetType().GetMethod("Collapse", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { true });
}

View File

@ -41,7 +41,7 @@ namespace QSB.QuantumSync.Patches
public static bool ShapeIsVisibleUsingCameraFrustum(ShapeVisibilityTracker __instance, ref bool __result)
{
__result = QuantumManager.IsVisibleUsingCameraFrustum(__instance, false);
__result = QuantumManager.IsVisibleUsingCameraFrustum(__instance, false).First;
return false;
}

View File

@ -1,8 +1,9 @@
using OWML.Common;
using QSB.Events;
using QSB.Patches;
using QSB.Player;
using QSB.Utility;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using UnityEngine;
@ -40,16 +41,36 @@ namespace QSB.QuantumSync.Patches
GameObject[] ____deactivateAtEye
)
{
if (QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck) && !QuantumManager.Shrine.IsPlayerInDarkness())
var isVisibleOutput = QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck);
//var moonVisible = isVisibleOutput.First;
var moonVisiblePlayers = isVisibleOutput.Second;
var inMoonPlayers = QSBPlayerManager.PlayerList.Where(x => x.IsInMoon);
var inShrinePlayers = QSBPlayerManager.PlayerList.Where(x => x.IsInShrine);
//var outMoonPlayers = QSBPlayerManager.PlayerList.Where(x => !x.IsInMoon);
var outShrinePlayers = QSBPlayerManager.PlayerList.Where(x => !x.IsInShrine);
var shrineLit = QuantumManager.Shrine.IsPlayerInDarkness();
// If any of the players in the moon are not in the shrine
if (inMoonPlayers.Any(x => !x.IsInShrine))
{
if (!skipInstantVisibilityCheck)
{
var method = new StackTrace().GetFrame(3).GetMethod();
DebugLog.ToConsole($"Warning - Tried to change moon state while still observed. Called by {method.DeclaringType}.{method.Name}", MessageType.Warning);
}
__result = false;
return false;
}
// If any of the players outside the shrine can see the moon
if (outShrinePlayers.Any(moonVisiblePlayers.Contains))
{
__result = false;
return false;
}
// If there are players in the shrine and the shrine is not lit
if(inShrinePlayers.Count() != 0 && !shrineLit)
{
__result = false;
return false;
}
var flag = false;
if (____isPlayerInside && ____hasSunCollapsed)
{
@ -98,7 +119,7 @@ namespace QSB.QuantumSync.Patches
{
Physics.SyncTransforms();
}
if (__instance.IsPlayerEntangled() || !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck))
if (__instance.IsPlayerEntangled() || !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck).First)
{
____moonBody.transform.position = position;
if (!Physics.autoSyncTransforms)

View File

@ -76,19 +76,22 @@ namespace QSB.QuantumSync
}
}
public static bool IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
public static Tuple<bool, List<PlayerInfo>> IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
{
var playersWithCameras = QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera);
if (playersWithCameras.Count == 0)
{
DebugLog.ToConsole($"Warning - Trying to run IsVisibleUsingCameraFrustum when there are no players!", MessageType.Warning);
return false;
return new Tuple<bool, List<PlayerInfo>>(false, null);
}
if (!tracker.gameObject.activeInHierarchy)
{
return false;
return new Tuple<bool, List<PlayerInfo>>(false, null);
}
var frustumMethod = tracker.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance);
var playersWhoCanSee = new List<PlayerInfo>();
var foundPlayers = false;
foreach (var player in playersWithCameras)
{
if (player.Camera == null)
@ -99,16 +102,18 @@ namespace QSB.QuantumSync
var isInFrustum = (bool)frustumMethod.Invoke(tracker, new object[] { player.Camera.GetFrustumPlanes() });
if (isInFrustum)
{
return true;
playersWhoCanSee.Add(player);
foundPlayers = true;
}
}
return false;
return new Tuple<bool, List<PlayerInfo>>(foundPlayers, playersWhoCanSee);
}
public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
{
return tracker.gameObject.activeInHierarchy
&& IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera)
&& IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera).First
&& QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera)
.Any(x => VisibilityOccluder.CanYouSee(tracker, x.Camera.mainCamera.transform.position));
}

View File

@ -19,7 +19,7 @@ namespace QSB.RoastingSync.Patches
public override void DoUnpatches()
{
// TODO : add unpatches
}
public static bool Marshmallow_SpawnMallow()

View File

@ -1,8 +1,6 @@
using OWML.Common;
using QSB.SectorSync.WorldObjects;
using QSB.Syncs;
using QSB.Syncs.RigidbodySync;
using QSB.Syncs.TransformSync;
using QSB.Utility;
using QSB.WorldSync;
using QuantumUNET;
@ -21,11 +19,12 @@ namespace QSB.SectorSync
private void OnEnable() => RepeatingManager.Repeatings.Add(this);
private void OnDisable() => RepeatingManager.Repeatings.Remove(this);
public List<ISectoredSync<Component>> SectoredSyncs = new List<ISectoredSync<Component>>();
public List<ISectoredSync<Transform>> SectoredTransformSyncs = new List<ISectoredSync<Transform>>();
public List<ISectoredSync<OWRigidbody>> SectoredRigidbodySyncs = new List<ISectoredSync<OWRigidbody>>();
public void Invoke()
{
foreach (var sync in SectoredSyncs)
foreach (var sync in SectoredTransformSyncs)
{
if (sync.AttachedObject == null)
{
@ -38,6 +37,20 @@ namespace QSB.SectorSync
CheckTransformSyncSector(sync);
}
}
foreach (var sync in SectoredRigidbodySyncs)
{
if (sync.AttachedObject == null)
{
continue;
}
if ((sync as QNetworkBehaviour).HasAuthority
&& sync.AttachedObject.gameObject.activeInHierarchy
&& sync.IsReady)
{
CheckTransformSyncSector(sync);
}
}
}
public override void Awake()

View File

@ -86,8 +86,10 @@ namespace QSB.SectorSync
return null;
}
var listToCheck = SectorList.Count(x => x.ShouldSyncTo(_targetType)) == 0
? QSBWorldSync.GetWorldObjects<QSBSector>()
var numSectorsCurrentlyIn = SectorList.Count(x => x.ShouldSyncTo(_targetType));
var listToCheck = numSectorsCurrentlyIn == 0
? QSBWorldSync.GetWorldObjects<QSBSector>().Where(x => !x.IsFakeSector)
: SectorList;
/* Explanation of working out which sector to sync to :
@ -113,7 +115,9 @@ namespace QSB.SectorSync
var ordered = activeNotNullNotBlacklisted
.OrderBy(sector => CalculateSectorScore(sector, trans, _attachedOWRigidbody));
// TODO : clean up this shit???
if (
numSectorsCurrentlyIn != 0 &&
// if any fake sectors are *roughly* in the same place as other sectors - we want fake sectors to override other sectors
QSBSectorManager.Instance.FakeSectors.Any(
x => OWMath.ApproxEquals(Vector3.Distance(x.Position, trans.position), Vector3.Distance(ordered.FirstOrDefault().Position, trans.position), 0.01f)

View File

@ -29,13 +29,11 @@ namespace QSB.ShipSync.TransformSync
{
if (HasAuthority && ShipManager.Instance.CurrentFlyer != QSBPlayerManager.LocalPlayerId)
{
DebugLog.DebugWrite($"Warning - Local player has ship authority, but is not the current flyer!", OWML.Common.MessageType.Warning);
return;
}
if (!HasAuthority && ShipManager.Instance.CurrentFlyer == QSBPlayerManager.LocalPlayerId)
{
DebugLog.DebugWrite($"Warning - Local player does not have ship authority, but is the current flyer!", OWML.Common.MessageType.Warning);
return;
}
@ -45,5 +43,6 @@ namespace QSB.ShipSync.TransformSync
public override TargetType Type => TargetType.Ship;
public override bool UseInterpolation => true;
protected override float DistanceLeeway => 20f;
}
}

View File

@ -2,7 +2,6 @@
using QSB.SectorSync.WorldObjects;
using QSB.WorldSync;
using QuantumUNET.Transport;
using System.Collections.Generic;
namespace QSB.Syncs.RigidbodySync
{
@ -15,14 +14,14 @@ namespace QSB.Syncs.RigidbodySync
public override void Start()
{
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
QSBSectorManager.Instance.SectoredSyncs.Add((ISectoredSync<UnityEngine.Component>)this);
QSBSectorManager.Instance.SectoredRigidbodySyncs.Add(this);
base.Start();
}
protected override void OnDestroy()
{
base.OnDestroy();
QSBSectorManager.Instance.SectoredSyncs.Remove((ISectoredSync<UnityEngine.Component>)this);
QSBSectorManager.Instance.SectoredRigidbodySyncs.Remove(this);
if (SectorSync != null)
{
Destroy(SectorSync);
@ -104,7 +103,7 @@ namespace QSB.Syncs.RigidbodySync
public void SetReferenceSector(QSBSector sector)
{
ReferenceSector = sector;
SetReferenceTransform(sector.Transform);
SetReferenceTransform(sector?.Transform);
}
}
}

View File

@ -1,4 +1,5 @@
using OWML.Common;
using OWML.Utils;
using QSB.Utility;
using QuantumUNET.Components;
using QuantumUNET.Transport;
@ -14,6 +15,10 @@ namespace QSB.Syncs.RigidbodySync
public abstract bool IsReady { get; }
public abstract bool UseInterpolation { get; }
protected virtual float DistanceLeeway { get; } = 5f;
private float _previousDistance;
private const float SmoothTime = 0.1f;
protected bool _isInitialized;
protected IntermediaryTransform _intermediaryTransform;
protected Vector3 _velocity;
@ -21,6 +26,8 @@ namespace QSB.Syncs.RigidbodySync
protected Vector3 _prevVelocity;
protected Vector3 _prevAngularVelocity;
private string _logName => $"{NetId}:{GetType().Name}";
private Vector3 _positionSmoothVelocity;
private Quaternion _rotationSmoothVelocity;
protected abstract OWRigidbody GetRigidbody();
@ -61,18 +68,6 @@ namespace QSB.Syncs.RigidbodySync
* We can't store the last two on the IntermediaryTransform, so they come from fields.
*/
// Get world position from IT.
// Get world rotation from IT.
// Get velocity from field.
// Get angular velocity from field.
// Send all.
// Set _prev fields.
var worldPos = _intermediaryTransform.GetPosition();
var worldRot = _intermediaryTransform.GetRotation();
var velocity = _velocity;
@ -82,6 +77,7 @@ namespace QSB.Syncs.RigidbodySync
SerializeRotation(writer, worldRot);
writer.Write(velocity);
writer.Write(angularVelocity);
_prevPosition = worldPos;
_prevRotation = worldRot;
_prevVelocity = velocity;
@ -153,6 +149,11 @@ namespace QSB.Syncs.RigidbodySync
return;
}
if (ReferenceTransform == null)
{
return;
}
UpdateTransform();
base.Update();
@ -164,7 +165,7 @@ namespace QSB.Syncs.RigidbodySync
{
_intermediaryTransform.EncodePosition(AttachedObject.transform.position);
_intermediaryTransform.EncodeRotation(AttachedObject.transform.rotation);
_velocity = AttachedObject.GetRelativeVelocity(ReferenceTransform.GetAttachedOWRigidbody());
_velocity = GetRelativeVelocity();
_angularVelocity = AttachedObject.GetRelativeAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody());
return;
}
@ -177,12 +178,41 @@ namespace QSB.Syncs.RigidbodySync
return;
}
AttachedObject.transform.position = targetPos;
AttachedObject.transform.rotation = targetRot;
AttachedObject.SetVelocity(ReferenceTransform.GetAttachedOWRigidbody().GetVelocity() + _velocity);
if (UseInterpolation)
{
AttachedObject.SetPosition(SmartPositionSmoothDamp(AttachedObject.transform.position, targetPos));
AttachedObject.SetRotation(QuaternionHelper.SmoothDamp(AttachedObject.transform.rotation, targetRot, ref _rotationSmoothVelocity, SmoothTime));
}
else
{
AttachedObject.SetPosition(targetPos);
AttachedObject.SetRotation(targetRot);
}
SetVelocity(AttachedObject, ReferenceTransform.GetAttachedOWRigidbody().GetPointVelocity(targetPos) + _velocity);
AttachedObject.SetAngularVelocity(ReferenceTransform.GetAttachedOWRigidbody().GetAngularVelocity() + _angularVelocity);
}
private void SetVelocity(OWRigidbody rigidbody, Vector3 newVelocity)
{
var isRunningKinematic = rigidbody.RunningKinematicSimulation();
var currentVelocity = rigidbody.GetValue<Vector3>("_currentVelocity");
if (isRunningKinematic)
{
var kinematicRigidbody = rigidbody.GetValue<KinematicRigidbody>("_kinematicRigidbody");
kinematicRigidbody.velocity = newVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameWorldVelocity();
}
else
{
var normalRigidbody = rigidbody.GetValue<Rigidbody>("_rigidbody");
normalRigidbody.velocity = newVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameWorldVelocity();
}
rigidbody.SetValue("_lastVelocity", currentVelocity);
rigidbody.SetValue("_currentVelocity", newVelocity);
}
public void SetReferenceTransform(Transform transform)
{
if (ReferenceTransform == transform)
@ -193,6 +223,21 @@ namespace QSB.Syncs.RigidbodySync
_intermediaryTransform.SetReferenceTransform(transform);
}
// TODO : remove .Distance
private Vector3 SmartPositionSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
{
var distance = Vector3.Distance(currentPosition, targetPosition);
if (distance > _previousDistance + DistanceLeeway)
{
DebugLog.DebugWrite($"Warning - {AttachedObject.name} moved too far!", MessageType.Warning);
_previousDistance = distance;
return targetPosition;
}
_previousDistance = distance;
return Vector3.SmoothDamp(currentPosition, targetPosition, ref _positionSmoothVelocity, SmoothTime);
}
// TODO : optimize by using sqrMagnitude
public override bool HasMoved()
{
var displacementMagnitude = (_intermediaryTransform.GetPosition() - _prevPosition).magnitude;
@ -201,6 +246,7 @@ namespace QSB.Syncs.RigidbodySync
{
return true;
}
if (Quaternion.Angle(_intermediaryTransform.GetRotation(), _prevRotation) > 1E-03f)
{
return true;
@ -212,6 +258,7 @@ namespace QSB.Syncs.RigidbodySync
{
return true;
}
if (angularVelocityChangeMagnitude > 1E-03f)
{
return true;
@ -223,9 +270,16 @@ namespace QSB.Syncs.RigidbodySync
public float GetVelocityChangeMagnitude()
=> (_velocity - _prevVelocity).magnitude;
public Vector3 GetRelativeVelocity()
=> ReferenceTransform.GetAttachedOWRigidbody().GetPointVelocity(AttachedObject.transform.position) - AttachedObject.GetVelocity();
private void OnRenderObject()
{
if (!QSBCore.WorldObjectsReady || !QSBCore.DebugMode || !QSBCore.ShowLinesInDebug || !IsReady)
if (!QSBCore.WorldObjectsReady
|| !QSBCore.DebugMode
|| !QSBCore.ShowLinesInDebug
|| !IsReady
|| ReferenceTransform == null)
{
return;
}
@ -235,6 +289,8 @@ namespace QSB.Syncs.RigidbodySync
var color = HasMoved() ? Color.green : Color.yellow;
Popcron.Gizmos.Cube(AttachedObject.transform.position, AttachedObject.transform.rotation, Vector3.one / 2, color);
Popcron.Gizmos.Line(AttachedObject.transform.position, ReferenceTransform.position, Color.cyan);
Popcron.Gizmos.Line(AttachedObject.transform.position, AttachedObject.transform.position + GetRelativeVelocity(), Color.blue);
}
}
}

View File

@ -16,8 +16,36 @@ namespace QSB.Syncs.TransformSync
public abstract class BaseTransformSync : QNetworkTransform, ISync<Transform>
{
public uint AttachedNetId => NetIdentity?.NetId.Value ?? uint.MaxValue;
public uint PlayerId => NetIdentity.RootIdentity?.NetId.Value ?? NetIdentity.NetId.Value;
public uint AttachedNetId
{
get
{
if (NetIdentity == null)
{
DebugLog.ToConsole($"Error - Trying to get AttachedNetId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
return uint.MaxValue;
}
return NetIdentity.NetId.Value;
}
}
public uint PlayerId
{
get
{
if (NetIdentity == null)
{
DebugLog.ToConsole($"Error - Trying to get PlayerId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
return uint.MaxValue;
}
return NetIdentity.RootIdentity != null
? NetIdentity.RootIdentity.NetId.Value
: AttachedNetId;
}
}
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
public Transform ReferenceTransform { get; set; }
@ -53,7 +81,7 @@ namespace QSB.Syncs.TransformSync
{
if (!HasAuthority && AttachedObject != null)
{
Destroy(AttachedObject);
Destroy(AttachedObject.gameObject);
}
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
}
@ -69,7 +97,7 @@ namespace QSB.Syncs.TransformSync
}
if (!HasAuthority && AttachedObject != null)
{
Destroy(AttachedObject);
Destroy(AttachedObject.gameObject);
}
AttachedObject = HasAuthority ? InitLocalTransform() : InitRemoteTransform();
_isInitialized = true;
@ -149,6 +177,11 @@ namespace QSB.Syncs.TransformSync
return;
}
if (ReferenceTransform == null)
{
return;
}
UpdateTransform();
base.Update();
@ -196,7 +229,7 @@ namespace QSB.Syncs.TransformSync
_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);
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));
@ -234,12 +267,11 @@ namespace QSB.Syncs.TransformSync
private void OnRenderObject()
{
if (!QSBCore.WorldObjectsReady || !QSBCore.DebugMode || !QSBCore.ShowLinesInDebug || !IsReady)
{
return;
}
if (ReferenceTransform == null)
if (!QSBCore.WorldObjectsReady
|| !QSBCore.DebugMode
|| !QSBCore.ShowLinesInDebug
|| !IsReady
|| ReferenceTransform == null)
{
return;
}

View File

@ -2,7 +2,6 @@
using QSB.SectorSync.WorldObjects;
using QSB.WorldSync;
using QuantumUNET.Transport;
using System.Collections.Generic;
using UnityEngine;
namespace QSB.Syncs.TransformSync
@ -16,14 +15,14 @@ namespace QSB.Syncs.TransformSync
public override void Start()
{
SectorSync = gameObject.AddComponent<SectorSync.SectorSync>();
QSBSectorManager.Instance.SectoredSyncs.Add((ISectoredSync<UnityEngine.Component>)this);
QSBSectorManager.Instance.SectoredTransformSyncs.Add(this);
base.Start();
}
protected override void OnDestroy()
{
base.OnDestroy();
QSBSectorManager.Instance.SectoredSyncs.Remove((ISectoredSync<UnityEngine.Component>)this);
QSBSectorManager.Instance.SectoredTransformSyncs.Remove(this);
if (SectorSync != null)
{
Destroy(SectorSync);
@ -105,7 +104,7 @@ namespace QSB.Syncs.TransformSync
public void SetReferenceSector(QSBSector sector)
{
ReferenceSector = sector;
SetReferenceTransform(sector.Transform);
SetReferenceTransform(sector?.Transform);
}
}
}

View File

@ -11,8 +11,36 @@ namespace QSB.Syncs.TransformSync
{
public abstract class UnparentedBaseTransformSync : QNetworkTransform, ISync<GameObject>
{
public uint AttachedNetId => NetIdentity?.NetId.Value ?? uint.MaxValue;
public uint PlayerId => NetIdentity.RootIdentity?.NetId.Value ?? NetIdentity.NetId.Value;
public uint AttachedNetId
{
get
{
if (NetIdentity == null)
{
DebugLog.ToConsole($"Error - Trying to get AttachedNetId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
return uint.MaxValue;
}
return NetIdentity.NetId.Value;
}
}
public uint PlayerId
{
get
{
if (NetIdentity == null)
{
DebugLog.ToConsole($"Error - Trying to get PlayerId with null NetIdentity! Type:{GetType().Name} GrandType:{GetType().GetType().Name}", MessageType.Error);
return uint.MaxValue;
}
return NetIdentity.RootIdentity != null
? NetIdentity.RootIdentity.NetId.Value
: AttachedNetId;
}
}
public PlayerInfo Player => QSBPlayerManager.GetPlayer(PlayerId);
public Transform ReferenceTransform { get; set; }
@ -47,7 +75,7 @@ namespace QSB.Syncs.TransformSync
{
if (!HasAuthority && AttachedObject != null)
{
Destroy(AttachedObject);
Destroy(AttachedObject.gameObject);
}
QSBSceneManager.OnSceneLoaded -= OnSceneLoaded;
}
@ -130,6 +158,11 @@ namespace QSB.Syncs.TransformSync
return;
}
if (ReferenceTransform == null)
{
return;
}
UpdateTransform();
base.Update();
@ -177,11 +210,13 @@ namespace QSB.Syncs.TransformSync
_intermediaryTransform.SetReferenceTransform(transform);
}
// TODO : remove .Distance
private Vector3 SmartSmoothDamp(Vector3 currentPosition, Vector3 targetPosition)
{
var distance = Vector3.Distance(currentPosition, targetPosition);
if (distance > _previousDistance + DistanceLeeway)
{
DebugLog.DebugWrite($"Warning - {AttachedObject.name} moved too far!", MessageType.Warning);
_previousDistance = distance;
return targetPosition;
}
@ -191,7 +226,11 @@ namespace QSB.Syncs.TransformSync
private void OnRenderObject()
{
if (!QSBCore.WorldObjectsReady || !QSBCore.DebugMode || !QSBCore.ShowLinesInDebug || !IsReady)
if (!QSBCore.WorldObjectsReady
|| !QSBCore.DebugMode
|| !QSBCore.ShowLinesInDebug
|| !IsReady
|| ReferenceTransform == null)
{
return;
}

View File

@ -7,17 +7,10 @@ namespace QSB.TimeSync.Patches
{
public override QSBPatchTypes Type => QSBPatchTypes.OnNonServerClientConnect;
public static bool OnStartOfTimeLoopPrefix(ref PlayerCameraEffectController __instance)
{
if (__instance.gameObject.CompareTag("MainCamera") && QSBSceneManager.CurrentScene != OWScene.EyeOfTheUniverse)
{
__instance.Invoke("WakeUp");
}
return false;
}
public override void DoPatches()
=> QSBCore.HarmonyHelper.EmptyMethod<OWInput>("OnStartOfTimeLoop");
public override void DoPatches() => QSBCore.HarmonyHelper.AddPrefix<PlayerCameraEffectController>("OnStartOfTimeLoop", typeof(WakeUpPatches), nameof(OnStartOfTimeLoopPrefix));
public override void DoUnpatches() => QSBCore.HarmonyHelper.Unpatch<PlayerCameraEffectController>("OnStartOfTimeLoop");
public override void DoUnpatches()
=> QSBCore.HarmonyHelper.Unpatch<OWInput>("OnStartOfTimeLoop");
}
}

View File

@ -1,4 +1,5 @@
using OWML.Common;
using OWML.Utils;
using QSB.DeathSync;
using QSB.Events;
using QSB.TimeSync.Events;
@ -27,6 +28,7 @@ namespace QSB.TimeSync
private float _serverTime;
private bool _isFirstFastForward = true;
private int _serverLoopCount;
private bool _hasWokenUp;
public override void OnStartLocalPlayer() => LocalInstance = this;
@ -60,6 +62,7 @@ namespace QSB.TimeSync
{
RespawnOnDeath.Instance.Init();
}
_hasWokenUp = true;
}
public void OnDestroy()
@ -71,8 +74,13 @@ namespace QSB.TimeSync
private void OnSceneLoaded(OWScene scene, bool isInUniverse)
{
DebugLog.DebugWrite($"ONSCENELOADED");
_hasWokenUp = false;
if (isInUniverse)
{
if (scene == OWScene.EyeOfTheUniverse)
{
_hasWokenUp = true;
}
Init();
}
else
@ -158,6 +166,7 @@ namespace QSB.TimeSync
{
Locator.GetActiveCamera().enabled = false;
}
OWInput.ChangeInputMode(InputMode.None);
_state = State.FastForwarding;
OWTime.SetMaxDeltaTime(0.033333335f);
OWTime.SetFixedTimestep(0.033333335f);
@ -173,6 +182,7 @@ namespace QSB.TimeSync
}
DebugLog.DebugWrite($"START PAUSING (Target:{_serverTime} Current:{Time.timeSinceLevelLoad})", MessageType.Info);
Locator.GetActiveCamera().enabled = false;
OWInput.ChangeInputMode(InputMode.None);
OWTime.SetTimeScale(0f);
_state = State.Pausing;
SpinnerUI.Show();
@ -194,8 +204,22 @@ namespace QSB.TimeSync
TimeSyncUI.Stop();
QSBEventManager.FireEvent(EventNames.QSBPlayerStatesRequest);
RespawnOnDeath.Instance.Init();
if (OWInput.GetInputMode() == InputMode.None)
{
OWInput.RestorePreviousInputs();
}
if (!_hasWokenUp)
{
WakeUp();
OWInput.ChangeInputMode(InputMode.Character);
}
}
private void WakeUp()
=> Locator.GetPlayerCamera().GetComponent<PlayerCameraEffectController>().Invoke("WakeUp");
public void Update()
{
if (IsServer)