예제 #1
0
        public static void ShowVehicleArticulationChain(WoWUnit wowUnit)
        {
            var tmp         = new StringBuilder();
            var indentLevel = 4;

            do
            {
                var indent         = string.Empty.PadLeft(indentLevel);
                var fieldSeparator = string.Format("\n  {0}", indent);

                tmp.Append(wowUnit.SafeName);

                var worldMatrix = wowUnit.GetWorldMatrix();
                var pitch       = StyxWoW.Memory.Read <float>(wowUnit.BaseAddress + 0x820 + 0x24);
                tmp.AppendFormat("{0}{1} (pitch: {2}): {3}",
                                 fieldSeparator,
                                 wowUnit.SafeName,
                                 pitch,
                                 worldMatrix.ToString_FullInfo(false, indentLevel));

                wowUnit = wowUnit.Transport as WoWUnit;

                if (wowUnit != null)
                {
                    tmp.AppendFormat("{0} => ", fieldSeparator);
                }

                indentLevel += 4;
            } while (wowUnit != null);

            QBCLog.Debug("Articulation chain: {0}", tmp.ToString());
        }
예제 #2
0
        /// <summary>
        ///     Executes a hook. This also sets QBCLog.BehaviorLoggingContext and logs when hook starts/stops executing, if enabled
        /// </summary>
        /// <param name="cb">The CustomForcedBehavior.</param>
        /// <param name="taskProducer">The task producer.</param>
        /// <param name="name">The name. Used to identify hooks that can have multiple instances running at a time.</param>
        /// <param name="logExecution">if set to <c>true</c> [log execution].</param>
        /// <returns>
        ///     Returns value produced by the coroutine returned from <paramref name="taskProducer" />.
        /// </returns>
        /// <exception cref="Exception">Coroutine status was invalid</exception>
        /// <exception cref="System.Exception">Coroutine status was invalid</exception>
        public static async Task <bool> ExecuteHook(CustomForcedBehavior cb, Func <Task <bool> > taskProducer, string name = "", bool logExecution = true)
        {
            using (var coroutine = new Coroutine(async() => await taskProducer()))
            {
                var hookType = cb.GetType();

                string identifier = hookType + name;

                // Change the logging context to the Hook instance so QBCLog messages correctly display the originating QB.
                var originalLoggingContext = QBCLog.BehaviorLoggingContext;
                QBCLog.BehaviorLoggingContext = cb;
                try
                {
                    while (true)
                    {
                        coroutine.Resume();

                        bool executed;
                        switch (coroutine.Status)
                        {
                        case CoroutineStatus.Runnable:
                            executed = true;
                            break;

                        case CoroutineStatus.RanToCompletion:
                            executed = (bool)coroutine.Result;
                            break;

                        default:
                            throw new Exception("Unexpected Coroutine status");
                        }

                        if (logExecution)
                        {
                            bool executedPreviously;
                            s_hookExecutionStates.TryGetValue(identifier, out executedPreviously);

                            if (executed != executedPreviously)
                            {
                                s_hookExecutionStates[identifier] = executed;
                                // log execution state changes.
                                QBCLog.Debug(executed ? "Executing {0}hook" : "Stopped executing {0}hook", name != null ? name + " " : "");
                            }
                        }

                        if (coroutine.Status != CoroutineStatus.Runnable)
                        {
                            return(executed);
                        }

                        await Coroutine.Yield();
                    }
                }
                finally
                {
                    QBCLog.BehaviorLoggingContext = originalLoggingContext;
                }
            }
        }
        // Stolen from Singluar.
        private static WoWGuid ArgToGuid(object o)
        {
            string svalue = o.ToString();

            try
            {
                WoWGuid guid;
                if (WoWGuid.TryParseFriendly(svalue, out guid))
                {
                    return(guid);
                }
            }
            catch
            {
                QBCLog.Debug("error parsing Guid '{0}'", o.ToString());
            }
            return(WoWGuid.Empty);
        }
        /// <summary>
        /// <para>This reports problems, and stops BT processing if there was a problem with attributes...
        /// We had to defer this action, as the 'profile line number' is not available during the element's
        /// constructor call.</para>
        /// <para>It also captures the user's configuration, and installs Behavior Tree hooks.  The items will
        /// be restored when the behavior terminates, or Honorbuddy is stopped.</para>
        /// </summary>
        /// <return>true, if the behavior should run; false, if it should not.</return>
        /// <param name="extraGoalTextDescription"></param>
        protected bool OnStart_QuestBehaviorCore(string extraGoalTextDescription = null)
        {
            // Semantic coherency / covariant dependency checks...
            UsageCheck_SemanticCoherency(Element, QuestObjectiveIndex > 0 && !VariantQuestIds.Any(),
                                         context => $"QuestObjectiveIndex of '{QuestObjectiveIndex}' specified, but no corresponding QuestId provided");

            UsageCheck_SemanticCoherency(Element,
                                         _providedQuestIdAndQuestVariantIds,
                                         context => "Cannot provide both a QuestId and VariantQuestIds at same time.");

            EvaluateUsage_SemanticCoherency(Element);

            // Deprecated attributes...
            EvaluateUsage_DeprecatedAttributes(Element);

            // This reports problems, and stops BT processing if there was a problem with attributes...
            // We had to defer this action, as the 'profile line number' is not available during the element's
            // constructor call.
            OnStart_HandleAttributeProblem();

            var questId = GetQuestId();

            // If the quest is complete, this behavior is already done...
            // So we don't want to falsely inform the user of things that will be skipped.
            // NB: Since the IsDone property may skip checking the 'progress conditions', we need to explicltly
            // check them here to see if we even need to start the behavior.
            if (!(IsDone || !UtilIsProgressRequirementsMet(questId, QuestRequirementInLog, QuestRequirementComplete)))
            {
                this.UpdateGoalText(questId, extraGoalTextDescription);

                // Start the timer to measure the behavior run time...
                _behaviorRunTimer.Restart();

                // Monitored Behaviors...
                if (QuestBehaviorCoreSettings.Instance.MonitoredBehaviors.Contains(GetType().Name))
                {
                    QBCLog.Debug("MONITORED BEHAVIOR: {0}", GetType().Name);
                    AudibleNotifyOn(true);
                }

                _configMemento = CreateConfigMemento();

                if (Targeting.Instance != null)
                {
                    Targeting.Instance.IncludeTargetsFilter += TargetFilter_IncludeTargets;
                    Targeting.Instance.RemoveTargetsFilter  += TargetFilter_RemoveTargets;
                    Targeting.Instance.WeighTargetsFilter   += TargetFilter_WeighTargets;
                }

                Query.InCompetitionReset();
                Utility.BlacklistsReset();

                _behaviorTreeHook_CombatMain   = BehaviorHookInstall("Combat_Main", CreateBehavior_CombatMain());
                _behaviorTreeHook_CombatOnly   = BehaviorHookInstall("Combat_Only", CreateBehavior_CombatOnly());
                _behaviorTreeHook_DeathMain    = BehaviorHookInstall("Death_Main", CreateBehavior_DeathMain());
                _behaviorTreeHook_QuestbotMain = BehaviorHookInstall("Questbot_Main", CreateBehavior_QuestbotMain());

                BlackspotManager.AddBlackspots(_temporaryBlackspots.GetBlackspots());

                if (_temporaryAvoidMobs != null)
                {
                    foreach (var avoidMobId in _temporaryAvoidMobs.GetAvoidMobIds())
                    {
                        // NB: ProfileManager.CurrentProfile.AvoidMobs will never be null
                        if (!ProfileManager.CurrentProfile.AvoidMobs.Contains(avoidMobId))
                        {
                            ProfileManager.CurrentProfile.AvoidMobs.Add(avoidMobId);
                        }
                    }
                }

                return(true);    // behavior should run
            }

            return(false);   // behavior should NOT run
        }