private bool GohomeHandler(EntityInfo npc, AiStateInfo info, long deltaTime) { info.Time += deltaTime; if (info.Time > 100) { info.Time = 0; } else { return(true); } ScriptRuntime.Vector3 targetPos = info.HomePos; ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float distSqr = Geometry.DistanceSquare(srcPos, info.HomePos); if (distSqr <= 1) { npc.GetMovementStateInfo().IsMoving = false; AiCommand.AiStopPursue(npc); info.ChangeToState((int)PredefinedAiStateId.Idle); return(false); } else { npc.GetMovementStateInfo().IsMoving = true; npc.GetMovementStateInfo().TargetPosition = targetPos; AiCommand.AiPursue(npc, targetPos); } return(true); }
private bool GohomeHandler(EntityInfo entity, AiStateInfo info, long deltaTime) { info.Time += deltaTime; if (info.Time > c_IntervalTime) { info.Time = 0; EntityInfo leader = AiLogicUtility.GetLivingCharacterInfoHelper(entity, info.LeaderId); if (null != leader) { float minDist = entity.GetRadius() + leader.GetRadius(); ScriptRuntime.Vector3 targetPos = GetHomePos(entity.GetMovementStateInfo().FormationIndex, leader); ScriptRuntime.Vector3 srcPos = entity.GetMovementStateInfo().GetPosition3D(); float powDistToHome = Geometry.DistanceSquare(srcPos, targetPos); if (powDistToHome <= (minDist + 1) * (minDist + 1)) { AiCommand.AiStopPursue(entity); info.ChangeToState((int)PredefinedAiStateId.Idle); return(false); } else { AiCommand.AiPursue(entity, targetPos); } } else { AiCommand.AiStopPursue(entity); info.ChangeToState((int)PredefinedAiStateId.Idle); return(false); } } return(true); }
public bool ExecCommand(StoryInstance instance, StoryMessageHandler handler, StoryValueParams _params, long delta) { var args = _params.Values; if (!m_ParamReaded) { m_ObjId = args[0]; m_SkillInfo = args[1].ObjectVal as SkillInfo; } if (!m_SkillCasted) { EntityInfo npc = PluginFramework.Instance.GetEntityById(m_ObjId); if (null != npc && !npc.IsUnderControl()) { int targetId = npc.GetAiStateInfo().Target; EntityInfo target = PluginFramework.Instance.GetEntityById(targetId); if (null != target && !target.IsDead() && Geometry.DistanceSquare(npc.GetMovementStateInfo().GetPosition3D(), target.GetMovementStateInfo().GetPosition3D()) <= m_SkillInfo.Distance * m_SkillInfo.Distance) { ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); float dir = Geometry.GetYRadian(srcPos, targetPos); float curDir = npc.GetMovementStateInfo().GetFaceDir(); if (Mathf.Abs(dir - curDir) > 0.157f) { npc.GetMovementStateInfo().SetWantedFaceDir(dir); } else { m_SkillCasted = true; AiCommand.AiStopPursue(npc); AiCommand.AiSkill(npc, m_SkillInfo.SkillId); } return(true); } else if (!m_SkillInfo.ConfigData.skillData.needTarget) { m_SkillCasted = true; AiCommand.AiStopPursue(npc); AiCommand.AiSkill(npc, m_SkillInfo.SkillId); } } } else { EntityInfo npc = PluginFramework.Instance.GetEntityById(m_ObjId); if (null != npc) { AiStateInfo info = npc.GetAiStateInfo(); if (npc.GetSkillStateInfo().IsSkillActivated()) { return(true); } else { return(false); } } } return(false); }
public static bool GetResult(out ScriptRuntime.Vector3 res) { object obj; bool ret = GetResult(out obj); res = (ScriptRuntime.Vector3)obj; return(ret); }
private void SelectTargetPos(EntityInfo npc) { ScriptRuntime.Vector3 pos = npc.GetMovementStateInfo().GetPosition3D(); float dx = Helper.Random.Next(m_Radius) - m_Radius / 2; float dz = Helper.Random.Next(m_Radius) - m_Radius / 2; pos.X += dx; pos.Z += dz; npc.GetMovementStateInfo().TargetPosition = AiCommand.AiGetValidPosition(npc, pos, m_Radius); }
public static ScriptRuntime.Vector3 GetCenter(ScriptRuntime.Vector3 fvPos1, ScriptRuntime.Vector3 fvPos2) { ScriptRuntime.Vector3 fvRet = new ScriptRuntime.Vector3(); fvRet.X = (fvPos1.X + fvPos2.X) / 2.0f; fvRet.Y = (fvPos1.Y + fvPos2.Y) / 2.0f; fvRet.Z = (fvPos1.Z + fvPos2.Z) / 2.0f; return fvRet; }
public static ScriptRuntime.Vector3 AiGetValidPosition(EntityInfo npc, ScriptRuntime.Vector3 target, float maxDistance) { NavMeshHit navMeshHit; NavMesh.SamplePosition(new UnityEngine.Vector3(target.X, target.Y, target.Z), out navMeshHit, maxDistance, NavMesh.AllAreas); if (!float.IsInfinity(navMeshHit.position.x) && !float.IsInfinity(navMeshHit.position.y) && !float.IsInfinity(navMeshHit.position.z)) { return(new ScriptRuntime.Vector3(navMeshHit.position.x, navMeshHit.position.y, navMeshHit.position.z)); } return(target); }
static public int constructor(IntPtr l) { try { int argc = LuaDLL.lua_gettop(l); ScriptRuntime.Vector3 o; if (argc == 4) { System.Single a1; checkType(l, 2, out a1); System.Single a2; checkType(l, 3, out a2); System.Single a3; checkType(l, 4, out a3); o = new ScriptRuntime.Vector3(a1, a2, a3); pushValue(l, true); pushValue(l, o); return(2); } else if (argc == 2) { System.Single a1; checkType(l, 2, out a1); o = new ScriptRuntime.Vector3(a1); pushValue(l, true); pushValue(l, o); return(2); } else if (argc == 3) { ScriptRuntime.Vector2 a1; checkValueType(l, 2, out a1); System.Single a2; checkType(l, 3, out a2); o = new ScriptRuntime.Vector3(a1, a2); pushValue(l, true); pushValue(l, o); return(2); } else if (argc <= 1) { o = new ScriptRuntime.Vector3(); pushValue(l, true); pushObject(l, o); return(2); } return(error(l, "New object failed.")); } catch (Exception e) { return(error(l, e)); } }
private bool RandMoveHandler(EntityInfo npc, AiStateInfo info, long deltaTime) { info.Time += deltaTime; m_PursueInterval += deltaTime; if (info.Time > m_Time) { info.Time = 0; npc.GetMovementStateInfo().IsMoving = false; AiCommand.AiStopPursue(npc); info.ChangeToState((int)PredefinedAiStateId.Idle); EntityInfo target = PluginFramework.Instance.GetEntityById(info.Target); if (null != target) { float dir = Geometry.GetYRadian(npc.GetMovementStateInfo().GetPosition3D(), target.GetMovementStateInfo().GetPosition3D()); npc.GetMovementStateInfo().SetFaceDir(dir); } return(false); } if (m_PursueInterval < 100) { return(true); } else { m_PursueInterval = 0; } ScriptRuntime.Vector3 targetPos = npc.GetMovementStateInfo().TargetPosition; ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float distSqr = Geometry.DistanceSquare(srcPos, targetPos); if (distSqr <= 1) { if (npc.GetMovementStateInfo().IsMoving) { npc.GetMovementStateInfo().IsMoving = false; AiCommand.AiStopPursue(npc); info.ChangeToState((int)PredefinedAiStateId.Idle); } } else { npc.GetMovementStateInfo().IsMoving = true; AiCommand.AiPursue(npc, targetPos); } return(true); }
public bool ExecCommand(StoryInstance instance, StoryValueParams _params, long delta) { ArrayList args = _params.Values; if (!m_KeepAwayStarted) { m_KeepAwayStarted = true; m_ObjId = (int)args[0]; m_SkillInfo = args[1] as SkillInfo; m_Ratio = (float)System.Convert.ChangeType(args[2], typeof(float)); } EntityInfo npc = PluginFramework.Instance.GetEntityById(m_ObjId); if (null != npc && !npc.IsUnderControl()) { AiStateInfo info = npc.GetAiStateInfo(); EntityInfo target = PluginFramework.Instance.GetEntityById(info.Target); if (null != target && null != m_SkillInfo) { info.Time += delta; if (info.Time > 100) { info.Time = 0; } else { return(true); } ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); float distSqr = Geometry.DistanceSquare(srcPos, targetPos); ScriptRuntime.Vector3 dir = srcPos - targetPos; dir.Normalize(); targetPos = targetPos + dir * m_Ratio * m_SkillInfo.Distance; if (distSqr < m_Ratio * m_Ratio * m_SkillInfo.Distance * m_SkillInfo.Distance) { AiCommand.AiPursue(npc, targetPos); return(true); } } } return(false); }
public static void AiPursue(EntityInfo npc, ScriptRuntime.Vector3 target) { MovementStateInfo msi = npc.GetMovementStateInfo(); msi.IsMoving = true; msi.TargetPosition = target; float dir = Geometry.GetYRadian(msi.GetPosition3D(), target); msi.SetFaceDir(dir); Msg_RC_NpcMove npcMoveBuilder = DataSyncUtility.BuildNpcMoveMessage(npc); if (null != npcMoveBuilder) { Scene scene = npc.SceneContext.CustomData as Scene; if (null != scene) { scene.NotifyAllUser(RoomMessageDefine.Msg_RC_NpcMove, npcMoveBuilder); } } }
public bool ExecCommand(StoryInstance instance, StoryMessageHandler handler, StoryValueParams _params, long delta) { ArrayList args = _params.Values; if (!m_ChaseStarted) { m_ChaseStarted = true; m_ObjId = (int)args[0]; m_SkillInfo = args[1] as SkillInfo; } EntityInfo npc = PluginFramework.Instance.GetEntityById(m_ObjId); if (null != npc && !npc.IsUnderControl()) { AiStateInfo info = npc.GetAiStateInfo(); EntityInfo target = PluginFramework.Instance.GetEntityById(info.Target); if (null != target && null != m_SkillInfo) { info.Time += delta; if (info.Time > 100) { info.Time = 0; } else { return(true); } ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); float distSqr = Geometry.DistanceSquare(srcPos, targetPos); if (distSqr > m_SkillInfo.Distance * m_SkillInfo.Distance) { AiCommand.AiPursue(npc, targetPos); return(true); } } } return(false); }
private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { return; } NpcAiStateInfo info = npc.GetAiStateInfo(); info.Time += deltaTime; if (info.Time > m_IntervalTime) { AiData_PveNpc_General data = GetAiData(npc); if (null != data) { data.Time += info.Time; info.Time = 0; bool goHome = false; CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target); //CharacterInfo target = AiLogicUtility.GetInterestestTargetHelper(npc, CharacterRelation.RELATION_ENEMY, AiTargetType.USER); 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 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)); NotifyNpcFace(npc, dir); //npc.GetMovementStateInfo().SetFaceDir(dir); npc.GetMovementStateInfo().SetMoveDir(dir); if (null != OnNpcSkill) { OnNpcSkill(npc, 10001, target); } } } else if (true) { 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); } } else { info.Time = 0; } } }
private void PathToTarget(UserInfo user, AiPathData data, Vector3 pathTargetPos, long deltaTime) { UserAiStateInfo info = user.GetAiStateInfo(); if (null != data) { data.UpdateTime += deltaTime; ScriptRuntime.Vector3 srcPos = user.GetMovementStateInfo().GetPosition3D(); float dir = user.GetMovementStateInfo().GetMoveDir(); bool findObstacle = false; bool havePathPoint = data.HavePathPoint; if (havePathPoint)//沿路点列表移动的逻辑 { Vector3 targetPos = data.CurPathPoint; if (!data.IsReached(srcPos))//向指定路点移动(避让移动过程) { user.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); if (!Geometry.IsSameDouble(angle, user.GetMovementStateInfo().GetMoveDir())) { user.GetMovementStateInfo().SetFaceDir(angle); user.GetMovementStateInfo().SetMoveDir(angle); user.GetMovementStateInfo().IsMoving = true; NotifyUserMove(user); } } else//改变路点或结束沿路点移动 { data.UseNextPathPoint(); if (data.HavePathPoint) { targetPos = data.CurPathPoint; user.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); user.GetMovementStateInfo().SetFaceDir(angle); user.GetMovementStateInfo().SetMoveDir(angle); user.GetMovementStateInfo().IsMoving = true; NotifyUserMove(user); } else { data.Clear(); } } } if (!havePathPoint || findObstacle)//获得路点过程(寻路) { data.Clear(); Vector3 targetPos = pathTargetPos; if (Geometry.DistanceSquare(srcPos, targetPos) > 400) { targetPos = user.SpatialSystem.CalcNearstReachablePoint(srcPos, targetPos, 20); } bool canGo = true; /* * if (!user.SpatialSystem.GetCellMapView(user.AvoidanceRadius).CanPass(targetPos)) { * if (!AiLogicUtility.GetWalkablePosition(user.SpatialSystem.GetCellMapView(user.AvoidanceRadius), targetPos, srcPos, ref targetPos)) * canGo = false; * }*/ if (canGo) { List <Vector3> posList = null; if (user.SpatialSystem.CanPass(user.SpaceObject, targetPos)) { posList = new List <Vector3>(); posList.Add(srcPos); posList.Add(targetPos); } else { long stTime = TimeUtility.GetElapsedTimeUs(); posList = user.SpatialSystem.FindPath(srcPos, targetPos, user.AvoidanceRadius); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 1000) { LogSystem.Warn("pvp FindPath consume {0} us,user:{1} from:{2} to:{3} radius:{4} pos:{5}", calcTime, user.GetId(), srcPos.ToString(), targetPos.ToString(), user.AvoidanceRadius, user.GetMovementStateInfo().GetPosition3D().ToString()); } } if (posList.Count >= 2) { data.SetPathPoints(posList[0], posList, 1); targetPos = data.CurPathPoint; user.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); user.GetMovementStateInfo().SetFaceDir(angle); user.GetMovementStateInfo().SetMoveDir(angle); user.GetMovementStateInfo().IsMoving = true; NotifyUserMove(user); } else { user.GetMovementStateInfo().IsMoving = false; NotifyUserMove(user); } } else { user.GetMovementStateInfo().IsMoving = false; NotifyUserMove(user); } } } }
private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { return; } NpcAiStateInfo info = npc.GetAiStateInfo(); //ai配置参数 long maxPursuitTime = int.Parse(info.AiParam[0]); long minPursuitTime = int.Parse(info.AiParam[1]); // bool goHome = false; info.Time += deltaTime; CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target); AiData_PvpNpc_General data = GetAiData(npc); if (null != target && info.Time <= maxPursuitTime && null != data) { if (info.Time >= minPursuitTime) { //超过最小追击时间,尝试换攻击目标 CharacterInfo interestestTarget = GetInterestestTargetHelper(npc, CharacterRelation.RELATION_ENEMY); if (null != interestestTarget && interestestTarget != target) { info.Time = 0; info.Target = interestestTarget.GetId(); data.FoundPath.Clear(); target = interestestTarget; } } float dist = (float)(npc.GetActualProperty().AttackRange *npc.AttackRangeCoefficient); float distGoHome = (float)npc.GohomeRange; 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())) { npc.GetMovementStateInfo().IsMoving = false; info.Time = 0; ChangeToState(npc, (int)AiStateId.Combat); NotifyNpcMove(npc); } else if (powDistToHome < distGoHome * distGoHome) { if (AiLogicUtility.GetWalkablePosition(target, npc, ref targetPos)) { PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, deltaTime); } else { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); } } else { goHome = true; } } else { goHome = true; } if (goHome) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; info.HomePos = GetHomePosition(npc, data); data.FoundPath.Clear(); ChangeToState(npc, (int)AiStateId.GoHome); } }
private bool CombatHandler(EntityInfo npc, AiStateInfo info, long deltaTime) { if (npc.GetSkillStateInfo().IsSkillActivated()) { return(true); } EntityInfo leader = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.LeaderId); ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); ScriptRuntime.Vector3 homePos = ScriptRuntime.Vector3.Zero; if (null != leader) { homePos = GetHomePos(npc.GetMovementStateInfo().FormationIndex, leader); } float distSqrToHome = Geometry.DistanceSquare(srcPos, homePos); if (distSqrToHome > npc.GohomeRange * npc.GohomeRange) { AiCommand.AiStopPursue(npc); info.ChangeToState((int)AiStateId.Gohome); return(true); } /// EntityInfo attackTarget = null; SkillStateInfo currSkInfo = npc.GetSkillStateInfo(); ///找到可以使用的技能 SkillInfo skInfo = AiLogicUtility.NpcFindCanUseSkill(npc); AiCommand.AiSelectSkill(npc, skInfo); if (skInfo == null) { //没有可以使用的技能就切换到Idle状态 info.ChangeToState((int)PredefinedAiStateId.Idle); return(false); } CharacterRelation relation = (skInfo.TargetType == SkillTargetType.Friend || skInfo.TargetType == SkillTargetType.RandFriend) ? CharacterRelation.RELATION_FRIEND : CharacterRelation.RELATION_ENEMY; attackTarget = AiLogicUtility.GetNearstTargetHelper( npc, skInfo.Distance, relation); if (attackTarget != null && null != skInfo) //攻击范围内找到可攻击目标 { info.Target = attackTarget.GetId(); AiCommand.AiStopPursue(npc); AiCommand.AiSkill(npc, skInfo.SkillId); //攻击目标 return(true); } attackTarget = AiLogicUtility.GetNearstTargetHelper( npc, npc.ViewRange, relation); if (attackTarget != null) //视野范围内找到可攻击目标 { AiCommand.AiPursue(npc, attackTarget.GetMovementStateInfo().GetPosition3D()); // 追赶目标 return(true); } currSkInfo.SetCurSkillInfo(0); AiCommand.AiStopPursue(npc); info.ChangeToState((int)AiStateId.Gohome); return(true); }
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; } } }
private void PathToTarget(NpcInfo npc, AiPathData data, Vector3 pathTargetPos, long deltaTime) { NpcAiStateInfo info = npc.GetAiStateInfo(); if (null != data) { data.UpdateTime += deltaTime; ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float dir = npc.GetMovementStateInfo().GetMoveDir(); bool findObstacle = false; bool havePathPoint = data.HavePathPoint; if (havePathPoint)//沿路点列表移动的逻辑 { Vector3 targetPos = data.CurPathPoint; if (!data.IsReached(srcPos))//向指定路点移动(避让移动过程) { float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); Vector3 prefVelocity = (float)npc.GetActualProperty().MoveSpeed *new Vector3((float)Math.Sin(angle), 0, (float)Math.Cos(angle)); Vector3 v = new Vector3(targetPos.X - srcPos.X, 0, targetPos.Z - srcPos.Z); v.Normalize(); Vector3 velocity = npc.SpaceObject.GetVelocity(); float speedSquare = (float)npc.GetActualProperty().MoveSpeed *(float)npc.GetActualProperty().MoveSpeed; long stTime = TimeUtility.GetElapsedTimeUs(); Vector3 newVelocity = npc.SpatialSystem.ComputeVelocity(npc.SpaceObject, v, (float)deltaTime / 1000, (float)npc.GetActualProperty().MoveSpeed, (float)npc.GetRadius(), data.IsUsingAvoidanceVelocity); findObstacle = !AiLogicUtility.IsWalkable(npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius), srcPos, newVelocity); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 10000) { LogSystem.Warn("*** pvp ComputeVelocity consume {0} us,npc:{1} velocity:{2} newVelocity:{3} deltaTime:{4} speed:{5} pos:{6}", calcTime, npc.GetId(), velocity.ToString(), newVelocity.ToString(), deltaTime, npc.GetActualProperty().MoveSpeed, npc.GetMovementStateInfo().GetPosition3D().ToString()); for (LinkedListNode <UserInfo> node = npc.UserManager.Users.FirstValue; null != node; node = node.Next) { UserInfo userInfo = node.Value; if (null != userInfo) { LogSystem.Warn("===>User:{0} Pos:{1}", userInfo.GetId(), userInfo.GetMovementStateInfo().GetPosition3D().ToString()); } } for (LinkedListNode <NpcInfo> node = npc.NpcManager.Npcs.FirstValue; null != node; node = node.Next) { NpcInfo npcInfo = node.Value; if (null != npcInfo) { LogSystem.Warn("===>Npc:{0} Pos:{1}", npcInfo.GetId(), npcInfo.GetMovementStateInfo().GetPosition3D().ToString()); } } } if (findObstacle)//当前移动方向遇到阻挡,停止移动,触发寻路 { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else if (data.UpdateTime > 1000)//避让速度改变每秒一次(表现上更像人类一些) { data.UpdateTime = 0; float newV = newVelocity.Length(); npc.VelocityCoefficient = newV / npc.GetActualProperty().MoveSpeed; float newAngle = Geometry.GetYAngle(new Vector2(0, 0), new Vector2(newVelocity.X, newVelocity.Z)); npc.GetMovementStateInfo().SetFaceDir(newAngle); npc.GetMovementStateInfo().SetMoveDir(newAngle); newVelocity.Normalize(); npc.GetMovementStateInfo().TargetPosition = srcPos + newVelocity * Geometry.Distance(srcPos, targetPos); npc.GetMovementStateInfo().IsMoving = true; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = true; } else if (Geometry.DistanceSquare(velocity, newVelocity) >= 9.0f) //没有到速度改变周期,但避让方向需要大幅调整 { if (Geometry.Dot(newVelocity, prefVelocity) > 0) //如果是调整为与目标方向一致,则进行调整 { float newAngle = Geometry.GetYAngle(new Vector2(0, 0), new Vector2(newVelocity.X, newVelocity.Z)); npc.GetMovementStateInfo().SetFaceDir(newAngle); npc.GetMovementStateInfo().SetMoveDir(newAngle); newVelocity.Normalize(); npc.GetMovementStateInfo().TargetPosition = srcPos + newVelocity * Geometry.Distance(srcPos, targetPos); npc.GetMovementStateInfo().IsMoving = true; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = true; } else//如果调整为远离目标方向,则停止 { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } else if (!npc.GetMovementStateInfo().IsMoving&& velocity.LengthSquared() > speedSquare * 0.25f)//正常移动过程,继续移动 { velocity.Normalize(); npc.GetMovementStateInfo().TargetPosition = srcPos + velocity * Geometry.Distance(srcPos, targetPos); npc.GetMovementStateInfo().IsMoving = true; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } else//改变路点或结束沿路点移动 { data.UseNextPathPoint(); if (data.HavePathPoint) { targetPos = data.CurPathPoint; npc.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetFaceDir(angle); npc.GetMovementStateInfo().SetMoveDir(angle); npc.GetMovementStateInfo().IsMoving = true; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else { data.Clear(); } } } if (!havePathPoint || findObstacle)//获得路点过程(寻路) { data.Clear(); Vector3 targetPos = pathTargetPos; bool canGo = true; if (!npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius).CanPass(targetPos)) { if (!AiLogicUtility.GetWalkablePosition(npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius), targetPos, srcPos, ref targetPos)) { canGo = false; } } if (canGo) { List <Vector3> posList = null; bool canPass = npc.SpatialSystem.CanPass(npc.SpaceObject, targetPos); if (canPass) { posList = new List <Vector3>(); posList.Add(srcPos); posList.Add(targetPos); } else { long stTime = TimeUtility.GetElapsedTimeUs(); posList = npc.SpatialSystem.FindPath(srcPos, targetPos, npc.AvoidanceRadius); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 10000) { LogSystem.Warn("*** pvp FindPath consume {0} us,npc:{1} from:{2} to:{3} radius:{4} pos:{5}", calcTime, npc.GetId(), srcPos.ToString(), targetPos.ToString(), npc.AvoidanceRadius, npc.GetMovementStateInfo().GetPosition3D().ToString()); } } if (posList.Count >= 2) { data.SetPathPoints(posList[0], posList, 1); targetPos = data.CurPathPoint; npc.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetFaceDir(angle); npc.GetMovementStateInfo().SetMoveDir(angle); npc.GetMovementStateInfo().IsMoving = true; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } else { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } } }
internal static void Execute(object msg, User user) { Msg_CR_UserMoveToPos move_msg = msg as Msg_CR_UserMoveToPos; if (move_msg == null) return; EntityInfo charactor = user.Info; if (charactor == null) { LogSys.Log(LOG_TYPE.DEBUG, "charactor {0}({1},{2},{3}) not exist", user.RoleId, user.GetKey(), user.Guid, user.Name); return; } /// if (charactor.GetAIEnable()) { float tx, tz; ProtoHelper.DecodePosition2D(move_msg.target_pos, out tx, out tz); ScriptRuntime.Vector3 pos = new ScriptRuntime.Vector3(tx, 0, tz); MovementStateInfo msi = charactor.GetMovementStateInfo(); msi.IsMoving = true; msi.TargetPosition = pos; float dir = Geometry.GetYRadian(msi.GetPosition3D(), pos); msi.SetFaceDir(dir); msi.SetMoveDir(dir); Msg_RC_NpcMove npcMoveBuilder = DataSyncUtility.BuildNpcMoveMessage(charactor); if (null != npcMoveBuilder) { Scene scene = user.OwnRoom.ActiveScene; if (null != scene) { scene.NotifyAllUser(RoomMessageDefine.Msg_RC_NpcMove, npcMoveBuilder); } } } }
private bool CombatHandler(EntityInfo npc, AiStateInfo info, long deltaTime) { info.Time += deltaTime; if (info.Time > 100) { info.Time = 0; } else { return(true); } if (npc.GetSkillStateInfo().IsSkillActivated()) { return(true); } ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float distSqrToHome = Geometry.DistanceSquare(srcPos, info.HomePos); if (distSqrToHome > npc.GohomeRange * npc.GohomeRange) { AiCommand.AiStopPursue(npc); info.ChangeToState((int)AiStateId.Gohome); return(true); } /// EntityInfo attackTarget = null; SkillStateInfo currSkInfo = npc.GetSkillStateInfo(); ///找到可以使用的技能 SkillInfo skInfo = AiLogicUtility.NpcFindCanUseSkill(npc); AiCommand.AiSelectSkill(npc, skInfo); if (skInfo == null) { AiCommand.AiStopPursue(npc); info.ChangeToState((int)PredefinedAiStateId.Idle); return(false); } CharacterRelation relation = skInfo.ConfigData.targetType == (int)SkillTargetType.Friend ? CharacterRelation.RELATION_FRIEND : CharacterRelation.RELATION_ENEMY; attackTarget = AiLogicUtility.GetNearstTargetHelper( npc, skInfo.Distance, relation); if (attackTarget != null && null != skInfo) //攻击范围内找到可攻击目标 { info.Target = attackTarget.GetId(); ScriptRuntime.Vector3 targetPos = attackTarget.GetMovementStateInfo().GetPosition3D(); float dir = Geometry.GetYRadian(srcPos, targetPos); float curDir = npc.GetMovementStateInfo().GetFaceDir(); if (Mathf.Abs(dir - curDir) > 0.157f) { npc.GetMovementStateInfo().SetWantedFaceDir(dir); } else { AiCommand.AiStopPursue(npc); AiCommand.AiSkill(npc, skInfo.SkillId); //攻击目标 } return(true); } attackTarget = AiLogicUtility.GetNearstTargetHelper( npc, npc.ViewRange, relation); if (attackTarget != null) //视野范围内找到可攻击目标 { AiCommand.AiPursue(npc, attackTarget.GetMovementStateInfo().GetPosition3D()); // 追赶目标 return(true); } currSkInfo.SetCurSkillInfo(0); AiCommand.AiStopPursue(npc); return(true); }
public static void AiPursue(EntityInfo npc, ScriptRuntime.Vector3 target) { EntityViewModel npcView = EntityViewModelManager.Instance.GetEntityViewById(npc.GetId()); npcView.MoveTo(target.X, target.Y, target.Z); }
public void Reset() { m_StateStack.Clear(); m_AiDatas.Clear(); if (null != m_AiStoryInstanceInfo) { m_AiStoryInstanceInfo.Recycle(); m_AiStoryInstanceInfo = null; } m_IsInited = false; m_AiLogic = 0; m_AiParam = new string[c_MaxAiParamNum]; m_AiStoryInstanceInfo = null; m_Time = 0; m_IsInited = false; m_leaderID = 0; m_HomePos = Vector3.Zero; m_Target = 0; m_HateTarget = 0; m_IsExternalTarget = false; m_LastChangeTargetTime = 0; }
private void PursuitHandler(UserInfo user, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (user.IsDead()) { return; } UserAiStateInfo info = user.GetAiStateInfo(); AiData_UserSelf_General data = GetAiData(user); if (null != data) { if (info.Target > 0) { CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(user, info.Target); if (null != target) { float dist = info.AttackRange - 1.0f; Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); ScriptRuntime.Vector3 srcPos = user.GetMovementStateInfo().GetPosition3D(); float powDist = Geometry.DistanceSquare(srcPos, targetPos); if (powDist < dist * dist) { user.GetMovementStateInfo().IsMoving = false; info.Time = 0; data.Time = 0; ChangeToState(user, (int)AiStateId.Combat); NotifyUserMove(user); } else { info.Time += deltaTime; if (info.Time > 100) { info.Time = 0; CharacterInfo target2 = GetCanAttackUserTarget(user); if (null == target2) { AiLogicUtility.GetNearstTargetHelper(user, CharacterRelation.RELATION_ENEMY); } if (null == target2 || target == target2) { PathToTarget(user, data.FoundPath, targetPos, deltaTime); } else { info.Target = target2.GetId(); return; } } } } else { user.GetMovementStateInfo().StopMove(); NotifyUserMove(user); info.Time = 0; data.Time = 0; data.FoundPath.Clear(); ChangeToState(user, (int)AiStateId.Idle); } } else { float dist = info.AttackRange; Vector3 targetPos = info.TargetPos; ScriptRuntime.Vector3 srcPos = user.GetMovementStateInfo().GetPosition3D(); float powDist = Geometry.DistanceSquare(srcPos, targetPos); if (powDist < dist * dist) { user.GetMovementStateInfo().IsMoving = false; info.Time = 0; data.Time = 0; ChangeToState(user, (int)AiStateId.Combat); NotifyUserMove(user); } else { info.Time += deltaTime; if (info.Time > 100) { info.Time = 0; PathToTarget(user, data.FoundPath, targetPos, deltaTime); } } } } }
public static ScriptRuntime.Vector3 AiGetValidPosition(EntityInfo npc, ScriptRuntime.Vector3 target, float maxDistance) { return(target); }