This commit is contained in:
AgustinGDLV 2023-05-28 11:10:50 -07:00
commit 3d4789c492
34 changed files with 6344 additions and 5490 deletions

View File

@ -332,57 +332,3 @@
createvisualtask AnimTask_IsDoubleBattle, 0
jumprettrue \ptr
.endm
@ keep CFRU macros cause I'm lazy. todo: update to createsprite and createvisualtask, respectively
.macro launchtemplate launchtemplatePtr launchtemplatePriority launchtemplateArgsNo launchtemplatearg0 launchtemplatearg1 launchtemplatearg2 launchtemplatearg3 launchtemplatearg4 launchtemplatearg5 launchtemplatearg6 launchtemplatearg7 launchtemplatearg8
.byte 0x2
.word \launchtemplatePtr
.byte \launchtemplatePriority
.byte \launchtemplateArgsNo
.hword \launchtemplatearg0
.hword \launchtemplatearg1
.hword \launchtemplatearg2
.hword \launchtemplatearg3
.hword \launchtemplatearg4
.hword \launchtemplatearg5
.hword \launchtemplatearg6
.hword \launchtemplatearg7
.hword \launchtemplatearg8
.endm
.macro launchtask launchtaskPtr launchtaskPriority launchtaskArgsNo launchtaskarg0 launchtaskarg1 launchtaskarg2 launchtaskarg3 launchtaskarg4 launchtaskarg5 launchtaskarg6 launchtaskarg7 launchtaskarg8
.byte 0x3
.word \launchtaskPtr
.byte \launchtaskPriority
.byte \launchtaskArgsNo
.hword \launchtaskarg0
.hword \launchtaskarg1
.hword \launchtaskarg2
.hword \launchtaskarg3
.hword \launchtaskarg4
.hword \launchtaskarg5
.hword \launchtaskarg6
.hword \launchtaskarg7
.hword \launchtaskarg8
.endm
.macro setblends setblends_value
.byte 0xC
.hword \setblends_value
.endm
.macro launchsoundtask launchsoundtaskPtr launchsoundtaskArgsNo launchsoundtaskarg0 launchsoundtaskarg1 launchsoundtaskarg2 launchsoundtaskarg3 launchsoundtaskarg4 launchsoundtaskarg5 launchsoundtaskarg6 launchsoundtaskarg7 launchsoundtaskarg8
.byte 0x1F
.word \launchsoundtaskPtr
.byte \launchsoundtaskArgsNo
.hword \launchsoundtaskarg0
.hword \launchsoundtaskarg1
.hword \launchsoundtaskarg2
.hword \launchsoundtaskarg3
.hword \launchsoundtaskarg4
.hword \launchsoundtaskarg5
.hword \launchsoundtaskarg6
.hword \launchsoundtaskarg7
.hword \launchsoundtaskarg8
.endm

View File

@ -1346,6 +1346,10 @@
callnative BS_ItemRestorePP
.endm
.macro tryrevertweatherform
callnative BS_TryRevertWeatherForm
.endm
.macro setsnow
callnative BS_SetSnow
.endm

File diff suppressed because it is too large Load Diff

View File

@ -1582,6 +1582,7 @@ BattleScript_MoveEffectCoreEnforcer::
printstring STRINGID_PKMNSABILITYSUPPRESSED
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
tryrevertweatherform
printstring STRINGID_EMPTYSTRING3
waitmessage 1
BattleScript_CoreEnforcerRet:
@ -2734,6 +2735,7 @@ BattleScript_EffectSimpleBeam:
printstring STRINGID_PKMNACQUIREDSIMPLE
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
tryrevertweatherform
printstring STRINGID_EMPTYSTRING3
waitmessage 1
tryendneutralizinggas BS_TARGET
@ -2833,6 +2835,7 @@ BattleScript_EffectWorrySeed:
printstring STRINGID_PKMNACQUIREDABILITY
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
tryrevertweatherform
printstring STRINGID_EMPTYSTRING3
waitmessage 1
goto BattleScript_MoveEnd
@ -2964,6 +2967,7 @@ BattleScript_EffectGastroAcid:
printstring STRINGID_PKMNSABILITYSUPPRESSED
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
tryrevertweatherform
printstring STRINGID_EMPTYSTRING3
waitmessage 1
tryendneutralizinggas BS_TARGET
@ -6863,6 +6867,7 @@ BattleScript_RainContinuesOrEnds::
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_RAIN_STOPPED, BattleScript_RainContinuesOrEndsEnd
playanimation BS_ATTACKER, B_ANIM_RAIN_CONTINUES
BattleScript_RainContinuesOrEndsEnd::
call BattleScript_ActivateWeatherAbilities
end2
BattleScript_DamagingWeatherContinues::
@ -6896,22 +6901,26 @@ BattleScript_DamagingWeatherLoopIncrement::
jumpifbytenotequal gBattleCommunication, gBattlersCount, BattleScript_DamagingWeatherLoop
BattleScript_DamagingWeatherContinuesEnd::
bicword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_GRUDGE
call BattleScript_ActivateWeatherAbilities
end2
BattleScript_SandStormHailSnowEnds::
printfromtable gSandStormHailSnowEndStringIds
waitmessage B_WAIT_TIME_LONG
call BattleScript_ActivateWeatherAbilities
end2
BattleScript_SunlightContinues::
printstring STRINGID_SUNLIGHTSTRONG
waitmessage B_WAIT_TIME_LONG
playanimation BS_ATTACKER, B_ANIM_SUN_CONTINUES
call BattleScript_ActivateWeatherAbilities
end2
BattleScript_SunlightFaded::
printstring STRINGID_SUNLIGHTFADED
waitmessage B_WAIT_TIME_LONG
call BattleScript_ActivateWeatherAbilities
end2
BattleScript_OverworldWeatherStarts::
@ -6990,8 +6999,6 @@ BattleScript_TerrainEnds_Ret::
playanimation BS_ATTACKER, B_ANIM_RESTORE_BG
return
BattleScript_GrassyTerrainEnds:
setbyte cMULTISTRING_CHOOSER, B_MSG_TERRAINENDS_GRASS
BattleScript_TerrainEnds::
call BattleScript_TerrainEnds_Ret
end2
@ -7188,8 +7195,10 @@ BattleScript_MistProtected::
return
BattleScript_RageIsBuilding::
statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_RageIsBuildingEnd
printstring STRINGID_PKMNRAGEBUILDING
waitmessage B_WAIT_TIME_LONG
BattleScript_RageIsBuildingEnd:
return
BattleScript_MoveUsedIsDisabled::
@ -8020,9 +8029,7 @@ BattleScript_CudChewActivates::
setbyte sBERRY_OVERRIDE, 0
end3
BattleScript_TargetFormChange::
pause 5
call BattleScript_AbilityPopUpTarget
BattleScript_TargetFormChangeNoPopup:
printstring STRINGID_EMPTYSTRING3
waitmessage 1
handleformchange BS_TARGET, 0
@ -8032,16 +8039,22 @@ BattleScript_TargetFormChange::
handleformchange BS_TARGET, 2
return
BattleScript_TargetFormChange::
pause 5
call BattleScript_AbilityPopUpTarget
call BattleScript_TargetFormChangeNoPopup
return
BattleScript_TargetFormChangeWithString::
pause 5
call BattleScript_AbilityPopUpTarget
printstring STRINGID_EMPTYSTRING3
waitmessage 1
handleformchange BS_TARGET, 0
handleformchange BS_TARGET, 1
playanimation BS_TARGET, B_ANIM_FORM_CHANGE, NULL
waitanimation
handleformchange BS_TARGET, 2
call BattleScript_TargetFormChangeNoPopup
printstring STRINGID_PKMNTRANSFORMED
waitmessage B_WAIT_TIME_LONG
return
BattleScript_TargetFormChangeWithStringNoPopup::
call BattleScript_TargetFormChangeNoPopup
printstring STRINGID_PKMNTRANSFORMED
waitmessage B_WAIT_TIME_LONG
return
@ -8532,10 +8545,13 @@ BattleScript_AbilityPopUp:
return
BattleScript_SpeedBoostActivates::
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_SpeedBoostActivatesEnd
call BattleScript_AbilityPopUp
setgraphicalstatchangevalues
playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printstring STRINGID_PKMNRAISEDSPEED
waitmessage B_WAIT_TIME_LONG
BattleScript_SpeedBoostActivatesEnd:
end3
@ Can't compare directly to a value, have to compare to value at pointer
@ -8689,14 +8705,15 @@ BattleScript_ShedSkinActivates::
end3
BattleScript_ActivateWeatherAbilities:
copybyte sBATTLER, gBattlerAttacker
setbyte gBattlerAttacker, 0
savetarget
setbyte gBattlerTarget, 0
BattleScript_ActivateWeatherAbilities_Loop:
activateweatherchangeabilities BS_ATTACKER
copybyte sBATTLER, gBattlerTarget
activateweatherchangeabilities BS_TARGET
BattleScript_ActivateWeatherAbilities_Increment:
addbyte gBattlerAttacker, 1
jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_ActivateWeatherAbilities_Loop
copybyte gBattlerAttacker, sBATTLER
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_ActivateWeatherAbilities_Loop
restoretarget
return
BattleScript_TryAdrenalineOrb:
@ -9047,8 +9064,8 @@ BattleScript_MoveStatDrain::
setgraphicalstatchangevalues
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
waitanimation
.if B_ABSORBING_ABILITY_STRING >= GEN_5
statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_MoveStatDrain_Cont
.if B_ABSORBING_ABILITY_STRING >= GEN_5
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
.else
@ -9187,7 +9204,6 @@ BattleScript_GrassyTerrainLoopIncrement::
BattleScript_GrassyTerrainLoopEnd::
bicword gHitMarker, HITMARKER_SKIP_DMG_TRACK | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_TERRAIN_PERMANENT, BattleScript_GrassyTerrainHealEnd
jumpifbyte CMP_EQUAL, gFieldTimers + 5, 0, BattleScript_GrassyTerrainEnds
BattleScript_GrassyTerrainHealEnd:
end2
@ -9328,6 +9344,7 @@ BattleScript_WeakArmorActivatesEnd:
return
BattleScript_RaiseStatOnFaintingTarget::
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_RaiseStatOnFaintingTarget_End
copybyte gBattlerAbility, gBattlerAttacker
call BattleScript_AbilityPopUp
setgraphicalstatchangevalues
@ -9335,9 +9352,11 @@ BattleScript_RaiseStatOnFaintingTarget::
waitanimation
printstring STRINGID_LASTABILITYRAISEDSTAT
waitmessage B_WAIT_TIME_LONG
BattleScript_RaiseStatOnFaintingTarget_End:
return
BattleScript_AttackerAbilityStatRaise::
statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_AttackerAbilityStatRaise_End
copybyte gBattlerAbility, gBattlerAttacker
call BattleScript_AbilityPopUp
setgraphicalstatchangevalues
@ -9345,6 +9364,7 @@ BattleScript_AttackerAbilityStatRaise::
waitanimation
printstring STRINGID_ATTACKERABILITYSTATRAISE
waitmessage B_WAIT_TIME_LONG
BattleScript_AttackerAbilityStatRaise_End:
return
BattleScript_FellStingerRaisesStat::

View File

@ -59,9 +59,9 @@ BattleScript_ItemRestoreHP::
end
BattleScript_ItemRestoreHP_SendOutRevivedBattler:
switchinanim BS_ATTACKER, FALSE
switchinanim BS_SCRIPTING, FALSE
waitstate
switchineffects BS_ATTACKER
switchineffects BS_SCRIPTING
end
BattleScript_ItemCureStatus::

View File

@ -1,3 +1,5 @@
.if DEBUG_OVERWORLD_MENU == TRUE
Debug_ShowFieldMessageStringVar4::
special ShowFieldMessageStringVar4
waitmessage
@ -90,3 +92,24 @@ Debug_Script_7::
Debug_Script_8::
end
Debug_CheckSaveBlock::
callnative CheckSaveBlock1Size
msgbox Debug_SaveBlock1Size, MSGBOX_DEFAULT
callnative CheckSaveBlock2Size
msgbox Debug_SaveBlock2Size, MSGBOX_DEFAULT
callnative CheckPokemonStorageSize
msgbox Debug_PokemonStorageSize, MSGBOX_DEFAULT
release
end
Debug_SaveBlock1Size::
.string "SaveBlock1 size: {STR_VAR_1}/{STR_VAR_2}.$"
Debug_SaveBlock2Size::
.string "SaveBlock2 size: {STR_VAR_1}/{STR_VAR_2}.$"
Debug_PokemonStorageSize::
.string "{PKMN}Storage size: {STR_VAR_1}/{STR_VAR_2}.$"
.endif

View File

@ -143,7 +143,7 @@ bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtk
bool32 ShouldBurnSelf(u8 battler, u16 ability);
bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove);
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender);
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility);
bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof);
u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move);
bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move);

View File

@ -470,6 +470,7 @@ extern const u8 BattleScript_MoveEffectStockpileWoreOff[];
extern const u8 BattleScript_StealthRockActivates[];
extern const u8 BattleScript_SpikesActivates[];
extern const u8 BattleScript_BerserkGeneRet[];
extern const u8 BattleScript_TargetFormChangeWithStringNoPopup[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];

View File

@ -139,7 +139,6 @@ void TryClearRageAndFuryCutter(void);
u8 AtkCanceller_UnableToUseMove(void);
u8 AtkCanceller_UnableToUseMove2(void);
bool8 HasNoMonsToSwitch(u8 battlerId, u8 r1, u8 r2);
u8 TryWeatherFormChange(u8 battlerId);
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility);
u8 AbilityBattleEffects(u8 caseID, u8 battlerId, u16 ability, u8 special, u16 moveArg);
bool32 IsNeutralizingGasOnField(void);
@ -235,5 +234,7 @@ u32 CountBattlerStatIncreases(u8 battlerId, bool32 countEvasionAcc);
bool32 IsMyceliumMightOnField(void);
bool8 ChangeTypeBasedOnTerrain(u8 battlerId);
void RemoveConfusionStatus(u8 battlerId);
u8 GetBattlerGender(u8 battlerId);
bool8 AreBattlersOfOppositeGender(u8 battler1, u8 battler2);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -198,7 +198,7 @@
#define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper)
#define B_AFFECTION_MECHANICS FALSE // In Gen6+, there's a stat called affection that can trigger different effects in battle. From LGPE onwards, those effects use friendship instead.
#define B_TRAINER_CLASS_POKE_BALLS GEN_LATEST // In Gen7+, trainers will use certain types of Poké Balls depending on their trainer class.
#define B_OBEDIENCE_MECHANICS GEN_LATEST // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level
#define B_OBEDIENCE_MECHANICS GEN_7 // In PLA+ (here Gen8+), obedience restrictions also apply to non-outsider Pokémon, albeit based on their level met rather than actual level
#define B_USE_FROSTBITE FALSE // In PLA, Frostbite replaces Freeze. Enabling this flag does the same here. Moves can still be cherry-picked to either Freeze or Frostbite. Freeze-Dry, Secret Power & Tri Attack depend on this config.
// Animation Settings

View File

@ -10,6 +10,7 @@
#define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8+, the Vitamins no longer have a cap of 100 EV per stat.
#define I_BERRY_EV_JUMP GEN_LATEST // In Gen4 only, EV-lowering Berries lower a stat's EV to 100 if it is above 100.
#define I_GRISEOUS_ORB_FORM_CHANGE GEN_LATEST // In Gen9+, the Griseous Orb no longer changes Giratina's form when held.
#define I_USE_EVO_HELD_ITEMS_FROM_BAG FALSE // If TRUE, items such as Razor Claw or Electirizer will be usable from the bag to evolve a Pokémon just like in LA.
// TM config
#define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1.

View File

@ -596,21 +596,6 @@
#define ANIM_WEATHER_HAIL 4
#define ANIM_WEATHER_SNOW 5
// mon pal blend
#define ANIM_PAL_BG 0x1
#define ANIM_PAL_ATK 0x2
#define ANIM_PAL_DEF 0x4
#define ANIM_PAL_ATK_PARTNER 0x8
#define ANIM_PAL_DEF_PARTNER 0x10
#define ANIM_PAL_ALL 0x1f
#define ANIM_PAL_BG_4 0x20
#define ANIM_PAL_BG_5 0x40
#define ANIM_PAL_ALL_BATTLERS 0x780
#define ANIM_PAL_PLAYER1 0x80
#define ANIM_PAL_PLAYER2 0x100
#define ANIM_PAL_OPPONENT1 0x200
#define ANIM_PAL_OPPONENT2 0x400
// horseshoe/fist frames
#define ANIM_RIGHT_FIST 0
#define ANIM_LEFT_FIST 2
@ -628,19 +613,18 @@
// Flags given to various functions to indicate which palettes to consider.
// Handled by UnpackSelectedBattlePalettes
#define F_PAL_BG (1 << 0)
#define F_PAL_ATTACKER (1 << 1)
#define F_PAL_TARGET (1 << 2)
#define F_PAL_ATK_PARTNER (1 << 3)
#define F_PAL_DEF_PARTNER (1 << 4)
#define F_PAL_ANIM_1 (1 << 5) // Palette set for GetBattleAnimBg1Data/GetBgDataForTransform. Only used (ineffectually?) by Aromatherapy.
#define F_PAL_ANIM_2 (1 << 6) // Palette set for GetBattleAnimBgData/GetBgDataForTransform. Unused.
#define F_PAL_ATK_SIDE (F_PAL_ATTACKER | F_PAL_ATK_PARTNER)
#define F_PAL_DEF_SIDE (F_PAL_TARGET | F_PAL_DEF_PARTNER)
#define F_PAL_BATTLERS (F_PAL_ATK_SIDE | F_PAL_DEF_SIDE)
// The below are only used by AnimTask_BlendBattleAnimPal to get battler sprite palettes by position rather than by role.
// It's redundant with F_PAL_BATTLERS, because they're only ever used together to refer to all the battlers at once.
#define F_PAL_BATTLERS_2 (1 << 7 | 1 << 8 | 1 << 9 | 1 << 10)
#define F_PAL_BG (1 << 0)
#define F_PAL_ATTACKER (1 << 1)
#define F_PAL_TARGET (1 << 2)
#define F_PAL_ATK_PARTNER (1 << 3)
#define F_PAL_DEF_PARTNER (1 << 4)
#define F_PAL_ANIM_1 (1 << 5) // Palette set for GetBattleAnimBg1Data/GetBgDataForTransform. Only used (ineffectually?) by Aromatherapy.
#define F_PAL_ANIM_2 (1 << 6) // Palette set for GetBattleAnimBgData/GetBgDataForTransform. Unused.
#define F_PAL_ATK_SIDE (F_PAL_ATTACKER | F_PAL_ATK_PARTNER)
#define F_PAL_DEF_SIDE (F_PAL_TARGET | F_PAL_DEF_PARTNER)
#define F_PAL_BATTLERS (F_PAL_ATK_SIDE | F_PAL_DEF_SIDE)
#define F_PAL_ADJACENT (F_PAL_DEF_SIDE | F_PAL_ATK_PARTNER)
#define F_PAL_ALL_BUT_DEF (F_PAL_ATK_SIDE | F_PAL_DEF_PARTNER)
#define F_PAL_ALL_BUT_ATK_PARTNER (F_PAL_ATTACKER | F_PAL_DEF_SIDE)
#endif // GUARD_CONSTANTS_BATTLE_ANIM_H

View File

@ -89,6 +89,7 @@
// Form change that activates when a specific weather is set during battle.
// param1: weather to check
// param2: (optional) revert if specified ability is lost
#define FORM_CHANGE_BATTLE_WEATHER 14
// Form change that activates when the mon Dynamaxes (TODO: with Gigantamax factor).

View File

@ -312,7 +312,9 @@
#define EVO_SCRIPT_TRIGGER_DMG 36 // Pokémon has specified HP below max, then player interacts trigger
#define EVO_DARK_SCROLL 37 // interacts with Scroll of Darkness
#define EVO_WATER_SCROLL 38 // interacts with Scroll of Waters
#define EVO_ITEM_NIGHT 39 // specified item is used on Pokémon at night
#define EVO_ITEM_NIGHT 39 // specified item is used on Pokémon, is night
#define EVO_ITEM_DAY 40 // specified item is used on Pokémon, is day
#define EVO_ITEM_HOLD 41 // Pokémon levels up, holds specified item
#define EVOS_PER_MON 11

View File

@ -1,6 +1,8 @@
#ifndef GUARD_MONEY_H
#define GUARD_MONEY_H
#define MAX_MONEY 999999
u32 GetMoney(u32 *moneyPtr);
void SetMoney(u32 *moneyPtr, u32 newValue);
bool8 IsEnoughMoney(u32 *moneyPtr, u32 cost);

View File

@ -248,7 +248,7 @@ static void CopyBattlerDataToAIParty(u32 bPosition, u32 side)
aiMon->species = bMon->species;
aiMon->level = bMon->level;
aiMon->status = bMon->status1;
aiMon->gender = GetGenderFromSpeciesAndPersonality(bMon->species, bMon->personality);
aiMon->gender = GetBattlerGender(battler);
aiMon->isFainted = FALSE;
aiMon->wasSentInBattle = TRUE;
aiMon->switchInCount++;
@ -1287,12 +1287,8 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 8;
break;
case EFFECT_CAPTIVATE:
{
u8 atkGender = GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality);
u8 defGender = GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality);
if (atkGender == MON_GENDERLESS || defGender == MON_GENDERLESS || atkGender == defGender)
score -= 10;
}
if (!AreBattlersOfOppositeGender(battlerAtk, battlerDef))
score -= 10;
break;
// other
case EFFECT_HAZE:
@ -1592,9 +1588,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score -= 2; // mainly to prevent looping between hail and snow
break;
case EFFECT_ATTRACT:
if (!AI_CanBeInfatuated(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef],
GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality),
GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality)))
if (!AI_CanBeInfatuated(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef]))
score -= 10;
break;
case EFFECT_SAFEGUARD:

View File

@ -591,7 +591,8 @@ void SetBattlerData(u8 battlerId)
{
if (!BattlerHasAi(battlerId))
{
u32 i, species, illusionSpecies;
u32 i, species, illusionSpecies, side;
side = GetBattlerSide(battlerId);
// Simulate Illusion
species = gBattleMons[battlerId].species;
@ -609,22 +610,22 @@ void SetBattlerData(u8 battlerId)
}
// Use the known battler's ability.
if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE)
gBattleMons[battlerId].ability = BATTLE_HISTORY->abilities[battlerId];
if (AI_PARTY->mons[side][gBattlerPartyIndexes[battlerId]].ability != ABILITY_NONE)
gBattleMons[battlerId].ability = AI_PARTY->mons[side][gBattlerPartyIndexes[battlerId]].ability;
// Check if mon can only have one ability.
else if (gSpeciesInfo[species].abilities[1] == ABILITY_NONE
|| gSpeciesInfo[species].abilities[1] == gSpeciesInfo[species].abilities[0])
|| gSpeciesInfo[species].abilities[1] == gSpeciesInfo[species].abilities[0])
gBattleMons[battlerId].ability = gSpeciesInfo[species].abilities[0];
// The ability is unknown.
else
gBattleMons[battlerId].ability = ABILITY_NONE;
if (BATTLE_HISTORY->itemEffects[battlerId] == 0)
if (AI_PARTY->mons[side][gBattlerPartyIndexes[battlerId]].heldEffect == 0)
gBattleMons[battlerId].item = 0;
for (i = 0; i < 4; i++)
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (BATTLE_HISTORY->usedMoves[battlerId][i] == 0)
if (AI_PARTY->mons[side][gBattlerPartyIndexes[battlerId]].moves[i] == 0)
gBattleMons[battlerId].moves[i] = 0;
}
}
@ -2966,14 +2967,12 @@ bool32 AI_CanGiveFrostbite(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 batt
return TRUE;
}
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender)
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility)
{
if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION)
|| AI_GetMoveEffectiveness(AI_THINKING_STRUCT->moveConsidered, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|| defAbility == ABILITY_OBLIVIOUS
|| atkGender == defGender
|| atkGender == MON_GENDERLESS
|| defGender == MON_GENDERLESS
|| !AreBattlersOfOppositeGender(battlerAtk, battlerDef)
|| AI_IsAbilityOnSide(battlerDef, ABILITY_AROMA_VEIL))
return FALSE;
return TRUE;

View File

@ -312,13 +312,10 @@ static void HandleInputChooseAction(void)
&& !(gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)])
&& !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{
// Return item to bag if partner had selected one.
if (gBattleResources->bufferA[gActiveBattler][1] == B_ACTION_USE_ITEM)
{
// Add item to bag if it is a ball
if (itemId <= LAST_BALL)
AddBagItem(itemId, 1);
else
return;
AddBagItem(itemId, 1);
}
PlaySE(SE_SELECT);
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_CANCEL_PARTNER, 0);

View File

@ -1018,11 +1018,13 @@ static void Task_ShowAiParty(u8 taskId)
gSprites[gSprites[data->spriteIds.aiPartyIcons[i]].sConditionSpriteId].oam.priority = 0;
if (aiMons[i].isFainted)
ailment = AILMENT_FNT;
else if (aiMons[i].status)
ailment = GetAilmentFromStatus(aiMons[i].status);
else
ailment = AILMENT_FNT + 1; // blank
StartSpriteAnim(&gSprites[gSprites[data->spriteIds.aiPartyIcons[i]].sConditionSpriteId], ailment - 1);
ailment = GetAilmentFromStatus(aiMons[i].status);
if (ailment != AILMENT_NONE)
StartSpriteAnim(&gSprites[gSprites[data->spriteIds.aiPartyIcons[i]].sConditionSpriteId], ailment - 1);
else
gSprites[gSprites[data->spriteIds.aiPartyIcons[i]].sConditionSpriteId].invisible = TRUE;
}
for (; i < PARTY_SIZE; i++)
data->spriteIds.aiPartyIcons[i] = 0xFF;

View File

@ -5440,7 +5440,6 @@ static void HandleEndTurn_FinishBattle(void)
BeginFastPaletteFade(3);
FadeOutMapMusic(5);
#if B_TRAINERS_KNOCK_OFF_ITEMS == TRUE || B_RESTORE_HELD_BATTLE_ITEMS == TRUE
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
TryRestoreHeldItems();
#endif

View File

@ -2523,6 +2523,7 @@ static void Cmd_datahpupdate(void)
gBattleMons[gActiveBattler].species = SPECIES_MIMIKYU_BUSTED;
BattleScriptPush(cmd->nextInstr);
gBattlescriptCurrInstr = BattleScript_TargetFormChange;
return;
}
else
{
@ -5587,7 +5588,7 @@ static void Cmd_moveend(void)
&& gBattleMoves[gCurrentMove].power != 0
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
{
gBattleMons[gBattlerTarget].statStages[STAT_ATK]++;
SET_STATCHANGER(STAT_ATK, 1, FALSE);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_RageIsBuilding;
effect = TRUE;
@ -9517,7 +9518,6 @@ static void Cmd_various(void)
&& !NoAliveMonsForEitherParty()
&& CompareStat(gBattlerAttacker, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
{
gBattleMons[gBattlerAttacker].statStages[STAT_ATK]++;
SET_STATCHANGER(STAT_ATK, 1, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK);
BattleScriptPush(cmd->nextInstr);
@ -9541,7 +9541,6 @@ static void Cmd_various(void)
&& !NoAliveMonsForEitherParty()
&& CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))
{
gBattleMons[gBattlerAttacker].statStages[STAT_SPATK]++;
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK);
BattleScriptPush(cmd->nextInstr);
@ -9593,7 +9592,6 @@ static void Cmd_various(void)
&& !NoAliveMonsForEitherParty()
&& CompareStat(gBattlerAttacker, i, MAX_STAT_STAGE, CMP_LESS_THAN))
{
gBattleMons[gBattlerAttacker].statStages[i]++;
SET_STATCHANGER(i, 1, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, i);
BattleScriptPush(cmd->nextInstr);
@ -9613,7 +9611,6 @@ static void Cmd_various(void)
&& !NoAliveMonsForEitherParty()
&& CompareStat(gBattleScripting.battler, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN))
{
gBattleMons[gBattleScripting.battler].statStages[STAT_SPATK]++;
SET_STATCHANGER(STAT_SPATK, 1, FALSE);
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK);
BattleScriptPushCursor();
@ -12803,26 +12800,6 @@ static void Cmd_tryinfatuating(void)
{
CMD_ARGS(const u8 *failInstr);
struct Pokemon *monAttacker, *monTarget;
u16 speciesAttacker, speciesTarget;
u32 personalityAttacker, personalityTarget;
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
monAttacker = &gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]];
else
monAttacker = &gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]];
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
monTarget = &gPlayerParty[gBattlerPartyIndexes[gBattlerTarget]];
else
monTarget = &gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]];
speciesAttacker = GetMonData(monAttacker, MON_DATA_SPECIES);
personalityAttacker = GetMonData(monAttacker, MON_DATA_PERSONALITY);
speciesTarget = GetMonData(monTarget, MON_DATA_SPECIES);
personalityTarget = GetMonData(monTarget, MON_DATA_PERSONALITY);
if (GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS)
{
gBattlescriptCurrInstr = BattleScript_NotAffectedAbilityPopUp;
@ -12831,10 +12808,8 @@ static void Cmd_tryinfatuating(void)
}
else
{
if (GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget)
|| gBattleMons[gBattlerTarget].status2 & STATUS2_INFATUATION
|| GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS
|| GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS)
if (gBattleMons[gBattlerTarget].status2 & STATUS2_INFATUATION
|| !AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget))
{
gBattlescriptCurrInstr = cmd->failInstr;
}
@ -16183,10 +16158,7 @@ static void Cmd_jumpifoppositegenders(void)
{
CMD_ARGS(const u8 *jumpInstr);
u32 atkGender = GetGenderFromSpeciesAndPersonality(gBattleMons[gBattlerAttacker].species, gBattleMons[gBattlerAttacker].personality);
u32 defGender = GetGenderFromSpeciesAndPersonality(gBattleMons[gBattlerTarget].species, gBattleMons[gBattlerTarget].personality);
if ((atkGender == MON_MALE && defGender == MON_FEMALE) || (atkGender == MON_FEMALE && defGender == MON_MALE))
if (AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget))
gBattlescriptCurrInstr = cmd->jumpInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
@ -16405,7 +16377,7 @@ void BS_CheckParentalBondCounter(void)
void BS_GetBattlerSide(void)
{
NATIVE_ARGS(u8 battler);
gBattleCommunication[0] = GetBattlerSide(cmd->battler);
gBattleCommunication[0] = GetBattlerSide(GetBattlerForBattleScript(cmd->battler));
gBattlescriptCurrInstr = cmd->nextInstr;
}
@ -16525,7 +16497,8 @@ u8 GetFirstFaintedPartyIndex(u8 battlerId)
return PARTY_SIZE;
}
void BS_ItemRestoreHP(void) {
void BS_ItemRestoreHP(void)
{
NATIVE_ARGS();
u16 healAmount;
u32 battlerId = MAX_BATTLERS_COUNT;
@ -16580,6 +16553,7 @@ void BS_ItemRestoreHP(void) {
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && battlerId != MAX_BATTLERS_COUNT)
{
gAbsentBattlerFlags &= ~gBitTable[battlerId];
gBattleScripting.battler = battlerId;
gBattleCommunication[MULTIUSE_STATE] = TRUE;
}
}
@ -16587,7 +16561,8 @@ void BS_ItemRestoreHP(void) {
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_ItemCureStatus(void) {
void BS_ItemCureStatus(void)
{
NATIVE_ARGS();
struct Pokemon *party = GetBattlerParty(gBattlerAttacker);
@ -16615,7 +16590,8 @@ void BS_ItemCureStatus(void) {
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_ItemIncreaseStat(void) {
void BS_ItemIncreaseStat(void)
{
NATIVE_ARGS();
u16 statId = GetItemEffect(gLastUsedItem)[1];
u16 stages = ItemId_GetHoldEffectParam(gLastUsedItem);
@ -16623,7 +16599,8 @@ void BS_ItemIncreaseStat(void) {
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_ItemRestorePP(void) {
void BS_ItemRestorePP(void)
{
NATIVE_ARGS();
const u8 *effect = GetItemEffect(gLastUsedItem);
u32 i, pp, maxPP, moveId, loopEnd;
@ -16675,6 +16652,19 @@ void BS_ItemRestorePP(void) {
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_TryRevertWeatherForm(void)
{
NATIVE_ARGS();
if (TryBattleFormChange(gBattlerTarget, FORM_CHANGE_BATTLE_WEATHER))
{
gBattleScripting.battler = gBattlerTarget;
BattleScriptPush(cmd->nextInstr);
gBattlescriptCurrInstr = BattleScript_TargetFormChangeWithStringNoPopup;
return;
}
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_SetSnow(void)
{
NATIVE_ARGS();

View File

@ -2074,19 +2074,16 @@ static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId)
{
if (gFieldStatuses & terrainFlag)
{
if (terrainFlag & STATUS_FIELD_GRASSY_TERRAIN)
BattleScriptExecute(BattleScript_GrassyTerrainHeals);
if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0)
{
gFieldStatuses &= ~terrainFlag;
TryToRevertMimicry();
if (!(terrainFlag & STATUS_FIELD_GRASSY_TERRAIN))
{
gBattleCommunication[MULTISTRING_CHOOSER] = stringTableId;
BattleScriptExecute(BattleScript_TerrainEnds);
}
gBattleCommunication[MULTISTRING_CHOOSER] = stringTableId;
BattleScriptExecute(BattleScript_TerrainEnds);
return TRUE;
}
if (terrainFlag & STATUS_FIELD_GRASSY_TERRAIN)
BattleScriptExecute(BattleScript_GrassyTerrainHeals);
return TRUE;
}
return FALSE;
}
@ -4075,96 +4072,6 @@ bool8 HasNoMonsToSwitch(u8 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2)
}
}
u8 TryWeatherFormChange(u8 battler)
{
u8 ret = 0;
bool32 weatherEffect = WEATHER_HAS_EFFECT;
u16 holdEffect = GetBattlerHoldEffect(battler, TRUE);
switch (gBattleMons[battler].species)
{
case SPECIES_CASTFORM:
/* Placeholder
case SPECIES_CASTFORM_RAINY:
case SPECIES_CASTFORM_SNOWY:
case SPECIES_CASTFORM_SUNNY:*/
#if B_WEATHER_FORMS >= GEN_5
if (gBattleMons[battler].hp == 0)
{
ret = 0; // No change
}
else if (GetBattlerAbility(battler) != ABILITY_FORECAST || !weatherEffect)
{
if (!IS_BATTLER_OF_TYPE(battler, TYPE_NORMAL))
{
SET_BATTLER_TYPE(battler, TYPE_NORMAL);
ret = CASTFORM_NORMAL + 1;
}
else
{
ret = 0; // No change
}
}
#else
if (GetBattlerAbility(battler) != ABILITY_FORECAST || gBattleMons[battler].hp == 0)
{
ret = 0; // No change
}
else if (!weatherEffect)
{
if (!IS_BATTLER_OF_TYPE(battler, TYPE_NORMAL))
{
SET_BATTLER_TYPE(battler, TYPE_NORMAL);
ret = CASTFORM_NORMAL + 1;
}
else
{
ret = 0; // No change
}
}
#endif
else if (holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA || (!(gBattleWeather & (B_WEATHER_RAIN | B_WEATHER_SUN | B_WEATHER_HAIL | B_WEATHER_SNOW)) && !IS_BATTLER_OF_TYPE(battler, TYPE_NORMAL)))
{
SET_BATTLER_TYPE(battler, TYPE_NORMAL);
ret = CASTFORM_NORMAL + 1;
}
else if (gBattleWeather & B_WEATHER_SUN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && !IS_BATTLER_OF_TYPE(battler, TYPE_FIRE))
{
SET_BATTLER_TYPE(battler, TYPE_FIRE);
ret = CASTFORM_FIRE + 1;
}
else if (gBattleWeather & B_WEATHER_RAIN && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && !IS_BATTLER_OF_TYPE(battler, TYPE_WATER))
{
SET_BATTLER_TYPE(battler, TYPE_WATER);
ret = CASTFORM_WATER + 1;
}
else if (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW) && !IS_BATTLER_OF_TYPE(battler, TYPE_ICE))
{
SET_BATTLER_TYPE(battler, TYPE_ICE);
ret = CASTFORM_ICE + 1;
}
break;
case SPECIES_CHERRIM:
// case SPECIES_CHERRIM_SUNSHINE:
if (gBattleMons[battler].hp == 0)
ret = 0; // No change
#if B_WEATHER_FORMS >= GEN_5
if (GetBattlerAbility(battler) != ABILITY_FLOWER_GIFT)
if (gBattleMonForms[battler] != 0)
ret = CHERRIM_OVERCAST + 1;
else
ret = 0; // No change
#endif
else if (gBattleMonForms[battler] == 0 && weatherEffect && holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA && gBattleWeather & B_WEATHER_SUN)
ret = CHERRIM_SUNSHINE + 1;
else if (gBattleMonForms[battler] != 0 && (!weatherEffect || holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA || !(gBattleWeather & B_WEATHER_SUN)))
ret = CHERRIM_OVERCAST + 1;
break;
}
return ret;
}
static const u16 sWeatherFlagsInfo[][3] =
{
[ENUM_WEATHER_RAIN] = {B_WEATHER_RAIN_TEMPORARY, B_WEATHER_RAIN_PERMANENT, HOLD_EFFECT_DAMP_ROCK},
@ -4345,7 +4252,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
{
u8 effect = 0;
u32 speciesAtk, speciesDef;
u32 pidAtk, pidDef;
u32 moveType, move;
u32 i, j;
@ -4356,10 +4262,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
gBattlerAttacker = battler;
speciesAtk = gBattleMons[gBattlerAttacker].species;
pidAtk = gBattleMons[gBattlerAttacker].personality;
speciesDef = gBattleMons[gBattlerTarget].species;
pidDef = gBattleMons[gBattlerTarget].personality;
if (special)
gLastUsedAbility = special;
@ -4621,7 +4524,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
if (CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
{
gBattleMons[battler].statStages[statId]++;
SET_STATCHANGER(statId, 1, FALSE);
gBattlerAttacker = battler;
PREPARE_STAT_BUFFER(gBattleTextBuff1, statId);
@ -4918,12 +4820,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
effect++;
}
break;
#if B_WEATHER_FORMS < GEN_5
default:
if (gBattleMons[battler].species == SPECIES_CHERRIM)
goto TRY_WEATHER_FORM;
break;
#endif
}
break;
case ABILITYEFFECT_ENDTURN: // 1
@ -4994,9 +4890,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITY_SPEED_BOOST:
if (CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN) && gDisableStructs[battler].isFirstTurn != 2)
{
gBattleMons[battler].statStages[STAT_SPEED]++;
gBattleScripting.animArg1 = 14 + STAT_SPEED;
gBattleScripting.animArg2 = 0;
SET_STATCHANGER(STAT_SPEED, 1, FALSE);
BattleScriptPushCursorAndCallback(BattleScript_SpeedBoostActivates);
gBattleScripting.battler = battler;
effect++;
@ -5291,7 +5185,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
SET_STATCHANGER(statId, statAmount, FALSE);
#if B_ABSORBING_ABILITY_STRING < GEN_5
gBattleMons[battler].statStages[statId]++;
PREPARE_STAT_BUFFER(gBattleTextBuff1, statId);
#endif
}
@ -5689,16 +5582,14 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& (IsMoveMakingContact(move, gBattlerAttacker))
&& TARGET_TURN_DAMAGED
&& gBattleMons[gBattlerTarget].hp != 0
&& RandomWeighted(RNG_CUTE_CHARM, 2, 1)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_OBLIVIOUS
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)
&& GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef)
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION)
&& GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != MON_GENDERLESS
&& GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != MON_GENDERLESS)
&& AreBattlersOfOppositeGender(gBattlerAttacker, gBattlerTarget)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_OBLIVIOUS
&& IsMoveMakingContact(move, gBattlerAttacker)
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL))
{
gBattleMons[gBattlerAttacker].status2 |= STATUS2_INFATUATED_WITH(gBattlerTarget);
BattleScriptPushCursor();
@ -6198,13 +6089,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
switch (gLastUsedAbility)
{
case ABILITY_FORECAST:
#if B_WEATHER_FORMS >= GEN_5
case ABILITY_FLOWER_GIFT:
#else
TRY_WEATHER_FORM:
#endif
if ((IsBattlerWeatherAffected(battler, gBattleWeather) || gBattleWeather == B_WEATHER_NONE)
&& TryBattleFormChange(battler, FORM_CHANGE_BATTLE_WEATHER))
if ((IsBattlerWeatherAffected(battler, gBattleWeather)
|| gBattleWeather == B_WEATHER_NONE
|| !WEATHER_HAS_EFFECT) // Air Lock active
&& TryBattleFormChange(battler, FORM_CHANGE_BATTLE_WEATHER))
{
BattleScriptPushCursorAndCallback(BattleScript_BattlerFormChangeWithStringEnd3);
effect++;
@ -6882,7 +6771,7 @@ static bool32 GetMentalHerbEffect(u8 battlerId)
static u8 TryConsumeMirrorHerb(u8 battlerId, bool32 execute)
{
u8 effect = 0;
if (gProtectStructs[battlerId].eatMirrorHerb) {
gLastUsedItem = gBattleMons[battlerId].item;
gBattleScripting.savedBattler = gBattlerAttacker;
@ -8935,15 +8824,10 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
MulModifier(&modifier, UQ_4_12(1.3));
break;
case ABILITY_RIVALRY:
if (GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality) != MON_GENDERLESS
&& GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality) != MON_GENDERLESS)
{
if (GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality)
== GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality))
MulModifier(&modifier, UQ_4_12(1.25));
else
MulModifier(&modifier, UQ_4_12(0.75));
}
if (AreBattlersOfOppositeGender(battlerAtk, battlerDef))
MulModifier(&modifier, UQ_4_12(1.25));
else
MulModifier(&modifier, UQ_4_12(0.75));
break;
case ABILITY_ANALYTIC:
if (GetBattlerTurnOrderNum(battlerAtk) == gBattlersCount - 1 && move != MOVE_FUTURE_SIGHT && move != MOVE_DOOM_DESIRE)
@ -9402,7 +9286,7 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b
break;
#endif
case ABILITY_FLOWER_GIFT:
if (gBattleMons[battlerAtk].species == SPECIES_CHERRIM && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN) && IS_MOVE_PHYSICAL(move))
if (gBattleMons[battlerAtk].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN) && IS_MOVE_PHYSICAL(move))
MulModifier(&modifier, UQ_4_12(1.5));
break;
case ABILITY_HUSTLE:
@ -9442,7 +9326,7 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b
switch (GetBattlerAbility(BATTLE_PARTNER(battlerAtk)))
{
case ABILITY_FLOWER_GIFT:
if (gBattleMons[BATTLE_PARTNER(battlerAtk)].species == SPECIES_CHERRIM && IsBattlerWeatherAffected(BATTLE_PARTNER(battlerAtk), B_WEATHER_SUN) && IS_MOVE_PHYSICAL(move))
if (gBattleMons[BATTLE_PARTNER(battlerAtk)].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(BATTLE_PARTNER(battlerAtk), B_WEATHER_SUN) && IS_MOVE_PHYSICAL(move))
MulModifier(&modifier, UQ_4_12(1.5));
break;
}
@ -9576,7 +9460,7 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
}
break;
case ABILITY_FLOWER_GIFT:
if (gBattleMons[battlerDef].species == SPECIES_CHERRIM && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SUN) && !usesDefStat)
if (gBattleMons[battlerDef].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SUN) && !usesDefStat)
MulModifier(&modifier, UQ_4_12(1.5));
break;
case ABILITY_PUNK_ROCK:
@ -9595,7 +9479,7 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType,
switch (GetBattlerAbility(BATTLE_PARTNER(battlerDef)))
{
case ABILITY_FLOWER_GIFT:
if (gBattleMons[BATTLE_PARTNER(battlerDef)].species == SPECIES_CHERRIM && IsBattlerWeatherAffected(BATTLE_PARTNER(battlerDef), B_WEATHER_SUN) && !usesDefStat)
if (gBattleMons[BATTLE_PARTNER(battlerDef)].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(BATTLE_PARTNER(battlerDef), B_WEATHER_SUN) && !usesDefStat)
MulModifier(&modifier, UQ_4_12(1.5));
break;
}
@ -10328,9 +10212,25 @@ u16 GetBattleFormChangeTargetSpecies(u8 battlerId, u16 method)
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_BATTLE_WEATHER:
if (gBattleWeather & formChanges[i].param1
|| (gBattleWeather == B_WEATHER_NONE && formChanges[i].param1 == B_WEATHER_NONE))
// Check if there is a required ability and if the battler's ability does not match it
// or is suppressed. If so, revert to the no weather form.
if (formChanges[i].param2
&& GetBattlerAbility(battlerId) != formChanges[i].param2
&& formChanges[i].param1 == B_WEATHER_NONE)
{
targetSpecies = formChanges[i].targetSpecies;
}
// We need to revert the weather form if the field is under Air Lock, too.
else if (!WEATHER_HAS_EFFECT && formChanges[i].param1 == B_WEATHER_NONE)
{
targetSpecies = formChanges[i].targetSpecies;
}
// Otherwise, just check for a match between the weather and the form change table.
else if (gBattleWeather & formChanges[i].param1
|| (gBattleWeather == B_WEATHER_NONE && formChanges[i].param1 == B_WEATHER_NONE))
{
targetSpecies = formChanges[i].targetSpecies;
}
break;
case FORM_CHANGE_BATTLE_TURN_END:
if (formChanges[i].param1 == GetBattlerAbility(battlerId))
@ -11108,3 +11008,16 @@ static bool8 CanBeInfinitelyConfused(u8 battlerId)
return TRUE;
}
u8 GetBattlerGender(u8 battlerId)
{
return GetGenderFromSpeciesAndPersonality(gBattleMons[battlerId].species,
gBattleMons[battlerId].personality);
}
bool8 AreBattlersOfOppositeGender(u8 battler1, u8 battler2)
{
u8 gender1 = GetBattlerGender(battler1);
u8 gender2 = GetBattlerGender(battler2);
return (gender1 != MON_GENDERLESS && gender2 != MON_GENDERLESS && gender1 != gender2);
}

