Would it be possible to get a tag for Order Bot that allows us to execute a line of code? This would help cover for tags we don't have, like casting spells, using abilities, and other things that might not warrant their own tag but need to be done in profiles from time to time. Something like the following would be awesome: Code: <Execute Code="Actionmanager.DoActionLocation("Fiery Breath", new Vector3("-76.40997, -2.187002, -75.45219"))" /> Is that possible? It would hopefully cut down on any future requests you might get for adding tags to Order Bot because we could build our own tag, in a way.
Just write your own profile tag and slap it inside a plugin, it should get picked up by the engine Code: using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using Clio.Utilities; using Clio.XmlEngine; using ff14bot.Behavior; using ff14bot.Helpers; using ff14bot.Managers; using ff14bot.Navigation; using TreeSharp; using Action = TreeSharp.Action; namespace ff14bot.NeoProfiles { [XmlElement("MoveTo")] public class MoveToTag : ProfileBehavior { private bool _done; [Clio.XmlEngine.XmlAttribute("XYZ")] public Vector3 XYZ { get { return Position; } set { Position = value; } } public Vector3 Position; [XmlAttribute("Name")] public string Name { get; set; } [DefaultValue(3)] [XmlAttribute("Distance")] public float Distance { get; set; } public override bool IsDone { get { return _done; } } protected override Composite CreateBehavior() { return new PrioritySelector( new Decorator( ret => Core.Me.Location.Distance(Position) <= Distance, new Sequence( new Action(ret => Navigator.Clear()), new Sleep(1000), new Action(ret => _done = true) )), CommonBehaviors.MoveAndStop(ret => Position, Distance,stopInRange:true, destinationName: Name) ); } /// <summary> /// This gets called when a while loop starts over so reset anything that is used inside the IsDone check /// </summary> public override void ResetCachedDone() { _done = false; } protected override void OnDone() { // Force a stop! Navigator.PlayerMover.MoveStop(); } } }
I think the point of asking for you to implement 1 Tag that can use a line of code is so that the community developers who are supporting your bot don't have to get into the details of how to write our own Tag. We want to be able to just put in the 1 line of code like Kaga explained in the original post. Is it too much to ask for 1 more tag to be developed by you?
Doing a tag that executes C# code is actually kinda complex and is a bit of a dirty hack that I'd like to avoid if possible. Also, a possible security risk, as people expect profiles to be safe.
I don't mind writing a tag, I just hope people will be sure to download it when they have a profile that requires it, haha. Thanks for the example code, I appreciate it.
Mastahg, is there a good way to disable combat while running a tag? There are some quests where you get a special mount and you have to go use one of the mount's abilities at various locations, but if the character enters combat on the way to that location, it dismounts the special mount and kills it, but then has to run back to the initial location and get the mount again. This obviously doesn't work, but if I could disable combat for the duration of that tag only, it would work wonderfully. Thanks!
I'll just be honest and say I don't understand what you mean, I'm still getting accustomed to TreeSharp. This is what I have right now... how can I do what you're saying? Code: using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using Clio.Utilities; using Clio.XmlEngine; using ff14bot.Behavior; using ff14bot.Helpers; using ff14bot.Managers; using ff14bot.Navigation; using TreeSharp; using Action = TreeSharp.Action; namespace ff14bot.NeoProfiles { [XmlElement("UseSpell")] public class UseSpellTag : ProfileBehavior { private bool _done; [Clio.XmlEngine.XmlAttribute("XYZ")] public Vector3 XYZ { get { return Position; } set { Position = value; } } public Vector3 Position; [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("SpellID")] public uint SpellID { get; set; } [XmlAttribute("NPC")] public uint NPC { get; set; } [DefaultValue(3)] [XmlAttribute("Distance")] public float Distance { get; set; } public override bool IsDone { get { return _done; } } protected override Composite CreateBehavior() { return new PrioritySelector( new Decorator(ret => Core.Me.Location.Distance(Position) <= Distance && !GameObjectManager.GetObjectByNPCId(NPC).IsVisible, new Action(ret => _done = true)), new Decorator(ret => Core.Me.Location.Distance(Position) <= Distance, new Action(r => { Navigator.PlayerMover.MoveStop(); if (!Core.Player.IsCasting) { Actionmanager.DoActionLocation(SpellID, Core.Player.Location); } } )), CommonBehaviors.MoveAndStop(ret => Position, Distance, stopInRange: true, destinationName: Name) ); } /// <summary> /// This gets called when a while loop starts over so reset anything that is used inside the IsDone check /// </summary> public override void ResetCachedDone() { _done = false; } protected override void OnDone() { // Force a stop! Navigator.PlayerMover.MoveStop(); } } }
That worked perfectly Mastahg, thank you! Here's another question: I'm making a tag for when you need to use an item/emote on a weakened NPC... Once the bot gets into combat it never seems to pulse the tag again until the character isn't in combat anymore. Is there any way around that? I can post/send you the code for the tag if that would help.
Ah, I look forward to this being implemented. Just for future reference if I or someone else runs across the same problem though, is there an easy fix for the problem of the tag not being pulsed in combat?
For the next version its setup so anytag that doesnt do anything weird can be setup to run while incombat by using our treehooks system.
It turned out I inadvertently lied... I thought I had tested the "new ActionAlwaysSucceed()" bit, but apparently I hadn't. Even with adding that bit of code the bot still fights any mobs it comes across while in that tag. Here's the updated code... Code: using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using Clio.Utilities; using Clio.XmlEngine; using ff14bot.Behavior; using ff14bot.Helpers; using ff14bot.Managers; using ff14bot.Navigation; using TreeSharp; using Action = TreeSharp.Action; namespace ff14bot.NeoProfiles { [XmlElement("UseSpell")] public class UseSpellTag : ProfileBehavior { private bool _done; [Clio.XmlEngine.XmlAttribute("XYZ")] public Vector3 XYZ { get { return Position; } set { Position = value; } } public Vector3 Position; [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("SpellID")] public uint SpellID { get; set; } [XmlAttribute("NPC")] public uint NPC { get; set; } [DefaultValue(3)] [XmlAttribute("Distance")] public float Distance { get; set; } public override bool IsDone { get { return _done; } } protected override Composite CreateBehavior() { return new PrioritySelector( new Decorator(ret => Core.Me.Location.Distance(Position) <= Distance && !GameObjectManager.GetObjectByNPCId(NPC).IsVisible, new Action(ret => _done = true)), new Decorator(ret => Core.Me.Location.Distance(Position) <= Distance, new Action(r => { Navigator.PlayerMover.MoveStop(); if (!Core.Player.IsCasting) { ff14bot.Managers.Actionmanager.DoActionLocation(SpellID, Core.Player.Location); } } )), CommonBehaviors.MoveAndStop(ret => Position, Distance, stopInRange: true, destinationName: Name), new ActionAlwaysSucceed() ); } /// <summary> /// This gets called when a while loop starts over so reset anything that is used inside the IsDone check /// </summary> public override void ResetCachedDone() { _done = false; } protected override void OnDone() { Navigator.PlayerMover.MoveStop(); } } } I also tried using the following to no avail: Code: new Decorator(r => true, new ActionAlwaysSucceed()) Any ideas as to why that might be?
Try this. Code: using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using Buddy.Auth.zlib; using Clio.Utilities; using Clio.XmlEngine; using ff14bot.Behavior; using ff14bot.Helpers; using ff14bot.Managers; using ff14bot.Navigation; using ff14bot.NeoProfiles; using TreeSharp; using Action = TreeSharp.Action; namespace ff14bot.NeoProfile { [XmlElement("UseSpell")] public class UseSpellTag : ProfileBehavior { private bool _done; [Clio.XmlEngine.XmlAttribute("XYZ")] public Vector3 XYZ { get { return Position; } set { Position = value; } } public Vector3 Position; [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("SpellID")] public uint SpellID { get; set; } [XmlAttribute("NPC")] public uint NPC { get; set; } [DefaultValue(3)] [XmlAttribute("Distance")] public float Distance { get; set; } public override bool IsDone { get { return _done; } } private bool IsFinished { get { var unit = GameObjectManager.GetObjectByNPCId(NPC); if (unit != null) { return !unit.IsVisible; } return true; } } protected Composite Behavior() { return new PrioritySelector( new Decorator(ret => Core.Me.Location.Distance(Position) <= Distance && IsFinished, new Action(ret => _done = true)), new Decorator(ret => Core.Me.Location.Distance(Position) <= Distance, new Action(r => { Navigator.PlayerMover.MoveStop(); if (!Core.Player.IsCasting) { ff14bot.Managers.Actionmanager.DoActionLocation(SpellID, Core.Player.Location); } } )), CommonBehaviors.MoveAndStop(ret => Position, Distance, stopInRange: true, destinationName: Name), new ActionAlwaysSucceed() ); } /// <summary> /// This gets called when a while loop starts over so reset anything that is used inside the IsDone check /// </summary> public override void ResetCachedDone() { _done = false; } private Composite _cache; protected override void OnStart() { //We need to cache the behaviors creation because we use the GUID to remove it later. _cache = Behavior(); TreeHooks.Instance.InsertHook("TreeStart", 0, _cache); } protected override void OnDone() { TreeHooks.Instance.RemoveHook("TreeStart", _cache); } } }
Thanks a lot Mastahg, that one -did- work like a charm. I'll keep the changes in mind if I run into a similar problem in the future. I don't know where to report this, but something I've noticed about the TalkTo tag is that if the TalkTo action closes out that step for the quest, the TalkTo tag works fine, even if there's more steps afterward. If you need to talk to multiple NPCs for a step however, the bot will reach the first one and talk to it, but after interacting it just sits there not doing anything, with Poi: Type: None | Talking to NPC NAME. Here's a log snippet, this happens any time I've tried to use multiple TalkTo tags in one quest step: Code: [00:58:46.516 D] Interacting with U'napa 0x135F8200 [00:58:47.801 D] Removed hook [RoutineCombat] 75131bf2-b42a-4a68-9952-c34d15bdb3d2 [00:58:47.803 V] [Poi.Clear] Reason: Current behavior changed to TalkToTag: IsDone: False, NpcId: 1008284, InteractDistance: 3, XYZ: <-306.447, 6.321288, 392.5078>, NPC: Cool-eyed Huntress 0x13642000, InCombat: False, QuestId: 66755, StepId: 6, PostCombatDelay: 0, QuestName: Ranger Rescue, IsDoneCache: False, Behavior: TreeSharp.PrioritySelector, . [00:58:47.803 D] Replaced hook [ProfileOrderBehavior_Hook] 2a96f229-d1bb-498d-af41-ed4a50760ecd [00:58:47.804 D] Requesting path on 146 from <-259.8388, 7.058125, 414.3142> to <-306.447, 6.321288, 392.5078> [00:58:48.061 D] Generated path to <-306.447, 6.321288, 392.5078> in 00:00:00.2568882 ms [00:58:56.102 D] Moving to next hop: <-300.0776, 5.02711, 390.855> (TalkToTag: Cool-eyed Huntress) D: 2.978645 [00:58:56.445 D] Moving to next hop: <-306.447, 6.389531, 391.8263> (TalkToTag: Cool-eyed Huntress) D: 5.825446 [00:58:56.991 D] Interacting with Cool-eyed Huntress 0x13642000
A small update to the previous edited post, I also tried using UseObject instead of TalkTo just in case that was how it was intended to be, but UseObject doesn't advance through the textboxes of the NPCs, so I assume TalkTo should be used, it just doesn't move on to the next NPC properly if they are on the same quest step.
What quest? If its a multiple objective quest within the same step then support for that is coming next patch.