Remove cases from ABE, add functionality of Flower Veil

This commit is contained in:
DizzyEggg 2019-03-31 21:38:58 +02:00
parent d90767c490
commit b12334c88b
13 changed files with 240 additions and 195 deletions

View File

@ -171,12 +171,21 @@
.4byte \ptr .4byte \ptr
.endm .endm
.macro jumpiftype battler:req, type:req, ptr:req .macro jumpbasedontype battler:req, type:req, case:req, ptr:req
.byte 0x22 .byte 0x22
.byte \battler .byte \battler
.byte \type .byte \type
.byte \case
.4byte \ptr .4byte \ptr
.endm .endm
.macro jumpiftype battler:req, type:req, ptr:req
jumpbasedontype \battler, \type, 1, \ptr
.endm
.macro jumpifnottype battler:req, type:req, ptr:req
jumpbasedontype \battler, \type, 0, \ptr
.endm
.macro getexp battler:req .macro getexp battler:req
.byte 0x23 .byte 0x23
@ -1728,3 +1737,10 @@
.macro dmgtocurrattackerhp .macro dmgtocurrattackerhp
manipulatedamage ATK80_CURR_ATTACKER_HP manipulatedamage ATK80_CURR_ATTACKER_HP
.endm .endm
.macro jumpifflowerveil jumpptr:req
jumpifnottype BS_TARGET, TYPE_GRASS, 1f
jumpifability BS_TARGET_SIDE, ABILITY_FLOWER_VEIL, \jumpptr
1:
.endm

View File

@ -1818,6 +1818,7 @@ BattleScript_EffectSleep::
jumpifsubstituteblocks BattleScript_ButItFailed jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_SLEEP, BattleScript_AlreadyAsleep jumpifstatus BS_TARGET, STATUS1_SLEEP, BattleScript_AlreadyAsleep
jumpifcantmakeasleep BattleScript_CantMakeAsleep jumpifcantmakeasleep BattleScript_CantMakeAsleep
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected
@ -1826,6 +1827,18 @@ BattleScript_EffectSleep::
setmoveeffect MOVE_EFFECT_SLEEP setmoveeffect MOVE_EFFECT_SLEEP
seteffectprimary seteffectprimary
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_FlowerVeilProtectsRet::
pause 0x20
call BattleScript_AbilityPopUp
printstring STRINGID_FLOWERVEILPROTECTED
waitmessage 0x40
return
BattleScript_FlowerVeilProtects:
call BattleScript_FlowerVeilProtectsRet
orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_AlreadyAsleep:: BattleScript_AlreadyAsleep::
setalreadystatusedmoveattempt BS_ATTACKER setalreadystatusedmoveattempt BS_ATTACKER
@ -2265,6 +2278,7 @@ BattleScript_EffectToxic::
attackstring attackstring
ppreduce ppreduce
jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifsubstituteblocks BattleScript_ButItFailed jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_POISON, BattleScript_AlreadyPoisoned
jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
@ -2587,6 +2601,7 @@ BattleScript_EffectPoison::
attackstring attackstring
ppreduce ppreduce
jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifsubstituteblocks BattleScript_ButItFailed jumpifsubstituteblocks BattleScript_ButItFailed
jumpifstatus BS_TARGET, STATUS1_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_POISON, BattleScript_AlreadyPoisoned
jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned
@ -2608,6 +2623,7 @@ BattleScript_EffectParalyze:
attackstring attackstring
ppreduce ppreduce
jumpifability BS_TARGET, ABILITY_LIMBER, BattleScript_LimberProtected jumpifability BS_TARGET, ABILITY_LIMBER, BattleScript_LimberProtected
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifsubstituteblocks BattleScript_ButItFailed jumpifsubstituteblocks BattleScript_ButItFailed
typecalc typecalc
jumpifmovehadnoeffect BattleScript_ButItFailed jumpifmovehadnoeffect BattleScript_ButItFailed
@ -3789,6 +3805,7 @@ BattleScript_EffectWillOWisp::
jumpifstatus BS_TARGET, STATUS1_BURN, BattleScript_AlreadyBurned jumpifstatus BS_TARGET, STATUS1_BURN, BattleScript_AlreadyBurned
jumpiftype BS_TARGET, TYPE_FIRE, BattleScript_NotAffected jumpiftype BS_TARGET, TYPE_FIRE, BattleScript_NotAffected
jumpifability BS_TARGET, ABILITY_WATER_VEIL, BattleScript_WaterVeilPrevents jumpifability BS_TARGET, ABILITY_WATER_VEIL, BattleScript_WaterVeilPrevents
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected
@ -4050,6 +4067,7 @@ BattleScript_EffectYawn::
ppreduce ppreduce
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_PrintBankAbilityMadeIneffective jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_PrintBankAbilityMadeIneffective
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_PrintBankAbilityMadeIneffective jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_PrintBankAbilityMadeIneffective
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifsubstituteblocks BattleScript_ButItFailed jumpifsubstituteblocks BattleScript_ButItFailed
jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, BattleScript_SafeguardProtected
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
@ -4061,7 +4079,7 @@ BattleScript_EffectYawn::
waitmessage 0x40 waitmessage 0x40
goto BattleScript_MoveEnd goto BattleScript_MoveEnd
BattleScript_PrintBankAbilityMadeIneffective:: BattleScript_PrintBankAbilityMadeIneffective::
copybyte sBATTLER, sBATTLER_WITH_ABILITY copybyte sBATTLER, gBattlerAbility
BattleScript_PrintAbilityMadeIneffective:: BattleScript_PrintAbilityMadeIneffective::
pause 0x20 pause 0x20
printstring STRINGID_PKMNSXMADEITINEFFECTIVE printstring STRINGID_PKMNSXMADEITINEFFECTIVE

View File

@ -620,7 +620,7 @@ struct BattleScripting
u8 animArg2; u8 animArg2;
u16 tripleKickPower; u16 tripleKickPower;
u8 atk49_state; u8 atk49_state;
u8 battlerWithAbility; u8 unused_15;
u8 unused_16; u8 unused_16;
u8 battler; u8 battler;
u8 animTurn; u8 animTurn;

View File

@ -14,6 +14,7 @@ void HandleBattleWindow(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags);
bool8 UproarWakeUpCheck(u8 battlerId); bool8 UproarWakeUpCheck(u8 battlerId);
bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move); bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move);
bool32 CanUseLastResort(u8 battlerId); bool32 CanUseLastResort(u8 battlerId);
u32 IsFlowerVeilProtected(u32 battler);
extern void (* const gBattleScriptingCommandsTable[])(void); extern void (* const gBattleScriptingCommandsTable[])(void);
extern const u8 gUnknown_0831C494[][4]; extern const u8 gUnknown_0831C494[][4];

View File

@ -300,5 +300,6 @@ extern const u8 BattleScript_PowderMoveNoEffect[];
extern const u8 BattleScript_GrassyTerrainLoop[]; extern const u8 BattleScript_GrassyTerrainLoop[];
extern const u8 BattleScript_VCreateStatLoss[]; extern const u8 BattleScript_VCreateStatLoss[];
extern const u8 BattleScript_SpikyShieldEffect[]; extern const u8 BattleScript_SpikyShieldEffect[];
extern const u8 BattleScript_FlowerVeilProtectsRet[];
#endif // GUARD_BATTLE_SCRIPTS_H #endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -6,7 +6,7 @@
#define MOVE_LIMITATION_DISABLED (1 << 2) #define MOVE_LIMITATION_DISABLED (1 << 2)
#define MOVE_LIMITATION_TORMENTED (1 << 3) #define MOVE_LIMITATION_TORMENTED (1 << 3)
#define MOVE_LIMITATION_TAUNT (1 << 4) #define MOVE_LIMITATION_TAUNT (1 << 4)
#define MOVE_LIMITATION_IMPRISON (1 << 5) #define MOVE_LIMITATION_IMPRISON (1 << 5)
#define ABILITYEFFECT_ON_SWITCHIN 0x0 #define ABILITYEFFECT_ON_SWITCHIN 0x0
#define ABILITYEFFECT_ENDTURN 0x1 #define ABILITYEFFECT_ENDTURN 0x1
@ -20,23 +20,13 @@
#define ABILITYEFFECT_INTIMIDATE1 0x9 #define ABILITYEFFECT_INTIMIDATE1 0x9
#define ABILITYEFFECT_INTIMIDATE2 0xA #define ABILITYEFFECT_INTIMIDATE2 0xA
#define ABILITYEFFECT_TRACE 0xB #define ABILITYEFFECT_TRACE 0xB
#define ABILITYEFFECT_CHECK_OTHER_SIDE 0xC
#define ABILITYEFFECT_CHECK_BATTLER_SIDE 0xD
#define ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER 0xF
#define ABILITYEFFECT_COUNT_OTHER_SIDE 0x10
#define ABILITYEFFECT_COUNT_BATTLER_SIDE 0x11
#define ABILITYEFFECT_COUNT_ON_FIELD 0x12
#define ABILITYEFFECT_CHECK_ON_FIELD 0x13
#define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF #define ABILITYEFFECT_SWITCH_IN_WEATHER 0xFF
#define ABILITY_ON_OPPOSING_FIELD(battlerId, abilityId)(AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, battlerId, abilityId, 0, 0))
#define ABILITY_ON_FIELD(abilityId)(AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, abilityId, 0, 0))
#define ITEMEFFECT_ON_SWITCH_IN 0x0 #define ITEMEFFECT_ON_SWITCH_IN 0x0
#define ITEMEFFECT_MOVE_END 0x3 #define ITEMEFFECT_MOVE_END 0x3
#define ITEMEFFECT_KINGSROCK_SHELLBELL 0x4 #define ITEMEFFECT_KINGSROCK_SHELLBELL 0x4
#define WEATHER_HAS_EFFECT ((!ABILITY_ON_FIELD(ABILITY_CLOUD_NINE) && !ABILITY_ON_FIELD(ABILITY_AIR_LOCK))) #define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK)))
#define IS_WHOLE_SIDE_ALIVE(battler)((IsBattlerAlive(battler) && IsBattlerAlive(BATTLE_PARTNER(battler)))) #define IS_WHOLE_SIDE_ALIVE(battler)((IsBattlerAlive(battler) && IsBattlerAlive(BATTLE_PARTNER(battler))))
@ -72,6 +62,11 @@ bool8 HasNoMonsToSwitch(u8 battlerId, u8 r1, u8 r2);
u8 CastformDataTypeChange(u8 battlerId); u8 CastformDataTypeChange(u8 battlerId);
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility); bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility);
u8 AbilityBattleEffects(u8 caseID, u8 battlerId, u8 ability, u8 special, u16 moveArg); u8 AbilityBattleEffects(u8 caseID, u8 battlerId, u8 ability, u8 special, u16 moveArg);
u32 GetBattlerAbility(u8 battlerId);
u32 IsAbilityOnSide(u32 battlerId, u32 ability);
u32 IsAbilityOnOpposingSide(u32 battlerId, u32 ability);
u32 IsAbilityOnField(u32 ability);
u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability);
void BattleScriptExecute(const u8* BS_ptr); void BattleScriptExecute(const u8* BS_ptr);
void BattleScriptPushCursorAndCallback(const u8* BS_ptr); void BattleScriptPushCursorAndCallback(const u8* BS_ptr);
u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn); u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn);
@ -79,7 +74,6 @@ void ClearFuryCutterDestinyBondGrudge(u8 battlerId);
void HandleAction_RunBattleScript(void); void HandleAction_RunBattleScript(void);
u8 GetMoveTarget(u16 move, u8 setTarget); u8 GetMoveTarget(u16 move, u8 setTarget);
u8 IsMonDisobedient(void); u8 IsMonDisobedient(void);
u32 GetBattlerAbility(u8 battlerId);
u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating); u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating);
u32 GetBattlerHoldEffectParam(u8 battlerId); u32 GetBattlerHoldEffectParam(u8 battlerId);
bool32 IsMoveMakingContact(u16 move, u8 battlerAtk); bool32 IsMoveMakingContact(u16 move, u8 battlerAtk);

View File

@ -11,7 +11,7 @@
#define sB_ANIM_ARG2 gBattleScripting + 0x11 #define sB_ANIM_ARG2 gBattleScripting + 0x11
#define sTRIPLE_KICK_POWER gBattleScripting + 0x12 #define sTRIPLE_KICK_POWER gBattleScripting + 0x12
#define sMOVEEND_STATE gBattleScripting + 0x14 #define sMOVEEND_STATE gBattleScripting + 0x14
#define sBATTLER_WITH_ABILITY gBattleScripting + 0x15 #define sUNUSED_15 gBattleScripting + 0x15
#define sUNUSED_16 gBattleScripting + 0x16 #define sUNUSED_16 gBattleScripting + 0x16
#define sBATTLER gBattleScripting + 0x17 #define sBATTLER gBattleScripting + 0x17
#define sB_ANIM_TURN gBattleScripting + 0x18 #define sB_ANIM_TURN gBattleScripting + 0x18
@ -45,7 +45,7 @@
#define BS_BATTLER_0 7 #define BS_BATTLER_0 7
#define BS_ATTACKER_WITH_PARTNER 4 // for atk98_status_icon_update #define BS_ATTACKER_WITH_PARTNER 4 // for atk98_status_icon_update
#define BS_ATTACKER_SIDE 8 // for atk1E_jumpifability #define BS_ATTACKER_SIDE 8 // for atk1E_jumpifability
#define BS_NOT_ATTACKER_SIDE 9 // for atk1E_jumpifability #define BS_TARGET_SIDE 9 // for atk1E_jumpifability
#define BS_SCRIPTING 10 #define BS_SCRIPTING 10
#define BS_PLAYER1 11 #define BS_PLAYER1 11
#define BS_OPPONENT1 12 #define BS_OPPONENT1 12
@ -139,6 +139,7 @@
#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 76 #define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 76
#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 77 #define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 77
#define VARIOUS_JUMP_IF_ROAR_FAILS 78 #define VARIOUS_JUMP_IF_ROAR_FAILS 78
#define VARIOUS_JUMP_IF_FLOWER_VEIL 79
// atk80, dmg manipulation // atk80, dmg manipulation
#define ATK80_DMG_CHANGE_SIGN 0 #define ATK80_DMG_CHANGE_SIGN 0

View File

@ -524,6 +524,7 @@
#define STRINGID_ELECTRICTERRAINPREVENTS 520 #define STRINGID_ELECTRICTERRAINPREVENTS 520
#define STRINGID_PSYCHICTERRAINPREVENTS 521 #define STRINGID_PSYCHICTERRAINPREVENTS 521
#define STRINGID_SAFETYGOOGLESPROTECTED 522 #define STRINGID_SAFETYGOOGLESPROTECTED 522
#define STRINGID_FLOWERVEILPROTECTED 523
#define BATTLESTRINGS_COUNT 529 #define BATTLESTRINGS_COUNT 529

View File

@ -414,11 +414,11 @@ static bool8 ShouldSwitch(void)
return FALSE; return FALSE;
if (gStatuses3[gActiveBattler] & STATUS3_ROOTED) if (gStatuses3[gActiveBattler] & STATUS3_ROOTED)
return FALSE; return FALSE;
if (ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_SHADOW_TAG)) if (IsAbilityOnOpposingSide(gActiveBattler, ABILITY_SHADOW_TAG))
return FALSE; return FALSE;
if (ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_ARENA_TRAP)) // Misses the flying type and Levitate check. if (IsAbilityOnOpposingSide(gActiveBattler, ABILITY_ARENA_TRAP)) // Misses the flying type and Levitate check.
return FALSE; return FALSE;
if (ABILITY_ON_FIELD(ABILITY_MAGNET_PULL)) if (IsAbilityOnField(ABILITY_MAGNET_PULL))
{ {
if (gBattleMons[gActiveBattler].type1 == TYPE_STEEL) if (gBattleMons[gActiveBattler].type1 == TYPE_STEEL)
return FALSE; return FALSE;

View File

@ -3711,7 +3711,7 @@ u8 IsRunningFromBattleImpossible(void)
return 2; return 2;
} }
} }
i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0); i = IsAbilityOnFieldExcept(gActiveBattler, ABILITY_MAGNET_PULL);
if (i != 0 && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)) if (i != 0 && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL))
{ {
gBattleScripting.battler = i - 1; gBattleScripting.battler = i - 1;
@ -3902,11 +3902,11 @@ static void HandleTurnActionSelectionState(void)
{ {
BtlController_EmitChoosePokemon(0, PARTY_CANT_SWITCH, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]); BtlController_EmitChoosePokemon(0, PARTY_CANT_SWITCH, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBattler]);
} }
else if ((i = ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_SHADOW_TAG)) else if ((i = IsAbilityOnOpposingSide(gActiveBattler, ABILITY_SHADOW_TAG))
|| ((i = ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_ARENA_TRAP)) || ((i = IsAbilityOnOpposingSide(gActiveBattler, ABILITY_ARENA_TRAP))
&& !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING) && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING)
&& gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE) && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE)
|| ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0)) || ((i = IsAbilityOnFieldExcept(gActiveBattler, ABILITY_MAGNET_PULL))
&& IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL))) && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)))
{ {
BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ABILITY_PREVENTS, 6, gLastUsedAbility, gBattleStruct->field_60[gActiveBattler]); BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ABILITY_PREVENTS, 6, gLastUsedAbility, gBattleStruct->field_60[gActiveBattler]);

View File

@ -649,9 +649,11 @@ static const u8 sText_GrassyTerrainHeals[] = _("{B_ATK_NAME_WITH_PREFIX} is heal
static const u8 sText_ElectricTerrainPreventsSleep[] = _("{B_DEF_NAME_WITH_PREFIX} surrounds itself\nwith electrified terrain!"); static const u8 sText_ElectricTerrainPreventsSleep[] = _("{B_DEF_NAME_WITH_PREFIX} surrounds itself\nwith electrified terrain!");
static const u8 sText_PsychicTerrainPreventsPriority[] = _("{B_DEF_NAME_WITH_PREFIX} surrounds itself\nwith psychic terrain!"); static const u8 sText_PsychicTerrainPreventsPriority[] = _("{B_DEF_NAME_WITH_PREFIX} surrounds itself\nwith psychic terrain!");
static const u8 sText_SafetyGooglesProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is not affected\nthanks to its {B_LAST_ITEM}!"); static const u8 sText_SafetyGooglesProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is not affected\nthanks to its {B_LAST_ITEM}!");
static const u8 sText_FlowerVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} surrounded itself\nwith a veil of petals!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{ {
[STRINGID_FLOWERVEILPROTECTED - 12] = sText_FlowerVeilProtected,
[STRINGID_SAFETYGOOGLESPROTECTED - 12] = sText_SafetyGooglesProtected, [STRINGID_SAFETYGOOGLESPROTECTED - 12] = sText_SafetyGooglesProtected,
[STRINGID_SPECTRALTHIEFSTEAL - 12] = sText_SpectralThiefSteal, [STRINGID_SPECTRALTHIEFSTEAL - 12] = sText_SpectralThiefSteal,
[STRINGID_BELCHCANTSELECT - 12] = sText_BelchCantUse, [STRINGID_BELCHCANTSELECT - 12] = sText_BelchCantUse,

View File

@ -109,7 +109,7 @@ static void atk1E_jumpifability(void);
static void atk1F_jumpifsideaffecting(void); static void atk1F_jumpifsideaffecting(void);
static void atk20_jumpifstat(void); static void atk20_jumpifstat(void);
static void atk21_jumpifstatus3condition(void); static void atk21_jumpifstatus3condition(void);
static void atk22_jumpiftype(void); static void atk22_jumpbasedontype(void);
static void atk23_getexp(void); static void atk23_getexp(void);
static void atk24(void); static void atk24(void);
static void atk25_movevaluescleanup(void); static void atk25_movevaluescleanup(void);
@ -368,7 +368,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atk1F_jumpifsideaffecting, atk1F_jumpifsideaffecting,
atk20_jumpifstat, atk20_jumpifstat,
atk21_jumpifstatus3condition, atk21_jumpifstatus3condition,
atk22_jumpiftype, atk22_jumpbasedontype,
atk23_getexp, atk23_getexp,
atk24, atk24,
atk25_movevaluescleanup, atk25_movevaluescleanup,
@ -1285,7 +1285,7 @@ static void atk02_attackstring(void)
static void atk03_ppreduce(void) static void atk03_ppreduce(void)
{ {
s32 ppToDeduct = 1; s32 i, ppToDeduct = 1;
if (gBattleControllerExecFlags) if (gBattleControllerExecFlags)
return; return;
@ -1295,14 +1295,22 @@ static void atk03_ppreduce(void)
switch (gBattleMoves[gCurrentMove].target) switch (gBattleMoves[gCurrentMove].target)
{ {
case MOVE_TARGET_FOES_AND_ALLY: case MOVE_TARGET_FOES_AND_ALLY:
ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBattlerAttacker, ABILITY_PRESSURE, 0, 0); for (i = 0; i < gBattlersCount; i++)
{
if (i != gBattlerAttacker && IsBattlerAlive(i))
ppToDeduct += (GetBattlerAbility(i) == ABILITY_PRESSURE);
}
break; break;
case MOVE_TARGET_BOTH: case MOVE_TARGET_BOTH:
case MOVE_TARGET_OPPONENTS_FIELD: case MOVE_TARGET_OPPONENTS_FIELD:
ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBattlerAttacker, ABILITY_PRESSURE, 0, 0); for (i = 0; i < gBattlersCount; i++)
{
if (GetBattlerSide(i) != GetBattlerSide(gBattlerAttacker) && IsBattlerAlive(i))
ppToDeduct += (GetBattlerAbility(i) == ABILITY_PRESSURE);
}
break; break;
default: default:
if (gBattlerAttacker != gBattlerTarget && gBattleMons[gBattlerTarget].ability == ABILITY_PRESSURE) if (gBattlerAttacker != gBattlerTarget && GetBattlerAbility(gBattlerTarget) == ABILITY_PRESSURE)
ppToDeduct++; ppToDeduct++;
break; break;
} }
@ -2004,7 +2012,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleScripting.battler = gBattlerAttacker; gBattleScripting.battler = gBattlerAttacker;
} }
if (gBattleMons[gEffectBattler].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) if (GetBattlerAbility(gEffectBattler) == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
&& !primary && gBattleScripting.moveEffect <= 9) && !primary && gBattleScripting.moveEffect <= 9)
INCREMENT_RESET_RETURN INCREMENT_RESET_RETURN
@ -2026,7 +2034,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
{ {
case STATUS1_SLEEP: case STATUS1_SLEEP:
// check active uproar // check active uproar
if (gBattleMons[gEffectBattler].ability != ABILITY_SOUNDPROOF) if (GetBattlerAbility(gEffectBattler) != ABILITY_SOUNDPROOF)
{ {
for (gActiveBattler = 0; for (gActiveBattler = 0;
gActiveBattler < gBattlersCount && !(gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR); gActiveBattler < gBattlersCount && !(gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR);
@ -2040,16 +2048,16 @@ void SetMoveEffect(bool32 primary, u32 certain)
break; break;
if (gActiveBattler != gBattlersCount) if (gActiveBattler != gBattlersCount)
break; break;
if (gBattleMons[gEffectBattler].ability == ABILITY_VITAL_SPIRIT) if (GetBattlerAbility(gEffectBattler) == ABILITY_VITAL_SPIRIT
break; || GetBattlerAbility(gEffectBattler) == ABILITY_INSOMNIA
if (gBattleMons[gEffectBattler].ability == ABILITY_INSOMNIA) || IsFlowerVeilProtected(gEffectBattler))
break; break;
CancelMultiTurnMoves(gEffectBattler); CancelMultiTurnMoves(gEffectBattler);
statusChanged = TRUE; statusChanged = TRUE;
break; break;
case STATUS1_POISON: case STATUS1_POISON:
if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{ {
gLastUsedAbility = ABILITY_IMMUNITY; gLastUsedAbility = ABILITY_IMMUNITY;
@ -2085,13 +2093,13 @@ void SetMoveEffect(bool32 primary, u32 certain)
break; break;
if (gBattleMons[gEffectBattler].status1) if (gBattleMons[gEffectBattler].status1)
break; break;
if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY) if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY || IsFlowerVeilProtected(gEffectBattler))
break; break;
statusChanged = TRUE; statusChanged = TRUE;
break; break;
case STATUS1_BURN: case STATUS1_BURN:
if (gBattleMons[gEffectBattler].ability == ABILITY_WATER_VEIL if (GetBattlerAbility(gEffectBattler) == ABILITY_WATER_VEIL
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{ {
gLastUsedAbility = ABILITY_WATER_VEIL; gLastUsedAbility = ABILITY_WATER_VEIL;
@ -2122,7 +2130,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
} }
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE)) if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE))
break; break;
if (gBattleMons[gEffectBattler].ability == ABILITY_WATER_VEIL) if (GetBattlerAbility(gEffectBattler) == ABILITY_WATER_VEIL || IsFlowerVeilProtected(gEffectBattler))
break; break;
if (gBattleMons[gEffectBattler].status1) if (gBattleMons[gEffectBattler].status1)
break; break;
@ -2138,14 +2146,14 @@ void SetMoveEffect(bool32 primary, u32 certain)
break; break;
if (noSunCanFreeze == 0) if (noSunCanFreeze == 0)
break; break;
if (gBattleMons[gEffectBattler].ability == ABILITY_MAGMA_ARMOR) if (GetBattlerAbility(gEffectBattler) == ABILITY_MAGMA_ARMOR || IsFlowerVeilProtected(gEffectBattler))
break; break;
CancelMultiTurnMoves(gEffectBattler); CancelMultiTurnMoves(gEffectBattler);
statusChanged = TRUE; statusChanged = TRUE;
break; break;
case STATUS1_PARALYSIS: case STATUS1_PARALYSIS:
if (gBattleMons[gEffectBattler].ability == ABILITY_LIMBER) if (GetBattlerAbility(gEffectBattler) == ABILITY_LIMBER)
{ {
if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)
{ {
@ -2181,7 +2189,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
} }
if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ELECTRIC)) if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ELECTRIC))
break; break;
if (gBattleMons[gEffectBattler].ability == ABILITY_LIMBER) if (GetBattlerAbility(gEffectBattler) == ABILITY_LIMBER || IsFlowerVeilProtected(gEffectBattler))
break; break;
if (gBattleMons[gEffectBattler].status1) if (gBattleMons[gEffectBattler].status1)
break; break;
@ -2189,7 +2197,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
statusChanged = TRUE; statusChanged = TRUE;
break; break;
case STATUS1_TOXIC_POISON: case STATUS1_TOXIC_POISON:
if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{ {
gLastUsedAbility = ABILITY_IMMUNITY; gLastUsedAbility = ABILITY_IMMUNITY;
RecordAbilityBattle(gEffectBattler, ABILITY_IMMUNITY); RecordAbilityBattle(gEffectBattler, ABILITY_IMMUNITY);
@ -2222,7 +2230,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
break; break;
if (!IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON) && !IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL)) if (!IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON) && !IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
{ {
if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY) if (GetBattlerAbility(gEffectBattler) == ABILITY_IMMUNITY || IsFlowerVeilProtected(gEffectBattler))
break; break;
// It's redundant, because at this point we know the status1 value is 0. // It's redundant, because at this point we know the status1 value is 0.
@ -2269,8 +2277,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
|| gBattleScripting.moveEffect == MOVE_EFFECT_PARALYSIS || gBattleScripting.moveEffect == MOVE_EFFECT_PARALYSIS
|| gBattleScripting.moveEffect == MOVE_EFFECT_BURN) || gBattleScripting.moveEffect == MOVE_EFFECT_BURN)
{ {
u8* synchronizeEffect = &gBattleStruct->synchronizeMoveEffect; gBattleStruct->synchronizeMoveEffect = gBattleScripting.moveEffect;
*synchronizeEffect = gBattleScripting.moveEffect;
gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT; gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT;
} }
return; return;
@ -2295,7 +2302,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
switch (gBattleScripting.moveEffect) switch (gBattleScripting.moveEffect)
{ {
case MOVE_EFFECT_CONFUSION: case MOVE_EFFECT_CONFUSION:
if (gBattleMons[gEffectBattler].ability == ABILITY_OWN_TEMPO if (GetBattlerAbility(gEffectBattler) == ABILITY_OWN_TEMPO
|| gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION) || gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION)
{ {
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
@ -2648,7 +2655,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
} }
break; break;
case MOVE_EFFECT_KNOCK_OFF: case MOVE_EFFECT_KNOCK_OFF:
if (gBattleMons[gEffectBattler].ability == ABILITY_STICKY_HOLD) if (GetBattlerAbility(gEffectBattler) == ABILITY_STICKY_HOLD)
{ {
if (gBattleMons[gEffectBattler].item == 0) if (gBattleMons[gEffectBattler].item == 0)
{ {
@ -2991,48 +2998,45 @@ static void atk1D_jumpifstatus2(void)
static void atk1E_jumpifability(void) static void atk1E_jumpifability(void)
{ {
u8 battlerId; u32 battlerId;
u8 ability = gBattlescriptCurrInstr[2]; bool32 hasAbility = FALSE;
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3); u32 ability = gBattlescriptCurrInstr[2];
if (gBattlescriptCurrInstr[1] == BS_ATTACKER_SIDE) switch (gBattlescriptCurrInstr[1])
{ {
battlerId = AbilityBattleEffects(ABILITYEFFECT_CHECK_BATTLER_SIDE, gBattlerAttacker, ability, 0, 0); default:
battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
if (GetBattlerAbility(battlerId) == ability)
hasAbility = TRUE;
break;
case BS_ATTACKER_SIDE:
battlerId = IsAbilityOnSide(gBattlerAttacker, ability);
if (battlerId) if (battlerId)
{ {
gLastUsedAbility = ability; battlerId--;
gBattlescriptCurrInstr = jumpPtr; hasAbility = TRUE;
RecordAbilityBattle(battlerId - 1, gLastUsedAbility);
gBattleScripting.battlerWithAbility = battlerId - 1;
} }
else break;
gBattlescriptCurrInstr += 7; case BS_TARGET_SIDE:
battlerId = IsAbilityOnOpposingSide(gBattlerAttacker, ability);
if (battlerId)
{
battlerId--;
hasAbility = TRUE;
}
break;
} }
else if (gBattlescriptCurrInstr[1] == BS_NOT_ATTACKER_SIDE)
if (hasAbility)
{ {
battlerId = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBattlerAttacker, ability, 0, 0); gLastUsedAbility = ability;
if (battlerId) gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
{ RecordAbilityBattle(battlerId, gLastUsedAbility);
gLastUsedAbility = ability; gBattlerAbility = battlerId;
gBattlescriptCurrInstr = jumpPtr;
RecordAbilityBattle(battlerId - 1, gLastUsedAbility);
gBattleScripting.battlerWithAbility = battlerId - 1;
}
else
gBattlescriptCurrInstr += 7;
} }
else else
{ {
battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); gBattlescriptCurrInstr += 7;
if (gBattleMons[battlerId].ability == ability)
{
gLastUsedAbility = ability;
gBattlescriptCurrInstr = jumpPtr;
RecordAbilityBattle(battlerId, gLastUsedAbility);
gBattleScripting.battlerWithAbility = battlerId;
}
else
gBattlescriptCurrInstr += 7;
} }
} }
@ -3138,16 +3142,28 @@ static void atk21_jumpifstatus3condition(void)
} }
} }
static void atk22_jumpiftype(void) static void atk22_jumpbasedontype(void)
{ {
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
u8 type = gBattlescriptCurrInstr[2]; u8 type = gBattlescriptCurrInstr[2];
const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3); const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 4);
if (IS_BATTLER_OF_TYPE(battlerId, type)) // jumpiftype
gBattlescriptCurrInstr = jumpPtr; if (gBattlescriptCurrInstr[3])
{
if (IS_BATTLER_OF_TYPE(battlerId, type))
gBattlescriptCurrInstr = jumpPtr;
else
gBattlescriptCurrInstr += 8;
}
// jumpifnottype
else else
gBattlescriptCurrInstr += 7; {
if (!IS_BATTLER_OF_TYPE(battlerId, type))
gBattlescriptCurrInstr = jumpPtr;
else
gBattlescriptCurrInstr += 8;
}
} }
static void atk23_getexp(void) static void atk23_getexp(void)
@ -3918,7 +3934,7 @@ static void atk42_setroost(void)
static void atk43_jumpifabilitypresent(void) static void atk43_jumpifabilitypresent(void)
{ {
if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, gBattlescriptCurrInstr[1], 0, 0)) if (IsAbilityOnField(gBattlescriptCurrInstr[1]))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else else
gBattlescriptCurrInstr += 6; gBattlescriptCurrInstr += 6;
@ -6360,6 +6376,14 @@ static bool32 ClearDefogHazards(u8 battlerAtk, bool32 clear)
return FALSE; return FALSE;
} }
u32 IsFlowerVeilProtected(u32 battler)
{
if (IS_BATTLER_OF_TYPE(battler, TYPE_GRASS))
return IsAbilityOnSide(battler, ABILITY_FLOWER_VEIL);
else
return 0;
}
static void atk76_various(void) static void atk76_various(void)
{ {
struct Pokemon *mon; struct Pokemon *mon;
@ -7689,15 +7713,15 @@ bool8 UproarWakeUpCheck(u8 battlerId)
static void atk84_jumpifcantmakeasleep(void) static void atk84_jumpifcantmakeasleep(void)
{ {
const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1); const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
u32 ability = GetBattlerAbility(gBattlerTarget);
if (UproarWakeUpCheck(gBattlerTarget)) if (UproarWakeUpCheck(gBattlerTarget))
{ {
gBattlescriptCurrInstr = jumpPtr; gBattlescriptCurrInstr = jumpPtr;
} }
else if (gBattleMons[gBattlerTarget].ability == ABILITY_INSOMNIA else if (ability == ABILITY_INSOMNIA || ability == ABILITY_VITAL_SPIRIT)
|| gBattleMons[gBattlerTarget].ability == ABILITY_VITAL_SPIRIT)
{ {
gLastUsedAbility = gBattleMons[gBattlerTarget].ability; gLastUsedAbility = ability;
gBattleCommunication[MULTISTRING_CHOOSER] = 2; gBattleCommunication[MULTISTRING_CHOOSER] = 2;
gBattlescriptCurrInstr = jumpPtr; gBattlescriptCurrInstr = jumpPtr;
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility); RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
@ -7851,8 +7875,8 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattlescriptCurrInstr = BattleScript_ButItFailed; gBattlescriptCurrInstr = BattleScript_ButItFailed;
return STAT_CHANGE_DIDNT_WORK; return STAT_CHANGE_DIDNT_WORK;
} }
else if ((gBattleMons[gActiveBattler].ability == ABILITY_CLEAR_BODY else if ((GetBattlerAbility(gActiveBattler) == ABILITY_CLEAR_BODY
|| gBattleMons[gActiveBattler].ability == ABILITY_WHITE_SMOKE) || GetBattlerAbility(gActiveBattler) == ABILITY_WHITE_SMOKE)
&& !certain && gCurrentMove != MOVE_CURSE) && !certain && gCurrentMove != MOVE_CURSE)
{ {
if (flags == STAT_CHANGE_BS_PTR) if (flags == STAT_CHANGE_BS_PTR)
@ -7867,14 +7891,34 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattleScripting.battler = gActiveBattler; gBattleScripting.battler = gActiveBattler;
gBattlerAbility = gActiveBattler; gBattlerAbility = gActiveBattler;
gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss; gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss;
gLastUsedAbility = gBattleMons[gActiveBattler].ability; gLastUsedAbility = GetBattlerAbility(gActiveBattler);
RecordAbilityBattle(gActiveBattler, gLastUsedAbility); RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
gSpecialStatuses[gActiveBattler].statLowered = 1; gSpecialStatuses[gActiveBattler].statLowered = 1;
} }
} }
return STAT_CHANGE_DIDNT_WORK; return STAT_CHANGE_DIDNT_WORK;
} }
else if (gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE else if ((index = IsFlowerVeilProtected(gActiveBattler)) && !certain)
{
if (flags == STAT_CHANGE_BS_PTR)
{
if (gSpecialStatuses[gActiveBattler].statLowered)
{
gBattlescriptCurrInstr = BS_ptr;
}
else
{
BattleScriptPush(BS_ptr);
gBattleScripting.battler = gActiveBattler;
gBattlerAbility = index - 1;
gBattlescriptCurrInstr = BattleScript_FlowerVeilProtectsRet;
gLastUsedAbility = ABILITY_FLOWER_VEIL;
gSpecialStatuses[gActiveBattler].statLowered = 1;
}
}
return STAT_CHANGE_DIDNT_WORK;
}
else if (GetBattlerAbility(gActiveBattler) == ABILITY_KEEN_EYE
&& !certain && statId == STAT_ACC) && !certain && statId == STAT_ACC)
{ {
if (flags == STAT_CHANGE_BS_PTR) if (flags == STAT_CHANGE_BS_PTR)
@ -7883,12 +7927,12 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattleScripting.battler = gActiveBattler; gBattleScripting.battler = gActiveBattler;
gBattlerAbility = gActiveBattler; gBattlerAbility = gActiveBattler;
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss;
gLastUsedAbility = gBattleMons[gActiveBattler].ability; gLastUsedAbility = GetBattlerAbility(gActiveBattler);
RecordAbilityBattle(gActiveBattler, gLastUsedAbility); RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
} }
return STAT_CHANGE_DIDNT_WORK; return STAT_CHANGE_DIDNT_WORK;
} }
else if (gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER else if (GetBattlerAbility(gActiveBattler) == ABILITY_HYPER_CUTTER
&& !certain && statId == STAT_ATK) && !certain && statId == STAT_ATK)
{ {
if (flags == STAT_CHANGE_BS_PTR) if (flags == STAT_CHANGE_BS_PTR)
@ -7897,12 +7941,12 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattleScripting.battler = gActiveBattler; gBattleScripting.battler = gActiveBattler;
gBattlerAbility = gActiveBattler; gBattlerAbility = gActiveBattler;
gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss;
gLastUsedAbility = gBattleMons[gActiveBattler].ability; gLastUsedAbility = GetBattlerAbility(gActiveBattler);
RecordAbilityBattle(gActiveBattler, gLastUsedAbility); RecordAbilityBattle(gActiveBattler, gLastUsedAbility);
} }
return STAT_CHANGE_DIDNT_WORK; return STAT_CHANGE_DIDNT_WORK;
} }
else if (gBattleMons[gActiveBattler].ability == ABILITY_SHIELD_DUST && flags == 0) else if (GetBattlerAbility(gActiveBattler) == ABILITY_SHIELD_DUST && flags == 0)
{ {
return STAT_CHANGE_DIDNT_WORK; return STAT_CHANGE_DIDNT_WORK;
} }

View File

@ -3560,83 +3560,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
} }
} }
break; break;
case ABILITYEFFECT_CHECK_OTHER_SIDE: // 12
side = GetBattlerSide(battler);
for (i = 0; i < gBattlersCount; i++)
{
if (GetBattlerSide(i) != side && gBattleMons[i].ability == ability)
{
gLastUsedAbility = ability;
effect = i + 1;
}
}
break;
case ABILITYEFFECT_CHECK_BATTLER_SIDE: // 13
side = GetBattlerSide(battler);
for (i = 0; i < gBattlersCount; i++)
{
if (GetBattlerSide(i) == side && gBattleMons[i].ability == ability)
{
gLastUsedAbility = ability;
effect = i + 1;
}
}
break;
case ABILITYEFFECT_CHECK_ON_FIELD: // 19
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].ability == ability && gBattleMons[i].hp != 0)
{
gLastUsedAbility = ability;
effect = i + 1;
}
}
break;
case ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER: // 15
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].ability == ability && i != battler)
{
gLastUsedAbility = ability;
effect = i + 1;
}
}
break;
case ABILITYEFFECT_COUNT_OTHER_SIDE: // 16
side = GetBattlerSide(battler);
for (i = 0; i < gBattlersCount; i++)
{
if (GetBattlerSide(i) != side && gBattleMons[i].ability == ability)
{
gLastUsedAbility = ability;
effect++;
}
}
break;
case ABILITYEFFECT_COUNT_BATTLER_SIDE: // 17
side = GetBattlerSide(battler);
for (i = 0; i < gBattlersCount; i++)
{
if (GetBattlerSide(i) == side && gBattleMons[i].ability == ability)
{
gLastUsedAbility = ability;
effect++;
}
}
break;
case ABILITYEFFECT_COUNT_ON_FIELD: // 18
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].ability == ability && i != battler)
{
gLastUsedAbility = ability;
effect++;
}
}
break;
} }
if (effect && caseID < ABILITYEFFECT_CHECK_OTHER_SIDE && gLastUsedAbility != 0xFF) if (effect && gLastUsedAbility != 0xFF)
RecordAbilityBattle(battler, gLastUsedAbility); RecordAbilityBattle(battler, gLastUsedAbility);
if (effect && caseID <= ABILITYEFFECT_MOVE_END) if (effect && caseID <= ABILITYEFFECT_MOVE_END)
gBattlerAbility = battler; gBattlerAbility = battler;
@ -3644,6 +3570,64 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
return effect; return effect;
} }
u32 GetBattlerAbility(u8 battlerId)
{
if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID)
return ABILITY_NONE;
else if ((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE)
&& sAbilitiesAffectedByMoldBreaker[gBattleMons[battlerId].ability]
&& gBattlerByTurnOrder[gCurrentTurnActionNumber] == gBattlerAttacker
&& gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE
&& gCurrentTurnActionNumber < gBattlersCount
&& !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID))
return ABILITY_NONE;
else
return gBattleMons[battlerId].ability;
}
u32 IsAbilityOnSide(u32 battlerId, u32 ability)
{
if (IsBattlerAlive(battlerId) && GetBattlerAbility(battlerId) == ability)
return battlerId + 1;
else if (IsBattlerAlive(BATTLE_PARTNER(battlerId)) && GetBattlerAbility(BATTLE_PARTNER(battlerId)) == ability)
return BATTLE_PARTNER(battlerId) + 1;
else
return 0;
}
u32 IsAbilityOnOpposingSide(u32 battlerId, u32 ability)
{
return IsAbilityOnSide(BATTLE_OPPOSITE(battlerId), ability);
}
u32 IsAbilityOnField(u32 ability)
{
u32 i;
for (i = 0; i < gBattlersCount; i++)
{
if (IsBattlerAlive(i) && GetBattlerAbility(i) == ability)
return i + 1;
}
return 0;
}
u32 IsAbilityOnFieldExcept(u32 battlerId, u32 ability)
{
u32 i;
for (i = 0; i < gBattlersCount; i++)
{
if (i != battlerId && IsBattlerAlive(i) && GetBattlerAbility(i) == ability)
return i + 1;
}
return 0;
}
void BattleScriptExecute(const u8 *BS_ptr) void BattleScriptExecute(const u8 *BS_ptr)
{ {
gBattlescriptCurrInstr = BS_ptr; gBattlescriptCurrInstr = BS_ptr;
@ -4372,7 +4356,7 @@ u8 GetMoveTarget(u16 move, u8 setTarget)
targetBattler = Random() % gBattlersCount; targetBattler = Random() % gBattlersCount;
} while (targetBattler == gBattlerAttacker || side == GetBattlerSide(targetBattler) || gAbsentBattlerFlags & gBitTable[targetBattler]); } while (targetBattler == gBattlerAttacker || side == GetBattlerSide(targetBattler) || gAbsentBattlerFlags & gBitTable[targetBattler]);
if (gBattleMoves[move].type == TYPE_ELECTRIC if (gBattleMoves[move].type == TYPE_ELECTRIC
&& AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBattlerAttacker, ABILITY_LIGHTNING_ROD, 0, 0) && IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD)
&& gBattleMons[targetBattler].ability != ABILITY_LIGHTNING_ROD) && gBattleMons[targetBattler].ability != ABILITY_LIGHTNING_ROD)
{ {
targetBattler ^= BIT_FLANK; targetBattler ^= BIT_FLANK;
@ -4380,7 +4364,7 @@ u8 GetMoveTarget(u16 move, u8 setTarget)
gSpecialStatuses[targetBattler].lightningRodRedirected = 1; gSpecialStatuses[targetBattler].lightningRodRedirected = 1;
} }
else if (gBattleMoves[move].type == TYPE_WATER else if (gBattleMoves[move].type == TYPE_WATER
&& AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIDE, gBattlerAttacker, ABILITY_STORM_DRAIN, 0, 0) && IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_STORM_DRAIN)
&& gBattleMons[targetBattler].ability != ABILITY_STORM_DRAIN) && gBattleMons[targetBattler].ability != ABILITY_STORM_DRAIN)
{ {
targetBattler ^= BIT_FLANK; targetBattler ^= BIT_FLANK;
@ -4564,23 +4548,6 @@ u8 IsMonDisobedient(void)
} }
} }
u32 GetBattlerAbility(u8 battlerId)
{
if (gStatuses3[battlerId] & STATUS3_GASTRO_ACID)
return ABILITY_NONE;
else if ((gBattleMons[gBattlerAttacker].ability == ABILITY_MOLD_BREAKER
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TERAVOLT
|| gBattleMons[gBattlerAttacker].ability == ABILITY_TURBOBLAZE)
&& sAbilitiesAffectedByMoldBreaker[gBattleMons[battlerId].ability]
&& gBattlerByTurnOrder[gCurrentTurnActionNumber] == gBattlerAttacker
&& gActionsByTurnOrder[gBattlerByTurnOrder[gBattlerAttacker]] == B_ACTION_USE_MOVE
&& gCurrentTurnActionNumber < gBattlersCount
&& !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID))
return ABILITY_NONE;
else
return gBattleMons[battlerId].ability;
}
u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating) u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating)
{ {
if (checkNegating) if (checkNegating)
@ -5052,10 +5019,10 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
} }
// field abilities // field abilities
if ((ABILITY_ON_FIELD(ABILITY_DARK_AURA) && moveType == TYPE_DARK) if ((IsAbilityOnField(ABILITY_DARK_AURA) && moveType == TYPE_DARK)
|| (ABILITY_ON_FIELD(ABILITY_FAIRY_AURA) && moveType == TYPE_FAIRY)) || (IsAbilityOnField(ABILITY_FAIRY_AURA) && moveType == TYPE_FAIRY))
{ {
if (ABILITY_ON_FIELD(ABILITY_AURA_BREAK)) if (IsAbilityOnField(ABILITY_AURA_BREAK))
MulModifier(&modifier, UQ_4_12(0.75)); MulModifier(&modifier, UQ_4_12(0.75));
else else
MulModifier(&modifier, UQ_4_12(1.25)); MulModifier(&modifier, UQ_4_12(1.25));