View File

@ -1,3 +1,11 @@
#if I_USE_EVO_HELD_ITEMS_FROM_BAG == TRUE
#define EVO_HELD_ITEM_TYPE ITEM_USE_PARTY_MENU
#define EVO_HELD_ITEM_FIELD_FUNC ItemUseOutOfBattle_EvolutionStone
#else
#define EVO_HELD_ITEM_TYPE ITEM_USE_BAG_MENU
#define EVO_HELD_ITEM_FIELD_FUNC ItemUseOutOfBattle_CannotUse
#endif
const struct Item gItems[] =
{
[ITEM_NONE] =
@ -2890,8 +2898,8 @@ const struct Item gItems[] =
.holdEffectParam = 10,
.description = sDragonScaleDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 30,
},
@ -2903,8 +2911,8 @@ const struct Item gItems[] =
.holdEffect = HOLD_EFFECT_UPGRADE,
.description = sUpgradeDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 30,
},
@ -2915,8 +2923,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sProtectorDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 80,
},
@ -2927,8 +2935,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sElectirizerDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 80,
},
@ -2939,8 +2947,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sMagmarizerDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 80,
},
@ -2951,8 +2959,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sDubiousDiscDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 50,
},
@ -2963,8 +2971,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sReaperClothDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 10,
},
@ -2975,8 +2983,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sPrismScaleDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 30,
},
@ -2987,8 +2995,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sWhippedDreamDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 80,
},
@ -2999,8 +3007,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sSachetDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 80,
},
@ -3011,8 +3019,8 @@ const struct Item gItems[] =
.price = 2000,
.description = sOvalStoneDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 80,
},
@ -5199,8 +5207,8 @@ const struct Item gItems[] =
.holdEffect = HOLD_EFFECT_DEEP_SEA_SCALE,
.description = sDeepSeaScaleDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 30,
},
@ -5212,8 +5220,8 @@ const struct Item gItems[] =
.holdEffect = HOLD_EFFECT_DEEP_SEA_TOOTH,
.description = sDeepSeaToothDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 90,
},
@ -5806,8 +5814,8 @@ const struct Item gItems[] =
.holdEffectParam = 20,
.description = sMetalCoatDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 30,
},
@ -6141,8 +6149,8 @@ const struct Item gItems[] =
.holdEffectParam = 10,
.description = sKingsRockDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 30,
},
@ -6503,8 +6511,8 @@ const struct Item gItems[] =
.holdEffect = HOLD_EFFECT_SCOPE_LENS,
.description = sRazorClawDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.type = EVO_HELD_ITEM_TYPE,
.fieldUseFunc = EVO_HELD_ITEM_FIELD_FUNC,
.flingPower = 80,
},

View File

