public Tree GetChaseTree( Vector3 hero, Target target, TimberChain timberChain, float maxDistanceToEnemy, float minDistanceToHero) { var castRange = timberChain.GetCastRange(); var targetPosition = target.GetPosition(); var targetDistance = target.GetDistance(hero); var ignoreMaxDistance = targetDistance > castRange + 200; var trees = GetAvailableTrees(hero, targetPosition, castRange).ToList(); return (trees.Where( x => (ignoreMaxDistance || x.Distance2D( TimberPrediction.PredictedXYZ( target, timberChain.CastPoint + x.Distance2D(targetPosition) / timberChain.Speed)) <= maxDistanceToEnemy || (Math.Abs( target.Hero.FindAngleR() - Utils.DegreeToRadian(target.Hero.FindAngleForTurnTime(x.Position))) < 0.3 && x.Distance2D(targetPosition) < targetDistance)) && x.Distance2D(hero) >= minDistanceToHero) .FirstOrDefault( z => trees.Where(x => !x.Equals(z)) .All(x => !IsPointOnLine(x.Position, hero, z.Position, forceRadius: 25)))); }
public Tree GetChaseTree( Hero hero, Target target, TimberChain timberChain, float maxDistanceToEnemy, float minDistanceToHero) { var castRange = timberChain.GetCastRange(); var targetPosition = target.GetPosition(); var targetDistance = target.GetDistance(hero.Position); var ignoreMaxDistance = targetDistance > castRange + 200; var delay = Game.RawGameTime + timberChain.CastPoint + Game.Ping / 1000; var trees = GetAvailableTrees(hero, targetPosition, castRange, delay, timberChain.Speed).ToList(); return (trees.Where( x => (ignoreMaxDistance || x.Distance2D( TimberPrediction.PredictedXYZ( target, timberChain.CastPoint + x.Distance2D(targetPosition) / timberChain.Speed)) <= maxDistanceToEnemy || (target.Hero.GetTurnTime(x.Position) <= 0 && x.Distance2D(targetPosition) < 600)) && x.Distance2D(hero) >= minDistanceToHero) .FirstOrDefault( z => trees.Where(x => !x.Equals(z)) .All( x => x.Distance2D(hero) > 150 && !IsPointOnLine(x.Position, hero.Position, z.Position, 25)))); }
public bool CheckTree(Hero hero, Vector3 position, TimberChain timberChain) { var distance = Math.Max(timberChain.GetCastRange(), hero.Distance2D(position)); var endPoint = hero.Position.Extend(position, distance); var delay = Game.RawGameTime + timberChain.CastPoint + Game.Ping / 1000; return(GetAvailableTrees(hero, endPoint, distance, delay, timberChain.Speed) .Any(x => IsPointOnLine(x.Position, hero.Position, endPoint, 20))); }
public bool CheckTree(Hero hero, Vector3 position, TimberChain timberChain) { var distance = Math.Max(timberChain.GetCastRange(), hero.Distance2D(position)); var endPoint = hero.Position.Extend(position, distance); var delay = Game.RawGameTime + timberChain.CastPoint + Game.Ping / 1000; return GetAvailableTrees(hero, endPoint, distance, delay, timberChain.Speed) .Any(x => IsPointOnLine(x.Position, hero.Position, endPoint, 20)); }
public void OnExecuteAbilitiy(Player sender, ExecuteOrderEventArgs args) { if (!menuManager.IsEnabled || !menuManager.IsSafeChainEnabled) { return; } var ability = args.Ability; if (ability == null || args.Order != Order.AbilityLocation || !ability.Equals(timberChain.Ability)) { return; } if (!treeFactory.CheckTree(hero.Position, args.TargetPosition, timberChain.GetCastRange())) { args.Process = false; } }
public Tree GetDamageTree(Hero hero, Vector3 target, TimberChain timberChain, bool dagger = false) { var delay = Game.RawGameTime + timberChain.CastPoint + Game.Ping / 1000; var trees = GetAvailableTrees(hero, target, timberChain.GetCastRange(), delay, timberChain.Speed).ToList(); return(trees.OrderBy(x => x.Distance2D(target)) .FirstOrDefault( x => trees.Where(z => !z.Equals(x)) .All( z => z.Distance2D(hero) > 150 && !IsPointOnLine(z.Position, hero.Position, x.Position, 25)) && (IsPointOnLine(target, hero.Position, x.Position, timberChain.Radius, false) || x.Distance2D(target) < timberChain.Radius - 50) && (dagger || x.Distance2D(target) < 600))); }
public void OnUpdate() { if (sleeper.Sleeping(this)) { return; } if (Game.IsPaused || !hero.IsAlive || hero.IsChanneling() || !menuManager.IsEnabled) { return; } var heroPosition = hero.Position; if (!aghsAdded && !sleeper.Sleeping(chakrams)) { if (hero.AghanimState()) { chakrams.Add( new Chakram( hero.Spellbook.Spells.First(x => x.Name == "shredder_chakram_2"), hero.Spellbook.Spells.First(x => x.Name == "shredder_return_chakram_2"))); aghsAdded = true; } sleeper.Sleep(5000, chakrams); } if (menuManager.MoveEnabled) { var blink = hero.FindItem("item_blink", true); var mousePosition = Game.MousePosition; if (blink != null && !sleeper.Sleeping(blink) && menuManager.IsItemEnabled(blink.StoredName()) && blink.CanBeCasted() && mousePosition.Distance2D(hero) > 500) { var castRange = blink.GetCastRange(); var blinkPosition = hero.Distance2D(mousePosition) > castRange ? (mousePosition - heroPosition) * castRange / mousePosition.Distance2D(hero) + heroPosition : mousePosition; blink.UseAbility(blinkPosition); sleeper.Sleep(1000, blink); } else if (timberChain.CanBeCasted()) { var moveTree = treeFactory.GetMoveTree(hero, mousePosition, timberChain.GetCastRange(), 800); if (moveTree != null) { timberChain.UseAbility(moveTree.Position); sleeper.Sleep( timberChain.GetSleepTime + moveTree.Distance2D(hero) / timberChain.Speed * 1000 * 2 + Game.Ping, this); return; } } if (!sleeper.Sleeping(hero)) { hero.Move(mousePosition); sleeper.Sleep(200, hero); } } else if (menuManager.ChaseEnabled) { if (!target.IsValid()) { return; } if (!target.Locked) { target.Locked = true; } if (!cameraCentered && menuManager.IsCenterCameraEnabled) { Game.ExecuteCommand("+dota_camera_center_on_hero"); cameraCentered = true; } var distanceToEnemy = target.GetDistance(heroPosition); var targetPosition = target.GetPosition(); var ping = Game.Ping; var phaseChakram = chakrams.FirstOrDefault(x => x.IsInPhase); if (phaseChakram != null) { var predictedPosition = TimberPrediction.PredictedXYZ( hero, target, distanceToEnemy / phaseChakram.Speed * 1000); if (phaseChakram.Position.Distance2D(predictedPosition) > phaseChakram.Radius) { phaseChakram.Stop(hero); treeFactory.ClearUnavailableTrees(true); sleeper.Sleep(ping + 100, this); return; } } if (timberChain.IsInPhase && timberChain.CastedOnEnemy) { var predictedPosition = TimberPrediction.PredictedXYZ( hero, target, distanceToEnemy / timberChain.Speed * 1000); if (timberChain.Position.Distance2D(predictedPosition) > timberChain.Radius) { timberChain.Stop(hero); timberChain.ChakramCombo = false; whirlingDeath.Combo = false; sleeper.Sleep(ping + 100, this); return; } } var doubleChakramDamage = chakrams.Count(x => x.Damaging(target)) == 2; var returnChakrams = chakrams.Where(x => x.ShouldReturn(hero, target, doubleChakramDamage)); foreach (var chakram in returnChakrams) { chakram.Return(); treeFactory.ClearUnavailableTrees(true); } var blink = hero.FindItem("item_blink", true); var shivasGuard = hero.FindItem("item_shivas_guard", true); var soulRing = hero.FindItem("item_soul_ring"); var usableChakram = chakrams.FirstOrDefault(x => x.CanBeCasted()); if (blink != null && !sleeper.Sleeping(blink) && menuManager.IsItemEnabled(blink.StoredName()) && blink.CanBeCasted() && distanceToEnemy > 500 && (target.FindAngle(heroPosition) > 0.6 || distanceToEnemy > 700) && (timberChain.Cooldown > 2 || distanceToEnemy > 800) && (whirlingDeath.CanBeCasted() || usableChakram != null) && hero.Modifiers.All(x => x.Name != timberChain.ModifierName) && !timberChain.IsSleeping) { var castRange = blink.GetCastRange(); var sleep = ping + 300; if (distanceToEnemy <= castRange) { var positionNearTree = treeFactory.GetBlinkPosition( target, heroPosition, castRange, whirlingDeath.Radius, whirlingDeath.CanBeCasted()); sleep += (float)hero.GetTurnTime(positionNearTree); blink.UseAbility(positionNearTree); } else { var maxDistancePosition = (targetPosition - heroPosition) * castRange / targetPosition.Distance2D(hero) + heroPosition; sleep += (float)hero.GetTurnTime(maxDistancePosition); blink.UseAbility(maxDistancePosition); } sleeper.Sleep(1000, blink); sleeper.Sleep(sleep, this); return; } if (soulRing != null && !sleeper.Sleeping(soulRing) && menuManager.IsItemEnabled(soulRing.StoredName()) && soulRing.CanBeCasted() && hero.Health > 600) { soulRing.UseAbility(); sleeper.Sleep(1000, soulRing); } if (shivasGuard != null && !sleeper.Sleeping(shivasGuard) && menuManager.IsItemEnabled(shivasGuard.StoredName()) && shivasGuard.CanBeCasted() && distanceToEnemy < 500) { shivasGuard.UseAbility(); sleeper.Sleep(1000, shivasGuard); } if (whirlingDeath.CanBeCasted() && (distanceToEnemy <= whirlingDeath.Radius || whirlingDeath.Combo && whirlingDeath.ComboDelayPassed)) { whirlingDeath.UseAbility(); whirlingDeath.Combo = false; timberChain.ChakramCombo = false; } if (timberChain.CanBeCasted() && (usableChakram == null || distanceToEnemy > 300)) { if ((blink == null || !blink.CanBeCasted() || !menuManager.IsItemEnabled(blink.Name)) && usableChakram != null && !chakrams.Any(x => x.IsSleeping || x.Casted) && distanceToEnemy < chakrams.First().GetCastRange() && treeFactory.TreesInPath(hero, targetPosition, 100) >= 5) { var predictedPosition = TimberPrediction.PredictedXYZ( hero, target, usableChakram.GetSleepTime + ping + target.GetDistance(heroPosition) / usableChakram.Speed * 1000 + usableChakram.Radius / 2 / target.Hero.MovementSpeed * 1000); usableChakram.UseAbility(predictedPosition, target.Hero, hero); treeFactory.SetUnavailableTrees(hero.Position, predictedPosition, usableChakram); sleeper.Sleep(usableChakram.GetSleepTime + ping, this); return; } var possibleDamageTree = treeFactory.GetDamageTree(hero, targetPosition, timberChain); if (target.IsVsisible && possibleDamageTree != null) { var predictedPosition = TimberPrediction.PredictedXYZ( hero, target, timberChain.CastPoint * 1000 + (distanceToEnemy + hero.Distance2D(possibleDamageTree.Position)) / timberChain.Speed * 1000 + ping); var damageTreeWithPrediction = treeFactory.GetDamageTree( hero, predictedPosition, timberChain, blink != null && !sleeper.Sleeping(blink) && menuManager.IsItemEnabled(blink.Name) && blink.CanBeCasted()); if (damageTreeWithPrediction != null) { timberChain.UseAbility(damageTreeWithPrediction.Position, true); timberChain.Position = predictedPosition; timberChain.ChakramCombo = distanceToEnemy > 600 && usableChakram != null; whirlingDeath.Combo = (distanceToEnemy < 400 || distanceToEnemy > 600) && whirlingDeath.CanBeCasted(); var sleep = timberChain.GetSleepTime + (float)hero.GetTurnTime(damageTreeWithPrediction.Position) * 1000; if (whirlingDeath.Combo) { whirlingDeath.SetComboDelay( sleep - ping + heroPosition.Distance2D(damageTreeWithPrediction) / timberChain.Speed * 1000 + distanceToEnemy / timberChain.Speed * 1000); } sleeper.Sleep(sleep + ping, this); return; } } else if (timberChain.Level >= 4 && hero.Mana > 500) { if (target.IsVsisible || distanceToEnemy > 400) { var chaseTree = treeFactory.GetChaseTree(hero, target, timberChain, 400, 600); if (chaseTree != null) { timberChain.UseAbility(chaseTree.Position); sleeper.Sleep( timberChain.GetSleepTime + (float)hero.GetTurnTime(chaseTree.Position) * 1000 + ping, this); return; } } } } if (usableChakram != null && (distanceToEnemy < 600 || target.FindAngle(heroPosition) <= 0.6 || timberChain.ChakramCombo) && (!whirlingDeath.Combo || !whirlingDeath.ComboDelayPassed) /*&& (TimberPrediction.StraightTime(target.Hero) > 500 || distanceToEnemy < 300)*/) { var predictedPosition = TimberPrediction.PredictedXYZ( hero, target, usableChakram.GetSleepTime + ping + target.GetDistance(heroPosition) / usableChakram.Speed * 1000 + usableChakram.Radius / 2 / target.Hero.MovementSpeed * 1000); usableChakram.UseAbility(predictedPosition, target.Hero, hero); timberChain.ChakramCombo = false; treeFactory.SetUnavailableTrees(hero.Position, predictedPosition, usableChakram); sleeper.Sleep( usableChakram.GetSleepTime + (float)hero.GetTurnTime(predictedPosition) * 1000 + ping, this); return; } if (!sleeper.Sleeping(orbwalker)) { orbwalker.OrbwalkOn(target.Hero, target.GetPosition()); } } else if (target.Locked) { if (cameraCentered) { Game.ExecuteCommand("-dota_camera_center_on_hero"); cameraCentered = false; } if (timberChain.IsInPhase) { timberChain.Stop(hero); } treeFactory.ClearUnavailableTrees(true); timberChain.ChakramCombo = false; whirlingDeath.Combo = false; var phaseChakrams = chakrams.Where(x => x.IsInPhase).ToList(); var castedChakrams = chakrams.Where(x => x.Casted).ToList(); if (phaseChakrams.Any()) { phaseChakrams.ForEach(x => x.Stop(hero)); } else if (castedChakrams.Any()) { castedChakrams.ForEach(x => x.Return()); } else { target.Locked = false; } sleeper.Sleep(500, this); } treeFactory.ClearUnavailableTrees(); }
public Tree GetChaseTree( Hero hero, Target target, TimberChain timberChain, float maxDistanceToEnemy, float minDistanceToHero) { var castRange = timberChain.GetCastRange(); var targetPosition = target.GetPosition(); var targetDistance = target.GetDistance(hero.Position); var ignoreMaxDistance = targetDistance > castRange + 200; var delay = Game.RawGameTime + timberChain.CastPoint + Game.Ping / 1000; var trees = GetAvailableTrees(hero, targetPosition, castRange, delay, timberChain.Speed).ToList(); return trees.Where( x => (ignoreMaxDistance || x.Distance2D( TimberPrediction.PredictedXYZ( target, timberChain.CastPoint + x.Distance2D(targetPosition) / timberChain.Speed)) <= maxDistanceToEnemy || (target.Hero.GetTurnTime(x.Position) <= 0 && x.Distance2D(targetPosition) < 600)) && x.Distance2D(hero) >= minDistanceToHero) .FirstOrDefault( z => trees.Where(x => !x.Equals(z)) .All( x => x.Distance2D(hero) > 150 && !IsPointOnLine(x.Position, hero.Position, z.Position, 25))); }
public Tree GetDamageTree(Hero hero, Vector3 target, TimberChain timberChain, bool dagger = false) { var delay = Game.RawGameTime + timberChain.CastPoint + Game.Ping / 1000; var trees = GetAvailableTrees(hero, target, timberChain.GetCastRange(), delay, timberChain.Speed).ToList(); return trees.OrderBy(x => x.Distance2D(target)) .FirstOrDefault( x => trees.Where(z => !z.Equals(x)) .All( z => z.Distance2D(hero) > 150 && !IsPointOnLine(z.Position, hero.Position, x.Position, 25)) && (IsPointOnLine(target, hero.Position, x.Position, timberChain.Radius, false) || x.Distance2D(target) < timberChain.Radius - 50) && (dagger || x.Distance2D(target) < 600)); }