zxl
/
CTT
forked from Cal/CTT
1
0
Fork 0
CTT/Server/Hotfix/Game/SkillSystem/NewSkill/System/ModifierContainerComponentS...

633 lines
28 KiB
C#

using Cal;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ET
{
public class ModifierContainerComponentUpdateSystem : UpdateSystem<ModifierContainerComponent>
{
public override void Update(ModifierContainerComponent self)
{
var now = TimeHelper.ClientNow();
using var needModifedListComponent = ListComponent<ModifierLogic>.Create();
using var _needModifedListComponent = ListComponent<ModifierId>.Create();
using var optionListComponent = ListComponent<(SkillOptionBase, ISkillSender)>.Create();
var needModifedList = needModifedListComponent.List;
var _needModifedList = _needModifedListComponent.List;
var optionList = optionListComponent.List;
foreach (var kv in self.timeDic)
{
if (now < kv.Value) continue;
if (!self.modifierDic.TryGetValue(kv.Key, out var modifierLogic))
{
_needModifedList.Add(kv.Key);
Log.Error($"{self.GetParent<Unit>()?.GetComponent<UnitSkillComponent>()?.GetLearnedSkills().FirstOrDefault()?.Id} this skill {modifierLogic?.skillLogic.skillId}");
continue;
}
if (!modifierLogic)
{
_needModifedList.Add(kv.Key);
Log.Error($"modifierLogic == null id= {self.Parent.Id} where {modifierLogic.IsDisposed}");
Log.Error($"{self.GetParent<Unit>()?.GetComponent<UnitSkillComponent>()?.GetLearnedSkills().FirstOrDefault()?.Id} this skill {modifierLogic?.skillLogic?.skillId}");
continue;
}
if (modifierLogic.modifierConfig == null)
{
Log.Error($"modifierLogic.modifierConfig == null where id= {self.Parent.Id} modifierId = {kv.Key}");
Log.Error($"{self.GetParent<Unit>()?.GetComponent<UnitSkillComponent>()?.GetLearnedSkills().FirstOrDefault()?.Id} this skill {modifierLogic?.skillLogic.skillId}");
continue;
}
needModifedList.Add(modifierLogic);
var dic = modifierLogic.modifierConfig?.modifierEventDic;
if (dic == null)
continue;
if (dic.TryGetValue(ModifierEventCondition., out var list))
{
foreach (var item in list)
{
optionList.Add((item, new ModifierSkillSender
{
caster = modifierLogic.skillLogic.owner,
skillLogic = modifierLogic.skillLogic,
modifierLogic = modifierLogic,
target = self.GetParent<Unit>()
}));
}
}
}
foreach (var item in _needModifedList)
{
self.timeDic.Remove(item);
}
foreach (var logic in needModifedList)
{
self.timeDic[logic.modifierId] = now + logic.interval;
}
foreach (var (option, skillSender) in optionList)
{
var skillOptionLogicBase = SkillOptionFactory.AcquireSkillOptionLogic(option);
skillSender.skillLogic.skillOptionLogics.Add(skillOptionLogicBase);
skillOptionLogicBase.HandleEvent(skillSender);
}
}
}
public class ModifierContainerComponentDestroySystem : DestroySystem<ModifierContainerComponent>
{
public override void Destroy(ModifierContainerComponent self)
{
foreach (var item in self.modifierDic.Values)
{
try
{
self.RemoveModifier(item);
}
catch (Exception e)
{
Log.Error(e);
}
}
self.modifierDic.Clear();
self.modifierStateDic.Clear();
self.timeDic.Clear();
self.modifierOptionByConditionDic.Clear();
}
}
public static class ModifierContainerComponentSystem
{
public static void ApplyModifier(this ModifierContainerComponent self, Unit owner, SkillLogic skillLogic, ModifierId modifierId)
{
if (!skillLogic.skillLogicConfig.modifierDic.TryGetValue(modifierId, out var modifierConfig))
{
return;
}
if (!modifierConfig.levelList.Contains(skillLogic.skillLevel))
return;
var target = self.GetParent<Unit>();
if (!SkillHelper.GetParam(modifierConfig.continueTime, skillLogic.skillConfigId, out var continueTime))
{
continueTime = 0;
}
if (!self.modifierDic.TryGetValue(modifierId, out var logic) || logic.IsDisposed)
{
logic = EntityFactory.CreateWithParent<ModifierLogic>(self);
logic.skillLogic = skillLogic;
logic.modifierConfig = modifierConfig;
//!特殊处理
if (continueTime == 0)
{
if (!IgnoreInvalid(modifierConfig.attribute))
return;
logic.overlay += 1;
OnBeforeCreateEvent();
DealEffect(owner, target, logic, modifierConfig);
OnAfterCreateEvent();
//!改变状态
logic.skillLogic.multipleDamageX10000 -= logic.multiDamageX10000;
logic.skillLogic.playAmount -= logic.playAmount;
logic.Dispose();
return;
}
}
else
{
if (AppConfig.inst.isTest)
Log.Warning($"dic already has the key:{modifierId} when create");
}
if (!logic)
{
Log.Error($"logic is invalid where id = {logic?.modifierId}");
return;
}
//!已经存在此modifier
if (self.modifierDic.ContainsKey(logic.modifierId))
{
var modifierAttribute = modifierConfig.attribute;
//!不改变属性(时间)
if (modifierAttribute == ModifierAttribute. ||
!IgnoreInvalid(modifierAttribute))
return;
//!可叠加的情况
if (modifierAttribute.HasFlag(ModifierAttribute.))
{
int maxOverlay = SkillHotfixHelper.GetOverlableBuffMaxLayer(modifierConfig.overlayType);
if (!SkillHelper.GetParam(modifierConfig.perOverlay, logic.skillLogic.skillConfigId, out var perOverlay))
{
perOverlay = 1;
}
logic.overlay += (int)perOverlay;
logic.overlay = Math.Clamp(logic.overlay, 1, maxOverlay);
}
//!可刷新的情况
if (modifierAttribute.HasFlag(ModifierAttribute.))
{
if (logic.continueTime != -1 * 1000)
{
var now = TimeHelper.ClientNow();
logic.cancellationToken?.Cancel();
logic.cancellationToken = new ETCancellationToken();
//Log.Debug($"modifier 原本结束时间:{TimeHelper.GetTime(logic.leastTime)},刷新后结束时间:{TimeHelper.GetTime(TimeHelper.ClientNow() + logic.continueTime)}");
logic.leastTime = now + logic.continueTime;
self.RemoveModifierIntetnal(logic).Coroutine();
}
}
}
//!不存在此modifier
else
{
OnBeforeCreateEvent();
AddToDic();
OnAfterCreateEvent();
if (modifierConfig.valueK != Cal.ModifierValueType.)
self.ChangeNumeric(target, logic, ValueChangeType.Plus);
if (modifierConfig.stateK != ModifierStateType.)
self.ChangeState(owner, target, logic, ValueChangeType.Plus);
logic.continueTime = (int)(continueTime * 1000);
var now = TimeHelper.ClientNow();
int iconId = modifierConfig.iconId;
if (iconId != 0)
{
string iconDesc = modifierConfig.iconDesc;
BuffBrocastComponent.Instance.AddChangeState(0, new EventType.BuffStateRet
{
Id = logic.Id,
targetUnit = target,
type = M2C_BattleChangeState.ChangeType.Add,
IconDesc = iconDesc,
IconId = iconId,
isBuff = logic.modifierConfig.buffType == BuffType.Buff,
time = logic.continueTime,
});
}
DealEffect(owner, target, logic, modifierConfig);
SetThinkerInterval(self, now, logic);
if (logic.continueTime != -1 * 1000)
{
logic.cancellationToken = new ETCancellationToken();
logic.leastTime = logic.continueTime + now;
self.RemoveModifierIntetnal(logic).Coroutine();
}
}
bool IgnoreInvalid(ModifierAttribute modifierAttribute)
{
if (modifierAttribute.HasFlag(ModifierAttribute.))
return self.HasState(ModifierStateType.);
return true;
}
void AddToDic()
{
float perOverlay = 1;
if (modifierConfig.attribute.HasFlag(ModifierAttribute.))
{
if (!SkillHelper.GetParam(modifierConfig.perOverlay, logic.skillLogic.skillConfigId, out perOverlay))
{
Log.Error($"perOnerlay is invalid where modifierId = {logic.modifierId}");
perOverlay = 1;
}
}
logic.overlay += (int)perOverlay;
if (!self.modifierDic.TryAdd(logic.modifierId, logic))
{
Log.Error($"dic add the modifier failly:{logic.modifierId} when apply");
}
else
{
var dic = logic.modifierConfig.modifierEventDic;
if (dic != null)
foreach (var kv in dic)
{
self.modifierOptionByConditionDic.Add(kv.Key, logic);
}
}
}
void OnBeforeCreateEvent()
{
logic.HandleEvent(ModifierEventCondition.modifier, new ModifierSkillSender
{
caster = owner,
target = target,
skillLogic = logic.skillLogic,
modifierLogic = logic
});
}
void OnAfterCreateEvent()
{
logic.HandleEvent(ModifierEventCondition.modifier, new ModifierSkillSender
{
caster = owner,
target = target,
skillLogic = logic.skillLogic,
modifierLogic = logic
});
}
}
private static void DealEffect(Unit owner, Unit target, ModifierLogic logic, ModifierConfig modifierConfig)
{
int effectId = modifierConfig.effectId;
if (effectId != 0)
{
target.GetComponent<BrocastComponent>().BrocastInterval(new M2C_PlaySkillEffect
{
UnitId = owner.Id,
TargetId = target.Id,
EffectId = effectId,
EffectPos = (int)modifierConfig.effectAttachType,
EffectTargetType = (int)EffectTargetType.Target,
Time = logic.continueTime,
});
}
}
private static void SetThinkerInterval(ModifierContainerComponent self, long now, ModifierLogic logic)
{
var modifierConfig = logic.modifierConfig;
if (modifierConfig.thinkerType == ThinkerType.)
{
return;
}
else
if (modifierConfig.thinkerType == ThinkerType. &&
SkillHelper.GetParam(modifierConfig.thinkInterval, logic.skillLogic.skillConfigId, out var inteval))
{
if (inteval <= 0)
{
return;
}
logic.interval = (int)(inteval * 1000);
}
else
{
logic.interval = SkillHotfixHelper.GetThinkerInterval(thinkerType: modifierConfig.thinkerType);
}
self.timeDic.Add(logic.modifierId, now + logic.interval);
}
public static void AddState(this ModifierContainerComponent self, ModifierStateType stateType, StateStateType stateStateType = StateStateType.)
{
self.modifierStateDic.TryAdd(stateType, stateStateType);
}
public static bool HasState(this ModifierContainerComponent self, ModifierStateType stateType)
{
if (self.modifierStateDic.TryGetValue(stateType, out var stateStateType))
return stateStateType == StateStateType.;
return false;
}
public static void ClearState(this ModifierContainerComponent self)
{
if (self.modifierStateDic.Count > 0)
{
if (AppConfig.inst.isTest)
Log.Error($"{self.Id} 清理 {self.modifierStateDic.Keys.ListToString()}");
}
self.modifierStateDic.Clear();
}
public static ModifierLogic GetModifierLogic(this ModifierContainerComponent self, ModifierId modifierId)
{
self.modifierDic.TryGetValue(modifierId, out var modifierLogic);
return modifierLogic;
}
public static (SkillOptionBase[], ModifierLogic) GetSkillOptionBaseArr(this ModifierContainerComponent self, ModifierEventCondition modifierEventCondition)
{
var set = self.modifierOptionByConditionDic[modifierEventCondition];
if (set.Count > 0)
foreach (var modifierLogic in set)
{
if (modifierLogic.IsDisposed) continue;
var dic = modifierLogic.modifierConfig.modifierEventDic;
if (dic != null)
if (dic.TryGetValue(modifierEventCondition, out var list))
return (list, modifierLogic);
}
return (null, null);
}
private static async ETVoid RemoveModifierIntetnal(this ModifierContainerComponent self, ModifierLogic modifierLogic)
{
bool ret = await TimerComponent.Instance.WaitTillAsync(modifierLogic.leastTime, modifierLogic.cancellationToken);
if (ret)
self.RemoveModifier(modifierLogic);
}
/// <summary>
/// 改变数值
/// </summary>
/// <param name="self"></param>
private static void ChangeNumeric(this ModifierContainerComponent self, Unit target, ModifierLogic logic, ValueChangeType valueChangeType)
{
try
{
var key = logic.modifierConfig.valueK;
if (key == Cal.ModifierValueType.) return;
var configValue = logic.modifierConfig.valueV;
var numTarget = target.GetComponent<NumericComponent>();
float sign = valueChangeType switch
{
ValueChangeType.Zero => 0,
ValueChangeType.Plus => 1,
ValueChangeType.Minus => -1,
_ => throw new Exception("类型错误"),
};
if (!SkillHelper.GetParam(configValue, logic.skillLogic.skillConfigId, out var value))
{
Log.Error($"cann't get the value where modifier = {logic.modifierId} type = {key}");
return;
}
if (sign == -1)
{
sign *= logic.skillLogic.dataOldX10000;
}
else
{
sign *= logic.skillLogic.dataX10000;
}
float finalValue = value * sign * 0.01f;
if (AppConfig.inst.showBattleDamageInfo)
Log.Debug($"{valueChangeType}了数值属性:{key} 改变量:{finalValue:p2}");
switch (key)
{
case Cal.ModifierValueType.:
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.MaxHpAdd, numTarget.Get(NumericType.MaxHpBase) * finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.MaxMpAdd, numTarget.Get(NumericType.MaxMpBase) * finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.PhyAtkAdd, numTarget.Get(NumericType.PhyAtkBase) * finalValue);
numTarget.AddSet(NumericType.SpiAtkAdd, numTarget.Get(NumericType.SpiAtkBase) * finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.PhyAtkAdd, numTarget.Get(NumericType.PhyAtkBase) * finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.SpiAtkAdd, numTarget.Get(NumericType.SpiAtkBase) * finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.PhyDefAdd, numTarget.Get(NumericType.PhyDefBase) * finalValue);
numTarget.AddSet(NumericType.SpiDefAdd, numTarget.Get(NumericType.SpiDefBase) * finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.PhyDefAdd, numTarget.Get(NumericType.PhyDefBase) * finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.SpiDefAdd, numTarget.Get(NumericType.SpiDefBase) * finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.PcrirAdd, finalValue);
numTarget.AddSet(NumericType.McrirAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.PcrirAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.McrirAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.PcriAdd, finalValue);
numTarget.AddSet(NumericType.McriAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.PcriAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.McriAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.RpcrirAdd, finalValue);
numTarget.AddSet(NumericType.RmcrirAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.RpcrirAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.RmcrirAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.RpcriAdd, finalValue);
numTarget.AddSet(NumericType.RmcriAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.RpcriAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.RmcriAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.NphyiAdd, finalValue);
numTarget.AddSet(NumericType.NmeniAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.NphyiAdd, finalValue);
break;
case Cal.ModifierValueType._:
numTarget.AddSet(NumericType.NmeniAdd, finalValue);
break;
case Cal.ModifierValueType.:
numTarget.AddSet(NumericType.DvoAdd, finalValue);
break;
case Cal.ModifierValueType.:
numTarget.AddSet(NumericType.SpdAdd, numTarget.Get(NumericType.SpdBase) * finalValue);
break;
case Cal.ModifierValueType.:
numTarget.AddSet(NumericType.HitAdd, numTarget.Get(NumericType.HitBase) * finalValue);
break;
case Cal.ModifierValueType.:
numTarget.AddSet(NumericType.ResAdd, numTarget.Get(NumericType.ResBase) * finalValue);
break;
default:
break;
}
}
catch (Exception e)
{
Log.Error(e);
}
}
/// <summary>
/// 附加状态
/// </summary>
/// <param name="self"></param>
private static void ChangeState(this ModifierContainerComponent self, Unit owner, Unit target, ModifierLogic logic, ValueChangeType valueChangeType)
{
try
{
var config = logic.modifierConfig;
if (config.stateK == ModifierStateType.) return;
if (AppConfig.inst.showBattleDamageInfo)
Log.Debug($"{valueChangeType}了状态属性:{config.stateK} ");
if (valueChangeType == ValueChangeType.Plus)
{
if (!self.modifierStateDic.ContainsKey(config.stateK))
self.modifierStateDic.Add(config.stateK, config.stateV);
}
else
if (valueChangeType == ValueChangeType.Minus)
self.modifierStateDic.Remove(config.stateK);
}
catch (Exception e)
{
Log.Error(e);
}
}
public static void RemoveModifier(this ModifierContainerComponent self, ISkillSender skillSender)
{
try
{
var modifierLogic = ((ModifierSkillSender)skillSender).modifierLogic;
if (modifierLogic == null)
Log.Error($"modifier is null where id = {modifierLogic.modifierId}");
self.RemoveModifier(modifierLogic);
}
catch (Exception e)
{
Log.Error(e);
}
}
public static void RemoveModifier(this ModifierContainerComponent self, ModifierLogic modifierLogic)
{
try
{
if (!modifierLogic)
return;
//!取消协程
modifierLogic.cancellationToken?.Cancel();
var owner = modifierLogic.skillLogic.owner;
var target = self.GetParent<Unit>();
var modifierId = modifierLogic.modifierId;
modifierLogic.HandleEvent(ModifierEventCondition.modifier, new ModifierSkillSender
{
caster = owner,
target = target,
skillLogic = modifierLogic.skillLogic,
modifierLogic = modifierLogic
});
//!改变状态
try
{
modifierLogic.skillLogic.multipleDamageX10000 -= modifierLogic.multiDamageX10000;
modifierLogic.skillLogic.playAmount -= modifierLogic.playAmount;
}
catch (Exception e)
{
Log.Error(e);
}
var dic = modifierLogic.skillLogic.skillLogicConfig?.modifierDic;
if (dic != null)
{
if (dic.TryGetValue(modifierId, out var modifierConfig))
{
if (modifierConfig.valueK != Cal.ModifierValueType.)
self.ChangeNumeric(target, modifierLogic, ValueChangeType.Minus);
if (modifierConfig.stateK != ModifierStateType.)
self.ChangeState(owner, target, modifierLogic, ValueChangeType.Minus);
}
}
self.timeDic.Remove(modifierId);
using var listComponent = ListComponent<(ModifierEventCondition, ModifierLogic)>.Create();
var needRemoveModifierSet = listComponent.List;
foreach (var kv in self.modifierOptionByConditionDic.GetDictionary())
{
foreach (var _logic in kv.Value)
{
try
{
if (!_logic.IsDisposed && _logic.modifierId == modifierId)
{
needRemoveModifierSet.Add((kv.Key, _logic));
}
}
catch (Exception e)
{
Log.Error(e);
}
}
}
foreach (var (eventCondition, __logic) in needRemoveModifierSet)
{
self.modifierOptionByConditionDic.Remove(eventCondition, __logic);
}
if (!self.modifierDic.Remove(modifierId))
{
Log.Error($"modifierDic remove the key fail :{modifierId}");
Log.Error($" id= {self.Parent.Id} {self.GetParent<Unit>()?.GetComponent<UnitSkillComponent>()?.GetLearnedSkills().FirstOrDefault()?.Id} this skill {modifierLogic?.skillLogic.skillId}");
}
modifierLogic.HandleEvent(ModifierEventCondition.modifier, new ModifierSkillSender
{
caster = owner,
target = target,
skillLogic = modifierLogic.skillLogic,
modifierLogic = modifierLogic
});
modifierLogic.Dispose();
}
catch (Exception e)
{
Log.Error(e);
modifierLogic.Dispose();
}
}
}
}