Advertisement
Guest User

Untitled

a guest
Apr 21st, 2018
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.56 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace gbf.Scripts.Chi {
  8. public class WaterVaruna : QuestScript {
  9. static readonly string[] Touchmark = new [] {
  10. "3000_1011",
  11. "3000_1012",
  12. "3000_1013",
  13. "3000_1014",
  14. "3000_1015",
  15. "3000_1016",
  16. "3000_1017",
  17. "3000_1018",
  18. "3000_1019"
  19. };
  20.  
  21. [Setting(Default: true, Label: "Use Debuffs")]
  22. public ScriptSetting<bool> UseDebuffs;
  23. [Setting(Default: 55, Label: "Pot character(s) below $ % hp")]
  24. public ScriptSetting<float> CharacterPotThreshold;
  25. [Setting(Default: 60, Label: "Pot if party below $ % hp")]
  26. public ScriptSetting<float> PartyPotThreshold;
  27. [Setting(Default: 3100000)]
  28. public ScriptSetting<float> ApproximateTurnDamage;
  29. [Setting(Default: 6500000)]
  30. public ScriptSetting<float> ApproximateFullchainDamage;
  31. [Setting(Default: true)]
  32. public ScriptSetting<bool> AutoCallForBackup;
  33. [Setting(Default: true)]
  34. public ScriptSetting<bool> CutTriggers;
  35. [Setting(Default: false, Label: "Request backup from Twitter")]
  36. public ScriptSetting<bool> TweetBackup;
  37. [Setting(Label: "Target enemy #: $", Default: 0)]
  38. public ScriptSetting<int> TargetEnemyNumber;
  39. [Setting(Default: true)]
  40. public ScriptSetting<bool> Clarity; //will spam clarity off CD
  41. [Setting(Default: false)]
  42. public ScriptSetting<bool> EnableBonito;
  43. [Setting(Default: false)]
  44. public ScriptSetting<bool> EnableVaruna;
  45. [Setting(Default: true)]
  46. public ScriptSetting<bool> GWPots;
  47. [Setting(Default: false)]
  48. public ScriptSetting<bool> FourthPursuit;
  49.  
  50.  
  51.  
  52.  
  53. bool HaveStickered, HaveCalledForBackup;
  54. float LastTurnStartBossHpPercent;
  55. protected int RequestingBackup;
  56. public const string BossCutUp = "1019_0_90";
  57. public const string WhyDoesThisThingHaveTwoBuffs = "1484";
  58.  
  59.  
  60. protected bool TappedTrigger;
  61.  
  62. public WaterVaruna () {
  63. }
  64.  
  65. public override string[] GetSummonSelectors () {
  66. var result = new List<string>();
  67. if (EnableVaruna) {
  68. // Varuna MLB
  69. result.Add("div.btn-supporter[data-supporter-max=\"1\"] div.prt-summon-image[data-image=\"2040100000\"]");
  70. // Varuna
  71. result.Add("div.btn-supporter div.prt-summon-image[data-image=\"2040100000\"]");
  72. }
  73.  
  74. // Europa MLB
  75. result.Add("div.btn-supporter[data-supporter-max=\"1\"] div.prt-summon-image[data-image=\"2040225000\"]");
  76. // Europa
  77. result.Add("div.btn-supporter div.prt-summon-image[data-image=\"2040225000\"]");
  78.  
  79. if (EnableBonito) {
  80. // Bonito MLB
  81. result.Add(
  82. "div.btn-supporter[data-supporter-max=\"1\"] div.prt-summon-image[data-image=\"2040167000\"]"
  83. );
  84. // Bonito
  85. result.Add(
  86. "div.btn-supporter div.prt-summon-image[data-image=\"2040167000\"]"
  87. );
  88. }
  89.  
  90. // Macula MLB
  91. result.Add(
  92. "div.btn-supporter[data-supporter-max=\"1\"] div.prt-summon-image[data-image=\"2040002000\"]"
  93. );
  94. // Macula
  95. result.Add(
  96. "div.btn-supporter div.prt-summon-image[data-image=\"2040002000\"]"
  97. );
  98.  
  99. return result.ToArray();
  100. }
  101.  
  102. private List<int> WhoNeedsHealing () {
  103. var result = new List<int>();
  104. for (var i = 0; i < CombatState.party.Length; i++) {
  105. if (CombatState.party[i].hp / (float)CombatState.party[i].hpMax * 100 <= CharacterPotThreshold)
  106. result.Add(i);
  107. }
  108.  
  109. return result;
  110. }
  111.  
  112. private List<int> WhoNeedsClearing () {
  113. var result = new List<int>();
  114. for (var i = 0; i < CombatState.party.Length; i++) {
  115. if (CombatState.party[i].IsDebuffed(Touchmark))
  116. result.Add(i);
  117. }
  118.  
  119. return result;
  120. }
  121.  
  122. private async Task GetPotions () {
  123. if (!HaveStickered) {
  124. HaveStickered = true;
  125. await this.AutoSticker();
  126. }
  127.  
  128. }
  129.  
  130. private bool ShouldPartyHeal {
  131. get {
  132. var wnh = WhoNeedsHealing();
  133. return (wnh.Count > 1) || (AverageHp <= PartyPotThreshold);
  134. }
  135. }
  136.  
  137. private async Task AutoHeal () {
  138. var wnc = WhoNeedsClearing();
  139. if (wnc.Count >= 1) {
  140. if (!await TryUseAbility("Clarity"))
  141. if (!await TryUseAbility("White Heal"))
  142. await TryUseSummon("Baal");
  143. }
  144.  
  145. if (AverageHp < 91)
  146. if (await TryUseAbility("And the Seasons Go On"))
  147. await WaitForIdle();
  148.  
  149. if (AverageHp < 91)
  150. if (await TryUseAbility("Panacea III"))
  151. await WaitForIdle();
  152.  
  153. if (AverageHp < 91)
  154. if (await TryUseSummon("Lucifer"))
  155. await WaitForIdle();
  156.  
  157. if (AverageHp < 95)
  158. if (await TryUseAbility("White Heal"))
  159. await WaitForIdle();
  160.  
  161. if (ShouldPartyHeal) {
  162. await GetPotions();
  163. if (!await this.TryUseBluePotion(true))
  164. if (GWPots) {
  165. await this.TryUseGwBluePotion(true);
  166. await WaitForIdle();
  167. }
  168. }
  169.  
  170. var wnh = WhoNeedsHealing();
  171. if (wnh.Count == 1) {
  172. if (!await TryUseAbility("Panacea III"))
  173. await this.TryUseGreenPotion(wnh[0], true);
  174. wnh = WhoNeedsHealing();
  175. }
  176.  
  177. await this.CloseHealWindow();
  178. }
  179.  
  180. private bool YodaHasShroud {
  181. get {
  182. return Party.Any(pm => pm.conditions.Any(c => Statuses.TripleShrouded.Contains(c)));
  183. }
  184. }
  185.  
  186. private float AverageHp {
  187. get {
  188. return Party.Average(pm => pm.hp / (float)pm.hpMax * 100f);
  189. }
  190. }
  191.  
  192. private async Task AutoSummon (bool isChainReady) {
  193. if (isChainReady)
  194. if (await TryUseSummons("Kaguya", "Bahamut"))
  195. return;
  196.  
  197. var boss = CombatState.enemies[0];
  198. if (
  199. (boss.mode == EnemyModes.Break) &&
  200. !(
  201. boss.conditions.Contains(Statuses.BreakKeepTime) &&
  202. boss.conditions.Contains(Statuses.BreakKeepDamage)
  203. )
  204. )
  205. if (await TryUseSummon("Macula Marius"))
  206. return;
  207.  
  208. if (!CombatState.party.Any(pm => pm.IsBuffed(Statuses.FireCarby, Statuses.LilyFireCut)))
  209. if (await TryUseSummon("Garnet Carbuncle"))
  210. return;
  211.  
  212. if (!CombatState.party.Any(pm => pm.conditions.Contains(Statuses.WaterCarby)))
  213. if (await TryUseSummon("Aquamarine Carbuncle"))
  214. return;
  215.  
  216. if (CombatState.party.All(pm => pm.ougi < 100))
  217. if (await TryUseSummon("Bonito"))
  218. return;
  219.  
  220. if (Party.Sum(pm => pm.ougi) >= 340)
  221. await TryUseSummon("Bahamut");
  222.  
  223. await TryUseSummon("Leviathan Omega");
  224.  
  225. // await TryUseSummon("Varuna");
  226. }
  227.  
  228. EnemyState Boss {
  229. get {
  230.  
  231. return Enemies.First();
  232. }
  233. }
  234.  
  235. private float PartyDamageCutPercentage {
  236. get {
  237. return (from pm in Party select GetDamageCutPercentage(pm)).Min();
  238. }
  239. }
  240.  
  241. private float GetDamageCutPercentage (PartyMemberState pm) {
  242. var result = 0;
  243.  
  244. if (pm.IsBuffed(Statuses.UnoFullCut))
  245. result = 100;
  246. else if (pm.IsBuffed(Statuses.UnoFullCut))
  247. result = 77;
  248. else if (pm.IsBuffed(Statuses.Athena))
  249. result = 30;
  250.  
  251. if (pm.IsBuffed(Statuses.LilyFireCut))
  252. result += 70;
  253.  
  254. if (pm.IsBuffed(Statuses.FireCarby))
  255. result += 50;
  256. else if (pm.IsBuffed(Statuses.WeakFireCarby))
  257. result += 25;
  258.  
  259. return result;
  260. }
  261.  
  262. public override async Task<bool> Step () {
  263. await WaitForIdle();
  264.  
  265. var target = (await ScriptUtil.PickTarget(this)).GetValueOrDefault(0);
  266. if (TargetEnemyNumber > 0)
  267. {
  268. await TrySetTarget(TargetEnemyNumber);
  269. }
  270.  
  271. if (!CombatState.canAct)
  272. return true;
  273.  
  274. if (CombatState.turn == 1) {
  275. TappedTrigger = false;
  276. }
  277.  
  278. if (CombatState.enemies[0].conditions.Contains("1019_0_90") ||
  279. CombatState.enemies[0].conditions.Contains("1484")) {
  280. if (!TappedTrigger) {
  281. await WaitForIdle();
  282. await SetOugiStatus(false);
  283. await WaitForIdle();
  284. await TryClickAttack();
  285. await Pause(30000);
  286. await WaitForIdle();
  287. TappedTrigger = true;
  288. return true;
  289. }
  290. if (await TryUseAbility("Dispel") ||
  291. await TryUseAbility("Dispel Deluge")) {
  292. await WaitForIdle();
  293. return true;
  294. }
  295. await Log("Damage cut buff detected, waiting for dispel...");
  296. await Engine.SetStatusMessage("Damage cut buff detected, waiting for dispel...");
  297. return true;
  298. }
  299.  
  300. var turnStartBossHpPercent = Boss.hp / (float)Boss.hpMax * 100;
  301.  
  302. if (CombatState.turn == 1)
  303. {
  304. HaveStickered = HaveCalledForBackup = false;
  305. LastTurnStartBossHpPercent = turnStartBossHpPercent;
  306. // HACK
  307.  
  308. if (AutoCallForBackup)
  309. {
  310. HaveCalledForBackup = true;
  311. await this.RequestBackupAndWait(1, 1, true, true, true);
  312.  
  313. }
  314. if (TweetBackup)
  315. {
  316. await this.TweetBackup();
  317. }
  318. await TryUseSummon("Leviathan Omega");
  319. }
  320.  
  321. var readyToChain = Party.Count(pm => pm.ougi >= 100);
  322. var almostReady = Party.Count(pm => pm.ougi <= 80);
  323. if (
  324. Party.All(pm => pm.ougi <= 70) ||
  325. (almostReady <= 2) && (almostReady > 0)
  326. )
  327. if (await TryUseAbility("Wings Shall Deliver You"))
  328. await WaitForIdle();
  329.  
  330. if (
  331. Party.All(pm => pm.ougi <= 70) ||
  332. (almostReady <= 2) && (almostReady > 0)
  333. )
  334. if (await TryUseAbility("Battleplan: Crescent Moon"))
  335. await WaitForIdle();
  336.  
  337. var isChainReady = this.IsChainReady(fourthPursuit: FourthPursuit);
  338.  
  339. var veilCount = Party.Count(pm => pm.conditions.Contains(Statuses.Veil));
  340.  
  341. if (veilCount < 4) {
  342. if (!await TryUseSummon("Apollo")) {
  343. await TryUseAbilities(null, UseAbilitiesMode.StopAfterFirstSuccess, "Loengard +", "Veil");
  344. }
  345. }
  346.  
  347. await AutoHeal();
  348.  
  349. await AutoSummon(isChainReady);
  350. if (UseDebuffs)
  351. {
  352. await TryUseAbilities(
  353. "Defense Breach",
  354. "Rain of Arrows III",
  355. "Fair Trick +",
  356. "Miserable Mist",
  357. "Unpredictable",
  358. "Dark Haze",
  359. "Battleplan: Crane Down ++",
  360. "Pastoral Dance: Bizen",
  361. "Fool You Thrice",
  362. "Blind",
  363. "Niflheim"
  364.  
  365. );
  366. }
  367. await TryUseAbilities(
  368. "Battleplan: Surround",
  369. "I Miss You So Much...",
  370. "Gammadion Cross",
  371. "Aether Blast III",
  372. "Frozen Gale"
  373. );
  374.  
  375. await TryUseAbility("Fighting Spirit", pm => pm.ougi <= 80);
  376.  
  377. if (Clarity)
  378. {
  379. await TryUseAbilities(
  380. "Peace of Mind",
  381. "Clarity"
  382. );
  383. }
  384.  
  385. if (!YodaHasShroud) {
  386. await TryUseAbility("Awakening +");
  387. await TryUseAbility("Perpetual Rotation");
  388. }
  389.  
  390. if (!this.IsChainReady(fourthPursuit: FourthPursuit)) {
  391. await TryUseAbility("Chaser");
  392. }
  393.  
  394. if (
  395. !Boss.conditions.Contains(Statuses.Gravity) ||
  396. // Dispel ATK up
  397. Boss.conditions.Any(c => c.StartsWith("1001_4"))
  398. )
  399. await TryUseAbility("Carnage");
  400.  
  401. await TryUseAbilities(
  402. (pm) => Boss.recast != Boss.recastMax, UseAbilitiesMode.WaitAfterUseIfPredicate,
  403. "Quadspell", "Stall II", "Stall III", "Closing Dance: Tokiyomi"
  404. );
  405.  
  406. await TryUseAbility("Four-Sky's Sorrow");
  407. await TryUseAbility("Gammadion Cross");
  408. await TryUseAbility("Gammadion Cross");
  409. await TryUseAbility("Gammadion Cross");
  410. await TryUseAbility("Gammadion Cross");
  411.  
  412. if (
  413. (AverageHp <= 50) ||
  414. (
  415. (Boss.hp <= (Boss.hpMax * 0.45f)) &&
  416. (AverageHp <= 80)
  417. )
  418. )
  419. await TryUseAbility("One-Rift's Benediction");
  420.  
  421. await TryUseAbility("Opening Dance: Kagura", pm => pm.conditions.Contains(Statuses.AdventOfSerenity));
  422. await TryUseAbility("Immutable Faith", pm => pm.ougi <= 50);
  423. await TryUseAbility("Frozen Gale +");
  424. await TryUseAbility("Enchanted Lands +", pm => pm.ougi < 80);
  425.  
  426. if (!CombatState.party.Any(pm => pm.IsBuffed(Statuses.FireCarby, Statuses.LilyFireCut))) {
  427. if (await TryUseAbility("Silverfrost Barrier"))
  428. await TryUseAbility("Avirati");
  429. }
  430.  
  431. await WaitForIdle();
  432. isChainReady = this.IsChainReady(fourthPursuit: FourthPursuit);
  433.  
  434. var isParalyzed = Boss.conditions.Contains(Statuses.PurplePara) ||
  435. Boss.conditions.Contains(Statuses.Paralyzed);
  436. var isOugiComing = (
  437. (Boss.recast <= 1) &&
  438. (Boss.mode != EnemyModes.Break)
  439. );
  440.  
  441. var usedSpark = false;
  442. if (!isChainReady && !isOugiComing)
  443. usedSpark = await TryUseAbility("Fleeting Spark");
  444.  
  445. await TryUseAbility("Spiral Spear", pm =>
  446. (usedSpark && (CombatState.turn <= 4)) ||
  447. (Boss.mode == EnemyModes.OD) ||
  448. (usedSpark && (Boss.mode == EnemyModes.Break))
  449. );
  450.  
  451. /*
  452. var silvaMeter =
  453. (from pm in Party
  454. where pm.name == "Silva"
  455. select pm.ougi).FirstOrDefault();
  456.  
  457. var isSilvaReady = (silvaMeter >= 100) && (Party.Count(pm => pm.ougi >= 90) < 3);
  458.  
  459. if (await TryUseAbility("Dead Specimen", pm => pm.ougi < 30))
  460. isSilvaReady = true;
  461.  
  462. if (!isChainReady && isSilvaReady)
  463. await Log("Silva solo ougi");
  464. else if (!isChainReady && shouldOugiHeal)
  465. await Log("Using ougi to heal");
  466.  
  467. var willOugi = isChainReady || shouldOugiHeal || isSilvaReady;
  468. if (willOugi && silvaMeter > 77)
  469. await TryUseAbility("Eagle Eye +");
  470. */
  471.  
  472. await WaitForIdle();
  473. var willOugi = isChainReady;
  474.  
  475. var predictedHealth = Boss.hp - (willOugi ? ApproximateFullchainDamage : ApproximateTurnDamage);
  476. var predictedHealthPercentage = predictedHealth / (float)Boss.hpMax * 100;
  477. var isTriggerComing = (
  478. (LastTurnStartBossHpPercent >= 75) &&
  479. ((predictedHealthPercentage < 75) && (predictedHealthPercentage >= 60))
  480. ) ||
  481. (
  482. (LastTurnStartBossHpPercent >= 50) &&
  483. (predictedHealthPercentage < 50)
  484. ) ||
  485. (
  486. (LastTurnStartBossHpPercent >= 25) &&
  487. ((predictedHealthPercentage < 25) && (predictedHealthPercentage >= 10))
  488. );
  489.  
  490. await Log("hp={0} predicted={1} isTriggerComing={2}", LastTurnStartBossHpPercent, predictedHealthPercentage, isTriggerComing);
  491.  
  492. if (
  493. !isParalyzed &&
  494. (isOugiComing || isTriggerComing && CutTriggers)
  495. ) {
  496. await Log("Cutting for {0}", isTriggerComing ? "trigger" : "ougi");
  497.  
  498. if (
  499. (
  500. (PartyDamageCutPercentage < 100) &&
  501. (isTriggerComing || (Boss.hp <= Boss.hpMax * 0.20f))
  502. ) || (PartyDamageCutPercentage < 60)
  503. ) {
  504. await TryUseAbilities(
  505. null, UseAbilitiesMode.StopAfterFirstSuccess,
  506. "Phalanx III", "Arm the Bastion", "Light Wall Divider"
  507. );
  508. await WaitForIdle();
  509. await TryUseSummon("Athena");
  510. }
  511. }
  512.  
  513. await SetOugiStatus(willOugi);
  514. await WaitForIdle();
  515.  
  516. LastTurnStartBossHpPercent = Boss.hp / (float)Boss.hpMax * 100;
  517. await TryClickAttack();
  518. if (isChainReady)
  519. await OugiRefresh();
  520. else
  521. await AttackRefresh();
  522.  
  523. return true;
  524. }
  525.  
  526. protected override void OnInitialize () {
  527. }
  528. }
  529. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement