AI Sync initial changes

This commit is contained in:
Aaro Varis
2025-03-09 21:42:39 +02:00
parent adbd7f4704
commit 20a624fb0f
19 changed files with 311 additions and 73 deletions

View File

@@ -93,8 +93,10 @@
<Compile Include="Data\PlayerScripts.cs" />
<Compile Include="Data\SpawnableManager.cs" />
<Compile Include="Data\Structs.cs" />
<Compile Include="Networking\Messages\AISyncMessage.cs" />
<Compile Include="Networking\Messages\DiscardSyncableMessage.cs" />
<Compile Include="Networking\Messages\GunSyncMessage.cs" />
<Compile Include="Patching\AIHealthPatches.cs" />
<Compile Include="Patching\HolsterSlotPatches.cs" />
<Compile Include="Networking\Messages\MagazineSyncMessage.cs" />
<Compile Include="Networking\Messages\ObjectDamageMessage.cs" />

View File

@@ -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<byte> 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)

View File

@@ -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<RigManager>();
if (playerRig != null)
return;
localPlayerGameObject = GameObject.Find("[RigManager (Default Brett)]");
playerRig = localPlayerGameObject.GetComponentInChildren<RigManager>();
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!

View File

@@ -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();
}

View File

@@ -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);
}
}
}

View File

@@ -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()

View File

@@ -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;

View File

@@ -20,5 +20,6 @@ namespace BoneSync.Networking
GunSync = 9,
SimpleObjectEventSync = 10,
PlugSync = 11,
AISync = 12,
}
}

View File

@@ -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)
{
}
}*/
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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());

View File

@@ -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<string, byte> handPoses = new Dictionary<string, byte>();
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;
}

View File

@@ -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());

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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<Socket>();
aiBrain = GetComponent<AIBrain>();
buttonToggles = GetComponentsInChildren<ButtonToggle>();
puppetMaster = aiBrain?.puppetMaster;
if (sockets.Length == 0)
{
plugs = GetComponentsInChildren<AlignPlug>();
@@ -342,7 +341,7 @@ namespace BoneSync.Sync.Components
public void RegisterSyncable()
{
if (!BoneSync.lobby.IsConnected()) return;
if (!BoneSync.IsConnected) return;
FindAndUpdateComponents();
if (Registered)
{

View File

@@ -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;
}

View File

@@ -16,7 +16,7 @@ namespace BoneSync.Sync.Components
{
private void SendObjectSync()
{
_lastSyncTime = Time.time;
_lastSyncTime = Time.realtimeSinceStartup;
ObjectSync.SendObjectSyncMessage(this);
}
public IEnumerator SyncCoroutineAsync()