field.lua 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. -- helper function that changes field maps through fadein and fadeout
  2. load_field_map_request = function( map_name, point_name )
  3. if type( map_name ) == "string" and map_name ~= "" then
  4. System.MapChanger.map_name = map_name
  5. System.MapChanger.point_name = point_name
  6. script:request( Script.SYSTEM, "MapChanger", "ffvii_field", 0 )
  7. end
  8. end
  9. set_entity_to_character = function( entity_name, character_name )
  10. if character_name == FFVII.Party[ 1 ] and entity_name ~= "" then
  11. if System.MapChanger.point_name ~= "" then
  12. local point = entity_manager:get_entity_point( System.MapChanger.point_name )
  13. if point ~= nil then
  14. local x, y, z = point:get_position()
  15. local rotation = point:get_rotation()
  16. local player = entity_manager:get_entity( entity_name )
  17. player:set_position( x, y, z )
  18. player:set_rotation( rotation )
  19. player:set_solid( true )
  20. player:set_visible( true )
  21. end
  22. end
  23. entity_manager:set_player_entity( entity_name )
  24. end
  25. entity_manager:set_entity_to_character(entity_name, character_name)
  26. end
  27. --[[
  28. Joins the party members in the field.
  29. @param speed Speed at which the characters join
  30. ]]
  31. join_party = function(speed)
  32. local player = entity_manager:get_player_entity()
  33. if (player == nil) then
  34. do return end
  35. end
  36. local x, y, z = player:get_position()
  37. for c = 2, 3 do
  38. if FFVII.Party[c] ~= nil then
  39. local character = entity_manager:get_entity_from_character_id(FFVII.Party[c])
  40. if character ~= nil then
  41. local cur_speed = character:get_move_auto_speed()
  42. character:set_solid(false)
  43. -- Approximated speed, good enough for now.
  44. -- TODO: Calculate speed based on time, as the orignal opcode.
  45. character:set_move_auto_speed(speed / 16)
  46. character:move_to_position(x, y)
  47. character:move_sync()
  48. character:set_move_auto_speed(cur_speed)
  49. character:set_visible(false)
  50. character:set_talkable(false)
  51. end
  52. end
  53. end
  54. end
  55. --[[
  56. Splits the party members in the field.
  57. @param ax_addr Bank for ax, or zero if ax is specified as a literal value.
  58. @param ay_addr Bank for ay, or zero if ay is specified as a literal value.
  59. @param ar_addr Bank for ar, or zero if ar is specified as a literal value.
  60. @param bx_addr Bank for bx, or zero if bx is specified as a literal value.
  61. @param by_addr Bank for by, or zero if by is specified as a literal value.
  62. @param br_addr Bank for br, or zero if by is specified as a literal value.
  63. @param ax X-coordinate of the second character in the party after the split, or address for the value if ax_addr is non-zero.
  64. @param ay Y-coordinate of the second character in the party after the split, or address for the value if ax_addr is non-zero.
  65. @param ar Direction the second character faces after the split, or address for the value if ar_addr is non-zero.
  66. @param bx X-coordinate of the third character in the party after the split, or address for the value if bx_addr is non-zero.
  67. @param by Y-coordinate of the third character in the party after the split, or address for the value if bx_addr is non-zero.
  68. @param br Direction the third character faces after the split, or address for the value if br_addr is non-zero.
  69. @param speed Speed at which the characters split.
  70. ]]
  71. split_party = function(ax, ay, ar, bx, by, br, speed)
  72. local player = entity_manager:get_player_entity()
  73. local x, y, z = player:get_position()
  74. for c = 2, 3 do
  75. if FFVII.Party[c] ~= nil then
  76. local character = entity_manager:get_entity_from_character_id(FFVII.Party[c])
  77. if character ~= nil then
  78. local cur_speed = character:get_move_auto_speed()
  79. -- Approximated speed, good enough for now.
  80. -- TODO: Calculate speed based on time, as the orignal opcode.
  81. character:set_move_auto_speed(speed / 16)
  82. character:set_position(x, y, z)
  83. character:set_visible(true)
  84. character:set_solid(false)
  85. if c == 2 then
  86. character:move_to_position(ax, ay)
  87. elseif c == 3 then
  88. character:move_to_position(bx, by)
  89. end
  90. character:move_sync()
  91. if c == 2 then
  92. character:set_rotation(ar)
  93. elseif c == 3 then
  94. character:set_rotation(br)
  95. end
  96. character:set_move_auto_speed(cur_speed)
  97. character:set_solid(true)
  98. character:set_talkable(true)
  99. end
  100. end
  101. end
  102. end
  103. --[[
  104. Locks or unlocks player movement and menu access.
  105. @param lock True to lock, false to unlock.
  106. ]]
  107. player_lock = function( lock )
  108. entity_manager:player_lock( lock )
  109. FFVII.MenuSettings.available = ( lock == false )
  110. end
  111. --[[
  112. Sets a bit variable on (1).
  113. @param bank Memory bank (0-index, as in game).
  114. @param variable Bank address (0-index, as in game).
  115. @param bit Address bit (0-index, as in game).
  116. ]]
  117. bit_on = function(bank, variable, bit)
  118. FFVII.BitBanks[bank + 1][variable + 1][bit + 1] = 1
  119. end
  120. --[[
  121. Sets a bit variable off (0).
  122. @param bank Memory bank (0-index, as in game).
  123. @param variable Bank address (0-index, as in game).
  124. @param bit Address bit (0-index, as in game).
  125. ]]
  126. bit_off = function(bank, variable, bit)
  127. FFVII.BitBanks[bank + 1][variable + 1][bit + 1] = 0
  128. end
  129. --[[
  130. Retrieves a bit variable.
  131. @param bank Memory bank (0-index, as in game).
  132. @param variable Bank address (0-index, as in game).
  133. @param bit Address bit (0-index, as in game).
  134. @return 1 or 0
  135. ]]
  136. bit = function(bank, variable, bit)
  137. return FFVII.BitBanks[bank + 1][variable + 1][bit + 1]
  138. end
  139. --[[
  140. Checks if a key is being pressed.
  141. @param key_code The code of the key to check.
  142. @return True if the key is being pressed, false otherwise.
  143. @todo Implement.
  144. ]]
  145. KeyOn = function(key_code)
  146. return true;
  147. end
  148. --[[
  149. Stores the coordinates and walkmesh triangle in memory.
  150. Stores the values as in the original game, without scaling.
  151. @param bx Bank at which to store the X coordinate.
  152. @param by Bank at which to store the Y coordinate.
  153. @param bz Bank at which to store the Z coordinate.
  154. @param bt Bank at which to store the triangle.
  155. @param id The entity ID.
  156. @param ax Address at which to store the X coordinate.
  157. @param ay Address at which to store the Y coordinate.
  158. @param az Address at which to store the Z coordinate.
  159. @param at Address at which to store the triangle.
  160. @param scale Map scale to multiply values
  161. ]]
  162. axyzi = function(bx, by, bz, bt, id, ax, ay, az, at, scale)
  163. local entity = entity_manager:get_entity_from_index(id)
  164. if entity == nil then
  165. do return end
  166. end
  167. script:wait(0.666667)
  168. local x, y, z = entity:get_position()
  169. local t = entity:get_move_triangle_id()
  170. FFVII.Banks[bx + 1][ax + 1] = math.floor(x * scale)
  171. FFVII.Banks[by + 1][ay + 1] = math.floor(y * scale)
  172. FFVII.Banks[bz + 1][az + 1] = math.floor(z * scale)
  173. FFVII.Banks[bt + 1][at + 1] = t
  174. return 0
  175. end
  176. System[ "MapChanger" ] = {
  177. map_name = "",
  178. point_name = "",
  179. ffvii_field = function( self )
  180. if self.map_name ~= "" then
  181. player_lock( true ) -- disable menu and pc movement while load map
  182. script:request_end_sync( Script.UI, "Fade", "fade_out", 0 )
  183. map( self.map_name )
  184. player_lock( false ) -- enable menu and pc movement after load map
  185. self.map_name = ""
  186. script:request_end_sync( Script.UI, "Fade", "fade_in", 0 )
  187. end
  188. return 0
  189. end,
  190. ffvii_battle = function( self )
  191. if self.map_name ~= "" then
  192. player_lock( true ) -- disable menu and pc movement while load map
  193. script:request_end_sync( Script.UI, "Fade", "fade_out", 0 )
  194. map( self.map_name )
  195. -- load battle ui
  196. -- load player entity
  197. self.map_name = ""
  198. script:request_end_sync( Script.UI, "Fade", "fade_in", 0 )
  199. end
  200. return 0
  201. end,
  202. }