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

[Pokeemerald] Tutorial : How to implement X/Y Sky Battles

6
Posts
4
Years
    • Seen Oct 28, 2023
    Hello, and welcome. Here is my first tutorial, which will explain what I've been working on the last week.
    For those who played Pokemon X/Y, you may remember the Sky Battles :
    It was a special battle where you could only use flying-type pokemon and pokemon that had levitate as their ability. Because I am working on an X/Y demake, I had to create it, so there you are.
    First, we will open src/battle_util.c and add these 3 functions :
    Spoiler:
    Just before I explain this, go into include/battle_util.h, and add this:
    Code:
    bool8 CanMonParticipateInSkyBattle(struct Pokemon* pokemon);
    bool8 IsMonBannedFromSkyBattles(u16 species);
    bool8 IsMoveBannedFromSkyBattles(u16 move);
    It has to be before the #endif
    The first function, CanMonParticipateInSkyBattle, checks if our pokemon has the ability levitate, or if the pokemon is a flying type. In my version, I decided to add a new condition: if our pokemon knows fly, he can participate too. Here's my modified CanMonParticipateInSkyBattle function, if you want to implement this :
    Spoiler:
    The two other functions, IsMonBannedFromSkyBattles and IsMoveBannedFromSkyBattles, will be used later. In pokemon X/Y, some pokemon couldn't join the battle, like the first stage of bird pokemon, hawlucha, etc. Every pokemon that was not flying visually. Also, some moves were banned, like ingrain for example: how would you use this in the sky.
    Now, we are going to create two special commands. Let's open src/field_specials.c and add these two functions :
    Spoiler:
    Also add this at the top of the file.
    Code:
    #include "load_save.h"
    #include "constants/abilities.h"
    Let's register them in data/specials.inc and add these two lines at the end of the file, following the others:
    Code:
    def_special CanDoSkyBattle
    def_special PrepareSkyBattle
    The first special will be used in a script. It will help us to check if the player has at least one alive pokemon that can participate. If it's the case, we can compare VAR_RESULT and use the special PrepareSkyBattle. This one will remember the position of the pokemons that will participate in the party and will remove the others. Once these two specials will be activated, you can just use the trainerbattle command. I don't know yet how I can change the background, but I'll edit the tutorial when I'll find a solution.
    As you can see, the second special sets a flag and a var. They don't exist in the game, so you'll have to create them. Open include/constants/flags.h and include/constants/vars.h. In these files, find an unused flag and var, and rename the unused flag FLAG_IS_IN_SKY_BATTLE and the unused var VAR_SKY_BATTLE_POKEMON_POSITIONS. For me, I choose 0x71 for the flag and 0x404E for the var.
    Now, we need to handle the end of the battle. Let's open src/battle_setup.c and go in the static void CB2_EndTrainerBattle(void) function, and add this just before this line : "else if (IsPlayerDefeated(gBattleOutcome) == TRUE)"
    Spoiler:
    You also need to add this before this line "if gTrainerBattleOpponent_A == TRAINER_SECRET_BASE"
    Code:
    bool8 everyPokemonFainted;
    u8 partyCount;
    u8 i;
    Finally, at the top of the file, add
    Code:
    #include "load_save.h"
    Let's explain this. If we are in a Sky Battle, the first thing we do is reset the flag, so the next battle won't be considered as a Sky Battle. Then, we use a function we don't have added yet. We want to load back the pokemon that we saved before we remove our pokemons in the battle, however, we need to update the ones which participated (else, they won't lose HP, PP, etc). Finally, we load back every mon. Then, we have to do another check, if the player loses. If the player lost the battle, we check if there is at least one pokemon in the party with more than 1HP. If that condition is false, the player blackouts.
    Warning: Since we only edit CB2_EndTrainerBattle, our Sky Battle system does not apply to wild battles. If you want to implement this and understand the code I gave, you can easily adapt this.
    We're almost there! Let's open src/load_save.c and add this function:
    Spoiler:
    We need to register this function in include/load_save.h, so we need to add this line
    Code:
    void UpdatePlayerSavedPartyAfterSkyBattle(void);
    We need to change one last file ! Let's go in src/battle_scripts_command.c
    Find the "Cmd_attackcanceler" function, and change the line "if (NoTargetPresent(gCurrentMove))" by
    Code:
    if (NoTargetPresent(gCurrentMove) || (FlagGet(FLAG_IS_IN_SKY_BATTLE) && IsMoveBannedFromSkyBattles(gCurrentMove)))
    That will make any banned move fail while used in a sky battle.
    Aaaand it's done! Now, if you want to create a Sky Battle using a script, you just have to use this:
    Code:
    special CanDoSkyBattle
    compare VAR_RESULT, FALSE
    goto_if_eq [Script where you can't do a Sky battle]
    special PrepareSkyBattle
    trainerbattle TRAINER_BATTLE_CONTINUE_SCRIPT [Your arguments for the battle]
    Thanks for reading! If there's any bug or thing I forgot in the tutorial, please let me know!
     
    Last edited:
    8
    Posts
    8
    Years
    • Seen Nov 12, 2022
    Hello Phlayne,

    I've been trying to use this tutorial but I'm running into two errors.
    I'm using one of the most recent rh-hideout pokeemerald builds .
    I get these errors:

    Spoiler:


    Battle_script_commands:

    in "Cmd_attackcanceler" function

    Spoiler:


    Load_save.c: added lines:


    Spoiler:




    So how would I make this function in load_save.c not 'implicit'?
    And what seems to be the mistake in the line in battle_script_commands.c?

    (I'm quite new at coding).
     

    PSF

    fangame developer
    9
    Posts
    3
    Years
  • Hello Phlayne,

    I've been trying to use this tutorial but I'm running into two errors.
    I'm using one of the most recent rh-hideout pokeemerald builds .
    I get these errors:

    Spoiler:


    Battle_script_commands:

    in "Cmd_attackcanceler" function

    Spoiler:


    Load_save.c: added lines:


    Spoiler:




    So how would I make this function in load_save.c not 'implicit'?
    And what seems to be the mistake in the line in battle_script_commands.c?

    (I'm quite new at coding).


    i don't know if you're still working on this, but in case anybody else is, this is a working version:

    https://github.com/rh-hideout/pokeemerald-expansion/pull/2950/files
     
    Last edited:
    Back
    Top