示例#1
0
 ///<summary>
 ///Used to recreate from temp into obstacle object.
 ///</summary>
 public CacheObject(CacheObject parent)
     : base(parent)
 {
     this.AcdGuid=parent.AcdGuid;
              this.BlacklistFlag=parent.BlacklistFlag;
              this.BlacklistLoops_=parent.BlacklistLoops_;
              this.gprect_=parent.gprect_;
              this.InteractionAttempts=parent.InteractionAttempts;
              this.LastLOSCheck=parent.LastLOSCheck;
              this.LoopsUnseen_=parent.LoopsUnseen_;
              this.losv3_=parent.losv3_;
              this.LosSearchRetryMilliseconds_=parent.LosSearchRetryMilliseconds_;
              this.NeedsRemoved=parent.NeedsRemoved;
              this.NeedsUpdate=parent.NeedsUpdate;
              this.PrioritizedDate=parent.PrioritizedDate;
              this.PriorityCounter=parent.PriorityCounter;
              this.position_=parent.Position;
              this.radius_=parent.Radius;
              this.RAGUID=parent.RAGUID;
              this.ref_DiaObject=parent.ref_DiaObject;
              this.removal_=parent.removal_;
              this.RequiresLOSCheck=parent.RequiresLOSCheck;
              this.SummonerID=parent.SummonerID;
              this.weight_=parent.Weight;
              this.HandleAsAvoidanceObject=parent.HandleAsAvoidanceObject;
 }
示例#2
0
 public CacheAvoidance(CacheObject parent, AvoidanceType type, Ray R, double speed)
     : base(parent)
 {
     this.AvoidanceType=type;
              this.ray_=R;
              this.Speed=speed;
              this.projectile_startPosition=base.Position;
 }
示例#3
0
        public CacheAvoidance(CacheObject parent, AvoidanceType avoidancetype)
            : base(parent)
        {
            this.AvoidanceType=avoidancetype;

                     //Special avoidances that require additional loops before removal
                     if ((AvoidanceType.TreeSpore|AvoidanceType.GrotesqueExplosion).HasFlag(this.AvoidanceType))
                          this.RefreshRemovalCounter=30;
        }
示例#4
0
 public CacheServerObject(CacheObject parent)
     : base(parent)
 {
 }
示例#5
0
 ///<summary>
 ///Tests if this intersects with current bot position using CacheObject
 ///</summary>
 public virtual bool TestIntersection(CacheObject OBJ, Vector3 BotPosition)
 {
     return MathEx.IntersectsPath(base.Position, this.Radius, BotPosition, base.BotMeleeVector);
 }
示例#6
0
 ///<summary>
 ///
 ///</summary>
 public CacheObstacle(CacheObject fromObj)
     : base(fromObj)
 {
     if (!base.Obstacletype.HasValue)
                   base.Obstacletype=ObstacleType.None;
 }
示例#7
0
        public override bool TestIntersection(CacheObject OBJ, Vector3 BotPosition)
        {
            if (this.Obstacletype.Value==ObstacleType.MovingAvoidance)
                     {
                          Vector3 ProjectileEndPoint=MathEx.GetPointAt(this.Position, this.ProjectileMaxRange, this.Rotation);
                          return GridPoint.LineIntersectsLine(BotPosition, this.Position, this.PointPosition, ProjectileEndPoint);
                     }

                     return MathEx.IntersectsPath(base.Position, this.Radius, BotPosition, OBJ.Position);
        }
示例#8
0
        ///<summary>
        ///Iterates through Usable objects and sets the Bot.CurrentTarget to the highest weighted object found inside the given list.
        ///</summary>
        private void WeightEvaluationObjList()
        {
            // Store if we are ignoring all units this cycle or not
                        bool bIgnoreAllUnits=!Bot.Combat.bAnyChampionsPresent
                                                    &&!Bot.Combat.bAnyMobsInCloseRange
                                                    &&((!Bot.Combat.bAnyTreasureGoblinsPresent&&Bot.SettingsFunky.GoblinPriority>=2)||Bot.SettingsFunky.GoblinPriority<2)
                                                    &&Bot.Character.dCurrentHealthPct>=0.85d;

                        //clear our last "avoid" list..
                        ObjectCache.Objects.objectsIgnoredDueToAvoidance.Clear();

                        double iHighestWeightFound=0;

                        foreach (CacheObject thisobj in Bot.ValidObjects)
                        {
                             thisobj.UpdateWeight();

                             if (thisobj.Weight==1)
                             {
                                    // Force the character to stay where it is if there is nothing available that is out of avoidance stuff and we aren't already in avoidance stuff
                                    thisobj.Weight=0;
                                    if (!Bot.Combat.RequiresAvoidance) Bot.Combat.bStayPutDuringAvoidance=true;
                                    continue;
                             }

                             // Is the weight of this one higher than the current-highest weight? Then make this the new primary target!
                             if (thisobj.Weight>iHighestWeightFound&&thisobj.Weight>0)
                             {
                                    //Check combat looting (Demonbuddy Setting)
                                    if (iHighestWeightFound>0
                                                         &&thisobj.targetType.Value==TargetType.Item
                                                         &&!Zeta.CommonBot.Settings.CharacterSettings.Instance.CombatLooting
                                                         &&CurrentTarget.targetType.Value==TargetType.Unit) continue;

                                    //cache RAGUID so we can switch back if we need to
                                    int CurrentTargetRAGUID=CurrentTarget!=null?CurrentTarget.RAGUID:-1;

                                    //Set our current target to this object!
                                    CurrentTarget=ObjectCache.Objects[thisobj.RAGUID];

                                    bool resetTarget=false;
                                    //Check for Range Classes and Unit Targets
                                    if (!Bot.Class.IsMeleeClass&&CurrentTarget.targetType.Value==TargetType.Unit&&Bot.Combat.NearbyAvoidances.Count>0)
                                    {
                                         //set unit target (for Ability selector).
                                         CurrentUnitTarget=(CacheUnit)CurrentTarget;

                                         //Generate next Ability..
                                         Ability nextAbility=Bot.Class.AbilitySelector();

                                         //reset unit target
                                         CurrentUnitTarget=null;

                                         //Check if we are already within interaction range.
                                         if (!thisobj.WithinInteractionRange())
                                         {
                                                Vector3 destinationV3=nextAbility.DestinationVector;
                                                //Check if the estimated destination will also be inside avoidance zone..
                                                if (ObjectCache.Obstacles.IsPositionWithinAvoidanceArea(destinationV3)
                                                    ||ObjectCache.Obstacles.TestVectorAgainstAvoidanceZones(destinationV3))
                                                {
                                                     //Only wait if the object is special and we are not avoiding..
                                                     if (thisobj.ObjectIsSpecial)
                                                     {
                                                            if (!Bot.Combat.RequiresAvoidance)
                                                            {
                                                                 Bot.Combat.bStayPutDuringAvoidance=true;
                                                                 resetTarget=true;
                                                            }
                                                            else if (!nextAbility.IsRanged&&nextAbility.Range>0)
                                                            {
                                                                 //Non-Ranged Ability.. act like melee..
                                                                 //Try to find a spot
                                                                 ObjectCache.Objects.objectsIgnoredDueToAvoidance.Add(thisobj);
                                                            }
                                                     }
                                                     else
                                                            resetTarget=true;
                                                }
                                         }
                                    }

                                    //Avoidance Attempt to find a location where we can attack!
                                    if (ObjectCache.Objects.objectsIgnoredDueToAvoidance.Contains(thisobj))
                                    {
                                         //Wait if no valid target found yet.. and no avoidance movement required.
                                         if (!Bot.Combat.RequiresAvoidance)
                                                Bot.Combat.bStayPutDuringAvoidance=true;

                                         //Check Bot Navigationally blocked
                                         Bot.NavigationCache.RefreshNavigationBlocked();
                                         if (!Bot.NavigationCache.BotIsNavigationallyBlocked)
                                         {
                                                Vector3 SafeLOSMovement;
                                                if (thisobj.GPRect.TryFindSafeSpot(Bot.Character.Position, out SafeLOSMovement, Vector3.Zero, Bot.Character.ShouldFlee, true))
                                                {
                                                     CurrentTarget=new CacheObject(SafeLOSMovement, TargetType.Avoidance, 20000, "SafetyMovement", 2.5f, -1);
                                                     //Reset Avoidance Timer so we don't trigger it while moving towards the target!
                                                     Bot.Combat.timeCancelledEmergencyMove=DateTime.Now;
                                                     Bot.Combat.iMillisecondsCancelledEmergencyMoveFor=1000+((int)(Bot.Target.CurrentTarget.CentreDistance/25f)*1000);
                                                }
                                                else
                                                {
                                                     resetTarget=true;
                                                }
                                         }
                                    }

                                    if (resetTarget)
                                    {
                                         CurrentTarget=CurrentTargetRAGUID!=-1?ObjectCache.Objects[CurrentTargetRAGUID]:null;
                                         continue;
                                    }

                                    iHighestWeightFound=thisobj.Weight;
                             }

                        } // Loop through all the objects and give them a weight
        }
