mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-01-14 15:43:43 +01:00
Merge remote-tracking branch 'RHH/battle_engine' into BE_plusMinus
# Conflicts: # include/constants/battle_config.h
This commit is contained in:
commit
56b9a50109
@ -288,43 +288,57 @@
|
||||
createvisualtask AnimTask_IsDoubleBattle, 0
|
||||
jumprettrue \ptr
|
||||
.endm
|
||||
|
||||
|
||||
@ keep CFRU macros cause I'm lazy. todo: update to createsprite and createvisualtask, respectively
|
||||
.macro launchtemplate launchtemplatePtr launchtemplatePriority launchtemplateArgsNo launchtemplatearg0 launchtemplatearg1 launchtemplatearg2 launchtemplatearg3 launchtemplatearg4 launchtemplatearg5 launchtemplatearg6 launchtemplatearg7 launchtemplatearg8
|
||||
.byte 0x2
|
||||
.word \launchtemplatePtr
|
||||
.byte \launchtemplatePriority
|
||||
.byte \launchtemplateArgsNo
|
||||
.hword \launchtemplatearg0
|
||||
.hword \launchtemplatearg1
|
||||
.hword \launchtemplatearg2
|
||||
.hword \launchtemplatearg3
|
||||
.hword \launchtemplatearg4
|
||||
.hword \launchtemplatearg5
|
||||
.hword \launchtemplatearg6
|
||||
.hword \launchtemplatearg7
|
||||
.hword \launchtemplatearg8
|
||||
.endm
|
||||
|
||||
.byte 0x2
|
||||
.word \launchtemplatePtr
|
||||
.byte \launchtemplatePriority
|
||||
.byte \launchtemplateArgsNo
|
||||
.hword \launchtemplatearg0
|
||||
.hword \launchtemplatearg1
|
||||
.hword \launchtemplatearg2
|
||||
.hword \launchtemplatearg3
|
||||
.hword \launchtemplatearg4
|
||||
.hword \launchtemplatearg5
|
||||
.hword \launchtemplatearg6
|
||||
.hword \launchtemplatearg7
|
||||
.hword \launchtemplatearg8
|
||||
.endm
|
||||
|
||||
.macro launchtask launchtaskPtr launchtaskPriority launchtaskArgsNo launchtaskarg0 launchtaskarg1 launchtaskarg2 launchtaskarg3 launchtaskarg4 launchtaskarg5 launchtaskarg6 launchtaskarg7 launchtaskarg8
|
||||
.byte 0x3
|
||||
.word \launchtaskPtr
|
||||
.byte \launchtaskPriority
|
||||
.byte \launchtaskArgsNo
|
||||
.hword \launchtaskarg0
|
||||
.hword \launchtaskarg1
|
||||
.hword \launchtaskarg2
|
||||
.hword \launchtaskarg3
|
||||
.hword \launchtaskarg4
|
||||
.hword \launchtaskarg5
|
||||
.hword \launchtaskarg6
|
||||
.hword \launchtaskarg7
|
||||
.hword \launchtaskarg8
|
||||
.endm
|
||||
|
||||
.byte 0x3
|
||||
.word \launchtaskPtr
|
||||
.byte \launchtaskPriority
|
||||
.byte \launchtaskArgsNo
|
||||
.hword \launchtaskarg0
|
||||
.hword \launchtaskarg1
|
||||
.hword \launchtaskarg2
|
||||
.hword \launchtaskarg3
|
||||
.hword \launchtaskarg4
|
||||
.hword \launchtaskarg5
|
||||
.hword \launchtaskarg6
|
||||
.hword \launchtaskarg7
|
||||
.hword \launchtaskarg8
|
||||
.endm
|
||||
|
||||
.macro setblends setblends_value
|
||||
.byte 0xC
|
||||
.hword \setblends_value
|
||||
.endm
|
||||
.byte 0xC
|
||||
.hword \setblends_value
|
||||
.endm
|
||||
|
||||
.macro launchsoundtask launchsoundtaskPtr launchsoundtaskArgsNo launchsoundtaskarg0 launchsoundtaskarg1 launchsoundtaskarg2 launchsoundtaskarg3 launchsoundtaskarg4 launchsoundtaskarg5 launchsoundtaskarg6 launchsoundtaskarg7 launchsoundtaskarg8
|
||||
.byte 0x1F
|
||||
.word \launchsoundtaskPtr
|
||||
.byte \launchsoundtaskArgsNo
|
||||
.hword \launchsoundtaskarg0
|
||||
.hword \launchsoundtaskarg1
|
||||
.hword \launchsoundtaskarg2
|
||||
.hword \launchsoundtaskarg3
|
||||
.hword \launchsoundtaskarg4
|
||||
.hword \launchsoundtaskarg5
|
||||
.hword \launchsoundtaskarg6
|
||||
.hword \launchsoundtaskarg7
|
||||
.hword \launchsoundtaskarg8
|
||||
.endm
|
||||
|
||||
|
@ -1785,6 +1785,10 @@
|
||||
various \battler, VARIOUS_TRY_ACTIVATE_GRIM_NEIGH
|
||||
.endm
|
||||
|
||||
.macro setzeffect
|
||||
various BS_ATTACKER, VARIOUS_SET_Z_EFFECT
|
||||
.endm
|
||||
|
||||
.macro consumeberry battler:req, restoreItem=FALSE
|
||||
various \battler, VARIOUS_CONSUME_BERRY
|
||||
.byte \restoreItem
|
||||
@ -1924,8 +1928,8 @@
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro photongeysercheck
|
||||
various BS_ATTACKER, VARIOUS_PHOTON_GEYSER_CHECK
|
||||
.macro photongeysercheck battler:req
|
||||
various \battler, VARIOUS_PHOTON_GEYSER_CHECK
|
||||
.endm
|
||||
|
||||
.macro shellsidearmcheck
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -411,6 +411,8 @@ gBattleScriptsForMoveEffects::
|
||||
.4byte BattleScript_EffectHit @ EFFECT_BEAK_BLAST
|
||||
.4byte BattleScript_EffectCourtChange @ EFFECT_COURT_CHANGE
|
||||
.4byte BattleScript_EffectSteelBeam @ EFFECT_STEEL_BEAM
|
||||
.4byte BattleScript_EffectExtremeEvoboost @ EFFECT_EXTREME_EVOBOOST
|
||||
.4byte BattleScript_EffectTerrainHit @ EFFECT_DAMAGE_SET_TERRAIN
|
||||
|
||||
BattleScript_EffectSteelBeam::
|
||||
attackcanceler
|
||||
@ -720,7 +722,7 @@ BattleScript_EffectPhotonGeyser:
|
||||
critcalc
|
||||
damagecalc
|
||||
adjustdamage
|
||||
photongeysercheck
|
||||
photongeysercheck BS_ATTACKER
|
||||
attackanimation
|
||||
waitanimation
|
||||
effectivenesssound
|
||||
@ -2152,9 +2154,7 @@ BattleScript_GrowthDoMoveAnim::
|
||||
waitanimation
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
playstatchangeanimation BS_ATTACKER, BIT_ATK | BIT_SPATK, 0
|
||||
.if B_GROWTH_UNDER_SUN >= GEN_5
|
||||
jumpifweatheraffected BS_ATTACKER, B_WEATHER_SUN, BattleScript_GrowthAtk2
|
||||
.endif
|
||||
setstatchanger STAT_ATK, 1, FALSE
|
||||
goto BattleScript_GrowthAtk
|
||||
BattleScript_GrowthAtk2:
|
||||
@ -2165,9 +2165,7 @@ BattleScript_GrowthAtk:
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_GrowthTrySpAtk::
|
||||
.if B_GROWTH_UNDER_SUN >= GEN_5
|
||||
jumpifweatheraffected BS_ATTACKER, B_WEATHER_SUN, BattleScript_GrowthSpAtk2
|
||||
.endif
|
||||
setstatchanger STAT_SPATK, 1, FALSE
|
||||
goto BattleScript_GrowthSpAtk
|
||||
BattleScript_GrowthSpAtk2:
|
||||
@ -5542,6 +5540,7 @@ BattleScript_EffectCharge::
|
||||
setcharge
|
||||
attackanimation
|
||||
waitanimation
|
||||
.if B_CHARGE_SPDEF_RAISE >= GEN_5
|
||||
setstatchanger STAT_SPDEF, 1, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_EffectChargeString
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_EffectChargeString
|
||||
@ -5550,6 +5549,7 @@ BattleScript_EffectCharge::
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
BattleScript_EffectChargeString:
|
||||
.endif
|
||||
printstring STRINGID_PKMNCHARGINGPOWER
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
@ -9514,6 +9514,124 @@ BattleScript_JabocaRowapBerryActivate_Dmg:
|
||||
removeitem BS_TARGET
|
||||
return
|
||||
|
||||
@ z moves / effects
|
||||
BattleScript_ZMoveActivateDamaging::
|
||||
printstring STRINGID_ZPOWERSURROUNDS
|
||||
playanimation BS_ATTACKER, B_ANIM_ZMOVE_ACTIVATE, NULL
|
||||
printstring STRINGID_ZMOVEUNLEASHED
|
||||
waitmessage 0x40
|
||||
return
|
||||
|
||||
BattleScript_ZMoveActivateStatus::
|
||||
savetarget
|
||||
printstring STRINGID_ZPOWERSURROUNDS
|
||||
playanimation BS_ATTACKER, B_ANIM_ZMOVE_ACTIVATE, NULL
|
||||
setzeffect
|
||||
restoretarget
|
||||
copybyte sSTATCHANGER, sSAVED_STAT_CHANGER
|
||||
return
|
||||
|
||||
BattleScript_ZEffectPrintString::
|
||||
printfromtable gZEffectStringIds
|
||||
waitmessage 0x40
|
||||
return
|
||||
|
||||
BattleScript_RecoverHPZMove::
|
||||
healthbarupdate BS_SCRIPTING
|
||||
datahpupdate BS_SCRIPTING
|
||||
printfromtable gZEffectStringIds
|
||||
waitmessage 0x40
|
||||
return
|
||||
|
||||
BattleScript_StatUpZMove::
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_StatUpZMoveEnd
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_StatUpZMoveEnd
|
||||
setgraphicalstatchangevalues
|
||||
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
|
||||
printstring STRINGID_ZMOVESTATUP
|
||||
waitmessage 0x40
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage 0x40
|
||||
BattleScript_StatUpZMoveEnd:
|
||||
return
|
||||
|
||||
BattleScript_HealReplacementZMove::
|
||||
playanimation BS_SCRIPTING B_ANIM_WISH_HEAL 0x0
|
||||
printfromtable gZEffectStringIds
|
||||
waitmessage 0x40
|
||||
healthbarupdate BS_SCRIPTING
|
||||
datahpupdate BS_SCRIPTING
|
||||
return
|
||||
|
||||
BattleScript_EffectExtremeEvoboost::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_ATK, MAX_STAT_STAGE, BattleScript_ExtremeEvoboostAnim
|
||||
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_DEF, MAX_STAT_STAGE, BattleScript_ExtremeEvoboostAnim
|
||||
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPEED, MAX_STAT_STAGE, BattleScript_ExtremeEvoboostAnim
|
||||
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPATK, MAX_STAT_STAGE, BattleScript_ExtremeEvoboostAnim
|
||||
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPDEF, MAX_STAT_STAGE, BattleScript_ExtremeEvoboostAnim
|
||||
goto BattleScript_ButItFailed
|
||||
BattleScript_ExtremeEvoboostAnim:
|
||||
attackanimation
|
||||
waitanimation
|
||||
BattleScript_ExtremeEvoboostAtk::
|
||||
setbyte sSTAT_ANIM_PLAYED, FALSE
|
||||
playstatchangeanimation BS_ATTACKER, BIT_ATK | BIT_DEF | BIT_SPEED | BIT_SPATK | BIT_SPDEF, 0x0
|
||||
setstatchanger STAT_ATK, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_ExtremeEvoboostDef
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage 0x40
|
||||
BattleScript_ExtremeEvoboostDef::
|
||||
setstatchanger STAT_DEF, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_ExtremeEvoboostSpeed
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage 0x40
|
||||
BattleScript_ExtremeEvoboostSpeed::
|
||||
setstatchanger STAT_SPEED, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_ExtremeEvoboostSpAtk
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage 0x40
|
||||
BattleScript_ExtremeEvoboostSpAtk::
|
||||
setstatchanger STAT_SPATK, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_ExtremeEvoboostSpDef
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage 0x40
|
||||
BattleScript_ExtremeEvoboostSpDef::
|
||||
setstatchanger STAT_SPDEF, 2, FALSE
|
||||
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_ExtremeEvoboostEnd
|
||||
printfromtable gStatUpStringIds
|
||||
waitmessage 0x40
|
||||
BattleScript_ExtremeEvoboostEnd::
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectTerrainHit:
|
||||
attackcanceler
|
||||
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
|
||||
attackstring
|
||||
ppreduce
|
||||
critcalc
|
||||
damagecalc
|
||||
adjustdamage
|
||||
attackanimation
|
||||
waitanimation
|
||||
effectivenesssound
|
||||
hitanimation BS_TARGET
|
||||
waitstate
|
||||
healthbarupdate BS_TARGET
|
||||
datahpupdate BS_TARGET
|
||||
critmessage
|
||||
waitmessage 0x40
|
||||
resultmessage
|
||||
waitmessage 0x40
|
||||
setterrain BattleScript_TryFaint
|
||||
playanimation BS_ATTACKER, B_ANIM_RESTORE_BG
|
||||
printfromtable gTerrainStringIds
|
||||
BattleScript_TryFaint:
|
||||
tryfaintmon BS_TARGET
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_Pickpocket::
|
||||
call BattleScript_AbilityPopUp
|
||||
jumpifability BS_ATTACKER, ABILITY_STICKY_HOLD, BattleScript_PickpocketPrevented
|
||||
|
BIN
graphics/battle_interface/z_move_trigger.png
Normal file
BIN
graphics/battle_interface/z_move_trigger.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 351 B |
@ -467,6 +467,25 @@ struct Illusion
|
||||
struct Pokemon *mon;
|
||||
};
|
||||
|
||||
struct ZMoveData
|
||||
{
|
||||
u8 viable:1; // current move can become a z move
|
||||
u8 viewing:1; // if player is viewing the z move name instead of regular moves
|
||||
u8 active:1; // is z move being used this turn
|
||||
u8 zStatusActive:1;
|
||||
u8 healReplacement:1;
|
||||
u8 activeSplit:2; // active z move split
|
||||
u8 zUnused:1;
|
||||
u8 triggerSpriteId;
|
||||
u8 possibleZMoves[MAX_BATTLERS_COUNT];
|
||||
u16 chosenZMove; // z move of move cursor is on
|
||||
u8 effect;
|
||||
u8 used[MAX_BATTLERS_COUNT]; //one per bank for multi-battles
|
||||
u16 toBeUsed[MAX_BATTLERS_COUNT]; // z moves per battler to be used
|
||||
u16 baseMoves[MAX_BATTLERS_COUNT];
|
||||
u8 splits[MAX_BATTLERS_COUNT];
|
||||
};
|
||||
|
||||
struct StolenItem
|
||||
{
|
||||
u16 originalItem:15;
|
||||
@ -571,6 +590,7 @@ struct BattleStruct
|
||||
u8 abilityPopUpSpriteIds[MAX_BATTLERS_COUNT][2]; // two per battler
|
||||
bool8 throwingPokeBall;
|
||||
struct MegaEvolutionData mega;
|
||||
struct ZMoveData zmove;
|
||||
const u8 *trainerSlideMsg;
|
||||
bool8 trainerSlideLowHpMsgDone;
|
||||
u8 introState;
|
||||
@ -595,6 +615,7 @@ struct BattleStruct
|
||||
u8 quickClawBattlerId;
|
||||
struct StolenItem itemStolen[PARTY_SIZE]; // Player's team that had items stolen (two bytes per party member)
|
||||
u8 blunderPolicy:1; // should blunder policy activate
|
||||
u8 swapDamageCategory:1; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
u8 ballSpriteIds[2]; // item gfx, window gfx
|
||||
u8 stickyWebUser;
|
||||
u8 appearedInBattle; // Bitfield to track which Pokemon appeared in battle. Used for Burmy's form change
|
||||
@ -811,7 +832,7 @@ extern u16 gBattle_WIN1V;
|
||||
extern u8 gDisplayedStringBattle[400];
|
||||
extern u8 gBattleTextBuff1[TEXT_BUFF_ARRAY_COUNT];
|
||||
extern u8 gBattleTextBuff2[TEXT_BUFF_ARRAY_COUNT];
|
||||
extern u8 gBattleTextBuff3[TEXT_BUFF_ARRAY_COUNT];
|
||||
extern u8 gBattleTextBuff3[30]; //to handle stupidly large z move names
|
||||
extern u32 gBattleTypeFlags;
|
||||
extern u8 gBattleTerrain;
|
||||
extern u32 gUnusedFirstBattleVar1;
|
||||
@ -918,7 +939,6 @@ extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
|
||||
extern bool8 gHasFetchedBall;
|
||||
extern u8 gLastUsedBall;
|
||||
extern u16 gLastThrownBall;
|
||||
extern bool8 gSwapDamageCategory; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
extern u8 gPartyCriticalHits[PARTY_SIZE];
|
||||
|
||||
#endif // GUARD_BATTLE_H
|
||||
|
@ -62,6 +62,7 @@ s8 GetAbilityRating(u16 ability);
|
||||
bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability);
|
||||
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move);
|
||||
u32 AI_GetBattlerMoveTargetType(u8 battlerId, u16 move);
|
||||
bool32 ShouldUseZMove(u8 activeId, u8 targetId, u16 chosenMove);
|
||||
|
||||
// stat stage checks
|
||||
bool32 AnyStatIsRaised(u8 battlerId);
|
||||
@ -82,7 +83,7 @@ bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility);
|
||||
// move checks
|
||||
bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect);
|
||||
bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split);
|
||||
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *effectiveness);
|
||||
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *effectiveness, bool32 considerZPower);
|
||||
u8 GetMoveDamageResult(u16 move);
|
||||
u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef);
|
||||
u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
|
@ -205,12 +205,14 @@ u8 GetSubstituteSpriteDefault_Y(u8 battlerId);
|
||||
#define STAT_ANIM_MULTIPLE_MINUS1 57
|
||||
#define STAT_ANIM_MULTIPLE_MINUS2 58
|
||||
void LaunchStatusAnimation(u8 battlerId, u8 statusAnimId);
|
||||
extern const union AnimCmd *const sAnims_SpinningSparkle[];
|
||||
|
||||
// battle_anim_ground.c
|
||||
void AnimTask_HorizontalShake(u8 taskId);
|
||||
void AnimMudSportDirt(struct Sprite *sprite);
|
||||
void AnimDirtScatter(struct Sprite *sprite);
|
||||
void AnimMudSportDirtRising(struct Sprite *sprite);
|
||||
void AnimDirtPlumeParticle(struct Sprite *);
|
||||
extern const union AffineAnimCmd *const gAffineAnims_SpinningBone[];
|
||||
|
||||
// battle_anim_throw.c
|
||||
@ -272,6 +274,7 @@ extern const union AnimCmd *const gScratchAnimTable[];
|
||||
extern const union AnimCmd *const gIngrainRootAnimTable[];
|
||||
extern const union AffineAnimCmd *const gSwiftStarAffineAnimTable[];
|
||||
extern const union AnimCmd *const gMetronomeThroughtBubbleAnimTable[];
|
||||
extern const union AffineAnimCmd *const gStockpileAbsorptionOrbAffineAnimTable[];
|
||||
|
||||
// battle_anim_effects_2.c
|
||||
void AnimUproarRing(struct Sprite *sprite);
|
||||
@ -280,6 +283,7 @@ void AnimOrbitFast(struct Sprite *sprite);
|
||||
void AnimOrbitScatter(struct Sprite *sprite);
|
||||
void AnimAngerMark(struct Sprite *sprite);
|
||||
void AnimHyperVoiceRing(struct Sprite *sprite);
|
||||
void AnimMagentaHeart(struct Sprite *);
|
||||
extern const union AffineAnimCmd *const gThinRingShrinkingAffineAnimTable[];
|
||||
extern const union AffineAnimCmd *const gThinRingExpandingAffineAnimTable[];
|
||||
extern const union AnimCmd *const gExplosionAnimTable[];
|
||||
@ -295,8 +299,13 @@ void AnimBlackSmoke(struct Sprite *sprite);
|
||||
void AnimSweetScentPetal(struct Sprite *sprite);
|
||||
void AnimTealAlert(struct Sprite *sprite);
|
||||
void AnimBlockX(struct Sprite *sprite);
|
||||
void AnimFlatterSpotlight_Step(struct Sprite *);
|
||||
void AnimAssistPawprint(struct Sprite *);
|
||||
void AnimReversalOrb(struct Sprite *);
|
||||
void AnimFlatterSpotlight_Step(struct Sprite *sprite);
|
||||
extern const union AnimCmd *const gOpeningEyeAnimTable[];
|
||||
extern const union AnimCmd *const gEclipsingOrbAnimTable[];
|
||||
extern const union AffineAnimCmd *const gSpotlightAffineAnimTable[];
|
||||
|
||||
// battle_anim_water.c
|
||||
void AnimWaterPulseRing(struct Sprite *sprite);
|
||||
@ -314,16 +323,21 @@ void AnimFlyBallUp(struct Sprite *sprite);
|
||||
void AnimFlyBallAttack(struct Sprite *sprite);
|
||||
void AnimFlyBallAttack_Step(struct Sprite *sprite);
|
||||
void AnimFlyBallUp_Step(struct Sprite *sprite);
|
||||
void AnimBounceBallLand(struct Sprite *);
|
||||
void AnimEllipticalGust(struct Sprite *);
|
||||
extern const union AnimCmd *const gAffineAnims_AirWaveCrescent[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_FlyBallUp[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_FlyBallAttack[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_BounceBallLand[];
|
||||
|
||||
// battle_anim_poison.c
|
||||
void AnimSludgeBombHitParticle(struct Sprite *);
|
||||
void AnimAcidPoisonBubble_Step(struct Sprite *sprite);
|
||||
void AnimBubbleEffect(struct Sprite *);
|
||||
extern const union AffineAnimCmd *const gAffineAnims_PoisonProjectile[];
|
||||
extern const union AnimCmd *const gAnims_PoisonProjectile[];
|
||||
extern const union AnimCmd *const gAnims_AcidPoisonDroplet[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_Bubble[];
|
||||
|
||||
// battle_anim_ghost.c
|
||||
void AnimGhostStatusSprite(struct Sprite *sprite);
|
||||
@ -419,6 +433,7 @@ void AnimSparkElectricity(struct Sprite *sprite);
|
||||
void AnimElectricPuff(struct Sprite *sprite);
|
||||
void AnimSparkElectricityFlashing(struct Sprite *sprite);
|
||||
void AnimGrowingShockWaveOrb(struct Sprite *sprite);
|
||||
void AnimElectricity(struct Sprite *);
|
||||
extern const union AffineAnimCmd *const gAffineAnims_GrowingElectricOrb[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_FlashingSpark[];
|
||||
extern const union AnimCmd *const gAnims_ThunderboltOrb[];
|
||||
@ -434,6 +449,7 @@ void AnimBasicFistOrFoot(struct Sprite *sprite);
|
||||
void AnimSpinningKickOrPunchFinish(struct Sprite *sprite);
|
||||
void AnimRevengeScratch(struct Sprite *sprite);
|
||||
void AnimDizzyPunchDuck(struct Sprite *sprite);
|
||||
void AnimSuperpowerFireball(struct Sprite *);
|
||||
extern const union AnimCmd *const gAnims_HandsAndFeet[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_MegaPunchKick[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_SpinningHandOrFoot[];
|
||||
@ -443,6 +459,7 @@ extern const union AnimCmd *const gAnims_RevengeBigScratch[];
|
||||
extern const union AnimCmd *const gAnims_FlyingRock[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_Whirlpool[];
|
||||
extern const union AffineAnimCmd *const gAffineAnims_BasicRock[];
|
||||
extern const union AnimCmd *const gAnims_FlyingRock[];
|
||||
void AnimParticleInVortex(struct Sprite *sprite);
|
||||
void AnimFallingRock(struct Sprite *sprite);
|
||||
void AnimRaiseSprite(struct Sprite *sprite);
|
||||
@ -477,7 +494,13 @@ extern const union AnimCmd *const gAnims_BlizzardIceCrystal[];
|
||||
// battle_anim_fire.c
|
||||
void AnimFireSpread(struct Sprite *sprite);
|
||||
void AnimFireSpiralOutward(struct Sprite *sprite);
|
||||
void AnimWillOWispOrb(struct Sprite *);
|
||||
void AnimEruptionFallingRock(struct Sprite *);
|
||||
void AnimFireCross(struct Sprite *);
|
||||
void AnimFirePlume(struct Sprite *);
|
||||
extern const union AnimCmd *const gAnims_FireBlastCross[];
|
||||
extern const union AnimCmd *const gAnims_WillOWispOrb[];
|
||||
extern const union AnimCmd *const gAnims_FirePlume[];
|
||||
|
||||
// battle_anim_dragon.c
|
||||
extern const union AnimCmd *const gAnims_DragonBreathFire[];
|
||||
|
@ -129,6 +129,7 @@ struct ChooseMoveStruct
|
||||
u8 monType2;
|
||||
u8 monType3;
|
||||
struct MegaEvolutionData mega;
|
||||
struct ZMoveData zmove;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -276,6 +277,8 @@ void Task_PlayerController_RestoreBgmAfterCry(u8 taskId);
|
||||
void ActionSelectionCreateCursorAt(u8 cursorPos, u8 unused);
|
||||
void ActionSelectionDestroyCursorAt(u8 cursorPos);
|
||||
void InitMoveSelectionsVarsAndStrings(void);
|
||||
void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1);
|
||||
void MoveSelectionDestroyCursorAt(u8 cursorPosition);
|
||||
|
||||
// recorded player controller
|
||||
void SetControllerToRecordedPlayer(void);
|
||||
|
@ -43,6 +43,7 @@ enum
|
||||
#define TAG_MEGA_INDICATOR_TILE 0xD778
|
||||
#define TAG_ALPHA_INDICATOR_TILE 0xD779
|
||||
#define TAG_OMEGA_INDICATOR_TILE 0xD77A
|
||||
#define TAG_ZMOVE_TRIGGER_TILE 0xD77B
|
||||
|
||||
#define TAG_HEALTHBOX_PAL 0xD6FF
|
||||
#define TAG_HEALTHBAR_PAL 0xD704
|
||||
@ -53,6 +54,7 @@ enum
|
||||
#define TAG_MEGA_INDICATOR_PAL 0xD778
|
||||
#define TAG_ALPHA_INDICATOR_PAL 0xD779
|
||||
#define TAG_OMEGA_INDICATOR_PAL 0xD77A
|
||||
#define TAG_ZMOVE_TRIGGER_PAL 0xD77B
|
||||
|
||||
enum
|
||||
{
|
||||
@ -97,6 +99,7 @@ u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale);
|
||||
u8 GetHPBarLevel(s16 hp, s16 maxhp);
|
||||
void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle);
|
||||
void DestroyAbilityPopUp(u8 battlerId);
|
||||
void HideTriggerSprites(void);
|
||||
bool32 CanThrowLastUsedBall(void);
|
||||
void TryHideLastUsedBall(void);
|
||||
void TryRestoreLastUsedBall(void);
|
||||
|
@ -240,6 +240,7 @@ void BattlePutTextOnWindow(const u8* text, u8 windowId);
|
||||
void SetPpNumbersPaletteInMoveSelection(void);
|
||||
u8 GetCurrentPpToMaxPpState(u8 currentPp, u8 maxPp);
|
||||
bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which);
|
||||
void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst);
|
||||
|
||||
extern struct BattleMsgData *gBattleMsgDataPtr;
|
||||
|
||||
|
@ -421,4 +421,13 @@ extern const u8 BattleScript_BeakBlastSetUp[];
|
||||
extern const u8 BattleScript_BeakBlastBurn[];
|
||||
extern const u8 BattleScript_DefDownSpeedUp[];
|
||||
|
||||
// zmoves
|
||||
extern const u8 BattleScript_ZMoveActivateDamaging[];
|
||||
extern const u8 BattleScript_ZMoveActivateStatus[];
|
||||
extern const u8 BattleScript_ZEffectPrintString[];
|
||||
extern const u8 BattleScript_RecoverHPZMove[];
|
||||
extern const u8 BattleScript_StatUpZMove[];
|
||||
extern const u8 BattleScript_HealReplacementZMove[];
|
||||
extern const u8 BattleScript_EffectExtremeEvoboost[];
|
||||
|
||||
#endif // GUARD_BATTLE_SCRIPTS_H
|
||||
|
@ -153,6 +153,8 @@ bool32 CanFling(u8 battlerId);
|
||||
bool32 IsTelekinesisBannedSpecies(u16 species);
|
||||
bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
|
||||
bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId);
|
||||
bool32 IsPartnerMonFromSameTrainer(u8 battlerId);
|
||||
u8 GetSplitBasedOnStats(u8 battlerId);
|
||||
void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast);
|
||||
bool32 TestSheerForceFlag(u8 battler, u16 move);
|
||||
void TryRestoreStolenItems(void);
|
||||
|
30
include/battle_z_move.h
Normal file
30
include/battle_z_move.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef GUARD_BATTLE_Z_MOVE_H
|
||||
#define GUARD_BATTLE_Z_MOVE_H
|
||||
|
||||
#include "constants/z_move_effects.h"
|
||||
|
||||
#define MOVE_Z_STATUS 0xFFFF
|
||||
|
||||
struct SignatureZMove
|
||||
{
|
||||
u16 species;
|
||||
u16 item;
|
||||
u16 move;
|
||||
u16 zmove;
|
||||
};
|
||||
|
||||
bool8 IsZMove(u16 move);
|
||||
void QueueZMove(u8 battlerId, u16 baseMove);
|
||||
bool32 IsViableZMove(u8 battlerId, u16 move);
|
||||
bool32 TryChangeZIndicator(u8 battlerId, u8 moveIndex);
|
||||
void CreateZMoveTriggerSprite(u8, bool8);
|
||||
void HideZMoveTriggerSprite(void);
|
||||
bool32 IsZMoveTriggerSpriteActive(void);
|
||||
void DestroyZMoveTriggerSprite(void);
|
||||
bool32 MoveSelectionDisplayZMove(u16 zmove);
|
||||
const u8* GetZMoveName(u16 move);
|
||||
void SetZEffect(void);
|
||||
bool32 IsZMoveUsable(u8 battlerId, u16 moveIndex);
|
||||
void GetUsableZMoves(u8 battlerId, u16 *moves);
|
||||
|
||||
#endif // GUARD_BATTLE_Z_MOVE_H
|
@ -535,6 +535,7 @@
|
||||
#define B_ANIM_AQUA_RING_HEAL 32
|
||||
#define B_ANIM_BEAK_BLAST_SETUP 33
|
||||
#define B_ANIM_SHELL_TRAP_SETUP 34
|
||||
#define B_ANIM_ZMOVE_ACTIVATE 35 // Using Z Moves
|
||||
|
||||
// special animations table (gBattleAnims_Special)
|
||||
#define B_ANIM_LVL_UP 0
|
||||
@ -601,6 +602,12 @@
|
||||
#define ANIM_RIGHT_FIST 0
|
||||
#define ANIM_LEFT_FIST 2
|
||||
|
||||
// fist/chop frames
|
||||
#define ANIM_FIST_1 0
|
||||
#define ANIM_FOOT_1 1
|
||||
#define ANIM_FOOT_2 2
|
||||
#define ANIM_CHOP 3
|
||||
|
||||
// surf wave palettes
|
||||
#define ANIM_SURF_PAL_SURF 0
|
||||
#define ANIM_SURF_PAL_MUDDY_WATER 1
|
||||
|
@ -87,6 +87,41 @@
|
||||
#define ITEM_RINDO_BERRY 207
|
||||
#define ITEM_YACHE_BERRY 208
|
||||
#define ITEM_GRISEOUS_ORB 369
|
||||
// z crystals
|
||||
#define ITEM_NORMALIUM_Z 568
|
||||
#define ITEM_FIGHTINIUM_Z 569
|
||||
#define ITEM_FLYINIUM_Z 570
|
||||
#define ITEM_POISONIUM_Z 571
|
||||
#define ITEM_GROUNDIUM_Z 572
|
||||
#define ITEM_ROCKIUM_Z 573
|
||||
#define ITEM_BUGINIUM_Z 574
|
||||
#define ITEM_GHOSTIUM_Z 575
|
||||
#define ITEM_STEELIUM_Z 576
|
||||
#define ITEM_FIRIUM_Z 577
|
||||
#define ITEM_WATERIUM_Z 578
|
||||
#define ITEM_GRASSIUM_Z 579
|
||||
#define ITEM_ELECTRIUM_Z 580
|
||||
#define ITEM_PSYCHIUM_Z 581
|
||||
#define ITEM_ICIUM_Z 582
|
||||
#define ITEM_DRAGONIUM_Z 583
|
||||
#define ITEM_DARKINIUM_Z 584
|
||||
#define ITEM_FAIRIUM_Z 585
|
||||
#define ITEM_ALORAICHIUM_Z 586
|
||||
#define ITEM_DECIDIUM_Z 587
|
||||
#define ITEM_EEVIUM_Z 588
|
||||
#define ITEM_INCINIUM_Z 589
|
||||
#define ITEM_KOMMONIUM_Z 590
|
||||
#define ITEM_LUNALIUM_Z 591
|
||||
#define ITEM_LYCANIUM_Z 592
|
||||
#define ITEM_MARSHADIUM_Z 593
|
||||
#define ITEM_MEWNIUM_Z 594
|
||||
#define ITEM_MIMIKIUM_Z 595
|
||||
#define ITEM_PIKANIUM_Z 596
|
||||
#define ITEM_PIKASHUNIUM_Z 597
|
||||
#define ITEM_PRIMARIUM_Z 598
|
||||
#define ITEM_SNORLIUM_Z 599
|
||||
#define ITEM_SOLGANIUM_Z 600
|
||||
#define ITEM_TAPUNIUM_Z 601
|
||||
#endif
|
||||
|
||||
#ifndef GEN_3
|
||||
@ -125,6 +160,7 @@
|
||||
#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.
|
||||
#define B_SPORT_DMG_REDUCTION GEN_7 // In Gen5+, Water/Mud Sport reduce Fire/Electric Damage by 67% instead of 50%.
|
||||
#define B_EXPLOSION_DEFENSE GEN_7 // In Gen5+, Self-Destruct and Explosion don't halve the targets' defense.
|
||||
|
||||
// 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.
|
||||
@ -148,14 +184,10 @@
|
||||
// Move data settings
|
||||
#define B_UPDATED_MOVE_DATA GEN_8 // Updates move data in gBattleMoves, including Power, Accuracy, PP, stat changes, targets, chances of secondary effects, etc.
|
||||
#define B_PHYSICAL_SPECIAL_SPLIT GEN_7 // In Gen3, the move's type determines if it will do physical or special damage. The split icon in the summary will reflect this.
|
||||
#define B_FELL_STINGER_STAT_RAISE GEN_7 // In Gen7+, it raises Atk by 3 stages instead of 2 if it causes the target to faint.
|
||||
#define B_KINGS_SHIELD_LOWER_ATK GEN_7 // In Gen7+, it lowers Atk by 1 stage instead of 2 of oponents that hit it.
|
||||
#define B_SPEED_BUFFING_RAPID_SPIN GEN_8 // In Gen8, Rapid Spin raises the user's Speed by 1 stage.
|
||||
#define B_RECOIL_IF_MISS_DMG GEN_7 // In Gen5+, Jump Kick and High Jump Kick will always do half of the user's max HP when missing.
|
||||
#define B_KLUTZ_FLING_INTERACTION GEN_7 // In Gen5+, Pokémon with the Klutz ability can't use Fling.
|
||||
#define B_UPDATED_CONVERSION GEN_7 // In Gen6+, Conversion changes the user's type to match their first move's. Before, it would choose a move at random.
|
||||
#define B_PP_REDUCED_BY_SPITE GEN_7 // In Gen4+, Spite reduces the foe's last move's PP by 4, instead of 2 to 5.
|
||||
#define B_MINIMIZE_EVASION GEN_7 // In Gen5+, Minimize raises evasion by 2 stages instead of 1.
|
||||
|
||||
// Move accuracy settings
|
||||
#define B_TOXIC_NEVER_MISS GEN_7 // In Gen6+, if Toxic is used by a Poison-type Pokémon, it will never miss.
|
||||
@ -163,6 +195,14 @@
|
||||
#define B_BLIZZARD_HAIL GEN_7 // In Gen4+, Blizzard bypasses accuracy checks if it's hailing.
|
||||
#define B_SHEER_COLD_ACC GEN_7 // In Gen7+, Sheer Cold's base chance of hitting is reduced to 20% if the user isn't Ice-typed.
|
||||
|
||||
// Move stat change settings
|
||||
#define B_FELL_STINGER_STAT_RAISE GEN_7 // In Gen7+, it raises Atk by 3 stages instead of 2 if it causes the target to faint.
|
||||
#define B_KINGS_SHIELD_LOWER_ATK GEN_7 // In Gen7+, it lowers Atk by 1 stage instead of 2 of oponents that hit it.
|
||||
#define B_SPEED_BUFFING_RAPID_SPIN GEN_8 // In Gen8, Rapid Spin raises the user's Speed by 1 stage.
|
||||
#define B_CHARGE_SPDEF_RAISE GEN_7 // In Gen5+, Charge raises the user's Special Defense by 1 stage.
|
||||
#define B_MINIMIZE_EVASION GEN_7 // In Gen5+, Minimize raises evasion by 2 stages instead of 1.
|
||||
#define B_GROWTH_STAT_RAISE GEN_7 // In Gen5+, Growth raises Attack in addition to Special Attack by 1 stage each. Under the effects of the sun, it raises them by 2 stages each instead.
|
||||
|
||||
// Other move settings
|
||||
#define B_SOUND_SUBSTITUTE GEN_7 // In Gen6+, sound moves bypass Substitute.
|
||||
#define B_INCINERATE_GEMS GEN_7 // In Gen6+, Incinerate can destroy Gems.
|
||||
@ -177,7 +217,6 @@
|
||||
#define B_HEAL_BLOCKING GEN_7 // In Gen5+, Heal Block prevents healing by Black Sludge, Leftovers, Shell Bell. Affected Pokémon will not consume held HP-restoring Berries or Berry Juice.
|
||||
// Draining abilities will not heal but will prevent damage. In Gen6+, Heal Block prevents the use of most HP-draining moves.
|
||||
#define B_ROOTED_GROUNDING GEN_7 // In Gen4+, Ingrain causes the affected Pokémon to become grounded.
|
||||
#define B_GROWTH_UNDER_SUN GEN_7 // In Gen5+, Growth's effects are doubled when under the effects of the sun.
|
||||
|
||||
// Ability settings
|
||||
#define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters.
|
||||
@ -191,6 +230,7 @@
|
||||
#define B_SYNCHRONIZE_TOXIC GEN_8 // In Gen5+, if a Pokémon with Synchronize is badly poisoned, the opponent will also become badly poisoned. Previously, the opponent would become regular poisoned.
|
||||
#define B_UPDATED_INTIMIDATE GEN_8 // In Gen8, Intimidate doesn't work on opponents with the Inner Focus, Scrappy, Own Tempo or Oblivious abilities. It also activates Rattled.
|
||||
#define B_OBLIVIOUS_TAUNT GEN_7 // In Gen6+, Pokémon with Oblivious can't be taunted.
|
||||
#define B_STURDY GEN_7 // In Gen5+, Sturdy causes the Pokémon to have 1 HP remaining if another Pokémon's attack or confusion damage would have brought it from full health to 0 HP.
|
||||
#define B_PLUS_MINUS_INTERACTION GEN_7 // In Gen5+, Plus and Minus can be activated with themselves and the opposite ability. Before, only the opposing ability could activate it.
|
||||
|
||||
// Item settings
|
||||
|
@ -394,7 +394,9 @@
|
||||
#define EFFECT_BEAK_BLAST 388
|
||||
#define EFFECT_COURT_CHANGE 389
|
||||
#define EFFECT_STEEL_BEAM 390
|
||||
#define EFFECT_EXTREME_EVOBOOST 391
|
||||
#define EFFECT_DAMAGE_SET_TERRAIN 392 // genesis supernova
|
||||
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 391
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 393
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
|
||||
|
@ -241,6 +241,7 @@
|
||||
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 150
|
||||
#define VARIOUS_SET_BEAK_BLAST 151
|
||||
#define VARIOUS_SWAP_SIDE_STATUSES 152
|
||||
#define VARIOUS_SET_Z_EFFECT 153
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
@ -615,8 +615,17 @@
|
||||
#define STRINGID_COURTCHANGE 613
|
||||
#define STRINGID_PLAYERLOSTTOENEMYTRAINER 614
|
||||
#define STRINGID_PLAYERPAIDPRIZEMONEY 615
|
||||
#define STRINGID_ZPOWERSURROUNDS 616
|
||||
#define STRINGID_ZMOVEUNLEASHED 617
|
||||
#define STRINGID_ZMOVERESETSSTATS 618
|
||||
#define STRINGID_ZMOVEALLSTATSUP 619
|
||||
#define STRINGID_ZMOVEZBOOSTCRIT 620
|
||||
#define STRINGID_ZMOVERESTOREHP 621
|
||||
#define STRINGID_ZMOVESTATUP 622
|
||||
#define STRINGID_ZMOVEHPTRAP 623
|
||||
#define STRINGID_TERRAINREMOVED 624
|
||||
|
||||
#define BATTLESTRINGS_COUNT 616
|
||||
#define BATTLESTRINGS_COUNT 625
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
@ -886,4 +895,13 @@
|
||||
#define B_MSG_WRAPPED_SNAP_TRAP 8
|
||||
#define TRAPPING_MOVES_COUNT 9
|
||||
|
||||
// z effects
|
||||
#define B_MSG_Z_RESET_STATS 0
|
||||
#define B_MSG_Z_ALL_STATS_UP 1
|
||||
#define B_MSG_Z_BOOST_CRITS 2
|
||||
#define B_MSG_Z_FOLLOW_ME 3
|
||||
#define B_MSG_Z_RECOVER_HP 4
|
||||
#define B_MSG_Z_STAT_UP 5
|
||||
#define B_MSG_Z_HP_TRAP 6
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H
|
||||
|
@ -784,6 +784,49 @@
|
||||
|
||||
#define MOVES_COUNT_GEN8 755
|
||||
|
||||
#define MOVES_COUNT MOVES_COUNT_GEN8
|
||||
#define MOVES_COUNT MOVES_COUNT_GEN8
|
||||
|
||||
// Z Moves
|
||||
#define MOVE_BREAKNECK_BLITZ (MOVES_COUNT + 0)
|
||||
#define MOVE_ALL_OUT_PUMMELING (MOVES_COUNT + 1)
|
||||
#define MOVE_SUPERSONIC_SKYSTRIKE (MOVES_COUNT + 2)
|
||||
#define MOVE_ACID_DOWNPOUR (MOVES_COUNT + 3)
|
||||
#define MOVE_TECTONIC_RAGE (MOVES_COUNT + 4)
|
||||
#define MOVE_CONTINENTAL_CRUSH (MOVES_COUNT + 5)
|
||||
#define MOVE_SAVAGE_SPIN_OUT (MOVES_COUNT + 6)
|
||||
#define MOVE_NEVER_ENDING_NIGHTMARE (MOVES_COUNT + 7)
|
||||
#define MOVE_CORKSCREW_CRASH (MOVES_COUNT + 8)
|
||||
#define MOVE_INFERNO_OVERDRIVE (MOVES_COUNT + 9)
|
||||
#define MOVE_HYDRO_VORTEX (MOVES_COUNT + 10)
|
||||
#define MOVE_BLOOM_DOOM (MOVES_COUNT + 11)
|
||||
#define MOVE_GIGAVOLT_HAVOC (MOVES_COUNT + 12)
|
||||
#define MOVE_SHATTERED_PSYCHE (MOVES_COUNT + 13)
|
||||
#define MOVE_SUBZERO_SLAMMER (MOVES_COUNT + 14)
|
||||
#define MOVE_DEVASTATING_DRAKE (MOVES_COUNT + 15)
|
||||
#define MOVE_BLACK_HOLE_ECLIPSE (MOVES_COUNT + 16)
|
||||
#define MOVE_TWINKLE_TACKLE (MOVES_COUNT + 17)
|
||||
// Signature Z Moves
|
||||
#define MOVE_CATASTROPIKA (MOVES_COUNT + 18)
|
||||
#define MOVE_10000000_VOLT_THUNDERBOLT (MOVES_COUNT + 19)
|
||||
#define MOVE_STOKED_SPARKSURFER (MOVES_COUNT + 20)
|
||||
#define MOVE_EXTREME_EVOBOOST (MOVES_COUNT + 21)
|
||||
#define MOVE_PULVERIZING_PANCAKE (MOVES_COUNT + 22)
|
||||
#define MOVE_GENESIS_SUPERNOVA (MOVES_COUNT + 23)
|
||||
#define MOVE_SINISTER_ARROW_RAID (MOVES_COUNT + 24)
|
||||
#define MOVE_MALICIOUS_MOONSAULT (MOVES_COUNT + 25)
|
||||
#define MOVE_OCEANIC_OPERETTA (MOVES_COUNT + 26)
|
||||
#define MOVE_SPLINTERED_STORMSHARDS (MOVES_COUNT + 27)
|
||||
#define MOVE_LETS_SNUGGLE_FOREVER (MOVES_COUNT + 28)
|
||||
#define MOVE_CLANGOROUS_SOULBLAZE (MOVES_COUNT + 29)
|
||||
#define MOVE_GUARDIAN_OF_ALOLA (MOVES_COUNT + 30)
|
||||
#define MOVE_SEARING_SUNRAZE_SMASH (MOVES_COUNT + 31)
|
||||
#define MOVE_MENACING_MOONRAZE_MAELSTROM (MOVES_COUNT + 32)
|
||||
#define MOVE_LIGHT_THAT_BURNS_THE_SKY (MOVES_COUNT + 33)
|
||||
#define MOVE_SOUL_STEALING_7_STAR_STRIKE (MOVES_COUNT + 34)
|
||||
|
||||
#define FIRST_Z_MOVE MOVE_BREAKNECK_BLITZ
|
||||
#define LAST_Z_MOVE MOVE_SOUL_STEALING_7_STAR_STRIKE
|
||||
|
||||
#define MOVES_COUNT_Z (LAST_Z_MOVE + 1)
|
||||
|
||||
#endif // GUARD_CONSTANTS_MOVES_H
|
||||
|
38
include/constants/z_move_effects.h
Normal file
38
include/constants/z_move_effects.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef GUARD_Z_MOVE_EFFECTS_H
|
||||
#define GUARD_Z_MOVE_EFFECTS_H
|
||||
|
||||
#define Z_EFFECT_NONE 0
|
||||
#define Z_EFFECT_RESET_STATS 1
|
||||
#define Z_EFFECT_ALL_STATS_UP_1 2
|
||||
#define Z_EFFECT_BOOST_CRITS 3
|
||||
#define Z_EFFECT_FOLLOW_ME 4
|
||||
#define Z_EFFECT_CURSE 5
|
||||
#define Z_EFFECT_RECOVER_HP 6
|
||||
#define Z_EFFECT_RESTORE_REPLACEMENT_HP 7
|
||||
|
||||
#define Z_EFFECT_ATK_UP_1 8
|
||||
#define Z_EFFECT_DEF_UP_1 9
|
||||
#define Z_EFFECT_SPD_UP_1 10
|
||||
#define Z_EFFECT_SPATK_UP_1 11
|
||||
#define Z_EFFECT_SPDEF_UP_1 12
|
||||
#define Z_EFFECT_ACC_UP_1 13
|
||||
#define Z_EFFECT_EVSN_UP_1 14
|
||||
|
||||
#define Z_EFFECT_ATK_UP_2 15
|
||||
#define Z_EFFECT_DEF_UP_2 16
|
||||
#define Z_EFFECT_SPD_UP_2 17
|
||||
#define Z_EFFECT_SPATK_UP_2 18
|
||||
#define Z_EFFECT_SPDEF_UP_2 19
|
||||
#define Z_EFFECT_ACC_UP_2 20
|
||||
#define Z_EFFECT_EVSN_UP_2 21
|
||||
|
||||
#define Z_EFFECT_ATK_UP_3 22
|
||||
#define Z_EFFECT_DEF_UP_3 23
|
||||
#define Z_EFFECT_SPD_UP_3 24
|
||||
#define Z_EFFECT_SPATK_UP_3 25
|
||||
#define Z_EFFECT_SPDEF_UP_3 26
|
||||
#define Z_EFFECT_ACC_UP_3 27
|
||||
#define Z_EFFECT_EVSN_UP_3 28
|
||||
|
||||
|
||||
#endif // GUARD_Z_MOVE_EFFECTS_H
|
@ -126,5 +126,6 @@ extern const struct Trainer gTrainers[];
|
||||
extern const u8 gTrainerClassNames[][13];
|
||||
extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1];
|
||||
extern const u8 gMoveNames[MOVES_COUNT][MOVE_NAME_LENGTH + 1];
|
||||
extern const u8 *const gZMoveNames[];
|
||||
|
||||
#endif // GUARD_DATA_H
|
||||
|
@ -231,7 +231,7 @@ struct BaseStats
|
||||
struct BattleMove
|
||||
{
|
||||
u16 effect;
|
||||
u8 power;
|
||||
u16 power; //higher than 255 for z moves
|
||||
u8 type;
|
||||
u8 accuracy;
|
||||
u8 pp;
|
||||
@ -241,6 +241,8 @@ struct BattleMove
|
||||
u32 flags;
|
||||
u8 split;
|
||||
u8 argument;
|
||||
u8 zMovePower;
|
||||
u8 zMoveEffect;
|
||||
};
|
||||
|
||||
#define SPINDA_SPOT_WIDTH 16
|
||||
|
@ -91,6 +91,7 @@ SECTIONS {
|
||||
src/battle_bg.o(.text);
|
||||
src/battle_main.o(.text);
|
||||
src/battle_util.o(.text);
|
||||
src/battle_z_move.o(.text);
|
||||
src/battle_script_commands.o(.text);
|
||||
src/battle_util2.o(.text);
|
||||
src/battle_controller_player.o(.text);
|
||||
@ -481,6 +482,7 @@ SECTIONS {
|
||||
src/battle_bg.o(.rodata);
|
||||
src/battle_main.o(.rodata);
|
||||
src/battle_util.o(.rodata);
|
||||
src/battle_z_move.o(.rodata);
|
||||
src/battle_script_commands.o(.rodata);
|
||||
src/battle_controller_player.o(.rodata);
|
||||
src/battle_anim_smokescreen.o(.rodata);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "battle_ai_main.h"
|
||||
#include "battle_factory.h"
|
||||
#include "battle_setup.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "data.h"
|
||||
#include "event_data.h"
|
||||
#include "item.h"
|
||||
@ -255,8 +256,8 @@ void GetAiLogicData(void)
|
||||
|
||||
memset(AI_DATA, 0, sizeof(struct AiLogicData));
|
||||
|
||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER)
|
||||
&& !IsWildMonSmart()))
|
||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER))
|
||||
&& !IsWildMonSmart())
|
||||
return;
|
||||
|
||||
// get/assume all battler data
|
||||
@ -291,7 +292,7 @@ void GetAiLogicData(void)
|
||||
&& move != 0xFFFF
|
||||
//&& gBattleMoves[move].power != 0 /* we want to get effectiveness of status moves */
|
||||
&& !(AI_DATA->moveLimitations[battlerAtk] & gBitTable[i])) {
|
||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness);
|
||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE);
|
||||
}
|
||||
|
||||
AI_DATA->simulatedDmg[battlerAtk][battlerDef][i] = dmg;
|
||||
@ -985,8 +986,10 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score -= 20;
|
||||
else if (!HasMoveWithType(battlerAtk, TYPE_ELECTRIC))
|
||||
score -= 10;
|
||||
#if B_CHARGE_SPDEF_RAISE >= GEN_5
|
||||
else if (!BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPDEF))
|
||||
score -= 5;
|
||||
#endif
|
||||
break;
|
||||
case EFFECT_QUIVER_DANCE:
|
||||
case EFFECT_GEOMANCY:
|
||||
@ -2383,9 +2386,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
|| IsInstructBannedMove(instructedMove)
|
||||
|| MoveRequiresRecharging(instructedMove)
|
||||
|| MoveCallsOtherMove(instructedMove)
|
||||
#ifdef ITEM_Z_POWER_RING
|
||||
//|| (IsZMove(instructedMove))
|
||||
#endif
|
||||
|| IsZMove(instructedMove)
|
||||
|| (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF)
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_MULTIPLETURNS
|
||||
|| PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, AI_DATA->partnerMove))
|
||||
@ -2491,15 +2492,14 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
//break;
|
||||
//case EFFECT_BEAK_BLAST:
|
||||
//break;
|
||||
/*case EFFECT_SKY_DROP:
|
||||
case EFFECT_SKY_DROP:
|
||||
if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING))
|
||||
score -= 10;
|
||||
if (WillFaintFromWeather(battlerAtk)
|
||||
|| MoveBlockedBySubstitute(move, battlerAtk, battlerDef)
|
||||
|| GetSpeciesWeight(gBattleMons[battlerDef].species, AI_DATA->abilities[battlerDef], AI_DATA->holdEffects[battlerDef], battlerDef, TRUE) >= 2000) //200.0 kg
|
||||
if (BattlerWillFaintFromWeather(battlerAtk, AI_DATA->abilities[battlerAtk])
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| GetBattlerWeight(battlerDef) >= 2000) //200.0 kg
|
||||
score -= 10;
|
||||
break;
|
||||
*/
|
||||
/*case EFFECT_NO_RETREAT:
|
||||
if (TrappedByNoRetreat(battlerAtk))
|
||||
score -= 10;
|
||||
@ -4051,8 +4051,9 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
case EFFECT_CHARGE:
|
||||
if (HasDamagingMoveOfType(battlerAtk, TYPE_ELECTRIC))
|
||||
score += 2;
|
||||
|
||||
#if B_CHARGE_SPDEF_RAISE >= GEN_5
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPDEF, &score);
|
||||
#endif
|
||||
break;
|
||||
case EFFECT_TAUNT:
|
||||
if (IS_MOVE_STATUS(predictedMove))
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "global.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "malloc.h"
|
||||
#include "battle.h"
|
||||
#include "battle_anim.h"
|
||||
@ -374,15 +375,9 @@ static const u16 sIgnoreMoldBreakerMoves[] =
|
||||
MOVE_MOONGEIST_BEAM,
|
||||
MOVE_SUNSTEEL_STRIKE,
|
||||
MOVE_PHOTON_GEYSER,
|
||||
#ifdef MOVE_LIGHT_THAT_BURNS_THE_SKY
|
||||
MOVE_LIGHT_THAT_BURNS_THE_SKY,
|
||||
#endif
|
||||
#ifdef MOVE_MENACING_MOONRAZE_MAELSTROM
|
||||
MOVE_MENACING_MOONRAZE_MAELSTROM,
|
||||
#endif
|
||||
#ifdef MOVE_SEARING_SUNRAZE_SMASH
|
||||
MOVE_SEARING_SUNRAZE_SMASH,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const u16 sInstructBannedMoves[] =
|
||||
@ -605,7 +600,7 @@ bool32 AtMaxHp(u8 battlerId)
|
||||
bool32 IsBattlerTrapped(u8 battler, bool8 checkSwitch)
|
||||
{
|
||||
u8 holdEffect = AI_DATA->holdEffects[battler];
|
||||
if (IS_BATTLER_OF_TYPE(battler, TYPE_GHOST)
|
||||
if ((B_GHOSTS_ESCAPE >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
|
||||
|| (checkSwitch && holdEffect == HOLD_EFFECT_SHED_SHELL)
|
||||
|| (!checkSwitch && GetBattlerAbility(battler) == ABILITY_RUN_AWAY)
|
||||
|| (!checkSwitch && holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN))
|
||||
@ -616,7 +611,7 @@ bool32 IsBattlerTrapped(u8 battler, bool8 checkSwitch)
|
||||
{
|
||||
if (gBattleMons[battler].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED)
|
||||
|| IsAbilityPreventingEscape(battler)
|
||||
|| gStatuses3[battler] & (STATUS3_ROOTED) // TODO: sky drop target in air
|
||||
|| gStatuses3[battler] & (STATUS3_ROOTED | STATUS3_SKY_DROPPED)
|
||||
|| (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK))
|
||||
return TRUE;
|
||||
}
|
||||
@ -720,12 +715,19 @@ static bool32 AI_GetIfCrit(u32 move, u8 battlerAtk, u8 battlerDef)
|
||||
return isCrit;
|
||||
}
|
||||
|
||||
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness)
|
||||
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness, bool32 considerZPower)
|
||||
{
|
||||
s32 dmg, moveType, critDmg, normalDmg;
|
||||
s8 critChance;
|
||||
u16 effectivenessMultiplier;
|
||||
|
||||
if (considerZPower && IsViableZMove(battlerAtk, move))
|
||||
{
|
||||
//temporarily enable z moves for damage calcs
|
||||
gBattleStruct->zmove.baseMoves[battlerAtk] = move;
|
||||
gBattleStruct->zmove.active = TRUE;
|
||||
}
|
||||
|
||||
SaveBattlerData(battlerAtk);
|
||||
SaveBattlerData(battlerDef);
|
||||
|
||||
@ -800,6 +802,8 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness)
|
||||
// convert multiper to AI_EFFECTIVENESS_xX
|
||||
*typeEffectiveness = AI_GetEffectiveness(effectivenessMultiplier);
|
||||
|
||||
gBattleStruct->zmove.active = FALSE;
|
||||
gBattleStruct->zmove.baseMoves[battlerAtk] = MOVE_NONE;
|
||||
return dmg;
|
||||
}
|
||||
|
||||
@ -1102,7 +1106,7 @@ bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits)
|
||||
if (move != MOVE_NONE
|
||||
&& move != 0xFFFF
|
||||
&& !(unusable & gBitTable[i])
|
||||
&& AI_CalcDamage(move, battlerDef, battlerAtk, &effectiveness) >= gBattleMons[battlerAtk].hp)
|
||||
&& AI_CalcDamage(move, battlerDef, battlerAtk, &effectiveness, FALSE) >= gBattleMons[battlerAtk].hp)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@ -2053,7 +2057,9 @@ bool32 IsStatRaisingEffect(u16 effect)
|
||||
case EFFECT_EVASION_UP_2:
|
||||
case EFFECT_MINIMIZE:
|
||||
case EFFECT_DEFENSE_CURL:
|
||||
#if B_CHARGE_SPDEF_RAISE >= GEN_5
|
||||
case EFFECT_CHARGE:
|
||||
#endif
|
||||
case EFFECT_CALM_MIND:
|
||||
case EFFECT_COSMIC_POWER:
|
||||
case EFFECT_DRAGON_DANCE:
|
||||
@ -2457,13 +2463,13 @@ bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 mo
|
||||
|
||||
if (!IS_MOVE_STATUS(move) && (shouldSwitch
|
||||
|| (AtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH
|
||||
|| defAbility == ABILITY_STURDY || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD))))
|
||||
|| (defAbility == ABILITY_STURDY && B_STURDY >= GEN_5) || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD))))
|
||||
return PIVOT; // pivot to break sash/sturdy/multiscale
|
||||
}
|
||||
else if (!hasStatBoost)
|
||||
{
|
||||
if (!IS_MOVE_STATUS(move) && (AtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH
|
||||
|| defAbility == ABILITY_STURDY || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD)))
|
||||
|| (defAbility == ABILITY_STURDY && B_STURDY >= GEN_5) || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD)))
|
||||
return PIVOT; // pivot to break sash/sturdy/multiscale
|
||||
|
||||
if (shouldSwitch)
|
||||
@ -3219,7 +3225,7 @@ s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon
|
||||
battleMons[i] = gBattleMons[i];
|
||||
|
||||
PokemonToBattleMon(mon, &gBattleMons[battlerAtk]);
|
||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness);
|
||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, FALSE);
|
||||
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
gBattleMons[i] = battleMons[i];
|
||||
@ -3599,3 +3605,37 @@ bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//TODO - this could use some more sophisticated logic
|
||||
bool32 ShouldUseZMove(u8 battlerAtk, u8 battlerDef, u16 chosenMove)
|
||||
{
|
||||
// simple logic. just upgrades chosen move to z move if possible, unless regular move would kill opponent
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && battlerDef == BATTLE_PARTNER(battlerAtk))
|
||||
return FALSE; //don't use z move on partner
|
||||
if (gBattleStruct->zmove.used[battlerAtk])
|
||||
return FALSE; //cant use z move twice
|
||||
|
||||
if (IsViableZMove(battlerAtk, chosenMove))
|
||||
{
|
||||
u8 effectiveness;
|
||||
|
||||
#ifdef POKEMON_EXPANSION
|
||||
if (gBattleMons[battlerDef].ability == ABILITY_DISGUISE && gBattleMons[battlerDef].species == SPECIES_MIMIKYU)
|
||||
return FALSE; // Don't waste a Z-Move busting disguise
|
||||
if (gBattleMons[battlerDef].ability == ABILITY_ICE_FACE && gBattleMons[battlerDef].species == SPECIES_EISCUE && IS_MOVE_PHYSICAL(chosenMove))
|
||||
return FALSE; // Don't waste a Z-Move busting Ice Face
|
||||
#endif
|
||||
|
||||
if (IS_MOVE_STATUS(chosenMove) && !IS_MOVE_STATUS(gBattleStruct->zmove.chosenZMove))
|
||||
return FALSE;
|
||||
else if (!IS_MOVE_STATUS(chosenMove) && IS_MOVE_STATUS(gBattleStruct->zmove.chosenZMove))
|
||||
return FALSE;
|
||||
|
||||
if (!IS_MOVE_STATUS(chosenMove) && AI_CalcDamage(chosenMove, battlerAtk, battlerDef, &effectiveness, FALSE) >= gBattleMons[battlerDef].hp)
|
||||
return FALSE; // don't waste damaging z move if can otherwise faint target
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ static void AnimSoftBoiledEgg_Step4(struct Sprite *);
|
||||
static void AnimSoftBoiledEgg_Step4_Callback(struct Sprite *);
|
||||
static void AnimSpeedDust(struct Sprite *);
|
||||
static void AnimHealBellMusicNote(struct Sprite *);
|
||||
static void AnimMagentaHeart(struct Sprite *);
|
||||
static void AnimRedHeartProjectile(struct Sprite *);
|
||||
static void AnimRedHeartProjectile_Step(struct Sprite *);
|
||||
static void AnimRedHeartRising(struct Sprite *);
|
||||
@ -3101,7 +3100,7 @@ static void AnimHealBellMusicNote(struct Sprite *sprite)
|
||||
SetMusicNotePalette(sprite, gBattleAnimArgs[5], gBattleAnimArgs[6]);
|
||||
}
|
||||
|
||||
static void AnimMagentaHeart(struct Sprite *sprite)
|
||||
void AnimMagentaHeart(struct Sprite *sprite)
|
||||
{
|
||||
if (++sprite->data[0] == 1)
|
||||
InitSpritePosToAnimAttacker(sprite, FALSE);
|
||||
|
@ -66,8 +66,6 @@ static void AnimPainSplitProjectile(struct Sprite *);
|
||||
static void AnimFlatterConfetti(struct Sprite *);
|
||||
static void AnimFlatterConfetti_Step(struct Sprite *);
|
||||
static void AnimFlatterSpotlight(struct Sprite *);
|
||||
static void AnimFlatterSpotlight_Step(struct Sprite *);
|
||||
static void AnimReversalOrb(struct Sprite *);
|
||||
static void AnimReversalOrb_Step(struct Sprite *);
|
||||
static void AnimYawnCloud(struct Sprite *);
|
||||
static void AnimYawnCloud_Step(struct Sprite *);
|
||||
@ -76,7 +74,6 @@ static void AnimFacadeSweatDrop(struct Sprite *);
|
||||
static void AnimRoarNoiseLine(struct Sprite *);
|
||||
static void AnimRoarNoiseLine_Step(struct Sprite *);
|
||||
static void AnimGlareEyeDot(struct Sprite *);
|
||||
static void AnimAssistPawprint(struct Sprite *);
|
||||
static void AnimSmellingSaltsHand(struct Sprite *);
|
||||
static void AnimSmellingSaltsHand_Step(struct Sprite *);
|
||||
static void AnimSmellingSaltExclamation(struct Sprite *);
|
||||
@ -3200,7 +3197,7 @@ static void AnimFlatterSpotlight(struct Sprite *sprite)
|
||||
sprite->callback = AnimFlatterSpotlight_Step;
|
||||
}
|
||||
|
||||
static void AnimFlatterSpotlight_Step(struct Sprite *sprite)
|
||||
void AnimFlatterSpotlight_Step(struct Sprite *sprite)
|
||||
{
|
||||
switch (sprite->data[1])
|
||||
{
|
||||
@ -3234,7 +3231,7 @@ static void AnimFlatterSpotlight_Step(struct Sprite *sprite)
|
||||
// Spins an orb around the attacking mon, while its path radius grows and shrinks.
|
||||
// arg 0: duration
|
||||
// arg 1: initial wave offset
|
||||
static void AnimReversalOrb(struct Sprite *sprite)
|
||||
void AnimReversalOrb(struct Sprite *sprite)
|
||||
{
|
||||
sprite->x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
|
||||
sprite->y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
|
||||
@ -4162,7 +4159,7 @@ static void AnimGlareEyeDot(struct Sprite *sprite)
|
||||
// arg 2: destination x position
|
||||
// arg 3: destination y position
|
||||
// arg 4: duration
|
||||
static void AnimAssistPawprint(struct Sprite *sprite)
|
||||
void AnimAssistPawprint(struct Sprite *sprite)
|
||||
{
|
||||
sprite->x = gBattleAnimArgs[0];
|
||||
sprite->y = gBattleAnimArgs[1];
|
||||
|
@ -15,7 +15,6 @@ static void AnimZapCannonSpark_Step(struct Sprite *);
|
||||
static void AnimThunderboltOrb(struct Sprite *);
|
||||
static void AnimThunderboltOrb_Step(struct Sprite *);
|
||||
static void AnimSparkElectricityFlashing_Step(struct Sprite *);
|
||||
static void AnimElectricity(struct Sprite *);
|
||||
static void AnimTask_ElectricBolt_Step(u8 taskId);
|
||||
static void AnimElectricBoltSegment(struct Sprite *);
|
||||
static void AnimThunderWave_Step(struct Sprite *);
|
||||
@ -758,7 +757,7 @@ static void AnimSparkElectricityFlashing_Step(struct Sprite *sprite)
|
||||
}
|
||||
|
||||
// Electricity arcs around the target. Used for Paralysis and various electric move hits
|
||||
static void AnimElectricity(struct Sprite *sprite)
|
||||
void AnimElectricity(struct Sprite *sprite)
|
||||
{
|
||||
if (!InitSpritePosToAnimBattler(gBattleAnimArgs[4], sprite, FALSE))
|
||||
return;
|
||||
|
@ -24,7 +24,6 @@ static void AnimSuperpowerOrb_Step(struct Sprite *);
|
||||
static void AnimSuperpowerRock(struct Sprite *);
|
||||
static void AnimSuperpowerRock_Step1(struct Sprite *);
|
||||
static void AnimSuperpowerRock_Step2(struct Sprite *);
|
||||
static void AnimSuperpowerFireball(struct Sprite *);
|
||||
static void AnimArmThrustHit(struct Sprite *);
|
||||
static void AnimArmThrustHit_Step(struct Sprite *sprite);
|
||||
static void AnimFocusPunchFist(struct Sprite *);
|
||||
@ -966,7 +965,7 @@ static void AnimSuperpowerRock_Step2(struct Sprite *sprite)
|
||||
DestroyAnimSprite(sprite);
|
||||
}
|
||||
|
||||
static void AnimSuperpowerFireball(struct Sprite *sprite)
|
||||
void AnimSuperpowerFireball(struct Sprite *sprite)
|
||||
{
|
||||
u8 battler;
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "trig.h"
|
||||
|
||||
static void AnimFireSpiralInward(struct Sprite *);
|
||||
static void AnimFirePlume(struct Sprite *);
|
||||
static void AnimLargeFlame(struct Sprite *);
|
||||
static void AnimLargeFlame_Step(struct Sprite *);
|
||||
static void AnimUnusedSmallEmber(struct Sprite *);
|
||||
@ -21,7 +20,6 @@ static void AnimFireRing_Step1(struct Sprite *);
|
||||
static void AnimFireRing_Step2(struct Sprite *);
|
||||
static void AnimFireRing_Step3(struct Sprite *);
|
||||
static void UpdateFireRingCircleOffset(struct Sprite *);
|
||||
static void AnimFireCross(struct Sprite *);
|
||||
static void AnimFireSpiralOutward_Step1(struct Sprite *);
|
||||
static void AnimFireSpiralOutward_Step2(struct Sprite *);
|
||||
static void AnimTask_EruptionLaunchRocks_Step(u8 taskId);
|
||||
@ -30,9 +28,7 @@ static void AnimEruptionLaunchRock(struct Sprite *);
|
||||
static u16 GetEruptionLaunchRockInitialYPos(u8 spriteId);
|
||||
static void InitEruptionLaunchRockCoordData(struct Sprite *sprite, s16 x, s16 y);
|
||||
static void UpdateEruptionLaunchRockPos(struct Sprite *);
|
||||
static void AnimEruptionFallingRock(struct Sprite *);
|
||||
static void AnimEruptionFallingRock_Step(struct Sprite *);
|
||||
static void AnimWillOWispOrb(struct Sprite *);
|
||||
static void AnimWillOWispOrb_Step(struct Sprite *);
|
||||
static void AnimWillOWispFire(struct Sprite *);
|
||||
static void AnimTask_MoveHeatWaveTargets_Step(u8 taskId);
|
||||
@ -111,7 +107,7 @@ static const union AnimCmd sAnim_FirePlume[] =
|
||||
ANIMCMD_JUMP(0),
|
||||
};
|
||||
|
||||
static const union AnimCmd *const sAnims_FirePlume[] =
|
||||
const union AnimCmd *const gAnims_FirePlume[] =
|
||||
{
|
||||
sAnim_FirePlume,
|
||||
};
|
||||
@ -155,7 +151,7 @@ const struct SpriteTemplate gFirePlumeSpriteTemplate =
|
||||
.tileTag = ANIM_TAG_FIRE_PLUME,
|
||||
.paletteTag = ANIM_TAG_FIRE_PLUME,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = sAnims_FirePlume,
|
||||
.anims = gAnims_FirePlume,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimFirePlume,
|
||||
@ -167,7 +163,7 @@ static const struct SpriteTemplate sUnusedEmberFirePlumeSpriteTemplate =
|
||||
.tileTag = ANIM_TAG_SMALL_EMBER,
|
||||
.paletteTag = ANIM_TAG_SMALL_EMBER,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = sAnims_FirePlume,
|
||||
.anims = gAnims_FirePlume,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimFirePlume,
|
||||
@ -428,7 +424,7 @@ static const union AnimCmd sAnim_WillOWispOrb_3[] =
|
||||
ANIMCMD_END,
|
||||
};
|
||||
|
||||
static const union AnimCmd *const sAnims_WillOWispOrb[] =
|
||||
const union AnimCmd *const gAnims_WillOWispOrb[] =
|
||||
{
|
||||
sAnim_WillOWispOrb_0,
|
||||
sAnim_WillOWispOrb_1,
|
||||
@ -441,7 +437,7 @@ const struct SpriteTemplate gWillOWispOrbSpriteTemplate =
|
||||
.tileTag = ANIM_TAG_WISP_ORB,
|
||||
.paletteTag = ANIM_TAG_WISP_ORB,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_16x16,
|
||||
.anims = sAnims_WillOWispOrb,
|
||||
.anims = gAnims_WillOWispOrb,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimWillOWispOrb,
|
||||
@ -502,7 +498,7 @@ const struct SpriteTemplate gLavaPlumeSpriteTemplate =
|
||||
.tileTag = ANIM_TAG_FIRE_PLUME,
|
||||
.paletteTag = ANIM_TAG_FIRE_PLUME,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = sAnims_FirePlume,
|
||||
.anims = gAnims_FirePlume,
|
||||
.images = NULL,
|
||||
.affineAnims = gLavaPlumeAffineAnims,
|
||||
.callback = AnimLavaPlumeOrbitScatter,
|
||||
@ -576,7 +572,7 @@ void AnimFireSpread(struct Sprite *sprite)
|
||||
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
|
||||
}
|
||||
|
||||
static void AnimFirePlume(struct Sprite *sprite)
|
||||
void AnimFirePlume(struct Sprite *sprite)
|
||||
{
|
||||
SetSpriteCoordsToAnimAttackerCoords(sprite);
|
||||
|
||||
@ -806,7 +802,7 @@ static void UpdateFireRingCircleOffset(struct Sprite *sprite)
|
||||
// arg 3: x delta
|
||||
// arg 4: y delta
|
||||
// AnimFireCross(struct Sprite *sprite)
|
||||
static void AnimFireCross(struct Sprite *sprite)
|
||||
void AnimFireCross(struct Sprite *sprite)
|
||||
{
|
||||
sprite->x += gBattleAnimArgs[0];
|
||||
sprite->y += gBattleAnimArgs[1];
|
||||
@ -1075,7 +1071,7 @@ static void UpdateEruptionLaunchRockPos(struct Sprite *sprite)
|
||||
sprite->invisible = TRUE;
|
||||
}
|
||||
|
||||
static void AnimEruptionFallingRock(struct Sprite *sprite)
|
||||
void AnimEruptionFallingRock(struct Sprite *sprite)
|
||||
{
|
||||
sprite->x = gBattleAnimArgs[0];
|
||||
sprite->y = gBattleAnimArgs[1];
|
||||
@ -1133,7 +1129,7 @@ static void AnimEruptionFallingRock_Step(struct Sprite *sprite)
|
||||
}
|
||||
}
|
||||
|
||||
static void AnimWillOWispOrb(struct Sprite *sprite)
|
||||
void AnimWillOWispOrb(struct Sprite *sprite)
|
||||
{
|
||||
switch (sprite->data[0])
|
||||
{
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
extern const struct SpriteTemplate gFlashingHitSplatSpriteTemplate;
|
||||
|
||||
static void AnimEllipticalGust(struct Sprite *);
|
||||
static void AnimEllipticalGust_Step(struct Sprite *);
|
||||
static void AnimGustToTarget(struct Sprite *);
|
||||
static void AnimGustToTarget_Step(struct Sprite *);
|
||||
@ -20,7 +19,6 @@ static void AnimWhirlwindLine_Step(struct Sprite *);
|
||||
static void AnimUnusedBubbleThrow(struct Sprite *);
|
||||
static void AnimWhirlwindLine(struct Sprite *);
|
||||
static void AnimBounceBallShrink(struct Sprite *);
|
||||
static void AnimBounceBallLand(struct Sprite *);
|
||||
static void AnimDiveBall(struct Sprite *);
|
||||
static void AnimDiveBall_Step1(struct Sprite *);
|
||||
static void AnimDiveBall_Step2(struct Sprite *);
|
||||
@ -246,7 +244,7 @@ static const union AffineAnimCmd sAffineAnim_BounceBallLand[] =
|
||||
AFFINEANIMCMD_END,
|
||||
};
|
||||
|
||||
static const union AffineAnimCmd *const sAffineAnims_BounceBallLand[] =
|
||||
const union AffineAnimCmd *const gAffineAnims_BounceBallLand[] =
|
||||
{
|
||||
sAffineAnim_BounceBallLand,
|
||||
};
|
||||
@ -258,7 +256,7 @@ const struct SpriteTemplate gBounceBallLandSpriteTemplate =
|
||||
.oam = &gOamData_AffineDouble_ObjNormal_64x64,
|
||||
.anims = gDummySpriteAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = sAffineAnims_BounceBallLand,
|
||||
.affineAnims = gAffineAnims_BounceBallLand,
|
||||
.callback = AnimBounceBallLand,
|
||||
};
|
||||
|
||||
@ -347,7 +345,7 @@ const struct SpriteTemplate gSkyAttackBirdSpriteTemplate =
|
||||
};
|
||||
|
||||
|
||||
static void AnimEllipticalGust(struct Sprite *sprite)
|
||||
void AnimEllipticalGust(struct Sprite *sprite)
|
||||
{
|
||||
InitSpritePosToAnimTarget(sprite, FALSE);
|
||||
sprite->y += 20;
|
||||
@ -980,7 +978,7 @@ static void AnimBounceBallShrink(struct Sprite *sprite)
|
||||
}
|
||||
}
|
||||
|
||||
static void AnimBounceBallLand(struct Sprite *sprite)
|
||||
void AnimBounceBallLand(struct Sprite *sprite)
|
||||
{
|
||||
switch (sprite->data[0])
|
||||
{
|
||||
|
@ -1442,3 +1442,68 @@ static void AnimPoltergeistItem(struct Sprite *sprite)
|
||||
if (sprite->data[2] == 256)
|
||||
DestroyAnimSprite(sprite);
|
||||
}
|
||||
|
||||
//pulverizing pancake - destiny bond shadow from attacker to target
|
||||
void AnimTask_PulverizingPancakeWhiteShadow(u8 taskId)
|
||||
{
|
||||
struct Task *task;
|
||||
s16 battler;
|
||||
u8 spriteId;
|
||||
s16 baseX, baseY;
|
||||
s16 x, y;
|
||||
|
||||
task = &gTasks[taskId];
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
|
||||
task->data[5] = 0;
|
||||
task->data[6] = 0;
|
||||
task->data[7] = 0;
|
||||
task->data[8] = 0;
|
||||
task->data[9] = 16;
|
||||
task->data[10] = gBattleAnimArgs[0];
|
||||
|
||||
baseX = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
|
||||
baseY = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_BOTTOM);
|
||||
if (!IsContest())
|
||||
{
|
||||
spriteId = CreateSprite(&gDestinyBondWhiteShadowSpriteTemplate, baseX, baseY, 55);
|
||||
if (spriteId != MAX_SPRITES)
|
||||
{
|
||||
x = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
|
||||
y = GetBattlerSpriteCoordAttr(gBattleAnimTarget, BATTLER_COORD_ATTR_BOTTOM);
|
||||
gSprites[spriteId].data[0] = baseX << 4;
|
||||
gSprites[spriteId].data[1] = baseY << 4;
|
||||
gSprites[spriteId].data[2] = ((x - baseX) << 4) / gBattleAnimArgs[1];
|
||||
gSprites[spriteId].data[3] = ((y - baseY) << 4) / gBattleAnimArgs[1];
|
||||
gSprites[spriteId].data[4] = gBattleAnimArgs[1];
|
||||
gSprites[spriteId].data[5] = x;
|
||||
gSprites[spriteId].data[6] = y;
|
||||
gSprites[spriteId].callback = AnimDestinyBondWhiteShadow_Step;
|
||||
|
||||
task->data[task->data[12] + 13] = spriteId;
|
||||
task->data[12]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteId = CreateSprite(&gDestinyBondWhiteShadowSpriteTemplate, baseX, baseY, 55);
|
||||
if (spriteId != MAX_SPRITES)
|
||||
{
|
||||
x = 48;
|
||||
y = 40;
|
||||
gSprites[spriteId].data[0] = baseX << 4;
|
||||
gSprites[spriteId].data[1] = baseY << 4;
|
||||
gSprites[spriteId].data[2] = ((x - baseX) << 4) / gBattleAnimArgs[1];
|
||||
gSprites[spriteId].data[3] = ((y - baseY) << 4) / gBattleAnimArgs[1];
|
||||
gSprites[spriteId].data[4] = gBattleAnimArgs[1];
|
||||
gSprites[spriteId].data[5] = x;
|
||||
gSprites[spriteId].data[6] = y;
|
||||
gSprites[spriteId].callback = AnimDestinyBondWhiteShadow_Step;
|
||||
|
||||
task->data[13] = spriteId;
|
||||
task->data[12] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
task->func = AnimTask_DestinyBondWhiteShadow_Step;
|
||||
}
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
static void AnimBonemerangProjectile(struct Sprite *);
|
||||
static void AnimBoneHitProjectile(struct Sprite *);
|
||||
static void AnimDirtPlumeParticle(struct Sprite *);
|
||||
static void AnimDirtPlumeParticle_Step(struct Sprite *);
|
||||
static void AnimDigDirtMound(struct Sprite *);
|
||||
static void AnimBonemerangProjectile_Step(struct Sprite *);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,6 @@ static void AnimSludgeProjectile_Step(struct Sprite *);
|
||||
static void AnimAcidPoisonBubble(struct Sprite *);
|
||||
static void AnimSludgeBombHitParticle_Step(struct Sprite *);
|
||||
static void AnimAcidPoisonDroplet(struct Sprite *);
|
||||
static void AnimBubbleEffect(struct Sprite *);
|
||||
static void AnimBubbleEffect_Step(struct Sprite *);
|
||||
static void AnimSuckerPunchStep(struct Sprite *sprite);
|
||||
static void AnimSuckerPunch(struct Sprite *sprite);
|
||||
@ -161,7 +160,7 @@ static const union AffineAnimCmd sAffineAnim_Bubble[] =
|
||||
AFFINEANIMCMD_END,
|
||||
};
|
||||
|
||||
static const union AffineAnimCmd *const sAffineAnims_Bubble[] =
|
||||
const union AffineAnimCmd *const gAffineAnims_Bubble[] =
|
||||
{
|
||||
sAffineAnim_Bubble,
|
||||
};
|
||||
@ -173,7 +172,7 @@ const struct SpriteTemplate gPoisonBubbleSpriteTemplate =
|
||||
.oam = &gOamData_AffineNormal_ObjNormal_16x16,
|
||||
.anims = gAnims_PoisonProjectile,
|
||||
.images = NULL,
|
||||
.affineAnims = sAffineAnims_Bubble,
|
||||
.affineAnims = gAffineAnims_Bubble,
|
||||
.callback = AnimBubbleEffect,
|
||||
};
|
||||
|
||||
@ -184,7 +183,7 @@ const struct SpriteTemplate gWaterBubbleSpriteTemplate =
|
||||
.oam = &gOamData_AffineNormal_ObjBlend_16x16,
|
||||
.anims = gAnims_WaterBubble,
|
||||
.images = NULL,
|
||||
.affineAnims = sAffineAnims_Bubble,
|
||||
.affineAnims = gAffineAnims_Bubble,
|
||||
.callback = AnimBubbleEffect,
|
||||
};
|
||||
|
||||
@ -505,7 +504,7 @@ static void AnimAcidPoisonDroplet(struct Sprite *sprite)
|
||||
// arg 0: initial x pixel offset
|
||||
// arg 1: initial y pixel offset
|
||||
// arg 2: 0 = single-target, 1 = multi-target
|
||||
static void AnimBubbleEffect(struct Sprite *sprite)
|
||||
void AnimBubbleEffect(struct Sprite *sprite)
|
||||
{
|
||||
if (!gBattleAnimArgs[2])
|
||||
{
|
||||
|
@ -703,6 +703,54 @@ void AnimTask_Rollout(u8 taskId)
|
||||
task->func = AnimTask_Rollout_Step;
|
||||
}
|
||||
|
||||
void AnimTask_TectonicRageRollout(u8 taskId)
|
||||
{
|
||||
u16 var0, var1, var2, var3;
|
||||
int var5;
|
||||
s16 pan1, pan2;
|
||||
struct Task *task;
|
||||
u8 rolloutCounter = 1;
|
||||
|
||||
task = &gTasks[taskId];
|
||||
|
||||
var0 = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
|
||||
var1 = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 24;
|
||||
var2 = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
|
||||
var3 = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + 24;
|
||||
|
||||
if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget)
|
||||
var3 = var1;
|
||||
|
||||
task->data[8] = 48 - (rolloutCounter * 8); //rollout speed
|
||||
task->data[0] = 0;
|
||||
task->data[11] = 0;
|
||||
task->data[9] = 0;
|
||||
task->data[12] = 1;
|
||||
|
||||
var5 = task->data[8];
|
||||
if (var5 < 0)
|
||||
var5 += 7;
|
||||
|
||||
task->data[10] = (var5 >> 3) - 1;
|
||||
|
||||
task->data[2] = var0 * 8;
|
||||
task->data[3] = var1 * 8;
|
||||
task->data[4] = ((var2 - var0) * 8) / task->data[8];
|
||||
task->data[5] = ((var3 - var1) * 8) / task->data[8];
|
||||
task->data[6] = 0;
|
||||
task->data[7] = 0;
|
||||
|
||||
pan1 = BattleAnimAdjustPanning(-64);
|
||||
pan2 = BattleAnimAdjustPanning(63);
|
||||
|
||||
task->data[13] = pan1;
|
||||
task->data[14] = (pan2 - pan1) / task->data[8];
|
||||
task->data[1] = rolloutCounter;
|
||||
task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
|
||||
|
||||
task->func = AnimTask_Rollout_Step;
|
||||
}
|
||||
|
||||
static void AnimTask_Rollout_Step(u8 taskId)
|
||||
{
|
||||
struct Task *task;
|
||||
|
@ -107,7 +107,7 @@ static const union AnimCmd sAnim_SpinningSparkle[] =
|
||||
ANIMCMD_END
|
||||
};
|
||||
|
||||
static const union AnimCmd *const sAnims_SpinningSparkle[] =
|
||||
const union AnimCmd *const sAnims_SpinningSparkle[] =
|
||||
{
|
||||
sAnim_SpinningSparkle
|
||||
};
|
||||
@ -379,6 +379,25 @@ static void AnimFlashingCircleImpact_Step(struct Sprite *sprite)
|
||||
}
|
||||
}
|
||||
|
||||
void AnimTask_FrozenIceCubeAttacker(u8 taskId)
|
||||
{
|
||||
s16 x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) - 32;
|
||||
s16 y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET) - 36;
|
||||
u8 spriteId;
|
||||
|
||||
if (IsContest())
|
||||
x -= 6;
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
|
||||
spriteId = CreateSprite(&gFrozenIceCubeSpriteTemplate, x, y, 4);
|
||||
if (GetSpriteTileStartByTag(ANIM_TAG_ICE_CUBE) == 0xFFFF)
|
||||
gSprites[spriteId].invisible = TRUE;
|
||||
SetSubspriteTables(&gSprites[spriteId], sFrozenIceCubeSubspriteTable);
|
||||
gTasks[taskId].data[15] = spriteId;
|
||||
gTasks[taskId].func = AnimTask_FrozenIceCube_Step1;
|
||||
}
|
||||
|
||||
|
||||
void AnimTask_FrozenIceCube(u8 taskId)
|
||||
{
|
||||
s16 x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) - 32;
|
||||
|
@ -194,7 +194,7 @@ static const struct WindowTemplate gStandardBattleWindowTemplates[] =
|
||||
.bg = 0,
|
||||
.tilemapLeft = 2,
|
||||
.tilemapTop = 55,
|
||||
.width = 8,
|
||||
.width = 12, //for z move names
|
||||
.height = 2,
|
||||
.paletteNum = 5,
|
||||
.baseBlock = 0x0300,
|
||||
@ -206,7 +206,7 @@ static const struct WindowTemplate gStandardBattleWindowTemplates[] =
|
||||
.width = 8,
|
||||
.height = 2,
|
||||
.paletteNum = 5,
|
||||
.baseBlock = 0x0310,
|
||||
.baseBlock = 0x0318,
|
||||
},
|
||||
[B_WIN_MOVE_NAME_3] = {
|
||||
.bg = 0,
|
||||
@ -215,7 +215,7 @@ static const struct WindowTemplate gStandardBattleWindowTemplates[] =
|
||||
.width = 8,
|
||||
.height = 2,
|
||||
.paletteNum = 5,
|
||||
.baseBlock = 0x0320,
|
||||
.baseBlock = 0x0328,
|
||||
},
|
||||
[B_WIN_MOVE_NAME_4] = {
|
||||
.bg = 0,
|
||||
@ -224,7 +224,7 @@ static const struct WindowTemplate gStandardBattleWindowTemplates[] =
|
||||
.width = 8,
|
||||
.height = 2,
|
||||
.paletteNum = 5,
|
||||
.baseBlock = 0x0330,
|
||||
.baseBlock = 0x0338,
|
||||
},
|
||||
[B_WIN_PP] = {
|
||||
.bg = 0,
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "global.h"
|
||||
#include "battle.h"
|
||||
#include "battle_ai_main.h"
|
||||
#include "battle_ai_util.h"
|
||||
#include "battle_anim.h"
|
||||
#include "battle_arena.h"
|
||||
#include "battle_controllers.h"
|
||||
@ -9,6 +10,7 @@
|
||||
#include "battle_setup.h"
|
||||
#include "battle_tower.h"
|
||||
#include "battle_tv.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "bg.h"
|
||||
#include "data.h"
|
||||
#include "frontier_util.h"
|
||||
@ -1580,16 +1582,25 @@ static void OpponentHandleChooseMove(void)
|
||||
gBattlerTarget = gActiveBattler;
|
||||
if (GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[chosenMoveId]) & MOVE_TARGET_BOTH)
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
||||
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
||||
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
||||
u16 chosenMove = moveInfo->moves[chosenMoveId];
|
||||
|
||||
if (gBattleMoves[chosenMove].target & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
|
||||
gBattlerTarget = gActiveBattler;
|
||||
if (gBattleMoves[chosenMove].target & MOVE_TARGET_BOTH)
|
||||
{
|
||||
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
||||
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
||||
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
||||
}
|
||||
|
||||
if (ShouldUseZMove(gActiveBattler, gBattlerTarget, chosenMove))
|
||||
QueueZMove(gActiveBattler, chosenMove);
|
||||
|
||||
if (CanMegaEvolve(gActiveBattler)) // If opponent can mega evolve, do it.
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8));
|
||||
else
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8));
|
||||
}
|
||||
|
||||
// If opponent can mega evolve, do it.
|
||||
if (CanMegaEvolve(gActiveBattler))
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8));
|
||||
else
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8));
|
||||
break;
|
||||
}
|
||||
OpponentBufferExecCompleted();
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "battle_message.h"
|
||||
#include "battle_setup.h"
|
||||
#include "battle_tv.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "bg.h"
|
||||
#include "data.h"
|
||||
#include "item.h"
|
||||
@ -98,8 +99,6 @@ static void PlayerCmdEnd(void);
|
||||
static void PlayerBufferRunCommand(void);
|
||||
static void HandleInputChooseTarget(void);
|
||||
static void HandleInputChooseMove(void);
|
||||
static void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1);
|
||||
static void MoveSelectionDestroyCursorAt(u8 cursorPos);
|
||||
static void MoveSelectionDisplayPpNumber(void);
|
||||
static void MoveSelectionDisplayPpString(void);
|
||||
static void MoveSelectionDisplayMoveType(void);
|
||||
@ -122,6 +121,8 @@ static void PlayerDoMoveAnimation(void);
|
||||
static void Task_StartSendOutAnim(u8 taskId);
|
||||
static void EndDrawPartyStatusSummary(void);
|
||||
|
||||
static void ReloadMoveNames(void);
|
||||
|
||||
static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
|
||||
{
|
||||
[CONTROLLER_GETMONDATA] = PlayerHandleGetMonData,
|
||||
@ -381,7 +382,7 @@ static void HandleInputChooseTarget(void)
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
|
||||
EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX);
|
||||
TryHideLastUsedBall();
|
||||
HideMegaTriggerSprite();
|
||||
HideTriggerSprites();
|
||||
PlayerBufferExecCompleted();
|
||||
}
|
||||
else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59)
|
||||
@ -565,7 +566,7 @@ static void HandleInputShowTargets(void)
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
|
||||
else
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
|
||||
HideMegaTriggerSprite();
|
||||
HideTriggerSprites();
|
||||
TryHideLastUsedBall();
|
||||
PlayerBufferExecCompleted();
|
||||
}
|
||||
@ -613,7 +614,17 @@ static void HandleInputChooseMove(void)
|
||||
{
|
||||
moveTarget = GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]);
|
||||
}
|
||||
|
||||
|
||||
if (gBattleStruct->zmove.viewing)
|
||||
{
|
||||
u16 chosenMove = moveInfo->moves[gMoveSelectionCursor[gActiveBattler]];
|
||||
|
||||
QueueZMove(gActiveBattler, chosenMove);
|
||||
gBattleStruct->zmove.viewing = FALSE;
|
||||
if (gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]].split != SPLIT_STATUS)
|
||||
moveTarget = MOVE_TARGET_SELECTED; //damaging z moves always have selected target
|
||||
}
|
||||
|
||||
if (moveTarget & MOVE_TARGET_USER)
|
||||
gMultiUsePlayerCursor = gActiveBattler;
|
||||
else
|
||||
@ -671,7 +682,7 @@ static void HandleInputChooseMove(void)
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8));
|
||||
else
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
|
||||
HideMegaTriggerSprite();
|
||||
HideTriggerSprites();
|
||||
TryHideLastUsedBall();
|
||||
PlayerBufferExecCompleted();
|
||||
break;
|
||||
@ -698,12 +709,20 @@ static void HandleInputChooseMove(void)
|
||||
else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
gBattleStruct->mega.playerSelect = FALSE;
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, 0xFFFF);
|
||||
HideMegaTriggerSprite();
|
||||
PlayerBufferExecCompleted();
|
||||
if (gBattleStruct->zmove.viewing)
|
||||
{
|
||||
ReloadMoveNames();
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleStruct->mega.playerSelect = FALSE;
|
||||
gBattleStruct->zmove.viable = FALSE;
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, 10, 0xFFFF);
|
||||
HideTriggerSprites();
|
||||
PlayerBufferExecCompleted();
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_LEFT))
|
||||
else if (JOY_NEW(DPAD_LEFT) && !gBattleStruct->zmove.viewing)
|
||||
{
|
||||
if (gMoveSelectionCursor[gActiveBattler] & 1)
|
||||
{
|
||||
@ -713,9 +732,10 @@ static void HandleInputChooseMove(void)
|
||||
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0);
|
||||
MoveSelectionDisplayPpNumber();
|
||||
MoveSelectionDisplayMoveType();
|
||||
TryChangeZIndicator(gActiveBattler, gMoveSelectionCursor[gActiveBattler]);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_RIGHT))
|
||||
else if (JOY_NEW(DPAD_RIGHT) && !gBattleStruct->zmove.viewing)
|
||||
{
|
||||
if (!(gMoveSelectionCursor[gActiveBattler] & 1)
|
||||
&& (gMoveSelectionCursor[gActiveBattler] ^ 1) < gNumberOfMovesToChoose)
|
||||
@ -726,9 +746,10 @@ static void HandleInputChooseMove(void)
|
||||
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0);
|
||||
MoveSelectionDisplayPpNumber();
|
||||
MoveSelectionDisplayMoveType();
|
||||
TryChangeZIndicator(gActiveBattler, gMoveSelectionCursor[gActiveBattler]);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_UP))
|
||||
else if (JOY_NEW(DPAD_UP) && !gBattleStruct->zmove.viewing)
|
||||
{
|
||||
if (gMoveSelectionCursor[gActiveBattler] & 2)
|
||||
{
|
||||
@ -738,9 +759,10 @@ static void HandleInputChooseMove(void)
|
||||
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0);
|
||||
MoveSelectionDisplayPpNumber();
|
||||
MoveSelectionDisplayMoveType();
|
||||
TryChangeZIndicator(gActiveBattler, gMoveSelectionCursor[gActiveBattler]);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_DOWN))
|
||||
else if (JOY_NEW(DPAD_DOWN) && !gBattleStruct->zmove.viewing)
|
||||
{
|
||||
if (!(gMoveSelectionCursor[gActiveBattler] & 2)
|
||||
&& (gMoveSelectionCursor[gActiveBattler] ^ 2) < gNumberOfMovesToChoose)
|
||||
@ -751,9 +773,10 @@ static void HandleInputChooseMove(void)
|
||||
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0);
|
||||
MoveSelectionDisplayPpNumber();
|
||||
MoveSelectionDisplayMoveType();
|
||||
TryChangeZIndicator(gActiveBattler, gMoveSelectionCursor[gActiveBattler]);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(SELECT_BUTTON))
|
||||
else if (JOY_NEW(SELECT_BUTTON) && !gBattleStruct->zmove.viewing)
|
||||
{
|
||||
if (gNumberOfMovesToChoose > 1 && !(gBattleTypeFlags & BATTLE_TYPE_LINK))
|
||||
{
|
||||
@ -769,7 +792,7 @@ static void HandleInputChooseMove(void)
|
||||
gBattlerControllerFuncs[gActiveBattler] = HandleMoveSwitching;
|
||||
}
|
||||
}
|
||||
else if (gMain.newKeys & START_BUTTON)
|
||||
else if (JOY_NEW(START_BUTTON))
|
||||
{
|
||||
if (CanMegaEvolve(gActiveBattler))
|
||||
{
|
||||
@ -777,9 +800,30 @@ static void HandleInputChooseMove(void)
|
||||
ChangeMegaTriggerSprite(gBattleStruct->mega.triggerSpriteId, gBattleStruct->mega.playerSelect);
|
||||
PlaySE(SE_SELECT);
|
||||
}
|
||||
else if (gBattleStruct->zmove.viable)
|
||||
{
|
||||
// show z move name / info
|
||||
//TODO: brighten z move symbol
|
||||
PlaySE(SE_SELECT);
|
||||
if (!gBattleStruct->zmove.viewing)
|
||||
MoveSelectionDisplayZMove(gBattleStruct->zmove.chosenZMove);
|
||||
else
|
||||
ReloadMoveNames();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ReloadMoveNames(void)
|
||||
{
|
||||
gBattleStruct->mega.playerSelect = FALSE;
|
||||
gBattleStruct->zmove.viewing = FALSE;
|
||||
MoveSelectionDestroyCursorAt(0);
|
||||
MoveSelectionDisplayMoveNames();
|
||||
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0);
|
||||
MoveSelectionDisplayPpNumber();
|
||||
MoveSelectionDisplayMoveType();
|
||||
}
|
||||
|
||||
static u32 HandleMoveInputUnused(void)
|
||||
{
|
||||
u32 var = 0;
|
||||
@ -1684,7 +1728,7 @@ static void MoveSelectionDisplayMoveType(void)
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MOVE_TYPE);
|
||||
}
|
||||
|
||||
static void MoveSelectionCreateCursorAt(u8 cursorPosition, u8 arg1)
|
||||
void MoveSelectionCreateCursorAt(u8 cursorPosition, u8 arg1)
|
||||
{
|
||||
u16 src[2];
|
||||
src[0] = arg1 + 1;
|
||||
@ -1694,7 +1738,7 @@ static void MoveSelectionCreateCursorAt(u8 cursorPosition, u8 arg1)
|
||||
CopyBgTilemapBufferToVram(0);
|
||||
}
|
||||
|
||||
static void MoveSelectionDestroyCursorAt(u8 cursorPosition)
|
||||
void MoveSelectionDestroyCursorAt(u8 cursorPosition)
|
||||
{
|
||||
u16 src[2];
|
||||
src[0] = 0x1016;
|
||||
@ -2813,12 +2857,20 @@ static void PlayerHandleChooseMove(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]);
|
||||
|
||||
InitMoveSelectionsVarsAndStrings();
|
||||
gBattleStruct->mega.playerSelect = FALSE;
|
||||
if (!IsMegaTriggerSpriteActive())
|
||||
gBattleStruct->mega.triggerSpriteId = 0xFF;
|
||||
if (CanMegaEvolve(gActiveBattler))
|
||||
CreateMegaTriggerSprite(gActiveBattler, 0);
|
||||
if (!IsZMoveTriggerSpriteActive())
|
||||
gBattleStruct->zmove.triggerSpriteId = 0xFF;
|
||||
|
||||
GetUsableZMoves(gActiveBattler, moveInfo->moves);
|
||||
gBattleStruct->zmove.viable = IsZMoveUsable(gActiveBattler, gMoveSelectionCursor[gActiveBattler]);
|
||||
CreateZMoveTriggerSprite(gActiveBattler, gBattleStruct->zmove.viable);
|
||||
gBattlerControllerFuncs[gActiveBattler] = HandleChooseMoveAfterDma3;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
#include "global.h"
|
||||
#include "battle.h"
|
||||
#include "battle_ai_main.h"
|
||||
#include "battle_ai_util.h"
|
||||
#include "battle_anim.h"
|
||||
#include "battle_controllers.h"
|
||||
#include "battle_message.h"
|
||||
#include "battle_interface.h"
|
||||
#include "battle_setup.h"
|
||||
#include "battle_tower.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "bg.h"
|
||||
#include "data.h"
|
||||
#include "item_use.h"
|
||||
@ -1526,6 +1528,9 @@ static void PlayerPartnerHandleChooseMove(void)
|
||||
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
|
||||
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
||||
}
|
||||
|
||||
if (ShouldUseZMove(gActiveBattler, gBattlerTarget, moveInfo->moves[chosenMoveId]))
|
||||
QueueZMove(gActiveBattler, moveInfo->moves[chosenMoveId]);
|
||||
|
||||
// If partner can mega evolve, do it.
|
||||
if (CanMegaEvolve(gActiveBattler))
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "pokemon.h"
|
||||
#include "battle_controllers.h"
|
||||
#include "battle_interface.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "graphics.h"
|
||||
#include "sprite.h"
|
||||
#include "window.h"
|
||||
@ -1530,6 +1531,12 @@ void HideMegaTriggerSprite(void)
|
||||
}
|
||||
}
|
||||
|
||||
void HideTriggerSprites(void)
|
||||
{
|
||||
HideMegaTriggerSprite();
|
||||
HideZMoveTriggerSprite();
|
||||
}
|
||||
|
||||
void DestroyMegaTriggerSprite(void)
|
||||
{
|
||||
FreeSpritePaletteByTag(TAG_MEGA_TRIGGER_PAL);
|
||||
|
@ -134,7 +134,7 @@ EWRAM_DATA u16 gBattle_WIN1V = 0;
|
||||
EWRAM_DATA u8 gDisplayedStringBattle[400] = {0};
|
||||
EWRAM_DATA u8 gBattleTextBuff1[TEXT_BUFF_ARRAY_COUNT] = {0};
|
||||
EWRAM_DATA u8 gBattleTextBuff2[TEXT_BUFF_ARRAY_COUNT] = {0};
|
||||
EWRAM_DATA u8 gBattleTextBuff3[TEXT_BUFF_ARRAY_COUNT] = {0};
|
||||
EWRAM_DATA u8 gBattleTextBuff3[30] = {0}; //expanded for stupidly long z move names
|
||||
// The below array is never intentionally used. However, Juan's
|
||||
// defeat text (SootopolisCity_Gym_1F_Text_JuanDefeat) is too long
|
||||
// for gDisplayedStringBattle and overflows into this array. If it
|
||||
@ -239,7 +239,6 @@ EWRAM_DATA struct TotemBoost gTotemBoosts[MAX_BATTLERS_COUNT] = {0};
|
||||
EWRAM_DATA bool8 gHasFetchedBall = FALSE;
|
||||
EWRAM_DATA u8 gLastUsedBall = 0;
|
||||
EWRAM_DATA u16 gLastThrownBall = 0;
|
||||
EWRAM_DATA bool8 gSwapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
EWRAM_DATA u8 gPartyCriticalHits[PARTY_SIZE] = {0};
|
||||
EWRAM_DATA static u8 sTriedEvolving = 0;
|
||||
|
||||
@ -3007,7 +3006,7 @@ static void BattleStartClearSetData(void)
|
||||
gPartyCriticalHits[i] = 0;
|
||||
}
|
||||
|
||||
gSwapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
gBattleStruct->swapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
}
|
||||
|
||||
void SwitchInClearSetData(void)
|
||||
@ -3992,6 +3991,7 @@ static void HandleTurnActionSelectionState(void)
|
||||
{
|
||||
struct ChooseMoveStruct moveInfo;
|
||||
|
||||
moveInfo.zmove = gBattleStruct->zmove;
|
||||
moveInfo.mega = gBattleStruct->mega;
|
||||
moveInfo.species = gBattleMons[gActiveBattler].species;
|
||||
moveInfo.monType1 = gBattleMons[gActiveBattler].type1;
|
||||
@ -4107,6 +4107,7 @@ static void HandleTurnActionSelectionState(void)
|
||||
}
|
||||
|
||||
gBattleStruct->mega.toEvolve &= ~(gBitTable[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))]);
|
||||
gBattleStruct->zmove.toBeUsed[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))] = MOVE_NONE;
|
||||
BtlController_EmitEndBounceEffect(BUFFER_A);
|
||||
MarkBattlerForControllerExec(gActiveBattler);
|
||||
return;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "battle_message.h"
|
||||
#include "battle_setup.h"
|
||||
#include "battle_tower.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "data.h"
|
||||
#include "event_data.h"
|
||||
#include "frontier_util.h"
|
||||
@ -48,7 +49,6 @@ struct BattleWindowText
|
||||
|
||||
static void ChooseMoveUsedParticle(u8 *textPtr);
|
||||
static void ChooseTypeOfMoveUsedString(u8 *dst);
|
||||
static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst);
|
||||
|
||||
static EWRAM_DATA u16 sBattlerAbilities[MAX_BATTLERS_COUNT] = {0};
|
||||
EWRAM_DATA struct BattleMsgData *gBattleMsgDataPtr = NULL;
|
||||
@ -700,6 +700,15 @@ static const u8 sText_CanActFaster[] = _("{B_ATK_NAME_WITH_PREFIX} can act faste
|
||||
static const u8 sText_MicleBerryActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted the accuracy of its\nnext move using {B_LAST_ITEM}!");
|
||||
static const u8 sText_PkmnShookOffTheTaunt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shook off\nthe taunt!");
|
||||
static const u8 sText_PkmnGotOverItsInfatuation[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} got over\nits infatuation!");
|
||||
static const u8 sText_ZPowerSurrounds[] = _("{B_ATK_NAME_WITH_PREFIX} surrounds\nitself with its Z-Power!");
|
||||
static const u8 sText_ZPowerUnleashed[] = _("{B_ATK_NAME_WITH_PREFIX} unleashes\nits full-force Z-Move!");
|
||||
static const u8 sText_ZMoveResetsStats[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} returned its\ndecreased stats to normal using\lits Z-Power!");
|
||||
static const u8 sText_ZMoveAllStatsUp[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted all\nof its stats using its Z-Power!");
|
||||
static const u8 sText_ZMoveBoostCrit[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted its\ncritical-hit ratio using its Z-Power!");
|
||||
static const u8 sText_ZMoveRestoreHp[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored its\nHP using its Z-Power!");
|
||||
static const u8 sText_ZMoveStatUp[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted\nits stats using its Z-Power!");
|
||||
static const u8 sText_ZMoveHpSwitchInTrap[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s HP was restored by the Z-Power!");
|
||||
static const u8 sText_TerrainReturnedToNormal[] = _("The terrain returned to\nnormal!");
|
||||
static const u8 sText_ItemCannotBeRemoved[] = _("{B_ATK_NAME_WITH_PREFIX}'s item cannot be removed!");
|
||||
static const u8 sText_StickyBarbTransfer[] = _("The {B_LAST_ITEM} attached itself to\n{B_ATK_NAME_WITH_PREFIX}!");
|
||||
static const u8 sText_PkmnBurnHealed[] = _("{B_DEF_NAME_WITH_PREFIX}'s\nburn was healed.");
|
||||
@ -745,8 +754,17 @@ static const u8 sText_MeteorBeamCharging[] = _("{B_ATK_NAME_WITH_PREFIX} is over
|
||||
static const u8 sText_HeatingUpBeak[] = _("{B_ATK_NAME_WITH_PREFIX} started\nheating up its beak!");
|
||||
static const u8 sText_CourtChange[] = _("{B_ATK_NAME_WITH_PREFIX} swapped the battle\neffects affecting each side!");
|
||||
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_ZPOWERSURROUNDS - BATTLESTRINGS_TABLE_START] = sText_ZPowerSurrounds,
|
||||
[STRINGID_ZMOVEUNLEASHED - BATTLESTRINGS_TABLE_START] = sText_ZPowerUnleashed,
|
||||
[STRINGID_ZMOVERESETSSTATS - BATTLESTRINGS_TABLE_START] = sText_ZMoveResetsStats,
|
||||
[STRINGID_ZMOVEALLSTATSUP - BATTLESTRINGS_TABLE_START] = sText_ZMoveAllStatsUp,
|
||||
[STRINGID_ZMOVEZBOOSTCRIT - BATTLESTRINGS_TABLE_START] = sText_ZMoveBoostCrit,
|
||||
[STRINGID_ZMOVERESTOREHP - BATTLESTRINGS_TABLE_START] = sText_ZMoveRestoreHp,
|
||||
[STRINGID_ZMOVESTATUP - BATTLESTRINGS_TABLE_START] = sText_ZMoveStatUp,
|
||||
[STRINGID_ZMOVEHPTRAP - BATTLESTRINGS_TABLE_START] = sText_ZMoveHpSwitchInTrap,
|
||||
[STRINGID_PLAYERLOSTTOENEMYTRAINER - BATTLESTRINGS_TABLE_START] = sText_PlayerLostToEnemyTrainer,
|
||||
[STRINGID_PLAYERPAIDPRIZEMONEY - BATTLESTRINGS_TABLE_START] = sText_PlayerPaidPrizeMoney,
|
||||
[STRINGID_COURTCHANGE - BATTLESTRINGS_TABLE_START] = sText_CourtChange,
|
||||
@ -1353,6 +1371,17 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
[STRINGID_TARGETTOOHEAVY - BATTLESTRINGS_TABLE_START] = sText_TargetTooHeavy,
|
||||
};
|
||||
|
||||
const u16 gZEffectStringIds[] =
|
||||
{
|
||||
[B_MSG_Z_RESET_STATS] = STRINGID_ZMOVERESETSSTATS,
|
||||
[B_MSG_Z_ALL_STATS_UP]= STRINGID_ZMOVEALLSTATSUP,
|
||||
[B_MSG_Z_BOOST_CRITS] = STRINGID_ZMOVEZBOOSTCRIT,
|
||||
[B_MSG_Z_FOLLOW_ME] = STRINGID_PKMNCENTERATTENTION,
|
||||
[B_MSG_Z_RECOVER_HP] = STRINGID_ZMOVERESTOREHP,
|
||||
[B_MSG_Z_STAT_UP] = STRINGID_ZMOVESTATUP,
|
||||
[B_MSG_Z_HP_TRAP] = STRINGID_ZMOVEHPTRAP,
|
||||
};
|
||||
|
||||
const u16 gMentalHerbCureStringIds[] =
|
||||
{
|
||||
[B_MSG_MENTALHERBCURE_INFATUATION] = STRINGID_ATKGOTOVERINFATUATION,
|
||||
@ -1365,7 +1394,7 @@ const u16 gMentalHerbCureStringIds[] =
|
||||
|
||||
const u16 gTerrainStringIds[] =
|
||||
{
|
||||
STRINGID_TERRAINBECOMESMISTY, STRINGID_TERRAINBECOMESGRASSY, STRINGID_TERRAINBECOMESELECTRIC, STRINGID_TERRAINBECOMESPSYCHIC
|
||||
STRINGID_TERRAINBECOMESMISTY, STRINGID_TERRAINBECOMESGRASSY, STRINGID_TERRAINBECOMESELECTRIC, STRINGID_TERRAINBECOMESPSYCHIC, STRINGID_TERRAINREMOVED,
|
||||
};
|
||||
|
||||
const u16 gTerrainEndingStringIds[] =
|
||||
@ -2794,7 +2823,9 @@ void BufferStringBattle(u16 stringID)
|
||||
}
|
||||
break;
|
||||
case STRINGID_USEDMOVE: // pokemon used a move msg
|
||||
if (gBattleMsgDataPtr->currentMove >= MOVES_COUNT)
|
||||
if (gBattleStruct->zmove.active && gBattleStruct->zmove.activeSplit != SPLIT_STATUS)
|
||||
StringCopy(gBattleTextBuff3, GetZMoveName(gBattleMsgDataPtr->currentMove));
|
||||
else if (gBattleMsgDataPtr->currentMove >= MOVES_COUNT)
|
||||
StringCopy(gBattleTextBuff3, sATypeMove_Table[*(&gBattleStruct->stringMoveType)]);
|
||||
else
|
||||
StringCopy(gBattleTextBuff3, gMoveNames[gBattleMsgDataPtr->currentMove]);
|
||||
@ -3222,13 +3253,17 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
|
||||
HANDLE_NICKNAME_STRING_CASE(gBattleScripting.battler)
|
||||
break;
|
||||
case B_TXT_CURRENT_MOVE: // current move name
|
||||
if (gBattleMsgDataPtr->currentMove >= MOVES_COUNT)
|
||||
if (gBattleStruct->zmove.active)
|
||||
toCpy = GetZMoveName(gBattleMsgDataPtr->currentMove);
|
||||
else if (gBattleMsgDataPtr->currentMove >= MOVES_COUNT)
|
||||
toCpy = sATypeMove_Table[gBattleStruct->stringMoveType];
|
||||
else
|
||||
toCpy = gMoveNames[gBattleMsgDataPtr->currentMove];
|
||||
break;
|
||||
case B_TXT_LAST_MOVE: // originally used move name
|
||||
if (gBattleMsgDataPtr->originallyUsedMove >= MOVES_COUNT)
|
||||
if (gBattleStruct->zmove.active)
|
||||
toCpy = GetZMoveName(gBattleMsgDataPtr->originallyUsedMove);
|
||||
else if (gBattleMsgDataPtr->originallyUsedMove >= MOVES_COUNT)
|
||||
toCpy = sATypeMove_Table[gBattleStruct->stringMoveType];
|
||||
else
|
||||
toCpy = gMoveNames[gBattleMsgDataPtr->originallyUsedMove];
|
||||
@ -3558,7 +3593,7 @@ static void IllusionNickHack(u32 battlerId, u32 partyId, u8 *dst)
|
||||
GetMonData(mon, MON_DATA_NICKNAME, dst);
|
||||
}
|
||||
|
||||
static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst)
|
||||
void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst)
|
||||
{
|
||||
u32 srcID = 1;
|
||||
u32 value = 0;
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include "battle_ai_main.h"
|
||||
#include "battle_ai_util.h"
|
||||
#include "battle_scripts.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/abilities.h"
|
||||
#include "item.h"
|
||||
#include "util.h"
|
||||
#include "pokemon.h"
|
||||
@ -1618,6 +1621,12 @@ static bool32 AccuracyCalcHelper(u16 move)
|
||||
RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (gBattleStruct->zmove.active && !(gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE))
|
||||
{
|
||||
JumpIfMoveFailed(7, move);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE)
|
||||
|| (!(gBattleMoves[move].flags & (FLAG_DMG_IN_AIR | FLAG_DMG_2X_IN_AIR)) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR)
|
||||
@ -1975,16 +1984,18 @@ static void Cmd_adjustdamage(void)
|
||||
RecordItemEffectBattle(gBattlerTarget, holdEffect);
|
||||
gSpecialStatuses[gBattlerTarget].focusBanded = TRUE;
|
||||
}
|
||||
else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && BATTLER_MAX_HP(gBattlerTarget))
|
||||
{
|
||||
RecordItemEffectBattle(gBattlerTarget, holdEffect);
|
||||
gSpecialStatuses[gBattlerTarget].focusSashed = TRUE;
|
||||
}
|
||||
#if B_STURDY >= GEN_5
|
||||
else if (GetBattlerAbility(gBattlerTarget) == ABILITY_STURDY && BATTLER_MAX_HP(gBattlerTarget))
|
||||
{
|
||||
RecordAbilityBattle(gBattlerTarget, ABILITY_STURDY);
|
||||
gSpecialStatuses[gBattlerTarget].sturdied = TRUE;
|
||||
}
|
||||
#endif
|
||||
else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && BATTLER_MAX_HP(gBattlerTarget))
|
||||
{
|
||||
RecordItemEffectBattle(gBattlerTarget, holdEffect);
|
||||
gSpecialStatuses[gBattlerTarget].focusSashed = TRUE;
|
||||
}
|
||||
|
||||
if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE
|
||||
&& !gProtectStructs[gBattlerTarget].endured
|
||||
@ -5622,6 +5633,10 @@ static void Cmd_moveend(void)
|
||||
gSpecialStatuses[gBattlerAttacker].damagedMons = 0;
|
||||
gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
|
||||
gBattleScripting.moveEffect = 0;
|
||||
// clear attacker z move data
|
||||
gBattleStruct->zmove.active = FALSE;
|
||||
gBattleStruct->zmove.toBeUsed[gBattlerAttacker] = MOVE_NONE;
|
||||
gBattleStruct->zmove.effect = EFFECT_HIT;
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_COUNT:
|
||||
@ -6400,6 +6415,16 @@ static void Cmd_switchineffects(void)
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_StickyWebOnSwitchIn;
|
||||
}
|
||||
else if (gBattleMons[gActiveBattler].hp != gBattleMons[gActiveBattler].maxHP && gBattleStruct->zmove.healReplacement)
|
||||
{
|
||||
gBattleStruct->zmove.healReplacement = FALSE;
|
||||
gBattleMoveDamage = -1 * (gBattleMons[gActiveBattler].maxHP);
|
||||
gBattleScripting.battler = gActiveBattler;
|
||||
BattleScriptPushCursor();
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_HP_TRAP;
|
||||
gBattlescriptCurrInstr = BattleScript_HealReplacementZMove;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is a hack here to ensure the truant counter will be 0 when the battler's next turn starts.
|
||||
@ -7498,12 +7523,12 @@ static bool32 HasAttackerFaintedTarget(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void HandleTerrainMove(u32 moveEffect)
|
||||
static void HandleTerrainMove(u16 move)
|
||||
{
|
||||
u32 statusFlag = 0;
|
||||
u8 *timer = NULL;
|
||||
|
||||
switch (moveEffect)
|
||||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
case EFFECT_MISTY_TERRAIN:
|
||||
statusFlag = STATUS_FIELD_MISTY_TERRAIN, timer = &gFieldTimers.terrainTimer;
|
||||
@ -7521,6 +7546,31 @@ static void HandleTerrainMove(u32 moveEffect)
|
||||
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN, timer = &gFieldTimers.terrainTimer;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
break;
|
||||
case EFFECT_DAMAGE_SET_TERRAIN:
|
||||
switch (gBattleMoves[move].argument)
|
||||
{
|
||||
case 0: //genesis supernova
|
||||
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN, timer = &gFieldTimers.terrainTimer;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
|
||||
break;
|
||||
case 1: //splintered stormshards
|
||||
if (!(gFieldStatuses & (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN)))
|
||||
{
|
||||
//no terrain to remove -> jump to battle script pointer
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove all terrain
|
||||
gFieldStatuses &= ~(STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
|
||||
gBattlescriptCurrInstr += 7;
|
||||
}
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (gFieldStatuses & statusFlag || statusFlag == 0)
|
||||
@ -8425,7 +8475,7 @@ static void Cmd_various(void)
|
||||
}
|
||||
break;
|
||||
case VARIOUS_SET_TERRAIN:
|
||||
HandleTerrainMove(gBattleMoves[gCurrentMove].effect);
|
||||
HandleTerrainMove(gCurrentMove);
|
||||
return;
|
||||
case VARIOUS_TRY_ME_FIRST:
|
||||
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
|
||||
@ -8986,6 +9036,9 @@ static void Cmd_various(void)
|
||||
gBattlescriptCurrInstr += 7; // exit if loop failed (failsafe)
|
||||
}
|
||||
return;
|
||||
case VARIOUS_SET_Z_EFFECT:
|
||||
SetZEffect(); //handles battle script jumping internally
|
||||
return;
|
||||
case VARIOUS_MOVEEND_ITEM_EFFECTS:
|
||||
if (ItemBattleEffects(ITEMEFFECT_NORMAL, gActiveBattler, FALSE))
|
||||
return;
|
||||
@ -9141,7 +9194,7 @@ static void Cmd_various(void)
|
||||
break;
|
||||
case VARIOUS_JUMP_IF_UNDER_200:
|
||||
// If the Pokemon is less than 200 kg, or weighing less than 441 lbs, then Sky Drop will work. Otherwise, it will fail.
|
||||
if (GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species), 1) < 441)
|
||||
if (GetBattlerWeight(gBattlerTarget) < 2000)
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
else
|
||||
gBattlescriptCurrInstr += 7;
|
||||
@ -9353,24 +9406,8 @@ static void Cmd_various(void)
|
||||
gBattlescriptCurrInstr += 9;
|
||||
return;
|
||||
case VARIOUS_PHOTON_GEYSER_CHECK:
|
||||
{
|
||||
u32 attackerAtkStat = gBattleMons[gBattlerAttacker].attack;
|
||||
u8 attackerAtkStage = gBattleMons[gBattlerAttacker].statStages[STAT_ATK];
|
||||
u32 attackerSpAtkStat = gBattleMons[gBattlerAttacker].spAttack;
|
||||
|
||||
gSwapDamageCategory = FALSE;
|
||||
|
||||
attackerAtkStat *= gStatStageRatios[attackerAtkStage][0];
|
||||
attackerAtkStat /= gStatStageRatios[attackerAtkStage][1];
|
||||
|
||||
attackerAtkStage = gBattleMons[gBattlerAttacker].statStages[STAT_SPATK];
|
||||
attackerSpAtkStat *= gStatStageRatios[attackerAtkStage][0];
|
||||
attackerSpAtkStat /= gStatStageRatios[attackerAtkStage][1];
|
||||
|
||||
if (attackerAtkStat > attackerSpAtkStat)
|
||||
gSwapDamageCategory = TRUE;
|
||||
gBattleStruct->swapDamageCategory = (GetSplitBasedOnStats(gActiveBattler) == SPLIT_SPECIAL);
|
||||
break;
|
||||
}
|
||||
case VARIOUS_SHELL_SIDE_ARM_CHECK: // 0% chance GameFreak actually checks this way according to DaWobblefet, but this is the only functional explanation at the moment
|
||||
{
|
||||
u32 attackerAtkStat = gBattleMons[gBattlerAttacker].attack;
|
||||
@ -9381,7 +9418,7 @@ static void Cmd_various(void)
|
||||
u32 physical;
|
||||
u32 special;
|
||||
|
||||
gSwapDamageCategory = FALSE;
|
||||
gBattleStruct->swapDamageCategory = FALSE;
|
||||
|
||||
statStage = gBattleMons[gBattlerAttacker].statStages[STAT_ATK];
|
||||
attackerAtkStat *= gStatStageRatios[statStage][0];
|
||||
@ -9404,7 +9441,7 @@ static void Cmd_various(void)
|
||||
special = ((((2 * gBattleMons[gBattlerAttacker].level / 5 + 2) * gBattleMoves[gCurrentMove].power * attackerSpAtkStat) / targetSpDefStat) / 50);
|
||||
|
||||
if (((physical > special) || (physical == special && (Random() % 2) == 0)))
|
||||
gSwapDamageCategory = TRUE;
|
||||
gBattleStruct->swapDamageCategory = TRUE;
|
||||
break;
|
||||
}
|
||||
case VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED:
|
||||
|
@ -268,15 +268,15 @@ void HandleAction_UseMove(void)
|
||||
gCurrentMove = gChosenMove = gLockedMoves[gBattlerAttacker];
|
||||
}
|
||||
// encore forces you to use the same move
|
||||
else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE
|
||||
&& gDisableStructs[gBattlerAttacker].encoredMove == gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos])
|
||||
else if (!gBattleStruct->zmove.active && gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE
|
||||
&& gDisableStructs[gBattlerAttacker].encoredMove == gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos])
|
||||
{
|
||||
gCurrentMove = gChosenMove = gDisableStructs[gBattlerAttacker].encoredMove;
|
||||
gCurrMovePos = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos;
|
||||
*(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
|
||||
}
|
||||
// check if the encored move wasn't overwritten
|
||||
else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE
|
||||
else if (!gBattleStruct->zmove.active && gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE
|
||||
&& gDisableStructs[gBattlerAttacker].encoredMove != gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos])
|
||||
{
|
||||
gCurrMovePos = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos;
|
||||
@ -295,6 +295,12 @@ void HandleAction_UseMove(void)
|
||||
{
|
||||
gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
|
||||
}
|
||||
|
||||
// check z move used
|
||||
if (gBattleStruct->zmove.toBeUsed[gBattlerAttacker] != MOVE_NONE && !IS_MOVE_STATUS(gCurrentMove))
|
||||
{
|
||||
gCurrentMove = gBattleStruct->zmove.toBeUsed[gBattlerAttacker];
|
||||
}
|
||||
|
||||
if (gBattleMons[gBattlerAttacker].hp != 0)
|
||||
{
|
||||
@ -1758,7 +1764,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (gDisableStructs[gActiveBattler].tauntTimer != 0 && gBattleMoves[move].power == 0)
|
||||
if (!gBattleStruct->zmove.active && gDisableStructs[gActiveBattler].tauntTimer != 0 && gBattleMoves[move].power == 0)
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1773,7 +1779,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (gDisableStructs[gActiveBattler].throatChopTimer != 0 && gBattleMoves[move].flags & FLAG_SOUND)
|
||||
if (!gBattleStruct->zmove.active && gDisableStructs[gActiveBattler].throatChopTimer != 0 && gBattleMoves[move].flags & FLAG_SOUND)
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1788,7 +1794,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (GetImprisonedMovesCount(gActiveBattler, move))
|
||||
if (!gBattleStruct->zmove.active && GetImprisonedMovesCount(gActiveBattler, move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1803,7 +1809,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsGravityPreventingMove(move))
|
||||
if (!gBattleStruct->zmove.active && IsGravityPreventingMove(move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1818,7 +1824,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsHealBlockPreventingMove(gActiveBattler, move))
|
||||
if (!gBattleStruct->zmove.active && IsHealBlockPreventingMove(gActiveBattler, move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -1833,7 +1839,7 @@ u8 TrySetCantSelectMoveBattleScript(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsBelchPreventingMove(gActiveBattler, move))
|
||||
if (!gBattleStruct->zmove.active && IsBelchPreventingMove(gActiveBattler, move))
|
||||
{
|
||||
gCurrentMove = move;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||
@ -3373,6 +3379,7 @@ enum
|
||||
CANCELLER_POWDER_MOVE,
|
||||
CANCELLER_POWDER_STATUS,
|
||||
CANCELLER_THROAT_CHOP,
|
||||
CANCELLER_Z_MOVES,
|
||||
CANCELLER_END,
|
||||
CANCELLER_PSYCHIC_TERRAIN,
|
||||
CANCELLER_END2,
|
||||
@ -3711,6 +3718,33 @@ u8 AtkCanceller_UnableToUseMove(void)
|
||||
}
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_Z_MOVES:
|
||||
if (gBattleStruct->zmove.toBeUsed[gBattlerAttacker] != MOVE_NONE)
|
||||
{
|
||||
//attacker has a queued z move
|
||||
gBattleStruct->zmove.active = TRUE;
|
||||
gBattleStruct->zmove.activeSplit = gBattleStruct->zmove.splits[gBattlerAttacker];
|
||||
RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_Z_CRYSTAL);
|
||||
gBattleStruct->zmove.used[gBattlerAttacker] = TRUE;
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsPartnerMonFromSameTrainer(gBattlerAttacker))
|
||||
gBattleStruct->zmove.used[BATTLE_PARTNER(gBattlerAttacker)] = TRUE; //if 1v1 double, set partner used flag as well
|
||||
|
||||
gBattleScripting.battler = gBattlerAttacker;
|
||||
if (gBattleStruct->zmove.activeSplit == SPLIT_STATUS)
|
||||
{
|
||||
gBattleStruct->zmove.effect = gBattleMoves[gBattleStruct->zmove.baseMoves[gBattlerAttacker]].zMoveEffect;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_ZMoveActivateStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_ZMoveActivateDamaging;
|
||||
}
|
||||
effect = 1;
|
||||
}
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_END:
|
||||
break;
|
||||
}
|
||||
@ -7706,7 +7740,7 @@ bool32 IsMoveMakingContact(u16 move, u8 battlerAtk)
|
||||
{
|
||||
if (!(gBattleMoves[move].flags & FLAG_MAKES_CONTACT))
|
||||
{
|
||||
if (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gSwapDamageCategory)
|
||||
if (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->swapDamageCategory)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
@ -7739,7 +7773,7 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
|
||||
// Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here.
|
||||
// This means extra logic is needed to handle Shell Side Arm.
|
||||
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT || (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gSwapDamageCategory)))
|
||||
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT || (gBattleMoves[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->swapDamageCategory)))
|
||||
return FALSE;
|
||||
else if (!(gBattleMoves[move].flags & FLAG_PROTECT_AFFECTED))
|
||||
return FALSE;
|
||||
@ -8012,6 +8046,9 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
u32 i;
|
||||
u16 basePower = gBattleMoves[move].power;
|
||||
u32 weight, hpFraction, speed;
|
||||
|
||||
if (gBattleStruct->zmove.active)
|
||||
return gBattleMoves[gBattleStruct->zmove.baseMoves[battlerAtk]].zMovePower;
|
||||
|
||||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
@ -8813,6 +8850,12 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
|
||||
usesDefStat = FALSE;
|
||||
}
|
||||
|
||||
#if B_EXPLOSION_DEFENSE <= GEN_4
|
||||
// Self-destruct / Explosion cut defense in half
|
||||
if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION)
|
||||
defStat /= 2;
|
||||
#endif
|
||||
|
||||
// critical hits ignore positive stat changes
|
||||
if (isCrit && defStage > DEFAULT_STAT_STAGE)
|
||||
defStage = DEFAULT_STAT_STAGE;
|
||||
@ -9415,6 +9458,11 @@ bool32 CanMegaEvolve(u8 battlerId)
|
||||
// Check if trainer already mega evolved a pokemon.
|
||||
if (mega->alreadyEvolved[battlerPosition])
|
||||
return FALSE;
|
||||
|
||||
// Cannot use z move and mega evolve on same turn
|
||||
if (gBattleStruct->zmove.toBeUsed[battlerId])
|
||||
return FALSE;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
|
||||
&& IsPartnerMonFromSameTrainer(battlerId)
|
||||
&& (mega->alreadyEvolved[partnerPosition] || (mega->toEvolve & gBitTable[BATTLE_PARTNER(battlerId)])))
|
||||
@ -9660,7 +9708,9 @@ bool8 ShouldGetStatBadgeBoost(u16 badgeFlag, u8 battlerId)
|
||||
|
||||
u8 GetBattleMoveSplit(u32 moveId)
|
||||
{
|
||||
if (gSwapDamageCategory) // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
if (gBattleStruct != NULL && gBattleStruct->zmove.active && !IS_MOVE_STATUS(moveId))
|
||||
return gBattleStruct->zmove.activeSplit;
|
||||
if (gBattleStruct != NULL && gBattleStruct->swapDamageCategory) // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
return SPLIT_PHYSICAL;
|
||||
else if (IS_MOVE_STATUS(moveId) || B_PHYSICAL_SPECIAL_SPLIT >= GEN_4)
|
||||
return gBattleMoves[moveId].split;
|
||||
@ -9708,6 +9758,24 @@ static bool32 IsUnnerveAbilityOnOpposingSide(u8 battlerId)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Photon geyser & light that burns the sky
|
||||
u8 GetSplitBasedOnStats(u8 battlerId)
|
||||
{
|
||||
u32 attack = gBattleMons[battlerId].attack;
|
||||
u32 spAttack = gBattleMons[battlerId].spAttack;
|
||||
|
||||
attack = attack * gStatStageRatios[gBattleMons[battlerId].statStages[STAT_ATK]][0];
|
||||
attack = attack / gStatStageRatios[gBattleMons[battlerId].statStages[STAT_ATK]][1];
|
||||
|
||||
spAttack = spAttack * gStatStageRatios[gBattleMons[battlerId].statStages[STAT_SPATK]][0];
|
||||
spAttack = spAttack / gStatStageRatios[gBattleMons[battlerId].statStages[STAT_SPATK]][1];
|
||||
|
||||
if (spAttack >= attack)
|
||||
return SPLIT_SPECIAL;
|
||||
else
|
||||
return SPLIT_PHYSICAL;
|
||||
}
|
||||
|
||||
bool32 TestMoveFlags(u16 move, u32 flag)
|
||||
{
|
||||
if (gBattleMoves[move].flags & flag)
|
||||
@ -9726,7 +9794,7 @@ struct Pokemon *GetBattlerPartyData(u8 battlerId)
|
||||
return mon;
|
||||
}
|
||||
|
||||
//Make sure the input bank is any bank on the specific mon's side
|
||||
// Make sure the input bank is any bank on the specific mon's side
|
||||
bool32 CanFling(u8 battlerId)
|
||||
{
|
||||
u16 item = gBattleMons[battlerId].item;
|
||||
@ -9745,7 +9813,7 @@ bool32 CanFling(u8 battlerId)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ability checks
|
||||
// Ability checks
|
||||
bool32 IsRolePlayBannedAbilityAtk(u16 ability)
|
||||
{
|
||||
u32 i;
|
||||
|
679
src/battle_z_move.c
Normal file
679
src/battle_z_move.c
Normal file
@ -0,0 +1,679 @@
|
||||
#include "global.h"
|
||||
#include "malloc.h"
|
||||
#include "battle.h"
|
||||
#include "pokemon.h"
|
||||
#include "battle_ai_main.h"
|
||||
#include "battle_ai_util.h"
|
||||
#include "battle_controllers.h"
|
||||
#include "battle_interface.h"
|
||||
#include "battle_message.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "battle_scripts.h"
|
||||
#include "graphics.h"
|
||||
#include "sprite.h"
|
||||
#include "window.h"
|
||||
#include "string_util.h"
|
||||
#include "text.h"
|
||||
#include "item.h"
|
||||
#include "strings.h"
|
||||
#include "sound.h"
|
||||
#include "constants/songs.h"
|
||||
#include "decompress.h"
|
||||
#include "task.h"
|
||||
#include "util.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "battle_message.h"
|
||||
#include "pokedex.h"
|
||||
#include "palette.h"
|
||||
#include "international_string_util.h"
|
||||
#include "safari_zone.h"
|
||||
#include "battle_anim.h"
|
||||
#include "constants/battle_anim.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "battle_debug.h"
|
||||
#include "constants/battle_config.h"
|
||||
#include "data.h"
|
||||
#include "pokemon_summary_screen.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/species.h"
|
||||
#include "constants/hold_effects.h"
|
||||
#include "constants/battle_string_ids.h"
|
||||
#include "constants/battle_move_effects.h"
|
||||
#include "constants/abilities.h"
|
||||
#include "constants/moves.h"
|
||||
|
||||
#define STAT_STAGE(battler, stat) (gBattleMons[battler].statStages[stat - 1])
|
||||
|
||||
// Function Declarations
|
||||
static void SpriteCB_ZMoveTrigger(struct Sprite *sprite);
|
||||
static u16 GetSignatureZMove(u16 move, u16 species, u16 item);
|
||||
static u16 GetTypeBasedZMove(u16 move, u8 battler);
|
||||
static void ZMoveSelectionDisplayPpNumber(void);
|
||||
static void ZMoveSelectionDisplayPower(u16 move, u16 zMove);
|
||||
static void ShowZMoveTriggerSprite(void);
|
||||
static bool32 AreStatsMaxed(u8 battlerId, u8 n);
|
||||
static u8 GetZMoveScore(u8 battlerAtk, u8 battlerDef, u16 baseMove, u16 zMove);
|
||||
|
||||
// Const Data
|
||||
static const struct SignatureZMove sSignatureZMoves[] =
|
||||
{
|
||||
#ifdef POKEMON_EXPANSION
|
||||
{SPECIES_PIKACHU_COSPLAY, ITEM_PIKANIUM_Z, MOVE_VOLT_TACKLE, MOVE_CATASTROPIKA},
|
||||
{SPECIES_PIKACHU_ROCK_STAR, ITEM_PIKANIUM_Z, MOVE_VOLT_TACKLE, MOVE_CATASTROPIKA},
|
||||
{SPECIES_PIKACHU_BELLE, ITEM_PIKANIUM_Z, MOVE_VOLT_TACKLE, MOVE_CATASTROPIKA},
|
||||
{SPECIES_PIKACHU_POP_STAR, ITEM_PIKANIUM_Z, MOVE_VOLT_TACKLE, MOVE_CATASTROPIKA},
|
||||
{SPECIES_PIKACHU_PH_D, ITEM_PIKANIUM_Z, MOVE_VOLT_TACKLE, MOVE_CATASTROPIKA},
|
||||
{SPECIES_PIKACHU_LIBRE, ITEM_PIKANIUM_Z, MOVE_VOLT_TACKLE, MOVE_CATASTROPIKA},
|
||||
|
||||
{SPECIES_RAICHU_ALOLAN, ITEM_ALORAICHIUM_Z, MOVE_THUNDERBOLT, MOVE_STOKED_SPARKSURFER},
|
||||
{SPECIES_DECIDUEYE, ITEM_DECIDIUM_Z, MOVE_SPIRIT_SHACKLE, MOVE_SINISTER_ARROW_RAID},
|
||||
{SPECIES_INCINEROAR, ITEM_INCINIUM_Z, MOVE_DARKEST_LARIAT, MOVE_MALICIOUS_MOONSAULT},
|
||||
{SPECIES_KOMMO_O, ITEM_KOMMONIUM_Z, MOVE_CLANGING_SCALES, MOVE_CLANGOROUS_SOULBLAZE},
|
||||
{SPECIES_LUNALA, ITEM_LUNALIUM_Z, MOVE_MOONGEIST_BEAM, MOVE_MENACING_MOONRAZE_MAELSTROM},
|
||||
{SPECIES_NECROZMA_DAWN_WINGS, ITEM_LUNALIUM_Z, MOVE_MOONGEIST_BEAM, MOVE_MENACING_MOONRAZE_MAELSTROM},
|
||||
{SPECIES_LYCANROC, ITEM_LYCANIUM_Z, MOVE_STONE_EDGE, MOVE_SPLINTERED_STORMSHARDS},
|
||||
{SPECIES_LYCANROC_MIDNIGHT, ITEM_LYCANIUM_Z, MOVE_STONE_EDGE, MOVE_SPLINTERED_STORMSHARDS},
|
||||
|
||||
{SPECIES_LYCANROC_DUSK, ITEM_LYCANIUM_Z, MOVE_STONE_EDGE, MOVE_SPLINTERED_STORMSHARDS},
|
||||
{SPECIES_MARSHADOW, ITEM_MARSHADIUM_Z, MOVE_SPECTRAL_THIEF, MOVE_SOUL_STEALING_7_STAR_STRIKE},
|
||||
{SPECIES_MIMIKYU, ITEM_MIMIKIUM_Z, MOVE_PLAY_ROUGH, MOVE_LETS_SNUGGLE_FOREVER},
|
||||
{SPECIES_MIMIKYU_BUSTED, ITEM_MIMIKIUM_Z, MOVE_PLAY_ROUGH, MOVE_LETS_SNUGGLE_FOREVER},
|
||||
{SPECIES_PIKACHU_ORIGINAL_CAP, ITEM_PIKASHUNIUM_Z, MOVE_THUNDERBOLT, MOVE_10000000_VOLT_THUNDERBOLT},
|
||||
{SPECIES_PIKACHU_HOENN_CAP, ITEM_PIKASHUNIUM_Z, MOVE_THUNDERBOLT, MOVE_10000000_VOLT_THUNDERBOLT},
|
||||
{SPECIES_PIKACHU_SINNOH_CAP, ITEM_PIKASHUNIUM_Z, MOVE_THUNDERBOLT, MOVE_10000000_VOLT_THUNDERBOLT},
|
||||
{SPECIES_PIKACHU_UNOVA_CAP, ITEM_PIKASHUNIUM_Z, MOVE_THUNDERBOLT, MOVE_10000000_VOLT_THUNDERBOLT},
|
||||
{SPECIES_PIKACHU_KALOS_CAP, ITEM_PIKASHUNIUM_Z, MOVE_THUNDERBOLT, MOVE_10000000_VOLT_THUNDERBOLT},
|
||||
{SPECIES_PIKACHU_ALOLA_CAP, ITEM_PIKASHUNIUM_Z, MOVE_THUNDERBOLT, MOVE_10000000_VOLT_THUNDERBOLT},
|
||||
{SPECIES_PIKACHU_PARTNER_CAP, ITEM_PIKASHUNIUM_Z, MOVE_THUNDERBOLT, MOVE_10000000_VOLT_THUNDERBOLT},
|
||||
{SPECIES_PIKACHU_WORLD_CAP, ITEM_PIKASHUNIUM_Z, MOVE_THUNDERBOLT, MOVE_10000000_VOLT_THUNDERBOLT},
|
||||
{SPECIES_PRIMARINA, ITEM_PRIMARIUM_Z, MOVE_SPARKLING_ARIA, MOVE_OCEANIC_OPERETTA},
|
||||
{SPECIES_SOLGALEO, ITEM_SOLGANIUM_Z, MOVE_SUNSTEEL_STRIKE, MOVE_SEARING_SUNRAZE_SMASH},
|
||||
{SPECIES_NECROZMA_DUSK_MANE, ITEM_SOLGANIUM_Z, MOVE_SUNSTEEL_STRIKE, MOVE_SEARING_SUNRAZE_SMASH},
|
||||
{SPECIES_TAPU_KOKO, ITEM_TAPUNIUM_Z, MOVE_NATURES_MADNESS, MOVE_GUARDIAN_OF_ALOLA},
|
||||
{SPECIES_TAPU_BULU, ITEM_TAPUNIUM_Z, MOVE_NATURES_MADNESS, MOVE_GUARDIAN_OF_ALOLA},
|
||||
{SPECIES_TAPU_LELE, ITEM_TAPUNIUM_Z, MOVE_NATURES_MADNESS, MOVE_GUARDIAN_OF_ALOLA},
|
||||
{SPECIES_TAPU_FINI, ITEM_TAPUNIUM_Z, MOVE_NATURES_MADNESS, MOVE_GUARDIAN_OF_ALOLA},
|
||||
{SPECIES_NECROZMA_ULTRA, ITEM_ULTRANECROZIUM_Z, MOVE_PHOTON_GEYSER, MOVE_LIGHT_THAT_BURNS_THE_SKY},
|
||||
#endif
|
||||
{SPECIES_MEW, ITEM_MEWNIUM_Z, MOVE_PSYCHIC, MOVE_GENESIS_SUPERNOVA},
|
||||
{SPECIES_PIKACHU, ITEM_PIKANIUM_Z, MOVE_VOLT_TACKLE, MOVE_CATASTROPIKA},
|
||||
{SPECIES_EEVEE, ITEM_EEVIUM_Z, MOVE_LAST_RESORT, MOVE_EXTREME_EVOBOOST},
|
||||
{SPECIES_SNORLAX, ITEM_SNORLIUM_Z, MOVE_GIGA_IMPACT, MOVE_PULVERIZING_PANCAKE},
|
||||
};
|
||||
|
||||
static const u8 sText_ResetStats[] = _("Reset Lowered Stats");
|
||||
static const u8 sText_StatsPlus[] = _("+ All Stats");
|
||||
static const u8 sText_StatsPlus2[] = _("++ All Stats");
|
||||
static const u8 sText_CritHitsPlus[] = _("+ Critical Hit Chance");
|
||||
static const u8 sText_FollowMe[] = _("Follow Me");
|
||||
static const u8 sText_RecoverHP[] = _("Recover HP");
|
||||
static const u8 sText_HealAllyHP[] = _("Heal Replacement HP");
|
||||
static const u8 sText_PowerColon[] = _("Power: ");
|
||||
|
||||
static const u32 sZMoveTriggerGfx[] = INCBIN_U32("graphics/battle_interface/z_move_trigger.4bpp.lz");
|
||||
static const u16 sZMoveTriggerPal[] = INCBIN_U16("graphics/battle_interface/z_move_trigger.gbapal");
|
||||
|
||||
static const struct CompressedSpriteSheet sSpriteSheet_ZMoveTrigger = {
|
||||
sZMoveTriggerGfx, (32 * 32) / 2, TAG_ZMOVE_TRIGGER_TILE
|
||||
};
|
||||
|
||||
static const struct SpritePalette sSpritePalette_ZMoveTrigger = {
|
||||
sZMoveTriggerPal, TAG_ZMOVE_TRIGGER_PAL
|
||||
};
|
||||
|
||||
static const struct OamData sOamData_ZMoveTrigger =
|
||||
{
|
||||
.affineMode = ST_OAM_AFFINE_OFF,
|
||||
.objMode = ST_OAM_OBJ_NORMAL,
|
||||
.shape = SPRITE_SHAPE(32x32),
|
||||
.size = SPRITE_SIZE(32x32),
|
||||
.priority = 1,
|
||||
};
|
||||
|
||||
static const struct SpriteTemplate sSpriteTemplate_ZMoveTrigger =
|
||||
{
|
||||
.tileTag = TAG_ZMOVE_TRIGGER_TILE,
|
||||
.paletteTag = TAG_ZMOVE_TRIGGER_PAL,
|
||||
.oam = &sOamData_ZMoveTrigger,
|
||||
.anims = gDummySpriteAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = SpriteCB_ZMoveTrigger
|
||||
};
|
||||
|
||||
// Functions
|
||||
bool8 IsZMove(u16 move)
|
||||
{
|
||||
return move >= FIRST_Z_MOVE && move <= LAST_Z_MOVE;
|
||||
}
|
||||
|
||||
void QueueZMove(u8 battlerId, u16 baseMove)
|
||||
{
|
||||
gBattleStruct->zmove.toBeUsed[battlerId] = gBattleStruct->zmove.chosenZMove;
|
||||
gBattleStruct->zmove.baseMoves[battlerId] = baseMove;
|
||||
if (gBattleStruct->zmove.chosenZMove == MOVE_LIGHT_THAT_BURNS_THE_SKY)
|
||||
gBattleStruct->zmove.splits[battlerId] = GetSplitBasedOnStats(battlerId);
|
||||
else
|
||||
gBattleStruct->zmove.splits[battlerId] = gBattleMoves[baseMove].split;
|
||||
}
|
||||
|
||||
bool32 IsViableZMove(u8 battlerId, u16 move)
|
||||
{
|
||||
struct Pokemon *mon;
|
||||
struct MegaEvolutionData *mega = &(((struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]))->mega);
|
||||
u8 battlerPosition = GetBattlerPosition(battlerId);
|
||||
u8 partnerPosition = GetBattlerPosition(BATTLE_PARTNER(battlerId));
|
||||
u32 item;
|
||||
u16 holdEffect;
|
||||
u16 species;
|
||||
|
||||
if (gBattleStruct->zmove.used[battlerId])
|
||||
return FALSE;
|
||||
|
||||
species = gBattleMons[battlerId].species;
|
||||
item = gBattleMons[battlerId].item;
|
||||
if (gBattleTypeFlags & (BATTLE_TYPE_SAFARI | BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FRONTIER))
|
||||
return FALSE;
|
||||
|
||||
#ifdef ITEM_Z_RING
|
||||
if ((GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT || (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(battlerId) == B_POSITION_PLAYER_RIGHT)) && !CheckBagHasItem(ITEM_Z_RING, 1))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (mega->alreadyEvolved[battlerPosition])
|
||||
return FALSE; // Trainer has mega evolved
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
if (IsPartnerMonFromSameTrainer(battlerId) && (mega->alreadyEvolved[partnerPosition] || (mega->toEvolve & gBitTable[BATTLE_PARTNER(battlerId)])))
|
||||
return FALSE; // Partner has mega evolved or is about to mega evolve
|
||||
}
|
||||
|
||||
if (B_ENABLE_DEBUG && gBattleStruct->debugHoldEffects[battlerId])
|
||||
holdEffect = gBattleStruct->debugHoldEffects[battlerId];
|
||||
else if (item == ITEM_ENIGMA_BERRY)
|
||||
return FALSE; // HoldEffect = gEnigmaBerries[battlerId].holdEffect;
|
||||
else
|
||||
holdEffect = ItemId_GetHoldEffect(item);
|
||||
|
||||
#ifdef ITEM_ULTRANECROZIUM_Z
|
||||
if (holdEffect == HOLD_EFFECT_Z_CRYSTAL || item == ITEM_ULTRANECROZIUM_Z)
|
||||
#else
|
||||
if (holdEffect == HOLD_EFFECT_Z_CRYSTAL)
|
||||
#endif
|
||||
{
|
||||
u16 zMove = GetSignatureZMove(move, gBattleMons[battlerId].species, item);
|
||||
if (zMove != MOVE_NONE)
|
||||
{
|
||||
gBattleStruct->zmove.chosenZMove = zMove; // Signature z move exists
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (move != MOVE_NONE && zMove != MOVE_Z_STATUS && gBattleMoves[move].type == ItemId_GetSecondaryId(item))
|
||||
{
|
||||
if (IS_MOVE_STATUS(gBattleMoves[move].split))
|
||||
gBattleStruct->zmove.chosenZMove = move;
|
||||
else
|
||||
gBattleStruct->zmove.chosenZMove = GetTypeBasedZMove(move, battlerId);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void GetUsableZMoves(u8 battlerId, u16 *moves)
|
||||
{
|
||||
u32 i;
|
||||
gBattleStruct->zmove.possibleZMoves[battlerId] = 0;
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE && IsViableZMove(battlerId, moves[i]))
|
||||
gBattleStruct->zmove.possibleZMoves[battlerId] |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
bool32 IsZMoveUsable(u8 battlerId, u16 moveIndex)
|
||||
{
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsPartnerMonFromSameTrainer(battlerId) && gBattleStruct->zmove.toBeUsed[BATTLE_PARTNER(battlerId)] != MOVE_NONE)
|
||||
return FALSE; // Player's other mon has a z move queued up already
|
||||
if (gBattleStruct->zmove.possibleZMoves[battlerId] & (1 << moveIndex))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 TryChangeZIndicator(u8 battlerId, u8 moveIndex)
|
||||
{
|
||||
bool32 viableZMove = IsZMoveUsable(battlerId, moveIndex);
|
||||
|
||||
if (gBattleStruct->zmove.viable && !viableZMove)
|
||||
HideZMoveTriggerSprite(); // Was a viable z move, now is not -> slide out
|
||||
else if (!gBattleStruct->zmove.viable && viableZMove)
|
||||
ShowZMoveTriggerSprite(); // Was not a viable z move, now is -> slide back in
|
||||
}
|
||||
|
||||
#define SINGLES_Z_TRIGGER_POS_X_OPTIMAL (29)
|
||||
#define SINGLES_Z_TRIGGER_POS_X_PRIORITY (29)
|
||||
#define SINGLES_Z_TRIGGER_POS_X_SLIDE (15)
|
||||
#define SINGLES_Z_TRIGGER_POS_Y_DIFF (-10)
|
||||
|
||||
#define DOUBLES_Z_TRIGGER_POS_X_OPTIMAL SINGLES_Z_TRIGGER_POS_X_OPTIMAL
|
||||
#define DOUBLES_Z_TRIGGER_POS_X_PRIORITY SINGLES_Z_TRIGGER_POS_X_PRIORITY
|
||||
#define DOUBLES_Z_TRIGGER_POS_X_SLIDE SINGLES_Z_TRIGGER_POS_X_SLIDE
|
||||
#define DOUBLES_Z_TRIGGER_POS_Y_DIFF (-4)
|
||||
|
||||
#define tBattler data[0]
|
||||
#define tHide data[1]
|
||||
|
||||
void CreateZMoveTriggerSprite(u8 battlerId, bool8 viable)
|
||||
{
|
||||
s16 x, y;
|
||||
|
||||
LoadSpritePalette(&sSpritePalette_ZMoveTrigger);
|
||||
if (GetSpriteTileStartByTag(TAG_ZMOVE_TRIGGER_TILE) == 0xFFFF)
|
||||
LoadCompressedSpriteSheetUsingHeap(&sSpriteSheet_ZMoveTrigger);
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
x = gSprites[gHealthboxSpriteIds[battlerId]].x - DOUBLES_Z_TRIGGER_POS_X_SLIDE;
|
||||
y = gSprites[gHealthboxSpriteIds[battlerId]].y - DOUBLES_Z_TRIGGER_POS_Y_DIFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = gSprites[gHealthboxSpriteIds[battlerId]].x - SINGLES_Z_TRIGGER_POS_X_SLIDE;
|
||||
y = gSprites[gHealthboxSpriteIds[battlerId]].y - SINGLES_Z_TRIGGER_POS_Y_DIFF, 0;
|
||||
}
|
||||
|
||||
if (gBattleStruct->zmove.triggerSpriteId == 0xFF)
|
||||
gBattleStruct->zmove.triggerSpriteId = CreateSprite(&sSpriteTemplate_ZMoveTrigger, x, y, 0);
|
||||
|
||||
gSprites[gBattleStruct->zmove.triggerSpriteId].tBattler = battlerId;
|
||||
gSprites[gBattleStruct->zmove.triggerSpriteId].tHide = (viable == TRUE) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
static void SpriteCB_ZMoveTrigger(struct Sprite *sprite)
|
||||
{
|
||||
s32 xSlide, xPriority, xOptimal;
|
||||
s32 yDiff;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||||
{
|
||||
xSlide = DOUBLES_Z_TRIGGER_POS_X_SLIDE;
|
||||
xPriority = DOUBLES_Z_TRIGGER_POS_X_PRIORITY;
|
||||
xOptimal = DOUBLES_Z_TRIGGER_POS_X_OPTIMAL;
|
||||
yDiff = DOUBLES_Z_TRIGGER_POS_Y_DIFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
xSlide = SINGLES_Z_TRIGGER_POS_X_SLIDE;
|
||||
xPriority = SINGLES_Z_TRIGGER_POS_X_PRIORITY;
|
||||
xOptimal = SINGLES_Z_TRIGGER_POS_X_OPTIMAL;
|
||||
yDiff = SINGLES_Z_TRIGGER_POS_Y_DIFF;
|
||||
}
|
||||
|
||||
if (sprite->tHide)
|
||||
{
|
||||
if (sprite->x != gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xSlide)
|
||||
sprite->x++;
|
||||
|
||||
if (sprite->x >= gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xPriority)
|
||||
sprite->oam.priority = 2;
|
||||
else
|
||||
sprite->oam.priority = 1;
|
||||
|
||||
sprite->y = gSprites[gHealthboxSpriteIds[sprite->tBattler]].y - yDiff;
|
||||
sprite->y2 = gSprites[gHealthboxSpriteIds[sprite->tBattler]].y2 - yDiff;
|
||||
if (sprite->x == gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xSlide)
|
||||
DestroyZMoveTriggerSprite();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sprite->x != gSprites[gHealthboxSpriteIds[sprite->tBattler]].x - xOptimal)
|
||||
{
|
||||
sprite->x--;
|
||||
sprite->oam.priority = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->oam.priority = 1;
|
||||
}
|
||||
sprite->y = gSprites[gHealthboxSpriteIds[sprite->tBattler]].y - yDiff;
|
||||
sprite->y2 = gSprites[gHealthboxSpriteIds[sprite->tBattler]].y2 - yDiff;
|
||||
}
|
||||
}
|
||||
|
||||
bool32 IsZMoveTriggerSpriteActive(void)
|
||||
{
|
||||
if (GetSpriteTileStartByTag(TAG_ZMOVE_TRIGGER_TILE) == 0xFFFF)
|
||||
return FALSE;
|
||||
else if (IndexOfSpritePaletteTag(TAG_ZMOVE_TRIGGER_PAL) != 0xFF)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void HideZMoveTriggerSprite(void)
|
||||
{
|
||||
struct Sprite *sprite = &gSprites[gBattleStruct->zmove.triggerSpriteId];
|
||||
sprite->tHide = TRUE;
|
||||
gBattleStruct->zmove.viable = FALSE;
|
||||
}
|
||||
|
||||
static void ShowZMoveTriggerSprite(void)
|
||||
{
|
||||
struct Sprite *sprite = &gSprites[gBattleStruct->zmove.triggerSpriteId];
|
||||
gBattleStruct->zmove.viable = TRUE;
|
||||
CreateZMoveTriggerSprite(sprite->tBattler, TRUE);
|
||||
}
|
||||
|
||||
void DestroyZMoveTriggerSprite(void)
|
||||
{
|
||||
FreeSpritePaletteByTag(TAG_ZMOVE_TRIGGER_PAL);
|
||||
FreeSpriteTilesByTag(TAG_ZMOVE_TRIGGER_TILE);
|
||||
if (gBattleStruct->zmove.triggerSpriteId != 0xFF)
|
||||
DestroySprite(&gSprites[gBattleStruct->zmove.triggerSpriteId]);
|
||||
|
||||
gBattleStruct->zmove.triggerSpriteId = 0xFF;
|
||||
}
|
||||
|
||||
static u16 GetSignatureZMove(u16 move, u16 species, u16 item)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
// Check signature z move
|
||||
for (i = 0; i < ARRAY_COUNT(sSignatureZMoves); ++i)
|
||||
{
|
||||
if (sSignatureZMoves[i].item == item && sSignatureZMoves[i].species == species && sSignatureZMoves[i].move == move)
|
||||
return sSignatureZMoves[i].zmove;
|
||||
}
|
||||
|
||||
return MOVE_NONE;
|
||||
}
|
||||
|
||||
static u16 GetTypeBasedZMove(u16 move, u8 battler)
|
||||
{
|
||||
u8 moveType = gBattleMoves[move].type;
|
||||
|
||||
// Get z move from type
|
||||
if (moveType < TYPE_FIRE)
|
||||
return MOVE_BREAKNECK_BLITZ + moveType;
|
||||
else if (moveType >= TYPE_FAIRY)
|
||||
return MOVE_TWINKLE_TACKLE + (moveType - TYPE_FAIRY);
|
||||
else
|
||||
return MOVE_BREAKNECK_BLITZ + (moveType - 1);
|
||||
}
|
||||
|
||||
bool32 MoveSelectionDisplayZMove(u16 zmove)
|
||||
{
|
||||
u32 i;
|
||||
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]);
|
||||
u16 move = moveInfo->moves[gMoveSelectionCursor[gActiveBattler]];
|
||||
|
||||
PlaySE(SE_SELECT);
|
||||
gBattleStruct->zmove.viewing = TRUE;
|
||||
if (zmove != MOVE_NONE)
|
||||
{
|
||||
// Clear move slots
|
||||
for (i = 0; i < MAX_MON_MOVES; ++i)
|
||||
{
|
||||
MoveSelectionDestroyCursorAt(i);
|
||||
StringCopy(gDisplayedStringBattle, gText_EmptyString2);
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, i + 3);
|
||||
}
|
||||
|
||||
if (IS_MOVE_STATUS(move))
|
||||
{
|
||||
u8 zEffect = gBattleMoves[move].zMoveEffect;
|
||||
|
||||
gDisplayedStringBattle[0] = EOS;
|
||||
|
||||
if (zEffect == Z_EFFECT_CURSE)
|
||||
{
|
||||
if (moveInfo->monType1 == TYPE_GHOST || moveInfo->monType2 == TYPE_GHOST || moveInfo->monType3 == TYPE_GHOST)
|
||||
zEffect = Z_EFFECT_RECOVER_HP;
|
||||
else
|
||||
zEffect = Z_EFFECT_ATK_UP_1;
|
||||
}
|
||||
|
||||
switch (zEffect)
|
||||
{
|
||||
case Z_EFFECT_RESET_STATS:
|
||||
StringCopy(gDisplayedStringBattle, sText_ResetStats);
|
||||
break;
|
||||
case Z_EFFECT_ALL_STATS_UP_1:
|
||||
StringCopy(gDisplayedStringBattle, sText_StatsPlus);
|
||||
break;
|
||||
case Z_EFFECT_BOOST_CRITS:
|
||||
StringCopy(gDisplayedStringBattle, sText_CritHitsPlus);
|
||||
break;
|
||||
case Z_EFFECT_FOLLOW_ME:
|
||||
StringCopy(gDisplayedStringBattle, sText_FollowMe);
|
||||
break;
|
||||
case Z_EFFECT_RECOVER_HP:
|
||||
StringCopy(gDisplayedStringBattle, sText_RecoverHP);
|
||||
break;
|
||||
case Z_EFFECT_RESTORE_REPLACEMENT_HP:
|
||||
StringCopy(gDisplayedStringBattle, sText_HealAllyHP);
|
||||
break;
|
||||
case Z_EFFECT_ATK_UP_1:
|
||||
case Z_EFFECT_DEF_UP_1:
|
||||
case Z_EFFECT_SPD_UP_1:
|
||||
case Z_EFFECT_SPATK_UP_1:
|
||||
case Z_EFFECT_SPDEF_UP_1:
|
||||
case Z_EFFECT_ACC_UP_1:
|
||||
case Z_EFFECT_EVSN_UP_1:
|
||||
gDisplayedStringBattle[0] = CHAR_PLUS;
|
||||
gDisplayedStringBattle[1] = 0;
|
||||
gDisplayedStringBattle[2] = EOS;
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, zEffect - Z_EFFECT_ATK_UP_1 + 1);
|
||||
ExpandBattleTextBuffPlaceholders(gBattleTextBuff1, gDisplayedStringBattle + 2);
|
||||
break;
|
||||
case Z_EFFECT_ATK_UP_2:
|
||||
case Z_EFFECT_DEF_UP_2:
|
||||
case Z_EFFECT_SPD_UP_2:
|
||||
case Z_EFFECT_SPATK_UP_2:
|
||||
case Z_EFFECT_SPDEF_UP_2:
|
||||
case Z_EFFECT_ACC_UP_2:
|
||||
case Z_EFFECT_EVSN_UP_2:
|
||||
gDisplayedStringBattle[0] = CHAR_PLUS;
|
||||
gDisplayedStringBattle[1] = CHAR_PLUS;
|
||||
gDisplayedStringBattle[2] = 0;
|
||||
gDisplayedStringBattle[3] = EOS;
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, zEffect - Z_EFFECT_ATK_UP_2 + 1);
|
||||
ExpandBattleTextBuffPlaceholders(gBattleTextBuff1, gDisplayedStringBattle + 3);
|
||||
break;
|
||||
case Z_EFFECT_ATK_UP_3:
|
||||
case Z_EFFECT_DEF_UP_3:
|
||||
case Z_EFFECT_SPD_UP_3:
|
||||
case Z_EFFECT_SPATK_UP_3:
|
||||
case Z_EFFECT_SPDEF_UP_3:
|
||||
case Z_EFFECT_ACC_UP_3:
|
||||
case Z_EFFECT_EVSN_UP_3:
|
||||
gDisplayedStringBattle[0] = CHAR_PLUS;
|
||||
gDisplayedStringBattle[1] = CHAR_PLUS;
|
||||
gDisplayedStringBattle[2] = CHAR_PLUS;
|
||||
gDisplayedStringBattle[3] = 0;
|
||||
gDisplayedStringBattle[4] = EOS;
|
||||
PREPARE_STAT_BUFFER(gBattleTextBuff1, zEffect - Z_EFFECT_ATK_UP_3 + 1);
|
||||
ExpandBattleTextBuffPlaceholders(gBattleTextBuff1, gDisplayedStringBattle + 4);
|
||||
break;
|
||||
}
|
||||
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, 5); // Slot of Move 3
|
||||
gDisplayedStringBattle[0] = CHAR_Z;
|
||||
gDisplayedStringBattle[1] = CHAR_HYPHEN;
|
||||
StringCopy(gDisplayedStringBattle + 2, gMoveNames[move]);
|
||||
}
|
||||
else if (zmove == MOVE_EXTREME_EVOBOOST)
|
||||
{
|
||||
// Damaging move -> status z move
|
||||
StringCopy(gDisplayedStringBattle, sText_StatsPlus2);
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, 5); // Slot of Move 3
|
||||
StringCopy(gDisplayedStringBattle, GetZMoveName(zmove));
|
||||
}
|
||||
else
|
||||
{
|
||||
ZMoveSelectionDisplayPower(move, zmove);
|
||||
StringCopy(gDisplayedStringBattle, GetZMoveName(zmove));
|
||||
}
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, 3); // First move slot
|
||||
|
||||
ZMoveSelectionDisplayPpNumber();
|
||||
MoveSelectionCreateCursorAt(0, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void ZMoveSelectionDisplayPower(u16 move, u16 zMove)
|
||||
{
|
||||
u8 *txtPtr;
|
||||
u16 power = gBattleMoves[move].zMovePower;
|
||||
|
||||
if (zMove >= MOVE_CATASTROPIKA)
|
||||
power = gBattleMoves[zMove].power;
|
||||
|
||||
if (gBattleMoves[move].split != SPLIT_STATUS)
|
||||
{
|
||||
txtPtr = StringCopy(gDisplayedStringBattle, sText_PowerColon);
|
||||
ConvertIntToDecimalStringN(txtPtr, power, STR_CONV_MODE_LEFT_ALIGN, 3);
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, 5); // Bottom left
|
||||
}
|
||||
}
|
||||
|
||||
static void ZMoveSelectionDisplayPpNumber(void)
|
||||
{
|
||||
u8 *txtPtr;
|
||||
struct ChooseMoveStruct *moveInfo;
|
||||
|
||||
if (gBattleResources->bufferA[gActiveBattler][2] == TRUE) // Check if we didn't want to display pp number
|
||||
return;
|
||||
|
||||
SetPpNumbersPaletteInMoveSelection();
|
||||
moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[gActiveBattler][4]);
|
||||
txtPtr = ConvertIntToDecimalStringN(gDisplayedStringBattle, 1, STR_CONV_MODE_RIGHT_ALIGN, 2);
|
||||
*(txtPtr)++ = CHAR_SLASH;
|
||||
ConvertIntToDecimalStringN(txtPtr, 1, STR_CONV_MODE_RIGHT_ALIGN, 2);
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, 9);
|
||||
}
|
||||
|
||||
const u8* GetZMoveName(u16 move)
|
||||
{
|
||||
if (IsZMove(move))
|
||||
return gZMoveNames[move - FIRST_Z_MOVE];
|
||||
else
|
||||
return gZMoveNames[0]; // Failsafe
|
||||
}
|
||||
|
||||
#define Z_EFFECT_BS_LENGTH 3
|
||||
// This function kinda cheats by setting a return battle script to after the setzeffect various command
|
||||
// and then jumping to a z effect script
|
||||
void SetZEffect(void)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
gBattleStruct->zmove.zStatusActive = TRUE;
|
||||
if (gBattleStruct->zmove.effect == Z_EFFECT_CURSE)
|
||||
{
|
||||
if (IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
|
||||
gBattleStruct->zmove.effect = Z_EFFECT_RECOVER_HP;
|
||||
else
|
||||
gBattleStruct->zmove.effect = Z_EFFECT_ATK_UP_1;
|
||||
}
|
||||
|
||||
gBattleScripting.savedStatChanger = gBattleScripting.statChanger; // Save used move's stat changer (e.g. for Z-Growl)
|
||||
gBattleScripting.battler = gBattlerAttacker;
|
||||
|
||||
switch (gBattleStruct->zmove.effect)
|
||||
{
|
||||
case Z_EFFECT_RESET_STATS:
|
||||
for (i = 0; i < NUM_BATTLE_STATS - 1; i++)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].statStages[i] < DEFAULT_STAT_STAGE)
|
||||
gBattleMons[gBattlerAttacker].statStages[i] = DEFAULT_STAT_STAGE;
|
||||
}
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_RESET_STATS;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_ZEffectPrintString;
|
||||
break;
|
||||
case Z_EFFECT_ALL_STATS_UP_1:
|
||||
if (!AreStatsMaxed(gBattlerAttacker, STAT_SPDEF))
|
||||
{
|
||||
for (i = 0; i < STAT_ACC - 1; i++) // Doesn't increase Acc or Evsn
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].statStages[i] < 12)
|
||||
++gBattleMons[gBattlerAttacker].statStages[i];
|
||||
}
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_ALL_STATS_UP;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_ZEffectPrintString;
|
||||
}
|
||||
break;
|
||||
case Z_EFFECT_BOOST_CRITS:
|
||||
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY))
|
||||
{
|
||||
gBattleMons[gBattlerAttacker].status2 |= STATUS2_FOCUS_ENERGY;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_BOOST_CRITS;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_ZEffectPrintString;
|
||||
}
|
||||
break;
|
||||
case Z_EFFECT_FOLLOW_ME:
|
||||
gSideTimers[GetBattlerSide(gBattlerAttacker)].followmeTimer = 1;
|
||||
gSideTimers[GetBattlerSide(gBattlerAttacker)].followmeTarget = gBattlerAttacker;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_FOLLOW_ME;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_ZEffectPrintString;
|
||||
break;
|
||||
case Z_EFFECT_RECOVER_HP:
|
||||
if (gBattleMons[gBattlerAttacker].hp != gBattleMons[gBattlerAttacker].maxHP)
|
||||
{
|
||||
gBattleMoveDamage = (-1) * gBattleMons[gBattlerAttacker].maxHP;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_RECOVER_HP;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_RecoverHPZMove;
|
||||
}
|
||||
break;
|
||||
case Z_EFFECT_RESTORE_REPLACEMENT_HP:
|
||||
gBattleStruct->zmove.healReplacement = TRUE;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_HP_TRAP;
|
||||
gBattlescriptCurrInstr = BattleScript_ZEffectPrintString;
|
||||
break;
|
||||
case Z_EFFECT_ATK_UP_1 ... Z_EFFECT_EVSN_UP_1:
|
||||
SET_STATCHANGER(gBattleStruct->zmove.effect - Z_EFFECT_ATK_UP_1 + 1, 1, FALSE);
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_StatUpZMove;
|
||||
break;
|
||||
case Z_EFFECT_ATK_UP_2 ... Z_EFFECT_EVSN_UP_2:
|
||||
SET_STATCHANGER(gBattleStruct->zmove.effect - Z_EFFECT_ATK_UP_2 + 1, 2, FALSE);
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_StatUpZMove;
|
||||
break;
|
||||
case Z_EFFECT_ATK_UP_3 ... Z_EFFECT_EVSN_UP_3:
|
||||
SET_STATCHANGER(gBattleStruct->zmove.effect - Z_EFFECT_ATK_UP_3 + 1, 3, FALSE);
|
||||
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
|
||||
gBattlescriptCurrInstr = BattleScript_StatUpZMove;
|
||||
break;
|
||||
default:
|
||||
gBattlescriptCurrInstr += 3;
|
||||
break;
|
||||
}
|
||||
|
||||
gBattleStruct->zmove.zStatusActive = FALSE;
|
||||
}
|
||||
|
||||
static bool32 AreStatsMaxed(u8 battlerId, u8 n)
|
||||
{
|
||||
u32 i;
|
||||
for (i = STAT_ATK; i <= n; i++)
|
||||
{
|
||||
if (STAT_STAGE(battlerId, i) < MAX_STAT_STAGE)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -757,3 +757,78 @@ const u8 gMoveNames[MOVES_COUNT][MOVE_NAME_LENGTH + 1] =
|
||||
[MOVE_ASTRAL_BARRAGE] = _("AstrlBarrage"),
|
||||
[MOVE_EERIE_SPELL] = _("Eerie Spell"),
|
||||
};
|
||||
|
||||
static const u8 sText_Breakneck_Blitz[] = _("Breakneck Blitz");
|
||||
static const u8 sText_All_Out_Pummeling[] = _("All Out Pummeling");
|
||||
static const u8 sText_Supersonic_Skystrike[] = _("Supersonic Skystrike");
|
||||
static const u8 sText_Acid_Downpour[] = _("Acid Downpour");
|
||||
static const u8 sText_Tectonic_Rage[] = _("Tectonic Rage");
|
||||
static const u8 sText_Continental_Crush[] = _("Continental Crush");
|
||||
static const u8 sText_Savage_Spin_Out[] = _("Savage Spin Out");
|
||||
static const u8 sText_Never_Ending_Nightmare[] = _("Never Ending Nightmare");
|
||||
static const u8 sText_Corkscrew_Crash[] = _("Corkscrew Crash");
|
||||
static const u8 sText_Inferno_Overdrive[] = _("Inferno Overdrive");
|
||||
static const u8 sText_Hydro_Vortex[] = _("Hydro Vortex");
|
||||
static const u8 sText_Bloom_Doom[] = _("Bloom Doom");
|
||||
static const u8 sText_Gigavolt_Havoc[] = _("Gigavolt Havoc");
|
||||
static const u8 sText_Shattered_Psyche[] = _("Shattered Psyche");
|
||||
static const u8 sText_Subzero_Slammer[] = _("Subzero Slammer");
|
||||
static const u8 sText_Devastating_Drake[] = _("Devastating Drake");
|
||||
static const u8 sText_Black_Hole_Eclipse[] = _("Black Hole Eclipse");
|
||||
static const u8 sText_Twinkle_Tackle[] = _("Twinkle Tackle");
|
||||
static const u8 sText_Catastropika[] = _("Catastropika");
|
||||
static const u8 sText_10000000_Volt_Thunderbolt[] = _("10000000 Volt Thunderbolt");
|
||||
static const u8 sText_Stoked_Sparksurfer[] = _("Stoked Sparksurfer");
|
||||
static const u8 sText_Extreme_Evoboost[] = _("Extreme Evoboost");
|
||||
static const u8 sText_Pulverizing_Pancake[] = _("Pulverizing Pancake");
|
||||
static const u8 sText_Genesis_Supernova[] = _("Genesis Supernova");
|
||||
static const u8 sText_Sinister_Arrow_Raid[] = _("Sinister Arrow Raid");
|
||||
static const u8 sText_Malicious_Moonsault[] = _("Malicious Moonsault");
|
||||
static const u8 sText_Oceanic_Operetta[] = _("Oceanic Operetta");
|
||||
static const u8 sText_Splintered_Stormshards[] = _("Splintered Stormshards");
|
||||
static const u8 sText_Lets_Snuggle_Forever[] = _("Let's Snuggle Forever");
|
||||
static const u8 sText_Clangorous_Soulblaze[] = _("Clangorous Soulblaze");
|
||||
static const u8 sText_Guardian_Of_Alola[] = _("Guardian Of Alola");
|
||||
static const u8 sText_Searing_Sunraze_Smash[] = _("Searing Sunraze Smash");
|
||||
static const u8 sText_Menacing_Moonraze_Maelstrom[] = _("Menacing Moonraze Maelstrom");
|
||||
static const u8 sText_Light_That_Burns_The_Sky[] = _("Light That Burns The Sky");
|
||||
static const u8 sText_Soul_Stealing_7_Star_Strike[] = _("Soul Stealing 7 Star Strike");
|
||||
|
||||
const u8 *const gZMoveNames[] =
|
||||
{
|
||||
[MOVE_BREAKNECK_BLITZ - FIRST_Z_MOVE] = sText_Breakneck_Blitz,
|
||||
[MOVE_ALL_OUT_PUMMELING - FIRST_Z_MOVE] = sText_All_Out_Pummeling,
|
||||
[MOVE_SUPERSONIC_SKYSTRIKE - FIRST_Z_MOVE] = sText_Supersonic_Skystrike,
|
||||
[MOVE_ACID_DOWNPOUR - FIRST_Z_MOVE] = sText_Acid_Downpour,
|
||||
[MOVE_TECTONIC_RAGE - FIRST_Z_MOVE] = sText_Tectonic_Rage,
|
||||
[MOVE_CONTINENTAL_CRUSH - FIRST_Z_MOVE] = sText_Continental_Crush,
|
||||
[MOVE_SAVAGE_SPIN_OUT - FIRST_Z_MOVE] = sText_Savage_Spin_Out,
|
||||
[MOVE_NEVER_ENDING_NIGHTMARE - FIRST_Z_MOVE] = sText_Never_Ending_Nightmare,
|
||||
[MOVE_CORKSCREW_CRASH - FIRST_Z_MOVE] = sText_Corkscrew_Crash,
|
||||
[MOVE_INFERNO_OVERDRIVE - FIRST_Z_MOVE] = sText_Inferno_Overdrive,
|
||||
[MOVE_HYDRO_VORTEX - FIRST_Z_MOVE] = sText_Hydro_Vortex,
|
||||
[MOVE_BLOOM_DOOM - FIRST_Z_MOVE] = sText_Bloom_Doom,
|
||||
[MOVE_GIGAVOLT_HAVOC - FIRST_Z_MOVE] = sText_Gigavolt_Havoc,
|
||||
[MOVE_SHATTERED_PSYCHE - FIRST_Z_MOVE] = sText_Shattered_Psyche,
|
||||
[MOVE_SUBZERO_SLAMMER - FIRST_Z_MOVE] = sText_Subzero_Slammer,
|
||||
[MOVE_DEVASTATING_DRAKE - FIRST_Z_MOVE] = sText_Devastating_Drake,
|
||||
[MOVE_BLACK_HOLE_ECLIPSE - FIRST_Z_MOVE] = sText_Black_Hole_Eclipse,
|
||||
[MOVE_TWINKLE_TACKLE - FIRST_Z_MOVE] = sText_Twinkle_Tackle,
|
||||
[MOVE_CATASTROPIKA - FIRST_Z_MOVE] = sText_Catastropika,
|
||||
[MOVE_10000000_VOLT_THUNDERBOLT - FIRST_Z_MOVE] = sText_10000000_Volt_Thunderbolt,
|
||||
[MOVE_STOKED_SPARKSURFER - FIRST_Z_MOVE] = sText_Stoked_Sparksurfer,
|
||||
[MOVE_EXTREME_EVOBOOST - FIRST_Z_MOVE] = sText_Extreme_Evoboost,
|
||||
[MOVE_PULVERIZING_PANCAKE - FIRST_Z_MOVE] = sText_Pulverizing_Pancake,
|
||||
[MOVE_GENESIS_SUPERNOVA - FIRST_Z_MOVE] = sText_Genesis_Supernova,
|
||||
[MOVE_SINISTER_ARROW_RAID - FIRST_Z_MOVE] = sText_Sinister_Arrow_Raid,
|
||||
[MOVE_MALICIOUS_MOONSAULT - FIRST_Z_MOVE] = sText_Malicious_Moonsault,
|
||||
[MOVE_OCEANIC_OPERETTA - FIRST_Z_MOVE] = sText_Oceanic_Operetta,
|
||||
[MOVE_SPLINTERED_STORMSHARDS - FIRST_Z_MOVE] = sText_Splintered_Stormshards,
|
||||
[MOVE_LETS_SNUGGLE_FOREVER - FIRST_Z_MOVE] = sText_Lets_Snuggle_Forever,
|
||||
[MOVE_CLANGOROUS_SOULBLAZE - FIRST_Z_MOVE] = sText_Clangorous_Soulblaze,
|
||||
[MOVE_GUARDIAN_OF_ALOLA - FIRST_Z_MOVE] = sText_Guardian_Of_Alola,
|
||||
[MOVE_SEARING_SUNRAZE_SMASH - FIRST_Z_MOVE] = sText_Searing_Sunraze_Smash,
|
||||
[MOVE_MENACING_MOONRAZE_MAELSTROM - FIRST_Z_MOVE] = sText_Menacing_Moonraze_Maelstrom,
|
||||
[MOVE_LIGHT_THAT_BURNS_THE_SKY - FIRST_Z_MOVE] = sText_Light_That_Burns_The_Sky,
|
||||
[MOVE_SOUL_STEALING_7_STAR_STRIKE - FIRST_Z_MOVE] = sText_Soul_Stealing_7_Star_Strike,
|
||||
};
|
||||
|
19
src/item.c
19
src/item.c
@ -948,25 +948,6 @@ u8 ItemId_GetSecondaryId(u16 itemId)
|
||||
return gItems[SanitizeItemId(itemId)].secondaryId;
|
||||
}
|
||||
|
||||
bool32 IsPinchBerryItemEffect(u16 holdEffect)
|
||||
{
|
||||
switch (holdEffect)
|
||||
{
|
||||
case HOLD_EFFECT_ATTACK_UP:
|
||||
case HOLD_EFFECT_DEFENSE_UP:
|
||||
case HOLD_EFFECT_SPEED_UP:
|
||||
case HOLD_EFFECT_SP_ATTACK_UP:
|
||||
case HOLD_EFFECT_SP_DEFENSE_UP:
|
||||
case HOLD_EFFECT_CRITICAL_UP:
|
||||
case HOLD_EFFECT_RANDOM_STAT_UP:
|
||||
case HOLD_EFFECT_CUSTAP_BERRY:
|
||||
case HOLD_EFFECT_MICLE_BERRY:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u8 ItemId_GetFlingPower(u16 itemId)
|
||||
{
|
||||
return gItems[SanitizeItemId(itemId)].flingPower;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "battle_pyramid.h"
|
||||
#include "battle_setup.h"
|
||||
#include "battle_tower.h"
|
||||
#include "battle_z_move.h"
|
||||
#include "data.h"
|
||||
#include "event_data.h"
|
||||
#include "evolution_scene.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user