public void CanDequeueManually() { var random = new Random(); var max = 1000; var dequeuedCount = random.Next(1, max - 1); var value = 0; var remainder = 0; ActionQueue <int> .Clear(); // Add random number of items to queue. Enumerable.Range(1, max).ToList().ForEach(ActionQueue <int> .Enqueue); // Dequeue a (different and smaller) random number of times. for (var i = 0; i < dequeuedCount; i++) { value = ActionQueue <int> .Dequeue(); } // Work out how many items there should be left in the queue. remainder = max - dequeuedCount; // Make sure we dequeued as many items as expected. Assert.AreEqual(value, dequeuedCount); // Make sure there are as many items left in the queue as expected. Assert.AreEqual(ActionQueue <int> .Count, remainder); }
protected void InvokeActionQueue() { while (ActionQueue.Count > 0) { ActionQueue.Dequeue().Invoke(); } }
public void ExecuteTurn() { nav.ExecutePath(); if (ActionQueue.Count > 0) { action = ActionQueue.Dequeue(); } }
public override void DoCheckFlee() { int numAttackers = GetAttackerCount(); // Less then specified hp or mana plus 10%, and more then 1 attacker? if ((_ak.get_MobHealth(petID) < profile.GetInteger("FleeBelowHealth") + 10 || _ak.PlayerMana < profile.GetInteger("FleeBelowMana") + 10) && numAttackers > 1) { // Yes? RUN FOREST RUN ! // Should we leave the pet behind to die? if (profile.GetBool("Necro.FleeLeavePet")) { AddMessage("Leave pet to die as we flee"); //switch quickbar and cast UseQbar(profile.GetString("Necro.PetHereQ"), profile.GetString("Necro.PetHereKey")); } Action = BotAction.Flee; ActionQueue.Clear(); ActionQueue.Enqueue(BotAction.Rest); return; } //Just one attacker, and below health at which we should run away? if (_ak.get_MobHealth(petID) < profile.GetInteger("FleeBelowHealth") || _ak.PlayerMana < profile.GetInteger("FleeBelowMana")) { // Our attacker has more HP then us? if (_ak.TargetIndex > 0 && _ak.get_MobHealth(petID) < _ak.TargetObject.Health) { // Yes? RUN FOREST RUN ! // Should we leave the pet behind to die? if (profile.GetBool("Necro.FleeLeavePet")) { AddMessage("Leave pet to die as we flee"); //switch quickbar and cast UseQbar(profile.GetString("Necro.PetHereQ"), profile.GetString("Necro.PetHereKey")); } Action = BotAction.Flee; ActionQueue.Clear(); ActionQueue.Enqueue(BotAction.Rest); return; } } // Check if we have a next action if (ActionQueue.Count == 0) { throw new Exception("No action in ActionQueue"); } // Next Action Action = ActionQueue.Dequeue(); }
public override void DoProtect() { // Check if we have a next action if (ActionQueue.Count == 0) { throw new Exception("No action in ActionQueue"); } // Next Action Action = ActionQueue.Dequeue(); }
public void NextAction() { if (ActionQueue.Count > 0) { action = ActionQueue.Dequeue(); } else { action = null; FinishActions(); } }
protected virtual void ActionTick() { //Debug.Log(gameObject.name + ": ActionTick!"); // are there any actions in the queue? if yes, take the next one if (actionQueue.Count == 0) { SelectAction(); } if (actionQueue.Count > 0) { SetCurrentAction(actionQueue.Dequeue()); } }
public override void DoCheckFlee() { int numAttackers = GetAttackerCount(); // Less then specified hp or mana plus 10%, and more then 1 attacker? if (_ak.PlayerHealth < profile.GetInteger("FleeBelowHealth") + 10 && numAttackers > 1) { // Yes? RUN FOREST RUN ! AddMessage("Run away!"); Action = BotAction.Flee; PlayerKeys.Sprint(KeyDirection.KeyUpDown); ActionQueue.Clear(); ActionQueue.Enqueue(BotAction.Rest); return; } //Just one attacker, and below health at which we should run away? if (_ak.PlayerHealth < profile.GetInteger("FleeBelowHealth")) { // Our attacker has more HP then us? if (_ak.TargetIndex > 0 && _ak.PlayerHealth < _ak.TargetObject.Health) { // Yes? RUN FOREST RUN ! AddMessage("Run away!"); Action = BotAction.Flee; PlayerKeys.Sprint(KeyDirection.KeyUpDown); ActionQueue.Clear(); ActionQueue.Enqueue(BotAction.Rest); return; } } // Check if we have a next action if (ActionQueue.Count == 0) { throw new Exception("No action in ActionQueue"); } // Next Action Action = ActionQueue.Dequeue(); }
public void Update(GameTime gameTime) { _behavior?.Update(gameTime); if (!CurrentAction?.IsStillRunning(this) ?? true) { CurrentAction = null; if (ActionQueue.Count > 0) { CurrentAction = ActionQueue.Dequeue(); if (ActionQueue.Count == 0) { _behavior?.IaFinish(); } } } CurrentAction?.Perform(this, gameTime); }
public void Populate() { ActionQueue.Dequeue(ref Populating, this); }
public override void DoProtect() { // Do we have instant debuff set? If not dont bother trying to protect (for now) if (profile.GetString("Necro.DebuffQ") == "" || profile.GetString("Necro.DebuffKey") == "") { return; } try { // Retrieve a list of objects near enough to be attacking our group int myX = _ak.gPlayerXCoord; int myY = _ak.gPlayerYCoord; AKServer.DLL.DAoCServer.Group groupMembers = _ak.GroupMemberInfo; // In a group? If not just return if (groupMembers.GroupMemberTable.Count == 0) { return; } ArrayList pets = new ArrayList(); if (petID > 0) { pets.Add(petID); } int spawnID = _ak.SearchArea((int)profile.GetFloat("SearchDistance"), AKServer.DLL.DAoCServer.DAOCObjectClass.ocMob, pets); while (spawnID != -1) { int mobTarget = _ak.get_MobTarget(spawnID); foreach (AKServer.DLL.DAoCServer.GroupMember grpMember in groupMembers.GroupMemberTable.Values) { //Is this group member being attacked? if (grpMember.ID == mobTarget) { //Yes, use instant debuff to get aggro! if (_ak.isPlayerSitting) { PlayerKeys.SitStand(KeyDirection.KeyUpDown); Thread.Sleep(500); } _ak.SetTarget(spawnID); Thread.Sleep(150); PlayerKeys.Face(KeyDirection.KeyUpDown); UseQbar(profile.GetString("Necro.DebuffQ"), profile.GetString("Necro.DebuffKey")); AddMessage("Protected " + _ak.get_MobName(mobTarget) + " by attacking " + _ak.get_MobName(spawnID)); } } spawnID = _ak.SearchAreaNext((int)profile.GetFloat("SearchDistance"), AKServer.DLL.DAoCServer.DAOCObjectClass.ocMob, pets); } } catch (Exception e) { AddMessage("caught exception " + e.Message); } finally { // Check if we have a next action if (ActionQueue.Count == 0) { throw new Exception("No action in ActionQueue"); } // Next Action Action = ActionQueue.Dequeue(); } }
public override void DoGetInRange() { nextSpell = eRangedFights.First; // Do we have a target and is it not fighting someone else? if (_ak.TargetIndex < 1 || (_ak.TargetObject != null && _ak.TargetObject.TargetID != 0 && _ak.TargetObject.TargetID != _ak.PlayerID)) { // No? Stop moving _ak.StopRunning(); // Check agro Action = BotAction.Protect; // If we were in Melee code, maybe it died? if (ActionQueue.Count > 0 && ActionQueue.Peek(0) == BotAction.MeleeFight) { // Let melee code do whatever it does when something dies return; } else { // Find a new target ActionQueue.Clear(); ActionQueue.Enqueue(BotAction.CheckAgro); ActionQueue.Enqueue(BotAction.FindTarget); } return; } // Get the next action from the queue BotAction NextAction = ActionQueue.Dequeue(); // By default assume a ranged attack distance (move closer then the max, so mobs that run away are caught easier) float AttackDistance = profile.GetFloat("MaximumRangedAttackDistance") * 0.95f; // Calculate the distance to the target FROM PET float TargetDistance = DistanceToPet(_ak.TargetIndex); // Check if we're past the minimum distance, go to melee distance else if (TargetDistance < profile.GetFloat("MinimumRangedAttackDistance")) { NextAction = BotAction.MeleeFight; } // Should we go to melee attack distance? if (NextAction == BotAction.MeleeFight || (ActionQueue.Count > 0 && ActionQueue.Peek(0) == BotAction.MeleeFight)) { AttackDistance = 200; //200 should be close enough to /stick to the target } // TODO: Add (extra) stuck checking here float distToWalk = TargetDistance - AttackDistance; // AddMessage("DEBUG: distToWalk " + distToWalk.ToString() + " target index " + _ak.TargetIndex); // Do our final distance move? if (_ak.TargetIndex > 0 && distToWalk <= 200) { // Do our final move MoveTo(_ak.TargetIndex, AttackDistance, true); // make sure we are facing the target PlayerKeys.Face(KeyDirection.KeyUpDown); // One final agro check, might be the same monster though Action = BotAction.CheckAgro; // Make sure we do the appropriate action ActionQueue.Clear(); ActionQueue.Enqueue(BotAction.Protect); ActionQueue.Enqueue(NextAction); } else { // Walk to our target in small steps if (_ak.TargetIndex > 0) { MoveTo(_ak.TargetIndex, TargetDistance - (distToWalk / 4), false); } // Recheck if our target is still the closest once, only if not incombat // Use multiple checks because once in a great while GetAttackerCount is 0 and something is hitting us if (GetAttackerCount() == 0 || _ak.isPlayerInCombat || (petID > 0 && !_ak.get_isMobInCombat(petID))) { // Setup our bot actions Action = BotAction.Protect; ActionQueue.Clear(); ActionQueue.Enqueue(BotAction.CheckAgro); ActionQueue.Enqueue(BotAction.FindTarget); } else { // In combat, just get in range //for some reason we need to break auto face //before moveto will work right PlayerKeys.TurnLeft(KeyDirection.KeyDown); Thread.Sleep(25); PlayerKeys.TurnLeft(KeyDirection.KeyUp); Action = BotAction.GetInRange; ActionQueue.Clear(); ActionQueue.Enqueue(BotAction.Protect); ActionQueue.Enqueue(NextAction); } } }
public virtual void LateUpdate() { if (CurrentAction != null && CurrentAction.Running) { if (CurrentAction.ShouldAbort()) { AbortPlan(); return; } else { Profiler.BeginSample("Agent.Run"); var actionStatus = CurrentAction.Perform(); CurrentAction.OnPerform?.Invoke(); if (actionStatus == EActionStatus.Failed) { AbortPlan(); } if (actionStatus == EActionStatus.Success) { CurrentAction.PostPerform(); CurrentAction.OnPostPerform?.Invoke(); CurrentAction.Running = false; } Profiler.EndSample(); } Profiler.BeginSample("Agent.CanAbortPlan"); if (PlannerSettings.CanAbortPlans && CurrentAction.CanAbort() && Time.time - _planStartTime > PlannerSettings.PlanRate) { AbortPlan(); } Profiler.EndSample(); return; } if (_replan || ActionQueue == null) { foreach (var goal in _orderedGoals) { Profiler.BeginSample("Agent.Plan"); ActionQueue = Planner.Plan(this, goal.Key, World.Instance.StateMap, Actions, States.GetStates(), false); _planStartTime = Time.time; Profiler.EndSample(); if (ActionQueue == null) { continue; } CurrentGoal = goal; _replan = false; StoredActionQueue.Clear(); foreach (var action in ActionQueue) { StoredActionQueue.Enqueue(action); } break; } } // Goal reached! if (ActionQueue != null && ActionQueue.Count == 0) { if (CurrentGoal.Once) { Goals.Remove(CurrentGoal); _orderedGoals.Remove(CurrentGoal); } _replan = true; } // Try do Action Profiler.BeginSample("Agent.PrePerform"); if (ActionQueue != null && ActionQueue.Count > 0) { CurrentAction = ActionQueue.Dequeue(); if (CurrentAction.PrePerform()) { if (CurrentAction.TrackStopWatch) { CurrentAction.Stopwatch.Restart(); } else { CurrentAction.Stopwatch.Reset(); } CurrentAction.Running = true; CurrentAction.OnPrePerform?.Invoke(); } else { AbortPlan(); } } Profiler.EndSample(); }