Master to upcoming, 2024-11-29 (#5735)
|
@ -6,12 +6,16 @@
|
|||
|
||||
pokeemerald-expansion is a decomp hack base project based off pret's [pokeemerald](https://github.com/pret/pokeemerald) decompilation project. It's recommended that any new projects that plan on using it, to clone this repository instead of pret's vanilla repository, as we regurlarly incorporate pret's documentation changes. This is ***NOT*** a standalone romhack, and as such, most features will be unavailable and/or unbalanced if played as is.
|
||||
|
||||
## Using pokeemerald-expansion
|
||||
|
||||
If you use pokeemerald-expansion in your hack, please add RHH (Rom Hacking Hideout) to your credits list. Optionally, you can list the version used, so it can help players know what features to expect.
|
||||
You can phrase it as the following:
|
||||
```
|
||||
Based off RHH's pokeemerald-expansion 1.9.3 https://github.com/rh-hideout/pokeemerald-expansion/
|
||||
```
|
||||
|
||||
Please follow the instructions in `INSTALL.md` to get pokeemerald-expansion set up on your machine.
|
||||
|
||||
## What features are included?
|
||||
- ***IMPORTANT*❗❗ Read through these to learn what features you can toggle**:
|
||||
- [Battle configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/battle.h)
|
||||
|
|
|
@ -10093,7 +10093,6 @@ gBattleAnimMove_FloralHealing::
|
|||
loadspritegfx ANIM_TAG_ORBS @circles
|
||||
loadspritegfx ANIM_TAG_PINK_PETAL @pink particles
|
||||
monbg ANIM_ATTACKER
|
||||
monbg ANIM_TARGET
|
||||
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
|
||||
call CIRCLES_LEAVES
|
||||
call CIRCLES_LEAVES
|
||||
|
@ -10101,6 +10100,7 @@ gBattleAnimMove_FloralHealing::
|
|||
panse SE_M_COMET_PUNCH, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 0x2, 0x0
|
||||
playsewithpan SE_M_TWISTER, 0x0
|
||||
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 0x46, 0x1, 0x40
|
||||
clearmonbg ANIM_ATTACKER
|
||||
delay 0x2
|
||||
createsprite gFloralHealingWindLeavesTemplate, ANIM_ATTACKER, 2, 0x3c, 0x0, 0x40
|
||||
delay 0x2
|
||||
|
@ -10123,6 +10123,7 @@ gBattleAnimMove_FloralHealing::
|
|||
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 0x55, 0x0, 0x78
|
||||
delay 0x2
|
||||
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_TARGET, 0x12, 0xa
|
||||
monbg ANIM_TARGET
|
||||
call FloralHealingSpores
|
||||
call FloralHealingSpores
|
||||
call FloralHealingSpores
|
||||
|
@ -10133,7 +10134,6 @@ gBattleAnimMove_FloralHealing::
|
|||
createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 16, 0xc, 0xfffb, 0x1, 0x0, 0x20, 0x3c, 0x1
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_TARGET
|
||||
clearmonbg ANIM_ATTACKER
|
||||
end
|
||||
FloralHealingSpores:
|
||||
createsprite gFloralHealingFlowerTemplate, ANIM_ATTACKER, 2, 0x0, 0xffec, 0x55, 0x50, 0x0
|
||||
|
|
|
@ -2401,7 +2401,6 @@ BattleScript_EffectHealingWish::
|
|||
storehealingwish BS_ATTACKER
|
||||
.if B_HEALING_WISH_SWITCH <= GEN_4
|
||||
openpartyscreen BS_ATTACKER, BattleScript_EffectHealingWishEnd
|
||||
switchoutabilities BS_ATTACKER
|
||||
waitstate
|
||||
switchhandleorder BS_ATTACKER, 2
|
||||
returnatktoball
|
||||
|
@ -5755,7 +5754,6 @@ BattleScript_PrintFullBox::
|
|||
|
||||
BattleScript_ActionSwitch::
|
||||
hpthresholds2 BS_ATTACKER
|
||||
saveattacker
|
||||
printstring STRINGID_RETURNMON
|
||||
jumpifbattletype BATTLE_TYPE_DOUBLE, BattleScript_PursuitSwitchDmgSetMultihit
|
||||
setmultihit 1
|
||||
|
@ -5773,7 +5771,6 @@ BattleScript_DoSwitchOut::
|
|||
switchoutabilities BS_ATTACKER
|
||||
updatedynamax
|
||||
waitstate
|
||||
restoreattacker
|
||||
returnatktoball
|
||||
waitstate
|
||||
drawpartystatussummary BS_ATTACKER
|
||||
|
@ -9633,7 +9630,9 @@ BattleScript_EjectButtonActivates::
|
|||
removeitem BS_SCRIPTING
|
||||
makeinvisible BS_SCRIPTING
|
||||
openpartyscreen BS_SCRIPTING, BattleScript_EjectButtonEnd
|
||||
copybyte sSAVED_BATTLER, sBATTLER
|
||||
switchoutabilities BS_SCRIPTING
|
||||
copybyte sBATTLER, sSAVED_BATTLER
|
||||
waitstate
|
||||
switchhandleorder BS_SCRIPTING 0x2
|
||||
returntoball BS_SCRIPTING, FALSE
|
||||
|
@ -9730,6 +9729,7 @@ BattleScript_PastelVeilEnd:
|
|||
end3
|
||||
|
||||
BattleScript_NeutralizingGasExits::
|
||||
saveattacker
|
||||
savetarget
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_NEUTRALIZINGGASOVER
|
||||
|
@ -9739,6 +9739,7 @@ BattleScript_NeutralizingGasExitsLoop:
|
|||
switchinabilities BS_TARGET
|
||||
addbyte gBattlerTarget, 1
|
||||
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_NeutralizingGasExitsLoop
|
||||
restoreattacker
|
||||
restoretarget
|
||||
return
|
||||
|
||||
|
|
Before Width: | Height: | Size: 686 B After Width: | Height: | Size: 813 B |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 1.3 KiB |
|
@ -1,7 +1,7 @@
|
|||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
255 255 255
|
||||
120 255 255
|
||||
254 235 185
|
||||
220 220 218
|
||||
235 192 100
|
||||
|
@ -16,4 +16,4 @@ JASC-PAL
|
|||
64 64 64
|
||||
45 43 43
|
||||
8 8 8
|
||||
0 0 0
|
||||
255 255 255
|
||||
|
|
|
@ -16,4 +16,4 @@ JASC-PAL
|
|||
64 64 64
|
||||
45 43 43
|
||||
8 8 8
|
||||
0 0 0
|
||||
255 255 255
|
||||
|
|
Before Width: | Height: | Size: 691 B After Width: | Height: | Size: 618 B |
Before Width: | Height: | Size: 565 B After Width: | Height: | Size: 563 B |
|
@ -289,9 +289,9 @@ enum MoveEndEffects
|
|||
MOVEEND_RECOIL,
|
||||
MOVEEND_ITEM_EFFECTS_ATTACKER,
|
||||
MOVEEND_MAGICIAN, // Occurs after final multi-hit strike, and after other items/abilities would activate
|
||||
MOVEEND_RED_CARD, // Red Card triggers before Eject Pack
|
||||
MOVEEND_EJECT_ITEMS,
|
||||
MOVEEND_WHITE_HERB,
|
||||
MOVEEND_RED_CARD,
|
||||
MOVEEND_LIFEORB_SHELLBELL, // Includes shell bell, throat spray, etc
|
||||
MOVEEND_CHANGED_ITEMS,
|
||||
MOVEEND_PICKPOCKET,
|
||||
|
|
|
@ -134,4 +134,8 @@
|
|||
// param1: amount of days
|
||||
#define FORM_CHANGE_DAYS_PASSED 23
|
||||
|
||||
// Form change for Aegislash
|
||||
#define FORM_CHANGE_BATTLE_ATTACK 24
|
||||
#define FORM_CHANGE_BATTLE_KINGS_SHIELD 25
|
||||
|
||||
#endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
|
||||
|
|
|
@ -1125,7 +1125,6 @@ static bool32 NoTargetPresent(u8 battler, u32 move)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
// TODO: Convert this to a proper FORM_CHANGE type.
|
||||
static bool32 TryAegiFormChange(void)
|
||||
{
|
||||
// Only Aegislash with Stance Change can transform, transformed mons cannot.
|
||||
|
@ -1140,12 +1139,12 @@ static bool32 TryAegiFormChange(void)
|
|||
case SPECIES_AEGISLASH_SHIELD: // Shield -> Blade
|
||||
if (IS_MOVE_STATUS(gCurrentMove))
|
||||
return FALSE;
|
||||
gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_BLADE;
|
||||
TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_ATTACK);
|
||||
break;
|
||||
case SPECIES_AEGISLASH_BLADE: // Blade -> Shield
|
||||
if (gCurrentMove != MOVE_KINGS_SHIELD)
|
||||
return FALSE;
|
||||
gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_SHIELD;
|
||||
TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_KINGS_SHIELD);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1782,8 +1781,6 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u
|
|||
if (!RandomPercentage(RNG_ACCURACY, accuracy))
|
||||
{
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
if (holdEffectAtk == HOLD_EFFECT_BLUNDER_POLICY)
|
||||
gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks
|
||||
|
||||
if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS
|
||||
&& !recalcDragonDarts // So we don't jump back and forth between targets
|
||||
|
@ -2266,6 +2263,7 @@ END:
|
|||
}
|
||||
if (gSpecialStatuses[gBattlerAttacker].gemBoost
|
||||
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||
&& gBattleMons[gBattlerAttacker].item
|
||||
&& gMovesInfo[gCurrentMove].effect != EFFECT_PLEDGE
|
||||
&& gCurrentMove != MOVE_STRUGGLE)
|
||||
|
@ -2678,6 +2676,13 @@ static void Cmd_resultmessage(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (gMoveResultFlags & MOVE_RESULT_MISSED && !(gMoveResultFlags & (MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED)))
|
||||
{
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_BLUNDER_POLICY
|
||||
&& !IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove))
|
||||
gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks
|
||||
}
|
||||
|
||||
if (gMoveResultFlags & MOVE_RESULT_MISSED && (!(gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK))
|
||||
{
|
||||
if (gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK) // Wonder Guard or Levitate - show the ability pop-up
|
||||
|
@ -4157,6 +4162,15 @@ static void Cmd_tryfaintmon(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (gBattleMons[battler].ability == ABILITY_NEUTRALIZING_GAS
|
||||
&& !(gAbsentBattlerFlags & (1u << battler))
|
||||
&& !IsBattlerAlive(battler))
|
||||
{
|
||||
gBattleMons[battler].ability = ABILITY_NONE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
return;
|
||||
}
|
||||
if (cmd->battler == BS_ATTACKER)
|
||||
{
|
||||
destinyBondBattler = gBattlerTarget;
|
||||
|
@ -14788,7 +14802,7 @@ static void Cmd_switchoutabilities(void)
|
|||
MarkBattlerForControllerExec(battler);
|
||||
break;
|
||||
case ABILITY_REGENERATOR:
|
||||
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 3;
|
||||
gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 3;
|
||||
gBattleMoveDamage += gBattleMons[battler].hp;
|
||||
if (gBattleMoveDamage > gBattleMons[battler].maxHP)
|
||||
gBattleMoveDamage = gBattleMons[battler].maxHP;
|
||||
|
|
|
@ -6889,7 +6889,7 @@ static u8 TrySetEnigmaBerry(u32 battler)
|
|||
{
|
||||
if (IsBattlerAlive(battler)
|
||||
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
|
||||
&& ((TARGET_TURN_DAMAGED && gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || gBattleScripting.overrideBerryRequirements)
|
||||
&& ((BATTLER_TURN_DAMAGED(battler) && gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || gBattleScripting.overrideBerryRequirements)
|
||||
&& !(gBattleScripting.overrideBerryRequirements && gBattleMons[battler].hp == gBattleMons[battler].maxHP)
|
||||
&& (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)))
|
||||
{
|
||||
|
@ -6913,7 +6913,7 @@ static u8 DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category)
|
|||
|| (!DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
|
||||
&& GetBattleMoveCategory(gCurrentMove) == category
|
||||
&& battler != gBattlerAttacker
|
||||
&& TARGET_TURN_DAMAGED))
|
||||
&& BATTLER_TURN_DAMAGED(battler)))
|
||||
)
|
||||
{
|
||||
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
||||
|
@ -10936,6 +10936,10 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
|
|||
if (GetBattlerTeraType(battler) == formChanges[i].param1)
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
case FORM_CHANGE_BATTLE_ATTACK:
|
||||
case FORM_CHANGE_BATTLE_KINGS_SHIELD:
|
||||
targetSpecies = formChanges[i].targetSpecies;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12217,7 +12217,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
|||
{
|
||||
.name = COMPOUND_STRING("Coil"),
|
||||
.description = COMPOUND_STRING(
|
||||
"Coils up to raise Attack\n"
|
||||
"Coils up to raise Attack,\n"
|
||||
"Defense and Accuracy."),
|
||||
.effect = EFFECT_COIL,
|
||||
.power = 0,
|
||||
|
@ -17335,7 +17335,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
|||
.name = COMPOUND_STRING("Octolock"),
|
||||
.description = COMPOUND_STRING(
|
||||
"Traps the foe to lower Def\n"
|
||||
"and Sp. Def fall each turn."),
|
||||
"and Sp. Def each turn."),
|
||||
.effect = EFFECT_OCTOLOCK,
|
||||
.power = 0,
|
||||
.type = TYPE_FIGHTING,
|
||||
|
@ -20610,6 +20610,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
|||
.priority = 0,
|
||||
.category = DAMAGE_CATEGORY_PHYSICAL,
|
||||
.makesContact = TRUE,
|
||||
.minimizeDoubleDamage = TRUE,
|
||||
.battleAnimScript = gBattleAnimMove_SupercellSlam,
|
||||
},
|
||||
|
||||
|
|
|
@ -789,9 +789,11 @@ static const struct FormChange sFurfrouFormChangeTable[] = {
|
|||
|
||||
#if P_FAMILY_HONEDGE
|
||||
static const struct FormChange sAegislashFormChangeTable[] = {
|
||||
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_AEGISLASH_SHIELD},
|
||||
{FORM_CHANGE_FAINT, SPECIES_AEGISLASH_SHIELD},
|
||||
{FORM_CHANGE_END_BATTLE, SPECIES_AEGISLASH_SHIELD},
|
||||
{FORM_CHANGE_BATTLE_ATTACK, SPECIES_AEGISLASH_BLADE},
|
||||
{FORM_CHANGE_BATTLE_KINGS_SHIELD, SPECIES_AEGISLASH_SHIELD},
|
||||
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_AEGISLASH_SHIELD},
|
||||
{FORM_CHANGE_FAINT, SPECIES_AEGISLASH_SHIELD},
|
||||
{FORM_CHANGE_END_BATTLE, SPECIES_AEGISLASH_SHIELD},
|
||||
{FORM_CHANGE_TERMINATOR},
|
||||
};
|
||||
#endif //P_FAMILY_HONEDGE
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(B_PROTEAN_LIBERO == GEN_9);
|
||||
ASSUME(B_DAUNTLESS_SHIELD == GEN_9);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Dauntless Shield raises Defense by one stage")
|
||||
|
|
|
@ -246,7 +246,7 @@ DOUBLE_BATTLE_TEST("Intimidate is not going to trigger if a mon switches out thr
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutralizing Gas")
|
||||
SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutralizing Gas - switching out")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||
|
@ -263,3 +263,91 @@ SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutral
|
|||
SEND_IN_MESSAGE("Wobbuffet");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - switching moves")
|
||||
{
|
||||
u32 move;
|
||||
PARAMETRIZE { move = MOVE_U_TURN; }
|
||||
PARAMETRIZE { move = MOVE_HEALING_WISH; }
|
||||
PARAMETRIZE { move = MOVE_BATON_PASS; }
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE);
|
||||
ASSUME(gMovesInfo[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH);
|
||||
ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); SEND_OUT(player, 1); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS);
|
||||
MESSAGE("Neutralizing gas filled the area!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
|
||||
SEND_IN_MESSAGE("Wobbuffet");
|
||||
} THEN {
|
||||
if (move == MOVE_HEALING_WISH)
|
||||
EXPECT_EQ(player->hp, player->maxHP);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - opponent caused switches")
|
||||
{
|
||||
u32 move, item;
|
||||
PARAMETRIZE { move = MOVE_TACKLE; item = ITEM_EJECT_BUTTON; }
|
||||
PARAMETRIZE { move = MOVE_GROWL; item = ITEM_EJECT_PACK; }
|
||||
PARAMETRIZE { move = MOVE_ROAR; item = ITEM_NONE; }
|
||||
PARAMETRIZE { move = MOVE_DRAGON_TAIL; item = ITEM_NONE; }
|
||||
GIVEN {
|
||||
ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON);
|
||||
ASSUME(gItemsInfo[ITEM_EJECT_PACK].holdEffect == HOLD_EFFECT_EJECT_PACK);
|
||||
ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
|
||||
ASSUME(gMovesInfo[MOVE_ROAR].effect == EFFECT_ROAR);
|
||||
ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); Item(item); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); }
|
||||
} WHEN {
|
||||
if (item != ITEM_NONE) {
|
||||
TURN { MOVE(opponent, move); SEND_OUT(player, 1); }
|
||||
} else {
|
||||
TURN { MOVE(opponent, move); }
|
||||
}
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS);
|
||||
MESSAGE("Neutralizing gas filled the area!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
if (item != ITEM_NONE)
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
|
||||
if (item != ITEM_NONE) {
|
||||
SEND_IN_MESSAGE("Wobbuffet");
|
||||
} else {
|
||||
MESSAGE("Wobbuffet was dragged out!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - fainted")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_FELL_STINGER].effect == EFFECT_FELL_STINGER);
|
||||
PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); HP(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_FELL_STINGER); SEND_OUT(player, 1); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS);
|
||||
MESSAGE("Neutralizing gas filled the area!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FELL_STINGER, opponent);
|
||||
MESSAGE("The effects of the neutralizing gas wore off!");
|
||||
ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
|
||||
MESSAGE("Weezing fainted!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||
SEND_IN_MESSAGE("Wobbuffet");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
67
test/battle/hold_effect/blunder_policy.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gItemsInfo[ITEM_BLUNDER_POLICY].holdEffect == HOLD_EFFECT_BLUNDER_POLICY);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Blunder Policy raises the users speed by 2 stages if the user misses")
|
||||
{
|
||||
PASSES_RANDOMLY(3, 10, RNG_ACCURACY);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FOCUS_BLAST); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
} THEN {
|
||||
EXPECT(player->item == ITEM_NONE);
|
||||
EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SINGLE_BATTLE_TEST("Blunder Policy will never trigger if the move fails due to an immunity")
|
||||
{
|
||||
PASSES_RANDOMLY(10, 10, RNG_ACCURACY);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); }
|
||||
OPPONENT(SPECIES_GASTLY);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FOCUS_BLAST); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
}
|
||||
} THEN {
|
||||
EXPECT(player->item == ITEM_BLUNDER_POLICY);
|
||||
EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Blunder Policy will never trigger if the move fails due to Protect")
|
||||
{
|
||||
PASSES_RANDOMLY(10, 10, RNG_ACCURACY);
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].accuracy == 70);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_FOCUS_BLAST); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
}
|
||||
} THEN {
|
||||
EXPECT(player->item == ITEM_BLUNDER_POLICY);
|
||||
EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
|
@ -58,3 +58,19 @@ SINGLE_BATTLE_TEST("Enigma Berry does nothing if Heal Block applies")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Enigma Berry doesn't trigger if partner was hit")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_ENIGMA_BERRY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
|
||||
} THEN {
|
||||
EXPECT(opponentRight->item == ITEM_ENIGMA_BERRY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,3 +73,19 @@ SINGLE_BATTLE_TEST("Kee Berry doesn't trigger if the item hold user used a physi
|
|||
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Kee Berry doesn't trigger if partner was hit")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_KEE_BERRY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
|
||||
} THEN {
|
||||
EXPECT(opponentRight->item == ITEM_KEE_BERRY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,3 +73,19 @@ SINGLE_BATTLE_TEST("Maranga Berry doesn't trigger if the item hold user used a s
|
|||
EXPECT_EQ(player->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Maranga Berry doesn't trigger if partner was hit")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT) { Item(ITEM_MARANGA_BERRY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
|
||||
} THEN {
|
||||
EXPECT(opponentRight->item == ITEM_MARANGA_BERRY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -468,3 +468,25 @@ SINGLE_BATTLE_TEST("Red Card prevents Emergency Exit activation when triggered")
|
|||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed");
|
||||
|
||||
SINGLE_BATTLE_TEST("Red Card activates before Eject Pack")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(MoveHasAdditionalEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_OVERHEAT); MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_OVERHEAT, player);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Wobbuffet is switched out with the Eject Button!");
|
||||
}
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
|
||||
MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,3 +26,21 @@ SINGLE_BATTLE_TEST("Confusion adds a 50/33% chance to hit self with 40 power")
|
|||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Confusion self hit does not consume Gems")
|
||||
{
|
||||
PASSES_RANDOMLY(B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50, 100, RNG_CONFUSION);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_CONFUSE_RAY); MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Normal Gem strengthened Wobbuffet's power!");
|
||||
}
|
||||
MESSAGE("It hurt itself in its confusion!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1545,6 +1545,7 @@ static void fprint_species(FILE *f, const char *prefix, struct String s)
|
|||
static const unsigned char *male = (unsigned char *)u8"♂";
|
||||
static const unsigned char *female = (unsigned char *)u8"♀";
|
||||
static const unsigned char *e_diacritic = (unsigned char *)u8"é";
|
||||
static const unsigned char *right_single_quotation_mark = (unsigned char *)u8"’";
|
||||
for (int i = 0; i < s.string_n; i++)
|
||||
{
|
||||
unsigned char c = s.string[i];
|
||||
|
@ -1562,7 +1563,7 @@ static void fprint_species(FILE *f, const char *prefix, struct String s)
|
|||
underscore = false;
|
||||
fputc(c - 'a' + 'A', f);
|
||||
}
|
||||
else if (c == '\'' || c == '%')
|
||||
else if (c == '\'' || c == '%' || is_utf8_character(s, &i, right_single_quotation_mark))
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
|
|