• Visit Rebornbuddy
  • Odd Behavior Interacting with NPC during Quest

    Discussion in 'Community Developer Forum' started by mistahmikey, Jun 7, 2016.

    1. mistahmikey

      mistahmikey New Member

      Joined:
      Jun 29, 2015
      Messages:
      161
      Likes Received:
      3
      Trophy Points:
      0
      I am trying to modify the TalkTo tag behavior to work with an NPC that requires a long series of question popups to be answered. I am using y2crazy's TalkToPlus tag approach for the most part, where he inherits from TalkTo and overrides TalkTo.CreateBehavior to provide Quest-specific dialog interaction. I have modified his TalkToPlus.CreateBehavior to sequence the correct answers to all the dialogs that pop up during Quest step 4. The problem I am seeing is that it appears RB is somehow interacting with the NPC outside of my code. Here is the tag, which has been reduced to just interact with the NPC at the proper quest step:

      Code:
      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Linq;
      using System.Runtime.InteropServices;
      using System.Text;
      using System.Threading;
      using System.Threading.Tasks;
      using System.Windows.Forms;
      using System.Windows.Media;
      using System.Diagnostics;
      using Clio.Utilities;
      using Clio.XmlEngine;
      using ff14bot.Behavior;
      using ff14bot.Helpers;
      using ff14bot.Managers;
      using ff14bot.Navigation;
      using ff14bot.NeoProfiles;
      using ff14bot.RemoteWindows;
      using TreeSharp;
      using Action = TreeSharp.Action;
      
      namespace ff14bot.NeoProfiles.Tags
      {
          [XmlElement("TalkToPlus")]
      
          class TalkToPlusTag : TalkToTag
          {
      		private int question = -1;
      
              private void Log(string text, params object[] args)
              {
                  Logging.Write(Colors.White, "[TalkToPlus] " + text + " ", args);
              }
      		
              protected override void OnResetCachedDone()
              {
      			question = -1;
                  base.OnResetCachedDone();
      		}
              protected override Composite CreateBehavior()
              {
                  return new PrioritySelector(
      				new Decorator(ret => QuestId == 67669 &&  QuestLogManager.GetQuestById(QuestId).Step == 4 && question == -1,
      					new Action(r => 
      					{
      						GameObjectManager.GetObjectByNPCId((uint)NpcId).Interact();
      						question = 1;
      						
      						Log("QuestId 67669, Step 4, Interact");
      						
      						return RunStatus.Success; 
      					})
      				),
      				new Decorator(ret => question == 1 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("The killer is among us"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, The killer is among us",question);
      							
      							question = 2;							
      						}
      						
      						return RunStatus.Success;
      					})
                      ),
                      new Decorator(ret => question == 2 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("Yes"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, Yes",question);
      							
      							question = 3;							
      						}
      						
      						return RunStatus.Success;							
      					})
                      ),
                      new Decorator(ret => question == 3 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("mixed in his drink"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, mixed in his drink",question);
      							
      							question = 4;						
      						}
      						
      						return RunStatus.Success;                    
      					})
      				),
                      new Decorator(ret => question == 4 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("smell his glass"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, smell his glass",question);							
      							
      							question = 5;							
      						}
      						
      						return RunStatus.Success;
      					})
                      ),
                      new Decorator(ret => question == 5 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("already on the table"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, already on the table",question);							
      							
      							question = 6;							
      						}
      						
      						return RunStatus.Success;                    
      					})
                      ),
                      new Decorator(ret => question == 6 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("phial"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, phial",question);							
      
      							question = 7;							
      						}
      						
      						return RunStatus.Success;                    
      					})
      				),
                      new Decorator(ret => question == 7 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("Senor"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, Senor",question);							
      
      							question = 8;							
      						}
      						
      						return RunStatus.Success;                    
      					})
                      ),
                      new Decorator(ret => question == 8 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("true killer"))
      						{						
      							Log("QuestId 67669, Step 4, Question {0}, true killer",question);							
      
      							question = 9;
      						}
      						
      						return RunStatus.Success;                    							
      					})
      				),
                      new Decorator(ret => question == 9 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("gambling habit"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, gambling habit",question);							
      
      							question = 10;						
      						}
      						
      						return RunStatus.Success;                    
      					})
      				),
                      new Decorator(ret => question == 10 && SelectString.IsOpen,
      					new Action(r =>
      					{
      						if (SelectString.ClickLineContains("Roland"))
      						{
      							Log("QuestId 67669, Step 4, Question {0}, Roland",question);							
      
      							question = -1;							
      						}
      						
      						return RunStatus.Success;                    
      					})
      				)
      			);
              }
          }
      }
      Right off the bat something unexpected happens. After I interact with the NPC, the resulting talk dialogs are getting automatically dismissed somehow, even though I have suppressed that behavior by not calling TalkTo.CreateBehavior at the bottom of my PrioritySelector. There is no code associated with the TalkToPlus tag that is calling Talk.Next(). I have no idea how these dialogs are getting dismissed.

      However, I am able to answer the first five questions, and I see the log messages of their associated Decorators indicating my code is doing the answering. Again, the talk dialogs that result after answering a question are being magically dismissed. Once it gets to question 5, the remainder of the question dialogs that get popped up are being automatically answered somehow outside of my code - I see no more of the log messages that would occur if my code was selected to answer them, yet the quest progresses forward, albeit incorrectly, and winds up getting into an endless question/answer loop due to the wrong "auto" answers. Here is the log snippet from running the code:

      Code:
      [13:48:56.911 V] [Poi.Clear] Reason: Current behavior changed to TalkToPlusTag: IsDone: False, NpcId: 1017051, InteractDistance: 5, BypassTargetChange: False, XYZ: <53.18424, 20.99973, 77.31863>, NPC: Ollier 0x14228E50, HighPriority: False, LineNumber: 315, InCombat: False, QuestId: 67669, StepId: 0, PostCombatDelay: 0, QuestName: And Then There Were Some, IsDoneCache: False, Behavior: TreeSharp.PrioritySelector, .
      [13:48:56.911 D] Replaced hook [ProfileOrderBehavior_Hook] 1605b537-7d86-40c1-ad41-2f28760f526f
      [13:48:56.913 D] Interacting with Ollier 0x14228E50
      [13:48:56.913 N] [TalkToPlus] QuestId 67669, Step 4, Interact 
      [13:48:57.841 N] [TalkToPlus] QuestId 67669, Step 4, Question 1, The killer is among us 
      [13:48:58.673 N] [TalkToPlus] QuestId 67669, Step 4, Question 2, Yes 
      [13:49:21.492 N] [TalkToPlus] QuestId 67669, Step 4, Question 3, mixed in his drink 
      [13:49:27.719 N] [TalkToPlus] QuestId 67669, Step 4, Question 4, smell his glass 
      [13:49:37.112 N] [TalkToPlus] QuestId 67669, Step 4, Question 5, already on the table 
      I have tried removing all 3rd party plugins and botbases (except for ExBuddy) but it doesn't make any difference. Any ideas as to how RB is interacting with the NPC outside of my tag code would be appreciated.

      Thanks.
       
      Last edited: Jun 8, 2016
    2. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      4,976
      Likes Received:
      327
      Trophy Points:
      83
      Orderbot handles SelectString's that appear during a cutscene. You can queue up what options you want to use before your talkto with the SelectStringOverride tag.
       
    3. mistahmikey

      mistahmikey New Member

      Joined:
      Jun 29, 2015
      Messages:
      161
      Likes Received:
      3
      Trophy Points:
      0
      Ok, I tried using SelectStringOverride as follows:

      Code:
      					<MoveTo Name="Ollier" XYZ="53.18424, 20.99973, 77.31863" />
      					<SelectStringOverride Index="0,0,0,2,2,2,0,2,0,1" QuestId="67669" StepId="4"/>
      					<TalkTo NpcId="1017051" XYZ="53.18424, 20.99973, 77.31863" QuestId="67669" StepId="4"/>
      
      This did not work for me. At first, it got a ways into the sequence, and I started getting the following:

      Code:
      [22:43:58.910 N] Waiting at location for valid npc to spawn
      [22:44:03.942 D] System.NullReferenceException: Object reference not set to an instance of an object.
         at ff14bot.NeoProfiles.Tags.TalkToTag.<CreateBehavior>b__32_14(Object ret) in C:\Users\Mike\Desktop\Rebornbuddy\Quest Behaviors\TalkTo.cs:line 135
         at TreeSharp.Action.RunAction(Object context)
         at TreeSharp.Action.<Execute>d__13.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at ff14bot.Behavior.HookExecutor.Run(Object context)
         at TreeSharp.Action.RunAction(Object context)
         at TreeSharp.Action.<Execute>d__13.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at ff14bot.Behavior.HookExecutor.Run(Object context)
         at TreeSharp.Action.RunAction(Object context)
         at TreeSharp.Action.<Execute>d__13.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.Decorator.<Execute>d__12.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at ff14bot.TreeRoot.()
      [22:44:04.440 N] Waiting at location for valid npc to spawn
      [22:44:09.473 D] System.NullReferenceException: Object reference not set to an instance of an object.
         at ff14bot.NeoProfiles.Tags.TalkToTag.<CreateBehavior>b__32_14(Object ret) in C:\Users\Mike\Desktop\Rebornbuddy\Quest Behaviors\TalkTo.cs:line 135
         at TreeSharp.Action.RunAction(Object context)
         at TreeSharp.Action.<Execute>d__13.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at ff14bot.Behavior.HookExecutor.Run(Object context)
         at TreeSharp.Action.RunAction(Object context)
         at TreeSharp.Action.<Execute>d__13.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at ff14bot.Behavior.HookExecutor.Run(Object context)
         at TreeSharp.Action.RunAction(Object context)
         at TreeSharp.Action.<Execute>d__13.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.Decorator.<Execute>d__12.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at TreeSharp.PrioritySelector.<Execute>d__2.MoveNext()
         at TreeSharp.Composite.Tick(Object context)
         at ff14bot.TreeRoot.()
      
      Looking at TalkTo.cs, I was able to get rid of the stack dump by putting a decorator on the last action and guarding it with NPC != null. But while this eliminated the stack dump, the dialogs still are not being answered properly. I am absolutely certain the that indexes provided are correct, as I have checked it numerous times now manually.

      So I am unable to make this work. Is there some way to tell Orderbot not to interact with the NPC during the conversation so it can be completely handled via custom code? If not, could it be added? If not, how do I make this work? Perhaps as a debug aid, you could have Orderbot log each index/line it is uses during the interaction - otherwise, it's impossible to tell if Orderbot is really using the indexes I gave it properly.

      Thanks.
       
      Last edited: Jun 8, 2016
    4. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      4,976
      Likes Received:
      327
      Trophy Points:
      83
      You'll need your modified behavior for the non cutscene ones.
       
    5. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      4,976
      Likes Received:
      327
      Trophy Points:
      83
      You could also use a codechunk
       
    6. mistahmikey

      mistahmikey New Member

      Joined:
      Jun 29, 2015
      Messages:
      161
      Likes Received:
      3
      Trophy Points:
      0
      There are several cutscenes during that quest step. I am not sure what indexes I would need to have SelectStringOverride handle and which ones my custom code should handle.

      As far as the code chuck is concerned, is Orderbot suspended during the codechunk? I initially tried to do the entire quest step in a coroutine, but I guess because things like Talk.Next and SelectString.ClickSlot are not awaitable the coroutine doesn't yield after calling them so the game does not change state. Wouldn't the code chunk have this same issue?
       
    7. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      4,976
      Likes Received:
      327
      Trophy Points:
      83
      the only time stuff gets dequeued from the orderbot list is when its used, since it only gets used during the cutscene portions just queue up the orders that happen during the cutscene.

      Theres no way around having orderbot handle some of them as the logic that handles that also handles the talk dialogs and closing trade windows from players etc.


      as for the codechunk if your inside a while loop you need to await Coroutine.Yield();

      Code:
      
      
      
      while(!SelectString.IsOpen)
      {
      if (Talk.DialogOpen)
      {
      Talk.Next();
      }
      await Coroutine.Yield();
      }
      
      
      would run until the first selectstring appeared



      something for your case would be


      Code:
      
      queue<int> queus = new queue(2,3,3,4)
      
      Start:
      while(!SelectString.IsOpen)
      {
      if (Talk.DialogOpen)
      {
      Talk.Next();
      }
      await Coroutine.Yield();
      }
      
      if (que.count > 0)
      {
      SelectString.ClickSlot(que.Dequeue);
      goto Start;
      }
      
      don't have an ide so psudoish
       
    8. mistahmikey

      mistahmikey New Member

      Joined:
      Jun 29, 2015
      Messages:
      161
      Likes Received:
      3
      Trophy Points:
      0
      Ok, I'll play around with that for a bit. Thanks for the ideas.
       
    9. mistahmikey

      mistahmikey New Member

      Joined:
      Jun 29, 2015
      Messages:
      161
      Likes Received:
      3
      Trophy Points:
      0
      Using a coroutine I was able to sequence things properly and complete the quest. But now I have another odd problem.

      The quest is repeatable. I am able to pickup the quest again, but when I run the exact same profile code to step through the quest, it refuses to interact with any of the quest NPCs, even though they have the same NpcId. No error messages in the log and the TalkTo tag appears to do nothing - doesn't even show up in the log as being invoked. I can manually step though the quest and restart the profile, and it will go to the next NPC and once again no interaction occurs.

      So is there something different that must be done to run a repeatable quest?
       
    10. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      4,976
      Likes Received:
      327
      Trophy Points:
      83
      You need to use the RegisterDailies tag
       
    11. mistahmikey

      mistahmikey New Member

      Joined:
      Jun 29, 2015
      Messages:
      161
      Likes Received:
      3
      Trophy Points:
      0
      Heh. Ok, so that got me going for the repeatable quest. Now, when I turn the quest in, there is a popup for the reward that is not being accepted. I don't think I had to do that manually the first time though. Some other subtlety I have missed?

      After I manually accepted the reward, for some reason, the quest somehow got picked up again automatically before the script finished (I have no loop in it). Is that a feature of "dailies"?
       
    12. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      4,976
      Likes Received:
      327
      Trophy Points:
      83
      No idea

      Dailies aren't a 'feature', they need to be tagged cause the game handles them differently and theres no easy way to tell them apart. Check your code again as there is nothing like that.
       
    13. mistahmikey

      mistahmikey New Member

      Joined:
      Jun 29, 2015
      Messages:
      161
      Likes Received:
      3
      Trophy Points:
      0
      Ah, I was mistaken about the reward - the popup is actually the quest being automatically offered again by the NPC because the TurnIn tag somehow is not detecting the the quest completed. So when I clicked on it, thinking it was the reward because my brain is fried, it actually started the quest again :p

      Anyway, there does appear to be something amiss with the turnin tag - it is not completing, and repeatedly tries to interact with the NPC:

      Code:
      [03:29:25.397 N] [TurnInTag] Turning in quest And Then There Were Some(67669) from Ollier at <16.91355, 3.99973, 39.59686>
      [03:29:25.398 V] [Poi.Clear] Reason: Current behavior changed to TurnInTag: RewardSlot: -1, ItemIds: null, RequiresHq: null, IsDone: False, NpcId: 1016998, InteractDistance: 5, XYZ: <16.91355, 3.99973, 39.59686>, NPC: Ollier 0x151C2980, HighPriority: False, LineNumber: 341, InCombat: False, QuestId: 67669, StepId: 255, PostCombatDelay: 0, QuestName: And Then There Were Some, IsDoneCache: False, Behavior: TreeSharp.PrioritySelector, .
      [03:29:25.398 D] Replaced hook [ProfileOrderBehavior_Hook] 0f77f21e-c152-4d38-b1bb-731d5e016177
      [03:29:25.399 D] Requesting path on 144 from <53.98478, 20.99973, 74.47569> to <16.91355, 3.99973, 39.59686>
      [03:29:25.422 D] Generated path to <16.91355, 3.99973, 39.59686> in 00:00:00.0229936 ms
      [03:29:25.467 N] Sprinting
      [03:29:25.467 D] DoAction Spell 3 0xE0000000
      [03:29:28.097 D] Moving to next hop: <33.70065, 18.06595, 97.84918> (TurnInTag: Ollier) D: 13.79671
      [03:29:29.731 D] Moving to next hop: <32.29922, 17.62856, 98.41392> (TurnInTag: Ollier) D: 2.158749
      [03:29:29.898 D] Moving to next hop: <31.07273, 16.75441, 99.65511> (TurnInTag: Ollier) D: 2.694128
      [03:29:30.131 D] Moving to next hop: <30.42348, 16.42955, 99.77819> (TurnInTag: Ollier) D: 1.39759
      [03:29:30.197 D] Moving to next hop: <27.85585, 15.29174, 100.8673> (TurnInTag: Ollier) D: 3.82427
      [03:29:30.564 D] Moving to next hop: <27.00238, 14.99356, 100.9742> (TurnInTag: Ollier) D: 1.63063
      [03:29:30.664 D] Moving to next hop: <24.70689, 13.91422, 101.6006> (TurnInTag: Ollier) D: 3.366841
      [03:29:30.996 D] Moving to next hop: <23.77528, 13.56151, 101.1658> (TurnInTag: Ollier) D: 1.586786
      [03:29:31.133 D] Moving to next hop: <20.92954, 12.23186, 100.2782> (TurnInTag: Ollier) D: 3.682652
      [03:29:31.497 D] Moving to next hop: <19.98306, 11.83712, 100.264> (TurnInTag: Ollier) D: 1.595556
      [03:29:31.597 D] Moving to next hop: <17.92928, 10.60412, 98.0238> (TurnInTag: Ollier) D: 3.876117
      [03:29:31.964 D] Moving to next hop: <16.54076, 9.915389, 96.94527> (TurnInTag: Ollier) D: 2.663524
      [03:29:32.198 D] Moving to next hop: <16.12629, 9.532109, 96.27399> (TurnInTag: Ollier) D: 1.529494
      [03:29:32.297 D] Moving to next hop: <15.70519, 8.969353, 95.38362> (TurnInTag: Ollier) D: 1.799475
      [03:29:32.431 D] Moving to next hop: <14.65249, 8.51965, 94.75597> (TurnInTag: Ollier) D: 1.891354
      [03:29:32.565 D] Moving to next hop: <13.74083, 7.101558, 91.8235> (TurnInTag: Ollier) D: 4.046055
      [03:29:32.964 D] Moving to next hop: <15.69787, 3.999998, 82.0662> (TurnInTag: Ollier) D: 10.95762
      [03:29:34.232 D] Moving to next hop: <10.92054, 3.999998, 67.69707> (TurnInTag: Ollier) D: 15.64965
      [03:29:36.165 D] Moving to next hop: <12.74475, 4.084345, 53.17956> (TurnInTag: Ollier) D: 15.15422
      [03:29:38.031 D] Moving to next hop: <11.35499, 4.11152, 52.91882> (TurnInTag: Ollier) D: 1.577831
      [03:29:38.132 D] Moving to next hop: <6.993085, 4.009274, 51.747> (TurnInTag: Ollier) D: 5.27805
      [03:29:38.731 D] Moving to next hop: <6.404489, 4.018307, 50.65307> (TurnInTag: Ollier) D: 1.722833
      [03:29:38.864 D] Moving to next hop: <6.330033, 4.030712, 48.5444> (TurnInTag: Ollier) D: 2.671162
      [03:29:39.131 D] Moving to next hop: <7.411065, 4.062657, 45.99053> (TurnInTag: Ollier) D: 3.275637
      [03:29:39.465 D] Moving to next hop: <9.15125, 4.008882, 43.88712> (TurnInTag: Ollier) D: 3.365983
      [03:29:39.798 D] Moving to next hop: <16.91355, 3.99973, 39.59686> (TurnInTag: Ollier) D: 9.559087
      [03:29:40.398 D] Interacting with Ollier 0x151C2980
      [03:30:37.864 D] Interacting with Ollier 0x151C2980
      [03:31:02.365 D] Interacting with Ollier 0x151C2980
      [03:31:22.366 D] Interacting with Ollier 0x151C2980
      [03:31:51.443 D] Interacting with Ollier 0x151C2980
      
       
    14. mastahg

      mastahg Administrator Staff Member

      Joined:
      Feb 27, 2011
      Messages:
      4,976
      Likes Received:
      327
      Trophy Points:
      83
      Seasonal events don't work properly, take a look at y2krazys svn. The lua funcs we normally use return incorrect values for the seasonal quests.
       
      y2krazy likes this.

    Share This Page