materia_menu.lua 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. if UiContainer == nil then UiContainer = {} end
  2. --- The item menu.
  3. UiContainer.MateriaMenu = {
  4. --- Current header cursor row (1: Check/Weapon, 2: Order/Armor).
  5. header_position_row = 1,
  6. --- Current header cursor position (1: Check/Order, 2-9: Weapon/Armor slots).
  7. header_position = 1,
  8. --- Current header cursor max row.
  9. header_position_row_total = 2,
  10. --- Current header cursor max position.
  11. header_position_total = 9,
  12. --- ID of the character the menu is open for.
  13. char_id = -1,
  14. --- Cursor position in the materia list.
  15. list_position = 1,
  16. --- Max cursor postion in the materia list.
  17. list_position_total = 10,
  18. --- First visible position in the materia list
  19. list_first_visible = 1,
  20. --- Max materias in the list
  21. list_size = 200,
  22. --- Run when the menu is creaded.
  23. --
  24. -- It does nothing.
  25. on_start = function(self)
  26. return 0
  27. end,
  28. --- Handles button events.
  29. --
  30. -- For the current submenu, handles directional keys, enter and escape events.
  31. -- @param button Pressed direction or action name.
  32. -- @param event Trigger event. Normally, "Press".
  33. on_button = function(self, button, event)
  34. if UiContainer.current_menu == "materia" then
  35. if UiContainer.current_submenu == "" then
  36. -- TODO: Handle L1/R1 (change character)
  37. -- TODO: Handle square: Materia menu
  38. if button == Config.ACTIONS.CANCEL and event == "Press" then
  39. audio_manager:play_sound("Back")
  40. UiContainer.current_menu = "main"
  41. script:request_end_sync(Script.UI, "MateriaMenu", "hide", 0)
  42. elseif button == Config.CONTROLS.DOWN then
  43. audio_manager:play_sound("Cursor")
  44. self.header_position_row = self.header_position_row + 1
  45. if self.header_position_row > self.header_position_row_total then
  46. self.header_position_row = 1
  47. end
  48. ui_manager:get_widget("MateriaMenu.Container.Character.Cursor"):set_default_animation("Position" .. self.header_position_row .. "-" .. self.header_position)
  49. self.populate_details(self, false)
  50. elseif button == Config.CONTROLS.UP then
  51. audio_manager:play_sound("Cursor")
  52. self.header_position_row = self.header_position_row - 1
  53. if self.header_position_row < 1 then
  54. self.header_position_row = self.header_position_row_total
  55. end
  56. ui_manager:get_widget("MateriaMenu.Container.Character.Cursor"):set_default_animation("Position" .. self.header_position_row .. "-" .. self.header_position)
  57. self.populate_details(self, false)
  58. elseif button == Config.CONTROLS.RIGHT then
  59. audio_manager:play_sound("Cursor")
  60. self.header_position = self.header_position + 1
  61. if self.header_position > self.header_position_total then
  62. self.header_position = 1
  63. end
  64. ui_manager:get_widget("MateriaMenu.Container.Character.Cursor"):set_default_animation("Position" .. self.header_position_row .. "-" .. self.header_position)
  65. self.populate_details(self, false)
  66. elseif button == Config.CONTROLS.LEFT then
  67. audio_manager:play_sound("Cursor")
  68. self.header_position = self.header_position - 1
  69. if self.header_position < 1 then
  70. self.header_position = self.header_position_total
  71. end
  72. ui_manager:get_widget("MateriaMenu.Container.Character.Cursor"):set_default_animation("Position" .. self.header_position_row .. "-" .. self.header_position)
  73. self.populate_details(self, false)
  74. elseif button == Config.ACTIONS.CONFIRM then
  75. if self.header_position_row == 1 and self.header_position == 1 then
  76. -- TODO: Command menu
  77. elseif self.header_position_row == 2 and self.header_position == 1 then
  78. -- TODO: Order menu
  79. else
  80. -- TODO: Check for avalid slot before entering list
  81. if self.header_position_row == 1 and #(Game.Items[Characters[self.char_id].weapon.id].slots) > self.header_position - 2 then
  82. self.submenu_list(self)
  83. elseif self.header_position_row == 2 and #(Game.Items[Characters[self.char_id].armor.id].slots) > self.header_position -2 then
  84. self.submenu_list(self)
  85. else
  86. audio_manager:play_sound("Error")
  87. return 0
  88. end
  89. audio_manager:play_sound("Cursor")
  90. end
  91. -- TODO: Triangle->Remove
  92. else
  93. return 0
  94. end
  95. elseif UiContainer.current_submenu == "list" then
  96. if button == Config.CONTROLS.DOWN then
  97. if self.list_first_visible + self.list_position > self.list_size then
  98. -- At the very end, do nothing
  99. audio_manager:play_sound("Error")
  100. return 0
  101. end
  102. audio_manager:play_sound("Cursor")
  103. if self.list_position == self.list_position_total then
  104. -- The cursor is at the end. Scroll page, but dont change cursor.
  105. self.list_first_visible = self.list_first_visible + 1
  106. self.populate_list(self)
  107. else
  108. -- The cursor is not at the end, move cursor down.
  109. self.list_position = self.list_position + 1
  110. end
  111. ui_manager:get_widget("MateriaMenu.Container.List.Cursor"):set_default_animation("Position" .. self.list_position)
  112. -- Show details
  113. self.populate_details(self, true)
  114. elseif button == Config.CONTROLS.UP then
  115. if self.list_first_visible == 1 and self.list_position == 1 then
  116. -- At the very begining, do nothing
  117. audio_manager:play_sound("Error")
  118. return 0
  119. end
  120. audio_manager:play_sound("Cursor")
  121. if self.list_position == 1 then
  122. -- The cursor is at the end. Scroll page, but dont change cursor.
  123. self.list_first_visible = self.list_first_visible - 1
  124. self.populate_list(self)
  125. else
  126. -- The cursor is not at the end, move cursor down.
  127. self.list_position = self.list_position - 1
  128. end
  129. ui_manager:get_widget("MateriaMenu.Container.List.Cursor"):set_default_animation("Position" .. self.list_position)
  130. -- Show details
  131. self.populate_details(self, true)
  132. elseif button == Config.ACTIONS.R1 then
  133. if self.list_first_visible + self.list_position_total < self.list_size - self.list_position_total then
  134. audio_manager:play_sound("Cursor")
  135. self.list_first_visible = self.list_first_visible + self.list_position_total
  136. self.populate_list(self)
  137. self.populate_details(self, true)
  138. else
  139. audio_manager:play_sound("Error")
  140. end
  141. elseif button == Config.ACTIONS.L1 then
  142. if self.list_first_visible - self.list_position_total > 1 then
  143. audio_manager:play_sound("Cursor")
  144. self.list_first_visible = self.list_first_visible - self.list_position_total
  145. self.populate_list(self)
  146. self.populate_details(self, true)
  147. else
  148. audio_manager:play_sound("Error")
  149. end
  150. elseif button == Config.ACTIONS.CANCEL and event == "Press" then
  151. audio_manager:play_sound("Back")
  152. self.submenu_none(self)
  153. elseif button == Config.ACTIONS.CONFIRM then
  154. -- TODO: Replace for "Equip materia" sound.
  155. audio_manager:play_sound("Cursor")
  156. self.equip_materia(self)
  157. end
  158. end
  159. end
  160. return 0
  161. end,
  162. --- Opens the materia menu.
  163. --
  164. -- Populates and updates displayed data before opening.
  165. show = function(self)
  166. self.char_id = UiContainer.current_character_id
  167. ui_manager:get_widget("MateriaMenu"):set_visible(true)
  168. UiContainer.current_menu = "materia"
  169. UiContainer.current_submenu = ""
  170. self.header_position_row = 1
  171. self.header_position = 1
  172. self.list_position = 1
  173. self.list_first_visible = 1
  174. self.populate_list(self)
  175. self.submenu_none(self)
  176. self.populate_commands(self)
  177. return 0;
  178. end,
  179. --- Enters or returns to the main equip menu.
  180. submenu_none = function(self)
  181. UiContainer.current_submenu = ""
  182. UiContainer.populate_character_data("MateriaMenu.Container.Character", Characters[self.char_id])
  183. ui_manager:get_widget("MateriaMenu.Container.Character.Portrait"):set_image("characters/" .. tostring(self.char_id) .. ".png")
  184. self.populate_equip(self)
  185. -- TODO: Do something for chars 9 and 10
  186. ui_manager:get_widget("MateriaMenu.Container.Character.WpnIcon"):set_image("icons/item_weapon_" .. tostring(self.char_id) .. ".png")
  187. ui_manager:get_widget("MateriaMenu.Container.List.Cursor"):set_visible(false)
  188. --TODO: Uncomment when implemented: ui_manager:get_widget("MateriaMenu.Container.Order.Cursor"):set_visible(false)
  189. ui_manager:get_widget("MateriaMenu.Container.Character.Cursor"):set_visible(true)
  190. self.populate_details(self, false)
  191. end,
  192. submenu_list = function(self)
  193. UiContainer.current_submenu = "list"
  194. ui_manager:get_widget("MateriaMenu.Container.List.Cursor"):set_visible(true)
  195. self.populate_details(self, true)
  196. end,
  197. --- Populate the equipment section.
  198. --
  199. -- It fills the header with weapn and armor names, slots, and current materia.
  200. populate_equip = function(self)
  201. local weapon = Game.Items[Characters[self.char_id].weapon.id]
  202. local armor = Game.Items[Characters[self.char_id].armor.id]
  203. ui_manager:get_widget("MateriaMenu.Container.Character.WpnLbl"):set_text(weapon.name)
  204. ui_manager:get_widget("MateriaMenu.Container.Character.ArmLbl"):set_text(armor.name)
  205. for i = 1, 8 do
  206. -- Show/hide slots
  207. -- TODO: Change image for no-growth slots?
  208. if #(weapon.slots) >= i then
  209. ui_manager:get_widget("MateriaMenu.Container.Character.WeaponSlots.Slot" .. tostring(i)):set_visible(true)
  210. else
  211. ui_manager:get_widget("MateriaMenu.Container.Character.WeaponSlots.Slot" .. tostring(i)):set_visible(false)
  212. end
  213. if #(armor.slots) >= i then
  214. ui_manager:get_widget("MateriaMenu.Container.Character.ArmorSlots.Slot" .. tostring(i)):set_visible(true)
  215. else
  216. ui_manager:get_widget("MateriaMenu.Container.Character.ArmorSlots.Slot" .. tostring(i)):set_visible(false)
  217. end
  218. -- Show/hide linkers
  219. if i % 2 ~= 0 then
  220. if #(weapon.slots) > i and weapon.slots[i] == 1 then
  221. ui_manager:get_widget("MateriaMenu.Container.Character.WeaponSlots.Link" .. tostring(math.floor(i / 2) + 1)):set_visible(true)
  222. else
  223. ui_manager:get_widget("MateriaMenu.Container.Character.WeaponSlots.Link" .. tostring(math.floor(i / 2) + 1)):set_visible(false)
  224. end
  225. if #(armor.slots) > i and armor.slots[i] == 1 then
  226. ui_manager:get_widget("MateriaMenu.Container.Character.ArmorSlots.Link" .. tostring(math.floor(i / 2) + 1)):set_visible(true)
  227. else
  228. ui_manager:get_widget("MateriaMenu.Container.Character.ArmorSlots.Link" .. tostring(math.floor(i / 2) + 1)):set_visible(false)
  229. end
  230. end
  231. -- Show/hide/set materia
  232. if Characters[self.char_id].weapon.materia[i - 1] ~= nil then
  233. local mat_type = Game.Materia[Characters[self.char_id].weapon.materia[i - 1].id].type
  234. ui_manager:get_widget("MateriaMenu.Container.Character.WeaponSlots.Mat" .. tostring(i)):set_image("icons/materia_" .. tostring(mat_type) .. ".png")
  235. ui_manager:get_widget("MateriaMenu.Container.Character.WeaponSlots.Mat" .. tostring(i)):set_visible(true)
  236. else
  237. ui_manager:get_widget("MateriaMenu.Container.Character.WeaponSlots.Mat" .. tostring(i)):set_visible(false)
  238. end
  239. if Characters[self.char_id].armor.materia[i - 1] ~= nil then
  240. local mat_type = Game.Materia[Characters[self.char_id].armor.materia[i - 1].id].type
  241. ui_manager:get_widget("MateriaMenu.Container.Character.ArmorSlots.Mat" .. tostring(i)):set_image("icons/materia_" .. tostring(mat_type) .. ".png")
  242. ui_manager:get_widget("MateriaMenu.Container.Character.ArmorSlots.Mat" .. tostring(i)):set_visible(true)
  243. else
  244. ui_manager:get_widget("MateriaMenu.Container.Character.ArmorSlots.Mat" .. tostring(i)):set_visible(false)
  245. end
  246. end
  247. end,
  248. --- Hiddes the materia details.
  249. --
  250. -- Must be called when the cursor goes into an empty slot
  251. hide_details = function(self)
  252. -- TODO
  253. ui_manager:get_widget("MateriaMenu.Container.Details.Empty"):set_visible(true)
  254. ui_manager:get_widget("MateriaMenu.Container.Details.Commands"):set_visible(false)
  255. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill"):set_visible(false)
  256. ui_manager:get_widget("MateriaMenu.Container.Details.Materia"):set_visible(false)
  257. ui_manager:get_widget("MateriaMenu.Container.Help.Help"):set_text("")
  258. end,
  259. --- Show details of an enemy skill materia.
  260. --
  261. -- Must be called when the cursor goes over an enemy skill materia
  262. --
  263. -- @param materia Selected Enemy Skill materia.
  264. populate_e_skill_details = function(self, materia)
  265. if materia.id ~= Materia.ENEMY_SKILL_ID then
  266. print("ERROR: Tried to get enemy skill info form non-enemy skill materia with ID " .. tostring(materia.id))
  267. return 0
  268. elseif materia.skills == nil then
  269. print("ERROR: Enemy skill materia has no skill information")
  270. --return 0
  271. end
  272. ui_manager:get_widget("MateriaMenu.Container.Help.Help"):set_text(Game.Materia[materia.id].description)
  273. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill.Name"):set_text(Game.Materia[materia.id].name)
  274. ui_manager:get_widget("MateriaMenu.Container.Details.Empty"):set_visible(false)
  275. ui_manager:get_widget("MateriaMenu.Container.Details.Commands"):set_visible(false)
  276. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill"):set_visible(true)
  277. ui_manager:get_widget("MateriaMenu.Container.Details.Materia"):set_visible(false)
  278. for s = 1, 24 do
  279. if materia.skills[s] ~= nil and materia.skills[s] == true then
  280. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill.Stars.Star" .. tostring(s)):set_image("icons/materia_star_3.png")
  281. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill.Skills.Skill" .. tostring(s)):set_text(Game.Attacks[71 + s].name)
  282. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill.Skills.Skill" .. tostring(s)):set_visible(true)
  283. else
  284. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill.Stars.Star" .. tostring(s)):set_image("icons/materia_star_empty_3.png")
  285. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill.Skills.Skill" .. tostring(s)):set_visible(false)
  286. end
  287. end
  288. end,
  289. --- Displays the command list in the details window
  290. populate_commands = function(self)
  291. ui_manager:get_widget("MateriaMenu.Container.Details.Empty"):set_visible(false)
  292. ui_manager:get_widget("MateriaMenu.Container.Details.Commands"):set_visible(true)
  293. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill"):set_visible(false)
  294. ui_manager:get_widget("MateriaMenu.Container.Details.Materia"):set_visible(false)
  295. ui_manager:get_widget("MateriaMenu.Container.Help.Help"):set_text("")
  296. -- TODO
  297. end,
  298. --- Populated the details of the selected header item (check, materia, or none).
  299. --
  300. -- @param from_list If true, data will be read from the item higlighted in the list on the
  301. -- right. If false, data wil be red from the currently equipped items.
  302. populate_details = function(self, from_list)
  303. local id
  304. local ap
  305. local ap_next
  306. local level
  307. local max_level
  308. local master = false
  309. local materia -- Materia static information, as in Game.Materia[]
  310. local materia_selected -- Materia instance information, as in Materia[]
  311. if from_list == false then
  312. -- Get data from equiped materia
  313. if self.header_position_row == 1 then
  314. -- "Check" highlighted
  315. if self.header_position == 1 then
  316. self.populate_commands(self)
  317. return 0
  318. end
  319. -- Weapon materia
  320. local weapon_id = Characters[self.char_id].weapon.id
  321. local weapon = Game.Items[weapon_id]
  322. if #(weapon.slots) < self.header_position -1 or Characters[self.char_id].weapon.materia[self.header_position - 2] == nil then
  323. -- No slot or no materia in slot. Clear and exit
  324. self.hide_details(self)
  325. return 0
  326. end
  327. materia_selected = Characters[self.char_id].weapon.materia[self.header_position - 2]
  328. id = Characters[self.char_id].weapon.materia[self.header_position - 2].id
  329. ap = Characters[self.char_id].weapon.materia[self.header_position - 2].ap
  330. materia = Game.Materia[id]
  331. elseif self.header_position_row == 2 then
  332. -- "Order" highlighted
  333. if self.header_position == 1 then
  334. self.hide_details(self)
  335. return 0
  336. end
  337. -- Armor materia
  338. local armor_id = Characters[self.char_id].armor.id
  339. local armor = Game.Items[armor_id]
  340. if #(armor.slots) < self.header_position - 1 or Characters[self.char_id].armor.materia[self.header_position - 2] == nil then
  341. -- No slot or no materia in slot. Clear and exit
  342. self.hide_details(self)
  343. return 0
  344. end
  345. materia_selected = Characters[self.char_id].armor.materia[self.header_position - 2]
  346. id = Characters[self.char_id].armor.materia[self.header_position - 2].id
  347. ap = Characters[self.char_id].armor.materia[self.header_position - 2].ap
  348. materia = Game.Materia[id]
  349. else
  350. -- This should not happen, but just in case.
  351. self.hide_details(self)
  352. return 0
  353. end
  354. else
  355. --Get materia data from list.
  356. local mat_position = self.list_first_visible + self.list_position - 1
  357. if Materia[mat_position] == nil then
  358. self.hide_details(self)
  359. return 0
  360. end
  361. materia_selected = Materia[mat_position]
  362. id = Materia[mat_position].id
  363. ap = Materia[mat_position].ap
  364. materia = Game.Materia[Materia[mat_position].id]
  365. end
  366. -- Materia should be set, but just in case, one last check.
  367. if materia == nil then
  368. self.hide_details(self)
  369. return
  370. end
  371. -- Check for enemy skill. It is handled by another function.
  372. if id == Materia.ENEMY_SKILL_ID then
  373. self.populate_e_skill_details(self, materia_selected)
  374. return 0
  375. end
  376. ui_manager:get_widget("MateriaMenu.Container.Details.Empty"):set_visible(false)
  377. ui_manager:get_widget("MateriaMenu.Container.Details.Commands"):set_visible(false)
  378. ui_manager:get_widget("MateriaMenu.Container.Details.EnemySkill"):set_visible(false)
  379. ui_manager:get_widget("MateriaMenu.Container.Details.Materia"):set_visible(true)
  380. ui_manager:get_widget("MateriaMenu.Container.Help.Help"):set_text(Game.Materia[id].description)
  381. -- Get level and max level, and check for master.
  382. level = 0
  383. for lv, lv_ap in ipairs(materia.levels_ap) do
  384. if lv_ap > ap then
  385. break
  386. end
  387. level = level + 1
  388. end
  389. max_level = #(materia.levels_ap)
  390. if level == max_level then
  391. master = true
  392. ap_next = 0
  393. else
  394. ap_next = materia.levels_ap[level + 1] - ap
  395. end
  396. -- Start displaying data
  397. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Icon"):set_image("icons/materia_" .. tostring(materia.type) .. ".png")
  398. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Name"):set_text(materia.name)
  399. for l = 1, 5 do
  400. if l > max_level then
  401. -- No such level, hide star.
  402. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Stars.Star" .. tostring(l)):set_visible(false)
  403. else
  404. if l <= level then
  405. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Stars.Star" .. tostring(l)):set_image("icons/materia_star_" .. tostring(materia.type) .. ".png")
  406. else
  407. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Stars.Star" .. tostring(l)):set_image("icons/materia_star_empty_" .. tostring(materia.type) .. ".png")
  408. end
  409. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Stars.Star" .. tostring(l)):set_visible(true)
  410. end
  411. end
  412. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.AP"):set_text(UiContainer.pad_value(ap, 6))
  413. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.APNext"):set_text(UiContainer.pad_value(ap_next, 6))
  414. --ui_manager:get_widget("MateriaMenu.Container.Details.Materia.AP"):set_text(UiContainer.pad_value(200000, 6))
  415. --ui_manager:get_widget("MateriaMenu.Container.Details.Materia.APNext"):set_text(UiContainer.pad_value(30000, 6))
  416. -- Hide all attacks
  417. for a = 1, 5 do
  418. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(a)):set_visible(false)
  419. end
  420. -- Show attacks, vary by type
  421. if materia.type == Materia.TYPE.MAGIC then
  422. local attack_index = 1
  423. for attack_level, attack_id in pairs(materia.magic) do
  424. if level >= attack_level then
  425. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(attack_index)):set_colour(1, 1, 1)
  426. else
  427. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(attack_index)):set_colour(0.6, 0.6, 0.6)
  428. end
  429. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(attack_index)):set_text(Game.Attacks[attack_id].name)
  430. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(attack_index)):set_visible(true)
  431. attack_index = attack_index + 1
  432. end
  433. elseif materia.type == Materia.TYPE.SUMMON then
  434. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_colour(1, 1, 1)
  435. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_text(Game.Attacks[materia.summon].name)
  436. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_visible(true)
  437. elseif materia.type == Materia.TYPE.COMMAND then
  438. local attack_index = 1
  439. for attack_level, attack_id in ipairs(materia.command) do
  440. if level >= attack_level then
  441. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(attack_index)):set_colour(1, 1, 1)
  442. else
  443. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(attack_index)):set_colour(0.6, 0.6, 0.6)
  444. end
  445. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(attack_index)):set_text(Game.Commands[attack_id].name)
  446. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability" .. tostring(attack_index)):set_visible(true)
  447. attack_index = attack_index + 1
  448. end
  449. elseif materia.type == Materia.TYPE.INDEPENDENT then
  450. local bonus = 0
  451. for l = 1, max_level do
  452. if l <= level and materia.ability.param[l] ~= nil then
  453. bonus = materia.ability.param[l]
  454. end
  455. end
  456. if materia.ability ~= nil then
  457. local text = "TEXT"
  458. if materia.ability.id == Materia.ABILITY.MP_PLUS then
  459. text = "<include name=\"StatMP\"/> +<colour value=\"1 1 0\">" .. tostring(bonus) .. "</colour>%"
  460. elseif materia.ability.id == Materia.ABILITY.HP_PLUS then
  461. text = "<include name=\"StatHP\"/> +<colour value=\"1 1 0\">" .. tostring(bonus) .. "</colour>%"
  462. elseif materia.ability.id == Materia.ABILITY.STR_PLUS then
  463. text = "<include name=\"StatStr\"/> +<colour value=\"1 1 0\">" .. tostring(bonus) .. "</colour>%"
  464. elseif materia.ability.id == Materia.ABILITY.VIT_PLUS then
  465. text = "<include name=\"StatVit\"/> +<colour value=\"1 1 0\">" .. tostring(bonus) .. "</colour>%"
  466. elseif materia.ability.id == Materia.ABILITY.MAG_PLUS then
  467. text = "<include name=\"StatMag\"/> +<colour value=\"1 1 0\">" .. tostring(bonus) .. "</colour>%"
  468. elseif materia.ability.id == Materia.ABILITY.DEX_PLUS then
  469. text = "<include name=\"StatDex\"/> +<colour value=\"1 1 0\">" .. tostring(bonus) .. "</colour>%"
  470. elseif materia.ability.id == Materia.ABILITY.LCK_PLUS then
  471. text = "<include name=\"StatLck\"/> +<colour value=\"1 1 0\">" .. tostring(bonus) .. "</colour>%"
  472. elseif materia.ability.id == Materia.ABILITY.EXP_PLUS then
  473. text = "<include name=\"StatEXP\"/> +"
  474. elseif materia.ability.id == Materia.ABILITY.MONEY_PLUS then
  475. text = "<include name=\"Currency\"/> +"
  476. elseif materia.ability.id == Materia.ABILITY.ENCOUNTER_DOWN then
  477. text = "<include name=\"MateriaEncounters\"/> -"
  478. elseif materia.ability.id == Materia.ABILITY.ENCOUNTER_UP then
  479. text = "<include name=\"MateriaEncountersChocobo\"/> -"
  480. elseif materia.ability.id == Materia.ABILITY.PREEMPTIVE then
  481. text = materia.name
  482. elseif materia.ability.id == Materia.ABILITY.LONG_RANGE then
  483. text = materia.name
  484. elseif materia.ability.id == Materia.ABILITY.MEGA_ALL then
  485. text = materia.name
  486. elseif materia.ability.id == Materia.ABILITY.COUNTER_ATTACK then
  487. text = materia.name
  488. elseif materia.ability.id == Materia.ABILITY.COVER then
  489. text = materia.name .. " +<colour value=\"1 1 0\">" .. tostring(bonus) .. "</colour>%"
  490. elseif materia.ability.id == Materia.ABILITY.UNDERWATER then
  491. text = materia.name
  492. elseif materia.ability.id == Materia.ABILITY.HP_MP then
  493. text = materia.name
  494. end
  495. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_colour(1, 1, 1)
  496. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_text(text)
  497. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_visible(true)
  498. end
  499. elseif materia.type == Materia.TYPE.SUPPORT then
  500. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_colour(1, 1, 1)
  501. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_text(materia.name)
  502. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Abilities.Ability1"):set_visible(true)
  503. end
  504. -- Hide all effects
  505. for a = 1, 7 do
  506. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(a)):set_visible(false)
  507. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(a)):set_visible(false)
  508. end
  509. -- Show effects, if any.
  510. local effect_index = 1
  511. if materia.stats.str ~= nil and materia.stats.str ~= 0 then
  512. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_text("<include name=\"StatStr\" />")
  513. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_visible(true)
  514. if materia.stats.str < 0 then
  515. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 0 0\">-" .. UiContainer.pad_value(-1 * materia.stats.str, 2) .. "</colour>")
  516. else
  517. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 1 0\">+" .. UiContainer.pad_value(materia.stats.str, 2) .. "</colour>")
  518. end
  519. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_visible(true)
  520. effect_index = effect_index + 1
  521. end
  522. if materia.stats.vit ~= nil and materia.stats.vit ~= 0 then
  523. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_text("<include name=\"StatVit\" />")
  524. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_visible(true)
  525. if materia.stats.vit < 0 then
  526. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 0 0\">-" .. UiContainer.pad_value(-1 * materia.stats.vit, 2) .. "</colour>")
  527. else
  528. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 1 0\">+" .. UiContainer.pad_value(materia.stats.vit, 2) .. "</colour>")
  529. end
  530. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_visible(true)
  531. effect_index = effect_index + 1
  532. end
  533. if materia.stats.mag ~= nil and materia.stats.mag ~= 0 then
  534. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_text("<include name=\"StatMag\" />")
  535. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_visible(true)
  536. if materia.stats.mag < 0 then
  537. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 0 0\">-" .. UiContainer.pad_value(-1 * materia.stats.mag, 2) .. "</colour>")
  538. else
  539. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 1 0\">+" .. UiContainer.pad_value(materia.stats.mag, 2) .. "</colour>")
  540. end
  541. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_visible(true)
  542. effect_index = effect_index + 1
  543. end
  544. if materia.stats.spr ~= nil and materia.stats.spr ~= 0 then
  545. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_text("<include name=\"StatSpr\" />")
  546. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_visible(true)
  547. if materia.stats.spr < 0 then
  548. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 0 0\">-" .. UiContainer.pad_value(-1 * materia.stats.spr, 2) .. "</colour>")
  549. else
  550. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 1 0\">+" .. UiContainer.pad_value(materia.stats.spr, 2) .. "</colour>")
  551. end
  552. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_visible(true)
  553. effect_index = effect_index + 1
  554. end
  555. if materia.stats.dex ~= nil and materia.stats.dex ~= 0 then
  556. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_text("<include name=\"StatDex\" />")
  557. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_visible(true)
  558. if materia.stats.dex < 0 then
  559. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 0 0\">-" .. UiContainer.pad_value(-1 * materia.stats.dex, 2) .. "</colour>")
  560. else
  561. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 1 0\">+" .. UiContainer.pad_value(materia.stats.dex, 2) .. "</colour>")
  562. end
  563. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_visible(true)
  564. effect_index = effect_index + 1
  565. end
  566. if materia.stats.lck ~= nil and materia.stats.lck ~= 0 then
  567. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_text("<include name=\"StatLck\" />")
  568. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_visible(true)
  569. if materia.stats.lck < 0 then
  570. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 0 0\">-" .. UiContainer.pad_value(-1 * materia.stats.lck, 2) .. "</colour>")
  571. else
  572. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 1 0\">+" .. UiContainer.pad_value(materia.stats.lck, 2) .. "</colour>")
  573. end
  574. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_visible(true)
  575. effect_index = effect_index + 1
  576. end
  577. if materia.stats.hp ~= nil and materia.stats.hp ~= 0 then
  578. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_text("<include name=\"StatHP\" />")
  579. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_visible(true)
  580. if materia.stats.hp < 0 then
  581. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 0 0\">-" .. UiContainer.pad_value(-1 * materia.stats.hp, 2) .. "%</colour>")
  582. else
  583. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 1 0\">+" .. UiContainer.pad_value(materia.stats.hp, 2) .. "%</colour>")
  584. end
  585. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_visible(true)
  586. effect_index = effect_index + 1
  587. end
  588. if materia.stats.mp ~= nil and materia.stats.mp ~= 0 then
  589. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_text("<include name=\"StatMP\" />")
  590. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Stat" .. tostring(effect_index)):set_visible(true)
  591. if materia.stats.mp < 0 then
  592. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 0 0\">-" .. UiContainer.pad_value(-1 * materia.stats.mp, 2) .. "%</colour>")
  593. else
  594. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_text("<colour value=\"1 1 0\">+" .. UiContainer.pad_value(materia.stats.mp, 2) .. "%</colour>")
  595. end
  596. ui_manager:get_widget("MateriaMenu.Container.Details.Materia.Effects.Val" .. tostring(effect_index)):set_visible(true)
  597. effect_index = effect_index + 1
  598. end
  599. end,
  600. --- Populates the materia list.
  601. populate_list = function(self)
  602. local pos = 1
  603. for i = self.list_first_visible, self.list_first_visible + self.list_position_total - 1 do
  604. if Materia[i] ~= nil then
  605. local type = Game.Materia[Materia[i].id].type
  606. local name = Game.Materia[Materia[i].id].name
  607. ui_manager:get_widget("MateriaMenu.Container.List.Icon" .. tostring(pos)):set_image("icons/materia_" .. tostring(type) .. ".png")
  608. ui_manager:get_widget("MateriaMenu.Container.List.Icon" .. tostring(pos)):set_visible(true)
  609. ui_manager:get_widget("MateriaMenu.Container.List.Name" .. tostring(pos)):set_text(name)
  610. ui_manager:get_widget("MateriaMenu.Container.List.Name" .. tostring(pos)):set_visible(true)
  611. else
  612. ui_manager:get_widget("MateriaMenu.Container.List.Icon" .. tostring(pos)):set_visible(false)
  613. ui_manager:get_widget("MateriaMenu.Container.List.Name" .. tostring(pos)):set_visible(false)
  614. end
  615. pos = pos + 1
  616. end
  617. -- Set scroll bar position
  618. local scroll = ui_manager:get_widget("MateriaMenu.Container.List.Scroll")
  619. -- first_item_in_window == 1 then Top -> 0%3
  620. -- first_item_in_window == inventory_size - first_item_in_window then top = 100%-21
  621. local percent = math.floor((self.list_first_visible - 1) * 100 / (self.list_size - self.list_position_total))
  622. local fixed = 3 + (-1 * math.floor(self.list_first_visible - 1) * 25 / (self.list_size - self.list_position_total))
  623. scroll:set_y(percent, fixed)
  624. end,
  625. --- Equips the materia selected in the list at the currently selected slot.
  626. --
  627. -- It can also be used to swap or remove materia.
  628. equip_materia = function(self)
  629. local equip
  630. local equip_slot = self.header_position - 2 -- 0-8
  631. local list_pos = self.list_first_visible + self.list_position - 1
  632. local materia_equip = {id = nil, ap = 0}
  633. local materia_list = {id = nil, ap = 0}
  634. --- Get info about the seleceted materias (equipped and in the list)
  635. if self.header_position_row == 1 then
  636. equip = Inventory.ITEM_TYPE.WEAPON
  637. if equip_slot + 1 > #(Game.Items[Characters[self.char_id].weapon.id].slots) then
  638. print("BEEP No slot " .. tostring(equip_slot) .. " in current weapon.")
  639. return 0
  640. end
  641. if Characters[self.char_id].weapon.materia[equip_slot] ~= nil then
  642. materia_equip = Characters[self.char_id].weapon.materia[equip_slot]
  643. end
  644. elseif self.header_position_row == 2 then
  645. equip = Inventory.ITEM_TYPE.ARMOR
  646. if equip_slot + 1 > #(Game.Items[Characters[self.char_id].armor.id].slots) then
  647. print("BEEP No slot " .. tostring(equip_slot) .. " in current armor.")
  648. return 0
  649. end
  650. if Characters[self.char_id].armor.materia[equip_slot] ~= nil then
  651. materia_equip = Characters[self.char_id].armor.materia[equip_slot]
  652. end
  653. end
  654. if Materia[list_pos] ~= nil then
  655. materia_list = Materia[list_pos]
  656. end
  657. --- Equipped materia to the list (can be null)
  658. Materia[list_pos] = materia_equip
  659. if Materia[list_pos].id == nil then
  660. Materia[list_pos] = nil
  661. end
  662. --- Materia from list to weapon or armor
  663. if equip == Inventory.ITEM_TYPE.WEAPON then
  664. Characters[self.char_id].weapon.materia[equip_slot] = materia_list
  665. if Characters[self.char_id].weapon.materia[equip_slot].id == nil then
  666. Characters[self.char_id].weapon.materia[equip_slot] = nil
  667. end
  668. elseif equip == Inventory.ITEM_TYPE.ARMOR then
  669. Characters[self.char_id].armor.materia[equip_slot] = materia_list
  670. if Characters[self.char_id].armor.materia[equip_slot].id == nil then
  671. Characters[self.char_id].armor.materia[equip_slot] = nil
  672. end
  673. end
  674. -- Reload character data and list.
  675. self.populate_equip(self)
  676. self.populate_list(self)
  677. self.submenu_none(self)
  678. end,
  679. --- Hides the item menu and goes back to the main menu.
  680. hide = function(self)
  681. ui_manager:get_widget("MateriaMenu"):set_visible(false)
  682. UiContainer.current_menu = "main"
  683. UiContainer.current_submenu = ""
  684. return 0;
  685. end,
  686. }