The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Fan Games > Binary ROM Hacking > Binary Hack Research & Development
Reload this Page Code ASM Resource Thread

Notices
For all updates, view the main page.

Binary Hack Research & Development Got a well-founded knack with your binary Pokémon hacks? Love reverse-engineering them? For the traditional Pokémon ROM hacker, this is the spot for polling and gathering your ideas, and then implementing them! Share your hypothesis, get ideas from others, and collaborate to create!

Ad Content
Reply
 
Thread Tools
  #1501   Link to this post, but load the entire thread.  
Old June 6th, 2020 (10:09 PM). Edited June 6th, 2020 by AkameTheBulbasaur.
AkameTheBulbasaur's Avatar
AkameTheBulbasaur AkameTheBulbasaur is offline
Akame Marukawa of Iyotono
 
Join Date: May 2013
Location: A place :D
Age: 25
Gender: Male
Nature: Docile
Posts: 408
Var Mathematics For FireRed
In NPC scripting, there exist commands to add/subtract an integer value to a variable (AddVar an SubtractVar). However, these commands may be a little bit limited. It may be that you want to multiply or divide a var, or add two vars together. In that case, you can use these:

What To Do First
First, you will want to find two half-words of free RAM. It does not need to be permanent RAM (RAM that is saved with the game). However, you will need to know what number var that RAM corresponds to. I recommend NOT using the 0x8000+ temp vars, since then you will be unable to manipulate values stored into them.

These routines use the vars 0x4074 and 0x4075 by default, but these can be changed in the following way.

1. Figure out the difference between the var you want to use and 0x4074. Keep in mind this is in hexadecimal.
2. Multiply that value by two.
3. Add (or subtract if your var is less than 0x4074) from 0x02026614. This is still in hexadecimal. You should then get the RAM address of the var you want to use.
4. Repeat for the second var if desired.
5. Change the addresses after .Var4074 and .Var4075.

The Actual Routines
The routines below perform the following operations:

1. Addition
2. Subtraction
3. Multiplication
4. Division
5. AND
6. OR

For the AND and OR operations, I'll explain them a little for those who are not familiar with them. If you AND two binary numbers, the resulting number has the bit equal to one if the corresponding bits of the input numbers are the same, and zero if they were different. For example, 1011 AND 1100 = 1000.

For the OR operation, if both bits of the input numbers are zero, it returns zero. Otherwise it returns one. In other words, if one OR the other number has a bit equal to one, the resulting number's bit is set equal to one. For example, 0010 OR 1000 = 1010.

Add Vars
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global AddVars

/* The purpose of this function is to add the vars */
/* stored in 0x4074 and 0x4075 */

/* This adds 0x4075 to 0x4074 */
/* Since addition is commutative, this doesn't matter */
/* But for the SubtractVar routine this will matter */

Main:
push {r0-r5, lr}
ldr r4, .Var4074 /* First Var */
ldrh r4, [r4]
ldr r5, .Var4075 /* Second Var */
ldrh r5, [r5]

GetTheRAM:
mov r0, r4
bl GetVarRAM
mov r4, r0 /* Address of the first var */
ldrh r4, [r4] /* Value in that var */
mov r0, r5
bl GetVarRAM
mov r5, r0 /* Address of the second var */
ldrh r5, [r5] /* Value in that var */

AddThem:
add r4, r4, r5 /* Adds r5 to r4 and stores in r4 */
ldr r0, .LastResult
strh r4, [r0] /* Puts result in LASTRESULT */
pop {r0-r5, pc}

GetVarRAM:
ldr r1, .GetVarRAM
bx r1

.align 2
.Var4074: .word 0x02026614
.Var4075: .word 0x02026616
.GetVarRAM: .word 0x0806E455
.LastResult: .word 0x020370D0


Subtract Vars
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global SubtractVars

/* The purpose of this function is to subtract the vars */
/* stored in 0x4074 and 0x4075 */

/* This subtracts 0x4075 from 0x4074 */
/* Subtraction is NOT commutative so the order matters! */
/* Also, negative numbers are represented as really big */
/* Positive numbers */

/* So 0x0 - 0x1 = 0xFFFF = 65,535 */

Main:
push {r0-r5, lr}
ldr r4, .Var4074 /* First Var */
ldrh r4, [r4]
ldr r5, .Var4075 /* Second Var */
ldrh r5, [r5]

GetTheRAM:
mov r0, r4
bl GetVarRAM
mov r4, r0 /* Address of the first var */
ldrh r4, [r4] /* Value in that var */
mov r0, r5
bl GetVarRAM
mov r5, r0 /* Address of the second var */
ldrh r5, [r5] /* Value in that var */

SubtractThem:
sub r4, r4, r5 /* Subtracts r5 from r4 and stores in r4 */
ldr r0, .LastResult
strh r4, [r0] /* Puts result in LASTRESULT */
pop {r0-r5, pc}

GetVarRAM:
ldr r1, .GetVarRAM
bx r1

.align 2
.Var4074: .word 0x02026614
.Var4075: .word 0x02026616
.GetVarRAM: .word 0x0806E455
.LastResult: .word 0x020370D0


Multiply Vars
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global MultiplyVars

/* The purpose of this function is to multiply the vars */
/* stored in 0x4074 and 0x4075 */

/* This multiplies 0x4075 and 0x4074 */
/* Multiplication is commutative yay */

Main:
push {r0-r5, lr}
ldr r4, .Var4074 /* First Var */
ldrh r4, [r4]
ldr r5, .Var4075 /* Second Var */
ldrh r5, [r5]

GetTheRAM:
mov r0, r4
bl GetVarRAM
mov r4, r0 /* Address of the first var */
ldrh r4, [r4] /* Value in that var */
mov r0, r5
bl GetVarRAM
mov r5, r0 /* Address of the second var */
ldrh r5, [r5] /* Value in that var */

MultiplyThem:
mul r4, r5 /* Multiplies r4 by r5 */
ldr r0, .LastResult
strh r4, [r0] /* Puts result in LASTRESULT */
pop {r0-r5, pc}

GetVarRAM:
ldr r1, .GetVarRAM
bx r1

.align 2
.Var4074: .word 0x02026614
.Var4075: .word 0x02026616
.GetVarRAM: .word 0x0806E455
.LastResult: .word 0x020370D0


Divide Vars
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global AddVars

/* The purpose of this function is to divide the vars */
/* stored in 0x4074 and 0x4075 */

/* This divides 0x4074 by 0x4075 */
/* Division is very much NOT commutative */
/* Also, this is INTEGER division */
/* Meaning that it rounds to the previous integer */
/* So if your result would be 1/2, it rounds to 0 */

Main:
push {r0-r5, lr}
ldr r4, .Var4074 /* First Var */
ldrh r4, [r4]
ldr r5, .Var4075 /* Second Var */
ldrh r5, [r5]

GetTheRAM:
mov r0, r4
bl GetVarRAM
mov r4, r0 /* Address of the first var */
ldrh r4, [r4] /* Value in that var */
mov r0, r5
bl GetVarRAM
mov r5, r0 /* Address of the second var */
ldrh r5, [r5] /* Value in that var */

DivideThem:
mov r0, r4
mov r1, r5
bl Division
mov r4, r0
ldr r0, .LastResult
strh r4, [r0] /* Puts result in LASTRESULT */
pop {r0-r5, pc}

GetVarRAM:
ldr r1, .GetVarRAM
bx r1

Division:
ldr r2, .Divide
bx r2

.align 2
.Var4074: .word 0x02026614
.Var4075: .word 0x02026616
.GetVarRAM: .word 0x0806E455
.Divide: .word 0x081E4019
.LastResult: .word 0x020370D0


AND Vars
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global ANDVars

/* The purpose of this function is to perform the AND operation on the vars */
/* stored in 0x4074 and 0x4075 */

/* This ANDs 0x4075 & 0x4074 */
/* This operation is commutative */

Main:
push {r0-r5, lr}
ldr r4, .Var4074 /* First Var */
ldrh r4, [r4]
ldr r5, .Var4075 /* Second Var */
ldrh r5, [r5]

GetTheRAM:
mov r0, r4
bl GetVarRAM
mov r4, r0 /* Address of the first var */
ldrh r4, [r4] /* Value in that var */
mov r0, r5
bl GetVarRAM
mov r5, r0 /* Address of the second var */
ldrh r5, [r5] /* Value in that var */

SubtractThem:
and r4, r5 /* AND r4, r5 */
ldr r0, .LastResult
strh r4, [r0] /* Puts result in LASTRESULT */
pop {r0-r5, pc}

GetVarRAM:
ldr r1, .GetVarRAM
bx r1

.align 2
.Var4074: .word 0x02026614
.Var4075: .word 0x02026616
.GetVarRAM: .word 0x0806E455
.LastResult: .word 0x020370D0


OR Vars
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global ANDVars

/* The purpose of this function is to perform the OR operation on the vars */
/* stored in 0x4074 and 0x4075 */

/* This ORs 0x4075 & 0x4074 */
/* This operation is commutative */


Main:
push {r0-r5, lr}
ldr r4, .Var4074 /* First Var */
ldrh r4, [r4]
ldr r5, .Var4075 /* Second Var */
ldrh r5, [r5]

GetTheRAM:
mov r0, r4
bl GetVarRAM
mov r4, r0 /* Address of the first var */
ldrh r4, [r4] /* Value in that var */
mov r0, r5
bl GetVarRAM
mov r5, r0 /* Address of the second var */
ldrh r5, [r5] /* Value in that var */

SubtractThem:
orr r4, r5 /* OR r4, r5 */
ldr r0, .LastResult
strh r4, [r0] /* Puts result in LASTRESULT */
pop {r0-r5, pc}

GetVarRAM:
ldr r1, .GetVarRAM
bx r1

.align 2
.Var4074: .word 0x02026614
.Var4075: .word 0x02026616
.GetVarRAM: .word 0x0806E455
.LastResult: .word 0x020370D0


How To Use Them
These are meant to be used in NPC scripts. You use them as follows:

#org @Script
setvar 0x8000 0xAAAA ' Whatever value you want
setvar 0x8001 0xBBBB ' Whatever value you want
setvar 0x4074 0x8000
setvar 0x4075 0x8001
callasm 0x8AABBCC+1 ' AABBCC is the offset where you inserted the routine. Add one for THUMB.
...


The result is stored into LASTRESULT. The original vars are not changed by the routine at all.
__________________
"The human sacrificed himself, to save the Pokemon. I pitted them against each other, but not until they set aside their differences did I see the true power they all share deep inside. I see now that the circumstances of one's birth are irrelevant; it is what you do with the gift of life that determines who you are." -Mewtwo
Reply With Quote
  #1502   Link to this post, but load the entire thread.  
Old June 11th, 2020 (7:53 PM).
ssd1334 ssd1334 is offline
ssd1334
 
Join Date: May 2020
Location: New York
Gender: Male
Posts: 3
how did you edit the IV values for hidden power types?
Reply With Quote
  #1503   Link to this post, but load the entire thread.  
Old June 12th, 2020 (4:23 PM).
RichterSnipes's Avatar
RichterSnipes RichterSnipes is offline
Not even a nibble...
 
Join Date: Oct 2011
Location: USA
Age: 30
Gender: Male
Nature: Modest
Posts: 507
Quote:
Originally Posted by Skeli View Post
Only Buy 1 TM From Shops [FR]

If you've decided to make your TMs reusable in Fire Red, this routine will remove the option to buy more than one of each from shops. Credits to azurile13 for the first part (Main) of the code.The only thing that needs changing is the line ".equ offset".
Spoiler:
Code:
.thumb
.global AlreadyOwnTM

.equ rom, 0x8000000
.equ offset, 0x893960 @CHANGE THIS LINE

.org 0x9BC3C, 0xFF
	ldr r1, .Pointer1
	bx r1
.Pointer1: .word Main + rom + 1

.org 0x9BC7C, 0xFF
	ldr r0, .Pointer2
	bx r0
.Pointer2: .word OnlyBuyOne + rom + 1

.org 0x9BEBC, 0xFF
	ldr r1, .Pointer3
	bx r1
.Pointer3: .word AddItem + rom + 1

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

.org offset, 0xFF
Main:
	lsr r4, r0, #0x10
	mov r0, r4
	ldr r2, .GetItemPocket
	bl Jump
	cmp r0, #0x4
	bne Return
	mov r0, r4
	mov r1, #0x1
	ldr r2, .CheckItem
	bl Jump
	cmp r0, #0x0
	bne AlreadyOwn

Return:
	mov r0, r4
	ldr r1, =0x809BC45
	bx r1

AlreadyOwn:
	ldr r1, .AlreadyHaveTMString
	ldr r2, =0x809BC67
	bx r2

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

OnlyBuyOne:
	ldr r1, .FCodeBuffer2
	mov r0, r4
	ldr r2, .ItemID_Copy_Name
	bl Jump
	mov r0, r4
	ldr r2, .GetItemPocket
	bl Jump
	cmp r0, #0x4
	bne Return2

GetPrice:
	mov r0, r4
	ldr r2, .GetMarketPrice
	bl Jump
	mov r1, r0
	ldr r0, .FCodeBuffer2
	add r0, #0x20
	mov r2, #0x3
	mov r3, #0x8
	bl Hex2Dec
	ldr r1, .NewYouWantString
	ldr r2, =0x809BE91
	ldr r3, =0x809BC89
	bx r3

Return2:
	ldr r1, =0x809BC85
	bx r1

Hex2Dec:
	ldr r4, =0x8008E79
	bx r4

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

AddItem:
	ldr r2, .GetItemPocket
	bl Jump
	cmp r0, #0x4
	bne Return3
	mov r0, #0x1
	strh r1, [r4, #0x2]

Return3:
	ldrh r0, [r4, #0xA]
	ldrh r1, [r4, #0x2]
	ldr r2, .Bag_Add_Item
	bl Jump
	lsl r0, #0x18
	ldr r2, =0x809BEC5
Jump:
	bx r2

.align 2
.FCodeBuffer2: .word 0x2021CD0
.GetItemPocket: .word 0x809A9D9
.CheckItem: .word 0x8099F41
.ItemID_Copy_Name: .word 0x8099E91
.GetMarketPrice: .word 0x809A901
.Bag_Add_Item: .word 0x809A085
.AlreadyHaveTMString: .word STRING1 + rom
.NewYouWantString: .word STRING2 + rom

STRING1: .byte 0xD3, 0xE3, 0xE9, 0x00, 0xD5, 0xE0, 0xE6, 0xD9, 0xD5, 0xD8, 0xED, 0x00, 0xE3, 0xEB, 0xE2, 0x00, 0xE8, 0xDC, 0xD5, 0xE8, 0x00, 0xCE, 0xC7, 0xAD, 0xFC, 0x09, 0xFF
STRING2: .byte 0xFD, 0x02, 0xB8, 0xFE, 0xCE, 0xDC, 0xD5, 0xE8, 0x00, 0xEB, 0xDD, 0xE0, 0xE0, 0x00, 0xD6, 0xD9, 0x00, 0xB7, 0xFD, 0x03, 0xAD, 0x00, 0xC9, 0xDF, 0xD5, 0xED, 0xAC, 0xFF
I've got a pretty big issue with this code. After inserting it, any time I try to purchase an item from a vendor they try to sell it for absurdly low prices at first. For example, if you try to buy a Great Ball from someone, they initially sell it at $3 instead of $600. And yes, that's how much it actually takes away from you, not the $600. If you change the quantity of item, the price goes back to what it normally should be per item.

These super low prices that are offered for each item appear to actually be the internal item ID number for each thing, converted to decimal format. One Potion, for instance, costs $13. It's item ID value is 0xD.

Anyone have any ideas what's going on here? Did I do something wrong?
__________________
My hacks:


Reply With Quote
  #1504   Link to this post, but load the entire thread.  
Old June 13th, 2020 (2:25 AM).
elie2222's Avatar
elie2222 elie2222 is offline
 
Join Date: Oct 2018
Age: 29
Gender: Male
Posts: 24
Can anyone please help me add the Everstone 100% chance nature inheriting mechanism to the IV inheriting posted by FBI ?

Spoiler:
Quote:
Originally Posted by FBI View Post

Inheriting IVs from parents (via Destiny Knot, in the daycare)



How to insert:

Before doing anything, look at the code. There are two comments that say:
@masterball lol. Change to item you want :D
@Parent2 has masterball :D
At those lines, change the line to "cmp r0, #0xDestinyKnotItemID" and
"cmp r3, #0xDestinyKnotItemID" respectively.

Once you're done that, compile and insert into free space.
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r3, r6}
	mov r6, lr
	mov r0, r5
	mov r1, #0xC
	ldr r2, =(0x803FD44 +1)
	bl linker
	mov r3, r0
	mov r0, r5
	add r0, r0, #0x8C
	mov r1, #0xC
	ldr r2, =(0x803FD44 +1)
	bl linker
	cmp r0, #0x1 @masterball lol. Change to item you want :D
	beq inherit
	cmp r3, #0x1 @Parent2 has masterball :D
	beq inherit

end:
	mov lr, r6
	pop {r3, r6}
	mov r0, SP
	mov r1, r5
	ldr r3, = (0x8045AC0 +1)
	bl linkerTwo
	ldr r0, =(0x8046100+1)
	bx r0

inherit:
	mov r3, #0x5
	bl generateRand
	ldrh r3, [r3]
	push {r4, r7}
	mov r4, #0x27
	add r4, r4, r3 @uninherited stat
	mov r7, #0x0

loop:
	cmp r7, #0x6
	beq prepareEnd
	cmp r7, r4
	beq next
	mov r3, #0x1
	bl generateRand @get a random parent's specified IV
	mov r0, r3
	ldrh r0, [r0]
	mov r1, #0x8C
	mul r0, r0, r1
	add r0, r0, r5
	mov r1, #0x27
	add r1, r1, r7
	ldr r2, =(0x803FBE8 +1)
	bl linker
	ldr r2, = (0x20370D0) @set IV to child
	strh r0, [r2]
	mov r1, #0x27
	add r1, r1, r7
	mov r0, SP
	ldr r3, =(0x804037C +1)
	bl linkerTwo	
next:
	add r7, r7, #0x1
	b loop
	 
prepareEnd:
	mov r0, SP
	ldr r3, =(0x803E47C +1) @calc stats
	bl linker
	pop {r4, r7}
	b end

generateRand:
	ldr r2, =(0x8044EC8 +1) @get a random between 0 - r3 (r3 = HW)
	bl linker
	lsl r0, r0, #0x10
	lsr r0, r0, #0x10
	mov r1, r3
	ldr r3, =(0x81E4684 +1)
	bl linkerTwo
	ldr r3, = 0x20370D0 @could just move it to r3 I suppose
	strh r0, [r3]
	bx lr
		

linker:
	bx r2

linkerTwo:
	bx r3


.align 2


Here's a compiled version:
Code:
48 B4 76 46 28 1C 0C 21 26 4A 00 F0 49 F8 03 1C 28 1C 8C 30 0C 21 23 4A 00 F0 42 F8 01 28 0A D0 01 2B 08 D0 B6 46 48 BC 68 46 29 1C 1E 4B 00 F0 38 F8 1E 48 00 47 05 23 00 F0 26 F8 1B 88 90 B4 27 24 E4 18 00 27 06 2F 18 D0 A7 42 14 D0 01 23 00 F0 1A F8 18 1C 00 88 8C 21 48 43 40 19 27 21 C9 19 13 4A 00 F0 1C F8 12 4A 10 80 27 21 C9 19 68 46 11 4B 00 F0 15 F8 01 37 E4 E7 68 46 0F 4B 00 F0 0E F8 90 BC CD E7 0D 4A 00 F0 09 F8 00 04 00 0C 19 1C 0B 4B 00 F0 04 F8 06 4B 18 80 70 47 10 47 18 47 45 FD 03 08 C1 5A 04 08 01 61 04 08 E9 FB 03 08 D0 70 03 02 7D 03 04 08 7D E4 03 08 C9 4E 04 08 85 46 1E 08
Now go to 0x460F8 and insert the following:
Code:
 00 48 00 47 XX XX XX 08
Where XX XX XX is the pointer in reverse hex +1 of the routine you just compiled.


How it works:
When the egg is generated, we check both parents to see if their holding an item matching the item we're looking for. If they are, the egg inherits 5/6 IVs from their parents. Each parent has a 50% chance to pass down one of their IVs.

There is no usage section, because the rest is done automagically when you have two compatible Pokemon in the daycare and they make an egg :)

Also, sorry for the double post, I wanted a fresh post for the first page :P
Reply With Quote
  #1505   Link to this post, but load the entire thread.  
Old June 16th, 2020 (12:45 PM). Edited June 16th, 2020 by fireYtail.
fireYtail's Avatar
fireYtail fireYtail is offline
 
Join Date: May 2020
Location: Spain
Age: 27
Gender: Male
Posts: 2
Hi, there! I've been making Pokémon FireRed hack roms for some time now, but never got to understand ASM, so I have a few requests about problems I've been facing. First of all, I'm familiar with XSE scripts and hexadecial numbers and HxD (hex editor), but not with how ASM works. The furthest I've reached is executing my custom menus (normal XSE scripts) via a key item using the "use of select" option in complete item editor. However this only works in overworld mode... I've miserably failed to run anything custom in-battle. I know battle scripts are different than XSE scripts, and have also downloaded the battle script pro tool, but that's about it. I have the thumb ASM compiler too. Well, I should go to the point now.

I'll start with the biggest issue. If flag 0x301 is set then receive all Pokémon from trainers upon trainer defeat (thief mode) Now I have a few questions here. Is there a way to call an ASM routine every time a trainer has been defeated? (or a battle ends, for that matter?) Trainer party data is located at ram offset 0x0202402C, is this data automatically cleared upon battle finish? I would need this data to be taken and then given to the player in the same way givepokemon works. What I mean by this is, first use the player's party slots then send the remaining Pokémon to the PC. In other words I need the party at said address to be given to the player as is (save maybe bug fixes?) If this being done automatically is not possible then I can script every single NPC in the game a callasm. That'd be more work, but it'd still be doable without having to manually script every single Pokémon from every single trainer in the game via givepokemon, special(s) and JPAN's hacks. That's a lot of work to do, you got the idea. Plus, in such a way it'd be impossible to replicate the IVs (and EVs as well?) from the stolen Pokémon, since I can't know their values during battle. Again, I know nothing of ASM but I guess just copying data from one ram location to another must not be too hard to script.

But that's not my only concern. I also need a way to make battles against 1 Pokémon, fully customizable except for moves (default attacks), that you can't run away from, that you can't catch the Pokémon by any means and that you earn an also customizable amount of price money for. I'm unsure as to whether I can already do this with what's already on the internet. I used to "do this" by creating 386 new trainers with a single Pokémon each, but that's a lot of work to do and also "ugly" if you get my meaning. Unprofessional.

Last but not least, we hear a lot about XSE scripts calling ASM, but what about it in reverse? Is it possible? (Guessing it is, since "virtually anything" is possible with ASM) I ask this because I want to change the exit option of the start menu to one that runs my XSE script with custom multichoice menus and submenus, instead of having to use a key item to be able to run the script from anywhere. Or even better, cancel button select "register" feature and call my script whenever select is pressed (without a custom item) Is it possible? Or even better, if I'm allowed to request, whenever you press the L and R buttons both at the same time in overworld mode (I have already disabled the annoying help system that takes priority over everything else, but had no luck with JPAN's key scripts nor walking scripts, changed default game settings as well)

Thank you very much in advance for your help and please have a nice day ^^ If someone could lend me a hand with JPAN's key scripts and/or walking scripts, that would be a great plus.

Edit: Oh, I almost forgot, JPAN's species changer leaves the name intact so I'd need code to set a Pokémon name to the default for its species, too.
Edit2: Oh my God, I can't believe it but I managed to find the pointer to the script that runs when select is pressed and no item is registered, it's at offset 0x10ADA8!
Reply With Quote
  #1506   Link to this post, but load the entire thread.  
Old June 18th, 2020 (11:57 PM). Edited June 19th, 2020 by fireYtail.
fireYtail's Avatar
fireYtail fireYtail is offline
 
Join Date: May 2020
Location: Spain
Age: 27
Gender: Male
Posts: 2
Quote:
Originally Posted by FBI View Post
It should have no problems with any other hacks; this check is quite standalone. I should also mention the Pokemon you captured from another trainer will act like a Pokemon who has been traded. If you don't have the badges to train it, it will disobey you.



Thanks for that.



Thanks. To my knowledge, the gameshark code still turns your Pokemon to a bad egg. This fixes the bad egg too!

Anyways, I've finished all the requests which I'm willing to do. Keep shooting them at me guys :P

EDIT:


Toggling Capturability of Pokemon



So it's quite likely that maybe you want a Pokemon to be uncapturable, and at the same time you don't want to diminish it's catch rate to 0 in your Pokemon editor. Or perhaps you used the "capture trainer Pokemon" hack and you don't want it to work for all trainers. No problem, this is the hack for you :P

Basically it checks if variable 0x8000 is 0x1 or not. If it's 0x1, then any Pokemon you encounter (trainer or wild, via script or natural encounter) will become uncapturable even with the master ball. Simply set 0x8000 back to normal for the original game mechanics.
Note: If you use this hack, to say make it so the player can only capture a certain trainer's Pokemon, you will need to set 0x8000 right before the encounter, and unset it after (which is quite simple)
Note2: This hack won't let you capture trainer Pokemon, you need to have the capture trainer Pokemon hack from last time to create that effect.

How to insert:

First compile the following ASM code and insert into free space:
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	ldr r0, =(0x2022B4C)
	ldr r1, [r0]
	ldr r2, .VAR
	ldrb r2, [r2]
	cmp r2, #0x1
	beq uncatchable
	ldr r0, = (0x802D490 +1)
	bx r0

uncatchable:
	ldr r0, = (0x802D460 +1)
	bx r0
	
	

.align 2
.VAR:
	.word 0x020270B8 + (0x8000 * 2) @change to var of your choice if you want


Here is a compiled version:
Code:
05 48 01 68 03 4A 12 78 01 2A 01 D0 03 48 00 47 03 48 00 47 B8 70 03 02 4C 2B 02 02 91 D4 02 08 61 D4 02 08
Now navigate to 0x2D452 and insert the following:
Code:
01 48 00 47 00 00 XX XX XX 08
Where XX XX XX is the reverse hex pointer to where you inserted the above routine. That's it :)
EDIT: Add one to the pointer.

Here's a pesky Rattata:

(Yes, the Pokeball animation is still there, this was taken after it.)
Unfortunately, unlike the toggle run away code, this ASM isn't working with special 0x138...

Edit: After some more testing I found out neither of them worked because I was using a variable under 0x8000..
Reply With Quote
  #1507   Link to this post, but load the entire thread.  
Old June 24th, 2020 (12:31 PM). Edited January 22nd, 2021 by AkameTheBulbasaur.
AkameTheBulbasaur's Avatar
AkameTheBulbasaur AkameTheBulbasaur is offline
Akame Marukawa of Iyotono
 
Join Date: May 2013
Location: A place :D
Age: 25
Gender: Male
Nature: Docile
Posts: 408
Nature Changing
Before I begin, I should mention that this only works for FireRed at the moment. This is because it uses the Lustre stat, which in FireRed is unused but in Emerald is not. If you can find another stat to use, (or you don't have contests in your Emerald hack), then you can use this.

Offsets listed here are for FireRed, though, so keep that in mind if you decide to port it.

Anyway, without further ado, I present Nature Changing!

How Does It Work?
Skip this if you don't care about the behind the scenes stuff.

Basically, this hijacks the GetNature function. It first checks the Lustre stat of the Pokemon in question. If it's equal to zero, then it gets the Nature form the PID as usual. If it's not zero, then it uses the Lustre value as the Nature, effectively changing the Pokemon's Nature without messing with the PID (and potentially messing up other stuff like the Pokemon's gender, Shininess, etc.).

This does mean you can't set the Nature to Hardy, but this is not that big of a deal since there are other neutral Natures you can use.

The Main Event
I have written an instruction manual that explains how to use the hack in detail. It also contains links to download everything.

The link presented below is the link to download the folder with the Instruction Manual and all the routines. Not every routine in the folder is one you need to insert, as there are a couple of optional add-ons to make changed Natures compatible with other hacks.

Download: Here!
__________________
"The human sacrificed himself, to save the Pokemon. I pitted them against each other, but not until they set aside their differences did I see the true power they all share deep inside. I see now that the circumstances of one's birth are irrelevant; it is what you do with the gift of life that determines who you are." -Mewtwo
Reply With Quote
  #1508   Link to this post, but load the entire thread.  
Old June 29th, 2020 (7:10 AM).
ssd1334 ssd1334 is offline
ssd1334
 
Join Date: May 2020
Location: New York
Gender: Male
Posts: 3
Quote:
Originally Posted by FBI View Post

Getting IVs and EVs



The routines are very similar so I ended up just combining the two routines into one. Basically given a slot number of a Pokemon in 0x8004, the routines will return the EVs or IVs, respectively, into the vars 0x8005-0x800A with 0x8003 as the IV/EV switch.


How to insert:

Compile and insert the following routine into free space:

Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r5, lr}
	mov r4, #0x0
	
loop:
	cmp r4, #0x6
	bhi end
	ldr r0, =(0x20370C0) @var 0x8004 = slot number
	ldrh r0, [r0]
	mov r1, #0x64
	mul r1, r1, r0
	ldr r0, =(0x2024284)
	add r0, r0, r1
	ldr r3, =(0x20370BE)
	ldrh r3, [r3]
	cmp r3, #0x0
	beq EVs
	add r1, r1, #0x27 @IV
	b continue
	
EVs:
	add r1, r1, #0x1A
	
continue:
	ldr r2, =(0x803FBE8 +1)
	bl linker
	mov r1, r0
	@get var
	ldr r2, =(0x20370C2) @using vars 0x8005-0x800A
	lsl r0, r4, #0x1
	add r2, r2, r0
	strh r1, [r2] @store IV in var
	add r4, r4, #0x1
	b loop

linker:
	bx r2
	
end:
	pop {r0-r5, pc}

.align 2



Usage:
setvar 0x8003 0x[anything except 0 = IV, 0 = EV]
setvar 0x8004 0x[slot number 0 to 5]
callasm 0x[this routine +1]

The variables will be:
0x8005: HP IV/EV
0x8006: Atk IV/EV
0x8007: Def IV/EV
0x8008: Spd IV/EV
0x8009: S.atk IV/EV
0x800A: S.def IV/EV
see idk if im stupid or something, but i cant seem to figure out how to compile stuff in assembly
Reply With Quote
  #1509   Link to this post, but load the entire thread.  
Old June 30th, 2020 (1:19 AM). Edited June 30th, 2020 by AkameTheBulbasaur.
AkameTheBulbasaur's Avatar
AkameTheBulbasaur AkameTheBulbasaur is offline
Akame Marukawa of Iyotono
 
Join Date: May 2013
Location: A place :D
Age: 25
Gender: Male
Nature: Docile
Posts: 408
Quote:
Originally Posted by ssd1334 View Post
see idk if im stupid or something, but i cant seem to figure out how to compile stuff in assembly
I recommend using this tool. It's easy to use and lets you assemble directly into the ROM. Just copy-paste the routine you want to assemble in there, click the button and go!

A Timer System
This is mainly for Fire Red, but it could also work for Emerald if you have enough Free RAM. More on that as we go.

Anyway, this is a way to allow yourself to have timed events in Fire Red. As you may already know, FireRed does not have a Real Time Clock like Ruby/Sapphire/Emerald does. It does, however, have an internal clock that keeps track of how long you have been playing the game.

You could, if you wanted, try to use it to have timed events. For example, if you wanted to have something occur every ten minutes, and you knew the RAM for where the time you've been playing is, then you could theoretically do something like this:
  1. Save the current time when the event starts.
  2. When the script is run again, check the time again.
  3. If it's StartingTime + LengthOfEvent, then the event is over.

This is obnoxious for a variety of reasons. One, it kind depends on having a script run to end the event. Two, what happens if you've somehow been playing for 999 hours and 59 minutes. Then all your timed events break. Sure, that is a ridiculously long time, but still.

Then, I came across a few hacks that other people had made, which when brought together, opened a whole new world for me.

What You Need
Before we get started, there are a few things that you will need to have in your game first.

Now, you may be wondering, what on Earth is this dubious, unnamed patch and what on Earth is it doing to my ROM? The answer to that is is disables the "Previously On Your Quest" feature (the little slideshow that happens when you boot up the game). Now why would this be required for a Timer System?

The answer is that it frees up a TON of RAM. Like seriously, a TON. Like sooooooooo many bytes of RAM it's ridiculous. The best part? This RAM is saved by the game. Basically, if you want to expand your bag size, you don't need to use JPAN's Save Block anymore.

If you have a hack in progress, this is objectively the better way to free up RAM because now you don't need to restart any save files. In fact, I would just do this anyway, unless you REEEEEEALLY need the "Previously On Your Quest" thing for some reason.

What To Do
First, you will need to create a table. This table will have all the RAM Addresses of all the timers that you will want to use. You are really only limited by the amount of free RAM you can use for Vars. You could have one timer, or 100! I personally have 96.

Each entry of the table is four bytes long and is simply a pointer to the RAM addresss. If you want some help with figuring out what RAM addresses to use, click on the spoiler. The table needs to be terminated with FF FF FF FF.

Spoiler:
Var 0x4000 is at 0x0202652C. Let's say I want to know where Var 0x4050 is located. First, get the difference between the Var and 0x4000. In this case, it is 0x50. Then, multiply it by two. We know have 0xA0. Then add it to 0x0202652C. So Var 0x4050 is located at 0x020265CC.


If you are lazy and you applied the patch above, then you can use this table. It has 100 timers (you can use only part of it if you need less). It starts at 0x0202752C and ends at 0x020275F4. In Var terms, this is 0x4800 to 0x4864.

Spoiler:
2C 75 02 02 2A 75 02 02 2E 75 02 02 30 75 02 02 32 75 02 02 34 75 02 02 36 75 02 02 38 75 02 02 3A 75 02 02 3E 75 02 02 40 75 02 02 42 75 02 02 44 75 02 02 46 75 02 02 48 75 02 02 4A 75 02 02 4E 75 02 02 50 75 02 02 52 75 02 02 54 75 02 02 56 75 02 02 58 75 02 02 5A 75 02 02 5E 75 02 02 60 75 02 02 62 75 02 02 64 75 02 02 66 75 02 02 68 75 02 02 6A 75 02 02 6E 75 02 02 70 75 02 02 72 75 02 02 74 75 02 02 76 75 02 02 78 75 02 02 7A 75 02 02 7E 75 02 02 80 75 02 02 82 75 02 02 84 75 02 02 86 75 02 02 88 75 02 02 8A 75 02 02 8E 75 02 02 90 75 02 02 92 75 02 02 94 75 02 02 96 75 02 02 98 75 02 02 9A 75 02 02 9E 75 02 02 A0 75 02 02 A2 75 02 02 A4 75 02 02 A6 75 02 02 A8 75 02 02 AA 75 02 02 AE 75 02 02 B0 75 02 02 B2 75 02 02 B4 75 02 02 B6 75 02 02 B8 75 02 02 BA 75 02 02 BE 75 02 02 C0 75 02 02 C2 75 02 02 C4 75 02 02 C6 75 02 02 C8 75 02 02 CA 75 02 02 CE 75 02 02 D0 75 02 02 D2 75 02 02 D4 75 02 02 D6 75 02 02 D8 75 02 02 DA 75 02 02 DE 75 02 02 E0 75 02 02 E2 75 02 02 E4 75 02 02 E6 75 02 02 E8 75 02 02 EA 75 02 02 EE 75 02 02 F0 75 02 02 F2 75 02 02 F4 75 02 02 FF FF FF FF


The second table you will need to insert is a table that has the time limits for all your timers. Each entry is a half-word (two bytes long) and you will need one for each timer that you have in the previous table.

There are two options you have for each entry. If you enter in a number other than 0xFFFE, then it will function as a typical timer. For example, if you set it to 0x5, then after five minutes, it will be reset.

If you use 0xFFFE, then it turns your timer into a stopwatch. This will make the timer keep going until it reaches 0xFFFF minutes. How long is that? 0xFFFF = 65,535 minutes = 1092.25 hours = 45.5 days = long enough that you probably won't get to that point.

Okay, now you're ready to insert this routine somewhere and then add a pointer to it in the Minute Routine table (see FBI's Minute Routine post). Add the addresses of the tables after where it says .VarRAMTable and .TimeLimits.

Advance Timer Routine
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global EventTimers

/*
The purpose of this routine is to increment by 1 the Vars
that contain the timers for events like the records for
Gaikoku's Place.

Every minute, it will check over each timer and see if it is
set to 0x1. If so, it means the timer is active.

It will then add one to the value of the timer. If the limit is
not 0xFFFE, it will then check to see if it's reached the limit
*/

Main:
push {r0-r7, lr}
ldr r0, .VarRAMTable
ldr r1, .TimeLimits
mov r2, #0x0
mov r7, #0x0

Loop:
add r0, r0, #0x4
add r1, r1, #0x2
ldr r3, [r0] /* RAM Address of first var */
ldr r5, .Done /* End of table */
cmp r3, r5
beq Return
ldrh r4, [r1] /* Time Limit */
ldrh r6, [r3] /* r6 = Value in timer */
cmp r6, #0x1 /* 0x1 = Timer is activated */
bge CheckMax


FinishLoop:
add r2, r2, #0x4
add r7, r7, #0x2
b Loop

CheckMax:
ldr r5, .Done2
cmp r4, r5 /* Infinite Time */
beq AddOne
add r4, r4, #0x1 /* Add one here because you needed Var = 0x1 to start timer at all */
cmp r6, r4 /* Compare current minutes to limit */
bge Reset
add r6, r6, #0x1
strh r6, [r3]
b FinishLoop

AddOne:
ldr r5, .Done
lsl r5, r5, #0x10
lsr r5, r5, #0x10
cmp r6, r5 /* Compare the current time to 0xFFFF (the maximum) */
beq FinishLoop /* Don't add one here or it will break other timers */
add r6, r6, #0x1
strh r6, [r3]
b FinishLoop

Reset:
mov r5, #0x0
strh r5, [r3] /* Set RAM to zero */
b FinishLoop

Return:
pop {r0-r7, pc}

.align 2
.VarRAMTable: .word 0x08
.TimeLimits: .word 0x08
.Done: .word 0xFFFFFFFF
.Done2: .word 0x0000FFFE


How To Use
Now that we have it all inserted, how do we use it? In order to start a timer, just set the corresponding Var equal to 0x1. If it's a timer, the Var will reset itself when it reaches the limit. If it's a stopwatch, you will have to set it back to zero yourself.

Here's an example script showing the basics. It uses the Subtract Var routine that I linked above. In the script, the player is asked if they want some Lemonade. If they accept, they are given a Lemonade item and the timer is set. They can come back after fifteen minutes and get another. If they talk to the NPC before 15 minutes have elapsed, the NPC will tell the player how long they have to wait.

Note that this is fifteen minutes of in-game time. Turning off/pausing the game and coming back fifteen minutes later will not count.

Spoiler:
#dyn 0x740000
#org @Start
lock
faceplayer
textcolor RED
compare 0x4075 0x0 ' Timer is not running
if true jump @TimeToGive
setvar 0x8000 0xF ' Reset every fifteen minutes
setvar 0x4819 0x8000
setvar 0x481A 0x4075
callasm 0x8DE2F81 ' Subtract 0x4075 from 0x8000
storevar 0 LASTRESULT
message @NotReady
callstd MSG_SIGN
release
end

#org @TimeToGive
message @Hello
callstd MSG_YESNO
compare LASTRESULT YES
if true jump @Yes
message @Okay
callstd MSG_SIGN
release
end

#org @Yes
checkitemspaceinbag LEMONADE 1 ' Room for lemonade?
compare LASTRESULT FALSE
if true jump @Item
message @Give
callstd MSG_SIGN
additem LEMONADE 1
setvar 0x4075 0x1 ' Set Timer
textcolor GRAY
message @Get
callstd MSG_SIGN
fanfare 0x102
waitfanfare
release
end

#org @Item
textcolor GRAY
message @NoRoom
callstd MSG_SIGN
release
end

#org @Hello
= Melissa Hydan: Hello \v\h01!\pI just made some lemonade!\pIt's the Hydan family specialty!\pWould you like some?

#org @Give
= Here you go!\pI'll have some more in 15 minutes.

#org @okay
= Oh, all right.\pYou can come back any time.

#org @Get
= I received a Lemonade!

#org @NoRoom
= I have no space for it!

#org @NotReady
= Melissa Hydan: Hello \v\h01!\pWere you wanting some lemonade?\pI'll have some more ready in \v\h02\nminutes.\pCome back then, okay?


Ideas
Here are some ideas of what you can use this for.
  • Berry Trees (Have berries grow after certain amount of time).
  • A lottery you can play once every X minutes.
  • A delivery system where you can get a package after X minutes.
  • Timing how long it takes you to beat a trainer.
  • A sale at a store that lasts for X minutes and occurs every Y minutes.
  • Anything you can think of!
__________________
"The human sacrificed himself, to save the Pokemon. I pitted them against each other, but not until they set aside their differences did I see the true power they all share deep inside. I see now that the circumstances of one's birth are irrelevant; it is what you do with the gift of life that determines who you are." -Mewtwo
Reply With Quote
  #1510   Link to this post, but load the entire thread.  
Old July 12th, 2020 (2:26 PM).
Julez1003 Julez1003 is offline
 
Join Date: Dec 2018
Gender: Male
Nature: Calm
Posts: 2
Heyo, i really like the 80x80 Mugshot Routine jiangzhengwenjzw has made and try atm to make it work on emerald, but unfortunately, i couldn´t achieve this.
I already tried to research the offsets for emerald but i couldn´t find the correct offsets for this.
So i would like to ask for some help.
Can somebody of you help me with the routine, please?
It would be awesome, because my knowledge is not the greatest. I also searched a lot on google, but the results, i found, aren´t really useful.
Reply With Quote
  #1511   Link to this post, but load the entire thread.  
Old August 6th, 2020 (11:00 AM). Edited September 6th, 2020 by Pyxal.
Pyxal's Avatar
Pyxal Pyxal is offline
It's pronounced pixel.
 
Join Date: Jul 2019
Location: Pakistan
Age: 17
Posts: 987
The following development is done by DoesntKnowHowToPlay, and I have no part in it. This has been re-posted as the original link had died.

[FR] Displaying IV's on the stat screen
A small piece of ASM that allows you to view IV's in the Pokémon stat screen.


• Step 1 - Image insert
First, insert the following image using NSE or TileMolester. Remember the address where you put it:
Spoiler:


It uses the same palette as the type chart, which is located at 0xE95DBC in vanilla FR. If you changed that palette, you'll have to change the above image as well (You'll probably want to change the image anyway since it's frankly rather minimalist).


• Step 2 - Actual ASM
Next you will need to insert the following ASM. It doesn't matter where, but do remember where you put it.
Code:
cmp r0, #0x0
beq Abort
cmp r0, #0x3
bgt Abort
cmp r0, #0x1
bne StandardAbort
b Start

Abort:
ldr r1, .AbortAddr
bx r1

StandardAbort:
ldr r1, .StandardAbortAddr
bx r1

.align 2
.AbortAddr: .word 0x08137bfd
.StandardAbortAddr: .word 0x08137bf9

Start:
ldr r0, .ActiveMonPtr
ldr r1, .ActiveOffset
ldr r0, [r0, #0x0]
add r6, r0, r1

add sp, #-0x18

HPIV:
mov r0, r6
mov r1, #0x27
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x6
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



AtkIV:
mov r0, r6
mov r1, #0x28
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x17
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



DefIV:
mov r0, r6
mov r1, #0x29
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x24
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler


SAtkIV:
mov r0, r6
mov r1, #0x2B
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x31
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



SDefIV:
mov r0, r6
mov r1, #0x2C
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x3E
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



SpeedIV:
mov r0, r6
mov r1, #0x2A
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x4B
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



add sp, #0x18
b Abort


GraphicHandler:
ldr r4, .HandlerAddr
bx r4

Decrypter:
ldr r2, .DecrypterAddr
bx r2

.align 2
.GraphicAddr: .word 0x08XXXXXX
.HandlerAddr: .word 0x080041f1
.ActiveMonPtr: .word 0x0203b140
.ActiveOffset: .word 0x00003290
.MonIndex: .word 0x0203b16c
.DecrypterAddr: .word 0x0803FBE9

Replace the
0x08XXXXXX
with the address of the image you just inserted (no +1 or reverse needed).

• Step 3 - Byte changes
  1. At 0x137BF0, place 00 49 08 47 followed by a pointer to the code you just inserted plus one (for example, if you inserted it at 0x800000, you will place 00 49 08 47 01 00 80 08 at 0x137BF0).
  2. At 0x137BE4, place 01 20 03 E0.

Ending notes
With that, you should be good to go. In typical Pokémon fashion, this code does not give you the specific values; it instead gives you a unique two-value range. If you want to change that it's rather easy; cut every line starting with lsr in the code and reassemble it, then adjust the image so it has 32 meaningful values instead of 16.

Credits
DoesntKnowHowToPlay - Actual code, image
Lunos - He did the actual Google cache magic too find it

Again, this is done by DoesntKnowHowToPlay, and it is not done by me. Any credit should go DoesntKnowHowToPlay, and not me.
__________________
Reply With Quote
  #1512   Link to this post, but load the entire thread.  
Old September 3rd, 2020 (11:53 AM). Edited September 3rd, 2020 by Raduziel.
Raduziel's Avatar
Raduziel Raduziel is offline
 
Join Date: Sep 2020
Location: Rio de Janeiro, Brazil
Age: 34
Gender: Male
Posts: 34
Hey Upsurge,

First, thanks for the feedback at the other thread.

Second, I have some questions (I told I was green)...

1) The image you kindly provided was saved at 71C000 (used Free Space Finder to find this spot). Should I replace the XXXXXX in your routine as 0x0871C000 or as 0x71C000? I guess it is the first option but I think it is best to ask.

2) I've copied your routine using Notepad++ and saved as IVRanking.asm but I have no idea about what I do with this file. So, I used a Thumb to turn this .asm into a .bin, opened this .bin file and my rom using HxD and pasted the bin's code inside the ROM starting at 71B500, I think this covers this step - let me know if I'm wrong, please.

3)

Quote:
Originally Posted by Upsurge View Post
• Step 3 - Byte changes
  1. At 0x137BF0, place 00 49 08 47 followed by a pointer to the code you just inserted plus one (for example, if you inserted it at 0x800000, you will place 00 49 08 47 01 00 80 08 at 0x137BF0).
  2. At x137BE4, place 01 20 03 E0.
Can you please explain exactly how this is done?

Thanks in advance.
Reply With Quote
  #1513   Link to this post, but load the entire thread.  
Old September 3rd, 2020 (8:08 PM).
Pyxal's Avatar
Pyxal Pyxal is offline
It's pronounced pixel.
 
Join Date: Jul 2019
Location: Pakistan
Age: 17
Posts: 987
Quote:
Originally Posted by Raduziel View Post
<snip>
This is NOT my routine. As said above, it is done by DoesntKnowHowToPlay.

1) This image was by DonestKnowHowToPlay, and yes, like this: 71C000. As an example, the routine would become:
Spoiler:
Code:
cmp r0, #0x0
beq Abort
cmp r0, #0x3
bgt Abort
cmp r0, #0x1
bne StandardAbort
b Start

Abort:
ldr r1, .AbortAddr
bx r1

StandardAbort:
ldr r1, .StandardAbortAddr
bx r1

.align 2
.AbortAddr: .word 0x08137bfd
.StandardAbortAddr: .word 0x08137bf9

