• 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.

[Other] [HELP] Make an Item that Uses Fly

247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
I've been trying to figure out a way to make each HM move work without a Pokemon on the player's team needing to know the move. I've more-or-less figured out how to go about this with most of the HMs, but Fly is a bit different from the rest. Since it's not a normal field-effect like the rest of the HMs, as the player usually needs to go into their party menu to use it, its code and application is a bit different, and I can't seem to make heads-or-tails of how to use it. Does anyone know how one could go about creating an item that, when used, goes through the normal Fly process?

Edit: I've compiled all of the information that was gathered in the later posts here, in case you just want to know how to make HM items.
Spoiler:
 
Last edited:
2
Posts
3
Years
  • Age 20
  • Seen Jun 11, 2020
Sorry I don't know but this is exactly what I about to try to do. How did you get the other ones working? I'm new to this and I'm not really sure where to begin.
 
247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
Sorry I don't know but this is exactly what I about to try to do. How did you get the other ones working? I'm new to this and I'm not really sure where to begin.

No problem, I can help you out! You'll want to look at data/scripts/surf.inc and data/scripts/field_move_scripts.inc. Across these two files, you can edit Surf, Cut, Rock Smash, Strength, Waterfall, and Dive. In every script for each of these moves, there's one important series of lines:
Code:
lockall
checkpartymove MOVE_<WHATEVER THE MOVE IS>
compare VAR_RESULT, PARTY_SIZE
goto_if_eq EventScript_Check<CAN'T USE MOVE>
setfieldeffectargument 0, VAR_RESULT
bufferpartymonnick 0, VAR_RESULT	
buffermovename 1, MOVE_<WHATERVER THE MOVE IS>
msgbox Text_WantTo<Use Move>, MSGBOX_YESNO
compare VAR_RESULT, NO
goto_if_eq EventScript_Cancel<Move>
msgbox Text_MonUsedFieldMove, MSGBOX_DEFAULT
closemessage
These lines handle checking to see if a Pokemon on the player's team has the proper move, and if so, displays the text that says "Pokemon used <Move>". All we have to do is change these lines to instead look for a specific item in the player's bag. If the player has it, then the move goes forward like normal. Otherwise, the game'll say the move can't be used. Let's say, for example, that I wanted the player to need a Potion in order to use Cut on a tree. This would be done in the first script of field_move_scripts.inc. This is how the first four lines after "lockall" of the script would look:
Code:
checkitem ITEM_POTION, 1
compare VAR_RESULT, FALSE
goto_if_eq EventScript_CheckTreeCantCut
setfieldeffectargument 0, ITEM_POTION
The command "checkitem" needs both the item index (the name of the item) and the quantity, which is why I added a 1 at the end. With this, as long as the player has at least 1 Potion, they will be able to cut down a tree. It also takes the Potion's index as a field-effect argument, which will be used later. The only problem is that the game also needs to get the Pokemon's nickname and sprite to display while doing the "Pokemon used Cut" animation. And we don't want that. So, the first thing we do is delete the following lines:
Code:
bufferpartymonnick 0, VAR_RESULT
buffermovename 1, MOVE_CUT
msgbox Text_MonUsedFieldMove, MSGBOX_DEFAULT
Deleting these lines makes sure that we aren't using the dialogue that normally appears when using cut.