@ -39,7 +39,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_GROWLITHE] = {{EVO_ITEM, ITEM_FIRE_STONE, SPECIES_ARCANINE}},
[SPECIES_POLIWAG] = {{EVO_LEVEL, 25, SPECIES_POLIWHIRL}},
[SPECIES_POLIWHIRL] = {{EVO_ITEM, ITEM_WATER_STONE, SPECIES_POLIWRATH},
{EVO_TRADE_ITEM, ITEM_KINGS_ROCK, SPECIES_POLITOED}},
{EVO_TRADE_ITEM, ITEM_KINGS_ROCK, SPECIES_POLITOED},
{EVO_ITEM, ITEM_KINGS_ROCK, SPECIES_POLITOED}},
[SPECIES_ABRA] = {{EVO_LEVEL, 16, SPECIES_KADABRA}},
[SPECIES_KADABRA] = {{EVO_TRADE, 0, SPECIES_ALAKAZAM},
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_ALAKAZAM}},
@ -54,7 +55,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_GOLEM}},
[SPECIES_PONYTA] = {{EVO_LEVEL, 40, SPECIES_RAPIDASH}},
[SPECIES_SLOWPOKE] = {{EVO_LEVEL, 37, SPECIES_SLOWBRO},
{EVO_TRADE_ITEM, ITEM_KINGS_ROCK, SPECIES_SLOWKING}},
{EVO_TRADE_ITEM, ITEM_KINGS_ROCK, SPECIES_SLOWKING},
{EVO_ITEM, ITEM_KINGS_ROCK, SPECIES_SLOWKING}},
[SPECIES_MAGNEMITE] = {{EVO_LEVEL, 30, SPECIES_MAGNETON}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_MAGNETON] = {{EVO_MAPSEC, MAPSEC_NEW_MAUVILLE, SPECIES_MAGNEZONE},
@ -67,7 +69,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_GASTLY] = {{EVO_LEVEL, 25, SPECIES_HAUNTER}},
[SPECIES_HAUNTER] = {{EVO_TRADE, 0, SPECIES_GENGAR},
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_GENGAR}},
[SPECIES_ONIX] = {{EVO_TRADE_ITEM, ITEM_METAL_COAT, SPECIES_STEELIX}},
[SPECIES_ONIX] = {{EVO_TRADE_ITEM, ITEM_METAL_COAT, SPECIES_STEELIX},
{EVO_ITEM, ITEM_METAL_COAT, SPECIES_STEELIX}},
[SPECIES_DROWZEE] = {{EVO_LEVEL, 26, SPECIES_HYPNO}},
[SPECIES_KRABBY] = {{EVO_LEVEL, 28, SPECIES_KINGLER}},
[SPECIES_VOLTORB] = {{EVO_LEVEL, 30, SPECIES_ELECTRODE}},
@ -81,21 +84,26 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_KOFFING] = {{EVO_LEVEL, 35, SPECIES_WEEZING}},
[SPECIES_RHYHORN] = {{EVO_LEVEL, 42, SPECIES_RHYDON}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_RHYDON] = {{EVO_TRADE_ITEM, ITEM_PROTECTOR, SPECIES_RHYPERIOR}},
[SPECIES_RHYDON] = {{EVO_TRADE_ITEM, ITEM_PROTECTOR, SPECIES_RHYPERIOR},
{EVO_ITEM, ITEM_PROTECTOR, SPECIES_RHYPERIOR}},
#endif
[SPECIES_CHANSEY] = {{EVO_FRIENDSHIP, 0, SPECIES_BLISSEY}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_TANGELA] = {{EVO_MOVE, MOVE_ANCIENT_POWER, SPECIES_TANGROWTH}},
#endif
[SPECIES_HORSEA] = {{EVO_LEVEL, 32, SPECIES_SEADRA}},
[SPECIES_SEADRA] = {{EVO_TRADE_ITEM, ITEM_DRAGON_SCALE, SPECIES_KINGDRA}},
[SPECIES_SEADRA] = {{EVO_TRADE_ITEM, ITEM_DRAGON_SCALE, SPECIES_KINGDRA},
{EVO_ITEM, ITEM_DRAGON_SCALE, SPECIES_KINGDRA}},
[SPECIES_GOLDEEN] = {{EVO_LEVEL, 33, SPECIES_SEAKING}},
[SPECIES_STARYU] = {{EVO_ITEM, ITEM_WATER_STONE, SPECIES_STARMIE}},
[SPECIES_SCYTHER] = {{EVO_TRADE_ITEM, ITEM_METAL_COAT, SPECIES_SCIZOR},
{EVO_ITEM, ITEM_BLACK_AUGURITE, SPECIES_KLEAVOR}},
{EVO_ITEM, ITEM_BLACK_AUGURITE, SPECIES_KLEAVOR},
{EVO_ITEM, ITEM_METAL_COAT, SPECIES_SCIZOR}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_ELECTABUZZ] = {{EVO_TRADE_ITEM, ITEM_ELECTIRIZER, SPECIES_ELECTIVIRE}},
[SPECIES_MAGMAR] = {{EVO_TRADE_ITEM, ITEM_MAGMARIZER, SPECIES_MAGMORTAR}},
[SPECIES_ELECTABUZZ] = {{EVO_TRADE_ITEM, ITEM_ELECTIRIZER, SPECIES_ELECTIVIRE},
{EVO_ITEM, ITEM_ELECTIRIZER, SPECIES_ELECTIVIRE}},
[SPECIES_MAGMAR] = {{EVO_TRADE_ITEM, ITEM_MAGMARIZER, SPECIES_MAGMORTAR},
{EVO_ITEM, ITEM_MAGMARIZER, SPECIES_MAGMORTAR}},
#endif
[SPECIES_MAGIKARP] = {{EVO_LEVEL, 20, SPECIES_GYARADOS}},
[SPECIES_EEVEE] = {{EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_JOLTEON},
@ -113,7 +121,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
{EVO_MOVE_TYPE, TYPE_FAIRY, SPECIES_SYLVEON}
#endif
},
[SPECIES_PORYGON] = {{EVO_TRADE_ITEM, ITEM_UPGRADE, SPECIES_PORYGON2}},
[SPECIES_PORYGON] = {{EVO_TRADE_ITEM, ITEM_UPGRADE, SPECIES_PORYGON2},
{EVO_ITEM, ITEM_UPGRADE, SPECIES_PORYGON2}},
[SPECIES_OMANYTE] = {{EVO_LEVEL, 40, SPECIES_OMASTAR}},
[SPECIES_KABUTO] = {{EVO_LEVEL, 40, SPECIES_KABUTOPS}},
[SPECIES_DRATINI] = {{EVO_LEVEL, 30, SPECIES_DRAGONAIR}},
@ -154,11 +163,13 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
#endif
[SPECIES_PINECO] = {{EVO_LEVEL, 31, SPECIES_FORRETRESS}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_GLIGAR] = {{EVO_ITEM_HOLD_NIGHT, ITEM_RAZOR_FANG, SPECIES_GLISCOR}},
[SPECIES_GLIGAR] = {{EVO_ITEM_HOLD_NIGHT, ITEM_RAZOR_FANG, SPECIES_GLISCOR},
{EVO_ITEM_NIGHT, ITEM_RAZOR_FANG, SPECIES_GLISCOR}},
#endif
[SPECIES_SNUBBULL] = {{EVO_LEVEL, 23, SPECIES_GRANBULL}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_SNEASEL] = {{EVO_ITEM_HOLD_NIGHT, ITEM_RAZOR_CLAW, SPECIES_WEAVILE}},
[SPECIES_SNEASEL] = {{EVO_ITEM_HOLD_NIGHT, ITEM_RAZOR_CLAW, SPECIES_WEAVILE},
{EVO_ITEM_NIGHT, ITEM_RAZOR_CLAW, SPECIES_WEAVILE}},
#endif
[SPECIES_TEDDIURSA] = {{EVO_LEVEL, 30, SPECIES_URSARING}},
[SPECIES_SLUGMA] = {{EVO_LEVEL, 38, SPECIES_MAGCARGO}},
@ -170,7 +181,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_HOUNDOUR] = {{EVO_LEVEL, 24, SPECIES_HOUNDOOM}},
[SPECIES_PHANPY] = {{EVO_LEVEL, 25, SPECIES_DONPHAN}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_PORYGON2] = {{EVO_TRADE_ITEM, ITEM_DUBIOUS_DISC, SPECIES_PORYGON_Z}},
[SPECIES_PORYGON2] = {{EVO_TRADE_ITEM, ITEM_DUBIOUS_DISC, SPECIES_PORYGON_Z},
{EVO_ITEM, ITEM_DUBIOUS_DISC, SPECIES_PORYGON_Z}},
#endif
[SPECIES_TYROGUE] = {{EVO_LEVEL_ATK_LT_DEF, 20, SPECIES_HITMONCHAN},
{EVO_LEVEL_ATK_GT_DEF, 20, SPECIES_HITMONLEE},
@ -211,7 +223,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_BARBOACH] = {{EVO_LEVEL, 30, SPECIES_WHISCASH}},
[SPECIES_CORPHISH] = {{EVO_LEVEL, 30, SPECIES_CRAWDAUNT}},
[SPECIES_FEEBAS] = {{EVO_BEAUTY, 170, SPECIES_MILOTIC},
{EVO_TRADE_ITEM, ITEM_PRISM_SCALE, SPECIES_MILOTIC}},
{EVO_TRADE_ITEM, ITEM_PRISM_SCALE, SPECIES_MILOTIC},
{EVO_ITEM, ITEM_PRISM_SCALE, SPECIES_MILOTIC}},
[SPECIES_CARVANHA] = {{EVO_LEVEL, 30, SPECIES_SHARPEDO}},
[SPECIES_TRAPINCH] = {{EVO_LEVEL, 35, SPECIES_VIBRAVA}},
[SPECIES_VIBRAVA] = {{EVO_LEVEL, 45, SPECIES_FLYGON}},
@ -233,7 +246,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_WYNAUT] = {{EVO_LEVEL, 15, SPECIES_WOBBUFFET}},
[SPECIES_DUSKULL] = {{EVO_LEVEL, 37, SPECIES_DUSCLOPS}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_DUSCLOPS] = {{EVO_TRADE_ITEM, ITEM_REAPER_CLOTH, SPECIES_DUSKNOIR}},
[SPECIES_DUSCLOPS] = {{EVO_TRADE_ITEM, ITEM_REAPER_CLOTH, SPECIES_DUSKNOIR},
{EVO_ITEM, ITEM_REAPER_CLOTH, SPECIES_DUSKNOIR}},
[SPECIES_ROSELIA] = {{EVO_ITEM, ITEM_SHINY_STONE, SPECIES_ROSERADE}},
#endif
[SPECIES_SLAKOTH] = {{EVO_LEVEL, 18, SPECIES_VIGOROTH}},
@ -242,7 +256,9 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_WHISMUR] = {{EVO_LEVEL, 20, SPECIES_LOUDRED}},
[SPECIES_LOUDRED] = {{EVO_LEVEL, 40, SPECIES_EXPLOUD}},
[SPECIES_CLAMPERL] = {{EVO_TRADE_ITEM, ITEM_DEEP_SEA_TOOTH, SPECIES_HUNTAIL},
{EVO_TRADE_ITEM, ITEM_DEEP_SEA_SCALE, SPECIES_GOREBYSS}},
{EVO_TRADE_ITEM, ITEM_DEEP_SEA_SCALE, SPECIES_GOREBYSS},
{EVO_ITEM, ITEM_DEEP_SEA_TOOTH, SPECIES_HUNTAIL},
{EVO_ITEM, ITEM_DEEP_SEA_SCALE, SPECIES_GOREBYSS}},
[SPECIES_SHUPPET] = {{EVO_LEVEL, 37, SPECIES_BANETTE}},
[SPECIES_ARON] = {{EVO_LEVEL, 32, SPECIES_LAIRON}},
[SPECIES_LAIRON] = {{EVO_LEVEL, 42, SPECIES_AGGRON}},
@ -289,7 +305,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_BRONZOR] = {{EVO_LEVEL, 33, SPECIES_BRONZONG}},
[SPECIES_BONSLY] = {{EVO_MOVE, MOVE_MIMIC, SPECIES_SUDOWOODO}},
[SPECIES_MIME_JR] = {{EVO_MOVE, MOVE_MIMIC, SPECIES_MR_MIME}},
[SPECIES_HAPPINY] = {{EVO_ITEM_HOLD_DAY, ITEM_OVAL_STONE, SPECIES_CHANSEY}},
[SPECIES_HAPPINY] = {{EVO_ITEM_HOLD_DAY, ITEM_OVAL_STONE, SPECIES_CHANSEY},
{EVO_ITEM_DAY, ITEM_OVAL_STONE, SPECIES_CHANSEY}},
[SPECIES_GIBLE] = {{EVO_LEVEL, 24, SPECIES_GABITE}},
[SPECIES_GABITE] = {{EVO_LEVEL, 48, SPECIES_GARCHOMP}},
[SPECIES_MUNCHLAX] = {{EVO_FRIENDSHIP, 0, SPECIES_SNORLAX}},
@ -400,8 +417,10 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
{EVO_LEVEL_FEMALE, 25, SPECIES_MEOWSTIC_FEMALE}},
[SPECIES_HONEDGE] = {{EVO_LEVEL, 35, SPECIES_DOUBLADE}},
[SPECIES_DOUBLADE] = {{EVO_ITEM, ITEM_DUSK_STONE, SPECIES_AEGISLASH}},
[SPECIES_SPRITZEE] = {{EVO_TRADE_ITEM, ITEM_SACHET, SPECIES_AROMATISSE}},
[SPECIES_SWIRLIX] = {{EVO_TRADE_ITEM, ITEM_WHIPPED_DREAM, SPECIES_SLURPUFF}},
[SPECIES_SPRITZEE] = {{EVO_TRADE_ITEM, ITEM_SACHET, SPECIES_AROMATISSE},
{EVO_ITEM, ITEM_SACHET, SPECIES_AROMATISSE}},
[SPECIES_SWIRLIX] = {{EVO_TRADE_ITEM, ITEM_WHIPPED_DREAM, SPECIES_SLURPUFF},
{EVO_ITEM, ITEM_WHIPPED_DREAM, SPECIES_SLURPUFF}},
[SPECIES_INKAY] = {{EVO_LEVEL, 30, SPECIES_MALAMAR}},
[SPECIES_BINACLE] = {{EVO_LEVEL, 39, SPECIES_BARBARACLE}},
[SPECIES_SKRELP] = {{EVO_LEVEL, 48, SPECIES_DRAGALGE}},
@ -565,5 +584,7 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
#if P_GEN_8_POKEMON == TRUE
[SPECIES_SINISTEA_ANTIQUE] = {{EVO_ITEM, ITEM_CHIPPED_POT, SPECIES_POLTEAGEIST_ANTIQUE}},
[SPECIES_URSARING] = {{EVO_ITEM_NIGHT, ITEM_PEAT_BLOCK, SPECIES_URSALUNA}},
[SPECIES_SNEASEL_HISUIAN] = {{EVO_ITEM_DAY, ITEM_RAZOR_CLAW, SPECIES_SNEASLER},
{EVO_ITEM_HOLD_DAY, ITEM_RAZOR_CLAW, SPECIES_SNEASLER}},
#endif
};

