AkameTheBulbasaur
Akame Marukawa of Iyotono
- 410
- Posts
- 11
- Years
- A place :D
- Seen Apr 20, 2025
Acknowledgments
First and foremost I have to thank Knizz for her previous research on the Trainer AI Scripting system! Because of her hard work, I was able to have a foundation for all the research I've done. By extension, I also have to thank JPAN, because Knizz said she relied heavily on that as well.
If you want to see Knizz's original work, it is in this thread.
I should say that this particular research is for FireRed. I think that Emerald uses the same sort of system (with different offsets) but I haven't checked. Don't sue me if it's different!
And with that, let's get on with the show!
Introduction
There have been a few attempts in the past of improving the difficulty of ROM Hacks, such as DoesntKnowHowToPlay's Trainer EV hack (here), but I wasn't quite satisfied with that.
I used that hack, and JPAN's dynamic trainer level hack (to make trainer levels match your own), and that helped genuinely increase the difficulty, but I found it wasn't enough. I wanted to really control how the AI works from its core.
So I found Knizz's earlier thread from 2014, which detailed a sort of scripting system for the AI, theoretically making it possible to write your own scripts and customize the AI. It was a really good start, but I couldn't find very much information outside of that thread.
The last post in that thread is from 2015. The development on that front seemed to stagnate.
So I decided I would try to research the commands myself, just for fun, and see how far I got. I was originally intending to post what I found to that thread after I was done. Five months later and the post I'd written down was so long I thought it would be easier to give it it's own thread.
The Commands
There are two main variables in Trainer AI Scripting. The first and foremost is the Free Variable. This is like LASTRESULT in NPC scripting. Many of the commands store their results here, and you can then use this result for other commands.
Many commands jump to a given address if the free variable compares to something.
The second variable is the Considered Move Variable. This variable has the index number of the move being considered while the script is running. You can compare it to things or get Move data from it.
Useful numbers:
Attacker is 1, Defender is 0.
True is 1, False is 0.
Basic syntax rules:
The target (if applicable) always comes first, and the address to jump to (if applicable always comes last). If any of the below commands have more than two arguments, this is how the order will almost always go.
Some of the existing commands I thought were either written in a clunky way, or I thought of something I could add to them (I think one of them was bugged to begin with) so I rewrote them. I'll include the routines for the rewritten versions after the description of the commands.
I should note that there are, for some unknown reason, commands in default FireRed that do nothing. I don't mean they have a redundant or pointless effect, I mean they literally do nothing. I tried using one and it soft locked the game. This is useful because it means you can add about ten new commands without replacing or expanding the table!
In fact, because of the CallASM command (which I wrote recently and have included at the very bottom) you don't need to expand the table at all if you don't want to!
DISCLAIMER: Adding in the new or rewritten commands that will follow won't make the AI smarter. Only creating new scripts using the commands will.
WARNING ABOUT CERTAIN REWRITTEN COMMANDS!
The first iteration of this thread included a warning about how certain rewritten commands are incompatible with default AI scripts because the amount of arguments in them is different. Somehow, this warning was deleted, so I'm putting it back because it's kinda important lol.
JumpIfDamageBonusEquals has extra arguments, and thus if you put it in and do not change the default script, the game will crash.
This really shouldn't be an issue, as the modified command is really intended to be used with modified scripts. However, if for some reason you want to use the default scripts, follow the instructions below:
Documents
Since I keep updating this because I either add new commands or update old ones, I decided it would be way easier to have a Google Doc with all the information on it. It's easier for me to update that.
There are three. The first is the command description list. Please note that these descriptions are of the updated commands. So if a command was rewritten or updated, the rewritten/updated version is used. It also includes descriptions of new commands.
The second is a folder that has all the rewritten command routines in it.
The third is another folder that has all the new command routines in it.
Links
1. AI Command Descriptions
2. Rewritten Commands
3. New Commands
Callasm Command
I am putting this command separately because it is a big deal. With it, you can have as many commands as you need regardless of how big or small your command table is. You can literally use this to do pretty much anything you want.
The syntax looks like this
Callasm OFFSET + 1
Arguments for asm routine
Put the arguments for the command (if any) immediately after the pointer to the command routine. Then, just format the routine as if it were a normal command called from the table. The AI Cursor is updated in the routine it calls, so you can have as many or as little arguments as you need.
Macros
The final gift I would like to impart on the masses at Pokecommunity is this. I've created a few macros to use to help compile scripts.
The link to view all of them is here.
The way to use them is to include the relevant macros at the top of the script (and by that I mean copy and paste them into the beginning of your script), and then just type the script using this sort of form:
.equ ROM, 0x8
Main:
JumpIfMoveScriptEquals 0x1 CauseSleep+ROM
ReturnToBattle
CauseSleep:
JumpIfStatus1Equals Defender 0x000000FF Decrease32+ROM
ReturnToBattle
Decrease32:
AddToViabilityScore 0xE0
ReturnToBattle
That way, you can just compile this with any sort of THUMB assembler. Remember to put the offset that you're inserting the script at after the ".equ ROM, 0x8". If you don't the pointers in your script will be all wrong.
I recommend
Conclusion
This thread is the culmination of over five months worth of research and work. My hope with all of this is to give ROM hackers the ability to truly customize the AI. This can be used not just to raise the difficulty/challenge of games, but also to add support to the ever-growing list of new moves and abilities being added to the gen III games.
First and foremost I have to thank Knizz for her previous research on the Trainer AI Scripting system! Because of her hard work, I was able to have a foundation for all the research I've done. By extension, I also have to thank JPAN, because Knizz said she relied heavily on that as well.
If you want to see Knizz's original work, it is in this thread.
I should say that this particular research is for FireRed. I think that Emerald uses the same sort of system (with different offsets) but I haven't checked. Don't sue me if it's different!
And with that, let's get on with the show!
Introduction
There have been a few attempts in the past of improving the difficulty of ROM Hacks, such as DoesntKnowHowToPlay's Trainer EV hack (here), but I wasn't quite satisfied with that.
I used that hack, and JPAN's dynamic trainer level hack (to make trainer levels match your own), and that helped genuinely increase the difficulty, but I found it wasn't enough. I wanted to really control how the AI works from its core.
So I found Knizz's earlier thread from 2014, which detailed a sort of scripting system for the AI, theoretically making it possible to write your own scripts and customize the AI. It was a really good start, but I couldn't find very much information outside of that thread.
The last post in that thread is from 2015. The development on that front seemed to stagnate.
So I decided I would try to research the commands myself, just for fun, and see how far I got. I was originally intending to post what I found to that thread after I was done. Five months later and the post I'd written down was so long I thought it would be easier to give it it's own thread.
The Commands
There are two main variables in Trainer AI Scripting. The first and foremost is the Free Variable. This is like LASTRESULT in NPC scripting. Many of the commands store their results here, and you can then use this result for other commands.
Many commands jump to a given address if the free variable compares to something.
The second variable is the Considered Move Variable. This variable has the index number of the move being considered while the script is running. You can compare it to things or get Move data from it.
Useful numbers:
Attacker is 1, Defender is 0.
True is 1, False is 0.
Basic syntax rules:
The target (if applicable) always comes first, and the address to jump to (if applicable always comes last). If any of the below commands have more than two arguments, this is how the order will almost always go.
Some of the existing commands I thought were either written in a clunky way, or I thought of something I could add to them (I think one of them was bugged to begin with) so I rewrote them. I'll include the routines for the rewritten versions after the description of the commands.
I should note that there are, for some unknown reason, commands in default FireRed that do nothing. I don't mean they have a redundant or pointless effect, I mean they literally do nothing. I tried using one and it soft locked the game. This is useful because it means you can add about ten new commands without replacing or expanding the table!
In fact, because of the CallASM command (which I wrote recently and have included at the very bottom) you don't need to expand the table at all if you don't want to!
DISCLAIMER: Adding in the new or rewritten commands that will follow won't make the AI smarter. Only creating new scripts using the commands will.
WARNING ABOUT CERTAIN REWRITTEN COMMANDS!
The first iteration of this thread included a warning about how certain rewritten commands are incompatible with default AI scripts because the amount of arguments in them is different. Somehow, this warning was deleted, so I'm putting it back because it's kinda important lol.
JumpIfDamageBonusEquals has extra arguments, and thus if you put it in and do not change the default script, the game will crash.
This really shouldn't be an issue, as the modified command is really intended to be used with modified scripts. However, if for some reason you want to use the default scripts, follow the instructions below:
- Download (or make your own) this file. It is 16 MB of just FF.
- Open this in a THUMB editor.
Spoiler:.macro RandomJumpIfLessThan Value Address
.byte 0x0
.byte \Value
.word \Address
.endm
.macro RandomJumpIfMoreThan Value Address
.byte 0x1
.byte \Value
.word \Address
.endm
.macro RandomJumpOneIn256 Address
.byte 0x2
.word \Address
.endm
.macro RandomJump255In256 Address
.byte 0x3
.word \Address
.endm
.macro AddToViabilityScore Value
.byte 0x4
.byte \Value
.endm
.macro JumpIfHealthLessThan Target Value Address
.byte 0x5
.byte \Target
.byte \Value
.word \Address
.endm
.macro JumpIfHealthMoreThan Target Value Address
.byte 0x6
.byte \Target
.byte \Value
.word \Address
.endm
.macro JumpIfHealthEquals Target Value Address
.byte 0x7
.byte \Target
.byte \Value
.word \Address
.endm
.macro JumpIfHealthNotEqual Target Value Address
.byte 0x8
.byte \Target
.byte \Value
.word \Address
.endm
.macro JumpIfStatus1Equals Target Status Address
.byte 0x9
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfStatus1NotEqual Target Status Address
.byte 0xA
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfStatus2Equals Target Status Address
.byte 0xB
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfStatus2NotEqual Target Status Address
.byte 0xC
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfStatus3Equals Target Status Address
.byte 0xD
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfStatus3NotEqual Target Status Address
.byte 0xE
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfStatus4Equals Target Status Address
.byte 0xF
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfStatus4NotEqual Target Status Address
.byte 0x10
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfByteLessThan Value Address
.byte 0x11
.byte \Value
.word \Address
.endm
.macro JumpIfByteMoreThan Value Address
.byte 0x12
.byte \Value
.word \Address
.endm
.macro JumpIfByteEquals Value Address
.byte 0x13
.byte \Value
.word \Address
.endm
.macro JumpIfByteNotEqual Value Address
.byte 0x14
.byte \Value
.word \Address
.endm
.macro JumpIfWordLessThan Value Address
.byte 0x15
.word \Value
.word \Address
.endm
.macro JumpIfWordMoreThan Value Address
.byte 0x16
.word \Value
.word \Address
.endm
.macro JumpIfWordEquals Value Address
.byte 0x17
.word \Value
.word \Address
.endm
.macro JumpIfWordNotEqual Value Address
.byte 0x18
.word \Value
.word \Address
.endm
.macro JumpIfMoveIDEquals Move Address
.byte 0x19
.hword \Move
.word \Address
.endm
.macro JumpIfMoveIDNotEqual Move Address
.byte 0x1A
.hword \Move
.word \Address
.endm
.macro JumpIfByteInList List Address
.byte 0x1B
.word \List
.word \Address
.endm
.macro JumpIfByteNotInList List Address
.byte 0x1C
.word \List
.word \Address
.endm
.macro JumpIfHalfwordInList List Address
.byte 0x1D
.word \List
.word \Address
.endm
.macro JumpIfHalfwordNotInList List Address
.byte 0x1E
.word \List
.word \Address
.endm
.macro JumpIfAttackerHasDamagingMoves Address
.byte 0x1F
.word \Address
.endm
.macro JumpIfAttackerHasNoDamagingMoves Address
.byte 0x20
.word \Address
.endm
.macro GetBattleTurnCounter
.byte 0x21
.endm
.macro GetType Argument
.byte 0x22
.byte \Argument
.endm
.macro GetPowerOfConsideredMove
.byte 0x23
.endm
.macro GetPowerOfStrongestMove
.byte 0x24
.endm
.macro GetMoveLastUsed Target
.byte 0x25
.byte \Target
.endm
.macro JumpIfFreeVarEquals Value Address
.byte 0x26
.byte \Value
.word \Address
.endm
.macro JumpIfFreeVarNotEqual Value Address
.byte 0x27
.byte \Value
.word \Address
.endm
.macro JumpIfMoveWouldHitFirst Priority Address
.byte 0x28
.byte \Priority
.word \Address
.endm
.macro JumpIfMoveWouldHitSecond Priority Address
.byte x29
.byte \Priority
.word \Address
.endm
.macro GetPerishCount Target
.byte 0x2A
.byte \Target
.endm
.macro GetSpikesLayer Target
.byte 0x2B
.byte \Target
.endm
.macro CountViablePokemonOnTeam Target
.byte 0x2C
.byte \Target
.endm
.macro GetMoveID
.byte 0x2D
.endm
.macro GetMoveScriptID Move
.byte 0x2E
.byte \Move
.endm
.macro GetAbility Target
.byte 0x2F
.byte \Target
.endm
.macro CallASM Address
.byte 0x30
.word \Address
.endm
.macro JumpIfDamageBonusEquals Move Value Address
.byte 0x31
.byte \Move
.byte \Value
.word \Address
.endm
.macro JumpIfAnyOrAllStatsAre Target Argument Compare Value Address
.byte 0x32
.byte \Target
.byte \Argument
.byte \Compare
.byte \Value
.word \Address
.endm
.macro DoesTeeterDanceWork
.byte 0x33
.endm
.macro JumpIfAnyPokemonHasStatus Target Status Address
.byte 0x34
.byte \Target
.word \Status
.word \Address
.endm
.macro JumpIfNoPokemonHasStatus Target Status Address
.byte 0x35
.byte \Target
.word \Status
.word \Address
.endm
.macro GetWeather
.byte 0x36
.endm
.macro JumpIfMoveScriptEquals Value Address
.byte 0x37
.byte \Value
.word \Address
.endm
.macro JumpIfMoveScriptNotEqual Value Address
.byte 0x38
.byte \Value
.word \Address
.endm
.macro JumpIfStatBuffLessThan Target Stat Value Address
.byte 0x39
.byte \Target
.byte \Stat
.byte \Value
.word \Address
.endm
.macro JumpIfStatBuffMoreThan Target Stat Value Address
.byte 0x3A
.byte \Target
.byte \Stat
.byte \Value
.word \Address
.endm
.macro JumpIfStatBuffEquals Target Stat Value Address
.byte 0x3B
.byte \Target
.byte \Stat
.byte \Value
.word \Address
.endm
.macro JumpIfStatBuffNotEqual Target Stat Value Address
.byte 0x3C
.byte \Target
.byte \Stat
.byte \Value
.word \Address
.endm
.macro JumpIfMoveKnocksOut Address
.byte 0x3D
.word \Address
.endm
.macro JumpIfMoveDoesntKnockOut Address
.byte 0x3E
.word \Address
.endm
.macro JumpIfMoveInMoveSet Target Move Address
.byte 0x3F
.byte \Target
.hword \Move
.word \Address
.endm
.macro JumpIfMoveNotInMoveSet Target Move Address
.byte 0x40
.byte \Target
.hword \Move
.word \Address
.endm
.macro JumpIfMoveScriptInMoveSet Target Script Address
.byte 0x41
.byte \Target
.byte \Script
.word \Address
.endm
.macro JumpIfMoveScriptNotInMoveSet Target Script Address
.byte 0x42
.byte \Target
.byte \Script
.word \Address
.endm
.macro JumpIfMoveSetRestricted Target Restriction Address
.byte 0x43
.byte \Target
.byte \Restriction
.word \Address
.endm
.macro JumpIfEncoreIs Value Address
.byte 0x44
.byte \Value
.byte \Address
.endm
.macro RunAway
.byte 0x45
.endm
.macro GetMovePriority Move
.byte 0x46
.byte \Move
.endm
.macro SafariZone
.byte 0x47
.endm
.macro GetHeldItemEffect Target
.byte 0x48
.byte \Target
.endm
.macro GetGender Target
.byte 0x49
.byte \Target
.endm
.macro CheckIfFirstTurn Target
.byte 0x4A
.byte \Target
.endm
.macro GetStockpileCounter Target
.byte 0x4B
.byte \Target
.endm
.macro CheckIfDoubleBattle
.byte 0x4C
.endm
.macro GetItemID Target
.byte 0x4D
.byte \Target
.endm
.macro GetKindOfMove Move
.byte 0x4E
.byte \Move
.endm
.macro GetMoveAccuracy
.byte 0x4F
.endm
.macro GetMoveRange Move
.byte 0x50
.byte \Move
.endm
.macro GetProtectActivity Target
.byte 0x51
.byte \Target
.endm
.macro GetTarget
.byte 0x52
.endm
.macro GetSubHealthRatio Target
.byte 0x53
.byte \Target
.endm
.macro CheckIfMoveFlagSet Move Flag
.byte 0x54
.hword \Move
.byte \Flag
.endm
.macro CheckIfInverseBattle
.byte 0x55
.endm
.macro CheckIfStatsAre Target Stat1 Stat2 Compare
.byte 0x56
.byte \Target
.byte \Stat1
.byte \Stat2
.byte \Compare
.endm
.macro GetDataAtRAM Size Address
.byte 0x57
.byte \Size
.word \Address
.endm
.macro Call Address
.byte 0x58
.word \Address
.endm
.macro Jump Address
.byte 0x59
.word \Address
.endm
.macro ReturnToBattle
.byte 0x5A
.endm
.macro JumpIfBattlerLevelsAre Value Address
.byte 0x5B
.byte \Value
.word \Address
.endm
.macro JumpIfTauntTurnsNotZero Address
.byte 0x5C
.word \Address
.endm
.macro JumpIfTauntTurnsZero Address
.byte 0x5D
.word \Address
.endm
.equ Defender, 0x0
.equ Attacker, 0x1
.equ APartner, 0x2
.equ DPartner, 0x3
.equ Priority, 0x1
.equ NoPriority, 0x0
.equ Done, 0xFFFF
.equ Finished, 0xFF
.equ CurrentMove, 0x12
.equ MoveVar, 0x0
.equ FreeVar, 0x1
.equ Partner, 0x1
.equ Byte, 0x0
.equ HalfWord, 0x1
.equ Word, 0x2
.equ True, 0x1
.equ False, 0x0
.equ DType1, 0x0
.equ AType1, 0x1
.equ DType2, 0x2
.equ AType2, 0x3
.equ Move, 0x4
.equ Var, 0x5
.equ APType1, 0x6
.equ DPType1, 0x7
.equ APType2, 0x8
.equ DPType2, 0x9
.equ DoubleWeak, 0xF0
.equ Weak, 0x78
.equ Neutral, 0x28
.equ Resist, 0x1E
.equ DoubleResist, 0xF
.equ Immune, 0x0
.equ Equal, 0x0
.equ NotEqual, 0x1
.equ LessThan, 0x2
.equ MoreThan, 0x3
.equ AllFoes, 0x8
.equ AllButUser, 0x20
.equ User, 0x10
.equ Target, 0x0
.equ Random, 0x4
.equ Everyone, 0x30
.equ Any, 0x0
.equ All, 0x1
.equ Clear, 0x0
.equ Rain_Storm, 0x1
.equ Sun_Shine, 0x2
.equ Sand_Storm, 0x3
.equ Hail_Storm, 0x4
.equ Sleep, 0x00000007
.equ Poisoned, 0x00000008
.equ Burn, 0x00000010
.equ Freeze, 0x00000020
.equ Paralyze, 0x00000040
.equ BadPoison, 0x00000080
.equ MajorStatus, 0x000000FF
.equ Confused, 0x00000007
.equ CantSleep, 0x00000070
.equ Trapped, 0x0400E000
.equ InLove, 0x000F0000
.equ RechargeUp, 0x00400000
.equ SubActive, 0x01000000
.equ DBondUp, 0x02000000
.equ NMareUp, 0x08000000
.equ CurseUp, 0x10000000
.equ DCurlUp, 0x40000000
.equ TormentUp, 0x80000000
.equ LSeedUp, 0x00000004
.equ LockOnUp, 0x00000010
.equ PanicModeUp, 0x00000020
.equ SInvulnerable, 0x000400C0
.equ ChargeUp, 0x00000200
.equ IngrainUp, 0x00000400
.equ Flying, 0x00000040
.equ Digging, 0x00000080
.equ GrudgeUp, 0x00004000
.equ Diving, 0x00040000
.equ ReflectUp, 0x00000001
.equ LScreenUp, 0x00000002
.equ SpikesUp, 0x00000010
.equ SGuardUp, 0x00000020
.equ MistUp, 0x00000100
.equ Attack, 0x1
.equ Defense, 0x2
.equ Speed, 0x3
.equ SpAttack, 0x4
.equ SpDefense, 0x5
.equ Accuracy, 0x6
.equ Evasion, 0x7
.equ Physical, 0x0
.equ Special, 0x1
.equ Status, 0x2
.equ DirectContact, 0x1
.equ ProtectBlocked, 0x2
.equ MagicCoatBlock, 0x4
.equ SnatchBlock, 0x8
.equ MirrorMoveUsable, 0x10
.equ KingsRockBlock, 0x20
.equ AllMoveFlags, 0x3F
.equ Stench, 0x1
.equ Drizzle, 0x2
.equ SpeedBoost, 0x3
.equ BattleArmor, 0x4
.equ Sturdy, 0x5
.equ Damp, 0x6
.equ Limber, 0x7
.equ SandVeil, 0x8
.equ Static, 0x9
.equ VoltAbsorb, 0xA
.equ WaterAbsorb, 0xB
.equ Oblivious, 0xC
.equ CloudNine, 0xD
.equ CompoundEyes, 0xE
.equ Insomnia, 0xF
.equ ColorChange, 0x10
.equ Immunity, 0x11
.equ FlashFire, 0x12
.equ ShieldDust, 0x13
.equ OwnTempo, 0x14
.equ SuctionCups, 0x15
.equ Intimidate, 0x16
.equ ShadowTag, 0x17
.equ RoughSkin, 0x18
.equ WonderGuard, 0x19
.equ Levitate, 0x1A
.equ EffectSpore, 0x1B
.equ Synchronize, 0x1C
.equ ClearBody, 0x1D
.equ NaturalCure, 0x1E
.equ LightningRod, 0x1F
.equ SereneGrace, 0x20
.equ SwiftSwim, 0x21
.equ Chlorophyll, 0x22
.equ Illuminate, 0x23
.equ Trace, 0x24
.equ HugePower, 0x25
.equ PoisonPoint, 0x26
.equ InnerFocus, 0x27
.equ MagmaArmor, 0x28
.equ WaterVeil, 0x29
.equ MagnetPull, 0x2A
.equ FrostVeil, 0x2B
.equ RainDish, 0x2C
.equ SandStream, 0x2D
.equ Pressure, 0x2E
.equ ThickFat, 0x2F
.equ EarlyBird, 0x30
.equ FlameBody, 0x31
.equ RunAway, 0x32
.equ KeenEye, 0x33
.equ HyperCutter, 0x34
.equ PickUp, 0x35
.equ Truant, 0x36
.equ Hustle, 0x37
.equ CuteCharm, 0x38
.equ Plus, 0x39
.equ Minus, 0x3A
.equ Forecast, 0x3B
.equ StickyHold, 0x3C
.equ ShedSkin, 0x3D
.equ Guts, 0x3E
.equ MarvelScale, 0x3F
.equ LiquidOoze, 0x40
.equ Overgrow, 0x41
.equ Blaze, 0x42
.equ Torrent, 0x43
.equ Swarm, 0x44
.equ RockHead, 0x45
.equ Drought, 0x46
.equ ArenaTrap, 0x47
.equ VitalSpirit, 0x48
.equ WhiteSmoke, 0x49
.equ PurePower, 0x4A
.equ ShellArmor, 0x4B
.equ SnowWarning, 0x4C
.equ AirLock, 0x4D
.equ None, 0x0
.equ MasterBall, 0x1
.equ UltraBall, 0x2
.equ GreatBall, 0x3
.equ PokeBall, 0x4
.equ SafariBall, 0x5
.equ NetBall, 0x6
.equ DiveBall, 0x7
.equ NestBall, 0x8
.equ RepeatBall, 0x9
.equ TimerBall, 0xA
.equ LuxuryBall, 0xB
.equ QuickBall, 0xC
.equ Potion, 0xD
.equ Banitsa, 0xE
.equ Flan, 0xF
.equ Gyuvech, 0x10
.equ OmanyteCake, 0x11
.equ CrabCake, 0x12
.equ FullRestore, 0x13
.equ MaxPotion, 0x14
.equ HyperPotion, 0x15
.equ SuperPotion, 0x16
.equ Tarator, 0x17
.equ Revive, 0x18
.equ MaxRevive, 0x19
.equ FreshWater, 0x1A
.equ SodaPop, 0x1B
.equ Lemonade, 0x1C
.equ MooMooMilk, 0x1D
.equ EnergyPowder, 0x1E
.equ EnergyRoot, 0x1F
.equ HealPowder, 0x20
.equ RevivalHerb, 0x21
.equ Tea, 0x22
.equ MaxEther, 0x23
.equ Elixir, 0x24
.equ MaxElixir, 0x25
.equ LavaCookie, 0x26
.equ BlueFlute, 0x27
.equ YellowFlute, 0x28
.equ RedFlute, 0x29
.equ BlackFlute, 0x2A
.equ WhiteFlute, 0x2B
.equ BerryJuice, 0x2C
.equ SacredAsh, 0x2D
.equ MizuSalt, 0x2E
.equ MizuShell, 0x2F
.equ RedShard, 0x30
.equ BlueShard, 0x31
.equ YellowShard, 0x32
.equ GreenShard, 0x33
.equ Iyoko, 0x34
.equ Quesadilla, 0x35
.equ PikaCookie, 0x36
.equ Triagel, 0x37
.equ HealthWing, 0x38
.equ MuscleWing, 0x39
.equ ResistWing, 0x3A
.equ CleverWing, 0x3B
.equ GeniusWing, 0x3C
.equ SwiftWing, 0x3D
.equ Yonjin, 0x3E
.equ HPUp, 0x3F
.equ Protein, 0x40
.equ Iron, 0x41
.equ Carbos, 0x42
.equ Calcium, 0x43
.equ RareCandy, 0x44
.equ PPUp, 0x45
.equ Zinc, 0x46
.equ PPMax, 0x47
.equ Maitzei, 0x48
.equ AlterStone, 0x49
.equ Electirizer, 0x4A
.equ XAttack, 0x4B
.equ XDefend, 0x4C
.equ XSpeed, 0x4D
.equ XAccuracy, 0x4E
.equ XSpecial, 0x4F
.equ ClefairyDoll, 0x50
.equ FluffyTail, 0x51
.equ Ambonyan, 0x52
.equ NanabCake, 0x53
.equ Lobster, 0x54
.equ EscapeRope, 0x55
.equ VeranoCone, 0x56
.equ Apple, 0x57
.equ GreenApple, 0x58
.equ GoldenApple, 0x59
.equ RainbowApple, 0x5A
.equ Banana, 0x5B
.equ SpotPizza, 0x5C
.equ SunStone, 0x5D
.equ MoonStone, 0x5E
.equ FireStone, 0x5F
.equ ThunderStone, 0x60
.equ WaterStone, 0x61
.equ LeafStone, 0x62
.equ IceCream, 0x63
.equ MewMacaroni, 0x64
.equ Paella, 0x65
.equ Pancakes, 0x66
.equ TinyMushroom, 0x67
.equ BigMushroom, 0x68
.equ Kanaba, 0x69
.equ Pearl, 0x6A
.equ BigPearl, 0x6B
.equ Stardust, 0x6C
.equ StarPiece, 0x6D
.equ Nugget, 0x6E
.equ HeartScale, 0x6F
.equ LaggingTail, 0x70
.equ CheesePizza, 0x71
.equ ChocoPizza, 0x72
.equ ExpertBelt, 0x73
.equ GrillCheese, 0x74
.equ Hamburger, 0x75
.equ Invention, 0x76
.equ WhitePizza, 0x77
.equ Magmarizer, 0x78
.equ OrangeMail, 0x79
.equ HarborMail, 0x7A
.equ GlitterMail, 0x7B
.equ MechMail, 0x7C
.equ WoodMail, 0x7D
.equ WaveMail, 0x7E
.equ BeadMail, 0x7F
.equ ShadowMail, 0x80
.equ TropicMail, 0x81
.equ DreamMail, 0x82
.equ FabMail, 0x83
.equ RetroMail, 0x84
.equ CheriBerry, 0x85
.equ ChestoBerry, 0x86
.equ PechaBerry, 0x87
.equ RawstBerry, 0x88
.equ AspearBerry, 0x89
.equ LeppaBerry, 0x8A
.equ OranBerry, 0x8B
.equ PersimBerry, 0x8C
.equ LumBerry, 0x8D
.equ SitrusBerry, 0x8E
.equ FigyBerry, 0x8F
.equ WikiBerry, 0x90
.equ MagoBerry, 0x91
.equ AguavBerry, 0x92
.equ IapapaBerry, 0x93
.equ RazzBerry, 0x94
.equ BlukBerry, 0x95
.equ NanabBerry, 0x96
.equ WepearBerry, 0x97
.equ PinapBerry, 0x98
.equ PomegBerry, 0x99
.equ KelpsyBerry, 0x9A
.equ QualotBerry, 0x9B
.equ HondewBerry, 0x9C
.equ GrepaBerry, 0x9D
.equ TamatoBerry, 0x9E
.equ CornnBerry, 0x9F
.equ MagostBerry, 0xA0
.equ RabutaBerry, 0xA1
.equ NomelBerry, 0xA2
.equ SpelonBerry, 0xA3
.equ PamtreBerry, 0xA4
.equ WatmelBerry, 0xA5
.equ DurinBerry, 0xA6
.equ BelueBerry, 0xA7
.equ LiechiBerry, 0xA8
.equ GanlonBerry, 0xA9
.equ SalacBerry, 0xAA
.equ PetayaBerry, 0xAB
.equ ApicotBerry, 0xAC
.equ LansatBerry, 0xAD
.equ StarfBerry, 0xAE
.equ EnigmaBerry, 0xAF
.equ BlackSludge, 0xB0
.equ AssaultVest, 0xB1
.equ RazorClaw, 0xB2
.equ BrightPowder, 0xB3
.equ WhiteHerb, 0xB4
.equ MachoBrace, 0xB5
.equ ExpBrace, 0xB6
.equ QuickClaw, 0xB7
.equ SootheBell, 0xB8
.equ MentalHerb, 0xB9
.equ ChoiceBand, 0xBA
.equ KingsRock, 0xBB
.equ SilverPowder, 0xBC
.equ AmuletCoin, 0xBD
.equ CleanseTag, 0xBE
.equ SoulDew, 0xBF
.equ DeepSeaTooth, 0xC0
.equ DeepSeaScale, 0xC1
.equ SmokeBall, 0xC2
.equ Everstone, 0xC3
.equ FocusBand, 0xC4
.equ LuckyEgg, 0xC5
.equ ScopeLens, 0xC6
.equ MetalCoat, 0xC7
.equ Leftovers, 0xC8
.equ DragonScale, 0xC9
.equ LightBall, 0xCA
.equ SoftSand, 0xCB
.equ HardStone, 0xCC
.equ MiracleSeed, 0xCD
.equ Blackglasses, 0xCE
.equ BlackBelt, 0xCF
.equ Magnet, 0xD0
.equ MysticWater, 0xD1
.equ SharpBeak, 0xD2
.equ PoisonBarb, 0xD3
.equ NeverMeltIce, 0xD4
.equ SpellTag, 0xD5
.equ TwistedSpoon, 0xD6
.equ Charcoal, 0xD7
.equ DragonFang, 0xD8
.equ SilkScarf, 0xD9
.equ UpGrade, 0xDA
.equ ShellBell, 0xDB
.equ SeaIncense, 0xDC
.equ MindIncense, 0xDD
.equ LuckyPunch, 0xDE
.equ MetalPowder, 0xDF
.equ ThickClub, 0xE0
.equ Stick, 0xE1
.equ SmoothRock, 0xE2
.equ IcyRock, 0xE3
.equ DampRock, 0xE4
.equ HeatRock, 0xE5
.equ WideLens, 0xE6
.equ LightClay, 0xE7
.equ PowerWeight, 0xE8
.equ PowerBracer, 0xE9
.equ PowerBelt, 0xEA
.equ PowerAnklet, 0xEB
.equ PowerLens, 0xEC
.equ PowerBand, 0xED
.equ BigNugget, 0xEE
.equ ShinyCharm, 0xEF
.equ RelicCrown, 0xF0
.equ RelicStatue, 0xF1
.equ RelicVase, 0xF2
.equ MicleBerry, 0xF3
.equ CustapBerry, 0xF4
.equ JabocaBerry, 0xF5
.equ RazorRang, 0xF6
.equ Eviolite, 0xF7
.equ FloatStone, 0xF8
.equ BindingVine, 0xF9
.equ IronBall, 0xFA
.equ CellBattery, 0xFB
.equ FlameOrb, 0xFC
.equ PixieOrb, 0xFD
.equ RedScarf, 0xFE
.equ BlueScarf, 0xFF
.equ PinkScarf, 0x100
.equ GreenScarf, 0x101
.equ YellowScarf, 0x102
.equ SnowCloak, 0x103
.equ CoinCase, 0x104
.equ ItemFinder, 0x105
.equ OldRod, 0x106
.equ GoodRod, 0x107
.equ SuperRod, 0x108
.equ SSPostcard, 0x109
.equ BowPostcard, 0x10A
.equ BooPostcard, 0x10B
.equ WailmerPail, 0x10C
.equ Suitcase, 0x10D
.equ ZapPostcard, 0x10E
.equ ClosetKey, 0x10F
.equ SunCloak, 0x110
.equ SandCloak, 0x111
.equ Letter, 0x112
.equ EonPostcard, 0x113
.equ Orb, 0x114
.equ SapphireEgg, 0x115
.equ RareBone, 0x116
.equ PearlEgg, 0x117
.equ Meteorite, 0x118
.equ PowPostcard, 0x119
.equ BronzeEgg, 0x11A
.equ SilverEgg, 0x11B
.equ GoldenEgg, 0x11C
.equ RubyEgg, 0x11D
.equ RootFossil, 0x11E
.equ ClawFossil, 0x11F
.equ FunPostcard, 0x120
.equ TM01, 0x121
.equ TM02, 0x122
.equ TM03, 0x123
.equ TM04, 0x124
.equ TM05, 0x125
.equ TM06, 0x126
.equ TM07, 0x127
.equ TM08, 0x128
.equ TM09, 0x129
.equ TM10, 0x12A
.equ TM11, 0x12B
.equ TM12, 0x12C
.equ TM13, 0x12D
.equ TM14, 0x12E
.equ TM15, 0x12F
.equ TM16, 0x130
.equ TM17, 0x131
.equ TM18, 0x132
.equ TM19, 0x133
.equ TM20, 0x134
.equ TM21, 0x135
.equ TM22, 0x136
.equ TM23, 0x137
.equ TM24, 0x138
.equ TM25, 0x139
.equ TM26, 0x13A
.equ TM27, 0x13B
.equ TM28, 0x13C
.equ TM29, 0x13D
.equ TM30, 0x13E
.equ TM31, 0x13F
.equ TM32, 0x140
.equ TM33, 0x141
.equ TM34, 0x142
.equ TM35, 0x143
.equ TM36, 0x144
.equ TM37, 0x145
.equ TM38, 0x146
.equ TM39, 0x147
.equ TM40, 0x148
.equ TM41, 0x149
.equ TM42, 0x14A
.equ TM43, 0x14B
.equ TM44, 0x14C
.equ TM45, 0x14D
.equ TM46, 0x14E
.equ TM47, 0x14F
.equ TM48, 0x150
.equ TM49, 0x151
.equ TM50, 0x152
.equ HM01, 0x153
.equ HM02, 0x154
.equ HM03, 0x155
.equ HM04, 0x156
.equ HM05, 0x157
.equ HM06, 0x158
.equ HM07, 0x159
.equ HM08, 0x15A
.equ AmethystEgg, 0x15B
.equ GarnetEgg, 0x15C
.equ Package, 0x15D
.equ LostFlute, 0x15E
.equ FocusSash, 0x15F
.equ BikePostcard, 0x160
.equ ToxicOrb, 0x161
.equ OldAmber, 0x162
.equ SandIncense, 0x163
.equ RockyHelmet, 0x164
.equ HelixFossil, 0x165
.equ DomeFossil, 0x166
.equ ShedShell, 0x167
.equ Bicycle, 0x168
.equ TownMap, 0x169
.equ RainCloak, 0x16A
.equ OddIncense, 0x16B
.equ TMCase, 0x16C
.equ BerryPouch, 0x16D
.equ SheepyTV, 0x16E
.equ TriPostcard, 0x16F
.equ PictureBook, 0x170
.equ Snowball, 0x171
.equ MysticTicket, 0x172
.equ PoryPhone, 0x173
.equ WiseGlasses, 0x174
.equ Ruby, 0x175
.equ Sapphire, 0x176
.equ QuiverDance, 0x1
.equ KarateChop, 0x2
.equ DoubleSlap, 0x3
.equ CometPunch, 0x4
.equ MegaPunch, 0x5
.equ PayDay, 0x6
.equ FirePunch, 0x7
.equ IcePunch, 0x8
.equ Thunderpunch, 0x9
.equ Scratch, 0xA
.equ ViceGrip, 0xB
.equ Guillotine, 0xC
.equ RazorWind, 0xD
.equ SwordsDance, 0xE
.equ Cut, 0xF
.equ Gust, 0x10
.equ WingAttack, 0x11
.equ Whirlwind, 0x12
.equ Fly, 0x13
.equ Bind, 0x14
.equ Slam, 0x15
.equ VineWhip, 0x16
.equ Stomp, 0x17
.equ DoubleKick, 0x18
.equ MegaKick, 0x19
.equ JumpKick, 0x1A
.equ RollingKick, 0x1B
.equ SandAttack, 0x1C
.equ Headbutt, 0x1D
.equ HornAttack, 0x1E
.equ FuryAttack, 0x1F
.equ DragonRush, 0x20
.equ Tackle, 0x21
.equ BodySlam, 0x22
.equ Wrap, 0x23
.equ TakeDown, 0x24
.equ Thrash, 0x25
.equ DoubleEdge, 0x26
.equ TailWhip, 0x27
.equ PoisonSting, 0x28
.equ Twineedle, 0x29
.equ PinMissisle, 0x2A
.equ Leer, 0x2B
.equ Bite, 0x2C
.equ Growl, 0x2D
.equ Roar, 0x2E
.equ Sing, 0x2F
.equ Supersonic, 0x30
.equ SonicBoom, 0x31
.equ Disable, 0x32
.equ Acid, 0x33
.equ Ember, 0x34
.equ Flamethrower, 0x35
.equ Mist, 0x36
.equ WaterGun, 0x37
.equ HydroPump, 0x38
.equ Surf, 0x39
.equ IceBeam, 0x3A
.equ Blizzard, 0x3B
.equ Psybeam, 0x3C
.equ BubbleBeam, 0x3D
.equ AuroraBeam, 0x3E
.equ HyperBeam, 0x3F
.equ Peck, 0x40
.equ DrillPeck, 0x41
.equ Recycle, 0x42
.equ LowKick, 0x43
.equ Counter, 0x44
.equ SeismicToss, 0x45
.equ Strength, 0x46
.equ Absorb, 0x47
.equ MegaDrain, 0x48
.equ LeechSeed, 0x49
.equ Growth, 0x4A
.equ RazorLeaf, 0x4B
.equ SolarBeam, 0x4C
.equ Poisonpowder, 0x4D
.equ StunSpore, 0x4E
.equ SleepPowder, 0x4F
.equ PetalDance, 0x50
.equ StringShot, 0x51
.equ Snatch, 0x52
.equ FireSpin, 0x53
.equ Thundershock, 0x54
.equ Thunderbolt, 0x55
.equ ThunderWave, 0x56
.equ Thunder, 0x57
.equ RockThrow, 0x58
.equ Earthquake, 0x59
.equ Fissure, 0x5A
.equ Dig, 0x5B
.equ Toxic, 0x5C
.equ Confusion, 0x5D
.equ Psychic, 0x5E
.equ Hypnosis, 0x5F
.equ Meditate, 0x60
.equ Agility, 0x61
.equ QuickAttack, 0x62
.equ Rage, 0x63
.equ Teleport, 0x64
.equ NightShade, 0x65
.equ Mimic, 0x66
.equ Screech, 0x67
.equ DoubleTeam, 0x68
.equ Recover, 0x69
.equ Harden, 0x6A
.equ Minimize, 0x6B
.equ Smokescreen, 0x6C
.equ ConfuseRay, 0x6D
.equ Withdraw, 0x6E
.equ DefenseCurl, 0x6F
.equ Barrier, 0x70
.equ LightScreen, 0x71
.equ Haze, 0x72
.equ Reflect, 0x73
.equ IceBurn, 0x74
.equ OminousWind, 0x75
.equ Metronome, 0x76
.equ MirrorMove, 0x77
.equ PowerGem, 0x78
.equ EggBomb, 0x79
.equ Lick, 0x7A
.equ Smog, 0x7B
.equ Sludge, 0x7C
.equ BoneClub, 0x7D
.equ FireBlast, 0x7E
.equ Waterfall, 0x7F
.equ Clamp, 0x80
.equ Swift, 0x81
.equ SkullBash, 0x82
.equ SpikeCannon, 0x83
.equ Constrict, 0x84
.equ Amnesia, 0x85
.equ Kinesis, 0x86
.equ SoftBoiled, 0x87
.equ HiJumpKick, 0x88
.equ Glare, 0x89
.equ DreamEater, 0x8A
.equ PoisonGas, 0x8B
.equ Barrage, 0x8C
.equ LeechLife, 0x8D
.equ LovelyKiss, 0x8E
.equ SkyAttack, 0x8F
.equ Transform, 0x90
.equ Bubble, 0x91
.equ DizzyPunch, 0x92
.equ Spore, 0x93
.equ SwitchMove, 0x94
.equ SkillSwap, 0x95
.equ PoisonJab, 0x96
.equ AcidArmor, 0x97
.equ Crabhammer, 0x98
.equ SeedBomb, 0x99
.equ FurySwipes, 0x9A
.equ Bonemerang, 0x9B
.equ Rest, 0x9C
.equ RockSlide, 0x9D
.equ HyperFang, 0x9E
.equ Sharpen, 0x9F
.equ Conversion, 0xA0
.equ TriAttack, 0xA1
.equ SuperFang, 0xA2
.equ Slash, 0xA3
.equ Substitute, 0xA4
.equ Struggle, 0xA5
.equ Sketch, 0xA6
.equ TripleKick, 0xA7
.equ Thief, 0xA8
.equ SpiderWeb, 0xA9
.equ MindReader, 0xAA
.equ Nightmare, 0xAB
.equ FlameWheel, 0xAC
.equ Snore, 0xAD
.equ Curse, 0xAE
.equ Flail, 0xAF
.equ Conversion2, 0xB0
.equ Aeroblast, 0xB1
.equ CottonGuard, 0xB2
.equ Reversal, 0xB3
.equ Spite, 0xB4
.equ PowderSnow, 0xB5
.equ Protect, 0xB6
.equ MachPunch, 0xB7
.equ ScaryFace, 0xB8
.equ FeintAttack, 0xB9
.equ SweetKiss, 0xBA
.equ BellyDrum, 0xBB
.equ SludgeBomb, 0xBC
.equ MudSlap, 0xBD
.equ Octazooka, 0xBE
.equ Spikes, 0xBF
.equ ZapCannon, 0xC0
.equ Moonblast, 0xC1
.equ DestinyBond, 0xC2
.equ PerishSong, 0xC3
.equ IcyWind, 0xC4
.equ Detect, 0xC5
.equ BoneRush, 0xC6
.equ LockOn, 0xC7
.equ Outrage, 0xC8
.equ Sandstorm, 0xC9
.equ GigaDrain, 0xCA
.equ Endure, 0xCB
.equ Charm, 0xCC
.equ Rollout, 0xCD
.equ FalseSwipe, 0xCE
.equ Swagger, 0xCF
.equ MilkDrink, 0xD0
.equ Spark, 0xD1
.equ FuryCutter, 0xD2
.equ SteelWing, 0xD3
.equ MeanLook, 0xD4
.equ Attract, 0xD5
.equ SleepTalk, 0xD6
.equ HealBell, 0xD7
.equ Return, 0xD8
.equ Present, 0xD9
.equ Roost, 0xDA
.equ Safeguard, 0xDB
.equ PainSplit, 0xDC
.equ SacredFire, 0xDD
.equ Magnitude, 0xDE
.equ DynamicPunch, 0xDF
.equ Megahorn, 0xE0
.equ Dragonbreath, 0xE1
.equ BatonPass, 0xE2
.equ Encore, 0xE3
.equ Pursuit, 0xE4
.equ RapidSpin, 0xE5
.equ SweetScent, 0xE6
.equ IronTail, 0xE7
.equ MetalClaw, 0xE8
.equ VitalThrow, 0xE9
.equ MorningSun, 0xEA
.equ Synthesis, 0xEB
.equ Moonlight, 0xEC
.equ HiddenPower, 0xED
.equ CrossChop, 0xEE
.equ Twister, 0xEF
.equ RainDance, 0xF0
.equ SunnyDay, 0xF1
.equ Crunch, 0xF2
.equ MirrorCoat, 0xF3
.equ PsychUp, 0xF4
.equ Extremespeed, 0xF5
.equ Ancientpower, 0xF6
.equ ShadowBall, 0xF7
.equ FutureSight, 0xF8
.equ RockSmash, 0xF9
.equ Whirlpool, 0xFA
.equ BeatUp, 0xFB
.equ FakeOut, 0xFC
.equ Uproar, 0xFD
.equ Stockpile, 0xFE
.equ SpitUp, 0xFF
.equ Swallow, 0x100
.equ HeatWave, 0x101
.equ Hail, 0x102
.equ Torment, 0x103
.equ Flatter, 0x104
.equ WillOWisp, 0x105
.equ FlameCharge, 0x106
.equ Facade, 0x107
.equ FocusPunch, 0x108
.equ Smellingsalt, 0x109
.equ DracoMeteor, 0x10A
.equ NaturePower, 0x10B
.equ Charge, 0x10C
.equ CrossPoison, 0x10D
.equ DazzleGleam, 0x10E
.equ Trick, 0x10F
.equ EarthPower, 0x110
.equ Wish, 0x111
.equ Assist, 0x112
.equ Ingrain, 0x113
.equ Superpower, 0x114
.equ MagicCoat, 0x115
.equ XScissor, 0x116
.equ Revenge, 0x117
.equ BrickBreak, 0x118
.equ Yawn, 0x119
.equ KnockOff, 0x11A
.equ Endeavor, 0x11B
.equ Eruption, 0x11C
.equ LightOfRuin, 0x11D
.equ DrainKiss, 0x11E
.equ Refresh, 0x11F
.equ Grudge, 0x120
.equ FairyWind, 0x121
.equ SecretPower, 0x122
.equ Dive, 0x123
.equ ArmThrust, 0x124
.equ Camouflage, 0x125
.equ TailGlow, 0x126
.equ LusterPurge, 0x127
.equ MistBall, 0x128
.equ Featherdance, 0x129
.equ TeeterDance, 0x12A
.equ BlazeKick, 0x12B
.equ ShadowClaw, 0x12C
.equ IceBall, 0x12D
.equ NeedleArm, 0x12E
.equ SlackOff, 0x12F
.equ HyperVoice, 0x130
.equ PoisonFang, 0x131
.equ CrushClaw, 0x132
.equ BlastBurn, 0x133
.equ HydroCannon, 0x134
.equ MeteorMash, 0x135
.equ Astonish, 0x136
.equ WeatherBall, 0x137
.equ Aromatherapy, 0x138
.equ FakeTears, 0x139
.equ AirSlash, 0x13A
.equ Overheat, 0x13B
.equ PlayRough, 0x13C
.equ RockTomb, 0x13D
.equ SilverWind, 0x13E
.equ MetalSound, 0x13F
.equ Grasswhistle, 0x140
.equ Tickle, 0x141
.equ CosmicPower, 0x142
.equ WaterSpout, 0x143
.equ SignalBeam, 0x144
.equ ShadowPunch, 0x145
.equ Extrasensory, 0x146
.equ SkyUppercut, 0x147
.equ SandTomb, 0x148
.equ SheerCold, 0x149
.equ MuddyWater, 0x14A
.equ BulletSeed, 0x14B
.equ AerialAce, 0x14C
.equ IcicleSpear, 0x14D
.equ IronDefense, 0x14E
.equ Block, 0x14F
.equ Howl, 0x150
.equ DragonClaw, 0x151
.equ FrenzyPlant, 0x152
.equ BulkUp, 0x153
.equ Bounce, 0x154
.equ MudShot, 0x155
.equ PoisonTail, 0x156
.equ Covet, 0x157
.equ VoltTackle, 0x158
.equ MagicalLeaf, 0x159
.equ Scald, 0x15A
.equ CalmMind, 0x15B
.equ LeafBlade, 0x15C
.equ DragonDance, 0x15D
.equ RockBlast, 0x15E
.equ ShockWave, 0x15F
.equ WaterPulse, 0x160
.equ DoomDesire, 0x161
.equ PsychoBoost, 0x162
.equ Normal, 0x0
.equ Fighting, 0x1
.equ Flying, 0x2
.equ Poison, 0x3
.equ Ground, 0x4
.equ Rock, 0x5
.equ Bug, 0x6
.equ Ghost, 0x7
.equ Steel, 0x8
.equ Fairy, 0x9
.equ Fire, 0xA
.equ Water, 0xB
.equ Grass, 0xC
.equ Electric, 0xD
.equ Psychic, 0xE
.equ Ice, 0xF
.equ Dragon, 0x10
.equ Dark, 0x11
.macro Pointer Address
.word \Address
.endm
.equ ROM, 0x8000000
.equ Offset, 0x
.org 0x1D9BF4, 0xFF
Pointer MoveCheck + ROM
.org 0x1D9C97, 0xFF
Pointer WonderGuardCheck + ROM
.org 0x1D9D2F, 0xFF
Pointer DampCheck + ROM
.org 0x1D9D35, 0xFF
Pointer DreamEaterCheck + ROM
.org 0x1D9DAD, 0xFF
Pointer OHKO + ROM
.org 0x1D9E31, 0xFF
Pointer ParalyseCheck + ROM
.org 0x1D9ECD, 0xFF
Pointer MagnitudeCheck + ROM
.org 0x1DA44D, 0xFF
Pointer AbsorbCheck + ROM
.org 0x1DA459, 0xFF
Pointer DreamEaterCheck2 + ROM
.org Offset, 0xFF
AbsorbCheck:
JumpIfDamageBonusEquals 0x0 0x14 0x81DA749
JumpIfDamageBonusEquals 0x0 0xA 0x81DA749
Jump 0x81DA751
.org Offset+0x13, 0xFF
DreamEaterCheck2:
JumpIfDamageBonusEquals 0x0 0xA 0x81DA7C1
JumpIfDamageBonusEquals 0x0 0x14 0x81DA7C1
Jump 0x81DA7C3
.org Offset+0x26, 0xFF
MoveCheck:
GetPowerOfStrongestMove
JumpIfByteEquals 0x0 0x81D9CE0
JumpIfDamageBonusEquals 0x0 0x0 0x81DA433
GetAbility Defender
JumpIfByteEquals 0xA 0x81D9CA6
JumpIfByteEquals 0xB 0x81D9CB3
JumpIfByteEquals 0x12 0x81D9CC0
JumpIfByteEquals 0x19 0x81D9CCD
JumpIfByteEquals 0x1A 0x81D9CD8
Jump 0x81D9CE0
.org Offset+0x59, 0xFF
WonderGuardCheck:
JumpIfDamageBonusEquals 0x0 0x50 0x81D9CE0
Jump 0x81DA433
.org Offset+0x65, 0xFF
DampCheck:
JumpIfDamageBonusEquals 0x0 0x0 0x81DA433
GetAbility Defender
JumpIfByteEquals 0x6 0x81DA433
CountViablePokemonOnTeam Attacker
JumpIfByteNotEqual 0x0 0x81D9FF2
CountViablePokemonOnTeam Defender
JumpIfByteNotEqual 0x0 0x81DA433
Jump 0x81DA424
ReturnToBattle
.org Offset+0x8A, 0xFF
DreamEaterCheck:
JumpIfStatus1NotEqual Defender 0x7 0x81DA430
JumpIfDamageBonusEquals 0x0 0x0 0x81DA433
ReturnToBattle
.org Offset+0x9C, 0xFF
OHKO:
JumpIfDamageBonusEquals 0x0 0x0 0x81DA433
GetAbility Defender
JumpIfByteEquals 0x5 0x81DA433
JumpIfBattlerLevelsAre 0x1 0x81DA433
ReturnToBattle
.org Offset+0xB2, 0xFF
MagnitudeCheck:
GetAbility Defender
JumpIfByteEquals 0x1A 0x81DA433
JumpIfDamageBonusEquals 0x0 0x0 0x81DA433
GetAbility Defender
JumpIfByteNotEqual 0x19 0x81DA1CB
JumpIfDamageBonusEquals 0x0 0x50 0x81DA1CB
Jump 0x81DA433
.org Offset+0xD5, 0xFF
ParalyseCheck:
JumpIfDamageBonusEquals 0x0 0x0 0x81DA433
GetAbility Defender
JumpIfByteEquals 0x7 0x81DA433
JumpIfStatus1Equals Defender 0xFF 0x81DA433
ReturnToBattle
.org 0xFFFFFF, 0xFF
.byte 0xFF - Go to the part that says ".equ Offset, 0x" and add after the 0x the offset of some free space. You will need 0xEF (239) bytes worth.
- Compile to a binary file with your favourite THUMB compiler.
- Create an ips patch by using the blank file as the unmodified file and your new binary file as the modified one.
- Now you can patch a FireRed ROM with it.
Documents
Since I keep updating this because I either add new commands or update old ones, I decided it would be way easier to have a Google Doc with all the information on it. It's easier for me to update that.
There are three. The first is the command description list. Please note that these descriptions are of the updated commands. So if a command was rewritten or updated, the rewritten/updated version is used. It also includes descriptions of new commands.
The second is a folder that has all the rewritten command routines in it.
The third is another folder that has all the new command routines in it.
Links
1. AI Command Descriptions
2. Rewritten Commands
3. New Commands
Callasm Command
I am putting this command separately because it is a big deal. With it, you can have as many commands as you need regardless of how big or small your command table is. You can literally use this to do pretty much anything you want.
The syntax looks like this
Callasm OFFSET + 1
Arguments for asm routine
Put the arguments for the command (if any) immediately after the pointer to the command routine. Then, just format the routine as if it were a normal command called from the table. The AI Cursor is updated in the routine it calls, so you can have as many or as little arguments as you need.
Spoiler:
/*Put XX XX XX 08 at 0x3F5664*/
.text
.align 2
.thumb
.thumb_func
Main:
push {r4, lr}
ldr r4, .AICursor
ldr r3, [r4]
add r3, r3, #0x4
str r3, [r4]
sub r3, r3, #0x4
ldrb r1, [r3, #0x1]
ldrb r0, [r3, #0x2]
lsl r0, r0, #0x8
orr r1, r0
ldrb r0, [r3, #0x3]
lsl r0, r0, #0x10
orr r1, r0
ldrb r0, [r3, #0x4]
lsl r0, r0, #0x18
orr r1, r0
bl DoRoutine
pop {r4}
pop {r0}
bx r0
DoRoutine:
bx r1
.align 2
.AICursor: .word 0x02039A00
.text
.align 2
.thumb
.thumb_func
Main:
push {r4, lr}
ldr r4, .AICursor
ldr r3, [r4]
add r3, r3, #0x4
str r3, [r4]
sub r3, r3, #0x4
ldrb r1, [r3, #0x1]
ldrb r0, [r3, #0x2]
lsl r0, r0, #0x8
orr r1, r0
ldrb r0, [r3, #0x3]
lsl r0, r0, #0x10
orr r1, r0
ldrb r0, [r3, #0x4]
lsl r0, r0, #0x18
orr r1, r0
bl DoRoutine
pop {r4}
pop {r0}
bx r0
DoRoutine:
bx r1
.align 2
.AICursor: .word 0x02039A00
Macros
The final gift I would like to impart on the masses at Pokecommunity is this. I've created a few macros to use to help compile scripts.
The link to view all of them is here.
The way to use them is to include the relevant macros at the top of the script (and by that I mean copy and paste them into the beginning of your script), and then just type the script using this sort of form:
.equ ROM, 0x8
Main:
JumpIfMoveScriptEquals 0x1 CauseSleep+ROM
ReturnToBattle
CauseSleep:
JumpIfStatus1Equals Defender 0x000000FF Decrease32+ROM
ReturnToBattle
Decrease32:
AddToViabilityScore 0xE0
ReturnToBattle
That way, you can just compile this with any sort of THUMB assembler. Remember to put the offset that you're inserting the script at after the ".equ ROM, 0x8". If you don't the pointers in your script will be all wrong.
I recommend
Conclusion
This thread is the culmination of over five months worth of research and work. My hope with all of this is to give ROM hackers the ability to truly customize the AI. This can be used not just to raise the difficulty/challenge of games, but also to add support to the ever-growing list of new moves and abilities being added to the gen III games.
Last edited: