Adds ability Zero to Hero (#3542)
This commit is contained in:
parent
954f67a29f
commit
4b3c96a89b
10 changed files with 183 additions and 2 deletions
|
@ -8678,6 +8678,13 @@ BattleScript_CostarActivates::
|
|||
waitmessage B_WAIT_TIME_LONG
|
||||
end3
|
||||
|
||||
BattleScript_ZeroToHeroActivates::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_ZEROTOHEROTRANSFORMATION
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end3
|
||||
|
||||
BattleScript_AttackWeakenedByStrongWinds::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_ATTACKWEAKENEDBSTRONGWINDS
|
||||
|
|
|
@ -700,7 +700,7 @@ struct BattleStruct
|
|||
bool8 effectsBeforeUsingMoveDone:1; // Mega Evo and Focus Punch/Shell Trap effects.
|
||||
u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit.
|
||||
u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching)
|
||||
bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face.
|
||||
bool8 allowedToChangeFormInWeather[PARTY_SIZE][NUM_BATTLE_SIDES]; // For each party member and side, used by Ice Face.
|
||||
u8 battleBondTransformed[NUM_BATTLE_SIDES]; // Bitfield for each party.
|
||||
u8 storedHealingWish:4; // Each battler as a bit.
|
||||
u8 storedLunarDance:4; // Each battler as a bit.
|
||||
|
@ -718,6 +718,7 @@ struct BattleStruct
|
|||
bool8 trainerSlideBeforeFirstTurnMsgDone;
|
||||
u32 aiDelayTimer; // Counts number of frames AI takes to choose an action.
|
||||
u32 aiDelayFrames; // Number of frames it took to choose an action.
|
||||
bool8 transformZeroToHero[PARTY_SIZE][NUM_BATTLE_SIDES];
|
||||
};
|
||||
|
||||
// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,
|
||||
|
|
|
@ -459,6 +459,7 @@ extern const u8 BattleScript_RuinAbilityActivates[];
|
|||
extern const u8 BattleScript_CudChewActivates[];
|
||||
extern const u8 BattleScript_SupremeOverlordActivates[];
|
||||
extern const u8 BattleScript_CostarActivates[];
|
||||
extern const u8 BattleScript_ZeroToHeroActivates[];
|
||||
extern const u8 BattleScript_ToxicDebrisActivates[];
|
||||
extern const u8 BattleScript_EarthEaterActivates[];
|
||||
extern const u8 BattleScript_MimicryActivates_End3[];
|
||||
|
|
|
@ -685,8 +685,9 @@
|
|||
#define STRINGID_TEAMSURROUNDEDBYROCKS 683
|
||||
#define STRINGID_PKMNHURTBYROCKSTHROWN 684
|
||||
#define STRINGID_MOVEBLOCKEDBYDYNAMAX 685
|
||||
#define STRINGID_ZEROTOHEROTRANSFORMATION 686
|
||||
|
||||
#define BATTLESTRINGS_COUNT 686
|
||||
#define BATTLESTRINGS_COUNT 687
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
|
|
@ -822,9 +822,11 @@ static const u8 sText_TargetIsBeingSaltCured[] = _("{B_DEF_NAME_WITH_PREFIX} is
|
|||
static const u8 sText_TargetIsHurtBySaltCure[] = _("{B_DEF_NAME_WITH_PREFIX} is hurt by {B_BUFF1}!");
|
||||
static const u8 sText_OpportunistCopied[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} copied its\nopponent's stat changes!");
|
||||
static const u8 sText_TargetCoveredInStickyCandySyrup[] = _("{B_DEF_NAME_WITH_PREFIX} got covered\nin sticky syrup!");
|
||||
static const u8 sText_ZeroToHeroTransformation[] = _("{B_ATK_NAME_WITH_PREFIX} underwent a heroic\ntransformation!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_ZEROTOHEROTRANSFORMATION - BATTLESTRINGS_TABLE_START] = sText_ZeroToHeroTransformation,
|
||||
[STRINGID_MOVEBLOCKEDBYDYNAMAX - BATTLESTRINGS_TABLE_START] = sText_MoveBlockedByDynamax,
|
||||
[STRINGID_OPPORTUNISTCOPIED - BATTLESTRINGS_TABLE_START] = sText_OpportunistCopied,
|
||||
[STRINGID_TARGETISHURTBYSALTCURE - BATTLESTRINGS_TABLE_START] = sText_TargetIsHurtBySaltCure,
|
||||
|
|
|
@ -9151,6 +9151,7 @@ static void Cmd_various(void)
|
|||
case ABILITY_SCHOOLING: case ABILITY_COMATOSE:
|
||||
case ABILITY_SHIELDS_DOWN: case ABILITY_DISGUISE:
|
||||
case ABILITY_RKS_SYSTEM: case ABILITY_TRACE:
|
||||
case ABILITY_ZERO_TO_HERO:
|
||||
break;
|
||||
default:
|
||||
gBattleStruct->tracedAbility[gBattlerAbility] = gBattleMons[battler].ability; // re-using the variable for trace
|
||||
|
|
|
@ -113,6 +113,7 @@ static const u16 sSkillSwapBannedAbilities[] =
|
|||
ABILITY_ICE_FACE,
|
||||
ABILITY_HUNGER_SWITCH,
|
||||
ABILITY_GULP_MISSILE,
|
||||
ABILITY_ZERO_TO_HERO,
|
||||
};
|
||||
|
||||
static const u16 sRolePlayBannedAbilities[] =
|
||||
|
@ -138,6 +139,7 @@ static const u16 sRolePlayBannedAbilities[] =
|
|||
ABILITY_ICE_FACE,
|
||||
ABILITY_HUNGER_SWITCH,
|
||||
ABILITY_GULP_MISSILE,
|
||||
ABILITY_ZERO_TO_HERO,
|
||||
};
|
||||
|
||||
static const u16 sRolePlayBannedAttackerAbilities[] =
|
||||
|
@ -154,6 +156,7 @@ static const u16 sRolePlayBannedAttackerAbilities[] =
|
|||
ABILITY_POWER_CONSTRUCT,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_GULP_MISSILE,
|
||||
ABILITY_ZERO_TO_HERO,
|
||||
};
|
||||
|
||||
static const u16 sWorrySeedBannedAbilities[] =
|
||||
|
@ -170,6 +173,7 @@ static const u16 sWorrySeedBannedAbilities[] =
|
|||
ABILITY_TRUANT,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_GULP_MISSILE,
|
||||
ABILITY_ZERO_TO_HERO,
|
||||
};
|
||||
|
||||
static const u16 sGastroAcidBannedAbilities[] =
|
||||
|
@ -188,6 +192,7 @@ static const u16 sGastroAcidBannedAbilities[] =
|
|||
ABILITY_SHIELDS_DOWN,
|
||||
ABILITY_STANCE_CHANGE,
|
||||
ABILITY_ZEN_MODE,
|
||||
ABILITY_ZERO_TO_HERO,
|
||||
};
|
||||
|
||||
static const u16 sEntrainmentBannedAttackerAbilities[] =
|
||||
|
@ -206,6 +211,7 @@ static const u16 sEntrainmentBannedAttackerAbilities[] =
|
|||
ABILITY_ICE_FACE,
|
||||
ABILITY_HUNGER_SWITCH,
|
||||
ABILITY_GULP_MISSILE,
|
||||
ABILITY_ZERO_TO_HERO,
|
||||
};
|
||||
|
||||
static const u16 sEntrainmentTargetSimpleBeamBannedAbilities[] =
|
||||
|
@ -221,6 +227,7 @@ static const u16 sEntrainmentTargetSimpleBeamBannedAbilities[] =
|
|||
ABILITY_BATTLE_BOND,
|
||||
ABILITY_ICE_FACE,
|
||||
ABILITY_GULP_MISSILE,
|
||||
ABILITY_ZERO_TO_HERO,
|
||||
};
|
||||
|
||||
static u8 CalcBeatUpPower(void)
|
||||
|
@ -994,6 +1001,7 @@ static const u8 sAbilitiesNotTraced[ABILITIES_COUNT] =
|
|||
[ABILITY_STANCE_CHANGE] = 1,
|
||||
[ABILITY_TRACE] = 1,
|
||||
[ABILITY_ZEN_MODE] = 1,
|
||||
[ABILITY_ZERO_TO_HERO] = 1,
|
||||
};
|
||||
|
||||
static const u8 sHoldEffectToType[][2] =
|
||||
|
@ -4695,6 +4703,17 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_ZERO_TO_HERO:
|
||||
if (!gSpecialStatuses[battler].switchInAbilityDone
|
||||
&& gBattleMons[battler].species == SPECIES_PALAFIN_HERO
|
||||
&& !gBattleStruct->transformZeroToHero[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)])
|
||||
{
|
||||
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
|
||||
gBattleStruct->transformZeroToHero[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)] = TRUE;
|
||||
BattleScriptPushCursorAndCallback(BattleScript_ZeroToHeroActivates);
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_ENDTURN: // 1
|
||||
|
@ -6078,6 +6097,7 @@ bool32 IsNeutralizingGasBannedAbility(u32 ability)
|
|||
case ABILITY_ICE_FACE:
|
||||
case ABILITY_AS_ONE_ICE_RIDER:
|
||||
case ABILITY_AS_ONE_SHADOW_RIDER:
|
||||
case ABILITY_ZERO_TO_HERO:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
|
|
|
@ -355,6 +355,8 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
|
|||
[SPECIES_ENAMORUS_THERIAN] = sEnamorusFormChangeTable,
|
||||
#endif
|
||||
#if P_GEN_9_POKEMON == TRUE
|
||||
[SPECIES_PALAFIN_ZERO] = sPalafinZeroFormChangeTable,
|
||||
[SPECIES_PALAFIN_HERO] = sPalafinZeroFormChangeTable,
|
||||
[SPECIES_OGERPON_TEAL_MASK] = sOgerponFormChangeTable,
|
||||
[SPECIES_OGERPON_WELLSPRING_MASK] = sOgerponFormChangeTable,
|
||||
[SPECIES_OGERPON_HEARTHFLAME_MASK] = sOgerponFormChangeTable,
|
||||
|
|
|
@ -800,6 +800,12 @@ static const struct FormChange sUrshifuRapidStrikeFormChangeTable[] =
|
|||
{FORM_CHANGE_TERMINATOR},
|
||||
};
|
||||
|
||||
static const struct FormChange sPalafinZeroFormChangeTable[] =
|
||||
{
|
||||
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_PALAFIN_HERO},
|
||||
{FORM_CHANGE_TERMINATOR},
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#undef WHEN_LEARNED
|
||||
|
|
140
test/battle/ability/zero_to_hero.c
Normal file
140
test/battle/ability/zero_to_hero.c
Normal file
|
@ -0,0 +1,140 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(P_GEN_9_POKEMON == TRUE);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Zero to Hero transforms Palafin when it switches out")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { SWITCH(player, 1); }
|
||||
TURN { SWITCH(player, 0); }
|
||||
} SCENE {
|
||||
MESSAGE("Palafin, that's enough! Come back!");
|
||||
MESSAGE("Go! Wobbuffet!");
|
||||
MESSAGE("Wobbuffet, that's enough! Come back!");
|
||||
MESSAGE("Go! Palafin!");
|
||||
ABILITY_POPUP(player, ABILITY_ZERO_TO_HERO);
|
||||
MESSAGE("Palafin underwent a heroic transformation!");
|
||||
} THEN { EXPECT_EQ(player->species, SPECIES_PALAFIN_HERO); }
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Zero to Hero can't be surpressed by Neutralizing Gas")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_KOFFING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||
} WHEN {
|
||||
TURN { SWITCH(player, 1); }
|
||||
TURN { SWITCH(player, 0); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(opponent, ABILITY_NEUTRALIZING_GAS);
|
||||
ABILITY_POPUP(player, ABILITY_ZERO_TO_HERO);
|
||||
MESSAGE("Palafin underwent a heroic transformation!");
|
||||
} THEN { EXPECT_EQ(player->species, SPECIES_PALAFIN_HERO); }
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Zero to Hero transforms both player and opponent")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { SWITCH(player, 1); SWITCH(opponent, 1); }
|
||||
TURN { SWITCH(player, 0); SWITCH(opponent, 0); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_ZERO_TO_HERO);
|
||||
MESSAGE("Palafin underwent a heroic transformation!");
|
||||
ABILITY_POPUP(opponent, ABILITY_ZERO_TO_HERO);
|
||||
MESSAGE("Foe Palafin underwent a heroic transformation!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->species, SPECIES_PALAFIN_HERO);
|
||||
EXPECT_EQ(opponent->species, SPECIES_PALAFIN_HERO);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Zero to Hero will activate if a switch move is used")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_FLIP_TURN].effect == EFFECT_HIT_ESCAPE);
|
||||
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FLIP_TURN); SEND_OUT(player, 1); }
|
||||
TURN { SWITCH(player, 0); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLIP_TURN, player);
|
||||
ABILITY_POPUP(player, ABILITY_ZERO_TO_HERO);
|
||||
MESSAGE("Palafin underwent a heroic transformation!");
|
||||
} THEN { EXPECT_EQ(player->species, SPECIES_PALAFIN_HERO); }
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Gastro Acid, Worry Seed, and Simple Beam fail if the target has the Ability Zero to Hero")
|
||||
{
|
||||
u16 move;
|
||||
|
||||
PARAMETRIZE { move = MOVE_GASTRO_ACID; }
|
||||
PARAMETRIZE { move = MOVE_WORRY_SEED; }
|
||||
PARAMETRIZE { move = MOVE_SIMPLE_BEAM; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_GASTRO_ACID].effect == EFFECT_GASTRO_ACID);
|
||||
ASSUME(gBattleMoves[MOVE_WORRY_SEED].effect == EFFECT_WORRY_SEED);
|
||||
ASSUME(gBattleMoves[MOVE_SIMPLE_BEAM].effect == EFFECT_SIMPLE_BEAM);
|
||||
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Role Play, Skill Swap, and Entrainment fail if either Pokémon has Zero to Hero")
|
||||
{
|
||||
u16 move;
|
||||
|
||||
PARAMETRIZE { move = MOVE_ROLE_PLAY; }
|
||||
PARAMETRIZE { move = MOVE_SKILL_SWAP; }
|
||||
PARAMETRIZE { move = MOVE_ENTRAINMENT; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY);
|
||||
ASSUME(gBattleMoves[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP);
|
||||
ASSUME(gBattleMoves[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT);
|
||||
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
// Write Trace test and move this one to that file (including every other ability that can't be copied)
|
||||
SINGLE_BATTLE_TEST("Zero to Hero cannot be copied by Trace")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
|
||||
OPPONENT(SPECIES_RALTS) { Ability(ABILITY_TRACE); }
|
||||
} WHEN {
|
||||
TURN {}
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ABILITY_POPUP(opponent, ABILITY_TRACE);
|
||||
MESSAGE("Foe Ralts Traced Palafin's Zero to Hero!");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue