Merge branch 'battle_engine' into battle_bond

This commit is contained in:
BuffelSaft 2021-10-14 16:24:59 +13:00
commit fc6e8f598c
10 changed files with 214 additions and 85 deletions

View File

@ -1825,6 +1825,16 @@
various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER
.endm .endm
.macro getrototillertargets ptr:req
various BS_ATTACKER, VARIOUS_GET_ROTOTILLER_TARGETS
.4byte \ptr
.endm
.macro jumpifnotrototilleraffected battler:req, ptr:req
various \battler, VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED
.4byte \ptr
.endm
.macro tryactivatebattlebond battler:req .macro tryactivatebattlebond battler:req
various \battler, VARIOUS_TRY_ACTIVATE_BATTLE_BOND various \battler, VARIOUS_TRY_ACTIVATE_BATTLE_BOND
.endm .endm

View File

@ -952,22 +952,19 @@ BattleScript_EffectRototiller:
attackcanceler attackcanceler
attackstring attackstring
ppreduce ppreduce
selectfirstvalidtarget getrototillertargets BattleScript_ButItFailed
BattleScript_RototillerLoop: @ at least one battler is affected
movevaluescleanup
jumpifnotgrounded BS_TARGET, BattleScript_RototillerNoEffect
jumpiftype BS_TARGET, TYPE_GRASS, BattleScript_RototillerLoop2
BattleScript_RototillerNoEffect:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NOEFFECTONTARGET
waitmessage B_WAIT_TIME_LONG
goto BattleScript_RototillerMoveTargetEnd
BattleScript_RototillerLoop2:
jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerDoMoveAnim
jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats
BattleScript_RototillerDoMoveAnim::
attackanimation attackanimation
waitanimation waitanimation
savetarget
setbyte gBattlerTarget, 0
BattleScript_RototillerLoop:
movevaluescleanup
jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_RototillerCheckAffected
jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, MAX_STAT_STAGE, BattleScript_RototillerCantRaiseMultipleStats
BattleScript_RototillerCheckAffected:
jumpifnotrototilleraffected BS_TARGET, BattleScript_RototillerNoEffect
BattleScript_RototillerAffected:
setbyte sSTAT_ANIM_PLAYED, FALSE setbyte sSTAT_ANIM_PLAYED, FALSE
playstatchangeanimation BS_TARGET, BIT_ATK | BIT_SPATK, 0 playstatchangeanimation BS_TARGET, BIT_ATK | BIT_SPATK, 0
setstatchanger STAT_ATK, 1, FALSE setstatchanger STAT_ATK, 1, FALSE
@ -983,13 +980,22 @@ BattleScript_RototillerTrySpAtk::
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
BattleScript_RototillerMoveTargetEnd: BattleScript_RototillerMoveTargetEnd:
moveendto MOVEEND_NEXT_TARGET moveendto MOVEEND_NEXT_TARGET
jumpifnexttargetvalid BattleScript_RototillerLoop addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_RototillerLoop
end end
BattleScript_RototillerCantRaiseMultipleStats: BattleScript_RototillerCantRaiseMultipleStats:
copybyte gBattlerAttacker, gBattlerTarget
printstring STRINGID_STATSWONTINCREASE2 printstring STRINGID_STATSWONTINCREASE2
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
goto BattleScript_RototillerMoveTargetEnd goto BattleScript_RototillerMoveTargetEnd
BattleScript_RototillerNoEffect:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NOEFFECTONTARGET
waitmessage B_WAIT_TIME_LONG
goto BattleScript_RototillerMoveTargetEnd
BattleScript_EffectBestow: BattleScript_EffectBestow:
attackcanceler attackcanceler
accuracycheck BattleScript_PrintMoveMissed, NO_ACC_CALC_CHECK_LOCK_ON accuracycheck BattleScript_PrintMoveMissed, NO_ACC_CALC_CHECK_LOCK_ON

View File

@ -175,6 +175,7 @@ struct SpecialStatus
u8 instructedChosenTarget:3; u8 instructedChosenTarget:3;
u8 berryReduced:1; u8 berryReduced:1;
u8 gemBoost:1; u8 gemBoost:1;
u8 rototillerAffected:1; // to be affected by rototiller
u8 gemParam; u8 gemParam;
u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute. u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute.
u8 dancerUsedMove:1; u8 dancerUsedMove:1;

View File

@ -153,7 +153,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); bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
// ability checks // ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability); bool32 IsRolePlayBannedAbilityAtk(u16 ability);

View File

@ -387,4 +387,6 @@
#define MOVE_TARGET_OPPONENTS_FIELD 0x40 #define MOVE_TARGET_OPPONENTS_FIELD 0x40
#define MOVE_TARGET_ALLY 0x80 #define MOVE_TARGET_ALLY 0x80
#define MOVE_TARGET_ALL_BATTLERS (MOVE_TARGET_BOTH | MOVE_TARGET_OPPONENTS_FIELD)
#endif // GUARD_CONSTANTS_BATTLE_H #endif // GUARD_CONSTANTS_BATTLE_H

View File

@ -185,7 +185,9 @@
#define VARIOUS_REMOVE_TERRAIN 113 #define VARIOUS_REMOVE_TERRAIN 113
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114 #define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115 #define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 116 #define VARIOUS_GET_ROTOTILLER_TARGETS 116
#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 117
#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 118
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0

View File

@ -496,6 +496,19 @@ static void HandleInputChooseTarget(void)
} }
} }
static void HideAllTargets(void)
{
s32 i;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (IsBattlerAlive(i) && gBattleSpritesDataPtr->healthBoxesData[i].healthboxIsBouncing)
{
gSprites[gBattlerSpriteIds[i]].callback = SpriteCb_HideAsMoveTarget;
EndBounceEffect(i, BOUNCE_HEALTHBOX);
}
}
}
static void HideShownTargets(void) static void HideShownTargets(void)
{ {
s32 i; s32 i;
@ -509,6 +522,34 @@ static void HideShownTargets(void)
} }
} }
static void HandleInputShowEntireFieldTargets(void)
{
if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
gPlayerDpadHoldFrames++;
else
gPlayerDpadHoldFrames = 0;
if (JOY_NEW(A_BUTTON))
{
PlaySE(SE_SELECT);
HideAllTargets();
if (gBattleStruct->mega.playerSelect)
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
else
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
HideMegaTriggerSprite();
PlayerBufferExecCompleted();
}
else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59)
{
PlaySE(SE_SELECT);
HideAllTargets();
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove;
DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1);
DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1);
}
}
static void HandleInputShowTargets(void) static void HandleInputShowTargets(void)
{ {
if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
@ -601,18 +642,31 @@ static void HandleInputChooseMove(void)
} }
// Show all available targets for multi-target moves // Show all available targets for multi-target moves
if (B_SHOW_TARGETS && moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) if (B_SHOW_TARGETS)
{ {
TryShowAsTarget(gMultiUsePlayerCursor); if ((moveTarget & MOVE_TARGET_ALL_BATTLERS) == MOVE_TARGET_ALL_BATTLERS)
TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor)); {
if (moveTarget & MOVE_TARGET_FOES_AND_ALLY) u32 i = 0;
TryShowAsTarget(BATTLE_PARTNER(gActiveBattler)); for (i = 0; i < gBattlersCount; i++)
canSelectTarget = 2; TryShowAsTarget(i);
canSelectTarget = 3;
}
else if (moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
{
TryShowAsTarget(gMultiUsePlayerCursor);
TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor));
if (moveTarget & MOVE_TARGET_FOES_AND_ALLY)
TryShowAsTarget(BATTLE_PARTNER(gActiveBattler));
canSelectTarget = 2;
}
} }
} }
if (canSelectTarget == 0) switch (canSelectTarget)
{ {
case 0:
default:
if (gBattleStruct->mega.playerSelect) if (gBattleStruct->mega.playerSelect)
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
else else
@ -620,9 +674,8 @@ static void HandleInputChooseMove(void)
HideMegaTriggerSprite(); HideMegaTriggerSprite();
TryHideLastUsedBall(); TryHideLastUsedBall();
PlayerBufferExecCompleted(); PlayerBufferExecCompleted();
} break;
else if (canSelectTarget == 1) case 1:
{
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget; gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget;
if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
@ -633,10 +686,13 @@ static void HandleInputChooseMove(void)
gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCb_ShowAsMoveTarget; gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCb_ShowAsMoveTarget;
} break;
else case 2:
{
gBattlerControllerFuncs[gActiveBattler] = HandleInputShowTargets; gBattlerControllerFuncs[gActiveBattler] = HandleInputShowTargets;
break;
case 3: // Entire field
gBattlerControllerFuncs[gActiveBattler] = HandleInputShowEntireFieldTargets;
break;
} }
} }
else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59) else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59)

View File

@ -1437,7 +1437,7 @@ 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;
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker)) if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker, TRUE))
{ {
// Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker // Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker
gBattlerTarget = gBattlerAttacker; gBattlerTarget = gBattlerAttacker;
@ -4527,12 +4527,13 @@ static void Cmd_endselectionscript(void)
static void Cmd_playanimation(void) static void Cmd_playanimation(void)
{ {
const u16* argumentPtr; const u16* argumentPtr;
u8 animId = gBattlescriptCurrInstr[2];
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3); argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
#if B_TERRAIN_BG_CHANGE == FALSE #if B_TERRAIN_BG_CHANGE == FALSE
if (gBattlescriptCurrInstr[2] == B_ANIM_RESTORE_BG) if (animId == B_ANIM_RESTORE_BG)
{ {
// workaround for .if not working // workaround for .if not working
gBattlescriptCurrInstr += 7; gBattlescriptCurrInstr += 7;
@ -4540,28 +4541,28 @@ static void Cmd_playanimation(void)
} }
#endif #endif
if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE if (animId == B_ANIM_STATS_CHANGE
|| gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE || animId == B_ANIM_SNATCH_MOVE
|| gBattlescriptCurrInstr[2] == B_ANIM_MEGA_EVOLUTION || animId == B_ANIM_MEGA_EVOLUTION
|| gBattlescriptCurrInstr[2] == B_ANIM_ILLUSION_OFF || animId == B_ANIM_ILLUSION_OFF
|| gBattlescriptCurrInstr[2] == B_ANIM_FORM_CHANGE || animId == B_ANIM_FORM_CHANGE
|| gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE) || animId == B_ANIM_SUBSTITUTE_FADE)
{ {
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler); MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7; gBattlescriptCurrInstr += 7;
} }
else if (gHitMarker & HITMARKER_NO_ANIMATIONS) else if (gHitMarker & HITMARKER_NO_ANIMATIONS && animId != B_ANIM_RESTORE_BG)
{ {
BattleScriptPush(gBattlescriptCurrInstr + 7); BattleScriptPush(gBattlescriptCurrInstr + 7);
gBattlescriptCurrInstr = BattleScript_Pausex20; gBattlescriptCurrInstr = BattleScript_Pausex20;
} }
else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES else if (animId == B_ANIM_RAIN_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES || animId == B_ANIM_SUN_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES || animId == B_ANIM_SANDSTORM_CONTINUES
|| gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES) || animId == B_ANIM_HAIL_CONTINUES)
{ {
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler); MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7; gBattlescriptCurrInstr += 7;
} }
@ -4571,7 +4572,7 @@ static void Cmd_playanimation(void)
} }
else else
{ {
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); BtlController_EmitBattleAnimation(0, animId, *argumentPtr);
MarkBattlerForControllerExec(gActiveBattler); MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 7; gBattlescriptCurrInstr += 7;
} }
@ -7376,6 +7377,21 @@ static u32 GetHighestStatId(u32 battlerId)
return highestId; return highestId;
} }
static bool32 IsRototillerAffected(u32 battlerId)
{
if (!IsBattlerAlive(battlerId))
return FALSE;
if (!IsBattlerGrounded(battlerId))
return FALSE; // Only grounded battlers affected
if (!IS_BATTLER_OF_TYPE(battlerId, TYPE_GRASS))
return FALSE; // Only grass types affected
if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE)
return FALSE; // Rototiller doesn't affected semi-invulnerable battlers
if (BlocksPrankster(MOVE_ROTOTILLER, gBattlerAttacker, battlerId, FALSE))
return FALSE;
return TRUE;
}
static void Cmd_various(void) static void Cmd_various(void)
{ {
struct Pokemon *mon; struct Pokemon *mon;
@ -8784,7 +8800,7 @@ 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: case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler)) if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler, TRUE))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else else
gBattlescriptCurrInstr += 7; gBattlescriptCurrInstr += 7;
@ -8822,6 +8838,37 @@ static void Cmd_various(void)
} }
break; break;
} }
case VARIOUS_GET_ROTOTILLER_TARGETS:
// Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!'
{
u32 count = 0;
for (i = 0; i < gBattlersCount; i++)
{
gSpecialStatuses[i].rototillerAffected = FALSE;
if (IsRototillerAffected(i))
{
gSpecialStatuses[i].rototillerAffected = TRUE;
count++;
}
}
if (count == 0)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Rototiller fails
else
gBattlescriptCurrInstr += 7;
}
return;
case VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED:
if (gSpecialStatuses[gActiveBattler].rototillerAffected)
{
gSpecialStatuses[gActiveBattler].rototillerAffected = FALSE;
gBattlescriptCurrInstr += 7;
}
else
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Unaffected by rototiller - print STRINGID_NOEFFECTONTARGET
}
return;
case VARIOUS_TRY_ACTIVATE_BATTLE_BOND: case VARIOUS_TRY_ACTIVATE_BATTLE_BOND:
if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND
&& HasAttackerFaintedTarget() && HasAttackerFaintedTarget()
@ -10996,7 +11043,7 @@ static void Cmd_trysetperishsong(void)
{ {
if (gStatuses3[i] & STATUS3_PERISH_SONG if (gStatuses3[i] & STATUS3_PERISH_SONG
|| GetBattlerAbility(i) == ABILITY_SOUNDPROOF || GetBattlerAbility(i) == ABILITY_SOUNDPROOF
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i)) || BlocksPrankster(gCurrentMove, gBattlerAttacker, i, TRUE))
{ {
notAffectedCount++; notAffectedCount++;
} }

View File

@ -2234,7 +2234,7 @@ u8 DoFieldEndTurnEffects(void)
break; break;
case ENDTURN_ELECTRIC_TERRAIN: case ENDTURN_ELECTRIC_TERRAIN:
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN
&& ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0)) && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.electricTerrainTimer == 0))
{ {
gFieldStatuses &= ~(STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT); gFieldStatuses &= ~(STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT);
BattleScriptExecute(BattleScript_ElectricTerrainEnds); BattleScriptExecute(BattleScript_ElectricTerrainEnds);
@ -2244,7 +2244,7 @@ u8 DoFieldEndTurnEffects(void)
break; break;
case ENDTURN_MISTY_TERRAIN: case ENDTURN_MISTY_TERRAIN:
if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN
&& ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0)) && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.mistyTerrainTimer == 0))
{ {
gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN); gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN);
BattleScriptExecute(BattleScript_MistyTerrainEnds); BattleScriptExecute(BattleScript_MistyTerrainEnds);
@ -2266,7 +2266,7 @@ u8 DoFieldEndTurnEffects(void)
break; break;
case ENDTURN_PSYCHIC_TERRAIN: case ENDTURN_PSYCHIC_TERRAIN:
if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN
&& ((!gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0)) && (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.psychicTerrainTimer == 0))
{ {
gFieldStatuses &= ~(STATUS_FIELD_PSYCHIC_TERRAIN); gFieldStatuses &= ~(STATUS_FIELD_PSYCHIC_TERRAIN);
BattleScriptExecute(BattleScript_PsychicTerrainEnds); BattleScriptExecute(BattleScript_PsychicTerrainEnds);
@ -3436,7 +3436,7 @@ u8 AtkCanceller_UnableToUseMove(void)
gBattleStruct->atkCancellerTracker++; gBattleStruct->atkCancellerTracker++;
break; break;
case CANCELLER_PRANKSTER: case CANCELLER_PRANKSTER:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget) if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget, TRUE)
&& !(IS_MOVE_STATUS(gCurrentMove) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE)) && !(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))) if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
@ -9432,16 +9432,21 @@ void DoBurmyFormChange(u32 monId)
} }
} }
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef) bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget)
{ {
#if B_PRANKSTER_DARK_TYPES >= GEN_7 #if B_PRANKSTER_DARK_TYPES >= GEN_7
if (gProtectStructs[battlerPrankster].pranksterElevated 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; return FALSE;
if (GetBattlerSide(battlerPrankster) == GetBattlerSide(battlerDef))
return FALSE;
if (checkTarget && (gBattleMoves[move].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)))
return FALSE;
if (!IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK))
return FALSE;
if (gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)
return FALSE;
return TRUE;
#endif
return FALSE;
} }

