Group.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. using Microsoft.Xna.Framework;
  2. using OpenVIII.IGMData.Pool;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. namespace OpenVIII.IGMData.Target
  8. {
  9. public class Group : IGMData.Group.Base
  10. {
  11. #region Fields
  12. private readonly int[] Renzokuken_hits = { 4, 5, 6, 7 };
  13. private IReadOnlyDictionary<int, Func<bool>> CommandFunc;
  14. private bool skipend = false;
  15. #endregion Fields
  16. #region Properties
  17. public Kernel_bin.Blue_magic_Quistis_limit_break BlueMagic { get; private set; }
  18. public Kernel_bin.Battle_Commands Command { get; private set; }
  19. public Combine.KernelItem CombineKernelItem { get; private set; }
  20. public Kernel_bin.Enemy_Attacks_Data EnemyAttack { get; private set; }
  21. public Item_In_Menu Item { get; private set; }
  22. public Kernel_bin.Magic_Data Magic { get; private set; }
  23. public Random RandomTarget { get; private set; } = false;
  24. public int Casts { get; private set; }
  25. public Kernel_bin.Target Target { get; private set; }
  26. private Draw Draw_Pool => (Draw)ITEM[2, 0];
  27. private Enemies TargetEnemies => (Enemies)ITEM[0, 0];
  28. private Party TargetParty => (Party)ITEM[1, 0];
  29. #endregion Properties
  30. #region Methods
  31. public static Group Create(Damageable damageable, bool makesubs = true)
  32. {
  33. const int X1 = 32;
  34. const int Width1 = 400;
  35. const int Height = 140;
  36. const int X2 = X1 + Width1;
  37. const int Width2 = 180;
  38. const int Y = 632 - Height;
  39. Group r = Create<Group>(
  40. Enemies.Create(new Rectangle(X1, Y, Width1, Height)),
  41. Party.Create(new Rectangle(X2, Y, Width2, Height)),
  42. makesubs ? IGMData.Pool.Draw.Create(new Rectangle(X1 + 50, Y - 50, 300, 192), damageable, true) : null);
  43. r.SetDamageable(damageable, null);
  44. r.CONTAINER.Pos = new Rectangle(X1, Y, Width1 + Width2, Height);
  45. r.after();
  46. return r;
  47. }
  48. public override void Draw() => base.Draw();
  49. public override bool Inputs()
  50. {
  51. bool ret = false;
  52. if (Draw_Pool?.Enabled ?? false)
  53. {
  54. TargetEnemies.Cursor_Status |= Cursor_Status.Blinking;
  55. return Draw_Pool.Inputs();
  56. }
  57. else
  58. {
  59. TargetEnemies.Cursor_Status &= ~Cursor_Status.Blinking;
  60. }
  61. if (TargetEnemies.Enabled && (((TargetEnemies.Cursor_Status | TargetParty.Cursor_Status) & Cursor_Status.Enabled) == 0 || !TargetParty.Enabled))
  62. TargetEnemies.Cursor_Status |= Cursor_Status.Enabled;
  63. else if (TargetParty.Enabled && (((TargetEnemies.Cursor_Status | TargetParty.Cursor_Status) & Cursor_Status.Enabled) == 0 || !TargetEnemies.Enabled))
  64. TargetParty.Cursor_Status |= Cursor_Status.Enabled;
  65. if (TargetEnemies.Enabled && ((TargetEnemies.Cursor_Status & Cursor_Status.Enabled) != 0 || TargetEnemies.CONTAINER.Pos.Contains(MouseLocation)))
  66. {
  67. TargetEnemies.Cursor_Status |= Cursor_Status.Enabled;
  68. TargetParty.Cursor_Status &= ~Cursor_Status.Enabled;
  69. ret = TargetEnemies.Inputs();
  70. }
  71. if (!ret && TargetParty.Enabled && ((TargetParty.Cursor_Status & Cursor_Status.Enabled) != 0 || TargetParty.CONTAINER.Pos.Contains(MouseLocation)))
  72. {
  73. TargetParty.Cursor_Status |= Cursor_Status.Enabled;
  74. TargetEnemies.Cursor_Status &= ~Cursor_Status.Enabled;
  75. ret = TargetParty.Inputs();
  76. }
  77. if (!ret)
  78. {
  79. Cursor_Status = Cursor_Status.Hidden | Cursor_Status.Static | Cursor_Status.Enabled;
  80. skipdata = true;
  81. ret = base.Inputs();
  82. skipdata = false;
  83. }
  84. return ret;
  85. }
  86. public override bool Inputs_CANCEL()
  87. {
  88. Hide();
  89. return true;
  90. }
  91. public override bool Inputs_OKAY()
  92. {
  93. base.Inputs_OKAY();
  94. return Execute();
  95. }
  96. /// <summary>
  97. /// Execute the ability on the Target. If Random is set execute on random target.
  98. /// </summary>
  99. /// <returns></returns>
  100. public bool Execute()
  101. {
  102. bool ret = false;
  103. while (Casts-- > 0)
  104. {
  105. skipend = Casts > 0;
  106. if (CommandFunc.TryGetValue(Command.ID, out Func<bool> val))
  107. ret = val.Invoke() || ret;
  108. else
  109. ret = CommandDefault() || ret;
  110. }
  111. return ret;
  112. }
  113. public void EndTurn()
  114. {
  115. if (!skipend)
  116. Damageable?.EndTurn();
  117. }
  118. public override void Refresh(Damageable damageable)
  119. {
  120. base.Refresh(damageable);
  121. Draw_Pool?.Refresh(damageable);
  122. }
  123. public override void Reset()
  124. {
  125. HideChildren();
  126. Hide();
  127. base.Reset();
  128. }
  129. public void SelectTargetWindows(Combine.KernelItem c)
  130. {
  131. Kernel_bin.Target t = c.Target;
  132. SelectTargetWindows(t);
  133. Command = Kernel_bin.BattleCommands[19];
  134. CombineKernelItem = c;
  135. }
  136. public void SelectTargetWindows(Kernel_bin.Enemy_Attacks_Data c)
  137. {
  138. // we don't know what the enemy attacks default target is. Setting a general default here.
  139. // The battle AI script sets the target for the enemies
  140. // http://forums.qhimm.com/index.php?topic=18384.0
  141. Kernel_bin.Target t = Kernel_bin.Target.Ally | Kernel_bin.Target.Enemy | Kernel_bin.Target.Single_Target;
  142. SelectTargetWindows(t);
  143. Command = Kernel_bin.BattleCommands[1];
  144. EnemyAttack = c;
  145. }
  146. public void SelectTargetWindows(Item_In_Menu c, bool shot = false)
  147. {
  148. Kernel_bin.Target t = c.Battle?.Target ?? Kernel_bin.Target.Enemy | Kernel_bin.Target.Single_Target;
  149. if (shot)
  150. t = c.Shot.Target;
  151. SelectTargetWindows(t);
  152. Command = Kernel_bin.BattleCommands[shot ? 14 : 4];
  153. Item = c;
  154. }
  155. public void SelectTargetWindows(Kernel_bin.Battle_Commands c)
  156. {
  157. Kernel_bin.Target t = c.Target;
  158. SelectTargetWindows(t);
  159. Command = c;
  160. Magic = null;
  161. BlueMagic = null;
  162. }
  163. public void SelectTargetWindows(Kernel_bin.Magic_Data c, int casts = 1, Random random = default)
  164. {
  165. Kernel_bin.Target t = c.Target;
  166. SelectTargetWindows(t, casts, random);
  167. Command = Kernel_bin.BattleCommands[2];
  168. Magic = c;
  169. }
  170. public void SelectTargetWindows(Kernel_bin.Blue_magic_Quistis_limit_break c)
  171. {
  172. //not sure if target data is missing for blue magic.
  173. //The target box does show up in game so I imagine the target data is in there somewhere.
  174. Kernel_bin.Target t = c.Target;
  175. SelectTargetWindows(t);
  176. Command = Kernel_bin.BattleCommands[15];
  177. BlueMagic = c;
  178. }
  179. public override void Show() => base.Show();
  180. public void ShowTargetWindows()
  181. {
  182. skipdata = true;
  183. Show();
  184. skipdata = false;
  185. Refresh();
  186. }
  187. protected override void Init()
  188. {
  189. base.Init();
  190. if (CommandFunc == null)
  191. CommandFunc = new Dictionary<int, Func<bool>>
  192. {
  193. //{0,Command00 },
  194. {1,Command01_ATTACK },
  195. {2,Command02_MAGIC },
  196. //{3,Command03_GF },
  197. {4,Command04_ITEM },
  198. {5,Command05_RENZOKUKEN },
  199. {6,Command06_DRAW },
  200. {7,Command07_DEVOUR },
  201. //{8,Command08_UNNAMED },
  202. //{9,Command09_CAST },
  203. //{10,Command10_STOCK },
  204. {11,Command11_DUEL },
  205. {12,Command12_MUG },
  206. //{13,Command13_NOMSG },
  207. {14,Command14_SHOT },
  208. {15,Command15_BLUE_MAGIC },
  209. //{16,Command16_SLOT },
  210. {17,Command17_FIRE_CROSS_NO_MERCY },
  211. {18,Command18_SORCERY_ICE_STRIKE },
  212. {19,Command19_COMBINE },
  213. {20,Command20_DESPERADO },
  214. {21,Command21_BLOOD_PAIN },
  215. {22,Command22_MASSIVE_ANCHOR },
  216. //{23,Command23_DEFEND },
  217. {24,Command24_MADRUSH },
  218. {25,Command25_TREATMENT },
  219. {26,Command26_RECOVERY },
  220. {27,Command27_REVIVE },
  221. {28,Command28_DARKSIDE },
  222. {29,Command29_CARD },
  223. {30,Command30_DOOM },
  224. {31,Command31_KAMIKAZI },
  225. {32,Command32_ABSORB },
  226. {33,Command33_LVL_DOWN },
  227. {34,Command34_LVL_UP },
  228. {35,Command35_SINGLE },
  229. {36,Command36_DOUBLE },
  230. {37,Command37_TRIPLE },
  231. {38,Command38_MINIMOG },
  232. };
  233. //bool Command00() => throw new NotImplementedException();
  234. bool Command01_ATTACK()
  235. {
  236. Neededvaribles(out Damageable[] d);
  237. if (EnemyAttack != null && Damageable.GetEnemy(out Enemy e))
  238. {
  239. Debug.WriteLine($"{Damageable.Name} uses {EnemyAttack.Name}({EnemyAttack.MagicID}) enemy attack on { DebugMessageSuffix(d) }");
  240. }
  241. EndTurn();
  242. return true;
  243. }
  244. bool Command02_MAGIC()
  245. {
  246. Neededvaribles(out Damageable[] d, Magic.PositiveMagic);
  247. Debug.WriteLine($"{Damageable.Name} casts {Magic.Name}({Magic.ID}) spell on { DebugMessageSuffix(d) }");
  248. EndTurn();
  249. return true;
  250. }
  251. //bool Command03_GF() => throw new NotImplementedException();
  252. bool Command04_ITEM()
  253. {
  254. Neededvaribles(out Damageable[] d);
  255. Debug.WriteLine($"{Damageable.Name} uses {Item.Name}({Item.ID}) item on { DebugMessageSuffix(d) }");
  256. EndTurn();
  257. return true;
  258. }
  259. bool Command05_RENZOKUKEN()
  260. {
  261. Neededvaribles(out Damageable[] d);
  262. if (d.First().GetType() == typeof(Enemy) && Damageable.GetCharacterData(out Saves.CharacterData c))
  263. {
  264. Saves.CharacterData squall = Memory.State[Characters.Squall_Leonhart];
  265. //Renzokuken
  266. byte weaponid = squall.WeaponID;
  267. int hits = 0;
  268. if (c.CurrentCrisisLevel > 0)
  269. hits = c.CurrentCrisisLevel < Renzokuken_hits.Length ? Renzokuken_hits[c.CurrentCrisisLevel] : Renzokuken_hits.Last();
  270. //else return false;
  271. else hits = Renzokuken_hits.First();
  272. int finisherchance = (c.CurrentCrisisLevel + 1) * 60;
  273. bool willfinish = Memory.Random.Next(byte.MaxValue + 1) <= finisherchance;
  274. int choosefinish = Memory.Random.Next(3 + 1);
  275. Kernel_bin.Weapons_Data weapondata = Kernel_bin.WeaponsData[weaponid];
  276. Kernel_bin.Renzokeken_Finisher renzokekenfinisher = weapondata.Renzokuken;
  277. if (renzokekenfinisher == 0)
  278. willfinish = false;
  279. //per wiki the chance of which finisher is 25% each and the highest value finisher get the remaining of 100 percent.
  280. //so rough divide is 100% when you only only have that
  281. //when you unlock 2 one is 75% chance
  282. //when you onlock 3 last one is 50%
  283. //when you unlock all 4 it's 25% each.
  284. //finishers each have their own target
  285. Menu.BattleMenus.GetCurrentBattleMenu().Renzokeken.Reset(hits);
  286. Menu.BattleMenus.GetCurrentBattleMenu().Renzokeken.Show();
  287. if (willfinish)
  288. {
  289. List<Kernel_bin.Renzokeken_Finisher> flags = Enum.GetValues(typeof(Kernel_bin.Renzokeken_Finisher))
  290. .Cast<Kernel_bin.Renzokeken_Finisher>()
  291. .Where(f => (f & renzokekenfinisher) != 0)
  292. .ToList();
  293. Kernel_bin.Renzokeken_Finisher finisher = choosefinish >= flags.Count ? flags.Last() : flags[choosefinish];
  294. Debug.WriteLine($"{Damageable.Name} hits {hits} times with {Command.Name}({Command.ID}) then uses {Kernel_bin.RenzokukenFinishersData[finisher].Name}.");
  295. }
  296. else
  297. Debug.WriteLine($"{Damageable.Name} hits {hits} times with {Command.Name}({Command.ID}) then fails to use a finisher.");
  298. }
  299. return true;
  300. }
  301. bool Command06_DRAW()
  302. {
  303. Neededvaribles(out Damageable[] d);
  304. //draw
  305. //spawn a 1 page 4 row pool of the magic/gfs that the selected enemy has.
  306. if (d.First().GetType() == typeof(Enemy))
  307. {
  308. Enemy e = (Enemy)d.First();
  309. DrawMagic(e.DrawList);
  310. Draw_Pool.Refresh(e.DrawList);
  311. Draw_Pool.Show();
  312. }
  313. return true;
  314. }
  315. bool Command07_DEVOUR()
  316. {
  317. Neededvaribles(out Damageable[] d);
  318. //TODO add devour commands
  319. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  320. EndTurn();
  321. return true;
  322. }
  323. //bool Command08_UNNAMED() => throw new NotImplementedException();
  324. //bool Command09_CAST() => throw new NotImplementedException();
  325. //bool Command10_STOCK() => throw new NotImplementedException();
  326. bool Command11_DUEL()
  327. {
  328. Neededvaribles(out Damageable[] d);
  329. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  330. EndTurn();
  331. return true;
  332. }
  333. bool Command12_MUG()
  334. {
  335. Neededvaribles(out Damageable[] d);
  336. if (d.First().GetType() == typeof(Enemy))
  337. {
  338. Enemy e = (Enemy)d.First();
  339. //unsure if party member being ejected or if they need to be in the party for rare item to work
  340. Saves.Item i = e.Mug(Damageable.SPD, Memory.State.PartyHasAbility(Kernel_bin.Abilities.RareItem));
  341. Debug.WriteLine($"{Damageable.Name} stole {i.DATA?.Name}({i.ID}) x {i.QTY} from { DebugMessageSuffix(d) }");
  342. }
  343. EndTurn();
  344. return true;
  345. }
  346. //bool Command13_NOMSG() => throw new NotImplementedException();
  347. bool Command14_SHOT()
  348. {
  349. Neededvaribles(out Damageable[] d);
  350. Menu.BattleMenus.GetCurrentBattleMenu().Shot.Refresh(Item,d);
  351. Menu.BattleMenus.GetCurrentBattleMenu().Shot.Show();
  352. Debug.WriteLine($"{Damageable.Name} uses {Item.Name}({Item.ID}) item on { DebugMessageSuffix(d) }");
  353. return true;
  354. }
  355. bool Command15_BLUE_MAGIC()
  356. {
  357. Neededvaribles(out Damageable[] d);
  358. Debug.WriteLine($"{Damageable.Name} casts {BlueMagic.Name}({BlueMagic.ID}) spell on { DebugMessageSuffix(d) }");
  359. EndTurn();
  360. return false;
  361. }
  362. //bool Command16_SLOT() => throw new NotImplementedException();
  363. bool Command17_FIRE_CROSS_NO_MERCY()
  364. {
  365. Neededvaribles(out Damageable[] d);
  366. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  367. EndTurn();
  368. return true;
  369. }
  370. bool Command18_SORCERY_ICE_STRIKE()
  371. {
  372. Neededvaribles(out Damageable[] d);
  373. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  374. EndTurn();
  375. return true;
  376. }
  377. bool Command19_COMBINE()
  378. {
  379. //perform angelo attack unless angel wing is unlocked and chosen in menu.
  380. Neededvaribles(out Damageable[] d);
  381. Debug.WriteLine($"{Damageable.Name} used {CombineKernelItem.Name}({CombineKernelItem.ID}) - Combine Limit Break on { DebugMessageSuffix(d) }");
  382. EndTurn();
  383. return true;
  384. }
  385. bool Command20_DESPERADO()
  386. {
  387. Neededvaribles(out Damageable[] d);
  388. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  389. EndTurn();
  390. return true;
  391. }
  392. bool Command21_BLOOD_PAIN()
  393. {
  394. Neededvaribles(out Damageable[] d);
  395. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  396. EndTurn();
  397. return true;
  398. }
  399. bool Command22_MASSIVE_ANCHOR()
  400. {
  401. Neededvaribles(out Damageable[] d);
  402. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  403. EndTurn();
  404. return true;
  405. }
  406. //bool Command23_DEFEND() => throw new NotImplementedException();
  407. bool Command24_MADRUSH()
  408. {
  409. Neededvaribles(out Damageable[] d);
  410. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  411. EndTurn();
  412. return true;
  413. }
  414. bool Command25_TREATMENT()
  415. {
  416. Neededvaribles(out Damageable[] d);
  417. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  418. EndTurn();
  419. return true;
  420. }
  421. bool Command26_RECOVERY()
  422. {
  423. Neededvaribles(out Damageable[] d);
  424. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  425. EndTurn();
  426. return true;
  427. }
  428. bool Command27_REVIVE()
  429. {
  430. Neededvaribles(out Damageable[] d);
  431. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  432. EndTurn();
  433. return true;
  434. }
  435. bool Command28_DARKSIDE()
  436. {
  437. Neededvaribles(out Damageable[] d);
  438. EndTurn();
  439. return true;
  440. }
  441. bool Command29_CARD()
  442. {
  443. Neededvaribles(out Damageable[] d);
  444. if (d.First().GetType() == typeof(Enemy))
  445. {
  446. Enemy e = (Enemy)d.First();
  447. Cards.ID c = e.Card();
  448. if (c == Cards.ID.Fail)
  449. Debug.WriteLine($"{Damageable.Name} Failed to use {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  450. else if (c == Cards.ID.Immune)
  451. Debug.WriteLine($"{Damageable.Name} Failed to use {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) } because they are immune!");
  452. else
  453. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) } and got a {c} card");
  454. EndTurn();
  455. }
  456. return true;
  457. }
  458. bool Command30_DOOM()
  459. {
  460. Neededvaribles(out Damageable[] d);
  461. EndTurn();
  462. return true;
  463. }
  464. bool Command31_KAMIKAZI()
  465. {
  466. Neededvaribles(out Damageable[] d);
  467. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  468. EndTurn();
  469. return true;
  470. }
  471. bool Command32_ABSORB()
  472. {
  473. Neededvaribles(out Damageable[] d);
  474. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  475. EndTurn();
  476. return true;
  477. }
  478. bool Command33_LVL_DOWN()
  479. {
  480. Neededvaribles(out Damageable[] d);
  481. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  482. EndTurn();
  483. return true;
  484. }
  485. bool Command34_LVL_UP()
  486. {
  487. Neededvaribles(out Damageable[] d);
  488. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  489. EndTurn();
  490. return true;
  491. }
  492. bool Command35_SINGLE() => Command02_MAGIC();
  493. bool Command36_DOUBLE()
  494. {
  495. // CHOOSE 2X TARGETS
  496. throw new NotImplementedException();
  497. }
  498. bool Command37_TRIPLE()
  499. {
  500. // CHOOSE 3X TARGETS
  501. throw new NotImplementedException();
  502. }
  503. bool Command38_MINIMOG()
  504. {
  505. Neededvaribles(out Damageable[] d);
  506. Debug.WriteLine($"{Damageable.Name} used {Command.Name}({Command.ID}) on { DebugMessageSuffix(d) }");
  507. EndTurn();
  508. return true;
  509. }
  510. }
  511. private void after()
  512. {
  513. TargetEnemies.Target_Party = TargetParty;
  514. TargetParty.Target_Enemies = TargetEnemies;
  515. Draw_Pool?.Hide();
  516. Hide();
  517. }
  518. private bool CommandDefault() => throw new NotImplementedException();
  519. private string DamageableNames(Damageable[] e)
  520. {
  521. string r = $"[{e[0].Name}";
  522. for (int j = 1; j < e.Length; j++)
  523. r += $", {e[j]}";
  524. r += "]";
  525. return r;
  526. }
  527. private void DebugMessageCommand(IGMData.Target.Enemies i, Damageable[] d, Damageable fromvc) => Debug.WriteLine($"{Damageable.Name} uses {Command.Name}({Command.ID}) command on { DebugMessageSuffix(d) }");
  528. private string DebugMessageSuffix(Damageable[] d) => $"{DamageableNames(d)}({(d.Length == 1 ? TargetEnemies.CURSOR_SELECT.ToString() : "MultiSelect")})";
  529. /// <summary>
  530. /// Display pool with list
  531. /// </summary>
  532. /// <param name="drawList"></param>
  533. private void DrawMagic(Debug_battleDat.Magic[] drawList) => Debug.WriteLine($"Display draw pool: {string.Join(", ", drawList)}");
  534. private void Neededvaribles(out Damageable[] d, bool positive = false)
  535. {
  536. Damageable[] e = null;
  537. Damageable[] vc = null;
  538. IEnumerable<Saves.CharacterData> party = Memory.State.Party.Where(x => x != Characters.Blank).Select(y => Memory.State[y]);
  539. if (Target.HasFlag(Kernel_bin.Target.Single_Target))
  540. {
  541. if (TargetEnemies.Enabled && TargetParty.Enabled && RandomTarget.Single && RandomTarget.Side)
  542. {
  543. List<Damageable> CombinedTargets = new List<Damageable>();
  544. if (RandomTarget.PositiveMatters)
  545. {
  546. if (positive)
  547. CombinedTargets.AddRange(party);
  548. else
  549. CombinedTargets.AddRange(Enemy.Party);
  550. }
  551. else
  552. {
  553. CombinedTargets.AddRange(Enemy.Party);
  554. CombinedTargets.AddRange(party);
  555. }
  556. Damageable rand = CombinedTargets.Random();
  557. if (typeof(Enemy).Equals(rand.GetType()))
  558. {
  559. e = new Damageable[] { rand };
  560. }
  561. else if (typeof(Saves.CharacterData).Equals(rand.GetType()))
  562. {
  563. vc = new Damageable[] { rand };
  564. }
  565. }
  566. else
  567. {
  568. if (RandomTarget.Single)
  569. {
  570. TargetParty.Random();
  571. TargetEnemies.Random();
  572. }
  573. e = new Enemy[] { Enemy.Party[TargetEnemies.CURSOR_SELECT < Enemy.Party.Count ? TargetEnemies.CURSOR_SELECT : Enemy.Party.Count - 1] };
  574. vc = new Saves.CharacterData[] { party.ElementAt(TargetParty.CURSOR_SELECT) };
  575. }
  576. }
  577. else
  578. {
  579. vc = party.ToArray();
  580. e = Enemy.Party.ToArray();
  581. if (RandomTarget.Side && TargetEnemies.Enabled && TargetParty.Enabled)
  582. {
  583. if (RandomTarget.PositiveMatters)
  584. {
  585. if (positive)
  586. e = null;
  587. else
  588. vc = null;
  589. }
  590. else
  591. switch (Memory.Random.Next(2))
  592. {
  593. case 0:
  594. vc = null;
  595. break;
  596. case 1:
  597. e = null;
  598. break;
  599. }
  600. }
  601. }
  602. Characters c = Memory.State.PartyData.Where(x => x != Characters.Blank).ToList()[TargetParty.CURSOR_SELECT];
  603. Damageable fromc = Menu.BattleMenus.GetDamageable();
  604. //fromvc = Memory.State.Party.Where(x => x != Characters.Blank).ToList()[p];
  605. if (RandomTarget.PositiveMatters)
  606. {
  607. if (positive)
  608. e = null;
  609. else
  610. vc = null;
  611. }
  612. d = vc;
  613. if (((TargetEnemies.Cursor_Status & Cursor_Status.Enabled) != 0 && TargetEnemies.Enabled) || d == null)
  614. d = e;
  615. DebugMessageCommand(TargetEnemies, d, Damageable);
  616. }
  617. private void SelectTargetWindows(Kernel_bin.Target t, int casts = 1, Random random = default)
  618. {
  619. RandomTarget = random ?? new Random(false);
  620. Casts = casts;
  621. Target = t;
  622. if ((t & Kernel_bin.Target.Ally) != 0 || t == Kernel_bin.Target.None || ((t & Kernel_bin.Target.Enemy) == 0 && (t & Kernel_bin.Target.Single_Side) != 0))
  623. {
  624. TargetParty.Show();
  625. TargetAll(TargetParty);
  626. }
  627. else
  628. TargetParty.Hide();
  629. if ((t & Kernel_bin.Target.Enemy) != 0)
  630. {
  631. TargetEnemies.Show();
  632. TargetAll(TargetEnemies);
  633. }
  634. else
  635. TargetEnemies.Hide();
  636. void TargetAll(IGMData.Base i)
  637. {
  638. if (Target.HasFlag(Kernel_bin.Target.Single_Target))
  639. {
  640. i.Cursor_Status &= ~Cursor_Status.All;
  641. }
  642. else
  643. i.Cursor_Status |= Cursor_Status.All;
  644. }
  645. if (Damageable.GetEnemy(out Enemy e))
  646. {
  647. if (TargetEnemies.Enabled == (TargetParty.Enabled == true))
  648. {
  649. //do nothing
  650. }
  651. else if (TargetEnemies.Enabled && !TargetParty.Enabled)
  652. {
  653. TargetParty.Show();
  654. TargetEnemies.Hide();
  655. }
  656. else if (!TargetEnemies.Enabled && TargetParty.Enabled)
  657. {
  658. TargetParty.Hide();
  659. TargetEnemies.Show();
  660. }
  661. }
  662. }
  663. #endregion Methods
  664. }
  665. }