Now we need to account for the sprite of the Pokemon that usually appears during the animation. For this, we're going to need to jump over to src/field_effect.c. Find this:
Code:
bool8 FldEff_FieldMoveShowMonInit(void)
{
    struct Pokemon *pokemon;
    u32 flag = gFieldEffectArguments[0] & 0x80000000;
    pokemon = &gPlayerParty[(u8)gFieldEffectArguments[0]];
    gFieldEffectArguments[0] = GetMonData(pokemon, MON_DATA_SPECIES);
    gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_OT_ID);
    gFieldEffectArguments[2] = GetMonData(pokemon, MON_DATA_PERSONALITY);
    gFieldEffectArguments[0] |= flag;
    FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON);
    FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
    return FALSE;
}
We're going to change it to this:
Code:
bool8 FldEff_FieldMoveShowMonInit(void)
{
	u32 flag = gFieldEffectArguments[0] & 0x80000000;
	gFieldEffectArguments[0] |= flag;
	FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON);
	FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
	return FALSE;
}
What we've done here is just deleted a huge chunk of the code that messes up the process. If you're nervous about comitting to this change, you can instead comment-out the code like this:
Code:
bool8 FldEff_FieldMoveShowMonInit(void)
{
    /*struct Pokemon *pokemon;
    u32 flag = gFieldEffectArguments[0] & 0x80000000;
    pokemon = &gPlayerParty[(u8)gFieldEffectArguments[0]];
    gFieldEffectArguments[0] = GetMonData(pokemon, MON_DATA_SPECIES);
    gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_OT_ID);
    gFieldEffectArguments[2] = GetMonData(pokemon, MON_DATA_PERSONALITY);*/
    gFieldEffectArguments[0] |= flag;
    FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON);
    FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
    return FALSE;
}
This way, in case you decide to go back to using HM moves instead of items, you can just undo this change.

At this point, the game will work as you have intended it: as long as the player has at least 1 Potion (and the first Gym Badge, but you can delete that check as well if you want), they can cut down a tree without any glitches. However, the animation will look a little strange, with a seemingly random Pokemon appearing. If you don't want that, the following changes will fix that.

First, at the top of field_effect.c, you'll see several instances of "#include". Add this to the end of that section:
Code:
#include "item_icon.h"
This will give us access to the "AddItemIconSprite" method that will be used in the next section of code.

The next thing we look for is this:
Code:
static u8 sub_80B8C60(u32 a0, u32 a1, u32 a2)
{
    u16 v0;
    u8 monSprite;
    struct Sprite *sprite;
    v0 = (a0 & 0x80000000) >> 16;
    a0 &= 0x7fffffff;
    monSprite = CreateMonSprite_FieldMove(a0, a1, a2, 0x140, 0x50, 0);
    sprite = &gSprites[monSprite];
    sprite->callback = SpriteCallbackDummy;
    sprite->oam.priority = 0;
    sprite->data[0] = a0;
    sprite->data[6] = v0;
    return monSprite;
}
We then change it to this:
Code:
static u8 sub_80B8C60(u32 a0, u32 a1, u32 a2)
{
    u16 v0;
    u8 monSprite;
    struct Sprite *sprite;
    v0 = (a0 & 0x80000000) >> 16;
    a0 &= 0x7fffffff;
    monSprite = AddItemIconSprite(2110,2110,a0);
    gSprites[monSprite].pos1.y = 0x50;
    gSprites[monSprite].pos1.x = 0x140;
    sprite = &gSprites[monSprite];
    sprite->callback = SpriteCallbackDummy;
    sprite->oam.priority = 0;
    sprite->data[0] = a0;
    sprite->data[6] = v0;
    return monSprite;
}
This makes the sprite that appears for the animation use the sprite of the item rather than the sprite of a Pokemon. This is where that setfieldargument line that we changed from the script comes into play, as a0 is equal to the item index of the Potion.

Immediately below that function is this one:
Code:
static void sub_80B8CC0(struct Sprite *sprite)
{
    if ((sprite->pos1.x -= 20) <= 0x78)
    {
        sprite->pos1.x = 0x78;
        sprite->data[1] = 30;
        sprite->callback = sub_80B8D04;
        if (sprite->data[6])
        {
            PlayCry2(sprite->data[0], 0, 0x7d, 0xa);
        }
        else
        {
            PlayCry1(sprite->data[0], 0);
        }
    }
}
The following change can vary depending on how you want to implement it. Changing this function will change the sound effect that is played during the animation. Normally, the Pokemon's cry is played. We aren't using a Pokemon anymore, though. Currently, this is the change that I've made:
Code:
static void sub_80B8CC0(struct Sprite *sprite)
{
    if ((sprite->pos1.x -= 20) <= 0x78)
    {
        sprite->pos1.x = 0x78;
        sprite->data[1] = 30;
        sprite->callback = sub_80B8D04;
	PlaySE(SE_KAIFUKU);
    }
}
This change makes it so that the Potion healing sound effect plays during the animation, which I specifically chose since you're using a Potion to cut a tree. The only problem with this is that every single time an HM move is used, no matter what item is required, it will always play that same sound effect. If you want it to change depending on which item is being used, you'll want to make a switch statement, where you compare sprite->data[0] to whatever item it is that the player is using. For example, say you wanted the Potion sound effect to be used when a Potion is used, and the Bicycle Bell sound effect to be used when a Pokeball is used. Here's what it would look like:
Code:
static void sub_80B8CC0(struct Sprite *sprite)
{
    if ((sprite->pos1.x -= 20) <= 0x78)
    {
        sprite->pos1.x = 0x78;
        sprite->data[1] = 30;
        sprite->callback = sub_80B8D04;
	switch(sprite->data[0])
	{
	case 4:
		PlaySE(SE_JITENSYA);
		break;
	case 28:
		PlaySE(SE_KAIFUKU);
		break;
	}
    }
}
The numbers used for the cases in the switch statement are unique to each item. The names used in PlaySE are unique to each sound effect. You can find the values for each item in include/constants/items.h, and you can find the names for each sound effect in include/constants/songs.h.

And with that, you're done! You've got Cut (when being used on trees) to work as long as the player is holding a Potion! If you want to change which item is required for each HM move, you'll have to go through data/scripts/field_move_scripts.inc and data/scripts/surf.inc and make similar changes to each HM's script. You only need to do most of the stuff in field_effect.c once, as it applies to all HM move animations and sound effects. The one thing you may need to go back to and change is if you want to add more sound effects. In that case, you just add more cases in that last switch statement. If you have any questions or errors when applying this, just let me know, and I'll try to help you out.

Even with all of this, however, I can't get Fly to work in the same way, since Fly is not technically an overworld event. It only occurs when the player goes into their party menu, selects a Pokemon that knows Fly, and then chooses Fly from the list that appears. This process follows a very different set of procedures, and I have yet to get it to work with an item. If someone can figure out how to get it to work, I'd be more than happy to see how it's done.
 
Last edited:
2
Posts
3
Years
  • Age 20
  • Seen Jun 11, 2020
Thanks. I'm using pokefirered instead of emerald but your instructions were very clear and I was able to get it working (I only tested cut but I did the same thing for everything but flash and fly so it should work).
I also figured out how to get fly working (once again firered not emerald) but the sprite and cry still use the first pokemon in your party. I haven't even tried to fix this yet so I'm not sure how hard it would be.

