private AiData_Npc_CommonMelee GetAiData(NpcInfo npc) { AiData_Npc_CommonMelee data = npc.GetAiStateInfo().AiDatas.GetData <AiData_Npc_CommonMelee>(); if (null == data) { data = new AiData_Npc_CommonMelee(); npc.GetAiStateInfo().AiDatas.AddData(data); } return(data); }
private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (!CanAiControl(npc)) { npc.GetMovementStateInfo().IsMoving = false; return; } NpcAiStateInfo info = npc.GetAiStateInfo(); AiData_Npc_CommonMelee data = GetAiData(npc); if (null != data) { CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target); if (null != target) { float dist = (float)npc.GetActualProperty().AttackRange; float distGoHome = (float)npc.GohomeRange; Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float powDist = Geometry.DistanceSquare(srcPos, targetPos); float powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos); // 遇敌是播放特效, 逗留两秒。 if (data.WaitTime <= npc.MeetEnemyStayTime) { if (!data.HasMeetEnemy) { NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack); data.HasMeetEnemy = true; } TrySeeTarget(npc, target); data.WaitTime += deltaTime; return; } // 走向目标1.5秒 if (data.MeetEnemyWalkTime < npc.MeetEnemyWalkTime) { data.MeetEnemyWalkTime += deltaTime; NotifyNpcWalk(npc); info.Time += deltaTime; if (info.Time > m_IntervalTime) { info.Time = 0; if (!npc.UnityPathFinding) { AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } else { if (!npc.PathFindingFinished) { GfxSystem.NpcCommonMeleePathToTarget(npc, targetPos); ChangeToState(npc, (int)AiStateId.PathFinding); } else { npc.PathFindingFinished = false; AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } } } return; } // 大于攻击距离 跑向目标 if (powDist > m_AttackRange * m_AttackRange && 0 == data.CurAiAction) { npc.IsTaunt = false; NotifyNpcRun(npc); info.Time += deltaTime; if (info.Time > m_IntervalTime) { info.Time = 0; if (!npc.UnityPathFinding) { AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } else { if (!npc.PathFindingFinished) { GfxSystem.NpcCommonMeleePathToTarget(npc, targetPos); ChangeToState(npc, (int)AiStateId.PathFinding); } else { npc.PathFindingFinished = false; AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } } } } else { //小于攻击距离 if (data.CurAiAction == (int)AiAction.NONE) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.CurAiAction = (int)GetNextAction(); } switch (data.CurAiAction) { case (int)AiAction.SKILL: if (0 >= data.SkillToCast) { data.SkillToCast = GetCanCastSkillId(npc, (float)Math.Sqrt(powDist)); } if (0 >= data.SkillToCast || !AiLogicUtility.CanCastSkill(npc, data.SkillToCast, target)) { info.Time += deltaTime; if (info.Time > m_IntervalTime) { info.Time = 0; NotifyNpcRun(npc); if (!npc.UnityPathFinding) { AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } else { if (!npc.PathFindingFinished) { GfxSystem.NpcCommonMeleePathToTarget(npc, targetPos); ChangeToState(npc, (int)AiStateId.PathFinding); } else { npc.PathFindingFinished = false; AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } } } } else { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); if (TryCastSkill(npc, data.SkillToCast, target)) { data.CurAiAction = 0; data.SkillToCast = -1; } } break; case (int)AiAction.STAND: data.ChaseStandTime += deltaTime; TrySeeTarget(npc, target); if (data.ChaseStandTime > m_ChaseWalkMaxTime) { data.ChaseStandTime = 0; data.CurAiAction = 0; } break; case (int)AiAction.TAUNT: npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); npc.IsTaunt = true; data.TauntTime += deltaTime; TrySeeTarget(npc, target); if (data.TauntTime > m_TauntTime) { npc.IsTaunt = false; data.TauntTime = 0; data.CurAiAction = 0; } break; case (int)AiAction.WALK: data.ChaseWalkTime += deltaTime; info.Time += deltaTime; if (info.Time > m_IntervalTime) { info.Time = 0; NotifyNpcWalk(npc); if (!npc.UnityPathFinding) { AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } else { if (!npc.PathFindingFinished) { GfxSystem.NpcCommonMeleePathToTarget(npc, targetPos); ChangeToState(npc, (int)AiStateId.PathFinding); } else { npc.PathFindingFinished = false; AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } } } if (data.ChaseWalkTime > m_ChaseStandMaxTime) { data.ChaseWalkTime = 0; data.CurAiAction = 0; } break; } } } else { NotifyNpcTargetChange(npc); npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; ChangeToState(npc, (int)AiStateId.Idle); } } }