diff --git a/BoneSync/BoneSync.csproj b/BoneSync/BoneSync.csproj
index 818b769..26d93f2 100644
--- a/BoneSync/BoneSync.csproj
+++ b/BoneSync/BoneSync.csproj
@@ -93,8 +93,10 @@
+
+
diff --git a/BoneSync/Data/ByteEncoder.cs b/BoneSync/Data/ByteEncoder.cs
index 1b1f682..b5e1101 100644
--- a/BoneSync/Data/ByteEncoder.cs
+++ b/BoneSync/Data/ByteEncoder.cs
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using UnityEngine;
namespace BoneSync.Data
{
@@ -45,6 +46,7 @@ namespace BoneSync.Data
}
internal class ByteEncoder
{
+
public List Data;
public ByteEncoder()
{
@@ -61,6 +63,11 @@ namespace BoneSync.Data
return Data.ToArray();
}
+ public void SetBytes(byte[] data)
+ {
+ Data = data.ToList();
+ }
+
public void WriteByte(byte value)
{
Data.Add(value);
@@ -169,30 +176,30 @@ namespace BoneSync.Data
return BitConverter.ToUInt64(ReadBytes(sizeof(ulong)), 0);
}
- public void WriteVector3(UnityEngine.Vector3 value)
+ public void WriteVector3(Vector3 value)
{
WriteFloat(value.x);
WriteFloat(value.y);
WriteFloat(value.z);
}
- public UnityEngine.Vector3 ReadVector3()
+ public Vector3 ReadVector3()
{
float x = ReadFloat();
float y = ReadFloat();
float z = ReadFloat();
- return new UnityEngine.Vector3(x, y, z);
+ return new Vector3(x, y, z);
}
- public void WriteQuaternion(UnityEngine.Quaternion value)
+ public void WriteQuaternion(Quaternion value)
{
WriteVector3(value.eulerAngles);
}
- public UnityEngine.Quaternion ReadQuaternion()
+ public Quaternion ReadQuaternion()
{
- UnityEngine.Vector3 eulerAngles = ReadVector3();
- return UnityEngine.Quaternion.Euler(eulerAngles);
+ Vector3 eulerAngles = ReadVector3();
+ return Quaternion.Euler(eulerAngles);
}
public void WriteSimpleTransform(SimpleSyncTransform value)
@@ -204,9 +211,9 @@ namespace BoneSync.Data
public SimpleSyncTransform ReadSimpleTransform()
{
- UnityEngine.Vector3 position = ReadVector3();
- UnityEngine.Quaternion rotation = ReadQuaternion();
- UnityEngine.Vector3 scale = ReadVector3();
+ Vector3 position = ReadVector3();
+ Quaternion rotation = ReadQuaternion();
+ Vector3 scale = ReadVector3();
return new SimpleSyncTransform()
{
position = position,
@@ -215,7 +222,7 @@ namespace BoneSync.Data
};
}
- public void WriteMatrix4x4(UnityEngine.Matrix4x4 matrix)
+ public void WriteMatrix4x4(Matrix4x4 matrix)
{
for (int i = 0; i < 16; i++)
{
@@ -223,9 +230,9 @@ namespace BoneSync.Data
}
}
- public UnityEngine.Matrix4x4 ReadMatrix4x4()
+ public Matrix4x4 ReadMatrix4x4()
{
- UnityEngine.Matrix4x4 matrix = new UnityEngine.Matrix4x4();
+ Matrix4x4 matrix = new Matrix4x4();
for (int i = 0; i < 16; i++)
{
matrix[i] = ReadFloat();
@@ -307,12 +314,14 @@ namespace BoneSync.Data
public void WriteCompressedFloat(float value)
{
// write a float in the range of 0-1 with 2 decimal places
- WriteByte((byte)(value * 100));
+ value = Mathf.Clamp01(value);
+ int rounded = Mathf.FloorToInt(value * 255f);
+ WriteByte((byte)rounded);
}
public float ReadCompressedFloat()
{
- return ReadByte() / 100f;
+ return ReadByte() / 255f;
}
public void WriteFingerCurl(SimpleFingerCurl fingerCurl)
diff --git a/BoneSync/Data/PlayerScripts.cs b/BoneSync/Data/PlayerScripts.cs
index a114bf7..e504973 100644
--- a/BoneSync/Data/PlayerScripts.cs
+++ b/BoneSync/Data/PlayerScripts.cs
@@ -10,12 +10,14 @@ using StressLevelZero.Rig;
using StressLevelZero.VRMK;
using UnhollowerBaseLib;
using UnityEngine;
+using StressLevelZero.Player;
namespace BoneSync.Data
{
// copied from Entanglement mod
public static class PlayerScripts
{
+ public static GameObject localPlayerGameObject;
public static RigManager playerRig;
public static PhysBody playerPhysBody;
public static Player_Health playerHealth;
@@ -28,13 +30,15 @@ namespace BoneSync.Data
public static void GetPlayerScripts()
{
- GameObject localPlayerRig = GameObject.Find("[RigManager (Default Brett)]/[SkeletonRig (GameWorld Brett)]");
- playerRig = localPlayerRig.GetComponentInChildren();
+ if (playerRig != null)
+ return;
+ localPlayerGameObject = GameObject.Find("[RigManager (Default Brett)]");
+ playerRig = localPlayerGameObject.GetComponentInChildren();
playerHealth = playerRig.playerHealth;
reloadLevelOnDeath = playerHealth.reloadLevelOnDeath;
- playerHealth.reloadLevelOnDeath = !BoneSync.lobby.IsConnected();
+ playerHealth.reloadLevelOnDeath = !BoneSync.IsConnected;
try
{
@@ -54,6 +58,7 @@ namespace BoneSync.Data
public static void GetHandPoses()
{
+ GetPlayerScripts();
// Checks if we already got the hand poses to prevent crashes
if (playerHandPoses == null)
CharacterAnimationManager.FetchHandPoseList(out playerHandPoses); // Lets hope this is constant!
diff --git a/BoneSync/MelonLoaderMod.cs b/BoneSync/MelonLoaderMod.cs
index a543204..64b9e0d 100644
--- a/BoneSync/MelonLoaderMod.cs
+++ b/BoneSync/MelonLoaderMod.cs
@@ -24,6 +24,12 @@ namespace BoneSync
public class BoneSync : MelonMod
{
+ public static bool IsConnected
+ {
+ get; private set;
+ }
+
+
public static LobbyManager lobby;
public static TransportBase transport;
public override void OnApplicationStart()
@@ -70,8 +76,8 @@ namespace BoneSync
public override void OnUpdate()
{
-
- bool processPackets = transport.Tick();
+ PlayerRig.LocalSyncTick();
+ transport.Tick();
//PlayerRig.Tick();
@@ -85,12 +91,6 @@ namespace BoneSync
lobby.CreateLobby();
}
- if (Input.GetKeyDown(KeyCode.L))
- {
- MelonLogger.Msg("Reloading bundle");
- PlayerRig.LoadBundle();
- }
-
if (Input.GetKeyDown(KeyCode.N))
{
MelonLogger.Msg("Creating debug player rig");
@@ -111,6 +111,8 @@ namespace BoneSync
public override void OnFixedUpdate()
{
+ IsConnected = lobby.IsConnected();
+ transport.Tick();
PlayerRig.Tick();
}
diff --git a/BoneSync/Networking/Messages/AISyncMessage.cs b/BoneSync/Networking/Messages/AISyncMessage.cs
new file mode 100644
index 0000000..4714fc2
--- /dev/null
+++ b/BoneSync/Networking/Messages/AISyncMessage.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using BoneSync.Sync;
+using BoneSync.Sync.Components;
+using PuppetMasta;
+using StressLevelZero.AI;
+
+namespace BoneSync.Networking.Messages
+{
+ public struct AIBehaviourHealth
+ {
+ public float cur_hp;
+ public float cur_arm_lf;
+ public float cur_arm_rt;
+ public float cur_leg_lf;
+ public float cur_leg_rt;
+
+ public AIBehaviourHealth(SubBehaviourHealth behaviourHealth)
+ {
+ cur_hp = behaviourHealth.cur_hp;
+ cur_arm_lf = behaviourHealth.cur_arm_lf;
+ cur_arm_rt = behaviourHealth.cur_arm_rt;
+ cur_leg_lf = behaviourHealth.cur_leg_lf;
+ cur_leg_rt = behaviourHealth.cur_leg_rt;
+ }
+ }
+
+ public struct AISyncInfo
+ {
+ public ushort syncId;
+ public AIBehaviourHealth health;
+ public PuppetMaster.State puppetState;
+ public PuppetMaster.Mode puppetMode;
+ public BehaviourBaseNav.MentalState mentalState;
+
+ public AISyncInfo(ushort syncid, AIBrain aiBrain)
+ {
+ this.syncId = syncid;
+ this.health = new AIBehaviourHealth(aiBrain.behaviour.health);
+ this.puppetState = aiBrain.puppetMaster.activeState;
+ this.puppetMode = aiBrain.puppetMaster.activeMode;
+ this.mentalState = aiBrain.behaviour.mentalState;
+ }
+ }
+ [PacketType(PacketType.AISync), PacketReliability(PacketReliability.Unreliable)]
+ public class AISyncMessage : NetworkMessage
+ {
+ private AISyncInfo _aiSyncInfo;
+ public AISyncInfo aiSyncInfo => _aiSyncInfo;
+
+ public AISyncMessage(AISyncInfo aiSyncInfo)
+ {
+ _aiSyncInfo = aiSyncInfo;
+ byteEncoder.WriteUShort(_aiSyncInfo.syncId);
+ byteEncoder.WriteCompressedFloat(_aiSyncInfo.health.cur_hp);
+ byteEncoder.WriteCompressedFloat(_aiSyncInfo.health.cur_arm_lf);
+ byteEncoder.WriteCompressedFloat(_aiSyncInfo.health.cur_arm_rt);
+ byteEncoder.WriteCompressedFloat(_aiSyncInfo.health.cur_leg_lf);
+ byteEncoder.WriteCompressedFloat(_aiSyncInfo.health.cur_leg_rt);
+ byteEncoder.WriteByte((byte)_aiSyncInfo.puppetState);
+ byteEncoder.WriteByte((byte)_aiSyncInfo.puppetMode);
+ byteEncoder.WriteByte((byte)_aiSyncInfo.mentalState);
+ }
+
+ public AISyncMessage(Packet packet)
+ {
+ byteEncoder.WriteBytes(packet.Data);
+ _aiSyncInfo = new AISyncInfo();
+ _aiSyncInfo.syncId = byteEncoder.ReadUShort();
+ _aiSyncInfo.health.cur_hp = byteEncoder.ReadCompressedFloat();
+ _aiSyncInfo.health.cur_arm_lf = byteEncoder.ReadCompressedFloat();
+ _aiSyncInfo.health.cur_arm_rt = byteEncoder.ReadCompressedFloat();
+ _aiSyncInfo.health.cur_leg_lf = byteEncoder.ReadCompressedFloat();
+ _aiSyncInfo.health.cur_leg_rt = byteEncoder.ReadCompressedFloat();
+ _aiSyncInfo.puppetState = (PuppetMaster.State)byteEncoder.ReadByte();
+ _aiSyncInfo.puppetMode = (PuppetMaster.Mode)byteEncoder.ReadByte();
+ _aiSyncInfo.mentalState = (BehaviourBaseNav.MentalState)byteEncoder.ReadByte();
+ }
+
+ public override void Execute()
+ {
+ Syncable syncable = ObjectSyncCache.GetSyncable(_aiSyncInfo.syncId);
+ if (syncable == null) return;
+ syncable.OnAISyncData(_aiSyncInfo);
+ }
+ }
+}
diff --git a/BoneSync/Networking/Messages/PlayerSyncMessage.cs b/BoneSync/Networking/Messages/PlayerSyncMessage.cs
index 66ccd2a..d0f43e7 100644
--- a/BoneSync/Networking/Messages/PlayerSyncMessage.cs
+++ b/BoneSync/Networking/Messages/PlayerSyncMessage.cs
@@ -56,12 +56,12 @@ namespace BoneSync.Networking.Messages
byteEncoder.WriteSimpleTransform(_playerSyncInfo.headPos);
byteEncoder.WriteSimpleTransform(_playerSyncInfo.leftHandPos);
byteEncoder.WriteSimpleTransform(_playerSyncInfo.rightHandPos);
- byteEncoder.WriteFingerCurl(_playerSyncInfo.leftHandFingerCurl);
- byteEncoder.WriteFingerCurl(_playerSyncInfo.rightHandFingerCurl);
byteEncoder.WriteByte(_playerSyncInfo.poseIndexRight);
byteEncoder.WriteByte(_playerSyncInfo.poseIndexLeft);
- byteEncoder.WriteFloat(_playerSyncInfo.poseRadiusRight);
- byteEncoder.WriteFloat(_playerSyncInfo.poseRadiusLeft);
+ byteEncoder.WriteCompressedFloat(_playerSyncInfo.poseRadiusRight);
+ byteEncoder.WriteCompressedFloat(_playerSyncInfo.poseRadiusLeft);
+ byteEncoder.WriteFingerCurl(_playerSyncInfo.leftHandFingerCurl);
+ byteEncoder.WriteFingerCurl(_playerSyncInfo.rightHandFingerCurl);
}
public PlayerSyncMessage(Packet packet)
@@ -71,12 +71,12 @@ namespace BoneSync.Networking.Messages
_playerSyncInfo.headPos = byteEncoder.ReadSimpleTransform();
_playerSyncInfo.leftHandPos = byteEncoder.ReadSimpleTransform();
_playerSyncInfo.rightHandPos = byteEncoder.ReadSimpleTransform();
- _playerSyncInfo.leftHandFingerCurl = byteEncoder.ReadFingerCurl();
- _playerSyncInfo.rightHandFingerCurl = byteEncoder.ReadFingerCurl();
_playerSyncInfo.poseIndexRight = byteEncoder.ReadByte();
_playerSyncInfo.poseIndexLeft = byteEncoder.ReadByte();
- _playerSyncInfo.poseRadiusRight = byteEncoder.ReadFloat();
- _playerSyncInfo.poseRadiusLeft = byteEncoder.ReadFloat();
+ _playerSyncInfo.poseRadiusRight = byteEncoder.ReadCompressedFloat();
+ _playerSyncInfo.poseRadiusLeft = byteEncoder.ReadCompressedFloat();
+ _playerSyncInfo.leftHandFingerCurl = byteEncoder.ReadFingerCurl();
+ _playerSyncInfo.rightHandFingerCurl = byteEncoder.ReadFingerCurl();
}
public override void Execute()
diff --git a/BoneSync/Networking/NetworkMessage.cs b/BoneSync/Networking/NetworkMessage.cs
index 19a49c0..8d18cd4 100644
--- a/BoneSync/Networking/NetworkMessage.cs
+++ b/BoneSync/Networking/NetworkMessage.cs
@@ -145,7 +145,7 @@ namespace BoneSync.Networking
}
public void Send(ulong receiverId)
{
- if (BoneSync.lobby.IsConnected() == false)
+ if (BoneSync.IsConnected == false)
{
MelonLogger.Warning("Cannot send packet, not connected to lobby");
return;
diff --git a/BoneSync/Networking/PacketTypes.cs b/BoneSync/Networking/PacketTypes.cs
index 49ab1bf..2ae2fb3 100644
--- a/BoneSync/Networking/PacketTypes.cs
+++ b/BoneSync/Networking/PacketTypes.cs
@@ -20,5 +20,6 @@ namespace BoneSync.Networking
GunSync = 9,
SimpleObjectEventSync = 10,
PlugSync = 11,
+ AISync = 12,
}
}
diff --git a/BoneSync/Patching/AIHealthPatches.cs b/BoneSync/Patching/AIHealthPatches.cs
new file mode 100644
index 0000000..e7fad6b
--- /dev/null
+++ b/BoneSync/Patching/AIHealthPatches.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HarmonyLib;
+using PuppetMasta;
+namespace BoneSync.Patching
+{
+ /*
+ [HarmonyPatch(typeof(SubBehaviourHealth))]
+ internal class AIHealthPatches
+ {
+ [HarmonyPatch(nameof(SubBehaviourHealth.TakeDamage)), HarmonyPostfix]
+ private static void DamagePrefix(SubBehaviourHealth __instance)
+ {
+
+ }
+ }*/
+}
diff --git a/BoneSync/Patching/GunPatches.cs b/BoneSync/Patching/GunPatches.cs
index 78b3dd0..d703c8e 100644
--- a/BoneSync/Patching/GunPatches.cs
+++ b/BoneSync/Patching/GunPatches.cs
@@ -27,7 +27,7 @@ namespace BoneSync.Patching
public static void OnFirePatch(Gun __instance)
{
MelonLoader.MelonLogger.Msg("Gun.OnFire: " + __instance.name);
- if (!BoneSync.lobby.IsConnected()) return;
+ if (!BoneSync.IsConnected) return;
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance.gameObject);
if (syncable == null) return;
diff --git a/BoneSync/Patching/ObjectHealthPatches.cs b/BoneSync/Patching/ObjectHealthPatches.cs
index fb7085f..7cb494d 100644
--- a/BoneSync/Patching/ObjectHealthPatches.cs
+++ b/BoneSync/Patching/ObjectHealthPatches.cs
@@ -24,6 +24,7 @@ namespace BoneSync.Patching
private static bool TakeDamagePatch(ObjectDestructable __instance, ref Vector3 normal, ref float damage, ref bool crit, ref AttackType attackType)
{
if (CallPatchedMethods.allowPatchedMethodCall) return true;
+ if (!BoneSync.IsConnected) return true;
if (damage < 0.05f) return true; // ignore small damage (e.g. a little bit of fall damage)
MelonLoader.MelonLogger.Msg("ObjectDestructable.TakeDamage: " + damage);
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance.gameObject);
@@ -46,7 +47,7 @@ namespace BoneSync.Patching
[HarmonyPrefix]
private static bool LootTablePatch(ObjectDestructable __instance, ref LootTableData __result)
{
- if (!BoneSync.lobby.IsConnected()) return true;
+ if (!BoneSync.IsConnected) return true;
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance.gameObject);
if (syncable != null && !BoneSync.lobby.IsHost)
{
@@ -65,6 +66,7 @@ namespace BoneSync.Patching
private static bool TakeDamagePatch(Prop_Health __instance, ref float damage, ref bool crit, ref AttackType attackType)
{
if (CallPatchedMethods.allowPatchedMethodCall) return true;
+ if (!BoneSync.IsConnected) return true;
MelonLoader.MelonLogger.Msg("Prop_Health.TAKEDAMAGE: " + damage);
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance.gameObject);
if (syncable != null)
diff --git a/BoneSync/Patching/PoolPatches.cs b/BoneSync/Patching/PoolPatches.cs
index 16e9fa1..f826c65 100644
--- a/BoneSync/Patching/PoolPatches.cs
+++ b/BoneSync/Patching/PoolPatches.cs
@@ -92,7 +92,7 @@ namespace BoneSync.Patching
if (__instance.Prefab == null) return;
if (CallPatchedMethods.allowPatchedMethodCall) return;
if (PoolBlacklist.isBlacklistedPool(__instance)) return;
- if (BoneSync.lobby.IsConnected())
+ if (BoneSync.IsConnected)
{
MelonLogger.Msg("Patched Spawning object in pool: " + __instance.name);
bool isHost = BoneSync.lobby.IsHost;
@@ -108,7 +108,7 @@ namespace BoneSync.Patching
if (__instance.Prefab == null) return true;
if (CallPatchedMethods.allowPatchedMethodCall) return true;
if (PoolBlacklist.isBlacklistedPool(__instance)) return true;
- if (BoneSync.lobby.IsConnected())
+ if (BoneSync.IsConnected)
{
MelonLogger.Msg("Patched Spawning object in pool: " + __instance.name);
return BoneSync.lobby.IsHost; // only allow host to spawn objects naturally
@@ -126,7 +126,7 @@ namespace BoneSync.Patching
public static void OnSpawnPatchPost(Poolee __instance)
{
if (CallPatchedMethods.allowPatchedMethodCall) return;
- if (!BoneSync.lobby.IsConnected()) return;
+ if (!BoneSync.IsConnected) return;
MelonLogger.Msg("Poolee.OnSpawn: " + __instance.gameObject.transform.GetPath());
@@ -149,7 +149,7 @@ namespace BoneSync.Patching
public static void OnDespawnPatchPost(Poolee __instance)
{
if (CallPatchedMethods.allowPatchedMethodCall) return;
- if (!BoneSync.lobby.IsConnected()) return;
+ if (!BoneSync.IsConnected) return;
MelonLogger.Msg("Poolee.OnDespawn: " + __instance.gameObject.transform.GetPath());
diff --git a/BoneSync/Patching/SkeletonHandPatches.cs b/BoneSync/Patching/SkeletonHandPatches.cs
index 7231eec..ec622cb 100644
--- a/BoneSync/Patching/SkeletonHandPatches.cs
+++ b/BoneSync/Patching/SkeletonHandPatches.cs
@@ -21,13 +21,43 @@ namespace BoneSync.Patching
public static byte poseIndexLeft = 0;
public static float radiusLeft = 0.0f;
- [HarmonyPatch(nameof(SkeletonHand.SetHandPose)), HarmonyPostfix]
+ private static Dictionary handPoses = new Dictionary();
+
+ private static byte GetHandPoseIndex(string handPoseName)
+ {
+ if (handPoses.ContainsKey(handPoseName))
+ return handPoses[handPoseName];
+
+ if (PlayerScripts.playerHandPoses == null)
+ {
+ MelonLogger.Error("PlayerScripts.playerHandPoses is null!");
+ return 0;
+ }
+ if (PlayerScripts.playerHandPoses.Count == 0)
+ {
+ MelonLogger.Msg("PlayerScripts.playerHandPoses is empty, getting hand poses...");
+ PlayerScripts.GetHandPoses();
+ }
+
+ bool found = PlayerScripts.playerHandPoses.Contains(handPoseName);
+ if (!found)
+ {
+ //MelonLogger.Error($"Hand pose {handPoseName} not found in playerHandPoses!");
+ return 0;
+ }
+ byte index = (byte)PlayerScripts.playerHandPoses.IndexOf(handPoseName);
+ handPoses.Add(handPoseName, index);
+ return index;
+ }
+
+
+ [HarmonyPatch(nameof(SkeletonHand.SetHandPose)), HarmonyPrefix]
private static void SetHandPosePostfix(SkeletonHand __instance, string handPoseName)
{
if (!__instance.GetCharacterAnimationManager()) return;
MelonLogger.Msg($"SetHandPosePostfix: {handPoseName}");
- int poseIndex = PlayerScripts.playerHandPoses.IndexOf(handPoseName);
+ int poseIndex = GetHandPoseIndex(handPoseName);
switch (__instance.handedness)
{
case Handedness.LEFT:
@@ -40,18 +70,23 @@ namespace BoneSync.Patching
}
- [HarmonyPatch(nameof(SkeletonHand.SetCylinderRadius)), HarmonyPostfix]
+ [HarmonyPatch(nameof(SkeletonHand.SetCylinderRadius)), HarmonyPrefix]
private static void SetCylinderRadiusPrefix(SkeletonHand __instance, float radius)
{
if (!__instance.GetCharacterAnimationManager()) return;
- MelonLogger.Msg($"SetCylinderRadiusPrefix: {radius}");
+
+ //MelonLogger.Msg($"SetCylinderRadiusPrefix: {radius}");
switch (__instance.handedness)
{
case Handedness.LEFT:
+ if (radiusLeft == radius) return;
+ MelonLogger.Msg($"SetCylinderRadiusPrefixLeft: {radius}");
radiusLeft = radius;
break;
case Handedness.RIGHT:
+ if (radiusRight == radius) return;
+ MelonLogger.Msg($"SetCylinderRadiusPrefixRight: {radius}");
radiusRight = radius;
break;
}
diff --git a/BoneSync/Patching/ZonePatches.cs b/BoneSync/Patching/ZonePatches.cs
index 122048f..015680a 100644
--- a/BoneSync/Patching/ZonePatches.cs
+++ b/BoneSync/Patching/ZonePatches.cs
@@ -18,7 +18,7 @@ namespace BoneSync.Patching
[HarmonyPatch(nameof(ZoneSpawner.Spawn)), HarmonyPrefix]
public static bool ZoneSpawnPrefix(ZoneSpawner __instance)
{
- if (!BoneSync.lobby.IsConnected()) return true; // do not block if not connected
+ if (!BoneSync.IsConnected) return true; // do not block if not connected
MelonLogger.Msg("ZoneSpawner.Spawn: " + __instance.transform.GetPath());
@@ -38,7 +38,7 @@ namespace BoneSync.Patching
[HarmonyPatch(nameof(ZoneEncounter.StartEncounter)), HarmonyPrefix]
public static bool ZoneEncounterSpawnPrefix(ZoneEncounter __instance)
{
- if (!BoneSync.lobby.IsConnected()) return true;
+ if (!BoneSync.IsConnected) return true;
MelonLogger.Msg("ZoneEncounter.StartEncounter: " + __instance.transform.GetPath());
diff --git a/BoneSync/Player/PlayerRig.cs b/BoneSync/Player/PlayerRig.cs
index 79ab243..d679bec 100644
--- a/BoneSync/Player/PlayerRig.cs
+++ b/BoneSync/Player/PlayerRig.cs
@@ -17,13 +17,15 @@ using BoneSync.Data;
using StressLevelZero.Interaction;
using UnhollowerBaseLib;
using BoneSync.Patching;
+using BoneSync.Sync.Components;
+using Oculus.Platform.Models;
namespace BoneSync.Player
{
internal class PlayerRig
{
- private const float RIG_SYNC_FPS = 30;
+ private const float RIG_SYNC_FPS = Syncable.SYNC_FPS;
public static AssetBundle rigBundle;
private static float _lastLocalSyncTime = 0;
@@ -57,15 +59,18 @@ namespace BoneSync.Player
{
playerRig.UpdateIK();
}
-
- if (Time.time - _lastLocalSyncTime > 1 / RIG_SYNC_FPS)
- {
- SendLocalPlayerSync();
- _lastLocalSyncTime = Time.time;
- }
}
+ public static void LocalSyncTick()
+ {
+ if (Time.realtimeSinceStartup - _lastLocalSyncTime > 1 / RIG_SYNC_FPS)
+ {
+ SendLocalPlayerSync();
+ _lastLocalSyncTime = Time.realtimeSinceStartup;
+ }
+ }
+
private void SetFingerCurl(Handedness handedness, SimpleFingerCurl fingerCurl)
{
characterAnimationManager.ApplyFingerCurl(handedness, 1f - fingerCurl.thumb, 1f - fingerCurl.index, 1f - fingerCurl.middle, 1f - fingerCurl.ring, 1f - fingerCurl.pinky);
@@ -82,6 +87,12 @@ namespace BoneSync.Player
SetFingerCurl(Handedness.LEFT, playerSyncInfo.leftHandFingerCurl);
SetFingerCurl(Handedness.RIGHT, playerSyncInfo.rightHandFingerCurl);
+
+ UpdatePose(Handedness.LEFT, playerSyncInfo.poseIndexLeft);
+ UpdatePose(Handedness.RIGHT, playerSyncInfo.poseIndexRight);
+
+ UpdatePoseRadius(Handedness.LEFT, playerSyncInfo.poseRadiusLeft);
+ UpdatePoseRadius(Handedness.RIGHT, playerSyncInfo.poseRadiusRight);
}
public void UpdatePose(Handedness hand, int index)
@@ -97,21 +108,34 @@ namespace BoneSync.Player
public void UpdatePoseRadius(Handedness hand, float radius) => characterAnimationManager?.SetCylinderRadius(hand, radius);
+ private static GameObject localPlayerRig;
+ private static Transform localRigRoot;
+ private static Transform localRigHeadTransform;
+ private static Transform localRigLeftHandTransform;
+ private static Transform localRigRightHandTransform;
+ public static void SetLocalRigReferences()
+ {
+ if (localPlayerRig != null) return;
+ localPlayerRig = GameObject.Find("[RigManager (Default Brett)]/[SkeletonRig (GameWorld Brett)]");
+ localRigRoot = localPlayerRig.transform;
+
+ localRigHeadTransform = localRigRoot.Find("Head");
+ localRigLeftHandTransform = localRigRoot.Find("Hand (left)");
+ localRigRightHandTransform = localRigRoot.Find("Hand (right)");
+ }
+
public static PlayerSyncInfo? GetLocalSyncInfo()
{
- GameObject localPlayerRig = GameObject.Find("[RigManager (Default Brett)]/[SkeletonRig (GameWorld Brett)]");
+ SetLocalRigReferences();
+
if (localPlayerRig == null)
{
MelonLogger.Msg("Local player rig not found");
return null;
}
- Transform root = localPlayerRig.transform;
+
- Transform localHeadTransform = root.Find("Head");
- Transform localLeftHandTransform = root.Find("Hand (left)");
- Transform localRightHandTransform = root.Find("Hand (right)");
-
- if (localHeadTransform == null || localLeftHandTransform == null || localRightHandTransform == null)
+ if (localRigHeadTransform == null || localRigLeftHandTransform == null || localRigRightHandTransform == null)
{
MelonLogger.Msg("Local player rig components not found");
return null;
@@ -119,10 +143,10 @@ namespace BoneSync.Player
PlayerSyncInfo playerSyncInfo = new PlayerSyncInfo()
{
- rootPos = root.position,
- headPos = new SimpleSyncTransform(localHeadTransform),
- leftHandPos = new SimpleSyncTransform(localLeftHandTransform),
- rightHandPos = new SimpleSyncTransform(localRightHandTransform),
+ rootPos = localRigRoot.position,
+ headPos = new SimpleSyncTransform(localRigHeadTransform),
+ leftHandPos = new SimpleSyncTransform(localRigLeftHandTransform),
+ rightHandPos = new SimpleSyncTransform(localRigRightHandTransform),
//leftHandFingerCurl = new SimpleFingerCurl(PlayerScripts.playerLeftHand.fingerCurl),
//rightHandFingerCurl = new SimpleFingerCurl(PlayerScripts.playerRightHand.fingerCurl)
poseIndexLeft = SkeletonHandPatches.poseIndexLeft,
@@ -142,7 +166,7 @@ namespace BoneSync.Player
private static void SendLocalPlayerSync()
{
- if (!BoneSync.lobby.IsConnected()) return;
+ if (!BoneSync.IsConnected) return;
//MelonLogger.Msg("Sending local player sync");
PlayerSyncInfo? playerSyncInfo = GetLocalSyncInfo();
if (!playerSyncInfo.HasValue) return;
diff --git a/BoneSync/Sync/Components/SyncableAI.cs b/BoneSync/Sync/Components/SyncableAI.cs
index 67692a9..0f618bf 100644
--- a/BoneSync/Sync/Components/SyncableAI.cs
+++ b/BoneSync/Sync/Components/SyncableAI.cs
@@ -3,13 +3,62 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using BoneSync.Networking.Messages;
using UnityEngine;
namespace BoneSync.Sync.Components
{
public partial class Syncable : MonoBehaviour
{
-
+ private AISyncInfo _aiSyncInfo;
+ private float _lastAISyncTime;
+ private const float AI_SYNC_FPS = 5f;
+
+ private void TrySendAISync()
+ {
+ if (!isOwner) return;
+ if (!aiBrain) return;
+ if (Time.realtimeSinceStartup - _lastAISyncTime > 1 / AI_SYNC_FPS)
+ {
+ _SendAIStateSync();
+ }
+ }
+ private void _SendAIStateSync()
+ {
+ if (!aiBrain) return;
+ _lastAISyncTime = Time.realtimeSinceStartup;
+ AISyncInfo aiSyncInfo = new AISyncInfo(_syncId, aiBrain);
+ AISyncMessage message = new AISyncMessage(aiSyncInfo);
+ message.Broadcast();
+ }
+
+ private void _ApplyAISyncInfo(AISyncInfo aiSyncInfo)
+ {
+ if (!aiBrain) return;
+ aiBrain.behaviour.health.cur_hp = aiSyncInfo.health.cur_hp;
+ aiBrain.behaviour.health.cur_arm_lf = aiSyncInfo.health.cur_arm_lf;
+ aiBrain.behaviour.health.cur_arm_rt = aiSyncInfo.health.cur_arm_rt;
+ aiBrain.behaviour.health.cur_leg_lf = aiSyncInfo.health.cur_leg_lf;
+ aiBrain.behaviour.health.cur_leg_rt = aiSyncInfo.health.cur_leg_rt;
+
+ if (aiSyncInfo.health.cur_hp <= 0 && !aiBrain.puppetMaster.isDead)
+ {
+ aiBrain.puppetMaster.Kill();
+ }
+ else if (aiSyncInfo.health.cur_hp > 0 && aiBrain.puppetMaster.isDead)
+ {
+ aiBrain.puppetMaster.Resurrect();
+ }
+
+ aiBrain.puppetMaster.activeState = aiSyncInfo.puppetState;
+ aiBrain.puppetMaster.activeMode = aiSyncInfo.puppetMode;
+ aiBrain.behaviour.mentalState = aiSyncInfo.mentalState;
+ }
+ public void OnAISyncData(AISyncInfo aiSyncInfo)
+ {
+ _aiSyncInfo = aiSyncInfo;
+ _ApplyAISyncInfo(_aiSyncInfo);
+ }
}
}
diff --git a/BoneSync/Sync/Components/SyncableBase.cs b/BoneSync/Sync/Components/SyncableBase.cs
index 43bc62c..c178182 100644
--- a/BoneSync/Sync/Components/SyncableBase.cs
+++ b/BoneSync/Sync/Components/SyncableBase.cs
@@ -79,7 +79,7 @@ namespace BoneSync.Sync.Components
private bool _attemptedRegister;
public bool Registered => _syncId != 0;
- public bool isStale => Time.time - _lastSyncTime > 5f;
+ public bool isStale => Time.realtimeSinceStartup - _lastSyncTime > 5f;
public bool isOwner => _ownerId == BoneSync.lobby.GetLocalId();
public void SetInHolster(bool val)
@@ -119,7 +119,6 @@ namespace BoneSync.Sync.Components
private Socket[] sockets;
private AIBrain aiBrain;
- private PuppetMaster puppetMaster;
private PullDevice pullDevice;
private ButtonToggle[] buttonToggles;
@@ -167,6 +166,7 @@ namespace BoneSync.Sync.Components
public string GetSyncableWorldPath()
{
+ if (transform == null) return "";
if (poolee && poolee.pool)
{
return "";
@@ -195,7 +195,6 @@ namespace BoneSync.Sync.Components
sockets = GetComponentsInChildren();
aiBrain = GetComponent();
buttonToggles = GetComponentsInChildren();
- puppetMaster = aiBrain?.puppetMaster;
if (sockets.Length == 0)
{
plugs = GetComponentsInChildren();
@@ -342,7 +341,7 @@ namespace BoneSync.Sync.Components
public void RegisterSyncable()
{
- if (!BoneSync.lobby.IsConnected()) return;
+ if (!BoneSync.IsConnected) return;
FindAndUpdateComponents();
if (Registered)
{
diff --git a/BoneSync/Sync/Components/SyncableDamage.cs b/BoneSync/Sync/Components/SyncableDamage.cs
index ccdd709..01d543e 100644
--- a/BoneSync/Sync/Components/SyncableDamage.cs
+++ b/BoneSync/Sync/Components/SyncableDamage.cs
@@ -23,7 +23,7 @@ namespace BoneSync.Sync.Components
originalLootTableData = objectDestructable.lootTable;
}
- if (!BoneSync.lobby.IsConnected() || BoneSync.lobby.IsHost)
+ if (!BoneSync.IsConnected || BoneSync.lobby.IsHost)
{
objectDestructable.lootTable = originalLootTableData;
}
diff --git a/BoneSync/Sync/Components/SyncableNetworking.cs b/BoneSync/Sync/Components/SyncableNetworking.cs
index e83693c..0da83a3 100644
--- a/BoneSync/Sync/Components/SyncableNetworking.cs
+++ b/BoneSync/Sync/Components/SyncableNetworking.cs
@@ -16,7 +16,7 @@ namespace BoneSync.Sync.Components
{
private void SendObjectSync()
{
- _lastSyncTime = Time.time;
+ _lastSyncTime = Time.realtimeSinceStartup;
ObjectSync.SendObjectSyncMessage(this);
}
public IEnumerator SyncCoroutineAsync()