The first thing I did is make a new item called FLY (for the others I used things like surfboard and scuba gear but I can't think of anything good for fly and waterfall) by editing both include/constants/item.h and src/data/item.h
In include/constants/item.h I just changed one of the unused item definitions:
Code:
#define ITEM_F1 241
to
Code:
#define ITEM_FLY 241

and in src/data/item.h I edited the matching code for the same unused item:
Code:
{
        .name = _("????????"),
        .itemId = ITEM_NONE,
        .price = 0,
        .holdEffect = HOLD_EFFECT_NONE,
        .holdEffectParam = 0,
        .description = gItemDescription_ITEM_NONE,
        .importance = 0,
        .exitsBagOnUse = 0,
        .pocket = POCKET_ITEMS,
        .type = 4,
        .fieldUseFunc = FieldUseFunc_OakStopsYou,
        .battleUsage = 0,
        .battleUseFunc = NULL,
        .secondaryId = 0
},
to
Code:
{
        .name = _("FLY"),
        .itemId = ITEM_FLY,
        .price = 0,
        .holdEffect = HOLD_EFFECT_NONE,
        .holdEffectParam = 0,
        .description = gItemDescription_ITEM_FLY,
        .importance = 1,
        .exitsBagOnUse = 0,
        .pocket = POCKET_KEY_ITEMS,
        .type = 4,
        .fieldUseFunc = FieldUseFunc_Fly,
        .battleUsage = 0,
        .battleUseFunc = NULL,
        .secondaryId = 0
},
and added the description near the top of the file with the others
Code:
const u8 gItemDescription_ITEM_FLY[] = _("Fly to anywhere you have\nalready been.");

and then I went to src/item_use.c and created the FieldUseFunc_Fly function:
Code:
void FieldUseFunc_Fly(u8 taskId)
{
    ItemMenu_SetExitCallback(CB2_OpenFlyMap);
    ItemMenu_StartFadeToExitCallback(taskId);
}
which sets the callback function of ItemMenu to the same callback function used in party_menu.c which is what normally calls fly when you choose the move from a pokemon. It then calls the callback function with ItemMenu_StartFadeToExitCallback(taskId);

This allows fly to be used by going to the key items pocket and using the FLY item. As I said earlier the sprite and cry are still used from the first pokemon in your party. This can probably be changed in scr/region_map.c as that is where CB2_OpenFlyMap is defined. A similar process would probably also be used for flash but I haven't tried it yet.
 
247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
Thanks for that bit of code! For those that are using Pokeemerald, it'll look a bit more like this:
Code:
void FieldUseFunc_Fly(u8 taskId)
{
    gBagMenu->mainCallback2 = CB2_OpenFlyMap;
    Task_FadeAndCloseBagMenu(taskId);
}
I also added a bit more, making it work more like a normal item and like the normal Fly process:
Code:
void ItemUseOutOfBattle_Bird(u8 taskId)
{
	if(Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType) == TRUE)
	{
		gSaveBlock2Ptr->ItemArg = 112;
		if(!gTasks[taskId].tUsingRegisteredKeyItem)
		{
			gBagMenu->mainCallback2 = CB2_OpenFlyMap;
			Task_FadeAndCloseBagMenu(taskId);
		}
		else
		{
			SetMainCallback2(CB2_OpenFlyMap);
			DestroyTask(taskId);
		}
	}
	else
		DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);
}
With this code, if the player is in an area where they can't use Fly, they'll get the "There's a time and place for everything" message. Otherwise, it then checks to see if the player is using the Fly item as a registered item. If not, it fades out into the Fly map. If the item is being used as a registered item, it immediately goes to the Fly map.

In regard to the Pokemon sprite and cry still being used, I fixed that. You may notice that I added "gSaveBlock2Ptr->ItemArg" in the previous code segment. This is the variable I use to make sure the correct sprite and sound effect are used. In each of the functions that I changed in my previous post, change every instance of "gFieldEffectArguments[0]" to "gSaveBlock2Ptr->ItemArg". You will also need to change this method:
Code:
bool8 FldEff_FieldMoveShowMon(void)
{
    u8 taskId;
    if (IsMapTypeOutdoors(GetCurrentMapType()) == TRUE)
    {
        taskId = CreateTask(sub_80B8554, 0xff);
    } else
    {
        taskId = CreateTask(sub_80B88B4, 0xff);
    }
    gTasks[taskId].data[15] = sub_80B8C60(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
    return FALSE;
}
Change the "gFieldEffectArguments[0]" to "gSaveBlock2Ptr->ItemArg". Lastly, go to include/global.h and add this:
Code:
struct SaveBlock2
{
.......................
u16 ItemArg;
}; // sizeof=0xF2C
This variable is used to hold the value for whatever item is being used. The reason I did this rather than just using gFieldEffectArguments[0] like before is because of Cut. If you were to use Cut while standing in grass with the previous code I had written, you would get an incorrect sprite and no cry. This is because the game goes through a specific process that uses gFieldEffectArguments[0] when the player stands in grass, thus changing the value of that variable. With ItemArg, we don't have to worry about that. All you need to do is assign ItemArg whatever value your item is during your ItemUseOutOfBattle process (my Fly item's value is 112), and you should get the correct sprite and sound effect showing up. Hopefully that helps! Again, thanks Seldon2066 for that Fly code!
 