View File

@ -1789,7 +1789,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 30, .pp = 30,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = FLAG_PROTECT_AFFECTED, .flags = FLAG_PROTECT_AFFECTED,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -3101,7 +3101,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 5, .pp = 5,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = FLAG_SOUND, .flags = FLAG_SOUND,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -3205,7 +3205,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -3809,7 +3809,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 5, .pp = 5,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -3823,7 +3823,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 5, .pp = 5,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -4130,7 +4130,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = FLAG_PROTECT_AFFECTED, .flags = FLAG_PROTECT_AFFECTED,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -4773,7 +4773,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 100, .accuracy = 100,
.pp = 15, .pp = 15,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -5513,7 +5513,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 100, .accuracy = 100,
.pp = 15, .pp = 15,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -5670,7 +5670,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 5, .pp = 5,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -6884,7 +6884,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 5, .pp = 5,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = -7, .priority = -7,
.flags = FLAG_MIRROR_MOVE_AFFECTED, .flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -7487,7 +7487,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.flags = FLAG_MIRROR_MOVE_AFFECTED, .flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
}, },
@ -7579,7 +7579,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.flags = FLAG_MIRROR_MOVE_AFFECTED, .flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
}, },
@ -8847,7 +8847,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -8941,7 +8941,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 25, .pp = 25,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 1, .priority = 1,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -9092,7 +9092,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER | MOVE_TARGET_FOES_AND_ALLY, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -9106,7 +9106,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -9120,7 +9120,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -9204,7 +9204,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = FLAG_MIRROR_MOVE_AFFECTED, .flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -9454,7 +9454,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -9974,7 +9974,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -10857,7 +10857,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 0, .accuracy = 0,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = 0, .flags = 0,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,
@ -10913,7 +10913,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
.accuracy = 100, .accuracy = 100,
.pp = 10, .pp = 10,
.secondaryEffectChance = 0, .secondaryEffectChance = 0,
.target = MOVE_TARGET_USER, .target = MOVE_TARGET_ALL_BATTLERS,
.priority = 0, .priority = 0,
.flags = FLAG_MIRROR_MOVE_AFFECTED, .flags = FLAG_MIRROR_MOVE_AFFECTED,
.split = SPLIT_STATUS, .split = SPLIT_STATUS,