summaryrefslogtreecommitdiff
path: root/Valheim_v202102/Valheim/assembly_valheim/ZSyncTransform.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Valheim_v202102/Valheim/assembly_valheim/ZSyncTransform.cs')
-rw-r--r--Valheim_v202102/Valheim/assembly_valheim/ZSyncTransform.cs327
1 files changed, 327 insertions, 0 deletions
diff --git a/Valheim_v202102/Valheim/assembly_valheim/ZSyncTransform.cs b/Valheim_v202102/Valheim/assembly_valheim/ZSyncTransform.cs
new file mode 100644
index 0000000..01431f0
--- /dev/null
+++ b/Valheim_v202102/Valheim/assembly_valheim/ZSyncTransform.cs
@@ -0,0 +1,327 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class ZSyncTransform : MonoBehaviour
+{
+ public bool m_syncPosition = true;
+
+ public bool m_syncRotation = true;
+
+ public bool m_syncScale;
+
+ public bool m_syncBodyVelocity;
+
+ public bool m_characterParentSync;
+
+ private const float m_smoothness = 0.2f;
+
+ private bool m_isKinematicBody;
+
+ private bool m_useGravity = true;
+
+ private Vector3 m_tempRelPos;
+
+ private bool m_haveTempRelPos;
+
+ private float m_targetPosTimer;
+
+ private uint m_posRevision;
+
+ private int m_lastUpdateFrame = -1;
+
+ private static int m_velHash = "vel".GetStableHashCode();
+
+ private static int m_scaleHash = "scale".GetStableHashCode();
+
+ private static int m_bodyVel = "body_vel".GetStableHashCode();
+
+ private static int m_bodyAVel = "body_avel".GetStableHashCode();
+
+ private static int m_relPos = "relPos".GetStableHashCode();
+
+ private static KeyValuePair<int, int> m_parentIDHash = ZDO.GetHashZDOID("parentID");
+
+ private ZNetView m_nview;
+
+ private Rigidbody m_body;
+
+ private Projectile m_projectile;
+
+ private Character m_character;
+
+ private void Awake()
+ {
+ m_nview = GetComponent<ZNetView>();
+ m_body = GetComponent<Rigidbody>();
+ m_projectile = GetComponent<Projectile>();
+ m_character = GetComponent<Character>();
+ if (m_nview.GetZDO() == null)
+ {
+ base.enabled = false;
+ }
+ else if ((bool)m_body)
+ {
+ m_isKinematicBody = m_body.isKinematic;
+ m_useGravity = m_body.useGravity;
+ }
+ }
+
+ private Vector3 GetVelocity()
+ {
+ if (m_body != null)
+ {
+ return m_body.velocity;
+ }
+ if (m_projectile != null)
+ {
+ return m_projectile.GetVelocity();
+ }
+ return Vector3.zero;
+ }
+
+ private Vector3 GetPosition()
+ {
+ if (!m_body)
+ {
+ return base.transform.position;
+ }
+ return m_body.position;
+ }
+
+ private void OwnerSync()
+ {
+ ZDO zDO = m_nview.GetZDO();
+ if (!zDO.IsOwner())
+ {
+ return;
+ }
+ if (base.transform.position.y < -5000f)
+ {
+ if ((bool)m_body)
+ {
+ m_body.velocity = Vector3.zero;
+ }
+ ZLog.Log("Object fell out of world:" + base.gameObject.name);
+ float groundHeight = ZoneSystem.instance.GetGroundHeight(base.transform.position);
+ Vector3 position = base.transform.position;
+ position.y = groundHeight + 1f;
+ base.transform.position = position;
+ return;
+ }
+ if (m_syncPosition)
+ {
+ zDO.SetPosition(GetPosition());
+ zDO.Set(m_velHash, GetVelocity());
+ if (m_characterParentSync)
+ {
+ if (m_character.GetRelativePosition(out var parent, out var relativePos, out var relativeVel))
+ {
+ zDO.Set(m_parentIDHash, parent);
+ zDO.Set(m_relPos, relativePos);
+ zDO.Set(m_velHash, relativeVel);
+ }
+ else
+ {
+ zDO.Set(m_parentIDHash, ZDOID.None);
+ }
+ }
+ }
+ if (m_syncRotation && base.transform.hasChanged)
+ {
+ Quaternion rotation = (m_body ? m_body.rotation : base.transform.rotation);
+ zDO.SetRotation(rotation);
+ }
+ if (m_syncScale && base.transform.hasChanged)
+ {
+ zDO.Set(m_scaleHash, base.transform.localScale);
+ }
+ if ((bool)m_body)
+ {
+ if (m_syncBodyVelocity)
+ {
+ m_nview.GetZDO().Set(m_bodyVel, m_body.velocity);
+ m_nview.GetZDO().Set(m_bodyAVel, m_body.angularVelocity);
+ }
+ m_body.useGravity = m_useGravity;
+ }
+ base.transform.hasChanged = false;
+ }
+
+ private void SyncPosition(ZDO zdo, float dt)
+ {
+ if (m_characterParentSync && zdo.HasOwner())
+ {
+ ZDOID zDOID = zdo.GetZDOID(m_parentIDHash);
+ if (!zDOID.IsNone())
+ {
+ GameObject gameObject = ZNetScene.instance.FindInstance(zDOID);
+ if ((bool)gameObject)
+ {
+ ZSyncTransform component = gameObject.GetComponent<ZSyncTransform>();
+ if ((bool)component)
+ {
+ component.ClientSync(dt);
+ }
+ Vector3 vector = zdo.GetVec3(m_relPos, Vector3.zero);
+ Vector3 vec = zdo.GetVec3(m_velHash, Vector3.zero);
+ if (zdo.m_dataRevision != m_posRevision)
+ {
+ m_posRevision = zdo.m_dataRevision;
+ m_targetPosTimer = 0f;
+ }
+ m_targetPosTimer += dt;
+ m_targetPosTimer = Mathf.Min(m_targetPosTimer, 2f);
+ vector += vec * m_targetPosTimer;
+ if (!m_haveTempRelPos)
+ {
+ m_haveTempRelPos = true;
+ m_tempRelPos = vector;
+ }
+ if (Vector3.Distance(m_tempRelPos, vector) > 0.001f)
+ {
+ m_tempRelPos = Vector3.Lerp(m_tempRelPos, vector, 0.2f);
+ vector = m_tempRelPos;
+ }
+ Vector3 vector2 = gameObject.transform.TransformPoint(vector);
+ if (Vector3.Distance(base.transform.position, vector2) > 0.001f)
+ {
+ base.transform.position = vector2;
+ }
+ return;
+ }
+ }
+ }
+ m_haveTempRelPos = false;
+ Vector3 position = zdo.GetPosition();
+ if (zdo.m_dataRevision != m_posRevision)
+ {
+ m_posRevision = zdo.m_dataRevision;
+ m_targetPosTimer = 0f;
+ }
+ if (zdo.HasOwner())
+ {
+ m_targetPosTimer += dt;
+ m_targetPosTimer = Mathf.Min(m_targetPosTimer, 2f);
+ Vector3 vec2 = zdo.GetVec3(m_velHash, Vector3.zero);
+ position += vec2 * m_targetPosTimer;
+ }
+ if (Vector3.Distance(base.transform.position, position) > 0.001f)
+ {
+ base.transform.position = Vector3.Lerp(base.transform.position, position, 0.2f);
+ }
+ }
+
+ private void ClientSync(float dt)
+ {
+ ZDO zDO = m_nview.GetZDO();
+ if (zDO.IsOwner())
+ {
+ return;
+ }
+ int frameCount = Time.frameCount;
+ if (m_lastUpdateFrame == frameCount)
+ {
+ return;
+ }
+ m_lastUpdateFrame = frameCount;
+ if (m_isKinematicBody)
+ {
+ if (m_syncPosition)
+ {
+ Vector3 vector = zDO.GetPosition();
+ if (Vector3.Distance(m_body.position, vector) > 5f)
+ {
+ m_body.position = vector;
+ }
+ else
+ {
+ if (Vector3.Distance(m_body.position, vector) > 0.01f)
+ {
+ vector = Vector3.Lerp(m_body.position, vector, 0.2f);
+ }
+ m_body.MovePosition(vector);
+ }
+ }
+ if (m_syncRotation)
+ {
+ Quaternion rotation = zDO.GetRotation();
+ if (Quaternion.Angle(m_body.rotation, rotation) > 45f)
+ {
+ m_body.rotation = rotation;
+ }
+ else
+ {
+ m_body.MoveRotation(rotation);
+ }
+ }
+ }
+ else
+ {
+ if (m_syncPosition)
+ {
+ SyncPosition(zDO, dt);
+ }
+ if (m_syncRotation)
+ {
+ Quaternion rotation2 = zDO.GetRotation();
+ if (Quaternion.Angle(base.transform.rotation, rotation2) > 0.001f)
+ {
+ base.transform.rotation = Quaternion.Slerp(base.transform.rotation, rotation2, 0.2f);
+ }
+ }
+ if ((bool)m_body)
+ {
+ m_body.useGravity = false;
+ if (m_syncBodyVelocity && m_nview.HasOwner())
+ {
+ Vector3 vec = zDO.GetVec3(m_bodyVel, Vector3.zero);
+ Vector3 vec2 = zDO.GetVec3(m_bodyAVel, Vector3.zero);
+ if (vec.magnitude > 0.01f || vec2.magnitude > 0.01f)
+ {
+ m_body.velocity = vec;
+ m_body.angularVelocity = vec2;
+ }
+ else
+ {
+ m_body.Sleep();
+ }
+ }
+ else if (!m_body.IsSleeping())
+ {
+ m_body.velocity = Vector3.zero;
+ m_body.angularVelocity = Vector3.zero;
+ m_body.Sleep();
+ }
+ }
+ }
+ if (m_syncScale)
+ {
+ Vector3 vec3 = zDO.GetVec3(m_scaleHash, base.transform.localScale);
+ base.transform.localScale = vec3;
+ }
+ }
+
+ private void FixedUpdate()
+ {
+ if (m_nview.IsValid())
+ {
+ ClientSync(Time.fixedDeltaTime);
+ }
+ }
+
+ private void LateUpdate()
+ {
+ if (m_nview.IsValid())
+ {
+ OwnerSync();
+ }
+ }
+
+ public void SyncNow()
+ {
+ if (m_nview.IsValid())
+ {
+ OwnerSync();
+ }
+ }
+}