r2mods/ilspy_dump/ror2_csproj/RoR2.CharacterSpeech/CharacterSpeechController.cs

302 lines
6.4 KiB
C#

using System;
using System.Collections.Generic;
using RoR2.ConVar;
using UnityEngine;
using UnityEngine.Networking;
namespace RoR2.CharacterSpeech;
public class CharacterSpeechController : MonoBehaviour
{
[Serializable]
public struct SpeechInfo
{
public string token;
public float duration;
public float maxWait;
public float priority;
public bool mustPlay;
public override string ToString()
{
return $"{{ token=\"{token}\" duration={duration} maxWait={maxWait} priority={priority} mustPlay={mustPlay} }}";
}
}
[Serializable]
private struct SpeechRequest
{
public SpeechInfo speechInfo;
public float submitTime;
public override string ToString()
{
return $"{{ speechInfo={speechInfo} submitTime={submitTime} }}";
}
}
public CharacterMaster initialCharacterMaster;
public string chatFormatToken;
private float localTime;
private float nextSpeakTime;
private List<SpeechRequest> speechRequestQueue;
private CharacterMaster _characterMaster;
private CharacterBody _currentCharacterBody;
private static readonly BoolConVar cvEnableLogging = new BoolConVar("character_speech_debug", ConVarFlags.None, "0", "Enables/disables debug logging for CharacterSpeechController");
public CharacterMaster characterMaster
{
get
{
return _characterMaster;
}
set
{
if ((object)_characterMaster != value)
{
if ((object)_characterMaster != null)
{
OnCharacterMasterLost(_characterMaster);
}
_characterMaster = value;
if ((object)_characterMaster != null)
{
OnCharacterMasterDiscovered(_characterMaster);
}
}
}
}
public CharacterBody currentCharacterBody
{
get
{
return _currentCharacterBody;
}
private set
{
if ((object)_currentCharacterBody != value)
{
if ((object)_currentCharacterBody != null)
{
OnCharacterBodyLost(_currentCharacterBody);
}
_currentCharacterBody = value;
if ((object)_currentCharacterBody != null)
{
OnCharacterBodyDiscovered(_currentCharacterBody);
}
}
}
}
public event Action<CharacterMaster> onCharacterMasterDiscovered;
public event Action<CharacterMaster> onCharacterMasterLost;
public event Action<CharacterBody> onCharacterBodyDiscovered;
public event Action<CharacterBody> onCharacterBodyLost;
private void Awake()
{
if (!NetworkServer.active)
{
base.enabled = false;
}
else
{
speechRequestQueue = new List<SpeechRequest>();
}
}
private void Start()
{
if ((object)characterMaster == null)
{
characterMaster = initialCharacterMaster;
}
}
private void FixedUpdate()
{
Process(Time.fixedDeltaTime);
}
private void OnDestroy()
{
if (NetworkServer.active)
{
characterMaster = null;
}
}
public void SpeakNow(in SpeechInfo speechInfo)
{
if (!NetworkServer.active)
{
return;
}
if (cvEnableLogging.value)
{
Log($"Playing speech: {speechInfo}");
}
nextSpeakTime = localTime + speechInfo.duration;
CharacterBody characterBody = null;
GameObject sender = null;
SfxLocator sfxLocator = null;
if ((bool)characterMaster)
{
characterBody = characterMaster.GetBody();
if ((bool)characterBody)
{
sfxLocator = characterBody.GetComponent<SfxLocator>();
}
}
Chat.SendBroadcastChat(new Chat.NpcChatMessage
{
baseToken = speechInfo.token,
formatStringToken = chatFormatToken,
sender = sender,
sound = sfxLocator?.barkSound
});
}
public void EnqueueSpeech(in SpeechInfo speechInfo)
{
if (NetworkServer.active)
{
SpeechRequest speechRequest = default(SpeechRequest);
speechRequest.speechInfo = speechInfo;
speechRequest.submitTime = localTime;
SpeechRequest speechRequest2 = speechRequest;
speechRequestQueue.Add(speechRequest2);
if (cvEnableLogging.value)
{
Log($"Enqueued speech: {speechRequest2}");
}
}
}
private void Process(float deltaTime)
{
localTime += deltaTime;
if (!(nextSpeakTime <= localTime))
{
return;
}
int bestNextRequestIndex = GetBestNextRequestIndex();
if (bestNextRequestIndex == -1)
{
return;
}
SpeechRequest speechRequest = speechRequestQueue[bestNextRequestIndex];
if (cvEnableLogging.value)
{
Log($"Found best request: bestNextRequestIndex={bestNextRequestIndex} bestNextRequest={speechRequest}");
for (int i = 0; i < bestNextRequestIndex; i++)
{
Log($"Dropping request: i={i} request={speechRequestQueue[i]}");
}
}
speechRequestQueue.RemoveRange(0, bestNextRequestIndex + 1);
SpeakNow(in speechRequest.speechInfo);
}
private int GetBestNextRequestIndex()
{
if (speechRequestQueue.Count == 0)
{
return -1;
}
for (int i = 0; i < speechRequestQueue.Count; i++)
{
SpeechRequest speechRequest = speechRequestQueue[i];
SpeechInfo speechInfo = speechRequest.speechInfo;
if (speechInfo.mustPlay)
{
return i;
}
float num = speechRequest.submitTime + speechInfo.maxWait;
if (localTime > num)
{
continue;
}
float num2 = localTime + speechInfo.duration;
bool flag = false;
for (int j = i + 1; j < speechRequestQueue.Count; j++)
{
SpeechRequest speechRequest2 = speechRequestQueue[j];
SpeechInfo speechInfo2 = speechRequest2.speechInfo;
if (!(speechInfo.priority >= speechInfo2.priority) || speechInfo2.mustPlay)
{
if (speechRequest2.submitTime + speechInfo2.maxWait < num2)
{
flag = true;
break;
}
num2 += speechInfo2.duration;
}
}
if (!flag)
{
return i;
}
}
return -1;
}
private void OnCharacterMasterDiscovered(CharacterMaster characterMaster)
{
characterMaster.onBodyStart += OnCharacterMasterBodyStart;
this.onCharacterMasterDiscovered?.Invoke(characterMaster);
currentCharacterBody = characterMaster.GetBody();
}
private void OnCharacterMasterLost(CharacterMaster characterMaster)
{
currentCharacterBody = null;
this.onCharacterMasterLost?.Invoke(characterMaster);
characterMaster.onBodyDestroyed -= OnCharacterMasterBodyDestroyed;
}
private void OnCharacterMasterBodyStart(CharacterBody characterBody)
{
currentCharacterBody = characterBody;
}
private void OnCharacterMasterBodyDestroyed(CharacterBody characterBody)
{
if ((object)characterBody == currentCharacterBody)
{
currentCharacterBody = null;
}
}
private void OnCharacterBodyDiscovered(CharacterBody characterBody)
{
this.onCharacterBodyDiscovered?.Invoke(characterBody);
}
private void OnCharacterBodyLost(CharacterBody characterBody)
{
this.onCharacterBodyLost?.Invoke(characterBody);
}
private void Log(string str)
{
}
}