Start:
ldr r0, .ActiveMonPtr
ldr r1, .ActiveOffset
ldr r0, [r0, #0x0]
add r6, r0, r1

add sp, #-0x18

HPIV:
mov r0, r6
mov r1, #0x27
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x6
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



AtkIV:
mov r0, r6
mov r1, #0x28
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x17
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



DefIV:
mov r0, r6
mov r1, #0x29
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x24
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler


SAtkIV:
mov r0, r6
mov r1, #0x2B
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x31
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



SDefIV:
mov r0, r6
mov r1, #0x2C
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x3E
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



SpeedIV:
mov r0, r6
mov r1, #0x2A
bl Decrypter

mov r5, r0
lsr r5, r5, #0x1
mov r0, #0x40
mul r5, r0, r5

mov r1, #0x80
str r1, [sp, #0x0]
str r1, [sp, #0x4]

#x, y position
mov r2, #0xC
str r2, [sp, #0x8]
mov r1, #0x4B
str r1, [sp, #0xc]

#x, y size
mov r2, #0x10
str r2, [sp, #0x10]
mov r1, #0x8
str r1, [sp, #0x14]

mov r0, #0x3
ldr r1, .GraphicAddr
add r1, r5
mov r2, #0x0
mov r3, #0x0
bl GraphicHandler



add sp, #0x18
b Abort


GraphicHandler:
ldr r4, .HandlerAddr
bx r4

Decrypter:
ldr r2, .DecrypterAddr
bx r2

.align 2
.GraphicAddr: .word 0x0871C000
.HandlerAddr: .word 0x080041f1
.ActiveMonPtr: .word 0x0203b140
.ActiveOffset: .word 0x00003290
.MonIndex: .word 0x0203b16c
.DecrypterAddr: .word 0x0803FBE9


2) Yes, it covers this step. To automagically insert routines into your ROM, use this tool.

3) Basically you go to address's 0x137BF0 and 0x137BE4 in any hex editor, and replace (Ctrl+B) them with the said bytes.
__________________
Reply With Quote
  #1514   Link to this post, but load the entire thread.  
Old September 3rd, 2020 (8:23 PM).
Raduziel's Avatar
Raduziel Raduziel is offline
 
Join Date: Sep 2020
Location: Rio de Janeiro, Brazil
Age: 34
Gender: Male
Posts: 34
Thanks for linking the tool, this will make my life easier in the future, I suppose.

Quote:
Originally Posted by Upsurge View Post
3) Basically you go to address's 0x137BF0 and 0x137BE4 in any hex editor, and replace (Ctrl+B) them with the said bytes.
Ok, I got step 3.2, but 3.1 keeps elluding me.

In your example 0x800000 became 00 80 08 and that is the part that I'm failing to understand. Can you please explain this further? My case is 71B500, would the final input be 00 49 08 47 01 00 71 B5 08?

Again, thanks for taking the time to guide me through this.
Reply With Quote
  #1515   Link to this post, but load the entire thread.  
Old September 3rd, 2020 (8:24 PM).
Pyxal's Avatar
Pyxal Pyxal is offline
It's pronounced pixel.
 
Join Date: Jul 2019
Location: Pakistan
Age: 17
Posts: 987
Quote:
Originally Posted by Raduziel View Post
Thanks for linking the tool, this will make my life easier in the future, I suppose.



Ok, I got step 3.2, but 3.1 keeps elluding me.

In your example 0x800000 became 00 80 08 and that is the part that I'm failing to understand. Can you please explain this further? My case is 71B500, would the final input be 00 49 08 47 01 00 71 B5 08?

Again, thanks for taking the time to guide me through this.
It will become 00 49 08 47 01 01 B5 71 08.
__________________
Reply With Quote
  #1516   Link to this post, but load the entire thread.  
Old September 3rd, 2020 (8:41 PM). Edited September 3rd, 2020 by Raduziel.
Raduziel's Avatar
Raduziel Raduziel is offline
 
Join Date: Sep 2020
Location: Rio de Janeiro, Brazil
Age: 34
Gender: Male
Posts: 34
Quote:
Originally Posted by Upsurge View Post
It will become 00 49 08 47 01 01 B5 71 08.
Thanks!

Looks like it is almost done but apparently I messed up somehow. The attached image shows the ranking boxes are there but no value inside though.

Edit: This was how I've inserted the image

NSE -> Load ROM -> Open Sprite -> Selected the one from the image above -> File -> Insert -> Image Data -> FreeSpaceFinder (checking from the beginning of the ROM and telling the size is 2048 bytes) -> 71C000 - Save


It is working perfectly, I was dumb and using an old backup without the inserted image. Thanks for guiding me through this. Cheers!
Attached Images
File Type: png Capturar.PNG‎ (55.7 KB, 48 views) (Save to Dropbox)
Reply With Quote
  #1517   Link to this post, but load the entire thread.  
Old September 4th, 2020 (1:27 PM).
Raduziel's Avatar
Raduziel Raduziel is offline
 
Join Date: Sep 2020
Location: Rio de Janeiro, Brazil
Age: 34
Gender: Male
Posts: 34
Does anyone know how to alter the ASM routine to use a 256x8 image instead of a 128x32 one?

Thanks!
Reply With Quote
  #1518   Link to this post, but load the entire thread.  
Old September 11th, 2020 (5:02 AM).
Raduziel's Avatar
Raduziel Raduziel is offline
 
Join Date: Sep 2020
Location: Rio de Janeiro, Brazil
Age: 34
Gender: Male
Posts: 34
Quote:
Originally Posted by Pokemon_XY View Post
I've found a way to make TMs unsellable:
Hi,

I made all the changes but I can still sell TMs (they are reusable already).

On top of your changes I've used HexManiacAdvance to alter the Mystery Byte of TMs to "1" (the same way that HMs are displayed).

I'm using CFRU, by the way, but didn't set the flag for reusable TMs while installing that - everything achieved was through this thread (so far: reusable and no number display).

Thanks!
Reply With Quote
  #1519   Link to this post, but load the entire thread.  
Old September 18th, 2020 (10:21 AM). Edited September 21st, 2020 by BluRose.
BluRose BluRose is offline
blu rass
 
Join Date: Apr 2014
Location: michigan tech
Age: 22
Gender: Male
Nature: Timid
Posts: 812
modulate experience with two scripting vars



take your experience and multiply it by the "var numerator" and then divide it by the "var denominator"

strongly suggest using higher numbers, i.e. if you want a 60% experience thing then set the numerator to 60 and the denominator to 100 so that the processor generates slightly more accurate numbers
also make sure that you can't really get more than about 56,000 experience, as that causes interesting errors

credit me and akamethebulbasaur
for fire red:
Spoiler:
Code:
/* Put 00 48 00 47 XX XX XX 08 a 0x21C38 and edit the var numbers at the bottom as you please */
.text
.align 2
.thumb
.thumb_func

EditarExperiencia:
    push {r1}
    ldr r0, .VarDenominador        /* Puedes cambiarla */
    mov r3, pc
    add r3, #7
    mov lr, r3
    ldr r3, .VarGet
    bx r3
    cmp r0, #0
    beq _dontdividebyzero
_continue:
    push {r0}
    ldr r0, .VarNumerador
    mov r3, pc
    add r3, #7
    mov lr, r3
    ldr r3, .VarGet
    bx r3
_terminar:
    pop {r1-r2}
    mul r0, r2
    mov r3, pc
    add r3, #7
    mov lr, r3
    ldr r3, .Dividir
    bx r3
    ldr r2, .Volver
    bx r2

_dontdividebyzero:
    mov r0, #1
    b _continue  

.align 2


.Volver:
    .word 0x08021C40 | 1
.VarNumerador:
    .word 0x40XX
.VarDenominador:
    .word 0x40XX
.VarGet:
    .word 0x0806E568 | 1
.Dividir:
    .word 0x081E4018 | 1
__________________
heyo check out my github:

BluRosie
highlights:
battle engine for heartgold
various feature branches in heart gold (fairy type, odd egg, mud slopes)

i'm a big part of the development team of pokemon firegold! all the code that i develop for that hack is also on my github

also on discord: BluRose#0412
Reply With Quote
  #1520   Link to this post, but load the entire thread.  
Old September 20th, 2020 (12:33 PM). Edited September 21st, 2020 by BluRose.
BluRose BluRose is offline
blu rass
 
Join Date: Apr 2014
Location: michigan tech
Age: 22
Gender: Male
Nature: Timid
Posts: 812
not to double post but

give your opposing trainers evs and ivs based on a var each



this primarily to make difficulty hacks where there can be multiple difficulties

put a value in one var that you want the opponents ivs to be and another value in another var that you want your opponent's evs to be (and yes, all of them will be the same)
the pokemon has to have just a custom item (at least that check mark ticked in your favorite trainer editor) then all of their values will be set. custom moveset doesn't have to be defined :P

pastebin right here

credit me and doesntknowhowtoplay
for fire red:
Spoiler:
Code:
@ new and improved
@ note:  check the box that makes the mon hold an item
@ pokemon tiene que tener un objeto, no importa si tiene movimientos personalizados

.align 2
.thumb
.thumb_func

.equ address_to_insert, 0xXXXXXX @ cambia esto, no 08 o algo así

.org 0x11596
mov r0, #1 @ used to determine return address
push {r0}
ldr r0, .Address_2
bx r0

.align 2

.Address_2: .word (0x08000001 | address_to_insert)

.org 0x115f6
mov r0, r1
mov r6, r0
b 0x11604

.org 0x1162c
mov r0, #0
push {r0}
ldr r0, .Method_Addr
bx r0

.align 2

.Method_Addr: .word (0x08000001 | address_to_insert)

.org 0x3dc70
b 0x3dcd0


.org address_to_insert 

LoadItem:
add r5, #0x6
add r0, r4, #0x0
mov r1, #0xc
add r2, r5, #0x0
bl Insert_Element

StartEVs:
ldr r0, .VarEVs
bl get_value_from_var
mov r5, #0x1A
push {r0}

LoadEVs:
mov r0, r4
mov r1, r5
mov r2, sp
bl Insert_Element
add r5, #1
cmp r5, #0x1F+1
bne LoadEVs

StartIVs:
pop {r0}
ldr r0, .VarIVs
bl get_value_from_var
mov r5, #0x27
push {r0}

IVLoop:
mov r0, r4
mov r1, r5
mov r2, sp
bl Insert_Element
add r5, r5, #0x1
cmp r5, #0x2C+1
bne IVLoop

End:
pop {r6}
mov r0, r4
bl Recalculate_Stats
pop {r1}
cmp r1, #0
bne return_2
ldr r1, .Return_Addr_1
bx r1

return_2:
ldr r1, .Return_Addr_2
bx r1

Insert_Element:
ldr r3, .Insert_Addr
bx r3

Recalculate_Stats:
ldr r1, .Recalc_Addr
bx r1

get_value_from_var:
ldr r2, .VarGet
bx r2

Mod:
ldr r3, .Mod_Addr
bx r3

.align 2
.Return_Addr_1: .word 0x08011639 @ item and custom moves
.Return_Addr_2: .word 0x0801166D @ just holding an item
.VarEVs: .word 0x000040XX @ change this
.VarIVs: .word 0x000040XX @ change this
.VarGet: .word 0x0806E569
.Insert_Addr: .word 0x0804037d
.Recalc_Addr: .word 0x0803e47d
.Mod_Addr: .word 0x081e4685


EDIT: new and improved! only needs you to check the custom item instead of going all in on the moveset too
__________________
heyo check out my github:

BluRosie
highlights:
battle engine for heartgold
various feature branches in heart gold (fairy type, odd egg, mud slopes)

i'm a big part of the development team of pokemon firegold! all the code that i develop for that hack is also on my github

also on discord: BluRose#0412
Reply With Quote
  #1521   Link to this post, but load the entire thread.  
Old September 20th, 2020 (8:40 PM).
Bela Bela is offline
Banned
 
Join Date: Apr 2009
Location: United States
Age: 33
Gender: Male
Nature: Modest
Posts: 262
Quote:
Originally Posted by kleenexfeu View Post
Well done on that KDS !

<snip>

Bonus:
-Life Orb boost
-Light ball updated
-Item that boost a certain type of attack for Emerald
-Timespace Orbs for Emerald

Note that for timespace orbs and new boost-type item, you can adjust the power added the same way than miracle seed and the like.

Spoiler:

Emerald:
Code:
CheckLifeOrb:
cmp r2, #0x43	/*Held item effect of life orb, I chose 0x43 (= 67 in decimal) because it's unused*/
beq Lifeorb

CheckNewItem:
cmp r2, #0x44	/*Held item effect of the boost item, I chose 0x44 (= 68 in decimal) because it's unused*/
beq NewItem

CheckAdamantOrb:
cmp r2, #0x45	/*Unused held item effect*/
bne CheckLustreous
ldrh r0, [r6]
mov r3, #0xFF	/*0xFF + 0xE4 = 0x1E3 = 483 = index number of Dialga*/
add r3, #0xE4
cmp r0, r3
beq AdamantOrb

CheckLustreous:
cmp r2, #0x46	/*Unused held item effect*/
bne CheckGriseous
ldrh r0, [r6]
mov r3, #0xFF	/*0xFF + 0xE5 = 0x1E4 = 484 = index number of Palkia*/
add r3, #0xE5
cmp r0, r3
beq LustreousOrb

CheckGriseous:
cmp r2, #0x47	/*Unused held item effect*/
bne CheckLightBall
ldrh r0, [r6]
mov r3, #0xFF	/*0xFF + 0xE8 = 0x1E7 = 487 = index number of Giratina*/
add r3, #0xE8
cmp r0, r3
beq GriseousOrb
b Back

AdamantOrb:
push {r0-r5}
mov r1, #8	/*Steel type*/
mov r2, #0x10	/*Dragon type*/
b CheckExceptionTypeAttack

LustreousOrb:
push {r0-r5}
mov r1, #0xB	/*Water type*/
mov r2, #0x10	/*Dragon type*/
b CheckExceptionTypeAttack

GriseousOrb:
push {r0-r5}
mov r1, #7	/*Ghost type*/
mov r2, #0x10	/*Dragon type*/
b CheckExceptionTypeAttack

NewItem:
push {r0-r5}
mov r1, #9	/*New type you want to boost*/
mov r2, #9	/*New type you want to boost, here I choose the same because I want it boost only one type*/

CheckExceptionTypeAttack:
ldr r4, CheckTypeLoc
ldr r4, [r4]
ldrb r4, [r4, #0x13]
cmp r4, #0
beq GetMoveType
mov r5, #0x3F
and r4, r5
cmp r4, r1
beq Boost
cmp r4, r2
beq Boost
b PopAndBack

Back:
ldr r0, Return
bx r0

PopAndBack:
pop {r0-r5}
b Back

CheckLightBall:
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #0x19
beq Lightball
b Back

GetMoveType:
ldr r3, CurMoveIndex
ldrh r3, [r3]
ldr r4, MoveData
mov r5, #0xC
mul r5, r3
add r4, r5
ldrb r4, [r4, #2]
cmp r4, r1
beq Boost
cmp r4, r2
bne PopAndBack

Boost:
pop {r0-r5}
ldrh r3, [r6, #0x2E]
lsl r0, r3, #4
push {r1}
mov r1, #6
mul r3, r1
pop {r1}
add r3, r0
lsl r3, #1
ldr r0, LocItems
add r3, r0
add r3, #0x13
ldrb r0, [r3]
mov r3, #0x52
mul r0, r3
lsr r0, #6
add r0, #0x7B
mul r7, r0
lsr r7, #7
mov r3, r8
mul r3, r0
lsr r3, #7
mov r8, r3
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1
b Back

.align 2
Return: .word 0x0806983E+1
LocItems: .word 0x085839A0           /*Location of your items Data*/
CurMoveIndex: .word 0x020241EA
MoveData: .word 0x0831C898           /*Location of your move data*/
CheckTypeLoc: .word 0x0202449C

/*00 48 00 47 XX XX XX 08 00 00 00 at 0x6982C*/
Fire Red:
Code:
cmp r2, #0x43   /*Held item effect, I chose 0x43 (=67 in dec) because it is unused in the game*/
beq Lifeorb
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #0x19
beq Lightball
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1

Back:
ldr r0, Return
bx r0

.align 2
Return: .word 0x0803F00A+1

/*00 48 00 47 XX XX XX 08 00 00 00 at 0803EFF8*/
Hey everybody, I know it's been 5 years since this was written and most people have moved on from this form of hacking, but I have a small request. I'm interested in adding the time-space orbs and the Pixie Plate to FireRed. From what I have been able to find on this forum, it looks like kleenexfeu did both for Emerald, but this has never been ported to FireRed.

While I know the CFRU engine exists and likely has these elements, I'm not looking to completely overhaul the game or re-do everything to use that base. I'm also unsure if these could be extracted from CFRU or not. My thinking is that the routines in the quoted post have not been written for FireRed, and a port of them are what I'd need. If someone out there is able to help me with this, please reach out to me on Discord or reply here. Thank you! :)
Reply With Quote
  #1522   Link to this post, but load the entire thread.  
Old September 21st, 2020 (8:13 AM).
Super Versekr Dark Super Versekr Dark is offline
 
Join Date: Jan 2017
Gender: Male
Posts: 79
Quote:
Originally Posted by BluRose View Post
not to double post but

give your opposing trainers evs and ivs based on a var each



this primarily to make difficulty hacks where there can be multiple difficulties

put a value in one var that you want the opponents ivs to be and another value in another var that you want your opponent's evs to be (and yes, all of them will be the same)
the pokemon has to have both a custom moveset and a custom item (at least those check marks ticked in your favorite trainer editor) then all of their values will be set

pastebin right here

credit me and doesntknowhowtoplay
for fire red:
Spoiler:
Code:
# note:  mon has to hold both an item and have a custom moveset
# pokemon tiene que tener un objeto y tener movimientos definidos

.align 2
.thumb
.thumb_func

.org 0x115f6
mov r0, r1
mov r6, r0
b 0x11604

.org 0x1162c
ldr r0, .Method_Addr
bx r0

.Method_Addr: .word (0x08000001 | 0xXXXXXX)

.org 0x3dc70
b 0x3dcd0


.org 0xXXXXXX # change this and the other above

LoadItem:
add r5, #0x6
add r0, r4, #0x0
mov r1, #0xc
add r2, r5, #0x0
bl Insert_Element

StartEVs:
ldr r0, .VarEVs
bl get_value_from_var
mov r5, #0x1A
push {r0}

LoadEVs:
mov r0, r4
mov r1, r5
mov r2, sp
bl Insert_Element
add r5, #1
cmp r5, #0x1F+1
bne LoadEVs

StartIVs:
pop {r0}
ldr r0, .VarIVs
bl get_value_from_var
mov r5, #0x27
push {r0}

IVLoop:
mov r0, r4
mov r1, r5
mov r2, sp
bl Insert_Element
add r5, r5, #0x1
cmp r5, #0x2C+1
bne IVLoop

End:
pop {r6}
mov r0, r4
bl Recalculate_Stats
ldr r1, .Return_Addr
bx r1

Insert_Element:
ldr r3, .Insert_Addr
bx r3

Recalculate_Stats:
ldr r1, .Recalc_Addr
bx r1

get_value_from_var:
ldr r2, .VarGet
bx r2

Mod:
ldr r3, .Mod_Addr
bx r3

.align 2
.Return_Addr: .word 0x08011639
.VarEVs: .word 0x000040XX # change this
.VarIVs: .word 0x000040XX # change this
.VarGet: .word 0x0806E569
.Insert_Addr: .word 0x0804037d
.Recalc_Addr: .word 0x0803e47d
.Mod_Addr: .word 0x081e4685
Excuse me, how would the script be done?
Reply With Quote
  #1523   Link to this post, but load the entire thread.  
Old September 21st, 2020 (11:15 AM). Edited January 13th, 2021 by BluRose.
BluRose BluRose is offline
blu rass
 
Join Date: Apr 2014
Location: michigan tech
Age: 22
Gender: Male
Nature: Timid
Posts: 812
Quote:
Originally Posted by Super Versekr Dark View Post
Excuse me, how would the script be done?
if you want to have a trainer that has its evs and ivs change with difficulty, then you just need to
- make the trainer's pokémon have a custom held item (moveset optional)
- insert the routine
- in any script, set the variables that you chose to the evs and ivs you desire
i recommend using vars from 0x4012-0x40FF, or if you don't want to clean the rom of its scripts then 0x40C0-0x40FF

si quieres un entrenador que tiene evs y ivs que cambian con dificultad, pues necesitas
- hacer que el pokemon del entrenador tiene un objeto (moveset no es necesario)
- insertar la rutina
- en un script, carga las variables que escoges para tener los evs y los ivs a los valores que deseas
recomiendo que uses vars desde 0x4012-0x40FF, o si no quieres borrar la rom de sus scripts 0x40C0-0x40FF
__________________
heyo check out my github:

BluRosie
highlights:
battle engine for heartgold
various feature branches in heart gold (fairy type, odd egg, mud slopes)

i'm a big part of the development team of pokemon firegold! all the code that i develop for that hack is also on my github

also on discord: BluRose#0412
Reply With Quote
  #1524   Link to this post, but load the entire thread.  
Old September 21st, 2020 (11:21 AM). Edited September 29th, 2020 by Dr. Seuss.
Dr. Seuss's Avatar
Dr. Seuss Dr. Seuss is offline
Navegando en mi automóvil, hablando con la nena por el móvil 😎...
 
Join Date: Feb 2014
Location: Guatemala City
Age: 27
Gender: Male
Nature: Brave
Posts: 521
It's been a long time since the main post was updated, so after a few hours I finished to update the index for you to easily find any ASM routine posted in this thread.

If a link is not properly working or I missed a routine feel free to PM me or any mod to add it to the index
__________________
Graphic design is my passion...

Click on the picture to see the best hack ever created (?
Reply With Quote
  #1525   Link to this post, but load the entire thread.  
Old September 25th, 2020 (10:32 AM). Edited September 29th, 2020 by BluRose.
BluRose BluRose is offline
blu rass
 
Join Date: Apr 2014
Location: michigan tech
Age: 22
Gender: Male
Nature: Timid
Posts: 812
Quote:
Originally Posted by Bela View Post
- snip -
Quote:
Originally Posted by kleenexfeu View Post
- snip -
Bonus:
-Life Orb boost
-Light ball updated
-Item that boost a certain type of attack for Emerald
-Timespace Orbs for Emerald

Note that for timespace orbs and new boost-type item, you can adjust the power added the same way than miracle seed and the like.

Spoiler:

Emerald:
Code:
CheckLifeOrb:
cmp r2, #0x43	/*Held item effect of life orb, I chose 0x43 (= 67 in decimal) because it's unused*/
beq Lifeorb

CheckNewItem:
cmp r2, #0x44	/*Held item effect of the boost item, I chose 0x44 (= 68 in decimal) because it's unused*/
beq NewItem

CheckAdamantOrb:
cmp r2, #0x45	/*Unused held item effect*/
bne CheckLustreous
ldrh r0, [r6]
mov r3, #0xFF	/*0xFF + 0xE4 = 0x1E3 = 483 = index number of Dialga*/
add r3, #0xE4
cmp r0, r3
beq AdamantOrb

CheckLustreous:
cmp r2, #0x46	/*Unused held item effect*/
bne CheckGriseous
ldrh r0, [r6]
mov r3, #0xFF	/*0xFF + 0xE5 = 0x1E4 = 484 = index number of Palkia*/
add r3, #0xE5
cmp r0, r3
beq LustreousOrb

CheckGriseous:
cmp r2, #0x47	/*Unused held item effect*/
bne CheckLightBall
ldrh r0, [r6]
mov r3, #0xFF	/*0xFF + 0xE8 = 0x1E7 = 487 = index number of Giratina*/
add r3, #0xE8
cmp r0, r3
beq GriseousOrb
b Back

AdamantOrb:
push {r0-r5}
mov r1, #8	/*Steel type*/
mov r2, #0x10	/*Dragon type*/
b CheckExceptionTypeAttack

LustreousOrb:
push {r0-r5}
mov r1, #0xB	/*Water type*/
mov r2, #0x10	/*Dragon type*/
b CheckExceptionTypeAttack

GriseousOrb:
push {r0-r5}
mov r1, #7	/*Ghost type*/
mov r2, #0x10	/*Dragon type*/
b CheckExceptionTypeAttack

NewItem:
push {r0-r5}
mov r1, #9	/*New type you want to boost*/
mov r2, #9	/*New type you want to boost, here I choose the same because I want it boost only one type*/

CheckExceptionTypeAttack:
ldr r4, CheckTypeLoc
ldr r4, [r4]
ldrb r4, [r4, #0x13]
cmp r4, #0
beq GetMoveType
mov r5, #0x3F
and r4, r5
cmp r4, r1
beq Boost
cmp r4, r2
beq Boost
b PopAndBack

Back:
ldr r0, Return
bx r0

PopAndBack:
pop {r0-r5}
b Back

CheckLightBall:
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #0x19
beq Lightball
b Back

GetMoveType:
ldr r3, CurMoveIndex
ldrh r3, [r3]
ldr r4, MoveData
mov r5, #0xC
mul r5, r3
add r4, r5
ldrb r4, [r4, #2]
cmp r4, r1
beq Boost
cmp r4, r2
bne PopAndBack

Boost:
pop {r0-r5}
ldrh r3, [r6, #0x2E]
lsl r0, r3, #4
push {r1}
mov r1, #6
mul r3, r1
pop {r1}
add r3, r0
lsl r3, #1
ldr r0, LocItems
add r3, r0
add r3, #0x13
ldrb r0, [r3]
mov r3, #0x52
mul r0, r3
lsr r0, #6
add r0, #0x7B
mul r7, r0
lsr r7, #7
mov r3, r8
mul r3, r0
lsr r3, #7
mov r8, r3
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1
b Back

.align 2
Return: .word 0x0806983E+1
LocItems: .word 0x085839A0           /*Location of your items Data*/
CurMoveIndex: .word 0x020241EA
MoveData: .word 0x0831C898           /*Location of your move data*/
CheckTypeLoc: .word 0x0202449C

/*00 48 00 47 XX XX XX 08 00 00 00 at 0x6982C*/
Fire Red:
Code:
cmp r2, #0x43   /*Held item effect, I chose 0x43 (=67 in dec) because it is unused in the game*/
beq Lifeorb
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #0x19
beq Lightball
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1

Back:
ldr r0, Return
bx r0

.align 2
Return: .word 0x0803F00A+1

/*00 48 00 47 XX XX XX 08 00 00 00 at 0803EFF8*/
life orb, new fairy plate, spacial orbs, and the new soul dew (as of gen 7) all in one routine! based on the quoted routine.

for fire red:
Spoiler:
Code:
.align 2

.thumb
.thumb_func

@ 00 48 00 47 XX XX XX 08 00 00 00 at 0803EFF8
@ also change gItems and gBattleMoves at the bottom of the post

.equ .giratina, 0x1000 @ giratina index
.equ .dialga, 0x1001 @ dialga index
.equ .palkia, 0x1002 @ palkia index
.equ .pikachu, 0x19 @ pikachu index
.equ .latios, 408
.equ .latias, 407

CheckAnyItem:
cmp r2, #0x43   @ boost life orb held effect
beq Lifeorb
cmp r2, #0x44   @ boost fairy type held effect
beq FairyPlate
cmp r2, #0x45   @ adamant orb held effect
beq AdamantOrb
cmp r2, #0x46   @ lustrous orb held effect
beq LustrousOrb
cmp r2, #0x47   @ griseous orb held effect
beq GriseousOrb
cmp r2, #0x48   @ soul dew gen 7 held effect.  can not be the same as the normal soul dew!  it's a new held effect here
beq NewSoulDew
cmp r2, #0x2D   @ light ball held effect
bne Back
ldrh r0, [r6]
cmp r0, #.pikachu
beq Lightball   @ if pikachu then go to lightball
b Back

FairyPlate:
push {r0-r5}
mov r0, #9 @ your fairy type
mov r1, #9 @ your fairy type
b CheckTypeOfAttack

AdamantOrb:
push {r0-r5}
ldrh r0, [r6]
ldr r1, =(.dialga)
cmp r0, r1
bne PopAndBack
mov r0, #8
mov r1, #16
b CheckTypeOfAttack

LustrousOrb:
push {r0-r5}
ldrh r0, [r6]
ldr r1, =(.palkia)
cmp r0, r1
bne PopAndBack
mov r0, #0xB
mov r1, #16
b CheckTypeOfAttack

GriseousOrb:
push {r0-r5}
ldrh r0, [r6]
ldr r1, =(.giratina)
cmp r0, r1
bne PopAndBack
mov r0, #7
mov r1, #16
b CheckTypeOfAttack

NewSoulDew:
push {r0-r5}
ldrh r0, [r6]
ldr r1, =(.latias)
cmp r0, r1
add r1, #1 @ latios = latias + 1
cmp r0, r1
bne PopAndBack
mov r0, #0xE
mov r1, #0x10
@b CheckTypeOfAttack  @ fall through

CheckTypeOfAttack:
ldr r4, gBattleStruct
ldr r4, [r4]
ldrb r4, [r4, #0x13] @ check for the dynamic move type
cmp r4, #0
beq GetMoveType
mov r5, #0x3F
and r4, r5
cmp r4, r1
beq Boost
cmp r4, r2
beq Boost
b PopAndBack

GetMoveType:
ldr r3, gCurrentMove
ldrh r3, [r3]
ldr r4, gBattleMoves
mov r5, #0xC
mul r5, r3
add r4, r5
ldrb r4, [r4, #2]
cmp r4, r1
beq Boost
cmp r4, r2
bne PopAndBack

@ fall through

Boost:
pop {r0-r5}
ldrh r3, [r6, #0x2E]
lsl r0, r3, #4
push {r1}
mov r1, #6
mul r3, r1
pop {r1}
add r3, r0
lsl r3, #1
ldr r0, gItems
add r3, r0
add r3, #0x13
ldrb r0, [r3]
mov r3, #0x52
mul r0, r3
lsr r0, #6
add r0, #0x7B
mul r7, r0
lsr r7, #7
mov r3, r8
mul r3, r0
lsr r3, #7
mov r8, r3
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7 
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1

Back:
ldr r0, Return
bx r0

PopAndBack:
pop {r0-r5}
b Back

.align 2
Return: .word 0x0803F00A | 1
gCurrentMove:  .word 0x02023D4A
gBattleMoves:  .word 0x08250C04 @ change this
gBattleStruct:  .word 0x02023FE8
gItems:  .word 0x083DB028 @ change this
works the same where it's based on the parameter in the item effect structure

EDIT: added species requirements and now it doesn't crash
wholly tested now basically

EDIT: updated it to include gen 7's soul dew updates. note that it can't use the same held effect as the normal soul dew
__________________
heyo check out my github:

BluRosie
highlights:
battle engine for heartgold
various feature branches in heart gold (fairy type, odd egg, mud slopes)

i'm a big part of the development team of pokemon firegold! all the code that i develop for that hack is also on my github

also on discord: BluRose#0412
Reply With Quote
Reply

Quick Reply

Join the conversation!

Create an account to post a reply in this thread, participate in other discussions, and more!

Create a PokéCommunity Account
Ad Content
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 8:46 AM.