Merge pull request #1932 from BuffelSaft/gen_8_moves_batch2

Gen 8 moves batch + Beak Blast
This commit is contained in:
ghoulslash 2022-05-01 07:47:11 -04:00 committed by GitHub
commit f0d74b60ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 429 additions and 98 deletions

View File

@ -1968,6 +1968,14 @@
various \battler, VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM
.endm
.macro setbeakblast battler:req
various \battler, VARIOUS_SET_BEAK_BLAST
.endm
.macro swapsidestatuses
various BS_ATTACKER, VARIOUS_SWAP_SIDE_STATUSES
.endm
@ helpful macros
.macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7

View File

@ -829,6 +829,8 @@ gBattleAnims_General::
.4byte General_StrongWinds @ B_ANIM_STRONG_WINDS
.4byte General_PrimalReversion @ B_ANIM_PRIMAL_REVERSION
.4byte General_AquaRingHeal @ B_ANIM_AQUA_RING_HEAL
.4byte General_BeakBlastSetUp @ B_ANIM_BEAK_BLAST_SETUP
.4byte General_ShellTrapSetUp @ B_ANIM_SHELL_TRAP_SETUP
.align 2
gBattleAnims_Special::
@ -11735,7 +11737,7 @@ Move_INSTRUCT::
blendoff
end
Move_BEAK_BLAST::
General_BeakBlastSetUp:
loadspritegfx ANIM_TAG_SMALL_EMBER @Fire
playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER
delay 0x3
@ -11743,7 +11745,7 @@ Move_BEAK_BLAST::
launchtemplate gFireSpiralOutwardSpriteTemplate 0x3 0x4 0x0 0x0 0x38 0x0
waitforvisualfinish
end
BeakBlastUnleash:
Move_BEAK_BLAST::
loadspritegfx ANIM_TAG_IMPACT
launchtask AnimTask_BlendBattleAnimPal 0xA 0x5 ANIM_PAL_ATK 0x2 0x0 0x9 0x1F
waitforvisualfinish
@ -11892,8 +11894,7 @@ Move_AURORA_VEIL::
blendoff
end
Move_SHELL_TRAP::
ShellTrapChargeUp:
General_ShellTrapSetUp:
loadspritegfx ANIM_TAG_SMALL_EMBER
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_TARGET
@ -11910,6 +11911,7 @@ ShellTrapChargeUp:
clearmonbg ANIM_TARGET
blendoff
end
Move_SHELL_TRAP::
ShellTrapUnleash:
loadspritegfx ANIM_TAG_IMPACT @pound
loadspritegfx ANIM_TAG_SMALL_RED_EYE @red
@ -13605,8 +13607,8 @@ Move_DRUM_BEATING::
blendoff
end
Move_SNAP_TRAP::
end @ to do:
Move_SNAP_TRAP:: @ placeholder
goto Move_BITE
Move_PYRO_BALL::
loadspritegfx ANIM_TAG_FLAT_ROCK
@ -24214,6 +24216,7 @@ General_TurnTrap:
jumpargeq 0, TRAP_ANIM_SAND_TOMB, Status_SandTomb
jumpargeq 0, TRAP_ANIM_MAGMA_STORM, Status_MagmaStorm
jumpargeq 0, TRAP_ANIM_INFESTATION, Status_Infestation
jumpargeq 0, TRAP_ANIM_SNAP_TRAP, Status_Snap_Trap
goto Status_BindWrap
Status_BindWrap:
loadspritegfx ANIM_TAG_TENDRILS
@ -24300,6 +24303,9 @@ Status_Clamp:
waitforvisualfinish
end
Status_Snap_Trap: @ placeholder
goto Move_BITE
Status_SandTomb:
loadspritegfx ANIM_TAG_MUD_SAND
createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 0, 4, 2, 0, 7, RGB(19, 17, 0)

View File

@ -404,6 +404,119 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectClangorousSoul @ EFFECT_CLANGOROUS_SOUL
.4byte BattleScript_EffectHit @ EFFECT_BOLT_BEAK
.4byte BattleScript_EffectSkyDrop @ EFFECT_SKY_DROP
.4byte BattleScript_EffectHit @ EFFECT_EXPANDING_FORCE
.4byte BattleScript_EffectScaleShot @ EFFECT_SCALE_SHOT
.4byte BattleScript_EffectMeteorBeam @ EFFECT_METEOR_BEAM
.4byte BattleScript_EffectHit @ EFFECT_RISING_VOLTAGE
.4byte BattleScript_EffectHit @ EFFECT_BEAK_BLAST
.4byte BattleScript_EffectCourtChange @ EFFECT_COURT_CHANGE
BattleScript_EffectCourtChange::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
swapsidestatuses
attackanimation
waitanimation
printstring STRINGID_COURTCHANGE
waitmessage 0x40
goto BattleScript_MoveEnd
BattleScript_BeakBlastSetUp::
setbeakblast BS_ATTACKER
printstring STRINGID_EMPTYSTRING3
waitmessage 0x1
playanimation BS_ATTACKER, B_ANIM_BEAK_BLAST_SETUP, NULL
printstring STRINGID_HEATUPBEAK
waitmessage 0x40
end2
BattleScript_BeakBlastBurn::
setbyte cMULTISTRING_CHOOSER, 0
copybyte gEffectBattler, gBattlerAttacker
call BattleScript_MoveEffectBurn
return
BattleScript_EffectMeteorBeam::
@ DecideTurn
jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_TwoTurnMovesSecondTurn
jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_NO_ATTACKSTRING, BattleScript_TwoTurnMovesSecondTurn
setbyte sTWOTURN_STRINGID, B_MSG_TURN1_METEOR_BEAM
call BattleScript_FirstChargingTurnMeteorBeam
jumpifnoholdeffect BS_ATTACKER, HOLD_EFFECT_POWER_HERB, BattleScript_MoveEnd
call BattleScript_PowerHerbActivation
goto BattleScript_TwoTurnMovesSecondTurn
BattleScript_FirstChargingTurnMeteorBeam::
attackcanceler
printstring STRINGID_EMPTYSTRING3
ppreduce
attackanimation
waitanimation
orword gHitMarker, HITMARKER_CHARGING
setmoveeffect MOVE_EFFECT_CHARGING | MOVE_EFFECT_AFFECTS_USER
seteffectprimary
copybyte cMULTISTRING_CHOOSER, sTWOTURN_STRINGID
printfromtable gFirstTurnOfTwoStringIds
waitmessage 0x40
setmoveeffect MOVE_EFFECT_SP_ATK_PLUS_1 | MOVE_EFFECT_AFFECTS_USER
seteffectsecondary
return
BattleScript_EffectScaleShot::
attackcanceler
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
setmultihitcounter 0x0
initmultihitstring
sethword sMULTIHIT_EFFECT, 0x0
BattleScript_ScaleShotLoop::
jumpifhasnohp BS_ATTACKER, BattleScript_ScaleShotEnd
jumpifhasnohp BS_TARGET, BattleScript_ScaleShotPrintStrings
jumpifhalfword CMP_EQUAL, gChosenMove, MOVE_SLEEP_TALK, BattleScript_ScaleShotDoMultiHit
jumpifstatus BS_ATTACKER, STATUS1_SLEEP, BattleScript_ScaleShotPrintStrings
BattleScript_ScaleShotDoMultiHit::
movevaluescleanup
copyhword sMOVE_EFFECT, sMULTIHIT_EFFECT
critcalc
damagecalc
jumpifmovehadnoeffect BattleScript_ScaleShotMultiHitNoMoreHits
adjustdamage
attackanimation
waitanimation
effectivenesssound
hitanimation BS_TARGET
waitstate
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
critmessage
waitmessage 0x40
multihitresultmessage
printstring STRINGID_EMPTYSTRING3
waitmessage 0x1
addbyte sMULTIHIT_STRING + 4, 0x1
moveendto MOVEEND_NEXT_TARGET
jumpifbyte CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_FOE_ENDURED, BattleScript_ScaleShotPrintStrings
decrementmultihit BattleScript_ScaleShotLoop
goto BattleScript_ScaleShotPrintStrings
BattleScript_ScaleShotMultiHitNoMoreHits::
pause 0x20
BattleScript_ScaleShotPrintStrings::
resultmessage
waitmessage 0x40
jumpifmovehadnoeffect BattleScript_ScaleShotEnd
copyarray gBattleTextBuff1, sMULTIHIT_STRING, 0x6
printstring STRINGID_HITXTIMES
waitmessage 0x40
BattleScript_ScaleShotEnd::
setmoveeffect MOVE_EFFECT_SCALE_SHOT | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN
seteffectwithchance
tryfaintmon BS_TARGET
moveendcase MOVEEND_SYNCHRONIZE_TARGET
moveendfrom MOVEEND_STATUS_IMMUNITY_ABILITIES
end
BattleScript_EffectSkyDrop:
jumpifstatus2 BS_ATTACKER, STATUS2_MULTIPLETURNS, BattleScript_SkyDropTurn2
@ -6760,6 +6873,7 @@ BattleScript_ToxicSpikesPoisoned::
BattleScript_StickyWebOnSwitchIn::
savetarget
copybyte gBattlerTarget, sBATTLER
setbyte sSTICKY_WEB_STAT_DROP, 1
printstring STRINGID_STICKYWEBSWITCHIN
waitmessage B_WAIT_TIME_LONG
jumpifability BS_TARGET, ABILITY_MIRROR_ARMOR, BattleScript_MirrorArmorReflectStickyWeb
@ -7168,6 +7282,26 @@ BattleScript_DefSpDefDownTrySpDef::
BattleScript_DefSpDefDownRet::
return
BattleScript_DefDownSpeedUp::
jumpifstat BS_ATTACKER, CMP_GREATER_THAN, STAT_DEF, MIN_STAT_STAGE, BattleScript_DefDownSpeedUpTryDef
jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPEED, MAX_STAT_STAGE, BattleScript_DefDownSpeedUpRet
BattleScript_DefDownSpeedUpTryDef::
playstatchangeanimation BS_ATTACKER, BIT_DEF, STAT_CHANGE_NEGATIVE | STAT_CHANGE_CANT_PREVENT
setstatchanger STAT_DEF, 1, TRUE
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR | MOVE_EFFECT_CERTAIN, BattleScript_DefDownSpeedUpTrySpeed
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_DefDownSpeedUpTrySpeed
printfromtable gStatDownStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_DefDownSpeedUpTrySpeed:
playstatchangeanimation BS_ATTACKER, BIT_SPEED, 0
setstatchanger STAT_SPEED, 1, FALSE
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR | MOVE_EFFECT_CERTAIN, BattleScript_DefDownSpeedUpRet
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_DefDownSpeedUpRet
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_DefDownSpeedUpRet::
return
BattleScript_KnockedOff::
playanimation BS_TARGET, B_ANIM_ITEM_KNOCKOFF
printstring STRINGID_PKMNKNOCKEDOFF

View File

@ -141,10 +141,12 @@ struct ProtectStruct
u32 usedMicleBerry:1;
u32 usedCustapBerry:1; // also quick claw
u32 touchedProtectLike:1;
u32 disableEjectPack:1;
u32 statFell:1;
u32 pranksterElevated:1;
u32 quickDraw:1;
// End of 32-bit bitfield
u16 disableEjectPack:1;
u16 statFell:1;
u16 pranksterElevated:1;
u16 quickDraw:1;
u16 beakBlastCharge:1;
u32 physicalDmg;
u32 specialDmg;
u8 physicalBattlerId;
@ -194,19 +196,21 @@ struct SideTimer
u8 mistBattlerId;
u8 safeguardTimer;
u8 safeguardBattlerId;
u8 followmeTimer;
u8 followmeTarget:3;
u8 followmePowder:1; // Rage powder, does not affect grass type pokemon.
u8 spikesAmount;
u8 toxicSpikesAmount;
u8 stealthRockAmount;
u8 stickyWebAmount;
u8 stickyWebBattlerSide; // Used for Court Change
u8 auroraVeilTimer;
u8 auroraVeilBattlerId;
u8 tailwindTimer;
u8 tailwindBattlerId;
u8 luckyChantTimer;
u8 luckyChantBattlerId;
// Timers below this point are not swapped by Court Change
u8 followmeTimer;
u8 followmeTarget:3;
u8 followmePowder:1; // Rage powder, does not affect grass type pokemon.
u8 retaliateTimer;
};
@ -699,6 +703,7 @@ struct BattleScripting
u16 abilityPopupOverwrite;
u8 switchCase; // Special switching conditions, eg. red card
u8 overrideBerryRequirements;
u8 stickyWebStatDrop; // To prevent Defiant activating on a Court Change'd Sticky Web
};
struct BattleSpriteInfo

View File

@ -60,6 +60,7 @@ bool32 IsAbilityOfRating(u16 ability, s8 rating);
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);
// stat stage checks
bool32 AnyStatIsRaised(u8 battlerId);

View File

@ -416,5 +416,8 @@ extern const u8 BattleScript_BothCanNoLongerEscape[];
extern const u8 BattleScript_OctolockEndTurn[];
extern const u8 BattleScript_NeutralizingGasExits[];
extern const u8 BattleScript_MagicianActivates[];
extern const u8 BattleScript_BeakBlastSetUp[];
extern const u8 BattleScript_BeakBlastBurn[];
extern const u8 BattleScript_DefDownSpeedUp[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -170,7 +170,7 @@ bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags);
void TryToApplyMimicry(u8 battlerId, bool8 various);
void TryToRevertMimicry(void);
void RestoreBattlerOriginalTypes(u8 battlerId);
u32 GetBattlerMoveTargetType(u8 battlerId, u16 move);
// Ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
bool32 IsRolePlayBannedAbility(u16 ability);

View File

@ -363,8 +363,9 @@
#define MOVE_EFFECT_RELIC_SONG 0x47
#define MOVE_EFFECT_TRAP_BOTH 0x48
#define MOVE_EFFECT_SKY_DROP 0x49
#define MOVE_EFFECT_SCALE_SHOT 0x4A
#define NUM_MOVE_EFFECTS 0x50
#define NUM_MOVE_EFFECTS 0x4B
#define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000

View File

@ -532,6 +532,8 @@
#define B_ANIM_STRONG_WINDS 30
#define B_ANIM_PRIMAL_REVERSION 31
#define B_ANIM_AQUA_RING_HEAL 32
#define B_ANIM_BEAK_BLAST_SETUP 33
#define B_ANIM_SHELL_TRAP_SETUP 34
// special animations table (gBattleAnims_Special)
#define B_ANIM_LVL_UP 0
@ -570,6 +572,7 @@
#define TRAP_ANIM_SAND_TOMB 4
#define TRAP_ANIM_MAGMA_STORM 5
#define TRAP_ANIM_INFESTATION 6
#define TRAP_ANIM_SNAP_TRAP 7
// Weather defines for battle animation scripts.
#define ANIM_WEATHER_NONE 0

View File

@ -387,7 +387,13 @@
#define EFFECT_CLANGOROUS_SOUL 381
#define EFFECT_BOLT_BEAK 382
#define EFFECT_SKY_DROP 383
#define EFFECT_EXPANDING_FORCE 384
#define EFFECT_SCALE_SHOT 385
#define EFFECT_METEOR_BEAM 386
#define EFFECT_RISING_VOLTAGE 387
#define EFFECT_BEAK_BLAST 388
#define EFFECT_COURT_CHANGE 389
#define NUM_BATTLE_MOVE_EFFECTS 384
#define NUM_BATTLE_MOVE_EFFECTS 390
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -39,6 +39,7 @@
#define sABILITY_OVERWRITE (gBattleScripting + 0x34) // abilityPopupOverwrite
#define sSWITCH_CASE (gBattleScripting + 0x36) // switchCase
#define sBERRY_OVERRIDE (gBattleScripting + 0x37) // overrideBerryRequirements
#define sSTICKY_WEB_STAT_DROP (gBattleScripting + 0x38) // stickyWebStatDrop
// Array entries for battle communication
#define MULTIUSE_STATE 0
@ -238,6 +239,8 @@
#define VARIOUS_SAVE_BATTLER_ITEM 148
#define VARIOUS_RESTORE_BATTLER_ITEM 149
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 150
#define VARIOUS_SET_BEAK_BLAST 151
#define VARIOUS_SWAP_SIDE_STATUSES 152
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View File

@ -609,8 +609,12 @@
#define STRINGID_NEUTRALIZINGGASOVER 607
#define STRINGID_TARGETTOOHEAVY 608
#define STRINGID_PKMNTOOKTARGETHIGH 609
#define STRINGID_PKMNINSNAPTRAP 610
#define STRINGID_METEORBEAMCHARGING 611
#define STRINGID_HEATUPBEAK 612
#define STRINGID_COURTCHANGE 613
#define BATTLESTRINGS_COUNT 610
#define BATTLESTRINGS_COUNT 614
// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
@ -667,6 +671,7 @@
#define B_MSG_TURN1_GEOMANCY 9
#define B_MSG_TURN1_FREEZE_SHOCK 10
#define B_MSG_TURN1_SKY_DROP 11
#define B_MSG_TURN1_METEOR_BEAM 12
// gMoveWeatherChangeStringIds
#define B_MSG_STARTED_RAIN 0

View File

@ -550,7 +550,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
u8 atkPriority = GetMovePriority(battlerAtk, move);
u16 moveEffect = gBattleMoves[move].effect;
s32 moveType;
u16 moveTarget = gBattleMoves[move].target;
u16 moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move);
u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move);
u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef);
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
@ -566,7 +566,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
GET_MOVE_TYPE(move, moveType);
// check non-user target
if (!(gBattleMoves[move].target & MOVE_TARGET_USER))
if (!(moveTarget & MOVE_TARGET_USER))
{
// handle negative checks on non-user target
// check powder moves
@ -2371,7 +2371,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
}
else
{
if (gBattleMoves[instructedMove].target & (MOVE_TARGET_SELECTED
if (AI_GetBattlerMoveTargetType(battlerDef, instructedMove) & (MOVE_TARGET_SELECTED
| MOVE_TARGET_DEPENDS
| MOVE_TARGET_RANDOM
| MOVE_TARGET_BOTH
@ -2568,7 +2568,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// move data
u8 moveType = gBattleMoves[move].type;
u16 effect = gBattleMoves[move].effect;
u16 target = gBattleMoves[move].target;
u16 moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move);
// ally data
u8 battlerAtkPartner = AI_DATA->battlerAtkPartner;
u16 atkPartnerAbility = AI_DATA->atkPartnerAbility;
@ -2607,7 +2607,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (IsAttackBoostMoveEffect(effect))
score -= 3;
// encourage moves hitting multiple opponents
if (!IS_MOVE_STATUS(move) && (gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
if (!IS_MOVE_STATUS(move) && (moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
score += 3;
}
}
@ -2675,7 +2675,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (GetMoveDamageResult(move) == MOVE_POWER_OTHER)
{
// partner ability checks
if (!partnerProtecting && gBattleMoves[move].target != MOVE_TARGET_BOTH && !DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move))
if (!partnerProtecting && moveTarget != MOVE_TARGET_BOTH && !DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move))
{
switch (atkPartnerAbility)
{
@ -2875,7 +2875,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (instructedMove != MOVE_NONE
&& !IS_MOVE_STATUS(instructedMove)
&& gBattleMoves[instructedMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) // Use instruct on multi-target moves
&& (AI_GetBattlerMoveTargetType(battlerAtkPartner, instructedMove) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) // Use instruct on multi-target moves
{
RETURN_SCORE_PLUS(1);
}
@ -3698,24 +3698,24 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break;
case MOVE_WIDE_GUARD:
if (predictedMove != MOVE_NONE && gBattleMoves[predictedMove].target & (MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_BOTH))
if (predictedMove != MOVE_NONE && AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_BOTH))
{
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
}
else if (isDoubleBattle && gBattleMoves[AI_DATA->partnerMove].target & MOVE_TARGET_FOES_AND_ALLY)
else if (isDoubleBattle && AI_GetBattlerMoveTargetType(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) & MOVE_TARGET_FOES_AND_ALLY)
{
if (AI_DATA->atkAbility != ABILITY_TELEPATHY)
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
}
break;
case MOVE_CRAFTY_SHIELD:
if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(gBattleMoves[predictedMove].target & MOVE_TARGET_USER))
if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER))
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break;
case MOVE_MAT_BLOCK:
if (gDisableStructs[battlerAtk].isFirstTurn && predictedMove != MOVE_NONE
&& !IS_MOVE_STATUS(predictedMove) && !(gBattleMoves[predictedMove].target & MOVE_TARGET_USER))
&& !IS_MOVE_STATUS(predictedMove) && !(AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER))
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break;
case MOVE_KINGS_SHIELD:
@ -4160,7 +4160,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 10;
break;
case EFFECT_MAGIC_COAT:
if (IS_MOVE_STATUS(predictedMove) && gBattleMoves[predictedMove].target & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH))
if (IS_MOVE_STATUS(predictedMove) && AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH))
score += 3;
break;
case EFFECT_RECYCLE:

View File

@ -1251,6 +1251,16 @@ bool32 AI_WeatherHasEffect(void)
return TRUE;
}
u32 AI_GetBattlerMoveTargetType(u8 battlerId, u16 move)
{
u32 target;
if (gBattleMoves[move].effect == EFFECT_EXPANDING_FORCE && AI_IsTerrainAffected(battlerId, STATUS_FIELD_PSYCHIC_TERRAIN))
return MOVE_TARGET_BOTH;
else
return gBattleMoves[move].target;
}
bool32 IsAromaVeilProtectedMove(u16 move)
{
u32 i;
@ -1919,9 +1929,8 @@ bool32 HasMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef, u8 accCheck, bool32
if (ignoreStatus && IS_MOVE_STATUS(moves[i]))
continue;
else if ((!IS_MOVE_STATUS(moves[i]) && gBattleMoves[moves[i]].accuracy == 0)
|| gBattleMoves[moves[i]].target & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD))
|| AI_GetBattlerMoveTargetType(battlerAtk, moves[i]) & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD))
continue;
if (AI_GetMoveAccuracy(battlerAtk, battlerDef, atkAbility, defAbility, atkHoldEffect, defHoldEffect, moves[i]) <= accCheck)
return TRUE;
}

View File

@ -204,7 +204,7 @@ void DoMoveAnim(u16 move)
gBattleAnimAttacker = gBattlerAttacker;
gBattleAnimTarget = gBattlerTarget;
// Make sure the anim target of moves hitting everyone is at the opposite side.
if (gBattleMoves[move].target & MOVE_TARGET_FOES_AND_ALLY && IsDoubleBattle())
if (GetBattlerMoveTargetType(gBattlerAttacker, move) & MOVE_TARGET_FOES_AND_ALLY && IsDoubleBattle())
{
while (GET_BATTLER_SIDE(gBattleAnimAttacker) == GET_BATTLER_SIDE(gBattleAnimTarget))
{

View File

@ -2500,6 +2500,8 @@ void AnimTask_GetTrappedMoveAnimId(u8 taskId)
gBattleAnimArgs[0] = TRAP_ANIM_MAGMA_STORM;
else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_INFESTATION)
gBattleAnimArgs[0] = TRAP_ANIM_INFESTATION;
else if (gBattleSpritesDataPtr->animationData->animArg == MOVE_SNAP_TRAP)
gBattleAnimArgs[0] = TRAP_ANIM_SNAP_TRAP;
else
gBattleAnimArgs[0] = TRAP_ANIM_BIND;

View File

@ -1584,9 +1584,9 @@ static void OpponentHandleChooseMove(void)
BtlController_EmitTwoReturnValues(BUFFER_B, 15, gBattlerTarget);
break;
default:
if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
if (GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[chosenMoveId]) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
gBattlerTarget = gActiveBattler;
if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH)
if (GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[chosenMoveId]) & MOVE_TARGET_BOTH)
{
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
@ -1611,7 +1611,7 @@ static void OpponentHandleChooseMove(void)
move = moveInfo->moves[chosenMoveId];
} while (move == MOVE_NONE);
if (gBattleMoves[move].target & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
if (GetBattlerMoveTargetType(gActiveBattler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gActiveBattler << 8));
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{

View File

@ -357,6 +357,7 @@ static void HandleInputChooseTarget(void)
s32 i;
static const u8 identities[MAX_BATTLERS_COUNT] = {B_POSITION_PLAYER_LEFT, B_POSITION_PLAYER_RIGHT, B_POSITION_OPPONENT_RIGHT, B_POSITION_OPPONENT_LEFT};
u16 move = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler]);
u16 moveTarget = GetBattlerMoveTargetType(gActiveBattler, move);
DoBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX, 15, 1);
for (i = 0; i < gBattlersCount; i++)
@ -397,7 +398,7 @@ static void HandleInputChooseTarget(void)
PlaySE(SE_SELECT);
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCb_HideAsMoveTarget;
if (gBattleMoves[move].target == (MOVE_TARGET_USER | MOVE_TARGET_ALLY))
if (moveTarget == (MOVE_TARGET_USER | MOVE_TARGET_ALLY))
{
gMultiUsePlayerCursor ^= BIT_FLANK;
}
@ -426,7 +427,7 @@ static void HandleInputChooseTarget(void)
case B_POSITION_PLAYER_RIGHT:
if (gActiveBattler != gMultiUsePlayerCursor)
i++;
else if (gBattleMoves[move].target & MOVE_TARGET_USER_OR_SELECTED)
else if (moveTarget & MOVE_TARGET_USER_OR_SELECTED)
i++;
break;
case B_POSITION_OPPONENT_LEFT:
@ -446,7 +447,7 @@ static void HandleInputChooseTarget(void)
PlaySE(SE_SELECT);
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCb_HideAsMoveTarget;
if (gBattleMoves[move].target == (MOVE_TARGET_USER | MOVE_TARGET_ALLY))
if (moveTarget == (MOVE_TARGET_USER | MOVE_TARGET_ALLY))
{
gMultiUsePlayerCursor ^= BIT_FLANK;
}
@ -475,7 +476,7 @@ static void HandleInputChooseTarget(void)
case B_POSITION_PLAYER_RIGHT:
if (gActiveBattler != gMultiUsePlayerCursor)
i++;
else if (gBattleMoves[move].target & MOVE_TARGET_USER_OR_SELECTED)
else if (moveTarget & MOVE_TARGET_USER_OR_SELECTED)
i++;
break;
case B_POSITION_OPPONENT_LEFT:
@ -608,7 +609,7 @@ static void HandleInputChooseMove(void)
}
else
{
moveTarget = gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]].target;
moveTarget = GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]);
}
if (moveTarget & MOVE_TARGET_USER)

View File

@ -34,7 +34,7 @@ extern const struct CompressedSpriteSheet gSpriteSheet_EnemyShadow;
extern const struct SpriteTemplate gSpriteTemplate_EnemyShadow;
// this file's functions
static u8 GetBattlePalaceMoveGroup(u16 move);
static u8 GetBattlePalaceMoveGroup(u8 battlerId, u16 move);
static u16 GetBattlePalaceTarget(void);
static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite);
static bool8 ShouldAnimBeDoneRegardlessOfSubstitute(u8 animId);
@ -151,7 +151,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
{
if (moveInfo->moves[i] == MOVE_NONE)
break;
if (selectedGroup == GetBattlePalaceMoveGroup(moveInfo->moves[i]) && moveInfo->currentPp[i] != 0)
if (selectedGroup == GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]) && moveInfo->currentPp[i] != 0)
selectedMoves |= gBitTable[i];
}
@ -177,11 +177,11 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
{
// validMoveFlags is used here as a bitfield for which moves can be used for each move group type
// first 4 bits are for attack (1 for each move), then 4 bits for defense, and 4 for support
if (GetBattlePalaceMoveGroup(moveInfo->moves[i]) == PALACE_MOVE_GROUP_ATTACK && !(gBitTable[i] & unusableMovesBits))
if (GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_ATTACK && !(gBitTable[i] & unusableMovesBits))
validMoveFlags += (1 << 0);
if (GetBattlePalaceMoveGroup(moveInfo->moves[i]) == PALACE_MOVE_GROUP_DEFENSE && !(gBitTable[i] & unusableMovesBits))
if (GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_DEFENSE && !(gBitTable[i] & unusableMovesBits))
validMoveFlags += (1 << 4);
if (GetBattlePalaceMoveGroup(moveInfo->moves[i]) == PALACE_MOVE_GROUP_SUPPORT && !(gBitTable[i] & unusableMovesBits))
if (GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_SUPPORT && !(gBitTable[i] & unusableMovesBits))
validMoveFlags += (1 << 8);
}
@ -218,7 +218,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
do
{
i = Random() % MAX_MON_MOVES;
if (!(gBitTable[i] & unusableMovesBits) && validMoveGroup == GetBattlePalaceMoveGroup(moveInfo->moves[i]))
if (!(gBitTable[i] & unusableMovesBits) && validMoveGroup == GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]))
chosenMoveId = i;
} while (chosenMoveId == -1);
}
@ -247,7 +247,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
}
else
{
moveTarget = gBattleMoves[moveInfo->moves[chosenMoveId]].target;
moveTarget = GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[chosenMoveId]);
}
if (moveTarget & MOVE_TARGET_USER)
@ -269,9 +269,9 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
#undef numValidMoveGroups
#undef validMoveGroup
static u8 GetBattlePalaceMoveGroup(u16 move)
static u8 GetBattlePalaceMoveGroup(u8 battlerId, u16 move)
{
switch (gBattleMoves[move].target)
switch (GetBattlerMoveTargetType(battlerId, move))
{
case MOVE_TARGET_SELECTED:
case MOVE_TARGET_USER_OR_SELECTED:

View File

@ -4820,13 +4820,19 @@ static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void)
{
gActiveBattler = gBattlerAttacker = gBattleStruct->focusPunchBattlerId;
gBattleStruct->focusPunchBattlerId++;
if (gChosenMoveByBattler[gActiveBattler] == MOVE_FOCUS_PUNCH
&& !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
if (!(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
&& !(gDisableStructs[gBattlerAttacker].truantCounter)
&& !(gProtectStructs[gActiveBattler].noValidMoves))
{
BattleScriptExecute(BattleScript_FocusPunchSetUp);
return;
switch(gChosenMoveByBattler[gActiveBattler])
{
case MOVE_FOCUS_PUNCH:
BattleScriptExecute(BattleScript_FocusPunchSetUp);
return;
case MOVE_BEAK_BLAST:
BattleScriptExecute(BattleScript_BeakBlastSetUp);
return;
}
}
}
}

View File

@ -144,6 +144,7 @@ static const u8 sText_PkmnDugHole[] = _("{B_ATK_NAME_WITH_PREFIX} dug a hole!");
static const u8 sText_PkmnHidUnderwater[] = _("{B_ATK_NAME_WITH_PREFIX} hid\nunderwater!");
static const u8 sText_PkmnSprangUp[] = _("{B_ATK_NAME_WITH_PREFIX} sprang up!");
static const u8 sText_PkmnSqueezedByBind[] = _("{B_DEF_NAME_WITH_PREFIX} was squeezed by\n{B_ATK_NAME_WITH_PREFIX}'s BIND!");
static const u8 sText_PkmnInSnapTrap[] = _("{B_DEF_NAME_WITH_PREFIX} got trapped\nby a snap trap!");
static const u8 sText_PkmnTrappedInVortex[] = _("{B_DEF_NAME_WITH_PREFIX} was trapped\nin the vortex!");
static const u8 sText_PkmnTrappedBySandTomb[] = _("{B_DEF_NAME_WITH_PREFIX} was trapped\nby SAND TOMB!");
static const u8 sText_PkmnWrappedBy[] = _("{B_DEF_NAME_WITH_PREFIX} was WRAPPED by\n{B_ATK_NAME_WITH_PREFIX}!");
@ -734,9 +735,16 @@ static const u8 sText_NeutralizingGasEnters[] = _("Neutralizing Gas filled the a
static const u8 sText_NeutralizingGasOver[] = _("The effects of Neutralizing\nGas wore off!");
static const u8 sText_PkmnTookTargetHigh[] = _("{B_ATK_NAME_WITH_PREFIX} took {B_DEF_NAME_WITH_PREFIX}\ninto the air!");
static const u8 sText_TargetTooHeavy[] = _("But the target\nwas too heavy!");
static const u8 sText_MeteorBeamCharging[] = _("{B_ATK_NAME_WITH_PREFIX} is overflowing\nwith space energy!");
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_COURTCHANGE - BATTLESTRINGS_TABLE_START] = sText_CourtChange,
[STRINGID_HEATUPBEAK - BATTLESTRINGS_TABLE_START] = sText_HeatingUpBeak,
[STRINGID_METEORBEAMCHARGING - BATTLESTRINGS_TABLE_START] = sText_MeteorBeamCharging,
[STRINGID_PKMNINSNAPTRAP - BATTLESTRINGS_TABLE_START] = sText_PkmnInSnapTrap,
[STRINGID_NEUTRALIZINGGASOVER - BATTLESTRINGS_TABLE_START] = sText_NeutralizingGasOver,
[STRINGID_NEUTRALIZINGGASENTERS - BATTLESTRINGS_TABLE_START] = sText_NeutralizingGasEnters,
[STRINGID_BATTLERTYPECHANGEDTO - BATTLESTRINGS_TABLE_START] = sText_BattlerTypeChangedTo,
@ -1550,6 +1558,7 @@ const u16 gFirstTurnOfTwoStringIds[] =
[B_MSG_TURN1_GEOMANCY] = STRINGID_PKNMABSORBINGPOWER,
[B_MSG_TURN1_FREEZE_SHOCK] = STRINGID_CLOAKEDINAFREEZINGLIGHT,
[B_MSG_TURN1_SKY_DROP] = STRINGID_PKMNTOOKTARGETHIGH,
[B_MSG_TURN1_METEOR_BEAM] = STRINGID_METEORBEAMCHARGING,
};
// Index copied from move's index in sTrappingMoves
@ -1563,6 +1572,7 @@ const u16 gWrappedStringIds[] =
STRINGID_PKMNTRAPPEDBYSANDTOMB, // MOVE_SAND_TOMB
STRINGID_TRAPPEDBYSWIRLINGMAGMA, // MOVE_MAGMA_STORM
STRINGID_INFESTATION, // MOVE_INFESTATION
STRINGID_PKMNINSNAPTRAP, // MOVE_SNAPTRAP
};
const u16 gMistUsedStringIds[] =

View File

@ -281,7 +281,7 @@ static const s32 sExperienceScalingFactors[] =
static const u16 sTrappingMoves[] =
{
MOVE_BIND, MOVE_WRAP, MOVE_FIRE_SPIN, MOVE_CLAMP, MOVE_WHIRLPOOL, MOVE_SAND_TOMB, MOVE_MAGMA_STORM, MOVE_INFESTATION, 0xFFFF
MOVE_BIND, MOVE_WRAP, MOVE_FIRE_SPIN, MOVE_CLAMP, MOVE_WHIRLPOOL, MOVE_SAND_TOMB, MOVE_MAGMA_STORM, MOVE_INFESTATION, MOVE_SNAP_TRAP, 0xFFFF
};
#define STAT_CHANGE_WORKED 0
@ -1296,12 +1296,12 @@ static const u8 sBattlePalaceNatureToFlavorTextId[NUM_NATURES] =
[NATURE_QUIRKY] = B_MSG_EAGER_FOR_MORE,
};
static bool32 NoTargetPresent(u32 move)
static bool32 NoTargetPresent(u8 battlerId, u32 move)
{
if (!IsBattlerAlive(gBattlerTarget))
gBattlerTarget = GetMoveTarget(move, NO_TARGET_OVERRIDE);
switch (gBattleMoves[move].target)
switch (GetBattlerMoveTargetType(battlerId, move))
{
case MOVE_TARGET_SELECTED:
case MOVE_TARGET_DEPENDS:
@ -1446,7 +1446,7 @@ static void Cmd_attackcanceler(void)
}
gHitMarker |= HITMARKER_OBEYS;
if (NoTargetPresent(gCurrentMove) && (!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
if (NoTargetPresent(gBattlerAttacker, gCurrentMove) && (!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
{
gBattlescriptCurrInstr = BattleScript_ButItFailedAtkStringPpReduce;
if (!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
@ -1530,6 +1530,11 @@ static void Cmd_attackcanceler(void)
gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED;
gBattlescriptCurrInstr++;
}
else if (gProtectStructs[gBattlerTarget].beakBlastCharge && IsMoveMakingContact(gCurrentMove, gBattlerAttacker))
{
gProtectStructs[gBattlerAttacker].touchedProtectLike = TRUE;
gBattlescriptCurrInstr++;
}
else
{
gBattlescriptCurrInstr++;
@ -1724,6 +1729,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move)
static void Cmd_accuracycheck(void)
{
u16 type, move = T2_READ_16(gBattlescriptCurrInstr + 5);
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move);
if (move == ACC_CURR_MOVE)
move = gCurrentMove;
@ -1753,7 +1759,7 @@ static void Cmd_accuracycheck(void)
gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE &&
(gBattleMoves[move].target == MOVE_TARGET_BOTH || gBattleMoves[move].target == MOVE_TARGET_FOES_AND_ALLY))
(moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY))
gBattleCommunication[MISS_TYPE] = B_MSG_AVOIDED_ATK;
else
gBattleCommunication[MISS_TYPE] = B_MSG_MISSED;
@ -1787,7 +1793,7 @@ static void Cmd_ppreduce(void)
if (!gSpecialStatuses[gBattlerAttacker].ppNotAffectedByPressure)
{
switch (gBattleMoves[gCurrentMove].target)
switch (GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove))
{
case MOVE_TARGET_FOES_AND_ALLY:
for (i = 0; i < gBattlersCount; i++)
@ -2087,6 +2093,8 @@ static void Cmd_multihitresultmessage(void)
static void Cmd_attackanimation(void)
{
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
if (gBattleControllerExecFlags)
return;
@ -2103,9 +2111,9 @@ static void Cmd_attackanimation(void)
}
else
{
if ((gBattleMoves[gCurrentMove].target & MOVE_TARGET_BOTH
|| gBattleMoves[gCurrentMove].target & MOVE_TARGET_FOES_AND_ALLY
|| gBattleMoves[gCurrentMove].target & MOVE_TARGET_DEPENDS)
if ((moveTarget & MOVE_TARGET_BOTH
|| moveTarget & MOVE_TARGET_FOES_AND_ALLY
|| moveTarget & MOVE_TARGET_DEPENDS)
&& gBattleScripting.animTargetsHit)
{
gBattlescriptCurrInstr++;
@ -3159,7 +3167,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
| BATTLE_TYPE_LINK
| BATTLE_TYPE_RECORDED_LINK
| BATTLE_TYPE_SECRET_BASE))
&& (gWishFutureKnock.knockedOffMons[side] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]))
&& (gWishFutureKnock.knockedOffMons[side] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]))
{
gBattlescriptCurrInstr++;
}
@ -3495,6 +3503,13 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleMons[gBattlerTarget].status2 |= STATUS2_ESCAPE_PREVENTION;
gBattleMons[gBattlerAttacker].status2 |= STATUS2_ESCAPE_PREVENTION;
break;
case MOVE_EFFECT_SCALE_SHOT:
if (!NoAliveMonsForEitherParty())
{
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_DefDownSpeedUp;
}
break;
}
}
}
@ -5014,7 +5029,7 @@ static void Cmd_moveend(void)
}
else if (gProtectStructs[gBattlerTarget].obstructed && gCurrentMove != MOVE_SUCKER_PUNCH)
{
gProtectStructs[gBattlerAttacker].touchedProtectLike = 0;
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
i = gBattlerAttacker;
gBattlerAttacker = gBattlerTarget;
gBattlerTarget = i; // gBattlerTarget and gBattlerAttacker are swapped in order to activate Defiant, if applicable
@ -5023,6 +5038,17 @@ static void Cmd_moveend(void)
gBattlescriptCurrInstr = BattleScript_KingsShieldEffect;
effect = 1;
}
// Not strictly a protect effect, but works the same way
else if (gProtectStructs[gBattlerTarget].beakBlastCharge
&& CanBeBurned(gBattlerAttacker)
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
{
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
gBattleMons[gBattlerAttacker].status1 = STATUS1_BURN;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BeakBlastBurn;
effect = 1;
}
}
gBattleScripting.moveendState++;
break;
@ -5318,6 +5344,8 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_NEXT_TARGET: // For moves hitting two opposing Pokemon.
{
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
// Set a flag if move hits either target (for throat spray that can't check damage)
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
@ -5326,12 +5354,13 @@ static void Cmd_moveend(void)
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& !gProtectStructs[gBattlerAttacker].chargingTurn
&& (gBattleMoves[gCurrentMove].target == MOVE_TARGET_BOTH || gBattleMoves[gCurrentMove].target == MOVE_TARGET_FOES_AND_ALLY)
&& (moveTarget == MOVE_TARGET_BOTH
|| moveTarget == MOVE_TARGET_FOES_AND_ALLY)
&& !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
{
u8 battlerId;
if (gBattleMoves[gCurrentMove].target == MOVE_TARGET_FOES_AND_ALLY)
if (moveTarget == MOVE_TARGET_FOES_AND_ALLY)
{
gHitMarker |= HITMARKER_NO_PPDEDUCT;
for (battlerId = gBattlerTarget + 1; battlerId < gBattlersCount; battlerId++)
@ -5367,6 +5396,7 @@ static void Cmd_moveend(void)
RecordLastUsedMoveBy(gBattlerAttacker, gCurrentMove);
gBattleScripting.moveendState++;
break;
}
case MOVEEND_EJECT_BUTTON:
if (gCurrentMove != MOVE_DRAGON_TAIL
&& gCurrentMove != MOVE_CIRCLE_THROW
@ -7621,6 +7651,66 @@ static bool32 IsRototillerAffected(u32 battlerId)
return TRUE;
}
#define COURTCHANGE_SWAP(status, structField, temp) \
{ \
temp = gSideStatuses[B_SIDE_PLAYER]; \
if (gSideStatuses[B_SIDE_OPPONENT] & status) \
gSideStatuses[B_SIDE_PLAYER] |= status; \
else \
gSideStatuses[B_SIDE_PLAYER] &= ~(status); \
if (temp & status) \
gSideStatuses[B_SIDE_OPPONENT] |= status; \
else \
gSideStatuses[B_SIDE_OPPONENT] &= ~(status); \
SWAP(sideTimerPlayer->structField, sideTimerOpp->structField, temp);\
} \
#define UPDATE_COURTCHANGED_BATTLER(structField)\
{ \
sideTimerPlayer->structField ^= BIT_SIDE; \
sideTimerOpp->structField ^= BIT_SIDE; \
} \
static bool32 CourtChangeSwapSideStatuses(void)
{
struct SideTimer *sideTimerPlayer = &gSideTimers[B_SIDE_PLAYER];
struct SideTimer *sideTimerOpp = &gSideTimers[B_SIDE_OPPONENT];
u32 temp;
// TODO: add Pledge-related effects
// TODO: add Gigantamax-related effects
// Swap timers and statuses
COURTCHANGE_SWAP(SIDE_STATUS_REFLECT, reflectTimer, temp)
COURTCHANGE_SWAP(SIDE_STATUS_LIGHTSCREEN, lightscreenTimer, temp)
COURTCHANGE_SWAP(SIDE_STATUS_MIST, mistTimer, temp);
COURTCHANGE_SWAP(SIDE_STATUS_SAFEGUARD, safeguardTimer, temp);
COURTCHANGE_SWAP(SIDE_STATUS_AURORA_VEIL, auroraVeilTimer, temp);
COURTCHANGE_SWAP(SIDE_STATUS_TAILWIND, tailwindTimer, temp);
// Lucky Chant doesn't exist in gen 8, but seems like it should be affected by Court Change
COURTCHANGE_SWAP(SIDE_STATUS_LUCKY_CHANT, luckyChantTimer, temp);
COURTCHANGE_SWAP(SIDE_STATUS_SPIKES, spikesAmount, temp);
COURTCHANGE_SWAP(SIDE_STATUS_STEALTH_ROCK, stealthRockAmount, temp);
COURTCHANGE_SWAP(SIDE_STATUS_TOXIC_SPIKES, toxicSpikesAmount, temp);
COURTCHANGE_SWAP(SIDE_STATUS_STICKY_WEB, stickyWebAmount, temp);
// Change battler IDs of swapped effects. Needed for the correct string when they expire
// E.g. "Foe's Reflect wore off!"
UPDATE_COURTCHANGED_BATTLER(reflectBattlerId);
UPDATE_COURTCHANGED_BATTLER(lightscreenBattlerId);
UPDATE_COURTCHANGED_BATTLER(mistBattlerId);
UPDATE_COURTCHANGED_BATTLER(safeguardBattlerId);
UPDATE_COURTCHANGED_BATTLER(auroraVeilBattlerId);
UPDATE_COURTCHANGED_BATTLER(tailwindBattlerId);
UPDATE_COURTCHANGED_BATTLER(luckyChantBattlerId);
// For Mirror Armor only
gBattleStruct->stickyWebUser = gBattlerAttacker;
// Track which side originally set the Sticky Web
SWAP(sideTimerPlayer->stickyWebBattlerSide, sideTimerOpp->stickyWebBattlerSide, temp);
}
static void Cmd_various(void)
{
struct Pokemon *mon;
@ -8322,6 +8412,7 @@ static void Cmd_various(void)
case MOVE_MIRROR_COAT:
case MOVE_METAL_BURST:
case MOVE_ME_FIRST:
case MOVE_BEAK_BLAST:
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
break;
default:
@ -9474,6 +9565,12 @@ static void Cmd_various(void)
case VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM:
gBattleMons[gActiveBattler].item = gLastUsedItem;
break;
case VARIOUS_SET_BEAK_BLAST:
gProtectStructs[gBattlerAttacker].beakBlastCharge = TRUE;
break;
case VARIOUS_SWAP_SIDE_STATUSES:
CourtChangeSwapSideStatuses();
break;
} // End of switch (gBattlescriptCurrInstr[2])
gBattlescriptCurrInstr += 3;
@ -9618,7 +9715,7 @@ static void Cmd_jumpifnexttargetvalid(void)
for (gBattlerTarget++; gBattlerTarget < gBattlersCount; gBattlerTarget++)
{
if (gBattlerTarget == gBattlerAttacker && !(gBattleMoves[gCurrentMove].target & MOVE_TARGET_USER))
if (gBattlerTarget == gBattlerAttacker && !(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove) & MOVE_TARGET_USER))
continue;
if (IsBattlerAlive(gBattlerTarget))
break;
@ -11429,7 +11526,8 @@ static bool8 IsTwoTurnsMove(u16 move)
|| gBattleMoves[move].effect == EFFECT_TWO_TURNS_ATTACK
|| gBattleMoves[move].effect == EFFECT_SOLAR_BEAM
|| gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE
|| gBattleMoves[move].effect == EFFECT_BIDE)
|| gBattleMoves[move].effect == EFFECT_BIDE
|| gBattleMoves[move].effect == EFFECT_METEOR_BEAM)
return TRUE;
else
return FALSE;
@ -12123,6 +12221,7 @@ static void Cmd_recoverbasedonsunlight(void)
static void Cmd_setstickyweb(void)
{
u8 targetSide = GetBattlerSide(gBattlerTarget);
if (gSideStatuses[targetSide] & SIDE_STATUS_STICKY_WEB)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
@ -12130,6 +12229,7 @@ static void Cmd_setstickyweb(void)
else
{
gSideStatuses[targetSide] |= SIDE_STATUS_STICKY_WEB;
gSideTimers[targetSide].stickyWebBattlerSide = GetBattlerSide(gBattlerAttacker); // For Court Change/Defiant - set this to the user's side
gSideTimers[targetSide].stickyWebAmount = 1;
gBattleStruct->stickyWebUser = gBattlerAttacker; // For Mirror Armor
gBattlescriptCurrInstr += 5;
@ -12140,7 +12240,7 @@ static void Cmd_selectfirstvalidtarget(void)
{
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
{
if (gBattlerTarget == gBattlerAttacker && !(gBattleMoves[gCurrentMove].target & MOVE_TARGET_USER))
if (gBattlerTarget == gBattlerAttacker && !(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove) & MOVE_TARGET_USER))
continue;
if (IsBattlerAlive(gBattlerTarget))
break;
@ -12441,7 +12541,7 @@ static void Cmd_tryswapitems(void) // trick
u8 sideAttacker = GetBattlerSide(gBattlerAttacker);
u8 sideTarget = GetBattlerSide(gBattlerTarget);
// you can't swap items if they were knocked off in regular battles
// You can't swap items if they were knocked off in regular battles
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_FRONTIER

View File

@ -238,6 +238,7 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
void HandleAction_UseMove(void)
{
u32 i, side, moveType, var = 4;
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
if (gBattleStruct->absentBattlerFlags & gBitTable[gBattlerAttacker] || !IsBattlerAlive(gBattlerAttacker))
@ -310,14 +311,14 @@ void HandleAction_UseMove(void)
// choose target
side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
if (IsAffectedByFollowMe(gBattlerAttacker, side, gCurrentMove)
&& gBattleMoves[gCurrentMove].target == MOVE_TARGET_SELECTED
&& moveTarget == MOVE_TARGET_SELECTED
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gSideTimers[side].followmeTarget))
{
gBattleStruct->moveTarget[gBattlerAttacker] = gBattlerTarget = gSideTimers[side].followmeTarget; // follow me moxie fix
}
else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
&& gSideTimers[side].followmeTimer == 0
&& (gBattleMoves[gCurrentMove].power != 0 || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER)
&& (gBattleMoves[gCurrentMove].power != 0 || moveTarget != MOVE_TARGET_USER)
&& ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
{
@ -338,7 +339,7 @@ void HandleAction_UseMove(void)
}
if (var == 4)
{
if (gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM)
if (moveTarget & MOVE_TARGET_RANDOM)
{
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
{
@ -355,7 +356,7 @@ void HandleAction_UseMove(void)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
}
}
else if (gBattleMoves[gChosenMove].target & MOVE_TARGET_FOES_AND_ALLY)
else if (moveTarget & MOVE_TARGET_FOES_AND_ALLY)
{
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
{
@ -399,7 +400,7 @@ void HandleAction_UseMove(void)
}
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM)
&& moveTarget & MOVE_TARGET_RANDOM)
{
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
{
@ -422,7 +423,7 @@ void HandleAction_UseMove(void)
gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK);
}
}
else if (gBattleMoves[gChosenMove].target == MOVE_TARGET_ALLY)
else if (moveTarget == MOVE_TARGET_ALLY)
{
if (IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))
gBattlerTarget = BATTLE_PARTNER(gBattlerAttacker);
@ -430,7 +431,7 @@ void HandleAction_UseMove(void)
gBattlerTarget = gBattlerAttacker;
}
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE
&& gBattleMoves[gChosenMove].target == MOVE_TARGET_FOES_AND_ALLY)
&& moveTarget == MOVE_TARGET_FOES_AND_ALLY)
{
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
{
@ -1547,6 +1548,7 @@ bool8 WasUnableToUseMove(u8 battler)
void PrepareStringBattle(u16 stringId, u8 battler)
{
u32 targetSide = GetBattlerSide(gBattlerTarget);
u16 battlerAbility = GetBattlerAbility(battler);
u16 targetAbility = GetBattlerAbility(gBattlerTarget);
// Support for Contrary ability.
@ -1567,8 +1569,10 @@ void PrepareStringBattle(u16 stringId, u8 battler)
&& ((targetAbility == ABILITY_DEFIANT && CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
|| (targetAbility == ABILITY_COMPETITIVE && CompareStat(gBattlerTarget, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)))
&& gSpecialStatuses[gBattlerTarget].changedStatsBattlerId != BATTLE_PARTNER(gBattlerTarget)
&& gSpecialStatuses[gBattlerTarget].changedStatsBattlerId != gBattlerTarget)
&& ((gSpecialStatuses[gBattlerTarget].changedStatsBattlerId != gBattlerTarget) || gBattleScripting.stickyWebStatDrop == 1)
&& !(gBattleScripting.stickyWebStatDrop == 1 && gSideTimers[targetSide].stickyWebBattlerSide == targetSide)) // Sticky Web must have been set by the foe
{
gBattleScripting.stickyWebStatDrop = 0;
gBattlerAbility = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_DefiantActivates;
@ -4808,7 +4812,10 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
}
break;
case ABILITYEFFECT_MOVES_BLOCK: // 2
if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND && !(gBattleMoves[move].target & MOVE_TARGET_USER))
{
u16 moveTarget = GetBattlerMoveTargetType(battler, move);
if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND && !(moveTarget & MOVE_TARGET_USER))
|| (gLastUsedAbility == ABILITY_BULLETPROOF && gBattleMoves[move].flags & FLAG_BALLISTIC))
{
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)
@ -4831,14 +4838,14 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
else if (BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE)
&& !(IS_MOVE_STATUS(move) && GetBattlerAbility(gBattlerTarget) == ABILITY_MAGIC_BOUNCE))
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected
gBattleScripting.battler = gBattlerAbility = gBattlerTarget;
gBattlescriptCurrInstr = BattleScript_DarkTypePreventsPrankster;
effect = 1;
}
break;
}
case ABILITYEFFECT_ABSORBING: // 3
if (move != MOVE_NONE)
{
@ -7424,7 +7431,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
if (setTarget != NO_TARGET_OVERRIDE)
moveTarget = setTarget - 1;
else
moveTarget = gBattleMoves[move].target;
moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move);
// Special cases
if (move == MOVE_CURSE && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
@ -7697,7 +7704,7 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
else if (gProtectStructs[battlerId].protected)
return TRUE;
else if (gSideStatuses[GetBattlerSide(battlerId)] & SIDE_STATUS_WIDE_GUARD
&& gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
&& GetBattlerMoveTargetType(gBattlerAttacker, move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
return TRUE;
else if (gProtectStructs[battlerId].banefulBunkered)
return TRUE;
@ -7823,7 +7830,7 @@ u32 CountBattlerStatIncreases(u8 battlerId, bool32 countEvasionAcc)
u32 GetMoveTargetCount(u16 move, u8 battlerAtk, u8 battlerDef)
{
switch (gBattleMoves[move].target)
switch (GetBattlerMoveTargetType(gBattlerAttacker, move))
{
case MOVE_TARGET_BOTH:
return IsBattlerAlive(battlerDef)
@ -8162,9 +8169,17 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
&& IsBattlerGrounded(gBattlerAttacker))
basePower *= 2;
break;
case EFFECT_EXPANDING_FORCE:
if (IsBattlerTerrainAffected(gBattlerAttacker, STATUS_FIELD_PSYCHIC_TERRAIN))
MulModifier(&basePower, UQ_4_12(1.5));
break;
case EFFECT_RISING_VOLTAGE:
if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_ELECTRIC_TERRAIN))
basePower *= 2;
break;
}
// move-specific base power changes
// Move-specific base power changes
switch (move)
{
case MOVE_WATER_SHURIKEN:
@ -10004,7 +10019,7 @@ bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 chec
return FALSE;
if (GetBattlerSide(battlerPrankster) == GetBattlerSide(battlerDef))
return FALSE;
if (checkTarget && (gBattleMoves[move].target & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)))
if (checkTarget && (GetBattlerMoveTargetType(battlerPrankster, move) & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_DEPENDS)))
return FALSE;
if (!IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK))
return FALSE;
@ -10036,3 +10051,16 @@ bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags)
}
return FALSE;
}
// Gets move target before redirection effects etc. are applied
// Possible return values are defined in battle.h following MOVE_TARGET_SELECTED
u32 GetBattlerMoveTargetType(u8 battlerId, u16 move)
{
u32 target;
if (gBattleMoves[move].effect == EFFECT_EXPANDING_FORCE
&& IsBattlerTerrainAffected(battlerId, STATUS_FIELD_PSYCHIC_TERRAIN))
return MOVE_TARGET_BOTH;
else
return gBattleMoves[move].target;
}

View File

@ -5388,7 +5388,7 @@ static void SetBattleTargetSpritePosition(void)
static void SetMoveTargetPosition(u16 move)
{
switch (gBattleMoves[move].target)
switch (GetBattlerMoveTargetType(gBattlerAttacker, move))
{
case MOVE_TARGET_USER_OR_SELECTED:
case MOVE_TARGET_USER:

View File

@ -10142,7 +10142,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_BEAK_BLAST] =
{
.effect = EFFECT_PLACEHOLDER,
.effect = EFFECT_BEAK_BLAST,
.power = 100,
.type = TYPE_FLYING,
.accuracy = 100,
@ -10212,13 +10212,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_SHELL_TRAP] =
{
.effect = EFFECT_PLACEHOLDER,
.effect = EFFECT_PLACEHOLDER, // EFFECT_SHELL_TRAP,
.power = 150,
.type = TYPE_FIRE,
.accuracy = 100,
.pp = 5,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_SELECTED,
.target = MOVE_TARGET_BOTH,
.priority = -3,
.flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
.split = SPLIT_SPECIAL,
@ -10913,7 +10913,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_COURT_CHANGE] =
{
.effect = EFFECT_PLACEHOLDER, //TODO
.effect = EFFECT_COURT_CHANGE,
.power = 0,
.type = TYPE_NORMAL,
.accuracy = 100,
@ -10983,7 +10983,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_SNAP_TRAP] =
{
.effect = EFFECT_TRAP, //TODO: add case/effect
.effect = EFFECT_TRAP,
.power = 35,
.type = TYPE_GRASS,
.accuracy = 100,
@ -11235,7 +11235,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_EXPANDING_FORCE] =
{
.effect = EFFECT_PLACEHOLDER, //TODO
.effect = EFFECT_EXPANDING_FORCE,
.power = 80,
.type = TYPE_PSYCHIC,
.accuracy = 100,
@ -11263,12 +11263,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_SCALE_SHOT] =
{
.effect = EFFECT_PLACEHOLDER, //TODO (EFFECT_MULTI_HIT + ABILITY_WEAK_ARMOR,
.effect = EFFECT_SCALE_SHOT,
.power = 25,
.type = TYPE_DRAGON,
.accuracy = 90,
.pp = 20,
.secondaryEffectChance = 0,
.secondaryEffectChance = 100,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED,
@ -11277,7 +11277,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_METEOR_BEAM] =
{
.effect = EFFECT_PLACEHOLDER, //TODO
.effect = EFFECT_METEOR_BEAM,
.power = 120,
.type = TYPE_ROCK,
.accuracy = 90,
@ -11333,7 +11333,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_RISING_VOLTAGE] =
{
.effect = EFFECT_PLACEHOLDER, //TODO
.effect = EFFECT_RISING_VOLTAGE,
.power = 70,
.type = TYPE_ELECTRIC,
.accuracy = 100,
@ -11417,7 +11417,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_CORROSIVE_GAS] =
{
.effect = EFFECT_PLACEHOLDER, //TODO
.effect = EFFECT_PLACEHOLDER, // EFFECT_CORROSIVE_GAS, TODO
.power = 0,
.type = TYPE_POISON,
.accuracy = 100,