184 lines
6.4 KiB
C#
184 lines
6.4 KiB
C#
using Games.LogicObj;
|
||
using GCGame.Table;
|
||
using Module.Log;
|
||
using System.Collections.Generic;
|
||
|
||
/// <summary>
|
||
/// 此处的buff效果处理 直接使用EffectLogic来控制,所以没写单例模式
|
||
/// 该类只是控制buff 的客户端表现(界面显示,模型变换,NPC隐藏等等)
|
||
/// </summary>
|
||
public class ImpactEffectMgr
|
||
{
|
||
private const int _defaultBodyPart = 0;
|
||
private readonly List<ImpactEffectBase> _impacts = new List<ImpactEffectBase>();
|
||
|
||
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<ImpactEffectBase> 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();
|
||
}
|
||
} |