Merge pull request #1338 from ghoulslash/ripen

Add Ripen and Finish Gen4 Berries
This commit is contained in:
Eduardo Quezada D'Ottone 2021-03-13 11:16:42 -03:00 committed by GitHub
commit 292993e360
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 446 additions and 50 deletions

View File

@ -7555,6 +7555,11 @@ BattleScript_WhiteHerbRet::
return
BattleScript_ItemHealHP_RemoveItemRet::
jumpifability BS_SCRIPTING, ABILITY_RIPEN, BattleScript_ItemHealHP_RemoveItemRet_AbilityPopUp
goto BattleScript_ItemHealHP_RemoveItemRet_Anim
BattleScript_ItemHealHP_RemoveItemRet_AbilityPopUp:
call BattleScript_AbilityPopUp
BattleScript_ItemHealHP_RemoveItemRet_Anim:
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_PKMNSITEMRESTOREDHEALTH
waitmessage 0x40
@ -7563,7 +7568,13 @@ BattleScript_ItemHealHP_RemoveItemRet::
datahpupdate BS_SCRIPTING
removeitem BS_SCRIPTING
return
BattleScript_ItemHealHP_RemoveItemEnd2::
jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_ItemHealHP_RemoveItemEnd2_AbilityPopUp
goto BattleScript_ItemHealHP_RemoveItemEnd2_Anim
BattleScript_ItemHealHP_RemoveItemEnd2_AbilityPopUp:
call BattleScript_AbilityPopUp
BattleScript_ItemHealHP_RemoveItemEnd2_Anim:
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_PKMNSITEMRESTOREDHEALTH
waitmessage 0x40
@ -7574,6 +7585,11 @@ BattleScript_ItemHealHP_RemoveItemEnd2::
end2
BattleScript_BerryPPHealEnd2::
jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_BerryPPHealEnd2_AbilityPopup
goto BattleScript_BerryPPHealEnd2_Anim
BattleScript_BerryPPHealEnd2_AbilityPopup:
call BattleScript_AbilityPopUp
BattleScript_BerryPPHealEnd2_Anim:
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_PKMNSITEMRESTOREDPP
waitmessage 0x40
@ -7637,6 +7653,11 @@ BattleScript_HangedOnMsgRet:
return
BattleScript_BerryConfuseHealEnd2::
jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_BerryConfuseHealEnd2_AbilityPopup
goto BattleScript_BerryConfuseHealEnd2_Anim
BattleScript_BerryConfuseHealEnd2_AbilityPopup:
call BattleScript_AbilityPopUp
BattleScript_BerryConfuseHealEnd2_Anim:
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_PKMNSITEMRESTOREDHEALTH
waitmessage 0x40
@ -7650,7 +7671,31 @@ BattleScript_BerryConfuseHealEnd2::
removeitem BS_ATTACKER
end2
BattleScript_BerryConfuseHealRet::
jumpifability BS_SCRIPTING, ABILITY_RIPEN, BattleScript_BerryConfuseHealRet_AbilityPopup
goto BattleScript_BerryConfuseHealRet_Anim
BattleScript_BerryConfuseHealRet_AbilityPopup:
call BattleScript_AbilityPopUp
BattleScript_BerryConfuseHealRet_Anim:
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_PKMNSITEMRESTOREDHEALTH
waitmessage 0x40
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
healthbarupdate BS_SCRIPTING
datahpupdate BS_SCRIPTING
printstring STRINGID_FORXCOMMAYZ
waitmessage 0x40
setmoveeffect MOVE_EFFECT_CONFUSION | MOVE_EFFECT_AFFECTS_USER
seteffectprimary
removeitem BS_SCRIPTING
return
BattleScript_BerryStatRaiseEnd2::
jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_BerryStatRaiseEnd2_AbilityPopup
goto BattleScript_BerryStatRaiseEnd2_Anim
BattleScript_BerryStatRaiseEnd2_AbilityPopup:
call BattleScript_AbilityPopUp
BattleScript_BerryStatRaiseEnd2_Anim:
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_BUFF_ALLOW_PTR, BattleScript_82DB85B
BattleScript_82DB85B::
@ -7659,6 +7704,20 @@ BattleScript_82DB85B::
removeitem BS_ATTACKER
end2
BattleScript_BerryStatRaiseRet::
jumpifability BS_SCRIPTING, ABILITY_RIPEN, BattleScript_BerryStatRaiseRet_AbilityPopup
goto BattleScript_BerryStatRaiseRet_Anim
BattleScript_BerryStatRaiseRet_AbilityPopup:
call BattleScript_AbilityPopUp
BattleScript_BerryStatRaiseRet_Anim:
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
statbuffchange STAT_BUFF_ALLOW_PTR, BattleScript_BerryStatRaiseRet_End
BattleScript_BerryStatRaiseRet_End:
setbyte cMULTISTRING_CHOOSER, 0x4
call BattleScript_StatUp
removeitem BS_SCRIPTING
return
BattleScript_BerryFocusEnergyEnd2::
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_PKMNUSEDXTOGETPUMPED
@ -7827,3 +7886,61 @@ BattleScript_AnnounceAirLockCloudNine::
waitmessage 0x40
call BattleScript_WeatherFormChanges
end3
BattleScript_QuickClawActivation::
printstring STRINGID_EMPTYSTRING3
waitmessage 0x1
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
waitanimation
printstring STRINGID_CANACTFASTERTHANKSTO
waitmessage 0x40
end2
BattleScript_CustapBerryActivation::
printstring STRINGID_EMPTYSTRING3
waitmessage 0x1
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
waitanimation
printstring STRINGID_CANACTFASTERTHANKSTO
waitmessage 0x40
removeitem BS_ATTACKER
end2
BattleScript_MicleBerryActivateEnd2::
jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_MicleBerryActivateEnd2_Ripen
goto BattleScript_MicleBerryActivateEnd2_Anim
BattleScript_MicleBerryActivateEnd2_Ripen:
call BattleScript_AbilityPopUp
BattleScript_MicleBerryActivateEnd2_Anim:
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_MICLEBERRYACTIVATES
waitmessage 0x40
removeitem BS_ATTACKER
end2
BattleScript_MicleBerryActivateRet::
jumpifability BS_SCRIPTING, ABILITY_RIPEN, BattleScript_MicleBerryActivateRet_Ripen
goto BattleScript_MicleBerryActivateRet_Anim
BattleScript_MicleBerryActivateRet_Ripen:
call BattleScript_AbilityPopUp
BattleScript_MicleBerryActivateRet_Anim:
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_MICLEBERRYACTIVATES
waitmessage 0x40
removeitem BS_SCRIPTING
return
BattleScript_JabocaRowapBerryActivates::
jumpifability BS_TARGET, ABILITY_RIPEN, BattleScript_JabocaRowapBerryActivate_Ripen
goto BattleScript_JabocaRowapBerryActivate_Anim
BattleScript_JabocaRowapBerryActivate_Ripen:
call BattleScript_AbilityPopUp
BattleScript_JabocaRowapBerryActivate_Anim:
jumpifabsent BS_TARGET, BattleScript_JabocaRowapBerryActivate_Dmg @ dont play the animation for a fainted target
playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT, NULL
waitanimation
BattleScript_JabocaRowapBerryActivate_Dmg:
call BattleScript_HurtAttacker
removeitem BS_TARGET
return

View File

@ -140,6 +140,8 @@ struct ProtectStruct
u32 usedGravityPreventedMove:1;
u32 powderSelfDmg:1;
u32 usedThroatChopPreventedMove:1;
u32 micle:1;
u32 custap:1; // also quick claw
u32 physicalDmg;
u32 specialDmg;
u8 physicalBattlerId;
@ -543,6 +545,7 @@ struct BattleStruct
u8 sameMoveTurns[MAX_BATTLERS_COUNT]; // For Metronome, number of times the same moves has been SUCCESFULLY used.
u16 moveEffect2; // For Knock Off
u16 changedSpecies[PARTY_SIZE]; // For Zygarde or future forms when multiple mons can change into the same pokemon.
u8 quickClawBattlerId;
};
#define GET_MOVE_TYPE(move, typeArg) \

View File

@ -209,7 +209,9 @@ extern const u8 BattleScript_ItemHealHP_Ret[];
extern const u8 BattleScript_SelectingNotAllowedMoveChoiceItem[];
extern const u8 BattleScript_HangedOnMsg[];
extern const u8 BattleScript_BerryConfuseHealEnd2[];
extern const u8 BattleScript_BerryConfuseHealRet[];
extern const u8 BattleScript_BerryStatRaiseEnd2[];
extern const u8 BattleScript_BerryStatRaiseRet[];
extern const u8 BattleScript_BerryFocusEnergyEnd2[];
extern const u8 BattleScript_ActionSelectionItemsCantBeUsed[];
extern const u8 BattleScript_ArenaTurnBeginning[];
@ -360,5 +362,10 @@ extern const u8 BattleScript_SandSpitActivates[];
extern const u8 BattleScript_PerishBodyActivates[];
extern const u8 BattleScript_ActivateAsOne[];
extern const u8 BattleScript_RaiseStatOnFaintingTarget[];
extern const u8 BattleScript_QuickClawActivation[];
extern const u8 BattleScript_CustapBerryActivation[];
extern const u8 BattleScript_MicleBerryActivateEnd2[];
extern const u8 BattleScript_MicleBerryActivateRet[];
extern const u8 BattleScript_JabocaRowapBerryActivates[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -131,5 +131,6 @@ void ClearIllusionMon(u32 battlerId);
bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId);
bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId);
u8 GetBattleMoveSplit(u32 moveId);
bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -566,8 +566,10 @@
#define STRINGID_AURAFLAREDTOLIFE 562
#define STRINGID_ASONEENTERS 563
#define STRINGID_CURIOUSMEDICINEENTERS 564
#define STRINGID_CANACTFASTERTHANKSTO 565
#define STRINGID_MICLEBERRYACTIVATES 566
#define BATTLESTRINGS_COUNT 565
#define BATTLESTRINGS_COUNT 567
//// multichoice message IDs
// switch in ability message

