Advertisement
Guest User

sf3 hitbox lua

a guest
Apr 27th, 2011
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.15 KB | None | 0 0
  1. --modified april 27, 2011 to add previously omitted vulnerable hitbox
  2. local SCREEN_WIDTH = 384
  3. local SCREEN_HEIGHT = 224
  4. local GROUND_OFFSET = 40
  5. local MAX_GAME_OBJECTS = 30
  6. local AXIS_COLOUR = 0xFFFFFFFF
  7. local AXIS_SIZE = 25
  8. local HITBOX_PASSIVE = 0
  9. local HITBOX_ACTIVE = 1
  10. local HITBOX_TEST = 2
  11. local HITBOX_PASSIVE_COLOUR = 0x00008080
  12. local HITBOX_ACTIVE_COLOUR = 0x00FF00C0
  13. local HITBOX_TEST_COLOUR = 0x00008080
  14. local GAME_PHASE_PLAYING = 2
  15.  
  16. local address = {
  17. player1 = 0x02068C6C,
  18. player2 = 0x02069104,
  19. screen_center_x = 0x02026CB0,
  20. game_phase = 0x020154A6
  21. }
  22. local globals = {
  23. game_phase = 0,
  24. screen_center_x = 0,
  25. num_misc_objs = 0
  26. }
  27. local player1 = {}
  28. local player2 = {}
  29. local misc_objs = {}
  30.  
  31.  
  32. function update_globals()
  33. globals.screen_center_x = memory.readword(address.screen_center_x)
  34. globals.game_phase = memory.readword(address.game_phase)
  35. end
  36.  
  37.  
  38. function hitbox_load(obj, i, type, facing_dir, offset_x, offset_y, addr)
  39. local left = memory.readwordsigned(addr)
  40. local right = memory.readwordsigned(addr + 2)
  41. local bottom = memory.readwordsigned(addr + 4)
  42. local top = memory.readwordsigned(addr + 6)
  43.  
  44. if facing_dir == 1 then
  45. left = -left
  46. right = -right
  47. end
  48.  
  49. left = left + offset_x
  50. right = right + left
  51. bottom = bottom + offset_y
  52. top = top + bottom
  53.  
  54. if type == HITBOX_PASSIVE then
  55. obj.p_hboxes[i] = {
  56. left = left,
  57. right = right,
  58. bottom = bottom,
  59. top = top,
  60. type = type
  61. }
  62. end
  63.  
  64. if type == HITBOX_ACTIVE then
  65. obj.a_hboxes[i] = {
  66. left = left,
  67. right = right,
  68. bottom = bottom,
  69. top = top,
  70. type = type
  71. }
  72. end
  73.  
  74. if type == HITBOX_TEST then
  75. obj.t_hboxes[i] = {
  76. left = left,
  77. right = right,
  78. bottom = bottom,
  79. top = top,
  80. type = type
  81. }
  82. end
  83. end
  84.  
  85.  
  86. function update_game_object(obj, base)
  87. obj.p_hboxes = {}
  88. obj.a_hboxes = {}
  89. obj.t_hboxes = {}
  90.  
  91. obj.facing_dir = memory.readbyte(base + 0xA)
  92. obj.opponent_dir = memory.readbyte(base + 0xB)
  93. obj.pos_x = memory.readword(base + 0x64)
  94. obj.pos_y = memory.readword(base + 0x68)
  95. obj.anim_frame = memory.readword(base + 0x21A)
  96.  
  97. -- Load the passive hitboxes
  98. local p_hb_addr = memory.readdword(base + 0x2A0)
  99. for i = 1, 4 do
  100. hitbox_load(obj, i, HITBOX_PASSIVE, obj.facing_dir, obj.pos_x, obj.pos_y, p_hb_addr)
  101. p_hb_addr = p_hb_addr + 8
  102. end
  103.  
  104. -- Load the active hitboxes
  105. local a_hb_addr = memory.readdword(base + 0x2C8)
  106. for i = 1, 4 do
  107. hitbox_load(obj, i, HITBOX_ACTIVE, obj.facing_dir, obj.pos_x, obj.pos_y, a_hb_addr)
  108. a_hb_addr = a_hb_addr + 8
  109. end
  110.  
  111. -- the vuln attack box pointer address is -0x2A8 away from base
  112. -- however, lua won't let me subtract from hex for some dumb reason so i'm using this stupid if/else
  113.  
  114. local vuln_attack_address
  115.  
  116. if (obj == player1) then
  117. vuln_attack_pointer_address = 0x02068F14
  118. else --obj == player2
  119. vuln_attack_pointer_address = 0x020693AC
  120. end
  121.  
  122. local t_hb_addr = memory.readdword(vuln_attack_pointer_address)
  123. for i = 1, 4 do
  124. hitbox_load(obj, i, HITBOX_TEST, obj.facing_dir, obj.pos_x, obj.pos_y, t_hb_addr)
  125. t_hb_addr = t_hb_addr + 8
  126. end
  127. end
  128.  
  129.  
  130. function read_misc_objects()
  131. local obj_index
  132. local obj_addr
  133.  
  134. local p_hb_addr
  135. local a_hb_addr
  136.  
  137. -- This function reads all game objects other than the two player characters.
  138. -- This includes all projectiles and even Yang's Seiei-Enbu shadows.
  139.  
  140. -- The game uses the same structure all over the place and groups them
  141. -- into lists with each element containing an index to the next element
  142. -- in that list. An index of -1 signals the end of the list.
  143.  
  144. -- I believe there are at least 7 lists (0-6) but it seems everything we need
  145. -- (and lots we don't) is in list 3.
  146. local list = 3
  147.  
  148. num_misc_objs = 1
  149. obj_index = memory.readwordsigned(0x02068A96 + (list * 2))
  150.  
  151. while num_misc_objs <= MAX_GAME_OBJECTS and obj_index ~= -1 do
  152. obj_addr = 0x02028990 + (obj_index * 0x800)
  153.  
  154. -- I don't really know how to tell different game objects types apart yet so
  155. -- just read everything that has non-zero hitbox addresses. Seems to
  156. -- work fine...
  157. p_hb_addr = memory.readdword(obj_addr + 0x2A0)
  158. a_hb_addr = memory.readdword(obj_addr + 0x2C8)
  159.  
  160. if p_hb_addr ~= 0 and a_hb_addr ~= 0 then
  161. misc_objs[num_misc_objs] = {}
  162. update_game_object(misc_objs[num_misc_objs], obj_addr)
  163. num_misc_objs = num_misc_objs + 1
  164. end
  165.  
  166. -- Get the index to the next object in this list.
  167. obj_index = memory.readwordsigned(obj_addr + 0x1C)
  168. end
  169. end
  170.  
  171.  
  172. function game_x_to_mame(x)
  173. local left_edge = globals.screen_center_x - (SCREEN_WIDTH / 2)
  174. return (x - left_edge)
  175. end
  176.  
  177.  
  178. function game_y_to_mame(y)
  179. -- Why subtract 17? No idea, the game driver does the same thing.
  180. return (SCREEN_HEIGHT - (y + GROUND_OFFSET - 17))
  181. end
  182.  
  183.  
  184. function draw_hitbox(hb)
  185. local left = game_x_to_mame(hb.left)
  186. local bottom = game_y_to_mame(hb.bottom)
  187. local right = game_x_to_mame(hb.right)
  188. local top = game_y_to_mame(hb.top)
  189.  
  190. if(hb.type == HITBOX_PASSIVE) then
  191. colour = HITBOX_PASSIVE_COLOUR
  192. end
  193.  
  194. if(hb.type == HITBOX_ACTIVE) then
  195. colour = HITBOX_ACTIVE_COLOUR
  196. end
  197.  
  198. if(hb.type == HITBOX_TEST) then
  199. colour = HITBOX_TEST_COLOUR
  200. end
  201.  
  202. gui.box(left, top, right, bottom, colour)
  203. end
  204.  
  205.  
  206. function draw_game_object(obj)
  207. local x = game_x_to_mame(obj.pos_x)
  208. local y = game_y_to_mame(obj.pos_y)
  209.  
  210. for i = 1, 4 do
  211. draw_hitbox(obj.p_hboxes[i])
  212. draw_hitbox(obj.a_hboxes[i])
  213. draw_hitbox(obj.t_hboxes[i])
  214. end
  215.  
  216. gui.drawline(x, y-AXIS_SIZE, x, y+AXIS_SIZE, AXIS_COLOUR)
  217. gui.drawline(x-AXIS_SIZE, y, x+AXIS_SIZE, y, AXIS_COLOUR)
  218. end
  219.  
  220.  
  221. function render_sfiii_hitboxes()
  222. update_globals()
  223. if globals.game_phase ~= GAME_PHASE_PLAYING then
  224. gui.clearuncommitted()
  225. return
  226. end
  227.  
  228. update_game_object(player1, address.player1)
  229. draw_game_object(player1)
  230. update_game_object(player2, address.player2)
  231. draw_game_object(player2)
  232.  
  233. read_misc_objects()
  234. for i = 1, num_misc_objs-1 do
  235. draw_game_object(misc_objs[i])
  236. end
  237. end
  238.  
  239.  
  240. gui.register( function()
  241. render_sfiii_hitboxes()
  242. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement