public override void Initialize() { DateTime timeStart = DateTime.UtcNow; Logger.WriteFile("Initialize: started"); // cannot call method which references SingularSettings TalentManager.Init(); // initializes CurrentSpec which is referenced everywhere SingularSettings.Initialize(); // loads Singular global and spec-specific settings (must determine spec first) DetermineCurrentWoWContext(); Task.Run(() => WriteSupportInfo()); _lastLogLevel = GlobalSettings.Instance.LogLevel; // When we actually need to use it, we will. Spell.Init(); Spell.GcdInitialize(); EventHandlers.Init(); MountManager.Init(); HotkeyDirector.Init(); MovementManager.Init(); // SoulstoneManager.Init(); // switch to using Death behavior Dispelling.Init(); PartyBuff.Init(); Singular.Lists.BossList.Init(); Targeting.Instance.WeighTargetsFilter += PullMoreWeighTargetsFilter; //Logger.Write("Combat log event handler started."); // Do this now, so we ensure we update our context when needed. BotEvents.Player.OnMapChanged += e => { // Don't run this handler if we're not the current routine! if (!WeAreTheCurrentCombatRoutine) { return; } // Only ever update the context. All our internal handlers will use the context changed event // so we're not reliant on anything outside of ourselves for updates. UpdateContext(); }; TreeHooks.Instance.HooksCleared += () => { // Don't run this handler if we're not the current routine! if (!WeAreTheCurrentCombatRoutine) { return; } Logger.Write(LogColor.Hilite, "Hooks cleared, re-creating behaviors"); RebuildBehaviors(silent: true); Spell.GcdInitialize(); // probably not needed, but quick }; GlobalSettings.Instance.PropertyChanged += (sender, e) => { // Don't run this handler if we're not the current routine! if (!WeAreTheCurrentCombatRoutine) { return; } // only LogLevel change will impact our behav trees // .. as we conditionally include/omit some diagnostic nodes if debugging // also need to keep a cached copy of prior value as the event // .. fires on the settor, not when the value is different if (e.PropertyName == "LogLevel" && _lastLogLevel != GlobalSettings.Instance.LogLevel) { _lastLogLevel = GlobalSettings.Instance.LogLevel; Logger.Write(LogColor.Hilite, "HonorBuddy {0} setting changed to {1}, re-creating behaviors", e.PropertyName, _lastLogLevel.ToString()); RebuildBehaviors(); Spell.GcdInitialize(); // probably not needed, but quick } }; // install botevent handler so we can consolidate validation on whether // .. local botevent handlers should be called or not SingularBotEventInitialize(); Logger.Write("Determining talent spec."); try { TalentManager.Update(); } catch (Exception e) { StopBot(e.ToString()); } Logger.Write("Current spec is " + SpecName()); // write current settings to log file... only written at startup and when Save press in Settings UI Task.Run(() => SingularSettings.Instance.LogSettings()); // Update the current WoWContext, and fire an event for the change. UpdateContext(); // NOTE: Hook these events AFTER the context update. OnWoWContextChanged += (orig, ne) => { Logger.Write(LogColor.Hilite, "Context changed, re-creating behaviors"); SingularRoutine.DescribeContext(); RebuildBehaviors(); Spell.GcdInitialize(); Singular.Lists.BossList.Init(); }; RoutineManager.Reloaded += (s, e) => { Logger.Write(LogColor.Hilite, "Routines were reloaded, re-creating behaviors"); RebuildBehaviors(silent: true); Spell.GcdInitialize(); }; // create silently since Start button will create a context change (at least first Start) // .. which will build behaviors again if (!Instance.RebuildBehaviors()) { return; } // if (IsPluginEnabled("DrinkPotions")) { Logger.Write(LogColor.Hilite, "info: disabling DrinkPotions plugin, conflicts with Singular potion support"); SetPluginEnabled("DrinkPotions", false); } SpellImmunityManager.Add(16292, WoWSpellSchool.Frost); // http://www.wowhead.com/npc=16292/aquantion Logger.WriteDebug(Color.White, "Verified behaviors can be created!"); Logger.Write("Initialization complete!"); Logger.WriteDiagnostic(Color.White, "Initialize: completed taking {0:F2} seconds", (DateTime.UtcNow - timeStart).TotalSeconds); }
public static void DescribeContext() { using (StyxWoW.Memory.AcquireFrame()) { string sRace = RaceName(); if (Me.Race == WoWRace.Pandaren) { sRace = " " + Me.FactionGroup.ToString() + sRace; } Logging.Write(" "); // spacer before prior log text Logger.Write(Color.LightGreen, "Your Level {0}{1}{2} Build is", Me.Level, SingularRoutine.RaceName(), SingularRoutine.SpecAndClassName()); Logger.Write(Color.LightGreen, "... running the {0} bot in {1} {2}", GetBotName(), Me.RealZoneText, !Me.IsInInstance || Battlegrounds.IsInsideBattleground ? "" : "[" + GetInstanceDifficultyName() + "]" ); Logger.WriteFile(" MapId = {0}", Me.MapId); Logger.WriteFile(" ZoneId = {0}", Me.ZoneId); /* * if (Me.CurrentMap != null && Me.CurrentMap.IsValid) * { * Logger.WriteFile(" AreaTableId = {0}", Me.CurrentMap.AreaTableId); * Logger.WriteFile(" InternalName = {0}", Me.CurrentMap.InternalName); * Logger.WriteFile(" IsArena = {0}", Me.CurrentMap.IsArena.ToYN()); * Logger.WriteFile(" IsBattleground = {0}", Me.CurrentMap.IsBattleground.ToYN()); * Logger.WriteFile(" IsContinent = {0}", Me.CurrentMap.IsContinent.ToYN()); * Logger.WriteFile(" IsDungeon = {0}", Me.CurrentMap.IsDungeon.ToYN()); * Logger.WriteFile(" IsInstance = {0}", Me.CurrentMap.IsInstance.ToYN()); * Logger.WriteFile(" IsRaid = {0}", Me.CurrentMap.IsRaid.ToYN()); * Logger.WriteFile(" IsScenario = {0}", Me.CurrentMap.IsScenario.ToYN()); * Logger.WriteFile(" MapDescription = {0}", Me.CurrentMap.MapDescription); * Logger.WriteFile(" MapDescription2 = {0}", Me.CurrentMap.MapDescription2); * Logger.WriteFile(" MapType = {0}", Me.CurrentMap.MapType); * Logger.WriteFile(" MaxPlayers = {0}", Me.CurrentMap.MaxPlayers); * Logger.WriteFile(" Name = {0}", Me.CurrentMap.Name); * } */ string sRunningAs = ""; if (Me.CurrentMap == null) { sRunningAs = "Unknown"; } else if (Me.CurrentMap.IsArena) { sRunningAs = "Arena"; } else if (Me.CurrentMap.IsBattleground) { sRunningAs = "Battleground"; } else if (Me.CurrentMap.IsScenario) { sRunningAs = "Scenario"; } else if (Me.CurrentMap.IsRaid) { sRunningAs = "Raid"; } else if (Me.CurrentMap.IsDungeon) { sRunningAs = "Dungeon"; } else if (Me.CurrentMap.IsInstance) { sRunningAs = "Instance"; } else { sRunningAs = "Zone: " + Me.CurrentMap.Name; } Logger.Write(Color.LightGreen, "... {0} using my {1} Behaviors {2}", sRunningAs, CurrentWoWContext == WoWContext.Normal ? "SOLO" : CurrentWoWContext.ToString().ToUpper(), !Me.IsInGroup() ? "alone" : "in a group of " + Unit.GroupMemberInfos.Count().ToString() ); if (CurrentWoWContext != WoWContext.Battlegrounds && Me.IsInGroup()) { Logger.Write(Color.LightGreen, "... in a group as {0} role with {1} of {2} players", (Me.Role & (WoWPartyMember.GroupRole.Tank | WoWPartyMember.GroupRole.Healer | WoWPartyMember.GroupRole.Damage)).ToString().ToUpper(), Me.GroupInfo.NumRaidMembers, (int)Math.Max(Me.CurrentMap.MaxPlayers, Me.GroupInfo.GroupSize) ); } Item.WriteCharacterGearAndSetupInfo(); Logger.WriteFile(" "); Logger.WriteFile("My Current Dynamic Info"); Logger.WriteFile("======================="); Logger.WriteFile("Combat Reach: {0:F4}", Me.CombatReach); Logger.WriteFile("Bounding Height: {0:F4}", Me.BoundingHeight); Logger.WriteFile(" "); #if LOG_GROUP_COMPOSITION if (CurrentWoWContext == WoWContext.Instances) { int idx = 1; Logger.WriteFile(" "); Logger.WriteFile("Group Comprised of {0} members as follows:", Me.GroupInfo.NumRaidMembers); foreach (var pm in Me.GroupInfo.RaidMembers) { string role = (pm.Role & ~WoWPartyMember.GroupRole.None).ToString().ToUpper() + " "; role = role.Substring(0, 6); Logger.WriteFile("{0} {1} {2} {3} {4} {5}", idx++, role, pm.IsOnline ? "online " : "offline", pm.Level, pm.HealthMax, pm.Specialization ); } Logger.WriteFile(" "); } #endif if (Styx.CommonBot.Targeting.PullDistance < 25) { Logger.Write(LogColor.Hilite, "your Pull Distance is {0:F0} yds which is low for any class!!!", Styx.CommonBot.Targeting.PullDistance); } } }