using Cal; using Cal.DataTable; using System; using System.Collections.Generic; using System.Linq; namespace ET { public class PlayerSkillAIAwakeSystem: AwakeSystem { public override void Awake(SkillAI self) { } } public class SkillAIDestroySystem: DestroySystem { public override void Destroy(SkillAI self) { self.CurrSkillNode = null; self.AutoSkillList.Clear(); self.canSkill = false; } } public static class PlayerSkillAISystem { public static bool CheckCD(this SkillAI self, long now) { if (self == null) { Log.Error($"skillAI = null"); return false; } if (!(now - self.lastSkillTime >= self.roundCD)) { return false; } self.lastSkillTime = now; return true; } public static void PlayAutoSkill(this SkillAI self, long now) { if (!self.canSkill) return; self.canSkill = false; LinkedList skills = self.AutoSkillList; if (skills.Count == 0) return; PlaySkill(self, skills, now); } private static void PlaySkill(this SkillAI self, LinkedList list, long now) { try { Unit unit = self.GetParent(); int skillCount = list.Count; for (int i = 0; i < skillCount; i++) { int skillId = self.GetCurrSkillId(list); if (skillId == 0) continue; string ret = self.PlaySkill(skillId, now, true); if (ret == null) { SkillMgrComponent skillMgr = unit.GetComponent(); SkillLogic skillLogic = skillMgr.GetSkill(skillId); if (skillLogic == null) { Log.Error($"skillLogic == null where skillid = {skillId}"); return; } SetMainUICD(unit, skillId, skillLogic.skillConfig.CD); return; } } } catch (Exception e) { Log.Error(e); } } private static void SetMainUICD(Unit unit, int id, int skillCD) { UserSetting userSetting = unit.GetComponent(); userSetting.StartCD(MainUIType.SkillSlot, id, skillCD); } public static string PlaySkill(this SkillAI self, int skillId, long now, bool isAuto = false) { try { Unit unit = self.GetParent(); if (skillId == 0) { Log.Error($"skillId == 0"); return "系统错误"; } UnitSkill skill = unit.GetComponent().GetLearnedSkill(skillId); if (skill == UnitSkill.Null) { Log.Error($"【{UserComponent.Instance.Get(unit.Id)?.NickName} ({unit.Id})】使用了没学会的技能,技能id={skillId}"); return "系统错误"; } int level = skill.Level; //!+暂时 var skillLogic = GetSkillLogic(unit, skillId, level); if (skillLogic == null) { Log.Error($"{unit.Id.GetPlayerFormatName()} has not the skill where skillId = {skillId} level = {level}"); return "系统错误,没有技能"; } //!判断状态 if (CheckUnActionState(unit)) { return "禁足"; } return CheckSkillConditionAndSpell(now, unit, skillLogic, isAuto); } catch (Exception e) { Log.Error(e); return "系统错误"; } } private static SkillLogic GetSkillLogic(Unit unit, int skillId, int level) { SkillMgrComponent skillMgr = unit.GetComponent(); SkillLogic skillLogic = skillMgr.GetSkill(skillId); if (skillLogic == null) { Log.Error($"skillLogic == null where skillid = {skillId}"); return null; } skillLogic.skillLevel = level; return skillLogic; } private static string CheckSkillConditionAndSpell(long now, Unit unit, SkillLogic skillLogic, bool isAuto) { SkillLogicConfig skillConfig = skillLogic.skillLogicConfig; if (now - skillLogic.lastCDTime < skillConfig.CD) { return "冷却中!"; } string canCast = null; SkillCastType skillCastType = skillConfig.cast.skillCastType; switch (skillCastType) { case SkillCastType.无消耗: break; case SkillCastType.消耗精力: if (!CastMp(unit, skillConfig.cast)) canCast = "精力不足!"; break; case SkillCastType.消耗血量: if (!CastHp(unit, skillConfig.cast)) canCast = "血量不足!"; break; default: break; } if (isAuto) { if (canCast != null) { skillLogic = GetSkillLogic(unit, SkillHotfixHelper.GetNomalSkillId(unit), 1); if (skillLogic == null) { Log.Error($"{unit.Id.GetPlayerFormatName()} has not the skill where skillId = {SkillHotfixHelper.GetNomalSkillId(unit)}"); } skillConfig = skillLogic.skillLogicConfig; if (now - skillLogic.lastCDTime < skillConfig.CD) { return "冷却中!"; } } } else { if (canCast != null) return canCast; } //!选择目标 TargetableUnitComponent targetComponent = unit.GetComponent(); if (!targetComponent) { Log.Error($"targetComponent == null where id = {unit.Id}"); return "系统错误"; } targetComponent.SelectTarget(skillLogic.skillLogicConfig); long time = skillLogic.lastCDTime; skillLogic.lastCDTime = now; //!执行技能逻辑 bool ret = unit.GetComponent().StartSpellSkill(skillLogic); if (!ret) { skillLogic.lastCDTime = time; return "特别原因"; } return null; } private static bool CastHp(Unit unit, CastParam cast) { NumericComponent num = unit.GetComponent(); float hp = num.Get(NumericType.Hp); float value = 0; switch (cast.castBaseType) { case CastBaseType.Level: float level = num.Get(NumericType.Level); value = level * cast.skillCast; break; case CastBaseType.Curr: float currHp = num.Get(NumericType.Hp); value = currHp * cast.skillCast; break; case CastBaseType.Max: float maxHp = num.Get(NumericType.MaxHp); value = maxHp * cast.skillCast; break; case CastBaseType.Other: break; default: break; } if (hp < value) return false; num.ReduceSet(NumericType.Hp, value); return true; } private static bool CastMp(Unit unit, CastParam cast) { NumericComponent num = unit.GetComponent(); float mp = num.Get(NumericType.Mp); float value = 0; switch (cast.castBaseType) { case CastBaseType.Level: float level = num.Get(NumericType.Level); value = level * cast.skillCast; break; case CastBaseType.Curr: float currHp = num.Get(NumericType.Mp); value = currHp * cast.skillCast; break; case CastBaseType.Max: float maxHp = num.Get(NumericType.MaxMp); value = maxHp * cast.skillCast; break; case CastBaseType.Other: break; default: break; } if (mp < value) return false; num.ReduceSet(NumericType.Mp, value); return true; } /// /// 怪物释放逻辑 /// /// public static void PlaySkill(this SkillAI self) { try { Unit unit = self.GetParent(); if (!unit) return; LinkedList list = self.AutoSkillList; int skillId = self.GetCurrSkillId(list); if (skillId == 0) return; UnitSkillComponent skillConponent = unit.GetComponent(); UnitSkill skill = skillConponent.GetLearnedSkill(skillId); if (skill == UnitSkill.Null) { Log.Error($"skill == null where skillid = {skillId}"); return; } int level = skill.Level; AttackComponent attacker = unit.GetComponent(); SkillMgrComponent skillMgr = unit.GetComponent(); SkillLogic skillLogic = skillMgr.GetSkill(skillId); if (skillLogic == null) { Log.Error($"skillLogic == null where skillid = {skillId}"); return; } skillLogic.skillLevel = level; //!判断状态 if (CheckUnActionState(unit)) { return; } //!选择目标 TargetableUnitComponent targetComponent = unit.GetComponent(); if (!targetComponent) Log.Error($"targetComponent == null where id = {unit.Id}"); else targetComponent.SelectTarget(skillLogic.skillLogicConfig); attacker.StartSpellSkill(skillLogic); } catch (Exception e) { Log.Error(e); } } public static void UpdateAutoSkill(this SkillAI self) { LinkedList list = self.Parent.GetComponent().GetAutoSkills(); self.AutoSkillList.Clear(); foreach (int item in list) { self.AutoSkillList.AddLast(item); } } private static bool CheckUnActionState(Unit unit) { ModifierContainerComponent modifierContainer = unit.GetComponent(); return Check(modifierContainer, ModifierStateType.眩晕) || Check(modifierContainer, ModifierStateType.石化) || Check(modifierContainer, ModifierStateType.冰冻) || Check(modifierContainer, ModifierStateType.沉默); static bool Check(ModifierContainerComponent modifierContainer, ModifierStateType modifierStateType) => modifierContainer.HasState(modifierStateType); } private static int GetCurrSkillId(this SkillAI self, LinkedList list) { try { LinkedListNode curr = self.CurrSkillNode ?? list.First; if (curr == list.Last) self.CurrSkillNode = null; else self.CurrSkillNode = curr.Next; return curr.Value; } catch (Exception e) { Log.Error(e); } return 0; } } }