• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Complete FireRed Upgrade: Creating Custom Moves

12
Posts
3
Years
Note: I won't include making Move Animations in this tutorial. If you want to get familiar with Move Animations, check out this thread:
https://www.pokecommunity.com/showthread.php?t=385321

Okay! Now, I've been using the CFRU for about half a year, and have gotten pretty used to it. At first, I struggled at even generating a test.gba :v, but now (thanks to Skeli and the members in the Unbound server), I have managed to code in my own custom moves and abilities. I know a lot of people using the CFRU would want to do the same, but have given up since they don't know much about coding and stuff. Just to tell you, I have no experience in C, Python, ASM, or anything like that, so you don't necessarily need programming skills to put in your moves.

Anyway, done with the intro stuff. I hope you enjoy this tutorial and do not have a hard time understanding the codes!

Step 1: Defining the moves and their data

A. Defining the move itself

Crack open include/constants/moves.h and scroll to the end of the file. Then define your own move below
Code:
#define MOVE_DRAGONENERGY 0x2E3

It should look something like this:
Code:
#define MOVE_DRAGONENERGY 0x2E3
#define MOVE_DARK_INFERNO 0x2E4

Then, replace the entire defines below with this:
Spoiler:

Change the value of MOVE_BREAKNECK_BLITZ_P = 0x2E5 to whatever yours might be (Usually the value next to your move) or don't if you've added only one move like me here.

Also, change MOVE_DRAGONENERGY in the last define to the name of your move, in my case, MOVE_DARK_INFERNO:

Code:
#define NON_Z_MOVE_COUNT   (MOVE_DARK_INFERNO + 1)

Be sure to define your move(s) in asm_defines.s as well, and don't bother about the enum thingy there as you won't probably be using the Max Moves in scripts anyway.
Feel free to delete the max moves' defines.

B. Adding their descriptions

Go to assembly/data/attack_description_table.s and add your own define below DESC_DRAGON_ENERGY:
Code:
.word DESC_DRAGON_ENERGY
.word DESC_DARK_INFERNO

Continue on to strings/attack_descriptions.string and add your description(s):
Code:
#org @DESC_DRAGON_ENERGY
The higher the\nuser's HP, the\nmore powerful this\nattack becomes.

#org @DESC_DARK_INFERNO
The user causes a\nmassive fire using\nits Dark power. It\nmay burn the foe or\nmake it flinch.

Also, add the move's name in strings/attack_name_table.string:
Code:
#org @NAME_DRAGON_ENERGY
DragonEnergy

#org @NAME_DARK_INFERNO
Dark Inferno

Make sure that all these strings are exactly below Dragon Energy's or it will cause problems with the game.

Step 2: Creating the move's data

Open src/tables/battle_moves.c and add the data for your move. It should be in this format.
Code:
	[MOVE_DRAGONENERGY] =
	{	//ANIM TODO
		.effect = EFFECT_HIT,
		.power = 40, //PLACEHOLDER DATA
		.type = TYPE_DRAGON,
		.accuracy = 100,
		.pp = 35,
		.secondaryEffectChance = 0,
		.target = MOVE_TARGET_SELECTED,
		.priority = 0,
		.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED,
		.z_move_power = 100,
		.split = SPLIT_SPECIAL,
		.z_move_effect = 0
	},

	[MOVE_DARK_INFERNO] =
	{
		.effect = EFFECT_FLINCH_HIT,
		.power = 100,
		.type = TYPE_FIRE,
		.accuracy = 90,
		.pp = 15,
		.secondaryEffectChance = 15,
		.target = MOVE_TARGET_SELECTED,
		.priority = 0,
		.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED,
		.split = SPLIT_PHYSICAL,
		.z_move_power = 180,
		.z_move_effect = 0
	}

As for the secondary effects, you can see those in include/constants/battle_move_effects.h.

Then, scroll down to the table gDynamaxMovePowers and add the power of your move's max move:
Code:
	[MOVE_DRAGONENERGY] = 100,
	[MOVE_DARK_INFERNO] = 130,

Step 3: Creating the move's effect

Here comes the difficult part. Well, it won't be if you aren't creating your own move effect, but anyway, let's get started.

A. Making a move with 2 secondary effects

If you want two secondary effects to be added to your new move, then open up assembly/battle_scripts/general_attack_battle_scripts.s and scroll to the script of the move effect number (The indices are in include/constants/battle_move_effects.h)

In my case, I want the move to have an equal chance of burning and flinching, so I scroll to BS_031_Flinch:
If you'll notice, Fire Fang has the same effect as my new move, so I simply add:

