To help myself make it i'm going to make a "dev" plugin that captures every move of every monsterr i think it's better than going through the codedom
I will add this to the main post, but if you wanna help me capture a few boss move, use this AssistantBot : Code: using System.Collections.Generic; using log4net; using Loki.Bot; using Loki.Bot.Settings; using Loki.Game; using Loki.Game.GameData; using Loki.Game.Objects; using Loki.Utilities; using System; using System.Windows; using System.Windows.Markup; using System.IO; using System; using System.Windows.Data; using System.Threading.Tasks; using System.Linq; using System.Windows.Controls; //!CompilerOption|AddRef|C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Speech.dll namespace AlertBot { /// <summary> </summary> public class AlertBot : IBot { private static readonly ILog Log = Logger.GetLoggerInstanceForType(); struct Skill { public readonly Loki.Game.NativeWrappers.ActionWrapper action; public readonly int createdts; public int timeout; public readonly bool active; public Skill(Loki.Game.NativeWrappers.ActionWrapper action) { this.action = action; this.createdts = (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; this.timeout = 3; this.active = true; } public override bool Equals(Object obj) { // Check for null values and compare run-time types. if (obj == null || GetType() != obj.GetType()) return false; Skill s = (Skill)obj; return (s.action.Skill.Name == action.Skill.Name) && (s.action.Destination.Equals(action.Destination)) && (s.createdts - createdts <= 3); } public override int GetHashCode() { return (action.GetHashCode() + action.Destination.GetHashCode() + createdts) % 100000000; } } private readonly List<Skill> _trackedSkills = new List<Skill>(); #region Implementation of IAuthored /// <summary> The name of this bot. </summary> public string Name { get { return "AssistantBot"; } } /// <summary> The description of this bot. </summary> public string Description { get { return "This bot will assist you during manual play."; } } /// <summary>The author of this bot.</summary> public string Author { get { return "JYam"; } } /// <summary>The version of this bot's implementation.</summary> public Version Version { get { return new Version(0, 0, 1, 1); } } #endregion #region Implementation of IBase /// <summary>Initializes this object. This is called when the object is loaded into the bot.</summary> public void Initialize() { } #endregion #region Implementation of IRunnable /// <summary> The bot start callback. Do any initialization here. </summary> public void Start() { Log.DebugFormat("[AssistantBot] Start"); // Reset the default MsBetweenTicks on start. Log.DebugFormat("[Start] MsBetweenTicks: {0}.", MainSettings.Instance.MsBetweenTicks); Log.DebugFormat("[Start] InputEventMsDelay: {0}.", MainSettings.Instance.InputEventMsDelay); GameEventManager.Start(); GameEventManager.AreaChanged += GameEventManagerOnAreaChanged; } /// <summary> The bot tick callback. Do any update logic here. </summary> public void Tick() { // We don't want to do anything when we're not in game! if (!LokiPoe.IsInGame) return; GameEventManager.Tick(); foreach (Monster obj in LokiPoe.ObjectManager.GetObjectsByType<Monster>()) { if (obj.IsHostile && obj.Rarity == Rarity.Unique && obj.HasCurrentAction && obj.CurrentAction.Skill != null && obj.CurrentAction.Skill.Name.Length >= 5) { Loki.Game.NativeWrappers.ActionWrapper action = ((Monster)obj).CurrentAction; if (!_trackedSkills.Contains(new Skill(action))) { _trackedSkills.Add(new Skill(action)); Log.DebugFormat("Action performed by {0} [X : {1}, Y : {2}]", obj.Name, obj.Position.X, obj.Position.Y); if (action.Destination != null) Log.DebugFormat("Destination X : {0}, Y : {1}", action.Destination.X, action.Destination.Y); if (action.Target != null) Log.DebugFormat("Target X : {0}, Y : {1}", action.Target.Position.X, action.Target.Position.Y); if (action.Skill != null) Log.DebugFormat("{0} [ID : {2} - Addr : {3}] ~ {1}", action.Skill.Name, action.Skill.Description, action.Skill.Id, action.Skill.BaseAddress); } } List<Skill> toDelete = new List<Skill>(); foreach (Skill s in _trackedSkills) { if (s.createdts + s.timeout <= (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds) { toDelete.Add(s); } } foreach (Skill s in toDelete) { _trackedSkills.Remove(s); } } } /// <summary> The bot stop callback. Do any pre-dispose cleanup here. </summary> public void Stop() { Log.DebugFormat("[AssistantBot] OnStop"); GameEventManager.Stop(); GameEventManager.AreaChanged -= GameEventManagerOnAreaChanged; } #endregion #region Implementation of IConfigurable public JsonSettings Settings { get { return null; } } /// <summary> The bot's settings control. This will be added to the Exilebuddy Settings tab.</summary> public UserControl Control { get { return null; } } #endregion #region Implementation of IDisposable /// <summary> </summary> public void Dispose() { } #endregion #region Override of Object /// <summary> /// /// </summary> /// <returns></returns> public override string ToString() { return Name + ": " + Description; } #endregion #region Coroutine Logic #endregion private void GameEventManagerOnAreaChanged(object sender, AreaChangedEventArgs areaChangedEventArgs) { _trackedSkills.Clear(); } } } Put this in Bot/AssistantBot/AssistantBot.cs, use it instead of grindbasicbot and just start the bot and play, whenever a boss uses a special move, it gets added to the console window.
Also pushedx, is there a way to know if a skill is the same "cast" instance as another for now i'm using Code: return (s.action.Skill.Name == action.Skill.Name) && (s.action.Destination.Equals(action.Destination)) && (s.createdts - createdts <= 3); To distinguish between cast but i still get stuff like ethereal knives registered 4x because apparently the Destination changes during windup?
Vaal bro, full fight logs : www.privatepaste.com :: Paste ID b6b5caa98c 3 boss fight logs : www.privatepaste.com :: Paste ID e299cc9365
Atziri's going to do harder because her skills are always multi state or something, need to detect transition.
Hello friends, First, thank you gyam for this and helping improve EB even more. So, could someone help me on how to exactly add this dodge code inside my ExampleRoutine.cs, please? I'm following the guide but I'm a bit lost. I found the flameblast logic in the code and just before that I'm pasting the whole code part jyam gave us there. I'm just wondering about the really final part where it says: Code: if (!await Coroutines.MoveToLocation(dodgepos, 1, 1000)) { Log.InfoFormat("[Warning] Failed Dodge"); } } } } else { } } Is that should end like that with a empty "else"? And how about that last code piece that he said to place it "outside the function in CR." Where exactly it goes in my ExampleRoutine.cs? Could someone paste the last line of the original file so I can search for it and paste the rest of the code? Or if you guys don't mind share full ExampleRoutine.cs already with the dodge added so I can copy/paste everything and avoid problems. Again, thanks in advance.
yeah im also kinda confused on where to paste the code exactly since im getting tons of errorĀ“s when pasting the code before this: // If we have flameblast, we need to use special logic for it. if (_flameblastSlot != -1) isnt this the flameblast logic??? edit: thank you very much author for providing the modified example routine (now only gift us with your custom filter to skip mobs until dominus... )
Thank you for the CR, gonna test it. How are you changing the attack range on the fly? I am trying now also to get the AuraName for the Bloodlines Mod: Phylacteral Link and Bearers of the Guardian. For Phylacteral Link, we need to focus into the guy that has the "bigger ring" (and move to melee range to it, bcse the others with "smaller ring" might block the way and/or stay in the way of projectiles you cast) . . . For Bearers of the Guardian, we need to ignore the unique guy, focus on the blue mobs that has "Bearers of the Guardian", once all gone and the unique guy is not invul (maybe there is a far away blue mob with "Bearers of the Guardian"), kill the unique . . . For Necrovigil, the implementation we have now, is ok (ignore them), but sometimes they block the way/stay in the way of spells . . . The best would be to be able to identify if they are on top of the "green ring" that makes them invul, if not, kill them . . . Here is the code for a mob with 1 life standing on top of the green ring, invul (CannotDie = 1) You need to register and have one post to see spoilers! Monster Affixes - Path of Exile Wiki
check area + tileset, if it's not matching dominus area, make your Combat range to 1. How to check if you're in dominus area : Code: if (LokiPoe.ObjectManager.GetObjectByMetadata("Metadata/Monsters/Demonmodular/TowerSpawners/TowerFightStarter") != null) { //We are in dominus ring area ExampleRoutineSettings.Instance.CombatRange = 50; } else { ExampleRoutineSettings.Instance.CombatRange = 1; } idk if it works as i don't know if combatrange is writtable or not, my way of doing it is kinda different but can't share it atm. but this should work the exact same (albeit this one still is gonna try corrupted area and open chestbox, you need to disable them) if it's writtable.
Hey WhereIsMyMind, I believe those are disposable objects, the ones like attack projectiles. They are objects but are destroyed after X time or condition. I think.
jyam, is this still being developed/updated? Would it be possible to add to this bot, that once a hand of god is detected that within the evade movement we hit/use a lightning res flask, if available?
He's waiting for the id0 objects to be implemented (projectiles & stuff) when it's gonna happen, I'll add communication into flaskhelper to detect such avoidance/possibilities
can you tell me how to use it? i replace file in it C:\Users\***\Desktop\Budy\Routines\ExampleRoutine\ExampleRoutine.cs take in BasicGrindBot -> The Upper Sceptre of God and start he come to dominus move 2-3 steps, then use TP and go back to town after he go to the new copy of Sceptre of God and same tp in dominus