< >
Hello, guest! Please log in or register.

The PokéCommunity

Go Back     The PokéCommunity Forums > ROM Hacking > Tools, Tutorials & Resources Tutorial [FireRed] Hidden Abilities

Notices

Tools, Tutorials & Resources Various tools to help you develop your hacks can be found here.
New threads in this forum are to be approved by a moderator before they are displayed.

Reply Post Reply
 
Thread Tools
  #1    
Old September 8th, 2015 (12:36 PM). Edited September 10th, 2015 by azurile13.
azurile13 azurile13 is offline
 
Join Date: Mar 2015
Posts: 353
I’ve been dragging my feet on writing this up, but today I bring you hidden abilities for FireRed.

Prerequisites
- Basic experience inserting ASM
- A hex editor
- The ability to read and write simple routines is a plus, though not required

I’ll try to be detailed with what specifically each step is doing in order to make modifications easier. If you don’t care about that, simply look for the walls of code.

Step 1: New Method for Determining Abilities
Spoiler:
In a vanilla ROM, a commonly used subroutine for deciding which ability a Pokemon gets is found at 0x08040D38. The function takes species and “ability bit” as arguments. This “ability bit” is a single bit in the Misc data substructure and is actually redundant, as it is merely a copy of the least significant bit of personality for any Pokemon with two possible abilities. My goal is to instead use “ability bit” as a marker for a Pokemon with hidden abilities and use personality to read the slotted abilities of Pokemon that do not have the hidden ability marker. All future mentions of “ability bit” (mostly in various routines I wrote) are now a reference to a hidden ability marker.

Assemble and paste binary at 0x08040D38:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x040D38

main:
	push {lr}
	bl offset_to_ability
	ldr r2, b_last_copied_ability
	strb r0, [r2]
	pop {r1}
	bx r1

