Selphie_Slots.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System.Collections.Generic;
  2. using Microsoft.Xna.Framework;
  3. using OpenVIII.IGMData.Target;
  4. using OpenVIII.IGMDataItem;
  5. using OpenVIII.Kernel;
  6. namespace OpenVIII.IGMData
  7. {
  8. public class SelphieSlots : Base
  9. {
  10. #region Fields
  11. private MagicData _magicData;
  12. #endregion Fields
  13. #region Properties
  14. public int Casts { get => Number.Data; private set => Number.Data = value; }
  15. public MagicData MagicData
  16. {
  17. get => _magicData; private set
  18. {
  19. _magicData = value;
  20. Name = value?.Name;
  21. }
  22. }
  23. public FF8String Name { get => Spell.Data; private set => Spell.Data = value; }
  24. private Text Cast { get => (Text)ITEM[6, 0]; set => ITEM[6, 0] = value; }
  25. private Text DoOver { get => (Text)ITEM[3, 0]; set => ITEM[3, 0] = value; }
  26. private Integer Number { get => (Integer)ITEM[1, 0]; set => ITEM[1, 0] = value; }
  27. private Text Spell { get => (Text)ITEM[0, 0]; set => ITEM[0, 0] = value; }
  28. private Slot SpellData
  29. {
  30. get
  31. {
  32. if (Spells == null) return default;
  33. var spells = Spells;
  34. return spells[Memory.Random.Next(spells.Count)];
  35. }
  36. }
  37. /// <summary>
  38. /// List of Spells
  39. /// </summary>
  40. private IReadOnlyList<Slot> Spells => (SpellSet?.SlotID ?? -1) == -1 ? null : Memory.KernelBin.SelphieLimitBreakSets[SpellSet.SlotID]?.Slots;
  41. /// <summary>
  42. /// Spell set
  43. /// </summary>
  44. private SlotArray SpellSet => Memory.KernelBin.SlotArray != null ? Memory.KernelBin.SlotArray[MathHelper.Clamp((TombolaLevel * 12) + TombolaLevel, 0, Memory.KernelBin.SlotArray.Count - 1)] : null;
  45. private Target.Group TargetGroup { get => (Target.Group)ITEM[8, 0]; set => ITEM[8, 0] = value; }
  46. private Text Times { get => (Text)ITEM[2, 0]; set => ITEM[2, 0] = value; }
  47. /// <summary>
  48. /// Selphie's TombolaLevel
  49. /// </summary>
  50. private short TombolaLevel => Damageable != null && Damageable.GetCharacterData(out var c) ? checked((short)(Damageable.Level / 10 + c.CurrentCrisisLevel + Memory.Random.Next(5) - 1)) : (short)0;
  51. /// <summary>
  52. /// Selphie's TombolaLevel
  53. /// </summary>
  54. private byte TombolaMod
  55. {
  56. get
  57. {
  58. var rnd = checked((byte)Memory.Random.Next(256));
  59. if (rnd >= 249) return 4;
  60. if (rnd >= 209) return 3;
  61. if (rnd >= 159) return 2;
  62. if (rnd >= 39) return 1;
  63. return 0;
  64. }
  65. }
  66. #endregion Properties
  67. #region Methods
  68. public override bool Inputs_CANCEL()
  69. {
  70. base.Inputs_OKAY();
  71. Refresh();
  72. return true;
  73. }
  74. public override bool Inputs_OKAY()
  75. {
  76. switch (CURSOR_SELECT)
  77. {
  78. case 3:
  79. Inputs_CANCEL();
  80. break;
  81. case 6:
  82. base.Inputs_OKAY();
  83. if (MagicData != null)
  84. {
  85. // will probably need an extra method to make sure positive spells cast only on party members.
  86. // and negative spells only hit the enemies.
  87. //Single targets are random but if cursor is on enemy it will only hit an enemy.
  88. // and if it's on a party member it'll only hit a party member.
  89. TargetGroup?.SelectTargetWindows(MagicData, Casts, new Random { Single = true, PositiveMatters = true });
  90. // show target window so target selection code works.
  91. TargetGroup?.ShowTargetWindows();
  92. // Execute the spells.
  93. // This should hide the targetwindow as turn ends.
  94. TargetGroup?.Execute();
  95. Hide();
  96. }
  97. else
  98. Inputs_CANCEL();
  99. break;
  100. }
  101. return true;
  102. }
  103. public override void Refresh()
  104. {
  105. var spell_data = SpellData;
  106. MagicData = spell_data.MagicData;
  107. Casts = spell_data.Casts;
  108. SetCursor_select(3);
  109. base.Refresh();
  110. }
  111. protected override void Init()
  112. {
  113. Table_Options |= Table_Options.FillRows;
  114. base.Init();
  115. // 0,1,2
  116. // 3,4,5
  117. // 6,7,8
  118. BLANKS.SetAll(true);
  119. Spell = new Text { Pos = SIZE[0] };
  120. Number = new Integer { Pos = SIZE[1], Spaces = 3, NumType = Icons.NumType.SysFntBig };
  121. Times = new Text { Data = Memory.Strings[Strings.FileID.Kernel][30, 65], Pos = SIZE[2] };
  122. DoOver = new Text { Data = Memory.Strings[Strings.FileID.Kernel][30, 67], Pos = SIZE[3] };
  123. BLANKS[3] = false;
  124. Cast = new Text { Data = Memory.Strings[Strings.FileID.Kernel][30, 66], Pos = SIZE[6] };
  125. BLANKS[6] = false;
  126. TargetGroup = Target.Group.Create(Damageable);
  127. TargetGroup.Hide();
  128. Cursor_Status |= Cursor_Status.Enabled;
  129. }
  130. protected override void InitShift(int i, int col, int row)
  131. {
  132. base.InitShift(i, col, row);
  133. SIZE[i].Inflate(-22, -12);
  134. if (row == 0) SIZE[i].Offset(0, 8);
  135. if (col == 1) SIZE[i].Offset(8, 0);
  136. if (col == 2) SIZE[i].Offset(-16, 0);
  137. if (row > 0) SIZE[i].Offset(20, 0);
  138. }
  139. public static SelphieSlots Create(Rectangle pos, Damageable damageable = null, bool battle = true) => Create<SelphieSlots>(9, 1, new Box { Pos = pos, Title = Icons.ID.SPECIAL }, 3, 3, damageable, battle: battle);
  140. #endregion Methods
  141. }
  142. }