item_menu.lua 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. if UiContainer == nil then UiContainer = {} end
  2. --- The item menu.
  3. UiContainer.ItemMenu = {
  4. --- Current cursor position in the top bar (1-3).
  5. bar_position = 1,
  6. --- Max cursor position in the top bar.
  7. bar_position_total = 3,
  8. --- Current cursor position in the item list (1-13).
  9. --
  10. -- It doesn't represent the item id or the inventory position, but the highlighted row among
  11. -- the ten displayed.
  12. item_cursor_position = 1,
  13. --- Max cursor position in the item list.
  14. item_cursor_position_total = 13,
  15. --- Highlighted inventory position (1-320).
  16. item_cursor_item_selected = 1,
  17. --- Current cursor position in the character section (1-3).
  18. char_position = 1,
  19. --- Max cursor position in the character section.
  20. char_position_total = 3,
  21. --- First inventory entry currently visible in the item list.
  22. first_item_in_window = 0,
  23. --- Key items cursor vertical position (0-9)
  24. --
  25. -- It doesn't represent the item id or the inventory position, but the highlighted row among
  26. -- the ten displayed.
  27. key_items_cursor_y_position = 1,
  28. --- Key items cursor horizontal position (0-1)
  29. --
  30. -- It doesn't represent the item id or the inventory position, but the highlighted row among
  31. -- the ten displayed. 1 if the cursor is in the left column, 2 if it's on the right.
  32. key_items_cursor_x_position = 1,
  33. --- Max vertical cursor position in the key item list.
  34. key_items_cursor_y_position_total = 13,
  35. --- Total number of rows in the key items window.
  36. --
  37. -- Includes visible and scrolled/scrollable rows. Since there are 51 key items, there are
  38. -- 26 rows.
  39. key_items_total_rows = 26,
  40. --- First visible row of key items (0-16)
  41. --
  42. -- Changes as the key item list scrols vertically.
  43. first_key_item_row_in_window = 1,
  44. --- Current cursor position in the order section (1-8).
  45. order_cursor_position = 1,
  46. --- Max cursor position in the order section.
  47. order_cursor_position_total = 8,
  48. --- Item ID of the currently selected (not highlighted) item.
  49. item_in_use = nil,
  50. --- Indicates it the selected item affect the entire party.
  51. item_in_use_party = false,
  52. -- Slots in the party inventory
  53. inventory_size = 320,
  54. --- Run when the menu is creaded.
  55. --
  56. -- It does nothing.
  57. on_start = function(self)
  58. return 0
  59. end,
  60. --- Handles button events.
  61. --
  62. -- For the current submenu, handles directional keys, enter and escape events.
  63. -- @param button Pressed direction or action name.
  64. -- @param event Trigger event. Normally, "Press".
  65. on_button = function(self, button, event)
  66. if UiContainer.current_menu == "item" then
  67. if UiContainer.current_submenu == "bar_selection" then
  68. if button == Config.ACTIONS.CANCEL and event == "Press" then
  69. audio_manager:play_sound("Back")
  70. UiContainer.current_menu = "main"
  71. script:request_end_sync(Script.UI, "ItemMenu", "hide", 0)
  72. elseif button == Config.CONTROLS.RIGHT then
  73. audio_manager:play_sound("Cursor")
  74. self.bar_position = self.bar_position + 1
  75. if self.bar_position > self.bar_position_total then
  76. self.bar_position = 1
  77. end
  78. ui_manager:get_widget("ItemMenu.Container.ItemMenuTopBar.Cursor"):set_default_animation("Position" .. self.bar_position)
  79. -- If highlighted, show key items.
  80. if self.bar_position == 3 then
  81. ui_manager:get_widget("ItemMenu.Container.KeyItems"):set_visible(true)
  82. else
  83. ui_manager:get_widget("ItemMenu.Container.KeyItems"):set_visible(false)
  84. end
  85. elseif button == Config.CONTROLS.LEFT then
  86. audio_manager:play_sound("Cursor")
  87. self.bar_position = self.bar_position - 1
  88. if self.bar_position < 1 then
  89. self.bar_position = self.bar_position_total
  90. end
  91. ui_manager:get_widget("ItemMenu.Container.ItemMenuTopBar.Cursor"):set_default_animation("Position" .. self.bar_position)
  92. -- If highlighted, show key items.
  93. if self.bar_position == 3 then
  94. ui_manager:get_widget("ItemMenu.Container.KeyItems"):set_visible(true)
  95. else
  96. ui_manager:get_widget("ItemMenu.Container.KeyItems"):set_visible(false)
  97. end
  98. elseif button == Config.ACTIONS.CONFIRM then
  99. if self.bar_position == 1 then
  100. self.submenu_items(self)
  101. elseif self.bar_position == 2 then
  102. self.submenu_order(self)
  103. elseif self.bar_position == 3 then
  104. self.submenu_key_items(self)
  105. else
  106. return 0
  107. end
  108. audio_manager:play_sound("Cursor")
  109. else
  110. return 0
  111. end
  112. elseif UiContainer.current_submenu == "order_selection" then
  113. if button == Config.ACTIONS.CANCEL and event == "Press" then
  114. audio_manager:play_sound("Back")
  115. self.submenu_bar(self)
  116. elseif button == Config.CONTROLS.DOWN then
  117. audio_manager:play_sound("Cursor")
  118. self.order_cursor_position = self.order_cursor_position + 1
  119. if self.order_cursor_position > self.order_cursor_position_total then
  120. self.order_cursor_position = 1
  121. end
  122. ui_manager:get_widget("ItemMenu.Container.ItemOrder.Cursor"):set_default_animation("Position" .. self.order_cursor_position)
  123. elseif button == Config.CONTROLS.UP then
  124. audio_manager:play_sound("Cursor")
  125. self.order_cursor_position = self.order_cursor_position - 1
  126. if self.order_cursor_position <= 0 then
  127. self.order_cursor_position = self.order_cursor_position_total
  128. end
  129. ui_manager:get_widget("ItemMenu.Container.ItemOrder.Cursor"):set_default_animation("Position" .. self.order_cursor_position)
  130. elseif button == Config.ACTIONS.CONFIRM then
  131. audio_manager:play_sound("Cursor")
  132. if self.order_cursor_position == 1 then
  133. Inventory.sort(Inventory.ORDER.CUSTOM)
  134. elseif self.order_cursor_position == 2 then
  135. Inventory.sort(Inventory.ORDER.FIELD)
  136. elseif self.order_cursor_position == 3 then
  137. Inventory.sort(Inventory.ORDER.BATTLE)
  138. elseif self.order_cursor_position == 4 then
  139. Inventory.sort(Inventory.ORDER.THROW)
  140. elseif self.order_cursor_position == 5 then
  141. Inventory.sort(Inventory.ORDER.TYPE)
  142. elseif self.order_cursor_position == 6 then
  143. Inventory.sort(Inventory.ORDER.NAME)
  144. elseif self.order_cursor_position == 7 then
  145. Inventory.sort(Inventory.ORDER.MOST)
  146. elseif self.order_cursor_position == 8 then
  147. Inventory.sort(Inventory.ORDER.LEAST)
  148. end
  149. self.populate_items(self)
  150. self.submenu_bar(self)
  151. end
  152. elseif UiContainer.current_submenu == "item_selection" then
  153. local cursor = ui_manager:get_widget("ItemMenu.Container.ItemList.Cursor")
  154. local desc_label = ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText")
  155. if button == Config.CONTROLS.DOWN then
  156. if self.item_cursor_item_selected >= self.inventory_size then
  157. -- At the very end, do nothing
  158. audio_manager:play_sound("Error")
  159. return 0
  160. end
  161. audio_manager:play_sound("Cursor")
  162. self.item_cursor_item_selected = self.item_cursor_item_selected + 1
  163. if self.item_cursor_position == self.item_cursor_position_total then
  164. -- The cursor is at the end. Scroll page, but dont change cursor.
  165. self.first_item_in_window = self.first_item_in_window + 1
  166. self.populate_items(self)
  167. else
  168. -- The cursor is not at the end, move cursor down.
  169. self.item_cursor_position = self.item_cursor_position + 1
  170. end
  171. cursor:set_default_animation("Position" .. self.item_cursor_position)
  172. -- If an item is selected, show description
  173. self.show_item_description(self)
  174. elseif button == Config.CONTROLS.UP then
  175. if self.item_cursor_item_selected <= 1 then
  176. -- At the very begining, do nothing
  177. audio_manager:play_sound("Error")
  178. return 0
  179. end
  180. audio_manager:play_sound("Cursor")
  181. self.item_cursor_item_selected = self.item_cursor_item_selected - 1
  182. if self.item_cursor_position == 1 then
  183. -- The cursor is at the end. Scroll page, but dont change cursor.
  184. self.first_item_in_window = self.first_item_in_window - 1
  185. self.populate_items(self)
  186. else
  187. -- The cursor is not at the end, move cursor down.
  188. self.item_cursor_position = self.item_cursor_position - 1
  189. end
  190. cursor:set_default_animation("Position" .. self.item_cursor_position)
  191. -- If an item is selected, show description
  192. self.show_item_description(self)
  193. elseif button == Config.ACTIONS.R1 then
  194. if self.first_item_in_window + self.item_cursor_position_total < self.inventory_size - self.item_cursor_position_total then
  195. audio_manager:play_sound("Cursor")
  196. self.item_cursor_item_selected = self.item_cursor_item_selected + self.item_cursor_position_total
  197. self.first_item_in_window = self.first_item_in_window + self.item_cursor_position_total
  198. self.populate_items(self)
  199. self.show_item_description(self)
  200. else
  201. audio_manager:play_sound("Error")
  202. end
  203. elseif button == Config.ACTIONS.L1 then
  204. if self.first_item_in_window - self.item_cursor_position_total >= 0 then
  205. audio_manager:play_sound("Cursor")
  206. self.item_cursor_item_selected = self.item_cursor_item_selected - self.item_cursor_position_total
  207. self.first_item_in_window = self.first_item_in_window - self.item_cursor_position_total
  208. self.populate_items(self)
  209. self.show_item_description(self)
  210. else
  211. audio_manager:play_sound("Error")
  212. end
  213. elseif button == Config.ACTIONS.CANCEL and event == "Press" then
  214. audio_manager:play_sound("Back")
  215. self.submenu_bar(self)
  216. UiContainer.current_submenu = "bar_selection"
  217. ui_manager:get_widget("ItemMenu.Container.ItemList.Cursor"):set_visible(false)
  218. elseif button == Config.ACTIONS.CONFIRM then
  219. local selected = Inventory[self.item_cursor_item_selected]
  220. if selected ~= nil and Game.Items[selected.item].menu == 1 then
  221. audio_manager:play_sound("Cursor")
  222. self.item_in_use = selected.item
  223. if (Game.Items[selected.item].target.default_multiple) == 1 then
  224. self.item_in_use_party = true
  225. self.submenu_chars(self, true)
  226. else
  227. self.item_in_use_party = false
  228. self.submenu_chars(self, false)
  229. end
  230. else
  231. audio_manager:play_sound("Error")
  232. end
  233. end
  234. elseif UiContainer.current_submenu == "char_selection" then
  235. if button == Config.CONTROLS.DOWN then
  236. if self.item_in_use_party == true then
  237. return 0
  238. else
  239. audio_manager:play_sound("Cursor")
  240. self.char_position = self.char_position + 1
  241. if self.char_position > self.char_position_total then
  242. self.char_position = 1
  243. end
  244. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_default_animation("Position" .. self.char_position)
  245. end
  246. elseif button == Config.CONTROLS.UP then
  247. if self.item_in_use_party == true then
  248. return 0
  249. else
  250. audio_manager:play_sound("Cursor")
  251. self.char_position = self.char_position - 1
  252. if self.char_position < 1 then
  253. self.char_position = self.char_position_total
  254. end
  255. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_default_animation("Position" .. self.char_position)
  256. end
  257. elseif button == Config.ACTIONS.CANCEL then
  258. audio_manager:play_sound("Back")
  259. self.submenu_items(self)
  260. elseif button == Config.ACTIONS.CONFIRM then
  261. local use_result = false
  262. if self.item_in_use_party == true then
  263. use_result = self.use_item(self, self.item_in_use, nil)
  264. else
  265. use_result = self.use_item(self, self.item_in_use, self.char_position)
  266. end
  267. if use_result == false then
  268. audio_manager:play_sound("Error")
  269. else
  270. -- TODO: Audio here? or in use_item?
  271. end
  272. end
  273. elseif UiContainer.current_submenu == "key_item_selection" then
  274. if button == Config.CONTROLS.DOWN then
  275. if self.key_items_cursor_y_position == self.key_items_cursor_y_position_total and self.first_key_item_row_in_window == self.key_items_total_rows - self.key_items_cursor_y_position then
  276. -- Last key item selected, do nothing
  277. audio_manager:play_sound("Error")
  278. return 0
  279. end
  280. audio_manager:play_sound("Cursor")
  281. if self.key_items_cursor_y_position == self.key_items_cursor_y_position_total then
  282. -- Scroll down by 1, don't move cursor
  283. self.first_key_item_row_in_window = self.first_key_item_row_in_window + 1
  284. self.populate_key_items(self)
  285. else
  286. -- Move cursor down by 1.
  287. self.key_items_cursor_y_position = self.key_items_cursor_y_position + 1
  288. end
  289. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_default_animation("Position" .. self.key_items_cursor_y_position .. "-" .. self.key_items_cursor_x_position)
  290. -- Show description of the selected item, if any.
  291. local k_selected_id = 2 * (self.first_key_item_row_in_window + self.key_items_cursor_y_position - 2) + self.key_items_cursor_x_position - 1
  292. if (Inventory.key[k_selected_id] == true) then
  293. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text(Game.Key_Items[k_selected_id].description)
  294. else
  295. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  296. end
  297. elseif button == Config.CONTROLS.UP then
  298. if self.key_items_cursor_y_position == 1 and self.first_key_item_row_in_window == 1 then
  299. -- First item, do nothing.
  300. audio_manager:play_sound("Error")
  301. return 0
  302. end
  303. audio_manager:play_sound("Cursor")
  304. if self.key_items_cursor_y_position == 1 then
  305. -- Scroll down by 1, don't move cursor
  306. self.first_key_item_row_in_window = self.first_key_item_row_in_window - 1
  307. self.populate_key_items(self)
  308. else
  309. -- Move cursor up by 1.
  310. self.key_items_cursor_y_position = self.key_items_cursor_y_position - 1
  311. end
  312. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_default_animation("Position" .. self.key_items_cursor_y_position .. "-" .. self.key_items_cursor_x_position)
  313. -- Show description of the selected item, if any.
  314. local k_selected_id = 2 * (self.first_key_item_row_in_window + self.key_items_cursor_y_position - 2) + self.key_items_cursor_x_position - 1
  315. if (Inventory.key[k_selected_id] == true) then
  316. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text(Game.Key_Items[k_selected_id].description)
  317. else
  318. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  319. end
  320. elseif button == Config.CONTROLS.RIGHT then
  321. local k_selected_id = 2 * (self.first_key_item_row_in_window + self.key_items_cursor_y_position - 2) + self.key_items_cursor_x_position - 1
  322. if k_selected_id >= 50 then
  323. -- Already in last item, do nothing
  324. audio_manager:play_sound("Error")
  325. return 0
  326. end
  327. audio_manager:play_sound("Cursor")
  328. k_selected_id = k_selected_id + 1
  329. if self.key_items_cursor_x_position == 1 then
  330. -- If on the left, move to the right. No scrolling.
  331. self.key_items_cursor_x_position = 2
  332. else
  333. -- If on the right, move to left and one row down...
  334. self.key_items_cursor_x_position = 1
  335. if self.key_items_cursor_y_position == self.key_items_cursor_y_position_total then
  336. -- ... by scrolling down by 1, not moving cursor.
  337. self.first_key_item_row_in_window = self.first_key_item_row_in_window + 1
  338. self.populate_key_items(self)
  339. else
  340. -- ... by moving the cursor down.
  341. self.key_items_cursor_y_position = self.key_items_cursor_y_position + 1
  342. end
  343. end
  344. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_default_animation("Position" .. self.key_items_cursor_y_position .. "-" .. self.key_items_cursor_x_position)
  345. -- Show description of the selected item, if any.
  346. if (Inventory.key[k_selected_id] == true) then
  347. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text(Game.Key_Items[k_selected_id].description)
  348. else
  349. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  350. end
  351. elseif button == Config.CONTROLS.LEFT then
  352. local k_selected_id = 2 * (self.first_key_item_row_in_window + self.key_items_cursor_y_position - 2) + self.key_items_cursor_x_position - 1
  353. if k_selected_id <= 0 then
  354. -- Already in first item, do nothing
  355. audio_manager:play_sound("Error")
  356. return 0
  357. end
  358. audio_manager:play_sound("Cursor")
  359. k_selected_id = k_selected_id - 1
  360. if self.key_items_cursor_x_position == 2 then
  361. -- If on the right, move to the left. No scrolling.
  362. self.key_items_cursor_x_position = 1
  363. else
  364. -- If on the left, move to right and one row up...
  365. self.key_items_cursor_x_position = 2
  366. if self.key_items_cursor_y_position == 1 then
  367. -- ... by scrolling up by 1, not moving cursor.
  368. self.first_key_item_row_in_window = self.first_key_item_row_in_window - 1
  369. self.populate_key_items(self)
  370. else
  371. -- ... by moving the cursor up.
  372. self.key_items_cursor_y_position = self.key_items_cursor_y_position - 1
  373. end
  374. end
  375. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_default_animation("Position" .. self.key_items_cursor_y_position .. "-" .. self.key_items_cursor_x_position)
  376. -- Show description of the selected item, if any.
  377. if (Inventory.key[k_selected_id] == true) then
  378. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text(Game.Key_Items[k_selected_id].description)
  379. else
  380. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  381. end
  382. elseif button == Config.ACTIONS.R1 then
  383. if self.first_key_item_row_in_window + self.key_items_cursor_y_position_total < self.key_items_total_rows - self.key_items_cursor_y_position_total then
  384. audio_manager:play_sound("Cursor")
  385. self.first_key_item_row_in_window = self.first_key_item_row_in_window + self.key_items_cursor_y_position_total
  386. self.populate_items(self)
  387. -- Show description of the selected item, if any.
  388. local k_selected_id = 2 * (self.first_key_item_row_in_window + self.key_items_cursor_y_position - 2) + self.key_items_cursor_x_position - 1
  389. if (Inventory.key[k_selected_id] == true) then
  390. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text(Game.Key_Items[k_selected_id].description)
  391. else
  392. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  393. end
  394. else
  395. audio_manager:play_sound("Error")
  396. end
  397. elseif button == Config.ACTIONS.L1 then
  398. if self.first_key_item_row_in_window + self.key_items_cursor_y_position_total > 1 then
  399. audio_manager:play_sound("Cursor")
  400. self.first_key_item_row_in_window = self.first_key_item_row_in_window - self.key_items_cursor_y_position_total
  401. self.populate_items(self)
  402. -- Show description of the selected item, if any.
  403. local k_selected_id = 2 * (self.first_key_item_row_in_window + self.key_items_cursor_y_position - 2) + self.key_items_cursor_x_position - 1
  404. if (Inventory.key[k_selected_id] == true) then
  405. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text(Game.Key_Items[k_selected_id].description)
  406. else
  407. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  408. end
  409. else
  410. audio_manager:play_sound("Cursor")
  411. end
  412. elseif button == Config.ACTIONS.CANCEL then
  413. audio_manager:play_sound("Back")
  414. self.submenu_bar(self)
  415. end
  416. end
  417. end
  418. return 0
  419. end,
  420. --- Opens the main menu.
  421. --
  422. -- Populates and updates displayed data before opening.
  423. show = function(self)
  424. ui_manager:get_widget("ItemMenu"):set_visible(true)
  425. UiContainer.current_menu = "item"
  426. self.char_position_total = 0
  427. for c = 1, 3 do
  428. if Party[c] ~= nil then
  429. self.char_position_total = self.char_position_total + 1
  430. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(c), Characters[Party[c]])
  431. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(c) .. ".Portrait"):set_image("characters/" .. tostring(Party[c]) .. ".png")
  432. else
  433. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(c), nil)
  434. end
  435. end
  436. self.populate_items(self)
  437. self.populate_key_items(self)
  438. self.submenu_items(self)
  439. return 0;
  440. end,
  441. --- Initializes the selection of the menu section in the top bar.
  442. submenu_bar = function(self)
  443. UiContainer.current_submenu = "bar_selection"
  444. ui_manager:get_widget("ItemMenu.Container.ItemList.Cursor"):set_visible(false)
  445. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_visible(false)
  446. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.CursorMultiple"):set_visible(false)
  447. ui_manager:get_widget("ItemMenu.Container.ItemMenuTopBar.Cursor"):set_visible(true)
  448. ui_manager:get_widget("ItemMenu.Container.ItemMenuTopBar.Cursor"):set_default_animation("Position" .. self.bar_position)
  449. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  450. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_visible(false)
  451. ui_manager:get_widget("ItemMenu.Container.ItemOrder.Cursor"):set_visible(false)
  452. ui_manager:get_widget("ItemMenu.Container.ItemOrder"):set_visible(false)
  453. end,
  454. --- Initializes the sorting mode window.
  455. submenu_order = function(self)
  456. UiContainer.current_submenu = "order_selection"
  457. self.order_cursor_position = 1
  458. ui_manager:get_widget("ItemMenu.Container.ItemList.Cursor"):set_visible(false)
  459. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_visible(false)
  460. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.CursorMultiple"):set_visible(false)
  461. ui_manager:get_widget("ItemMenu.Container.ItemMenuTopBar.Cursor"):set_visible(false)
  462. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  463. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_visible(false)
  464. ui_manager:get_widget("ItemMenu.Container.ItemOrder"):set_visible(true)
  465. ui_manager:get_widget("ItemMenu.Container.ItemOrder.Cursor"):set_visible(true)
  466. ui_manager:get_widget("ItemMenu.Container.ItemOrder.Cursor"):set_default_animation("Position" .. self.order_cursor_position)
  467. end,
  468. --- Shows the description of the highlighted inventory item, or clears it if the slot is empty.
  469. show_item_description = function(self)
  470. local label = ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText")
  471. local entry = Inventory[self.item_cursor_item_selected]
  472. if entry ~= nil then
  473. label:set_text(Game.Items[entry.item].description)
  474. else
  475. label:set_text("")
  476. end
  477. end,
  478. --- Initializes the item selection selection mode.
  479. submenu_items = function(self)
  480. UiContainer.current_submenu = "item_selection"
  481. ui_manager:get_widget("ItemMenu.Container.ItemList.Cursor"):set_visible(true)
  482. ui_manager:get_widget("ItemMenu.Container.ItemList.Cursor"):set_default_animation("Position" .. self.item_cursor_position)
  483. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_visible(false)
  484. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.CursorMultiple"):set_visible(false)
  485. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_visible(false)
  486. ui_manager:get_widget("ItemMenu.Container.ItemOrder.Cursor"):set_visible(false)
  487. --ui_manager:get_widget("ItemMenu.Container.ItemMenuTopBar.Cursor"):set_visible(false)
  488. -- Show description of the very first item, if any.
  489. -- TODO: Selected, not first
  490. -- Show description of the selected item, if any.
  491. local k_selected_id = (self.first_key_item_row_in_window + self.key_items_cursor_y_position) * 2 + self.key_items_cursor_x_position
  492. if (Inventory.key[k_selected_id] == true) then
  493. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text(Game.Key_Items[k_selected_id].description)
  494. else
  495. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  496. end
  497. self.show_item_description(self)
  498. end,
  499. --- Initializes the character selection mode.
  500. submenu_chars = function(self, multiple)
  501. UiContainer.current_submenu = "char_selection"
  502. --ui_manager:get_widget("ItemMenu.Container.ItemList.Cursor"):set_visible(false)
  503. --ui_manager:get_widget("ItemMenu.Container.ItemMenuTopBar.Cursor"):set_visible(false)
  504. if (multiple == true) then
  505. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_visible(false)
  506. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.CursorMultiple"):set_visible(true)
  507. else
  508. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.CursorMultiple"):set_visible(false)
  509. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_visible(true)
  510. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_default_animation("Position" .. self.char_position)
  511. end
  512. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_visible(false)
  513. ui_manager:get_widget("ItemMenu.Container.ItemOrder.Cursor"):set_visible(false)
  514. end,
  515. --- Initializes the key item selection mode.
  516. submenu_key_items = function(self)
  517. UiContainer.current_submenu = "key_item_selection"
  518. ui_manager:get_widget("ItemMenu.Container.ItemList.Cursor"):set_visible(true)
  519. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.Cursor"):set_visible(false)
  520. ui_manager:get_widget("ItemMenu.Container.ItemMenuCharacters.CursorMultiple"):set_visible(false)
  521. ui_manager:get_widget("ItemMenu.Container.ItemOrder.Cursor"):set_visible(false)
  522. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_visible(true)
  523. ui_manager:get_widget("ItemMenu.Container.KeyItems.Cursor"):set_default_animation("Position" .. self.key_items_cursor_y_position .. "-" .. self.key_items_cursor_x_position)
  524. -- Show description of the selected item, if any.
  525. local k_selected_id = 2 * (self.first_key_item_row_in_window + self.key_items_cursor_y_position - 2) + self.key_items_cursor_x_position - 1
  526. if (Inventory.key[k_selected_id] == true) then
  527. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text(Game.Key_Items[k_selected_id].description)
  528. else
  529. ui_manager:get_widget("ItemMenu.Container.ItemMenuSecondBar.ItemText"):set_text("")
  530. end
  531. end,
  532. --- Uses an item from the menu.
  533. --
  534. -- Checks the item conditions. If they are valid, uses the item and discounts 1 from the
  535. -- inventory.
  536. --
  537. -- @param item The ID of the item being used.
  538. -- @param character_pos Position in the party of the character on which to use the item (1-3).
  539. -- If nil, the item affects the whole party.
  540. use_item = function(self, item, character_pos)
  541. char_id = -1
  542. if character_pos then
  543. -- Normal item, use in one character.
  544. char_id = Party[character_pos]
  545. end
  546. -- TODO: When HP MAX is fixed, use it instead of base.
  547. if Game.Items[item].dmg_formula == 2 then
  548. -- HP or MP heal: Potion, Hi-Potion, X-Potion, Ether, Turbo Ether, Phoenix Down
  549. if Game.Items[item].dmg_modifier == 6 then
  550. -- Partial restore: Potion, Hi-Potion, Ether
  551. if Game.Items[item].restore == 0 then
  552. -- Partial HP restore: Potion, Hi potion. Based on power.
  553. if char_id == -1 then
  554. return false
  555. end
  556. if Characters[char_id].stats.hp.current < Characters[char_id].stats.hp.base then
  557. Characters[char_id].stats.hp.current = Characters[char_id].stats.hp.current + (25 * Game.Items[item].power)
  558. if Characters[char_id].stats.hp.current > Characters[char_id].stats.hp.base then
  559. Characters[char_id].stats.hp.current = Characters[char_id].stats.hp.base
  560. end
  561. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  562. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  563. else
  564. return false
  565. end
  566. elseif Game.Items[item].restore == 1 then
  567. -- Partial MP restore: Ether. Based on power.
  568. if Characters[char_id].stats.mp.current < Characters[char_id].stats.mp.base then
  569. Characters[char_id].stats.mp.current = Characters[char_id].stats.mp.current + (25 * Game.Items[item].power)
  570. if Characters[char_id].stats.mp.current > Characters[char_id].stats.mp.base then
  571. Characters[char_id].stats.mp.current = Characters[char_id].stats.mp.base
  572. end
  573. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  574. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  575. else
  576. return false
  577. end
  578. end
  579. elseif Game.Items[item].dmg_modifier == 4 then
  580. -- Full restore: X-Potion, Turbo Ether or partial resurrect: Phoenix Down.
  581. if Game.Items[item].restore == 0 then
  582. -- Full HP restore: X-Potion. Power ignored.
  583. if char_id == -1 then
  584. return false
  585. end
  586. if Characters[char_id].stats.hp.current < Characters[char_id].stats.hp.base then
  587. Characters[char_id].stats.hp.current = Characters[char_id].stats.hp.base
  588. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  589. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  590. else
  591. return false
  592. end
  593. elseif Game.Items[item].restore == 1 then
  594. -- Full MP restore: Turbo ether. Power ignored.
  595. if Characters[char_id].stats.mp.current < Characters[char_id].stats.mp.base then
  596. Characters[char_id].stats.mp.current = Characters[char_id].stats.mp.base
  597. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  598. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  599. else
  600. return false
  601. end
  602. else
  603. -- Resurrect: Phoenix down. Power / 32 is the percent of max HP.
  604. if Characters[char_id].stats.hp.current == 0 then
  605. Characters[char_id].stats.hp.current = math.floor(Game.Items[item].power * Characters[char_id].stats.hp.current / 32)
  606. if Characters[char_id].stats.hp.current > Characters[char_id].stats.hp.base then
  607. Characters[char_id].stats.hp.current = Characters[char_id].stats.hp.base
  608. end
  609. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  610. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  611. else
  612. return false
  613. end
  614. end
  615. end
  616. elseif Game.Items[item].dmg_formula == 0 and Game.Items[item].dmg_modifier == 0 then
  617. -- Full HP and MP restore: Elixir, Megalixir
  618. if Game.Items[item].target.default_multiple == 0 then
  619. --Full HP and MP restore for single target: Elixir.
  620. if Characters[char_id].stats.hp.current < Characters[char_id].stats.hp.base or Characters[char_id].stats.mp.current < Characters[char_id].stats.mp.base then
  621. Characters[char_id].stats.hp.current = Characters[char_id].stats.hp.base
  622. Characters[char_id].stats.mp.current = Characters[char_id].stats.mp.base
  623. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  624. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  625. else
  626. return false
  627. end
  628. else
  629. --Full HP and MP restore for party: MegaElixir.
  630. local useable = false;
  631. for c = 1, 3 do
  632. if Characters[c] ~= nil then
  633. if Characters[c].stats.hp.current < Characters[c].stats.hp.base then
  634. useable = true
  635. elseif Characters[c].stats.mp.current < Characters[c].stats.mp.base then
  636. useable = true
  637. end
  638. end
  639. end
  640. if useable == true then
  641. for pos = 1, 3 do
  642. if Characters[Party[pos]] ~= nil then
  643. Characters[Party[pos]].stats.hp.current = Characters[Party[pos]].stats.hp.base
  644. Characters[Party[pos]].stats.mp.current = Characters[Party[pos]].stats.mp.base
  645. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(pos), Characters[Party[pos]])
  646. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(pos), Characters[Party[pos]])
  647. end
  648. end
  649. else
  650. return false
  651. end
  652. end
  653. elseif Game.Items[item].dmg_formula == 4 then
  654. -- Status change: Hyper, Tranquilizer
  655. if #(Game.Items[item].status) > 0 then
  656. for _, status in ipairs(Game.Items[item].status) do
  657. if status.status == 5 then
  658. -- Fury. Cure saddness or induce fury.
  659. local sadness_key = -1
  660. local fury_key = -1
  661. for st_key, st_val in ipairs(Characters[char_id].status) do
  662. if st_val == 4 then
  663. sadness_key = st_key
  664. elseif st_val == 5 then
  665. fury_key = st_key
  666. end
  667. end
  668. -- If fury already, donothing. If sad, cure. Else, apply fury.
  669. if fury_key ~= -1 then
  670. return false
  671. elseif sadness_key ~= -1 then
  672. table.remove(Characters[char_id].status, sadness_key)
  673. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  674. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  675. else
  676. table.insert(Characters[char_id].status, 5)
  677. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  678. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  679. end
  680. elseif status.status == 4 then
  681. -- Saddness. Cure fury or induce sadness.
  682. local sadness_key = -1
  683. local fury_key = -1
  684. for st_key, st_val in ipairs(Characters[char_id].status) do
  685. if st_val == 4 then
  686. sadness_key = st_key
  687. elseif st_val == 5 then
  688. fury_key = st_key
  689. end
  690. end
  691. -- If fury already, donothing. If sad, cure. Else, apply fury.
  692. if sadness_key ~= -1 then
  693. return false
  694. elseif fury_key ~= -1 then
  695. table.remove(Characters[char_id].status, fury_key)
  696. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  697. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  698. else
  699. table.insert(Characters[char_id].status, 4)
  700. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(character_pos), Characters[char_id])
  701. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(character_pos), Characters[char_id])
  702. end
  703. end
  704. end
  705. end
  706. elseif Game.Items[item].id == 70 then
  707. -- Tent. Can't be differenciated by other means other than ID. Full HP and MP restore for party.
  708. local useable = false;
  709. for c = 1, 3 do
  710. if Characters[c] ~= nil then
  711. if Characters[c].stats.hp.current < Characters[c].stats.hp.base then
  712. useable = true
  713. elseif Characters[c].stats.mp.current < Characters[c].stats.mp.base then
  714. useable = true
  715. end
  716. end
  717. end
  718. if useable == true then
  719. for pos = 1, 3 do
  720. if Characters[Party[pos]] ~= nil then
  721. Characters[Party[pos]].stats.hp.current = Characters[Party[pos]].stats.hp.base
  722. Characters[Party[pos]].stats.mp.current = Characters[Party[pos]].stats.mp.base
  723. UiContainer.populate_character_data("ItemMenu.Container.ItemMenuCharacters.Character" .. tostring(pos), Characters[Party[pos]])
  724. UiContainer.populate_character_data("MainMenu.Container.Characters.Character" .. tostring(pos), Characters[Party[pos]])
  725. end
  726. end
  727. else
  728. return false
  729. end
  730. elseif Game.Items[item].id == 71 then
  731. -- Power source. Can't be differenciated by other means other than ID. STR bonus + 1.
  732. -- Original game caps bonus at 255. V-Gears doesn't.
  733. Characters[char_id].stats.str.bonus = Characters[char_id].stats.str.bonus + 1
  734. elseif Game.Items[item].id == 72 then
  735. -- Guard source. Can't be differenciated by other means other than ID. VIT bonus + 1.
  736. -- Original game caps bonus at 255. V-Gears doesn't.
  737. Characters[char_id].stats.vit.bonus = Characters[char_id].stats.vit.bonus + 1
  738. elseif Game.Items[item].id == 73 then
  739. -- Magic source. Can't be differenciated by other means other than ID. MAG bonus + 1.
  740. -- Original game caps bonus at 255. V-Gears doesn't.
  741. Characters[char_id].stats.mag.bonus = Characters[char_id].stats.mag.bonus + 1
  742. elseif Game.Items[item].id == 74 then
  743. -- Mind source. Can't be differenciated by other means other than ID. SPR bonus + 1.
  744. -- Original game caps bonus at 255. V-Gears doesn't.
  745. Characters[char_id].stats.spr.bonus = Characters[char_id].stats.spr.bonus + 1
  746. elseif Game.Items[item].id == 75 then
  747. -- Speed source. Can't be differenciated by other means other than ID. DEX bonus + 1.
  748. -- Original game caps bonus at 255. V-Gears doesn't.
  749. Characters[char_id].stats.dex.bonus = Characters[char_id].stats.dex.bonus + 1
  750. elseif Game.Items[item].id == 76 then
  751. -- Luck source. Can't be differenciated by other means other than ID. LCK bonus + 1.
  752. -- Original game caps bonus at 255. V-Gears doesn't.
  753. Characters[char_id].stats.lck.bonus = Characters[char_id].stats.lck.bonus + 1
  754. elseif Game.Items[item].id == 87 then
  755. -- Omnislash. Can't be differenciated by other means other than ID.
  756. -- Functionality hardcoded here.
  757. if (char_id ~= 0) then
  758. -- TODO: Show some message
  759. return false
  760. end
  761. for l = 1, 3 do
  762. if Characters[0].limit.learned[l][1] == 0 or Characters[0].limit.learned[l][2] == 0 then
  763. -- Some limit not learned yet. Show some message.
  764. return false
  765. end
  766. end
  767. if Characters[0].limit.learned[4][1] == 1 then
  768. -- Already learned
  769. return false
  770. end
  771. Characters[0].limit.learned[4][1] = 1
  772. elseif Game.Items[item].id == 88 then
  773. -- Catastrophe. Can't be differenciated by other means other than ID.
  774. -- Functionality hardcoded here.
  775. if (char_id ~= 1) then
  776. -- TODO: Show some message
  777. return false
  778. end
  779. for l = 1, 3 do
  780. if Characters[1].limit.learned[l][1] == 0 or Characters[1].limit.learned[l][2] == 0 then
  781. -- Some limit not learned yet. Show some message.
  782. return false
  783. end
  784. end
  785. if Characters[1].limit.learned[4][1] == 1 then
  786. -- Already learned
  787. return false
  788. end
  789. Characters[1].limit.learned[4][1] = 1
  790. elseif Game.Items[item].id == 89 then
  791. -- Final Heaven. Can't be differenciated by other means other than ID.
  792. -- Functionality hardcoded here.
  793. if (char_id ~= 2) then
  794. -- TODO: Show some message
  795. return false
  796. end
  797. for l = 1, 3 do
  798. if Characters[2].limit.learned[l][1] == 2 or Characters[2].limit.learned[l][2] == 0 then
  799. -- Some limit not learned yet. Show some message.
  800. return false
  801. end
  802. end
  803. if Characters[2].limit.learned[4][1] == 1 then
  804. -- Already learned
  805. return false
  806. end
  807. Characters[2].limit.learned[4][1] = 1
  808. elseif Game.Items[item].id == 90 then
  809. -- Great Gospel. Can't be differenciated by other means other than ID.
  810. -- Functionality hardcoded here.
  811. if (char_id ~= 3) then
  812. -- TODO: Show some message
  813. return false
  814. end
  815. for l = 1, 3 do
  816. if Characters[3].limit.learned[l][1] == 0 or Characters[3].limit.learned[l][2] == 0 then
  817. -- Some limit not learned yet. Show some message.
  818. return false
  819. end
  820. end
  821. if Characters[3].limit.learned[4][1] == 1 then
  822. -- Already learned
  823. return false
  824. end
  825. Characters[3].limit.learned[4][1] = 1
  826. elseif Game.Items[item].id == 91 then
  827. -- Cosmo Memory. Can't be differenciated by other means other than ID.
  828. -- Functionality hardcoded here.
  829. if (char_id ~= 4) then
  830. -- TODO: Show some message
  831. return false
  832. end
  833. for l = 1, 3 do
  834. if Characters[4].limit.learned[l][1] == 0 or Characters[4].limit.learned[l][2] == 0 then
  835. -- Some limit not learned yet. Show some message.
  836. return false
  837. end
  838. end
  839. if Characters[4].limit.learned[4][1] == 1 then
  840. -- Already learned
  841. return false
  842. end
  843. Characters[4].limit.learned[4][1] = 1
  844. elseif Game.Items[item].id == 92 then
  845. -- All Creation. Can't be differenciated by other means other than ID.
  846. -- Functionality hardcoded here.
  847. if (char_id ~= 5) then
  848. -- TODO: Show some message
  849. return false
  850. end
  851. for l = 1, 3 do
  852. if Characters[5].limit.learned[l][1] == 0 or Characters[5].limit.learned[l][2] == 0 then
  853. -- Some limit not learned yet. Show some message.
  854. return false
  855. end
  856. end
  857. if Characters[5].limit.learned[4][1] == 1 then
  858. -- Already learned
  859. return false
  860. end
  861. Characters[5].limit.learned[4][1] = 1
  862. elseif Game.Items[item].id == 93 then
  863. -- Chaos. Can't be differenciated by other means other than ID.
  864. -- Functionality hardcoded here.
  865. if (char_id ~= 7) then
  866. -- TODO: Show some message
  867. return false
  868. end
  869. for l = 1, 3 do
  870. if Characters[7].limit.learned[l][1] == 0 then
  871. -- Some limit not learned yet. Show some message.
  872. return false
  873. end
  874. end
  875. if Characters[7].limit.learned[4][1] == 1 then
  876. -- Already learned
  877. return false
  878. end
  879. Characters[0].limit.learned[4][1] = 1
  880. elseif Game.Items[item].id == 94 then
  881. -- Highwind. Can't be differenciated by other means other than ID.
  882. -- Functionality hardcoded here.
  883. if (char_id ~= 8) then
  884. -- TODO: Show some message
  885. return false
  886. end
  887. for l = 1, 3 do
  888. if Characters[8].limit.learned[l][1] == 0 or Characters[8].limit.learned[l][2] == 0 then
  889. -- Some limit not learned yet. Show some message.
  890. return false
  891. end
  892. end
  893. if Characters[8].limit.learned[4][1] == 1 then
  894. -- Already learned
  895. return false
  896. end
  897. Characters[8].limit.learned[4][1] = 1
  898. elseif Game.Items[item].id == 98 then
  899. -- Save Crystal. Can't be differenciated by other means other than ID.
  900. -- TODO: Implement.
  901. return false
  902. end
  903. -- If this point has been reached, an item has been succesfully used.
  904. -- Discount it from the inventory.
  905. Inventory.remove_item(item, 1)
  906. self.populate_items(self)
  907. -- If it was the last item, go back to the list
  908. if Inventory.get_item_quantity(item) == 0 then
  909. self.submenu_items(self)
  910. end
  911. return true
  912. end,
  913. --- Populates the visible inventory entries.
  914. --
  915. -- 13 entries visible at a time.
  916. populate_items = function(self)
  917. local first_item_in_window = self.first_item_in_window
  918. for i = 1, self.item_cursor_position_total do
  919. local w_icon = ui_manager:get_widget("ItemMenu.Container.ItemList.Icon" .. tostring(i))
  920. local w_name = ui_manager:get_widget("ItemMenu.Container.ItemList.Name" .. tostring(i))
  921. local w_colon = ui_manager:get_widget("ItemMenu.Container.ItemList.Colon" .. tostring(i))
  922. local w_qty = ui_manager:get_widget("ItemMenu.Container.ItemList.Qty" .. tostring(i))
  923. local inventory_index = i + first_item_in_window
  924. if Inventory[inventory_index] == nil then
  925. w_icon:set_visible(false)
  926. w_name:set_visible(false)
  927. w_colon:set_visible(false)
  928. w_qty:set_visible(false)
  929. else
  930. local useable = Game.Items[Inventory[inventory_index].item].menu
  931. local type = Game.Items[Inventory[inventory_index].item].type
  932. -- TODO: Get icon.
  933. w_icon:set_visible(true)
  934. w_name:set_visible(true)
  935. w_colon:set_visible(true)
  936. w_qty:set_visible(true)
  937. -- TODO: Gray for unuseable
  938. if (useable == 1) then
  939. w_name:set_colour(1.0, 1.0, 1.0)
  940. w_colon:set_colour(1.0, 1.0, 1.0)
  941. w_qty:set_colour(1.0, 1.0, 1.0)
  942. else
  943. w_name:set_colour(0.6, 0.6, 0.6)
  944. w_colon:set_colour(0.6, 0.6, 0.6)
  945. w_qty:set_colour(0.6, 0.6, 0.6)
  946. end
  947. -- Item icon
  948. if type == Inventory.ITEM_TYPE.ITEM then
  949. w_icon:set_image("icons/item_item.png")
  950. elseif type == Inventory.ITEM_TYPE.ARMOR then
  951. w_icon:set_image("icons/item_armor.png")
  952. elseif type == Inventory.ITEM_TYPE.ACCESSORY then
  953. w_icon:set_image("icons/item_accessory.png")
  954. elseif type == Inventory.ITEM_TYPE.WEAPON then
  955. local users = Game.Items[Inventory[inventory_index].item].users
  956. for _, v in ipairs(users) do
  957. if v >= 0 and v <= 8 then
  958. w_icon:set_image("icons/item_weapon_" .. v .. ".png")
  959. break;
  960. end
  961. end
  962. end
  963. w_name:set_text(Game.Items[Inventory[inventory_index].item].name)
  964. w_qty:set_text(tostring(Inventory[inventory_index].quantity))
  965. w_colon:set_text(":") -- Refresh text to apply colour.
  966. end
  967. end
  968. -- Set scroll bar position
  969. local scroll = ui_manager:get_widget("ItemMenu.Container.ItemList.Scroll")
  970. -- first_item_in_window == 1 then Top -> 0%3
  971. -- first_item_in_window == inventory_size - first_item_in_window then top = 100%-21
  972. local percent = math.floor(self.first_item_in_window * 100 / (self.inventory_size - self.item_cursor_position_total))
  973. local fixed = -1 * math.floor(self.first_item_in_window * 17 / (self.inventory_size - self.item_cursor_position_total)) + 3
  974. scroll:set_y(percent, fixed)
  975. return
  976. end,
  977. --- Populates the visible key items entries.
  978. --
  979. -- 26 entries visible at a time (13 rows).
  980. populate_key_items = function(self)
  981. local first_key_item_row_in_window = self.first_key_item_row_in_window
  982. for i = 1, self.key_items_cursor_y_position_total do
  983. local label_left = ui_manager:get_widget("ItemMenu.Container.KeyItems.KeyItem" .. tostring(i) .. "-1")
  984. local label_right = ui_manager:get_widget("ItemMenu.Container.KeyItems.KeyItem" .. tostring(i) .. "-2")
  985. local left_item_index = (first_key_item_row_in_window + i - 2) * 2
  986. local right_item_index = left_item_index + 1
  987. if Inventory.has_key_item(left_item_index) == true then -- Left column
  988. label_left:set_text(Game.Key_Items[left_item_index].name)
  989. else
  990. label_left:set_text("")
  991. end
  992. if Inventory.has_key_item(right_item_index) == true then -- Right column
  993. label_right:set_text(Game.Key_Items[right_item_index].name)
  994. else
  995. label_right:set_text("")
  996. end
  997. end
  998. -- Set scroll bar position
  999. local scroll = ui_manager:get_widget("ItemMenu.Container.KeyItems.Scroll")
  1000. -- first_key_item_row_in_window == 1 then Top -> 0%3
  1001. -- first_key_item_row_in_window == key_items_total_rows - first_key_item_row_in_window = 100%-21
  1002. local percent = math.ceil((self.first_key_item_row_in_window - 1) * 100 / (self.key_items_total_rows - self.key_items_cursor_y_position_total))
  1003. local fixed = -1 * math.floor((self.first_key_item_row_in_window - 1) * 13 / (self.key_items_total_rows - self.key_items_cursor_y_position_total)) + 3
  1004. scroll:set_y(percent, fixed)
  1005. return
  1006. end,
  1007. --- Hides the item menu and goes back to the main menu.
  1008. hide = function(self)
  1009. ui_manager:get_widget("ItemMenu"):set_visible(false)
  1010. UiContainer.current_menu = "main"
  1011. UiContainer.current_submenu = ""
  1012. UiContainer.resume_menu("main")
  1013. return 0;
  1014. end,
  1015. }