Merge branch 'upcoming' of https://github.com/rh-hideout/pokeemerald-expansion into trainerSlideMsgUpdate

This commit is contained in:
LOuroboros 2023-02-21 04:46:28 -03:00
commit 24581426a1
22 changed files with 516 additions and 142 deletions

View File

@ -270,6 +270,50 @@
.macro stopsound
.byte 0x2f
.endm
@ same as createvisualtask except takes in battlerargindex, which is the battle anim arg index of the battler to loop through
.macro createvisualtaskontargets addr:req, priority:req, battlerargindex:req, argv:vararg
.byte 0x30
.4byte \addr
.byte \priority
.byte \battlerargindex
.byte (.Lcreatetask_\@_2 - .Lcreatetask_\@_1) / 2 @ num_args
.Lcreatetask_\@_1:
.2byte \argv
.Lcreatetask_\@_2:
.endm
@ same as createsprite except takes in battlerargindex, which is the battle anim arg index of the battler to loop through
.macro createspriteontargets template:req, anim_battler:req, subpriority_offset:req, battlerargindex:req, argv:vararg
.byte 0x31
.4byte \template
.if \anim_battler == ANIM_TARGET
.byte 0x80 | (\subpriority_offset & 0x7F)
.else
.byte (\subpriority_offset & 0x7F)
.endif
.byte \battlerargindex
.byte (.Lsprite_\@_2 - .Lsprite_\@_1) / 2
.Lsprite_\@_1:
.2byte \argv
.Lsprite_\@_2:
.endm
@ does not overwrite gBattleAnimArgs[battlerargindex], some sprite templates are too dependent on the value (e.g. heal block)
.macro createspriteontargets_onpos template:req, anim_battler:req, subpriority_offset:req, battlerargindex:req, argv:vararg
.byte 0x32
.4byte \template
.if \anim_battler == ANIM_TARGET
.byte 0x80 | (\subpriority_offset & 0x7F)
.else
.byte (\subpriority_offset & 0x7F)
.endif
.byte \battlerargindex
.byte (.Lsprite_\@_2 - .Lsprite_\@_1) / 2
.Lsprite_\@_1:
.2byte \argv
.Lsprite_\@_2:
.endm
@ useful macros
.macro jumpreteq value:req, ptr:req

View File

@ -1322,6 +1322,11 @@
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
.endm
@ Stores Healing Wish effect.
.macro storehealingwish battler:req
various \battler, VARIOUS_STORE_HEALING_WISH
.endm
.macro setmagiccoattarget battler:req
various \battler, VARIOUS_SET_MAGIC_COAT_TARGET

View File

@ -1492,22 +1492,22 @@ Move_HEAL_BLOCK:
loadspritegfx ANIM_TAG_BLUE_STAR
monbg ANIM_TARGET
createsoundtask SoundTask_PlaySeChangingVolume, SE_M_ABSORB_2, SOUND_PAN_TARGET, 256, -16, 0, 2
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 0, -5, 1, 0
createspriteontargets_onpos gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 2, 0, -5, ANIM_TARGET, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, -15, 10, 1, 0
createspriteontargets_onpos gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 2, -15, 10, ANIM_TARGET, 0
delay 7
createvisualtask AnimTask_BlendBattleAnimPal, 10, 1 | 4, 4, 2, 12, 0, RGB_BLACK
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 0, -5, 1, 0
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_DEF_SIDE, 4, 2, 12, 0, RGB_BLACK
createspriteontargets_onpos gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 2, 0, -5, ANIM_TARGET, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, -15, 10, 1, 0
createspriteontargets_onpos gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 2, -15, 10, ANIM_TARGET, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, -15, -15, 1, 0
createspriteontargets_onpos gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 2, -15, -15, ANIM_TARGET, 0
delay 7
createsprite gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 10, -5, 1, 0
createspriteontargets_onpos gHealingBlueStarSpriteTemplate, ANIM_TARGET, 2, 2, 10, -5, ANIM_TARGET, 0
delay 7
waitforvisualfinish
delay 11
createvisualtask AnimTask_BlendBattleAnimPal, 10, 1 | 4, 4, 2, 0, 12, RGB_BLACK
createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_DEF_SIDE, 4, 2, 0, 12, RGB_BLACK
waitforvisualfinish
clearmonbg ANIM_TARGET
end
@ -6405,11 +6405,7 @@ Move_ELECTROWEB:
clearmonbg ANIM_DEF_PARTNER
delay 1
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 5, 1, 2, 9, 0, RGB_BLACK
@ ElectricityEffect looks ugly against both opponents, to do later
jumpifdoublebattle Move_ELECTROWEB_Wait
call ElectricityEffect
call ElectricityEffect_OnTargets
Move_ELECTROWEB_Wait:
waitforvisualfinish
end
@ -9278,16 +9274,16 @@ Move_EERIE_IMPULSE::
Move_VENOM_DRENCH::
loadspritegfx ANIM_TAG_POISON_BUBBLE
monbg ANIM_DEF_PARTNER
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xfffb 0x1 0xfffb 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xfffb 0x1 0xfffb 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x5 0x0 0x6 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x5 0x0 0x6 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x13 0x1 0xa 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x13 0x1 0xa 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xffe9 0x2 0xfff6 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xffe9 0x2 0xfff6 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
call AcidDrench
@ -9296,28 +9292,28 @@ Move_VENOM_DRENCH::
clearmonbg ANIM_DEF_PARTNER
end
AcidDrench:
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xffec 0x0 0xfff6 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xffec 0x0 0xfff6 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x1c 0x1 0xa 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x1c 0x1 0xa 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xfff6 0x1 0xfffb 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xfff6 0x1 0xfffb 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xa 0x0 0x6 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xa 0x0 0x6 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x18 0x1 0xa 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x18 0x1 0xa 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xffe0 0x2 0xfff6 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xffe0 0x2 0xfff6 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xffec 0x0 0xfff6 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0xffec 0x0 0xfff6 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x1e 0x2 0xa 0x0
launchtemplate gVenomDrenchAcidTemplate 0x82, 0x4, 0x1e 0x2 0xa 1
playsewithpan SE_M_BUBBLE3, SOUND_PAN_TARGET
delay 0x2
return
@ -10175,6 +10171,7 @@ Move_ORIGIN_PULSE::
launchtemplate gOriginPulseOrbInwardTemplate 0x82 0x5 0x1 0x0 0xFF2A 0xFFAA 0x10 @between left and upper left
launchtemplate gOriginPulseOrbInwardTemplate 0x82 0x5 0x1 0x0 0xFFDA 0xFF94 0x10 @between up and upper left
waitforvisualfinish
createvisualtaskontargets AnimTask_ShakeMon2, 5, 0, ANIM_TARGET, 2, 0, 18, 1
monbg ANIM_DEF_PARTNER
launchtemplate gOriginPulseBasicSplatTemplate 0x83 0x4 0xffb0 0xfff0 0x1 0x1
stopsound
@ -23375,15 +23372,15 @@ Move_OVERHEAT:
waitforvisualfinish
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -5, 3, ANIM_TARGET, 0
playsewithpan SE_M_FLAMETHROWER, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 10, 0, 25, 1
createvisualtaskontargets AnimTask_ShakeMon, 2, 0, ANIM_TARGET, 10, 0, 25, 1
delay 6
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 8, -5, ANIM_TARGET, 0
createspriteontargets gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 2, 8, -5, ANIM_TARGET, 0
playsewithpan SE_M_FLAMETHROWER, SOUND_PAN_TARGET
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 10, 10, ANIM_TARGET, 0
createspriteontargets gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 2, 10, 10, ANIM_TARGET, 0
playsewithpan SE_M_FLAMETHROWER, SOUND_PAN_TARGET
delay 8
createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, ANIM_TARGET, 0
createspriteontargets gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 2, 0, 0, ANIM_TARGET, 0
playsewithpan SE_M_FLAMETHROWER, SOUND_PAN_TARGET
createvisualtask AnimTask_CopyPalFadedToUnfaded, 5, 1
delay 1
@ -24209,21 +24206,40 @@ WaterBubblesEffectLong:
ElectricityEffect:
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_TARGET
ElectricityEffectNoSound:
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 5, 0, 5, 0, ANIM_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 5, 0, 5, 0, ANIM_TARGET
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -5, 10, 5, 1, ANIM_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, -5, 10, 5, 1, ANIM_TARGET
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 15, 20, 5, 2, ANIM_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 15, 20, 5, 2, ANIM_TARGET
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -15, -10, 5, 0, ANIM_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, -15, -10, 5, 0, ANIM_TARGET
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 25, 0, 5, 1, ANIM_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 25, 0, 5, 1, ANIM_TARGET
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -8, 8, 5, 2, ANIM_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, -8, 8, 5, 2, ANIM_TARGET
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 2, -8, 5, 0, ANIM_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 2, -8, 5, 0, ANIM_TARGET
delay 2
createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -20, 15, 5, 1, ANIM_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, -20, 15, 5, 1, ANIM_TARGET
return
ElectricityEffect_OnTargets:
playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_TARGET
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 4, 5, 0, 5, 0, ANIM_TARGET
delay 2
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 4, -5, 10, 5, 1, ANIM_TARGET
delay 2
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 4, 15, 20, 5, 2, ANIM_TARGET
delay 2
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 4, -15, -10, 5, 0, ANIM_TARGET
delay 2
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 4, 25, 0, 5, 1, ANIM_TARGET
delay 2
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 4, -8, 8, 5, 2, ANIM_TARGET
delay 2
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 4, 2, -8, 5, 0, ANIM_TARGET
delay 2
createspriteontargets gElectricitySpriteTemplate, ANIM_TARGET, 2, 4, -20, 15, 5, 1, ANIM_TARGET
return
ConfusionEffect:

View File

@ -2697,6 +2697,8 @@ BattleScript_EffectHealingWish:
instanthpdrop BS_ATTACKER
setatkhptozero
tryfaintmon BS_ATTACKER
storehealingwish BS_ATTACKER
.if B_HEALING_WISH_SWITCH <= GEN_4
openpartyscreen BS_ATTACKER, BattleScript_EffectHealingWishEnd
switchoutabilities BS_ATTACKER
waitstate
@ -2711,11 +2713,19 @@ BattleScript_EffectHealingWish:
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
switchineffects BS_ATTACKER
.endif
BattleScript_EffectHealingWishEnd:
moveendall
end
BattleScript_HealingWishActivates::
setbyte cMULTISTRING_CHOOSER, 0
jumpifnotchosenmove MOVE_LUNAR_DANCE, BattleScript_EffectHealingWishNewMon
goto BattleScript_EffectHealingWishRestore
BattleScript_LunarDanceActivates::
setbyte cMULTISTRING_CHOOSER, 1
restorepp BS_ATTACKER
BattleScript_EffectHealingWishNewMon:
BattleScript_EffectHealingWishRestore:
printfromtable gHealingWishStringIds
waitmessage B_WAIT_TIME_LONG
playanimation BS_ATTACKER, B_ANIM_WISH_HEAL
@ -2730,10 +2740,7 @@ BattleScript_EffectHealingWishNewMon:
waitstate
printstring STRINGID_HEALINGWISHHEALED
waitmessage B_WAIT_TIME_LONG
switchineffects BS_ATTACKER
BattleScript_EffectHealingWishEnd:
moveendall
end
return
BattleScript_EffectWorrySeed:
attackcanceler

View File

@ -655,6 +655,8 @@ struct BattleStruct
u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching)
bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face.
u8 battleBondTransformed[NUM_BATTLE_SIDES]; // Bitfield for each party.
u8 storedHealingWish:4; // Each battler as a bit.
u8 storedLunarDance:4; // Each battler as a bit.
bool8 trainerSlideHalfHpMsgDone:1;
u8 trainerSlideFirstCriticalHitMsgState:2;
u8 trainerSlideFirstSuperEffectiveHitMsgState:2;

View File

@ -452,6 +452,8 @@ extern const u8 BattleScript_MimicryActivates_End3[];
extern const u8 BattleScript_IceFaceNullsDamage[];
extern const u8 BattleScript_BattlerFormChangeWithStringEnd3[];
extern const u8 BattleScript_DampPreventsAftermath[];
extern const u8 BattleScript_HealingWishActivates[];
extern const u8 BattleScript_LunarDanceActivates[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];

View File

@ -181,6 +181,7 @@ void UndoMegaEvolution(u32 monId);
void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut);
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
bool32 CanBattlerGetOrLoseItem(u8 battlerId, u16 itemId);
u32 GetIllusionMonSpecies(u32 battlerId);
struct Pokemon *GetIllusionMonPtr(u32 battlerId);
void ClearIllusionMon(u32 battlerId);
bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId);

View File

@ -95,6 +95,8 @@
#define B_BEAT_UP GEN_LATEST // In Gen5+, Beat Up uses a different formula to calculate its damage, and deals Dark-type damage. Prior to Gen 5, each hit also announces the party member's name.
#define B_DARK_VOID_FAIL GEN_LATEST // In Gen7+, only Darkrai can use Dark Void.
#define B_BURN_HIT_THAW GEN_LATEST // In Gen6+, damaging moves with a chance of burn will thaw the target, regardless if they're fire-type moves or not.
#define B_HEALING_WISH_SWITCH GEN_LATEST // In Gen5+, the mon receiving Healing Wish is sent out at the end of the turn.
// Additionally, in gen8+ the Healing Wish's effect will be stored until the user switches into a statused or hurt mon.
// Ability settings
#define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters.

View File

@ -13,11 +13,14 @@
#define P_EGG_HATCH_LEVEL GEN_LATEST // Since Gen 4, Pokémon will hatch from eggs at level 1 instead of 5.
#define P_BALL_INHERITING GEN_LATEST // Since Gen 6, Eggs from the Daycare will inherit the Poké Ball from their mother. From Gen7 onwards, the father can pass it down as well, as long as it's of the same species as the mother.
// Other settings
// Species-specific settings
#define P_SHEDINJA_BALL GEN_LATEST // Since Gen 4, Shedinja requires a Poké Ball for its evolution. In Gen 3, Shedinja inherits Nincada's Ball.
#define P_LEGENDARY_PERFECT_IVS GEN_LATEST // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs.
#define P_KADABRA_EVERSTONE GEN_LATEST // Since Gen 4, Kadabra can evolve even when holding an Everstone.
#define P_HIPPO_GENDER_DIFF_ICONS TRUE // If TRUE, will give Hippopotas and Hippowdon custom icons for their female forms.
#define P_SHUCKLE_BERRY_JUICE TRUE // In Gen 2, Shuckle had a 1/16 chance of converting Berry that it's holding into Berry Juice. Setting this to TRUE will allow to do this with an Oran Berry, which is the spiritual succesor of the Berry item.
// Other settings
#define P_LEGENDARY_PERFECT_IVS GEN_LATEST // Since Gen 6, Legendaries, Mythicals and Ultra Beasts found in the wild or given through gifts have at least 3 perfect IVs.
// Flag settings
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.

View File

@ -257,8 +257,9 @@
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 165
#define VARIOUS_JUMP_IF_NO_VALID_TARGETS 166
#define VARIOUS_JUMP_IF_EMERGENCY_EXITED 167
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE 168
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION 169
#define VARIOUS_STORE_HEALING_WISH 168
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE 169
#define VARIOUS_TRY_TRAINER_SLIDE_MSG_MEGA_EVOLUTION 170
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View File

@ -982,6 +982,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// stat raising effects
case EFFECT_ATTACK_UP:
case EFFECT_ATTACK_UP_2:
case EFFECT_ATTACK_UP_USER_ALLY:
if (!BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL))
score -= 10;
break;
@ -3191,6 +3192,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// stat raising effects
case EFFECT_ATTACK_UP:
case EFFECT_ATTACK_UP_2:
case EFFECT_ATTACK_UP_USER_ALLY:
if (MovesWithSplitUnusable(battlerAtk, battlerDef, SPLIT_PHYSICAL))
{
score -= 8;
@ -4824,6 +4826,7 @@ static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
switch (gBattleMoves[move].effect)
{
case EFFECT_ATTACK_UP:
case EFFECT_ATTACK_UP_USER_ALLY:
case EFFECT_DEFENSE_UP:
case EFFECT_SPEED_UP:
case EFFECT_SPECIAL_ATTACK_UP:
@ -5154,6 +5157,7 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
switch (effect)
{
case EFFECT_ATTACK_UP:
case EFFECT_ATTACK_UP_USER_ALLY:
case EFFECT_DEFENSE_UP:
case EFFECT_SPEED_UP:
case EFFECT_SPECIAL_ATTACK_UP:

View File

@ -3,6 +3,7 @@
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_util.h"
#include "bg.h"
#include "contest.h"
#include "decompress.h"
@ -81,7 +82,9 @@ static void Cmd_visible(void);
static void Cmd_teamattack_moveback(void);
static void Cmd_teamattack_movefwd(void);
static void Cmd_stopsound(void);
static void Cmd_createvisualtaskontargets(void);
static void Cmd_createspriteontargets(void);
static void Cmd_createspriteontargets_onpos(void);
static void RunAnimScriptCommand(void);
static void Task_UpdateMonBg(u8 taskId);
static void FlipBattlerBgTiles(void);
@ -169,6 +172,9 @@ static void (* const sScriptCmdTable[])(void) =
Cmd_teamattack_moveback, // 0x2D
Cmd_teamattack_movefwd, // 0x2E
Cmd_stopsound, // 0x2F
Cmd_createvisualtaskontargets, // 0x30
Cmd_createspriteontargets, // 0x31
Cmd_createspriteontargets_onpos, // 0x32
};
void ClearBattleAnimationVars(void)
@ -425,29 +431,46 @@ static void Cmd_unloadspritegfx(void)
ClearSpriteIndex(GET_TRUE_SPRITE_INDEX(index));
}
static void Cmd_createsprite(void)
static u8 GetBattleAnimMoveTargets(u8 battlerArgIndex, u8 *targets)
{
s32 i;
const struct SpriteTemplate *template;
u8 argVar;
u8 argsCount;
s16 subpriority;
sBattleAnimScriptPtr++;
template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr));
sBattleAnimScriptPtr += 4;
argVar = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
argsCount = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
for (i = 0; i < argsCount; i++)
u8 numTargets = 1;
switch (GetBattlerMoveTargetType(gBattleAnimAttacker, gAnimMoveIndex))
{
gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 2;
case MOVE_TARGET_BOTH:
targets[0] = gBattleAnimArgs[battlerArgIndex];
numTargets = 1;
if (IsBattlerAlive(targets[0] ^ BIT_FLANK)) {
targets[1] = targets[0] ^ BIT_FLANK;
numTargets++;
}
break;
case MOVE_TARGET_FOES_AND_ALLY:
targets[0] = gBattleAnimArgs[battlerArgIndex];
numTargets = 1;
if (IsBattlerAlive(targets[0] ^ BIT_FLANK)) {
targets[1] = targets[0] ^ BIT_FLANK;
numTargets++;
}
if (IsBattlerAlive(gBattleAnimAttacker ^ BIT_FLANK)) {
targets[2] = gBattleAnimAttacker ^ BIT_FLANK;
numTargets++;
}
break;
default:
targets[0] = gBattleAnimArgs[battlerArgIndex]; // original
numTargets = 1;
break;
}
return numTargets;
}
static s16 GetSubpriorityForMoveAnim(u8 argVar)
{
s16 subpriority;
if (argVar & ANIMSPRITE_IS_TARGET)
{
argVar ^= ANIMSPRITE_IS_TARGET;
@ -470,6 +493,34 @@ static void Cmd_createsprite(void)
if (subpriority < 3)
subpriority = 3;
return subpriority;
}
static void Cmd_createsprite(void)
{
s32 i;
const struct SpriteTemplate *template;
u8 argVar;
u8 argsCount;
s16 subpriority;
sBattleAnimScriptPtr++;
template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr));
sBattleAnimScriptPtr += 4;
argVar = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
argsCount = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
for (i = 0; i < argsCount; i++)
{
gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 2;
}
subpriority = GetSubpriorityForMoveAnim(argVar);
CreateSpriteAndAnimate(
template,
@ -479,6 +530,85 @@ static void Cmd_createsprite(void)
gAnimVisualTaskCount++;
}
static void CreateSpriteOnTargets(const struct SpriteTemplate *template, u8 argVar, u8 battlerArgIndex, u8 argsCount, bool32 overwriteAnimTgt)
{
u32 i;
u8 targets[MAX_BATTLERS_COUNT];
int ntargets;
s16 subpriority;
for (i = 0; i < argsCount; i++)
{
gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 2;
}
subpriority = GetSubpriorityForMoveAnim(argVar);
ntargets = GetBattleAnimMoveTargets(battlerArgIndex, targets);
for (i = 0; i < ntargets; i++) {
if (overwriteAnimTgt)
gBattleAnimArgs[battlerArgIndex] = targets[i];
CreateSpriteAndAnimate(
template,
GetBattlerSpriteCoord(targets[i], BATTLER_COORD_X_2),
GetBattlerSpriteCoord(targets[i], BATTLER_COORD_Y_PIC_OFFSET),
subpriority);
gAnimVisualTaskCount++;
}
}
// will NOT overwrite gBattleAnimArgs
static void Cmd_createspriteontargets_onpos(void)
{
const struct SpriteTemplate *template;
u8 argVar;
u8 argsCount;
u8 battlerArgIndex;
sBattleAnimScriptPtr++;
template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr));
sBattleAnimScriptPtr += 4;
argVar = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
battlerArgIndex = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
argsCount = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
CreateSpriteOnTargets(template, argVar, battlerArgIndex, argsCount, FALSE);
}
// DOES overwrite gBattleAnimArgs
static void Cmd_createspriteontargets(void)
{
const struct SpriteTemplate *template;
u8 argVar;
u8 argsCount;
u8 battlerArgIndex;
sBattleAnimScriptPtr++;
template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr));
sBattleAnimScriptPtr += 4;
argVar = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
battlerArgIndex = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
argsCount = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
CreateSpriteOnTargets(template, argVar, battlerArgIndex, argsCount, TRUE);
}
static void Cmd_createvisualtask(void)
{
TaskFunc taskFunc;
@ -509,6 +639,48 @@ static void Cmd_createvisualtask(void)
gAnimVisualTaskCount++;
}
static void Cmd_createvisualtaskontargets(void)
{
TaskFunc taskFunc;
u8 taskPriority;
u8 taskId;
u8 numArgs;
u8 battlerArgIndex; // index in gBattleAnimArgs that has the battlerId
s32 i;
u8 targets[MAX_BATTLERS_COUNT] = {0};
sBattleAnimScriptPtr++;
taskFunc = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 4;
taskPriority = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
battlerArgIndex = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
numArgs = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
// copy task arguments
for (i = 0; i < numArgs; i++) {
gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 2;
}
numArgs = GetBattleAnimMoveTargets(battlerArgIndex, targets);
for (i = 0; i < numArgs; i++)
{
gBattleAnimArgs[battlerArgIndex] = targets[i];
taskId = CreateTask(taskFunc, taskPriority);
taskFunc(taskId);
gAnimVisualTaskCount++;
}
}
static void Cmd_delay(void)
{
sBattleAnimScriptPtr++;

View File

@ -4806,8 +4806,8 @@ void AnimTask_CycleMagicalLeafPal(u8 taskId)
void AnimNeedleArmSpike(struct Sprite *sprite)
{
u8 a;
u8 b;
s16 a;
s16 b;
u16 c;
u16 x;
u16 y;
@ -4820,13 +4820,27 @@ void AnimNeedleArmSpike(struct Sprite *sprite)
{
if (gBattleAnimArgs[0] == 0)
{
a = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
b = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
if (IsDoubleBattle())
{
SetAverageBattlerPositions(gBattleAnimAttacker, TRUE, &a, &b);
}
else
{
a = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
b = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
}
}
else
{
a = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
b = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
if (IsDoubleBattle())
{
SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &a, &b);
}
else
{
a = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
b = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
}
}
sprite->data[0] = gBattleAnimArgs[4];

View File

@ -1149,7 +1149,9 @@ static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit)
ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1];
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
species = GetIllusionMonSpecies(battlerId);
if (species == SPECIES_NONE)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim);
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId));

View File

@ -1177,7 +1177,9 @@ static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit)
ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1];
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
species = GetIllusionMonSpecies(battlerId);
if (species == SPECIES_NONE)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim);
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId));

View File

@ -6935,6 +6935,24 @@ static void Cmd_switchineffects(void)
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SwitchInAbilityMsgRet;
}
// Healing Wish activates before hazards.
// Starting from Gen8 - it heals only pokemon which can be healed. In gens 5,6,7 the effect activates anyways.
else if (((gBattleStruct->storedHealingWish & gBitTable[gActiveBattler]) || (gBattleStruct->storedLunarDance & gBitTable[gActiveBattler]))
&& (gBattleMons[gActiveBattler].hp != gBattleMons[gActiveBattler].maxHP || gBattleMons[gActiveBattler].status1 != 0 || B_HEALING_WISH_SWITCH < GEN_8))
{
if (gBattleStruct->storedHealingWish & gBitTable[gActiveBattler])
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_HealingWishActivates;
gBattleStruct->storedHealingWish &= ~(gBitTable[gActiveBattler]);
}
else // Lunar Dance
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_LunarDanceActivates;
gBattleStruct->storedLunarDance &= ~(gBitTable[gActiveBattler]);
}
}
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES)
&& GetBattlerAbility(gActiveBattler) != ABILITY_MAGIC_GUARD
@ -11051,6 +11069,15 @@ static void Cmd_various(void)
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_STORE_HEALING_WISH:
{
VARIOUS_ARGS();
if (gCurrentMove == MOVE_LUNAR_DANCE)
gBattleStruct->storedLunarDance |= gBitTable[gActiveBattler];
else
gBattleStruct->storedHealingWish |= gBitTable[gActiveBattler];
break;
}
case VARIOUS_TRY_TRAINER_SLIDE_MSG_Z_MOVE:
{
VARIOUS_ARGS();
@ -14930,55 +14957,18 @@ static void Cmd_pickup(void)
{
CMD_ARGS();
s32 i;
u16 species, heldItem;
u16 ability;
u32 i, j;
u16 species, heldItem, ability;
u8 lvlDivBy10;
if (InBattlePike())
{
}
else if (InBattlePyramid())
if (!InBattlePike()) // No items in Battle Pike.
{
bool32 isInPyramid = InBattlePyramid_();
for (i = 0; i < PARTY_SIZE; i++)
{
species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
ability = gSpeciesInfo[species].abilities[GetMonData(&gPlayerParty[i], MON_DATA_ABILITY_NUM)];
if (ability == ABILITY_PICKUP
&& species != SPECIES_NONE
&& species != SPECIES_EGG
&& heldItem == ITEM_NONE
&& (Random() % 10) == 0)
{
heldItem = GetBattlePyramidPickupItemId();
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem);
}
#if (defined ITEM_HONEY)
else if (ability == ABILITY_HONEY_GATHER
&& species != 0
&& species != SPECIES_EGG
&& heldItem == ITEM_NONE)
{
if ((lvlDivBy10 + 1 ) * 5 > Random() % 100)
{
heldItem = ITEM_HONEY;
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem);
}
}
#endif
}
}
else
{
for (i = 0; i < PARTY_SIZE; i++)
{
species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
lvlDivBy10 = (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL)-1) / 10; //Moving this here makes it easier to add in abilities like Honey Gather
lvlDivBy10 = (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL)-1) / 10; //Moving this here makes it easier to add in abilities like Honey Gather.
if (lvlDivBy10 > 9)
lvlDivBy10 = 9;
@ -14990,24 +14980,30 @@ static void Cmd_pickup(void)
&& heldItem == ITEM_NONE
&& (Random() % 10) == 0)
{
s32 j;
s32 rand = Random() % 100;
for (j = 0; j < (int)ARRAY_COUNT(sPickupProbabilities); j++)
if (isInPyramid)
{
if (sPickupProbabilities[j] > rand)
heldItem = GetBattlePyramidPickupItemId();
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem);
}
else
{
u32 rand = Random() % 100;
for (j = 0; j < ARRAY_COUNT(sPickupProbabilities); j++)
{
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sPickupItems[lvlDivBy10 + j]);
break;
}
else if (rand == 99 || rand == 98)
{
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sRarePickupItems[lvlDivBy10 + (99 - rand)]);
break;
if (sPickupProbabilities[j] > rand)
{
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sPickupItems[lvlDivBy10 + j]);
break;
}
else if (rand == 99 || rand == 98)
{
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &sRarePickupItems[lvlDivBy10 + (99 - rand)]);
break;
}
}
}
}
#if (defined ITEM_HONEY)
else if (ability == ABILITY_HONEY_GATHER
&& species != 0
&& species != SPECIES_EGG
@ -15019,6 +15015,14 @@ static void Cmd_pickup(void)
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem);
}
}
#if P_SHUCKLE_BERRY_JUICE == TRUE
else if (species == SPECIES_SHUCKLE
&& heldItem == ITEM_ORAN_BERRY
&& (Random() % 16) == 0)
{
heldItem = ITEM_BERRY_JUICE;
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &heldItem);
}
#endif
}
}
@ -16108,10 +16112,8 @@ static bool32 CriticalCapture(u32 odds)
else
odds = (odds * 250) / 100;
#ifdef ITEM_CATCHING_CHARM
if (CheckBagHasItem(ITEM_CATCHING_CHARM, 1))
odds = (odds * (100 + B_CATCHING_CHARM_BOOST)) / 100;
#endif
odds /= 6;
if ((Random() % 255) < odds)

View File

@ -10276,6 +10276,14 @@ void ClearIllusionMon(u32 battlerId)
memset(&gBattleStruct->illusion[battlerId], 0, sizeof(gBattleStruct->illusion[battlerId]));
}
u32 GetIllusionMonSpecies(u32 battlerId)
{
struct Pokemon *illusionMon = GetIllusionMonPtr(battlerId);
if (illusionMon != NULL)
return GetMonData(illusionMon, MON_DATA_SPECIES);
return SPECIES_NONE;
}
bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId)
{
struct Pokemon *party, *partnerMon;

View File

@ -204,11 +204,7 @@ bool32 IsViableZMove(u8 battlerId, u16 move)
else
holdEffect = ItemId_GetHoldEffect(item);
#ifdef ITEM_ULTRANECROZIUM_Z
if (holdEffect == HOLD_EFFECT_Z_CRYSTAL || item == ITEM_ULTRANECROZIUM_Z)
#else
if (holdEffect == HOLD_EFFECT_Z_CRYSTAL)
#endif
{
u16 zMove = GetSignatureZMove(move, gBattleMons[battlerId].species, item);
if (zMove != MOVE_NONE)

View File

@ -6833,7 +6833,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
.accuracy = 100,
.pp = 15,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_SELECTED,
.target = MOVE_TARGET_BOTH,
.priority = 0,
.split = SPLIT_STATUS,
.zMovePower = 0,
@ -13294,7 +13294,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
.effect = EFFECT_DEFENSE_UP_HIT,
.power = 70,
.type = TYPE_PSYCHIC,
.accuracy = 100,
.accuracy = 90,
.pp = 10,
.secondaryEffectChance = 100,
.target = MOVE_TARGET_SELECTED,

View File

@ -5165,7 +5165,6 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task)
u16 *itemPtr = &gSpecialVar_ItemId;
bool8 cannotUseEffect;
u8 holdEffectParam = ItemId_GetHoldEffectParam(*itemPtr);
u16 targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE, NULL);
sInitialLevel = GetMonData(mon, MON_DATA_LEVEL);
if (sInitialLevel != MAX_LEVEL)
@ -5181,10 +5180,22 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task)
PlaySE(SE_SELECT);
if (cannotUseEffect)
{
if (targetSpecies != SPECIES_NONE && holdEffectParam == 0)
u16 targetSpecies = SPECIES_NONE;
// Resets values to 0 so other means of teaching moves doesn't overwrite levels
sInitialLevel = 0;
sFinalLevel = 0;
if (holdEffectParam == 0)
targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE, NULL);
if (targetSpecies != SPECIES_NONE)
{
PartyMenuTryEvolution(taskId);
RemoveBagItem(gSpecialVar_ItemId, 1);
FreePartyPointers();
gCB2_AfterEvolution = gPartyMenu.exitCallback;
BeginEvolutionScene(mon, targetSpecies, TRUE, gPartyMenu.slotId);
DestroyTask(taskId);
}
else
{

View File

@ -0,0 +1,80 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH);
ASSUME(gBattleMoves[MOVE_LUNAR_DANCE].effect == EFFECT_HEALING_WISH);
}
#define TEST_MAX_HP (100)
SINGLE_BATTLE_TEST("Healing Wish causes the user to faint and fully heals the replacement")
{
GIVEN {
ASSUME(B_HEALING_WISH_SWITCH >= GEN_5);
PLAYER(SPECIES_GARDEVOIR);
PLAYER(SPECIES_WYNAUT) { HP(1); MaxHP(TEST_MAX_HP); Status1(STATUS1_POISON); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_HEALING_WISH); SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_HEALING_WISH, player);
HP_BAR(player, hp: 0);
MESSAGE("Gardevoir fainted!");
MESSAGE("The healing wish came true for Wynaut!");
HP_BAR(player, hp: TEST_MAX_HP);
STATUS_ICON(player, none: TRUE);
MESSAGE("Wynaut regained health!");
}
}
DOUBLE_BATTLE_TEST("Lunar Dance causes the user to faint and fully heals the replacement in a double battle")
{
GIVEN {
ASSUME(B_HEALING_WISH_SWITCH >= GEN_5);
PLAYER(SPECIES_GARDEVOIR) { Speed(300); }
PLAYER(SPECIES_WOBBUFFET) { Speed(50); }
PLAYER(SPECIES_WYNAUT) { HP(TEST_MAX_HP - 1); MaxHP(TEST_MAX_HP); Status1(STATUS1_BURN); Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(50); }
} WHEN {
TURN { MOVE(playerLeft, MOVE_LUNAR_DANCE); SEND_OUT(playerLeft, 2); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_LUNAR_DANCE, playerLeft);
HP_BAR(playerLeft, hp: 0);
MESSAGE("Gardevoir fainted!");
MESSAGE("Wynaut became cloaked in mystical moonlight!");
HP_BAR(playerLeft, hp: TEST_MAX_HP);
STATUS_ICON(playerLeft, none: TRUE);
MESSAGE("Wynaut regained health!");
}
}
SINGLE_BATTLE_TEST("Healing Wish effect activates only if the switched pokemon can be healed")
{
GIVEN {
ASSUME(B_HEALING_WISH_SWITCH >= GEN_8);
PLAYER(SPECIES_GARDEVOIR) { Speed(300); }
PLAYER(SPECIES_NINJASK) { Speed(400); }
PLAYER(SPECIES_WYNAUT) { HP(TEST_MAX_HP / 2); MaxHP(TEST_MAX_HP); Status1(STATUS1_PARALYSIS); Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) {Speed(50); }
} WHEN {
TURN { MOVE(player, MOVE_HEALING_WISH); SEND_OUT(player, 1); }
TURN { MOVE(player, MOVE_U_TURN); SEND_OUT(player, 2); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_HEALING_WISH, player);
HP_BAR(player, hp: 0);
MESSAGE("Gardevoir fainted!");
NONE_OF {
MESSAGE("The healing wish came true for Wynaut!");
MESSAGE("Wynaut regained health!");
}
ANIMATION(ANIM_TYPE_MOVE, MOVE_U_TURN, player);
MESSAGE("Do it! Wynaut!");
MESSAGE("The healing wish came true for Wynaut!");
HP_BAR(player, hp: TEST_MAX_HP);
STATUS_ICON(player, none: TRUE);
MESSAGE("Wynaut regained health!");
}
}

View File

@ -42,8 +42,8 @@ SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on protect")
SINGLE_BATTLE_TEST("Jump Kick has no recoil if no target")
{
KNOWN_FAILING; // #2596.
GIVEN {
ASSUME(B_HEALING_WISH_SWITCH >= GEN_5);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);