Example #1
0
        public int CalcRemoteMineCount(Hero target, bool isCurrentLife = true)
        {
            var life = isCurrentLife ? target.Health : target.MaximumHealth;
            var damageAfterFirstBomb = _updater._main.RemoteMine.GetDamage(target);

            if (damageAfterFirstBomb <= 0)
            {
                return(0);
            }
            if (target.HeroId == HeroId.npc_dota_hero_medusa)
            {
                var shield = target.GetAbilityById(AbilityId.medusa_mana_shield);
                if (shield.IsToggled)
                {
                    var treshold =
                        shield.GetAbilitySpecialData("damage_per_mana");
                    DamageCalcHelpers.CalcDamageForDusa(ref damageAfterFirstBomb, target, treshold);
                }
            }


            var count = (int)Math.Ceiling(life / damageAfterFirstBomb);

            return(count);
        }
Example #2
0
        public float CalcHealthAfterSuicide(Hero target, bool isCurrentLife = true)
        {
            var life = isCurrentLife ? target.Health : target.MaximumHealth;
            var damageAfterFirstBomb = _updater._main.Suicide.GetDamage(target);

            if (damageAfterFirstBomb <= 0)
            {
                return(0);
            }
            if (target.HeroId == HeroId.npc_dota_hero_medusa)
            {
                var shield = target.GetAbilityById(AbilityId.medusa_mana_shield);
                if (shield.IsToggled)
                {
                    var treshold =
                        shield.GetAbilitySpecialData("damage_per_mana");
                    DamageCalcHelpers.CalcDamageForDusa(ref damageAfterFirstBomb, target, treshold);
                }
            }
            else if (target.HeroId == HeroId.npc_dota_hero_visage)
            {
                var graveKeeper      = target.GetModifierByName("modifier_visage_gravekeepers_cloak");
                var graveKeeperCount = graveKeeper?.StackCount;
                if (!(graveKeeperCount > 0))
                {
                    return(life - damageAfterFirstBomb);
                }
                var percentBlock =
                    (float)(target.GetAbilityById(AbilityId.visage_gravekeepers_cloak)
                            .GetAbilitySpecialData("damage_reduction") *
                            graveKeeperCount);
                damageAfterFirstBomb -= damageAfterFirstBomb * (percentBlock / 100);
            }

            return(life - damageAfterFirstBomb);
        }