Last edited:
4
Posts
3
Years
  • Age 33
  • Seen Aug 19, 2022
Just want to say thanks for posting this code. I appreciate all the hard work you put in to doing this.
 
247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
Just want to say thanks for posting this code. I appreciate all the hard work you put in to doing this.

I appreciate that! I figured there's no reason for everyone to keep needing to figure out this stuff, so I decided to write up what I did so that everyone else has an easier time. I've been helped by a lot of other users who have done the same, and I wanted to contribute to the mass of knowledge.
 
8
Posts
7
Years
  • Age 30
  • Seen Nov 12, 2022
Hey, when implementing:

static u8 sub_80B8C60(u32 a0, u32 a1, u32 a2)
{
u16 v0;
u8 monSprite;
struct Sprite *sprite;
v0 = (a0 & 0x80000000) >> 16;
a0 &= 0x7fffffff;
monSprite = AddItemIconSprite(2110,2110,a0);
gSprites[monSprite].pos1.y = 0x50;
gSprites[monSprite].pos1.x = 0x140;
sprite = &gSprites[monSprite];
sprite->callback = SpriteCallbackDummy;
sprite->oam.priority = 0;
sprite->data[0] = a0;
sprite->data[6] = v0;
return monSprite;
}

I get the error:
$ make -j4
arm-none-eabi-as -mcpu=arm7tdmi --defsym MODERN=0 -o build/emerald/src/fldeff_flash.o build/emerald/src/fldeff_flash.s
agbcc: warnings being treated as errors
src/field_effect.c: In function `sub_80B8C60':
src/field_effect.c:2805: warning: implicit declaration of function `AddItemIconSprite'
arm-none-eabi-as -mcpu=arm7tdmi --defsym MODERN=0 -o build/emerald/src/battle_transition.o build/emerald/src/battle_transition.s
make: *** [Makefile:255: build/emerald/src/field_effect.o] Fout 1


Not really have much experience with coding, but what do I need to do to include the AdditemIconSprite function?
Or did I forget to do something earlier in the process?
 

MysteryGift

disassembly tinkerer / pkmnubuntu dev
27
Posts
6
Years
"warning: implicit declaration of function 'AddItemIconSprite'" - you need to declare the function 'AddItemIconSprite'. The compiler gets to the line "monSprite = AddItemIconSprite(2110,2110,a0);" and does not understand what "AddItemIcon..." means.

I'm not sure how the function would need to be declared, but generally in C you declare functions the following way:

Spoiler:


somebody dear god correct me if I'm wrong - still learning!
 
247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
Hey, when implementing:

static u8 sub_80B8C60(u32 a0, u32 a1, u32 a2)
{
u16 v0;
u8 monSprite;
struct Sprite *sprite;
v0 = (a0 & 0x80000000) >> 16;
a0 &= 0x7fffffff;
monSprite = AddItemIconSprite(2110,2110,a0);
gSprites[monSprite].pos1.y = 0x50;
gSprites[monSprite].pos1.x = 0x140;
sprite = &gSprites[monSprite];
sprite->callback = SpriteCallbackDummy;
sprite->oam.priority = 0;
sprite->data[0] = a0;
sprite->data[6] = v0;
return monSprite;
}

