mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-01-26 18:35:34 +00:00
Merge pull request #379 from misternebula/suspend-authority-sync
suspendable authority sync
This commit is contained in:
commit
4dc5d0ce63
@ -24,10 +24,10 @@ namespace QSB.Anglerfish.Events
|
||||
LocalDisturbancePos = qsbAngler.AttachedObject._localDisturbancePos
|
||||
};
|
||||
|
||||
public override void OnReceiveLocal(bool isHost, AnglerChangeStateMessage message) => OnReceive(isHost, message);
|
||||
public override void OnReceiveRemote(bool isHost, AnglerChangeStateMessage message) => OnReceive(isHost, message);
|
||||
public override void OnReceiveLocal(bool isHost, AnglerChangeStateMessage message) => OnReceive(message);
|
||||
public override void OnReceiveRemote(bool isHost, AnglerChangeStateMessage message) => OnReceive(message);
|
||||
|
||||
private static void OnReceive(bool isHost, AnglerChangeStateMessage message)
|
||||
private static void OnReceive(AnglerChangeStateMessage message)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
@ -35,12 +35,6 @@ namespace QSB.Anglerfish.Events
|
||||
}
|
||||
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromId<QSBAngler>(message.ObjectId);
|
||||
|
||||
if (isHost)
|
||||
{
|
||||
qsbAngler.TransferAuthority(message.FromId);
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = IdToTarget(message.TargetId);
|
||||
qsbAngler.AttachedObject._localDisturbancePos = message.LocalDisturbancePos;
|
||||
qsbAngler.AttachedObject.ChangeState(message.EnumValue);
|
||||
|
@ -2,8 +2,8 @@
|
||||
using QSB.Anglerfish.WorldObjects;
|
||||
using QSB.Events;
|
||||
using QSB.Patches;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Anglerfish.Patches
|
||||
@ -17,14 +17,41 @@ namespace QSB.Anglerfish.Patches
|
||||
public static bool GetTargetPosition(AnglerfishController __instance, ref Vector3 __result)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
|
||||
if (qsbAngler.TargetTransform != null)
|
||||
{
|
||||
__result = qsbAngler.TargetTransform.position;
|
||||
}
|
||||
__result = __instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.OnSectorOccupantsUpdated))]
|
||||
public static bool OnSectorOccupantsUpdated(AnglerfishController __instance)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
|
||||
__result = qsbAngler.TargetTransform != null
|
||||
? qsbAngler.TargetTransform.position
|
||||
: __instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos);
|
||||
if (!__instance.gameObject.activeSelf && __instance._sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe | DynamicOccupant.Ship))
|
||||
{
|
||||
__instance.gameObject.SetActive(true);
|
||||
__instance._anglerBody.Unsuspend();
|
||||
__instance.RaiseEvent(nameof(__instance.OnAnglerUnsuspended), __instance._currentState);
|
||||
QSBEventManager.FireEvent(EventNames.QSBSuspendChange, qsbAngler.TransformSync.NetIdentity, false);
|
||||
return false;
|
||||
}
|
||||
if (__instance.gameObject.activeSelf && !__instance._sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe | DynamicOccupant.Ship))
|
||||
{
|
||||
__instance._anglerBody.Suspend();
|
||||
__instance.gameObject.SetActive(false);
|
||||
__instance.RaiseEvent(nameof(__instance.OnAnglerSuspended), __instance._currentState);
|
||||
QSBEventManager.FireEvent(EventNames.QSBSuspendChange, qsbAngler.TransformSync.NetIdentity, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -35,18 +62,13 @@ namespace QSB.Anglerfish.Patches
|
||||
SectorDetector sectorDetector)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(qsbAngler.TargetTransform != null) || !(sectorDetector.GetAttachedOWRigidbody().transform == qsbAngler.TargetTransform))
|
||||
if (qsbAngler.TargetTransform != null && sectorDetector.GetAttachedOWRigidbody().transform == qsbAngler.TargetTransform)
|
||||
{
|
||||
return false;
|
||||
qsbAngler.TargetTransform = null;
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -54,113 +76,92 @@ namespace QSB.Anglerfish.Patches
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.UpdateState))]
|
||||
public static bool UpdateState(AnglerfishController __instance)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
|
||||
switch (__instance._currentState)
|
||||
{
|
||||
case AnglerfishController.AnglerState.Investigating:
|
||||
if ((__instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos) - __instance._anglerBody.GetPosition()).sqrMagnitude >= __instance._arrivalDistance * (double)__instance._arrivalDistance)
|
||||
if ((__instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos) - __instance._anglerBody.GetPosition()).sqrMagnitude < __instance._arrivalDistance * __instance._arrivalDistance)
|
||||
{
|
||||
break;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Chasing:
|
||||
if (qsbAngler.TargetTransform == null)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((qsbAngler.TargetTransform.position - __instance._anglerBody.GetPosition()).sqrMagnitude <= __instance._escapeDistance * (double)__instance._escapeDistance)
|
||||
if ((qsbAngler.TargetTransform.position - __instance._anglerBody.GetPosition()).sqrMagnitude > __instance._escapeDistance * __instance._escapeDistance)
|
||||
{
|
||||
break;
|
||||
qsbAngler.TargetTransform = null;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
return false;
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = null;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Consuming:
|
||||
if (__instance._consumeComplete)
|
||||
if (!__instance._consumeComplete)
|
||||
{
|
||||
break;
|
||||
if (qsbAngler.TargetTransform == null)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
return false;
|
||||
}
|
||||
var num = Time.time - __instance._consumeStartTime;
|
||||
if (qsbAngler.TargetTransform.CompareTag("Player") && num > __instance._consumeDeathDelay)
|
||||
{
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
__instance._consumeComplete = true;
|
||||
return false;
|
||||
}
|
||||
if (qsbAngler.TargetTransform.CompareTag("Ship"))
|
||||
{
|
||||
if (num > __instance._consumeShipCrushDelay)
|
||||
{
|
||||
qsbAngler.TargetTransform.GetComponentInChildren<ShipDamageController>().TriggerSystemFailure();
|
||||
}
|
||||
if (num > __instance._consumeDeathDelay)
|
||||
{
|
||||
if (PlayerState.IsInsideShip())
|
||||
{
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
}
|
||||
__instance._consumeComplete = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (qsbAngler.TargetTransform == null)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
}
|
||||
|
||||
var num = Time.time - __instance._consumeStartTime;
|
||||
if (qsbAngler.TargetTransform.CompareTag("Player") && num > (double)__instance._consumeDeathDelay)
|
||||
else
|
||||
{
|
||||
qsbAngler.TargetTransform = null;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
__instance.ApplyDrag(1f);
|
||||
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
__instance._consumeComplete = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!qsbAngler.TargetTransform.CompareTag("Ship"))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (num > (double)__instance._consumeShipCrushDelay)
|
||||
{
|
||||
qsbAngler.TargetTransform.GetComponentInChildren<ShipDamageController>().TriggerSystemFailure();
|
||||
}
|
||||
|
||||
if (num <= (double)__instance._consumeDeathDelay)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (PlayerState.IsInsideShip())
|
||||
{
|
||||
qsbAngler.TargetTransform = null;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
__instance.ApplyDrag(1f);
|
||||
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
}
|
||||
|
||||
__instance._consumeComplete = true;
|
||||
break;
|
||||
|
||||
case AnglerfishController.AnglerState.Stunned:
|
||||
__instance._stunTimer -= Time.deltaTime;
|
||||
if (__instance._stunTimer > 0.0)
|
||||
if (__instance._stunTimer <= 0f)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (qsbAngler.TargetTransform != null)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
|
||||
if (qsbAngler.TargetTransform != null)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
return false;
|
||||
}
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
}
|
||||
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Lurking);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -170,80 +171,79 @@ namespace QSB.Anglerfish.Patches
|
||||
[HarmonyPatch(typeof(AnglerfishController), nameof(AnglerfishController.UpdateMovement))]
|
||||
public static bool UpdateMovement(AnglerfishController __instance)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
qsbAngler.UpdateTargetVelocity();
|
||||
|
||||
qsbAngler.FixedUpdate();
|
||||
|
||||
if (__instance._anglerBody.GetVelocity().sqrMagnitude > (double)Mathf.Pow(__instance._chaseSpeed * 1.5f, 2f))
|
||||
if (__instance._anglerBody.GetVelocity().sqrMagnitude > Mathf.Pow(__instance._chaseSpeed * 1.5f, 2f))
|
||||
{
|
||||
__instance.ApplyDrag(10f);
|
||||
}
|
||||
|
||||
switch (__instance._currentState)
|
||||
{
|
||||
case AnglerfishController.AnglerState.Lurking:
|
||||
__instance.ApplyDrag(1f);
|
||||
break;
|
||||
|
||||
return false;
|
||||
case AnglerfishController.AnglerState.Investigating:
|
||||
{
|
||||
var targetPos = __instance._brambleBody.transform.TransformPoint(__instance._localDisturbancePos);
|
||||
__instance.RotateTowardsTarget(targetPos, __instance._turnSpeed, __instance._turnSpeed);
|
||||
if (__instance._turningInPlace)
|
||||
if (!__instance._turningInPlace)
|
||||
{
|
||||
break;
|
||||
__instance.MoveTowardsTarget(targetPos, __instance._investigateSpeed, __instance._acceleration);
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance.MoveTowardsTarget(targetPos, __instance._investigateSpeed, __instance._acceleration);
|
||||
break;
|
||||
|
||||
}
|
||||
case AnglerfishController.AnglerState.Chasing:
|
||||
{
|
||||
var velocity = qsbAngler.TargetVelocity;
|
||||
var normalized = velocity.normalized;
|
||||
var from = __instance._anglerBody.GetPosition() + __instance.transform.TransformDirection(__instance._mouthOffset) - qsbAngler.TargetTransform.position;
|
||||
var magnitude1 = velocity.magnitude;
|
||||
var num1 = Vector3.Angle(from, normalized);
|
||||
var a = magnitude1 * 2f;
|
||||
var num2 = a;
|
||||
if (num1 < 90.0)
|
||||
var magnitude = velocity.magnitude;
|
||||
var num = Vector3.Angle(from, normalized);
|
||||
var num2 = magnitude * 2f;
|
||||
var d = num2;
|
||||
if (num < 90f)
|
||||
{
|
||||
var magnitude2 = (double)from.magnitude;
|
||||
var num3 = (float)magnitude2 * Mathf.Sin(num1 * ((float)Math.PI / 180f));
|
||||
var num4 = (float)magnitude2 * Mathf.Cos(num1 * ((float)Math.PI / 180f));
|
||||
var magnitude2 = from.magnitude;
|
||||
var num3 = magnitude2 * Mathf.Sin(num * 0.017453292f);
|
||||
var num4 = magnitude2 * Mathf.Cos(num * 0.017453292f);
|
||||
var magnitude3 = __instance._anglerBody.GetVelocity().magnitude;
|
||||
var num5 = num4 / Mathf.Max(magnitude1, 0.0001f) / (num3 / Mathf.Max(magnitude3, 0.0001f));
|
||||
if (num5 <= 1.0)
|
||||
var num5 = num4 / Mathf.Max(magnitude, 0.0001f);
|
||||
var num6 = num3 / Mathf.Max(magnitude3, 0.0001f);
|
||||
var num7 = num5 / num6;
|
||||
if (num7 <= 1f)
|
||||
{
|
||||
var t = Mathf.Clamp01(num5);
|
||||
num2 = Mathf.Lerp(a, num4, t);
|
||||
var t = Mathf.Clamp01(num7);
|
||||
d = Mathf.Lerp(num2, num4, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
var num6 = Mathf.InverseLerp(1f, 4f, num5);
|
||||
num2 = Mathf.Lerp(num4, 0.0f, num6 * num6);
|
||||
var num8 = Mathf.InverseLerp(1f, 4f, num7);
|
||||
d = Mathf.Lerp(num4, 0f, num8 * num8);
|
||||
}
|
||||
}
|
||||
|
||||
__instance._targetPos = qsbAngler.TargetTransform.position + (normalized * num2);
|
||||
__instance._targetPos = qsbAngler.TargetTransform.position + normalized * d;
|
||||
__instance.RotateTowardsTarget(__instance._targetPos, __instance._turnSpeed, __instance._quickTurnSpeed);
|
||||
if (__instance._turningInPlace)
|
||||
if (!__instance._turningInPlace)
|
||||
{
|
||||
break;
|
||||
__instance.MoveTowardsTarget(__instance._targetPos, __instance._chaseSpeed, __instance._acceleration);
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance.MoveTowardsTarget(__instance._targetPos, __instance._chaseSpeed, __instance._acceleration);
|
||||
break;
|
||||
|
||||
}
|
||||
case AnglerfishController.AnglerState.Consuming:
|
||||
__instance.ApplyDrag(1f);
|
||||
break;
|
||||
|
||||
return false;
|
||||
case AnglerfishController.AnglerState.Stunned:
|
||||
__instance.ApplyDrag(0.5f);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -255,19 +255,16 @@ namespace QSB.Anglerfish.Patches
|
||||
ImpactData impact)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var attachedOwRigidbody = impact.otherCollider.GetAttachedOWRigidbody();
|
||||
if ((attachedOwRigidbody.CompareTag("Player") || attachedOwRigidbody.CompareTag("Ship"))
|
||||
var attachedOWRigidbody = impact.otherCollider.GetAttachedOWRigidbody();
|
||||
if ((attachedOWRigidbody.CompareTag("Player") || attachedOWRigidbody.CompareTag("Ship"))
|
||||
&& __instance._currentState != AnglerfishController.AnglerState.Consuming
|
||||
&& __instance._currentState != AnglerfishController.AnglerState.Stunned)
|
||||
{
|
||||
qsbAngler.TargetTransform = attachedOwRigidbody.transform;
|
||||
qsbAngler.TargetTransform = attachedOWRigidbody.transform;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -279,48 +276,31 @@ namespace QSB.Anglerfish.Patches
|
||||
NoiseMaker noiseMaker)
|
||||
{
|
||||
var qsbAngler = QSBWorldSync.GetWorldFromUnity<QSBAngler>(__instance);
|
||||
if (qsbAngler == null || qsbAngler.TransformSync == null)
|
||||
|
||||
if (__instance._currentState is AnglerfishController.AnglerState.Consuming or AnglerfishController.AnglerState.Stunned)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (__instance._currentState is AnglerfishController.AnglerState.Consuming
|
||||
or AnglerfishController.AnglerState.Stunned)
|
||||
if ((noiseMaker.GetNoiseOrigin() - __instance.transform.position).sqrMagnitude < __instance._pursueDistance * __instance._pursueDistance)
|
||||
{
|
||||
return false;
|
||||
if (qsbAngler.TargetTransform != noiseMaker.GetAttachedBody().transform)
|
||||
{
|
||||
qsbAngler.TargetTransform = noiseMaker.GetAttachedBody().transform;
|
||||
if (__instance._currentState != AnglerfishController.AnglerState.Chasing)
|
||||
{
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
|
||||
}
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((noiseMaker.GetNoiseOrigin() - __instance.transform.position).sqrMagnitude < __instance._pursueDistance * (double)__instance._pursueDistance)
|
||||
else if (__instance._currentState is AnglerfishController.AnglerState.Lurking or AnglerfishController.AnglerState.Investigating)
|
||||
{
|
||||
if (!(qsbAngler.TargetTransform != noiseMaker.GetAttachedBody().transform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = noiseMaker.GetAttachedBody().transform;
|
||||
if (__instance._currentState == AnglerfishController.AnglerState.Chasing)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Chasing);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__instance._currentState is not AnglerfishController.AnglerState.Lurking
|
||||
and not AnglerfishController.AnglerState.Investigating)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance._localDisturbancePos = __instance._brambleBody.transform.InverseTransformPoint(noiseMaker.GetNoiseOrigin());
|
||||
if (__instance._currentState == AnglerfishController.AnglerState.Investigating)
|
||||
if (__instance._currentState != AnglerfishController.AnglerState.Investigating)
|
||||
{
|
||||
return false;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Investigating);
|
||||
}
|
||||
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Investigating);
|
||||
QSBEventManager.FireEvent(EventNames.QSBAnglerChangeState, qsbAngler);
|
||||
}
|
||||
|
||||
@ -336,20 +316,14 @@ namespace QSB.Anglerfish.Patches
|
||||
|
||||
if (__instance._currentState == AnglerfishController.AnglerState.Consuming)
|
||||
{
|
||||
if (qsbAngler.TargetTransform.CompareTag("Player") || !caughtBody.CompareTag("Player"))
|
||||
if (!qsbAngler.TargetTransform.CompareTag("Player") && caughtBody.CompareTag("Player"))
|
||||
{
|
||||
return false;
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
}
|
||||
|
||||
Locator.GetDeathManager().KillPlayer(DeathType.Digestion);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
if (caughtBody.CompareTag("Player") || caughtBody.CompareTag("Ship"))
|
||||
{
|
||||
if (!caughtBody.CompareTag("Player") && !caughtBody.CompareTag("Ship"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qsbAngler.TargetTransform = caughtBody.transform;
|
||||
__instance._consumeStartTime = Time.time;
|
||||
__instance.ChangeState(AnglerfishController.AnglerState.Consuming);
|
||||
|
@ -1,10 +1,9 @@
|
||||
using QSB.Anglerfish.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QSB.Events;
|
||||
using QSB.SuspendableSync;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace QSB.Anglerfish.WorldObjects
|
||||
{
|
||||
@ -23,39 +22,26 @@ namespace QSB.Anglerfish.WorldObjects
|
||||
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
Object.Instantiate(QSBNetworkManager.Instance.AnglerPrefab).SpawnWithServerAuthority();
|
||||
QNetworkServer.Spawn(Object.Instantiate(QSBNetworkManager.Instance.AnglerPrefab));
|
||||
QSBCore.UnityEvents.RunWhen(() => TransformSync, () =>
|
||||
SuspendableManager.Register(TransformSync.NetIdentity));
|
||||
}
|
||||
|
||||
// for when you host/connect mid-game
|
||||
QSBCore.UnityEvents.RunWhen(() => TransformSync, () =>
|
||||
QSBEventManager.FireEvent(EventNames.QSBSuspendChange, TransformSync.NetIdentity, AttachedObject._anglerBody.IsSuspended()));
|
||||
}
|
||||
|
||||
public override void OnRemoval()
|
||||
{
|
||||
if (QSBCore.IsHost)
|
||||
{
|
||||
SuspendableManager.Unregister(TransformSync.NetIdentity);
|
||||
QNetworkServer.Destroy(TransformSync.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void TransferAuthority(uint id)
|
||||
{
|
||||
var conn = QNetworkServer.connections.First(x => x.GetPlayerId() == id);
|
||||
var identity = TransformSync.NetIdentity;
|
||||
|
||||
if (identity.ClientAuthorityOwner == conn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (identity.ClientAuthorityOwner != null)
|
||||
{
|
||||
identity.RemoveClientAuthority(identity.ClientAuthorityOwner);
|
||||
}
|
||||
|
||||
identity.AssignClientAuthority(conn);
|
||||
|
||||
DebugLog.DebugWrite($"angler {ObjectId} - transferred authority to {id}");
|
||||
}
|
||||
|
||||
public void FixedUpdate()
|
||||
public void UpdateTargetVelocity()
|
||||
{
|
||||
if (TargetTransform == null)
|
||||
{
|
||||
|
@ -1,14 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace QSB.Events
|
||||
namespace QSB.Events
|
||||
{
|
||||
public abstract class BaseQSBEvent : IQSBEvent
|
||||
{
|
||||
protected static int _msgType = 0;
|
||||
internal static int _msgType;
|
||||
|
||||
public abstract void SetupListener();
|
||||
public abstract void CloseListener();
|
||||
|
@ -101,5 +101,6 @@
|
||||
public static string QSBLearnLaunchCodes = "QSBLearnLaunchCodes";
|
||||
public static string QSBSatelliteRepairTick = "QSBSatelliteRepairTick";
|
||||
public static string QSBSatelliteRepaired = "QSBSatelliteRepairTick";
|
||||
public static string QSBSuspendChange = "QSBSuspendChange";
|
||||
}
|
||||
}
|
||||
|
@ -5,4 +5,4 @@
|
||||
void SetupListener();
|
||||
void CloseListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using OWML.Common;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
@ -6,8 +7,6 @@ using QSB.Player.Events;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET.Components;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Events
|
||||
{
|
||||
@ -29,11 +28,6 @@ namespace QSB.Events
|
||||
_eventHandler.OnServerReceiveMessage += message => OnReceive(true, message);
|
||||
}
|
||||
|
||||
~QSBEvent()
|
||||
{
|
||||
_msgType--;
|
||||
}
|
||||
|
||||
public virtual void OnReceiveRemote(bool isHost, T message) { }
|
||||
public virtual void OnReceiveLocal(bool isHost, T message) { }
|
||||
|
||||
@ -114,4 +108,4 @@ namespace QSB.Events
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OWML.Common;
|
||||
using System.Collections.Generic;
|
||||
using OWML.Common;
|
||||
using QSB.Anglerfish.Events;
|
||||
using QSB.Animation.NPC.Events;
|
||||
using QSB.Animation.Player.Events;
|
||||
@ -21,6 +22,7 @@ using QSB.ShipSync.Events;
|
||||
using QSB.ShipSync.Events.Component;
|
||||
using QSB.ShipSync.Events.Hull;
|
||||
using QSB.StatueSync.Events;
|
||||
using QSB.SuspendableSync;
|
||||
using QSB.TimeSync.Events;
|
||||
using QSB.Tools.FlashlightTool.Events;
|
||||
using QSB.Tools.ProbeLauncherTool.Events;
|
||||
@ -32,9 +34,6 @@ using QSB.Tools.TranslatorTool.TranslationSync.Events;
|
||||
using QSB.Utility;
|
||||
using QSB.Utility.Events;
|
||||
using QSB.ZeroGCaveSync.Events;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace QSB.Events
|
||||
{
|
||||
@ -46,6 +45,7 @@ namespace QSB.Events
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
BaseQSBEvent._msgType = 0;
|
||||
_eventList = new List<IQSBEvent>
|
||||
{
|
||||
// Player
|
||||
@ -112,6 +112,7 @@ namespace QSB.Events
|
||||
new IdentifyFrequencyEvent(),
|
||||
new IdentifySignalEvent(),
|
||||
new NpcAnimationEvent(),
|
||||
new SuspendChangeEvent(),
|
||||
// Ship
|
||||
new FlyShipEvent(),
|
||||
new HatchEvent(),
|
||||
|
@ -148,6 +148,10 @@ namespace QSB.MeteorSync.Patches
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!MeteorManager.Ready)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var qsbFragment = QSBWorldSync.GetWorldFromUnity<QSBFragment>(__instance._detachableFragment._fragmentIntegrity);
|
||||
|
||||
|
@ -15,6 +15,11 @@ namespace QSB.MeteorSync.Patches
|
||||
[HarmonyPatch(typeof(MeteorLauncher), nameof(MeteorLauncher.FixedUpdate))]
|
||||
public static bool FixedUpdate(MeteorLauncher __instance)
|
||||
{
|
||||
if (!MeteorManager.Ready)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (__instance._launchedMeteors != null)
|
||||
{
|
||||
for (var i = __instance._launchedMeteors.Count - 1; i >= 0; i--)
|
||||
@ -197,6 +202,10 @@ namespace QSB.MeteorSync.Patches
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!MeteorManager.Ready)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var qsbFragment = QSBWorldSync.GetWorldFromUnity<QSBFragment>(__instance._detachableFragment._fragmentIntegrity);
|
||||
|
||||
|
@ -84,10 +84,18 @@ namespace QSB.Patches
|
||||
|
||||
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") }
|
||||
{
|
||||
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);
|
||||
@ -109,13 +117,13 @@ namespace QSB.Patches
|
||||
try
|
||||
{
|
||||
patch.DoPatches(TypeToInstance[type]);
|
||||
_patchedTypes.Add(type);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
DebugLog.ToConsole($"Error while patching {patch.GetType().Name} :\r\n{ex}", MessageType.Error);
|
||||
}
|
||||
}
|
||||
_patchedTypes.Add(type);
|
||||
}
|
||||
|
||||
public static void DoUnpatchType(QSBPatchTypes type)
|
||||
|
@ -1,4 +1,6 @@
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using QSB.ClientServerStateSync;
|
||||
using QSB.DeathSync;
|
||||
@ -8,13 +10,13 @@ using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.PoolSync;
|
||||
using QSB.ShipSync.TransformSync;
|
||||
using QSB.SuspendableSync;
|
||||
using QSB.TimeSync;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
using QuantumUNET;
|
||||
using QuantumUNET.Components;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
@ -157,7 +159,7 @@ namespace QSB
|
||||
if (!QSBCore.IsHost)
|
||||
{
|
||||
QSBCore.UnityEvents.RunWhen(() => QSBEventManager.Ready && PlayerTransformSync.LocalInstance != null,
|
||||
() => QSBEventManager.FireEvent(EventNames.QSBRequestStateResync));
|
||||
() => QSBEventManager.FireEvent(EventNames.QSBRequestStateResync));
|
||||
}
|
||||
|
||||
_everConnected = true;
|
||||
@ -199,24 +201,38 @@ namespace QSB
|
||||
OnClientDisconnected?.SafeInvoke(conn.LastError);
|
||||
}
|
||||
|
||||
public override void OnServerDisconnect(QNetworkConnection connection) // Called on the server when any client disconnects
|
||||
public override void OnServerDisconnect(QNetworkConnection conn) // Called on the server when any client disconnects
|
||||
{
|
||||
base.OnServerDisconnect(connection);
|
||||
DebugLog.DebugWrite("OnServerDisconnect", MessageType.Info);
|
||||
|
||||
// remove authority for orbs
|
||||
foreach (var item in NomaiOrbTransformSync.OrbTransformSyncs)
|
||||
{
|
||||
if (item is null)
|
||||
if (!item)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var identity = item.GetComponent<QNetworkIdentity>();
|
||||
if (identity.ClientAuthorityOwner == connection)
|
||||
var identity = item.NetIdentity;
|
||||
if (identity.ClientAuthorityOwner == conn)
|
||||
{
|
||||
identity.RemoveClientAuthority(connection);
|
||||
identity.RemoveClientAuthority(conn);
|
||||
}
|
||||
}
|
||||
|
||||
// remove authority from ship
|
||||
if (ShipTransformSync.LocalInstance)
|
||||
{
|
||||
var identity = ShipTransformSync.LocalInstance.NetIdentity;
|
||||
if (identity.ClientAuthorityOwner == conn)
|
||||
{
|
||||
identity.RemoveClientAuthority(conn);
|
||||
}
|
||||
}
|
||||
|
||||
SuspendableManager.OnDisconnect(conn);
|
||||
|
||||
base.OnServerDisconnect(conn);
|
||||
}
|
||||
|
||||
public override void OnStopServer()
|
||||
|
37
QSB/SuspendableSync/SuspendChangeEvent.cs
Normal file
37
QSB/SuspendableSync/SuspendChangeEvent.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using QSB.Events;
|
||||
using QuantumUNET.Components;
|
||||
|
||||
namespace QSB.SuspendableSync
|
||||
{
|
||||
public class SuspendChangeEvent : QSBEvent<SuspendChangeMessage>
|
||||
{
|
||||
public override void SetupListener() =>
|
||||
GlobalMessenger<QNetworkIdentity, bool>.AddListener(EventNames.QSBSuspendChange, Handler);
|
||||
|
||||
public override void CloseListener() =>
|
||||
GlobalMessenger<QNetworkIdentity, bool>.RemoveListener(EventNames.QSBSuspendChange, Handler);
|
||||
|
||||
private void Handler(QNetworkIdentity identity, bool suspended) => SendEvent(CreateMessage(identity, suspended));
|
||||
|
||||
private SuspendChangeMessage CreateMessage(QNetworkIdentity identity, bool unsuspended) => new()
|
||||
{
|
||||
OnlySendToHost = true,
|
||||
Identity = identity,
|
||||
Suspended = unsuspended
|
||||
};
|
||||
|
||||
|
||||
public override void OnReceiveLocal(bool isHost, SuspendChangeMessage message) => OnReceive(message);
|
||||
public override void OnReceiveRemote(bool isHost, SuspendChangeMessage message) => OnReceive(message);
|
||||
|
||||
private static void OnReceive(SuspendChangeMessage message)
|
||||
{
|
||||
if (!QSBCore.WorldObjectsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SuspendableManager.UpdateSuspended(message.FromId, message.Identity, message.Suspended);
|
||||
}
|
||||
}
|
||||
}
|
26
QSB/SuspendableSync/SuspendChangeMessage.cs
Normal file
26
QSB/SuspendableSync/SuspendChangeMessage.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using QSB.Messaging;
|
||||
using QuantumUNET.Components;
|
||||
using QuantumUNET.Transport;
|
||||
|
||||
namespace QSB.SuspendableSync
|
||||
{
|
||||
public class SuspendChangeMessage : PlayerMessage
|
||||
{
|
||||
public QNetworkIdentity Identity;
|
||||
public bool Suspended;
|
||||
|
||||
public override void Deserialize(QNetworkReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
Identity = reader.ReadNetworkIdentity();
|
||||
Suspended = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
public override void Serialize(QNetworkWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(Identity);
|
||||
writer.Write(Suspended);
|
||||
}
|
||||
}
|
||||
}
|
80
QSB/SuspendableSync/SuspendableManager.cs
Normal file
80
QSB/SuspendableSync/SuspendableManager.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QSB.Utility;
|
||||
using QuantumUNET;
|
||||
using QuantumUNET.Components;
|
||||
|
||||
namespace QSB.SuspendableSync
|
||||
{
|
||||
/// all of this is host only
|
||||
public static class SuspendableManager
|
||||
{
|
||||
private static readonly Dictionary<QNetworkIdentity, List<uint>> _unsuspendedFor = new();
|
||||
|
||||
public static void Register(QNetworkIdentity identity) => _unsuspendedFor.Add(identity, new List<uint>());
|
||||
public static void Unregister(QNetworkIdentity identity) => _unsuspendedFor.Remove(identity);
|
||||
|
||||
public static void UpdateSuspended(uint id, QNetworkIdentity identity, bool suspended)
|
||||
{
|
||||
var unsuspendedFor = _unsuspendedFor[identity];
|
||||
|
||||
var oldSuspended = !unsuspendedFor.Contains(id);
|
||||
if (suspended == oldSuspended)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!suspended)
|
||||
{
|
||||
unsuspendedFor.Add(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsuspendedFor.Remove(id);
|
||||
}
|
||||
|
||||
var newOwner = unsuspendedFor.Count != 0 ? unsuspendedFor[0] : uint.MaxValue;
|
||||
SetAuthority(identity, newOwner);
|
||||
}
|
||||
|
||||
private static void SetAuthority(QNetworkIdentity identity, uint id)
|
||||
{
|
||||
var oldConn = identity.ClientAuthorityOwner;
|
||||
var newConn = id != uint.MaxValue
|
||||
? QNetworkServer.connections.First(x => x.GetPlayerId() == id)
|
||||
: null;
|
||||
|
||||
if (oldConn == newConn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldConn != null)
|
||||
{
|
||||
identity.RemoveClientAuthority(oldConn);
|
||||
}
|
||||
|
||||
if (newConn != null)
|
||||
{
|
||||
identity.AssignClientAuthority(newConn);
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"{identity.NetId}:{identity.gameObject.name} - set authority to {id}");
|
||||
}
|
||||
|
||||
|
||||
/// transfer authority to a different client
|
||||
public static void OnDisconnect(QNetworkConnection conn)
|
||||
{
|
||||
var id = conn.GetPlayerId();
|
||||
foreach (var (identity, unsuspendedFor) in _unsuspendedFor)
|
||||
{
|
||||
if (unsuspendedFor.Remove(id))
|
||||
{
|
||||
var newOwner = unsuspendedFor.Count != 0 ? unsuspendedFor[0] : uint.MaxValue;
|
||||
SetAuthority(identity, newOwner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user