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

256 lines
6.2 KiB
C#

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
namespace RoR2.CharacterSpeech;
[RequireComponent(typeof(CharacterSpeechController))]
public class SimpleCombatSpeechDriver : BaseCharacterSpeechDriver
{
[Serializable]
public struct SpeechCategory
{
public string refName;
public float chanceToTrigger;
public SpeechInfo[] speechInfos;
public WeightedSelection<SpeechInfo> speechSelection;
}
[Serializable]
public struct SpeechInfo
{
public string nameToken;
public float weight;
}
[Header("Speech Info")]
public float minimumDurationBetweenSpeech;
public bool removeRepeats;
[SerializeField]
public SpeechCategory[] speechCategories;
[Tooltip("The refname to automatically submit speech for when damage is dealt.")]
public string damageDealtRefName;
[Header("Combat Parameters")]
public bool scaleChanceOnDamageDealtByHealthFractionDealt = true;
public float scaleChanceOnDamageDealtMultiplier = 1f;
[Header("Events")]
public DamageReportUnityEvent onBodyDamageDealt;
public UnityEvent onStart;
public DamageReportUnityEvent onBodyKill;
public DamageReportUnityEvent onBodyDeath;
public DamageReportUnityEvent onBossAllyDeath;
private float lastSpeechStopwatch = float.PositiveInfinity;
protected new void Awake()
{
base.Awake();
}
protected void Start()
{
if (NetworkServer.active)
{
Initialize();
onStart?.Invoke();
}
}
protected new void OnDestroy()
{
base.OnDestroy();
}
protected void FixedUpdate()
{
lastSpeechStopwatch += Time.fixedDeltaTime;
}
public void TriggerSpeech(string refName)
{
if (lastSpeechStopwatch < minimumDurationBetweenSpeech)
{
return;
}
int num = FindSpeechCategoryIndexByName(refName);
if (num == -1)
{
Debug.LogWarningFormat("Speech category \"{0}\" could not be found.", refName);
return;
}
ref SpeechCategory reference = ref speechCategories[num];
if (UnityEngine.Random.value < reference.chanceToTrigger)
{
SubmitSpeechRequestFromCategory(ref reference);
}
}
private void SubmitSpeechRequestFromCategory(ref SpeechCategory category)
{
if (category.speechSelection == null || category.speechSelection.Count <= 0)
{
if (category.speechInfos.Length == 0)
{
return;
}
InitializeCategory(ref category);
}
int num = category.speechSelection.EvaluateToChoiceIndex(UnityEngine.Random.value);
SpeechInfo value = category.speechSelection.GetChoice(num).value;
if (removeRepeats)
{
category.speechSelection.RemoveChoice(num);
}
lastSpeechStopwatch = 0f;
CharacterSpeechController obj = base.characterSpeechController;
CharacterSpeechController.SpeechInfo speechInfo = new CharacterSpeechController.SpeechInfo
{
token = value.nameToken,
duration = minimumDurationBetweenSpeech,
maxWait = minimumDurationBetweenSpeech,
mustPlay = false
};
obj.EnqueueSpeech(in speechInfo);
}
private int FindSpeechCategoryIndexByName(string refName)
{
for (int i = 0; i < speechCategories.Length; i++)
{
if (string.Equals(speechCategories[i].refName, refName, StringComparison.Ordinal))
{
return i;
}
}
return -1;
}
private void Initialize()
{
for (int i = 0; i < speechCategories.Length; i++)
{
InitializeCategory(ref speechCategories[i]);
}
}
private void InitializeCategory(ref SpeechCategory speechCategory)
{
WeightedSelection<SpeechInfo> weightedSelection = new WeightedSelection<SpeechInfo>();
for (int i = 0; i < speechCategory.speechInfos.Length; i++)
{
SpeechInfo value = speechCategory.speechInfos[i];
weightedSelection.AddChoice(value, value.weight);
}
speechCategory.speechSelection = weightedSelection;
}
protected override void OnCharacterBodyDiscovered(CharacterBody characterBody)
{
base.OnCharacterBodyDiscovered(characterBody);
GlobalEventManager.onServerDamageDealt += OnServerDamageDealt;
GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeathGlobal;
}
protected override void OnCharacterBodyLost(CharacterBody characterBody)
{
GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeathGlobal;
GlobalEventManager.onServerDamageDealt -= OnServerDamageDealt;
base.OnCharacterBodyLost(characterBody);
}
private void OnServerDamageDealt(DamageReport damageReport)
{
if ((object)damageReport.attackerBody == base.currentCharacterBody)
{
OnBodyDamageDealt(damageReport);
}
if ((object)damageReport.victimBody == base.currentCharacterBody)
{
OnBodyDamageTaken(damageReport);
}
}
private void OnCharacterDeathGlobal(DamageReport damageReport)
{
CharacterBody characterBody = base.currentCharacterBody;
if (!(characterBody == null))
{
if ((object)damageReport.attackerBody == characterBody)
{
OnBodyKill(damageReport);
}
if ((object)damageReport.victimBody == characterBody)
{
OnBodyDeath(damageReport);
}
else if (damageReport.victimBody.teamComponent.teamIndex == characterBody.teamComponent.teamIndex)
{
OnBossAllyDeath(damageReport);
}
}
}
private void OnBodyDamageDealt(DamageReport damageReport)
{
if (scaleChanceOnDamageDealtByHealthFractionDealt && (bool)damageReport.victim && !string.IsNullOrEmpty(damageDealtRefName))
{
int num = FindSpeechCategoryIndexByName(damageDealtRefName);
if (num == -1)
{
Debug.LogWarningFormat("Speech category \"{0}\" could not be found.", damageDealtRefName);
}
else
{
ref SpeechCategory reference = ref speechCategories[num];
float num2 = reference.chanceToTrigger;
if (scaleChanceOnDamageDealtByHealthFractionDealt)
{
float fullCombinedHealth = damageReport.victim.fullCombinedHealth;
float num3 = damageReport.damageDealt / fullCombinedHealth;
num2 *= num3;
}
num2 *= scaleChanceOnDamageDealtMultiplier;
if (UnityEngine.Random.value < num2)
{
SubmitSpeechRequestFromCategory(ref reference);
}
}
}
onBodyDamageDealt?.Invoke(damageReport);
}
private void OnBodyDamageTaken(DamageReport damageReport)
{
}
private void OnBodyKill(DamageReport damageReport)
{
onBodyKill?.Invoke(damageReport);
}
private void OnBodyDeath(DamageReport damageReport)
{
onBodyDeath?.Invoke(damageReport);
}
private void OnBossAllyDeath(DamageReport damageReport)
{
onBossAllyDeath?.Invoke(damageReport);
}
}