示例#9
0
 public CacheDestructable(CacheObject baseobj)
     : base(baseobj)
 {
 }
示例#10
0
 public CacheGizmo(CacheObject baseobj)
     : base(baseobj)
 {
 }
示例#11
0
        //internal bool UsedAutoMovementCommand=false;
        internal static RunStatus TargetMoveTo(CacheObject obj)
        {
            #region DebugInfo
                     if (Bot.SettingsFunky.DebugStatusBar)
                     {
                          string Action="[Move-";
                          switch (obj.targetType.Value)
                          {
                                case TargetType.Avoidance:
                                     Action+="Avoid] ";
                                     break;
                                case TargetType.Unit:
                                     if (obj.LOSV3!=Vector3.Zero)
                                          Action+="LOS] ";
                                     else if (Bot.NavigationCache.groupRunningBehavior&&Bot.NavigationCache.groupingCurrentUnit!=null&&Bot.NavigationCache.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;
                          }
                          Bot.Target.UpdateStatusText(Action);
                     }
                     #endregion

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

                     if (Bot.SettingsFunky.SkipAhead)
                          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.)
                     if (NonMovementCounter>50)
                     {
                          Logging.WriteVerbose("{0}: Ignoring obj {1} due to no movement counter reaching {2}", "[Funky]", obj.InternalName+" _ SNO:"+obj.SNOID, NonMovementCounter);
                          obj.BlacklistLoops=50;
                          obj.RequiresLOSCheck=true;
                          Bot.Combat.bForceTargetUpdate=true;
                          NonMovementCounter=0;

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

                     Bot.NavigationCache.RefreshMovementCache();
                     Bot.NavigationCache.ObstaclePrioritizeCheck();

                     #region DistanceChecks

                     // Count how long we have failed to move - body block stuff etc.
                     if (!Bot.NavigationCache.IsMoving||Bot.NavigationCache.currentMovementState.Equals(MovementState.WalkingInPlace)||Bot.NavigationCache.currentMovementState.Equals(MovementState.None))
                     {
                          bForceNewMovement=true;
                          if (DateTime.Now.Subtract(LastMovementDuringCombat).TotalMilliseconds>=250)
                          {
                                LastMovementDuringCombat=DateTime.Now;
                                // We've been stuck at least 250 ms, let's go and pick new targets etc.
                                BlockedMovementCounter++;
                                Bot.Combat.bForceCloseRangeTarget=true;
                                Bot.Combat.lastForcedKeepCloseRange=DateTime.Now;

                                // Tell target finder to prioritize close-combat targets incase we were bodyblocked
                                #region TargetingPriortize
                                switch (BlockedMovementCounter)
                                {
                                     case 2:
                                     case 3:
                                          //Than check our movement state
                                          //If we are moving to a LOS location.. nullify it!
                                          if (obj.LOSV3!=Vector3.Zero)
                                          {
                                                Logging.WriteVerbose("Blockcounter Reseting LOS Movement Vector");
                                                obj.LOSV3=Vector3.Zero;
                                          }

                                          var intersectingObstacles=Bot.Combat.NearbyObstacleObjects //ObjectCache.Obstacles.Values.OfType<CacheServerObject>()
                                                                                    .Where(obstacle =>
                                                                                         !Bot.Combat.PrioritizedRAGUIDs.Contains(obstacle.RAGUID)//Only objects not already prioritized
                                                                                         &&obstacle.Obstacletype.HasValue
                                                                                         &&ObstacleType.Navigation.HasFlag(obstacle.Obstacletype.Value)//only navigation/intersection blocking objects!
                                                                                         &&obstacle.RadiusDistance<=10f);

                                          if (intersectingObstacles.Any())
                                          {
                                                var intersectingObjectRAGUIDs=(from objs in intersectingObstacles
                                                                                         select objs.RAGUID);

                                                Bot.Combat.PrioritizedRAGUIDs.AddRange(intersectingObjectRAGUIDs);
                                          }

                                          if (Bot.NavigationCache.groupRunningBehavior)
                                          {
                                                Logging.WriteVerbose("Grouping Behavior stopped due to blocking counter");
                                                Bot.NavigationCache.GroupingFinishBehavior();
                                                Bot.NavigationCache.groupingSuspendedDate=DateTime.Now.AddMilliseconds(2500);
                                                Bot.Combat.bForceTargetUpdate=true;
                                                return RunStatus.Running;
                                          }

                                          if (obj.targetType.Value==TargetType.Avoidance)
                                          {//Avoidance Movement..
                                                Bot.Combat.timeCancelledFleeMove=DateTime.Now;
                                                Bot.Combat.timeCancelledEmergencyMove=DateTime.Now;
                                                Bot.NavigationCache.BlacklistLastSafespot();
                                                Bot.UpdateAvoidKiteRates();
                                                Bot.Combat.bForceTargetUpdate=true;
                                                return RunStatus.Running;
                                          }

                                          break;
                                     default:
                                          if (obj.targetType.Value!=TargetType.Avoidance)
                                          {
                                                //Finally try raycasting to see if navigation is possible..
                                                if (obj.Actortype.HasValue&&
                                                     (obj.Actortype.Value==ActorType.Gizmo||obj.Actortype.Value==ActorType.Unit))
                                                {
                                                     Vector3 hitTest;
                                                     // No raycast available, try and force-ignore this for a little while, and blacklist for a few seconds
                                                     if (Zeta.Navigation.Navigator.Raycast(Bot.Character.Position, obj.Position, out hitTest))
                                                     {
                                                          if (hitTest!=Vector3.Zero)
                                                          {
                                                                obj.RequiresLOSCheck=true;
                                                                obj.BlacklistLoops=10;
                                                                Logging.WriteDiagnostic("Ignoring object "+obj.InternalName+" due to not moving and raycast failure!", true);
                                                                Bot.Combat.bForceTargetUpdate=true;
                                                                return RunStatus.Running;
                                                          }
                                                     }
                                                }
                                                else if (obj.Actortype.HasValue&&obj.Actortype.Value.HasFlag(ActorType.Item))
                                                {
                                                     Bot.Combat.timeCancelledEmergencyMove=DateTime.Now;
                                                     Bot.Combat.timeCancelledFleeMove=DateTime.Now;

                                                     //Check if we can walk to this location from current location..
                                                     if (!Navigation.CanRayCast(Bot.Character.Position, CurrentTargetLocation, NavCellFlags.AllowWalk))
                                                     {
                                                          obj.BlacklistLoops=10;
                                                          obj.RequiresLOSCheck=true;
                                                          Logging.WriteDiagnostic("Ignoring Item {0} -- due to AllowWalk RayCast Failure!", obj.InternalName);
                                                          Bot.Combat.bForceTargetUpdate=true;
                                                          return RunStatus.Running;
                                                     }
                                                }
                                          }
                                          else
                                          {
                                                if (!Navigation.CanRayCast(Bot.Character.Position, CurrentTargetLocation, NavCellFlags.AllowWalk))
                                                {
                                                     Logging.WriteVerbose("Cannot continue with avoidance movement due to raycast failure!");
                                                     BlockedMovementCounter=0;

                                                     Bot.Combat.iMillisecondsCancelledEmergencyMoveFor/=2;
                                                     Bot.Combat.timeCancelledEmergencyMove=DateTime.Now;
                                                     //Ignore avoidance movements.
                                                     Bot.Combat.iMillisecondsCancelledFleeMoveFor/=2;
                                                     Bot.Combat.timeCancelledFleeMove=DateTime.Now;

                                                     Bot.NavigationCache.BlacklistLastSafespot();
                                                     Bot.Combat.bForceTargetUpdate=true;
                                                     return RunStatus.Running;
                                                }
                                          }
                                          break;
                                }
                                #endregion

                                if (obj.targetType.Value==TargetType.Item)
                                {
                                     obj.BlacklistLoops=1;
                                     Bot.Combat.bForceTargetUpdate=true;
                                }

                                return RunStatus.Running;
                          } // Been 250 milliseconds of non-movement?
                     }
                     else
                     {
                          // Movement has been made, so count the time last moved!
                          LastMovementDuringCombat=DateTime.Now;
                     }
                     #endregion

                     // Update the last distance stored
                     LastDistanceFromTarget=obj.DistanceFromTarget;

                     // 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;
                     }

                     float currentDistance=Vector3.Distance(LastTargetLocation, CurrentTargetLocation);

                     // If we're doing avoidance, globes or backtracking, try to use special abilities to move quicker
                     #region SpecialMovementChecks
                     if ((TargetType.Avoidance|TargetType.Gold|TargetType.Globe).HasFlag(obj.targetType.Value))
                     {

                          bool bTooMuchZChange=((Bot.Character.Position.Z-CurrentTargetLocation.Z)>=4f);

                          Ability MovementPower;
                          if (Bot.Class.FindMovementPower(out MovementPower))
                          {
                                double lastUsedAbilityMS=MovementPower.LastUsedMilliseconds;
                                bool foundMovementPower=false;
                                float pointDistance=0f;
                                Vector3 vTargetAimPoint=CurrentTargetLocation;
                                bool ignoreLOSTest=false;

                                switch (MovementPower.Power)
                                {
                                     case SNOPower.Monk_TempestRush:
                                          vTargetAimPoint=MathEx.CalculatePointFrom(CurrentTargetLocation, Bot.Character.Position, 10f);
                                          Bot.Character.UpdateAnimationState(false, true);
                                          bool isHobbling=Bot.Character.CurrentSNOAnim.HasFlag(SNOAnim.Monk_Female_Hobble_Run|SNOAnim.Monk_Male_HTH_Hobble_Run);
                                          foundMovementPower=(!bTooMuchZChange&&!Bot.Class.bWaitingForSpecial&&currentDistance<15f&&((isHobbling||lastUsedAbilityMS<300)&&Bot.Character.dCurrentEnergy>15)
                                                &&!ObjectCache.Obstacles.DoesPositionIntersectAny(vTargetAimPoint, ObstacleType.ServerObject));

                                          break;
                                     case SNOPower.DemonHunter_Vault:
                                          foundMovementPower=(obj.targetType.Value!=TargetType.Destructible&&!bTooMuchZChange&&currentDistance>=18f&&
                                                                     (lastUsedAbilityMS>=Bot.SettingsFunky.Class.iDHVaultMovementDelay));
                                          pointDistance=35f;
                                          if (currentDistance>pointDistance)
                                                vTargetAimPoint=MathEx.CalculatePointFrom(CurrentTargetLocation, Bot.Character.Position, pointDistance);
                                          break;
                                     case SNOPower.Barbarian_FuriousCharge:
                                          foundMovementPower=(obj.targetType.Value!=TargetType.Destructible&&!bTooMuchZChange
                                                                     &&(currentDistance>20f||obj.targetType.Value.HasFlag(TargetType.Avoidance)&&(NonMovementCounter>0||BlockedMovementCounter>0)));

                                          pointDistance=35f;
                                          if (currentDistance>pointDistance)
                                                vTargetAimPoint=MathEx.CalculatePointFrom(CurrentTargetLocation, Bot.Character.Position, pointDistance);

                                          break;
                                     case SNOPower.Barbarian_Leap:
                                     case SNOPower.Wizard_Archon_Teleport:
                                     case SNOPower.Wizard_Teleport:
                                          foundMovementPower=(obj.targetType.Value!=TargetType.Destructible&&!bTooMuchZChange
                                                                     &&(currentDistance>20f||obj.targetType.Value.HasFlag(TargetType.Avoidance)&&(NonMovementCounter>0||BlockedMovementCounter>0)));

                                          pointDistance=35f;
                                          if (currentDistance>pointDistance)
                                                vTargetAimPoint=MathEx.CalculatePointFrom(CurrentTargetLocation, Bot.Character.Position, pointDistance);

                                          //Teleport and Leap ignores raycast testing below!
                                          ignoreLOSTest=true;
                                          break;
                                     case SNOPower.Barbarian_Whirlwind:
                                          break;
                                     default:
                                          Bot.Character.WaitWhileAnimating(3, true);

                                          ZetaDia.Me.UsePower(MovementPower.Power, CurrentTargetLocation, Bot.Character.iCurrentWorldID, -1);
                                          MovementPower.LastUsed=DateTime.Now;

                                          Bot.Character.WaitWhileAnimating(6, true);
                                          // 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(Bot.Combat.lastForcedKeepCloseRange).TotalMilliseconds>=2000)
                                                BlockedMovementCounter=0;
                                          return RunStatus.Running;
                                }

                                if (foundMovementPower)
                                {

                                     if ((MovementPower.Power==SNOPower.Monk_TempestRush&&lastUsedAbilityMS>500)||
                                          (ignoreLOSTest||ZetaDia.Physics.Raycast(Bot.Character.Position, vTargetAimPoint, NavCellFlags.AllowWalk)))
                                     {
                                          ZetaDia.Me.UsePower(MovementPower.Power, vTargetAimPoint, Bot.Character.iCurrentWorldID, -1);
                                          MovementPower.LastUsed=DateTime.Now;

                                          // 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(Bot.Combat.lastForcedKeepCloseRange).TotalMilliseconds>=2000)
                                                BlockedMovementCounter=0;
                                          return RunStatus.Running;
                                     }
                                }
                          }

                          //Special Whirlwind Code
                          if (Bot.Class.AC==Zeta.Internals.Actors.ActorClass.Barbarian&&Bot.Class.HotbarPowers.Contains(SNOPower.Barbarian_Whirlwind))
                          {
                                // Whirlwind against everything within range (except backtrack points)
                                if (Bot.Character.dCurrentEnergy>=10
                                     &&Bot.Combat.iAnythingWithinRange[(int)RangeIntervals.Range_20]>=1
                                     &&obj.DistanceFromTarget<=12f
                                     &&(!Bot.Class.HotbarPowers.Contains(SNOPower.Barbarian_Sprint)||Bot.Class.HasBuff(SNOPower.Barbarian_Sprint))
                                     &&(!(TargetType.Avoidance|TargetType.Gold|TargetType.Globe).HasFlag(obj.targetType.Value)&obj.DistanceFromTarget>=6f)
                                     &&(obj.targetType.Value!=TargetType.Unit
                                     ||(obj.targetType.Value==TargetType.Unit&&!obj.IsTreasureGoblin
                                          &&(!Bot.SettingsFunky.Class.bSelectiveWhirlwind
                                                ||Bot.Combat.bAnyNonWWIgnoreMobsInRange
                                                ||!CacheIDLookup.hashActorSNOWhirlwindIgnore.Contains(obj.SNOID)))))
                                {
                                     // Special code to prevent whirlwind double-spam, this helps save fury
                                     bool bUseThisLoop=SNOPower.Barbarian_Whirlwind!=Bot.Combat.powerLastSnoPowerUsed;
                                     if (!bUseThisLoop)
                                     {
                                          Bot.Combat.powerLastSnoPowerUsed=SNOPower.None;
                                            if (DateTime.Now.Subtract(PowerCacheLookup.dictAbilityLastUse[SNOPower.Barbarian_Whirlwind]).TotalMilliseconds>=200)
                                                bUseThisLoop=true;
                                     }
                                     if (bUseThisLoop)
                                     {
                                          ZetaDia.Me.UsePower(SNOPower.Barbarian_Whirlwind, CurrentTargetLocation, Bot.Character.iCurrentWorldID, -1);
                                          Bot.Combat.powerLastSnoPowerUsed=SNOPower.Barbarian_Whirlwind;
                                            PowerCacheLookup.dictAbilityLastUse[SNOPower.Barbarian_Whirlwind]=DateTime.Now;
                                     }
                                     // Store the current destination for comparison incase of changes next loop
                                     LastTargetLocation=CurrentTargetLocation;
                                     // Reset total body-block count
                                     if ((!Bot.Combat.bForceCloseRangeTarget||DateTime.Now.Subtract(Bot.Combat.lastForcedKeepCloseRange).TotalMilliseconds>Bot.Combat.iMillisecondsForceCloseRange)&&
                                         DateTime.Now.Subtract(Bot.Combat.lastForcedKeepCloseRange).TotalMilliseconds>=2000)
                                          BlockedMovementCounter=0;
                                     return RunStatus.Running;
                                }
                          }
                     }
                     #endregion

                     // Now for the actual movement request stuff
                     IsAlreadyMoving=true;
                     LastMovementCommand=DateTime.Now;

                     if (DateTime.Now.Subtract(LastMovementAttempted).TotalMilliseconds>=250||currentDistance>=2f||bForceNewMovement)
                     {
                          if (obj.targetType.Value.Equals(TargetType.Avoidance))
                          {
                                if (NonMovementCounter<10)
                                     ZetaDia.Me.Movement.MoveActor(CurrentTargetLocation);
                                else
                                     ZetaDia.Me.UsePower(SNOPower.Walk, CurrentTargetLocation, Bot.Character.iCurrentWorldID, -1);
                          }
                          else
                          {
                                //Use Walk Power when not using LOS Movement, target is not an item and target does not ignore LOS.
                                bool UsePower=(NonMovementCounter<10&&!obj.UsingLOSV3&&obj.targetType.Value!=TargetType.Item&&!obj.IgnoresLOSCheck);
                                if (UsePower)
                                {
                                     ZetaDia.Me.UsePower(SNOPower.Walk, CurrentTargetLocation, Bot.Character.iCurrentWorldID, -1);
                                }
                                else
                                     ZetaDia.Me.Movement.MoveActor(CurrentTargetLocation);
                          }

                          LastMovementAttempted=DateTime.Now;
                          // 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(Bot.Combat.lastForcedKeepCloseRange).TotalMilliseconds>=2000)
                                BlockedMovementCounter=0;

                          //Herbfunk: Quick fix for stuck occuring on above average mob who is damaged..
                          if (LastPlayerLocation==Bot.Character.Position)
                                NonMovementCounter++;
                          else
                                NonMovementCounter=0;

                          LastPlayerLocation=Bot.Character.Position;
                     }

                     return RunStatus.Running;
        }