I get the error:
$ make -j4
arm-none-eabi-as -mcpu=arm7tdmi --defsym MODERN=0 -o build/emerald/src/fldeff_flash.o build/emerald/src/fldeff_flash.s
agbcc: warnings being treated as errors
src/field_effect.c: In function `sub_80B8C60':
src/field_effect.c:2805: warning: implicit declaration of function `AddItemIconSprite'
arm-none-eabi-as -mcpu=arm7tdmi --defsym MODERN=0 -o build/emerald/src/battle_transition.o build/emerald/src/battle_transition.s
make: *** [Makefile:255: build/emerald/src/field_effect.o] Fout 1


Not really have much experience with coding, but what do I need to do to include the AdditemIconSprite function?
Or did I forget to do something earlier in the process?

Whoops! There's a single line that I forgot to add to the post. At the top of field_effect.c, where you see a lot of "#include", add this:
Code:
#include "item_icon.h"
The "AddItemIconSprite" method is defined in item_icon.h, so that should take care of that error for you. Thanks for posting that!
 
24
Posts
3
Years
  • Age 30
  • Seen Aug 30, 2021
I've got this thing happening where if I use say, rock smash first, then cut, the item for the rock smash will always be the one that comes up, and vice versa. I reload the map, it will be whichever item I used first.
 
247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
I've got this thing happening where if I use say, rock smash first, then cut, the item for the rock smash will always be the one that comes up, and vice versa. I reload the map, it will be whichever item I used first.

Ah, crap. I forgot to add my fix for this in this thread.

In src/field_effect.c, look for the methods "sub_80B8A64" and "overworld_bg_setup_2". In both of those methods, you'll see this line of code:
Code:
FreeResourcesAndDestroySprite(&gSprites[task->data[15]], task->data[15]);
Swap this line out for this:
Code:
FieldEffectFreeGraphicsResources(&gSprites[task->data[15]]);
. This will take care of that glitch. I'll add this to one of the earlier posts.

The reason this glitch shows up is because we aren't using Pokemon Sprites anymore, but random graphics. The original method is specifically designed to handle Pokemon Sprites, and since these graphics aren't Pokemon, the game just doesn't get rid of the first sprite that was loaded until the map itself is reloaded.
 
24
Posts
3
Years
  • Age 30
  • Seen Aug 30, 2021
Did you ever run into this issue?
BtUhywo.gif

Something similar happens when I use the bike
 
247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
Did you ever run into this issue?
BtUhywo.gif

Something similar happens when I use the bike

Nope, can't say I have. That is really bizarre. I saw that you posted this issue in a different thread. I would obviously suggest looking into any changes you've made to anything relating to graphics in the game and see if one of those changes caused this, but beyond that, I have no idea why that would happen. All of the changes that I've made from this HM-To-Item process doesn't mess with the player avatar at all, so I would sincerely doubt that the source of the problem is this particular hack.
 
24
Posts
3
Years
  • Age 30
  • Seen Aug 30, 2021
Alright, thanks for the reply. When I figure it out, I'll give an update in my thread
 
3
Posts
3
Years
  • Age 27
  • Seen Sep 19, 2021
Thanks for that bit of code! For those that are using Pokeemerald, it'll look a bit more like this:
Code:
void FieldUseFunc_Fly(u8 taskId)
{
    gBagMenu->mainCallback2 = CB2_OpenFlyMap;
    Task_FadeAndCloseBagMenu(taskId);
}
I also added a bit more, making it work more like a normal item and like the normal Fly process:
Code:
void ItemUseOutOfBattle_Bird(u8 taskId)
{
	if(Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType) == TRUE)
	{
		gSaveBlock2Ptr->ItemArg = 112;
		if(!gTasks[taskId].tUsingRegisteredKeyItem)
		{
			gBagMenu->mainCallback2 = CB2_OpenFlyMap;
			Task_FadeAndCloseBagMenu(taskId);
		}
		else
		{
			SetMainCallback2(CB2_OpenFlyMap);
			DestroyTask(taskId);
		}
	}
	else
		DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);
}
With this code, if the player is in an area where they can't use Fly, they'll get the "There's a time and place for everything" message. Otherwise, it then checks to see if the player is using the Fly item as a registered item. If not, it fades out into the Fly map. If the item is being used as a registered item, it immediately goes to the Fly map.

