CTT/Server/Hotfix/Game/System/Battle/PlayerSkillAISystem.cs

375 lines
13 KiB
C#

using Cal;
using Cal.DataTable;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ET
{
public class PlayerSkillAIAwakeSystem: AwakeSystem<SkillAI>
{
public override void Awake(SkillAI self)
{
}
}
public class SkillAIDestroySystem: DestroySystem<SkillAI>
{
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)
{
self.lastSkillTime = now;
return true;
}
return false;
}
public static void PlayAutoSkill(this SkillAI self, long now)
{
if (!self.canSkill) return;
self.canSkill = false;
LinkedList<int> skills = self.AutoSkillList;
if (skills.Count == 0) return;
PlaySkill(self, skills, now);
}
private static void PlaySkill(this SkillAI self, LinkedList<int> list, long now)
{
try
{
Unit unit = self.GetParent<Unit>();
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<SkillMgrComponent>();
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>();
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<Unit>();
if (skillId == 0)
{
Log.Error($"skillId == 0");
return "系统错误";
}
UnitSkill skill = unit.GetComponent<UnitSkillComponent>().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<SkillMgrComponent>();
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 "冷却中!";
}
return canCast;
}
}
else
{
if (canCast != null) return canCast;
}
//!选择目标
TargetableUnitComponent targetComponent = unit.GetComponent<TargetableUnitComponent>();
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<AttackComponent>().StartSpellSkill(skillLogic);
if (!ret)
{
skillLogic.lastCDTime = time;
return "特别原因";
}
return null;
}
private static bool CastHp(Unit unit, CastParam cast)
{
NumericComponent num = unit.GetComponent<NumericComponent>();
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<NumericComponent>();
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;
}
/// <summary>
/// 怪物释放逻辑
/// </summary>
/// <param name="self"></param>
public static void PlaySkill(this SkillAI self)
{
try
{
Unit unit = self.GetParent<Unit>();
if (!unit) return;
LinkedList<int> list = self.AutoSkillList;
int skillId = self.GetCurrSkillId(list);
if (skillId == 0) return;
UnitSkillComponent skillConponent = unit.GetComponent<UnitSkillComponent>();
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<AttackComponent>();
SkillMgrComponent skillMgr = unit.GetComponent<SkillMgrComponent>();
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<TargetableUnitComponent>();
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<int> list = self.Parent.GetComponent<UserSetting>().GetAutoSkills();
self.AutoSkillList.Clear();
foreach (int item in list)
{
self.AutoSkillList.AddLast(item);
}
}
private static bool CheckUnActionState(Unit unit)
{
ModifierContainerComponent modifierContainer = unit.GetComponent<ModifierContainerComponent>();
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<int> list)
{
try
{
LinkedListNode<int> 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;
}
}
}