offset_to_ability:
	push {r4-r5, lr}
	mov r4, r0
	mov r1, #0xB
	bl main - 0x1150 @get_attr
	lsl r5, r0, #0x10
	lsr r5, r5, #0x10
	mov r0, r4
	mov r1, #0x2E
	bl main - 0x1150 @get_attr
	lsl r1, r0, #0x1F
	ldr r0, [r4, #0x0]
	mov r2, r5 @species
	bl determine_ability
	pop {r4-r5}
	pop {r1}
	bx r1

determine_and_copy:
	push {lr}
	bl determine_ability
	ldr r2, b_last_copied_ability
	strb r0, [r2]
	pop {r1}
	bx r1

determine_ability:
	lsl r3, r2, #0x3
	sub r3, r3, r2
	lsl r3, r3, #0x2
	ldr r2, base_stats_table
	add r3, r2, r3 
	cmp r1, #0x0
	beq no_hidden
	ldrb r2, [r3, #0x1A]
	cmp r2, #0x0
	bne copy_hidden

no_hidden:
	lsl r0, r0, #0x1F
	cmp r0, #0x0
	beq first_slotted
	ldrb r0, [r3, #0x17]
	cmp r0, #0x0
	beq first_slotted
	bx lr

first_slotted:
	ldrb r0, [r3, #0x16]
	bx lr

copy_hidden:
	mov r0, r2
	bx lr

.align

base_stats_table: .word 0xYYYYYYYY @vanilla: 0x08254784
b_last_copied_ability: .word 0x02023D6A
Change 0xYYYYYYYY in the literal pool to wherever your base stats table happens to be. If the format looks a little odd to you, I’ve written it this way to allow future routines with slightly different arguments and required output to easily bl to different parts of the function.

Step 2: Everywhere the Game Calls the Function
Spoiler:
We’ll be making slight modifications to eleven routines. For most of them, it is most efficient to add an additional argument (personality) before the bl.

Paste the binaries of each of the following where the .org indicates. DO NOT PASTE THE WALLS OF ZEROES. If you don’t like the .org format or are not comfortable with where to begin copy/paste, you can comment them out and assemble all twelve of these one at a time as separate files.
Code:
.text
.align 2
.thumb
.thumb_func

.org 0x013144
first_routine:
	mov r1, r9
	ldrb r1, [r1]
	mul r1, r7
	add r1, r8
	ldr r0, [r1, #0x48] @personality
	ldrh r2, [r1] @species
	ldrb r1, [r1, #0x17]
	lsr r1, r1, #0x7 @ability bit
	bl first_routine + 0x2DC28 @0x08040D6C


.org 0x023FD0
second_routine:
	ldrb r0, [r7]
	mul r0, r6
	add r0, r0, r4
	ldrh r2, [r0, #0x0] @species
	ldrb r1, [r0, #0x17]
	lsr r1, r1, #0x7 @ability bit
	ldr r0, [r1, #0x48] @personality
	bl second_routine + 0x1CD9C @0x08040D6C
	ldrb r1, [r7]
@switches


.org 0x026E34
third_routine:
	ldrb r0, [r4, #0x0] @personality
	mov r1, r6 @ability bit
	mov r2, r5 @species
	bl third_routine + 0x19F38 @0x08040D6C
	lsl r0, r0, #0x0
@player ability


.org 0x026ECC
fourth_routine:
	and r0, r1
	cmp r0, #0x0
	beq fourth_routine + 0x20
	ldrb r0, [r4, #0x0] @personality
	mov r1, r6 @ability bit
	mov r2, r5 @species
	bl fourth_routine + 0x19EA0 @0x08040D6C
	lsl r0, r0, #0x0
	cmp r0, #0x2B
	beq fourth_routine + 0x20
	mov r0, #0x1
@opponent ability


.org 0x02A800
fifth_routine_part_a:
	mov r1, #0x41
	bl fifth_routine_part_a + 0x153E8 @get_attr
	mov r5, r0
	mov r0, r4
	mov r1, #0x2E
	bl fifth_routine_part_a + 0x153E8 @get_attr
	ldrb r4, [r4, #0x0] @lowest personality byte
	lsl r0, r0, #0x18
	orr r4, r0 @000000b 00000000 00000000 pppppppp
@player ability second


.org 0x02A890
fifth_routine_part_b:
	lsl r0, r4, #0x18
	lsr r0, r0, #0x18 @personality lowest byte
	lsr r1, r4, #0x18 @ability bit
	mov r2, r5 @species
	bl fifth_routine_part_b + 0x164DC @0x08040D6C
@opponent ability second


.org 0x02CE60
sixth_routine:
	mov r1, #0x41
	bl sixth_routine + 0x12D88 @get_attr
	lsl r0, r0, #0x10
	lsr r5, r0, #0x10
	mov r0, r4
	mov r1, #0xC @held item
	bl sixth_routine + 0x12D88 @get_attr
	lsl r0, r0, #0x10
	lsr r6, r0, #0x10
	mov r0, r4
	mov r1, #0x2E
	bl sixth_routine + 0x12D88 @get_attr
	lsl r1, r0, #0x18
	lsr r1, r1, #0x18 @ability bit
	ldrb r0, [r4, #0x0] @personality
	mov r2, r5 @species
	bl sixth_routine + 0x13F1A @0x08040D7A
	b sixth_routine + 0x42 @0x0802CEA2
@pickup


.org 0x039548
seventh_routine:
	lsl r0, r0, #0x18
	lsr r1, r0, #0x18 @ability bit
	ldrb r0, [r5, #0x0] @personality
	mov r2, r4 @species
	bl seventh_routine + 0x7832 @ 0x08040D7A
	b seventh_routine + 0x2A @ 0x08039572
@water/volt absorb, flash fire


.org 0x03999E
eighth_routine:
	lsl r0, r0, #0x18
	lsr r1, r0, #0x18 @ability bit
	ldrb r0, [r5, #0x0] @personality
	mov r2, r4 @species
	bl eighth_routine + 0x73DC @ 0x08040D7A
	b eighth_routine + 0x2E @ 0x080399CC
@ai calculations


.org 0x041318
ninth_routine:
	ldrh r2, [r7] @species
	ldrb r1, [r7, #0x17]
	lsr r1, r1, #0x7 @ability bit
	ldrb r0, [r4, #0x0] @personality
	bl ninth_routine - 0x5AC @ 0x08040D6C
	add r1, r7, #0x4
	strb r0, [r1, #0x1C]
@poke summary info


.org 0x082C70
tenth_routine:
	bl tenth_routine - 0x41F38 @0x08040D38
@stench, illuminate


.org 0x1366EC
eleventh_routine:
	lsl r4, r0, #0x10
	ldr r0, [r6]
	add r0, r8
	ldrb r1, [r0, #0x0] @personality
	orr r4, r1 @ssssssss ssssssss 00000000 pppppppp
	mov r1, #0x2E
	bl eleventh_routine - 0xF6B04 @get_attr
	lsl r0, r0, #0x18
	lsr r1, r0, #0x18 @ability bit
	lsl r0, r4, #0x18
	lsr r0, r0, #0x18 @personality
	lsr r2, r4, #0x10 @species
	bl eleventh_routine - 0xF5980 @ 0x08040D6C
	lsl r0, r0, #0x18
	lsr r4, r0, #0x18
	ldr r0, [r6]
@ability names

Step 3: Base Stats Table
Spoiler:
The base stats table contains a 0x1C bytes long entry for each Pokemon in the game ordered by index number. Fortunately, there is a halfword of padding at the end. If you read the first routine, you’ll know that I used the first of them, byte 0x1A (zero indexed), to hold the index of a hidden ability.

Crack open a hex editor, change width to 0x1C bytes, and add hidden abilities to the base stats table. Leaving a hidden ability/second slotted ability as 0x00 won’t cause problems even if an in game Pokemon has a “hidden” marker; the routine from step 1 simply moves on until it finds a non-zero ability index. If you have not expanded Pokemon, your base stats table is most likely at 0x08254784. For convenience sake, here are the indices for each ability in a vanilla FireRed ROM:
Code:
stench:          .equ 1
drizzle:         .equ 2
speed_boost:     .equ 3
battle_armor:    .equ 4
sturdy:          .equ 5
damp:            .equ 6
limber:          .equ 7
sand_veil:       .equ 8
static_:         .equ 9
volt_absorb:     .equ 0xA
water_absorb:    .equ 0xB
oblivious:       .equ 0xC
cloud_nine:      .equ 0xD
compound_eyes:   .equ 0xE
insomnia:        .equ 0xF
color_change:    .equ 0x10
immunity:        .equ 0x11
flash_fire:      .equ 0x12
shield_dust:     .equ 0x13
own_tempo:       .equ 0x14
suction_cups:    .equ 0x15
intimidate:      .equ 0x16
shadow_tag:      .equ 0x17
rough_skin:      .equ 0x18
wonder_guard:    .equ 0x19
levitate:        .equ 0x1A
effect_spore:    .equ 0x1B
synchronize:     .equ 0x1C
clear_body:      .equ 0x1D
natural_cure:    .equ 0x1E
lightningrod:    .equ 0x1F
serene_grace:    .equ 0x20
swift_swim:      .equ 0x21
chlorophyll:     .equ 0x22
illuminate:      .equ 0x23
trace:           .equ 0x24
huge_power:      .equ 0x25
poison_point:    .equ 0x26
inner_focus:     .equ 0x27
magma_armor:     .equ 0x28
water_veil:      .equ 0x29
magnet_pull:     .equ 0x2A
soundproof:      .equ 0x2B
rain_dish:       .equ 0x2C
sand_stream:     .equ 0x2D
pressure:        .equ 0x2E
thick_fat:       .equ 0x2F
early_bird:      .equ 0x30
flame_body:      .equ 0x31
run_away:        .equ 0x32
keen_eye:        .equ 0x33
hyper_cutter:    .equ 0x34
pickup:          .equ 0x35
truant:          .equ 0x36
hustle:          .equ 0x37
cute_charm:      .equ 0x38
plus:            .equ 0x39
minus:           .equ 0x3A
forecast:        .equ 0x3B
sticky_hold:     .equ 0x3C
shed_skin:       .equ 0x3D
guts:            .equ 0x3E
marvel_scale:    .equ 0x3F
liquid_ooze:     .equ 0x40
overgrow:        .equ 0x41
blaze:           .equ 0x42
torrent:         .equ 0x43
swarm:           .equ 0x44
rock_head:       .equ 0x45
drought:         .equ 0x46
arena_trap:      .equ 0x47
vital_spirit:    .equ 0x48
white_smoke:     .equ 0x49
pure_power:      .equ 0x4A
shell_armor:     .equ 0x4B
cacophony:       .equ 0x4C
air_lock:        .equ 0x4D

Step 4: Pokemon Generation
Spoiler:
Great! Now the game knows how to read hidden abilities. But in the current state, the only in game effect would be a Pokemon having a hidden ability half the time and never having a second slotted ability. Clearly this isn’t ideal.

We begin with a commonly used Pokemon generation routine, specifically a part of it at 0x0803DD58. This is responsible for setting the ability bit of a Pokemon dependent on the least significant bit of personality and whether or not the Pokemon can have a second ability. There’s a little space here for some manipulation, but because the function is used by numerous other routines, I’ve decided to make it automatically set the “ability bit” of every Pokemon generated to zero. In other words, by default, generated Pokemon will not have a hidden ability. Any setting of the hidden ability bit will occur after this function is called to allow for more flexibility between different methods of Pokemon creation.

Assemble and paste binary at 0x0803DD58:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x03DD58

main:
	mov r0, #0x0
	str r0, [sp, #0x18]
	mov r0, r7
	mov r1, #0x2E
	mov r2, r9
	bl main + 0x2778 @ set_pokemon_data_2
	b main + 0x26 @ 0x0803DD7E

Step 5: Wild Pokemon
Spoiler:
As indicated by the header, we now work our way through being able to set hidden ability bits for wild Pokemon.

Assemble at 0x080829FC:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x0829FC

main:
	push {r4-r6, lr}
	sub sp, sp, #0x10
	lsl r4, r0, #0x10
	lsr r4, r4, #0x10
	lsl r6, r1, #0x18
	lsl r5, r2, #0x18
	lsr r5, r5, #0x18
	bl main - 0x44FC8 @purge_opponent 0x0803DA34
	cmp r4, #0xC9
	beq generate_unown
	mov r1, r4 @species
	mov r0, #0x0
	str r0, [sp, #0x0] @random personality
	b call_make_mon
	
generate_unown:
	ldr r0, block_eight
	ldr r0, [r0]
	ldrb r1, [r0, #0x5]
	sub r1, r1, #0x1B
	ldr r2, tanoby_table_probably
	lsl r1, r1, #0x18
	asr r1, r1, #0x18
	lsl r0, r1, #0x1
	add r0, r0, r1
	lsl r0, r0, #0x2
	add r0, r5, r0
	add r0, r0, r2
	ldrb r0, [r0]
	bl  unown_something
	mov r1, #0x1
	str r1, [sp, #0x0]
	str r0, [sp, #0x4]
	mov r1, #0xC9
	mov r0, #0x0

call_make_mon:
	str r0, [sp, #0x8] @no auto shineaz
	str r0, [sp, #0xC]
	ldr r0, party_opponent	
	lsr r2, r6, #0x18
	mov r3, #0x20
	bl main - 0x44FA8 @pokemon_make_2 0x0803DA54

checks_hidden_flag:
	ldr r0, flag_hex
	bl main - 0x1432C @flag check 0x0806E6D0

store_hidden_ability_result:
	str r0, [sp, #0x0]
	ldr r0, party_opponent
	mov r1, #0x2E
	mov r2, sp
	bl main - 0x4252C @set_pokemon_data_2 0x080404D0

clear_hidden_flag:
	ldr r0, flag_hex
	bl main - 0x14354 @flag clear 0x0806E6A8

end:
	add sp, sp, #0x10
	pop {r4-r6}
	pop {r0}
	bx r0

unown_something:
	push {r4-r5, lr}
	lsl r5, r0, #0x18

unown_loop:
	bl main - 0x3DB34 @ random 0x044EC8
	lsl r4, r0, #0x10
	bl main - 0x3DB34 @ random 0x044EC8
	orr r4, r0
	bl main + 0xBC @  0x08082AB8
	lsl r0, r0, #0x18
	cmp r0, r5
	bne unown_loop
	mov r0, r4
	pop {r4, r5}
	pop {r1}
	bx r1

.align

block_eight: .word 0x03005008
tanoby_table_probably:	.word 0x083CA71C
party_opponent: .word 0x0202402C
flag_hex: .word 0xYYY
Note the bolded instructions. These are merely examples; you can do whatever you want so long as the ultimate result is r0 containing byte 0x0 for no hidden ability or 0x1 for having a hidden ability in that first bolded section. Remember, however, that what is assembled cannot exceed the next routine which begins at 0x08082AB8. In total, (and assuming you removed all three bolded sections), you have 0x24 bytes to work with. If you need more than that, you’ll need to either give yourself extra bytes by finding inefficient instructions in the existing routine or add a hook.

I chose the format above to make it easy to work with for people without asm knowledge. In the current form, it will check a specified flag (0xYYY in the literal pool) and if the flag is set, gives the wild Pokemon a hidden ability bit. I also made the routine automatically clear the flag. This isn’t necessary, but I would guess that it’s easier to use from a scripting standpoint.

It is also rather simple to make a hidden ability luck dependent by bl’ing to the prng at 0x08044EC8 and doing a comparison after, or perhaps in lieu of, the flag check.

Don’t worry about the Unown stuff; I tacked it together because the only calls to it originated from this routine and I wanted to rewrite it to give more space for people to write hidden ability triggers.

Step 6: NPC Wild Encounters
Spoiler:
It would probably be useful to generate hidden ability Pokemon through script, such as legendaries or special Pokemon in general. Assemble and paste the following in any halfword aligned free space:
Code:
.text
.align 2
.thumb
.thumb_func

check_for_hidden:
	ldr r0, hex_flag
	ldr r3, func_flag_check
	bl bx_r3
	cmp r0, #0x1
	bne end

give_hidden_ability:
	push {r0}
	ldr r3, func_set_attr
	mov r2, sp
	mov r1, #0x2E
	mov r0, r8
	bl bx_r3
	add sp, #0x4

clear_flag:
	ldr r0, hex_flag
	ldr r3, func_flag_clear
	bl bx_r3

end:
	pop {r3}
	mov r8, r3
	pop {r4-r7}
	pop {r3}

bx_r3:
	bx r3

.align

func_flag_check: .word 0x0806E6D0 + 1
func_set_attr: .word 0x0804037C + 1
func_flag_clear: .word 0x0806E6A8 + 1
hex_flag: .word 0xYYY
It should look very familiar. Just like standard wild Pokemon, I’m using a simple flag to toggle hidden abilities. You can rewrite the conditions to be as arbitrary as you would like. It is worth mentioning that although it can be, the flag in this step does not necessarily need to be the same as the flag used in the fifth step.

Take note of where you pasted the above routine. You’ll need that offset to place the following at 0x080A02EC:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x0A02EC

main:
	ldr r0, check_for_hidden
	bx r0

.align

check_for_hidden: .word 0xYYYYYYYY + 1

Step 7: Daycare
Spoiler:
We’ll be doing another hook here. Again, assemble and paste binary in halfword aligned free space:
Code:
.text
.align 2
.thumb
.thumb_func

inherit_hidden:
	add r0, r5, #0x0
	ldr r3 , func_roll_gender
	bl bx_r3
	cmp r0, #0xFE
	beq mother_in_slot_one
	mov r0, r5
	add r0, r0, #0x8C
	mov r1, #0xB
	bl get_zero_attr
	cmp r0, #0x84
	beq mother_in_slot_one
	mov r0, r5
	add r0, r0, #0x8C
	b check_for_hidden

mother_in_slot_one:
	add r0, r5, #0x0

check_for_hidden:
	mov r1, #0x2E
	bl get_zero_attr
	cmp r0, #0x0
	beq end
	ldr r3, func_rand
	bl bx_r3
	lsr r0, r0, #0x8
	cmp r0, #0x99
	bhi end
	ldr r3, func_set_attr
	mov r2, #0x1
	push {r2}
	mov r2, sp
	mov r1, #0x2E
	mov r0, r4
	bl bx_r3
	add sp, #0x4

end:
	mov r2, r4
	add r2, r2, #0x6A
	mov r0, #0x1
	strb r0, [r2]
	mov r0, r4
	ldr r1, func_return
	bx r1

get_zero_attr:
	mov r2, #0x0
	ldr r3, func_get_attr

bx_r3:
	bx r3

.align

func_roll_gender: .word 0x0803F730 + 1
func_get_attr: .word 0x0803FBE8 + 1
func_rand: .word 0x08044EC8 + 1
func_set_attr: .word 0x0804037C + 1
func_return: .word 0x08046120 + 1
Add the following hook at 0x08046116:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x046116

main:
	mov r4, sp
	ldr r0, inherit_hidden
	bx r0

inherit_hidden: .word 0xYYYYYYYY + 1 @your routine

Step 8: Egg Hatching
Spoiler:
Apparently the egg hatching routine saves attributes that are already in the egg, calls a Pokemon making routine, then sets those attributes again. So two little fixes:

First, at 0x08046CA0:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x046CA0

main:

	mov r0, r6
	mov r1, #0x2E
Second, at 0x08046D3C:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x046D3C

main:
	mov r0, r5
	mov r1, #0x2E
Feel free to look at what’s going on here beginning at 0x08046BFC. All I’ve done was change the save and set obedience to instead save and set hidden ability bit. If you’re like, super attached to creating obedient/disobedient Mew/Deoxys eggs, I guess you can tighten up the main routine, but it honestly isn’t something I am particularly passionate about.

Step 9: Trainers
Spoiler:
A great way to selectively give hidden abilities to trainers is a modified version of DoesntKnowHowToPlay’s Trainer EV Method. It can be found here: http://www.pokecommunity.com/showthread.php?t=307117

Use any of the filler bytes and add a hidden ability insertion somewhere in the Method Address that mimics the load style. For example, the following could be placed anywhere around the loads:
Code:
lsl r0, r6, #0x4
ldr r2, .EV_Table
add r2, r0
add r2, #0xF @1 = hidden ability
mov r1, #0x2E @needed to set hidden ability bit
mov r0, r4
bl Insert_Element


And we’re done! But a few more comments.

All of the above steps were done with a vanilla FireRed ROM. I haven’t tested much with them, so I could imagine contributions to the Ability Resource/Move Resource Threads having conflicting hooks or more hooks being necessary for new and updated abilities/attacks. If necessary, I’ll attempt to make updates to remedy any incompatibilities. I’ll also be adding a method for triggering hidden abilities with rods sometime in the future. I haven’t even looked into it yet because, to be frank, it isn’t something I really cared about. But rest assured I’ll find another hook for completeness sake.

Credits:
A big thanks to Touched for providing the necessary hooks for many of these routines as well as walking me through a good amount of ASM reading and logic in general.

Also instrumental was the valuable research in knizz’s idb, IMO the greatest tool in a FireRed hacker’s arsenal.

DoesntKnowHowToPlay’s Trainer EV Hack saved me a good amount of time with trainer research.

Any questions/comments welcome.

Extras
Spoiler:
Flame Body and Magma Armor
Spoiler:
Halfword aligned free space:
Code:
.text
.align 2
.thumb
.thumb_func

check_flame:
	mov r5, #0x0 @counter

check_ability_loop:
	mov r0, #0x64
	mul r0, r5
	ldr r1, party_offset
	add r4, r1, r0
	mov r0, r4
	mov r1, #0x6
	ldr r3, func_get_attr
	bl bx_r3
	cmp r0, #0x0
	bne increment_loop
	mov r0, r4
	ldr r3, func_get_ability
	bl bx_r3
	cmp r0, #0x28 @magma armor
	beq set_doubled
	cmp r0, #0x31 @flame body
	beq set_doubled

increment_loop:
	add r5, #0x1
	ldr r0, party_quantity
	ldrb r0, [r0]
	cmp r5, r0
	ble check_ability_loop
	mov r7, #0x1
	b end

set_doubled:
	mov r7, #0x2

end:
	mov r5, #0x0
	ldr r3, func_return

bx_r3:
	bx r3

.align

party_offset: .word 0x02024284
party_quantity: .word 0x02024029
func_get_attr: .word 0x0803FBE8 + 1
func_get_ability: .word 0x08040D46 + 1
func_return: .word 0x080463A0 + 1
Assemble and paste at 0x08046340:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x046340

hook_flame_check:
	cmp r0, #0xFF
	bne hook_flame_check + 0x68  @0x080463A8
	ldr r0, check_flame
	bx r0

check_flame: .word 0xYYYYYYYY + 1
Where “check_flame” is the routine placed in free space above.
At 0x0804637C:
Code:
.text
.align 2
.thumb
.thumb_func

@.org 0x04637C

compare_to_decrement:
	cmp r0, r7
	bge reduce_cycles
	ldr r0, var8004
	strh r5, [r0]
	mov r0, #0x1
	b compare_to_decrement + 0x2E

party_player: .word 0x02024284
var8004: .word 0x020370C0

reduce_cycles:
	sub r0, r0, r7
	str r0, [sp, #0x0]
Reply With Quote

Relevant Advertising!

  #2    
Old September 8th, 2015 (2:46 PM).
Dark Zeta's Avatar
Dark Zeta Dark Zeta is offline
That guy you don't know yet
 
Join Date: Dec 2014
Location: Mississippi, U.S.
Age: 21
Gender: Male
Nature: Lax
Posts: 177
Well, since no one has said anything, this is fantastic. I've been wondering when someone would get along to doing this.

I have one problem that is very minor though. That unused half word is used in a routine to give wild Pokemon there own wild battle theme. That's very minute, but still a thing.

I am going to give my tool support for editing that byte, so no one here will have to hex edit anymore. (Just something to make it a little less tedious).
D&D Editor
Romhack.it
Romhack.me

Twitter
Reply With Quote
  #3    
Old September 8th, 2015 (3:23 PM).
azurile13 azurile13 is offline
 
Join Date: Mar 2015
Posts: 353
Quote:
Originally Posted by Dark Zeta View Post
Well, since no one has said anything, this is fantastic. I've been wondering when someone would get along to doing this.

I have one problem that is very minor though. That unused half word is used in a routine to give wild Pokemon there own wild battle theme. That's very minute, but still a thing.

I am going to give my tool support for editing that byte, so no one here will have to hex edit anymore. (Just something to make it a little less tedious).
Thanks a lot!

And really? I had no idea because they're zeroes all the way down. Do you know where that theme routine is? I don't understand why it would need that halfword of zeroes. I could either try to alter that routine or use free space to store the hidden abilities. It by no means needs to be in the base stats table; that was only for convenience.
Reply With Quote
  #4    
Old September 8th, 2015 (4:03 PM).
Dark Zeta's Avatar
Dark Zeta Dark Zeta is offline
That guy you don't know yet
 
Join Date: Dec 2014
Location: Mississippi, U.S.
Age: 21
Gender: Male
Nature: Lax
Posts: 177
Quote:
Originally Posted by azurile13 View Post
Thanks a lot!

And really? I had no idea because they're zeroes all the way down. Do you know where that theme routine is? I don't understand why it would need that halfword of zeroes. I could either try to alter that routine or use free space to store the hidden abilities. It by no means needs to be in the base stats table; that was only for convenience.
It is 00's in a vanilla ROM. Darthatron made a routine some time a while back that uses those halfwords though. I'm sure it can be modified to use only a byte though. That would allow for both routines to be used at the same time.

I see no problem with them being in the base stats table. It makes it easier to deal with tbh.

This is the original tutorial I used to implement the routine with my tool.
http://www.romhack.me/tutorials/view...tom-set-music/
D&D Editor
Romhack.it
Romhack.me

Twitter
Reply With Quote
  #5    
Old September 9th, 2015 (12:48 AM).
kleenexfeu kleenexfeu is offline
 
Join Date: Aug 2013
Gender: Male
Posts: 216
well done, and thanks for sharing such a good feature !

Other than congrat you, I wanted to say that feature shouldn't be a problem for new abilities. They are implemented in the battle engine while you're hooking in get_attr or set_attr, so no worries

For abilities with effect in the overworld though, slight modification should be done (flame body...)
Links for my work:
Dynamic Emerald Attack ROMbase
Mega Evolution, Wish, Primal Reversion for Emerald

Arceus and Giratina Forms
Some abilities:

Touched's Emerald IDB + Battle stuffs
Touched's Emerald IDB 6.8 + Battle stuffs
Reply With Quote
  #6    
Old September 9th, 2015 (12:58 AM).
Deokishisu's Avatar
Deokishisu Deokishisu is offline
Mr. Magius
 
Join Date: Feb 2006
Location: If I'm online, it's a safe bet I'm at a computer.
Gender: Male
Nature: Relaxed
Posts: 670
Quote:
Originally Posted by kleenexfeu View Post
well done, and thanks for sharing such a good feature !

Other than congrat you, I wanted to say that feature shouldn't be a problem for new abilities. They are implemented in the battle engine while you're hooking in get_attr or set_attr, so no worries

For abilities with effect in the overworld though, slight modification should be done (flame body...)
Pretty sure the only ability that works outside of battle in vanilla Firered is Pickup. Actually, maybe not even that. Doesn't Pickup work after winning a battle? So that probably doesn't count.
Reply With Quote
  #7    
Old September 9th, 2015 (1:06 AM).
kleenexfeu kleenexfeu is offline
 
Join Date: Aug 2013
Gender: Male
Posts: 216
Quote:
Originally Posted by Deokishisu View Post
Pretty sure the only ability that works outside of battle in vanilla Firered is Pickup. Actually, maybe not even that. Doesn't Pickup work after winning a battle? So that probably doesn't count.
Hackmew implemented the latest flame body effect : make eggs hatch faster when you carry a poke with flame body.
I don't know for pickup how that works.
Also I was talking about future abilities we could implement, because azurile talked about the resource thread.

Oh and I'm reading the article on bulbapedia, there's actually many abilities that have effect in the field, number of them where already present in genIII
Reply With Quote
  #8    
Old September 9th, 2015 (2:05 AM).
Deokishisu's Avatar
Deokishisu Deokishisu is offline
Mr. Magius
 
Join Date: Feb 2006
Location: If I'm online, it's a safe bet I'm at a computer.
Gender: Male
Nature: Relaxed
Posts: 670
Quote:
Originally Posted by kleenexfeu View Post
Hackmew implemented the latest flame body effect : make eggs hatch faster when you carry a poke with flame body.
I don't know for pickup how that works.
Also I was talking about future abilities we could implement, because azurile talked about the resource thread.

Oh and I'm reading the article on bulbapedia, there's actually many abilities that have effect in the field, number of them where already present in genIII
Didn't realize that you were talking about future abilities that could be implemented, my bad!

But all of the abilities that have field effects gained their field effect in Emerald. That wasn't a feature at all until then.
Reply With Quote
  #9    
Old September 9th, 2015 (1:21 PM). Edited September 9th, 2015 by azurile13.
azurile13 azurile13 is offline
 
Join Date: Mar 2015
Posts: 353
Quote:
Originally Posted by Dark Zeta View Post
It is 00's in a vanilla ROM. Darthatron made a routine some time a while back that uses those halfwords though. I'm sure it can be modified to use only a byte though. That would allow for both routines to be used at the same time.
Ah, that makes more sense. I thought you were referring to a routine that was naturally in the game and I was very confused.

Quote:
Originally Posted by kleenexfeu View Post
Other than congrat you, I wanted to say that feature shouldn't be a problem for new abilities. They are implemented in the battle engine while you're hooking in get_attr or set_attr, so no worries
Thanks! And that’s good to know. The reason I wasn’t sure was that there were a few hooks checking for abilities like Water Absorb and Flash Fire. I wasn’t sure if they were for AI logic or something like that.

Quote:
Originally Posted by Deokishisu View Post
Pretty sure the only ability that works outside of battle in vanilla Firered is Pickup. Actually, maybe not even that. Doesn't Pickup work after winning a battle? So that probably doesn't count.
Pickup is the reason for the “sixth_routine” in step 2.
There’s also a Stench and Illuminate check after “tenth_routine,” but no one cares about those abilities so they’re always forgotten.

Quote:
Originally Posted by kleenexfeu View Post
Hackmew implemented the latest flame body effect : make eggs hatch faster when you carry a poke with flame body.
I don't know for pickup how that works.
Also I was talking about future abilities we could implement, because azurile talked about the resource thread.

Oh and I'm reading the article on bulbapedia, there's actually many abilities that have effect in the field, number of them where already present in genIII
Yeah, I can create an “extras” section with optional added field effects. Even if they’re not specific to FireRed or hidden abilities, I think it would make sense to add them to avoid conflicting hooks. I’m not familiar with Hackmew’s Flame Body hack, but I already have one written up that works with hidden abilities; I’m sure it is basically the same thing. Effects related to encounter rates could probably be added around Stench and Illuminate. Magnet Pull-esque effects could be a little tricker, but worst case scenario you could load the list of all possible wild Pokemon and manually check each of them for a type. I’d predict that personality based effects like Synchronize and Cute Charm could be hooked in around “Step 5: Wild Pokemon.” Honey Gather at the same spot as Pickup. I think that I’m looking at the same list that you are, and most of them seem pretty doable.
Reply With Quote
  #10    
Old September 9th, 2015 (4:14 PM).
MrDollSteak's Avatar
MrDollSteak MrDollSteak is offline
Formerly known as 11bayerf1
 
Join Date: Dec 2008
Location: Hong Kong
Age: 21
Gender: Male
Posts: 728
This is an absolutely fantastic achievement!

I'm a bit unsure about the first example of the YYY flag. Does it mean that the game randomly sets the flag, and then generates a HA Pokemon when the flag is set, and then turns it off?

Or is it a matter of you're in a specific map bank, and it sets the flag?

What I think may be best is as you do with the NPC Routine, making it trigger on two flags. One flag that is set in a script, so you could make every Pokemon in a certain map or location have a hidden ability, and then the seperate randomly generated flag.

But either way, absolutely fantastic work! Great job
Reply With Quote
  #11    
Old September 10th, 2015 (11:18 AM).
Dark Zeta's Avatar
Dark Zeta Dark Zeta is offline
That guy you don't know yet
 
Join Date: Dec 2014
Location: Mississippi, U.S.
Age: 21
Gender: Male
Nature: Lax
Posts: 177
Quote:
Originally Posted by azurile13 View Post
Thanks a lot!

And really? I had no idea because they're zeroes all the way down. Do you know where that theme routine is? I don't understand why it would need that halfword of zeroes. I could either try to alter that routine or use free space to store the hidden abilities. It by no means needs to be in the base stats table; that was only for convenience.
Just letting you know my new update to my editor now supports your routine. You can test it if you want to.
D&D Editor
Romhack.it
Romhack.me

Twitter
Reply With Quote
  #12    
Old September 10th, 2015 (2:41 PM).
azurile13 azurile13 is offline
 
Join Date: Mar 2015
Posts: 353
Quote:
Originally Posted by MrDollSteak View Post
This is an absolutely fantastic achievement!

I'm a bit unsure about the first example of the YYY flag. Does it mean that the game randomly sets the flag, and then generates a HA Pokemon when the flag is set, and then turns it off?

Or is it a matter of you're in a specific map bank, and it sets the flag?

What I think may be best is as you do with the NPC Routine, making it trigger on two flags. One flag that is set in a script, so you could make every Pokemon in a certain map or location have a hidden ability, and then the seperate randomly generated flag.

But either way, absolutely fantastic work! Great job
I appreciate the feedback! Reading it over now, I see that I never explicitly said that you were meant to set the flag in the overworld. Nothing in the example routine was random, though I see how my follow up “prng” comment helped to further muddle the message. Oops. The idea was that you have some event and set a flag that makes the next Pokemon you find in the grass/water have a hidden ability, or perhaps you have level scripts on certain maps that set the flag. Now that I’m actually thinking it over, however, that seems quite inconvenient as there is nothing to turn the flag off when you enter a “non hidden” map without putting another level script on just about every other map with wild encounters.

Off the top of my head, I think that maybe a better way would be to make a table with a list of 2 byte entries of map bank and map number (or something like that) and make comparisons to whether or not the map you are in matches any of the maps in that table. The following uses more bytes than possible without a hook, but something like:
Code:
	ldr r0, current_map_bank_offset
	ldrh r0, [r0] @load bank and number simultaneously
	ldr r1, list_of_hidden_ability_maps
	mov r3, (number of maps on hidden ability maps list)

loop:
	cmp r3, #0x0
	beq end @none of the maps on the list match the map you're in
	ldrh r2, [r1]
	add r1, r1, #0x2 @move to offset of next map on table
	sub r3, #0x1
	cmp r0, r2
	bne loop
	mov r0, #0x1
store_hidden_ability_result:

. . . . . . .

current_map_bank_offset: .word 0x02031DBC
list_of_hidden_ability_maps: .word 0x08YYYYYY
But really, basically anything would work; I was aiming to give the maximum possible flexibility to someone who knows purely scripting commands.

Quote:
Originally Posted by Dark Zeta View Post
Just letting you know my new update to my editor now supports your routine. You can test it if you want to.
That’s good the hear! Unfortunately, I have a Mac, and I’m assuming your tool hasn’t been ported yet, so I can’t personally test it :/ But I can’t wait for a version that I can use!

On an unrelated note, I’ll slowly be adding overworld abilities to the OP. As a mini update, I’ve added Flame Body and Magma Armor because they’re easy to do they're super useful.
Reply With Quote
  #13    
Old September 10th, 2015 (4:22 PM).
MrDollSteak's Avatar
MrDollSteak MrDollSteak is offline
Formerly known as 11bayerf1
 
Join Date: Dec 2008
Location: Hong Kong
Age: 21
Gender: Male
Posts: 728
Quote:
Originally Posted by azurile13 View Post
I appreciate the feedback! Reading it over now, I see that I never explicitly said that you were meant to set the flag in the overworld. Nothing in the example routine was random, though I see how my follow up “prng” comment helped to further muddle the message. Oops. The idea was that you have some event and set a flag that makes the next Pokemon you find in the grass/water have a hidden ability, or perhaps you have level scripts on certain maps that set the flag. Now that I’m actually thinking it over, however, that seems quite inconvenient as there is nothing to turn the flag off when you enter a “non hidden” map without putting another level script on just about every other map with wild encounters.

Off the top of my head, I think that maybe a better way would be to make a table with a list of 2 byte entries of map bank and map number (or something like that) and make comparisons to whether or not the map you are in matches any of the maps in that table. The following uses more bytes than possible without a hook, but something like:
Code:
	ldr r0, current_map_bank_offset
	ldrh r0, [r0] @load bank and number simultaneously
	ldr r1, list_of_hidden_ability_maps
	mov r3, (number of maps on hidden ability maps list)

loop:
	cmp r3, #0x0
	beq end @none of the maps on the list match the map you're in
	ldrh r2, [r1]
	add r1, r1, #0x2 @move to offset of next map on table
	sub r3, #0x1
	cmp r0, r2
	bne loop
	mov r0, #0x1
store_hidden_ability_result:

. . . . . . .

current_map_bank_offset: .word 0x02031DBC
list_of_hidden_ability_maps: .word 0x08YYYYYY
But really, basically anything would work; I was aiming to give the maximum possible flexibility to someone who knows purely scripting commands.
Oh sure I understand completely! Sorry I thought I read something that said the flag was turned off in the battle. To be honest I think how it is is fine. I thought setting level scripts to turn them on / off would make the most sense and isn't too annoying.

Though the map bank idea sounds pretty good as well. Ulltimately the more options there are the better I think!

I'll look into porting this to Emerald soon
Reply With Quote
  #14    
Old September 24th, 2015 (8:45 AM).
Hbreathat Hbreathat is offline
 
Join Date: Sep 2015
Gender: Male
Posts: 5
hey when your done developing that tool pm me. And if possible can you make it compatible with pokémon Emerald?
Reply With Quote
  #15    
Old September 24th, 2015 (9:29 AM).
Dark Zeta's Avatar
Dark Zeta Dark Zeta is offline
That guy you don't know yet
 
Join Date: Dec 2014
Location: Mississippi, U.S.
Age: 21
Gender: Male
Nature: Lax
Posts: 177
Quote:
Originally Posted by Hbreathat View Post
hey when your done developing that tool pm me. And if possible can you make it compatible with pokémon Emerald?
Who is this in reference to?
D&D Editor
Romhack.it
Romhack.me

Twitter
Reply With Quote
  #16    
Old September 25th, 2015 (8:15 AM).
Hbreathat Hbreathat is offline
 
Join Date: Sep 2015
Gender: Male
Posts: 5
Leafeon and glaceon. if possible. thanks
Reply With Quote
  #17    
Old September 25th, 2015 (9:18 AM).
azurile13 azurile13 is offline
 
Join Date: Mar 2015
Posts: 353
Quote:
Originally Posted by Hbreathat View Post
Leafeon and glaceon. if possible. thanks
I don't know what thread you think you're in, but your requests commands don't make sense, so I suggest you read the OP.
Reply With Quote
Reply Post Reply
Quick Reply

Sponsored Links
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


  All times are GMT -8. The time now is 10:52 AM.


Contact Us Archive Privacy Statement Terms of Service Top