In regard to the Pokemon sprite and cry still being used, I fixed that. You may notice that I added "gSaveBlock2Ptr->ItemArg" in the previous code segment. This is the variable I use to make sure the correct sprite and sound effect are used. In each of the functions that I changed in my previous post, change every instance of "gFieldEffectArguments[0]" to "gSaveBlock2Ptr->ItemArg". You will also need to change this method:
Code:
bool8 FldEff_FieldMoveShowMon(void)
{
    u8 taskId;
    if (IsMapTypeOutdoors(GetCurrentMapType()) == TRUE)
    {
        taskId = CreateTask(sub_80B8554, 0xff);
    } else
    {
        taskId = CreateTask(sub_80B88B4, 0xff);
    }
    gTasks[taskId].data[15] = sub_80B8C60(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
    return FALSE;
}
Change the "gFieldEffectArguments[0]" to "gSaveBlock2Ptr->ItemArg". Lastly, go to include/global.h and add this:
Code:
struct SaveBlock2
{
.......................
u16 ItemArg;
}; // sizeof=0xF2C
This variable is used to hold the value for whatever item is being used. The reason I did this rather than just using gFieldEffectArguments[0] like before is because of Cut. If you were to use Cut while standing in grass with the previous code I had written, you would get an incorrect sprite and no cry. This is because the game goes through a specific process that uses gFieldEffectArguments[0] when the player stands in grass, thus changing the value of that variable. With ItemArg, we don't have to worry about that. All you need to do is assign ItemArg whatever value your item is during your ItemUseOutOfBattle process (my Fly item's value is 112), and you should get the correct sprite and sound effect showing up. Hopefully that helps! Again, thanks Seldon2066 for that Fly code!

does anyone know the new name of mainCallback2? i noticed some of the function names have changed since this post was made and i was able to figure what the new names of most of the functions were except mainCallback2.
 
247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
does anyone know the new name of mainCallback2? i noticed some of the function names have changed since this post was made and i was able to figure what the new names of most of the functions were except mainCallback2.

mainCallback2 is now exitCallback. You can see this by looking at an up-to-date repository's version of src/item_use.c and seeing whenever gBagMenu points at something to do with a callback, like in the function SetUpItemUseCallback.
 
3
Posts
3
Years
  • Age 27
  • Seen Sep 19, 2021
mainCallback2 is now exitCallback. You can see this by looking at an up-to-date repository's version of src/item_use.c and seeing whenever gBagMenu points at something to do with a callback, like in the function SetUpItemUseCallback.

when it went to that function it was using gBagMenu->newScreenCallback. i tried that here:
void ItemUseOutOfBattle_Bird(u8 taskId)
{
if (Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType) == TRUE)
{
gSaveBlock2Ptr->ItemArg = 607;
if (!gTasks[taskId].tUsingRegisteredKeyItem)
{
gBagMenu->newScreenCallback = CB2_OpenFlyMap;
Task_FadeAndCloseBagMenu(taskId);
}
else
{
SetMainCallback2(CB2_OpenFlyMap);
DestroyTask(taskId);
}
}
else
DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);
}

and was told "`CB2_OpenFlyMap' undeclared (first use in this function)". what did i miss in order to get Fly to work?
 
247
Posts
6
Years
  • Age 25
  • Seen Apr 17, 2024
when it went to that function it was using gBagMenu->newScreenCallback.

You are right. I didn't realize that they had updated it again. My bad.

and was told "`CB2_OpenFlyMap' undeclared (first use in this function)". what did i miss in order to get Fly to work?

Did you include region_map.h in your file? That should give you access to CB2_OpenFlyMap.
 
Back
Top