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<Circle>().Active)
{
Utility.DrawCircle(currentTarget.ServerPosition, currentTarget.BoundingRadius + 10,
Config.SubMenu("Draw").Item("DrawTarget").GetValue<Circle>().Color, 5);
Utility.DrawCircle(currentTarget.ServerPosition, currentTarget.BoundingRadius + 25,
Config.SubMenu("Draw").Item("DrawTarget").GetValue<Circle>().Color, 6);
Utility.DrawCircle(currentTarget.ServerPosition, currentTarget.BoundingRadius + 45,
Config.SubMenu("Draw").Item("DrawTarget").GetValue<Circle>().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<bool>())
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<Obj_AI_Hero>().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<bool>())
{
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<bool>() && 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<Obj_AI_Base>(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<bool>())
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<bool>())
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<bool>())
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<bool>();
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<bool>())
{
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<Obj_AI_Hero>())
{
if (hero.Team != myChamp.Team && !hero.IsDead && hero.IsVisible)
{
if (ultiReady && Config.SubMenu("KS").Item("KillStealR").GetValue<bool>() &&
hero.IsValidTarget(Skills[3].Range - 30) && GetRDamage(hero) - 20 >= hero.Health &&
!Config.SubMenu("KS").SubMenu("NoRKS").Item(hero.ChampionName).GetValue<bool>())
{
Skills[3].Cast(hero, aoe: true);
IsKSing = false;
}
else if (Config.SubMenu("KS").Item("KillStealQ").GetValue<bool>() && 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<bool>() && Skills[1].IsReady() &&
hero.IsValidTarget(Skills[1].Range) && GetWDamage(hero) - 10 >= hero.Health)
{
Skills[1].Cast();
}
else if (Config.SubMenu("KS").Item("KillStealT").GetValue<bool>() &&
(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<bool>() &&
Config.SubMenu("KS").Item("KillStealRActivate").GetValue<bool>() &&
hero.IsValidTarget(Skills[3].Range - 30) && GetRDamage(hero) - 20 >= hero.Health &&
orbwalker.ActiveMode.ToString() != "Combo")
{
IsKSing = true;
Skills[3].Cast();
}
}
}
}
}
}