Advertiser Content
Seen 1 Week Ago
Posted 1 Week Ago
9 posts
2.4 Years
Dear all,

I'm trying to make a move tutor that checks egg moves in addition to TM and tutor moves when determining if a Pokémon is able to learn a move. Example: Bulbasaur has Skull Bash as an egg move. If I made a tutor that teaches Skull Bash, I would like Bulbasaur to learn it.

I have found and modified the function CanMonLearnTMTutor in src/party_menu.c, but I am unable to include the array gEggMoves at src/data/pokemon/egg_moves.h. Upon compiling, if I try to include daycare.h and/or data/pokemon/egg_moves.h in party_menu.c, I get either an undeclared error or multiple definitions error for gEggMoves. As the include fails one way or another, I don't have very good understanding of how I could access the function GetEggMoves in src/daycare.c and gEggMoves in src/data/pokemon/egg_moves.h.

Any help would be greatly appreciated. If needed, I can post the error messages of each situation. Thank you in advance!

Lyzo

Back from vacation

Age 24
Male
The Netherlands
Seen 3 Weeks Ago
Posted July 2nd, 2019
263 posts
12.7 Years
Hm... What happens when you make gEggMoves[] a static constant instead of just a constant? Does that work?

It compiled for me, but not sure if your code would work that you modified. If you share it I can do some better testing.