View File

@ -112,6 +112,8 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
[SPECIES_BURMY] = sBurmyFormChangeTable,
[SPECIES_BURMY_SANDY_CLOAK] = sBurmyFormChangeTable,
[SPECIES_BURMY_TRASH_CLOAK] = sBurmyFormChangeTable,
[SPECIES_CHERRIM] = sCherrimFormChangeTable,
[SPECIES_CHERRIM_SUNSHINE] = sCherrimFormChangeTable,
[SPECIES_LOPUNNY] = sLopunnyFormChangeTable,
[SPECIES_LOPUNNY_MEGA] = sLopunnyFormChangeTable,
[SPECIES_GARCHOMP] = sGarchompFormChangeTable,

View File

@ -160,11 +160,19 @@ static const struct FormChange sAbsolFormChangeTable[] = {
};
static const struct FormChange sCastformFormChangeTable[] = {
#if B_WEATHER_FORMS >= GEN_5
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_SUNNY, B_WEATHER_SUN, ABILITY_FORECAST},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_RAINY, B_WEATHER_RAIN, ABILITY_FORECAST},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_SNOWY, B_WEATHER_HAIL | B_WEATHER_SNOW, ABILITY_FORECAST},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM, ~(B_WEATHER_SUN | B_WEATHER_RAIN | B_WEATHER_HAIL | B_WEATHER_SNOW), ABILITY_FORECAST},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM, B_WEATHER_NONE, ABILITY_FORECAST},
#else
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_SUNNY, B_WEATHER_SUN},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_RAINY, B_WEATHER_RAIN},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_SNOWY, B_WEATHER_HAIL},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM, ~(B_WEATHER_SUN | B_WEATHER_RAIN | B_WEATHER_HAIL)},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_SNOWY, B_WEATHER_HAIL | B_WEATHER_SNOW},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM, ~(B_WEATHER_SUN | B_WEATHER_RAIN | B_WEATHER_HAIL | B_WEATHER_SNOW)},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM, B_WEATHER_NONE},
#endif
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_CASTFORM},
{FORM_CHANGE_FAINT, SPECIES_CASTFORM},
{FORM_CHANGE_END_BATTLE, SPECIES_CASTFORM},
@ -235,9 +243,15 @@ static const struct FormChange sBurmyFormChangeTable[] = {
};
static const struct FormChange sCherrimFormChangeTable[] = {
#if B_WEATHER_FORMS >= GEN_5
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM_SUNSHINE, B_WEATHER_SUN, ABILITY_FLOWER_GIFT},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM, ~B_WEATHER_SUN, ABILITY_FLOWER_GIFT},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM, B_WEATHER_NONE, ABILITY_FLOWER_GIFT},
#else
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM_SUNSHINE, B_WEATHER_SUN},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM, ~B_WEATHER_SUN},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM, B_WEATHER_NONE},
#endif
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_CHERRIM},
{FORM_CHANGE_FAINT, SPECIES_CHERRIM},
{FORM_CHANGE_END_BATTLE, SPECIES_CHERRIM},

View File

@ -550,6 +550,22 @@ const u8 *const gItemEffectTable[ITEMS_COUNT] =
[ITEM_CHIPPED_POT] = gItemEffect_EvoItem,
[ITEM_GALARICA_CUFF] = gItemEffect_EvoItem,
[ITEM_GALARICA_WREATH] = gItemEffect_EvoItem,
[ITEM_DRAGON_SCALE] = gItemEffect_EvoItem,
[ITEM_UPGRADE] = gItemEffect_EvoItem,
[ITEM_PROTECTOR] = gItemEffect_EvoItem,
[ITEM_ELECTIRIZER] = gItemEffect_EvoItem,
[ITEM_MAGMARIZER] = gItemEffect_EvoItem,
[ITEM_DUBIOUS_DISC] = gItemEffect_EvoItem,
[ITEM_REAPER_CLOTH] = gItemEffect_EvoItem,
[ITEM_PRISM_SCALE] = gItemEffect_EvoItem,
[ITEM_WHIPPED_DREAM] = gItemEffect_EvoItem,
[ITEM_SACHET] = gItemEffect_EvoItem,
[ITEM_OVAL_STONE] = gItemEffect_EvoItem,
[ITEM_DEEP_SEA_SCALE] = gItemEffect_EvoItem,
[ITEM_DEEP_SEA_TOOTH] = gItemEffect_EvoItem,
[ITEM_METAL_COAT] = gItemEffect_EvoItem,
[ITEM_KINGS_ROCK] = gItemEffect_EvoItem,
[ITEM_RAZOR_CLAW] = gItemEffect_EvoItem,
[ITEM_AUSPICIOUS_ARMOR] = gItemEffect_EvoItem,
[ITEM_MALICIOUS_ARMOR] = gItemEffect_EvoItem,
[ITEM_SCROLL_OF_DARKNESS] = gItemEffect_EvoItem,

View File

@ -2649,8 +2649,8 @@ static const u8 sProtectivePadsDesc[] = _(
static const u8 sThroatSprayDesc[] = _(
"Raises Sp. Atk. if\n"
"a Pokémon is hit by\n"
"a sound-based move.");
"the holder uses a\n"
"sound-based move.");
static const u8 sEjectPackDesc[] = _(
"Forces the user to\n"

View File

@ -57,6 +57,7 @@
#include "constants/songs.h"
#include "constants/species.h"
#include "constants/weather.h"
#include "save.h"
#if DEBUG_OVERWORLD_MENU == TRUE
// *******************************
@ -292,6 +293,7 @@ extern u8 Debug_ShowFieldMessageStringVar4[];
extern u8 Debug_CheatStart[];
extern u8 PlayersHouse_2F_EventScript_SetWallClock[];
extern u8 PlayersHouse_2F_EventScript_CheckWallClock[];
extern u8 Debug_CheckSaveBlock[];
#include "data/map_group_count.h"
@ -1165,18 +1167,35 @@ static void DebugAction_Util_PoisonMons(u8 taskId)
PlaySE(SE_FIELD_POISON);
}
void CheckSaveBlock1Size(void)
{
u32 currSb1Size = sizeof(struct SaveBlock1);
u32 maxSb1Size = SECTOR_DATA_SIZE * (SECTOR_ID_SAVEBLOCK1_END - SECTOR_ID_SAVEBLOCK1_START + 1);
ConvertIntToDecimalStringN(gStringVar1, currSb1Size, STR_CONV_MODE_LEFT_ALIGN, 6);
ConvertIntToDecimalStringN(gStringVar2, maxSb1Size, STR_CONV_MODE_LEFT_ALIGN, 6);
}
void CheckSaveBlock2Size(void)
{
u32 currSb2Size = (sizeof(struct SaveBlock2));
u32 maxSb2Size = SECTOR_DATA_SIZE;
ConvertIntToDecimalStringN(gStringVar1, currSb2Size, STR_CONV_MODE_LEFT_ALIGN, 6);
ConvertIntToDecimalStringN(gStringVar2, maxSb2Size, STR_CONV_MODE_LEFT_ALIGN, 6);
}
void CheckPokemonStorageSize(void)
{
u32 currPkmnStorageSize = sizeof(struct PokemonStorage);
u32 maxPkmnStorageSize = SECTOR_DATA_SIZE * (SECTOR_ID_PKMN_STORAGE_END - SECTOR_ID_PKMN_STORAGE_START + 1);
ConvertIntToDecimalStringN(gStringVar1, currPkmnStorageSize, STR_CONV_MODE_LEFT_ALIGN, 6);
ConvertIntToDecimalStringN(gStringVar2, maxPkmnStorageSize, STR_CONV_MODE_LEFT_ALIGN, 6);
}
static void DebugAction_Util_CheckSaveBlock(u8 taskId)
{
static const u8 sDebugText_SaveBlockSize[] = _("SaveBlock1 is {STR_VAR_1} bytes long.\nMax size is 15872 bytes.\pSaveBlock2 is {STR_VAR_2} bytes long.\nMax size is 3968 bytes.\pPokemonStorage is {STR_VAR_3} bytes long.\nMax size is 35712 bytes.");
ConvertIntToDecimalStringN(gStringVar1, sizeof(struct SaveBlock1), STR_CONV_MODE_LEFT_ALIGN, 6);
ConvertIntToDecimalStringN(gStringVar2, sizeof(struct SaveBlock2), STR_CONV_MODE_LEFT_ALIGN, 6);
ConvertIntToDecimalStringN(gStringVar3, sizeof(struct PokemonStorage), STR_CONV_MODE_LEFT_ALIGN, 6);
StringExpandPlaceholders(gStringVar4, sDebugText_SaveBlockSize);
Debug_DestroyMenu_Full(taskId);
LockPlayerFieldControls();
ScriptContext_SetupScript(Debug_ShowFieldMessageStringVar4);
ScriptContext_SetupScript(Debug_CheckSaveBlock);
}
static const u8 sWeatherNames[22][24] = {
@ -2758,7 +2777,7 @@ static void DebugAction_Give_Pokemon_ComplexCreateMon(u8 taskId) //https://githu
static void DebugAction_Give_MaxMoney(u8 taskId)
{
SetMoney(&gSaveBlock1Ptr->money, 999999);
SetMoney(&gSaveBlock1Ptr->money, MAX_MONEY);
}
static void DebugAction_Give_MaxCoins(u8 taskId)

View File

@ -10,8 +10,6 @@
#include "strings.h"
#include "decompress.h"
#define MAX_MONEY 999999
EWRAM_DATA static u8 sMoneyBoxWindowId = 0;
EWRAM_DATA static u8 sMoneyLabelSpriteId = 0;

View File

@ -6633,6 +6633,14 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s
}
}
break;
case EVO_ITEM_HOLD:
if (heldItem == gEvolutionTable[species][i].param)
{
heldItem = 0;
SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem);
targetSpecies = gEvolutionTable[species][i].targetSpecies;
}
break;
}
}
break;
@ -6682,6 +6690,11 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 mode, u16 evolutionItem, s
if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && gEvolutionTable[species][i].param == evolutionItem)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_ITEM_DAY:
RtcCalcLocalTime();
if (gLocalTime.hours >= 12 && gLocalTime.hours < 24 && gEvolutionTable[species][i].param == evolutionItem)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
}
}
break;

