If there is anyone familiar with programming thouse kind of combat routines it would be great if someone could create one that manages to use Spectral Throw correctly and Double Strike / Heavy Strike on single target as a marauder, as of now (with me editing some lines for the spectral throw) yesterday I had like 4 successfull runs and 85 failed runs .. Which is, well .. not what my goal is unfortunately ... However I dont know exactly what went wrong, but if anyone wants to take a look at the logs I can post them on per request! Thanks in Advance.
devirated from apocs exile, this should use flasks and use dualstrike on < 3 and specthrow on >= 3 mobs. copy+paste code to yourbuddy\routines\randomstraw\isawesome.cs Code: using Loki.Bot; using Loki.Bot.Logic.Behaviors; using Loki.Game; using Loki.Game.GameData; using Loki.Game.Inventory; using Loki.Game.Objects; using Loki.TreeSharp; using Loki.Utilities; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Action = Loki.TreeSharp.Action; namespace SpecThrow_FireTrap { public partial class BETArnd : CombatRoutine { #region Flask Logic private readonly WaitTimer _flaskCd = new WaitTimer(TimeSpan.FromSeconds(0.5)); private IEnumerable<InventoryItem> LifeFlasks { get { IEnumerable<InventoryItem> inv = EntityManager.Me.Inventory.Flasks.Items; return from item in inv let flask = item.Flask where flask != null && flask.HealthRecover > 0 && flask.CanUse orderby flask.IsInstantRecovery ? flask.HealthRecover : flask.HealthRecoveredPerSecond descending select item; } } private IEnumerable<InventoryItem> ManaFlasks { get { IEnumerable<InventoryItem> inv = EntityManager.Me.Inventory.Flasks.Items; return from item in inv let flask = item.Flask where flask != null && flask.ManaRecover > 0 && flask.CanUse orderby flask.IsInstantRecovery ? flask.ManaRecover : flask.ManaRecoveredPerSecond descending select item; } } private IEnumerable<InventoryItem> GraniteFlasks { get { IEnumerable<InventoryItem> inv = EntityManager.Me.Inventory.Flasks.Items; return from item in inv let flask = item.Flask where flask != null && item.Name == "Granite Flask" && flask.CanUse select item; } } private IEnumerable<InventoryItem> QuicksilverFlasks { get { //InternalName: flask_utility_sprint, BuffType: 24, CasterId: 13848, OwnerId: 0, TimeLeft: 00:00:05.0710000, Charges: 1, Description: You have greatly increased Movement Speed IEnumerable<InventoryItem> inv = EntityManager.Me.Inventory.Flasks.Items; return from item in inv let flask = item.Flask where flask != null && item.Name == "Quicksilver Flask" && flask.CanUse select item; } } private Composite CreateFlaskLogic() { return new PrioritySelector( new Decorator(ret => _flaskCd.IsFinished && EntityManager.Me.HealthPercent < 70 && LifeFlasks.Count() != 0 && !EntityManager.Me.HasAura("flask_effect_life"), new Action(ret => { LifeFlasks.First().Use(); _flaskCd.Reset(); })), new Decorator(ret => _flaskCd.IsFinished && EntityManager.Me.ManaPercent < 50 && ManaFlasks.Count() != 0 && !EntityManager.Me.HasAura("flask_effect_mana"), new Action(ret => { ManaFlasks.First().Use(); _flaskCd.Reset(); })) ); } #endregion #region LOS/Movement private readonly Dictionary<string, DateTime> _totemTimers = new Dictionary<string, DateTime>(); internal Composite CreateMoveIntoRange(float range) { //// Using some new stuff from the bot! //return new ActionRunCoroutine(() => GetInRangeCoroutine(range)); return new Decorator(ret => BestTarget.Distance > range, CommonBehaviors.MoveTo(ret => BestTarget.Position, ret => "CreateMoveIntoRange")); } internal Composite CreateMoveToLoS(Monster m) { return new Decorator(ret => !BestTarget.IsInRangedLineOfSight && !BestTarget.IsInLineOfSight, CommonBehaviors.MoveTo(ret => BestTarget.Position, ret => "CreateMoveToLoS")); } #endregion private bool NumberOfMobsNear(PoEObject monster, float distance, int count, bool dead = false) { if (monster == null) { return false; } Vector2i mpos = monster.Position; int curCount = 0; foreach (Monster mob in Targeting.Combat.Targets.OfType<Monster>()) { if (mob.ID == monster.ID) { continue; } // If we're only checking for dead mobs... then... yeah... if (dead) { if (!mob.IsDead) continue; } else if (mob.IsDead) continue; if (mob.Position.Distance(mpos) < distance) { curCount++; } if (curCount >= count) { return true; } } return false; } public Monster BestTarget { get { return Targeting.Combat.Targets.FirstOrDefault() as Monster; // The stuff below was pseudocode that was not meant to be committed. // It's some stuff to help avoid target switching. //if (_bestTargetCached == null) //{ // _bestTargetCached = new CachePerTick<Monster>(() => // { // // So, we want to check a few small things. // // First, if we have no ID set, set it to the first thing on the combat list // if (_bestTargetIdCached == 0) // { // _bestTargetIdCached = Targeting.Combat.Targets.First().ID; // } // // Now, we know we have an ID set, so we can just grab the object. // var obj = EntityManager.GetObjectById<Monster>(_bestTargetIdCached); // if (obj == null || !obj.IsActive) // { // // This happens with "stale" or "dead" objects. So just reset ourselves. // _bestTargetIdCached = 0; // } // // Normally, I'd go with a "goto" type thing here, but in this case, it makes sense to just // // copy/paste some stuff, and return that. // if (_bestTargetIdCached == 0) // { // _bestTargetIdCached = Targeting.Combat.Targets.First().ID; // obj = EntityManager.GetObjectById<Monster>(_bestTargetIdCached); // } // // We have an object, go ahead and return it. // return obj; // }); //} //return _bestTargetCached; } } #region Overrides of CombatRoutine private bool _eventsHooked; /// <summary> Gets the name. </summary> /// <value> The name. </value> public override string Name { get { return "randomstraw"; } } public override Composite Buff { get { return new PrioritySelector( CreateFlaskLogic() ); } } public override Composite Combat { get { return new PrioritySelector( //CreateMoveIntoRange(80), //CreateMoveToLoS(BestTarget), SpellManager.CreateSpellCastComposite("Double Strike", ret => !NumberOfMobsNear(BestTarget, 15, 3), on => BestTarget), SpellManager.CreateSpellCastComposite("Spectral Throw", ret => NumberOfMobsNear(BestTarget, 15, 3), on => BestTarget) ); } } /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> /// <filterpriority>2</filterpriority> public override void Dispose() { } public void SwapWeapons() { Input.PressKey(ConfigManager.GetActionKey(ActionKey.WeaponSwap).Item1); } /// <summary> Initializes this <see cref="CombatRoutine" />. </summary> public override void Initialize() { if (!_eventsHooked) { // When we start the bot, we need to re-register all the available spells. This allows us to swap out skills // Without restarting the bot. _eventsHooked = true; } } #endregion } }
i didnt test it. what error is it throwing on startup? this routine is intended to work with the latest beta, .652
I was so excited to see someone had made this and to try it out, turns out it doesn't show up to select it. It would speed up kills, runs, and increase survivability. I'm trying to figure out what is wrong so I could somehow fix it, use leap instead of running, use double strike on elites only and use spectral throw on more then 2-3 mobs.
Basically what I do is editing the Spectral Throw line code, which is line 910 on the latest beta version: Register("Spectral Throw", ret => NumberOfMobsNear(BestTarget, 30, 1)); I guess the default is 10,2 just change it to 30,1
I just tried it, without much success. I have a basic understand of how programming works, I'm going to try my best to look at the newer updated API documentation. My guess is it's no longer working due to an update or change in the API, since there was a massive rework of the entire bot.
i can strip the exile.cs down as much as you want. just pm me your needs, conditions for skill usage "spectral throw on more than 2 mobs around" "heavy strike on less then 2 OR if enemy is magic or higher" are valid conditions
For those of you who want to do a Spectral Throw and Double strike build that works, Here it is. Find Exile.cs and find the following lines Replaced With Replace With Credits to RandomStraw & Tozededao