322 lines
11 KiB
C#
322 lines
11 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;
|
|||
|
var 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++)
|
|||
|
{
|
|||
|
var skillId = self.GetCurrSkillId(list);
|
|||
|
if (skillId == 0) continue;
|
|||
|
var ret = self.PlaySkill(skillId, now);
|
|||
|
if (ret == null)
|
|||
|
{
|
|||
|
var 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)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
Unit unit = self.GetParent<Unit>();
|
|||
|
if (skillId == 0)
|
|||
|
{
|
|||
|
Log.Error($"skillId == 0");
|
|||
|
return "系统错误";
|
|||
|
}
|
|||
|
var 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 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))
|
|||
|
{
|
|||
|
Log.Debug($"{unit.Id}禁足");
|
|||
|
return "禁足";
|
|||
|
}
|
|||
|
return CheckSkillCondition(now, unit, skillLogic);
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Log.Error(e);
|
|||
|
return "系统错误";
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
private static string CheckSkillCondition(long now, Unit unit, SkillLogic skillLogic)
|
|||
|
{
|
|||
|
SkillLogicConfig skillConfig = skillLogic.skillLogicConfig;
|
|||
|
if (now - skillLogic.lastCDTime < skillConfig.CD)
|
|||
|
{
|
|||
|
return "冷却中!";
|
|||
|
}
|
|||
|
//!选择目标
|
|||
|
var targetComponent = unit.GetComponent<TargetableUnitComponent>();
|
|||
|
if (!targetComponent)
|
|||
|
Log.Error($"targetComponent == null where id = {unit.Id}");
|
|||
|
else
|
|||
|
targetComponent.SelectTarget(skillLogic.skillLogicConfig);
|
|||
|
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 (canCast != null) return canCast;
|
|||
|
long time = skillLogic.lastCDTime;
|
|||
|
skillLogic.lastCDTime = now;
|
|||
|
//!执行技能逻辑
|
|||
|
var ret = unit.GetComponent<AttackComponent>().StartSpellSkill(skillLogic);
|
|||
|
if (!ret)
|
|||
|
{
|
|||
|
skillLogic.lastCDTime = time;
|
|||
|
return "特别原因";
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
private static bool CastHp(Unit unit, CastParam cast)
|
|||
|
{
|
|||
|
var 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)
|
|||
|
{
|
|||
|
var 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;
|
|||
|
var list = self.AutoSkillList;
|
|||
|
var skillId = self.GetCurrSkillId(list);
|
|||
|
if (skillId == 0) return;
|
|||
|
|
|||
|
var skillConponent = unit.GetComponent<UnitSkillComponent>();
|
|||
|
var skill = skillConponent.GetLearnedSkill(skillId);
|
|||
|
if (skill == UnitSkill.Null)
|
|||
|
{
|
|||
|
Log.Error($"skill == null where skillid = {skillId}");
|
|||
|
return;
|
|||
|
}
|
|||
|
int level = skill.Level;
|
|||
|
|
|||
|
var attacker = unit.GetComponent<AttackComponent>();
|
|||
|
var 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))
|
|||
|
{
|
|||
|
Log.Debug($"禁足");
|
|||
|
return;
|
|||
|
}
|
|||
|
//!选择目标
|
|||
|
var 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)
|
|||
|
{
|
|||
|
var list = self.Parent.GetComponent<UserSetting>().GetAutoSkills();
|
|||
|
self.AutoSkillList.Clear();
|
|||
|
foreach (var item in list)
|
|||
|
{
|
|||
|
self.AutoSkillList.AddLast(item);
|
|||
|
}
|
|||
|
}
|
|||
|
private static bool CheckUnActionState(Unit unit)
|
|||
|
{
|
|||
|
var 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
|
|||
|
{
|
|||
|
var 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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|