Merge branch 'battle_engine' of https://github.com/rh-hideout/pokeemerald-expansion into last_ball
This commit is contained in:
commit
ee3a2c97ee
20 changed files with 419 additions and 81 deletions
|
@ -1797,6 +1797,11 @@
|
|||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro jumpifpranksterblocked battler:req, ptr:req
|
||||
various \battler, VARIOUS_JUMP_IF_PRANKSTER_BLOCKED
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro eeriespellppreduce ptr:req
|
||||
various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE
|
||||
.4byte \ptr
|
||||
|
@ -1920,6 +1925,12 @@
|
|||
1:
|
||||
.endm
|
||||
|
||||
.macro jumpifflowerveilattacker jumpptr:req
|
||||
jumpifnottype BS_ATTACKER, TYPE_GRASS, 1f
|
||||
jumpifability BS_ATTACKER_SIDE, ABILITY_FLOWER_VEIL, \jumpptr
|
||||
1:
|
||||
.endm
|
||||
|
||||
.macro setallytonexttarget jumpptr:req
|
||||
jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f
|
||||
addbyte gBattlerTarget, 0x2
|
||||
|
|
|
@ -532,7 +532,7 @@ gBattleAnims_Moves::
|
|||
.4byte Move_QUASH
|
||||
.4byte Move_ACROBATICS
|
||||
.4byte Move_REFLECT_TYPE
|
||||
.4byte Move_RETALITATE
|
||||
.4byte Move_RETALIATE
|
||||
.4byte Move_FINAL_GAMBIT
|
||||
.4byte Move_BESTOW
|
||||
.4byte Move_INFERNO
|
||||
|
@ -822,6 +822,7 @@ gBattleAnims_General::
|
|||
.4byte General_SlideOffScreen @ B_ANIM_SLIDE_OFFSCREEN
|
||||
.4byte General_RestoreBg @ B_ANIM_RESTORE_BG
|
||||
.4byte General_TotemFlare @ B_ANIM_TOTEM_FLARE
|
||||
.4byte General_GulpMissile @ B_ANIM_GULP_MISSILE
|
||||
|
||||
.align 2
|
||||
gBattleAnims_Special::
|
||||
|
@ -5610,7 +5611,7 @@ Move_REFLECT_TYPE:
|
|||
blendoff
|
||||
end
|
||||
|
||||
Move_RETALITATE:
|
||||
Move_RETALIATE:
|
||||
loadspritegfx ANIM_TAG_CUT @Cut
|
||||
monbg ANIM_DEF_PARTNER
|
||||
setalpha 9, 8
|
||||
|
@ -24397,6 +24398,20 @@ General_TotemFlare::
|
|||
clearmonbg ANIM_ATTACKER
|
||||
end
|
||||
|
||||
General_GulpMissile: @ Tackle anim (placeholder)
|
||||
loadspritegfx ANIM_TAG_IMPACT
|
||||
monbg ANIM_ATTACKER
|
||||
setalpha 12, 8
|
||||
createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4
|
||||
delay 6
|
||||
createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_ATTACKER, 2
|
||||
createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 3, 0, 6, 1
|
||||
playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET
|
||||
waitforvisualfinish
|
||||
clearmonbg ANIM_ATTACKER
|
||||
blendoff
|
||||
end
|
||||
|
||||
RainbowEndureEffect:
|
||||
launchtemplate gBlueEndureEnergySpriteTemplate 0x2 0x4 0x0 0xffe8 0x1a 0x2
|
||||
delay 0x3
|
||||
|
|
|
@ -252,7 +252,7 @@ gBattleScriptsForMoveEffects::
|
|||
.4byte BattleScript_EffectHit @ EFFECT_ROUND
|
||||
.4byte BattleScript_EffectHit @ EFFECT_BRINE
|
||||
.4byte BattleScript_EffectHit @ EFFECT_VENOSHOCK
|
||||
.4byte BattleScript_EffectHit @ EFFECT_RETALITATE
|
||||
.4byte BattleScript_EffectHit @ EFFECT_RETALIATE
|
||||
.4byte BattleScript_EffectBulldoze @ EFFECT_BULLDOZE
|
||||
.4byte BattleScript_EffectHit @ EFFECT_FOUL_PLAY
|
||||
.4byte BattleScript_EffectHit @ EFFECT_PSYSHOCK
|
||||
|
@ -379,6 +379,7 @@ gBattleScriptsForMoveEffects::
|
|||
.4byte BattleScript_EffectDecorate @ EFFECT_DECORATE
|
||||
.4byte BattleScript_EffectHit @ EFFECT_SNIPE_SHOT
|
||||
.4byte BattleScript_EffectTripleHit @ EFFECT_TRIPLE_HIT
|
||||
.4byte BattleScript_EffectRecoilHP25 @ EFFECT_RECOIL_HP_25
|
||||
|
||||
BattleScript_EffectDecorate:
|
||||
attackcanceler
|
||||
|
@ -3867,19 +3868,25 @@ BattleScript_EffectPerishSong::
|
|||
waitanimation
|
||||
printstring STRINGID_FAINTINTHREE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setbyte sBATTLER, 0
|
||||
setbyte gBattlerTarget, 0
|
||||
BattleScript_PerishSongLoop::
|
||||
jumpifability BS_SCRIPTING, ABILITY_SOUNDPROOF, BattleScript_PerishSongNotAffected
|
||||
jumpifability BS_TARGET, ABILITY_SOUNDPROOF, BattleScript_PerishSongBlocked
|
||||
jumpifpranksterblocked BS_TARGET, BattleScript_PerishSongNotAffected
|
||||
BattleScript_PerishSongLoopIncrement::
|
||||
addbyte sBATTLER, 1
|
||||
jumpifbytenotequal sBATTLER, gBattlersCount, BattleScript_PerishSongLoop
|
||||
addbyte gBattlerTarget, 1
|
||||
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_PerishSongLoop
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_PerishSongNotAffected::
|
||||
BattleScript_PerishSongBlocked::
|
||||
printstring STRINGID_PKMNSXBLOCKSY2
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_PerishSongLoopIncrement
|
||||
|
||||
BattleScript_PerishSongNotAffected:
|
||||
printstring STRINGID_ITDOESNTAFFECT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_PerishSongLoopIncrement
|
||||
|
||||
BattleScript_EffectSandstorm::
|
||||
attackcanceler
|
||||
attackstring
|
||||
|
@ -4905,6 +4912,12 @@ BattleScript_EffectRecoil50:
|
|||
setmoveeffect MOVE_EFFECT_RECOIL_50 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
|
||||
goto BattleScript_EffectHit
|
||||
|
||||
BattleScript_EffectRecoilHP25:
|
||||
setmoveeffect MOVE_EFFECT_RECOIL_HP_25 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
|
||||
jumpifnotmove MOVE_STRUGGLE, BattleScript_EffectHit
|
||||
incrementgamestat GAME_STAT_USED_STRUGGLE
|
||||
goto BattleScript_EffectHit
|
||||
|
||||
BattleScript_EffectTeeterDance::
|
||||
attackcanceler
|
||||
attackstring
|
||||
|
@ -5994,6 +6007,76 @@ BattleScript_PerishBodyActivates::
|
|||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
|
||||
return
|
||||
|
||||
BattleScript_GulpMissileGorging::
|
||||
call BattleScript_AbilityPopUp
|
||||
playanimation BS_ATTACKER, B_ANIM_GULP_MISSILE, NULL
|
||||
waitanimation
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
|
||||
effectivenesssound
|
||||
hitanimation BS_ATTACKER
|
||||
waitstate
|
||||
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_GulpMissileNoDmgGorging
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
tryfaintmon BS_ATTACKER, FALSE, NULL
|
||||
getbattlerfainted BS_ATTACKER
|
||||
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_GulpMissileNoSecondEffectGorging
|
||||
BattleScript_GulpMissileNoDmgGorging:
|
||||
handleformchange BS_TARGET, 0
|
||||
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
|
||||
waitanimation
|
||||
swapattackerwithtarget
|
||||
setmoveeffect MOVE_EFFECT_PARALYSIS
|
||||
seteffectprimary
|
||||
swapattackerwithtarget
|
||||
return
|
||||
BattleScript_GulpMissileNoSecondEffectGorging:
|
||||
handleformchange BS_TARGET, 0
|
||||
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
|
||||
waitanimation
|
||||
return
|
||||
|
||||
BattleScript_GulpMissileGulping::
|
||||
call BattleScript_AbilityPopUp
|
||||
playanimation BS_ATTACKER, B_ANIM_GULP_MISSILE, NULL
|
||||
waitanimation
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000
|
||||
effectivenesssound
|
||||
hitanimation BS_ATTACKER
|
||||
waitstate
|
||||
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_GulpMissileNoDmgGulping
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
tryfaintmon BS_ATTACKER, FALSE, NULL
|
||||
getbattlerfainted BS_ATTACKER
|
||||
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifability BS_ATTACKER, ABILITY_CLEAR_BODY, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifability BS_ATTACKER, ABILITY_FULL_METAL_BODY, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifability BS_ATTACKER, ABILITY_WHITE_SMOKE, BattleScript_GulpMissileNoSecondEffectGulping
|
||||
jumpifflowerveilattacker BattleScript_GulpMissileNoSecondEffectGulping
|
||||
BattleScript_GulpMissileNoDmgGulping:
|
||||
handleformchange BS_TARGET, 0
|
||||
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
|
||||
waitanimation
|
||||
swapattackerwithtarget @ to make gStatDownStringIds down below print the right battler
|
||||
setstatchanger STAT_DEF, 1, TRUE
|
||||
statbuffchange STAT_BUFF_NOT_PROTECT_AFFECTED, BattleScript_GulpMissileGorgingTargetDefenseCantGoLower
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
printfromtable gStatDownStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
swapattackerwithtarget @ restore the battlers, just in case
|
||||
return
|
||||
BattleScript_GulpMissileNoSecondEffectGulping:
|
||||
handleformchange BS_TARGET, 0
|
||||
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
|
||||
waitanimation
|
||||
return
|
||||
BattleScript_GulpMissileGorgingTargetDefenseCantGoLower:
|
||||
printstring STRINGID_STATSWONTDECREASE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
||||
BattleScript_PerishSongCountGoesDown::
|
||||
printstring STRINGID_PKMNPERISHCOUNTFELL
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
|
@ -6328,6 +6411,17 @@ BattleScript_MagicCoatBounce::
|
|||
setmagiccoattarget BS_ATTACKER
|
||||
return
|
||||
|
||||
BattleScript_MagicCoatBouncePrankster::
|
||||
attackstring
|
||||
ppreduce
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printfromtable gMagicCoatBounceStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
printstring STRINGID_ITDOESNTAFFECT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_SnatchedMove::
|
||||
attackstring
|
||||
ppreduce
|
||||
|
@ -7624,6 +7718,19 @@ BattleScript_AbilityStatusEffect::
|
|||
seteffectsecondary
|
||||
return
|
||||
|
||||
BattleScript_BattleBondActivatesOnMoveEndAttacker::
|
||||
pause 5
|
||||
copybyte gBattlerAbility, gBattlerAttacker
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_ATTACKERBECAMEFULLYCHARGED
|
||||
handleformchange BS_ATTACKER, 0
|
||||
handleformchange BS_ATTACKER, 1
|
||||
playanimation BS_ATTACKER, B_ANIM_FORM_CHANGE, NULL
|
||||
waitanimation
|
||||
handleformchange BS_ATTACKER, 2
|
||||
printstring STRINGID_ATTACKERBECAMEASHSPECIES
|
||||
return
|
||||
|
||||
BattleScript_DancerActivates::
|
||||
call BattleScript_AbilityPopUp
|
||||
waitmessage B_WAIT_TIME_SHORT
|
||||
|
@ -8310,3 +8417,12 @@ BattleScript_EjectPackActivate_End2::
|
|||
BattleScript_EjectPackActivates::
|
||||
jumpifcantswitch BS_SCRIPTING, BattleScript_EjectButtonEnd
|
||||
goto BattleScript_EjectPackActivate_Ret
|
||||
|
||||
BattleScript_DarkTypePreventsPrankster::
|
||||
attackstring
|
||||
ppreduce
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_ITDOESNTAFFECT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
|
||||
goto BattleScript_MoveEnd
|
||||
|
|
|
@ -150,6 +150,7 @@ struct ProtectStruct
|
|||
u32 touchedProtectLike:1;
|
||||
u32 disableEjectPack:1;
|
||||
u32 statFell:1;
|
||||
u32 pranksterElevated:1;
|
||||
u32 physicalDmg;
|
||||
u32 specialDmg;
|
||||
u8 physicalBattlerId;
|
||||
|
|
|
@ -97,6 +97,7 @@ extern const u8 BattleScript_SelectingImprisonedMove[];
|
|||
extern const u8 BattleScript_SelectingImprisonedMoveInPalace[];
|
||||
extern const u8 BattleScript_GrudgeTakesPp[];
|
||||
extern const u8 BattleScript_MagicCoatBounce[];
|
||||
extern const u8 BattleScript_MagicCoatBouncePrankster[];
|
||||
extern const u8 BattleScript_SnatchedMove[];
|
||||
extern const u8 BattleScript_EnduredMsg[];
|
||||
extern const u8 BattleScript_OneHitKOMsg[];
|
||||
|
@ -384,5 +385,9 @@ extern const u8 BattleScript_MentalHerbCureEnd2[];
|
|||
extern const u8 BattleScript_TerrainPreventsEnd2[];
|
||||
extern const u8 BattleScript_MistyTerrainPrevents[];
|
||||
extern const u8 BattleScript_ElectricTerrainPrevents[];
|
||||
extern const u8 BattleScript_DarkTypePreventsPrankster[];
|
||||
extern const u8 BattleScript_GulpMissileGorging[];
|
||||
extern const u8 BattleScript_GulpMissileGulping[];
|
||||
extern const u8 BattleScript_BattleBondActivatesOnMoveEndAttacker[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
|
|
@ -153,6 +153,7 @@ bool32 CompareStat(u8 battlerId, u8 statId, u8 cmpTo, u8 cmpKind);
|
|||
bool32 TryRoomService(u8 battlerId);
|
||||
void BufferStatChange(u8 battlerId, u8 statId, u8 stringId);
|
||||
void DoBurmyFormChange(u32 monId);
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef);
|
||||
|
||||
// ability checks
|
||||
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
|
||||
|
|
|
@ -347,7 +347,8 @@
|
|||
#define MOVE_EFFECT_THROAT_CHOP 0x43
|
||||
#define MOVE_EFFECT_INCINERATE 0x44
|
||||
#define MOVE_EFFECT_BUG_BITE 0x45
|
||||
#define NUM_MOVE_EFFECTS 0x46
|
||||
#define MOVE_EFFECT_RECOIL_HP_25 0x46
|
||||
#define NUM_MOVE_EFFECTS 0x47
|
||||
|
||||
#define MOVE_EFFECT_AFFECTS_USER 0x4000
|
||||
#define MOVE_EFFECT_CERTAIN 0x8000
|
||||
|
|
|
@ -523,6 +523,7 @@
|
|||
#define B_ANIM_SLIDE_OFFSCREEN 26 // for Emergency Exit
|
||||
#define B_ANIM_RESTORE_BG 27 // for Terrain Endings
|
||||
#define B_ANIM_TOTEM_FLARE 28 // Totem boosts aura flare
|
||||
#define B_ANIM_GULP_MISSILE 29
|
||||
|
||||
// special animations table (gBattleAnims_Special)
|
||||
#define B_ANIM_LVL_UP 0
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
#define SPECIES_BURMY 0
|
||||
#define SPECIES_BURMY_SANDY_CLOAK 10013
|
||||
#define SPECIES_BURMY_TRASH_CLOAK 10014
|
||||
#define SPECIES_CRAMORANT 0
|
||||
#define SPECIES_CRAMORANT_GORGING 10015
|
||||
#define SPECIES_CRAMORANT_GULPING 10016
|
||||
#define SPECIES_GRENINJA_BATTLE_BOND 0
|
||||
#define SPECIES_GRENINJA_ASH 10017
|
||||
#endif
|
||||
|
||||
// Items with peculiar battle effects.
|
||||
|
@ -124,10 +129,12 @@
|
|||
#define B_GALE_WINGS GEN_7 // In Gen7+ requires full HP to trigger.
|
||||
#define B_STANCE_CHANGE_FAIL GEN_7 // In Gen7+, Stance Change fails if the Pokémon is unable to use a move because of confusion, paralysis, etc. In Gen6, it doesn't.
|
||||
#define B_GHOSTS_ESCAPE GEN_7 // In Gen6+, Ghost-type Pokémon can escape even when blocked by abilities such as Shadow Tag.
|
||||
#define B_SHADOW_TAG_ESCAPE GEN_7 // In Gen4+, if both sides have a Pokémon with Shadow Tag, all battlers can escape. Before, neither side could escape this situation.
|
||||
#define B_MOODY_ACC_EVASION GEN_8 // In Gen8, Moody CANNOT raise Accuracy and Evasion anymore.
|
||||
#define B_FLASH_FIRE_FROZEN GEN_7 // In Gen5+, Flash Fire can trigger even when frozen, when it couldn't before.
|
||||
#define B_SYNCHRONIZE_NATURE GEN_8 // In Gen8, if the Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same ability, as opposed to 50% previously.
|
||||
#define B_UPDATED_INTIMIDATE GEN_8 // In Gen8, Intimidate doesn't work on opponents with the Inner Focus, Scrappy, Own Tempo or Oblivious abilities.
|
||||
#define B_PRANKSTER_DARK_TYPES GEN_7 // In Gen7+, Prankster-elevated status moves do not affect Dark type Pokémon.
|
||||
|
||||
// Item settings
|
||||
#define B_HP_BERRIES GEN_7 // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.
|
||||
|
|
|
@ -236,7 +236,7 @@
|
|||
#define EFFECT_ROUND 230
|
||||
#define EFFECT_BRINE 231
|
||||
#define EFFECT_VENOSHOCK 232
|
||||
#define EFFECT_RETALITATE 233
|
||||
#define EFFECT_RETALIATE 233
|
||||
#define EFFECT_BULLDOZE 234
|
||||
#define EFFECT_FOUL_PLAY 235
|
||||
#define EFFECT_PSYSHOCK 236
|
||||
|
@ -363,7 +363,8 @@
|
|||
#define EFFECT_DECORATE 357
|
||||
#define EFFECT_SNIPE_SHOT 358
|
||||
#define EFFECT_TRIPLE_HIT 359
|
||||
#define EFFECT_RECOIL_HP_25 360
|
||||
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 360
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 361
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
|
||||
|
|
|
@ -183,6 +183,7 @@
|
|||
#define VARIOUS_JUMP_IF_TEAM_HEALTHY 111
|
||||
#define VARIOUS_TRY_HEAL_QUARTER_HP 112
|
||||
#define VARIOUS_REMOVE_TERRAIN 113
|
||||
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
|
|
@ -578,8 +578,10 @@
|
|||
#define STRINGID_ATKGOTOVERINFATUATION 574
|
||||
#define STRINGID_TORMENTEDNOMORE 575
|
||||
#define STRINGID_HEALBLOCKEDNOMORE 576
|
||||
#define STRINGID_ATTACKERBECAMEFULLYCHARGED 577
|
||||
#define STRINGID_ATTACKERBECAMEASHSPECIES 578
|
||||
|
||||
#define BATTLESTRINGS_COUNT 577
|
||||
#define BATTLESTRINGS_COUNT 579
|
||||
|
||||
// The below IDs are all indexes into battle message tables,
|
||||
// used to determine which of a set of messages to print.
|
||||
|
|
|
@ -520,6 +520,9 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||
u32 i;
|
||||
u16 predictedMove = gLastMoves[battlerDef]; // TODO better move prediction
|
||||
|
||||
SetTypeBeforeUsingMove(move, battlerAtk);
|
||||
GET_MOVE_TYPE(move, moveType);
|
||||
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||
return score;
|
||||
|
||||
|
@ -2472,7 +2475,10 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||
bool32 attackerHasBadAbility = (GetAbilityRating(AI_DATA->atkAbility) < 0);
|
||||
bool32 partnerHasBadAbility = (GetAbilityRating(atkPartnerAbility) < 0);
|
||||
u16 predictedMove = gLastMoves[battlerDef]; //for now
|
||||
|
||||
|
||||
SetTypeBeforeUsingMove(move, battlerAtk);
|
||||
GET_MOVE_TYPE(move, moveType);
|
||||
|
||||
// check what effect partner is using
|
||||
if (AI_DATA->partnerMove != 0)
|
||||
{
|
||||
|
@ -4751,7 +4757,10 @@ static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
|||
{
|
||||
u16 effect = gBattleMoves[move].effect;
|
||||
u8 moveType = gBattleMoves[move].type;
|
||||
|
||||
|
||||
SetTypeBeforeUsingMove(move, battlerAtk);
|
||||
GET_MOVE_TYPE(move, moveType);
|
||||
|
||||
if (IsTargetingPartner(battlerAtk, battlerDef))
|
||||
{
|
||||
if ((effect == EFFECT_HEAL_PULSE || effect == EFFECT_HIT_ENEMY_HEAL_ALLY)
|
||||
|
|
|
@ -2213,6 +2213,7 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo
|
|||
case B_ANIM_DOOM_DESIRE_HIT:
|
||||
case B_ANIM_WISH_HEAL:
|
||||
case B_ANIM_MEGA_EVOLUTION:
|
||||
case B_ANIM_GULP_MISSILE:
|
||||
hideHpBoxes = TRUE;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1053,6 +1053,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
|
|||
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])
|
||||
{
|
||||
objVram = ConvertIntToDecimalStringN(text, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
|
||||
xPos = 5 * (3 - (objVram - (text + 2))) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1060,6 +1061,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
|
|||
text[1] = CHAR_LV_2;
|
||||
|
||||
objVram = ConvertIntToDecimalStringN(text + 2, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
|
||||
xPos = 5 * (3 - (objVram - (text + 2)));
|
||||
}
|
||||
|
||||
xPos = 5 * (3 - (objVram - (text + 2)));
|
||||
|
@ -1507,18 +1509,12 @@ void DestroyMegaTriggerSprite(void)
|
|||
gBattleStruct->mega.triggerSpriteId = 0xFF;
|
||||
}
|
||||
|
||||
static const s8 sIndicatorPosSingles[][2] =
|
||||
static const s8 sIndicatorPositions[][2] =
|
||||
{
|
||||
[B_POSITION_PLAYER_LEFT] = {53, -8},
|
||||
[B_POSITION_OPPONENT_LEFT] = {45, -8},
|
||||
};
|
||||
|
||||
static const s8 sIndicatorPosDoubles[][2] =
|
||||
{
|
||||
[B_POSITION_PLAYER_LEFT] = {53, -8},
|
||||
[B_POSITION_OPPONENT_LEFT] = {45, -8},
|
||||
[B_POSITION_PLAYER_RIGHT] = {53, -8},
|
||||
[B_POSITION_OPPONENT_RIGHT] = {45, -8},
|
||||
[B_POSITION_PLAYER_LEFT] = {52, -9},
|
||||
[B_POSITION_OPPONENT_LEFT] = {44, -9},
|
||||
[B_POSITION_PLAYER_RIGHT] = {52, -9},
|
||||
[B_POSITION_OPPONENT_RIGHT] = {44, -9},
|
||||
};
|
||||
|
||||
u32 CreateMegaIndicatorSprite(u32 battlerId, u32 which)
|
||||
|
@ -1531,16 +1527,15 @@ u32 CreateMegaIndicatorSprite(u32 battlerId, u32 which)
|
|||
|
||||
position = GetBattlerPosition(battlerId);
|
||||
GetBattlerHealthboxCoords(battlerId, &x, &y);
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
x += sIndicatorPosDoubles[position][0];
|
||||
y += sIndicatorPosDoubles[position][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
x += sIndicatorPosSingles[position][0];
|
||||
y += sIndicatorPosSingles[position][1];
|
||||
}
|
||||
|
||||
x += sIndicatorPositions[position][0];
|
||||
y += sIndicatorPositions[position][1];
|
||||
|
||||
if (gBattleMons[battlerId].level >= 100)
|
||||
x -= 4;
|
||||
else if (gBattleMons[battlerId].level < 10)
|
||||
x += 5;
|
||||
|
||||
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_MegaIndicator, x, y, 0);
|
||||
gSprites[gSprites[gHealthboxSpriteIds[battlerId]].oam.affineParam].hOther_IndicatorSpriteId = spriteId;
|
||||
|
||||
|
|
|
@ -3096,6 +3096,7 @@ void FaintClearSetData(void)
|
|||
gProtectStructs[gActiveBattler].usedGravityPreventedMove = 0;
|
||||
gProtectStructs[gActiveBattler].usedThroatChopPreventedMove = 0;
|
||||
gProtectStructs[gActiveBattler].statRaised = 0;
|
||||
gProtectStructs[gActiveBattler].statFell = 0;
|
||||
|
||||
gDisableStructs[gActiveBattler].isFirstTurn = 2;
|
||||
|
||||
|
@ -3466,10 +3467,13 @@ static void TryDoEventsBeforeFirstTurn(void)
|
|||
return;
|
||||
|
||||
// Set invalid mons as absent(for example when starting a double battle with only one pokemon).
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI))
|
||||
{
|
||||
if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE)
|
||||
gAbsentBattlerFlags |= gBitTable[i];
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE)
|
||||
gAbsentBattlerFlags |= gBitTable[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (gBattleStruct->switchInAbilitiesCounter == 0)
|
||||
|
@ -3683,7 +3687,7 @@ u8 IsRunningFromBattleImpossible(void)
|
|||
return 0;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||||
return 0;
|
||||
if (gBattleMons[gActiveBattler].ability == ABILITY_RUN_AWAY)
|
||||
if (GetBattlerAbility(gActiveBattler) == ABILITY_RUN_AWAY)
|
||||
return 0;
|
||||
|
||||
if ((i = IsAbilityPreventingEscape(gActiveBattler)))
|
||||
|
@ -4315,6 +4319,7 @@ s8 GetChosenMovePriority(u32 battlerId)
|
|||
{
|
||||
u16 move;
|
||||
|
||||
gProtectStructs[battlerId].pranksterElevated = 0;
|
||||
if (gProtectStructs[battlerId].noValidMoves)
|
||||
move = MOVE_STRUGGLE;
|
||||
else
|
||||
|
@ -4336,6 +4341,7 @@ s8 GetMovePriority(u32 battlerId, u16 move)
|
|||
}
|
||||
else if (GetBattlerAbility(battlerId) == ABILITY_PRANKSTER && IS_MOVE_STATUS(move))
|
||||
{
|
||||
gProtectStructs[battlerId].pranksterElevated = 1;
|
||||
priority++;
|
||||
}
|
||||
else if (gBattleMoves[move].effect == EFFECT_GRASSY_GLIDE && gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerGrounded(battlerId))
|
||||
|
|
|
@ -704,10 +704,13 @@ static const u8 sText_EjectButtonActivate[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}
|
|||
static const u8 sText_AttackerGotOverInfatuation[] =_("{B_ATK_NAME_WITH_PREFIX} got over\nits infatuation!");
|
||||
static const u8 sText_TormentedNoMore[] = _("{B_ATK_NAME_WITH_PREFIX} is\ntormented no more!");
|
||||
static const u8 sText_HealBlockedNoMore[] = _("{B_ATK_NAME_WITH_PREFIX} is cured of\nits heal block!");
|
||||
|
||||
static const u8 sText_AttackerBecameFullyCharged[] = _("{B_ATK_NAME_WITH_PREFIX} became fully charged\ndue to its bond with its trainer!\p");
|
||||
static const u8 sText_AttackerBecameAshSpecies[] = _("{B_ATK_NAME_WITH_PREFIX} became Ash-{B_BUFF1}!\p");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_ATTACKERBECAMEASHSPECIES - 12] = sText_AttackerBecameAshSpecies,
|
||||
[STRINGID_ATTACKERBECAMEFULLYCHARGED - 12] = sText_AttackerBecameFullyCharged,
|
||||
[STRINGID_HEALBLOCKEDNOMORE - 12] = sText_HealBlockedNoMore,
|
||||
[STRINGID_TORMENTEDNOMORE - 12] = sText_TormentedNoMore,
|
||||
[STRINGID_ATKGOTOVERINFATUATION - 12] = sText_AttackerGotOverInfatuation,
|
||||
|
|
|
@ -1416,8 +1416,17 @@ static void Cmd_attackcanceler(void)
|
|||
gProtectStructs[gBattlerTarget].bounceMove = 0;
|
||||
gProtectStructs[gBattlerTarget].usesBouncedMove = 1;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce;
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker))
|
||||
{
|
||||
// Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker
|
||||
gBattlerTarget = gBattlerAttacker;
|
||||
gBattlescriptCurrInstr = BattleScript_MagicCoatBouncePrankster;
|
||||
}
|
||||
else
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_MagicCoatBounce;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE
|
||||
|
@ -3058,7 +3067,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
|
|||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
else if (gBattleMons[gBattlerTarget].item
|
||||
&& gBattleMons[gBattlerTarget].ability == ABILITY_STICKY_HOLD)
|
||||
&& GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD)
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_NoItemSteal;
|
||||
|
@ -3168,6 +3177,14 @@ void SetMoveEffect(bool32 primary, u32 certain)
|
|||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoilWithStatus;
|
||||
break;
|
||||
case MOVE_EFFECT_RECOIL_HP_25: // Struggle
|
||||
gBattleMoveDamage = (gBattleMons[gEffectBattler].maxHP) / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
|
||||
break;
|
||||
case MOVE_EFFECT_THRASH:
|
||||
if (gBattleMons[gEffectBattler].status2 & STATUS2_LOCK_CONFUSE)
|
||||
{
|
||||
|
@ -5092,6 +5109,7 @@ static void Cmd_moveend(void)
|
|||
MoveValuesCleanUp();
|
||||
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
|
||||
BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]);
|
||||
gBattleStruct->atkCancellerTracker = 0; // Run all cancellers on next target
|
||||
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
|
||||
return;
|
||||
}
|
||||
|
@ -5183,6 +5201,7 @@ static void Cmd_moveend(void)
|
|||
u8 battler = battlers[i];
|
||||
if (IsBattlerAlive(battler)
|
||||
&& gProtectStructs[battler].statFell
|
||||
&& gProtectStructs[battler].disableEjectPack == 0
|
||||
&& GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_EJECT_PACK
|
||||
&& !(gCurrentMove == MOVE_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker)) // Does not activate if attacker used Parting Shot and can switch out
|
||||
&& CountUsablePartyMons(battler) > 0) // Has mon to switch into
|
||||
|
@ -6573,6 +6592,7 @@ static void Cmd_jumptocalledmove(void)
|
|||
else
|
||||
gChosenMove = gCurrentMove = gCalledMove;
|
||||
|
||||
gBattleStruct->atkCancellerTracker = 0;
|
||||
gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
|
||||
}
|
||||
|
||||
|
@ -7273,7 +7293,7 @@ u32 IsLeafGuardProtected(u32 battler)
|
|||
bool32 IsShieldsDownProtected(u32 battler)
|
||||
{
|
||||
return (gBattleMons[battler].ability == ABILITY_SHIELDS_DOWN
|
||||
&& gBattleMons[battler].species == SPECIES_MINIOR);
|
||||
&& GetFormIdFromFormSpeciesId(gBattleMons[battler].species) < GetFormIdFromFormSpeciesId(SPECIES_MINIOR_CORE_RED)); // Minior is not in core form
|
||||
}
|
||||
|
||||
u32 IsAbilityStatusProtected(u32 battler)
|
||||
|
@ -7898,15 +7918,15 @@ static void Cmd_various(void)
|
|||
gBattlescriptCurrInstr += 7;
|
||||
return;
|
||||
case VARIOUS_SET_SIMPLE_BEAM:
|
||||
if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gActiveBattler].ability))
|
||||
if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)
|
||||
|| gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE)
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleMons[gActiveBattler].ability = ABILITY_SIMPLE;
|
||||
gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE;
|
||||
gBattlescriptCurrInstr += 7;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case VARIOUS_TRY_ENTRAINMENT:
|
||||
|
@ -8127,7 +8147,8 @@ static void Cmd_various(void)
|
|||
// Change species.
|
||||
if (gBattlescriptCurrInstr[3] == 0)
|
||||
{
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
|
||||
if (!gBattleTextBuff1)
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
|
||||
BtlController_EmitSetMonData(0, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], 2, &gBattleMons[gActiveBattler].species);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
}
|
||||
|
@ -8721,6 +8742,12 @@ static void Cmd_various(void)
|
|||
}
|
||||
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain
|
||||
break;
|
||||
case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED:
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler))
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
else
|
||||
gBattlescriptCurrInstr += 7;
|
||||
return;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr += 3;
|
||||
|
@ -9103,7 +9130,7 @@ bool8 UproarWakeUpCheck(u8 battlerId)
|
|||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[battlerId].ability == ABILITY_SOUNDPROOF)
|
||||
if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || GetBattlerAbility(battlerId) == ABILITY_SOUNDPROOF)
|
||||
continue;
|
||||
|
||||
gBattleScripting.battler = i;
|
||||
|
@ -9425,9 +9452,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
|
|||
}
|
||||
else
|
||||
{
|
||||
// Check eject pack. disableEjectPack set for edge cases (e.g. attacking weak armor'd eject pack holder with u-turn)
|
||||
if (gProtectStructs[gActiveBattler].disableEjectPack == 0)
|
||||
gProtectStructs[gActiveBattler].statFell = 1;
|
||||
gProtectStructs[gActiveBattler].statFell = 1; // Eject pack, lash out
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = (gBattlerTarget == gActiveBattler); // B_MSG_ATTACKER_STAT_FELL or B_MSG_DEFENDER_STAT_FELL
|
||||
}
|
||||
}
|
||||
|
@ -10754,7 +10779,7 @@ static void Cmd_healpartystatus(void)
|
|||
else
|
||||
party = gEnemyParty;
|
||||
|
||||
if (gBattleMons[gBattlerAttacker].ability != ABILITY_SOUNDPROOF)
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF)
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status1 = 0;
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~(STATUS2_NIGHTMARE);
|
||||
|
@ -10770,7 +10795,7 @@ static void Cmd_healpartystatus(void)
|
|||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& !(gAbsentBattlerFlags & gBitTable[gActiveBattler]))
|
||||
{
|
||||
if (gBattleMons[gActiveBattler].ability != ABILITY_SOUNDPROOF)
|
||||
if (GetBattlerAbility(gActiveBattler) != ABILITY_SOUNDPROOF)
|
||||
{
|
||||
gBattleMons[gActiveBattler].status1 = 0;
|
||||
gBattleMons[gActiveBattler].status2 &= ~(STATUS2_NIGHTMARE);
|
||||
|
@ -10883,7 +10908,8 @@ static void Cmd_trysetperishsong(void)
|
|||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gStatuses3[i] & STATUS3_PERISH_SONG
|
||||
|| gBattleMons[i].ability == ABILITY_SOUNDPROOF)
|
||||
|| GetBattlerAbility(i) == ABILITY_SOUNDPROOF
|
||||
|| BlocksPrankster(gCurrentMove, gBattlerAttacker, i))
|
||||
{
|
||||
notAffectedCount++;
|
||||
}
|
||||
|
@ -11598,7 +11624,7 @@ static void Cmd_tryswapitems(void) // trick
|
|||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
}
|
||||
// check if ability prevents swapping
|
||||
else if (gBattleMons[gBattlerTarget].ability == ABILITY_STICKY_HOLD)
|
||||
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates;
|
||||
gLastUsedAbility = gBattleMons[gBattlerTarget].ability;
|
||||
|
|
|
@ -994,6 +994,11 @@ static const u8 sAbilitiesAffectedByMoldBreaker[] =
|
|||
[ABILITY_FLUFFY] = 1,
|
||||
[ABILITY_QUEENLY_MAJESTY] = 1,
|
||||
[ABILITY_WATER_BUBBLE] = 1,
|
||||
[ABILITY_MIRROR_ARMOR] = 1,
|
||||
[ABILITY_PUNK_ROCK] = 1,
|
||||
[ABILITY_ICE_SCALES] = 1,
|
||||
[ABILITY_ICE_FACE] = 1,
|
||||
[ABILITY_PASTEL_VEIL] = 1,
|
||||
};
|
||||
|
||||
static const u8 sAbilitiesNotTraced[ABILITIES_COUNT] =
|
||||
|
@ -1274,7 +1279,7 @@ void PressurePPLose(u8 target, u8 attacker, u16 move)
|
|||
{
|
||||
int moveIndex;
|
||||
|
||||
if (gBattleMons[target].ability != ABILITY_PRESSURE)
|
||||
if (GetBattlerAbility(target) != ABILITY_PRESSURE)
|
||||
return;
|
||||
|
||||
for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
|
||||
|
@ -1306,7 +1311,7 @@ void PressurePPLoseOnUsingImprison(u8 attacker)
|
|||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (atkSide != GetBattlerSide(i) && gBattleMons[i].ability == ABILITY_PRESSURE)
|
||||
if (atkSide != GetBattlerSide(i) && GetBattlerAbility(i) == ABILITY_PRESSURE)
|
||||
{
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
|
@ -1339,7 +1344,7 @@ void PressurePPLoseOnUsingPerishSong(u8 attacker)
|
|||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].ability == ABILITY_PRESSURE && i != attacker)
|
||||
if (GetBattlerAbility(i) == ABILITY_PRESSURE && i != attacker)
|
||||
{
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
|
@ -2734,8 +2739,8 @@ u8 DoBattlerEndTurnEffects(void)
|
|||
{
|
||||
gStatuses3[gActiveBattler] -= STATUS3_YAWN_TURN(1);
|
||||
if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)
|
||||
&& gBattleMons[gActiveBattler].ability != ABILITY_VITAL_SPIRIT
|
||||
&& gBattleMons[gActiveBattler].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)
|
||||
&& GetBattlerAbility(gActiveBattler) != ABILITY_VITAL_SPIRIT
|
||||
&& GetBattlerAbility(gActiveBattler) != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)
|
||||
&& !IsLeafGuardProtected(gActiveBattler))
|
||||
{
|
||||
CancelMultiTurnMoves(gActiveBattler);
|
||||
|
@ -3098,6 +3103,7 @@ enum
|
|||
CANCELLER_POWDER_MOVE,
|
||||
CANCELLER_POWDER_STATUS,
|
||||
CANCELLER_THROAT_CHOP,
|
||||
CANCELLER_PRANKSTER,
|
||||
CANCELLER_END,
|
||||
CANCELLER_PSYCHIC_TERRAIN,
|
||||
CANCELLER_END2,
|
||||
|
@ -3131,7 +3137,7 @@ u8 AtkCanceller_UnableToUseMove(void)
|
|||
else
|
||||
{
|
||||
u8 toSub;
|
||||
if (gBattleMons[gBattlerAttacker].ability == ABILITY_EARLY_BIRD)
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_EARLY_BIRD)
|
||||
toSub = 2;
|
||||
else
|
||||
toSub = 1;
|
||||
|
@ -3141,7 +3147,7 @@ u8 AtkCanceller_UnableToUseMove(void)
|
|||
gBattleMons[gBattlerAttacker].status1 -= toSub;
|
||||
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
|
||||
{
|
||||
if (gCurrentMove != MOVE_SNORE && gCurrentMove != MOVE_SLEEP_TALK)
|
||||
if (gChosenMove != MOVE_SNORE && gChosenMove != MOVE_SLEEP_TALK)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
|
||||
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||||
|
@ -3425,6 +3431,18 @@ u8 AtkCanceller_UnableToUseMove(void)
|
|||
}
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_PRANKSTER:
|
||||
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gBattlerTarget)
|
||||
&& !(IS_MOVE_STATUS(gCurrentMove) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE))
|
||||
{
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
|
||||
CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected
|
||||
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
|
||||
gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster;
|
||||
effect = 1;
|
||||
}
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_END:
|
||||
break;
|
||||
}
|
||||
|
@ -3728,6 +3746,8 @@ static bool32 ShouldChangeFormHpBased(u32 battler)
|
|||
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET, 2},
|
||||
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW, 2},
|
||||
{ABILITY_SCHOOLING, SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, 4},
|
||||
{ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GORGING, 2},
|
||||
{ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GULPING, 1},
|
||||
};
|
||||
u32 i;
|
||||
|
||||
|
@ -4980,6 +5000,42 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
|||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_GULP_MISSILE:
|
||||
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
|
||||
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
|
||||
&& TARGET_TURN_DAMAGED
|
||||
&& IsBattlerAlive(battler))
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GORGING)
|
||||
{
|
||||
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerTarget]] = gBattleMons[gBattlerTarget].species;
|
||||
gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT;
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
}
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_GulpMissileGorging;
|
||||
effect++;
|
||||
}
|
||||
else if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GULPING)
|
||||
{
|
||||
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerTarget]] = gBattleMons[gBattlerTarget].species;
|
||||
gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT;
|
||||
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 4;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
}
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_GulpMissileGulping;
|
||||
effect++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_MOVE_END_ATTACKER: // Same as above, but for attacker
|
||||
|
@ -5016,6 +5072,27 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
|||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_GULP_MISSILE:
|
||||
if (((gCurrentMove == MOVE_SURF && TARGET_TURN_DAMAGED) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER)
|
||||
&& (effect = ShouldChangeFormHpBased(gBattlerAttacker)))
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_AttackerFormChange;
|
||||
effect++;
|
||||
}
|
||||
break;
|
||||
case ABILITY_BATTLE_BOND:
|
||||
if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND
|
||||
&& gBattleResults.opponentFaintCounter != 0
|
||||
&& CalculateEnemyPartyCount() > 1)
|
||||
{
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species);
|
||||
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
|
||||
gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_MOVE_END_OTHER: // Abilities that activate on *another* battler's moveend: Dancer, Soul-Heart, Receiver, Symbiosis
|
||||
|
@ -5338,11 +5415,15 @@ u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability)
|
|||
u32 IsAbilityPreventingEscape(u32 battlerId)
|
||||
{
|
||||
u32 id;
|
||||
|
||||
if (B_GHOSTS_ESCAPE >= GEN_6 && IS_BATTLER_OF_TYPE(battlerId, TYPE_GHOST))
|
||||
return 0;
|
||||
|
||||
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && gBattleMons[battlerId].ability != ABILITY_SHADOW_TAG)
|
||||
#if B_GHOSTS_ESCAPE >= GEN_6
|
||||
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_GHOST))
|
||||
return 0;
|
||||
#endif
|
||||
#if B_SHADOW_TAG_ESCAPE >= GEN_4
|
||||
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG)) && gBattleMons[battlerId].ability != ABILITY_SHADOW_TAG)
|
||||
#else
|
||||
if (id = IsAbilityOnOpposingSide(battlerId, ABILITY_SHADOW_TAG))
|
||||
#endif
|
||||
return id;
|
||||
if ((id = IsAbilityOnOpposingSide(battlerId, ABILITY_ARENA_TRAP)) && IsBattlerGrounded(battlerId))
|
||||
return id;
|
||||
|
@ -6009,6 +6090,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
|
|||
break;
|
||||
case HOLD_EFFECT_EJECT_PACK:
|
||||
if (gProtectStructs[battlerId].statFell
|
||||
&& gProtectStructs[battlerId].disableEjectPack == 0
|
||||
&& !(gCurrentMove == MOVE_PARTING_SHOT && CanBattlerSwitch(gBattlerAttacker))) // Does not activate if attacker used Parting Shot and can switch out
|
||||
{
|
||||
gProtectStructs[battlerId].statFell = FALSE;
|
||||
|
@ -6117,7 +6199,20 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
|
|||
break;
|
||||
case HOLD_EFFECT_BLACK_SLUDGE:
|
||||
if (IS_BATTLER_OF_TYPE(battlerId, TYPE_POISON))
|
||||
{
|
||||
goto LEFTOVERS;
|
||||
}
|
||||
else if (GetBattlerAbility(battlerId) != ABILITY_MAGIC_GUARD && !moveTurn)
|
||||
{
|
||||
gBattleMoveDamage = gBattleMons[battlerId].maxHP / 8;
|
||||
if (gBattleMoveDamage == 0)
|
||||
gBattleMoveDamage = 1;
|
||||
BattleScriptExecute(BattleScript_ItemHurtEnd2);
|
||||
effect = ITEM_HP_CHANGE;
|
||||
RecordItemEffectBattle(battlerId, battlerHoldEffect);
|
||||
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem);
|
||||
}
|
||||
break;
|
||||
case HOLD_EFFECT_LEFTOVERS:
|
||||
LEFTOVERS:
|
||||
if (gBattleMons[battlerId].hp < gBattleMons[battlerId].maxHP && !moveTurn)
|
||||
|
@ -6847,7 +6942,11 @@ u8 GetMoveTarget(u16 move, u8 setTarget)
|
|||
moveTarget = setTarget - 1;
|
||||
else
|
||||
moveTarget = gBattleMoves[move].target;
|
||||
|
||||
|
||||
// Special cases
|
||||
if (move == MOVE_CURSE && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
|
||||
moveTarget = MOVE_TARGET_USER;
|
||||
|
||||
switch (moveTarget)
|
||||
{
|
||||
case MOVE_TARGET_SELECTED:
|
||||
|
@ -7238,7 +7337,7 @@ static const u16 sWeightToDamageTable[] =
|
|||
};
|
||||
|
||||
static const u8 sSpeedDiffPowerTable[] = {40, 60, 80, 120, 150};
|
||||
static const u8 sHeatCrushPowerTable[] = {40, 40, 60, 80, 100, 120};
|
||||
static const u8 sHeatCrashPowerTable[] = {40, 40, 60, 80, 100, 120};
|
||||
static const u8 sTrumpCardPowerTable[] = {200, 80, 60, 50, 40};
|
||||
|
||||
const struct TypePower gNaturalGiftTable[] =
|
||||
|
@ -7410,7 +7509,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
|||
if (gBattleMons[battlerAtk].pp[i] >= ARRAY_COUNT(sTrumpCardPowerTable))
|
||||
basePower = sTrumpCardPowerTable[ARRAY_COUNT(sTrumpCardPowerTable) - 1];
|
||||
else
|
||||
basePower = sTrumpCardPowerTable[i];
|
||||
basePower = sTrumpCardPowerTable[gBattleMons[battlerAtk].pp[i]];
|
||||
}
|
||||
break;
|
||||
case EFFECT_ACROBATICS:
|
||||
|
@ -7433,10 +7532,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
|||
break;
|
||||
case EFFECT_HEAT_CRASH:
|
||||
weight = GetBattlerWeight(battlerAtk) / GetBattlerWeight(battlerDef);
|
||||
if (weight >= ARRAY_COUNT(sHeatCrushPowerTable))
|
||||
basePower = sHeatCrushPowerTable[ARRAY_COUNT(sHeatCrushPowerTable) - 1];
|
||||
if (weight >= ARRAY_COUNT(sHeatCrashPowerTable))
|
||||
basePower = sHeatCrashPowerTable[ARRAY_COUNT(sHeatCrashPowerTable) - 1];
|
||||
else
|
||||
basePower = sHeatCrushPowerTable[i];
|
||||
basePower = sHeatCrashPowerTable[i];
|
||||
break;
|
||||
case EFFECT_PUNISHMENT:
|
||||
basePower = 60 + (CountBattlerStatIncreases(battlerDef, FALSE) * 20);
|
||||
|
@ -7495,6 +7594,15 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
|||
break;
|
||||
}
|
||||
|
||||
// move-specific base power changes
|
||||
switch (move)
|
||||
{
|
||||
case MOVE_WATER_SHURIKEN:
|
||||
if (gBattleMons[battlerAtk].species == SPECIES_GRENINJA_ASH)
|
||||
basePower = 20;
|
||||
break;
|
||||
}
|
||||
|
||||
if (basePower == 0)
|
||||
basePower = 1;
|
||||
return basePower;
|
||||
|
@ -7758,7 +7866,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
|||
if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)
|
||||
MulModifier(&modifier, UQ_4_12(2.0));
|
||||
break;
|
||||
case EFFECT_RETALITATE:
|
||||
case EFFECT_RETALIATE:
|
||||
// todo
|
||||
break;
|
||||
case EFFECT_SOLARBEAM:
|
||||
|
@ -8136,6 +8244,7 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
|||
u32 abilityDef = GetBattlerAbility(battlerDef);
|
||||
u32 defSide = GET_BATTLER_SIDE(battlerDef);
|
||||
u16 finalModifier = UQ_4_12(1.0);
|
||||
u16 itemDef = gBattleMons[battlerDef].item;
|
||||
|
||||
// check multiple targets in double battle
|
||||
if (GetMoveTargetCount(move, battlerAtk, battlerDef) >= 2)
|
||||
|
@ -8256,7 +8365,8 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
|||
// berries reducing dmg
|
||||
case HOLD_EFFECT_RESIST_BERRY:
|
||||
if (moveType == GetBattlerHoldEffectParam(battlerDef)
|
||||
&& (moveType == TYPE_NORMAL || typeEffectivenessModifier >= UQ_4_12(2.0)))
|
||||
&& (moveType == TYPE_NORMAL || typeEffectivenessModifier >= UQ_4_12(2.0))
|
||||
&& !UnnerveOn(battlerDef, itemDef))
|
||||
{
|
||||
if (abilityDef == ABILITY_RIPEN)
|
||||
MulModifier(&finalModifier, UQ_4_12(0.25));
|
||||
|
@ -8657,6 +8767,9 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
|
|||
{SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET},
|
||||
{SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW},
|
||||
{SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI},
|
||||
{SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT},
|
||||
{SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT},
|
||||
{SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND},
|
||||
};
|
||||
|
||||
if (isSwitchingOut) // Don't revert Mimikyu Busted when switching out
|
||||
|
@ -9241,3 +9354,17 @@ void DoBurmyFormChange(u32 monId)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef)
|
||||
{
|
||||
#if B_PRANKSTER_DARK_TYPES >= GEN_7
|
||||
if (gProtectStructs[battlerPrankster].pranksterElevated
|
||||
&& GetBattlerSide(battlerPrankster) != GetBattlerSide(battlerDef)
|
||||
&& !(gBattleMoves[gCurrentMove].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)) // Don't block hazards, assist-type moves
|
||||
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) // Only Dark-types can block Prankster'd
|
||||
&& !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE))
|
||||
return TRUE;
|
||||
else
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -2599,11 +2599,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
|||
#if B_UPDATED_MOVE_DATA >= GEN_4
|
||||
.accuracy = 0,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.effect = EFFECT_RECOIL_HP_25,
|
||||
#else
|
||||
.accuracy = 100,
|
||||
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
|
||||
.effect = EFFECT_RECOIL_25,
|
||||
#endif
|
||||
.effect = EFFECT_RECOIL_25,
|
||||
.power = 50,
|
||||
.type = TYPE_NORMAL,
|
||||
.pp = 1,
|
||||
|
@ -3424,6 +3425,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
|||
|
||||
[MOVE_HEAL_BELL] =
|
||||
{
|
||||
#if B_UPDATED_MOVE_DATA != GEN_5
|
||||
.flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND,
|
||||
#else
|
||||
.flags = FLAG_SNATCH_AFFECTED,
|
||||
#endif
|
||||
.effect = EFFECT_HEAL_BELL,
|
||||
.power = 0,
|
||||
.type = TYPE_NORMAL,
|
||||
|
@ -3432,7 +3438,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
|||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.priority = 0,
|
||||
.flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND,
|
||||
.split = SPLIT_STATUS,
|
||||
},
|
||||
|
||||
|
@ -5338,6 +5343,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
|||
|
||||
[MOVE_HOWL] =
|
||||
{
|
||||
#if B_UPDATED_MOVE_DATA >= GEN_8
|
||||
.flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND,
|
||||
#else
|
||||
.flags = FLAG_SNATCH_AFFECTED,
|
||||
#endif
|
||||
.effect = EFFECT_ATTACK_UP,
|
||||
.power = 0,
|
||||
.type = TYPE_NORMAL,
|
||||
|
@ -5346,7 +5356,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
|||
.secondaryEffectChance = 0,
|
||||
.target = MOVE_TARGET_USER,
|
||||
.priority = 0,
|
||||
.flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND,
|
||||
.split = SPLIT_STATUS,
|
||||
},
|
||||
|
||||
|
@ -8097,7 +8106,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
|||
|
||||
[MOVE_RETALIATE] =
|
||||
{
|
||||
.effect = EFFECT_RETALITATE,
|
||||
.effect = EFFECT_RETALIATE,
|
||||
.power = 70,
|
||||
.type = TYPE_NORMAL,
|
||||
.accuracy = 100,
|
||||
|
@ -10226,7 +10235,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
|
|||
[MOVE_PSYCHIC_FANGS] =
|
||||
{
|
||||
.effect = EFFECT_BRICK_BREAK,
|
||||
.power = 75,
|
||||
.power = 85,
|
||||
.type = TYPE_PSYCHIC,
|
||||
.accuracy = 100,
|
||||
.pp = 15,
|
||||
|
|
Loading…
Reference in a new issue