using System.Collections.Generic; using System.Linq; using Cielonos.MainGame.Characters; using Cielonos.MainGame.Inventory; using SLSFramework.General; using UnityEngine; namespace Cielonos.MainGame { public abstract partial class CharacterBuffBase : BuffBase { public CharacterBase attachedCharacter; public CharacterBase sourceCharacter; public ItemBase sourceItem; /// /// 图标子模块 /// public IconSubmodule iconSubmodule; /// /// 事件子模块 /// public EventSubmodule eventSubmodule; /// /// 回合计数,每回合开始时计数-1。 /// public CountSubmodule roundCountSubmodule; /// /// 时间模块 /// public TimeSubmodule timeSubmodule; public UnitedStackSubmodule unitedStackSubmodule; public IndependentStackSubmodule independentStackSubmodule; public AttributeSubmodule attributeSubmodule; public StatusSubmodule statusSubmodule; } public partial class CharacterBuffBase { public sealed override bool OnBuffApply(out BuffBase existingBuff) { throw new System.NotImplementedException("请使用类型约束更强的OnBuffApply方法"); } public abstract bool OnBuffApply(out CharacterBuffBase existingBuff); public override void OnAfterFirstApply() { statusSubmodule?.AddStatus(); attachedCharacter.buffSm.buffList.Exclude(this).For(buff => buff.eventSubmodule?.onOtherBuffFirstApplied.Invoke(this)); } protected float DeltaTime => attachedCharacter.selfTimeSm.DeltaTime; public override void OnBuffUpdate() { timeSubmodule?.Update(DeltaTime); independentStackSubmodule?.Update(DeltaTime); } public override void OnBuffRemove() { attributeSubmodule?.RefreshAllModifiedAttributes(); statusSubmodule?.RemoveStatus(); iconSubmodule?.Remove(); } } public partial class CharacterBuffBase { protected bool FindExistingSameBuff(out T existingBuff) where T : CharacterBuffBase { return FindExistingSameBuff(out existingBuff, attachedCharacter.buffSm.buffList); } public override void Apply(CharacterBase attachedCharacter) { this.Apply(attachedCharacter, null, null); } public void Apply(CharacterBase attachedCharacter, CharacterBase sourceCharacter = null, ItemBase sourceItem = null) { this.attachedCharacter = attachedCharacter; this.sourceCharacter = sourceCharacter; this.sourceItem = sourceItem; if (OnBuffApply(out CharacterBuffBase existingBuff)) { this.attachedCharacter.buffSm.buffList.AddByPriority(this); OnAfterFirstApply(); if (iconSubmodule != null) { } } else { existingBuff.iconSubmodule?.Update(); } attachedCharacter.buffSm.buffList.Exclude(this).For(buff => buff.eventSubmodule?.onOtherBuffApplied.Invoke(this)); attributeSubmodule?.RefreshAllModifiedAttributes(); iconSubmodule?.Update(); } public override void Remove() { OnBuffRemove(); this.attachedCharacter.buffSm.buffList.Remove(this); attachedCharacter.buffSm.buffList.Exclude(this).For(buff => buff.eventSubmodule?.onOtherBuffRemoved.Invoke(this)); } public override void UntriggerRemove() { this.attachedCharacter.buffSm.buffList.Remove(this); } } public partial class CharacterBuffBase { public abstract class CharacterBuffSubmodule : BuffSubmodule { public CharacterBase character => (buff as CharacterBuffBase)?.attachedCharacter; protected CharacterBuffSubmodule(CharacterBuffBase buff) : base(buff) { } } /// /// Buff的角色状态调整模块 /// public class StatusSubmodule : CharacterBuffSubmodule { public List statusList; public StatusSubmodule(CharacterBuffBase buff, params StatusType[] statusTypes) : base(buff) { statusList = statusTypes.ToList(); } /// /// 将Buff内含的状态添加到角色身上(1层) /// public void AddStatus() { statusList.ForEach(status => character.statusSm.AddStatus(status)); } /// /// 将Buff内含的状态从角色身上移除(1层),注意,如果某个状态有其它的来源,这个状态的效果仍然存在。 /// public void RemoveStatus() { statusList.ForEach(status => character.statusSm.RemoveStatus(status)); } } /// /// Buff的角色通常属性调整模块 /// public class AttributeSubmodule : CharacterBuffSubmodule { public Dictionary numericChange; public Dictionary percentageChangeOfAccumulation; public Dictionary percentageChangeOfMultiplication; public AttributeSubmodule(CharacterBuffBase buff) : base(buff) { this.numericChange = new Dictionary(); this.percentageChangeOfAccumulation = new Dictionary(); this.percentageChangeOfMultiplication = new Dictionary(); } public List RefreshAllModifiedAttributes() { List modifiedAttributes = new List(); modifiedAttributes.AddRange(numericChange.Select(kvp => kvp.Key)); modifiedAttributes.AddRange(percentageChangeOfAccumulation.Select(kvp => kvp.Key)); modifiedAttributes.AddRange(percentageChangeOfMultiplication.Select(kvp => kvp.Key)); modifiedAttributes.ForEach(attr => character.attributeSm.RefreshAttribute(attr)); return modifiedAttributes; } } } }