using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
///
/// 包含效果的次级模块
///
public partial class EffectSubmodule : SubmoduleBase
{
public Dictionary> effectCollection;
public EffectSubmodule(GameElement attachedGameElement, EffectSubmodulePreset preset = EffectSubmodulePreset.Default)
: base(attachedGameElement)
{
effectCollection = new Dictionary>();
if (preset == EffectSubmodulePreset.Default) //对于默认的效果次级模块,有Prior、Default、Late三个效果集合
{
effectCollection.Add("Prior", new List());
effectCollection.Add("Default", new List());
effectCollection.Add("Late", new List());
}
else if (preset == EffectSubmodulePreset.Note) //对于Note的效果次级模块,在Note的不同状态下有独立的效果集合
{
effectCollection.Add("Generate", new List());
effectCollection.Add("GeneralJudge", new List());
effectCollection.Add("StartHold", new List()); //仅用于Hold
effectCollection.Add("Holding", new List()); //仅用于Hold
effectCollection.Add("Perfect", new List());
effectCollection.Add("Good", new List());
effectCollection.Add("Bad", new List());
effectCollection.Add("Miss", new List());
effectCollection.Add("AfterJudge", new List());
}
if (!HaveSameSubmodule)
{
(attachedGameElement as IHaveEffectSubmodule).effectSubmodule = this;
}
}
public EffectSubmodule(GameElement attachedGameElement, Dictionary> effectList_BM) : base(attachedGameElement)
{
effectCollection = new Dictionary>();
foreach (var effect in effectList_BM)
{
List effectList = new List();
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 EffectCollection { get; } =
new Dictionary()
{
{ "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> effectCollection;
public EffectSubmodule_BM()
{
}
public EffectSubmodule_BM(GameElement attachedElement) : base(attachedElement)
{
effectCollection = new Dictionary>();
IHaveEffectSubmodule element = attachedElement as IHaveEffectSubmodule;
foreach (var effect in element.effectSubmodule.effectCollection)
{
List effectList = new List();
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 override void DuplicateBM(GameElement attached)
{
(attached as IHaveEffectSubmodule).effectSubmodule = new EffectSubmodule(attached, 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;
///
/// 效果的持续时间,如果为0则表示瞬间效果
///
public float effectTime;
///
/// 是否是瞬间效果
///
public bool isInstantEffect => effectTime <= 0;
///
/// 效果的进度百分比
///
public float effectProgressPercent;
///
/// 效果当前的状态
///
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;
}
///
/// 当从Before状态进入Middle状态时,仅在效果的开始时触发一次方法
///
public virtual void PreExecute()
{
}
///
/// 在效果的持续时间内,触发这个方法
///
public virtual void Execute()
{
}
///
/// 如果是非瞬间效果,在效果完成后,触发这个方法;
/// 如果是瞬间效果,则此方法即为Execute。原有的Execute方法不被调用。
///
public virtual void Adjust()
{
}
///
/// 如果时间轴回退到效果的触发时间之前,则触发这个方法
///
public virtual void Recover()
{
}
///
/// 如果效果被打断,则触发这个方法
///
public virtual void Disrupt()
{
}
///
/// 转换为存档类
///
///
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;
}
///
/// 转换为游戏类
///
///
public abstract EffectBase ConvertToGameType(GameElement attachedGameElement);
}
}
}