示例#12
0
            ///<summary>
            ///Adds/Updates CacheObjects inside collection by Iteration of RactorList
            ///This is the method that caches all live data about an object!
            ///</summary>
            public static bool UpdateCacheObjectCollection()
            {
                if (!ZetaDia.IsInGame) return false;

                     HashSet<int> hashDoneThisRactor=new HashSet<int>();
                     foreach (Actor thisActor in ZetaDia.Actors.RActorList)
                     {
                          int tmp_raGUID;
                          DiaObject thisObj;

                          if (!thisActor.IsValid) continue;
                          //Convert to DiaObject
                          thisObj=(DiaObject)thisActor;
                          tmp_raGUID=thisObj.RActorGuid;

                          // See if we've already checked this ractor, this loop
                          if (hashDoneThisRactor.Contains(tmp_raGUID)) continue;
                          hashDoneThisRactor.Add(tmp_raGUID);

                          //Update RactorGUID and check blacklisting..
                          if (ObjectCache.IsRAGUIDBlacklisted(tmp_raGUID)) continue;
                          CacheObject tmp_CachedObj;
                          using (ZetaDia.Memory.AcquireFrame())
                          {
                                if (!ObjectCache.Objects.TryGetValue(tmp_raGUID, out tmp_CachedObj))
                                {
                                     Vector3 tmp_position;
                                     int tmp_acdguid;
                                     int tmp_SNOID;

                                     #region SNO
                                     //Lookup SNO
                                     try
                                     {
                                          tmp_SNOID=thisObj.ActorSNO;
                                     } catch (NullReferenceException) { Logging.WriteVerbose("Failure to get SNO from object! RaGUID: {0}", tmp_raGUID); continue; }
                                     #endregion

                                     //check our SNO blacklist
                                     if (ObjectCache.IsSNOIDBlacklisted(tmp_SNOID)&&!CacheIDLookup.hashSummonedPets.Contains(tmp_SNOID)) continue;

                                     #region Position
                                     try
                                     {
                                          tmp_position=thisObj.Position;
                                     } catch (NullReferenceException) { Logging.WriteVerbose("Failure to get position vector for RAGUID {0}", tmp_raGUID); continue; }

                                     #endregion

                                     #region AcdGUID
                                     try
                                     {
                                          tmp_acdguid=thisObj.ACDGuid;
                                     } catch (NullReferenceException) { Logging.WriteVerbose("Failure to get ACDGUID for RAGUID {0}", tmp_raGUID); continue; }

                                     #endregion

                                     tmp_CachedObj=new CacheObject(tmp_SNOID, tmp_raGUID, tmp_acdguid, tmp_position);
                                }
                                else
                                     //Reset unseen var
                                     tmp_CachedObj.LoopsUnseen=0;

                                //Validate
                                try
                                {
                                     if (thisObj.CommonData==null||thisObj.CommonData.ACDGuid!=thisObj.ACDGuid) continue;
                                } catch (NullReferenceException)
                                {
                                     continue;
                                }

                                //Check if this object is a summoned unit by a player...
                                #region SummonedUnits
                                if (tmp_CachedObj.IsSummonedPet)
                                {
                                     // Get the summoned-by info, cached if possible
                                     if (!tmp_CachedObj.SummonerID.HasValue)
                                     {
                                          try
                                          {
                                                tmp_CachedObj.SummonerID=thisObj.CommonData.GetAttribute<int>(ActorAttributeType.SummonedByACDID);
                                          } catch (Exception ex)
                                          {
                                                Logging.WriteVerbose("[Funky] Safely handled exception getting summoned-by info ["+tmp_CachedObj.SNOID.ToString()+"]");
                                                Logging.WriteDiagnostic(ex.ToString());
                                                continue;
                                          }
                                     }

                                     //See if this summoned unit was summoned by the bot.
                                     if (Bot.Character.iMyDynamicID==tmp_CachedObj.SummonerID.Value)
                                     {
                                          //Now modify the player data pets count..
                                          if (Bot.Class.AC==ActorClass.Monk)
                                                Bot.Character.PetData.MysticAlly++;
                                          else if (Bot.Class.AC==ActorClass.DemonHunter&&CacheIDLookup.hashDHPets.Contains(tmp_CachedObj.SNOID))
                                                Bot.Character.PetData.DemonHunterPet++;
                                          else if (Bot.Class.AC==ActorClass.WitchDoctor)
                                          {
                                                if (CacheIDLookup.hashZombie.Contains(tmp_CachedObj.SNOID))
                                                     Bot.Character.PetData.ZombieDogs++;
                                                else if (CacheIDLookup.hashGargantuan.Contains(tmp_CachedObj.SNOID))
                                                     Bot.Character.PetData.Gargantuan++;
                                          }
                                          else if (Bot.Class.AC==Zeta.Internals.Actors.ActorClass.Wizard)
                                          {
                                                //only count when range is within 45f (so we can summon a new one)
                                                if (CacheIDLookup.hashWizHydras.Contains(tmp_CachedObj.SNOID)&&tmp_CachedObj.CentreDistance<=45f)
                                                     Bot.Character.PetData.WizardHydra++;
                                          }
                                     }

                                     //We return regardless if it was summoned by us or not since this object is not anything we want to deal with..
                                     tmp_CachedObj.NeedsRemoved=true;
                                     continue;
                                }
                                #endregion

                                //Update any SNO Data.
                                #region SNO_Cache_Update
                                if (tmp_CachedObj.ref_DiaObject==null||tmp_CachedObj.ContainsNullValues())
                                {
                                     if (!tmp_CachedObj.UpdateData(thisObj, tmp_CachedObj.RAGUID))
                                          continue;
                                }
                                else if (!tmp_CachedObj.IsFinalized)
                                {//Finalize this data by recreating it and updating the Sno cache with a new finalized entry, this also clears our all Sno cache dictionaries since we no longer need them!
                                     ObjectCache.cacheSnoCollection.FinalizeEntry(tmp_CachedObj.SNOID);
                                }
                                #endregion

                                //Objects with static positions already cached don't need to be updated here.
                                if (!tmp_CachedObj.NeedsUpdate) continue;

                                //Obstacles -- (Not an actual object we add to targeting.)
                                if (tmp_CachedObj.targetType.Value==TargetType.Avoidance||tmp_CachedObj.IsObstacle||tmp_CachedObj.HandleAsAvoidanceObject)
                                {
                                     #region Obstacles
                                     bool bRequireAvoidance=false;
                                     bool bTravellingAvoidance=false;

                                     CacheObstacle thisObstacle;

                                     //Do we have this cached?
                                     if (!ObjectCache.Obstacles.TryGetValue(tmp_CachedObj.RAGUID, out thisObstacle))
                                     {
                                          AvoidanceType AvoidanceType=AvoidanceType.Unknown;
                                          if (tmp_CachedObj.IsAvoidance)
                                          {
                                                AvoidanceType=CacheIDLookup.FindAvoidanceUsingSNOID(tmp_CachedObj.SNOID);
                                                if (AvoidanceType==AvoidanceType.Unknown)
                                                {
                                                     AvoidanceType=CacheIDLookup.FindAvoidanceUsingName(tmp_CachedObj.InternalName);
                                                     if (AvoidanceType==AvoidanceType.Unknown) continue;
                                                }
                                          }

                                          if (tmp_CachedObj.IsAvoidance&&tmp_CachedObj.IsProjectileAvoidance)
                                          {//Ranged Projectiles require more than simple bounding points.. so we create it as avoidance zone to cache it with properties.
                                                //Check for intersection..
                                                ActorMovement thisMovement=thisObj.Movement;

                                                Vector2 Direction=thisMovement.DirectionVector;
                                                Ray R=new Ray(tmp_CachedObj.Position, Direction.ToVector3());
                                                double Speed;
                                                //Lookup Cached Speed, or add new entry.
                                                if (!ObjectCache.dictProjectileSpeed.TryGetValue(tmp_CachedObj.SNOID, out Speed))
                                                {
                                                     Speed=thisMovement.DesiredSpeed;
                                                     ObjectCache.dictProjectileSpeed.Add(tmp_CachedObj.SNOID, Speed);
                                                }

                                                thisObstacle=new CacheAvoidance(tmp_CachedObj, AvoidanceType, R, Speed);
                                                ObjectCache.Obstacles.Add(thisObstacle);
                                          }
                                          else if (tmp_CachedObj.IsAvoidance)
                                          {
                                                thisObstacle=new CacheAvoidance(tmp_CachedObj, AvoidanceType);
                                                ObjectCache.Obstacles.Add(thisObstacle);
                                          }
                                          else
                                          {
                                                //Obstacles.
                                                thisObstacle=new CacheServerObject(tmp_CachedObj);
                                                ObjectCache.Obstacles.Add(thisObstacle);
                                                continue;
                                          }
                                     }

                                     //Test if this avoidance requires movement now.
                                     if (thisObstacle is CacheAvoidance)
                                     {
                                          //Check last time we attempted avoidance movement (Only if its been at least a second since last time we required it..)
                                          //if (DateTime.Now.Subtract(Bot.Combat.LastAvoidanceMovement).TotalMilliseconds<1000)
                                          //continue;

                                          CacheAvoidance thisAvoidance=thisObstacle as CacheAvoidance;

                                          if (Bot.IgnoreAvoidance(thisAvoidance.AvoidanceType)) continue;

                                          //Only update position of Movement Avoidances!
                                          if (thisAvoidance.Obstacletype.Value==ObstacleType.MovingAvoidance)
                                          {
                                                //Blacklisted updates
                                                if (thisAvoidance.BlacklistRefreshCounter>0&&
                                                     !thisAvoidance.CheckUpdateForProjectile)
                                                {
                                                     thisAvoidance.BlacklistRefreshCounter--;
                                                }

                                                bRequireAvoidance=thisAvoidance.UpdateProjectileRayTest(tmp_CachedObj.Position);
                                                //If we need to avoid, than enable travel avoidance flag also.
                                                if (bRequireAvoidance) bTravellingAvoidance=true;
                                          }
                                          else
                                          {
                                                if (thisObstacle.CentreDistance<50f)
                                                     Bot.Combat.NearbyAvoidances.Add(thisObstacle.RAGUID);

                                                if (thisAvoidance.Position.Distance(Bot.Character.Position)<=thisAvoidance.Radius)
                                                     bRequireAvoidance=true;
                                          }

                                          Bot.Combat.RequiresAvoidance=bRequireAvoidance;
                                          Bot.Combat.TravellingAvoidance=bTravellingAvoidance;
                                          if (bRequireAvoidance)
                                                Bot.Combat.TriggeringAvoidances.Add((CacheAvoidance)thisObstacle);
                                     }
                                     else
                                     {
                                          //Add this server object to cell weighting in MGP
                                          //MGP.AddCellWeightingObstacle(thisObstacle.SNOID, thisObstacle.CollisionRadius.Value);

                                          //Add nearby objects to our collection (used in navblock/obstaclecheck methods to reduce queries)
                                          if (thisObstacle.CentreDistance<25f)
                                                Bot.Combat.NearbyObstacleObjects.Add((CacheServerObject)thisObstacle);
                                     }

                                     continue;
                                     #endregion
                                }

                                if (tmp_CachedObj.ObjectShouldBeRecreated)
                                {
                                     //Specific updates
                                     if (tmp_CachedObj.Actortype.Value==ActorType.Item)
                                     {
                                          tmp_CachedObj=new CacheItem(tmp_CachedObj);
                                     }
                                     else if (tmp_CachedObj.Actortype.Value==ActorType.Unit)
                                     {
                                          tmp_CachedObj=new CacheUnit(tmp_CachedObj);
                                     }
                                     else if (tmp_CachedObj.Actortype.Value==ActorType.Gizmo)
                                     {

                                          if (TargetType.Interactables.HasFlag(tmp_CachedObj.targetType.Value))
                                                tmp_CachedObj=new CacheInteractable(tmp_CachedObj);
                                          else
                                                tmp_CachedObj=new CacheDestructable(tmp_CachedObj);
                                     }
                                }

                                if (!tmp_CachedObj.UpdateData())
                                     continue;

                                //Obstacle cache
                                if (tmp_CachedObj.Obstacletype.Value!=ObstacleType.None
                                     &&(TargetType.ServerObjects.HasFlag(tmp_CachedObj.targetType.Value)))
                                {
                                     CacheObstacle thisObstacleObj;

                                     if (!ObjectCache.Obstacles.TryGetValue(tmp_CachedObj.RAGUID, out thisObstacleObj))
                                     {
                                          ObjectCache.Obstacles.Add(tmp_CachedObj.RAGUID, new CacheServerObject(tmp_CachedObj));
                                     }
                                     else
                                     {
                                          if (thisObstacleObj.targetType.Value==TargetType.Unit)
                                          {
                                                //Since units position requires updating, we update using the CacheObject
                                                thisObstacleObj.Position=tmp_CachedObj.Position;
                                                ObjectCache.Obstacles[tmp_CachedObj.RAGUID]=thisObstacleObj;
                                          }
                                          if (thisObstacleObj.CentreDistance<=25f)
                                                Bot.Combat.NearbyObstacleObjects.Add((CacheServerObject)thisObstacleObj);
                                     }
                                     //Add nearby objects to our collection (used in navblock/obstaclecheck methods to reduce queries)

                                }

                                //cache it
                                if (ObjectCache.Objects.ContainsKey(tmp_CachedObj.RAGUID))
                                     ObjectCache.Objects[tmp_CachedObj.RAGUID]=tmp_CachedObj;
                                else
                                     ObjectCache.Objects.Add(tmp_CachedObj.RAGUID, tmp_CachedObj);

                          }
                     } //End of Loop

                     //Tally up unseen objects.
                     var UnseenObjects=ObjectCache.Objects.Keys.Where<int>(O => !hashDoneThisRactor.Contains(O)).ToList();
                     if (UnseenObjects.Count()>0)
                     {
                          for (int i=0; i<UnseenObjects.Count(); i++)
                          {
                                ObjectCache.Objects[UnseenObjects[i]].LoopsUnseen++;
                          }
                     }

                     //Trim our collection every 5th refresh.
                     UpdateLoopCounter++;
                     if (UpdateLoopCounter>4)
                     {
                          UpdateLoopCounter=0;
                          //Now flag any objects not seen for 5 loops. Gold/Globe only 1 loop.
                          foreach (var item in ObjectCache.Objects.Values.Where<CacheObject>(CO => CO.LoopsUnseen>=5||
                                (CO.targetType.HasValue&&(CO.targetType.Value==TargetType.Gold||CO.targetType.Value==TargetType.Globe)&&CO.LoopsUnseen>0)))
                          {
                                item.NeedsRemoved=true;
                          }
                     }

                     return true;
            }
