private static void OnTargetSpellDetection(Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args)
        {
            try
            {
                //MissileEffect=Cassiopeia_Base_E_TwinFang_mis.troy
                if (sender.Position.Distance(ObjectManager.Player.Position) > DetectionRange)
                {
                    return; // only detect spells in range
                }
                if (!sender.IsValid <Obj_AI_Hero>())
                {
                    return; // only hero
                }
                if (!args.Target.IsValid <Obj_AI_Base>())
                {
                    return; // only targeted
                }
                if (args.SData.Name.ToLower().Contains("summoner") || args.SData.Name.ToLower().Contains("recall"))
                {
                    return; // ignore summoners TODO: add summoners to database
                }
                // TODO: add menu check
                //Cassiopeia_Base_E_TwinFang_tar.troy
                //Cassiopeia_Base_E_TwinFang_mis.troy

                /* foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(args.SData))
                 * {
                 *   string name = descriptor.Name;
                 *   object value = descriptor.GetValue(args.SData);
                 *  // if (value == "Cassiopeia_Base_E_TwinFang_mis.troy")
                 *    Console.WriteLine("{0}={1}", name, value);
                 * }*/

                var caster = (Obj_AI_Hero)sender;
                var target = (Obj_AI_Base)args.Target;
                var data   = TargetSpellDatabase.GetByName(args.SData.Name);


                if (Orbwalking.IsAutoAttack(args.SData.Name))
                {
                    data = new TargetSpellData(
                        caster.ChampionName.ToLower(),
                        args.SData.Name.ToLower(),
                        SpellSlot.Unknown,
                        SpellType.AutoAttack,
                        CcType.No,
                        caster.AttackRange,
                        caster.AttackDelay,
                        caster.BasicAttack.MissileSpeed); // TODO: check melee
                }

                /*if (data == null)
                 * {
                 *  Console.WriteLine("Target Spell not Found: " + args.SData.Name);
                 *  return;
                 * }*/

                ActiveTargeted.Add(new TargetSpell
                {
                    Caster        = caster,
                    Target        = target,
                    Spell         = data,
                    StartTick     = Environment.TickCount,
                    StartPosition = args.Start.To2D(),
                    blockBelow    = TargetedSpellManager.blockSpellOnHP(caster.ChampionName, args.SData.Name),
                    spellArgs     = args,
                    particleName  = getParticleName(args.SData.MissileEffect)
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
        private static void OnTargetSpellDetection(Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args)
        {
            try
            {
                // TODO: add menu check
                //Cassiopeia_Base_E_TwinFang_tar.troy
                //Cassiopeia_Base_E_TwinFang_mis.troy

                /* foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(args.SData))
                 * {
                 *   string name = descriptor.Name;
                 *   object value = descriptor.GetValue(args.SData);
                 *  // if (value == "Cassiopeia_Base_E_TwinFang_mis.troy")
                 *    Console.WriteLine("{0}={1}", name, value);
                 * }*/

                var caster = sender as AIHeroClient;
                var target = args.Target as Obj_AI_Base;
                if (caster == null || target == null)
                {
                    return;
                }

                var data = TargetSpellDatabase.GetByName(args.SData.Name);
                if (Orbwalking.IsAutoAttack(args.SData.Name))
                {
                    data = new TargetSpellData(
                        caster.ChampionName.ToLower(),
                        args.SData.Name.ToLower(),
                        SpellSlot.Unknown,
                        SpellType.AutoAttack,
                        CcType.No,
                        caster.AttackRange,
                        caster.AttackDelay,
                        caster.BasicAttack.MissileSpeed); // TODO: check melee
                }
                return;

                /*if (data == null)
                 * {
                 *  Console.WriteLine("Target Spell not Found: " + args.SData.Name);
                 *  return;
                 * }*/

                ActiveTargeted.Add(new TargetSpell
                {
                    Caster        = caster,
                    Target        = target,
                    Spell         = data,
                    StartTick     = Environment.TickCount,
                    StartPosition = args.Start.To2D(),
                    blockBelow    = TargetedSpellManager.blockSpellOnHP(caster.ChampionName, args.SData.Name),
                    spellArgs     = args,
                    particleName  = getParticleName(args.SData.MissileEffectName)
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
        private static void OnTargetSpellDetection(Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args)
        {
            try
            {
                //MissileEffect=Cassiopeia_Base_E_TwinFang_mis.troy
                if (sender.Position.Distance(ObjectManager.Player.Position) > DetectionRange)
                    return; // only detect spells in range

                if (!sender.IsValid<Obj_AI_Hero>())
                    return; // only hero

                if (!args.Target.IsValid<Obj_AI_Base>())
                    return; // only targeted

                if (args.SData.Name.ToLower().Contains("summoner") || args.SData.Name.ToLower().Contains("recall"))
                    return; // ignore summoners TODO: add summoners to database

                // TODO: add menu check
                //Cassiopeia_Base_E_TwinFang_tar.troy
                //Cassiopeia_Base_E_TwinFang_mis.troy
               /* foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(args.SData))
                {
                    string name = descriptor.Name;
                    object value = descriptor.GetValue(args.SData);
                   // if (value == "Cassiopeia_Base_E_TwinFang_mis.troy")
                     Console.WriteLine("{0}={1}", name, value);
                }*/

                var caster = (Obj_AI_Hero)sender;
                var target = (Obj_AI_Base)args.Target;
                var data = TargetSpellDatabase.GetByName(args.SData.Name);

                if (Orbwalking.IsAutoAttack(args.SData.Name))
                {
                    data = new TargetSpellData(
                        caster.ChampionName.ToLower(),
                        args.SData.Name.ToLower(),
                        SpellSlot.Unknown,
                        SpellType.AutoAttack,
                        CcType.No,
                        caster.AttackRange,
                        caster.AttackDelay,
                        caster.BasicAttack.MissileSpeed); // TODO: check melee
                }

                /*if (data == null)
                {
                    Console.WriteLine("Target Spell not Found: " + args.SData.Name);
                    return;
                }*/

                ActiveTargeted.Add(new TargetSpell
                {
                    Caster = caster,
                    Target = target,
                    Spell = data,
                    StartTick = Environment.TickCount,
                    StartPosition = args.Start.To2D(),
                    blockBelow = TargetedSpellManager.blockSpellOnHP(caster.ChampionName, args.SData.Name),
                    spellArgs = args,
                    particleName = getParticleName(args.SData.MissileEffect)

                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }