using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using LeagueSharp; using LeagueSharp.Common; using SharpDX; using Color = System.Drawing.Color; namespace LSharpTest { class Program { public const string Revision = "1.0b"; private static Obj_AI_Hero myChamp = ObjectManager.Player; private static Orbwalking.Orbwalker orbwalker; private static Spell[] Skills = {new Spell(SpellSlot.Q, 260), new Spell(SpellSlot.W, 250), new Spell(SpellSlot.E, 325), new Spell(SpellSlot.R, 900)}; private static Items.Item Tiamat = new Items.Item(3077, 400); private static Items.Item Hydra = new Items.Item(3074, 400); private static Items.Item Ghostblade = new Items.Item(3142, 600); private static Menu Config; //private static bool ProcessPackets; private static int qCount; private static int passive; private static int lastQCast; private static bool ultiOn; private static bool ultiReady; private static bool ProcessPackets; private static Spell nextSpell; private static Spell lastSpell; private static string lastSpellName; private static bool UseAttack; private static bool useTiamat; private static bool IsKSing; private static Obj_AI_Base currentTarget; private static int lastGapClose; private static bool IsRecalling; public static void Main(string[] args) { CustomEvents.Game.OnGameLoad += OnLoad; } private static void OnLoad(EventArgs args) { if (myChamp.ChampionName != "Riven") return; if (Utility.Map.GetMap()._MapType != Utility.Map.MapType.SummonersRift) { Game.PrintChat("Classy Riven is currently for Summoners Rift only. I'm sorry!"); return; } Config = new Menu("Classy Riven", "Riven", true); Config.AddSubMenu(new Menu("Orbwalker", "Orbwalker")); orbwalker = new Orbwalking.Orbwalker(Config.SubMenu("Orbwalker")); var tsMenu = new Menu("Target", "Target Selector"); SimpleTs.AddToMenu(tsMenu); Config.AddSubMenu(tsMenu); Config.AddToMainMenu(); Config.AddSubMenu(new Menu("Combo Settings", "ComboS")); Config.AddSubMenu(new Menu("KS(ecure) Settings", "KS")); Config.AddSubMenu(new Menu("Draw Settings", "Draw")); Config.SubMenu("ComboS").AddItem(new MenuItem("UseUlti", "Use Ultimate in Combo").SetValue(true)); Config.SubMenu("ComboS").AddItem(new MenuItem("UseQGapClose", "Use Q to gapclose").SetValue(true)); Config.AddItem(new MenuItem("AutoStun", "Auto Stun (ex. Gap Closer)").SetValue(true)); Config.SubMenu("KS").AddItem(new MenuItem("KillSecureRActivate", "Use Ultimate to Secure").SetValue(false)); Config.SubMenu("KS").AddItem(new MenuItem("KillSecureR", "Secure with R2").SetValue(true)); Config.SubMenu("KS").AddItem(new MenuItem("KillSecureQ", "Secure with Q").SetValue(true)); Config.SubMenu("KS").AddItem(new MenuItem("KillSecureW", "Secure with W").SetValue(true)); Config.SubMenu("KS").AddItem(new MenuItem("KillSecureT", "Secure with Tiamat").SetValue(true)); Config.SubMenu("Draw").AddItem(new MenuItem("DrawTarget", "Draw current target").SetValue(new Circle(true, Color.FromKnownColor(System.Drawing.KnownColor.Green)))); Config.SubMenu("Draw").AddItem(new MenuItem("lataaaa", "I'll add some more later")); Skills[3].SetSkillshot(0.25f, 60f, 2200, false, SkillshotType.SkillshotCone); Skills[2].SetSkillshot(0, 0, 1450, false, SkillshotType.SkillshotLine); Orbwalking.BeforeAttack += delegate(Orbwalking.BeforeAttackEventArgs __args) { if (!__args.Target.IsMinion) orbwalker.SetMovement(false); }; Obj_AI_Base.OnProcessSpellCast += OnProcessSpell; Obj_AI_Base.OnPlayAnimation += OnAnimation; Game.OnGameUpdate += OnGameUpdate; Game.OnGameUpdate += Buffs_GameUpdate; Game.OnGameProcessPacket += OnGameProcessPacket; Game.OnWndProc += OnWndProc; Drawing.OnDraw += OnDraw; AntiGapcloser.OnEnemyGapcloser += OnEnemyGapCloser; Game.PrintChat(String.Format("Classy Riven v {0}; TheMarv approves!", Revision)); } private static void OnDraw(EventArgs args) { if (Config.SubMenu("Draw").Item("DrawTarget").GetValue().Active) { Utility.DrawCircle(currentTarget.ServerPosition, currentTarget.BoundingRadius + 10, Config.SubMenu("Draw").Item("DrawTarget").GetValue().Color, 5); Utility.DrawCircle(currentTarget.ServerPosition, currentTarget.BoundingRadius + 25, Config.SubMenu("Draw").Item("DrawTarget").GetValue().Color, 6); Utility.DrawCircle(currentTarget.ServerPosition, currentTarget.BoundingRadius + 45, Config.SubMenu("Draw").Item("DrawTarget").GetValue().Color, 7); } } private static void Buffs_GameUpdate(EventArgs args) { bool ulti = false; bool ulti2 = false; bool q = false; BuffInstance[] buffList = myChamp.Buffs; foreach (BuffInstance buff in buffList) { if (buff.Name == "rivenpassiveaaboost") { passive = buff.Count; } if (buff.Name == "rivenwindslashready") { ulti = true; ultiReady = true; } if (buff.Name == "RivenTriCleave") { q = true; qCount = buff.Count; } if (buff.Name == "RivenFengShuiEngine") { ulti2 = true; ultiOn = true; } } if (q == false) qCount = 0; if (ulti == false) { ultiReady = false; IsKSing = false; } if (ulti2 == false) ultiOn = false; } public static void OnEnemyGapCloser(ActiveGapcloser gapcloser) { if (Skills[1].IsReady() && gapcloser.Sender.IsValidTarget(Skills[1].Range) && Config.Item("AutoStun").GetValue()) Skills[1].Cast(); } private static void OnGameUpdate(EventArgs args) { bool combo = orbwalker.ActiveMode.ToString().ToLower().Contains("combo"); //KillSecure(); // AutoStun(); if (combo) { if (currentTarget == null) AcquireTarget(); if (currentTarget.IsDead || currentTarget.IsInvulnerable || !currentTarget.IsVisible || currentTarget.IsZombie || !currentTarget.IsValidTarget(Skills[2].Range + Skills[0].Range + myChamp.AttackRange)) AcquireTarget(); if (!currentTarget.IsDead && currentTarget.IsVisible) { GapClose(currentTarget); Combo(currentTarget); var playerPos = Drawing.WorldToScreen(myChamp.Position); Drawing.DrawText(playerPos.X - 65, playerPos.Y + 20, System.Drawing.Color.Red, "Target: {0}", currentTarget.BaseSkinName); } } else { orbwalker.SetMovement(true); } } private static void AutoStun() { foreach (Obj_AI_Hero enemy in ObjectManager.Get().Where(hero => hero.Team != myChamp.Team)) { if (Skills[1].IsReady() && enemy.IsValidTarget(Skills[1].Range) && Config.SubMenu("Misc").SubMenu("AutoStun").Item("Stun" + enemy.ChampionName).GetValue()) { Skills[1].Cast(); } } } private static void AcquireTarget() { currentTarget = SimpleTs.GetTarget(Skills[2].Range + Skills[0].Range + myChamp.AttackRange, SimpleTs.DamageType.Physical); } public static void Combo(Obj_AI_Base target) { double noRComboDmg = DamageCalcNoR(target); if (Skills[3].IsReady() && !ultiReady && noRComboDmg < target.Health && Config.SubMenu("ComboS").Item("UseUlti").GetValue() && currentTarget is Obj_AI_Hero) { Skills[3].Cast(); } if (!(Tiamat.IsReady() || Hydra.IsReady()) && !Skills[0].IsReady() && Skills[1].IsReady() && currentTarget.IsValidTarget(Skills[1].Range)) Skills[1].Cast(); if (nextSpell == null && useTiamat) { if (Tiamat.IsReady()) Tiamat.Cast(); else if (Hydra.IsReady()) Hydra.Cast(); } if (nextSpell == null && UseAttack) { Orbwalking.LastAATick = Environment.TickCount + Game.Ping / 2; myChamp.IssueOrder(GameObjectOrder.AttackUnit, currentTarget); } if (nextSpell == Skills[0]) { Skills[0].Cast(currentTarget.ServerPosition, true); nextSpell = null; } if (nextSpell == Skills[1]) { Skills[1].Cast(); nextSpell = null; } if (nextSpell == Skills[2]) { Skills[2].Cast(currentTarget.ServerPosition); nextSpell = null; } } private static void OnWndProc(WndEventArgs args) { if (MenuGUI.IsChatOpen) return; } public static void OnGameProcessPacket(GamePacketEventArgs args) { try { if (args.PacketData[0] == 0x65) { var packet = new GamePacket(args.PacketData); packet.Position = 1; int targetId = packet.ReadInteger(); int damageType = packet.ReadByte(); packet.Position = 16; int sourceId = packet.ReadInteger(); if (myChamp.NetworkId != sourceId) return; var target = ObjectManager.GetUnitByNetworkId(targetId); if (orbwalker.ActiveMode.ToString() == "Combo") { if ((damageType == 3 || damageType == 4) && lastSpellName.Contains("Attack")) { if (Tiamat.IsReady() && currentTarget.IsValidTarget(Tiamat.Range)) { Tiamat.Cast(); } else if (Hydra.IsReady() && currentTarget.IsValidTarget(Hydra.Range)) { Hydra.Cast(); } else if (Skills[1].IsReady() && currentTarget.IsValidTarget(Skills[1].Range) && qCount != 0) { nextSpell = Skills[1]; } else { nextSpell = Skills[0]; } UseAttack = false; orbwalker.SetMovement(true); } } } else if (args.PacketData[0] == 0x34) { var packet = new GamePacket(args.PacketData); packet.Position = 9; int action = packet.ReadByte(); packet.Position = 1; int sourceId = packet.ReadInteger(); if (action == 17 && sourceId == myChamp.NetworkId) { if (ProcessPackets) { if (!Config.SubMenu("Misc").Item("DCFix").GetValue()) CancelAnimation(); Orbwalking.ResetAutoAttackTimer(); } } } else if (args.PacketData[0] == 0x61) { var packet = new GamePacket(args.PacketData); packet.Position = 12; int sourceId = packet.ReadInteger(); if (sourceId == myChamp.NetworkId) { if (currentTarget != null && ProcessPackets && orbwalker.ActiveMode.ToString() == "Combo") { Packet.C2S.Move.Encoded(new Packet.C2S.Move.Struct(currentTarget.ServerPosition.To2D().X, currentTarget.ServerPosition.To2D().Y, 3, currentTarget.NetworkId)).Send(); Orbwalking.ResetAutoAttackTimer(); ProcessPackets = false; } if (ProcessPackets) { Orbwalking.ResetAutoAttackTimer(); ProcessPackets = false; } } } else if (args.PacketData[0] == 0x38) //animation2 { var packet = new GamePacket(args.PacketData); packet.Position = 1; int sourceId = packet.ReadInteger(); if (packet.Size() == 9 && sourceId == myChamp.NetworkId) { if (ProcessPackets) { CancelAnimation(); // wait until recv packet 0x61 Orbwalking.ResetAutoAttackTimer(); } } } else if (args.PacketData[0] == 0xD8) { Packet.S2C.Recall.Struct packet = Packet.S2C.Recall.Decoded(args.PacketData); if (packet.UnitNetworkId == myChamp.NetworkId) { if (packet.Status == Packet.S2C.Recall.RecallStatus.RecallStarted) { IsRecalling = true; } else if (packet.Status == Packet.S2C.Recall.RecallStatus.RecallAborted || packet.Status == Packet.S2C.Recall.RecallStatus.RecallFinished) { IsRecalling = false; } } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } public static void OnAnimation(GameObject unit, GameObjectPlayAnimationEventArgs args) { if (unit.IsMe && orbwalker.ActiveMode.ToString() == "Combo") // Spell1 = Q { if (args.Animation.Contains("Spell1")) { ProcessPackets = true; if (!Config.SubMenu("Misc").Item("DCFix").GetValue()) CancelAnimation(); } } } public static void CancelAnimation() { Vector3 movePos = Game.CursorPos; if (currentTarget.IsValidTarget(600)) { movePos = currentTarget.ServerPosition + (myChamp.ServerPosition - currentTarget.ServerPosition); movePos.Normalize(); movePos *= myChamp.Distance(currentTarget.ServerPosition) + 55; } //Packet.C2S.Move.Encoded(new Packet.C2S.Move.Struct(movePos.X, movePos.Y)).Send(); myChamp.IssueOrder(GameObjectOrder.MoveTo, movePos); } private static double GetRDamage(Obj_AI_Base target) // DamageLib doesn't do this correctly yet { double minDmg = 0.0; if (Skills[3].Level == 0) return 0.0; minDmg = (80 + (40 * (Skills[3].Level - 1))) + 0.6 * ((0.2 * (myChamp.BaseAttackDamage + myChamp.FlatPhysicalDamageMod)) + myChamp.FlatPhysicalDamageMod); float targetPercentHealthMissing = 100 * (1 - target.Health / target.MaxHealth); double dmg = 0.0; if (targetPercentHealthMissing > 75.0f) { dmg = minDmg * 3; } else { dmg = minDmg + minDmg * (0.0267 * targetPercentHealthMissing); } double realDmg = myChamp.CalcDamage(target, Damage.DamageType.Physical, dmg - 20); return realDmg; } private static double GetUltiQDamage(Obj_AI_Base target) // account for bonus ulti AD { double dmg = 10 + ((Skills[0].Level - 1) * 20) + 0.6 * (1.2 * (myChamp.BaseAttackDamage + myChamp.FlatPhysicalDamageMod)); return myChamp.CalcDamage(target, Damage.DamageType.Physical, dmg - 10); } private static double GetUltiWDamage(Obj_AI_Base target) // account for bonus ulti AD { float totalAD = myChamp.FlatPhysicalDamageMod + myChamp.BaseAttackDamage; double dmg = 50 + ((Skills[1].Level - 1) * 30) + (0.2 * totalAD + myChamp.FlatPhysicalDamageMod); return myChamp.CalcDamage(target, Damage.DamageType.Physical, dmg - 10); } private static double GetQDamage(Obj_AI_Base target) { float totalAD = myChamp.FlatPhysicalDamageMod + myChamp.BaseAttackDamage; double dmg = 10 + ((Skills[0].Level - 1) * 20) + (0.35 + (myChamp.Level * 0.05)) * totalAD; return myChamp.CalcDamage(target, Damage.DamageType.Physical, dmg - 10); } private static double GetWDamage(Obj_AI_Base target) { float dmg = 50 + (Skills[1].Level * 30) + myChamp.FlatPhysicalDamageMod; return myChamp.CalcDamage(target, Damage.DamageType.Physical, dmg - 10); } private static double DamageCalcNoR(Obj_AI_Base target) { float health = target.Health; double qDamage = GetQDamage(target); double wDamage = GetWDamage(target); double tDamage = 0.0; double aDamage = myChamp.GetAutoAttackDamage(target); double pDmgMultiplier = 0.2 + (0.05 * Math.Floor(myChamp.Level / 3.0)); float totalAD = myChamp.BaseAttackDamage + myChamp.FlatPhysicalDamageMod; double pDamage = myChamp.CalcDamage(target, Damage.DamageType.Physical, pDmgMultiplier * totalAD); if (Tiamat.IsReady() || Hydra.IsReady()) tDamage = myChamp.GetItemDamage(target, Damage.DamageItems.Tiamat); if (!Skills[0].IsReady() && qCount == 0) qDamage = 0.0; if (!Skills[1].IsReady()) wDamage = 0.0; return wDamage + tDamage + (qDamage * (3 - qCount)) + (pDamage * (3 - qCount)) + aDamage * (3 - qCount); } public static double DamageCalcR(Obj_AI_Base target) { float health = target.Health; double qDamage = GetUltiQDamage(target); double wDamage = GetUltiWDamage(target); double rDamage = GetRDamage(target); double tDamage = 0.0; float totalAD = myChamp.FlatPhysicalDamageMod + myChamp.BaseAttackDamage; double aDamage = myChamp.CalcDamage(target, Damage.DamageType.Physical, 0.2 * totalAD + totalAD); double pDmgMultiplier = 0.2 + (0.05 * Math.Floor(myChamp.Level / 3.0)); double pDamage = myChamp.CalcDamage(target, Damage.DamageType.Physical, pDmgMultiplier * (0.2 * totalAD + totalAD)); if (Tiamat.IsReady() || Hydra.IsReady()) tDamage = myChamp.GetItemDamage(target, Damage.DamageItems.Tiamat); if (!Skills[0].IsReady() && qCount == 0) qDamage = 0.0; if (!Skills[1].IsReady()) wDamage = 0.0; if (Skills[3].IsReady()) rDamage = 0.0; return (pDamage * (3 - qCount)) + (aDamage * (3 - qCount)) + wDamage + tDamage + rDamage + (qDamage * (3 - qCount)); } public static void OnProcessSpell(Obj_AI_Base sender, GameObjectProcessSpellCastEventArgs args) { if (sender.IsMe) { string SpellName = args.SData.Name; lastSpellName = SpellName; if (IsKSing && SpellName == "RivenFengShuiEngine") // cancel r animation to fire quickly { if (Tiamat.IsReady()) Tiamat.Cast(); if (Hydra.IsReady()) Hydra.Cast(); } if (SpellName == "RivenTriCleave") { lastQCast = Environment.TickCount; } if (orbwalker.ActiveMode.ToString() == "Combo") { lastSpell = null; if (SpellName.Contains("Attack")) { // This should happen in packet too, but just in case :) if (Tiamat.IsReady() && currentTarget.IsValidTarget(Tiamat.Range)) { nextSpell = null; useTiamat = true; } else if (Hydra.IsReady() && currentTarget.IsValidTarget(Hydra.Range)) { nextSpell = null; useTiamat = true; } } else if (SpellName == "RivenTriCleave") { nextSpell = null; lastSpell = Skills[0]; if (!Config.SubMenu("Misc").Item("DCFix").GetValue()) CancelAnimation(); if (myChamp.Distance(currentTarget.ServerPosition) + currentTarget.BoundingRadius < myChamp.AttackRange + myChamp.BoundingRadius) { nextSpell = null; UseAttack = true; return; } if (Skills[1].IsReady() && currentTarget.IsValidTarget(Skills[1].Range)) nextSpell = Skills[1]; else { nextSpell = null; UseAttack = true; } } else if (SpellName == "RivenMartyr") { // Cancel W animation with Q if (Skills[0].IsReady()) { nextSpell = null; Utility.DelayAction.Add(175, delegate { nextSpell = Skills[0]; }); } else { nextSpell = null; UseAttack = true; } } else if (SpellName == "ItemTiamatCleave") { // Cancel tiamat animation with W or Q if (Skills[1].IsReady() && currentTarget.IsValidTarget(Skills[1].Range)) nextSpell = Skills[1]; else if (Skills[0].IsReady() && currentTarget.IsValidTarget(Skills[0].Range)) nextSpell = Skills[0]; } else if (SpellName == "RivenFengShuiEngine") { ultiOn = true; //Cast tiamat to cancel R animation if target is in range, otherwise Q or E if (Tiamat.IsReady() && currentTarget.IsValidTarget(Tiamat.Range)) { nextSpell = null; useTiamat = true; } else if (Hydra.IsReady() && currentTarget.IsValidTarget(Hydra.Range)) { nextSpell = null; useTiamat = true; } else if (Skills[0].IsReady() && currentTarget.IsValidTarget(Skills[0].Range)) { nextSpell = Skills[0]; } else if (Skills[2].IsReady()) { nextSpell = Skills[2]; } } } } } private static void GapClose(Obj_AI_Base target) { bool useE = Skills[2].IsReady(); bool useQ = Skills[0].IsReady() && qCount < 2 && Config.SubMenu("ComboS").Item("UseQGapClose").GetValue(); if (lastGapClose + 300 > Environment.TickCount && lastGapClose != 0) return; lastGapClose = Environment.TickCount; float aRange = myChamp.AttackRange + myChamp.BoundingRadius + target.BoundingRadius; float eRange = aRange + Skills[2].Range; float qRange = Skills[0].Range + aRange; float eqRange = Skills[0].Range + Skills[2].Range; float distance = myChamp.Distance(target.ServerPosition); if (distance < aRange) return; nextSpell = null; useTiamat = false; UseAttack = true; if (Ghostblade.IsReady()) Ghostblade.Cast(); if (useQ && qCount < 2 && Skills[0].IsReady() && qRange > distance && !Skills[2].IsReady()) { double noRComboDmg = DamageCalcNoR(target); if (Skills[3].IsReady() && !ultiReady && noRComboDmg < target.Health && Config.SubMenu("ComboS").Item("UseUlti").GetValue()) { Skills[3].Cast(); } Skills[0].Cast(target.ServerPosition, true); } else if (Skills[2].IsReady() && eRange > distance + aRange) { PredictionOutput pred = Prediction.GetPrediction(target, 0, 0, 1450); Skills[2].Cast(pred.CastPosition); } else if (useQ && Skills[2].IsReady() && Skills[0].IsReady() && eqRange + aRange > distance) { PredictionOutput pred = Prediction.GetPrediction(target, 0, 0, 1450); Skills[2].Cast(pred.CastPosition); } } private static void KillSecure() { foreach (Obj_AI_Hero hero in ObjectManager.Get()) { if (hero.Team != myChamp.Team && !hero.IsDead && hero.IsVisible) { if (ultiReady && Config.SubMenu("KS").Item("KillStealR").GetValue() && hero.IsValidTarget(Skills[3].Range - 30) && GetRDamage(hero) - 20 >= hero.Health && !Config.SubMenu("KS").SubMenu("NoRKS").Item(hero.ChampionName).GetValue()) { Skills[3].Cast(hero, aoe: true); IsKSing = false; } else if (Config.SubMenu("KS").Item("KillStealQ").GetValue() && Skills[0].IsReady() && hero.IsValidTarget(Skills[0].Range) && GetQDamage(hero) - 10 >= hero.Health) { Skills[0].Cast(hero.ServerPosition, true); } else if (Config.SubMenu("KS").Item("KillStealW").GetValue() && Skills[1].IsReady() && hero.IsValidTarget(Skills[1].Range) && GetWDamage(hero) - 10 >= hero.Health) { Skills[1].Cast(); } else if (Config.SubMenu("KS").Item("KillStealT").GetValue() && (Tiamat.IsReady() || Hydra.IsReady()) && hero.IsValidTarget(Tiamat.Range) && myChamp.GetItemDamage(hero, Damage.DamageItems.Tiamat) >= hero.Health) { if (Tiamat.IsReady()) Tiamat.Cast(); if (Hydra.IsReady()) Hydra.Cast(); } else if (!ultiReady && !ultiOn && Config.SubMenu("KS").Item("KillStealR").GetValue() && Config.SubMenu("KS").Item("KillStealRActivate").GetValue() && hero.IsValidTarget(Skills[3].Range - 30) && GetRDamage(hero) - 20 >= hero.Health && orbwalker.ActiveMode.ToString() != "Combo") { IsKSing = true; Skills[3].Cast(); } } } } } }