Files
ichni_Official/Assets/Scripts/Game/Base/GeneralSubmodules/EffectSubmodule.cs
SoulliesOfficial 6aa498f6be
2025-08-11 14:04:06 -04:00

329 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
/// <summary>
/// 包含效果的次级模块
/// </summary>
public partial class EffectSubmodule : SubmoduleBase
{
public Dictionary<string, List<EffectBase>> effectCollection;
public EffectSubmodule(GameElement attachedGameElement, EffectSubmodulePreset preset = EffectSubmodulePreset.Default)
: base(attachedGameElement)
{
effectCollection = new Dictionary<string, List<EffectBase>>();
if (preset == EffectSubmodulePreset.Default) //对于默认的效果次级模块有Prior、Default、Late三个效果集合
{
effectCollection.Add("Prior", new List<EffectBase>());
effectCollection.Add("Default", new List<EffectBase>());
effectCollection.Add("Late", new List<EffectBase>());
}
else if (preset == EffectSubmodulePreset.Note) //对于Note的效果次级模块在Note的不同状态下有独立的效果集合
{
effectCollection.Add("Generate", new List<EffectBase>());
effectCollection.Add("GeneralJudge", new List<EffectBase>());
effectCollection.Add("StartHold", new List<EffectBase>()); //仅用于Hold
effectCollection.Add("Holding", new List<EffectBase>()); //仅用于Hold
effectCollection.Add("Perfect", new List<EffectBase>());
effectCollection.Add("Good", new List<EffectBase>());
effectCollection.Add("Bad", new List<EffectBase>());
effectCollection.Add("Miss", new List<EffectBase>());
effectCollection.Add("AfterJudge", new List<EffectBase>());
}
if (!HaveSameSubmodule)
{
(attachedGameElement as IHaveEffectSubmodule).effectSubmodule = this;
}
}
public EffectSubmodule(GameElement attachedGameElement, Dictionary<string, List<EffectBase_BM>> effectList_BM) : base(attachedGameElement)
{
effectCollection = new Dictionary<string, List<EffectBase>>();
foreach (var effect in effectList_BM)
{
List<EffectBase> effectList = new List<EffectBase>();
foreach (var effectBM in effect.Value)
{
if (BeatmapContainer_BM.LowPriorityDataTypes.Contains(effectBM.GetType())) // 如果是低优先级数据类型
{
(GameManager.instance.beatmapContainer).lowPriorityActions.Add(() =>
{
effectList.Add(effectBM.ConvertToGameType(attachedGameElement));
});
}
else
{
effectList.Add(effectBM.ConvertToGameType(attachedGameElement));
}
}
effectCollection.Add(effect.Key, effectList);
}
if (!HaveSameSubmodule)
{
(attachedGameElement as IHaveEffectSubmodule).effectSubmodule = this;
}
}
}
public partial class EffectSubmodule
{
public override void SaveBM()
{
matchedBM = new EffectSubmodule_BM(attachedGameElement);
}
}
public partial class EffectSubmodule
{
public enum EffectSubmodulePreset
{
Default,
Note,
}
private static Dictionary<string, EffectBase> EffectCollection { get; } =
new Dictionary<string, EffectBase>()
{
{ "Bloom", new BloomEffect(1, 2, CustomCurvePresets.Parabolic(1, 0, 1)) },
{ "CameraShake", new CameraShakeEffect(1, 50, 1, 1, 1) },
{ "ChromaticAberration", new ChromaticAberrationEffect(1, 1, CustomCurvePresets.Parabolic(1, 0, 1)) },
{ "Vignette", new VignetteEffect(1, 1, 0.4f, Color.black, CustomCurvePresets.Parabolic(1, 0, 1)) },
{ "SetInteger", new SetIntegerEffect("New Variable", 0, false, 0, 1) },
{ "EnableControl", new EnableControlEffect(null, "New Variable", 0, false, "") },
{ "LowPassFilter", new LowPassFilterEffect(1, 10, CustomCurvePresets.Parabolic(1, 0, 1)) },
{ "HighPassFilter", new HighPassFilterEffect(1, 22000, CustomCurvePresets.Parabolic(1, 0, 1)) }
};
}
public interface IHaveEffectSubmodule
{
public EffectSubmodule effectSubmodule { get; set; }
}
namespace Beatmap
{
public class EffectSubmodule_BM : Submodule_BM
{
public Dictionary<string, List<EffectBase_BM>> effectCollection;
public EffectSubmodule_BM()
{
}
public EffectSubmodule_BM(GameElement attachedElement) : base(attachedElement)
{
effectCollection = new Dictionary<string, List<EffectBase_BM>>();
IHaveEffectSubmodule element = attachedElement as IHaveEffectSubmodule;
foreach (var effect in element.effectSubmodule.effectCollection)
{
List<EffectBase_BM> effectList = new List<EffectBase_BM>();
foreach (var effectBase in effect.Value)
{
effectList.Add(effectBase.ConvertToBM());
}
effectCollection.Add(effect.Key, effectList);
}
}
public override void ExecuteBM()
{
attachedElement = GameElement_BM.GetElement(attachedElementGuid);
(attachedElement as IHaveEffectSubmodule).effectSubmodule = new EffectSubmodule(attachedElement, effectCollection);
}
}
}
public abstract class EffectBase : IBaseElement
{
public enum EffectState
{
Before = -1,
Middle = 0,
After = 1,
Error = 100
}
public BaseElement_BM matchedBM { get; set; }
public GameElement attachedGameElement;
/// <summary>
/// 效果的持续时间如果为0则表示瞬间效果
/// </summary>
public float effectTime;
/// <summary>
/// 是否是瞬间效果
/// </summary>
public bool isInstantEffect => effectTime <= 0;
/// <summary>
/// 效果的进度百分比
/// </summary>
public float effectProgressPercent;
/// <summary>
/// 效果当前的状态
/// </summary>
public EffectState nowEffectState;
protected EffectBase()
{
this.effectTime = 0;
this.nowEffectState = EffectState.Before;
this.effectProgressPercent = 0;
}
protected EffectBase(float effectTime)
{
this.effectTime = effectTime;
this.nowEffectState = EffectState.Before;
this.effectProgressPercent = 0;
}
public void SaveBM()
{
throw new System.NotImplementedException();
}
public virtual void UpdateEffect(float triggerTime)
{
EffectState state = CheckEffectState(triggerTime);
float songTime = GameManager.instance.songTime;
if (state == EffectState.Before && nowEffectState != EffectState.Before)
{
nowEffectState = EffectState.Before;
effectProgressPercent = 0;
Recover();
}
else if (state == EffectState.Middle)
{
if (nowEffectState == EffectState.Before)
{
PreExecute();
}
nowEffectState = EffectState.Middle;
effectProgressPercent = (songTime - triggerTime) / effectTime;
Execute();
}
else if (state == EffectState.After && nowEffectState != EffectState.After)
{
nowEffectState = EffectState.After;
effectProgressPercent = 1;
Adjust();
}
}
protected virtual EffectState CheckEffectState(float triggerTime)
{
float songTime = GameManager.instance.songTime;
if (songTime < triggerTime)
{
return EffectState.Before;
}
if (songTime >= triggerTime &&
songTime <= triggerTime + effectTime)
{
return EffectState.Middle;
}
if (songTime > triggerTime + effectTime)
{
return EffectState.After;
}
return EffectState.Error;
}
/// <summary>
/// 当从Before状态进入Middle状态时仅在效果的开始时触发一次方法
/// </summary>
public virtual void PreExecute()
{
}
/// <summary>
/// 在效果的持续时间内,触发这个方法
/// </summary>
public virtual void Execute()
{
}
/// <summary>
/// 如果是非瞬间效果,在效果完成后,触发这个方法;
/// 如果是瞬间效果则此方法即为Execute。原有的Execute方法不被调用。
/// </summary>
public virtual void Adjust()
{
}
/// <summary>
/// 如果时间轴回退到效果的触发时间之前,则触发这个方法
/// </summary>
public virtual void Recover()
{
}
/// <summary>
/// 如果效果被打断,则触发这个方法
/// </summary>
public virtual void Disrupt()
{
}
/// <summary>
/// 转换为存档类
/// </summary>
/// <returns></returns>
public abstract EffectBase_BM ConvertToBM();
public void Refresh()
{
}
}
namespace Beatmap
{
public abstract class EffectBase_BM
{
public float effectTime;
public EffectBase_BM()
{
}
public EffectBase_BM(float effectTime)
{
this.effectTime = effectTime;
}
/// <summary>
/// 转换为游戏类
/// </summary>
/// <returns></returns>
public abstract EffectBase ConvertToGameType(GameElement attachedGameElement);
}
}
}