merge w be

This commit is contained in:
ghoulslash 2021-11-15 10:45:59 -05:00
commit 2a1299715f
35 changed files with 472 additions and 246 deletions

View File

@ -1877,6 +1877,10 @@
.2byte \species .2byte \species
.4byte \ptr .4byte \ptr
.endm .endm
.macro tryendneutralizinggas battler:req
various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS
.endm
.macro trytoapplymimicry battler:req, ptr:req .macro trytoapplymimicry battler:req, ptr:req
various \battler, VARIOUS_TRY_TO_APPLY_MIMICRY various \battler, VARIOUS_TRY_TO_APPLY_MIMICRY

View File

@ -2506,20 +2506,30 @@ Move_GIGA_IMPACT:
loadspritegfx ANIM_TAG_IMPACT loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER monbg ANIM_DEF_PARTNER
setalpha 12, 8 setalpha 12, 8
createvisualtask AnimTask_IsContest, 2
jumprettrue SetGigaImpactContestsBG
createvisualtask AnimTask_IsTargetPlayerSide, 2
jumpretfalse SetGigaImpactOpponentBG
goto SetGigaImpactPlayerBG
SetGigaImpactOpponentBG:
fadetobg BG_GIGA_IMPACT_OPPONENT
goto GigaImpactContinuity
SetGigaImpactPlayerBG:
fadetobg BG_GIGA_IMPACT_PLAYER
goto GigaImpactContinuity
SetGigaImpactContestsBG:
fadetobg BG_GIGA_IMPACT_CONTEST
goto GigaImpactContinuity
GigaImpactContinuity:
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 6, 1, ANIM_ATTACKER
waitforvisualfinish waitforvisualfinish
delay 11 delay 11
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5 createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5
delay 6 delay 6
@monbg ANIM_DEF_PARTNER waitbgfadeout
@setalpha 12, 8
@createvisualtask AnimTask_WindUpLunge, 5, 7, 0, -18, 8, 23, 10, 40, 10
@delay 35
createsprite gComplexPaletteBlendSpriteTemplate, 2, 7, 31, 3, 1, 0, 10, 0, 0
createsprite gBasicHitSplatSpriteTemplate, 4, 4, -10, 0, 1, 0 createsprite gBasicHitSplatSpriteTemplate, 4, 4, -10, 0, 1, 0
playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET
call SetImpactBackground
delay 1 delay 1
createsprite gSlideMonToOffsetSpriteTemplate 2, 5, 1, -16, 0, 0, 4 createsprite gSlideMonToOffsetSpriteTemplate 2, 5, 1, -16, 0, 0, 4
waitforvisualfinish waitforvisualfinish
@ -2534,6 +2544,7 @@ Move_GIGA_IMPACT:
blendoff blendoff
restorebg restorebg
waitbgfadein waitbgfadein
waitforvisualfinish
end end
Move_NASTY_PLOT: Move_NASTY_PLOT:
@ -7279,7 +7290,7 @@ Move_RELIC_SONG:
monbg ANIM_DEF_PARTNER monbg ANIM_DEF_PARTNER
launchtask AnimTask_MusicNotesRainbowBlend 0x2 0x0 launchtask AnimTask_MusicNotesRainbowBlend 0x2 0x0
waitforvisualfinish waitforvisualfinish
panse_1B 0x1DF, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 0x2, 0x0 @ ??? createvisualtask SoundTask_PlayCryWithEcho, 2, ANIM_ATTACKER, 2
launchtask AnimTask_UproarDistortion 0x2 0x1 0x0 launchtask AnimTask_UproarDistortion 0x2 0x1 0x0
launchtemplate gUproarRingSpriteTemplate 0x3 0x6 0x0 0x0 0x0 0x0 0x1f 0x8 launchtemplate gUproarRingSpriteTemplate 0x3 0x6 0x0 0x0 0x0 0x0 0x1f 0x8
launchtemplate gJaggedMusicNoteSpriteTemplate 0x2 0x4 0x0 0x1d 0xfff4 0x0 launchtemplate gJaggedMusicNoteSpriteTemplate 0x2 0x4 0x0 0x1d 0xfff4 0x0

View File

@ -2187,6 +2187,7 @@ BattleScript_EffectSimpleBeam:
trytoclearprimalweather trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3 printstring STRINGID_EMPTYSTRING3
waitmessage 1 waitmessage 1
tryendneutralizinggas BS_TARGET
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_EffectSuckerPunch: BattleScript_EffectSuckerPunch:
@ -2409,6 +2410,7 @@ BattleScript_EffectGastroAcid:
trytoclearprimalweather trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3 printstring STRINGID_EMPTYSTRING3
waitmessage 1 waitmessage 1
tryendneutralizinggas BS_TARGET
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_EffectToxicSpikes: BattleScript_EffectToxicSpikes:
@ -8378,6 +8380,12 @@ BattleScript_SwitchInAbilityMsg::
waitmessage B_WAIT_TIME_LONG waitmessage B_WAIT_TIME_LONG
end3 end3
BattleScript_SwitchInAbilityMsgRet::
call BattleScript_AbilityPopUp
printfromtable gSwitchInAbilityStringIds
waitmessage B_WAIT_TIME_LONG
return
BattleScript_ActivateAsOne:: BattleScript_ActivateAsOne::
call BattleScript_AbilityPopUp call BattleScript_AbilityPopUp
printfromtable gSwitchInAbilityStringIds printfromtable gSwitchInAbilityStringIds
@ -9231,3 +9239,19 @@ BattleScript_PastelVeilLoopIncrement:
goto BattleScript_PastelVeilEnd goto BattleScript_PastelVeilEnd
BattleScript_PastelVeilEnd: BattleScript_PastelVeilEnd:
end3 end3
sByteFour:
.byte MAX_BATTLERS_COUNT
BattleScript_NeutralizingGasExits::
savetarget
pause B_WAIT_TIME_SHORT
printstring STRINGID_NEUTRALIZINGGASOVER
waitmessage B_WAIT_TIME_LONG
setbyte gBattlerTarget, 0
BattleScript_NeutralizingGasExitsLoop:
switchinabilities BS_TARGET
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, sByteFour, BattleScript_NeutralizingGasExitsLoop @ SOMEHOW, comparing to gBattlersCount is problematic.
restoretarget
return

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
0 0 0
255 214 0
255 197 0
255 173 0
255 165 0
148 90 222
255 107 0
255 132 0
255 148 0
255 156 41
0 0 0
0 90 0
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
240 136 184
232 104 168
136 8 40
248 24 104
216 32 96
224 72 136
160 0 48
216 0 64
200 40 88
192 0 56
176 32 128
176 24 72
152 16 56
200 48 80
216 56 160

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -0,0 +1,3 @@
<EFBFBD>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> D!E!F!G!H!I!@!<21>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> њ ћ ќ § ў џ ђ Ј$Ї$І$Ѕ$Є$Ѓ$Ђ$Ё$ $  Ё Ђ Ѓ Є Ѕ І Ї Ј Љ Њ Ћ Ќ ­ Ў Џ
! ! ! !!!!И$З$Ж$Е$Д$Г$В$Б$А$А Б В Г Д Е Ж З И Й К Л М Н О П !!!!!!!Ш$Ч$Ц$Х$Ф$У$Т$С$Р$Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я *!+!,!-!.!/!"!и$з$ж$е$д$г$в$б$а$а б в г д е ж з и й к л м н о п :!;!<!=!>!?!2!ш$ч$ц$х$ф$у$т$с$р$р с т у ф х ц ч ш щ ъ ы ь э ю я J!K!L!M!N!O!B!ш,ч,ц,х,ф,у,т,с,р,р(с(т(у(ф(х(ц(ч(ш(щ(ъ(ы(ь(э(ю(я(J)K)L)M)N)O)B)и,з,ж,е,д,г,в,б,а,а(б(в(г(д(е(ж(з(и(й(к(л(м(н(о(п(:);)<)=)>)?)2)Ш,Ч,Ц,Х,Ф,У,Т,С,Р,Р(С(Т(У(Ф(Х(Ц(Ч(Ш(Щ(Ъ(Ы(Ь(Э(Ю(Я(*)+),)-).)/)")И,З,Ж,Е,Д,Г,В,Б,А,А(Б(В(Г(Д(Е(Ж(З(И(Й(К(Л(М(Н(О(П()))))))Ј,Ї,І,Ѕ,Є,Ѓ,Ђ,Ё, , (Ё(Ђ(Ѓ(Є(Ѕ(І(Ї(Ј(Љ(Њ(Ћ(Ќ(­(Ў(Џ(
) ) ) ))))<29>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(њ(ћ(ќ(§(ў(џ(ђ(<28>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(D)E)F)G)H)I)@)

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
41 49 49
106 139 189
246 131 180
255 0 255
255 16 98
238 98 164
230 65 131
222 0 57
222 24 90
205 41 74
205 32 82
189 0 49
172 16 65
156 0 41
148 16 49
131 8 32

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,19 +0,0 @@
JASC-PAL
0100
16
0 0 0
255 255 255
255 0 255
255 16 98
246 131 180
238 98 164
230 65 131
222 0 57
222 24 90
205 32 82
205 41 74
189 0 49
172 16 65
156 0 41
148 16 49
131 8 32

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,3 +0,0 @@
@%I%H%G%F%E%D%<25>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24> <20> <20> <20> <20> <20> <20> <20> <20> ђ$џ$ў$§$ќ$ћ$њ$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24>$<24> <20> <20> <20> <20> <20> <20> <20> <20> %%% % % %
%Џ$Ў$­$Ќ$Ћ$Њ$Љ$Ј$Ї$І$Ѕ$Є$Ѓ$Ђ$Ё$ $  Ё Ђ Ѓ Є Ѕ І Ї Ј %%%%%%%П$О$Н$М$Л$К$Й$И$З$Ж$Е$Д$Г$В$Б$А$А Б В Г Д Е Ж З И "%/%.%-%,%+%*%Я$Ю$Э$Ь$Ы$Ъ$Щ$Ш$Ч$Ц$Х$Ф$У$Т$С$Р$Р С Т У Ф Х Ц Ч Ш 2%?%>%=%<%;%:%п$о$н$м$л$к$й$и$з$ж$е$д$г$в$б$а$а б в г д е ж з и B%O%N%M%L%K%J%я$ю$э$ь$ы$ъ$щ$ш$ч$ц$х$ф$у$т$с$р$р с т у ф х ц ч ш B-O-N-M-L-K-J-я,ю,э,ь,ы,ъ,щ,ш,ч,ц,х,ф,у,т,с,р,р(с(т(у(ф(х(ц(ч(ш(2-?->-=-<-;-:-п,о,н,м,л,к,й,и,з,ж,е,д,г,в,б,а,а(б(в(г(д(е(ж(з(и("-/-.---,-+-*-Я,Ю,Э,Ь,Ы,Ъ,Щ,Ш,Ч,Ц,Х,Ф,У,Т,С,Р,Р(С(Т(У(Ф(Х(Ц(Ч(Ш(-------П,О,Н,М,Л,К,Й,И,З,Ж,Е,Д,Г,В,Б,А,А(Б(В(Г(Д(Е(Ж(З(И(--- - - -
-Џ,Ў,­,Ќ,Ћ,Њ,Љ,Ј,Ї,І,Ѕ,Є,Ѓ,Ђ,Ё, , (Ё(Ђ(Ѓ(Є(Ѕ(І(Ї(Ј(ђ,џ,ў,§,ќ,ћ,њ,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(@-I-H-G-F-E-D-<2D>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>,<2C>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(

View File

@ -62,12 +62,13 @@ struct ResourceFlags
u32 flags[4]; u32 flags[4];
}; };
#define RESOURCE_FLAG_FLASH_FIRE 0x1 #define RESOURCE_FLAG_FLASH_FIRE 0x1
#define RESOURCE_FLAG_ROOST 0x2 #define RESOURCE_FLAG_ROOST 0x2
#define RESOURCE_FLAG_UNBURDEN 0x4 #define RESOURCE_FLAG_UNBURDEN 0x4
#define RESOURCE_FLAG_INTIMIDATED 0x8 #define RESOURCE_FLAG_INTIMIDATED 0x8
#define RESOURCE_FLAG_TRACED 0x10 #define RESOURCE_FLAG_TRACED 0x10
#define RESOURCE_FLAG_EMERGENCY_EXIT 0x20 #define RESOURCE_FLAG_EMERGENCY_EXIT 0x20
#define RESOURCE_FLAG_NEUTRALIZING_GAS 0x40
struct DisableStruct struct DisableStruct
{ {
@ -184,6 +185,8 @@ struct SpecialStatus
u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute. u8 damagedMons:4; // Mons that have been damaged directly by using a move, includes substitute.
u8 dancerUsedMove:1; u8 dancerUsedMove:1;
u8 dancerOriginalTarget:3; u8 dancerOriginalTarget:3;
u8 announceNeutralizingGas:1; // See Cmd_switchineffects
u8 neutralizingGasRemoved:1; // See VARIOUS_TRY_END_NEUTRALIZING_GAS
s32 dmg; s32 dmg;
s32 physicalDmg; s32 physicalDmg;
s32 specialDmg; s32 specialDmg;

View File

@ -261,6 +261,7 @@ extern const u8 BattleScript_AttackerAbilityStatRaiseEnd3[];
extern const u8 BattleScript_PoisonHealActivates[]; extern const u8 BattleScript_PoisonHealActivates[];
extern const u8 BattleScript_BadDreamsActivates[]; extern const u8 BattleScript_BadDreamsActivates[];
extern const u8 BattleScript_SwitchInAbilityMsg[]; extern const u8 BattleScript_SwitchInAbilityMsg[];
extern const u8 BattleScript_SwitchInAbilityMsgRet[];
extern const u8 BattleScript_ToxicSpikesPoisoned[]; extern const u8 BattleScript_ToxicSpikesPoisoned[];
extern const u8 BattleScript_ToxicSpikesAbsorbed[]; extern const u8 BattleScript_ToxicSpikesAbsorbed[];
extern const u8 BattleScript_StickyWebOnSwitchIn[]; extern const u8 BattleScript_StickyWebOnSwitchIn[];
@ -413,5 +414,6 @@ extern const u8 BattleScript_AttackerFormChangeEnd3NoPopup[];
extern const u8 BattleScript_AttackerFormChangeMoveEffect[]; extern const u8 BattleScript_AttackerFormChangeMoveEffect[];
extern const u8 BattleScript_BothCanNoLongerEscape[]; extern const u8 BattleScript_BothCanNoLongerEscape[];
extern const u8 BattleScript_OctolockEndTurn[]; extern const u8 BattleScript_OctolockEndTurn[];
extern const u8 BattleScript_NeutralizingGasExits[];
#endif // GUARD_BATTLE_SCRIPTS_H #endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -8,21 +8,23 @@
#define MOVE_LIMITATION_TAUNT (1 << 4) #define MOVE_LIMITATION_TAUNT (1 << 4)
#define MOVE_LIMITATION_IMPRISON (1 << 5) #define MOVE_LIMITATION_IMPRISON (1 << 5)
#define ABILITYEFFECT_ON_SWITCHIN 0x0 #define ABILITYEFFECT_ON_SWITCHIN 0
#define ABILITYEFFECT_ENDTURN 0x1 #define ABILITYEFFECT_ENDTURN 1
#define ABILITYEFFECT_MOVES_BLOCK 0x2 #define ABILITYEFFECT_MOVES_BLOCK 2
#define ABILITYEFFECT_ABSORBING 0x3 #define ABILITYEFFECT_ABSORBING 3
#define ABILITYEFFECT_MOVE_END_ATTACKER 0x4 #define ABILITYEFFECT_MOVE_END_ATTACKER 4
#define ABILITYEFFECT_MOVE_END 0x5 #define ABILITYEFFECT_MOVE_END 5
#define ABILITYEFFECT_IMMUNITY 0x6 #define ABILITYEFFECT_IMMUNITY 6
#define ABILITYEFFECT_FORECAST 0x7 #define ABILITYEFFECT_FORECAST 7
#define ABILITYEFFECT_SYNCHRONIZE 0x8 #define ABILITYEFFECT_SYNCHRONIZE 8
#define ABILITYEFFECT_ATK_SYNCHRONIZE 0x9 #define ABILITYEFFECT_ATK_SYNCHRONIZE 9
#define ABILITYEFFECT_INTIMIDATE1 0xA #define ABILITYEFFECT_INTIMIDATE1 10
#define ABILITYEFFECT_INTIMIDATE2 0xB #define ABILITYEFFECT_INTIMIDATE2 11
#define ABILITYEFFECT_TRACE1 0xC #define ABILITYEFFECT_TRACE1 12
#define ABILITYEFFECT_TRACE2 0xD #define ABILITYEFFECT_TRACE2 13
#define ABILITYEFFECT_MOVE_END_OTHER 0xE #define ABILITYEFFECT_MOVE_END_OTHER 14
#define ABILITYEFFECT_NEUTRALIZINGGAS 15
// Special cases
#define ABILITYEFFECT_SWITCH_IN_TERRAIN 0xFE #define ABILITYEFFECT_SWITCH_IN_TERRAIN 0xFE
#define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF #define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF
@ -102,6 +104,7 @@ u32 IsAbilityOnOpposingSide(u32 battlerId, u32 ability);
u32 IsAbilityOnField(u32 ability); u32 IsAbilityOnField(u32 ability);
u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability); u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability);
u32 IsAbilityPreventingEscape(u32 battlerId); u32 IsAbilityPreventingEscape(u32 battlerId);
bool32 IsBattlerProtected(u8 battlerId, u16 move);
bool32 CanBattlerEscape(u32 battlerId); // no ability check bool32 CanBattlerEscape(u32 battlerId); // no ability check
void BattleScriptExecute(const u8* BS_ptr); void BattleScriptExecute(const u8* BS_ptr);
void BattleScriptPushCursorAndCallback(const u8* BS_ptr); void BattleScriptPushCursorAndCallback(const u8* BS_ptr);

View File

@ -114,6 +114,7 @@
#define B_PAYBACK_SWITCH_BOOST GEN_7 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled. #define B_PAYBACK_SWITCH_BOOST GEN_7 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled.
#define B_HIDDEN_POWER_DMG GEN_7 // In Gen6+, Hidden Power's base power was set to always be 60. Before, it was determined by the mon's IVs. #define B_HIDDEN_POWER_DMG GEN_7 // In Gen6+, Hidden Power's base power was set to always be 60. Before, it was determined by the mon's IVs.
#define B_ROUGH_SKIN_DMG GEN_7 // In Gen4+, Rough Skin contact damage is 1/8th of max HP instead of 1/16th. This will also affect Iron Barbs. #define B_ROUGH_SKIN_DMG GEN_7 // In Gen4+, Rough Skin contact damage is 1/8th of max HP instead of 1/16th. This will also affect Iron Barbs.
#define B_KNOCK_OFF_DMG GEN_8 // In Gen6+, Knock Off deals 50% more damage when knocking off an item
// Type settings // Type settings
#define B_GHOSTS_ESCAPE GEN_7 // In Gen6+, abilities like Shadow Tag or moves like Mean Look fail on Ghost-type Pokémon. They can also escape any Wild Battle. #define B_GHOSTS_ESCAPE GEN_7 // In Gen6+, abilities like Shadow Tag or moves like Mean Look fail on Ghost-type Pokémon. They can also escape any Wild Battle.
@ -152,6 +153,8 @@
#define B_MEMENTO_FAIL GEN_7 // In Gen4+, Memento fails if there is no target or if the target is protected or behind substitute. But not if Atk/Sp. Atk are at -6. #define B_MEMENTO_FAIL GEN_7 // In Gen4+, Memento fails if there is no target or if the target is protected or behind substitute. But not if Atk/Sp. Atk are at -6.
#define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally. #define B_GLARE_GHOST GEN_7 // In Gen4+, Glare can hit Ghost-type Pokémon normally.
#define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use. #define B_SKILL_SWAP GEN_7 // In Gen4+, Skill Swap triggers switch-in abilities after use.
#define B_BRICK_BREAK GEN_7 // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune.
#define B_WISH_HP_SOURCE GEN_7 // In Gen5+, Wish heals half of the user's max HP instead of the target's.
// Ability settings // Ability settings
#define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability. #define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability.
@ -181,6 +184,7 @@
#define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3. #define B_LURE_BALL_MODIFIER GEN_7 // In Gen7+, Lure Ball's catch multiplier is x5 instead of x3.
#define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow. #define B_HEAVY_BALL_MODIFIER GEN_7 // In Gen7+, Heavy Ball's ranges change. See Cmd_handleballthrow.
#define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose. #define B_DREAM_BALL_MODIFIER GEN_8 // In Gen8, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose.
#define B_SERENE_GRACE_BOOST GEN_7 // In Gen5+, Serene Grace boosts the added flinch chance of King's Rock and Razor Fang.
// Flag settings // Flag settings
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.

View File

@ -207,6 +207,7 @@
#define VARIOUS_CHECK_POLTERGEIST 134 #define VARIOUS_CHECK_POLTERGEIST 134
#define VARIOUS_SET_OCTOLOCK 135 #define VARIOUS_SET_OCTOLOCK 135
#define VARIOUS_CUT_1_3_HP_RAISE_STATS 136 #define VARIOUS_CUT_1_3_HP_RAISE_STATS 136
#define VARIOUS_TRY_END_NEUTRALIZING_GAS 137
// Cmd_manipulatedamage // Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0 #define DMG_CHANGE_SIGN 0
@ -225,6 +226,7 @@
// Cmd_statbuffchange // Cmd_statbuffchange
#define STAT_BUFF_ALLOW_PTR (1 << 0) // If set, allow use of jumpptr. Set in every use of statbuffchange #define STAT_BUFF_ALLOW_PTR (1 << 0) // If set, allow use of jumpptr. Set in every use of statbuffchange
#define STAT_BUFF_NOT_PROTECT_AFFECTED (1 << 5) #define STAT_BUFF_NOT_PROTECT_AFFECTED (1 << 5)
#define STAT_BUFF_UPDATE_MOVE_EFFECT (1 << 6)
// stat change flags for Cmd_playstatchangeanimation // stat change flags for Cmd_playstatchangeanimation
#define STAT_CHANGE_NEGATIVE (1 << 0) #define STAT_CHANGE_NEGATIVE (1 << 0)

View File

@ -607,8 +607,10 @@
#define STRINGID_PKMNBECAMEWEAKERTOFIRE 604 #define STRINGID_PKMNBECAMEWEAKERTOFIRE 604
#define STRINGID_ABOUTTOUSEPOLTERGEIST 605 #define STRINGID_ABOUTTOUSEPOLTERGEIST 605
#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 606 #define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 606
#define STRINGID_NEUTRALIZINGGASENTERS 607
#define STRINGID_NEUTRALIZINGGASOVER 608
#define BATTLESTRINGS_COUNT 607 #define BATTLESTRINGS_COUNT 609
// The below IDs are all indexes into battle message tables, // The below IDs are all indexes into battle message tables,
// used to determine which of a set of messages to print. // used to determine which of a set of messages to print.
@ -844,6 +846,7 @@
#define B_MSG_SWITCHIN_ASONE 13 #define B_MSG_SWITCHIN_ASONE 13
#define B_MSG_SWITCHIN_CURIOUS_MEDICINE 14 #define B_MSG_SWITCHIN_CURIOUS_MEDICINE 14
#define B_MSG_SWITCHIN_PASTEL_VEIL 15 #define B_MSG_SWITCHIN_PASTEL_VEIL 15
#define B_MSG_SWITCHIN_NEUTRALIZING_GAS 16
// gMentalHerbCureStringIds // gMentalHerbCureStringIds
#define B_MSG_MENTALHERBCURE_INFATUATION 0 #define B_MSG_MENTALHERBCURE_INFATUATION 0

View File

@ -62,12 +62,12 @@
#define HOLD_EFFECT_FIRE_POWER 58 #define HOLD_EFFECT_FIRE_POWER 58
#define HOLD_EFFECT_DRAGON_POWER 59 #define HOLD_EFFECT_DRAGON_POWER 59
#define HOLD_EFFECT_NORMAL_POWER 60 #define HOLD_EFFECT_NORMAL_POWER 60
#define HOLD_EFFECT_UP_GRADE 61 #define HOLD_EFFECT_UPGRADE 61
#define HOLD_EFFECT_SHELL_BELL 62 #define HOLD_EFFECT_SHELL_BELL 62
#define HOLD_EFFECT_LUCKY_PUNCH 63 #define HOLD_EFFECT_LUCKY_PUNCH 63
#define HOLD_EFFECT_METAL_POWDER 64 #define HOLD_EFFECT_METAL_POWDER 64
#define HOLD_EFFECT_THICK_CLUB 65 #define HOLD_EFFECT_THICK_CLUB 65
#define HOLD_EFFECT_STICK 66 #define HOLD_EFFECT_LEEK 66
// Gen4 hold effects. // Gen4 hold effects.
#define HOLD_EFFECT_CHOICE_SCARF 67 #define HOLD_EFFECT_CHOICE_SCARF 67

View File

@ -4937,10 +4937,13 @@ extern const u32 gBattleAnimBgImage_Hurricane[];
extern const u32 gBattleAnimBgPalette_Hurricane[]; extern const u32 gBattleAnimBgPalette_Hurricane[];
extern const u32 gBattleAnimBgTilemap_Hurricane[]; extern const u32 gBattleAnimBgTilemap_Hurricane[];
extern const u32 gBattleAnimBgPalette_RockWrecker[]; extern const u32 gBattleAnimBgPalette_RockWrecker[];
extern const u32 gBattleAnimBgTilemap_GigaImpactPlayer[];
extern const u32 gBattleAnimBgTilemap_GigaImpactOpponent[];
extern const u32 gBattleAnimBgTilemap_GigaImpactContest[];
extern const u32 gBattleAnimBgImage_GigaImpact[];
extern const u32 gBattleAnimBgPalette_GigaImpact[];
extern const u32 gBattleAnimBgImage_SpacialRend[]; extern const u32 gBattleAnimBgImage_SpacialRend[];
extern const u32 gBattleAnimBgPalette_SpacialRend[]; extern const u32 gBattleAnimBgPalette_SpacialRend[];
extern const u32 gBattleAnimBgTilemap_SpacialRendOpponent[];
extern const u32 gBattleAnimBgTilemap_SpacialRendPlayer[];
extern const u32 gBattleAnimBgPalette_DarkVoid[]; extern const u32 gBattleAnimBgPalette_DarkVoid[];
extern const u32 gBattleAnimBgTilemap_DarkVoid[]; extern const u32 gBattleAnimBgTilemap_DarkVoid[];
extern const u32 gBattleAnimBgPalette_Dark[]; extern const u32 gBattleAnimBgPalette_Dark[];
@ -4960,7 +4963,6 @@ extern const u32 gBattleAnimBgPalette_Fissure[];
extern const u32 gBattleAnimBgPalette_Bug[]; extern const u32 gBattleAnimBgPalette_Bug[];
extern const u32 gBattleAnimBgPalette_Solarbeam[]; extern const u32 gBattleAnimBgPalette_Solarbeam[];
extern const u32 gBattleAnimBgPalette_MagmaStorm[]; extern const u32 gBattleAnimBgPalette_MagmaStorm[];
extern const u32 gBattleAnimBgPalette_GigaImpact[];
extern const u32 gBattleAnimBgPalette_TrickRoom[]; extern const u32 gBattleAnimBgPalette_TrickRoom[];
extern const u32 gBattleAnimBgTilemap_Dark[]; extern const u32 gBattleAnimBgTilemap_Dark[];
extern const u32 gBattleAnimBgTilemap_Ghost[]; extern const u32 gBattleAnimBgTilemap_Ghost[];

View File

@ -2320,7 +2320,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|| IsInstructBannedMove(instructedMove) || IsInstructBannedMove(instructedMove)
|| MoveRequiresRecharging(instructedMove) || MoveRequiresRecharging(instructedMove)
|| MoveCallsOtherMove(instructedMove) || MoveCallsOtherMove(instructedMove)
#ifdef ITEM_Z_RING #ifdef ITEM_Z_POWER_RING
//|| (IsZMove(instructedMove)) //|| (IsZMove(instructedMove))
#endif #endif
|| (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF) || (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF)

View File

@ -82,7 +82,7 @@ static bool8 ShouldSwitchIfWonderGuard(void)
opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(gActiveBattler)); opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(gActiveBattler));
if (gBattleMons[GetBattlerAtPosition(opposingPosition)].ability != ABILITY_WONDER_GUARD) if (GetBattlerAbility(GetBattlerAtPosition(opposingPosition)) != ABILITY_WONDER_GUARD)
return FALSE; return FALSE;
// Check if Pokemon has a super effective move. // Check if Pokemon has a super effective move.
@ -176,7 +176,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
else else
return FALSE; return FALSE;
if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility) if (AI_GetAbility(gActiveBattler) == absorbingTypeAbility)
return FALSE; return FALSE;
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId); GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
@ -228,7 +228,7 @@ static bool8 ShouldSwitchIfNaturalCure(void)
{ {
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)) if (!(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP))
return FALSE; return FALSE;
if (gBattleMons[gActiveBattler].ability != ABILITY_NATURAL_CURE) if (AI_GetAbility(gActiveBattler) != ABILITY_NATURAL_CURE)
return FALSE; return FALSE;
if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 2) if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 2)
return FALSE; return FALSE;

View File

@ -1121,20 +1121,24 @@ bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability)
// does NOT include ability suppression checks // does NOT include ability suppression checks
s32 AI_GetAbility(u32 battlerId) s32 AI_GetAbility(u32 battlerId)
{ {
u32 knownAbility = GetBattlerAbility(battlerId);
// The AI knows its own ability. // The AI knows its own ability.
if (IsBattlerAIControlled(battlerId)) if (IsBattlerAIControlled(battlerId))
return gBattleMons[battlerId].ability; return knownAbility;
// Check neutralizing gas, gastro acid
if (knownAbility == ABILITY_NONE)
return knownAbility;
if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE) if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE)
return BATTLE_HISTORY->abilities[battlerId]; return BATTLE_HISTORY->abilities[battlerId];
// Abilities that prevent fleeing. // Abilities that prevent fleeing - treat as always known
if (gBattleMons[battlerId].ability == ABILITY_SHADOW_TAG if (knownAbility == ABILITY_SHADOW_TAG || knownAbility == ABILITY_MAGNET_PULL || knownAbility == ABILITY_ARENA_TRAP)
|| gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL return knownAbility;
|| gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP)
return gBattleMons[battlerId].ability; // Else, guess the ability
// AI has no knowledge of opponent, so it guesses which ability.
if (gBaseStats[gBattleMons[battlerId].species].abilities[0] != ABILITY_NONE) if (gBaseStats[gBattleMons[battlerId].species].abilities[0] != ABILITY_NONE)
{ {
u16 abilityGuess = ABILITY_NONE; u16 abilityGuess = ABILITY_NONE;
@ -1145,6 +1149,7 @@ s32 AI_GetAbility(u32 battlerId)
return abilityGuess; return abilityGuess;
} }
return ABILITY_NONE; // Unknown. return ABILITY_NONE; // Unknown.
} }

View File

@ -2052,13 +2052,13 @@ const struct BattleAnimBackground gBattleAnimBackgroundTable[] =
[BG_SOLARBEAM_CONTESTS] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_Solarbeam, gBattleAnimBgTilemap_ImpactContests}, [BG_SOLARBEAM_CONTESTS] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_Solarbeam, gBattleAnimBgTilemap_ImpactContests},
//new bgs //new bgs
[BG_MAGMA_STORM] = {gBattleAnimBgImage_InAir, gBattleAnimBgPalette_MagmaStorm, gBattleAnimBgTilemap_InAir}, [BG_MAGMA_STORM] = {gBattleAnimBgImage_InAir, gBattleAnimBgPalette_MagmaStorm, gBattleAnimBgTilemap_InAir},
[BG_GIGA_IMPACT_OPPONENT] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_ImpactOpponent}, [BG_GIGA_IMPACT_OPPONENT] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactOpponent},
[BG_GIGA_IMPACT_PLAYER] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_ImpactPlayer}, [BG_GIGA_IMPACT_PLAYER] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactPlayer},
[BG_GIGA_IMPACT_CONTEST] = {gBattleAnimBgImage_Impact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_ImpactContests}, [BG_GIGA_IMPACT_CONTEST] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactContest},
[BG_TRICK_ROOM] = {gBattleAnimBgImage_TrickRoom, gBattleAnimBgPalette_TrickRoom, gBattleAnimBgTilemap_TrickRoom}, [BG_TRICK_ROOM] = {gBattleAnimBgImage_TrickRoom, gBattleAnimBgPalette_TrickRoom, gBattleAnimBgTilemap_TrickRoom},
[BG_ROCK_WRECKER] = {gBattleAnimBgImage_Hurricane, gBattleAnimBgPalette_RockWrecker, gBattleAnimBgTilemap_Hurricane}, [BG_ROCK_WRECKER] = {gBattleAnimBgImage_Hurricane, gBattleAnimBgPalette_RockWrecker, gBattleAnimBgTilemap_Hurricane},
[BG_SPACIAL_REND_ON_OPPONENT] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_SpacialRendOpponent}, [BG_SPACIAL_REND_ON_OPPONENT] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_GigaImpactOpponent},
[BG_SPACIAL_REND_ON_PLAYER] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_SpacialRendPlayer}, [BG_SPACIAL_REND_ON_PLAYER] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_GigaImpactPlayer},
[BG_DARK_VOID] = {gBattleAnimBgImage_Waterfall, gBattleAnimBgPalette_DarkVoid, gBattleAnimBgTilemap_DarkVoid}, [BG_DARK_VOID] = {gBattleAnimBgImage_Waterfall, gBattleAnimBgPalette_DarkVoid, gBattleAnimBgTilemap_DarkVoid},
[BG_WATER] = {gBattleAnimBgImage_HydroPump, gBattleAnimBgPalette_HydroPump, gBattleAnimBgTilemap_HydroPump}, [BG_WATER] = {gBattleAnimBgImage_HydroPump, gBattleAnimBgPalette_HydroPump, gBattleAnimBgTilemap_HydroPump},
[BG_NIGHTMARE] = {gBattleAnimBgImage_Nightmare, gBattleAnimBgPalette_Nightmare, gBattleAnimBgTilemap_Nightmare}, [BG_NIGHTMARE] = {gBattleAnimBgImage_Nightmare, gBattleAnimBgPalette_Nightmare, gBattleAnimBgTilemap_Nightmare},

View File

@ -1924,12 +1924,20 @@ static const u8 sText_HoldEffectPsychicPower[] = _("Psychic Power");
static const u8 sText_HoldEffectFirePower[] = _("Fire Power"); static const u8 sText_HoldEffectFirePower[] = _("Fire Power");
static const u8 sText_HoldEffectDragonPower[] = _("Dragon Power"); static const u8 sText_HoldEffectDragonPower[] = _("Dragon Power");
static const u8 sText_HoldEffectNormalPower[] = _("Normal Power"); static const u8 sText_HoldEffectNormalPower[] = _("Normal Power");
static const u8 sText_HoldEffectUpGrade[] = _("Up Grade"); #ifdef ITEM_EXPANSION
static const u8 sText_HoldEffectUpgrade[] = _("Upgrade");
#else
static const u8 sText_HoldEffectUpgrade[] = _("Up Grade");
#endif
static const u8 sText_HoldEffectShellBell[] = _("Shell Bell"); static const u8 sText_HoldEffectShellBell[] = _("Shell Bell");
static const u8 sText_HoldEffectLuckyPunch[] = _("Lucky Punch"); static const u8 sText_HoldEffectLuckyPunch[] = _("Lucky Punch");
static const u8 sText_HoldEffectMetalPowder[] = _("Metal Powder"); static const u8 sText_HoldEffectMetalPowder[] = _("Metal Powder");
static const u8 sText_HoldEffectThickClub[] = _("Thick Club"); static const u8 sText_HoldEffectThickClub[] = _("Thick Club");
static const u8 sText_HoldEffectStick[] = _("Stick"); #ifdef ITEM_EXPANSION
static const u8 sText_HoldEffectLeek[] = _("Leek");
#else
static const u8 sText_HoldEffectLeek[] = _("Stick");
#endif
static const u8 sText_HoldEffectChoiceScarf[] = _("Choice Scarf"); static const u8 sText_HoldEffectChoiceScarf[] = _("Choice Scarf");
static const u8 sText_HoldEffectChoiceSpecs[] = _("Choice Specs"); static const u8 sText_HoldEffectChoiceSpecs[] = _("Choice Specs");
static const u8 sText_HoldEffectDampRock[] = _("Damp Rock"); static const u8 sText_HoldEffectDampRock[] = _("Damp Rock");
@ -2064,12 +2072,12 @@ static const u8 *const sHoldEffectNames[] =
[HOLD_EFFECT_FIRE_POWER] = sText_HoldEffectFirePower, [HOLD_EFFECT_FIRE_POWER] = sText_HoldEffectFirePower,
[HOLD_EFFECT_DRAGON_POWER] = sText_HoldEffectDragonPower, [HOLD_EFFECT_DRAGON_POWER] = sText_HoldEffectDragonPower,
[HOLD_EFFECT_NORMAL_POWER] = sText_HoldEffectNormalPower, [HOLD_EFFECT_NORMAL_POWER] = sText_HoldEffectNormalPower,
[HOLD_EFFECT_UP_GRADE] = sText_HoldEffectUpGrade, [HOLD_EFFECT_UPGRADE] = sText_HoldEffectUpgrade,
[HOLD_EFFECT_SHELL_BELL] = sText_HoldEffectShellBell, [HOLD_EFFECT_SHELL_BELL] = sText_HoldEffectShellBell,
[HOLD_EFFECT_LUCKY_PUNCH] = sText_HoldEffectLuckyPunch, [HOLD_EFFECT_LUCKY_PUNCH] = sText_HoldEffectLuckyPunch,
[HOLD_EFFECT_METAL_POWDER] = sText_HoldEffectMetalPowder, [HOLD_EFFECT_METAL_POWDER] = sText_HoldEffectMetalPowder,
[HOLD_EFFECT_THICK_CLUB] = sText_HoldEffectThickClub, [HOLD_EFFECT_THICK_CLUB] = sText_HoldEffectThickClub,
[HOLD_EFFECT_STICK] = sText_HoldEffectStick, [HOLD_EFFECT_LEEK] = sText_HoldEffectLeek,
[HOLD_EFFECT_CHOICE_SCARF] = sText_HoldEffectChoiceScarf, [HOLD_EFFECT_CHOICE_SCARF] = sText_HoldEffectChoiceScarf,
[HOLD_EFFECT_CHOICE_SPECS] = sText_HoldEffectChoiceSpecs, [HOLD_EFFECT_CHOICE_SPECS] = sText_HoldEffectChoiceSpecs,
[HOLD_EFFECT_DAMP_ROCK] = sText_HoldEffectDampRock, [HOLD_EFFECT_DAMP_ROCK] = sText_HoldEffectDampRock,

View File

@ -3548,7 +3548,11 @@ static void TryDoEventsBeforeFirstTurn(void)
return; return;
} }
} }
// Check neutralizing gas
if (AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, 0, 0, 0, 0) != 0)
return;
// Check all switch in abilities happening from the fastest mon to slowest. // Check all switch in abilities happening from the fastest mon to slowest.
while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount) while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount)
{ {

View File

@ -629,7 +629,7 @@ static const u8 sText_TerrainBecomesGrassy[] = _("Grass grew to cover\nthe battl
static const u8 sText_TerrainBecomesElectric[] = _("An electric current runs across\nthe battlefield!"); static const u8 sText_TerrainBecomesElectric[] = _("An electric current runs across\nthe battlefield!");
static const u8 sText_TerrainBecomesPsychic[] = _("The battlefield got weird!"); static const u8 sText_TerrainBecomesPsychic[] = _("The battlefield got weird!");
static const u8 sText_TargetElectrified[] = _("The {B_DEF_NAME_WITH_PREFIX}'s moves\nhave been electrified!"); static const u8 sText_TargetElectrified[] = _("The {B_DEF_NAME_WITH_PREFIX}'s moves\nhave been electrified!");
static const u8 sText_AssaultVestDoesntAllow[] = _("The effects of the {B_LAST_ITEM} prevent status\nmoves from being used!\p"); static const u8 sText_AssaultVestDoesntAllow[] = _("{B_LAST_ITEM}'s effects prevent\nstatus moves from being used!\p");
static const u8 sText_GravityPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} can't use {B_CURRENT_MOVE}\nbecause of gravity!\p"); static const u8 sText_GravityPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} can't use {B_CURRENT_MOVE}\nbecause of gravity!\p");
static const u8 sText_HealBlockPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} was\nprevented from healing!\p"); static const u8 sText_HealBlockPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} was\nprevented from healing!\p");
static const u8 sText_MegaEvoReacting[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ITEM} is \nreacting to {B_ATK_TRAINER_NAME}'s Mega Ring!"); static const u8 sText_MegaEvoReacting[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ITEM} is \nreacting to {B_ATK_TRAINER_NAME}'s Mega Ring!");
@ -733,9 +733,13 @@ static const u8 sText_CantEscapeDueToUsedMove[] = _("{B_ATK_NAME_WITH_PREFIX} ca
static const u8 sText_PkmnBecameWeakerToFire[] = _("{B_DEF_NAME_WITH_PREFIX} became\nweaker to fire!"); static const u8 sText_PkmnBecameWeakerToFire[] = _("{B_DEF_NAME_WITH_PREFIX} became\nweaker to fire!");
static const u8 sText_PkmnAboutToBeAttackedByItsItem[] = _("{B_DEF_NAME_WITH_PREFIX} is about\nto be attacked by its {B_BUFF1}!"); static const u8 sText_PkmnAboutToBeAttackedByItsItem[] = _("{B_DEF_NAME_WITH_PREFIX} is about\nto be attacked by its {B_BUFF1}!");
static const u8 sText_CantEscapeBecauseOfCurrentMove[] = _("{B_DEF_NAME_WITH_PREFIX} can no longer escape\nbecause of {B_CURRENT_MOVE}!"); static const u8 sText_CantEscapeBecauseOfCurrentMove[] = _("{B_DEF_NAME_WITH_PREFIX} can no longer escape\nbecause of {B_CURRENT_MOVE}!");
static const u8 sText_NeutralizingGasEnters[] = _("Neutralizing Gas filled the area!");
static const u8 sText_NeutralizingGasOver[] = _("The effects of Neutralizing\nGas wore off!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{ {
[STRINGID_NEUTRALIZINGGASOVER - 12] = sText_NeutralizingGasOver,
[STRINGID_NEUTRALIZINGGASENTERS - 12] = sText_NeutralizingGasEnters,
[STRINGID_BATTLERTYPECHANGEDTO - 12] = sText_BattlerTypeChangedTo, [STRINGID_BATTLERTYPECHANGEDTO - 12] = sText_BattlerTypeChangedTo,
[STRINGID_PASTELVEILENTERS - 12] = sText_PastelVeilEnters, [STRINGID_PASTELVEILENTERS - 12] = sText_PastelVeilEnters,
[STRINGID_PASTELVEILPROTECTED -12] = sText_PastelVeilProtected, [STRINGID_PASTELVEILPROTECTED -12] = sText_PastelVeilProtected,
@ -1392,6 +1396,7 @@ const u16 gSwitchInAbilityStringIds[] =
[B_MSG_SWITCHIN_ASONE] = STRINGID_ASONEENTERS, [B_MSG_SWITCHIN_ASONE] = STRINGID_ASONEENTERS,
[B_MSG_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS, [B_MSG_SWITCHIN_CURIOUS_MEDICINE] = STRINGID_CURIOUSMEDICINEENTERS,
[B_MSG_SWITCHIN_PASTEL_VEIL] = STRINGID_PASTELVEILENTERS, [B_MSG_SWITCHIN_PASTEL_VEIL] = STRINGID_PASTELVEILENTERS,
[B_MSG_SWITCHIN_NEUTRALIZING_GAS] = STRINGID_NEUTRALIZINGGASENTERS,
}; };
const u16 gMissStringIds[] = const u16 gMissStringIds[] =

View File

@ -1313,47 +1313,6 @@ static const u8 sBattlePalaceNatureToFlavorTextId[NUM_NATURES] =
[NATURE_QUIRKY] = B_MSG_EAGER_FOR_MORE, [NATURE_QUIRKY] = B_MSG_EAGER_FOR_MORE,
}; };
bool32 IsBattlerProtected(u8 battlerId, u16 move)
{
// Decorate bypasses protect and detect, but not crafty shield
if (move == MOVE_DECORATE)
{
if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD)
return TRUE;
else if (gProtectStructs[battlerId].protected)
return FALSE;
}
if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED))
return FALSE;
else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT)
return FALSE;
else if (gProtectStructs[battlerId].protected)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD
&& gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
return TRUE;
else if (gProtectStructs[battlerId].banefulBunkered)
return TRUE;
else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move))
return TRUE;
else if (gProtectStructs[battlerId].spikyShielded)
return TRUE;
else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD
&& GetChosenMovePriority(gBattlerAttacker) > 0)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD
&& IS_MOVE_STATUS(move))
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK
&& !IS_MOVE_STATUS(move))
return TRUE;
else
return FALSE;
}
static bool32 NoTargetPresent(u32 move) static bool32 NoTargetPresent(u32 move)
{ {
if (!IsBattlerAlive(gBattlerTarget)) if (!IsBattlerAlive(gBattlerTarget))
@ -1934,7 +1893,7 @@ s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbi
+ ((gBattleMoves[gCurrentMove].flags & FLAG_HIGH_CRIT) != 0) + ((gBattleMoves[gCurrentMove].flags & FLAG_HIGH_CRIT) != 0)
+ (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS) + (holdEffectAtk == HOLD_EFFECT_SCOPE_LENS)
+ 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY) + 2 * (holdEffectAtk == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBattlerAttacker].species == SPECIES_CHANSEY)
+ 2 * (holdEffectAtk == HOLD_EFFECT_STICK && gBattleMons[gBattlerAttacker].species == SPECIES_FARFETCHD) + 2 * (holdEffectAtk == HOLD_EFFECT_LEEK && gBattleMons[gBattlerAttacker].species == SPECIES_FARFETCHD)
+ (abilityAtk == ABILITY_SUPER_LUCK); + (abilityAtk == ABILITY_SUPER_LUCK);
if (critChance >= ARRAY_COUNT(sCriticalHitChance)) if (critChance >= ARRAY_COUNT(sCriticalHitChance))
@ -3071,7 +3030,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
if (NoAliveMonsForEitherParty() if (NoAliveMonsForEitherParty()
|| ChangeStatBuffs(SET_STAT_BUFF_VALUE(1), || ChangeStatBuffs(SET_STAT_BUFF_VALUE(1),
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_1 + 1, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_1 + 1,
affectsUser, 0)) affectsUser | STAT_BUFF_UPDATE_MOVE_EFFECT, 0))
{ {
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
} }
@ -3096,7 +3055,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE, if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE,
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_1 + 1, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_1 + 1,
flags, gBattlescriptCurrInstr + 1)) flags | STAT_BUFF_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1))
{ {
if (!mirrorArmorReflected) if (!mirrorArmorReflected)
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
@ -3119,7 +3078,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
if (NoAliveMonsForEitherParty() if (NoAliveMonsForEitherParty()
|| ChangeStatBuffs(SET_STAT_BUFF_VALUE(2), || ChangeStatBuffs(SET_STAT_BUFF_VALUE(2),
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_2 + 1, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_PLUS_2 + 1,
affectsUser, 0)) affectsUser | STAT_BUFF_UPDATE_MOVE_EFFECT, 0))
{ {
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
} }
@ -3143,7 +3102,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
flags |= STAT_BUFF_ALLOW_PTR; flags |= STAT_BUFF_ALLOW_PTR;
if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE, if (ChangeStatBuffs(SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE,
gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_2 + 1, gBattleScripting.moveEffect - MOVE_EFFECT_ATK_MINUS_2 + 1,
flags, gBattlescriptCurrInstr + 1)) flags | STAT_BUFF_UPDATE_MOVE_EFFECT, gBattlescriptCurrInstr + 1))
{ {
if (!mirrorArmorReflected) if (!mirrorArmorReflected)
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
@ -3205,7 +3164,11 @@ void SetMoveEffect(bool32 primary, u32 certain)
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility); RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
} }
else if (gBattleMons[gBattlerAttacker].item != 0 else if (gBattleMons[gBattlerAttacker].item != 0
#ifdef ITEM_EXPANSION
|| gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY_E_READER
#else
|| gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY || gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY
#endif
|| gBattleMons[gBattlerTarget].item == 0) || gBattleMons[gBattlerTarget].item == 0)
{ {
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
@ -6200,8 +6163,17 @@ static void Cmd_switchineffects(void)
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler)); gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler));
gSpecialStatuses[gActiveBattler].flag40 = 0; gSpecialStatuses[gActiveBattler].flag40 = 0;
if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED) // Neutralizing Gas announces itself before hazards
if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS && gSpecialStatuses[gActiveBattler].announceNeutralizingGas == 0)
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
gSpecialStatuses[gActiveBattler].announceNeutralizingGas = TRUE;
gBattlerAbility = gActiveBattler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SwitchInAbilityMsgRet;
}
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES) && (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES)
&& GetBattlerAbility(gActiveBattler) != ABILITY_MAGIC_GUARD && GetBattlerAbility(gActiveBattler) != ABILITY_MAGIC_GUARD
&& IsBattlerAffectedByHazards(gActiveBattler, FALSE) && IsBattlerAffectedByHazards(gActiveBattler, FALSE)
@ -6275,7 +6247,7 @@ static void Cmd_switchineffects(void)
{ {
// There is a hack here to ensure the truant counter will be 0 when the battler's next turn starts. // There is a hack here to ensure the truant counter will be 0 when the battler's next turn starts.
// The truant counter is not updated in the case where a mon switches in after a lost judgement in the battle arena. // The truant counter is not updated in the case where a mon switches in after a lost judgement in the battle arena.
if (gBattleMons[gActiveBattler].ability == ABILITY_TRUANT if (GetBattlerAbility(gActiveBattler) == ABILITY_TRUANT
&& gCurrentActionFuncId != B_ACTION_USE_MOVE && gCurrentActionFuncId != B_ACTION_USE_MOVE
&& !gDisableStructs[gActiveBattler].truantSwitchInHack) && !gDisableStructs[gActiveBattler].truantSwitchInHack)
gDisableStructs[gActiveBattler].truantCounter = 1; gDisableStructs[gActiveBattler].truantCounter = 1;
@ -7466,7 +7438,7 @@ u32 IsLeafGuardProtected(u32 battler)
bool32 IsShieldsDownProtected(u32 battler) bool32 IsShieldsDownProtected(u32 battler)
{ {
return (gBattleMons[battler].ability == ABILITY_SHIELDS_DOWN return (GetBattlerAbility(battler) == ABILITY_SHIELDS_DOWN
&& GetFormIdFromFormSpeciesId(gBattleMons[battler].species) < GetFormIdFromFormSpeciesId(SPECIES_MINIOR_CORE_RED)); // Minior is not in core form && GetFormIdFromFormSpeciesId(gBattleMons[battler].species) < GetFormIdFromFormSpeciesId(SPECIES_MINIOR_CORE_RED)); // Minior is not in core form
} }
@ -7934,6 +7906,7 @@ static void Cmd_various(void)
break; break;
case VARIOUS_SWITCHIN_ABILITIES: case VARIOUS_SWITCHIN_ABILITIES:
gBattlescriptCurrInstr += 3; gBattlescriptCurrInstr += 3;
AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, gActiveBattler, 0, 0, 0);
AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0);
AbilityBattleEffects(ABILITYEFFECT_INTIMIDATE2, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_INTIMIDATE2, gActiveBattler, 0, 0, 0);
AbilityBattleEffects(ABILITYEFFECT_TRACE2, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_TRACE2, gActiveBattler, 0, 0, 0);
@ -8114,6 +8087,9 @@ static void Cmd_various(void)
} }
else else
{ {
if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS)
gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE;
gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE; gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE;
gBattlescriptCurrInstr += 7; gBattlescriptCurrInstr += 7;
} }
@ -9017,6 +8993,15 @@ static void Cmd_various(void)
} }
break; break;
} }
case VARIOUS_TRY_END_NEUTRALIZING_GAS:
if (gSpecialStatuses[gActiveBattler].neutralizingGasRemoved)
{
gSpecialStatuses[gActiveBattler].neutralizingGasRemoved = FALSE;
BattleScriptPush(gBattlescriptCurrInstr + 3);
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
return;
}
break;
case VARIOUS_GET_ROTOTILLER_TARGETS: case VARIOUS_GET_ROTOTILLER_TARGETS:
// Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!' // Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!'
{ {
@ -9815,6 +9800,72 @@ static void Cmd_setdrainedhp(void)
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
} }
static u16 ReverseStatChangeMoveEffect(u16 moveEffect)
{
switch (moveEffect)
{
// +1
case MOVE_EFFECT_ATK_PLUS_1:
return MOVE_EFFECT_ATK_MINUS_1;
case MOVE_EFFECT_DEF_PLUS_1:
return MOVE_EFFECT_DEF_MINUS_1;
case MOVE_EFFECT_SPD_PLUS_1:
return MOVE_EFFECT_SPD_MINUS_1;
case MOVE_EFFECT_SP_ATK_PLUS_1:
return MOVE_EFFECT_SP_ATK_MINUS_1;
case MOVE_EFFECT_SP_DEF_PLUS_1:
return MOVE_EFFECT_SP_DEF_MINUS_1;
case MOVE_EFFECT_ACC_PLUS_1:
return MOVE_EFFECT_ACC_MINUS_1;
case MOVE_EFFECT_EVS_PLUS_1:
return MOVE_EFFECT_EVS_MINUS_1;
// -1
case MOVE_EFFECT_ATK_MINUS_1:
return MOVE_EFFECT_ATK_PLUS_1;
case MOVE_EFFECT_DEF_MINUS_1:
return MOVE_EFFECT_DEF_PLUS_1;
case MOVE_EFFECT_SPD_MINUS_1:
return MOVE_EFFECT_SPD_PLUS_1;
case MOVE_EFFECT_SP_ATK_MINUS_1:
return MOVE_EFFECT_SP_ATK_PLUS_1;
case MOVE_EFFECT_SP_DEF_MINUS_1:
return MOVE_EFFECT_SP_DEF_PLUS_1;
case MOVE_EFFECT_ACC_MINUS_1:
return MOVE_EFFECT_ACC_PLUS_1;
case MOVE_EFFECT_EVS_MINUS_1:
// +2
case MOVE_EFFECT_ATK_PLUS_2:
return MOVE_EFFECT_ATK_MINUS_2;
case MOVE_EFFECT_DEF_PLUS_2:
return MOVE_EFFECT_DEF_MINUS_2;
case MOVE_EFFECT_SPD_PLUS_2:
return MOVE_EFFECT_SPD_MINUS_2;
case MOVE_EFFECT_SP_ATK_PLUS_2:
return MOVE_EFFECT_SP_ATK_MINUS_2;
case MOVE_EFFECT_SP_DEF_PLUS_2:
return MOVE_EFFECT_SP_DEF_MINUS_2;
case MOVE_EFFECT_ACC_PLUS_2:
return MOVE_EFFECT_ACC_MINUS_2;
case MOVE_EFFECT_EVS_PLUS_2:
return MOVE_EFFECT_EVS_MINUS_2;
// -2
case MOVE_EFFECT_ATK_MINUS_2:
return MOVE_EFFECT_ATK_PLUS_2;
case MOVE_EFFECT_DEF_MINUS_2:
return MOVE_EFFECT_DEF_PLUS_2;
case MOVE_EFFECT_SPD_MINUS_2:
return MOVE_EFFECT_SPD_PLUS_2;
case MOVE_EFFECT_SP_ATK_MINUS_2:
return MOVE_EFFECT_SP_ATK_PLUS_2;
case MOVE_EFFECT_SP_DEF_MINUS_2:
return MOVE_EFFECT_SP_DEF_PLUS_2;
case MOVE_EFFECT_ACC_MINUS_2:
return MOVE_EFFECT_ACC_PLUS_2;
case MOVE_EFFECT_EVS_MINUS_2:
return MOVE_EFFECT_EVS_PLUS_2;
}
}
static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr) static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr)
{ {
bool32 certain = FALSE; bool32 certain = FALSE;
@ -9843,6 +9894,11 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
{ {
statValue ^= STAT_BUFF_NEGATIVE; statValue ^= STAT_BUFF_NEGATIVE;
gBattleScripting.statChanger ^= STAT_BUFF_NEGATIVE; gBattleScripting.statChanger ^= STAT_BUFF_NEGATIVE;
if (flags & STAT_BUFF_UPDATE_MOVE_EFFECT)
{
flags &= ~(STAT_BUFF_UPDATE_MOVE_EFFECT);
gBattleScripting.moveEffect = ReverseStatChangeMoveEffect(gBattleScripting.moveEffect);
}
} }
else if (GetBattlerAbility(gActiveBattler) == ABILITY_SIMPLE) else if (GetBattlerAbility(gActiveBattler) == ABILITY_SIMPLE)
{ {
@ -11361,11 +11417,11 @@ static void Cmd_healpartystatus(void)
u16 ability; u16 ability;
if (gBattlerPartyIndexes[gBattlerAttacker] == i) if (gBattlerPartyIndexes[gBattlerAttacker] == i)
ability = gBattleMons[gBattlerAttacker].ability; ability = GetBattlerAbility(gBattlerAttacker);
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& gBattlerPartyIndexes[gActiveBattler] == i && gBattlerPartyIndexes[gActiveBattler] == i
&& !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) && !(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
ability = gBattleMons[gActiveBattler].ability; ability = GetBattlerAbility(gActiveBattler);
else else
ability = GetAbilityBySpecies(species, abilityNum); ability = GetAbilityBySpecies(species, abilityNum);
@ -12276,12 +12332,13 @@ static void Cmd_trywish(void)
break; break;
case 1: // heal effect case 1: // heal effect
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget]) PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget])
#if B_WISH_HP_SOURCE >= GEN_5
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2; gBattleMoveDamage = max(1, gBattleMons[gWishFutureKnock.wishMonId[gBattlerTarget]].maxHP / 2);
if (gBattleMoveDamage == 0) #else
gBattleMoveDamage = 1; gBattleMoveDamage = max(1, gBattleMons[gBattlerTarget].maxHP / 2);
#endif
gBattleMoveDamage *= -1; gBattleMoveDamage *= -1;
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP) if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else else
@ -12314,6 +12371,9 @@ static void Cmd_setgastroacid(void)
} }
else else
{ {
if (gBattleMons[gBattlerTarget].ability == ABILITY_NEUTRALIZING_GAS)
gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE;
gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID; gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID;
gBattlescriptCurrInstr += 5; gBattlescriptCurrInstr += 5;
} }
@ -12594,25 +12654,33 @@ static void Cmd_trygetintimidatetarget(void)
static void Cmd_switchoutabilities(void) static void Cmd_switchoutabilities(void)
{ {
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS)
switch (GetBattlerAbility(gActiveBattler))
{ {
case ABILITY_NATURAL_CURE: gBattleMons[gActiveBattler].ability = ABILITY_NONE;
gBattleMons[gActiveBattler].status1 = 0; BattleScriptPush(gBattlescriptCurrInstr);
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1); gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
MarkBattlerForControllerExec(gActiveBattler); }
break; else
case ABILITY_REGENERATOR: {
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 3; switch (GetBattlerAbility(gActiveBattler))
gBattleMoveDamage += gBattleMons[gActiveBattler].hp; {
if (gBattleMoveDamage > gBattleMons[gActiveBattler].maxHP) case ABILITY_NATURAL_CURE:
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP; gBattleMons[gActiveBattler].status1 = 0;
BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 2, &gBattleMoveDamage); BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler); MarkBattlerForControllerExec(gActiveBattler);
break; break;
case ABILITY_REGENERATOR:
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 3;
gBattleMoveDamage += gBattleMons[gActiveBattler].hp;
if (gBattleMoveDamage > gBattleMons[gActiveBattler].maxHP)
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP;
BtlController_EmitSetMonData(0, REQUEST_HP_BATTLE, gBitTable[*(gBattleStruct->field_58 + gActiveBattler)], 2, &gBattleMoveDamage);
MarkBattlerForControllerExec(gActiveBattler);
break;
}
gBattlescriptCurrInstr += 2;
} }
gBattlescriptCurrInstr += 2;
} }
static void Cmd_jumpifhasnohp(void) static void Cmd_jumpifhasnohp(void)
@ -13032,14 +13100,32 @@ static void Cmd_snatchsetbattlers(void)
static void Cmd_removelightscreenreflect(void) // brick break static void Cmd_removelightscreenreflect(void) // brick break
{ {
u8 opposingSide = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE; u8 side;
bool32 failed;
if (gSideTimers[opposingSide].reflectTimer || gSideTimers[opposingSide].lightscreenTimer)
#if B_BRICK_BREAK >= GEN_4
side = GetBattlerSide(gBattlerAttacker);
#else
side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
#endif
#if B_BRICK_BREAK >= GEN_5
failed = (gMoveResultFlags & MOVE_RESULT_NO_EFFECT);
#else
failed = FALSE;
#endif
if (!failed
&& (gSideTimers[side].reflectTimer
|| gSideTimers[side].lightscreenTimer
|| gSideTimers[side].auroraVeilTimer))
{ {
gSideStatuses[opposingSide] &= ~(SIDE_STATUS_REFLECT); gSideStatuses[side] &= ~(SIDE_STATUS_REFLECT);
gSideStatuses[opposingSide] &= ~(SIDE_STATUS_LIGHTSCREEN); gSideStatuses[side] &= ~(SIDE_STATUS_LIGHTSCREEN);
gSideTimers[opposingSide].reflectTimer = 0; gSideStatuses[side] &= ~(SIDE_STATUS_AURORA_VEIL);
gSideTimers[opposingSide].lightscreenTimer = 0; gSideTimers[side].reflectTimer = 0;
gSideTimers[side].lightscreenTimer = 0;
gSideTimers[side].auroraVeilTimer = 0;
gBattleScripting.animTurn = 1; gBattleScripting.animTurn = 1;
gBattleScripting.animTargetsHit = 1; gBattleScripting.animTargetsHit = 1;
} }
@ -13089,7 +13175,7 @@ static void Cmd_handleballthrow(void)
u8 catchRate; u8 catchRate;
gLastThrownBall = gLastUsedItem; gLastThrownBall = gLastUsedItem;
if (gLastUsedItem == ITEM_SAFARI_BALL) if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
catchRate = gBattleStruct->safariCatchFactor * 1275 / 100; catchRate = gBattleStruct->safariCatchFactor * 1275 / 100;
else else
catchRate = gBaseStats[gBattleMons[gBattlerTarget].species].catchRate; catchRate = gBaseStats[gBattleMons[gBattlerTarget].species].catchRate;

View File

@ -317,8 +317,8 @@ void HandleAction_UseMove(void)
else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
&& gSideTimers[side].followmeTimer == 0 && gSideTimers[side].followmeTimer == 0
&& (gBattleMoves[gCurrentMove].power != 0 || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER) && (gBattleMoves[gCurrentMove].power != 0 || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER)
&& ((gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) && ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_STORM_DRAIN && moveType == TYPE_WATER))) || (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
{ {
side = GetBattlerSide(gBattlerAttacker); side = GetBattlerSide(gBattlerAttacker);
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
@ -387,9 +387,9 @@ void HandleAction_UseMove(void)
{ {
gActiveBattler = gBattlerByTurnOrder[var]; gActiveBattler = gBattlerByTurnOrder[var];
RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability);
if (gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD) if (GetBattlerAbility(gActiveBattler) == ABILITY_LIGHTNING_ROD)
gSpecialStatuses[gActiveBattler].lightningRodRedirected = TRUE; gSpecialStatuses[gActiveBattler].lightningRodRedirected = TRUE;
else if (gBattleMons[gActiveBattler].ability == ABILITY_STORM_DRAIN) else if (GetBattlerAbility(gActiveBattler) == ABILITY_STORM_DRAIN)
gSpecialStatuses[gActiveBattler].stormDrainRedirected = TRUE; gSpecialStatuses[gActiveBattler].stormDrainRedirected = TRUE;
gBattlerTarget = gActiveBattler; gBattlerTarget = gActiveBattler;
} }
@ -627,7 +627,7 @@ bool8 TryRunFromBattle(u8 battler)
effect++; effect++;
} }
#endif #endif
else if (gBattleMons[battler].ability == ABILITY_RUN_AWAY) else if (GetBattlerAbility(battler) == ABILITY_RUN_AWAY)
{ {
if (InBattlePyramid()) if (InBattlePyramid())
{ {
@ -1762,7 +1762,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
limitations++; limitations++;
} }
} }
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0) else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[move].power == 0 && move != MOVE_ME_FIRST)
{ {
gCurrentMove = move; gCurrentMove = move;
gLastUsedItem = gBattleMons[gActiveBattler].item; gLastUsedItem = gBattleMons[gActiveBattler].item;
@ -1834,7 +1834,7 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check)
unusableMoves |= gBitTable[i]; unusableMoves |= gBitTable[i];
else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[battlerId].moves[i]) else if (HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[battlerId].moves[i])
unusableMoves |= gBitTable[i]; unusableMoves |= gBitTable[i];
else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0) else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0 && gBattleMons[battlerId].moves[i] != MOVE_ME_FIRST)
unusableMoves |= gBitTable[i]; unusableMoves |= gBitTable[i];
else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i])) else if (IsGravityPreventingMove(gBattleMons[battlerId].moves[i]))
unusableMoves |= gBitTable[i]; unusableMoves |= gBitTable[i];
@ -2727,7 +2727,7 @@ u8 DoBattlerEndTurnEffects(void)
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
{ {
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
&& gBattleMons[gBattlerAttacker].ability != ABILITY_SOUNDPROOF) && GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF)
{ {
gBattleMons[gBattlerAttacker].status1 &= ~(STATUS1_SLEEP); gBattleMons[gBattlerAttacker].status1 &= ~(STATUS1_SLEEP);
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE); gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE);
@ -3311,7 +3311,7 @@ u8 AtkCanceller_UnableToUseMove(void)
gBattleStruct->atkCancellerTracker++; gBattleStruct->atkCancellerTracker++;
break; break;
case CANCELLER_TRUANT: // truant case CANCELLER_TRUANT: // truant
if (gBattleMons[gBattlerAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter) if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter)
{ {
CancelMultiTurnMoves(gBattlerAttacker); CancelMultiTurnMoves(gBattlerAttacker);
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
@ -3752,7 +3752,7 @@ u8 TryWeatherFormChange(u8 battler)
if (gBattleMons[battler].species == SPECIES_CASTFORM) if (gBattleMons[battler].species == SPECIES_CASTFORM)
{ {
if (gBattleMons[battler].ability != ABILITY_FORECAST || gBattleMons[battler].hp == 0) if (GetBattlerAbility(battler) != ABILITY_FORECAST || gBattleMons[battler].hp == 0)
{ {
ret = 0; ret = 0;
} }
@ -3788,11 +3788,11 @@ u8 TryWeatherFormChange(u8 battler)
} }
else if (gBattleMons[battler].species == SPECIES_CHERRIM) else if (gBattleMons[battler].species == SPECIES_CHERRIM)
{ {
if (gBattleMons[battler].ability != ABILITY_FLOWER_GIFT || gBattleMons[battler].hp == 0) if (GetBattlerAbility(battler) != ABILITY_FLOWER_GIFT || gBattleMons[battler].hp == 0)
ret = 0; ret = 0;
else if (gBattleMonForms[battler] == 0 && weatherEffect && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && gBattleWeather & WEATHER_SUN_ANY) else if (gBattleMonForms[battler] == 0 && weatherEffect && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && gBattleWeather & WEATHER_SUN_ANY)
ret = 2; ret = 2;
else if (gBattleMonForms[battler] != 0 && (!weatherEffect || holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA || !(gBattleWeather & WEATHER_SUN_ANY))) else if (gBattleMonForms[battler] != 0 && (!weatherEffect || holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA || !(gBattleWeather & WEATHER_SUN_ANY)))
ret = 1; ret = 1;
} }
@ -3878,7 +3878,7 @@ static bool32 ShouldChangeFormHpBased(u32 battler)
for (i = 0; i < ARRAY_COUNT(forms); i++) for (i = 0; i < ARRAY_COUNT(forms); i++)
{ {
if (gBattleMons[battler].ability == forms[i][0]) if (GetBattlerAbility(battler) == forms[i][0])
{ {
if (gBattleMons[battler].species == forms[i][2] if (gBattleMons[battler].species == forms[i][2]
&& gBattleMons[battler].hp > gBattleMons[battler].maxHP / forms[i][3]) && gBattleMons[battler].hp > gBattleMons[battler].maxHP / forms[i][3])
@ -5373,7 +5373,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITYEFFECT_IMMUNITY: // 5 case ABILITYEFFECT_IMMUNITY: // 5
for (battler = 0; battler < gBattlersCount; battler++) for (battler = 0; battler < gBattlersCount; battler++)
{ {
switch (gBattleMons[battler].ability) switch (GetBattlerAbility(battler))
{ {
case ABILITY_IMMUNITY: case ABILITY_IMMUNITY:
if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON | STATUS1_TOXIC_COUNTER)) if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON | STATUS1_TOXIC_COUNTER))
@ -5463,7 +5463,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITYEFFECT_FORECAST: // 6 case ABILITYEFFECT_FORECAST: // 6
for (battler = 0; battler < gBattlersCount; battler++) for (battler = 0; battler < gBattlersCount; battler++)
{ {
if (gBattleMons[battler].ability == ABILITY_FORECAST || gBattleMons[battler].ability == ABILITY_FLOWER_GIFT) if (GetBattlerAbility(battler) == ABILITY_FORECAST || GetBattlerAbility(battler) == ABILITY_FLOWER_GIFT)
{ {
effect = TryWeatherFormChange(battler); effect = TryWeatherFormChange(battler);
if (effect) if (effect)
@ -5524,7 +5524,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITYEFFECT_INTIMIDATE2: case ABILITYEFFECT_INTIMIDATE2:
for (i = 0; i < gBattlersCount; i++) for (i = 0; i < gBattlersCount; i++)
{ {
if (gBattleMons[i].ability == ABILITY_INTIMIDATE && gBattleResources->flags->flags[i] & RESOURCE_FLAG_INTIMIDATED) if (GetBattlerAbility(i) == ABILITY_INTIMIDATE && gBattleResources->flags->flags[i] & RESOURCE_FLAG_INTIMIDATED)
{ {
gLastUsedAbility = ABILITY_INTIMIDATE; gLastUsedAbility = ABILITY_INTIMIDATE;
gBattleResources->flags->flags[i] &= ~(RESOURCE_FLAG_INTIMIDATED); gBattleResources->flags->flags[i] &= ~(RESOURCE_FLAG_INTIMIDATED);
@ -5591,6 +5591,23 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
} }
} }
break; break;
case ABILITYEFFECT_NEUTRALIZINGGAS:
// Prints message only. separate from ABILITYEFFECT_ON_SWITCHIN bc activates before entry hazards
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gBattleResources->flags->flags[i] & RESOURCE_FLAG_NEUTRALIZING_GAS))
{
gBattleResources->flags->flags[i] |= RESOURCE_FLAG_NEUTRALIZING_GAS;
gBattlerAbility = i;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWITCHIN_NEUTRALIZING_GAS;
BattleScriptPushCursorAndCallback(BattleScript_SwitchInAbilityMsg);
effect++;
}
if (effect)
break;
}
break;
} }
if (effect && gLastUsedAbility != 0xFF) if (effect && gLastUsedAbility != 0xFF)
@ -5601,11 +5618,51 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
return effect; return effect;
} }
bool32 IsNeutralizingGasBannedAbility(u32 ability)
{
switch (ability)
{
case ABILITY_MULTITYPE:
case ABILITY_ZEN_MODE:
case ABILITY_STANCE_CHANGE:
case ABILITY_POWER_CONSTRUCT:
case ABILITY_SCHOOLING:
case ABILITY_RKS_SYSTEM:
case ABILITY_SHIELDS_DOWN:
case ABILITY_COMATOSE:
case ABILITY_DISGUISE:
case ABILITY_GULP_MISSILE:
case ABILITY_ICE_FACE:
case ABILITY_AS_ONE_ICE_RIDER:
case ABILITY_AS_ONE_SHADOW_RIDER:
return TRUE;
default:
return FALSE;
}
}
bool32 IsNeutralizingGasOnField(void)
{
u32 i;
for (i = 0; i < gBattlersCount; i++)
{
if (IsBattlerAlive(i) && gBattleMons[i].ability == ABILITY_NEUTRALIZING_GAS && !(gStatuses3[i] & STATUS3_GASTRO_ACID))
return TRUE;
}
return FALSE;
}
u32 GetBattlerAbility(u8 battlerId) u32 GetBattlerAbility(u8 battlerId)
{ {
if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID) if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID)
return ABILITY_NONE; return ABILITY_NONE;
else if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
if (IsNeutralizingGasOnField() && !IsNeutralizingGasBannedAbility(gBattleMons[battlerId].ability))
return ABILITY_NONE;
if ((((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT || gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE) || gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE)
&& !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID)) && !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID))
@ -5615,8 +5672,8 @@ u32 GetBattlerAbility(u8 battlerId)
&& gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE && gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE
&& gCurrentTurnActionNumber < gBattlersCount) && gCurrentTurnActionNumber < gBattlersCount)
return ABILITY_NONE; return ABILITY_NONE;
else
return gBattleMons[battlerId].ability; return gBattleMons[battlerId].ability;
} }
u32 IsAbilityOnSide(u32 battlerId, u32 ability) u32 IsAbilityOnSide(u32 battlerId, u32 ability)
@ -5668,7 +5725,7 @@ u32 IsAbilityPreventingEscape(u32 battlerId)
return 0; return 0;
#endif #endif
#if B_SHADOW_TAG_ESCAPE >= GEN_4 #if B_SHADOW_TAG_ESCAPE >= GEN_4
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && gBattleMons[battlerId].ability != ABILITY_SHADOW_TAG) if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && GetBattlerAbility(battlerId) != ABILITY_SHADOW_TAG)
#else #else
if (id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) if (id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG))
#endif #endif
@ -6860,8 +6917,10 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
switch (atkHoldEffect) switch (atkHoldEffect)
{ {
case HOLD_EFFECT_FLINCH: case HOLD_EFFECT_FLINCH:
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) #if B_SERENE_GRACE_BOOST >= GEN_5
atkHoldEffectParam *= 2; if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE)
atkHoldEffectParam *= 2;
#endif
if (gBattleMoveDamage != 0 // Need to have done damage if (gBattleMoveDamage != 0 // Need to have done damage
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& TARGET_TURN_DAMAGED && TARGET_TURN_DAMAGED
@ -7217,7 +7276,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
targetBattler = SetRandomTarget(gBattlerAttacker); targetBattler = SetRandomTarget(gBattlerAttacker);
if (gBattleMoves[move].type == TYPE_ELECTRIC if (gBattleMoves[move].type == TYPE_ELECTRIC
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD) && IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD)
&& gBattleMons[targetBattler].ability != ABILITY_LIGHTNING_ROD) && GetBattlerAbility(targetBattler) != ABILITY_LIGHTNING_ROD)
{ {
targetBattler ^= BIT_FLANK; targetBattler ^= BIT_FLANK;
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability); RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
@ -7225,7 +7284,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
} }
else if (gBattleMoves[move].type == TYPE_WATER else if (gBattleMoves[move].type == TYPE_WATER
&& IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_STORM_DRAIN) && IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_STORM_DRAIN)
&& gBattleMons[targetBattler].ability != ABILITY_STORM_DRAIN) && GetBattlerAbility(targetBattler) != ABILITY_STORM_DRAIN)
{ {
targetBattler ^= BIT_FLANK; targetBattler ^= BIT_FLANK;
RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability); RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability);
@ -7403,7 +7462,7 @@ u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating)
return HOLD_EFFECT_NONE; return HOLD_EFFECT_NONE;
if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM)
return HOLD_EFFECT_NONE; return HOLD_EFFECT_NONE;
if (gBattleMons[battlerId].ability == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID)) if (GetBattlerAbility(battlerId) == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID))
return HOLD_EFFECT_NONE; return HOLD_EFFECT_NONE;
} }
@ -7448,6 +7507,48 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk)
} }
} }
bool32 IsBattlerProtected(u8 battlerId, u16 move)
{
// Decorate bypasses protect and detect, but not crafty shield
if (move == MOVE_DECORATE)
{
if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD)
return TRUE;
else if (gProtectStructs[battlerId].protected)
return FALSE;
}
if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED))
return FALSE;
else if (gBattleMoves[move].effect == MOVE_EFFECT_FEINT)
return FALSE;
else if (gProtectStructs[battlerId].protected)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD
&& gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
return TRUE;
else if (gProtectStructs[battlerId].banefulBunkered)
return TRUE;
else if (gProtectStructs[battlerId].obstructed && !IS_MOVE_STATUS(move))
return TRUE;
else if (gProtectStructs[battlerId].spikyShielded)
return TRUE;
else if (gProtectStructs[battlerId].kingsShielded && gBattleMoves[move].power != 0)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_QUICK_GUARD
&& GetChosenMovePriority(gBattlerAttacker) > 0)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_CRAFTY_SHIELD
&& IS_MOVE_STATUS(move))
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_MAT_BLOCK
&& !IS_MOVE_STATUS(move))
return TRUE;
else
return FALSE;
}
bool32 IsBattlerGrounded(u8 battlerId) bool32 IsBattlerGrounded(u8 battlerId)
{ {
if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_IRON_BALL) if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_IRON_BALL)
@ -8030,7 +8131,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
if (IsAbilityOnField(ABILITY_AURA_BREAK)) if (IsAbilityOnField(ABILITY_AURA_BREAK))
MulModifier(&modifier, UQ_4_12(0.75)); MulModifier(&modifier, UQ_4_12(0.75));
else else
MulModifier(&modifier, UQ_4_12(1.25)); MulModifier(&modifier, UQ_4_12(1.33));
} }
// attacker partner's abilities // attacker partner's abilities
@ -8191,8 +8292,11 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
MulModifier(&modifier, UQ_4_12(0.5)); MulModifier(&modifier, UQ_4_12(0.5));
break; break;
case EFFECT_KNOCK_OFF: case EFFECT_KNOCK_OFF:
if (gBattleMons[battlerDef].item != ITEM_NONE && GetBattlerAbility(battlerDef) != ABILITY_STICKY_HOLD) #if B_KNOCK_OFF_DMG >= GEN_6
if (gBattleMons[battlerDef].item != ITEM_NONE
&& CanBattlerGetOrLoseItem(battlerDef, gBattleMons[battlerDef].item))
MulModifier(&modifier, UQ_4_12(1.5)); MulModifier(&modifier, UQ_4_12(1.5));
#endif
break; break;
} }
@ -8607,7 +8711,9 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
if (((gSideStatuses[defSide] & SIDE_STATUS_REFLECT && IS_MOVE_PHYSICAL(move)) if (((gSideStatuses[defSide] & SIDE_STATUS_REFLECT && IS_MOVE_PHYSICAL(move))
|| (gSideStatuses[defSide] & SIDE_STATUS_LIGHTSCREEN && IS_MOVE_SPECIAL(move)) || (gSideStatuses[defSide] & SIDE_STATUS_LIGHTSCREEN && IS_MOVE_SPECIAL(move))
|| (gSideStatuses[defSide] & SIDE_STATUS_AURORA_VEIL)) || (gSideStatuses[defSide] & SIDE_STATUS_AURORA_VEIL))
&& abilityAtk != ABILITY_INFILTRATOR) && abilityAtk != ABILITY_INFILTRATOR
&& !(isCrit)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
MulModifier(&finalModifier, UQ_4_12(0.66)); MulModifier(&finalModifier, UQ_4_12(0.66));
@ -8779,9 +8885,6 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt
if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot) if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot)
mod = UQ_4_12(2.0); mod = UQ_4_12(2.0);
if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT)
mod = UQ_4_12(1.0);
// WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon // WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_STRONG_WINDS) if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_STRONG_WINDS)
{ {
@ -9005,9 +9108,9 @@ bool32 CanMegaEvolve(u8 battlerId)
struct MegaEvolutionData *mega = &(((struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]))->mega); struct MegaEvolutionData *mega = &(((struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]))->mega);
#ifdef ITEM_EXPANSION #ifdef ITEM_EXPANSION
// Check if Player has a Mega Bracelet // Check if Player has a Mega Ring
if ((GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT || (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(battlerId) == B_POSITION_PLAYER_RIGHT)) if ((GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT || (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(battlerId) == B_POSITION_PLAYER_RIGHT))
&& !CheckBagHasItem(ITEM_MEGA_BRACELET, 1)) && !CheckBagHasItem(ITEM_MEGA_RING, 1))
return FALSE; return FALSE;
#endif #endif

View File

@ -142,7 +142,7 @@ u32 sub_805725C(u8 battlerId)
{ {
u32 toSub; u32 toSub;
if (gBattleMons[battlerId].ability == ABILITY_EARLY_BIRD) if (GetBattlerAbility(battlerId) == ABILITY_EARLY_BIRD)
toSub = 2; toSub = 2;
else else
toSub = 1; toSub = 1;

View File

@ -2680,7 +2680,7 @@ const struct Item gItems[] =
.name = _("UP-GRADE"), .name = _("UP-GRADE"),
.itemId = ITEM_UP_GRADE, .itemId = ITEM_UP_GRADE,
.price = 2100, .price = 2100,
.holdEffect = HOLD_EFFECT_UP_GRADE, .holdEffect = HOLD_EFFECT_UPGRADE,
.description = sUpGradeDesc, .description = sUpGradeDesc,
.pocket = POCKET_ITEMS, .pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU, .type = ITEM_USE_BAG_MENU,
@ -2767,7 +2767,7 @@ const struct Item gItems[] =
.name = _("STICK"), .name = _("STICK"),
.itemId = ITEM_STICK, .itemId = ITEM_STICK,
.price = 200, .price = 200,
.holdEffect = HOLD_EFFECT_STICK, .holdEffect = HOLD_EFFECT_LEEK,
.description = sStickDesc, .description = sStickDesc,
.pocket = POCKET_ITEMS, .pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU, .type = ITEM_USE_BAG_MENU,

View File

@ -1395,7 +1395,6 @@ const u32 gBattleAnimBgPalette_Solarbeam[] = INCBIN_U32("graphics/battle_anims/b
const u32 gBattleAnimBgPalette_MagmaStorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/magma_storm.gbapal.lz"); const u32 gBattleAnimBgPalette_MagmaStorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/magma_storm.gbapal.lz");
//new battle bgs //new battle bgs
const u32 gBattleAnimBgPalette_GigaImpact[] = INCBIN_U32("graphics/battle_anims/backgrounds/giga_impact.gbapal.lz");
const u32 gBattleAnimBgImage_Hurricane[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/hurricane.4bpp.lz"); const u32 gBattleAnimBgImage_Hurricane[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/hurricane.4bpp.lz");
const u32 gBattleAnimBgPalette_Hurricane[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/hurricane.gbapal.lz"); const u32 gBattleAnimBgPalette_Hurricane[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/hurricane.gbapal.lz");
@ -1403,10 +1402,14 @@ const u32 gBattleAnimBgTilemap_Hurricane[] = INCBIN_U32("graphics/battle_anims/b
const u32 gBattleAnimBgPalette_RockWrecker[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/rock_wrecker.gbapal.lz"); const u32 gBattleAnimBgPalette_RockWrecker[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/rock_wrecker.gbapal.lz");
const u32 gBattleAnimBgTilemap_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_player.bin.lz");
const u32 gBattleAnimBgTilemap_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_opponent.bin.lz");
const u32 gBattleAnimBgTilemap_GigaImpactContest[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_contest.bin.lz");
const u32 gBattleAnimBgImage_GigaImpact[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact.4bpp.lz");
const u32 gBattleAnimBgPalette_GigaImpact[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact.gbapal.lz");
const u32 gBattleAnimBgImage_SpacialRend[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend.4bpp.lz"); const u32 gBattleAnimBgImage_SpacialRend[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend.4bpp.lz");
const u32 gBattleAnimBgPalette_SpacialRend[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend.gbapal.lz"); const u32 gBattleAnimBgPalette_SpacialRend[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend.gbapal.lz");
const u32 gBattleAnimBgTilemap_SpacialRendOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend_opponent.bin.lz");
const u32 gBattleAnimBgTilemap_SpacialRendPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/spacial_rend_player.bin.lz");
const u32 gBattleAnimBgPalette_SludgeWave[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/sludge_wave.gbapal.lz"); const u32 gBattleAnimBgPalette_SludgeWave[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/sludge_wave.gbapal.lz");
@ -1450,14 +1453,6 @@ const u32 gBattleAnimBgTilemap_FocusBlast[] = INCBIN_U32("graphics/battle_anims/
const u32 gBattleAnimBgPalette_GarbageFalls[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/garbage_falls.gbapal.lz"); const u32 gBattleAnimBgPalette_GarbageFalls[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/garbage_falls.gbapal.lz");
const u32 gBattleAnimBgImage_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_opponent.4bpp.lz");
const u32 gBattleAnimBgPalette_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_opponent.gbapal.lz");
const u32 gBattleAnimBgTilemap_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_opponent.bin.lz");
const u32 gBattleAnimBgImage_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_player.4bpp.lz");
const u32 gBattleAnimBgPalette_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_player.gbapal.lz");
const u32 gBattleAnimBgTilemap_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/giga_impact_player.bin.lz");
const u32 gBattleAnimBgImage_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.4bpp.lz"); const u32 gBattleAnimBgImage_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.gbapal.lz"); const u32 gBattleAnimBgPalette_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.bin.lz"); const u32 gBattleAnimBgTilemap_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new/grassy_terrain.bin.lz");