| New file |
| | |
| | | using System.Collections; |
| | | using System.Collections.Generic; |
| | | using Snxxz.UI; |
| | | using UnityEngine; |
| | | |
| | | public class AI_Boss_HYQ : SampleAI |
| | | { |
| | | private int m_Step = 0; |
| | | private bool m_InShow = false; |
| | | private int m_LockSkill = 0; |
| | | private int m_NormalAtkCount = 0; |
| | | |
| | | public AI_Boss_HYQ(GA_NpcClientFightNorm owner, Vector3 bornPosition) : base(owner, bornPosition) |
| | | { |
| | | m_Step = 0; |
| | | m_SleepTime = 1f; |
| | | m_InShow = false; |
| | | m_CanCastSkill = false; |
| | | m_NormalAtkCount = 0; |
| | | } |
| | | |
| | | private void CheckStep() |
| | | { |
| | | var _hero = PlayerDatas.Instance.hero; |
| | | switch (m_Step) |
| | | { |
| | | case 0:// 检测普攻次数 |
| | | if (m_NormalAtkCount > 1) |
| | | { |
| | | m_Step = 1; |
| | | m_LockSkill = 10009; |
| | | m_CanCastSkill = true; |
| | | } |
| | | break; |
| | | case 1:// 检测血量 |
| | | if (m_Owner.ActorInfo.RealHp <= m_Owner.ActorInfo.RealMaxHp * .2f) |
| | | { |
| | | Debug.Log("触发了动画"); |
| | | m_Step = 2; |
| | | } |
| | | break; |
| | | case 2: |
| | | // Boss: 小辈感受吾真正的实力 |
| | | var _model1 = ModelCenter.Instance.GetModel<GuideDialogueModel>(); |
| | | _model1.dialogID = 1000; |
| | | _model1.onClose = Step_1_TalkFinished; |
| | | WindowCenter.Instance.Open<GuideDialogueWin>(); |
| | | if (_hero != null) |
| | | { |
| | | _hero.Behaviour.StopKillUntilDieAI(); |
| | | _hero.Behaviour.StopHandupAI(); |
| | | } |
| | | m_Step = 3; |
| | | break; |
| | | case 4:// 计算角色普攻次数 |
| | | if (m_NormalAtkCount > 3) |
| | | { |
| | | STM_NormalAttack.OnCastNormalAttack -= OnHeroNormalAttack; |
| | | m_NormalAtkCount = 0; |
| | | // Boss: 哈哈哈 |
| | | var _model2 = ModelCenter.Instance.GetModel<GuideDialogueModel>(); |
| | | _model2.dialogID = 1000; |
| | | _model2.onClose = Step_1_TalkFinished; |
| | | WindowCenter.Instance.Open<GuideDialogueWin>(); |
| | | if (_hero != null) |
| | | { |
| | | _hero.Behaviour.StopKillUntilDieAI(); |
| | | _hero.Behaviour.StopHandupAI(); |
| | | } |
| | | m_Step = 5; |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | private void Step_1_TalkFinished() |
| | | { |
| | | m_Step = 4; |
| | | m_NormalAtkCount = 0; |
| | | STM_NormalAttack.OnCastNormalAttack += OnHeroNormalAttack; |
| | | } |
| | | |
| | | private void OnHeroNormalAttack() |
| | | { |
| | | m_NormalAtkCount += 1; |
| | | } |
| | | |
| | | public override void Update() |
| | | { |
| | | if (m_InShow) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | CheckStep(); |
| | | |
| | | // ai休眠时间 |
| | | if (Time.realtimeSinceStartup - m_LastThinkTime > m_SleepTime) |
| | | { |
| | | _Thinking(); |
| | | } |
| | | |
| | | // 是否正在释放技能 |
| | | if (m_Owner.SkillMgr.CurCastSkill != null) |
| | | { |
| | | if (m_Owner.SkillMgr.CurCastSkill.SkillCompelete == false) |
| | | { |
| | | if (m_Owner.IsIdle()) |
| | | { |
| | | m_Owner.SkillMgr.CurCastSkill.SkillCompelete = true; |
| | | } |
| | | return; |
| | | } |
| | | |
| | | if (m_Owner.SkillMgr.CurCastSkill.SkillPreparing) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | if (m_Owner.NextAction == GAStaticDefine.Act_Warn) |
| | | { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | switch (m_AIStatus) |
| | | { |
| | | case E_AIStatus.Patrol: |
| | | _Patrol(); |
| | | break; |
| | | case E_AIStatus.Attack: |
| | | _Attack(); |
| | | break; |
| | | case E_AIStatus.MoveToBornPos: |
| | | MoveToBornPos(); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | private void MoveToBornPos() |
| | | { |
| | | var _dis = MathUtility.DistanceSqrtXZ(m_Owner.Pos, BornPos); |
| | | if (_dis > 0.1f) |
| | | { |
| | | m_Owner.MoveToPosition(BornPos); |
| | | } |
| | | else |
| | | { |
| | | m_AIStatus = E_AIStatus.Patrol; |
| | | } |
| | | } |
| | | |
| | | private byte atkStep; |
| | | private Vector3 atkPos; |
| | | |
| | | private void _Attack() |
| | | { |
| | | if (m_AIStatus == E_AIStatus.MoveToBornPos) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | GA_Hero _hero = PlayerDatas.Instance.hero; |
| | | |
| | | float _dis; |
| | | |
| | | switch (atkStep) |
| | | { |
| | | case 0: |
| | | _dis = GetNextSkill().skillInfo.config.AtkDist * .5f; |
| | | var _compareDis = MathUtility.DistanceSqrtXZ(_hero.Pos, m_Owner.Pos); |
| | | if (_compareDis < _dis * _dis) |
| | | { |
| | | atkStep = 1; |
| | | m_Owner.StopPathFind(); |
| | | m_Owner.Forward = MathUtility.ForwardXZ(_hero.Pos, m_Owner.Pos); |
| | | } |
| | | else |
| | | { |
| | | if (m_Owner.posIndex != -1) |
| | | { |
| | | HeroRoundGird.Instance.Release(m_Owner.posIndex); |
| | | m_Owner.posIndex = -1; |
| | | } |
| | | var _node = HeroRoundGird.Instance.Request(m_Owner.ServerInstID, m_Owner.Pos, _dis); |
| | | if (_node != null) |
| | | { |
| | | atkPos = HeroRoundGird.Instance.GetRealPos(_node); |
| | | m_Owner.posIndex = _node.index; |
| | | } |
| | | _dis = MathUtility.DistanceSqrtXZ(atkPos, m_Owner.Pos); |
| | | if (_dis < 0.2f) |
| | | { |
| | | atkStep = 1; |
| | | m_Owner.StopPathFind(); |
| | | m_Owner.Forward = MathUtility.ForwardXZ(_hero.Pos, m_Owner.Pos); |
| | | } |
| | | else |
| | | { |
| | | atkStep = 2; |
| | | } |
| | | } |
| | | |
| | | break; |
| | | case 2: |
| | | _dis = MathUtility.DistanceSqrtXZ(atkPos, m_Owner.Pos); |
| | | if (_dis < 0.2f) |
| | | { |
| | | atkStep = 0; |
| | | } |
| | | else |
| | | { |
| | | m_Owner.MoveToPosition(atkPos); |
| | | } |
| | | break; |
| | | case 1: |
| | | |
| | | if (Time.realtimeSinceStartup - m_LastAttackTime < m_Owner.NpcConfig.AtkInterval * Constants.F_GAMMA) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | var _skillID = GetNextSkill().id; |
| | | |
| | | Debug.LogFormat("{0} 释放了技能 {1}", m_Owner.ServerInstID, _skillID); |
| | | |
| | | m_Owner.CastSkill(_skillID); |
| | | atkStep = 0; |
| | | |
| | | if (_skillID == m_LockSkill) |
| | | { |
| | | m_LockSkill = 0; |
| | | } |
| | | |
| | | if (_skillID == m_BaseAtkSkillID) |
| | | { |
| | | m_NormalAtkCount += 1; |
| | | Debug.Log("次数增加了"); |
| | | } |
| | | |
| | | m_LastAttackTime = Time.realtimeSinceStartup; |
| | | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | private Skill GetNextSkill() |
| | | { |
| | | Skill _skill1 = null; |
| | | |
| | | if (m_CanCastSkill) |
| | | { |
| | | Debug.Log("可以释放技能了"); |
| | | if (m_LockSkill > 0) |
| | | { |
| | | Debug.Log("有指定技能"); |
| | | _skill1 = m_Owner.SkillMgr.Get(m_LockSkill); |
| | | if (!_skill1.IsValid()) |
| | | { |
| | | _skill1 = null; |
| | | } |
| | | } |
| | | |
| | | if (_skill1 == null) |
| | | { |
| | | for (int i = 0; i < m_SkillList.Count; ++i) |
| | | { |
| | | if (m_Owner.SkillMgr.Get(m_SkillList[i]).IsValid()) |
| | | { |
| | | _skill1 = m_Owner.SkillMgr.Get(m_SkillList[i]); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (_skill1 == null) |
| | | { |
| | | _skill1 = m_Owner.SkillMgr.Get(m_BaseAtkSkillID); |
| | | } |
| | | |
| | | return _skill1; |
| | | } |
| | | |
| | | private byte patrolStep; |
| | | private float patrolWaitTime; |
| | | private float patrolWaitRandomTime; |
| | | private Vector3 randomPos; |
| | | private void _Patrol() |
| | | { |
| | | if (m_AIStatus == E_AIStatus.MoveToBornPos) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | switch (patrolStep) |
| | | { |
| | | case 0: |
| | | patrolWaitRandomTime = Random.Range(2f, 4f); |
| | | patrolWaitTime = Time.realtimeSinceStartup; |
| | | patrolStep = 1; |
| | | break; |
| | | case 1: |
| | | if (Time.realtimeSinceStartup - patrolWaitTime > patrolWaitRandomTime) |
| | | { |
| | | patrolStep = 2; |
| | | patrolWaitTime = Time.realtimeSinceStartup; |
| | | randomPos = BornPos + new Vector3(Random.Range(-2f, 2f), 0, Random.Range(-2f, 2f)); |
| | | GActor.TryGetValidPos(randomPos, ref randomPos); |
| | | m_Owner.MoveToPosition(randomPos); |
| | | } |
| | | break; |
| | | case 2: |
| | | if (Time.realtimeSinceStartup - patrolWaitTime > 2) |
| | | { |
| | | patrolStep = 1; |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | private void _Thinking() |
| | | { |
| | | if (m_AIStatus == E_AIStatus.MoveToBornPos) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | float _compareDis; |
| | | // 思考 |
| | | var _hero = PlayerDatas.Instance.hero; |
| | | if (_hero == null || _hero.ActorInfo.serverDie) |
| | | { |
| | | // 主角不存在或者死亡了 |
| | | // 在出生点附近 |
| | | _compareDis = MathUtility.DistanceSqrtXZ(BornPos, m_Owner.Pos); |
| | | if (_compareDis < 4) |
| | | { |
| | | m_AIStatus = E_AIStatus.Patrol; |
| | | } |
| | | // 巡逻 |
| | | // 不在出生点附近 |
| | | else |
| | | { |
| | | // 回到出生点 |
| | | m_AIStatus = E_AIStatus.MoveToBornPos; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | _compareDis = MathUtility.DistanceSqrtXZ(m_Owner.Pos, BornPos); |
| | | |
| | | if (_compareDis > m_KeepBornDistSqrt) |
| | | { |
| | | m_AIStatus = E_AIStatus.MoveToBornPos; |
| | | } |
| | | else |
| | | { |
| | | // 玩家在可见范围内 |
| | | _compareDis = MathUtility.DistanceSqrtXZ(m_Owner.Pos, _hero.Pos); |
| | | if (_compareDis < m_KeepBornDistSqrt) |
| | | { |
| | | // 标识是否执行攻击逻辑 |
| | | bool _doAttack = false; |
| | | // 自己是主动怪 |
| | | if (m_Owner.NpcConfig.AtkType == 0) |
| | | { |
| | | _doAttack = true; |
| | | } |
| | | else |
| | | { |
| | | if (m_Owner.heroAttacked) |
| | | { |
| | | _doAttack = true; |
| | | } |
| | | } |
| | | |
| | | if (_doAttack) |
| | | { |
| | | m_AIStatus = E_AIStatus.Attack; |
| | | } |
| | | else |
| | | { |
| | | // 主角不存在或者死亡了 |
| | | // 在出生点附近 |
| | | _compareDis = MathUtility.DistanceSqrtXZ(BornPos, m_Owner.Pos); |
| | | if (_compareDis < 4) |
| | | { |
| | | m_AIStatus = E_AIStatus.Patrol; |
| | | } |
| | | // 巡逻 |
| | | // 不在出生点附近 |
| | | else |
| | | { |
| | | // 回到出生点 |
| | | m_AIStatus = E_AIStatus.MoveToBornPos; |
| | | atkStep = 0; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | m_AIStatus = E_AIStatus.Patrol; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |