mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 11:44:17 +01:00
Merge branch 'RHH/master' into RHH/upcoming
# Conflicts: # data/battle_anim_scripts.s # data/battle_scripts_1.s # include/battle_scripts.h # include/battle_util.h # src/battle_script_commands.c # src/battle_util.c
This commit is contained in:
commit
820113d883
@ -1312,6 +1312,12 @@
|
|||||||
.4byte \failInstr
|
.4byte \failInstr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
.macro jumpifcantfling battler:req, jumpInstr:req
|
||||||
|
callnative BS_JumpIfCantFling
|
||||||
|
.byte \battler
|
||||||
|
.4byte \jumpInstr
|
||||||
|
.endm
|
||||||
|
|
||||||
.macro jumpifholdeffect battler:req, holdEffect:req, jumpInstr:req
|
.macro jumpifholdeffect battler:req, holdEffect:req, jumpInstr:req
|
||||||
callnative BS_JumpIfHoldEffect
|
callnative BS_JumpIfHoldEffect
|
||||||
.byte \battler
|
.byte \battler
|
||||||
@ -2039,11 +2045,6 @@
|
|||||||
.4byte \jumpInstr
|
.4byte \jumpInstr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro jumpifcantfling battler:req, jumpInstr:req
|
|
||||||
various \battler, VARIOUS_JUMP_IF_CANT_FLING
|
|
||||||
.4byte \jumpInstr
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro curecertainstatuses battler:req
|
.macro curecertainstatuses battler:req
|
||||||
various \battler, VARIOUS_CURE_CERTAIN_STATUSES
|
various \battler, VARIOUS_CURE_CERTAIN_STATUSES
|
||||||
.endm
|
.endm
|
||||||
|
@ -1882,28 +1882,28 @@ Move_MAGNET_RISE:
|
|||||||
delay 0
|
delay 0
|
||||||
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_BATTLERS), -31, 1, 5, 5, RGB(31, 31, 20)
|
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_BATTLERS), -31, 1, 5, 5, RGB(31, 31, 20)
|
||||||
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
|
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
|
||||||
createvisualtask AnimTask_WindUpLunge, 5, ANIM_OPPONENT_RIGHT, 0, -12, 4, 10, 10, 12, 6
|
createvisualtask AnimTask_WindUpLunge, 5, ANIM_ATTACKER, -12, 4, 10, 10, 12, 6
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 32, 24, 190, 12, 0, 1, 0
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 32, 24, 190, 12, ANIM_ATTACKER, 1, 0
|
||||||
delay 0
|
delay 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 80, 24, 22, 12, 0, 1, 0
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 80, 24, 22, 12, ANIM_ATTACKER, 1, 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 156, 24, 121, 13, 0, 1, 1
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 156, 24, 121, 13, ANIM_ATTACKER, 1, 1
|
||||||
delay 0
|
delay 0
|
||||||
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
|
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
|
||||||
delay 4
|
delay 4
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 100, 24, 60, 10, 0, 1, 0
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 100, 24, 60, 10, ANIM_ATTACKER, 1, 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 170, 24, 42, 11, 0, 1, 1
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 170, 24, 42, 11, ANIM_ATTACKER, 1, 1
|
||||||
delay 0
|
delay 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 238, 24, 165, 10, 0, 1, 1
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 238, 24, 165, 10, ANIM_ATTACKER, 1, 1
|
||||||
delay 0
|
delay 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 32, 24, 190, 12, 0, 1, 0
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 32, 24, 190, 12, ANIM_ATTACKER, 1, 0
|
||||||
delay 0
|
delay 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 80, 24, 22, 12, 0, 1, 0
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 80, 24, 22, 12, ANIM_ATTACKER, 1, 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 156, 24, 121, 13, 0, 1, 1
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 156, 24, 121, 13, ANIM_ATTACKER, 1, 1
|
||||||
delay 0
|
delay 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 100, 24, 60, 10, 0, 1, 0
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 100, 24, 60, 10, ANIM_ATTACKER, 1, 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 170, 24, 42, 11, 0, 1, 1
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 170, 24, 42, 11, ANIM_ATTACKER, 1, 1
|
||||||
delay 0
|
delay 0
|
||||||
createsprite gSparkElectricitySpriteTemplate, 0, 7, 238, 24, 165, 10, 0, 1, 1
|
createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 238, 24, 165, 10, ANIM_ATTACKER, 1, 1
|
||||||
delay 0
|
delay 0
|
||||||
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_BATTLERS), -31, 1, 0, 0, RGB(31, 31, 20)
|
createvisualtask AnimTask_BlendColorCycle, 2, (F_PAL_BG | F_PAL_BATTLERS), -31, 1, 0, 0, RGB(31, 31, 20)
|
||||||
delay 20
|
delay 20
|
||||||
@ -8927,7 +8927,7 @@ Boomburst_Doubles:
|
|||||||
|
|
||||||
Move_FAIRY_LOCK::
|
Move_FAIRY_LOCK::
|
||||||
loadspritegfx ANIM_TAG_CHAIN_LINK @Chain Colour
|
loadspritegfx ANIM_TAG_CHAIN_LINK @Chain Colour
|
||||||
loadspritegfx ANIM_TAG_FAIRY_LOCK_CHAINS @Fairy Lock Chain
|
loadspritegfx ANIM_TAG_FAIRY_LOCK_CHAINS @AnimTask is missing for Fairy Lock Chain
|
||||||
setalpha 8, 8
|
setalpha 8, 8
|
||||||
monbg ANIM_ATK_PARTNER
|
monbg ANIM_ATK_PARTNER
|
||||||
createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x0, 0x8, 0x6B1F
|
createvisualtask AnimTask_BlendBattleAnimPal, 0xa, F_PAL_BG, 0x1, 0x0, 0x8, 0x6B1F
|
||||||
|
@ -918,12 +918,10 @@ BattleScript_SkyDropFlyingAlreadyConfused:
|
|||||||
goto BattleScript_ThrashConfuses
|
goto BattleScript_ThrashConfuses
|
||||||
|
|
||||||
BattleScript_EffectFling:
|
BattleScript_EffectFling:
|
||||||
|
attackcanceler
|
||||||
jumpifcantfling BS_ATTACKER, BattleScript_FailedFromAtkString
|
jumpifcantfling BS_ATTACKER, BattleScript_FailedFromAtkString
|
||||||
jumpifstatus3 BS_ATTACKER, STATUS3_EMBARGO, BattleScript_FailedFromAtkString
|
|
||||||
jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_MAGIC_ROOM, BattleScript_FailedFromAtkString
|
|
||||||
setlastuseditem BS_ATTACKER
|
setlastuseditem BS_ATTACKER
|
||||||
removeitem BS_ATTACKER
|
removeitem BS_ATTACKER
|
||||||
attackcanceler
|
|
||||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||||
attackstring
|
attackstring
|
||||||
pause B_WAIT_TIME_SHORT
|
pause B_WAIT_TIME_SHORT
|
||||||
@ -966,6 +964,10 @@ BattleScript_FlingEnd:
|
|||||||
trysymbiosis
|
trysymbiosis
|
||||||
goto BattleScript_MoveEnd
|
goto BattleScript_MoveEnd
|
||||||
|
|
||||||
|
BattleScript_FlingFailConsumeItem::
|
||||||
|
removeitem BS_ATTACKER
|
||||||
|
goto BattleScript_FailedFromAtkString
|
||||||
|
|
||||||
BattleScript_FlingFlameOrb:
|
BattleScript_FlingFlameOrb:
|
||||||
setmoveeffect MOVE_EFFECT_BURN
|
setmoveeffect MOVE_EFFECT_BURN
|
||||||
seteffectprimary
|
seteffectprimary
|
||||||
|
@ -10,6 +10,7 @@ extern const u8 BattleScript_MakeMoveMissed[];
|
|||||||
extern const u8 BattleScript_PrintMoveMissed[];
|
extern const u8 BattleScript_PrintMoveMissed[];
|
||||||
extern const u8 BattleScript_MoveMissedPause[];
|
extern const u8 BattleScript_MoveMissedPause[];
|
||||||
extern const u8 BattleScript_MoveMissed[];
|
extern const u8 BattleScript_MoveMissed[];
|
||||||
|
extern const u8 BattleScript_FlingFailConsumeItem[];
|
||||||
extern const u8 BattleScript_FailedFromAtkString[];
|
extern const u8 BattleScript_FailedFromAtkString[];
|
||||||
extern const u8 BattleScript_ButItFailed[];
|
extern const u8 BattleScript_ButItFailed[];
|
||||||
extern const u8 BattleScript_StatUp[];
|
extern const u8 BattleScript_StatUp[];
|
||||||
|
@ -192,7 +192,7 @@ void ClearIllusionMon(u32 battler);
|
|||||||
bool32 SetIllusionMon(struct Pokemon *mon, u32 battler);
|
bool32 SetIllusionMon(struct Pokemon *mon, u32 battler);
|
||||||
bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battler);
|
bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battler);
|
||||||
u8 GetBattleMoveSplit(u32 moveId);
|
u8 GetBattleMoveSplit(u32 moveId);
|
||||||
bool32 CanFling(u8 battler);
|
bool32 CanFling(u32 battler);
|
||||||
bool32 IsTelekinesisBannedSpecies(u16 species);
|
bool32 IsTelekinesisBannedSpecies(u16 species);
|
||||||
bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
|
bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
|
||||||
bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId);
|
bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId);
|
||||||
|
@ -230,7 +230,6 @@
|
|||||||
#define VARIOUS_SET_SKY_DROP 138
|
#define VARIOUS_SET_SKY_DROP 138
|
||||||
#define VARIOUS_CLEAR_SKY_DROP 139
|
#define VARIOUS_CLEAR_SKY_DROP 139
|
||||||
#define VARIOUS_SKY_DROP_YAWN 140
|
#define VARIOUS_SKY_DROP_YAWN 140
|
||||||
#define VARIOUS_JUMP_IF_CANT_FLING 141
|
|
||||||
#define VARIOUS_JUMP_IF_HOLD_EFFECT 142
|
#define VARIOUS_JUMP_IF_HOLD_EFFECT 142
|
||||||
#define VARIOUS_CURE_CERTAIN_STATUSES 143
|
#define VARIOUS_CURE_CERTAIN_STATUSES 143
|
||||||
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 144
|
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 144
|
||||||
|
@ -1370,9 +1370,15 @@ static void Cmd_attackcanceler(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gHitMarker |= HITMARKER_OBEYS;
|
gHitMarker |= HITMARKER_OBEYS;
|
||||||
if (NoTargetPresent(gBattlerAttacker, gCurrentMove) && (!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|
// Check if no available target present on the field.
|
||||||
|
if (NoTargetPresent(gBattlerAttacker, gCurrentMove)
|
||||||
|
&& (!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|
||||||
{
|
{
|
||||||
|
if (gBattleMoves[gCurrentMove].effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling.
|
||||||
|
gBattlescriptCurrInstr = BattleScript_FlingFailConsumeItem;
|
||||||
|
else
|
||||||
gBattlescriptCurrInstr = BattleScript_FailedFromAtkString;
|
gBattlescriptCurrInstr = BattleScript_FailedFromAtkString;
|
||||||
|
|
||||||
if (!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
if (!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
||||||
CancelMultiTurnMoves(gBattlerAttacker);
|
CancelMultiTurnMoves(gBattlerAttacker);
|
||||||
return;
|
return;
|
||||||
@ -10554,15 +10560,6 @@ static void Cmd_various(void)
|
|||||||
gBattlescriptCurrInstr = cmd->failInstr;
|
gBattlescriptCurrInstr = cmd->failInstr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case VARIOUS_JUMP_IF_CANT_FLING:
|
|
||||||
{
|
|
||||||
VARIOUS_ARGS(const u8 *jumpInstr);
|
|
||||||
if (!CanFling(battler))
|
|
||||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
|
||||||
else
|
|
||||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case VARIOUS_CURE_CERTAIN_STATUSES:
|
case VARIOUS_CURE_CERTAIN_STATUSES:
|
||||||
{
|
{
|
||||||
VARIOUS_ARGS();
|
VARIOUS_ARGS();
|
||||||
@ -15787,11 +15784,22 @@ void BS_CalcMetalBurstDmg(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BS_JumpIfCantFling(void)
|
||||||
|
{
|
||||||
|
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
|
||||||
|
|
||||||
|
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||||
|
if (!CanFling(battler))
|
||||||
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
|
else
|
||||||
|
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||||
|
}
|
||||||
|
|
||||||
void BS_JumpIfMoreThanHalfHP(void)
|
void BS_JumpIfMoreThanHalfHP(void)
|
||||||
{
|
{
|
||||||
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
|
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
|
||||||
|
|
||||||
u8 battler = GetBattlerForBattleScript(cmd->battler);
|
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||||
if (gBattleMons[battler].hp > (gBattleMons[battler].maxHP + 1) / 2)
|
if (gBattleMons[battler].hp > (gBattleMons[battler].maxHP + 1) / 2)
|
||||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||||
else
|
else
|
||||||
|
@ -6535,8 +6535,9 @@ static u8 DamagedStatBoostBerryEffect(u8 battler, u8 statId, u8 split)
|
|||||||
if (IsBattlerAlive(battler)
|
if (IsBattlerAlive(battler)
|
||||||
&& TARGET_TURN_DAMAGED
|
&& TARGET_TURN_DAMAGED
|
||||||
&& CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN)
|
&& CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN)
|
||||||
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
|
&& (gBattleScripting.overrideBerryRequirements
|
||||||
&& GetBattleMoveSplit(gCurrentMove) == split)
|
|| (!DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && GetBattleMoveSplit(gCurrentMove) == split))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
BufferStatChange(battler, statId, STRINGID_STATROSE);
|
||||||
|
|
||||||
@ -6742,6 +6743,12 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
|
|||||||
case HOLD_EFFECT_SP_DEFENSE_UP:
|
case HOLD_EFFECT_SP_DEFENSE_UP:
|
||||||
effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, FALSE);
|
effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, FALSE);
|
||||||
break;
|
break;
|
||||||
|
case HOLD_EFFECT_KEE_BERRY: // consume and boost defense if used physical move
|
||||||
|
effect = DamagedStatBoostBerryEffect(battler, STAT_DEF, SPLIT_PHYSICAL);
|
||||||
|
break;
|
||||||
|
case HOLD_EFFECT_MARANGA_BERRY: // consume and boost sp. defense if used special move
|
||||||
|
effect = DamagedStatBoostBerryEffect(battler, STAT_SPDEF, SPLIT_SPECIAL);
|
||||||
|
break;
|
||||||
case HOLD_EFFECT_RANDOM_STAT_UP:
|
case HOLD_EFFECT_RANDOM_STAT_UP:
|
||||||
effect = RandomStatRaiseBerry(battler, gLastUsedItem, FALSE);
|
effect = RandomStatRaiseBerry(battler, gLastUsedItem, FALSE);
|
||||||
break;
|
break;
|
||||||
@ -10601,11 +10608,9 @@ static u8 GetFlingPowerFromItemId(u16 itemId)
|
|||||||
return ItemId_GetFlingPower(itemId);
|
return ItemId_GetFlingPower(itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the input bank is any bank on the specific mon's side
|
bool32 CanFling(u32 battler)
|
||||||
bool32 CanFling(u8 battler)
|
|
||||||
{
|
{
|
||||||
u16 item = gBattleMons[battler].item;
|
u16 item = gBattleMons[battler].item;
|
||||||
u16 itemEffect = ItemId_GetHoldEffect(item);
|
|
||||||
|
|
||||||
if (item == ITEM_NONE
|
if (item == ITEM_NONE
|
||||||
#if B_KLUTZ_FLING_INTERACTION >= GEN_5
|
#if B_KLUTZ_FLING_INTERACTION >= GEN_5
|
||||||
|
336
test/battle/move_effect/fling.c
Normal file
336
test/battle/move_effect/fling.c
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "test/battle.h"
|
||||||
|
|
||||||
|
ASSUMPTIONS
|
||||||
|
{
|
||||||
|
ASSUME(gBattleMoves[MOVE_FLING].effect == EFFECT_FLING);
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling fails if pokemon holds no item")
|
||||||
|
{
|
||||||
|
u16 item;
|
||||||
|
|
||||||
|
PARAMETRIZE {item = ITEM_NONE; }
|
||||||
|
PARAMETRIZE {item = ITEM_RAZOR_CLAW; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Item(item); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_FLING);}
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
if (item != ITEM_NONE) {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
} else {
|
||||||
|
MESSAGE("But it failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling fails if pokemon is under the effects of Embargo or Magic Room")
|
||||||
|
{
|
||||||
|
u16 move;
|
||||||
|
|
||||||
|
PARAMETRIZE {move = MOVE_CELEBRATE; }
|
||||||
|
PARAMETRIZE {move = MOVE_EMBARGO; }
|
||||||
|
PARAMETRIZE {move = MOVE_MAGIC_ROOM; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(gBattleMoves[MOVE_EMBARGO].effect == EFFECT_EMBARGO);
|
||||||
|
ASSUME(gBattleMoves[MOVE_MAGIC_ROOM].effect == EFFECT_MAGIC_ROOM);
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RAZOR_CLAW); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(opponent, move); }
|
||||||
|
TURN { MOVE(player, MOVE_FLING); }
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
if (move == MOVE_CELEBRATE) {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
} else {
|
||||||
|
MESSAGE("But it failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling fails for pokemon with Klutz ability")
|
||||||
|
{
|
||||||
|
u16 ability;
|
||||||
|
|
||||||
|
PARAMETRIZE {ability = ABILITY_KLUTZ; }
|
||||||
|
PARAMETRIZE {ability = ABILITY_RUN_AWAY; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(P_GEN_4_POKEMON == TRUE);
|
||||||
|
ASSUME(B_KLUTZ_FLING_INTERACTION >= GEN_5);
|
||||||
|
PLAYER(SPECIES_BUNEARY) { Item(ITEM_RAZOR_CLAW); Ability(ability); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_FLING); }
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Buneary used Fling!");
|
||||||
|
if (ability != ABILITY_KLUTZ) {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
} else {
|
||||||
|
MESSAGE("But it failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling's thrown item can be regained with Recycle")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(gBattleMoves[MOVE_RECYCLE].effect == EFFECT_RECYCLE);
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_FLING);}
|
||||||
|
TURN { MOVE(player, MOVE_RECYCLE);}
|
||||||
|
TURN { MOVE(player, MOVE_FLING);}
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
MESSAGE("Wobbuffet used Recycle!");
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_RECYCLE, player);
|
||||||
|
MESSAGE("Wobbuffet found one Razor Claw!");
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling - Item is lost even when there is no target")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(gBattleMoves[MOVE_SELF_DESTRUCT].effect == EFFECT_EXPLOSION);
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); Speed(2); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET) {Speed(5); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET) {Speed(5); }
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(opponent, MOVE_SELF_DESTRUCT); MOVE(player, MOVE_FLING); SEND_OUT(opponent, 1); }
|
||||||
|
TURN { MOVE(player, MOVE_FLING); }
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Foe Wobbuffet used SelfDestruct!");
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_SELF_DESTRUCT, opponent);
|
||||||
|
HP_BAR(player);
|
||||||
|
MESSAGE("Foe Wobbuffet fainted!");
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
MESSAGE("But it failed!");
|
||||||
|
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
MESSAGE("But it failed!");
|
||||||
|
} THEN {
|
||||||
|
EXPECT_EQ(player->item, ITEM_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling - Item is lost when target protects itself")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
ASSUME(gBattleMoves[MOVE_PROTECT].effect == EFFECT_PROTECT);
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_FLING);}
|
||||||
|
TURN { MOVE(player, MOVE_FLING); }
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Foe Wobbuffet used Protect!");
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent);
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
MESSAGE("Foe Wobbuffet protected itself!");
|
||||||
|
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
MESSAGE("But it failed!");
|
||||||
|
} THEN {
|
||||||
|
EXPECT_EQ(player->item, ITEM_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling doesn't consume the item if pokemon is asleep/frozen/paralyzed")
|
||||||
|
{
|
||||||
|
u32 status;
|
||||||
|
u16 item;
|
||||||
|
|
||||||
|
PARAMETRIZE {status = STATUS1_SLEEP_TURN(2); item = ITEM_RAZOR_CLAW; }
|
||||||
|
PARAMETRIZE {status = STATUS1_PARALYSIS; item = ITEM_RAZOR_CLAW; }
|
||||||
|
PARAMETRIZE {status = STATUS1_FREEZE; item = ITEM_RAZOR_CLAW; }
|
||||||
|
PARAMETRIZE {status = STATUS1_SLEEP_TURN(2); item = ITEM_NONE; }
|
||||||
|
PARAMETRIZE {status = STATUS1_PARALYSIS; item = ITEM_NONE; }
|
||||||
|
PARAMETRIZE {status = STATUS1_FREEZE; item = ITEM_NONE; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) {Item(item); Status1(status); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
if (status == STATUS1_FREEZE) {
|
||||||
|
TURN { MOVE(player, MOVE_FLING, WITH_RNG(RNG_FROZEN, FALSE)); }
|
||||||
|
TURN { MOVE(player, MOVE_FLING, WITH_RNG(RNG_FROZEN, TRUE)); }
|
||||||
|
} else if (status == STATUS1_PARALYSIS) {
|
||||||
|
TURN { MOVE(player, MOVE_FLING, WITH_RNG(RNG_PARALYSIS, FALSE)); }
|
||||||
|
TURN { MOVE(player, MOVE_FLING, WITH_RNG(RNG_PARALYSIS, TRUE)); }
|
||||||
|
} else {
|
||||||
|
TURN { MOVE(player, MOVE_FLING); }
|
||||||
|
TURN { MOVE(player, MOVE_FLING); }
|
||||||
|
}
|
||||||
|
} SCENE {
|
||||||
|
if (status == STATUS1_FREEZE) {
|
||||||
|
MESSAGE("Wobbuffet is frozen solid!");
|
||||||
|
MESSAGE("Wobbuffet was defrosted!");
|
||||||
|
}
|
||||||
|
else if (status == STATUS1_PARALYSIS) {
|
||||||
|
MESSAGE("Wobbuffet is paralyzed! It can't move!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MESSAGE("Wobbuffet is fast asleep.");
|
||||||
|
MESSAGE("Wobbuffet woke up!");
|
||||||
|
}
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
if (item != ITEM_NONE) {
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
} else {
|
||||||
|
MESSAGE("But it failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} THEN {
|
||||||
|
EXPECT_EQ(player->item, ITEM_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling applies special effects when throwing specific Items")
|
||||||
|
{
|
||||||
|
u16 item, effect;
|
||||||
|
|
||||||
|
PARAMETRIZE {item = ITEM_FLAME_ORB; effect = EFFECT_WILL_O_WISP; }
|
||||||
|
PARAMETRIZE {item = ITEM_TOXIC_ORB; effect = EFFECT_TOXIC; }
|
||||||
|
PARAMETRIZE {item = ITEM_POISON_BARB; effect = EFFECT_POISON; }
|
||||||
|
PARAMETRIZE {item = ITEM_LIGHT_BALL; effect = EFFECT_PARALYZE; }
|
||||||
|
PARAMETRIZE {item = ITEM_RAZOR_FANG; effect = EFFECT_FLINCH_HIT; }
|
||||||
|
PARAMETRIZE {item = ITEM_KINGS_ROCK; effect = EFFECT_FLINCH_HIT; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Item(item); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_FLING); }
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
switch (effect)
|
||||||
|
{
|
||||||
|
case EFFECT_WILL_O_WISP:
|
||||||
|
MESSAGE("Foe Wobbuffet was burned!");
|
||||||
|
STATUS_ICON(opponent, STATUS1_BURN);
|
||||||
|
break;
|
||||||
|
case EFFECT_PARALYZE:
|
||||||
|
MESSAGE("Foe Wobbuffet is paralyzed! It may be unable to move!");
|
||||||
|
STATUS_ICON(opponent, STATUS1_PARALYSIS);
|
||||||
|
break;
|
||||||
|
case EFFECT_POISON:
|
||||||
|
MESSAGE("Foe Wobbuffet was poisoned!");
|
||||||
|
STATUS_ICON(opponent, STATUS1_POISON);
|
||||||
|
break;
|
||||||
|
case EFFECT_TOXIC:
|
||||||
|
MESSAGE("Foe Wobbuffet is badly poisoned!");
|
||||||
|
STATUS_ICON(opponent, STATUS1_TOXIC_POISON);
|
||||||
|
break;
|
||||||
|
case EFFECT_FLINCH_HIT:
|
||||||
|
MESSAGE("Foe Wobbuffet flinched!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Fling - thrown berry's effect activates for the target even if the trigger conditions are not met")
|
||||||
|
{
|
||||||
|
u16 item, effect;
|
||||||
|
u8 statId = 0;
|
||||||
|
u32 status1 = STATUS1_NONE;
|
||||||
|
|
||||||
|
PARAMETRIZE { item = ITEM_ORAN_BERRY; effect = HOLD_EFFECT_RESTORE_HP; }
|
||||||
|
PARAMETRIZE { item = ITEM_SITRUS_BERRY; effect = HOLD_EFFECT_RESTORE_HP; }
|
||||||
|
PARAMETRIZE { item = ITEM_CHESTO_BERRY; effect = HOLD_EFFECT_CURE_SLP; status1 = STATUS1_SLEEP; }
|
||||||
|
PARAMETRIZE { item = ITEM_CHERI_BERRY; effect = HOLD_EFFECT_CURE_PAR; status1 = STATUS1_PARALYSIS; }
|
||||||
|
PARAMETRIZE { item = ITEM_PECHA_BERRY; effect = HOLD_EFFECT_CURE_PSN; status1 = STATUS1_POISON; }
|
||||||
|
PARAMETRIZE { item = ITEM_PECHA_BERRY; effect = HOLD_EFFECT_CURE_PSN; status1 = STATUS1_TOXIC_POISON; }
|
||||||
|
PARAMETRIZE { item = ITEM_RAWST_BERRY; effect = HOLD_EFFECT_CURE_BRN; status1 = STATUS1_BURN; }
|
||||||
|
PARAMETRIZE { item = ITEM_ASPEAR_BERRY; effect = HOLD_EFFECT_CURE_FRZ; status1 = STATUS1_FREEZE; }
|
||||||
|
PARAMETRIZE { item = ITEM_APICOT_BERRY; effect = HOLD_EFFECT_SP_DEFENSE_UP; statId = STAT_SPDEF; }
|
||||||
|
PARAMETRIZE { item = ITEM_MARANGA_BERRY; effect = HOLD_EFFECT_MARANGA_BERRY; statId = STAT_SPDEF; }
|
||||||
|
PARAMETRIZE { item = ITEM_GANLON_BERRY; effect = HOLD_EFFECT_DEFENSE_UP; statId = STAT_DEF; }
|
||||||
|
PARAMETRIZE { item = ITEM_KEE_BERRY; effect = HOLD_EFFECT_KEE_BERRY; statId = STAT_DEF; }
|
||||||
|
PARAMETRIZE { item = ITEM_LIECHI_BERRY; effect = HOLD_EFFECT_ATTACK_UP; statId = STAT_ATK; }
|
||||||
|
PARAMETRIZE { item = ITEM_PETAYA_BERRY; effect = HOLD_EFFECT_SP_ATTACK_UP; statId = STAT_SPATK; }
|
||||||
|
PARAMETRIZE { item = ITEM_SALAC_BERRY; effect = HOLD_EFFECT_SPEED_UP; statId = STAT_SPEED; }
|
||||||
|
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Item(item); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); HP(399); MaxHP(400); }
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_FLING); }
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Wobbuffet used Fling!");
|
||||||
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
|
||||||
|
HP_BAR(opponent);
|
||||||
|
if (effect == HOLD_EFFECT_RESTORE_HP) {
|
||||||
|
if (item == ITEM_ORAN_BERRY) {
|
||||||
|
MESSAGE("Foe Wobbuffet's Oran Berry restored health!");
|
||||||
|
} else {
|
||||||
|
MESSAGE("Foe Wobbuffet's Sitrus Berry restored health!");
|
||||||
|
}
|
||||||
|
HP_BAR(opponent);
|
||||||
|
}
|
||||||
|
else if (status1 != STATUS1_NONE) {
|
||||||
|
if (status1 == STATUS1_BURN) {
|
||||||
|
MESSAGE("Foe Wobbuffet's Rawst Berry healed its burn!");
|
||||||
|
} else if (status1 == STATUS1_SLEEP) {
|
||||||
|
MESSAGE("Foe Wobbuffet's Chesto Berry woke it from its sleep!");
|
||||||
|
} else if (status1 == STATUS1_FREEZE) {
|
||||||
|
MESSAGE("Foe Wobbuffet's Aspear Berry defrosted it!");
|
||||||
|
} else if (status1 == STATUS1_PARALYSIS) {
|
||||||
|
MESSAGE("Foe Wobbuffet's Cheri Berry cured paralysis!");
|
||||||
|
} else if (status1 == STATUS1_TOXIC_POISON || status1 == STATUS1_POISON) {
|
||||||
|
MESSAGE("Foe Wobbuffet's Pecha Berry cured poison!");
|
||||||
|
}
|
||||||
|
NOT STATUS_ICON(opponent, status1);
|
||||||
|
}
|
||||||
|
else if (statId != 0) {
|
||||||
|
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
|
||||||
|
if (statId == STAT_ATK) {
|
||||||
|
MESSAGE("Using Liechi Berry, the Attack of Foe Wobbuffet rose!");
|
||||||
|
} else if (statId == STAT_DEF) {
|
||||||
|
if (item == ITEM_GANLON_BERRY) {
|
||||||
|
MESSAGE("Using Ganlon Berry, the Defense of Foe Wobbuffet rose!");
|
||||||
|
} else {
|
||||||
|
MESSAGE("Using Kee Berry, the Defense of Foe Wobbuffet rose!");
|
||||||
|
}
|
||||||
|
} else if (statId == STAT_SPDEF) {
|
||||||
|
if (item == ITEM_APICOT_BERRY) {
|
||||||
|
MESSAGE("Using Apicot Berry, the Sp. Def of Foe Wobbuffet rose!");
|
||||||
|
} else {
|
||||||
|
MESSAGE("Using Maranga Berry, the Sp. Def of Foe Wobbuffet rose!");
|
||||||
|
}
|
||||||
|
} else if (statId == STAT_SPEED) {
|
||||||
|
MESSAGE("Using Salac Berry, the Speed of Foe Wobbuffet rose!");
|
||||||
|
} else if (statId == STAT_SPATK) {
|
||||||
|
MESSAGE("Using Petaya Berry, the Sp. Atk of Foe Wobbuffet rose!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} THEN {
|
||||||
|
if (effect == HOLD_EFFECT_RESTORE_HP) {
|
||||||
|
EXPECT_EQ(opponent->hp, opponent->maxHP);
|
||||||
|
} else if (status1 != STATUS1_NONE) {
|
||||||
|
EXPECT_EQ(opponent->status1, STATUS1_NONE);
|
||||||
|
}
|
||||||
|
else if (statId != 0) {
|
||||||
|
EXPECT_EQ(opponent->statStages[statId], DEFAULT_STAT_STAGE + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user