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

Spectral Throw Double Strike Marauder - Anyone? :3

Zyrhon

New Member
Joined
Dec 6, 2011
Messages
11
Reaction score
0
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
    }
}
 
Hey! Thanks a bunch, however I cant pick it when trying to pick the combat routine? :c
 
Hey! Thanks a bunch, however I cant pick it when trying to pick the combat routine? :c

i didnt test it. what error is it throwing on startup?
this routine is intended to work with the latest beta, .652
 
Well, Doesnt show up when I want to select it. Can only select ApocsRanger, Exile & Braiinnnsss
 
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 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
Register("Spectral Throw", ret => NumberOfMobsNear(BestTarget, 10, 2));
Replaced With
Register("Spectral Throw", ret => NumberOfMobsNear(BestTarget, 30, 1));



Register("Double Strike";
Replace With
Register("Double Strike", ret => !NumberOfMobsNear(BestTarget, 13, 2) || BestTarget.Rarity >= Rarity.Rare);

Credits to RandomStraw & Tozededao
 
Back
Top