Jin


SUBMITTED BY: Alerand

DATE: May 7, 2016, 10:52 a.m.

FORMAT: Text only

SIZE: 19.2 kB

HITS: 11098

  1. #region
  2. using System;
  3. using System.Drawing;
  4. using System.Linq;
  5. using DetuksSharp;
  6. using LeagueSharp;
  7. using LeagueSharp.Common;
  8. #endregion
  9. namespace Marksman.Champions
  10. {
  11. internal class Jinx : Champion
  12. {
  13. public Spell E;
  14. public Spell Q;
  15. public Spell R;
  16. public Spell W;
  17. public Jinx()
  18. {
  19. Q = new Spell(SpellSlot.Q);
  20. W = new Spell(SpellSlot.W, 1500f);
  21. E = new Spell(SpellSlot.E, 900f);
  22. R = new Spell(SpellSlot.R, 25000f);
  23. W.SetSkillshot(0.6f, 60f, 3300f, true, SkillshotType.SkillshotLine);
  24. E.SetSkillshot(0.7f, 120f, 1750f, false, SkillshotType.SkillshotCircle);
  25. R.SetSkillshot(0.6f, 140f, 1700f, false, SkillshotType.SkillshotLine);
  26. Utils.Utils.PrintMessage("Jinx loaded.");
  27. }
  28. public float QAddRange
  29. {
  30. get { return 50 + 25*ObjectManager.Player.Spellbook.GetSpell(SpellSlot.Q).Level; }
  31. }
  32. private static bool FishBoneActive
  33. {
  34. get { return ObjectManager.Player.AttackRange > 565f; }
  35. }
  36. private static int PowPowStacks
  37. {
  38. get
  39. {
  40. return
  41. ObjectManager.Player.Buffs.Where(buff => buff.DisplayName.ToLower() == "jinxqramp")
  42. .Select(buff => buff.Count)
  43. .FirstOrDefault();
  44. }
  45. }
  46. public override void Drawing_OnDraw(EventArgs args)
  47. {
  48. Spell[] spellList = {W};
  49. var drawQbound = GetValue<Circle>("DrawQBound");
  50. foreach (var spell in spellList)
  51. {
  52. var menuItem = GetValue<Circle>("Draw" + spell.Slot);
  53. if (menuItem.Active)
  54. {
  55. Render.Circle.DrawCircle(ObjectManager.Player.Position, spell.Range, menuItem.Color);
  56. }
  57. }
  58. if (drawQbound.Active)
  59. {
  60. if (FishBoneActive)
  61. {
  62. Render.Circle.DrawCircle(
  63. ObjectManager.Player.Position, 525f + ObjectManager.Player.BoundingRadius + 65f,
  64. drawQbound.Color);
  65. }
  66. else
  67. {
  68. Render.Circle.DrawCircle(
  69. ObjectManager.Player.Position,
  70. 525f + ObjectManager.Player.BoundingRadius + 65f + QAddRange + 20f, drawQbound.Color);
  71. }
  72. }
  73. }
  74. public override void Game_OnGameUpdate(EventArgs args)
  75. {
  76. if (Q.IsReady() && GetValue<bool>("SwapDistance") && DeathWalker.CurrentMode == DeathWalker.Mode.Combo)
  77. {
  78. var activeQ = ObjectManager.Player.Spellbook.GetSpell(SpellSlot.Q).Level*25 + 650;
  79. var t = TargetSelector.GetTarget(activeQ, TargetSelector.DamageType.Physical);
  80. if (t.IsValidTarget() && ObjectManager.Player.Distance(t) > DeathWalker.getRealAutoAttackRange(null) + 65)
  81. {
  82. if (!FishBoneActive)
  83. {
  84. Q.Cast();
  85. DeathWalker.ForcedTarget = t;
  86. return;
  87. }
  88. }
  89. if (!t.IsValidTarget() ||
  90. ObjectManager.Player.Distance(t) < DeathWalker.getRealAutoAttackRange(null) + 65)
  91. {
  92. if (FishBoneActive)
  93. {
  94. Q.Cast();
  95. return;
  96. }
  97. }
  98. }
  99. var autoEi = GetValue<bool>("AutoEI");
  100. var autoEs = GetValue<bool>("AutoES");
  101. var autoEd = GetValue<bool>("AutoED");
  102. if (autoEs || autoEi || autoEd)
  103. {
  104. foreach (
  105. var enemy in ObjectManager.Get<Obj_AI_Hero>().Where(enemy => enemy.IsValidTarget(E.Range - 150)))
  106. {
  107. if (autoEs && E.IsReady() && enemy.HasBuffOfType(BuffType.Slow))
  108. {
  109. var castPosition =
  110. Prediction.GetPrediction(
  111. new PredictionInput
  112. {
  113. Unit = enemy,
  114. Delay = 0.7f,
  115. Radius = 120f,
  116. Speed = 1750f,
  117. Range = 900f,
  118. Type = SkillshotType.SkillshotCircle
  119. }).CastPosition;
  120. if (GetSlowEndTime(enemy) >= (Game.Time + E.Delay + 0.5f))
  121. {
  122. E.Cast(castPosition);
  123. }
  124. }
  125. if (autoEi && E.IsReady() &&
  126. (enemy.HasBuffOfType(BuffType.Stun) || enemy.HasBuffOfType(BuffType.Snare) ||
  127. enemy.HasBuffOfType(BuffType.Charm) || enemy.HasBuffOfType(BuffType.Fear) ||
  128. enemy.HasBuffOfType(BuffType.Taunt) || enemy.HasBuff("zhonyasringshield") ||
  129. enemy.HasBuff("Recall")))
  130. {
  131. E.CastIfHitchanceEquals(enemy, HitChance.High);
  132. }
  133. if (autoEd && E.IsReady() && enemy.IsDashing())
  134. {
  135. E.CastIfHitchanceEquals(enemy, HitChance.Dashing);
  136. }
  137. }
  138. }
  139. if (GetValue<KeyBind>("CastR").Active && R.IsReady())
  140. {
  141. var t = TargetSelector.GetTarget(1500, TargetSelector.DamageType.Physical);
  142. if (t.IsValidTarget())
  143. {
  144. if (ObjectManager.Player.GetSpellDamage(t, SpellSlot.R) > t.Health && !t.IsZombie)
  145. {
  146. //R.Cast(target);
  147. R.CastIfHitchanceEquals(t, HitChance.High, false);
  148. }
  149. }
  150. }
  151. /*
  152. if (GetValue<bool>("SwapQ") && FishBoneActive &&
  153. (LaneClearActive ||
  154. (HarassActive && TargetSelector.GetTarget(675f + QAddRange, TargetSelector.DamageType.Physical) == null)))
  155. {
  156. Q.Cast();
  157. }
  158. */
  159. if ((!ComboActive && !HarassActive) || !DeathWalker.canMove())
  160. {
  161. return;
  162. }
  163. var useQ = GetValue<bool>("UseQ" + (ComboActive ? "C" : "H"));
  164. var useW = GetValue<bool>("UseW" + (ComboActive ? "C" : "H"));
  165. var useR = GetValue<bool>("UseRC");
  166. if (useW && W.IsReady())
  167. {
  168. var t = TargetSelector.GetTarget(W.Range, TargetSelector.DamageType.Physical);
  169. var minW = GetValue<Slider>("MinWRange").Value;
  170. if (t.IsValidTarget() && GetRealDistance(t) >= minW)
  171. {
  172. if (W.Cast(t) == Spell.CastStates.SuccessfullyCasted)
  173. {
  174. return;
  175. }
  176. }
  177. }
  178. /*
  179. if (useQ)
  180. {
  181. foreach (var t in
  182. ObjectManager.Get<Obj_AI_Hero>()
  183. .Where(t => t.IsValidTarget(GetRealPowPowRange(t) + QAddRange + 20f)))
  184. {
  185. var swapDistance = GetValue<bool>("SwapDistance");
  186. var swapAoe = GetValue<bool>("SwapAOE");
  187. var distance = GetRealDistance(t);
  188. var powPowRange = GetRealPowPowRange(t);
  189. if (swapDistance && Q.IsReady())
  190. {
  191. if (distance > powPowRange && !FishBoneActive)
  192. {
  193. if (Q.Cast())
  194. {
  195. return;
  196. }
  197. }
  198. else if (distance < powPowRange && FishBoneActive)
  199. {
  200. if (Q.Cast())
  201. {
  202. return;
  203. }
  204. }
  205. }
  206. if (swapAoe && Q.IsReady())
  207. {
  208. if (distance > powPowRange && PowPowStacks > 2 && !FishBoneActive && CountEnemies(t, 150) > 1)
  209. {
  210. if (Q.Cast())
  211. {
  212. return;
  213. }
  214. }
  215. }
  216. }
  217. }
  218. */
  219. if (useR && R.IsReady())
  220. {
  221. var checkRok = GetValue<bool>("ROverKill");
  222. var minR = GetValue<Slider>("MinRRange").Value;
  223. var maxR = GetValue<Slider>("MaxRRange").Value;
  224. var t = TargetSelector.GetTarget(maxR, TargetSelector.DamageType.Physical);
  225. if (t.IsValidTarget())
  226. {
  227. var distance = GetRealDistance(t);
  228. if (!checkRok)
  229. {
  230. if (ObjectManager.Player.GetSpellDamage(t, SpellSlot.R, 1) > t.Health && !t.IsZombie)
  231. {
  232. R.CastIfHitchanceEquals(t, HitChance.High, false);
  233. //if (R.Cast(t) == Spell.CastStates.SuccessfullyCasted) { }
  234. }
  235. }
  236. else if (distance > minR)
  237. {
  238. var aDamage = ObjectManager.Player.GetAutoAttackDamage(t);
  239. var wDamage = ObjectManager.Player.GetSpellDamage(t, SpellSlot.W);
  240. var rDamage = ObjectManager.Player.GetSpellDamage(t, SpellSlot.R);
  241. var powPowRange = GetRealPowPowRange(t);
  242. if (distance < (powPowRange + QAddRange) && !(aDamage*3.5 > t.Health))
  243. {
  244. if (!W.IsReady() || !(wDamage > t.Health) || W.GetPrediction(t).CollisionObjects.Count > 0)
  245. {
  246. if (CountAlliesNearTarget(t, 500) <= 3)
  247. {
  248. if (rDamage > t.Health && !t.IsZombie/*&& !ObjectManager.Player.IsAutoAttacking &&
  249. !ObjectManager.Player.IsChanneling*/)
  250. {
  251. R.CastIfHitchanceEquals(t, HitChance.High, false);
  252. //if (R.Cast(t) == Spell.CastStates.SuccessfullyCasted) { }
  253. }
  254. }
  255. }
  256. }
  257. else if (distance > (powPowRange + QAddRange))
  258. {
  259. if (!W.IsReady() || !(wDamage > t.Health) || distance > W.Range ||
  260. W.GetPrediction(t).CollisionObjects.Count > 0)
  261. {
  262. if (CountAlliesNearTarget(t, 500) <= 3)
  263. {
  264. if (rDamage > t.Health && !t.IsZombie/*&& !ObjectManager.Player.IsAutoAttacking &&
  265. !ObjectManager.Player.IsChanneling*/)
  266. {
  267. R.CastIfHitchanceEquals(t, HitChance.High, false);
  268. //if (R.Cast(t) == Spell.CastStates.SuccessfullyCasted) { }
  269. }
  270. }
  271. }
  272. }
  273. }
  274. }
  275. }
  276. }
  277. public override void DeathWalker_AfterAttack(AttackableUnit unit, AttackableUnit target)
  278. {
  279. if ((ComboActive || HarassActive) && unit.IsMe && (target is Obj_AI_Hero))
  280. {
  281. var useQ = GetValue<bool>("UseQ" + (ComboActive ? "C" : "H"));
  282. var useW = GetValue<bool>("UseW" + (ComboActive ? "C" : "H"));
  283. if (useW && W.IsReady())
  284. {
  285. var t = TargetSelector.GetTarget(W.Range, TargetSelector.DamageType.Physical);
  286. var minW = GetValue<Slider>("MinWRange").Value;
  287. if (t.IsValidTarget() && GetRealDistance(t) >= minW)
  288. {
  289. if (W.Cast(t) == Spell.CastStates.SuccessfullyCasted)
  290. {
  291. return;
  292. }
  293. }
  294. }
  295. if (useQ)
  296. {
  297. foreach (var t in
  298. ObjectManager.Get<Obj_AI_Hero>()
  299. .Where(t => t.IsValidTarget(GetRealPowPowRange(t) + QAddRange + 20f)))
  300. {
  301. var swapDistance = GetValue<bool>("SwapDistance");
  302. var swapAoe = GetValue<bool>("SwapAOE");
  303. var distance = GetRealDistance(t);
  304. var powPowRange = GetRealPowPowRange(t);
  305. if (swapDistance && Q.IsReady())
  306. {
  307. if (distance > powPowRange && !FishBoneActive)
  308. {
  309. if (Q.Cast())
  310. {
  311. return;
  312. }
  313. }
  314. else if (distance < powPowRange && FishBoneActive)
  315. {
  316. if (Q.Cast())
  317. {
  318. return;
  319. }
  320. }
  321. }
  322. if (swapAoe && Q.IsReady())
  323. {
  324. if (distance > powPowRange && PowPowStacks > 2 && !FishBoneActive &&
  325. CountEnemies(t, 150) > 1)
  326. {
  327. if (Q.Cast())
  328. {
  329. return;
  330. }
  331. }
  332. }
  333. }
  334. }
  335. }
  336. }
  337. private static int CountEnemies(Obj_AI_Base target, float range)
  338. {
  339. return
  340. ObjectManager.Get<Obj_AI_Hero>()
  341. .Count(
  342. hero =>
  343. hero.IsValidTarget() && hero.Team != ObjectManager.Player.Team &&
  344. hero.ServerPosition.Distance(target.ServerPosition) <= range);
  345. }
  346. private int CountAlliesNearTarget(Obj_AI_Base target, float range)
  347. {
  348. return
  349. ObjectManager.Get<Obj_AI_Hero>()
  350. .Count(
  351. hero =>
  352. hero.Team == ObjectManager.Player.Team &&
  353. hero.ServerPosition.Distance(target.ServerPosition) <= range);
  354. }
  355. private static float GetRealPowPowRange(GameObject target)
  356. {
  357. return 525f + ObjectManager.Player.BoundingRadius + target.BoundingRadius;
  358. }
  359. private static float GetRealDistance(GameObject target)
  360. {
  361. return ObjectManager.Player.Position.Distance(target.Position) + ObjectManager.Player.BoundingRadius +
  362. target.BoundingRadius;
  363. }
  364. private static float GetSlowEndTime(Obj_AI_Base target)
  365. {
  366. return
  367. target.Buffs.OrderByDescending(buff => buff.EndTime - Game.Time)
  368. .Where(buff => buff.Type == BuffType.Slow)
  369. .Select(buff => buff.EndTime)
  370. .FirstOrDefault();
  371. }
  372. public override bool ComboMenu(Menu config)
  373. {
  374. config.AddItem(new MenuItem("UseQC" + Id, "Use Q").SetValue(true));
  375. config.AddItem(new MenuItem("UseWC" + Id, "Use W").SetValue(true));
  376. config.AddItem(new MenuItem("UseRC" + Id, "Use R").SetValue(true));
  377. return true;
  378. }
  379. public override bool HarassMenu(Menu config)
  380. {
  381. config.AddItem(new MenuItem("UseQH" + Id, "Use Q").SetValue(true));
  382. config.AddItem(new MenuItem("UseWH" + Id, "Use W").SetValue(false));
  383. return true;
  384. }
  385. public override bool LaneClearMenu(Menu config)
  386. {
  387. config.AddItem(new MenuItem("SwapQ" + Id, "Always swap to Minigun").SetValue(false));
  388. return true;
  389. }
  390. public override bool MiscMenu(Menu config)
  391. {
  392. config.AddItem(new MenuItem("SwapDistance" + Id, "Swap Q for distance").SetValue(true));
  393. config.AddItem(new MenuItem("SwapAOE" + Id, "Swap Q for AOE").SetValue(false));
  394. config.AddItem(new MenuItem("MinWRange" + Id, "Min W range").SetValue(new Slider(525 + 65*2, 0, 1200)));
  395. config.AddItem(new MenuItem("AutoEI" + Id, "Auto-E on immobile").SetValue(true));
  396. config.AddItem(new MenuItem("AutoES" + Id, "Auto-E on slowed").SetValue(true));
  397. config.AddItem(new MenuItem("AutoED" + Id, "Auto-E on dashing").SetValue(false));
  398. config.AddItem(
  399. new MenuItem("CastR" + Id, "Cast R (2000 Range)").SetValue(
  400. new KeyBind("T".ToCharArray()[0], KeyBindType.Press)));
  401. config.AddItem(new MenuItem("ROverKill" + Id, "Check R Overkill").SetValue(true));
  402. config.AddItem(new MenuItem("MinRRange" + Id, "Min R range").SetValue(new Slider(300, 0, 1500)));
  403. config.AddItem(new MenuItem("MaxRRange" + Id, "Max R range").SetValue(new Slider(1700, 0, 4000)));
  404. return true;
  405. }
  406. public override bool DrawingMenu(Menu config)
  407. {
  408. config.AddItem(
  409. new MenuItem("DrawQBound" + Id, "Draw Q bound").SetValue(
  410. new Circle(true, Color.FromArgb(100, 255, 0, 0))));
  411. config.AddItem(
  412. new MenuItem("DrawW" + Id, "W range").SetValue(new Circle(false, Color.CornflowerBlue)));
  413. return true;
  414. }
  415. public override bool ExtrasMenu(Menu config)
  416. {
  417. return true;
  418. }
  419. }
  420. }

comments powered by Disqus