Item.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. using Microsoft.Xna.Framework;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace OpenVIII.IGMData.Pool
  6. {
  7. public class Item : IGMData.Pool.Base<Saves.Data, ItemInMenu>
  8. {
  9. #region Fields
  10. private FF8String[] _helpStr;
  11. private bool eventSet = false;
  12. #endregion Fields
  13. #region Events
  14. public event EventHandler<KeyValuePair<ItemInMenu, FF8String>> ItemChangeHandler;
  15. #endregion Events
  16. #region Properties
  17. public IReadOnlyList<FF8String> HelpStr => _helpStr;
  18. public IGMData.Target.Group Target_Group => (IGMData.Target.Group)(((IGMData.Base)ITEM[Targets_Window, 0]));
  19. private int Targets_Window => Count - 3;
  20. #endregion Properties
  21. #region Methods
  22. public static Item Create(Rectangle pos, Damageable damageable = null, bool battle = false, int count = 4)
  23. {
  24. var r = Create<Item>(count + 1, 3, new IGMDataItem.Box { Pos = pos, Title = Icons.ID.ITEM }, count, 198 / count + 1, damageable,battle:battle);
  25. if (battle)
  26. r.ITEM[r.Targets_Window, 0] = IGMData.Target.Group.Create(r.Damageable);
  27. return r;
  28. }
  29. public static Item Create(Damageable damageable = null) => Create(new Rectangle(5, 150, 415, 480), damageable: damageable, battle: false, count: 13);
  30. public override void Draw() => base.Draw();
  31. public override void HideChildren()
  32. {
  33. if (Enabled)
  34. {
  35. if (!skipdata)
  36. {
  37. Target_Group.HideChildren();
  38. Target_Group.Hide();
  39. }
  40. }
  41. }
  42. public override bool Inputs()
  43. {
  44. var ret = false;
  45. if (InputITEM(Target_Group, ref ret))
  46. {
  47. }
  48. else
  49. {
  50. Cursor_Status &= ~Cursor_Status.Blinking;
  51. Cursor_Status |= Cursor_Status.Enabled;
  52. return base.Inputs();
  53. }
  54. return ret;
  55. }
  56. public override bool Inputs_CANCEL()
  57. {
  58. if (Battle)
  59. {
  60. Hide();
  61. }
  62. else
  63. {
  64. Menu.IGMItems.SetMode(IGMItems.Mode.TopMenu);
  65. base.Inputs_CANCEL();
  66. }
  67. return true;
  68. }
  69. public override bool Inputs_OKAY()
  70. {
  71. var item = Contents[CURSOR_SELECT];
  72. if (Battle)
  73. {
  74. Target_Group?.SelectTargetWindows(item);
  75. Target_Group?.ShowTargetWindows();
  76. }
  77. if (item.ItemTarget == ItemTarget.None)
  78. return false;
  79. base.Inputs_OKAY();
  80. Menu.IGMItems.SetMode(IGMItems.Mode.UseItemOnTarget);
  81. return true;
  82. }
  83. public override void ModeChangeEvent(object sender, Enum e)
  84. {
  85. if (e.Equals(IGMItems.Mode.SelectItem) || Battle)
  86. {
  87. Cursor_Status |= Cursor_Status.Enabled;
  88. }
  89. else if (e.Equals(IGMItems.Mode.UseItemOnTarget))
  90. {
  91. Cursor_Status |= Cursor_Status.Blinking;
  92. }
  93. else
  94. {
  95. Cursor_Status &= ~Cursor_Status.Enabled;
  96. }
  97. }
  98. public override void Refresh()
  99. {
  100. if (!Battle && !eventSet && Menu.IGMItems != null)
  101. {
  102. Menu.IGMItems.ModeChangeHandler += ModeChangeEvent;
  103. Menu.IGMItems.RefreshCompletedHandler += RefreshCompletedEvent;
  104. eventSet = true;
  105. }
  106. base.Refresh();
  107. Source = Memory.State;
  108. if (Source != null && Source.Items != null)
  109. {
  110. ((IGMDataItem.Box)CONTAINER).Title = Pages <= 1 ? (Icons.ID?)Icons.ID.ITEM : (Icons.ID?)(Icons.ID.ITEM_PG1 + (byte)Page);
  111. byte pos = 0;
  112. var skip = checked((short)(Page * Rows));
  113. Enemy e = null;
  114. if (Damageable?.GetEnemy(out e) ?? false)
  115. {
  116. sbyte addEnemyItem(ItemInMenu itemdata)
  117. {
  118. var item = new Saves.Item (itemdata.ID, byte.MaxValue );
  119. return AddItem(ref pos, ref skip, item, itemdata);
  120. }
  121. var items = new HashSet<ItemInMenu>();
  122. foreach(var a in e.Abilities.Where(x=>x.Item != null))
  123. items.Add(a.Item.Value);
  124. foreach (var a in e.DropList.Where(x => x.ID != 0 && x.Data != null))
  125. items.Add(a.Data.Value);
  126. foreach (var a in e.MugList.Where(x => x.ID != 0 && x.Data != null))
  127. items.Add(a.Data.Value);
  128. foreach (var i in items)
  129. if (addEnemyItem(i) == 0) break;
  130. NUM_.Hide();
  131. DefaultPages = items.Count / Rows;
  132. }
  133. else
  134. for (byte i = 0; pos < Rows && i < Source.Items.Count; i++)
  135. {
  136. var item = Source.Items[i];
  137. var itemdata = item.Data ?? new ItemInMenu();
  138. if (AddItem(ref pos, ref skip, item, itemdata) == 0) break;
  139. }
  140. for (; pos < Rows; pos++)
  141. {
  142. ((IGMDataItem.Integer)(ITEM[pos, 1])).Hide();
  143. if (pos == 0) return; // if page turning. this till be enough to trigger a try next page.
  144. ((IGMDataItem.Text)(ITEM[pos, 0])).Data = null;
  145. ((IGMDataItem.Integer)(ITEM[pos, 1])).Data = 0;
  146. ((IGMDataItem.Text)(ITEM[pos, 0])).Icon = Icons.ID.None;
  147. BLANKS[pos] = true;
  148. ITEM[pos, 1].Hide();
  149. ITEM[pos, 0].Hide();
  150. }
  151. }
  152. }
  153. private sbyte AddItem(ref byte pos, ref short skip, Saves.Item item, ItemInMenu itemdata)
  154. {
  155. if ((pos >= Rows)) //reached max rows.
  156. return 0;
  157. if ((item.ID == 0 || item.QTY == 0) || // skip empty values.
  158. (Battle && itemdata.Battle == null) || // if battle mode skip nonbattle items.
  159. (itemdata.ID == 0) || // skip empty values.
  160. (skip-- > 0)) //skip items that are on prev pages.
  161. return -1;
  162. Enemy e = null;
  163. if ((Damageable?.GetEnemy(out e) ?? false))
  164. {
  165. }
  166. var color = Font.ColorID.White;
  167. var palette = itemdata.Palette;
  168. if (!itemdata.ValidTarget(Battle))
  169. {
  170. color = Font.ColorID.Grey;
  171. BLANKS[pos] = true;
  172. palette = itemdata.FadedPalette;
  173. }
  174. else
  175. BLANKS[pos] = false;
  176. ((IGMDataItem.Text)(ITEM[pos, 0])).Data = itemdata.Name;
  177. ((IGMDataItem.Text)(ITEM[pos, 0])).Icon = itemdata.Icon;
  178. ((IGMDataItem.Text)(ITEM[pos, 0])).Palette = palette;
  179. ((IGMDataItem.Text)(ITEM[pos, 0])).FontColor = color;
  180. ((IGMDataItem.Integer)(ITEM[pos, 1])).Data = item.QTY;
  181. if (e != null)
  182. ITEM[pos, 1].Hide();
  183. else
  184. ITEM[pos, 1].Show();
  185. ((IGMDataItem.Integer)(ITEM[pos, 1])).FontColor = color;
  186. _helpStr[pos] = itemdata.Description;
  187. Contents[pos] = itemdata;
  188. ITEM[pos, 0].Show();
  189. pos++;
  190. return 1;
  191. }
  192. public override void Reset()
  193. {
  194. HideChildren();
  195. Hide();
  196. base.Reset();
  197. }
  198. protected override void DrawITEM(int i, int d)
  199. {
  200. if (Targets_Window >= i || !(Target_Group != null && Target_Group.Enabled))
  201. base.DrawITEM(i, d);
  202. }
  203. protected override void Init()
  204. {
  205. base.Init();
  206. _helpStr = new FF8String[Count];
  207. for (byte pos = 0; pos < Rows; pos++)
  208. {
  209. ITEM[pos, 0] = new IGMDataItem.Text { Pos = SIZE[pos] };
  210. ITEM[pos, 1] = new IGMDataItem.Integer { Pos = new Rectangle(SIZE[pos].X + SIZE[pos].Width - 60, SIZE[pos].Y, 0, 0), NumType = Icons.NumType.SysFntBig, Spaces = 3 };
  211. }
  212. NUM_ = new IGMDataItem.Icon { Data = Icons.ID.NUM_, Pos = new Rectangle(SIZE[Rows - 1].X + SIZE[Rows - 1].Width - 60, Y, 0, 0), Scale = new Vector2(2.5f) };
  213. PointerZIndex = Rows - 1;
  214. }
  215. protected IGMDataItem.Icon NUM_ { get
  216. { return ((IGMDataItem.Icon)ITEM[Count - 1, 2]); } private set { ITEM[Count - 1, 2] = value; } }
  217. protected override void InitShift(int i, int col, int row)
  218. {
  219. base.InitShift(i, col, row);
  220. //SIZE[i].Inflate(-18, -20);
  221. //SIZE[i].Y -= 5 * row;
  222. SIZE[i].Inflate(-22, -8);
  223. //SIZE[i].Offset(0, 12 + (-8 * row));
  224. var v = (int)(12 * TextScale.Y);
  225. SIZE[i].Height = v;
  226. SIZE[i].Y = Y + 18 + row * ((Height - 16) / Rows);
  227. }
  228. protected override void PAGE_NEXT()
  229. {
  230. var cnt = Pages;
  231. do
  232. {
  233. base.PAGE_NEXT();
  234. Refresh();
  235. skipsnd = true;
  236. }
  237. while (cnt-- > 0 && !((IGMDataItem.Integer)(ITEM[0, 1])).Enabled);
  238. ItemChangeHandler?.Invoke(this, new KeyValuePair<ItemInMenu, FF8String>(Contents[CURSOR_SELECT], HelpStr[CURSOR_SELECT]));
  239. }
  240. protected override void PAGE_PREV()
  241. {
  242. var cnt = Pages;
  243. do
  244. {
  245. base.PAGE_PREV();
  246. Refresh();
  247. skipsnd = true;
  248. }
  249. while (cnt-- > 0 && !((IGMDataItem.Integer)(ITEM[0, 1])).Enabled);
  250. ItemChangeHandler?.Invoke(this, new KeyValuePair<ItemInMenu, FF8String>(Contents[CURSOR_SELECT], HelpStr[CURSOR_SELECT]));
  251. }
  252. protected override void SetCursor_select(int value)
  253. {
  254. if (value != GetCursor_select())
  255. {
  256. base.SetCursor_select(value);
  257. ItemChangeHandler?.Invoke(this, new KeyValuePair<ItemInMenu, FF8String>(Contents[value], HelpStr[value]));
  258. }
  259. }
  260. private void RefreshCompletedEvent(object sender, EventArgs e) => ItemChangeHandler?.Invoke(this, new KeyValuePair<ItemInMenu, FF8String>(Contents[CURSOR_SELECT], HelpStr[CURSOR_SELECT]));
  261. #endregion Methods
  262. }
  263. }