private void ActionDriveHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { npc.GetMovementStateInfo().IsMoving = false; return; } NpcAiStateInfo info = npc.GetAiStateInfo(); AiData_Npc_ActionDrive data = GetAiData(npc); if (null != data) { CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target); if (null != target) { Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D(); Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float dist = Geometry.Distance(srcPos, targetPos); if (data.LastGfxState != npc.GfxStateFlag) { if (data.LastGfxState == (int)GfxCharacterState_Type.KnockDown && npc.GfxStateFlag == (int)GfxCharacterState_Type.GetUp) { // 起身 OnEvent(npc, (int)AiEventEnum.GET_UP, target, deltaTime); } data.LastGfxState = npc.GfxStateFlag; } if (npc.IsUnderControl()) { data.ControlTime += deltaTime; if (data.ControlTime > data.MaxControlTime && npc.CanDisControl()) { data.ControlTime = 0; OnEvent(npc, (int)AiEventEnum.CONTROL_TIME_OVERFLOW, target, deltaTime); } return; } ExecAiAction(npc, target, deltaTime); } else { if (null != data.ActiveAction) { AiActionInfo aiActionInfo = data.ActiveAction; AiActionForceStopDelegate handler = GetAiActionForceStopHandler(aiActionInfo.Config.AiActionType); if (null != handler) { handler(npc, target); } } else { npc.GetMovementStateInfo().IsMoving = false; } ChangeToState(npc, (int)AiStateId.Pursuit); } } }
protected bool CanAiControl(NpcInfo npc) { if (npc.IsDead() || npc.GetSkillStateInfo().IsSkillActivated() || npc.IsUnderControl()) { return(false); } return(true); }
public bool HasCombatNpcAlive() { bool result = false; for (LinkedListNode <NpcInfo> linkNode = m_Npcs.FirstValue; null != linkNode; linkNode = linkNode.Next) { NpcInfo npc = linkNode.Value; if (null != npc && npc.IsCombatNpc() && !npc.IsDead()) { result = true; break; } } return(result); }
public override void Execute(SceneLogicInfo info, long deltaTime) { if (null == info || info.IsLogicFinished || info.IsLogicPaused) { return; } info.Time += deltaTime; if (info.Time > 100) { NpcInAreaLogicInfo data = info.LogicDatas.GetData <NpcInAreaLogicInfo>(); if (null == data) { data = new NpcInAreaLogicInfo(); info.LogicDatas.AddData <NpcInAreaLogicInfo>(data); SceneLogicConfig sc = info.SceneLogicConfig; if (null != sc) { if (null != sc) { List <float> pts = Converter.ConvertNumericList <float>(sc.m_Params[0]); data.m_Area = new Vector3[pts.Count / 2]; for (int ix = 0; ix < pts.Count - 1; ix += 2) { data.m_Area[ix / 2].X = pts[ix]; data.m_Area[ix / 2].Z = pts[ix + 1]; } } } } info.Time = 0; if (null != data) { info.SpatialSystem.VisitObjectOutPolygon(data.m_Area, (float distSqr, ArkCrossEngineSpatial.ISpaceObject obj) => { if (obj.GetObjType() == ArkCrossEngineSpatial.SpatialObjType.kNPC) { NpcInfo npc = obj.RealObject as NpcInfo; if (null != npc && !npc.IsDead()) { npc.SetHp(Operate_Type.OT_Absolute, 0); SceneLogicSendStoryMessage(info, "npcleavearea", npc.GetId()); } } }); } } }
private void MoveNpc(NpcInfo obj, long deltaTime) { if (obj.IsHaveStateFlag(CharacterState_Type.CST_Sleep) || obj.IsHaveStateFlag(CharacterState_Type.CST_FixedPosition) || null != obj.ControllerObject) { return; } MovementStateInfo msi = obj.GetMovementStateInfo(); //npc执行移动时忽略阻挡与避让,这些行为由ai模块在规划其路径时执行。 if (!obj.IsDead() && obj.CanMove && msi.IsMoving && !msi.IsSkillMoving) { Vector3 pos = msi.GetPosition3D(); float cos_angle = (float)msi.MoveDirCosAngle; float sin_angle = (float)msi.MoveDirSinAngle; float speed = (float)obj.GetActualProperty().MoveSpeed *(float)obj.VelocityCoefficient; float distance = (speed * (float)(int)deltaTime) / 1000.0f; //LogSystem.Debug("MovementSystem npc:{0} speed:{1} deltaTime:{2} distance:{3}", obj.GetId(), speed, deltaTime, distance); float x = 0, y = 0; if (msi.CalcDistancSquareToTarget() < distance * distance) { x = msi.TargetPosition.X; y = msi.TargetPosition.Z; AdjustPosition(obj.SpatialSystem, ref x, ref y); Vector2 newPos = new Vector2(x, y); msi.SetPosition2D(newPos); } else { float len = pos.Length(); y = pos.Z + distance * cos_angle; x = pos.X + distance * sin_angle; AdjustPosition(obj.SpatialSystem, ref x, ref y); Vector2 newPos = new Vector2(x, y); msi.SetPosition2D(newPos); } } }
private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead() || npc.GetSkillStateInfo().IsSkillActivated()) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); return; } NpcAiStateInfo info = npc.GetAiStateInfo(); AiData_Npc_BossDevilWarrior data = GetAiData(npc); if (null != data) { CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target); if (null != target) { if (npc.IsUnderControl()) { data.ControlTime += deltaTime; if (data.ControlTime >= m_MaxControlTime && npc.CanDisControl() && AiLogicUtility.CanCastSkill(npc, data.DecontrolSkill, target)) { NotifyNpcAddImpact(npc, m_DisControlImpact); data.ControlTime = 0; TryCastSkill(npc, data.DecontrolSkill, target, false); data.CurSkillCombo = data.DecontrolCombo; data.CurSkillComboIndex = 0; } return; } 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 <= m_ResponseTime) { if (!data.HasMeetEnemy) { NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack); data.HasMeetEnemy = true; } TrySeeTarget(npc, target); data.WaitTime += deltaTime; return; } if (null != data.CurSkillCombo) { if (data.CurSkillCombo.Length > data.CurSkillComboIndex) { TryCastSkill(npc, data.CurSkillCombo[data.CurSkillComboIndex], target); data.CurSkillComboIndex = data.CurSkillComboIndex + 1; } else { data.CurSkillCombo = null; data.CurSkillComboIndex = 0; } } // 大于攻击距离 跑向目标 if (powDist > m_AttackRange * m_AttackRange) { if ((int)GfxCharacterState_Type.HitFly == target.GfxStateFlag) { if (TryCastSkill(npc, data.FlyRangeSkill, target)) { return; } } else { if (TryCastSkill(npc, data.RangeSkill, target)) { return; } } info.Time += deltaTime; if (info.Time > m_IntervalTime) { NotifyNpcRun(npc); info.Time = 0; AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } } else { if ((int)GfxCharacterState_Type.HitFly == target.GfxStateFlag) { if (TryCastSkill(npc, data.FlyMeeleSkill, target)) { return; } } else { if (TryCastSkill(npc, data.MeeleSkill, target)) { return; } } } } else { NotifyNpcTargetChange(npc); npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; ChangeToState(npc, (int)AiStateId.Idle); } } }
private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead() || npc.GetSkillStateInfo().IsSkillActivated()) { 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) { if (npc.IsUnderControl()) { data.ControlTime += deltaTime; if (data.ControlTime > m_MaxControlTime && npc.CanDisControl()) { data.ControlTime = 0; NotifyNpcAddImpact(npc, m_SuperArmorImpact); } return; } 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; 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; 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); 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); 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); } } }
private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); return; } NpcAiStateInfo info = npc.GetAiStateInfo(); AiData_Npc_CommonBoss data = GetAiData(npc); if (null != data) { CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target); if (null != target) { if (npc.GetSkillStateInfo().IsSkillActivated()) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.LastUseSkillTime = TimeUtility.GetServerMilliseconds(); return; } if (npc.IsUnderControl()) { data.ControlTime += deltaTime; if (data.ControlTime >= m_MaxControlTime && npc.CanDisControl() && AiLogicUtility.CanCastSkill(npc, m_DisControlSkillId, target)) { NotifyNpcAddImpact(npc, m_DisControlImpactId); data.ControlTime = 0; TryCastSkill(npc, m_DisControlSkillId, target, false); } return; } 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 <= m_ResponseTime) { if (!data.HasMeetEnemy) { NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack); data.HasMeetEnemy = true; } TrySeeTarget(npc, target); data.WaitTime += deltaTime; return; } int skillId = GetCanCastSkillId(npc, (float)Math.Sqrt(powDist)); long curTime = TimeUtility.GetServerMilliseconds(); if (-1 != skillId && curTime - data.LastUseSkillTime > m_SkillInterval && AiLogicUtility.CanCastSkill(npc, skillId, target)) { if (TryCastSkill(npc, skillId, target, true)) { NotifyNpcAddImpact(npc, m_SuperArmorImpactId); } } else { info.Time += deltaTime; if (info.Time > m_IntervalTime) { info.Time = 0; AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } } } else { NotifyNpcTargetChange(npc); npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; ChangeToState(npc, (int)AiStateId.Idle); } } }
private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); return; } if (npc.GetSkillStateInfo().IsSkillActivated()) { return; } NpcAiStateInfo info = npc.GetAiStateInfo(); AiData_Npc_Bluelf data = GetAiData(npc); if (null != data) { // 写黑板 if (0 != info.HateTarget) { GetBlackBorad(npc).TargetId = info.HateTarget; } if (npc.IsUnderControl()) { return; } // 读黑板 int blackBoardTarget = GetBlackBorad(npc).TargetId; if (0 != blackBoardTarget) { info.Target = blackBoardTarget; NotifyNpcTargetChange(npc); } 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 <= m_ResponseTime) { if (!data.HasMeetEnemy) { NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack); data.HasMeetEnemy = true; } TrySeeTarget(npc, target); data.WaitTime += deltaTime; return; } // 追逐目标 if (powDist > m_AttackRange * m_AttackRange) { npc.GetActualProperty().SetMoveSpeed(Operate_Type.OT_Absolute, AiLogicUtility.GetRunSpeed(npc)); npc.GetMovementStateInfo().MovementMode = MovementMode.HighSpeed; info.Time += deltaTime; if (info.Time > m_IntervalTime) { info.Time = 0; AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } } else { //小于攻击距离, 可以攻击 npc.GetMovementStateInfo().IsMoving = false; if (0 != blackBoardTarget) { int skillId = GetCanCastSkillId(npc, (float)Math.Sqrt(powDist)); TryCastSkill(npc, skillId, target); } else { // 不敢攻击 TrySeeTarget(npc, target); } } } else { NotifyNpcTargetChange(npc); npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; ChangeToState(npc, (int)AiStateId.Idle); } } }
private void IdleHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.GetSkillStateInfo().IsSkillActivated()) { return; } if (npc.IsDead()) { return; } if (npc.IsUnderControl()) { // 被动进入战斗 } NpcAiStateInfo info = npc.GetAiStateInfo(); AiData_Npc_ActionDrive data = GetAiData(npc); info.Time += deltaTime; if (info.Time > 100) { CharacterInfo target = AiLogicUtility.GetRandomTargetHelper(npc, CharacterRelation.RELATION_ENEMY, AiTargetType.ALL); if (null != target) { info.Target = target.GetId(); NotifyNpcTargetChange(npc); npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; ChangeToState(npc, (int)AiStateId.Pursuit); } else { if ((int)NpcTypeEnum.Partner == npc.NpcType) { CharacterInfo owner = npc.SceneContext.GetCharacterInfoById(npc.OwnerId); if (null != owner) { Vector3 targetPos = owner.GetMovementStateInfo().GetPosition3D(); Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); if (Geometry.DistanceSquare(targetPos, srcPos) > 16) { AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, info.Time, true, this); } else { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); } } else { UserInfo master = AiLogicUtility.GetRandomTargetHelper(npc, CharacterRelation.RELATION_FRIEND, AiTargetType.USER) as UserInfo; if (null != master) { npc.OwnerId = master.GetId(); } } } else { if (null != GetAiPatrolData(npc)) { npc.GetMovementStateInfo().IsMoving = false; ChangeToState(npc, (int)AiStateId.Patrol); } } } info.Time = 0; } }
private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime) { if (npc.IsDead()) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); return; } NpcAiStateInfo info = npc.GetAiStateInfo(); AiData_Npc_BossHulun data = GetAiData(npc); if (null != data) { CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target); if (null != target) { if (npc.IsUnderControl()) { data.ControlTime += deltaTime; if (data.ControlTime > m_MaxControlTime && npc.CanDisControl()) { NotifyNpcAddImpact(npc, m_SuperArmorImpactId); data.ControlTime = 0; NotifyNpcSkill(npc, 380308); } } 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 <= m_ResponseTime) { if (!data.HasMeetEnemy) { NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack); data.HasMeetEnemy = true; } TrySeeTarget(npc, target); data.WaitTime += deltaTime; return; } if (npc.GetSkillStateInfo().IsSkillActivated()) { SkillInfo curSkill = npc.GetSkillStateInfo().GetCurSkillInfo(); if (null != curSkill && curSkill.SkillId == data.ChaseTargetSkill) { NotifyNpcRun(npc); AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, deltaTime, true, this); data.IsUsingChaseSkill = true; } return; } else if (data.IsUsingChaseSkill) { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.IsUsingChaseSkill = false; } if (1 == data.CurStage) { if (npc.Hp < npc.GetActualProperty().HpMax *data.StageTwoLimit) { data.CurStage = 2; NotifyNpcSkill(npc, data.EnterStageTwoSkill); data.CurSkillCombo = null; data.CurSkillComboIndex = 0; return; } else { if (null == data.CurSkillCombo) { data.CurSkillCombo = data.m_StageOneSkillCombo; data.CurSkillComboIndex = 0; } } } else if (2 == data.CurStage) { if (npc.Hp < npc.GetActualProperty().HpMax *data.StageThreeLimit) { data.CurStage = 3; NotifyNpcSkill(npc, data.EnterStageTwoSkill); data.CurSkillCombo = null; data.CurSkillComboIndex = 0; return; } else { if (null == data.CurSkillCombo) { data.CurSkillCombo = data.m_StageTwoSkillCombo; data.CurSkillComboIndex = 0; } } } else if (3 == data.CurStage) { if (null == data.CurSkillCombo) { data.CurSkillCombo = data.m_StageThreeSkillCombo; data.CurSkillComboIndex = 0; } } if (null != data.CurSkillCombo) { if (data.CurSkillCombo.Length > data.CurSkillComboIndex) { if (TryCastSkill(npc, data.CurSkillCombo[data.CurSkillComboIndex], target)) { data.CurSkillComboIndex = data.CurSkillComboIndex + 1; return; } } else { data.CurSkillCombo = null; data.CurSkillComboIndex = 0; } } // 大于攻击距离 跑向目标 info.Time += deltaTime; if (info.Time > m_IntervalTime) { NotifyNpcRun(npc); info.Time = 0; AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this); } } else { NotifyNpcTargetChange(npc); npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); info.Time = 0; ChangeToState(npc, (int)AiStateId.Idle); } } }