fBaseXtensions.Targeting.TargetMovement.TargetMoveTo C# (CSharp) Method

TargetMoveTo() private method

private TargetMoveTo ( CacheObject obj ) : RunStatus
obj fBaseXtensions.Cache.Internal.Objects.CacheObject
return RunStatus
        internal RunStatus TargetMoveTo(CacheObject obj)
        {
            #region DebugInfo
            if (FunkyBaseExtension.Settings.Debugging.DebugStatusBar)
            {
                string Action = "[Move-";
                switch (obj.targetType.Value)
                {
                    case TargetType.Avoidance:
                        Action += "Avoid] ";
                        break;
                    case TargetType.Fleeing:
                        Action += "Flee] ";
                        break;

                    case TargetType.Backtrack:
                        Action += "BackTrack] ";
                        break;

                    case TargetType.LineOfSight:
                        Action += "LOS] ";
                        break;

                    case TargetType.Unit:
                        if (FunkyGame.Navigation.groupRunningBehavior && FunkyGame.Navigation.groupingCurrentUnit != null && FunkyGame.Navigation.groupingCurrentUnit == obj)
                            Action += "Grouping] ";
                        else
                            Action += "Combat] ";

                        break;
                    case TargetType.Item:
                    case TargetType.Gold:
                    case TargetType.Globe:
                        Action += "Pickup] ";
                        break;
                    case TargetType.Interactable:
                        Action += "Interact] ";
                        break;
                    case TargetType.Container:
                        Action += "Open] ";
                        break;
                    case TargetType.Destructible:
                    case TargetType.Barricade:
                        Action += "Destroy] ";
                        break;
                    case TargetType.Shrine:
                        Action += "Click] ";
                        break;
                }
                FunkyGame.sStatusText = Action + " ";

                FunkyGame.sStatusText += "Target=" + FunkyGame.Targeting.Cache.CurrentTarget.InternalName + " C-Dist=" + Math.Round(FunkyGame.Targeting.Cache.CurrentTarget.CentreDistance, 2) + ". " +
                     "R-Dist=" + Math.Round(FunkyGame.Targeting.Cache.CurrentTarget.RadiusDistance, 2) + ". ";

                if (FunkyGame.Targeting.Cache.CurrentTarget.targetType.Value == TargetType.Unit && FunkyGame.Hero.Class.PowerPrime.Power != SNOPower.None)
                    FunkyGame.sStatusText += "Power=" + FunkyGame.Hero.Class.PowerPrime.Power + " (range " + FunkyGame.Hero.Class.PowerPrime.MinimumRange + ") ";

                FunkyGame.sStatusText += "Weight=" + FunkyGame.Targeting.Cache.CurrentTarget.Weight;
                BotMain.StatusText = FunkyGame.sStatusText;
                FunkyGame.bResetStatusText = true;
            }
            #endregion

            // Are we currently incapacitated? If so then wait...
            if (FunkyGame.Hero.bIsIncapacitated || FunkyGame.Hero.bIsRooted)
                return RunStatus.Running;

            //Ignore skip ahead cache for LOS movements..
            if (FunkyBaseExtension.Settings.Debugging.SkipAhead && obj.targetType.Value != TargetType.LineOfSight)
                SkipAheadCache.RecordSkipAheadCachePoint();

            // Some stuff to avoid spamming usepower EVERY loop, and also to detect stucks/staying in one place for too long
            bool bForceNewMovement = false;

            //Herbfunk: Added this to prevent stucks attempting to move to a target blocked. (Case: 3 champs behind a wall, within range but could not engage due to being on the other side.)
            #region Non Movement Counter Reached
            if (NonMovementCounter > FunkyBaseExtension.Settings.Plugin.MovementNonMovementCount)
            {
                Logger.Write(LogLevel.Movement, "non movement counter reached {0}", NonMovementCounter);

                if (obj.Actortype.HasValue && obj.Actortype.Value.HasFlag(ActorType.Item))
                {
                    if (NonMovementCounter > 250)
                    {
                        //Are we stuck?
                        if (!Navigation.Navigation.MGP.CanStandAt(FunkyGame.Hero.Position))
                        {
                            Logger.DBLog.InfoFormat("Character is stuck inside non-standable location.. attempting townportal cast..");
                            ZetaDia.Me.UseTownPortal();
                            NonMovementCounter = 0;
                            return RunStatus.Running;
                        }
                    }

                    //Check if we can walk to this location from current location..
                    if (!Navigation.Navigation.CanRayCast(FunkyGame.Hero.Position, CurrentTargetLocation, UseSearchGridProvider: true))
                    {
                        obj.RequiresLOSCheck = true;
                        obj.BlacklistLoops = 50;

                        Logger.Write(LogLevel.Movement, "Ignoring Item {0} -- due to RayCast Failure!", obj.InternalName);

                        FunkyGame.Targeting.Cache.bForceTargetUpdate = true;
                        return RunStatus.Running;
                    }
                }
                else if (ObjectCache.CheckFlag(obj.targetType.Value, TargetType.LineOfSight | TargetType.Backtrack))
                {

                    Logger.Write(LogLevel.LineOfSight, "Line of Sight Movement Stalled!");

                    //FunkyGame.Navigation.LOSmovementObject = null;
                    Navigation.Navigation.NP.Clear();
                    FunkyGame.Targeting.Cache.bForceTargetUpdate = true;
                    NonMovementCounter = 0;
                    // Reset the emergency loop counter and return success
                    return RunStatus.Running;
                }
                else
                {
                    Logger.Write(LogLevel.Movement, "Ignoring obj {0} ", obj.InternalName + " _ SNO:" + obj.SNOID);
                    obj.BlacklistLoops = 50;
                    obj.RequiresLOSCheck = true;
                    FunkyGame.Targeting.Cache.bForceTargetUpdate = true;
                    NonMovementCounter = 0;

                    // Reset the emergency loop counter and return success
                    return RunStatus.Running;
                }
            }
            #endregion

            //Do a priority check for nearby obstacle objects.
            FunkyGame.Navigation.ObstaclePrioritizeCheck(15f);

            #region Evaluate Last Action

            // Position didn't change last update.. check if we are stuck!
            if (DateTime.Now.Subtract(lastPositionChange).TotalMilliseconds > 150 &&
                (!FunkyGame.Hero.IsMoving || FunkyGame.Hero.currentMovementState == MovementState.WalkingInPlace || FunkyGame.Hero.currentMovementState.Equals(MovementState.None)))
            {
                bForceNewMovement = true;
                if (DateTime.Now.Subtract(LastMovementDuringCombat).TotalMilliseconds >= 250)
                {
                    LastMovementDuringCombat = DateTime.Now;
                    BlockedMovementCounter++;

                    // Tell target finder to prioritize close-combat targets incase we were bodyblocked
                    #region TargetingPriortize
                    switch (BlockedMovementCounter)
                    {
                        case 2:
                        case 3:
                            if (FunkyGame.Navigation.groupRunningBehavior)
                            {
                                Logger.Write(LogLevel.Movement, "Grouping Behavior stopped due to blocking counter");

                                FunkyGame.Navigation.GroupingFinishBehavior();
                                FunkyGame.Navigation.groupingSuspendedDate = DateTime.Now.AddMilliseconds(4000);
                                FunkyGame.Targeting.Cache.bForceTargetUpdate = true;
                                return RunStatus.Running;
                            }

                            if (!ObjectCache.CheckFlag(obj.targetType.Value, TargetType.AvoidanceMovements))
                            {
                                //Finally try raycasting to see if navigation is possible..
                                if (obj.Actortype.HasValue &&
                                     (obj.Actortype.Value == ActorType.Gizmo || obj.Actortype.Value == ActorType.Monster))
                                {
                                    Vector3 hitTest;
                                    // No raycast available, try and force-ignore this for a little while, and blacklist for a few seconds
                                    if (Navigator.Raycast(FunkyGame.Hero.Position, obj.Position, out hitTest))
                                    {
                                        if (hitTest != Vector3.Zero)
                                        {
                                            obj.RequiresLOSCheck = true;
                                            obj.BlacklistLoops = 10;
                                            Logger.Write(LogLevel.Movement, "Ignoring object " + obj.InternalName + " due to not moving and raycast failure!", true);

                                            FunkyGame.Targeting.Cache.bForceTargetUpdate = true;
                                            return RunStatus.Running;
                                        }
                                    }
                                }
                                else if (obj.targetType.Value == TargetType.Item)
                                {
                                    obj.BlacklistLoops = 10;
                                    FunkyGame.Targeting.Cache.bForceTargetUpdate = true;
                                }
                            }
                            else
                            {
                                if (!Navigation.Navigation.CanRayCast(FunkyGame.Hero.Position, CurrentTargetLocation, NavCellFlags.AllowWalk))
                                {
                                    Logger.Write(LogLevel.Movement, "Cannot continue with avoidance movement due to raycast failure!");
                                    BlockedMovementCounter = 0;

                                    FunkyGame.Navigation.CurrentGPArea.BlacklistLastSafespot();
                                    FunkyGame.Navigation.vlastSafeSpot = Vector3.Zero;
                                    FunkyGame.Targeting.Cache.bForceTargetUpdate = true;
                                    return RunStatus.Running;
                                }
                            }
                            break;
                    }
                    #endregion

                    return RunStatus.Running;
                }
            }
            else
            {
                // Movement has been made, so count the time last moved!
                LastMovementDuringCombat = DateTime.Now;
            }
            #endregion

            // See if we want to ACTUALLY move, or are just waiting for the last move command...
            if (!bForceNewMovement && IsAlreadyMoving && CurrentTargetLocation == LastTargetLocation && DateTime.Now.Subtract(LastMovementCommand).TotalMilliseconds <= 100)
            {
                return RunStatus.Running;
            }

            // If we're doing avoidance, globes or backtracking, try to use special abilities to move quicker
            #region SpecialMovementChecks
            if (ObjectCache.CheckFlag(obj.targetType.Value, FunkyBaseExtension.Settings.Combat.CombatMovementTargetTypes))
            {
                Skill MovementPower;
                Vector3 MovementVector = FunkyGame.Hero.Class.FindCombatMovementPower(out MovementPower, obj.Position);
                if (MovementVector != Vector3.Zero)
                {
                    ZetaDia.Me.UsePower(MovementPower.Power, MovementVector, FunkyGame.Hero.CurrentWorldDynamicID, -1);
                    MovementPower.OnSuccessfullyUsed();

                    // Store the current destination for comparison incase of changes next loop
                    LastTargetLocation = CurrentTargetLocation;
                    // Reset total body-block count, since we should have moved
                    //if (DateTime.Now.Subtract(FunkyGame.Targeting.Cache.Environment.lastForcedKeepCloseRange).TotalMilliseconds>=2000)
                    BlockedMovementCounter = 0;

                    FunkyGame.Hero.Class.PowerPrime.WaitLoopsBefore = 5;

                    return RunStatus.Running;
                }

                //Special Whirlwind Code
                if (FunkyGame.Hero.Class.AC == ActorClass.Barbarian && Hotbar.HasPower(SNOPower.Barbarian_Whirlwind))
                {
                    // Whirlwind against everything within range (except backtrack points)
                    if (FunkyGame.Hero.dCurrentEnergy >= 10
                         && FunkyGame.Targeting.Cache.Environment.iAnythingWithinRange[(int)RangeIntervals.Range_20] >= 1
                         && obj.DistanceFromTarget <= 12f
                         && (!Hotbar.HasPower(SNOPower.Barbarian_Sprint) || Hotbar.HasBuff(SNOPower.Barbarian_Sprint))
                         && (ObjectCache.CheckFlag(obj.targetType.Value, TargetType.AvoidanceMovements | TargetType.Gold | TargetType.Globe) == false)
                         && (obj.targetType.Value != TargetType.Unit
                         || (obj.targetType.Value == TargetType.Unit && !obj.IsTreasureGoblin
                              && (!FunkyBaseExtension.Settings.Barbarian.bSelectiveWhirlwind
                                    || FunkyGame.Targeting.Cache.Environment.bAnyNonWWIgnoreMobsInRange
                                    || !CacheIDLookup.hashActorSNOWhirlwindIgnore.Contains(obj.SNOID)))))
                    {
                        // Special code to prevent whirlwind double-spam, this helps save fury
                        bool bUseThisLoop = SNOPower.Barbarian_Whirlwind != FunkyGame.Hero.Class.LastUsedAbility.Power;
                        if (!bUseThisLoop)
                        {
                            if (FunkyGame.Hero.Class.Abilities[SNOPower.Barbarian_Whirlwind].LastUsedMilliseconds >= 200)
                                bUseThisLoop = true;
                        }
                        if (bUseThisLoop)
                        {
                            ZetaDia.Me.UsePower(SNOPower.Barbarian_Whirlwind, CurrentTargetLocation, FunkyGame.Hero.CurrentWorldDynamicID);
                            FunkyGame.Hero.Class.Abilities[SNOPower.Barbarian_Whirlwind].OnSuccessfullyUsed();
                        }
                        // Store the current destination for comparison incase of changes next loop
                        LastTargetLocation = CurrentTargetLocation;
                        BlockedMovementCounter = 0;
                        return RunStatus.Running;
                    }
                }
            }
            #endregion

            //Special Movement Check for Steed Charge and Spirit Walk
            if (FunkyGame.Hero.Class.LastUsedAbility.IsSpecialMovementSkill && FunkyGame.Hero.Class.HasSpecialMovementBuff() && ObjectCache.CheckFlag(obj.targetType.Value, TargetType.Unit))
            {
                //Logger.DBLog.DebugFormat("Preforming ZigZag for special movement skill activation!");
                FunkyGame.Navigation.vPositionLastZigZagCheck = FunkyGame.Hero.Position;
                if (FunkyGame.Hero.Class.ShouldGenerateNewZigZagPath()) FunkyGame.Hero.Class.GenerateNewZigZagPath();
                CurrentTargetLocation = FunkyGame.Navigation.vSideToSideTarget;
            }

            // Now for the actual movement request stuff
            IsAlreadyMoving = true;
            UseTargetMovement(obj, bForceNewMovement);

            // Store the current destination for comparison incase of changes next loop
            LastMovementAttempted = DateTime.Now;
            LastTargetLocation = CurrentTargetLocation;

            //Check if we moved at least 5f..
            if (LastPlayerLocation.Distance(FunkyGame.Hero.Position) <= 5f)
                NonMovementCounter++;
            else
            {
                NonMovementCounter = 0;
                BlockedMovementCounter = 0;
            }

            //store player location
            LastPlayerLocation = FunkyGame.Hero.Position;

            return RunStatus.Running;
        }