private static bool FMIsInBloodElfStartingZone(FlightMaster fm) { return(fm.NPCId == 16189 || fm.NPCId == 16192 || fm.NPCId == 24851 || fm.NPCId == 26560); }
public static FlightMaster GetClosestFlightMasterFrom(float maxRadius) { FlightMaster result = null; // Pre order the list List <FlightMaster> orderedListFM = FlightMasterDB.FlightMasterList .FindAll(fm => (fm.IsDiscovered || WFMSettings.CurrentSettings.TakeUndiscoveredTaxi) && ToolBox.FMIsOnMyContinent(fm) && !fm.IsDisabledByPlugin()) .OrderBy(fm => fm.Position.DistanceTo(ObjectManager.Me.Position)).ToList(); foreach (FlightMaster flightMaster in orderedListFM) { if (flightMaster.Position.DistanceTo(ObjectManager.Me.Position) < maxRadius) { float realDist = ToolBox.CalculatePathTotalDistance(ObjectManager.Me.Position, flightMaster.Position); Logger.Log($"[FROM] {flightMaster.Name} is {Math.Round(realDist)} yards away"); if (realDist < maxRadius) { maxRadius = realDist; result = flightMaster; } } } return(result); }
// Requires FM map open public static FlightMaster GetBestAlternativeTo(List <string> reachableTaxis) { float num = ObjectManager.Me.Position.DistanceTo(destinationVector); FlightMaster resultFM = null; // Pre order the list List <FlightMaster> orderedListFM = FlightMasterDB.FlightMasterList .FindAll(fm => reachableTaxis.Contains(fm.Name)) .OrderBy(fm => fm.Position.DistanceTo(destinationVector)).ToList(); foreach (FlightMaster flightMaster in orderedListFM) { if (flightMaster.Position.DistanceTo(destinationVector) < num) { float realDist = ToolBox.CalculatePathTotalDistance(flightMaster.Position, destinationVector); Logger.Log($"[TO2] {flightMaster.Name} is {Math.Round(realDist)} yards away from destination"); if (realDist < num) { num = realDist; resultFM = flightMaster; } } } return(resultFM); }
public override void Run() { MovementManager.StopMoveNewThread(); MovementManager.StopMoveToNewThread(); FlightMaster flightmasterFrom = Main.from; FlightMaster flightmasterTo = Main.to; if (WFMMoveInteract.GoInteractwithFM(flightmasterFrom, true)) { if (FlightMasterDB.UpdateKnownFMs(flightmasterFrom)) { Logger.Log("Flightmaster list has changed. Trying to find a new path."); Main.to = null; Main.shouldTakeFlight = false; return; } List <string> reachableTaxis = new List <string>(); // Look for current To and record reachables in case we can't find it for (int i = 0; i < 120; i++) { string nodeStatus = Lua.LuaDoString <string>($"return TaxiNodeGetType({i})"); string nodeName = Lua.LuaDoString <string>($"return TaxiNodeName({i})"); if (nodeStatus == "REACHABLE") { if (nodeName == flightmasterTo.Name) { TakeTaxi(flightmasterFrom, nodeName); return; } reachableTaxis.Add(nodeName); } } // Find an alternative Logger.Log($"{flightmasterTo.Name} is unreachable, trying to find an alternative"); FlightMaster alternativeFm = Main.GetBestAlternativeTo(reachableTaxis); if (alternativeFm != null) { Logger.Log($"Found an alternative flight : {alternativeFm.Name}"); TakeTaxi(flightmasterFrom, alternativeFm.Name); return; } else { Main.shouldTakeFlight = false; ToolBox.PausePlugin("Couldn't find an alternative flight"); } } }
public static bool FMIsOnMyContinent(FlightMaster fm) { if (PlayerInBloodElfStartingZone()) { return(FMIsInBloodElfStartingZone(fm) || fm.Continent == ContinentId.Azeroth); } if (PlayerInDraneiStartingZone()) { return(FMIsInDraneiStartingZone(fm)); } return(!FMIsInDraneiStartingZone(fm) && (fm.Continent == (ContinentId)Usefuls.ContinentId || (FMIsInBloodElfStartingZone(fm) && (ContinentId)Usefuls.ContinentId == ContinentId.Azeroth))); }
public static bool ExceptionConditionsAreMet(FlightMaster fm) { return(fm != null && (fm.NPCId != 20234 || fm.Position.DistanceTo(ObjectManager.Me.Position) < 100) && // Shatter Point, Hellfire Peninsula (fm.NPCId != 19581 || GetReputation("The Aldor") > 0) && // Altar of Sha'tar, Shadowmoon Valley (fm.NPCId != 21766 || GetReputation("The Scryers") > 0) && // Sanctum of the Stars, Shadowmoon Valley (fm.NPCId != 30314 || Quest.GetLogQuestIsComplete(12896) || Quest.GetLogQuestIsComplete(12897)) && // The Shadow Vault, Icecrown (fm.NPCId != 28037 || Quest.GetLogQuestIsComplete(12523)) && // Nesingwary Base Camp, Sholazar Basin (fm.NPCId != 31069 || Quest.GetLogQuestIsComplete(13141)) && // Crusaders' Pinnacle, Icecrown (fm.NPCId != 32571 || Quest.GetLogQuestIsComplete(12956)) && // Dun Nifflelem, The Storm Peaks (fm.NPCId != 37915 || GetWoWVersion().Equals("3.3.5")) && // The Bulwark, Tirisfal (fm.NPCId != 37888 || GetWoWVersion().Equals("3.3.5")) && // Thondoril River, Western Plaguelands (fm.NPCId != 29480 || ObjectManager.Me.WowClass == WoWClass.DeathKnight) // Acherus: The Ebon Hold ); }
private void BackGroundPulse(object sender, DoWorkEventArgs args) { while (isLaunched) { try { if (inPause && pauseTimer.ElapsedMilliseconds > WFMSettings.CurrentSettings.PauseLengthInSeconds * 1000) { Logger.Log($"{WFMSettings.CurrentSettings.PauseLengthInSeconds} seconds elapsed in pause"); ToolBox.UnPausePlugin(); MovementManager.StopMoveNewThread(); MovementManager.StopMoveToNewThread(); } if (Conditions.InGameAndConnectedAndProductStartedNotInPause && !ObjectManager.Me.InCombatFlagOnly && !ObjectManager.Me.IsOnTaxi && ObjectManager.Me.IsAlive) { nearestFlightMaster = GetNearestFlightMaster(); // Mark flightmaster as To be discovered if (nearestFlightMaster != null && !nearestFlightMaster.IsDisabledByPlugin() && ToolBox.ExceptionConditionsAreMet(nearestFlightMaster) && !WFMSettings.CurrentSettings.KnownFlightsList.Contains(nearestFlightMaster.Name) && ToolBox.CalculatePathTotalDistance(ObjectManager.Me.Position, nearestFlightMaster.Position) < WFMSettings.CurrentSettings.DetectTaxiDistance * 1.2) { flightMasterToDiscover = nearestFlightMaster; } // Hook for HMP states locks and others if (discoverFlightMasterState.NeedToRun && currentState?.Priority < discoverFlightMasterState.Priority) { Logger.Log("Stop on tracks to ensure discovery"); MovementManager.StopMove(); MovementManager.StopMoveTo(); } } } catch (Exception arg) { Logger.LogError(string.Concat(arg)); } Thread.Sleep(3000); } }
private static WoWUnit FindNearbyAliveFM(FlightMaster fm) { for (int i = 1; i <= 3; i++) { WoWUnit nearbyFm = ObjectManager.GetObjectWoWUnit().Find(unit => unit.Entry == fm.NPCId && unit.IsAlive); if (nearbyFm != null) { return(nearbyFm); } else { Logger.Log($"FM detection failed, retrying ({i}/3)"); Thread.Sleep(1000); } } return(null); }
private static bool InteractWithFm(FlightMaster fm) { Interact.InteractGameObject(ObjectManager.GetWoWUnitByEntry(fm.NPCId).First().GetBaseAddress); for (int i = 1; i <= 5; i++) { if (ObjectManager.Target.Entry != fm.NPCId) { Logger.Log($"Failed to interact with NPC, retrying ({i}/5)"); Interact.InteractGameObject(ObjectManager.GetWoWUnitByEntry(fm.NPCId).First().GetBaseAddress); Thread.Sleep(500); } else { return(true); } } return(false); }
public override void Run() { MovementManager.StopMoveNewThread(); MovementManager.StopMoveToNewThread(); FlightMaster fmToDiscover = Main.flightMasterToDiscover; Logger.Log($"Discovering flight master {fmToDiscover.Name}"); // We go to the position if (WFMMoveInteract.GoInteractwithFM(fmToDiscover)) { FlightMasterDB.SetFlightMasterToKnown(fmToDiscover.NPCId); Main.flightMasterToDiscover = null; ToolBox.UnPausePlugin(); Main.shouldTakeFlight = false; FlightMasterDB.UpdateKnownFMs(fmToDiscover); MovementManager.StopMove(); // reset path } }
private static bool FmMapIsOpen(FlightMaster fm) { Usefuls.SelectGossipOption(GossipOptionsType.taxi); for (int i = 1; i <= 5; i++) { if (!Main.isFMMapOpen) { Logger.LogDebug($"Failed to open FM map, retrying ({i}/5)"); Lua.LuaDoString("CloseGossip()"); Thread.Sleep(500); if (InteractWithFm(fm)) { Usefuls.SelectGossipOption(GossipOptionsType.taxi); Thread.Sleep(500); } } else { return(true); } } return(false); }
public static FlightMaster GetClosestFlightMasterTo(float maxRadius) { FlightMaster result = null; // Pre order the list List <FlightMaster> orderedListFM = FlightMasterDB.FlightMasterList .FindAll(fm => fm.IsDiscovered && fm.NPCId != from.NPCId && ToolBox.FMIsOnMyContinent(fm)) .OrderBy(fm => fm.Position.DistanceTo(destinationVector)).ToList(); foreach (FlightMaster flightMaster in orderedListFM) { if (flightMaster.Position.DistanceTo(destinationVector) < maxRadius) { float realDist = ToolBox.CalculatePathTotalDistance(flightMaster.Position, destinationVector); Logger.Log($"[TO] {flightMaster.Name} is {Math.Round(realDist)} yards away from destination"); if (realDist < maxRadius) { maxRadius = realDist; result = flightMaster; } } } return(result); }
public static bool UpdateKnownFMs(FlightMaster FMWithMapOpen) { if ((ContinentId)Usefuls.ContinentId == ContinentId.Azeroth && !azerothNodesUpdated || (ContinentId)Usefuls.ContinentId == ContinentId.Kalimdor && !kalimdorNodesUpdated || (ContinentId)Usefuls.ContinentId == ContinentId.Expansion01 && !outlandNodesUpdated || (ContinentId)Usefuls.ContinentId == ContinentId.Northrend && !northrendNodesUpdated) { Logger.Log($"Updating known FlightMasters on {Usefuls.ContinentNameMpq} for this session"); bool allInvalid = true; bool latNodeWasInvalid = false; bool modificationWasMade = false; bool endOfListReached = false; // 3 attempts to discover flights for (int j = 1; j <= 3; j++) { if (endOfListReached) { if ((ContinentId)Usefuls.ContinentId == ContinentId.Azeroth) { azerothNodesUpdated = true; } else if ((ContinentId)Usefuls.ContinentId == ContinentId.Kalimdor) { kalimdorNodesUpdated = true; } else if ((ContinentId)Usefuls.ContinentId == ContinentId.Expansion01) { outlandNodesUpdated = true; } else if ((ContinentId)Usefuls.ContinentId == ContinentId.Northrend) { northrendNodesUpdated = true; } break; } WFMMoveInteract.GoInteractwithFM(FMWithMapOpen); // Loop through nodes for (int i = 0; i < 120; i++) { string nodeName = Lua.LuaDoString <string>($"return TaxiNodeName({i})"); if (nodeName != "INVALID") { allInvalid = false; latNodeWasInvalid = false; if (SetFlightMasterToKnown(nodeName) && modificationWasMade == false) { modificationWasMade = true; } } else { // we hit 2 invalids in a row - means this is the end of the list if (latNodeWasInvalid) { endOfListReached = true; break; } latNodeWasInvalid = true; if (SetFlightMasterToUnknown(nodeName) && modificationWasMade == false) { modificationWasMade = true; } } } if (allInvalid) { Lua.LuaDoString("CloseGossip()"); Logger.LogDebug($"All flight nodes are invalid, retrying ({j}/3)"); Thread.Sleep(500); } } if (allInvalid) { ToolBox.PausePlugin("Couldn't find a valid flight node"); } return(modificationWasMade); } return(false); }
public static void SetFlightMasterToUnknown(int flightMasterID) { FlightMaster flightMaster = GetFlightMasterById(flightMasterID); SetFlightMasterToUnknown(flightMaster.Name); }
public static bool SetFlightMasterToKnown(int flightMasterID) { FlightMaster flightMaster = GetFlightMasterById(flightMasterID); return(SetFlightMasterToKnown(flightMaster.Name)); }
public static bool GoInteractwithFM(FlightMaster fm, bool openMapRequired = false) { if (GoToTask.ToPosition(fm.Position, 5f)) { if (!Main.isLaunched || !Conditions.InGameAndConnectedAndAliveAndProductStartedNotInPause || ObjectManager.Me.Position.DistanceTo(fm.Position) > 10f) { return(false); } // We're in fight (possibly on mount) if (ObjectManager.Me.InCombatFlagOnly) { if (ObjectManager.Me.IsMounted) { MountTask.DismountMount(); } return(false); } // We have reached the FM if (ObjectManager.Me.IsMounted) { MountTask.DismountMount(); } // Check if FM is here or dead WoWUnit nearbyFM = FindNearbyAliveFM(fm); if (nearbyFM == null) { fm.Disable("FlightMaster is absent or dead."); ResetFlags(); return(false); } // Approach FM if (!GoToTask.ToPosition(nearbyFM.Position, 1f)) { return(false); } Interact.InteractGameObject(ObjectManager.GetWoWUnitByEntry(fm.NPCId).First().GetBaseAddress); // Check if interaction successful if (!InteractWithFm(fm)) { fm.Disable("Unable to interact with NPC"); ResetFlags(); return(false); } Usefuls.SelectGossipOption(GossipOptionsType.taxi); // Check if map open if (openMapRequired && !FmMapIsOpen(fm)) { fm.Disable("Unable to open FM map"); ResetFlags(); return(false); } return(true); } // We haven't reach the FM yet return(false); }
private void TakeTaxi(FlightMaster fm, string taxiNodeName) { string clickNodeLua = "TakeTaxiNode(" + Lua.LuaDoString <int>("for i=0,120 do if string.find(TaxiNodeName(i),'" + taxiNodeName.Replace("'", "\\'") + "') then return i end end", "").ToString() + ")"; Logger.LogDebug(clickNodeLua); Lua.LuaDoString(clickNodeLua, false); Thread.Sleep(500); // 5 tries to click on node if it failed for (int i = 1; i <= 5; i++) { if (ObjectManager.Me.IsCast) { Usefuls.WaitIsCasting(); i = 1; Logger.Log("You're casting, wait"); continue; } if (ObjectManager.Me.IsOnTaxi || Main.inPause) { break; } else { Logger.Log($"Taking taxi failed. Retrying ({i}/5)"); Lua.LuaDoString($"CloseTaxiMap(); CloseGossip();"); Main.errorTooFarAwayFromTaxiStand = false; Thread.Sleep(500); if (WFMMoveInteract.GoInteractwithFM(fm)) { Thread.Sleep(500); } Usefuls.SelectGossipOption(GossipOptionsType.taxi); Thread.Sleep(500); Lua.LuaDoString(clickNodeLua, false); Thread.Sleep(500); } } if (Main.inPause) { return; } if (Main.errorTooFarAwayFromTaxiStand) { ToolBox.PausePlugin("Taking taxi failed (error clicking node)"); } else { Logger.Log($"Flying to {taxiNodeName}"); } Thread.Sleep(Usefuls.Latency + 500); Main.shouldTakeFlight = false; Main.errorTooFarAwayFromTaxiStand = false; Thread.Sleep(Usefuls.Latency + 500); if (!ObjectManager.Me.IsOnTaxi) { ToolBox.PausePlugin("Taking taxi failed"); } }
private static bool FMIsInDraneiStartingZone(FlightMaster fm) { return(fm.NPCId == 17555 || fm.NPCId == 17554); }
protected override Composite CreateMainBehavior() { return(new PrioritySelector( // PvP server considerations... // Combat is disabled while on the Taxi. If on the ground, we want it enabled // in case we get attacked on a PvP server. new Decorator(context => !LevelBot.BehaviorFlags.HasFlag(BehaviorFlags.Combat), new Action(context => { LevelBot.BehaviorFlags |= BehaviorFlags.Combat; })), // Move to flight master, and interact to take taxi ride... new Decorator(context => !Me.OnTaxi, new PrioritySelector(context => { FlightMaster = Query.FindMobsAndFactions(Utility.ToEnumerable <int>(MobId_FlightMaster)) .FirstOrDefault() as WoWUnit; return context; }, // If flight master not in view, move to where he should be... new Decorator(context => FlightMaster == null, new ActionRunCoroutine( context => UtilityCoroutine.MoveTo( WaitLocation, "FlightMaster location", MovementBy))), // Make certain the bombs are in our backpack... new ActionRunCoroutine( ctx => _waitForInventoryItem ?? (_waitForInventoryItem = new UtilityCoroutine.WaitForInventoryItem( () => ItemId_Bomb, () => { QBCLog.ProfileError( "Cannot continue without required item: {0}", Utility.GetItemNameFromId(ItemId_Bomb)); BehaviorDone(); }))), // Move to flightmaster, and gossip to hitch a ride... new Decorator(context => FlightMaster != null, new PrioritySelector( new Decorator(context => !FlightMaster.WithinInteractRange, new ActionRunCoroutine( context => UtilityCoroutine.MoveTo( FlightMaster.Location, FlightMaster.SafeName, MovementBy))), new ActionRunCoroutine(context => CommonCoroutines.StopMoving()), new Decorator(ctx => Me.Mounted, new ActionRunCoroutine(ctx => CommonCoroutines.LandAndDismount())), new Decorator(context => !GossipFrame.Instance.IsVisible, new Action(context => { FlightMaster.Interact(); })), new Action(context => { GossipFrame.Instance.SelectGossipOption(GossipOption); }) )) )) )); }
private static void MovementEventsOnMovementPulse(List <Vector3> points, CancelEventArgs cancelable) { if (shouldTakeFlight && points.Last() == destinationVector && !inPause) { Logger.Log("Cancelled move to " + destinationVector); cancelable.Cancel = true; } if (!ObjectManager.Me.IsAlive || ObjectManager.Me.IsOnTaxi || shouldTakeFlight || !isLaunched || inPause) { return; } DateTime dateBegin = DateTime.Now; // If we have detected a potential FP travel float totalWalkingDistance = ToolBox.CalculatePathTotalDistance(ObjectManager.Me.Position, points.Last()); // If the path is shorter than setting, we skip if (totalWalkingDistance < (double)WFMSettings.CurrentSettings.TaxiTriggerDistance) { //Logger.LogDebug($"Path ({Math.Round(totalWalkingDistance)} yards) is shorter than trigger setting {WFMSettings.CurrentSettings.TaxiTriggerDistance}. Let's walk."); return; } Logger.Log($"{Math.Round(totalWalkingDistance)} yards path is longer than trigger setting {WFMSettings.CurrentSettings.TaxiTriggerDistance}. " + $"Searching for flights."); if (Logging.Status.Contains("Follow Path") && !Logging.Status.Contains("Resurrect") && totalWalkingDistance < (double)WFMSettings.CurrentSettings.SkipIfFollowPathDistance) { Logger.Log($"Currently following path. {totalWalkingDistance} yards is smaller than trigger setting {WFMSettings.CurrentSettings.SkipIfFollowPathDistance} yards. Ignoring flights."); return; } destinationVector = points.Last(); from = GetClosestFlightMasterFrom(totalWalkingDistance); if (from == null) { Logger.Log("No FROM found"); return; } double distanceToNearestFM = ToolBox.CalculatePathTotalDistance(ObjectManager.Me.Position, from.Position); double departureDistance = distanceToNearestFM + WFMSettings.CurrentSettings.MinimumDistanceSaving; to = GetClosestFlightMasterTo(from.Position.DistanceTo(destinationVector)); //Logger.Log($"Best FROM is {from?.Name}"); //Logger.Log($"Best TO is {to?.Name}"); if (from.Equals(to)) { to = null; } // Calculate total real distance FROM/TO // if no TO found, we set the total distance back to walking distance double processedDistance; if (to == null) { processedDistance = totalWalkingDistance; } else { processedDistance = departureDistance + ToolBox.CalculatePathTotalDistance(to.Position, destinationVector); } //Logger.Log($"Walking distance is {Math.Round(totalWalkingDistance)}"); //Logger.Log($"Processed distance is {Math.Round(processedDistance)}"); // If total real distance does not save any distance or is longer, try to find alternative if (processedDistance >= totalWalkingDistance || to == null) { if (to == null) { Logger.Log($"No direct flight path, trying to find an alternative, please wait"); } else { Logger.Log($"Flight from {from.Name} to {to.Name} would save {Math.Round(totalWalkingDistance - processedDistance + WFMSettings.CurrentSettings.MinimumDistanceSaving)} yards. " + $"You set a minimum of {WFMSettings.CurrentSettings.MinimumDistanceSaving} yards. Trying to find an alternative."); } // Pre order the list List <FlightMaster> orderedListFM = FlightMasterDB.FlightMasterList .FindAll(fm => fm.IsDiscovered && fm.NPCId != from.NPCId && ToolBox.FMIsOnMyContinent(fm)) .OrderBy(fm => fm.Position.DistanceTo(destinationVector)).ToList(); foreach (FlightMaster flightMaster in orderedListFM) { if (flightMaster.Position.DistanceTo(destinationVector) + departureDistance < processedDistance) { // Look for the closest available FM near destination double alternativeDistance = departureDistance + ToolBox.CalculatePathTotalDistance(flightMaster.Position, destinationVector); Logger.Log($"Alternative TO : {flightMaster.Name} ({Math.Round(alternativeDistance)} yards total)"); if (alternativeDistance < processedDistance) { processedDistance = alternativeDistance; to = flightMaster; } } } } if (to != null && from != null && !from.Equals(to) && processedDistance <= totalWalkingDistance) { double realProcessedDistance = Math.Round(processedDistance - WFMSettings.CurrentSettings.MinimumDistanceSaving); Logger.Log($"Flight found for {Math.Round(totalWalkingDistance)} yards path. Processed distance is {realProcessedDistance} yards." + $" Taking Taxi from {from.Name} to {to.Name}. (You will save {Math.Round(totalWalkingDistance) - realProcessedDistance} yards)"); MovementManager.StopMoveNewThread(); MovementManager.StopMoveToNewThread(); cancelable.Cancel = true; shouldTakeFlight = true; } else { Logger.Log($"No relevant flight found for {Math.Round(totalWalkingDistance)} yards path"); } Logger.Log($"Process time : {(DateTime.Now.Ticks - dateBegin.Ticks) / 10000} ms"); }