Example #3
0
        // private readonly MultiSleeper<string> _multiSleeper;

        public BombDamageManager(Updater updater)
        {
            _updater = updater;
            var me = updater._main.Me;

            DamageUpdater = UpdateManager.CreateUpdate(100, () =>
            {
                // O9K.Core.Managers.Entity.EntityManager9.EnemyHeroes
                foreach (var enemy in EntityManager.GetEntities <Hero>().Where(x =>
                                                                               x.IsValid && x.IsVisible && x.IsAlive && x.IsEnemy(me) && !x.IsIllusion))
                {
                    // var t = new O9K.Core.Entities.Heroes.Hero9(enemy);
                    var id                 = enemy.HeroId;
                    var landMineCount      = CalcLandMineCount(enemy);
                    var landMineCountMax   = CalcLandMineCount(enemy, false);
                    var removeMineCount    = CalcRemoteMineCount(enemy);
                    var removeMineCountMax = CalcRemoteMineCount(enemy, false);
                    var healthAfterSuicide = CalcHealthAfterSuicide(enemy);

                    if (DamageDictionary.TryGetValue(id, out var info))
                    {
                        info.UpdateInfo(landMineCount, landMineCountMax, removeMineCountMax, removeMineCount,
                                        healthAfterSuicide);
                    }
                    else
                    {
                        DamageDictionary.Add(id,
                                             new DamageInfo(landMineCount, landMineCountMax, removeMineCountMax, removeMineCount,
                                                            healthAfterSuicide));
                    }
                }
            });
            // var inActionSleeper = new MultiSleeper<uint>();
            UpdateManager.BeginInvoke(async() =>
            {
                while (true)
                {
                    var passedDelay = false;
                    starting:
                    var isForce = _updater.ForceStaff != null && _updater.ForceStaff.CanBeCasted();
                    var enemies = O9K.Core.Managers.Entity.EntityManager9.EnemyHeroes.OfType <Hero9>().Where(x =>
                                                                                                             x.IsValid && x.IsAlive && x.IsVisible && !x.IsIllusion && !x.IsMagicImmune && x.CanDie);
                    // var enemies = EntityManager.GetEntities<Hero>().Where(x =>
                    //     x.IsValid && x.IsVisible && x.IsAlive && x.IsEnemy(me) && !x.IsIllusion &&
                    //     !x.IsMagicImmune()/* &&
                    //     _updater._main.MenuManager.Targets.GetValue(x.HeroId)*/);
                    foreach (var enemy in enemies)
                    {
                        var handle = enemy.Handle;

                        if (MultiSleeper <uint> .Sleeping(handle))
                        {
                            continue;
                        }
                        if (enemy.HasModifier(new[]
                        {
                            "modifier_shredder_timber_chain", "modifier_storm_spirit_ball_lightning",
                            "modifier_item_aeon_disk_buff", "modifier_eul_cyclone",
                            "modifier_ember_spirit_sleight_of_fist_caster",
                            "modifier_ember_spirit_sleight_of_fist_caster_invulnerability",
                            "modifier_brewmaster_primal_split", "modifier_brewmaster_primal_split_delay",
                            "modifier_earth_spirit_rolling_boulder_caster", "modifier_morphling_waveform",
                            "modifier_phoenix_icarus_dive", "modifier_ursa_enrage"
                        }))
                        {
                            continue;
                        }
                        if (enemy.CanReincarnate && !_updater._main.MenuManager.DetonateOnAegis)
                        {
                            continue;
                        }

                        var itemBlink = enemy.Abilities.FirstOrDefault(x => x.Id == AbilityId.item_blink);
                        if (itemBlink != null)
                        {
                            if (itemBlink.Cooldown - itemBlink.RemainingCooldown <= 1 && itemBlink.Cooldown > 10)
                            {
                                continue;
                            }
                        }

                        var startManaCalc = 0f;
                        var threshold     = 0f;
                        var heroId        = enemy.Id;
                        var isDusa        = heroId == HeroId.npc_dota_hero_medusa;
                        var isAbba        = heroId == HeroId.npc_dota_hero_abaddon;
                        var health        = (float)enemy.Health;
                        if (isDusa)
                        {
                            startManaCalc = enemy.Mana;
                            var shield    = enemy.GetAbilityById(AbilityId.medusa_mana_shield);
                            if (shield.IsToggled)
                            {
                                threshold = shield.GetAbilitySpecialData("damage_per_mana");
                            }
                        }
                        else if (heroId == HeroId.npc_dota_hero_ember_spirit)
                        {
                            if (EmberShield == null)
                            {
                                EmberShield =
                                    enemy.GetAbilityById(AbilityId.ember_spirit_flame_guard);
                            }
                            if (enemy.HasModifier("modifier_ember_spirit_flame_guard"))
                            {
                                var extraLife = EmberShield.GetAbilitySpecialData("absorb_amount");
                                var talant    = enemy.GetAbilityById(AbilityId.special_bonus_unique_ember_spirit_1);
                                extraLife    += talant?.Level > 0
                                    ? talant.GetAbilitySpecialData("value")
                                    : 0;
                                health += extraLife;
                            }
                        }
                        else if (isAbba)
                        {
                        }


                        var raindrop = enemy.Abilities.FirstOrDefault(x => x.Id == AbilityId.item_infused_raindrop);
                        if (raindrop != null && raindrop.CanBeCasted())
                        {
                            var extraHealth = raindrop.BaseAbility.GetAbilitySpecialData("magic_damage_block");
                            health         += extraHealth;
                        }

                        var blockCount         = enemy.GetModifierStacks("modifier_templar_assassin_refraction_absorb");
                        var graveKeeper        = enemy.GetModifier("modifier_visage_gravekeepers_cloak");
                        var graveKeeperCount   = graveKeeper?.StackCount;
                        var aeon               = enemy.Abilities.FirstOrDefault(x => x.Id == AbilityId.item_aeon_disk);
                        var breakHealthForAeon = enemy.MaximumHealth * .7f;
                        var input              = new PredictionInput
                        {
                            Owner                   = me,
                            AreaOfEffect            = false,
                            CollisionTypes          = CollisionTypes.None,
                            Delay                   = 0.25f,
                            Speed                   = float.MaxValue,
                            Range                   = float.MaxValue,
                            Radius                  = 420,
                            PredictionSkillshotType = PredictionSkillshotType.SkillshotCircle
                        };
                        input          = input.WithTarget(enemy.BaseHero);
                        var prediction = PredictionManager.GetPrediction(input);
                        // ParticleManager.CircleParticle("123", prediction.CastPosition, 150, Color.Red);
                        var predictedPosition = prediction.CastPosition;
                        var pos     = /*_updater._main.MenuManager.UsePrediction ? predictedPosition :*/ enemy.Position;
                        var detList = new List <RemoteMine>();
                        var bombs   = updater
                                      .BombManager
                                      .RemoteMines
                                      .Where(x =>
                                             x.IsActive &&
                                             _updater._main.MenuManager.UsePrediction
                                    ? x.Position.IsInRange(pos, 420) && x.Position.IsInRange(predictedPosition, 420)
                                    : x.Position.IsInRange(pos, 420))
                                      .ToList();
                        var underStasisTrap = enemy.HasModifier("modifier_techies_stasis_trap_stunned");
                        foreach (var remoteMine in bombs.Where(x =>
                                                               x.StackerMain == null && x.Stacker.DetonateDict.TryGetValue(heroId, out var isEnable) &&
                                                               isEnable ||
                                                               x.StackerMain != null &&
                                                               x.StackerMain.Stacker.DetonateDict.TryGetValue(heroId, out var isEnable2) && isEnable2))
                        {
                            var damage = _updater._main.RemoteMine.GetDamage(remoteMine.Damage, enemy);
                            if (isDusa)
                            {
                                DamageCalcHelpers.CalcDamageForDusa(ref damage, ref startManaCalc, threshold);
                            }
                            detList.Add(remoteMine);
                            if (blockCount > 0)
                            {
                                blockCount--;
                            }
                            else if (graveKeeperCount > 0)
                            {
                                var percentBlock =
                                    (float)(enemy.GetAbilityById(AbilityId.visage_gravekeepers_cloak)
                                            .GetAbilitySpecialData("damage_reduction") *
                                            graveKeeperCount);
                                // TechiesCrappahilationPaid.Log.Warn(
                                //     $"Block:  {damage * (percentBlock / 100)}({percentBlock} %). Left blocks: {graveKeeperCount} " +
                                //     $"Damage changed: {damage} -> {damage - damage * (percentBlock / 100)}");
                                health -= damage - damage * (percentBlock / 100);
                                graveKeeperCount--;
                            }
                            else
                            {
                                health -= damage;
                            }

                            var extraDetonateTime = 0.25f * detList.Count;
                            var aeonByPass        = aeon != null && aeon.CanBeCasted() && health < breakHealthForAeon;


                            if (health + enemy.HealthRegeneration * extraDetonateTime < 0 || aeonByPass)
                            {
                                if (_updater._main.MenuManager.CameraMove)
                                {
                                    var heroPos         = enemy.Position;
                                    var consolePosition = $"{heroPos.X} {heroPos.Y}";
                                    GameManager.ExecuteCommand($"dota_camera_set_lookatpos {consolePosition}");
                                }

                                if (_updater._main.MenuManager.DelayOnDetonate.Value > 0 && !passedDelay &&
                                    !underStasisTrap)
                                {
                                    if (!MultiSleeper <string> .Sleeping("heroAfterForce" + heroId))
                                    {
                                        // TechiesCrappahilationPaid.Log.Warn(
                                        //     "delay on detonation start for " +
                                        //     _updater._main.MenuManager.DelayOnDetonate.Value.Value);
                                        await Task.Delay(_updater._main.MenuManager.DelayOnDetonate.Value);
                                        // TechiesCrappahilationPaid.Log.Warn("delay end");
                                        passedDelay = true;
                                        goto starting;
                                    }
                                }

                                await Task.Delay((int)(25 + GameManager.Ping));
                                if (_updater._main.MenuManager.DetonateAllInOnce && !aeonByPass)
                                {
                                    if (_updater._main.MenuManager.UseFocusedDetonation)
                                    {
                                        var minesToDetonate = bombs.FirstOrDefault();
                                        if (minesToDetonate != null)
                                        {
                                            _updater._main.FocusedDetonate.Cast(minesToDetonate.Position);
                                        }
                                    }
                                    else
                                    {
                                        foreach (var mine in bombs)
                                        {
                                            mine.Owner.Select(true);
                                        }

                                        await Task.Delay((int)(25 + GameManager.Ping));
                                        // OrderManager.CreateOrder(OrderType.Cast, bombs.Select(x => x.Owner), 0,
                                        //     bombs.FirstOrDefault().Owner.Spellbook.Spell1.AbilityIndex, Vector3.Zero,
                                        //     false, false, false);
                                        foreach (var mine in bombs)
                                        {
                                            mine.Owner.Spellbook.Spell1.Cast();
                                            mine.IsActive = false;
                                        }
                                    }
                                }
                                else
                                {
                                    foreach (var mine in detList)
                                    {
                                        mine.Owner.Select(true);
                                    }

                                    await Task.Delay((int)(25 + GameManager.Ping));
                                    // OrderManager.CreateOrder(OrderType.Cast, detList.Select(x => x.Owner).FirstOrDefault(), 0,
                                    //     detList.FirstOrDefault().Owner.Spellbook.Spell1.AbilityIndex, Vector3.Zero,
                                    //     false, false, false);
                                    foreach (var mine in detList)
                                    {
                                        mine.Owner.Spellbook.Spell1.Cast();
                                        mine.IsActive = false;
                                    }
                                }

                                MultiSleeper <uint> .Sleep(handle, extraDetonateTime + GameManager.Ping + 1500);


                                ////TODO: delay on detonation
                                goto EndOfActions;
                            }
                        }

                        if (isDusa)
                        {
                            startManaCalc = enemy.Mana;
                        }

                        if (isForce && _updater.ForceStaff.CanHit(enemy) && !enemy.IsRotating)
                        {
                            var isLinken = enemy.IsLinkensProtected;
                            if (isLinken && (_updater.Eul == null || !_updater.Eul.CanBeCasted()))
                            {
                                continue;
                            }

                            health            = enemy.Health;
                            var afterForcePos = enemy.BaseEntity.InFrontSuper(600);
                            foreach (var remoteMine in updater
                                     .BombManager.RemoteMines
                                     .Where(x => x.IsActive &&
                                            x.Position.IsInRange(
                                                afterForcePos,
                                                420) &&
                                            (
                                                x.StackerMain == null &&
                                                x.Stacker.DetonateDict.TryGetValue(heroId, out var isEnable) &&
                                                isEnable ||
                                                x.StackerMain != null &&
                                                x.StackerMain.Stacker.DetonateDict.TryGetValue(heroId,
                                                                                               out var isEnable2) && isEnable2
                                            )))
                            {
                                var damage = _updater._main.RemoteMine.GetDamage(remoteMine.Damage, enemy);
                                if (isDusa)
                                {
                                    DamageCalcHelpers.CalcDamageForDusa(ref damage, ref startManaCalc, threshold);
                                }
                                detList.Add(remoteMine);
                                health -= damage;
                                if (health + enemy.HealthRegeneration * 0.25f * detList.Count < 0)
                                {
                                    if (MultiSleeper <string> .Sleeping("force" + heroId))
                                    {
                                        continue;
                                    }
                                    if (isLinken)
                                    {
                                        _updater.Eul.UseAbility(enemy);
                                    }
                                    _updater.ForceStaff.UseAbility(enemy);

                                    if (enemy.CanBecomeMagicImmune && _updater.Hex != null &&
                                        _updater.Hex.CanHit(enemy) &&
                                        _updater.Hex.CanBeCasted())
                                    {
                                        _updater.Hex.UseAbility(enemy);
                                    }

                                    MultiSleeper <string> .Sleep("heroAfterForce" + heroId, 500);
                                    MultiSleeper <string> .Sleep("force" + heroId, 500);
                                }
                            }
                        }

                        EndOfActions:;
                    }

                    await Task.Delay(1);
                }
            });
        }