Change line 5 in data/pokemon/egg_moves.h :
static const u16 gEggMoves[] = {


^^ Thank you The Blueprint !!!
Seen 1 Week Ago
Posted 1 Week Ago
9 posts
2.4 Years
Hm... What happens when you make gEggMoves[] a static constant instead of just a constant? Does that work?

It compiled for me, but not sure if your code would work that you modified. If you share it I can do some better testing.

Change line 5 in data/pokemon/egg_moves.h :

static const u16 gEggMoves[] = {
Thank you for kind help! That did the trick. I have now been able to include the GetEggMoves function within CanMonLearnTMTutor. If and when I'm finished with modifying the function I will post the modifications here. Thanks again!

If I may ask, can you anticipate if changing gEggMoves to static will affect Daycare functionalities? I haven't yet tested that and I'm not well versed in C.
Seen 1 Week Ago
Posted 1 Week Ago
9 posts
2.4 Years
I have now achieved functionality for checking egg moves and level-up moves when the tutor decides if a Pokémon is able to learn a move. The process for the tutor as a whole is as follows:

1. The tutor asks the player to show a Pokémon
2. The tutor asks the player to choose one move from that Pokémon's current moveset
3. The tutor asks the player to select which Pokémon they want to teach that move; egg moves and level-up moves are included in the compatibility check here

Points 1 and 2 are working as intended, so I'll skip the code for them. The thing is, every Pokémon in my party is shown to be "NOT ABLE" to learn the move the player has selected even if they can learn it or they already know it. I've uploaded a video with this behaviour at youtu.be/K6BIiJf8TY4 (sorry that it's not a link but I have less than 5 posts).

The index number of the selected move is stored in VAR_0x8005 throughout the dialog. The index apparently used to be stored in gUnknown_0203CEC8.unkE and some move tutor related value instead in VAR_0x8005 in the original version of the function. The major modifications for point 3 include:

// sorry for the missing indents, the editor is being a pain
// code based on sub_81B7E4C
static void sub_81B7E4C_CustomTutor(u8 taskId)
{
struct Pokemon *mon;
s16 *move;
if (!gPaletteFade.active)
{

mon = &gPlayerParty[gUnknown_0203CEC8.unk9];
move = &gUnknown_0203CEC8.unkE;
GetMonNickname(mon, gStringVar1);

//gUnknown_0203CEC8.unkE = GetTutorMove(gSpecialVar_0x8005);
gUnknown_0203CEC8.unkE = gSpecialVar_0x8005;
//StringCopy(gStringVar2, gMoveNames[gUnknown_0203CEC8.unkE]);
StringCopy(gStringVar2, gMoveNames[gSpecialVar_0x8005]);
move[1] = 2;

//switch (CanMonLearnTMTutor(mon, 0, gSpecialVar_0x8005))
switch (CanMonLearnCustomTutor(mon, gSpecialVar_0x8005))
{

case CANNOT_LEARN_MOVE:
sub_81B6D98(taskId, gText_PkmnCantLearnMove);
return;

case ALREADY_KNOWS_MOVE:
sub_81B6D98(taskId, gText_PkmnAlreadyKnows);
return;

default:
//if (GiveMoveToMon(mon, gUnknown_0203CEC8.unkE) != 0xFFFF)
if (GiveMoveToMon(mon, gSpecialVar_0x8005) != 0xFFFF)
{
sub_81B6EB4(taskId);
return;
}
break;

}

sub_81B6D74(gText_PkmnNeedsToReplaceMove);
gTasks[taskId].func = sub_81B6FF4;
}
}
Code for the compatibility check function CanMonLearnCustomTutor is as follows:

// declaration in the beginning of the file
static u8 CanMonLearnCustomTutor(struct Pokemon *, u16);

// actual function
static u8 CanMonLearnCustomTutor(struct Pokemon *mon, u16 move)
{
u8 numMoves;
u16 numEggMoves;
u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
u16 i;
u8 n;

if (GetMonData(mon, MON_DATA_IS_EGG))
{
return CANNOT_LEARN_MOVE_IS_EGG;
}

if (MonKnowsMove(mon, move) == TRUE)
{
return ALREADY_KNOWS_MOVE;
}

// egg moves
numEggMoves = GetEggMoves(mon, sHatchedEggEggMoves);

for (i = 0; i < numEggMoves; i++)
{
if (sHatchedEggEggMoves[i] == move)
return CAN_LEARN_MOVE;
}

// level-up moves
numMoves = GetLevelUpMovesBySpecies(species, sHatchedEggLevelUpMoves);

for (n = 0; n < numMoves; n++)
{
if (move == sHatchedEggLevelUpMoves[n])
return CAN_LEARN_MOVE;
}

return CANNOT_LEARN_MOVE;
}
As can be seen from the video, the actual teaching of the move works as intended despite the text error. I have not yet been able to track down where the text is stored, although I suspect gStringVar4 or gUnknown_0203CEC8. I may be wrong, though. It would be really nice to able to solve this weird problem as the egg move and level-up move check is otherwise finished and functional.

Lyzo

Back from vacation

Age 24
Male
The Netherlands
Seen 3 Weeks Ago
Posted July 2nd, 2019
263 posts
12.7 Years
Already pretty cool!

I think all you have to do is edit the Display function in the party_menu.c to use your new custom function. Look for static void DisplayPartyPokemonSelectToTeachMove (around line 2089).

Change bolded below, but basically just changing CanMonLearnTutor = CanMonLearnCustomTutor
static void DisplayPartyPokemonSelectToTeachMove(u8 slot, u16 item, u8 tutor)
{
    switch (CanMonLearnCustomTutor(&gPlayerParty[slot], item, tutor))
    {
    case CANNOT_LEARN_MOVE:
    case CANNOT_LEARN_MOVE_IS_EGG:
        DisplayPartyPokemonSelectData(slot, 9);
        break;
    case ALREADY_KNOWS_MOVE:
        DisplayPartyPokemonSelectData(slot, 10);
        break;
    default:
        DisplayPartyPokemonSelectData(slot, 8);
        break;
    }
}
Does that work?


^^ Thank you The Blueprint !!!
Seen 1 Week Ago
Posted 1 Week Ago
9 posts
2.4 Years
Already pretty cool!

I think all you have to do is edit the Display function in the party_menu.c to use your new custom function. Look for static void DisplayPartyPokemonSelectToTeachMove (around line 2089).

Change bolded below, but basically just changing CanMonLearnTutor = CanMonLearnCustomTutor
static void DisplayPartyPokemonSelectToTeachMove(u8 slot, u16 item, u8 tutor)
{
    switch (CanMonLearnCustomTutor(&gPlayerParty[slot], item, tutor))
    {
    case CANNOT_LEARN_MOVE:
    case CANNOT_LEARN_MOVE_IS_EGG:
        DisplayPartyPokemonSelectData(slot, 9);
        break;
    case ALREADY_KNOWS_MOVE:
        DisplayPartyPokemonSelectData(slot, 10);
        break;
    default:
        DisplayPartyPokemonSelectData(slot, 8);
        break;
    }
}
Does that work?
That's it! The texts are now displayed correctly. Thank you so much! I have some work still left to do as I don't want to ruin the dialog for all the regular move tutors in the game and TMs/HMs, but this was absolutely perfect! Thanks again!
Advertiser Content