What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal
RebornBuddy Forums

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Utilizing the Navmesh System?

kagamihiiragi17

Community Developer
Joined
Jun 24, 2014
Messages
873
What's the best way to use the navmesh system that the Fate Bot uses? I can't find great documentation for it and it would be lovely in implementing repairs into Magitek. If anyone has some sample code I could look at or something that would be lovely. Thanks!
 
Navigation is a bit tricky since we use a remote server for navmeshs. There are three main functions that you'd be interested in. CanFullyNavigateTo,MoveToPointWithin,MoveTo

To query if you are able to reach a location:
This function is synchronous and canlockup the client for a short period so its best to cache the results or call it only once in a while.
Code:
            var nav = (Navigator.NavigationProvider as GaiaNavigator);
            var fates = FateManager.ActiveFates.Where(IsValid);


            var fateDatas = fates as FateData[] ?? fates.ToArray();
            var navReq = fateDatas.Select(r => new CanFullyNavigateTarget { Id = r.Id, Position = r.Location });
            if (!navReq.Any())
            {
                Logging.Write("No fates we can tackle currently.");
                return RunStatus.Failure;
            }
            var paths = nav.CanFullyNavigateTo(navReq);
            if (paths == null)
            {
                Logging.WriteDiagnostic("Something strange happened, null path returned.");
                return RunStatus.Failure;
            }


MoveToPointWithin,MoveTo are asynchronous and will not lockup, to be used you basically need to keep calling them with the same parameters so that they don't request a new path.

Movetopointwithin basicly picks a random spot within X yards of the provided spot that it can navigate to.:
Code:
Navigator.MoveToPointWithin(Poi.Current.Location, 15, "Moving to rest location")

For moveto we have nice wrappers that you should use inside commonbehaviors:

Code:
CommonBehaviors.CreateMountBehavior()

Code:
CommonBehaviors.MoveAndStop(ret => Location, r => 4f, true, "Moving to a location")


I'd be more concerned about getting the windows interaction working properly first. Once you have that done I can help you setup a POI chain that will integrate with the botbase.
 
I'd be more concerned about getting the windows interaction working properly first. Once you have that done I can help you setup a POI chain that will integrate with the botbase.

I have the window interaction done, for now it uses simple keyboard commands to navigate through the window (sending the client NumPad0 activates the cursor, and then you can navigate windows using NumPad8, NumPad2, NumPad6 and NumPad4) which works but in the future as window interaction is added to RebornBuddy we can clean up the code. Are there any downsides to navigating the window like that? The only downside I can think of is if someone has those keybindings changed, but we can add variables to the settings for people to input what they have their keybindings as.

The code looks like the following:

Code:
        [DllImport("user32.dll")]
        public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        public static void Repair()
        {
            // Ideally this will contain databases for each zone including all repairing NPCs (their names, and locations)
            // and will be able to navigate to the closest one, repair, then go back to the inital location

            Vector3 InitialLocation;
            InitialLocation = Core.Player.Location;

            const uint WM_KEYDOWN = 0x100;
            const uint WM_KEYUP = 0x0101;

            // Add code to target NPC and then
            // move player to the NPC as well
            

            // From here on the code should be fine
            // to complete the repair
            Core.Player.CurrentTarget.Interact();

            Thread.Sleep(1000);  // Wait for the window to open

            IntPtr hWnd;
            string processName = "ffxiv";
            Process[] processList = Process.GetProcesses();

foreach (Process P in processList)
            {
                if (P.ProcessName.Equals(processName))
                {
                    // The following code navigates the window and completes the repair, and then closes the window
                    IntPtr edit = P.MainWindowHandle;
                    if (Core.Target.Name == "Merchant & Mender")
                    {
                        // Merchant & Menders have an additional window before the repair window to navigate
                        PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                        PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                        Thread.Sleep(500);
                        PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad8), IntPtr.Zero);
                        PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad8), IntPtr.Zero);
                        Thread.Sleep(500);
                        PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad8), IntPtr.Zero);
                        PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad8), IntPtr.Zero);
                        Thread.Sleep(500);
                        PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                        PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                        Thread.Sleep(1000);
                    }
                    else
                    {
                        PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                        PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                        Thread.Sleep(500);
                    }
                    PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad6), IntPtr.Zero);
                    PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad6), IntPtr.Zero);
                    Thread.Sleep(500);
                    PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                    PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                    Thread.Sleep(500);
                    PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad4), IntPtr.Zero);
                    PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad4), IntPtr.Zero);
                    Thread.Sleep(500);
                    PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                    PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.NumPad0), IntPtr.Zero);
                    Thread.Sleep(500);
                    PostMessage(edit, WM_KEYDOWN, (IntPtr)(Keys.Escape), IntPtr.Zero);
                    PostMessage(edit, WM_KEYUP, (IntPtr)(Keys.Escape), IntPtr.Zero);
                }
            }

            Logging.Write("[Magitek] Repaired!");

            // Add logic to get back to the initial location
        }
 
Last edited:
Perhaps I'm showing my inexperience here, but I never did really get this working properly. Is there a good way to implement navigation without using TreeSharp? I'm still really new to TreeSharp so all my code for repairing is written in C#. Right now I have it set up to insert an NPC Name and location, and then ideally the bot will move to that location, interact with the NPC, do the repairs, and then move back to the initial location and resume the profile. I'd love to get this up and working but I still don't quite understand moving long distances. (moving in a straight line to a nearby point is easy, just a function call. If there was a nice function to move long distances on the same map that would be amazing! *wink*)
 
namespace ff14bot.Behavior
{
public static class CommonBehaviors
{
 
Sorry, I meant the navmesh system. CommonBehaviors doesn't use navmesh, right? Or did that change?
 
It depends on what botbase your using. But they were designed for orderbot/fatebot.
 
What's the best way to repeatedly call the MoveToPointWithin function without TreeSharp? Putting it in a while loop freezes the game, and I haven't had much luck using Timer.Elapsed, putting it in a new thread, using tasks, or much else either. Sorry for the repeated bother, C# is still somewhat new to me.
 
Back
Top