NAK_CVR_Mods/AASBufferFix/AASBufferHelper.cs
2023-01-27 04:43:44 -06:00

101 lines
No EOL
3.3 KiB
C#

using ABI_RC.Core.Player;
using UnityEngine;
namespace NAK.Melons.AASBufferFix;
public class AASBufferHelper : MonoBehaviour
{
public bool isAcceptingAAS = true;
internal PuppetMaster puppetMaster;
//outside buffers that dont get nuked on avatar load
private float[] aasBufferFloat = new float[0];
private int[] aasBufferInt = new int[0];
private byte[] aasBufferByte = new byte[0];
//footprint is each parameter bit type count multiplied together
private int aasFootprint = -1;
private int avatarFootprint = 0;
public void Start()
{
puppetMaster = GetComponent<PuppetMaster>();
}
public void OnAvatarInstantiated(Animator animator)
{
//create the loaded avatar footprint
avatarFootprint = Utils.GenerateAnimatorAASFootprint(animator);
//previous "bad data" now matches, apply buffered data
if (SyncDataMatchesExpected())
{
ApplyExternalAASBuffer();
}
}
public void OnAvatarDestroyed()
{
aasFootprint = -1;
avatarFootprint = 0;
isAcceptingAAS = false;
}
public void OnApplyAAS(float[] settingsFloat, int[] settingsInt, byte[] settingsByte)
{
//create the synced data footprint
aasFootprint = (settingsFloat.Length + 1) * ((settingsInt.Length) + 1) * ((settingsByte.Length) + 1);
if (!SyncDataMatchesExpected())
{
if (avatarFootprint == 0)
{
//we are receiving synced data, but the avatar has not loaded on our end
//we can only assume the data is correct, and store it for later
StoreExternalAASBuffer(settingsFloat, settingsInt, settingsByte);
return;
}
//avatar is loaded on our screen, but wearer is syncing bad data
//we will need to wait until it has loaded on their end
//there is also a chance the avatar is hidden, so the animator returned 1 on initialization
//(this was only one encounter during testing, someone being hidden by safety on world load)
}
else
{
//synced data matches what we expect
ApplyExternalAAS(settingsFloat, settingsInt, settingsByte);
}
}
public void ApplyExternalAASBuffer()
{
isAcceptingAAS = true;
puppetMaster?.ApplyAdvancedAvatarSettings(aasBufferFloat, aasBufferInt, aasBufferByte);
Destroy(this);
}
public void ApplyExternalAAS(float[] settingsFloat, int[] settingsInt, byte[] settingsByte)
{
isAcceptingAAS = true;
puppetMaster?.ApplyAdvancedAvatarSettings(settingsFloat, settingsInt, settingsByte);
Destroy(this);
}
public void StoreExternalAASBuffer(float[] settingsFloat, int[] settingsInt, byte[] settingsByte)
{
Array.Resize(ref aasBufferFloat, settingsFloat.Length);
Array.Resize(ref aasBufferInt, settingsInt.Length);
Array.Resize(ref aasBufferByte, settingsByte.Length);
Array.Copy(settingsFloat, aasBufferFloat, settingsFloat.Length);
Array.Copy(settingsInt, aasBufferInt, settingsInt.Length);
Array.Copy(settingsByte, aasBufferByte, settingsByte.Length);
}
public bool SyncDataMatchesExpected()
{
return aasFootprint == avatarFootprint;
}
}