Adds combined pledge move effects (#3336)
* Adds combined pledge move effects * added pledge status and various other fixes * leftover * fix triple arrow test tag * pledge moves can not be redirected by absorbing abilities * more pledge changes * remove duplicate test * Stab boost, Rainbow anim and new SeaOfFire anim * leftover --------- Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>
This commit is contained in:
parent
be42d4eafb
commit
b9edbb429b
26 changed files with 872 additions and 22 deletions
|
@ -1380,6 +1380,17 @@
|
|||
callnative BS_TryRelicSong
|
||||
.endm
|
||||
|
||||
.macro setpledge jumpInstr:req
|
||||
callnative BS_SetPledge
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro setpledgestatus battler:req sidestatus:req
|
||||
callnative BS_SetPledgeStatus
|
||||
.byte \battler
|
||||
.4byte \sidestatus
|
||||
.endm
|
||||
|
||||
.macro setzeffect
|
||||
callnative BS_SetZEffect
|
||||
.endm
|
||||
|
|
|
@ -1010,6 +1010,9 @@ gBattleAnims_General::
|
|||
.4byte General_DynamaxGrowth @ B_ANIM_DYNAMAX_GROWTH
|
||||
.4byte General_SetWeather @ B_ANIM_MAX_SET_WEATHER
|
||||
.4byte General_SyrupBombSpeedDrop @ B_ANIM_SYRUP_BOMB_SPEED_DROP
|
||||
.4byte General_Rainbow @ B_ANIM_RAINBOW
|
||||
.4byte General_SeaOfFire @ B_ANIM_SEA_OF_FIRE
|
||||
.4byte General_Swamp @ B_ANIM_SWAMP
|
||||
|
||||
.align 2
|
||||
gBattleAnims_Special::
|
||||
|
@ -27060,6 +27063,10 @@ General_HangedOn:
|
|||
end
|
||||
|
||||
General_Rain:
|
||||
call RainDrops
|
||||
end
|
||||
|
||||
RainDrops:
|
||||
loadspritegfx ANIM_TAG_RAIN_DROPS
|
||||
playsewithpan SE_M_RAIN_DANCE, SOUND_PAN_ATTACKER
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 2, 0, 4, RGB_BLACK
|
||||
|
@ -27070,7 +27077,7 @@ General_Rain:
|
|||
waitforvisualfinish
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 2, 4, 0, RGB_BLACK
|
||||
waitforvisualfinish
|
||||
end
|
||||
return
|
||||
|
||||
General_Sun:
|
||||
goto Move_SUNNY_DAY
|
||||
|
@ -27515,6 +27522,75 @@ General_AffectionHangedOn_3Hearts:
|
|||
General_SaltCureDamage::
|
||||
goto Status_Freeze
|
||||
|
||||
General_Rainbow::
|
||||
call RainDrops
|
||||
delay 30
|
||||
loadspritegfx ANIM_TAG_SUNLIGHT
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 1, 0, 6, RGB_WHITE
|
||||
waitforvisualfinish
|
||||
panse_adjustnone SE_M_PETAL_DANCE, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +1, 0
|
||||
call SunnyDayLightRay
|
||||
call SunnyDayLightRay
|
||||
call SunnyDayLightRay
|
||||
waitforvisualfinish
|
||||
createvisualtask AnimTask_BlendBattleAnimPal, 10, (F_PAL_BG | F_PAL_BATTLERS), 1, 6, 0, RGB_WHITE
|
||||
waitforvisualfinish
|
||||
delay 30
|
||||
fadetobg BG_RAINBOW
|
||||
panse_adjustnone SE_M_ABSORB_2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, +1, 0
|
||||
delay 90
|
||||
blendoff
|
||||
restorebg
|
||||
waitbgfadein
|
||||
clearmonbg ANIM_ATK_PARTNER
|
||||
end
|
||||
|
||||
General_SeaOfFire::
|
||||
loadspritegfx ANIM_TAG_SMALL_EMBER
|
||||
monbg ANIM_DEF_PARTNER
|
||||
splitbgprio ANIM_TARGET
|
||||
playsewithpan SE_M_SACRED_FIRE2, SOUND_PAN_TARGET
|
||||
call SeaOfFireTwisterDos
|
||||
delay 3
|
||||
call SeaOfFireTwisterTres
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_DEF_PARTNER
|
||||
blendoff
|
||||
end
|
||||
|
||||
SeaOfFireTwisterDos:
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 45, 90, 5, 70, 30
|
||||
delay 2
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 50, 85, 6, 60, 30
|
||||
delay 1
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 47, 77, 7, 60, 30
|
||||
delay 2
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 40, 86, 8, 50, 30
|
||||
delay 3
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 42, 82, 7, 45, 30
|
||||
delay 1
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 47, 83, 5, 38, 30
|
||||
delay 2
|
||||
return
|
||||
|
||||
SeaOfFireTwisterTres:
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 45, 90, 3, 45, 30
|
||||
delay 2
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 50, 85, 4, 39, 30
|
||||
delay 1
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 47, 77, 5, 39, 30
|
||||
delay 2
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 40, 86, 6, 32, 30
|
||||
delay 3
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 42, 82, 5, 27, 30
|
||||
delay 1
|
||||
createsprite gTwisterEmberSpriteTemplate, ANIM_TARGET, 2, 47, 83, 3, 24, 30
|
||||
delay 2
|
||||
return
|
||||
|
||||
General_Swamp:: @ To do
|
||||
goto Move_HAZE
|
||||
|
||||
SnatchMoveTrySwapFromSubstitute:
|
||||
createvisualtask AnimTask_IsAttackerBehindSubstitute, 2
|
||||
jumprettrue SnatchMoveSwapSubstituteForMon
|
||||
|
|
|
@ -231,7 +231,7 @@ gBattleScriptsForMoveEffects::
|
|||
.4byte BattleScript_EffectCalmMind @ EFFECT_CALM_MIND
|
||||
.4byte BattleScript_EffectDragonDance @ EFFECT_DRAGON_DANCE
|
||||
.4byte BattleScript_EffectCamouflage @ EFFECT_CAMOUFLAGE
|
||||
.4byte BattleScript_EffectHit @ EFFECT_PLEDGE
|
||||
.4byte BattleScript_EffectPledge @ EFFECT_PLEDGE
|
||||
.4byte BattleScript_EffectFling @ EFFECT_FLING
|
||||
.4byte BattleScript_EffectNaturalGift @ EFFECT_NATURAL_GIFT
|
||||
.4byte BattleScript_EffectWakeUpSlap @ EFFECT_WAKE_UP_SLAP
|
||||
|
@ -472,6 +472,90 @@ BattleScript_EffectMatchaGotcha::
|
|||
setmoveeffect MOVE_EFFECT_BURN
|
||||
goto BattleScript_EffectAbsorb
|
||||
|
||||
BattleScript_EffectPledge::
|
||||
attackcanceler
|
||||
setpledge BattleScript_HitFromAccCheck
|
||||
attackstring
|
||||
pause B_WAIT_TIME_MED
|
||||
ppreduce
|
||||
printstring STRINGID_WAITINGFORPARTNERSMOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectCombinedPledge_Water::
|
||||
call BattleScript_EffectHit_Pledge
|
||||
setpledgestatus BS_ATTACKER, SIDE_STATUS_RAINBOW
|
||||
pause B_WAIT_TIME_SHORTEST
|
||||
printstring STRINGID_ARAINBOWAPPEAREDONSIDE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
playanimation BS_ATTACKER, B_ANIM_RAINBOW
|
||||
waitanimation
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_TheRainbowDisappeared::
|
||||
printstring STRINGID_THERAINBOWDISAPPEARED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
||||
BattleScript_EffectCombinedPledge_Fire::
|
||||
call BattleScript_EffectHit_Pledge
|
||||
setpledgestatus BS_TARGET, SIDE_STATUS_SEA_OF_FIRE
|
||||
pause B_WAIT_TIME_SHORTEST
|
||||
printstring STRINGID_SEAOFFIREENVELOPEDSIDE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
playanimation BS_TARGET, B_ANIM_SEA_OF_FIRE
|
||||
waitanimation
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_HurtByTheSeaOfFire::
|
||||
printstring STRINGID_HURTBYTHESEAOFFIRE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_DoTurnDmg
|
||||
|
||||
BattleScript_TheSeaOfFireDisappeared::
|
||||
printstring STRINGID_THESEAOFFIREDISAPPEARED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
||||
BattleScript_EffectCombinedPledge_Grass::
|
||||
call BattleScript_EffectHit_Pledge
|
||||
setpledgestatus BS_TARGET, SIDE_STATUS_SWAMP
|
||||
pause B_WAIT_TIME_SHORTEST
|
||||
printstring STRINGID_SWAMPENVELOPEDSIDE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
playanimation BS_TARGET, B_ANIM_SWAMP
|
||||
waitanimation
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_TheSwampDisappeared::
|
||||
printstring STRINGID_THESWAMPDISAPPEARED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
||||
BattleScript_EffectHit_Pledge::
|
||||
pause B_WAIT_TIME_MED
|
||||
printstring STRINGID_THETWOMOVESBECOMEONE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
ppreduce
|
||||
critcalc
|
||||
damagecalc
|
||||
adjustdamage
|
||||
attackanimation
|
||||
waitanimation
|
||||
effectivenesssound
|
||||
hitanimation BS_TARGET
|
||||
waitstate
|
||||
healthbarupdate BS_TARGET
|
||||
datahpupdate BS_TARGET
|
||||
critmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
seteffectwithchance
|
||||
tryfaintmon BS_TARGET
|
||||
return
|
||||
|
||||
BattleScript_EffectSaltCure:
|
||||
call BattleScript_EffectHit_Ret
|
||||
tryfaintmon BS_TARGET
|
||||
|
|
BIN
graphics/battle_anims/backgrounds/rainbow.bin
Normal file
BIN
graphics/battle_anims/backgrounds/rainbow.bin
Normal file
Binary file not shown.
19
graphics/battle_anims/backgrounds/rainbow.pal
Normal file
19
graphics/battle_anims/backgrounds/rainbow.pal
Normal file
|
@ -0,0 +1,19 @@
|
|||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
109 92 75
|
||||
255 255 255
|
||||
255 107 122
|
||||
255 200 102
|
||||
255 255 107
|
||||
143 255 160
|
||||
107 255 255
|
||||
107 129 255
|
||||
220 114 255
|
||||
199 255 250
|
||||
232 240 248
|
||||
224 232 240
|
||||
208 224 240
|
||||
191 202 224
|
||||
183 189 202
|
||||
157 166 181
|
BIN
graphics/battle_anims/backgrounds/rainbow.png
Normal file
BIN
graphics/battle_anims/backgrounds/rainbow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
|
@ -235,6 +235,9 @@ struct SideTimer
|
|||
u8 retaliateTimer;
|
||||
u8 damageNonTypesTimer;
|
||||
u8 damageNonTypesType;
|
||||
u8 rainbowTimer;
|
||||
u8 seaOfFireTimer;
|
||||
u8 swampTimer;
|
||||
};
|
||||
|
||||
struct FieldTimer
|
||||
|
@ -726,6 +729,7 @@ struct BattleStruct
|
|||
u32 aiDelayTimer; // Counts number of frames AI takes to choose an action.
|
||||
u32 aiDelayFrames; // Number of frames it took to choose an action.
|
||||
bool8 transformZeroToHero[PARTY_SIZE][NUM_BATTLE_SIDES];
|
||||
u8 pledgeMove:1;
|
||||
};
|
||||
|
||||
// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,
|
||||
|
|
|
@ -483,6 +483,13 @@ extern const u8 BattleScript_SelectingNotAllowedCurrentMoveInPalace[];
|
|||
extern const u8 BattleScript_SaltCureExtraDamage[];
|
||||
extern const u8 BattleScript_SyrupBombEndTurn[];
|
||||
extern const u8 BattleScript_SyrupBombActivates[];
|
||||
extern const u8 BattleScript_EffectCombinedPledge_Water[];
|
||||
extern const u8 BattleScript_EffectCombinedPledge_Fire[];
|
||||
extern const u8 BattleScript_EffectCombinedPledge_Grass[];
|
||||
extern const u8 BattleScript_TheRainbowDisappeared[];
|
||||
extern const u8 BattleScript_HurtByTheSeaOfFire[];
|
||||
extern const u8 BattleScript_TheSeaOfFireDisappeared[];
|
||||
extern const u8 BattleScript_TheSwampDisappeared[];
|
||||
|
||||
// zmoves
|
||||
extern const u8 BattleScript_ZMoveActivateDamaging[];
|
||||
|
|
|
@ -247,7 +247,7 @@ void RemoveConfusionStatus(u32 battler);
|
|||
u8 GetBattlerGender(u32 battler);
|
||||
bool32 AreBattlersOfOppositeGender(u32 battler1, u32 battler2);
|
||||
bool32 AreBattlersOfSameGender(u32 battler1, u32 battler2);
|
||||
u32 CalcSecondaryEffectChance(u32 battler, u8 secondaryEffectChance);
|
||||
u32 CalcSecondaryEffectChance(u32 battler, u8 secondaryEffectChance, u16 moveEffect);
|
||||
u8 GetBattlerType(u32 battler, u8 typeIndex);
|
||||
|
||||
#endif // GUARD_BATTLE_UTIL_H
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#define B_TAUNT_TURNS GEN_LATEST // In Gen5+, Taunt lasts 3 turns if the user acts before the target, or 4 turns if the target acted before the user. In Gen3, taunt lasts 2 turns and in Gen 4, 3-5 turns.
|
||||
#define B_SPORT_TURNS GEN_LATEST // In Gen6+, Water/Mud Sport last 5 turns, even if the user switches out.
|
||||
#define B_MEGA_EVO_TURN_ORDER GEN_LATEST // In Gen7, a Pokémon's Speed after Mega Evolution is used to determine turn order, not its Speed before.
|
||||
#define B_RECALC_TURN_AFTER_ACTIONS GEN_LATEST // In Gen8, switching/using a move affects the current turn's order of actions.
|
||||
#define B_RECALC_TURN_AFTER_ACTIONS GEN_LATEST // In Gen8, switching/using a move affects the current turn's order of actions, better known as dynamic speed.
|
||||
#define B_FAINT_SWITCH_IN GEN_LATEST // In Gen4+, sending out a new Pokémon after the previous one fainted happens at the end of the turn. Before, it would happen after each action.
|
||||
|
||||
// Move data settings
|
||||
|
|
|
@ -238,9 +238,13 @@
|
|||
#define SIDE_STATUS_MAT_BLOCK (1 << 21)
|
||||
#define SIDE_STATUS_STEELSURGE (1 << 22)
|
||||
#define SIDE_STATUS_DAMAGE_NON_TYPES (1 << 23)
|
||||
#define SIDE_STATUS_RAINBOW (1 << 24)
|
||||
#define SIDE_STATUS_SEA_OF_FIRE (1 << 25)
|
||||
#define SIDE_STATUS_SWAMP (1 << 26)
|
||||
|
||||
#define SIDE_STATUS_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STEELSURGE)
|
||||
#define SIDE_STATUS_SCREEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL)
|
||||
#define SIDE_STATUS_PLEDGE_ANY (SIDE_STATUS_RAINBOW | SIDE_STATUS_SEA_OF_FIRE | SIDE_STATUS_SWAMP)
|
||||
|
||||
// Field affecting statuses.
|
||||
#define STATUS_FIELD_MAGIC_ROOM (1 << 0)
|
||||
|
|
|
@ -515,6 +515,7 @@
|
|||
#define BG_STEEL_BEAM_OPPONENT 78
|
||||
#define BG_STEEL_BEAM_PLAYER 79
|
||||
#define BG_CHLOROBLAST 80
|
||||
#define BG_RAINBOW 81
|
||||
|
||||
// table ids for general animations (gBattleAnims_General)
|
||||
#define B_ANIM_STATS_CHANGE 0
|
||||
|
@ -559,6 +560,9 @@
|
|||
#define B_ANIM_DYNAMAX_GROWTH 39
|
||||
#define B_ANIM_MAX_SET_WEATHER 40
|
||||
#define B_ANIM_SYRUP_BOMB_SPEED_DROP 41
|
||||
#define B_ANIM_RAINBOW 42
|
||||
#define B_ANIM_SEA_OF_FIRE 43
|
||||
#define B_ANIM_SWAMP 44
|
||||
|
||||
// special animations table (gBattleAnims_Special)
|
||||
#define B_ANIM_LVL_UP 0
|
||||
|
|
|
@ -686,8 +686,17 @@
|
|||
#define STRINGID_PKMNHURTBYROCKSTHROWN 684
|
||||
#define STRINGID_MOVEBLOCKEDBYDYNAMAX 685
|
||||
#define STRINGID_ZEROTOHEROTRANSFORMATION 686
|
||||
#define STRINGID_THETWOMOVESBECOMEONE 687
|
||||
#define STRINGID_ARAINBOWAPPEAREDONSIDE 688
|
||||
#define STRINGID_THERAINBOWDISAPPEARED 689
|
||||
#define STRINGID_WAITINGFORPARTNERSMOVE 690
|
||||
#define STRINGID_SEAOFFIREENVELOPEDSIDE 691
|
||||
#define STRINGID_HURTBYTHESEAOFFIRE 692
|
||||
#define STRINGID_THESEAOFFIREDISAPPEARED 693
|
||||
#define STRINGID_SWAMPENVELOPEDSIDE 694
|
||||
#define STRINGID_THESWAMPDISAPPEARED 695
|
||||
|
||||
#define BATTLESTRINGS_COUNT 687
|
||||
#define BATTLESTRINGS_COUNT 696
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
|
|
@ -11510,6 +11510,11 @@ extern const u16 gSlotMachineReelTimePikachu_Pal[];
|
|||
extern const u32 gBattleAnimBgTilemap_Sandstorm[];
|
||||
extern const u32 gBattleAnimBgImage_Sandstorm[];
|
||||
|
||||
// Pledge Effect field status - Rainbow
|
||||
extern const u32 gBattleAnimBgImage_Rainbow[];
|
||||
extern const u32 gBattleAnimBGPalette_Rainbow[];
|
||||
extern const u32 gBattleAnimBgTilemap_Rainbow[];
|
||||
|
||||
// Pokedex Area Screen
|
||||
extern const u32 gPokedexAreaScreenAreaUnknown_Gfx[];
|
||||
extern const u16 gPokedexAreaScreenAreaUnknown_Pal[];
|
||||
|
|
|
@ -578,6 +578,7 @@ static u32 ChooseMoveOrAction_Doubles(u32 battlerAi)
|
|||
AI_THINKING_STRUCT->aiLogicId = 0;
|
||||
AI_THINKING_STRUCT->movesetIndex = 0;
|
||||
flags = AI_THINKING_STRUCT->aiFlags;
|
||||
|
||||
while (flags != 0)
|
||||
{
|
||||
if (flags & 1)
|
||||
|
|
|
@ -278,6 +278,9 @@ void LaunchBattleAnimation(u32 animType, u32 animId)
|
|||
case B_ANIM_PRIMAL_REVERSION:
|
||||
case B_ANIM_ULTRA_BURST:
|
||||
case B_ANIM_GULP_MISSILE:
|
||||
case B_ANIM_RAINBOW:
|
||||
case B_ANIM_SEA_OF_FIRE:
|
||||
case B_ANIM_SWAMP:
|
||||
sAnimHideHpBoxes = TRUE;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -527,6 +527,18 @@ const struct SpriteTemplate gSpacialRendBladesTemplate2 =
|
|||
.callback = AnimFireSpread
|
||||
};
|
||||
|
||||
// Sea of Fire
|
||||
const struct SpriteTemplate gTwisterEmberSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_SMALL_EMBER,
|
||||
.paletteTag = ANIM_TAG_SMALL_EMBER,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = gAnims_BasicFire,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimMoveTwisterParticle,
|
||||
};
|
||||
|
||||
static void AnimLavaPlumeOrbitScatter(struct Sprite *sprite)
|
||||
{
|
||||
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
|
||||
|
|
|
@ -4651,6 +4651,9 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect)
|
|||
if (gBattleMons[battler].status1 & STATUS1_PARALYSIS && ability != ABILITY_QUICK_FEET)
|
||||
speed /= B_PARALYSIS_SPEED >= GEN_7 ? 2 : 4;
|
||||
|
||||
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SWAMP)
|
||||
speed /= 4;
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
|
|
|
@ -823,9 +823,27 @@ static const u8 sText_TargetIsHurtBySaltCure[] = _("{B_DEF_NAME_WITH_PREFIX} is
|
|||
static const u8 sText_OpportunistCopied[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} copied its\nopponent's stat changes!");
|
||||
static const u8 sText_TargetCoveredInStickyCandySyrup[] = _("{B_DEF_NAME_WITH_PREFIX} got covered\nin sticky syrup!");
|
||||
static const u8 sText_ZeroToHeroTransformation[] = _("{B_ATK_NAME_WITH_PREFIX} underwent a heroic\ntransformation!");
|
||||
static const u8 sText_TheTwoMovesBecomeOne[] = _("The two moves become one!\nIt's a combined move!{PAUSE 16}");
|
||||
static const u8 sText_ARainbowAppearedOnSide[] = _("A rainbow appeared in the sky\non {B_ATK_TEAM2} team's side!");
|
||||
static const u8 sText_TheRainbowDisappeared[] = _("The rainbow on {B_ATK_TEAM2}\nside disappeared!");
|
||||
static const u8 sText_WaitingForPartnersMove[] = _("{B_ATK_NAME_WITH_PREFIX} is waiting\nfor {B_ATK_PARTNER_NAME}'s move…{PAUSE 16}");
|
||||
static const u8 sText_SeaOfFireEnvelopedSide[] = _("A sea of fire enveloped\n{B_DEF_TEAM2} team!");
|
||||
static const u8 sText_HurtByTheSeaOfFire[] = _("{B_ATK_TEAM1} {B_ATK_NAME_WITH_PREFIX} was hurt\nby the sea of fire!");
|
||||
static const u8 sText_TheSeaOfFireDisappeared[] = _("The sea of fire around {B_ATK_TEAM2}\nteam disappeared!");
|
||||
static const u8 sText_SwampEnvelopedSide[] = _("A swamp enveloped\n{B_DEF_TEAM2} team!");
|
||||
static const u8 sText_TheSwampDisappeared[] = _("The swamp around {B_ATK_TEAM2}\nteam disappeared!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_THESWAMPDISAPPEARED - BATTLESTRINGS_TABLE_START] = sText_TheSwampDisappeared,
|
||||
[STRINGID_SWAMPENVELOPEDSIDE - BATTLESTRINGS_TABLE_START] = sText_SwampEnvelopedSide,
|
||||
[STRINGID_THESEAOFFIREDISAPPEARED - BATTLESTRINGS_TABLE_START] = sText_TheSeaOfFireDisappeared,
|
||||
[STRINGID_HURTBYTHESEAOFFIRE - BATTLESTRINGS_TABLE_START] = sText_HurtByTheSeaOfFire,
|
||||
[STRINGID_SEAOFFIREENVELOPEDSIDE - BATTLESTRINGS_TABLE_START] = sText_SeaOfFireEnvelopedSide,
|
||||
[STRINGID_WAITINGFORPARTNERSMOVE - BATTLESTRINGS_TABLE_START] = sText_WaitingForPartnersMove,
|
||||
[STRINGID_THERAINBOWDISAPPEARED - BATTLESTRINGS_TABLE_START] = sText_TheRainbowDisappeared,
|
||||
[STRINGID_ARAINBOWAPPEAREDONSIDE - BATTLESTRINGS_TABLE_START] = sText_ARainbowAppearedOnSide,
|
||||
[STRINGID_THETWOMOVESBECOMEONE - BATTLESTRINGS_TABLE_START] = sText_TheTwoMovesBecomeOne,
|
||||
[STRINGID_ZEROTOHEROTRANSFORMATION - BATTLESTRINGS_TABLE_START] = sText_ZeroToHeroTransformation,
|
||||
[STRINGID_MOVEBLOCKEDBYDYNAMAX - BATTLESTRINGS_TABLE_START] = sText_MoveBlockedByDynamax,
|
||||
[STRINGID_OPPORTUNISTCOPIED - BATTLESTRINGS_TABLE_START] = sText_OpportunistCopied,
|
||||
|
|
|
@ -2076,7 +2076,9 @@ END:
|
|||
}
|
||||
if (gSpecialStatuses[gBattlerAttacker].gemBoost
|
||||
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& gBattleMons[gBattlerAttacker].item)
|
||||
&& gBattleMons[gBattlerAttacker].item
|
||||
&& gBattleMoves[gCurrentMove].effect != EFFECT_PLEDGE
|
||||
&& gCurrentMove != MOVE_STRUGGLE)
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_GemActivates;
|
||||
|
@ -3598,8 +3600,8 @@ void SetMoveEffect(bool32 primary, u32 certain)
|
|||
break;
|
||||
case MOVE_EFFECT_TRIPLE_ARROWS:
|
||||
{
|
||||
u8 randomLowerDefenseChance = RandomPercentage(RNG_TRIPLE_ARROWS_DEFENSE_DOWN, CalcSecondaryEffectChance(gBattlerAttacker, 50));
|
||||
u8 randomFlinchChance = RandomPercentage(RNG_TRIPLE_ARROWS_FLINCH, CalcSecondaryEffectChance(gBattlerAttacker, 30));
|
||||
u8 randomLowerDefenseChance = RandomPercentage(RNG_TRIPLE_ARROWS_DEFENSE_DOWN, CalcSecondaryEffectChance(gBattlerAttacker, 50, EFFECT_DEFENSE_DOWN_HIT));
|
||||
u8 randomFlinchChance = RandomPercentage(RNG_TRIPLE_ARROWS_FLINCH, CalcSecondaryEffectChance(gBattlerAttacker, 30, EFFECT_FLINCH_HIT));
|
||||
|
||||
if (randomFlinchChance && battlerAbility != ABILITY_INNER_FOCUS && GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber)
|
||||
gBattleMons[gEffectBattler].status2 |= sStatusFlagsForMoveEffects[MOVE_EFFECT_FLINCH];
|
||||
|
@ -3639,7 +3641,7 @@ static void Cmd_seteffectwithchance(void)
|
|||
{
|
||||
CMD_ARGS();
|
||||
|
||||
u32 percentChance = CalcSecondaryEffectChance(gBattlerAttacker, gBattleMoves[gCurrentMove].secondaryEffectChance);
|
||||
u32 percentChance = CalcSecondaryEffectChance(gBattlerAttacker, gBattleMoves[gCurrentMove].secondaryEffectChance, gBattleMoves[gCurrentMove].effect);
|
||||
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& gBattleScripting.moveEffect)
|
||||
|
@ -8322,8 +8324,6 @@ static void CourtChangeSwapSideStatuses(void)
|
|||
struct SideTimer *sideTimerOpp = &gSideTimers[B_SIDE_OPPONENT];
|
||||
u32 temp;
|
||||
|
||||
// TODO: add Pledge-related effects
|
||||
|
||||
// Swap timers and statuses
|
||||
COURTCHANGE_SWAP(SIDE_STATUS_REFLECT, reflectTimer, temp)
|
||||
COURTCHANGE_SWAP(SIDE_STATUS_LIGHTSCREEN, lightscreenTimer, temp)
|
||||
|
@ -8339,6 +8339,10 @@ static void CourtChangeSwapSideStatuses(void)
|
|||
COURTCHANGE_SWAP(SIDE_STATUS_STICKY_WEB, stickyWebAmount, temp);
|
||||
COURTCHANGE_SWAP(SIDE_STATUS_STEELSURGE, steelsurgeAmount, temp);
|
||||
COURTCHANGE_SWAP(SIDE_STATUS_DAMAGE_NON_TYPES, damageNonTypesTimer, temp);
|
||||
// Track Pledge effect side
|
||||
COURTCHANGE_SWAP(SIDE_STATUS_RAINBOW, rainbowTimer, temp);
|
||||
COURTCHANGE_SWAP(SIDE_STATUS_SEA_OF_FIRE, seaOfFireTimer, temp);
|
||||
COURTCHANGE_SWAP(SIDE_STATUS_SWAMP, swampTimer, temp);
|
||||
|
||||
// Change battler IDs of swapped effects. Needed for the correct string when they expire
|
||||
// E.g. "Foe's Reflect wore off!"
|
||||
|
@ -16285,3 +16289,115 @@ void BS_TryRelicSong(void)
|
|||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
|
||||
void BS_SetPledge(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *jumpInstr);
|
||||
|
||||
u32 partner = BATTLE_PARTNER(gBattlerAttacker);
|
||||
u32 partnerMove = gBattleMons[partner].moves[gBattleStruct->chosenMovePositions[partner]];
|
||||
u32 i = 0;
|
||||
u32 k = 0;
|
||||
|
||||
if (gBattleStruct->pledgeMove)
|
||||
{
|
||||
PrepareStringBattle(STRINGID_USEDMOVE, gBattlerAttacker);
|
||||
gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED;
|
||||
|
||||
if ((gCurrentMove == MOVE_GRASS_PLEDGE && partnerMove == MOVE_WATER_PLEDGE)
|
||||
|| (gCurrentMove == MOVE_WATER_PLEDGE && partnerMove == MOVE_GRASS_PLEDGE))
|
||||
{
|
||||
gCurrentMove = MOVE_GRASS_PLEDGE;
|
||||
gBattlescriptCurrInstr = BattleScript_EffectCombinedPledge_Grass;
|
||||
}
|
||||
else if ((gCurrentMove == MOVE_FIRE_PLEDGE && partnerMove == MOVE_GRASS_PLEDGE)
|
||||
|| (gCurrentMove == MOVE_GRASS_PLEDGE && partnerMove == MOVE_FIRE_PLEDGE))
|
||||
{
|
||||
gCurrentMove = MOVE_FIRE_PLEDGE;
|
||||
gBattlescriptCurrInstr = BattleScript_EffectCombinedPledge_Fire;
|
||||
}
|
||||
else if ((gCurrentMove == MOVE_WATER_PLEDGE && partnerMove == MOVE_FIRE_PLEDGE)
|
||||
|| (gCurrentMove == MOVE_FIRE_PLEDGE && partnerMove == MOVE_WATER_PLEDGE))
|
||||
{
|
||||
gCurrentMove = MOVE_WATER_PLEDGE;
|
||||
gBattlescriptCurrInstr = BattleScript_EffectCombinedPledge_Water;
|
||||
}
|
||||
|
||||
gBattleCommunication[MSG_DISPLAY] = 0;
|
||||
}
|
||||
else if ((gChosenActionByBattler[partner] == B_ACTION_USE_MOVE)
|
||||
&& gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& IsBattlerAlive(partner)
|
||||
&& gCurrentMove != partnerMove
|
||||
&& gBattleMoves[partnerMove].effect == EFFECT_PLEDGE)
|
||||
{
|
||||
u32 currPledgeUser = 0;
|
||||
u32 newTurnOrder[] = {0xFF, 0xFF};
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattlerByTurnOrder[i] == gBattlerAttacker)
|
||||
{
|
||||
currPledgeUser = i + 1; // Current battler going after attacker
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = currPledgeUser; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattlerByTurnOrder[i] != partner)
|
||||
{
|
||||
newTurnOrder[k] = gBattlerByTurnOrder[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
gBattlerByTurnOrder[currPledgeUser] = partner;
|
||||
currPledgeUser++;
|
||||
|
||||
for (i = 0; newTurnOrder[i] != 0xFF && i < 2; i++)
|
||||
{
|
||||
gBattlerByTurnOrder[currPledgeUser] = newTurnOrder[i];
|
||||
currPledgeUser++;
|
||||
}
|
||||
|
||||
gBattleStruct->pledgeMove = TRUE;
|
||||
gBattleScripting.battler = partner;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void BS_SetPledgeStatus(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 battler, u32 sideStatus);
|
||||
|
||||
u32 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
u32 side = GetBattlerSide(battler);
|
||||
|
||||
gBattleStruct->pledgeMove = FALSE;
|
||||
if (!(gSideStatuses[side] & cmd->sideStatus))
|
||||
{
|
||||
gSideStatuses[side] |= cmd->sideStatus;
|
||||
|
||||
switch (cmd->sideStatus)
|
||||
{
|
||||
case SIDE_STATUS_RAINBOW:
|
||||
gSideTimers[side].rainbowTimer = 4;
|
||||
break;
|
||||
case SIDE_STATUS_SEA_OF_FIRE:
|
||||
gSideTimers[side].seaOfFireTimer = 4;
|
||||
break;
|
||||
case SIDE_STATUS_SWAMP:
|
||||
gSideTimers[side].swampTimer = 4;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEnd;
|
||||
}
|
||||
|
|
|
@ -373,6 +373,7 @@ void HandleAction_UseMove(void)
|
|||
|| (GetBattlerAbility(battler) == ABILITY_STORM_DRAIN && moveType == TYPE_WATER))
|
||||
&& GetBattlerTurnOrderNum(battler) < var
|
||||
&& gBattleMoves[gCurrentMove].effect != EFFECT_SNIPE_SHOT
|
||||
&& gBattleMoves[gCurrentMove].effect != EFFECT_PLEDGE
|
||||
&& (GetBattlerAbility(gBattlerAttacker) != ABILITY_PROPELLER_TAIL
|
||||
|| GetBattlerAbility(gBattlerAttacker) != ABILITY_STALWART))
|
||||
{
|
||||
|
@ -865,7 +866,7 @@ void HandleAction_ActionFinished(void)
|
|||
gBattleResources->battleScriptsStack->size = 0;
|
||||
gBattleStruct->dynamax.usingMaxMove[gBattlerAttacker] = 0;
|
||||
|
||||
if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 && !afterYouActive)
|
||||
if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove)
|
||||
{
|
||||
// i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already
|
||||
// taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action
|
||||
|
@ -1926,6 +1927,9 @@ enum
|
|||
ENDTURN_RETALIATE,
|
||||
ENDTURN_WEATHER_FORM,
|
||||
ENDTURN_STATUS_HEAL,
|
||||
ENDTURN_RAINBOW,
|
||||
ENDTURN_SEA_OF_FIRE,
|
||||
ENDTURN_SWAMP,
|
||||
ENDTURN_FIELD_COUNT,
|
||||
};
|
||||
|
||||
|
@ -2433,6 +2437,95 @@ u8 DoFieldEndTurnEffects(void)
|
|||
}
|
||||
gBattleStruct->turnCountersTracker++;
|
||||
break;
|
||||
case ENDTURN_RAINBOW:
|
||||
while (gBattleStruct->turnSideTracker < 2)
|
||||
{
|
||||
side = gBattleStruct->turnSideTracker;
|
||||
if (gSideStatuses[side] & SIDE_STATUS_RAINBOW)
|
||||
{
|
||||
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
|
||||
{
|
||||
if (GetBattlerSide(gBattlerAttacker) == side)
|
||||
break;
|
||||
}
|
||||
|
||||
if (gSideTimers[side].rainbowTimer > 0 && --gSideTimers[side].rainbowTimer == 0)
|
||||
{
|
||||
gSideStatuses[side] &= ~SIDE_STATUS_RAINBOW;
|
||||
BattleScriptExecute(BattleScript_TheRainbowDisappeared);
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
gBattleStruct->turnSideTracker++;
|
||||
if (effect != 0)
|
||||
break;
|
||||
}
|
||||
if (!effect)
|
||||
{
|
||||
gBattleStruct->turnCountersTracker++;
|
||||
gBattleStruct->turnSideTracker = 0;
|
||||
}
|
||||
break;
|
||||
case ENDTURN_SEA_OF_FIRE:
|
||||
while (gBattleStruct->turnSideTracker < 2)
|
||||
{
|
||||
side = gBattleStruct->turnSideTracker;
|
||||
|
||||
if (gSideStatuses[side] & SIDE_STATUS_SEA_OF_FIRE)
|
||||
{
|
||||
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
|
||||
{
|
||||
if (GetBattlerSide(gBattlerAttacker) == side)
|
||||
break;
|
||||
}
|
||||
|
||||
if (gSideTimers[side].seaOfFireTimer > 0 && --gSideTimers[side].seaOfFireTimer == 0)
|
||||
{
|
||||
gSideStatuses[side] &= ~SIDE_STATUS_SEA_OF_FIRE;
|
||||
BattleScriptExecute(BattleScript_TheSeaOfFireDisappeared);
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
gBattleStruct->turnSideTracker++;
|
||||
if (effect != 0)
|
||||
break;
|
||||
}
|
||||
if (!effect)
|
||||
{
|
||||
gBattleStruct->turnCountersTracker++;
|
||||
gBattleStruct->turnSideTracker = 0;
|
||||
}
|
||||
break;
|
||||
case ENDTURN_SWAMP:
|
||||
while (gBattleStruct->turnSideTracker < 2)
|
||||
{
|
||||
side = gBattleStruct->turnSideTracker;
|
||||
|
||||
if (gSideStatuses[side] & SIDE_STATUS_SWAMP)
|
||||
{
|
||||
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
|
||||
{
|
||||
if (GetBattlerSide(gBattlerAttacker) == side)
|
||||
break;
|
||||
}
|
||||
|
||||
if (gSideTimers[side].swampTimer > 0 && --gSideTimers[side].swampTimer == 0)
|
||||
{
|
||||
gSideStatuses[side] &= ~SIDE_STATUS_SWAMP;
|
||||
BattleScriptExecute(BattleScript_TheSwampDisappeared);
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
gBattleStruct->turnSideTracker++;
|
||||
if (effect != 0)
|
||||
break;
|
||||
}
|
||||
if (!effect)
|
||||
{
|
||||
gBattleStruct->turnCountersTracker++;
|
||||
gBattleStruct->turnSideTracker = 0;
|
||||
}
|
||||
break;
|
||||
case ENDTURN_FIELD_COUNT:
|
||||
effect++;
|
||||
break;
|
||||
|
@ -2483,6 +2576,7 @@ enum
|
|||
ENDTURN_SALT_CURE,
|
||||
ENDTURN_SYRUP_BOMB,
|
||||
ENDTURN_DYNAMAX,
|
||||
ENDTURN_SEA_OF_FIRE_DAMAGE,
|
||||
ENDTURN_BATTLER_COUNT
|
||||
};
|
||||
|
||||
|
@ -3069,6 +3163,17 @@ u8 DoBattlerEndTurnEffects(void)
|
|||
}
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_SEA_OF_FIRE_DAMAGE:
|
||||
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SEA_OF_FIRE)
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[battler].maxHP / 8;
|
||||
BtlController_EmitStatusAnimation(battler, BUFFER_A, FALSE, STATUS1_BURN);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
BattleScriptExecute(BattleScript_HurtByTheSeaOfFire);
|
||||
effect++;
|
||||
}
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_BATTLER_COUNT: // done
|
||||
gBattleStruct->turnEffectsTracker = 0;
|
||||
gBattleStruct->turnEffectsBattlerId++;
|
||||
|
@ -7610,6 +7715,8 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
|
|||
u16 ability = GetBattlerAbility(gBattlerAttacker);
|
||||
if (B_SERENE_GRACE_BOOST >= GEN_5 && ability == ABILITY_SERENE_GRACE)
|
||||
atkHoldEffectParam *= 2;
|
||||
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_RAINBOW && gCurrentMove != MOVE_SECRET_POWER)
|
||||
atkHoldEffectParam *= 2;
|
||||
if (gBattleMoveDamage != 0 // Need to have done damage
|
||||
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& TARGET_TURN_DAMAGED
|
||||
|
@ -8525,7 +8632,8 @@ static inline u32 CalcMoveBasePower(u32 move, u32 battlerAtk, u32 battlerDef, u3
|
|||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
case EFFECT_PLEDGE:
|
||||
// todo
|
||||
if (gBattleStruct->pledgeMove)
|
||||
basePower = 150;
|
||||
break;
|
||||
case EFFECT_FLING:
|
||||
basePower = GetFlingPowerFromItemId(gBattleMons[battlerAtk].item);
|
||||
|
@ -9504,7 +9612,9 @@ static inline uq4_12_t GetParentalBondModifier(u32 battlerAtk)
|
|||
|
||||
static inline uq4_12_t GetSameTypeAttackBonusModifier(u32 battlerAtk, u32 moveType, u32 move, u32 abilityAtk)
|
||||
{
|
||||
if (!IS_BATTLER_OF_TYPE(battlerAtk, moveType) || move == MOVE_STRUGGLE || move == MOVE_NONE)
|
||||
if (gBattleStruct->pledgeMove && IS_BATTLER_OF_TYPE(BATTLE_PARTNER(battlerAtk), moveType))
|
||||
return (abilityAtk == ABILITY_ADAPTABILITY) ? UQ_4_12(2.0) : UQ_4_12(1.5);
|
||||
else if (!IS_BATTLER_OF_TYPE(battlerAtk, moveType) || move == MOVE_STRUGGLE || move == MOVE_NONE)
|
||||
return UQ_4_12(1.0);
|
||||
return (abilityAtk == ABILITY_ADAPTABILITY) ? UQ_4_12(2.0) : UQ_4_12(1.5);
|
||||
}
|
||||
|
@ -11122,9 +11232,17 @@ bool32 AreBattlersOfSameGender(u32 battler1, u32 battler2)
|
|||
return (gender1 != MON_GENDERLESS && gender2 != MON_GENDERLESS && gender1 == gender2);
|
||||
}
|
||||
|
||||
u32 CalcSecondaryEffectChance(u32 battler, u8 secondaryEffectChance)
|
||||
u32 CalcSecondaryEffectChance(u32 battler, u8 secondaryEffectChance, u16 moveEffect)
|
||||
{
|
||||
if (GetBattlerAbility(battler) == ABILITY_SERENE_GRACE)
|
||||
bool8 hasSereneGrace = (GetBattlerAbility(battler) == ABILITY_SERENE_GRACE);
|
||||
bool8 hasRainbow = (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_RAINBOW) != 0;
|
||||
|
||||
if (hasRainbow && hasSereneGrace && moveEffect == EFFECT_FLINCH_HIT)
|
||||
return secondaryEffectChance *= 2;
|
||||
|
||||
if (hasSereneGrace)
|
||||
secondaryEffectChance *= 2;
|
||||
if (hasRainbow && moveEffect != EFFECT_SECRET_POWER)
|
||||
secondaryEffectChance *= 2;
|
||||
|
||||
return secondaryEffectChance;
|
||||
|
@ -11166,4 +11284,3 @@ u8 GetBattlerType(u32 battler, u8 typeIndex)
|
|||
|
||||
return types[typeIndex];
|
||||
}
|
||||
|
||||
|
|
|
@ -1996,4 +1996,5 @@ const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
|
|||
[BG_STEEL_BEAM_OPPONENT] = {gBattleAnimBgImage_Highspeed, gBattleAnimBgPalette_SteelBeam, gBattleAnimBgTilemap_HighspeedOpponent},
|
||||
[BG_STEEL_BEAM_PLAYER] = {gBattleAnimBgImage_Highspeed, gBattleAnimBgPalette_SteelBeam, gBattleAnimBgTilemap_HighspeedPlayer},
|
||||
[BG_CHLOROBLAST] = {gBattleAnimBgImage_HydroCannon, gBattleAnimBgPalette_Chloroblast, gBattleAnimBgTilemap_HydroCannon},
|
||||
[BG_RAINBOW] = {gBattleAnimBgImage_Rainbow, gBattleAnimBGPalette_Rainbow, gBattleAnimBgTilemap_Rainbow},
|
||||
};
|
||||
|
|
|
@ -1606,6 +1606,11 @@ const u32 gBattleAnimSpritePal_Slash2[] = INCBIN_U32("graphics/battle_anims/spri
|
|||
const u32 gBattleAnimSpriteGfx_WhiteShadow[] = INCBIN_U32("graphics/battle_anims/sprites/white_shadow.4bpp.lz");
|
||||
const u32 gBattleAnimSpritePal_WhiteShadow[] = INCBIN_U32("graphics/battle_anims/sprites/white_shadow.gbapal.lz");
|
||||
|
||||
// Pledge Effect field status - Rainbow
|
||||
const u32 gBattleAnimBgImage_Rainbow[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow.4bpp.lz");
|
||||
const u32 gBattleAnimBGPalette_Rainbow[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow.gbapal.lz");
|
||||
const u32 gBattleAnimBgTilemap_Rainbow[] = INCBIN_U32("graphics/battle_anims/backgrounds/rainbow.bin.lz");
|
||||
|
||||
const u32 gPartyMenuBg_Gfx[] = INCBIN_U32("graphics/party_menu/bg.4bpp.lz");
|
||||
const u32 gPartyMenuBg_Pal[] = INCBIN_U32("graphics/party_menu/bg.gbapal.lz");
|
||||
const u32 gPartyMenuBg_Tilemap[] = INCBIN_U32("graphics/party_menu/bg.bin.lz");
|
||||
|
|
|
@ -53,7 +53,6 @@ AI_SINGLE_BATTLE_TEST("AI prefers Water Gun over Bubble if it knows that foe has
|
|||
|
||||
PARAMETRIZE { abilityAI = ABILITY_MOXIE; }
|
||||
PARAMETRIZE { abilityAI = ABILITY_MOLD_BREAKER; } // Mold Breaker ignores Contrary.
|
||||
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_SHUCKLE) { Ability(ABILITY_CONTRARY); }
|
||||
|
|
|
@ -31,11 +31,11 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+")
|
|||
MOVE(player, MOVE_ICE_FANG, WITH_RNG(RNG_DAMAGE_MODIFIER, i));
|
||||
}
|
||||
}
|
||||
SCENE{
|
||||
SCENE {
|
||||
MESSAGE("Glaceon used Ice Fang!");
|
||||
HP_BAR(opponent, captureDamage: &dmg);
|
||||
}
|
||||
THEN{
|
||||
THEN {
|
||||
EXPECT_EQ(expectedDamage, dmg);
|
||||
}
|
||||
}
|
||||
|
@ -68,11 +68,11 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+ (Muscle Band, crit)")
|
|||
MOVE(player, MOVE_ICE_FANG, WITH_RNG(RNG_DAMAGE_MODIFIER, i), criticalHit: TRUE);
|
||||
}
|
||||
}
|
||||
SCENE{
|
||||
SCENE {
|
||||
MESSAGE("Glaceon used Ice Fang!");
|
||||
HP_BAR(opponent, captureDamage: &dmg);
|
||||
}
|
||||
THEN{
|
||||
THEN {
|
||||
EXPECT_EQ(expectedDamage, dmg);
|
||||
}
|
||||
}
|
||||
|
|
352
test/battle/move_effect/pledge.c
Normal file
352
test/battle/move_effect/pledge.c
Normal file
|
@ -0,0 +1,352 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_WATER_PLEDGE].effect == EFFECT_PLEDGE);
|
||||
ASSUME(gBattleMoves[MOVE_FIRE_PLEDGE].effect == EFFECT_PLEDGE);
|
||||
ASSUME(gBattleMoves[MOVE_GRASS_PLEDGE].effect == EFFECT_PLEDGE);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Water and Fire Pledge create a rainbow on the user's side of the field for four turns")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_WATER_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_FIRE_PLEDGE, target: opponentRight);
|
||||
}
|
||||
TURN {}
|
||||
TURN {}
|
||||
TURN {}
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Water Pledge!");
|
||||
MESSAGE("Wobbuffet is waiting for Wynaut's move…{PAUSE 16}");
|
||||
MESSAGE("Wynaut used Fire Pledge!");
|
||||
MESSAGE("The two moves become one! It's a combined move!{PAUSE 16}");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PLEDGE, playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
MESSAGE("A rainbow appeared in the sky on your team's side!");
|
||||
MESSAGE("The rainbow on your side disappeared!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Rainbow doubles the chance of secondary move effects")
|
||||
{
|
||||
PASSES_RANDOMLY(20, 100, RNG_SECONDARY_EFFECT);
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_EMBER].effect == EFFECT_BURN_HIT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_WATER_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_FIRE_PLEDGE, target: opponentRight);
|
||||
}
|
||||
TURN { MOVE(playerLeft, MOVE_EMBER, target: opponentRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PLEDGE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, playerLeft);
|
||||
MESSAGE("Foe Wynaut was burned!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Rainbow flinch chance does not stack with Serene Grace")
|
||||
{
|
||||
PASSES_RANDOMLY(60, 100, RNG_SECONDARY_EFFECT);
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_BITE].effect == EFFECT_FLINCH_HIT);
|
||||
PLAYER(SPECIES_TOGEPI) { Speed(8); Ability(ABILITY_SERENE_GRACE); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(5); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(3); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_WATER_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_FIRE_PLEDGE, target: opponentRight);
|
||||
}
|
||||
TURN { MOVE(playerLeft, MOVE_BITE, target: opponentRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PLEDGE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BITE, playerLeft);
|
||||
MESSAGE("Foe Wynaut flinched!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Rainbow flinch chance does not stack with Serene Grace if mvoe Triple Arrows is used")
|
||||
{
|
||||
PASSES_RANDOMLY(60, 100, RNG_TRIPLE_ARROWS_FLINCH);
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_TRIPLE_ARROWS].effect == EFFECT_TRIPLE_ARROWS);
|
||||
PLAYER(SPECIES_TOGEPI) { Speed(8); Ability(ABILITY_SERENE_GRACE); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(5); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(3); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_WATER_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_FIRE_PLEDGE, target: opponentRight);
|
||||
}
|
||||
TURN { MOVE(playerLeft, MOVE_TRIPLE_ARROWS, target: opponentRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PLEDGE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, playerLeft);
|
||||
MESSAGE("Foe Wynaut flinched!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Fire and Grass Pledge summons Sea Of Fire for four turns that damages the opponent")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_FIRE_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_GRASS_PLEDGE, target: opponentRight);
|
||||
}
|
||||
TURN {}
|
||||
TURN {}
|
||||
TURN {}
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Fire Pledge!");
|
||||
MESSAGE("Wobbuffet is waiting for Wynaut's move…{PAUSE 16}");
|
||||
MESSAGE("Wynaut used Grass Pledge!");
|
||||
MESSAGE("The two moves become one! It's a combined move!{PAUSE 16}");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FIRE_PLEDGE, playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
MESSAGE("A sea of fire enveloped the opposing team!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SEA_OF_FIRE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentLeft);
|
||||
MESSAGE("The opposing Foe Wobbuffet was hurt by the sea of fire!");
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentRight);
|
||||
MESSAGE("The opposing Foe Wynaut was hurt by the sea of fire!");
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentLeft);
|
||||
MESSAGE("The opposing Foe Wobbuffet was hurt by the sea of fire!");
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentRight);
|
||||
MESSAGE("The opposing Foe Wynaut was hurt by the sea of fire!");
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentLeft);
|
||||
MESSAGE("The opposing Foe Wobbuffet was hurt by the sea of fire!");
|
||||
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentRight);
|
||||
MESSAGE("The opposing Foe Wynaut was hurt by the sea of fire!");
|
||||
MESSAGE("The sea of fire around the opposing team disappeared!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Sea Of Fire deals 1/8th damage per turn")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_FIRE_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_GRASS_PLEDGE, target: opponentRight);
|
||||
}
|
||||
} SCENE {
|
||||
s32 maxHPopponentLeft = GetMonData(&OPPONENT_PARTY[0], MON_DATA_MAX_HP);
|
||||
s32 maxHPopponentRight = GetMonData(&OPPONENT_PARTY[1], MON_DATA_MAX_HP);
|
||||
HP_BAR(opponentLeft, damage: maxHPopponentLeft / 8);
|
||||
HP_BAR(opponentRight, damage: maxHPopponentRight / 8);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Grass and Water Pledge create a swamp on the user's side of the field for four turns")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_GRASS_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_WATER_PLEDGE, target: opponentRight);
|
||||
}
|
||||
TURN {}
|
||||
TURN {}
|
||||
TURN {}
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet used Grass Pledge!");
|
||||
MESSAGE("Wobbuffet is waiting for Wynaut's move…{PAUSE 16}");
|
||||
MESSAGE("Wynaut used Water Pledge!");
|
||||
MESSAGE("The two moves become one! It's a combined move!{PAUSE 16}");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GRASS_PLEDGE, playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
MESSAGE("A swamp enveloped the opposing team!");
|
||||
MESSAGE("The swamp around the opposing team disappeared!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Swamp reduces the speed of the effected side by 1/4th")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(5); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(4); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(12); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(8); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_GRASS_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_WATER_PLEDGE, target: opponentRight);
|
||||
}
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GRASS_PLEDGE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("The base power of a combined pledge move effect is 150")
|
||||
{
|
||||
s16 hyperBeamDamage;
|
||||
s16 combinedPledgeDamage;
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_HYPER_BEAM].power == 150);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentRight, MOVE_HYPER_BEAM, target: playerRight);
|
||||
MOVE(playerLeft, MOVE_WATER_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_FIRE_PLEDGE, target: opponentRight);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_BEAM, opponentRight);
|
||||
HP_BAR(playerRight, captureDamage: &hyperBeamDamage);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PLEDGE, playerRight);
|
||||
HP_BAR(opponentRight, captureDamage: &combinedPledgeDamage);
|
||||
} THEN {
|
||||
EXPECT_EQ(hyperBeamDamage, combinedPledgeDamage);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Pledge moves can not be redirected by absorbing abilities")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_LILEEP) { Ability(ABILITY_STORM_DRAIN); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_WATER_PLEDGE, target: opponentRight);}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PLEDGE, playerLeft);
|
||||
HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Pledge status timer does not reset if combined move is used again")
|
||||
{
|
||||
u16 pledgeMove1, pledgeMove2;
|
||||
|
||||
PARAMETRIZE { pledgeMove1 = MOVE_WATER_PLEDGE; pledgeMove2 = MOVE_FIRE_PLEDGE; }
|
||||
PARAMETRIZE { pledgeMove1 = MOVE_FIRE_PLEDGE; pledgeMove2 = MOVE_GRASS_PLEDGE; }
|
||||
PARAMETRIZE { pledgeMove1 = MOVE_GRASS_PLEDGE; pledgeMove2 = MOVE_WATER_PLEDGE; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, pledgeMove1, target: opponentLeft);
|
||||
MOVE(playerRight, pledgeMove2, target: opponentRight);
|
||||
}
|
||||
TURN { MOVE(playerLeft, pledgeMove1, target: opponentLeft);
|
||||
MOVE(playerRight, pledgeMove2, target: opponentRight);
|
||||
}
|
||||
TURN {}
|
||||
TURN {}
|
||||
TURN {}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, pledgeMove1, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, pledgeMove1, playerRight);
|
||||
if (pledgeMove1 == MOVE_WATER_PLEDGE && pledgeMove2 == MOVE_FIRE_PLEDGE)
|
||||
{
|
||||
NOT MESSAGE("A rainbow appeared in the sky on your team's side!");
|
||||
MESSAGE("The rainbow on your side disappeared!");
|
||||
}
|
||||
if (pledgeMove1 == MOVE_FIRE_PLEDGE && pledgeMove2 == MOVE_GRASS_PLEDGE)
|
||||
{
|
||||
NOT MESSAGE("A sea of fire enveloped the opposing team!");
|
||||
MESSAGE("The sea of fire around the opposing team disappeared!");
|
||||
}
|
||||
if (pledgeMove1 == MOVE_GRASS_PLEDGE && pledgeMove2 == MOVE_WATER_PLEDGE)
|
||||
{
|
||||
NOT MESSAGE("A swamp enveloped the opposing team!");
|
||||
MESSAGE("The swamp around the opposing team disappeared!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Pledge moves get same attack type bonus from partner", s16 damage)
|
||||
{
|
||||
u32 species;
|
||||
|
||||
PARAMETRIZE { species = SPECIES_WOBBUFFET; }
|
||||
PARAMETRIZE { species = SPECIES_CHARMANDER; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(species) { Speed(4); }
|
||||
PLAYER(SPECIES_WYNAUT) { Speed(3); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
|
||||
OPPONENT(SPECIES_WYNAUT) { Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_FIRE_PLEDGE, target: opponentLeft);
|
||||
MOVE(playerRight, MOVE_GRASS_PLEDGE, target: opponentRight);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FIRE_PLEDGE, playerRight);
|
||||
HP_BAR(opponentRight, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Damage calculation: Combined pledge move")
|
||||
{
|
||||
s16 dmg;
|
||||
s16 expectedDamage;
|
||||
PARAMETRIZE { expectedDamage = 159; }
|
||||
PARAMETRIZE { expectedDamage = 156; }
|
||||
PARAMETRIZE { expectedDamage = 154; }
|
||||
PARAMETRIZE { expectedDamage = 153; }
|
||||
PARAMETRIZE { expectedDamage = 151; }
|
||||
PARAMETRIZE { expectedDamage = 150; }
|
||||
PARAMETRIZE { expectedDamage = 148; }
|
||||
PARAMETRIZE { expectedDamage = 147; }
|
||||
PARAMETRIZE { expectedDamage = 145; }
|
||||
PARAMETRIZE { expectedDamage = 144; }
|
||||
PARAMETRIZE { expectedDamage = 142; }
|
||||
PARAMETRIZE { expectedDamage = 141; }
|
||||
PARAMETRIZE { expectedDamage = 139; }
|
||||
PARAMETRIZE { expectedDamage = 138; }
|
||||
PARAMETRIZE { expectedDamage = 136; }
|
||||
PARAMETRIZE { expectedDamage = 135; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(521); SpDefense(152); Speed(3); }
|
||||
OPPONENT(SPECIES_CHARIZARD) { Speed(8); }
|
||||
OPPONENT(SPECIES_EEVEE) { SpAttack(126); Speed(5); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_FIRE_PLEDGE, target: playerLeft, WITH_RNG(RNG_DAMAGE_MODIFIER, i));
|
||||
MOVE(opponentRight, MOVE_GRASS_PLEDGE, target: playerRight, WITH_RNG(RNG_DAMAGE_MODIFIER, i));
|
||||
}
|
||||
}
|
||||
SCENE {
|
||||
HP_BAR(playerRight, captureDamage: &dmg);
|
||||
}
|
||||
THEN {
|
||||
EXPECT_EQ(expectedDamage, dmg);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue