private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { return; } NpcAiStateInfo info = npc.GetAiStateInfo(); info.Time += deltaTime; float rps = npc.GetActualProperty().Rps; if (rps > 0.001f && info.Time > 1000 / rps) { info.Time = 0; CheckImpact(npc); bool toIdle = false; //修改确定攻击目标的逻辑 CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target); if (null != target && npc.SpatialSystem.CanShoot(npc.SpaceObject, target.GetMovementStateInfo().GetPosition3D())) { ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float powDist = Geometry.DistanceSquare(srcPos, targetPos); //npc与目标距离 float dist = (float)npc.GetActualProperty().AttackRange; //攻击范围 //float distView = (float)npc.ViewRange; //视野范围 if (powDist < dist * dist) { //在攻击范围内 float dir = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().IsMoving = false; npc.GetMovementStateInfo().SetFaceDir(dir); npc.GetMovementStateInfo().SetMoveDir(dir); if (npc.CanShoot()) { aiCmdDispatcher.NpcFace(npc, this); } } else { //如果原目标已经超出了攻击范围,防御塔应当重新进行探测,而不是跳转到Idle状态 CharacterInfo newTarget = GetNewTarget(npc); if (null != newTarget) { npc.GetMovementStateInfo().IsMoving = false; info.Time = 0; info.Target = newTarget.GetId(); } else { toIdle = true; } } } else { //如果原目标死亡或不可攻击,防御塔应当首先重新进行探测,而不是跳转到Idle状态 //若找到新目标,则进行攻击 //若没有心目标。则进入Idle状态 CharacterInfo newTarget = GetNewTarget(npc); if (null != newTarget) { npc.GetMovementStateInfo().IsMoving = false; info.Time = 0; info.Target = newTarget.GetId(); } else { toIdle = true; } } if (toIdle) { info.Time = 0; npc.GetMovementStateInfo().IsMoving = false; ChangeToState(npc, (int)AiStateId.Idle); } } }
private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { return; } NpcAiStateInfo info = npc.GetAiStateInfo(); info.Time += deltaTime; float rps = npc.GetActualProperty().Rps; if (rps > 0.001f && info.Time > 1000 / rps) { info.Time = 0; AiData_PveNpc_General data = GetAiData(npc); if (null != data) { bool goHome = false; CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target); if (null != target) { float dist = (float)npc.GetActualProperty().AttackRange; float distGoHome = (float)npc.GohomeRange; ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float powDist = Geometry.DistanceSquare(srcPos, targetPos); float powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos); if (powDist < dist * dist) { float dir = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetFaceDir(dir); npc.GetMovementStateInfo().SetMoveDir(dir); if (npc.CanShoot() && !npc.GetSkillStateInfo().IsSkillActivated()) { Data_NpcConfig npcConfig = NpcConfigProvider.Instance.GetNpcConfigById(npc.GetLinkId()); if (null == npcConfig) { return; } if (npcConfig.m_SkillList.Count >= 1) { ServerNpcSkill(npc, npcConfig.m_SkillList[0], target, targetPos, dir); } } } else if (powDistToHome < distGoHome * distGoHome) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; data.FoundPath.Clear(); ChangeToState(npc, (int)AiStateId.Pursuit); } else { goHome = true; } } else { goHome = true; } if (goHome) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; ChangeToState(npc, (int)AiStateId.GoHome); } } } }
private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { return; } NpcAiStateInfo info = npc.GetAiStateInfo(); info.Time += deltaTime; if (info.Time > 100) { AiData_PvpNpc_General data = GetAiData(npc); if (null != data) { data.Time += info.Time; data.ThinkingTime += info.Time; //ai配置参数 小兵思考时间 long thinkingTime = int.Parse(info.AiParam[2]); //大于思考时间 重新选择新的目标 if (data.ThinkingTime > thinkingTime) { CharacterInfo interestestTarget = GetInterestestTargetHelper(npc, CharacterRelation.RELATION_ENEMY); if (null != interestestTarget && info.Target != interestestTarget.GetId()) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; data.Time = 0; data.ThinkingTime = 0; info.Target = interestestTarget.GetId(); return; } } info.Time = 0; bool changeTarget = false; CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target); if (null != target) { float dist = (float)(npc.GetActualProperty().AttackRange *npc.AttackRangeCoefficient); float distGoHome = (float)npc.GohomeRange; ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float powDist = Geometry.DistanceSquare(srcPos, targetPos); float powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos); if (powDist < dist * dist && npc.SpatialSystem.CanShoot(npc.SpaceObject, target.GetMovementStateInfo().GetPosition3D())) { float rps = npc.GetActualProperty().Rps; if (rps > 0.001f && data.Time > 1000 / rps) { data.Time = 0; float dir = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetFaceDir(dir); npc.GetMovementStateInfo().SetMoveDir(dir); if (npc.CanShoot()) { aiCmdDispatcher.NpcFace(npc, this); } } } else if (powDistToHome < distGoHome * distGoHome) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; data.FoundPath.Clear(); ChangeToState(npc, (int)AiStateId.Pursuit); } else { changeTarget = true; } } else { changeTarget = true; } if (changeTarget) { data.FoundPath.Clear(); target = GetInterestestTargetHelper(npc, CharacterRelation.RELATION_ENEMY); if (null != target) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; info.Target = target.GetId(); ChangeToState(npc, (int)AiStateId.Pursuit); } else { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; info.HomePos = GetHomePosition(npc, data); ChangeToState(npc, (int)AiStateId.GoHome); } } } else { info.Time = 0; } } }