Merge pull request #1360 from ghoulslash/prankster

Prankster Gen 7
This commit is contained in:
ultima-soul 2021-09-23 12:27:15 -07:00 committed by GitHub
commit 3b951aeb83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 97 additions and 9 deletions

View File

@ -1797,6 +1797,11 @@
.4byte \ptr .4byte \ptr
.endm .endm
.macro jumpifpranksterblocked battler:req, ptr:req
various \battler, VARIOUS_JUMP_IF_PRANKSTER_BLOCKED
.4byte \ptr
.endm
.macro eeriespellppreduce ptr:req .macro eeriespellppreduce ptr:req
various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE
.4byte \ptr .4byte \ptr

View File

@ -3867,19 +3867,25 @@ BattleScript_EffectPerishSong::
waitanimation waitanimation
printstring STRINGID_FAINTINTHREE printstring STRINGID_FAINTINTHREE
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
setbyte sBATTLER, 0 setbyte gBattlerTarget, 0
BattleScript_PerishSongLoop:: BattleScript_PerishSongLoop::
jumpifability BS_SCRIPTING, ABILITY_SOUNDPROOF, BattleScript_PerishSongNotAffected jumpifability BS_TARGET, ABILITY_SOUNDPROOF, BattleScript_PerishSongBlocked
jumpifpranksterblocked BS_TARGET, BattleScript_PerishSongNotAffected
BattleScript_PerishSongLoopIncrement:: BattleScript_PerishSongLoopIncrement::
addbyte sBATTLER, 1 addbyte gBattlerTarget, 1
jumpifbytenotequal sBATTLER, gBattlersCount, BattleScript_PerishSongLoop jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_PerishSongLoop
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_PerishSongNotAffected:: BattleScript_PerishSongBlocked::
printstring STRINGID_PKMNSXBLOCKSY2 printstring STRINGID_PKMNSXBLOCKSY2
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
goto BattleScript_PerishSongLoopIncrement goto BattleScript_PerishSongLoopIncrement
BattleScript_PerishSongNotAffected:
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
goto BattleScript_PerishSongLoopIncrement
BattleScript_EffectSandstorm:: BattleScript_EffectSandstorm::
attackcanceler attackcanceler
attackstring attackstring
@ -6328,6 +6334,17 @@ BattleScript_MagicCoatBounce::
setmagiccoattarget BS_ATTACKER setmagiccoattarget BS_ATTACKER
return return
BattleScript_MagicCoatBouncePrankster::
attackstring
ppreduce
pause B_WAIT_TIME_SHORT
printfromtable gMagicCoatBounceStringIds
waitmessage B_WAIT_TIME_LONG
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
goto BattleScript_MoveEnd
BattleScript_SnatchedMove:: BattleScript_SnatchedMove::
attackstring attackstring
ppreduce ppreduce
@ -8310,3 +8327,12 @@ BattleScript_EjectPackActivate_End2::
BattleScript_EjectPackActivates:: BattleScript_EjectPackActivates::
jumpifcantswitch BS_SCRIPTING, BattleScript_EjectButtonEnd jumpifcantswitch BS_SCRIPTING, BattleScript_EjectButtonEnd
goto BattleScript_EjectPackActivate_Ret goto BattleScript_EjectPackActivate_Ret
BattleScript_DarkTypePreventsPrankster::
attackstring
ppreduce
pause B_WAIT_TIME_SHORT
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
goto BattleScript_MoveEnd

View File

@ -149,6 +149,7 @@ struct ProtectStruct
u32 touchedProtectLike:1; u32 touchedProtectLike:1;
u32 disableEjectPack:1; u32 disableEjectPack:1;
u32 statFell:1; u32 statFell:1;
u32 pranksterElevated:1;
u32 physicalDmg; u32 physicalDmg;
u32 specialDmg; u32 specialDmg;
u8 physicalBattlerId; u8 physicalBattlerId;

View File

