AI Sync initial changes
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
90
BoneSync/Networking/Messages/AISyncMessage.cs
Normal file
90
BoneSync/Networking/Messages/AISyncMessage.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -20,5 +20,6 @@ namespace BoneSync.Networking
|
||||
GunSync = 9,
|
||||
SimpleObjectEventSync = 10,
|
||||
PlugSync = 11,
|
||||
AISync = 12,
|
||||
}
|
||||
}
|
||||
|
||||
20
BoneSync/Patching/AIHealthPatches.cs
Normal file
20
BoneSync/Patching/AIHealthPatches.cs
Normal 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)
|
||||
{
|
||||
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
public static void LocalSyncTick()
|
||||
{
|
||||
if (Time.realtimeSinceStartup - _lastLocalSyncTime > 1 / RIG_SYNC_FPS)
|
||||
{
|
||||
SendLocalPlayerSync();
|
||||
_lastLocalSyncTime = Time.time;
|
||||
_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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace BoneSync.Sync.Components
|
||||
{
|
||||
private void SendObjectSync()
|
||||
{
|
||||
_lastSyncTime = Time.time;
|
||||
_lastSyncTime = Time.realtimeSinceStartup;
|
||||
ObjectSync.SendObjectSyncMessage(this);
|
||||
}
|
||||
public IEnumerator SyncCoroutineAsync()
|
||||
|
||||
Reference in New Issue
Block a user