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

[SOLVED] [pokeemerald-expansion] Making the terrain surge abilities permanent

20
Posts
288
Days
  • Hello, how do I make the terrain surge abilities (and the trick room ability that you can see my thread about earlier) permanent like gen 5 drizzle? I looked at where the config leads, but there doesn't seem to be a terrain equivalent of the commands used for permanent weather.
     

    Lunos

    Random Uruguayan User
    3,114
    Posts
    15
    Years
  • Hello, how do I make the terrain surge abilities (and the trick room ability that you can see my thread about earlier) permanent like gen 5 drizzle? I looked at where the config leads, but there doesn't seem to be a terrain equivalent of the commands used for permanent weather.
    Drizzle is not exactly permanent even in Gen. 5, after all, it can be replaced by a different weather through the use of a move or an ability.
    Field terrains that are set through the VAR_TERRAIN config parameter in the expansion (located in include/config/battle.h) work exactly the same.
    They're not bound by a timer, but they can be replaced by using a move like Grassy Terrain, or activating an ability like Grassy Surge.

    That same line of code tells you how to set up a permanent field terrain of the same characteristics on the C side of the codebase.
    Alternatively, you could assign a value to VAR_TERRAIN via VarSet and that should work too.
     
    20
    Posts
    288
    Days
  • Drizzle is not exactly permanent even in Gen. 5, after all, it can be replaced by a different weather through the use of a move or an ability.
    Field terrains that are set through the VAR_TERRAIN config parameter in the expansion (located in include/config/battle.h) work exactly the same.
    They're not bound by a timer, but they can be replaced by using a move like Grassy Terrain, or activating an ability like Grassy Surge.

    That same line of code tells you how to set up a permanent field terrain of the same characteristics on the C side of the codebase.
    Alternatively, you could assign a value to VAR_TERRAIN via VarSet and that should work too.
    I don't entirely follow, I didn't think trick room would be affected by VAR_TERRAIN, as it is a field status like terrain, but isn't a terrain. Also would you just add a VarSet(VAR_TERRAIN, STATUS_FIELD_TERRAIN right before the switch statement for each terrain?
     

    Lunos

    Random Uruguayan User
    3,114
    Posts
    15
    Years
  • I don't entirely follow, I didn't think trick room would be affected by VAR_TERRAIN, as it is a field status like terrain, but isn't a terrain. Also would you just add a VarSet(VAR_TERRAIN, STATUS_FIELD_TERRAIN right before the switch statement for each terrain?
    Trick Room isn't affected at all. The Field Terrains and Trick Room are identified as field statuses, but they are not mutually exclusive or related.
    If you read the part of the code linked above, you'll notice that the code involving VAR_TERRAIN lies inside a if (VarGet(VAR_TERRAIN) & STATUS_FIELD_TERRAIN_ANY) statement.
    STATUS_FIELD_TERRAIN_ANY can only ever expand to the 4 STATUS_FIELD_X_TERRAIN constants.

    Also would you just add a VarSet(VAR_TERRAIN, STATUS_FIELD_TERRAIN right before the switch statement for each terrain?
    You're missing the closing parentheses.

    Also, I have to apologize, I'm just realizing that I misread your first post. You wanted to make the surge abilities last as much as Drizzle and I didn't catch up on that. I read whatever.
    With that being said, in this case, what you would need to do is to modify each Surge ability's code, which are located in the case ABILITYEFFECT_ON_SWITCHIN of AbilityBattleEffects.
    The expansion has 2 different ways to set up a field terrain depending on the origin point of the field terrain change; move effect or ability effect.
    Moves set up a terrain by calling BS_SetRemoveTerrain via the setremoveterrain battle script macro, where as abilities call TryChangeBattleTerrain instead.
    Thus, in this case you'll want to focus on TryChangeBattleTerrain.

    You will notice that just like it's the case with BS_SetRemoveTerrain, TryChangeBattleTerrain sets the relevant flags and timer counts for the terrain changing effect on its own.
    By default the function can't generate a permanent field terrain, but since the expansion conveniently has a STATUS_FIELD_TERRAIN_PERMANENT, you can use it to produce the effect you want:
    Diff:
    diff --git a/src/battle_util.c b/src/battle_util.c
    index 4385dc3ec..22d04c43b 100644
    --- a/src/battle_util.c
    +++ b/src/battle_util.c
    @@ -3862,14 +3862,9 @@ static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer)
         if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle)))
         {
             gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN);
    -        gFieldStatuses |= statusFlag;
    +        gFieldStatuses = (statusFlag | STATUS_FIELD_TERRAIN_PERMANENT);
             gDisableStructs[battler].terrainAbilityDone = FALSE;
    
    -        if (GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_TERRAIN_EXTENDER)
    -            *timer = 8;
    -        else
    -            *timer = 5;
    -
             gBattleScripting.battler = battler;
             return TRUE;
         }

    The above would set up a field terrain normally and the permanent flag with it, as well as skipping setting up gFieldTimers.terrainTimer at all.
    This, however, has the side effect of making it so field terrain-changing moves would also generate permanent field terrain changes.
    That is because the STATUS_FIELD_TERRAIN_PERMANENT flag would remain set, and BS_SetRemoveTerrain doesn't do anything about it.
    If you want to retain the functionality of overwriting an existing different field terrain for X number of turns for field terrain-changing moves, you'll want to update BS_SetRemoveTerrain:
    Diff:
    diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
    index ec9afc056..d7843057c 100644
    --- a/src/battle_script_commands.c
    +++ b/src/battle_script_commands.c
    @@ -16206,7 +16206,7 @@ void BS_SetRemoveTerrain(void)
         {
             u16 atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
    
    -        gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
    +        gFieldStatuses &= ~(STATUS_FIELD_TERRAIN_ANY | STATUS_FIELD_TERRAIN_PERMANENT);
             gFieldStatuses |= statusFlag;
             gFieldTimers.terrainTimer = (atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5;
             gBattlescriptCurrInstr = cmd->nextInstr;
     
    Back
    Top