Code:
.global BS_031_Flinch
BS_031_Flinch:
	setmoveeffect MOVE_EFFECT_FLINCH
	jumpifmove MOVE_THUNDERFANG ThunderFangBS
	jumpifmove MOVE_FIREFANG FireFangBS
	jumpifmove MOVE_ICEFANG IceFangBS 
	jumpifmove MOVE_DARK_INFERNO FireFangBS
	goto BS_STANDARD_HIT

This makes sure that if the move effect is EFFECT_FLINCH_HIT (which is effect number 31) and if the move being used is Dark Inferno, it will jump to the script of Fire Fang.
Now you may ask: Why FireFangBS? Well, it's because both my move and Fire Fang have the same move effect- Flinch and Burn.

B. Making a move that does dual-type damage

If you want to make a move that does dual-type damage (like Flying Press), then open up src/damage_calc.c and search for the line:
Code:
	if (move == MOVE_FLYINGPRESS && moveType != TYPE_FLYING)

Add your own move data below that line:
Code:
	if (move == MOVE_FLYINGPRESS && moveType != TYPE_FLYING)
	{
		moveType = TYPE_FLYING;
		goto TYPE_LOOP;
	}

	if (move == MOVE_DARK_INFERNO && moveType != TYPE_DARK)
	{
		moveType = TYPE_DARK;
		goto TYPE_LOOP;
	}

This makes sure that the move Dark Inferno does both Fire and Dark-type damage. Also, be sure to do the same in:
Code:
	if (move == MOVE_FLYINGPRESS && moveType != TYPE_FLYING)
	{
		moveType = TYPE_FLYING;
		goto TYPE_LOOP_AI;
	}
by changing that to:

Code:
	if (move == MOVE_FLYINGPRESS && moveType != TYPE_FLYING)
	{
		moveType = TYPE_FLYING;
		goto TYPE_LOOP_AI;
	}

	if (move == MOVE_DARK_INFERNO && moveType != TYPE_DARK)
	{
		moveType = TYPE_DARK;
		goto TYPE_LOOP_AI;
	}

This makes sure that the move's dual-type damage occurs for the AI too.

C. Making a move that does Super-Effective damage against a certain type

If you want to make a move like Freeze-Dry that does Super-Effective damage against a certain type, stay on the file src/damage_calc.c and search for:
Code:
	if (move == MOVE_FREEZEDRY && defType == TYPE_WATER) //Always Super-Effective, even in Inverse Battles
		multiplier = TYPE_MUL_SUPER_EFFECTIVE;

Add your own code below:
Code:
	if (move == MOVE_FREEZEDRY && defType == TYPE_WATER) //Always Super-Effective, even in Inverse Battles
		multiplier = TYPE_MUL_SUPER_EFFECTIVE;

	else if (move == MOVE_DARK_INFERNO && defType == TYPE_FIGHTING) 
		multiplier = TYPE_MUL_SUPER_EFFECTIVE;

This makes it so that the move Dark Inferno is Super-Effective on Fighting-types too. Hopefully, you understand the codes and not be too confused by them.

D. Making a move that always results in a critical hit

If you want to make a Frost Breath like move, go to assembly/data/move_tables.s and search for gAlwaysCriticalMoves. Then add your own move below:
Code:
gAlwaysCriticalMoves:
.hword MOVE_STORMTHROW
.hword MOVE_FROSTBREATH
.hword MOVE_SURGINGSTRIKES
.hword MOVE_WICKEDBLOW
.hword MOVE_DARK_INFERNO
.hword MOVE_TABLES_TERMIN

There are many more such move tables that you might want to edit, so you might want to look at the tables. Simply add your own move to the table and you're gold.
I can't go on explaining how to add every move effect, so I covered only some major ones.

Step 4: Assigning the move animation to your move

As I've mentioned before, I won't be helping out with the move animations. I'll just mention how to assign them to your move. To do this, go to assembly/data/attack_anim_table.s
and add your animation below:
Code:
.word ANIM_DRAGON_ENERGY
.word ANIM_DARK_INFERNO

Make sure that the move animation is in order as that of the move strings.

Then, below the file, add something like:

Code:
.pool
ANIM_DARK_INFERNO:
(Your animation)

If you want to assign the move an animation of some other move, simply add in:

Code:
.pool
ANIM_DARK_INFERNO:
         goto ANIM_INFERNO
         endanimation

There are a lot of offsets on other animations on top of the file, so you can use them too if you want. For example:

Code:
.pool
ANIM_DARK_INFERNO:
         goto 0x81C7AF5 @Animation for Fire Blast given on top of the file
         endanimation

And... that's all! Clap for yourself if you actually read through all these and clap for yourself even more if you successfully added in your own move!
 
Last edited:
Back
Top