View File

@ -104,6 +104,12 @@
#define HOLD_EFFECT_RESIST_BERRY 98
#define HOLD_EFFECT_POWER_ITEM 99
#define HOLD_EFFECT_RESTORE_PCT_HP 100
#define HOLD_EFFECT_MICLE_BERRY 101
#define HOLD_EFFECT_CUSTAP_BERRY 102
#define HOLD_EFFECT_JABOCA_BERRY 103
#define HOLD_EFFECT_ROWAP_BERRY 104
#define HOLD_EFFECT_KEE_BERRY 105
#define HOLD_EFFECT_MARANGA_BERRY 106
// Gen5 hold effects
#define HOLD_EFFECT_FLOAT_STONE 115

View File

@ -107,6 +107,7 @@ static void sub_803CDF8(void);
static bool8 AllAtActionConfirmed(void);
static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void);
static void CheckMegaEvolutionBeforeTurn(void);
static void CheckQuickClaw_CustapBerryActivation(void);
static void FreeResetData_ReturnToOvOrDoEvolutions(void);
static void ReturnFromBattleToOverworld(void);
static void TryEvolvePokemon(void);
@ -4350,20 +4351,23 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
u8 strikesFirst = 0;
u32 speedBattler1 = 0, speedBattler2 = 0;
u32 holdEffectBattler1 = 0, holdEffectBattler2 = 0;
bool32 quickClawBattler1 = FALSE, quickClawBattler2 = FALSE;
s8 priority1 = 0, priority2 = 0;
speedBattler1 = GetBattlerTotalSpeedStat(battler1);
holdEffectBattler1 = GetBattlerHoldEffect(battler1, TRUE);
if (holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW
&& gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler1)) / 100)
quickClawBattler1 = TRUE;
if ((holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler1)) / 100)
|| (!IsAbilityOnOpposingSide(battler1, ABILITY_UNNERVE)
&& holdEffectBattler1 == HOLD_EFFECT_CUSTAP_BERRY
&& HasEnoughHpToEatBerry(battler1, 4, gBattleMons[battler1].item)))
gProtectStructs[battler1].custap = TRUE;
speedBattler2 = GetBattlerTotalSpeedStat(battler2);
holdEffectBattler2 = GetBattlerHoldEffect(battler2, TRUE);
if (holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW
&& gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler2)) / 100)
quickClawBattler2 = TRUE;
if ((holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler2)) / 100)
|| (!IsAbilityOnOpposingSide(battler2, ABILITY_UNNERVE)
&& holdEffectBattler2 == HOLD_EFFECT_CUSTAP_BERRY
&& HasEnoughHpToEatBerry(battler2, 4, gBattleMons[battler2].item)))
gProtectStructs[battler2].custap = TRUE;
if (!ignoreChosenMoves)
{
@ -4375,13 +4379,13 @@ u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves)
if (priority1 == priority2)
{
// QUICK CLAW - always first
// QUICK CLAW / CUSTAP - always first
// LAGGING TAIL - always last
// STALL - always last
if (quickClawBattler1 && !quickClawBattler2)
if (gProtectStructs[battler1].custap && !gProtectStructs[battler2].custap)
strikesFirst = 0;
else if (quickClawBattler2 && !quickClawBattler1)
else if (gProtectStructs[battler2].custap && !gProtectStructs[battler1].custap)
strikesFirst = 1;
else if (holdEffectBattler1 == HOLD_EFFECT_LAGGING_TAIL && holdEffectBattler2 != HOLD_EFFECT_LAGGING_TAIL)
strikesFirst = 1;
@ -4618,6 +4622,45 @@ static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void)
}
}
gBattleMainFunc = CheckQuickClaw_CustapBerryActivation;
gBattleStruct->quickClawBattlerId = 0;
}
static void CheckQuickClaw_CustapBerryActivation(void)
{
u32 i;
if (!(gHitMarker & HITMARKER_RUN))
{
while (gBattleStruct->quickClawBattlerId < gBattlersCount)
{
gActiveBattler = gBattlerAttacker = gBattleStruct->quickClawBattlerId;
gBattleStruct->quickClawBattlerId++;
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_MOVE
&& gChosenMoveByBattler[gActiveBattler] != MOVE_FOCUS_PUNCH // quick claw message doesn't need to activate here
&& gProtectStructs[gActiveBattler].custap
&& !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)
&& !(gDisableStructs[gBattlerAttacker].truantCounter)
&& !(gProtectStructs[gActiveBattler].noValidMoves))
{
gProtectStructs[gActiveBattler].custap = FALSE;
gLastUsedItem = gBattleMons[gActiveBattler].item;
if (GetBattlerHoldEffect(gActiveBattler, FALSE) == HOLD_EFFECT_CUSTAP_BERRY)
{
// don't record berry since its gone now
BattleScriptExecute(BattleScript_CustapBerryActivation);
}
else
{
RecordItemEffectBattle(gActiveBattler, GetBattlerHoldEffect(gActiveBattler, FALSE));
BattleScriptExecute(BattleScript_QuickClawActivation);
}
return;
}
}
}
// setup stuff before turns/actions
TryClearRageAndFuryCutter();
gCurrentTurnActionNumber = 0;
gCurrentActionFuncId = gActionsByTurnOrder[0];

View File

@ -693,9 +693,13 @@ static const u8 sText_PkmnsWillPerishIn3Turns[] = _("Both Pokémon will perish\n
static const u8 sText_AbilityRaisedStatDrastically[] = _("{B_DEF_ABILITY} raised {B_DEF_NAME_WITH_PREFIX}'s\n{B_BUFF1} drastically!");
static const u8 sText_AsOneEnters[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} has two Abilities!");
static const u8 sText_CuriousMedicineEnters[] = _("{B_EFF_NAME_WITH_PREFIX}'s\nstat changes were reset!");
static const u8 sText_CanActFaster[] = _("{B_ATK_NAME_WITH_PREFIX} can act faster,\nthanks to {B_LAST_ITEM}!");
static const u8 sText_MicleBerryActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted the accuracy of its\nnext move using {B_LAST_ITEM}!");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_MICLEBERRYACTIVATES - 12] = sText_MicleBerryActivates,
[STRINGID_CANACTFASTERTHANKSTO - 12] = sText_CanActFaster,
[STRINGID_CURIOUSMEDICINEENTERS - 12] = sText_CuriousMedicineEnters,
[STRINGID_ASONEENTERS - 12] = sText_AsOneEnters,
[STRINGID_ABILITYRAISEDSTATDRASTICALLY - 12] = sText_AbilityRaisedStatDrastically,

View File

@ -1564,6 +1564,15 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move)
else if (atkHoldEffect == HOLD_EFFECT_ZOOM_LENS && GetBattlerTurnOrderNum(battlerAtk) > GetBattlerTurnOrderNum(battlerDef));
calc = (calc * (100 + atkParam)) / 100;
if (gProtectStructs[battlerAtk].micle)
{
gProtectStructs[battlerAtk].micle = FALSE;
if (atkAbility == ABILITY_RIPEN)
calc = (calc * 140) / 100; // ripen gives 40% acc boost
else
calc = (calc * 120) / 100; // 20% acc boost
}
return calc;
}

View File

@ -5175,7 +5175,7 @@ enum
};
// second argument is 1/X of current hp compared to max hp
static bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId)
bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId)
{
bool32 isBerry = (ItemId_GetPocket(itemId) == POCKET_BERRIES);
@ -5197,7 +5197,7 @@ static bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId)
return FALSE;
}
static u8 HealConfuseBerry(u32 battlerId, u32 itemId, u8 flavorId)
static u8 HealConfuseBerry(u32 battlerId, u32 itemId, u8 flavorId, bool32 end2)
{
if (HasEnoughHpToEatBerry(battlerId, 2, itemId))
{
@ -5207,17 +5207,35 @@ static u8 HealConfuseBerry(u32 battlerId, u32 itemId, u8 flavorId)
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
gBattleMoveDamage *= -1;
if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, flavorId) < 0)
BattleScriptExecute(BattleScript_BerryConfuseHealEnd2);
if (GetBattlerAbility(battlerId) == ABILITY_RIPEN)
{
gBattleMoveDamage *= 2;
gBattlerAbility = battlerId;
}
if (end2)
{
if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, flavorId) < 0)
BattleScriptExecute(BattleScript_BerryConfuseHealEnd2);
else
BattleScriptExecute(BattleScript_ItemHealHP_RemoveItemEnd2);
}
else
BattleScriptExecute(BattleScript_ItemHealHP_RemoveItemEnd2);
{
BattleScriptPushCursor();
if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, flavorId) < 0)
gBattlescriptCurrInstr = BattleScript_BerryConfuseHealRet;
else
gBattlescriptCurrInstr = BattleScript_ItemHealHP_RemoveItemRet;
}
return ITEM_HP_CHANGE;
}
return 0;
}
static u8 StatRaiseBerry(u32 battlerId, u32 itemId, u32 statId)
static u8 StatRaiseBerry(u32 battlerId, u32 itemId, u32 statId, bool32 end2)
{
if (gBattleMons[battlerId].statStages[statId] < 0xC && HasEnoughHpToEatBerry(battlerId, GetBattlerHoldEffectParam(battlerId), itemId))
{
@ -5225,16 +5243,29 @@ static u8 StatRaiseBerry(u32 battlerId, u32 itemId, u32 statId)
PREPARE_STRING_BUFFER(gBattleTextBuff2, STRINGID_STATROSE);
gEffectBattler = battlerId;
SET_STATCHANGER(statId, 1, FALSE);
if (GetBattlerAbility(battlerId) == ABILITY_RIPEN)
SET_STATCHANGER(statId, 2, FALSE);
else
SET_STATCHANGER(statId, 1, FALSE);
gBattleScripting.animArg1 = 0xE + statId;
gBattleScripting.animArg2 = 0;
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
if (end2)
{
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
}
else
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryStatRaiseRet;
}
return ITEM_STATS_CHANGE;
}
return 0;
}
static u8 RandomStatRaiseBerry(u32 battlerId, u32 itemId)
static u8 RandomStatRaiseBerry(u32 battlerId, u32 itemId, bool32 end2)
{
s32 i;
@ -5262,10 +5293,71 @@ static u8 RandomStatRaiseBerry(u32 battlerId, u32 itemId)
gBattleTextBuff2[7] = EOS;
gEffectBattler = battlerId;
SET_STATCHANGER(i + 1, 2, FALSE);
if (GetBattlerAbility(battlerId) == ABILITY_RIPEN)
SET_STATCHANGER(i + 1, 4, FALSE);
else
SET_STATCHANGER(i + 1, 2, FALSE);
gBattleScripting.animArg1 = 0x21 + i + 6;
gBattleScripting.animArg2 = 0;
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
if (end2)
{
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
}
else
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryStatRaiseRet;
}
return ITEM_STATS_CHANGE;
}
return 0;
}
static u8 TrySetMicleBerry(u32 battlerId, u32 itemId, bool32 end2)
{
if (HasEnoughHpToEatBerry(battlerId, 4, itemId))
{
gProtectStructs[battlerId].micle = TRUE; // battler's next attack has increased accuracy
if (end2)
{
BattleScriptExecute(BattleScript_MicleBerryActivateEnd2);
}
else
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MicleBerryActivateRet;
}
return ITEM_EFFECT_OTHER;
}
return 0;
}
static u8 DamagedStatBoostBerryEffect(u8 battlerId, u8 statId, u8 split)
{
if (IsBattlerAlive(battlerId)
&& TARGET_TURN_DAMAGED
&& gBattleMons[battlerId].statStages[statId] < MAX_STAT_STAGE
&& !DoesSubstituteBlockMove(gBattlerAttacker, battlerId, gCurrentMove)
&& GetBattleMoveSplit(gCurrentMove) == split)
{
PREPARE_STAT_BUFFER(gBattleTextBuff1, statId);
PREPARE_STRING_BUFFER(gBattleTextBuff2, STRINGID_STATROSE);
gEffectBattler = battlerId;
if (GetBattlerAbility(battlerId) == ABILITY_RIPEN)
SET_STATCHANGER(statId, 2, FALSE);
else
SET_STATCHANGER(statId, 1, FALSE);
gBattleScripting.animArg1 = 0xE + statId;
gBattleScripting.animArg2 = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryStatRaiseRet;
return ITEM_STATS_CHANGE;
}
return 0;
@ -5280,6 +5372,11 @@ static u8 ItemHealHp(u32 battlerId, u32 itemId, bool32 end2, bool32 percentHeal)
else
gBattleMoveDamage = GetBattlerHoldEffectParam(battlerId) * -1;
// check ripen
if (ItemId_GetPocket(itemId) == POCKET_BERRIES && GetBattlerAbility(battlerId) == ABILITY_RIPEN)
gBattleMoveDamage *= 2;
gBattlerAbility = battlerId; // in SWSH, berry juice shows ability pop up but has no effect. This is mimicked here
if (end2)
{
BattleScriptExecute(BattleScript_ItemHealHP_RemoveItemEnd2);
@ -5347,43 +5444,43 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
break;
case HOLD_EFFECT_CONFUSE_SPICY:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SPICY);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SPICY, TRUE);
break;
case HOLD_EFFECT_CONFUSE_DRY:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_DRY);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_DRY, TRUE);
break;
case HOLD_EFFECT_CONFUSE_SWEET:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SWEET);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SWEET, TRUE);
break;
case HOLD_EFFECT_CONFUSE_BITTER:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_BITTER);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_BITTER, TRUE);
break;
case HOLD_EFFECT_CONFUSE_SOUR:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SOUR);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SOUR, TRUE);
break;
case HOLD_EFFECT_ATTACK_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_ATK);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_ATK, TRUE);
break;
case HOLD_EFFECT_DEFENSE_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_DEF);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_DEF, TRUE);
break;
case HOLD_EFFECT_SPEED_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPEED);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPEED, TRUE);
break;
case HOLD_EFFECT_SP_ATTACK_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPATK);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPATK, TRUE);
break;
case HOLD_EFFECT_SP_DEFENSE_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPDEF);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPDEF, TRUE);
break;
case HOLD_EFFECT_CRITICAL_UP:
if (B_BERRIES_INSTANT >= GEN_4 && !(gBattleMons[battlerId].status2 & STATUS2_FOCUS_ENERGY) && HasEnoughHpToEatBerry(battlerId, GetBattlerHoldEffectParam(battlerId), gLastUsedItem))
@ -5395,7 +5492,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
break;
case HOLD_EFFECT_RANDOM_STAT_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = RandomStatRaiseBerry(battlerId, gLastUsedItem);
effect = RandomStatRaiseBerry(battlerId, gLastUsedItem, TRUE);
break;
case HOLD_EFFECT_CURE_PAR:
if (B_BERRIES_INSTANT >= GEN_4 && gBattleMons[battlerId].status1 & STATUS1_PARALYSIS && !UnnerveOn(battlerId, gLastUsedItem))
@ -5527,7 +5624,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
effect = ItemHealHp(battlerId, gLastUsedItem, TRUE, FALSE);
break;
case HOLD_EFFECT_RESTORE_PCT_HP:
if (B_BERRIES_INSTANT >= GEN_4)
if (!moveTurn)
effect = ItemHealHp(battlerId, gLastUsedItem, TRUE, TRUE);
break;
case HOLD_EFFECT_RESTORE_PP:
@ -5552,10 +5649,17 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
if (i != MAX_MON_MOVES)
{
u8 maxPP = CalculatePPWithBonus(move, ppBonuses, i);
if (changedPP + GetBattlerHoldEffectParam(battlerId) > maxPP)
u8 ppRestored = GetBattlerHoldEffectParam(battlerId);
if (GetBattlerAbility(battlerId) == ABILITY_RIPEN)
{
ppRestored *= 2;
gBattlerAbility = battlerId;
}
if (changedPP + ppRestored > maxPP)
changedPP = maxPP;
else
changedPP = changedPP + GetBattlerHoldEffectParam(battlerId);
changedPP = changedPP + ppRestored;
PREPARE_MOVE_BUFFER(gBattleTextBuff1, move);
@ -5613,43 +5717,43 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
break;
case HOLD_EFFECT_CONFUSE_SPICY:
if (!moveTurn)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SPICY);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SPICY, TRUE);
break;
case HOLD_EFFECT_CONFUSE_DRY:
if (!moveTurn)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_DRY);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_DRY, TRUE);
break;
case HOLD_EFFECT_CONFUSE_SWEET:
if (!moveTurn)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SWEET);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SWEET, TRUE);
break;
case HOLD_EFFECT_CONFUSE_BITTER:
if (!moveTurn)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_BITTER);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_BITTER, TRUE);
break;
case HOLD_EFFECT_CONFUSE_SOUR:
if (!moveTurn)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SOUR);
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SOUR, TRUE);
break;
case HOLD_EFFECT_ATTACK_UP:
if (!moveTurn)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_ATK);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_ATK, TRUE);
break;
case HOLD_EFFECT_DEFENSE_UP:
if (!moveTurn)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_DEF);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_DEF, TRUE);
break;
case HOLD_EFFECT_SPEED_UP:
if (!moveTurn)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPEED);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPEED, TRUE);
break;
case HOLD_EFFECT_SP_ATTACK_UP:
if (!moveTurn)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPATK);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPATK, TRUE);
break;
case HOLD_EFFECT_SP_DEFENSE_UP:
if (!moveTurn)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPDEF);
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPDEF, TRUE);
break;
case HOLD_EFFECT_CRITICAL_UP:
if (!moveTurn && !(gBattleMons[battlerId].status2 & STATUS2_FOCUS_ENERGY) && HasEnoughHpToEatBerry(battlerId, GetBattlerHoldEffectParam(battlerId), gLastUsedItem))
@ -5661,7 +5765,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
break;
case HOLD_EFFECT_RANDOM_STAT_UP:
if (!moveTurn)
effect = RandomStatRaiseBerry(battlerId, gLastUsedItem);
effect = RandomStatRaiseBerry(battlerId, gLastUsedItem, TRUE);
break;
case HOLD_EFFECT_CURE_PAR:
if (gBattleMons[battlerId].status1 & STATUS1_PARALYSIS && !UnnerveOn(battlerId, gLastUsedItem))
@ -5767,6 +5871,10 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
effect = ITEM_EFFECT_OTHER;
}
break;
case HOLD_EFFECT_MICLE_BERRY:
if (!moveTurn)
effect = TrySetMicleBerry(battlerId, gLastUsedItem, TRUE);
break;
}
if (effect)
@ -5793,6 +5901,10 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
battlerHoldEffect = GetBattlerHoldEffect(battlerId, TRUE);
switch (battlerHoldEffect)
{
case HOLD_EFFECT_MICLE_BERRY:
if (B_HP_BERRIES >= GEN_4)
effect = TrySetMicleBerry(battlerId, gLastUsedItem, FALSE);
break;
case HOLD_EFFECT_RESTORE_HP:
if (B_HP_BERRIES >= GEN_4)
effect = ItemHealHp(battlerId, gLastUsedItem, FALSE, FALSE);
@ -5801,6 +5913,50 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
if (B_BERRIES_INSTANT >= GEN_4)
effect = ItemHealHp(battlerId, gLastUsedItem, FALSE, TRUE);
break;
case HOLD_EFFECT_CONFUSE_SPICY:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SPICY, FALSE);
break;
case HOLD_EFFECT_CONFUSE_DRY:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_DRY, FALSE);
break;
case HOLD_EFFECT_CONFUSE_SWEET:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SWEET, FALSE);
break;
case HOLD_EFFECT_CONFUSE_BITTER:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_BITTER, FALSE);
break;
case HOLD_EFFECT_CONFUSE_SOUR:
if (B_BERRIES_INSTANT >= GEN_4)
effect = HealConfuseBerry(battlerId, gLastUsedItem, FLAVOR_SOUR, FALSE);
break;
case HOLD_EFFECT_ATTACK_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_ATK, FALSE);
break;
case HOLD_EFFECT_DEFENSE_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_DEF, FALSE);
break;
case HOLD_EFFECT_SPEED_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPEED, FALSE);
break;
case HOLD_EFFECT_SP_ATTACK_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPATK, FALSE);
break;
case HOLD_EFFECT_SP_DEFENSE_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = StatRaiseBerry(battlerId, gLastUsedItem, STAT_SPDEF, FALSE);
break;
case HOLD_EFFECT_RANDOM_STAT_UP:
if (B_BERRIES_INSTANT >= GEN_4)
effect = RandomStatRaiseBerry(battlerId, gLastUsedItem, FALSE);
break;
case HOLD_EFFECT_CURE_PAR:
if (gBattleMons[battlerId].status1 & STATUS1_PARALYSIS && !UnnerveOn(battlerId, gLastUsedItem))
{
@ -6060,6 +6216,52 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
gBattleScripting.statChanger = SET_STATCHANGER(STAT_SPATK, 1, FALSE);
}
break;
case HOLD_EFFECT_JABOCA_BERRY: // consume and damage attacker if used physical move
if (IsBattlerAlive(battlerId)
&& TARGET_TURN_DAMAGED
&& !DoesSubstituteBlockMove(gBattlerAttacker, battlerId, gCurrentMove)
&& IS_MOVE_PHYSICAL(gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 8;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
if (GetBattlerAbility(battlerId) == ABILITY_RIPEN)
gBattleMoveDamage *= 2;
effect = ITEM_HP_CHANGE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_JabocaRowapBerryActivates;
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem);
RecordItemEffectBattle(battlerId, HOLD_EFFECT_ROCKY_HELMET);
}
break;
case HOLD_EFFECT_ROWAP_BERRY: // consume and damage attacker if used special move
if (IsBattlerAlive(battlerId)
&& TARGET_TURN_DAMAGED
&& !DoesSubstituteBlockMove(gBattlerAttacker, battlerId, gCurrentMove)
&& IS_MOVE_SPECIAL(gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 8;
if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1;
if (GetBattlerAbility(battlerId) == ABILITY_RIPEN)
gBattleMoveDamage *= 2;
effect = ITEM_HP_CHANGE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_JabocaRowapBerryActivates;
PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem);
RecordItemEffectBattle(battlerId, HOLD_EFFECT_ROCKY_HELMET);
}
break;
case HOLD_EFFECT_KEE_BERRY: // consume and boost defense if used physical move
effect = DamagedStatBoostBerryEffect(battlerId, STAT_DEF, SPLIT_PHYSICAL);
break;
case HOLD_EFFECT_MARANGA_BERRY: // consume and boost sp. defense if used special move
effect = DamagedStatBoostBerryEffect(battlerId, STAT_SPDEF, SPLIT_SPECIAL);
break;
}
}
break;
@ -7537,7 +7739,10 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
if (moveType == GetBattlerHoldEffectParam(battlerDef)
&& (moveType == TYPE_NORMAL || typeEffectivenessModifier >= UQ_4_12(2.0)))
{
MulModifier(&finalModifier, UQ_4_12(0.5));
if (abilityDef == ABILITY_RIPEN)
MulModifier(&finalModifier, UQ_4_12(0.25));
else
MulModifier(&finalModifier, UQ_4_12(0.5));
if (updateFlags)
gSpecialStatuses[battlerDef].berryReduced = 1;
}
@ -8100,4 +8305,3 @@ static bool32 IsUnnerveAbilityOnOpposingSide(u8 battlerId)
return TRUE;
return FALSE;
}