File diff suppressed because it is too large Load Diff

123
test/ability_flower_gift.c Normal file
View File

@ -0,0 +1,123 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim in harsh sunlight")
{
GIVEN {
PLAYER(SPECIES_CHERRIM) { Ability(ABILITY_FLOWER_GIFT); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SUNNY_DAY); }
} SCENE {
ABILITY_POPUP(player, ABILITY_FLOWER_GIFT);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Cherrim transformed!");
}
}
SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim back to normal when weather changes")
{
GIVEN {
PLAYER(SPECIES_CHERRIM) { Ability(ABILITY_FLOWER_GIFT); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SUNNY_DAY); }
TURN { MOVE(opponent, MOVE_RAIN_DANCE); }
} SCENE {
// transforms in sun
ABILITY_POPUP(player, ABILITY_FLOWER_GIFT);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Cherrim transformed!");
// back to normal
ABILITY_POPUP(player, ABILITY_FLOWER_GIFT);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Cherrim transformed!");
}
}
SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim back to normal when its ability is suppressed")
{
GIVEN {
ASSUME(B_WEATHER_FORMS >= GEN_5);
PLAYER(SPECIES_CHERRIM) { Ability(ABILITY_FLOWER_GIFT); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SUNNY_DAY); }
TURN { MOVE(opponent, MOVE_GASTRO_ACID); }
} SCENE {
// transforms in sun
ABILITY_POPUP(player, ABILITY_FLOWER_GIFT);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Cherrim transformed!");
// back to normal
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Cherrim transformed!");
}
}
DOUBLE_BATTLE_TEST("Flower Gift increases the attack of Cherrim and its allies by 1.5x", s16 damageL, s16 damageR)
{
bool32 sunny;
PARAMETRIZE { sunny = FALSE; }
PARAMETRIZE { sunny = TRUE; }
GIVEN {
PLAYER(SPECIES_CHERRIM) { Ability(ABILITY_FLOWER_GIFT); };
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (sunny)
TURN { MOVE(playerLeft, MOVE_SUNNY_DAY); }
TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft);
MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); }
} SCENE {
// sun activates
if (sunny) {
ABILITY_POPUP(playerLeft, ABILITY_FLOWER_GIFT);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, playerLeft);
MESSAGE("Cherrim transformed!");
}
// player uses Tackle
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft);
HP_BAR(opponentLeft, captureDamage: &results[i].damageL);
// partner uses Tackle
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
HP_BAR(opponentLeft, captureDamage: &results[i].damageR);
} FINALLY {
EXPECT_MUL_EQ(results[0].damageL, UQ_4_12(1.5), results[1].damageL);
EXPECT_MUL_EQ(results[0].damageR, UQ_4_12(1.5), results[1].damageR);
}
}
DOUBLE_BATTLE_TEST("Flower Gift increases the Sp. Def of Cherrim and its allies by 1.5x", s16 damageL, s16 damageR)
{
bool32 sunny;
PARAMETRIZE { sunny = FALSE; }
PARAMETRIZE { sunny = TRUE; }
GIVEN {
PLAYER(SPECIES_CHERRIM) { Ability(ABILITY_FLOWER_GIFT); };
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (sunny)
TURN { MOVE(playerLeft, MOVE_SUNNY_DAY); }
TURN { MOVE(opponentLeft, MOVE_HYPER_VOICE, target: playerLeft); }
} SCENE {
// sun activates
if (sunny) {
ABILITY_POPUP(playerLeft, ABILITY_FLOWER_GIFT);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, playerLeft);
MESSAGE("Cherrim transformed!");
}
// opponentLeft uses Hyper Voice
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, opponentLeft);
HP_BAR(playerLeft, captureDamage: &results[i].damageL);
HP_BAR(playerRight, captureDamage: &results[i].damageR);
} FINALLY {
EXPECT_MUL_EQ(results[1].damageL, UQ_4_12(1.5), results[0].damageL);
EXPECT_MUL_EQ(results[1].damageR, UQ_4_12(1.5), results[0].damageR);
}
}
TO_DO_BATTLE_TEST("Flower Gift does not transform Cherrim back to normal when suppressed if Cherrim is Dynamaxed");

255
test/ability_forecast.c Normal file
View File

@ -0,0 +1,255 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Forecast transforms Castform in weather from an opponent's move")
{
u32 move;
PARAMETRIZE { move = MOVE_SUNNY_DAY; }
PARAMETRIZE { move = MOVE_RAIN_DANCE; }
PARAMETRIZE { move = MOVE_HAIL; }
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, move); }
} SCENE {
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform in weather from its own move")
{
u32 move;
PARAMETRIZE { move = MOVE_SUNNY_DAY; }
PARAMETRIZE { move = MOVE_RAIN_DANCE; }
PARAMETRIZE { move = MOVE_HAIL; }
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
DOUBLE_BATTLE_TEST("Forecast transforms Castform in weather from a partner's move")
{
u32 move;
PARAMETRIZE { move = MOVE_SUNNY_DAY; }
PARAMETRIZE { move = MOVE_RAIN_DANCE; }
PARAMETRIZE { move = MOVE_HAIL; }
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(playerRight, move); }
} SCENE {
ABILITY_POPUP(playerLeft, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, playerLeft);
MESSAGE("Castform transformed!");
}
}
DOUBLE_BATTLE_TEST("Forecast transforms all Castforms present in weather")
{
u32 move;
PARAMETRIZE { move = MOVE_SUNNY_DAY; }
PARAMETRIZE { move = MOVE_RAIN_DANCE; }
PARAMETRIZE { move = MOVE_HAIL; }
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
} WHEN {
TURN { MOVE(playerRight, move); }
} SCENE {
ABILITY_POPUP(playerLeft, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, playerLeft);
MESSAGE("Castform transformed!");
ABILITY_POPUP(opponentLeft, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, opponentLeft);
MESSAGE("Foe Castform transformed!");
ABILITY_POPUP(playerRight, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, playerRight);
MESSAGE("Castform transformed!");
ABILITY_POPUP(opponentRight, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, opponentRight);
MESSAGE("Foe Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform in weather from an ability")
{
u32 species, ability;
PARAMETRIZE { species = SPECIES_KYOGRE; ability = ABILITY_DRIZZLE; }
PARAMETRIZE { species = SPECIES_GROUDON; ability = ABILITY_DROUGHT; }
PARAMETRIZE { species = SPECIES_ABOMASNOW; ability = ABILITY_SNOW_WARNING; }
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); };
} WHEN {
TURN { SWITCH(opponent, 1); }
} SCENE {
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform in primal weather")
{
u32 species, item, ability;
PARAMETRIZE { species = SPECIES_KYOGRE; ability = ABILITY_PRIMORDIAL_SEA; item = ITEM_BLUE_ORB; }
PARAMETRIZE { species = SPECIES_GROUDON; ability = ABILITY_DESOLATE_LAND; item = ITEM_RED_ORB; }
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(species) { Item(item); };
} WHEN {
TURN { SWITCH(opponent, 1); }
} SCENE {
ABILITY_POPUP(opponent, ability);
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal when weather expires")
{
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_RAIN_DANCE); }
TURN { }
TURN { }
TURN { }
TURN { }
TURN { }
} SCENE {
// transforms
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
// back to normal
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal when Sandstorm is active")
{
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_RAIN_DANCE); }
TURN { MOVE(player, MOVE_SANDSTORM); }
} SCENE {
// transforms
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
// back to normal
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal under Air Lock")
{
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_RAYQUAZA);
} WHEN {
TURN { MOVE(player, MOVE_RAIN_DANCE); }
TURN { SWITCH(opponent, 1); }
TURN { MOVE(opponent, MOVE_CELEBRATE, megaEvolve: TRUE); }
} SCENE {
// transforms
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
// back to normal
ABILITY_POPUP(opponent, ABILITY_AIR_LOCK);
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform on switch-in")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_RAIN_DANCE); }
TURN { SWITCH(player, 1); }
} SCENE {
// turn 1
ANIMATION(ANIM_TYPE_MOVE, MOVE_RAIN_DANCE, player);
// turn 2
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform when weather changes")
{
GIVEN {
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_RAIN_DANCE); }
TURN { MOVE(player, MOVE_SUNNY_DAY); }
} SCENE {
// transforms
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
// transforms again
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}
SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal when its ability is suppressed")
{
GIVEN {
ASSUME(B_WEATHER_FORMS >= GEN_5);
PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SUNNY_DAY); }
TURN { MOVE(opponent, MOVE_GASTRO_ACID); }
} SCENE {
// transforms in sun
ABILITY_POPUP(player, ABILITY_FORECAST);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
// back to normal
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Castform transformed!");
}
}