// 24Feb2013-08:10UTC chinajade public override void OnFinished() { // Defend against being called multiple times (just in case)... if (!IsOnFinishedRun) { if (Targeting.Instance != null) { Targeting.Instance.IncludeTargetsFilter -= TargetFilter_IncludeTargets; Targeting.Instance.RemoveTargetsFilter -= TargetFilter_RemoveTargets; Targeting.Instance.WeighTargetsFilter -= TargetFilter_WeighTargets; } // NB: we don't unhook _behaviorTreeHook_Main // This was installed when HB created the behavior, and its up to HB to unhook it BehaviorHookRemove("Combat_Main", ref _behaviorTreeHook_CombatMain); BehaviorHookRemove("Combat_Only", ref _behaviorTreeHook_CombatOnly); BehaviorHookRemove("Death_Main", ref _behaviorTreeHook_DeathMain); BehaviorHookRemove("Questbot_Main", ref _behaviorTreeHook_QuestbotMain); // Remove temporary blackspots... if (_temporaryBlackspots != null) { BlackspotManager.RemoveBlackspots(_temporaryBlackspots.GetBlackspots()); _temporaryBlackspots = null; } // Restore configuration... if (_configMemento != null) { _configMemento.Dispose(); _configMemento = null; } // Make sure we don't leave stale POIs set after finishing a QB. // This could happen if the user used a TerminateWhen to finish it // for example. BotPoi.Clear("Finished " + GetType().Name); TreeRoot.GoalText = string.Empty; TreeRoot.StatusText = string.Empty; // Report the behavior run time... if (_behaviorRunTimer.IsRunning) { _behaviorRunTimer.Stop(); QBCLog.DeveloperInfo("Behavior completed in {0}", Utility.PrettyTime(_behaviorRunTimer.Elapsed)); } base.OnFinished(); QBCLog.BehaviorLoggingContext = null; IsOnFinishedRun = true; } }
protected QuestBehaviorBase(Dictionary <string, string> args) : base(args) { QBCLog.BehaviorLoggingContext = this; try { // Quest handling... // QuestRequirement* attributes are explained here... // http://www.thebuddyforum.com/mediawiki/index.php?title=Honorbuddy_Programming_Cookbook:_QuestId_for_Custom_Behaviors // ...and also used for IsDone processing. // NB: quest ID is stored in a field which will be used for coherency checks. var questId = GetAttributeAsNullable <int>("QuestId", false, ConstrainAs.QuestId(this), null) ?? 0; var variantQuestIds = new HashSet <int>( GetAttributeAsArray("VariantQuestIds", false, ConstrainAs.QuestId(this), null, null) ?? new int[0]); if (questId != 0) { if (variantQuestIds.Any()) { _providedQuestIdAndQuestVariantIds = true; } variantQuestIds.Add(questId); } VariantQuestIds = variantQuestIds; QuestRequirementComplete = GetAttributeAsNullable <QuestCompleteRequirement>("QuestCompleteRequirement", false, null, null) ?? QuestCompleteRequirement.NotComplete; QuestRequirementInLog = GetAttributeAsNullable <QuestInLogRequirement>("QuestInLogRequirement", false, null, null) ?? QuestInLogRequirement.InLog; QuestObjectiveIndex = GetAttributeAsNullable <int>("QuestObjectiveIndex", false, new ConstrainTo.Domain <int>(1, 10), null) ?? 0; // Tunables... IgnoreMobsInBlackspots = GetAttributeAsNullable <bool>("IgnoreMobsInBlackspots", false, null, null) ?? true; MovementBy = GetAttributeAsNullable <MovementByType>("MovementBy", false, null, null) ?? MovementByType.FlightorPreferred; NonCompeteDistance = GetAttributeAsNullable <double>("NonCompeteDistance", false, new ConstrainTo.Domain <double>(0.0, 50.0), null) ?? 20.0; TerminateAtMaxRunTimeSecs = GetAttributeAsNullable <int>("TerminateAtMaxRunTimeSecs", false, new ConstrainTo.Domain <int>(0, int.MaxValue), null) ?? int.MaxValue; // Go ahead and compile the "TerminateWhen" expression to look for problems... // Doing this in the constructor allows us to catch 'blind change'problems when ProfileDebuggingMode is turned on. // If there is a problem, an exception will be thrown (and handled here). var terminateWhenExpression = GetAttributeAs <string>("TerminateWhen", false, ConstrainAs.StringNonEmpty, null); TerminateWhenCompiledExpression = Utility.ProduceParameterlessCompiledExpression <bool>(terminateWhenExpression); TerminateWhen = Utility.ProduceCachedValueFromCompiledExpression(TerminateWhenCompiledExpression, false); TerminationChecksQuestProgress = GetAttributeAsNullable <bool>("TerminationChecksQuestProgress", false, null, null) ?? true; // Dummy attributes... // These attributes are accepted, but not used. They are here to help the profile writer document without // causing "unknown attribute" warnings to be emitted. GetAttributeAs <string>("QuestName", false, ConstrainAs.StringNonEmpty, null); // XML types // Add temporary avoid mobs, if any were specified... // NB: ConfigMemento will restore the orginal list in OnFinished _temporaryAvoidMobs = AvoidMobsType.GetOrCreate(Element, "AvoidMobs"); // Add temporary blackspots, if any were specified... // NB: Ideally, we'd save and restore the original blackspot list. However, // BlackspotManager does not currently give us a way to "see" what is currently // on the list. _temporaryBlackspots = BlackspotsType.GetOrCreate(Element, "Blackspots"); PursuitList = PursuitListType.GetOrCreate(Element, "PursuitList"); } catch (Exception except) { if (Query.IsExceptionReportingNeeded(except)) { // Maintenance problems occur for a number of reasons. The primary two are... // * Changes were made to the behavior, and boundary conditions weren't properly tested. // * The Honorbuddy core was changed, and the behavior wasn't adjusted for the new changes. // In any case, we pinpoint the source of the problem area here, and hopefully it can be quickly // resolved. QBCLog.Exception(except); } IsAttributeProblem = true; } }