Files
Cielonos/Assets/Scripts/MainGame/Characters/Base/Subcontrollers/Reaction/DodgeSubmodule.cs
SoulliesOfficial f26f9fd374 爆更
2026-03-20 12:07:44 -04:00

174 lines
6.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Cielonos.MainGame.Characters.Inventory;
using MoreMountains.FeedbacksForThirdParty;
using Sirenix.OdinInspector;
using SLSUtilities.General;
using UnityEngine;
namespace Cielonos.MainGame.Characters
{
public class DodgeSubmodule : SubmoduleBase<ReactionSubcontroller>
{
public List<DodgeSource> dodgeSources;
public bool canDodge;
[ShowInInspector]
public bool isDodging => dodgeSources.Count > 0;
[ShowInInspector]
public bool isPerfectDodging => dodgeSources.Any(source => source.hasPerfectDodge && source.isDuringPerfectDodge);
public DodgeSubmodule(ReactionSubcontroller owner) : base(owner)
{
dodgeSources = new List<DodgeSource>();
canDodge = true;
}
public void ApplyDodge(DodgeSource source, bool refreshPerfect = false)
{
if (canDodge)
{
DodgeSource existingSource = dodgeSources.Find(x => x.dodgeName == source.dodgeName);
if (existingSource != null)
{
if (source.dodgeTime > existingSource.dodgeTime)
{
existingSource.dodgeTime = source.dodgeTime;
}
if (refreshPerfect && existingSource.hasPerfectDodge)
{
existingSource.isDuringPerfectDodge = true;
existingSource.perfectTime = source.perfectTime;
}
return;
}
dodgeSources.AddByPriority(source);
}
}
public void ApplyDodge(CharacterBase sourceCharacter, ItemBase sourceItem, string dodgeName,
int priority = 0, float dodgeTime = Mathf.Infinity, float perfectTime = 0.2f, bool refreshPerfect = false,
string normalEffectName = "NormalDodge", string perfectEffectName = "PerfectDodge")
{
DodgeSource newSource = new DodgeSource(sourceCharacter, sourceItem, dodgeName, priority,
normalEffectName, perfectEffectName, dodgeTime, perfectTime);
ApplyDodge(newSource, refreshPerfect);
}
public void RemoveDodge(string dodgeName)
{
dodgeSources.RemoveAll(source => source.dodgeName == dodgeName);
}
public DodgeSource GetCurrentDodgeSource()
{
return dodgeSources.Count == 0 ? null : dodgeSources[0];
}
public void Update()
{
if (isDodging)
{
dodgeSources.ForEach(source =>
{
source.dodgeTime -= owner.owner.selfTimeSm.DeltaTime;
if (source.hasPerfectDodge)
{
source.perfectTime -= owner.owner.selfTimeSm.DeltaTime;
if (source.perfectTime <= 0)
{
source.isDuringPerfectDodge = false;
}
}
});
dodgeSources.RemoveAll(source => source.dodgeTime <= 0);
}
}
}
public class DodgeSource : IPrioritized
{
public int Priority { get; private set; }
public CharacterBase sourceCharacter;
public ItemBase sourceItem;
public string dodgeName;
public bool hasPerfectDodge;
public bool isDuringPerfectDodge;
public float perfectTime;
public float dodgeTime;
public string perfectEffectName;
public Action onPerfectDodge;
public string normalEffectName;
public Action onNormalDodge;
public DodgeSource(CharacterBase sourceCharacter, ItemBase sourceItem, string dodgeName,
int priority, string dodgeEffectName, float dodgeTime)
{
this.sourceCharacter = sourceCharacter;
this.sourceItem = sourceItem;
this.dodgeName = dodgeName;
this.normalEffectName = dodgeEffectName;
this.Priority = priority;
this.dodgeTime = dodgeTime;
this.hasPerfectDodge = false;
this.isDuringPerfectDodge = false;
}
public DodgeSource(CharacterBase sourceCharacter, ItemBase sourceItem, string dodgeName,
int priority, string normalEffectName, string perfectEffectName, float dodgeTime, float perfectTime)
{
this.sourceCharacter = sourceCharacter;
this.sourceItem = sourceItem;
this.dodgeName = dodgeName;
this.normalEffectName = normalEffectName;
this.perfectEffectName = perfectEffectName;
this.Priority = priority;
this.dodgeTime = dodgeTime;
this.perfectTime = perfectTime;
this.hasPerfectDodge = true;
this.isDuringPerfectDodge = true;
}
public static DodgeSource Default(CharacterBase sourceCharacter, float duration = Mathf.Infinity)
{
DodgeSource defaultDodge = new DodgeSource(sourceCharacter, null, "DefaultDodge", 0, "NormalDodge", "PerfectDodge", duration, 0.2f);
if (sourceCharacter is Player player)
{
defaultDodge.onPerfectDodge = () =>
{
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_RadialBlur>().TargetCenter = player.GetNormalizedScreenPosition();
player.feedbackSc["PerfectDodge"].feedback.GetFeedbackOfType<MMF_AdvancedVignette>().Center = player.GetNormalizedScreenPosition();
};
}
return defaultDodge;
}
public void PerfectDodge()
{
onPerfectDodge?.Invoke();
if (sourceItem == null)
{
sourceCharacter?.feedbackSc["PerfectDodge"]?.Play();
Debug.Log("Perfect Dodge!");
}
}
public void NormalDodge()
{
onNormalDodge?.Invoke();
if (sourceItem == null)
{
sourceCharacter?.feedbackSc["NormalDodge"]?.Play();
}
}
}
}