public static IEnumerable<Vector3> PointsAroundTheTarget(Vector3 pos, float dist, float prec = 15, float prec2 = 5) { if (!pos.IsValid()) { return new List<Vector3>(); } var list = new List<Vector3>(); if (dist > 500) { prec = 20; prec2 = 6; } if (dist > 805) { prec = 35; prec2 = 8; } var angle = 360 / prec * System.Math.PI / 180.0f; var step = dist / prec2; for (var i = 0; i < prec; i++) { for (var j = 0; j < prec2; j++) { list.Add( new Vector3( pos.X + (float)(System.Math.Cos(angle * i) * (j * step)), pos.Y + (float)(System.Math.Sin(angle * i) * (j * step)), pos.Z)); } } return list; }
public static float AngleBetween(Vector3 oldPosition, Vector3 newPosition) { if (oldPosition.IsValid() && newPosition.IsValid()) { return (oldPosition - ObjectManager.Player.Position).To2D() .AngleBetween((newPosition - ObjectManager.Player.Position).To2D()); } return 0f; }
public override bool Use(Vector3 position) { if (position.IsValid()) { throw new ArgumentNullException(nameof(position)); } Log.Debug($"UseAbility {this.Instance.Name} @ {position}"); this.Instance.UseAbility(position); return true; }
public static void CastFlash(Vector3 position) { if (States.Flash != null && position.IsValid() && States.Flash.IsReady) { Player.CastSpell(States.Flash.Slot, position); Remove("FL"); } else { Remove("FL"); } }
public Vector3 GetFirstWallPoint(Vector3 start, Vector3 end, float range) { if (end.IsValid() && start.Distance(end) <= range) { var newPoint = start.Extend(end, range); return NavMesh.GetCollisionFlags(newPoint) == CollisionFlags.Wall || newPoint.IsWall() ? newPoint : Vector3.Zero; } return Vector3.Zero; }
public static void CastFlash(Vector3 position) { var flash = Player.Spells.FirstOrDefault(a => a.SData.Name == "summonerflash"); if (flash != null && position.IsValid() && flash.IsReady) { Player.CastSpell(flash.Slot, position); Remove("FL"); } else { Remove("FL"); } }
public static Vector3 Randomize(this CryptoRandom rnd, Vector3 position, int amount) { if (position.IsValid()) { if (amount > 0) { amount = rnd.Next((int) Math.Floor(amount * 0.9f), (int) Math.Ceiling(amount * 1.1f)); position.X += rnd.Next(0, amount * 2 + 1) - amount; position.Y += rnd.Next(0, amount * 2 + 1) - amount; } position.X = Truncate((int) position.X + (float) rnd.NextDouble(), 3); position.Y = Truncate((int) position.Y + (float) rnd.NextDouble(), 3); position.Z = NavMesh.GetHeightForPosition(position.X, position.Y); } return position; }
public static bool IsSharpTurn(Vector3 position, int minAngle) { if (position.IsValid()) { var currentPath = ObjectManager.Player.GetWaypoints(); if (currentPath.Count > 1 && currentPath.PathLength() > 100) { var movePath = ObjectManager.Player.GetPath(position); if (movePath.Length > 1) { var angle = (currentPath[1] - currentPath[0]).AngleBetween((movePath[1] - movePath[0]).To2D()); var distance = movePath.Last().To2D().Distance(currentPath.Last(), true); return !(angle < 10 && distance < 500 * 500 || distance < 50 * 50) && angle > minAngle; } } } return false; }
public override void AccumulateCorrection(ref Vector3 correction, ref float weight) { if (Parent.Speed < 0.01f) return; var characterBotEntity = Parent.BotEntity as MyCharacter; // remove me pls if (characterBotEntity == null) return; var position = Parent.PositionAndOrientation.Translation; BoundingBoxD box = new BoundingBoxD(position - Vector3D.One * 3, position + Vector3D.One * 3); Vector3D currentMovement = Parent.ForwardVector; var entities = MyEntities.GetEntitiesInAABB(ref box); foreach (var entity in entities) { var character = entity as MyCharacter; if (character == null || character == characterBotEntity) continue; if (character.ModelName == characterBotEntity.ModelName) // remove me pls continue; Vector3D characterPos = character.PositionComp.GetPosition(); Vector3D dir = characterPos - position; double dist = dir.Normalize(); dist = MathHelper.Clamp(dist, 0, 6); var cos = Vector3D.Dot(dir, currentMovement); var opposite = -dir; if (cos > -0.807) correction += (6f - dist) * Weight * opposite; if (!correction.IsValid()) { System.Diagnostics.Debugger.Break(); } } entities.Clear(); weight += Weight; }
public static List<Vector3> PointsAroundTheTarget(Vector3 pos, float dist, float prec = 15, float prec2 = 6) { if (!pos.IsValid()) { return new List<Vector3>(); } var list = new List<Vector3>(); if (dist > 205) { prec = 30; prec2 = 8; } if (dist > 805) { dist = (float) (dist*1.5); prec = 45; prec2 = 10; } var angle = 360/prec*Math.PI/180.0f; var step = dist*2/prec2; for (var i = 0; i < prec; i++) { for (var j = 0; j < 6; j++) { list.Add( new Vector3( pos.X + (float) (Math.Cos(angle*i)*(j*step)), pos.Y + (float) (Math.Sin(angle*i)*(j*step)) - 90, pos.Z)); } } return list; }
public static List<Vector3> PointsAroundTheTargetOuterRing(Vector3 pos, float dist, float width = 15) { if (!pos.IsValid()) { return new List<Vector3>(); } var list = new List<Vector3>(); var max = 2*dist/2*Math.PI/width/2; var angle = 360f/max*Math.PI/180.0f; for (var i = 0; i < max; i++) { list.Add( new Vector3( pos.X + (float) (Math.Cos(angle*i)*dist), pos.Y + (float) (Math.Sin(angle*i)*dist), pos.Z)); } return list; }
public static double GetAngle(Obj_AI_Base source, Vector3 target) { if (source == null || !target.IsValid()) { return 0; } return source.Direction.LSTo2D().LSPerpendicular().LSAngleBetween((target - source.Position).LSTo2D()); ; }
public static bool IsFacing(Obj_AI_Base source, Vector3 target, float angle = 90) { if (source == null || !target.IsValid()) { return false; } return (double) source.Direction.LSTo2D().LSPerpendicular().LSAngleBetween((target - source.Position).LSTo2D()) < angle; }
private bool CheckQusage(Vector3 pos, Obj_AI_Hero target) { return pos.IsValid() && pos.Distance(player.Position) < Q.Range && (target.HasBuff("fiorapassivemanager") || target.HasBuff("fiorarmark")) && !pos.IsWall() && Qradius > pos.Distance(target.Position); }
public static bool IsFacing(this Vector3 source, Vector3 target) { if (!source.IsValid() || !target.IsValid()) { return false; } const float angle = 90; return source.To2D().AngleBetween((target - source).To2D()) < angle; }
private static Tuple<AIHeroClient, int, Vector3> GetMultiHit(bool checkKill, int minHit, int mode) { var bestHit = 0; AIHeroClient bestTarget = null; var bestPos = new Vector3(); var targetKicks = GameObjects.EnemyHeroes //TargetSelector(R.Range + (mode == 2 ? 500 : 0), R.DamageType) .Where( i => i.LSIsValidTarget(R.Range + (mode == 2 ? 500 : 0)) && (mode != 2 || i.DistanceToPlayer() < R.Range + (WardManager.WardRange - Insec.GetDistance(i) - 80)) && i.Health + i.AttackShield > R.GetDamage(i) && !i.HasBuffOfType(BuffType.SpellShield) && !i.HasBuffOfType(BuffType.SpellImmunity)) .OrderByDescending(i => i.AllShield) .ToList(); foreach (var targetKick in targetKicks) { var posTarget = mode == 1 ? targetKick.ServerPosition : R.GetPredPosition(targetKick, true); R2.UpdateSourcePosition(posTarget, posTarget); R2.Width = targetKick.BoundingRadius; var targetHits = GameObjects.EnemyHeroes.Where( i => !i.Compare(targetKick) && i.IsValidTarget(R2.Range + R2.Width / 2, true, R2.From)) .OrderByDescending(i => new Priority().GetDefaultPriority(i)) .ToList(); var posEnd = new Vector3(); if (mode == 0) { var pos = R2.From.LSExtend(Player.ServerPosition, -R2.Range); targetHits = targetHits.Where(i => R2.WillHit(i, pos, 0, R2.MinHitChance)).ToList(); if (checkKill && targetHits.Any(i => i.Health + i.AttackShield <= GetRColDmg(targetKick, i))) { return new Tuple<AIHeroClient, int, Vector3>(targetKick, -1, posEnd); } } else { R2.Delay = R.Delay + (mode == 2 ? 0.05f : 0); var hits = new List<AIHeroClient>(); foreach (var targetHit in targetHits) { var list = new List<AIHeroClient>(); var pred = R2.GetPrediction(targetHit); var pos = new Vector3(); if (pred.Hitchance >= R2.MinHitChance) { list.Add(targetHit); list.AddRange( targetHits.Where( i => !i.Compare(targetHit) && R2.WillHit(i, pred.CastPosition, 0, R2.MinHitChance))); pos = mode == 1 ? pred.CastPosition : pred.Input.From.LSExtend(pred.CastPosition, -Insec.GetDistance(targetKick)); } if (!pos.IsValid()) { continue; } if (checkKill && list.Any(i => i.Health + i.AttackShield <= GetRColDmg(targetKick, i))) { return new Tuple<AIHeroClient, int, Vector3>(targetKick, -1, pos); } if (list.Count > hits.Count) { hits = list; posEnd = pos; } } targetHits = hits; } if (targetHits.Count > bestHit) { bestTarget = targetKick; bestHit = targetHits.Count; bestPos = posEnd; } } return new Tuple<AIHeroClient, int, Vector3>(bestTarget, bestHit >= minHit ? 1 : 0, bestPos); }
public static bool IsWallBetween(Vector3 start, Vector3 end, int step = 3) { if (start.IsValid() && end.IsValid() && step > 0) { var distance = start.Distance(end); for (var i = 0; i < distance; i = i + step) { if (NavMesh.GetCollisionFlags(start.Extend(end, i)) == CollisionFlags.Wall) { return true; } } } return false; }
private static Vector3 GetPositionBehind(AIHeroClient target, Vector3 to, Vector3 from = default(Vector3)) { return (from.IsValid() ? from : target.ServerPosition).LSExtend(to, -GetDistance(target)); }
private static bool CanDash( Obj_AI_Base target, bool inQCir = false, bool underTower = true, Vector3 pos = new Vector3()) { if (HaveE(target)) { return false; } if (!pos.IsValid()) { pos = target.ServerPosition; } var posAfterE = GetPosAfterDash(target); return (underTower || !posAfterE.IsUnderEnemyTurret()) && posAfterE.Distance(pos) < (inQCir ? Q3.Range : pos.DistanceToPlayer()) && Evade.IsSafePoint(posAfterE.ToVector2()).IsSafe; }
private static void GapByFlash(AIHeroClient target, Vector3 posBehind) { switch (getBoxItem(insecMenu, "FlashMode")) { case 0: GapByRFlash(target); break; case 1: GapByFlashR(target, posBehind); break; case 2: if (!posBehind.IsValid()) { GapByRFlash(target); } else { GapByFlashR(target, posBehind); } break; } }
private void HandeR(Obj_AI_Base target, Vector3 toVector3, bool toBarrel) { if (target == null || !toVector3.IsValid()) { return; } if (target.HasBuffOfType(BuffType.Snare) || target.HasBuffOfType(BuffType.Stun) || target.HasBuffOfType(BuffType.Suppression) || target.HasBuffOfType(BuffType.Knockup) && !target.HasBuffOfType(BuffType.Knockback) && !target.IsMoving && !target.IsDashing() && !justE) { var pred = Prediction.GetPrediction(target, 1000f); var cast = pred.UnitPosition.Extend(toVector3, -200); if (player.Distance(cast) < R.Range && checkBuffs(target, player.Distance(cast)) && pred.UnitPosition.Distance(target.Position) < 15 && ((!CombatHelper.CheckWalls(target.Position, toVector3)) || (toBarrel && savedQ.position.Distance(target.Position) < QExplosionRange))) { if (toBarrel && 4000 - savedQ.deltaT() > (player.Distance(cast) + cast.Distance(savedQ.position)) / R.Speed) { R.Cast(cast); return; } else if (!toBarrel) { R.Cast(cast); } } } /* if (!config.Item("insecOnlyStun", true).GetValue<bool>()) { var cast = R.GetPrediction(target, true, 90); if (cast.Hitchance >= HitChance.VeryHigh) { R.Cast(cast.CastPosition.Extend(savedQ.position, -100)); } }*/ }
private static void HandeR(Obj_AI_Base target, Vector3 toVector3, bool toBarrel) { if (target == null || !toVector3.IsValid()) { return; } var pred = LeagueSharp.Common.Prediction.GetPrediction(target, target.LSDistance(Player.ServerPosition) / R.Speed); if (pred.Hitchance >= HitChance.VeryHigh && !justE && !target.LSIsDashing()) { var cast = pred.UnitPosition.LSExtend(toVector3, -100); if (Player.LSDistance(cast) < R.Range && checkBuffs(target, Player.LSDistance(cast)) && pred.UnitPosition.LSDistance(target.Position) < 15 && ((!CombatHelper.CheckWalls(target.Position, toVector3)) || (toBarrel && savedQ.position.LSDistance(target.Position) < QExplosionRange))) { if (toBarrel && 4000 - savedQ.deltaT() > (Player.LSDistance(cast) + cast.LSDistance(savedQ.position)) / R.Speed) { R.Cast(cast); return; } else if (!toBarrel) { R.Cast(cast); } } } }
private List<Obj_AI_Hero> GetRTarget(Vector3 from = new Vector3()) { var pos = from.IsValid() ? from : Player.ServerPosition; return HeroManager.Enemies.Where( i => i.IsValidTarget() && pos.Distance(Prediction.GetPrediction(i, 0.25f).UnitPosition) < R.Range) .ToList(); }
private void Game_OnUpdate(EventArgs args) { var insecPoint = new Vector3(0, 2, 3); if (Clickposition == new Vector3(0, 0, 0)) insecPoint = Game.CursorPos; else insecPoint = Clickposition; if (!Menu._jumpMenu["inseckey"].Cast<KeyBind>().CurrentValue) { soldier = null; return; } azir.Orbwalk(Game.CursorPos); if (!insecPoint.IsValid()) return; var target = TargetSelector.SelectedTarget; if (!target.IsValidTarget() || target.IsZombie) return; if (azir.Hero.LSDistance(target) <= azir.Spells.R.Range && !azir.Hero.LSIsDashing()) { if (Clickposition == new Vector3(0, 0, 0)) { var tower = ObjectManager.Get<Obj_AI_Turret>().FirstOrDefault(it => it.IsAlly && it.LSIsValidTarget(1000)); if (tower != null) { if (azir.Spells.R.Cast(tower.ServerPosition)) return; } if (azir.Spells.R.Cast(Game.CursorPos)) return; } else { azir.Spells.R.Cast(Clickposition); } } var pos = target.ServerPosition.Extend(Game.CursorPos, -300); if (pos.Distance(azir.Hero.ServerPosition) <= 1100) { if (soldier == null) soldier = azir.soldierManager.ActiveSoldiers .Where(x => x.LSDistance(pos) <= 900) .OrderBy(x => x.Position.Distance(target.Position)).FirstOrDefault(); if (soldier == null) { castWOnAngle(HeroManager.Player.ServerPosition.LSTo2D(), target.ServerPosition.To2D(), 45); return; } if (soldier != null) { azir.Spells.E.Cast(soldier.Position); } if (!azir.Spells.E.IsReady()) { if (azir.Hero.LSDistance(soldier.ServerPosition) <= 150) { azir.Spells.Q.Cast(pos); } } } }
private int GetRangeDelay(Vector3 position, Vector3 lastPosition, int percent) { if (percent > 0 && position.IsValid() && lastPosition.IsValid()) { var distance = position.Distance(lastPosition); if (Helpers.AngleBetween(lastPosition, position) > _random.Next(15, 26) && distance > 200) { var rangeDelay = (int) (distance * _random.Next(75, 86) / 100 / 100 * percent); return Math.Min(_random.Next(1250, 1500) / 100 * percent, rangeDelay); } } return 0; }
public static double GetAngle(Obj_AI_Base source, Vector3 target) { if (source == null || !target.IsValid()) { return 0; } return Geometry.AngleBetween( Geometry.Perpendicular(Geometry.To2D(source.Direction)), Geometry.To2D(target - source.Position)); ; }
private static void SetSpellPosition(this Spell spell, Vector3 position) { if (position.IsValid()) { spell.From = position; spell.RangeCheckFrom = position; return; } spell.From = new Vector3(); spell.RangeCheckFrom = new Vector3(); }
private static void Game_OnUpdate(EventArgs args) { switch (Program.insecmode) { case 0: var hero = HeroManager.Allies.Where(x => !x.IsMe && !x.IsDead) .OrderByDescending(x => x.LSDistance(Player.Position)).LastOrDefault(); if (hero != null) InsecPoint = hero.Position; break; case 1: var turret = GameObjects.AllyTurrets.OrderByDescending(x => x.LSDistance(Player.Position)).LastOrDefault(); if (turret != null) InsecPoint = turret.Position; break; case 2: InsecPoint = Game.CursorPos; break; case 3: InsecPoint = LastLeftClick; break; } if (!Program.insec) return; if (Orbwalker.CanMove) { Orbwalker.MoveTo(Game.CursorPos); } if (!InsecPoint.IsValid()) return; var target = TargetSelector.SelectedTarget; if (!target.LSIsValidTarget() || target.IsZombie) return; if (!Program._r2.IsReady()) return; //case 1 Vector2 start1 = Player.Position.LSTo2D().LSExtend(InsecPoint.LSTo2D(), -300); Vector2 end1 = start1.LSExtend(Player.Position.LSTo2D(), 750); float width1 = Program._r.Level == 3 ? 125 * 6 / 2 : Program._r.Level == 2 ? 125 * 5 / 2 : 125 * 4 / 2; var Rect1 = new LeagueSharp.Common.Geometry.Polygon.Rectangle(start1, end1, width1 - 100); var Predicted1 = LeagueSharp.Common.Prediction.GetPrediction(target, Game.Ping / 1000f + 0.25f).UnitPosition; if (Rect1.IsInside(target.Position) && Rect1.IsInside(Predicted1)) { Program._r2.Cast(InsecPoint); return; } if (Environment.TickCount - LastJump < 1500) return; if (!Program._e.IsReady()) return; //case 2 var sold2 = Soldiers.soldier .Where(x => Player.LSDistance(x.Position) <= 1100) .OrderBy(x => x.Position.LSDistance(target.Position)).FirstOrDefault(); if (sold2 != null) { if (!Program._q2.IsReady()) { var time = Player.Position.LSDistance(sold2.Position) / 1700f; var predicted2 = LeagueSharp.Common.Prediction.GetPrediction(target, time).UnitPosition; Vector2 start2 = sold2.Position.LSTo2D().LSExtend(InsecPoint.LSTo2D(), -300); Vector2 end2 = start2.LSExtend(InsecPoint.LSTo2D(), 750); float width2 = Program._r.Level == 3 ? 125 * 6 / 2 : Program._r.Level == 2 ? 125 * 5 / 2 : 125 * 4 / 2; var Rect2 = new LeagueSharp.Common.Geometry.Polygon.Rectangle(start2, end2, width2 - 100); if (Rect2.IsInside(target.Position) && Rect2.IsInside(predicted2)) { Program._e.Cast(sold2.Position); LastJump = Environment.TickCount; return; } } if (Program._q2.IsReady() && target.LSDistance(sold2.Position) <= 875 - 100) { var time = (Player.LSDistance(sold2.Position) + sold2.Position.LSDistance(target.Position)) / 1700f; var predicted2 = LeagueSharp.Common.Prediction.GetPrediction(target, time).UnitPosition; Vector2 start2 = target.Position.LSTo2D().LSExtend(InsecPoint.LSTo2D(), -300); Vector2 end2 = start2.LSExtend(InsecPoint.LSTo2D(), 750); float width2 = Program._r.Level == 3 ? 125 * 6 / 2 : Program._r.Level == 2 ? 125 * 5 / 2 : 125 * 4 / 2; var Rect2 = new LeagueSharp.Common.Geometry.Polygon.Rectangle(start2, end2, width2 - 100); if (Rect2.IsInside(target.Position) && Rect2.IsInside(predicted2)) { var timetime = sold2.Position.LSDistance(Player.Position) * 1000 / 1700; Program._e.Cast(sold2.Position); LeagueSharp.Common.Utility.DelayAction.Add((int)timetime - 150 - Program.EQdelay, () => Program._q2.Cast(target.Position)); LastJump = Environment.TickCount; return; } } } if(Program._w.IsReady()) { var posWs = GeoAndExten.GetWsPosition(target.Position.LSTo2D()).Where(x => x != null); foreach (var posW in posWs) { if (!Program._q2.IsReady()) { var time = Player.Position.LSTo2D().LSDistance((Vector2)posW) / 1700f + 0.3f; var predicted2 = LeagueSharp.Common.Prediction.GetPrediction(target, time).UnitPosition; Vector2 start2 = ((Vector2)posW).LSExtend(InsecPoint.LSTo2D(), -300); Vector2 end2 = start2.LSExtend(InsecPoint.LSTo2D(), 750); float width2 = Program._r.Level == 3 ? 125 * 6 / 2 : Program._r.Level == 2 ? 125 * 5 / 2 : 125 * 4 / 2; var Rect2 = new LeagueSharp.Common.Geometry.Polygon.Rectangle(start2, end2, width2 - 100); if (Rect2.IsInside(target.Position) && Rect2.IsInside(predicted2)) { var timetime = ((Vector2)posW).LSDistance(Player.Position) * 1000 / 1700; Program._w.Cast(Player.Position.LSTo2D().LSExtend((Vector2)posW, Program._w.Range)); LeagueSharp.Common.Utility.DelayAction.Add(0, () => Program._e.Cast((Vector2)posW)); LeagueSharp.Common.Utility.DelayAction.Add((int)timetime + 300 - 150 - Program.EQdelay, () => Program._q2.Cast(target.Position)); LastJump = Environment.TickCount; return; } } if (Program._q2.IsReady() && target.LSDistance((Vector2)posW) <= 875 - 100) { var time = (Player.LSDistance((Vector2)posW) + ((Vector2)posW).LSDistance(target.Position)) / 1700f + 0.3f; var predicted2 = LeagueSharp.Common.Prediction.GetPrediction(target, time).UnitPosition; Vector2 start2 = target.Position.LSTo2D().LSExtend(InsecPoint.LSTo2D(), -300); Vector2 end2 = start2.LSExtend(InsecPoint.LSTo2D(), 750); float width2 = Program._r.Level == 3 ? 125 * 6 / 2 : Program._r.Level == 2 ? 125 * 5 / 2 : 125 * 4 / 2; var Rect2 = new LeagueSharp.Common.Geometry.Polygon.Rectangle(start2, end2, width2 - 100); if (Rect2.IsInside(target.Position) && Rect2.IsInside(predicted2)) { var timetime = ((Vector2)posW).LSDistance(Player.Position) * 1000 / 1700; Program._w.Cast(Player.Position.LSTo2D().LSExtend((Vector2)posW, Program._w.Range)); LeagueSharp.Common.Utility.DelayAction.Add(0, () => Program._e.Cast((Vector2)posW)); LeagueSharp.Common.Utility.DelayAction.Add((int)timetime + 300 - 150 - Program.EQdelay, () => Program._q2.Cast(target.Position)); LastJump = Environment.TickCount; return; } } } } }
private static void CastRFlash(Obj_AI_Base target) { var targetSelect = TargetSelector.SelectedTarget; if (!targetSelect.LSIsValidTarget() || !targetSelect.Compare(target) || target.Health + target.AttackShield <= R.GetDamage(target)) { return; } var pos = new Vector3(); if (getKeyBindItem(miscMenu, "RFlash")) { pos = Game.CursorPos; } else if (getKeyBindItem(bkMenu, "R") && posBubbaKushFlash.IsValid()) { pos = posBubbaKushFlash; } else if (getKeyBindItem(insecMenu, "R") && Insec.IsRecentRFlash) { pos = Insec.GetPositionKickTo((AIHeroClient)target); } if (pos.IsValid()) { Player.Spellbook.CastSpell( Flash, target.ServerPosition.LSExtend(pos, -(Player.BoundingRadius / 2 + target.BoundingRadius + 50))); } }
/// <summary> /// Casts the item on a Vector3 position. /// </summary> /// <param name="id"> /// Id of the Item. /// </param> /// <param name="position"> /// Position of the Item cast. /// </param> /// <returns> /// The <see cref="bool" />. /// </returns> public static bool UseItem(int id, Vector3 position) { return position.IsValid() && GameObjects.Player.InventoryItems.Where(slot => slot.Id == (ItemId)id) .Select(slot => GameObjects.Player.Spellbook.CastSpell(slot.SpellSlot, position)) .FirstOrDefault(); }