using Games.LogicObj; using GCGame.Table; using Module.Log; using System.Collections.Generic; /// /// 此处的buff效果处理 直接使用EffectLogic来控制,所以没写单例模式 /// 该类只是控制buff 的客户端表现(界面显示,模型变换,NPC隐藏等等) /// public class ImpactEffectMgr { private const int _defaultBodyPart = 0; private readonly List _impacts = new List(); public void StartImpactEffect(Tab_Effect effectData, Obj obj, float overrideDuration = -1f) { if (effectData == null || obj == null) return; var effectType = (EffectLogic.EffectType)effectData.Type; switch (effectType) { case EffectLogic.EffectType.TYPE_BLIND: case EffectLogic.EffectType.TYPE_CHAOS: case EffectLogic.EffectType.TYPE_SCREENUIEFFECT: case EffectLogic.EffectType.TYPE_CLIENTNPC: case EffectLogic.EffectType.TYPE_SCALE: BuildImpact(effectData, obj, _defaultBodyPart, overrideDuration); break; case EffectLogic.EffectType.TYPE_CHANGEMODELMAT: case EffectLogic.EffectType.TYPE_CHANGMATPRO: case EffectLogic.EffectType.TYPE_CHANGESHADER: case EffectLogic.EffectType.TYPE_ADDMAT: case EffectLogic.EffectType.TYPE_MATPROBYHEALTH: { // 临时移除特殊效果,等待重构以正常恢复渐变等效果 var count = effectData.getParamValueCount(); for (var i = 0; i < count; i++) { var param = effectData.GetParamValuebyIndex(i); if (param > -1) BuildImpact(effectData, obj, i, overrideDuration); } } break; default: LogModule.ErrorLog(string.Format("未处理类型为{0}的特殊Effect!", effectType)); break; } } public ImpactEffectBase BuildImpact(Tab_Effect effectData, Obj obj, int bodyPart, float overrideDuration) { var effectType = (EffectLogic.EffectType)effectData.Type; var impactEffect = _impacts.Find(a => a.ImpactEffectType == effectType && a.GetPart() == bodyPart && (!a.Overly || a.Data.EffectID == effectData.EffectID)); if (impactEffect == null) { impactEffect = CreateImpact(effectType); if (impactEffect != null) { impactEffect.SetPart(bodyPart); _impacts.Add(impactEffect); } } if (impactEffect != null) impactEffect.InitData(effectData, obj, overrideDuration); return impactEffect; } private ImpactEffectBase CreateImpact(EffectLogic.EffectType type) { ImpactEffectBase result = null; switch (type) { case EffectLogic.EffectType.TYPE_BLIND: result = new Impact_Blind(); break; case EffectLogic.EffectType.TYPE_SCREENUIEFFECT: result = new Impact_ScreenUIEffect(); break; case EffectLogic.EffectType.TYPE_CHAOS: result = new Impact_Chaos(); break; case EffectLogic.EffectType.TYPE_CHANGMATPRO: result = new Impact_ModeMatPro(); break; case EffectLogic.EffectType.TYPE_CHANGEMODELMAT: result = new Impact_ChangeModelMat(); break; case EffectLogic.EffectType.TYPE_CHANGESHADER: result = new Impact_ChangeModelShader(); break; case EffectLogic.EffectType.TYPE_ADDMAT: result = new Impact_AddMat(); break; case EffectLogic.EffectType.TYPE_CLIENTNPC: result = new Impact_ClientNpc(); break; case EffectLogic.EffectType.TYPE_MATPROBYHEALTH: result = new Impact_MatProByHealth(); break; case EffectLogic.EffectType.TYPE_SCALE: result = new Impact_ModelScale(); break; default: LogModule.ErrorLog(string.Format("未处理生成{0}类型的Impact!", type)); break; } return result; } public void OnUpdate() { for (var i = _impacts.Count - 1; i >= 0; i--) { try { var impact = _impacts[i]; if (!impact.OnUpdate()) EndImpactByIndex(i); } catch (System.Exception e) { LogModule.ErrorLog(e.ToString()); _impacts.RemoveAt(i); } } } public void RemoveImpactEffect(Tab_Effect effectData, bool bStopAll) { RemoveImpactEffect(a => a.Data == effectData, bStopAll); if (bStopAll) { ReStartNext((EffectLogic.EffectType)effectData.Type, 0); } } public void RemoveImpactEffect(Tab_Effect effectData, int bodyPart, bool bStopAll) { RemoveImpactEffect(a => a.Data == effectData && a.GetPart() == bodyPart, bStopAll); if (bStopAll) { ReStartNext((EffectLogic.EffectType)effectData.Type, 0); } } public void RemoveImpactEffect(System.Predicate predicate, bool bStopAll) { for (var i = _impacts.Count - 1; i >= 0; i--) if (predicate(_impacts[i])) { EndImpactByIndex(i, bStopAll); if (!bStopAll) { break; } } } private void ReStartNext(EffectLogic.EffectType type,int bodyPart) { var impactEffect = _impacts.FindLast(a => a.ImpactEffectType == type && a.Overly); if (impactEffect != null) impactEffect.StartEffect(); } private void EndImpactByIndex(int index,bool bStopAll = false) { var effectType = _impacts[index].ImpactEffectType; int bodyPart = _impacts[index].GetPart(); _impacts[index].StopEffect(); _impacts.RemoveAt(index); if (bStopAll == false) ReStartNext(effectType, bodyPart); } public void ClearEffect() { for (var i = 0; i < _impacts.Count; i++) _impacts[i].StopEffect(); _impacts.Clear(); } }