示例#13
0
        ///<summary>
        ///Update our current object data ("Current Target")
        ///</summary>
        public bool UpdateTarget()
        {
            //Generate a vaild object list using our cached collection!
                        Bot.ValidObjects=ObjectCache.Objects.Values.Where(obj => obj.ObjectIsValidForTargeting).ToList();

                        //Check avoidance requirement still valid
                        if (Bot.Combat.RequiresAvoidance&&
                                        Bot.Combat.TriggeringAvoidances.Count==0&&
                                        (!Bot.SettingsFunky.EnableFleeingBehavior||Bot.Character.dCurrentHealthPct>0.25d)) Bot.Combat.RequiresAvoidance=false;

                        #region Grouping Behavior Resume

                        if (Bot.NavigationCache.groupRunningBehavior)
                        {
                             if (!Bot.NavigationCache.groupReturningToOrgin)
                             {
                                  Bot.Combat.UpdateGroupClusteringVariables();

                                  bool EndBehavior=false;
                                  if (!Bot.NavigationCache.groupingCurrentUnit.ObjectIsValidForTargeting)
                                  {
                                        if (Bot.SettingsFunky.LogGroupingOutput)
                                             Logging.WriteVerbose("[Grouping] Target is no longer valid. Starting return to Orgin.");

                                        EndBehavior=true;
                                  }
                                  else if (Bot.NavigationCache.groupingCurrentUnit.CurrentHealthPct.Value<1d
                                        &&Bot.NavigationCache.groupingCurrentUnit.IsMoving)
                                  {
                                        if (Bot.SettingsFunky.LogGroupingOutput)
                                             Logging.WriteVerbose("[Grouping] Target has been engaged. Starting return to Orgin.");

                                        EndBehavior=true;
                                  }

                                  if (!EndBehavior)
                                  {
                                        CurrentTarget=Bot.NavigationCache.groupingCurrentUnit;
                                        return true;
                                  }
                                  else
                                  {
                                        Bot.NavigationCache.groupingCurrentUnit=null;
                                        Bot.NavigationCache.groupReturningToOrgin=true;
                                        CurrentTarget=Bot.NavigationCache.groupingOrginUnit;
                                        return true;
                                  }

                             }
                             else
                             {
                                  bool endBehavior=false;

                                  //Returning to Orgin Unit..
                                  if (!Bot.NavigationCache.groupingOrginUnit.ObjectIsValidForTargeting)
                                  {
                                        endBehavior=true;

                                        if (Bot.SettingsFunky.LogGroupingOutput)
                                             Logging.WriteVerbose("[Grouping] Orgin Target is no longer valid for targeting.");
                                  }
                                  else if (Bot.NavigationCache.groupingOrginUnit.CentreDistance<(Bot.Class.IsMeleeClass?25f:45f))
                                  {
                                        if (Bot.SettingsFunky.LogGroupingOutput)
                                             Logging.WriteVerbose("[Grouping] Orgin Target is within {0}f of the bot.", (Bot.Class.IsMeleeClass?25f:45f).ToString());

                                        endBehavior=true;
                                  }

                                  if (!endBehavior)
                                  {
                                        CurrentTarget=Bot.NavigationCache.groupingOrginUnit;
                                        return true;
                                  }
                                  else
                                        Bot.NavigationCache.GroupingFinishBehavior();
                             }
                        }
                        #endregion

                        Vector3 LOS=Vector3.Zero;

                        //Check if we require avoidance movement.
                        #region AvodianceMovementCheck

                        if (Bot.Combat.RequiresAvoidance&&(!Bot.Combat.bAnyTreasureGoblinsPresent||Bot.SettingsFunky.GoblinPriority<2)
                            &&(DateTime.Now.Subtract(Bot.Combat.timeCancelledEmergencyMove).TotalMilliseconds>Bot.Combat.iMillisecondsCancelledEmergencyMoveFor))
                        {

                             //Reuse the last generated safe spot...
                             if (DateTime.Now.Subtract(Bot.Combat.LastAvoidanceMovement).TotalMilliseconds>=
                                     Bot.Combat.iSecondsEmergencyMoveFor)
                             {
                                    Vector3 reuseV3=Bot.NavigationCache.AttemptToReuseLastLocationFound();
                                    if (reuseV3!=Vector3.Zero)
                                    {

                                         CurrentTarget=new CacheObject(reuseV3, TargetType.Avoidance, 20000f, "SafeAvoid", 2.5f, -1);
                                         return true;

                                    }
                             }

                             Vector3 vAnySafePoint;
                             //if (CurrentTarget!=null&&CurrentTarget.targetType.HasValue&&TargetType.ServerObjects.HasFlag(CurrentTarget.targetType.Value))
                             //    LOS=CurrentTarget.Position;
                             //else
                             //    LOS=Vector3.Zero;

                             if (Bot.NavigationCache.AttemptFindSafeSpot(out vAnySafePoint, LOS, Bot.Character.ShouldFlee))
                             {
                                    float distance=vAnySafePoint.Distance(Bot.Character.Position);

                                    float losdistance=0f;
                                    if (LOS!=Vector3.Zero) losdistance=LOS.Distance(Bot.Character.Position);

                                    string los=LOS!=Vector3.Zero?("\r\n using LOS location "+LOS.ToString()+" distance "+losdistance.ToString()):" ";

                                    Logging.WriteDiagnostic("Avoid Movement found AT {0} with {1} Distance", vAnySafePoint.ToString(), distance);
                                    //bFoundSafeSpot = true;

                                    //setup avoidance target
                                    if (CurrentTarget!=null) Bot.Combat.LastCachedTarget=CurrentTarget.Clone();
                                    CurrentTarget=new CacheObject(vAnySafePoint, TargetType.Avoidance, 20000f, "SafeAvoid", 2.5f, -1);

                                    //Estimate time we will be reusing this movement vector3
                                    Bot.Combat.iSecondsEmergencyMoveFor=1+(int)(distance/25f);

                                    //Avoidance takes priority over kiting..
                                    Bot.Combat.timeCancelledFleeMove=DateTime.Now;
                                    Bot.Combat.iMillisecondsCancelledFleeMoveFor=((Bot.Combat.iSecondsEmergencyMoveFor+1)*1000);

                                    return true;
                             }

                             Bot.UpdateAvoidKiteRates();
                        }
                        #endregion

                        Bot.Combat.bStayPutDuringAvoidance=false;

                        //cluster update
                        Bot.Combat.UpdateTargetClusteringVariables();

                        //Standard weighting of valid objects -- updates current target.
                        this.WeightEvaluationObjList();

                        //check Fleeing
                        #region Fleeing
                        if (Bot.SettingsFunky.EnableFleeingBehavior&&Bot.Character.dCurrentHealthPct<=Bot.SettingsFunky.FleeBotMinimumHealthPercent&&Bot.Combat.FleeTriggeringUnits.Count>0
                             &&(DateTime.Now.Subtract(Bot.Combat.timeCancelledFleeMove).TotalMilliseconds>Bot.Combat.iMillisecondsCancelledFleeMoveFor)
                             &&(!Bot.Combat.bAnyTreasureGoblinsPresent||Bot.SettingsFunky.GoblinPriority<2)
                             &&(Bot.Class.AC!=ActorClass.Wizard||(Bot.Class.AC==ActorClass.Wizard&&(!Bot.Class.HasBuff(SNOPower.Wizard_Archon)||!Bot.SettingsFunky.Class.bKiteOnlyArchon))))
                        {

                             //Resuse last safespot until timer expires!
                             if (DateTime.Now.Subtract(Bot.Combat.LastFleeAction).TotalSeconds<Bot.Combat.iSecondsFleeMoveFor)
                             {
                                    Vector3 reuseV3=Bot.NavigationCache.AttemptToReuseLastLocationFound();
                                    if (reuseV3!=Vector3.Zero)
                                    {
                                         CurrentTarget=new CacheObject(reuseV3, TargetType.Avoidance, 20000f, "FleeSpot", 2.5f, -1);
                                         return true;
                                    }
                             }

                             if (CurrentTarget!=null&&CurrentTarget.targetType.HasValue&&TargetType.ServerObjects.HasFlag(CurrentTarget.targetType.Value)
                                 &&(Bot.NavigationCache.CurrentGPArea==null||!Bot.NavigationCache.CurrentGPArea.AllGPRectsFailed))
                                    LOS=CurrentTarget.Position;
                             else
                                    LOS=Vector3.Zero;

                             Vector3 vAnySafePoint;
                             if (Bot.NavigationCache.AttemptFindSafeSpot(out vAnySafePoint, LOS, true))
                             {
                                    Logging.WriteDiagnostic("Flee Movement found AT {0} with {1} Distance", vAnySafePoint.ToString(), vAnySafePoint.Distance(Bot.Character.Position));
                                    Bot.Combat.IsFleeing=true;

                                    if (CurrentTarget!=null)
                                         Bot.Character.LastCachedTarget=CurrentTarget;

                                    CurrentTarget=new CacheObject(vAnySafePoint, TargetType.Avoidance, 20000f, "FleeSpot", 2.5f, -1);

                                    Bot.Combat.iSecondsFleeMoveFor=1+(int)(Vector3.Distance(Bot.Character.Position, vAnySafePoint)/25f);
                                    return true;
                             }
                             Bot.UpdateAvoidKiteRates();

                        }

                        //If we have a cached kite target.. and no current target, lets swap back!
                        if (Bot.Combat.FleeingLastTarget&&CurrentTarget==null
                                     &&Bot.Character.LastCachedTarget!=null
                                     &&ObjectCache.Objects.ContainsKey(Bot.Character.LastCachedTarget.RAGUID))
                        {
                             //Swap back to our orginal "kite" target
                             CurrentTarget=ObjectCache.Objects[Bot.Character.LastCachedTarget.RAGUID];
                             Logging.WriteVerbose("Swapping back to unit {0} after fleeing", CurrentTarget.InternalName);
                             return true;
                        }
                        #endregion

                        // No valid targets but we were told to stay put?
                        if (CurrentTarget==null&&Bot.Combat.bStayPutDuringAvoidance)
                        {
                             if (Bot.Combat.TriggeringAvoidances.Count==0)
                             {
                                    CurrentTarget=new CacheObject(Bot.Character.Position, TargetType.Avoidance, 20000, "StayPutPoint", 2.5f, -1);
                                    return true;
                             }
                             else
                                    Bot.Combat.iMillisecondsCancelledEmergencyMoveFor=0; //reset wait time
                        }

                        //Final Possible Target Check
                        if (CurrentTarget==null)
                        {
                             // See if we should wait for milliseconds for possible loot drops before continuing run
                             if (DateTime.Now.Subtract(Bot.Combat.lastHadUnitInSights).TotalMilliseconds<=Bot.SettingsFunky.AfterCombatDelay&&DateTime.Now.Subtract(Bot.Combat.lastHadEliteUnitInSights).TotalMilliseconds<=10000||
                                    //Cut the delay time in half for non-elite monsters!
                                 DateTime.Now.Subtract(Bot.Combat.lastHadUnitInSights).TotalMilliseconds<=Bot.SettingsFunky.AfterCombatDelay)
                             {
                                    CurrentTarget=new CacheObject(Bot.Character.Position, TargetType.Avoidance, 20000, "WaitForLootDrops", 2f, -1);
                                    return true;
                             }
                             //Herbfunks wait after loot containers are opened. 3s for rare chests, half the settings delay for everything else.
                             if ((DateTime.Now.Subtract(Bot.Combat.lastHadRareChestAsTarget).TotalMilliseconds<=3750)||
                                 (DateTime.Now.Subtract(Bot.Combat.lastHadContainerAsTarget).TotalMilliseconds<=(Bot.SettingsFunky.AfterCombatDelay*1.25)))
                             {
                                    CurrentTarget=new CacheObject(Bot.Character.Position, TargetType.Avoidance, 20000, "ContainerLootDropsWait", 2f, -1);
                                    return true;
                             }

                             // Finally, a special check for waiting for wrath of the berserker cooldown before engaging Azmodan
                             if (Bot.Class.HotbarPowers.Contains(SNOPower.Barbarian_WrathOfTheBerserker)&&Bot.SettingsFunky.Class.bWaitForWrath&&!Bot.Class.AbilityUseTimer(SNOPower.Barbarian_WrathOfTheBerserker)&&
                                 ZetaDia.CurrentWorldId==121214&&
                                 (Vector3.Distance(Bot.Character.Position, new Vector3(711.25f, 716.25f, 80.13903f))<=40f||Vector3.Distance(Bot.Character.Position, new Vector3(546.8467f, 551.7733f, 1.576313f))<=40f))
                             {
                                    Logging.Write("[Funky] Waiting for Wrath Of The Berserker cooldown before continuing to Azmodan.");
                                    CurrentTarget=new CacheObject(Bot.Character.Position, TargetType.Avoidance, 20000, "GilesWaitForWrath", 0f, -1);
                                    InactivityDetector.Reset();
                                    return true;
                             }
                             // And a special check for wizard archon
                             if (Bot.Class.HotbarPowers.Contains(SNOPower.Wizard_Archon)&&!Bot.Class.AbilityUseTimer(SNOPower.Wizard_Archon)&&Bot.SettingsFunky.Class.bWaitForArchon&&ZetaDia.CurrentWorldId==121214&&
                                 (Vector3.Distance(Bot.Character.Position, new Vector3(711.25f, 716.25f, 80.13903f))<=40f||Vector3.Distance(Bot.Character.Position, new Vector3(546.8467f, 551.7733f, 1.576313f))<=40f))
                             {
                                    Logging.Write("[Funky] Waiting for Wizard Archon cooldown before continuing to Azmodan.");
                                    CurrentTarget=new CacheObject(Bot.Character.Position, TargetType.Avoidance, 20000, "GilesWaitForArchon", 0f, -1);
                                    InactivityDetector.Reset();
                                    return true;
                             }
                             // And a very sexy special check for WD BigBadVoodoo
                             if (Bot.Class.HotbarPowers.Contains(SNOPower.Witchdoctor_BigBadVoodoo)&&!PowerManager.CanCast(SNOPower.Witchdoctor_BigBadVoodoo)&&ZetaDia.CurrentWorldId==121214&&
                                 (Vector3.Distance(Bot.Character.Position, new Vector3(711.25f, 716.25f, 80.13903f))<=40f||Vector3.Distance(Bot.Character.Position, new Vector3(546.8467f, 551.7733f, 1.576313f))<=40f))
                             {
                                    Logging.Write("[Funky] Waiting for WD BigBadVoodoo cooldown before continuing to Azmodan.");
                                    CurrentTarget=new CacheObject(Bot.Character.Position, TargetType.Avoidance, 20000, "GilesWaitForVoodooo", 0f, -1);
                                    InactivityDetector.Reset();
                                    return true;
                             }

                             //Check if our current path intersects avoidances. (When not in town, and not currently inside avoidance)
                             if (!Bot.Character.bIsInTown&&(Bot.SettingsFunky.AttemptAvoidanceMovements||Bot.Combat.CriticalAvoidance)
                                     &&Navigation.NP.CurrentPath.Count>0
                                     &&Bot.Combat.TriggeringAvoidances.Count==0)
                             {
                                    Vector3 curpos=Bot.Character.Position;
                                    IndexedList<Vector3> curpath=Navigation.NP.CurrentPath;

                                    var CurrentNearbyPath=curpath.Where(v => curpos.Distance(v)<=40f);
                                    if (CurrentNearbyPath!=null&&CurrentNearbyPath.Any())
                                    {
                                         CurrentNearbyPath.OrderBy(v => curpath.IndexOf(v));

                                         Vector3 lastV3=Vector3.Zero;
                                         foreach (var item in CurrentNearbyPath)
                                         {
                                                if (lastV3==Vector3.Zero)
                                                     lastV3=item;
                                                else if (ObjectCache.Obstacles.TestVectorAgainstAvoidanceZones(item, lastV3))
                                                {
                                                     CurrentTarget=new CacheObject(Bot.Character.Position, TargetType.Avoidance, 20000, "AvoidanceIntersection", 2.5f, -1);
                                                     return true;
                                                }
                                         }
                                    }
                             }
                        }
                        else
                        {
                             if (CurrentTarget.targetType.Equals(TargetType.Unit))
                             {
                                    //Update CurrentUnitTarget Variable.
                                    if (CurrentUnitTarget==null) CurrentUnitTarget=(CacheUnit)CurrentTarget;

                                    //Grouping Movements
                                    if (Bot.SettingsFunky.AttemptGroupingMovements
                                         &&CurrentUnitTarget.CurrentHealthPct.Value<1d
                                         &&DateTime.Compare(DateTime.Now,Bot.NavigationCache.groupingSuspendedDate)>0
                                         &&!CurrentUnitTarget.IsTreasureGoblin||Bot.SettingsFunky.GoblinPriority<2) //only after we engaged the target.
                                    {
                                         Bot.Combat.UpdateGroupClusteringVariables();

                                         if (Bot.Combat.CurrentGroupClusters.Count>0)
                                         {
                                                Cluster currentTargetCluster=CurrentUnitTarget.CurrentTargetCluster;
                                                if (currentTargetCluster!=null)
                                                {

                                                     int toughUnitCount=currentTargetCluster.ListUnits.Count(unit => unit.UnitMaxHitPointAverageWeight>0&&unit.CurrentHealthPct.Value>0.50d);

                                                     //Trigger for tough grouping..
                                                     if (toughUnitCount>1)
                                                     {
                                                            var targetableUnits=Bot.Combat.CurrentGroupClusters[0].ListUnits.Where(unit => unit.ObjectIsValidForTargeting && (unit.UnitMaxHitPointAverageWeight>0||unit.ObjectIsSpecial));
                                                            if (targetableUnits.Any())
                                                            {
                                                                 if (Bot.SettingsFunky.LogGroupingOutput)
                                                                     Logging.WriteVerbose("Starting Grouping Behavior. Triggered by Tough Group");

                                                                 //Activate Behavior
                                                                 Bot.NavigationCache.groupRunningBehavior=true;
                                                                 Bot.NavigationCache.groupingOrginUnit=(CacheUnit)ObjectCache.Objects[CurrentTarget.RAGUID];

                                                                 //Find initial grouping target..
                                                                 CurrentTarget=targetableUnits.First();
                                                                 CurrentUnitTarget=(CacheUnit)CurrentTarget;
                                                                 Bot.NavigationCache.groupingCurrentUnit=CurrentUnitTarget;
                                                            }
                                                     }
                                                }
                                         }
                                    }

                             }

                             return true;
                        }

                        return false;
        }
示例#14
0
 //Constructor
 public TargetHandler()
 {
     CurrentState=RunStatus.Running;
                 CurrentTarget=null;
 }
示例#15
0
 public CacheUnit(CacheObject baseobj)
     : base(baseobj)
 {
 }
示例#16
0
 public CacheInteractable(CacheObject baseobj)
     : base(baseobj)
 {
 }
示例#17
0
 public CacheItem(CacheObject baseobj)
     : base(baseobj)
 {
 }
示例#18
0
        internal static void IgnoreThisObject(CacheObject thisobj, bool removal=true, bool blacklistSNOID=true)
        {
            Logging.WriteVerbose("[Blacklist] Obj RAGUID {0} SNOID {1} ({2})", thisobj.RAGUID, thisobj.SNOID, thisobj.InternalName);

                int sno, raguid;
                sno=thisobj.SNOID;
                raguid=thisobj.RAGUID;

                //Add to our blacklist so we don't create it again..
                hashRGUIDIgnoreBlacklist.Add(raguid);

                if (blacklistSNOID)
                     //Blacklist SNO so we don't create it ever again!
                     CacheIDLookup.hashActorSNOIgnoreBlacklist.Add(sno);

                if (removal)
                {
                     //Clear SNO cache entries..
                     cacheSnoCollection.Remove(sno);
                     //Clear previous cache entries..
                     Objects.Remove(raguid);

                }
        }