Advertisement
blurose

[fr] headbutt trees

Sep 18th, 2020
471
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.69 KB | None | 0 0
  1. @ the whole headbutt tree system
  2. @ it implements jpan's behavior byte hack as well as the headbutt system in the space that the old routine took up. when he said it was overly inefficient, he meant it!
  3. @ compile this and then go to the offset 0x806D1F0 in the resulting .bin output. copy everything there until the next block of zeros. paste it to offset 0x6D1F0 in your rom.
  4. @ there are various parameters you can play around with. most of these are primarily the tables halfway through this.
  5. @ i tried to comment it throughout!
  6.  
  7. @ now, in amap, there's the one field that is primarily used in wild encounter spots. it's 2 when wild grass and 4 when surfing on water encounters.
  8. @ because we won't be walking on the headbutt tree, we can use this field to our advantage.
  9. @ cur_mapdata_block_get_field_at(s16 x, s16 y, u8 field) references a bunch of other routines, but eventually, it boils down to a bunch of preset fields or'd with the header info.
  10. @ the first is 0x1FF, or the 9 least significant bits. this is the behavior byte itself.
  11. @ the second is 0x3E00, or the next 5 bits in terms of significance. this allows for 2^5 (32) bits for use for our table.
  12. @ note that the entry entered in this table should be multiplied by 2 because of the way that amap (incorrectly) displays the data. this allows the code below to reference it properly.
  13. @ screens are given in the post.
  14.  
  15. .text
  16. .align 2
  17. .thumb
  18. .thumb_func
  19.  
  20. .org 0x08044EC8
  21.  
  22. @ returns r0 = pseudorandom number
  23. random:
  24. .hword 0x4A04
  25.  
  26. .org 0x08058F48
  27.  
  28. @ returns r0 = (metatile behavior long or blockinfo_bit_masks[field]) >> blockinfo_bit_right_shift_num[field]
  29. cur_mapdata_block_get_field_at: @ (s16 x, s16 y, u8 field)
  30. push {r4, lr}
  31.  
  32. .org 0x0806CE38
  33.  
  34. @ writes the next pos and height to the pointer given in r0
  35. player_get_next_pos_and_height: @ (*[s16 x, s16 y, u8 height])
  36. push {r4, r5, lr}
  37.  
  38. .org 0x0806D1F0
  39.  
  40. @ this assembly routine is a modded version of jpan's behavior byte hack that decreases space required for the table while slightly increasing what's needed for the code
  41. onpress_a_get_script_tile:
  42. lsl r1, r1, #0x18
  43. lsr r0, r1, #0x18
  44. cmp r0, #0x80
  45. blt _not_governed @ we don't care about entries less than h80
  46. sub r0, r0, #0x80
  47. lsl r0, r0, #0x2
  48. ldr r1, behavior_table_ref @ load the table pointer here
  49. add r0, r0, r1
  50. ldr r0, [r0] @ load the script pointer here
  51. b _return_loc
  52. _not_governed:
  53. mov r0, #0
  54. _return_loc:
  55. mov pc, lr
  56.  
  57. .align 2
  58.  
  59. behavior_table_ref:
  60. .word behavior_table
  61.  
  62. behavior_table: @ for the playerfacing behaviors
  63. .word 0
  64. .word 0x081A7606 @ bookshelf
  65. .word 0x081A760F @ market shelf
  66. .word 0x081A6955 @ pc
  67. .word 0
  68. .word 0x081A6C32 @ town map
  69. .word 0x081A764E @ tv
  70. .word 0x081A76E7 @ pokemon center
  71. .word 0x081A76DE @ pokemon mart
  72. .word 0x081A7657 @ cabinet
  73. .word 0x081A7660 @ cooking smells great!
  74. .word 0x081A7669 @ dresser
  75. .word 0x081A7672 @ snacks
  76. .word 0x081BBFD8 @ wireless
  77. .word 0x081BB8A7 @ not available
  78. .word 0x081A7702 @ questionnaire
  79. @ 0x90
  80. .word 0x081A7618 @ fridge
  81. .word 0x081A76F0 @ indigo plateau
  82. .word 0x081A76F9 @ indigo plateau 2
  83. .word 0x081A763C @ blueprint
  84. .word 0x081A767B @ pokemon pics
  85. .word 0x081A7684 @ complex machine. better not touch it!
  86. .word 0x081A768D @ telephone
  87. .word 0x081A762A @ complex numbers
  88. .word 0x081A7696 @ ads
  89. .word 0x081A769F @ tasty food
  90. .word 0x081A76A8 @ trash can
  91. .word 0x081A76B1 @ cup
  92. .word 0
  93. .word 0
  94. .word 0x081A76CC @ lights
  95. .word 0x081A76D5 @ tools
  96. @ 0xA0
  97. .word 0x081A7633 @ random machine
  98. .word 0x081A7621 @ consoles
  99. .word 0x081A7645 @ robbery
  100. .word 0x081C549C @ timer
  101. @ now, i personally added headbutt_script here, but it can go in any one of the zeros above. just make sure that you note the entry correctly!
  102. .word headbutt_script @ headbutt tree behavior byte (0xA4)
  103.  
  104. .equ table_amount, 3
  105. .equ terminate, 0xFE @ only rule here is that it isn't a pokemon you want to appear in a tree. if you wanted to use pokemon index 254, go for it i guess, but change this
  106. .equ var_begin, 0x020270B8
  107.  
  108. headbutt_tree:
  109. push {r4-r6, lr}
  110. ldr r0, var_8000 @ position_ptr
  111. @ the below branch will store the position in front of the player's x in var_8000, y in var_8001, and the height in the most significant byte of var_8002
  112. @ this is because it writes to the pointer in r0
  113. bl player_get_next_pos_and_height
  114. ldr r4, var_8000
  115. ldrh r0, [r4] @ x
  116. ldrh r1, [r4, #2] @ y
  117. mov r2, #1 @ field id
  118. @ the field entry 1 is 5 bits of the second behavior byte thing in advancemap. this means we can have up to 32 headbutt tables denoted by even numbers from 0-64 in amap.
  119. @ this is explained further above
  120. bl cur_mapdata_block_get_field_at
  121. lsl r0, r0, #0x18
  122. lsr r4, r0, #0x18 @ r4 = table number
  123. @ part below catches invalid tables and prevents them from working
  124. cmp r4, #table_amount
  125. bge _nothingfell
  126. ldr r0, tableoftables_ref
  127. lsl r1, r4, #2 @ r1 = table number * 4
  128. ldr r4, [r0, r1] @ r4 = table pointer to the relevant one
  129. @ below, generate a random number less than 100 to emulate chance
  130. bl random @ r0 = random()
  131. mov r1, #100
  132. bl __umodsi3 @ r0 = r0 % 100
  133. mov r5, #0 @ set up the loop counter
  134. ldr r6, terminate_byte
  135.  
  136. @ at this point, r0 = random() % 100, r4 = table pointer, r5 = loop counter, r6 = terminator
  137. _loop:
  138. mov r1, #7 @ 7 being the size of each entry
  139. mul r1, r5, r1
  140. add r3, r4, r1 @ store the current entry's pointer in r3
  141. ldrh r2, [r3] @ seems to be very finicky at times, loading random values from the surroundings?
  142. lsl r2, r2, #0x10
  143. lsr r2, r2, #0x10
  144. cmp r2, r6
  145. beq _nothingfell
  146. ldrb r2, [r3, #6] @ load the chance of this entry into r2
  147. cmp r0, r2
  148. ble _somethingfell
  149. add r5, r5, #1 @ increment the loop counter
  150. b _loop
  151.  
  152. _somethingfell:
  153. mov r4, r3
  154. @ at this point, r4 is the table entry we care about. don't touch it
  155. bl random @ generate a new random number
  156. @ r0 = random()
  157. ldrb r2, [r4, #2] @ load the lower level
  158. ldrb r1, [r4, #3] @ load the higher level
  159. sub r1, r1, r2 @ subtract the lower level from the higher level, store it as the parameter for modulo
  160. bl __umodsi3
  161. @ r0 = random() % (highlevel - lowlevel)
  162. ldrb r2, [r4, #2] @ load the lower level again bc umodsi ****in w the value
  163. add r1, r0, r2 @ level parameter
  164. ldrh r0, [r4] @ species parameter
  165. ldrh r2, [r4, #4] @ item parameter
  166. bl create_scripted_mon
  167. ldr r0, var_8000
  168. mov r1, #0
  169. strh r1, [r0, #0x18] @ store 0 into var_800D
  170. b _end
  171.  
  172. _nothingfell:
  173. ldr r0, var_8000
  174. mov r1, #0xFF
  175. strh r1, [r0, #0x18] @ store 0xFF into var_800D
  176.  
  177. _end:
  178. pop {r4-r6}
  179. pop {r1} @ this is the return method used by many of the script stuff so
  180. bx r1
  181.  
  182. .align 2
  183.  
  184. @ used to store the position struct
  185. var_8000:
  186. .word (var_begin + (0x8000 * 2))
  187.  
  188. terminate_byte:
  189. .word terminate
  190.  
  191. tableoftables_ref:
  192. .word tableoftables
  193.  
  194. @ note that, in order to expand the tables, you need to add another entry here for each of the tables.
  195. tableoftables:
  196. .word lowencounter
  197. .word medencounter
  198. .word highencounter
  199.  
  200. @ bunch of defines to make the below better readable
  201. .equ caterpie, 10
  202. .equ metapod, 11
  203. .equ butterfree, 12
  204. .equ weedle, 13
  205. .equ kakuna, 14
  206. .equ beedrill, 15
  207. .equ exeggcute, 102
  208. .equ exeggutor, 103
  209. .equ tangela, 114
  210. .equ pinsir, 127
  211. .equ snorlax, 143
  212. .equ pineco, 204
  213. .equ heracross, 214
  214.  
  215. @ a sample item
  216. .equ brightpowder, 179
  217.  
  218. @.org 0x08XXXXXX @ optional repoint of the tables below in case you want a higher amount of pokemon.
  219.  
  220. @ here's the table format:
  221. @ [2 bytes - species] [1 byte - lower level] [1 byte - higher level] [2 bytes] - item it can hold] [1 byte - chance it will appear]
  222. @ the chance byte at the very end is subtracted from the previous entry in the tables in order to get that specific entry's chance of showing up.
  223. @ sample entries are below:
  224.  
  225. lowencounter:
  226. .hword weedle @ species
  227. .byte 5 @ lower level
  228. .byte 7 @ higher level
  229. .hword brightpowder @ item
  230. .byte 20 @ chance
  231.  
  232. .hword kakuna @ species
  233. .byte 12 @ lower level
  234. .byte 15 @ higher level
  235. .hword 0 @ no item
  236. .byte 40 @ chance: 40 - 20 (weedle's entry above) = 20
  237.  
  238. .hword beedrill
  239. .byte 60
  240. .byte 70
  241. .hword brightpowder
  242. .byte 100 @ chance: 100 - 40 (kakuna's entry above) = 60
  243.  
  244. .hword terminate
  245.  
  246. @ this table represents an instance where we don't have to get a pokemon 100% of the time. the code handles it!
  247. medencounter:
  248. .hword caterpie
  249. .byte 5
  250. .byte 7
  251. .hword brightpowder
  252. .byte 35
  253.  
  254. .hword metapod
  255. .byte 12
  256. .byte 15
  257. .hword 0
  258. .byte 45
  259.  
  260. .hword butterfree
  261. .byte 60
  262. .byte 70
  263. .hword brightpowder
  264. .byte 50
  265.  
  266. .hword terminate
  267. @ 50% of the time, a pokemon won't fall.
  268.  
  269. highencounter:
  270. .hword exeggcute
  271. .byte 10
  272. .byte 12
  273. .hword 0
  274. .byte 40
  275.  
  276. .hword tangela
  277. .byte 20
  278. .byte 25
  279. .hword 0
  280. .byte 60
  281.  
  282. .hword heracross
  283. .byte 17
  284. .byte 22
  285. .hword brightpowder
  286. .byte 90
  287.  
  288. .hword snorlax
  289. .byte 50
  290. .byte 60
  291. .hword brightpowder
  292. .byte 100
  293.  
  294. .hword terminate
  295.  
  296. @ optional insert of the script. there's still about hB0 bytes left over after the script is inserted, allowing for about 19 EXTRA mon entries (on top of the 10 there already)
  297. @ repoint if so desired. the assembly will take care of it!
  298. @.org 0x08XXXXXX
  299.  
  300. .equ headbutt, 0x1D
  301. .equ lastresult, 0x800D
  302.  
  303. headbutt_script: @ this is included here for the dynamic compiling so that you don't have to care. feel free to edit it though
  304. .byte 0x6A
  305.  
  306. .byte 0x7C
  307. .hword headbutt
  308.  
  309. .byte 0x21
  310. .hword lastresult
  311. .hword 0x06
  312.  
  313. .byte 0x06
  314. .byte 0x01
  315. .word no_headbutt_in_party
  316.  
  317. .byte 0x9D
  318. .byte 0x00
  319. .hword lastresult
  320.  
  321. .byte 0x7F
  322. .byte 0x00
  323. .hword lastresult
  324.  
  325. .byte 0x82
  326. .byte 0x01
  327. .hword headbutt
  328.  
  329. .byte 0x0F
  330. .byte 0x00
  331. .word text_headbutt_in_party
  332. .byte 0x09
  333. .byte 0x05
  334.  
  335. .byte 0x21
  336. .hword lastresult
  337. .hword 0x00
  338.  
  339. .byte 0x06
  340. .byte 0x01
  341. .word said_no
  342.  
  343. .byte 0x0F
  344. .byte 0x00
  345. .word text_poke_used_atk
  346. .byte 0x09
  347. .byte 0x04
  348.  
  349. .byte 0x68
  350.  
  351. .byte 0x9C
  352. .hword 0x2
  353.  
  354. .byte 0x27
  355.  
  356. @ the callasm is here
  357. .byte 0x23
  358. .word headbutt_tree + 1
  359.  
  360. @ this comparison here prevents the dowildbattle from happening if lastresult is 0xFF (the chance was higher than the highest chance defined in the table)
  361. @ lastresult's modification is in the assembly above
  362. .byte 0x21
  363. .hword lastresult
  364. .hword 0xFF
  365.  
  366. .byte 0x06
  367. .byte 0x01
  368. .word tree_was_undisturbed
  369.  
  370. .byte 0x0F
  371. .byte 0x00
  372. .word text_exclamation
  373. .byte 0x09
  374. .byte 0x06
  375.  
  376. .byte 0xB7
  377.  
  378. .byte 0x6C
  379.  
  380. .byte 0x02
  381.  
  382. .byte 0xFF
  383.  
  384. no_headbutt_in_party:
  385. .byte 0x0F
  386. .byte 0x00
  387. .word text_cant_headbutt
  388. .byte 0x09
  389. .byte 0x06
  390.  
  391. .byte 0x6C
  392.  
  393. .byte 0x02
  394.  
  395. .byte 0xFF
  396.  
  397. said_no: @ closes the textbox
  398. .byte 0x68
  399.  
  400. .byte 0x6C
  401.  
  402. .byte 0x02
  403.  
  404. .byte 0xFF
  405.  
  406. tree_was_undisturbed:
  407. .byte 0x0F
  408. .byte 0x00
  409. .word text_tree_undisturbed
  410. .byte 0x09
  411. .byte 0x06
  412.  
  413. .byte 0x6C
  414.  
  415. .byte 0x02
  416.  
  417. .byte 0xFF
  418.  
  419. text_headbutt_in_party: @ This tree can be headbutted! Would you like to use headbutt?
  420. .byte 0xCE
  421. .byte 0xDC
  422. .byte 0xDD
  423. .byte 0xE7
  424. .byte 0x00
  425. .byte 0xE8
  426. .byte 0xE6
  427. .byte 0xD9
  428. .byte 0xD9
  429. .byte 0x00
  430. .byte 0xD7
  431. .byte 0xD5
  432. .byte 0xE2
  433. .byte 0x00
  434. .byte 0xD6
  435. .byte 0xD9
  436. .byte 0x00
  437. .byte 0xDC
  438. .byte 0xD9
  439. .byte 0xD5
  440. .byte 0xD8
  441. .byte 0xD6
  442. .byte 0xE9
  443. .byte 0xE8
  444. .byte 0xE8
  445. .byte 0xD9
  446. .byte 0xD8
  447. .byte 0xAB
  448. .byte 0xFE
  449. .byte 0xD1
  450. .byte 0xE3
  451. .byte 0xE9
  452. .byte 0xE0
  453. .byte 0xD8
  454. .byte 0x00
  455. .byte 0xED
  456. .byte 0xE3
  457. .byte 0xE9
  458. .byte 0x00
  459. .byte 0xE0
  460. .byte 0xDD
  461. .byte 0xDF
  462. .byte 0xD9
  463. .byte 0x00
  464. .byte 0xE8
  465. .byte 0xE3
  466. .byte 0x00
  467. .byte 0xE9
  468. .byte 0xE7
  469. .byte 0xD9
  470. .byte 0x00
  471. .byte 0xC2
  472. .byte 0xD9
  473. .byte 0xD5
  474. .byte 0xD8
  475. .byte 0xD6
  476. .byte 0xE9
  477. .byte 0xE8
  478. .byte 0xE8
  479. .byte 0xAC
  480. .byte 0xFF
  481. .byte 0x00
  482. .byte 0xFF
  483.  
  484. text_poke_used_atk: @ [string1] used [string2]!
  485. .byte 0xFD
  486. .byte 0x02
  487. .byte 0x00
  488. .byte 0xE9
  489. .byte 0xE7
  490. .byte 0xD9
  491. .byte 0xD8
  492. .byte 0x00
  493. .byte 0xFD
  494. .byte 0x03
  495. .byte 0xAB
  496. .byte 0xFF
  497. .byte 0x00
  498. .byte 0xFF
  499.  
  500. text_exclamation: @ Whoa!
  501. .byte 0xD1
  502. .byte 0xDC
  503. .byte 0xE3
  504. .byte 0xD5
  505. .byte 0xAB
  506. .byte 0xFF
  507. .byte 0x00
  508. .byte 0xFF
  509.  
  510. text_cant_headbutt: @ This tree looks like Pokémon can live in it.
  511. .byte 0xCE
  512. .byte 0xDC
  513. .byte 0xDD
  514. .byte 0xE7
  515. .byte 0x00
  516. .byte 0xE8
  517. .byte 0xE6
  518. .byte 0xD9
  519. .byte 0xD9
  520. .byte 0x00
  521. .byte 0xE0
  522. .byte 0xE3
  523. .byte 0xE3
  524. .byte 0xDF
  525. .byte 0xE7
  526. .byte 0x00
  527. .byte 0xE0
  528. .byte 0xDD
  529. .byte 0xDF
  530. .byte 0xD9
  531. .byte 0x00
  532. .byte 0xCA
  533. .byte 0xE3
  534. .byte 0xDF
  535. .byte 0x1B
  536. .byte 0xE1
  537. .byte 0xE3
  538. .byte 0xE2
  539. .byte 0x00
  540. .byte 0xD7
  541. .byte 0xD5
  542. .byte 0xE2
  543. .byte 0xFE
  544. .byte 0xE0
  545. .byte 0xDD
  546. .byte 0xEA
  547. .byte 0xD9
  548. .byte 0x00
  549. .byte 0xDD
  550. .byte 0xE2
  551. .byte 0x00
  552. .byte 0xDD
  553. .byte 0xE8
  554. .byte 0xAD
  555. .byte 0xFF
  556. .byte 0x00
  557. .byte 0xFF
  558.  
  559. text_tree_undisturbed: @ But the tree remained undisturbed...
  560. .byte 0xBC
  561. .byte 0xE9
  562. .byte 0xE8
  563. .byte 0x00
  564. .byte 0xE8
  565. .byte 0xDC
  566. .byte 0xD9
  567. .byte 0x00
  568. .byte 0xE8
  569. .byte 0xE6
  570. .byte 0xD9
  571. .byte 0xD9
  572. .byte 0x00
  573. .byte 0xE6
  574. .byte 0xD9
  575. .byte 0xE1
  576. .byte 0xD5
  577. .byte 0xDD
  578. .byte 0xE2
  579. .byte 0xD9
  580. .byte 0xD8
  581. .byte 0xFE
  582. .byte 0xE9
  583. .byte 0xE2
  584. .byte 0xD8
  585. .byte 0xDD
  586. .byte 0xE7
  587. .byte 0xE8
  588. .byte 0xE9
  589. .byte 0xE6
  590. .byte 0xD6
  591. .byte 0xD9
  592. .byte 0xD8
  593. .byte 0xAD
  594. .byte 0xAD
  595. .byte 0xAD
  596. .byte 0xFF
  597. .byte 0x00
  598.  
  599. .org 0x080A029C
  600.  
  601. create_scripted_mon: @ (u16 species, u8 level, u16 item)
  602. push {r4-r7, lr}
  603.  
  604. .org 0x081E4684
  605.  
  606. @ returns r0 = dividend % divisor
  607. __umodsi3: @ (u16 dividend, u16 divisor)
  608. cmp r1, #0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement