using CommonAI.Zone; using System.Collections.Generic; using XmdsCommon.Plugin; using UnityEngine; namespace ET.Client { [Event] [FriendOfAttribute(typeof(ET.Client.UnitRenderComponet))] public class BuffChangeEventHandler : BEvent { protected override async ETTask OnEvent(EventType.BuffChangeEvent args) { BattleUnit unit = UnitMgr.Instance.GetUnit(args.ObjectId) as BattleUnit; if (unit == null) { Log.Error($"buff unit not exist: {args.ObjectId}"); return; } var unitRender = ModelViewComponent.Instance.GetChild(args.ObjectId); if (unitRender == null) { Log.Debug($"buff unitrender not exist: {args.ObjectId}"); return; } //Log.Debug($"Buff({args.Buff?.BuffID}) {args.Type} @{unit.ZUnit.TemplateID}"); if (args.Type == EventType.BuffChangeEvent.BuffOP.Add) { BuffTemplate bt = args.Buff.Data; if (bt.MakeAvatar) { //TODO: 支持BUFF变身 Log.Error("Not implements MakeAvatar"); } AddBuff(args.Buff, unitRender, unit).Coroutine(); } else if (args.Type == EventType.BuffChangeEvent.BuffOP.Remove) { BuffTemplate bt = args.Buff.Data; RemoveBuff(bt, unitRender); } else if (args.Type == EventType.BuffChangeEvent.BuffOP.Change) { BuffTemplate bt = args.Buff.Data; //随BUFF状态变更,表现特效不同时. if ((bt.BindingEffectList != null && bt.BindingEffectList.Count > 0) || (bt.OverlayBindingEffect != null && bt.OverlayBindingEffect.Count > 0)) { var buff = args.Buff; if ((buff.OverlayLevel >= 0 && buff.OverlayLevel < bt.BindingEffectList.Count) || (buff.BuffExtendData > 0 && buff.OverlayLevel < bt.OverlayBindingEffect.Count)) { RemoveBuff(bt, unitRender); AddBuff(buff, unitRender, unit).Coroutine(); } } } else if (args.Type == EventType.BuffChangeEvent.BuffOP.Reload) { var list = unit.ZUnit.AllBuffs; list.ForEach((CommonAI.ZoneClient.ZoneUnit.BuffState buff) => { AddBuff(buff, unitRender, unit).Coroutine(); }); } MergeBuffStatus(unit, unitRender); await ETTask.CompletedTask; } private async ETTask AddBuff(CommonAI.ZoneClient.ZoneUnit.BuffState buff, UnitRenderComponet unitRender, BattleUnit unit) { BuffTemplate bt = buff.Data; //优先判断是否有叠层效果. LaunchEffect le = null; string key = bt.TemplateID.ToString(); //string effectName = ""; if (bt.OverlayBindingEffect != null && bt.OverlayBindingEffect.Count > 0) { if (buff.BuffExtendData > 0) { le = bt.OverlayBindingEffect[buff.OverlayLevel]; if (le.RType != LaunchEffect.RunType.Cycle_BindName) return; /*/超出最大层数,把最早的给移除掉 if (WordRainRecorderQueue.Count > 0 && WordRainRecorderQueue.Count >= me.Data.MaxOverlay) { string effectKey = WordRainRecorderQueue.Dequeue(); int effectStop; if (BuffEffects.TryGetValue(effectKey, out effectStop)) { BuffEffects.RemoveByKey(effectKey); StopEffect(effectStop); } } if (le.CricleMode != null) { WordRainRecorder += 1; key = bt.TemplateID.ToString() + "_" + me.BuffExtendData.ToString() + "_" + WordRainRecorder.ToString(); WordRainRecorderQueue.Enqueue(key); if (le.CricleMode.EffectName != null && le.CricleMode.EffectName.Length > me.BuffExtendDataIndex - 1 && me.BuffExtendDataIndex > 0) { effectName = le.CricleMode.EffectName[me.BuffExtendDataIndex - 1]; } }*/ } else { le = bt.OverlayBindingEffect[buff.OverlayLevel]; } } else { le = bt.BindingEffect; } if (le != null) { if (!unitRender.BuffEffects.ContainsKey(key)) { uint id = await EffectMgr.Instance.PlayEffect(le, unit.Id, Vector3.zero); unitRender.BuffEffects.Add(key, id); } else { EffectMgr.Instance.ResetEffect(unit.Id); } } if (bt.BindingEffectList.Count > 0) { System.Action PlayBindingEffect = async (buff, overLayer, maxOverLayer, templateID, index) => { string _bkey = string.Format("{0}_{1}", templateID, index); if (buff == null || unitRender.BuffEffects.ContainsKey(_bkey)) return; //uint id = PlayEffect(buff, false, -1, "", overLayer, maxOverLayer); uint id = await EffectMgr.Instance.PlayEffect(buff, unit.Id, Vector3.zero); unitRender.BuffEffects.Add(_bkey, id); }; if (bt.PlayType == BuffTemplate.BindingPlayType.All) { for (int i = 0; i < bt.BindingEffectList.Count; i++) { le = bt.BindingEffectList[i]; PlayBindingEffect(le, buff.OverlayLevel, bt.MaxOverlay, bt.TemplateID, i); } } else if (bt.PlayType == BuffTemplate.BindingPlayType.AppointOverLayer) { if (buff.OverlayLevel >= bt.BindingEffectList.Count) return; le = bt.BindingEffectList[buff.OverlayLevel]; PlayBindingEffect(le, buff.OverlayLevel, bt.MaxOverlay, bt.TemplateID, buff.OverlayLevel); } else if (bt.PlayType == BuffTemplate.BindingPlayType.IncludeOverLayer) { for (int i = 0; i < bt.BindingEffectList.Count; i++) { if (buff.OverlayLevel >= i) { le = bt.BindingEffectList[i]; PlayBindingEffect(le, buff.OverlayLevel, bt.MaxOverlay, bt.TemplateID, i); } else { break; } } } } } private void RemoveBuff(BuffTemplate bt, UnitRenderComponet unitRender) { var BuffEffects = unitRender.BuffEffects; if (BuffEffects != null) { uint effectStop = 0; string key = bt.ID.ToString(); if (BuffEffects.TryGetValue(key, out effectStop)) { BuffEffects.RemoveByKey(key); EffectMgr.Instance.RemoveEffect(effectStop); } if (bt.BindingEffectList.Count > 0) { string key2 = null; for (int i = 0; i < bt.BindingEffectList.Count; i++) { key2 = string.Format("{0}_{1}", key, i); if (BuffEffects.TryGetValue(key2, out effectStop)) { BuffEffects.RemoveByKey(key2); EffectMgr.Instance.RemoveEffect(effectStop); } } } } } private void MergeBuffStatus(BattleUnit unit, UnitRenderComponet unitRender) { bool bFrozen = false; bool bStealth = false; bool bNothingess = false; var list = unit.ZUnit.AllBuffs; list.ForEach((CommonAI.ZoneClient.ZoneUnit.BuffState buff) => { var ablist = (buff.Data.Properties as XmdsBuffProperties).BuffAbilityList; if (ablist != null) { foreach (var ab in ablist) { //TODO: 支持BUFF的冰冻、草丛、虚无效果 if (ab.ability == XmdsBuffProperties.XmdsBuffAbility.FROZEN || ab.ability == XmdsBuffProperties.XmdsBuffAbility.Fridge) { bFrozen = true; } else if (ab.ability == XmdsBuffProperties.XmdsBuffAbility.Stealth) { bStealth = true; //判断是不是在墙角,在墙角只更新currentMat,否则修改材质和currentMat /*foreach (var item in this.GameObject.GetComponentsInChildren()) { item.AddMatState(StateMaterial.HIDDING); }*/ } else if (ab.ability == XmdsBuffProperties.XmdsBuffAbility.Nothingness) { bNothingess = true; //this.HideSelf(true); } } } }); if (bFrozen) { unitRender.PauseAnimation(); unitRender.SetFrozen(); } else { unitRender.ResumeAnimation(); unitRender.ClearFrozen(); if (bStealth) { } else { if (bNothingess) { } } } } } }