@ -97,6 +97,7 @@ extern const u8 BattleScript_SelectingImprisonedMove[];
extern const u8 BattleScript_SelectingImprisonedMoveInPalace[]; extern const u8 BattleScript_SelectingImprisonedMoveInPalace[];
extern const u8 BattleScript_GrudgeTakesPp[]; extern const u8 BattleScript_GrudgeTakesPp[];
extern const u8 BattleScript_MagicCoatBounce[]; extern const u8 BattleScript_MagicCoatBounce[];
extern const u8 BattleScript_MagicCoatBouncePrankster[];
extern const u8 BattleScript_SnatchedMove[]; extern const u8 BattleScript_SnatchedMove[];
extern const u8 BattleScript_EnduredMsg[]; extern const u8 BattleScript_EnduredMsg[];
extern const u8 BattleScript_OneHitKOMsg[]; extern const u8 BattleScript_OneHitKOMsg[];
@ -384,5 +385,6 @@ extern const u8 BattleScript_MentalHerbCureEnd2[];
extern const u8 BattleScript_TerrainPreventsEnd2[]; extern const u8 BattleScript_TerrainPreventsEnd2[];
extern const u8 BattleScript_MistyTerrainPrevents[]; extern const u8 BattleScript_MistyTerrainPrevents[];
extern const u8 BattleScript_ElectricTerrainPrevents[]; extern const u8 BattleScript_ElectricTerrainPrevents[];
extern const u8 BattleScript_DarkTypePreventsPrankster[];
#endif // GUARD_BATTLE_SCRIPTS_H #endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -152,6 +152,7 @@ bool32 CompareStat(u8 battlerId, u8 statId, u8 cmpTo, u8 cmpKind);
bool32 TryRoomService(u8 battlerId); bool32 TryRoomService(u8 battlerId);
void BufferStatChange(u8 battlerId, u8 statId, u8 stringId); void BufferStatChange(u8 battlerId, u8 statId, u8 stringId);
void DoBurmyFormChange(u32 monId); void DoBurmyFormChange(u32 monId);
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef);
// ability checks // ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability); bool32 IsRolePlayBannedAbilityAtk(u16 ability);

View File

@ -128,6 +128,7 @@
#define B_FLASH_FIRE_FROZEN GEN_7 // In Gen5+, Flash Fire can trigger even when frozen, when it couldn't before. #define B_FLASH_FIRE_FROZEN GEN_7 // In Gen5+, Flash Fire can trigger even when frozen, when it couldn't before.
#define B_SYNCHRONIZE_NATURE GEN_8 // In Gen8, if the Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same ability, as opposed to 50% previously. #define B_SYNCHRONIZE_NATURE GEN_8 // In Gen8, if the Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same ability, as opposed to 50% previously.
#define B_UPDATED_INTIMIDATE GEN_8 // In Gen8, Intimidate doesn't work on opponents with the Inner Focus, Scrappy, Own Tempo or Oblivious abilities. #define B_UPDATED_INTIMIDATE GEN_8 // In Gen8, Intimidate doesn't work on opponents with the Inner Focus, Scrappy, Own Tempo or Oblivious abilities.
#define B_PRANKSTER_DARK_TYPES GEN_7 // In Gen7+, Prankster-elevated status moves do not affect Dark type Pokémon.
// Item settings // Item settings
#define B_HP_BERRIES GEN_7 // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn. #define B_HP_BERRIES GEN_7 // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.

View File

@ -183,6 +183,7 @@
#define VARIOUS_JUMP_IF_TEAM_HEALTHY 111 #define VARIOUS_JUMP_IF_TEAM_HEALTHY 111
#define VARIOUS_TRY_HEAL_QUARTER_HP 112 #define VARIOUS_TRY_HEAL_QUARTER_HP 112
#define VARIOUS_REMOVE_TERRAIN 113 #define VARIOUS_REMOVE_TERRAIN 113
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0

View File

@ -4302,6 +4302,7 @@ s8 GetChosenMovePriority(u32 battlerId)
{ {
u16 move; u16 move;
gProtectStructs[battlerId].pranksterElevated = 0;
if (gProtectStructs[battlerId].noValidMoves) if (gProtectStructs[battlerId].noValidMoves)
move = MOVE_STRUGGLE; move = MOVE_STRUGGLE;
else else
@ -4323,6 +4324,7 @@ s8 GetMovePriority(u32 battlerId, u16 move)
} }
else if (GetBattlerAbility(battlerId) == ABILITY_PRANKSTER && IS_MOVE_STATUS(move)) else if (GetBattlerAbility(battlerId) == ABILITY_PRANKSTER && IS_MOVE_STATUS(move))
{ {
gProtectStructs[battlerId].pranksterElevated = 1;
priority++; priority++;
} }
else if (gBattleMoves[move].effect == EFFECT_GRASSY_GLIDE && gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerGrounded(battlerId)) else if (gBattleMoves[move].effect == EFFECT_GRASSY_GLIDE && gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerGrounded(battlerId))

View File

@ -1416,8 +1416,17 @@ static void Cmd_attackcanceler(void)
gProtectStructs[gBattlerTarget].bounceMove = 0; gProtectStructs[gBattlerTarget].bounceMove = 0;
gProtectStructs[gBattlerTarget].usesBouncedMove = 1; gProtectStructs[gBattlerTarget].usesBouncedMove = 1;
gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattleCommunication[MULTISTRING_CHOOSER] = 0;
BattleScriptPushCursor(); if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker))
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce; {
// Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker
gBattlerTarget = gBattlerAttacker;
gBattlescriptCurrInstr = BattleScript_MagicCoatBouncePrankster;
}
else
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce;
}
return; return;
} }
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE else if (GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE
@ -5092,6 +5101,7 @@ static void Cmd_moveend(void)
MoveValuesCleanUp(); MoveValuesCleanUp();
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect; gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]);
gBattleStruct->atkCancellerTracker = 0; // Run all cancellers on next target
gBattlescriptCurrInstr = BattleScript_FlushMessageBox; gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return; return;
} }
@ -6573,6 +6583,7 @@ static void Cmd_jumptocalledmove(void)
else else
gChosenMove = gCurrentMove = gCalledMove; gChosenMove = gCurrentMove = gCalledMove;
gBattleStruct->atkCancellerTracker = 0;
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
} }
@ -8721,6 +8732,12 @@ static void Cmd_various(void)
} }
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain
break; break;
case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
} }
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;
@ -10883,7 +10900,8 @@ static void Cmd_trysetperishsong(void)
for (i = 0; i < gBattlersCount; i++) for (i = 0; i < gBattlersCount; i++)
{ {
if (gStatuses3[i] & STATUS3_PERISH_SONG if (gStatuses3[i] & STATUS3_PERISH_SONG
|| gBattleMons[i].ability == ABILITY_SOUNDPROOF) || gBattleMons[i].ability == ABILITY_SOUNDPROOF
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i))
{ {
notAffectedCount++; notAffectedCount++;
} }

View File

@ -3087,6 +3087,7 @@ enum
CANCELLER_POWDER_MOVE, CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS, CANCELLER_POWDER_STATUS,
CANCELLER_THROAT_CHOP, CANCELLER_THROAT_CHOP,
CANCELLER_PRANKSTER,
CANCELLER_END, CANCELLER_END,
CANCELLER_PSYCHIC_TERRAIN, CANCELLER_PSYCHIC_TERRAIN,
CANCELLER_END2, CANCELLER_END2,
@ -3414,6 +3415,18 @@ u8 AtkCanceller_UnableToUseMove(void)
} }
gBattleStruct->atkCancellerTracker++; gBattleStruct->atkCancellerTracker++;
break; break;
case CANCELLER_PRANKSTER:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget)
&& !(IS_MOVE_STATUS(gCurrentMove) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE))
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster;
effect = 1;
}
gBattleStruct->atkCancellerTracker++;
break;
case CANCELLER_END: case CANCELLER_END:
break; break;
} }
@ -6836,7 +6849,11 @@ u8 GetMoveTarget(u16 move, u8 setTarget)
moveTarget = setTarget - 1; moveTarget = setTarget - 1;
else else
moveTarget = gBattleMoves[move].target; moveTarget = gBattleMoves[move].target;
// Special cases
if (move == MOVE_CURSE && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
moveTarget = MOVE_TARGET_USER;
switch (moveTarget) switch (moveTarget)
{ {
case MOVE_TARGET_SELECTED: case MOVE_TARGET_SELECTED:
@ -9230,3 +9247,17 @@ void DoBurmyFormChange(u32 monId)
} }
} }
} }
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef)
{
#if B_PRANKSTER_DARK_TYPES >= GEN_7
if (gProtectStructs[battlerPrankster].pranksterElevated
&& GetBattlerSide(battlerPrankster) != GetBattlerSide(battlerDef)
&& !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)) // Don't block hazards, assist-type moves
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) // Only Dark-types can block Prankster'd
&& !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE))
return TRUE;
else
#endif
return FALSE;
}