Fixes Magician for spread moves (#8170)
This commit is contained in:
parent
43f9a78da5
commit
6c383fac96
@ -7111,7 +7111,7 @@ BattleScript_RecoilEnd::
|
||||
return
|
||||
|
||||
BattleScript_ItemSteal::
|
||||
playanimation BS_TARGET, B_ANIM_ITEM_STEAL
|
||||
playanimation BS_EFFECT_BATTLER, B_ANIM_ITEM_STEAL
|
||||
printstring STRINGID_PKMNSTOLEITEM
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
@ -9122,6 +9122,7 @@ BattleScript_Pickpocket::
|
||||
call BattleScript_AbilityPopUp
|
||||
jumpifability BS_ATTACKER, ABILITY_STICKY_HOLD, BattleScript_PickpocketPrevented
|
||||
swapattackerwithtarget
|
||||
copybyte gEffectBattler, gBattlerTarget
|
||||
call BattleScript_ItemSteal
|
||||
swapattackerwithtarget
|
||||
activateitemeffects
|
||||
|
||||
@ -303,7 +303,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
||||
[STRINGID_PKMNTRYINGTOTAKEFOE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is hoping to take its attacker down with it!"),
|
||||
[STRINGID_PKMNTOOKFOE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} took its attacker down with it!"),
|
||||
[STRINGID_PKMNREDUCEDPP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s PP was reduced!"),
|
||||
[STRINGID_PKMNSTOLEITEM] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} stole {B_DEF_NAME_WITH_PREFIX2}'s {B_LAST_ITEM}!"),
|
||||
[STRINGID_PKMNSTOLEITEM] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} stole {B_EFF_NAME_WITH_PREFIX2}'s {B_LAST_ITEM}!"),
|
||||
[STRINGID_TARGETCANTESCAPENOW] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} can no longer escape!"),
|
||||
[STRINGID_PKMNFELLINTONIGHTMARE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} began having a nightmare!"),
|
||||
[STRINGID_PKMNLOCKEDINNIGHTMARE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is locked in a nightmare!"),
|
||||
|
||||
@ -2831,11 +2831,11 @@ static void CheckSetUnburden(u8 battler)
|
||||
gDisableStructs[battler].unburdenActive = TRUE;
|
||||
}
|
||||
|
||||
// battlerStealer steals the item of battlerItem
|
||||
void StealTargetItem(u8 battlerStealer, u8 battlerItem)
|
||||
// battlerStealer steals the item of itemBattler
|
||||
void StealTargetItem(u8 battlerStealer, u8 itemBattler)
|
||||
{
|
||||
gLastUsedItem = gBattleMons[battlerItem].item;
|
||||
gBattleMons[battlerItem].item = ITEM_NONE;
|
||||
gLastUsedItem = gBattleMons[itemBattler].item;
|
||||
gBattleMons[itemBattler].item = ITEM_NONE;
|
||||
|
||||
if (GetGenConfig(GEN_STEAL_WILD_ITEMS) >= GEN_9
|
||||
&& !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))
|
||||
@ -2854,16 +2854,16 @@ void StealTargetItem(u8 battlerStealer, u8 battlerItem)
|
||||
MarkBattlerForControllerExec(battlerStealer);
|
||||
}
|
||||
|
||||
RecordItemEffectBattle(battlerItem, ITEM_NONE);
|
||||
CheckSetUnburden(battlerItem);
|
||||
RecordItemEffectBattle(itemBattler, ITEM_NONE);
|
||||
CheckSetUnburden(itemBattler);
|
||||
|
||||
BtlController_EmitSetMonData(battlerItem, B_COMM_TO_CONTROLLER, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].item), &gBattleMons[battlerItem].item); // remove target item
|
||||
MarkBattlerForControllerExec(battlerItem);
|
||||
BtlController_EmitSetMonData(itemBattler, B_COMM_TO_CONTROLLER, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[itemBattler].item), &gBattleMons[itemBattler].item); // remove target item
|
||||
MarkBattlerForControllerExec(itemBattler);
|
||||
|
||||
if (GetBattlerAbility(gBattlerTarget) != ABILITY_GORILLA_TACTICS)
|
||||
gBattleStruct->choicedMove[gBattlerTarget] = MOVE_NONE;
|
||||
if (GetBattlerAbility(itemBattler) != ABILITY_GORILLA_TACTICS)
|
||||
gBattleStruct->choicedMove[itemBattler] = MOVE_NONE;
|
||||
|
||||
TrySaveExchangedItem(battlerItem, gLastUsedItem);
|
||||
TrySaveExchangedItem(itemBattler, gLastUsedItem);
|
||||
}
|
||||
|
||||
static inline bool32 TrySetReflect(u32 battler)
|
||||
@ -5597,22 +5597,54 @@ static bool32 HandleMoveEndAbilityBlock(u32 battlerAtk, u32 battlerDef, u32 move
|
||||
switch (abilityAtk)
|
||||
{
|
||||
case ABILITY_MAGICIAN:
|
||||
if (move != MOVE_FLING && move != MOVE_NATURAL_GIFT
|
||||
if (GetMoveEffect(move) != EFFECT_FLING
|
||||
&& GetMoveEffect(move) != EFFECT_NATURAL_GIFT
|
||||
&& gBattleMons[battlerAtk].item == ITEM_NONE
|
||||
&& gBattleMons[battlerDef].item != ITEM_NONE
|
||||
&& IsBattlerAlive(battlerAtk)
|
||||
&& IsBattlerTurnDamaged(battlerDef)
|
||||
&& CanStealItem(battlerAtk, battlerDef, gBattleMons[battlerDef].item)
|
||||
&& !gSpecialStatuses[battlerAtk].gemBoost // In base game, gems are consumed after magician would activate.
|
||||
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(battlerDef)] & (1u << gBattlerPartyIndexes[battlerDef]))
|
||||
&& !DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
&& (GetBattlerAbility(battlerDef) != ABILITY_STICKY_HOLD || !IsBattlerAlive(battlerDef)))
|
||||
&& !gSpecialStatuses[battlerAtk].gemBoost) // In base game, gems are consumed after magician would activate.
|
||||
{
|
||||
StealTargetItem(battlerAtk, battlerDef);
|
||||
gBattleScripting.battler = gBattlerAbility = battlerAtk;
|
||||
gEffectBattler = battlerDef;
|
||||
BattleScriptCall(BattleScript_MagicianActivates);
|
||||
effect = TRUE;
|
||||
u32 numMagicianTargets = 0;
|
||||
u32 magicianTargets = 0;
|
||||
|
||||
for (u32 i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].item != ITEM_NONE
|
||||
&& i != battlerAtk
|
||||
&& IsBattlerTurnDamaged(i)
|
||||
&& CanStealItem(battlerAtk, i, gBattleMons[i].item)
|
||||
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(i)] & (1u << gBattlerPartyIndexes[i]))
|
||||
&& !DoesSubstituteBlockMove(battlerAtk, i, move)
|
||||
&& (GetBattlerAbility(i) != ABILITY_STICKY_HOLD || !IsBattlerAlive(i)))
|
||||
{
|
||||
magicianTargets |= 1u << i;
|
||||
numMagicianTargets++;
|
||||
}
|
||||
}
|
||||
|
||||
if (numMagicianTargets == 0)
|
||||
{
|
||||
effect = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
u8 battlers[4] = {0, 1, 2, 3};
|
||||
if (numMagicianTargets > 1)
|
||||
SortBattlersBySpeed(battlers, FALSE);
|
||||
|
||||
for (u32 i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
u32 battler = battlers[i];
|
||||
|
||||
if (!(magicianTargets & 1u << battler))
|
||||
continue;
|
||||
|
||||
StealTargetItem(battlerAtk, battler);
|
||||
gBattlerAbility = battlerAtk;
|
||||
gEffectBattler = battler;
|
||||
BattleScriptCall(BattleScript_MagicianActivates);
|
||||
effect = TRUE;
|
||||
break; // found target to steal from
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ABILITY_MOXIE:
|
||||
@ -5775,6 +5807,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
||||
gBattleMons[gBattlerAttacker].item = ITEM_NONE; // Item assigned later on with thief (see MOVEEND_CHANGED_ITEMS)
|
||||
gBattleStruct->changedItems[gBattlerAttacker] = gLastUsedItem; // Stolen item to be assigned later
|
||||
}
|
||||
gEffectBattler = gBattlerTarget;
|
||||
BattleScriptCall(BattleScript_ItemSteal);
|
||||
effect = TRUE;
|
||||
}
|
||||
|
||||
@ -25,3 +25,31 @@ SINGLE_BATTLE_TEST("Magician gets self-damage recoil after stealing Life Orb")
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Magician steal the item from the fastest possible target")
|
||||
{
|
||||
u32 playerRightSpeed = 0;
|
||||
u32 opponentLeftSpeed = 0;
|
||||
u32 opponentRightSpeed = 0;
|
||||
|
||||
PARAMETRIZE { playerRightSpeed = 4; opponentLeftSpeed = 2; opponentRightSpeed = 3; }
|
||||
PARAMETRIZE { playerRightSpeed = 3; opponentLeftSpeed = 4; opponentRightSpeed = 2; }
|
||||
PARAMETRIZE { playerRightSpeed = 2; opponentLeftSpeed = 3; opponentRightSpeed = 4; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DELPHOX) { Speed(1); Ability(ABILITY_MAGICIAN); Item(ITEM_NONE); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(playerRightSpeed); Item(ITEM_POKE_BALL); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(opponentLeftSpeed); Item(ITEM_GREAT_BALL); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(opponentRightSpeed); Item(ITEM_ULTRA_BALL); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_SURF); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(playerLeft, ABILITY_MAGICIAN);
|
||||
} THEN {
|
||||
if (playerRightSpeed == 4)
|
||||
EXPECT(playerLeft->item == ITEM_POKE_BALL);
|
||||
else if (opponentLeftSpeed == 4)
|
||||
EXPECT(playerLeft->item == ITEM_GREAT_BALL);
|
||||
else if (playerRightSpeed == 4)
|
||||
EXPECT(playerLeft->item == ITEM_ULTRA_BALL);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user