r2mods/ilspy_dump/ror2_csproj/RoR2/ChildMonsterController.cs

136 lines
3.3 KiB
C#

using EntityStates;
using EntityStates.ChildMonster;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Serialization;
namespace RoR2;
[RequireComponent(typeof(EntityStateMachine))]
[RequireComponent(typeof(CharacterBody))]
public class ChildMonsterController : MonoBehaviour
{
public CharacterBody characterBody;
public EntityStateMachine stateMachine;
public GameObject tpEffectPrefab;
[Tooltip("If Child receives this much cumulative damage, they will start trying to teleport.")]
[FormerlySerializedAs("frolicThreshold")]
public float cumulativeDamageThresholdBeforeFrolic = 10f;
[Tooltip("Does not apply to 'falling off cliffs!' teleporting.")]
public float teleportCooldown = 20f;
[Tooltip("Which skill slot is 'Frolic' (teleport) categorized as.")]
public SkillSlot frolicSkillSlot;
private float inAirTimer;
public float amountToFallBeforeTp = 1.5f;
private float cachedYPosition;
private SkillLocator skillLocator;
private float lastTeleportTimestamp = -1f;
private float healthAtLastTeleport;
private BaseState requestedTeleportState;
private bool hasAuthority;
private void Start()
{
skillLocator = characterBody.skillLocator;
cachedYPosition = characterBody.corePosition.y;
hasAuthority = Util.HasEffectiveAuthority(characterBody.networkIdentity);
RegisterTeleport(addInvincibility: false);
lastTeleportTimestamp = -1f;
}
private void Update()
{
if (characterBody == null || !characterBody.healthComponent.alive)
{
return;
}
TryRefreshTeleportAbility();
if (hasAuthority)
{
HandleFalling();
HandleCumulativeDamage();
if (requestedTeleportState != null)
{
SetNextStateToTeleport();
}
}
}
private void SetNextStateToTeleport()
{
if (stateMachine.CanInterruptState(requestedTeleportState.GetMinimumInterruptPriority()))
{
stateMachine.SetNextState(requestedTeleportState);
requestedTeleportState = null;
}
}
private void HandleFalling()
{
if (!characterBody.characterMotor.isGrounded && characterBody.corePosition.y < cachedYPosition)
{
inAirTimer += Time.deltaTime;
}
else
{
inAirTimer = 0f;
}
cachedYPosition = characterBody.corePosition.y;
if (inAirTimer > amountToFallBeforeTp)
{
inAirTimer = 0f;
requestedTeleportState = new FrolicAway();
}
}
private void TryRefreshTeleportAbility()
{
if (lastTeleportTimestamp != -1f && CheckTeleportAvailable())
{
lastTeleportTimestamp = -1f;
}
}
private void HandleCumulativeDamage()
{
if (requestedTeleportState == null && CheckTeleportAvailable() && healthAtLastTeleport - characterBody.healthComponent.health >= cumulativeDamageThresholdBeforeFrolic)
{
requestedTeleportState = new Frolic();
}
}
public bool CheckTeleportAvailable()
{
if (lastTeleportTimestamp != -1f)
{
return Time.time - lastTeleportTimestamp >= teleportCooldown;
}
return true;
}
public void RegisterTeleport(bool addInvincibility = true)
{
lastTeleportTimestamp = Time.time;
healthAtLastTeleport = characterBody.healthComponent.health;
requestedTeleportState = null;
skillLocator.GetSkill(frolicSkillSlot)?.DeductStock(100);
if (addInvincibility && NetworkServer.active && !characterBody.HasBuff(RoR2Content.Buffs.HiddenInvincibility))
{
characterBody.AddTimedBuff(RoR2Content.Buffs.HiddenInvincibility, 1.5f);
}
}
}