merge with be

This commit is contained in:
ghoulslash 2021-10-13 18:30:53 -04:00
commit a3d2bdc9cf
33 changed files with 1511 additions and 653 deletions

View File

@ -1826,6 +1826,10 @@
various BS_ATTACKER, VARIOUS_REMOVE_TERRAIN
.endm
.macro trytoclearprimalweather
various BS_ATTACKER, VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER
.endm
@ helpful macros
.macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7

View File

@ -823,6 +823,7 @@ gBattleAnims_General::
.4byte General_RestoreBg @ B_ANIM_RESTORE_BG
.4byte General_TotemFlare @ B_ANIM_TOTEM_FLARE
.4byte General_GulpMissile @ B_ANIM_GULP_MISSILE
.4byte General_StrongWinds @ B_ANIM_STRONG_WINDS
.align 2
gBattleAnims_Special::
@ -24412,6 +24413,17 @@ General_GulpMissile: @ Tackle anim (placeholder)
blendoff
end
General_StrongWinds::
loadspritegfx ANIM_TAG_FLYING_DIRT
playsewithpan SE_M_GUST, 0
createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_FLYING_DIRT, 0, 12, 12, RGB(20, 20, 20)
waitforvisualfinish
createvisualtask AnimTask_LoadWindstormBackground, 5, FALSE
delay 32
waitforvisualfinish
stopsound
end
RainbowEndureEffect:
launchtemplate gBlueEndureEnergySpriteTemplate 0x2 0x4 0x0 0xffe8 0x1a 0x2
delay 0x3

View File

@ -675,6 +675,9 @@ BattleScript_MoveEffectCoreEnforcer::
setgastroacid BattleScript_CoreEnforcerRet
printstring STRINGID_PKMNSABILITYSUPPRESSED
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
BattleScript_CoreEnforcerRet:
return
@ -767,6 +770,9 @@ BattleScript_EffectPartingShotSwitch:
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
@ -1771,6 +1777,9 @@ BattleScript_EffectSimpleBeam:
waitanimation
printstring STRINGID_PKMNACQUIREDSIMPLE
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
goto BattleScript_MoveEnd
BattleScript_EffectSuckerPunch:
@ -1819,6 +1828,9 @@ BattleScript_EffectHealingWish:
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
@ -1856,6 +1868,9 @@ BattleScript_EffectWorrySeed:
waitanimation
printstring STRINGID_PKMNACQUIREDABILITY
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
goto BattleScript_MoveEnd
BattleScript_EffectPowerSplit:
@ -1984,6 +1999,9 @@ BattleScript_EffectGastroAcid:
waitanimation
printstring STRINGID_PKMNSABILITYSUPPRESSED
waitmessage B_WAIT_TIME_LONG
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
goto BattleScript_MoveEnd
BattleScript_EffectToxicSpikes:
@ -2178,6 +2196,9 @@ BattleScript_EffectHitEscape:
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
@ -3116,6 +3137,9 @@ BattleScript_EffectTransform::
attackcanceler
attackstring
ppreduce
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
transformdataexecution
attackanimation
waitanimation
@ -3907,6 +3931,7 @@ BattleScript_PerishSongLoopIncrement::
goto BattleScript_MoveEnd
BattleScript_PerishSongBlocked::
copybyte sBATTLER, gBattlerTarget
printstring STRINGID_PKMNSXBLOCKSY2
waitmessage B_WAIT_TIME_LONG
goto BattleScript_PerishSongLoopIncrement
@ -3920,6 +3945,9 @@ BattleScript_EffectSandstorm::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
setsandstorm
goto BattleScript_MoveWeatherChange
@ -4053,6 +4081,9 @@ BattleScript_EffectBatonPass::
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
switchinanim BS_ATTACKER, TRUE
waitstate
@ -4122,6 +4153,9 @@ BattleScript_EffectRainDance::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
setrain
BattleScript_MoveWeatherChange::
attackanimation
@ -4135,9 +4169,80 @@ BattleScript_EffectSunnyDay::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
setsunny
goto BattleScript_MoveWeatherChange
BattleScript_ExtremelyHarshSunlightWasNotLessened:
pause B_WAIT_TIME_SHORT
printstring STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_ExtremelyHarshSunlightWasNotLessenedEnd3:
pause B_WAIT_TIME_SHORT
printstring STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_ExtremelyHarshSunlightWasNotLessenedRet:
pause B_WAIT_TIME_SHORT
printstring STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED
waitmessage B_WAIT_TIME_LONG
return
BattleScript_NoReliefFromHeavyRain:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NORELIEFROMHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_NoReliefFromHeavyRainEnd3:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NORELIEFROMHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_NoReliefFromHeavyRainRet:
pause B_WAIT_TIME_SHORT
printstring STRINGID_NORELIEFROMHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
return
BattleScript_MysteriousAirCurrentBlowsOn:
pause B_WAIT_TIME_SHORT
printstring STRINGID_MYSTERIOUSAIRCURRENTBLOWSON
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_MysteriousAirCurrentBlowsOnEnd3:
pause B_WAIT_TIME_SHORT
printstring STRINGID_MYSTERIOUSAIRCURRENTBLOWSON
waitmessage B_WAIT_TIME_LONG
end3
BattleScript_MysteriousAirCurrentBlowsOnRet:
pause B_WAIT_TIME_SHORT
printstring STRINGID_MYSTERIOUSAIRCURRENTBLOWSON
waitmessage B_WAIT_TIME_LONG
return
BattleScript_BlockedByPrimalWeatherEnd3::
call BattleScript_AbilityPopUp
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessenedEnd3
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRainEnd3
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOnEnd3
end3
BattleScript_BlockedByPrimalWeatherRet::
call BattleScript_AbilityPopUp
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessenedRet
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRainRet
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOnRet
return
BattleScript_EffectDefenseUpHit::
setmoveeffect MOVE_EFFECT_DEF_PLUS_1 | MOVE_EFFECT_AFFECTS_USER
goto BattleScript_EffectHit
@ -4495,6 +4600,9 @@ BattleScript_EffectHail::
attackcanceler
attackstring
ppreduce
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_SUN_PRIMAL, BattleScript_ExtremelyHarshSunlightWasNotLessened
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_RAIN_PRIMAL, BattleScript_NoReliefFromHeavyRain
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
sethail
goto BattleScript_MoveWeatherChange
@ -5261,6 +5369,9 @@ BattleScript_FaintedMonTryChooseAnother:
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
hidepartystatussummary BS_ATTACKER
switchinanim BS_ATTACKER, 0
@ -5271,6 +5382,9 @@ BattleScript_FaintedMonChooseAnother:
getswitchedmondata BS_FAINTED
switchindataupdate BS_FAINTED
hpthresholds BS_FAINTED
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
hidepartystatussummary BS_FAINTED
switchinanim BS_FAINTED, FALSE
@ -5303,6 +5417,9 @@ BattleScript_HandleFaintedMonLoop::
getswitchedmondata BS_FAINTED
switchindataupdate BS_FAINTED
hpthresholds BS_FAINTED
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
hidepartystatussummary BS_FAINTED
switchinanim BS_FAINTED, FALSE
@ -5505,6 +5622,9 @@ BattleScript_DoSwitchOut::
getswitchedmondata BS_ATTACKER
switchindataupdate BS_ATTACKER
hpthresholds BS_ATTACKER
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring STRINGID_SWITCHINMON
hidepartystatussummary BS_ATTACKER
switchinanim BS_ATTACKER, FALSE
@ -5806,6 +5926,9 @@ BattleScript_RoarSuccessSwitch::
call BattleScript_RoarSuccessRet
getswitchedmondata BS_TARGET
switchindataupdate BS_TARGET
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
switchinanim BS_TARGET, FALSE
waitstate
printstring STRINGID_PKMNWASDRAGGEDOUT
@ -6708,7 +6831,7 @@ BattleScript_PowderMoveNoEffect::
pause B_WAIT_TIME_SHORT
jumpiftype BS_TARGET, TYPE_GRASS, BattleScript_PowderMoveNoEffectPrint
jumpifability BS_TARGET, ABILITY_OVERCOAT, BattleScript_PowderMoveNoEffectOvercoat
printstring STRINGID_SAFETYGOOGLESPROTECTED
printstring STRINGID_SAFETYGOGGLESPROTECTED
goto BattleScript_PowderMoveNoEffectWaitMsg
BattleScript_PowderMoveNoEffectOvercoat:
call BattleScript_AbilityPopUp
@ -7251,6 +7374,56 @@ BattleScript_DroughtActivates::
call BattleScript_WeatherFormChanges
end3
BattleScript_DesolateLandActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_EXTREMELYHARSHSUNLIGHT
waitstate
playanimation BS_BATTLER_0, B_ANIM_SUN_CONTINUES, NULL
call BattleScript_WeatherFormChanges
end3
BattleScript_DesolateLandEvaporatesWaterTypeMoves::
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
pause B_WAIT_TIME_SHORT
ppreduce
printstring STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_PrimordialSeaActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_HEAVYRAIN
waitstate
playanimation BS_BATTLER_0, B_ANIM_RAIN_CONTINUES, NULL
call BattleScript_WeatherFormChanges
end3
BattleScript_PrimordialSeaFizzlesOutFireTypeMoves::
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
pause B_WAIT_TIME_SHORT
ppreduce
printstring STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_DeltaStreamActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
printstring STRINGID_MYSTERIOUSAIRCURRENT
waitstate
playanimation BS_ATTACKER, B_ANIM_STRONG_WINDS, NULL
end3
BattleScript_AttackWeakenedByStrongWinds::
pause B_WAIT_TIME_SHORT
printstring STRINGID_ATTACKWEAKENEDBSTRONGWINDS
waitmessage B_WAIT_TIME_LONG
return
BattleScript_SnowWarningActivates::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUp
@ -8075,22 +8248,22 @@ BattleScript_HangedOnMsgRet:
return
BattleScript_BerryConfuseHealEnd2::
jumpifability BS_ATTACKER, ABILITY_RIPEN, BattleScript_BerryConfuseHealEnd2_AbilityPopup
jumpifability BS_SCRIPTING, 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
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, NULL
printstring STRINGID_PKMNSITEMRESTOREDHEALTH
waitmessage B_WAIT_TIME_LONG
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
healthbarupdate BS_SCRIPTING
datahpupdate BS_SCRIPTING
printstring STRINGID_FORXCOMMAYZ
waitmessage B_WAIT_TIME_LONG
setmoveeffect MOVE_EFFECT_CONFUSION | MOVE_EFFECT_AFFECTS_USER
seteffectprimary
removeitem BS_ATTACKER
removeitem BS_SCRIPTING
end2
BattleScript_BerryConfuseHealRet::
@ -8107,9 +8280,9 @@ BattleScript_BerryConfuseHealRet_Anim:
datahpupdate BS_SCRIPTING
printstring STRINGID_FORXCOMMAYZ
waitmessage B_WAIT_TIME_LONG
setmoveeffect MOVE_EFFECT_CONFUSION | MOVE_EFFECT_AFFECTS_USER
setmoveeffect MOVE_EFFECT_CONFUSION | MOVE_EFFECT_CERTAIN
seteffectprimary
removeitem BS_SCRIPTING
removeitem BS_TARGET
return
BattleScript_BerryStatRaiseEnd2::
@ -8433,6 +8606,9 @@ BattleScript_EjectButtonActivates::
getswitchedmondata BS_SCRIPTING
switchindataupdate BS_SCRIPTING
hpthresholds BS_SCRIPTING
trytoclearprimalweather
printstring STRINGID_EMPTYSTRING3
waitmessage 1
printstring 0x3
switchinanim BS_SCRIPTING 0x1
waitstate

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
1 177 91
143 129 149
103 91 111
79 65 85
59 31 81
103 89 109
231 239 245
249 253 255
0 0 0
0 0 0
107 115 115
74 66 82
0 0 0
214 214 206
132 140 140
0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

View File

@ -37,6 +37,7 @@
#define B_ACTION_CANCEL_PARTNER 12 // when choosing an action
#define B_ACTION_NOTHING_FAINTED 13 // when choosing an action
#define B_ACTION_DEBUG 20
#define B_ACTION_THROW_BALL 21 // R to throw last used ball
#define B_ACTION_NONE 0xFF
#define MAX_TRAINER_ITEMS 4
@ -602,6 +603,7 @@ struct BattleStruct
u8 quickClawBattlerId;
struct StolenItem itemStolen[PARTY_SIZE]; // Player's team that had items stolen (two bytes per party member)
u8 blunderPolicy:1; // should blunder policy activate
u8 ballSpriteIds[2]; // item gfx, window gfx
};
#define GET_MOVE_TYPE(move, typeArg) \
@ -906,5 +908,6 @@ extern u8 gNumberOfMovesToChoose;
extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
extern bool8 gHasFetchedBall;
extern u8 gLastUsedBall;
extern u16 gLastThrownBall;
#endif // GUARD_BATTLE_H

View File

@ -93,5 +93,9 @@ u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale);
u8 GetHPBarLevel(s16 hp, s16 maxhp);
void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle);
void DestroyAbilityPopUp(u8 battlerId);
bool32 CanThrowLastUsedBall(void);
void TryHideLastUsedBall(void);
void TryRestoreLastUsedBall(void);
void TryAddLastUsedBallItemSprites(void);
#endif // GUARD_BATTLE_INTERFACE_H

View File

@ -390,5 +390,14 @@ extern const u8 BattleScript_DarkTypePreventsPrankster[];
extern const u8 BattleScript_GulpMissileGorging[];
extern const u8 BattleScript_GulpMissileGulping[];
extern const u8 BattleScript_BattleBondActivatesOnMoveEndAttacker[];
extern const u8 BattleScript_DesolateLandActivates[];
extern const u8 BattleScript_DesolateLandEvaporatesWaterTypeMoves[];
extern const u8 BattleScript_PrimordialSeaActivates[];
extern const u8 BattleScript_PrimordialSeaFizzlesOutFireTypeMoves[];
extern const u8 BattleScript_DeltaStreamActivates[];
extern const u8 BattleScript_MysteriousAirCurrentBlowsOn[];
extern const u8 BattleScript_AttackWeakenedByStrongWinds[];
extern const u8 BattleScript_BlockedByPrimalWeatherEnd3[];
extern const u8 BattleScript_BlockedByPrimalWeatherRet[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -48,6 +48,7 @@ struct TypePower
extern const struct TypePower gNaturalGiftTable[];
void HandleAction_ThrowBall(void);
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move);
void HandleAction_UseMove(void);
void HandleAction_Switch(void);

View File

@ -257,24 +257,31 @@
#define WEATHER_RAIN_TEMPORARY (1 << 0)
#define WEATHER_RAIN_DOWNPOUR (1 << 1) // unused
#define WEATHER_RAIN_PERMANENT (1 << 2)
#define WEATHER_RAIN_ANY (WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_DOWNPOUR | WEATHER_RAIN_PERMANENT)
#define WEATHER_SANDSTORM_TEMPORARY (1 << 3)
#define WEATHER_SANDSTORM_PERMANENT (1 << 4)
#define WEATHER_RAIN_PRIMAL (1 << 3)
#define WEATHER_RAIN_ANY (WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_DOWNPOUR | WEATHER_RAIN_PERMANENT | WEATHER_RAIN_PRIMAL)
#define WEATHER_SANDSTORM_TEMPORARY (1 << 4)
#define WEATHER_SANDSTORM_PERMANENT (1 << 5)
#define WEATHER_SANDSTORM_ANY (WEATHER_SANDSTORM_TEMPORARY | WEATHER_SANDSTORM_PERMANENT)
#define WEATHER_SUN_TEMPORARY (1 << 5)
#define WEATHER_SUN_PERMANENT (1 << 6)
#define WEATHER_SUN_ANY (WEATHER_SUN_TEMPORARY | WEATHER_SUN_PERMANENT)
#define WEATHER_HAIL_TEMPORARY (1 << 7)
#define WEATHER_HAIL_PERMANENT (1 << 8)
#define WEATHER_SUN_TEMPORARY (1 << 6)
#define WEATHER_SUN_PERMANENT (1 << 7)
#define WEATHER_SUN_PRIMAL (1 << 8)
#define WEATHER_SUN_ANY (WEATHER_SUN_TEMPORARY | WEATHER_SUN_PERMANENT | WEATHER_SUN_PRIMAL)
#define WEATHER_HAIL_TEMPORARY (1 << 9)
#define WEATHER_HAIL_PERMANENT (1 << 10)
#define WEATHER_HAIL_ANY (WEATHER_HAIL_TEMPORARY | WEATHER_HAIL_PERMANENT)
#define WEATHER_ANY (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY)
#define WEATHER_STRONG_WINDS (1 << 11)
#define WEATHER_ANY (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY | WEATHER_STRONG_WINDS)
#define WEATHER_PRIMAL_ANY (WEATHER_RAIN_PRIMAL | WEATHER_SUN_PRIMAL | WEATHER_STRONG_WINDS)
// Battle Weather as enum
#define ENUM_WEATHER_NONE 0
#define ENUM_WEATHER_RAIN 1
#define ENUM_WEATHER_SUN 2
#define ENUM_WEATHER_SANDSTORM 3
#define ENUM_WEATHER_HAIL 4
#define ENUM_WEATHER_NONE 0
#define ENUM_WEATHER_RAIN 1
#define ENUM_WEATHER_SUN 2
#define ENUM_WEATHER_SANDSTORM 3
#define ENUM_WEATHER_HAIL 4
#define ENUM_WEATHER_SUN_PRIMAL 5
#define ENUM_WEATHER_RAIN_PRIMAL 6
#define ENUM_WEATHER_STRONG_WINDS 7
// Move Effects
#define MOVE_EFFECT_SLEEP 0x1

View File

@ -524,6 +524,7 @@
#define B_ANIM_RESTORE_BG 27 // for Terrain Endings
#define B_ANIM_TOTEM_FLARE 28 // Totem boosts aura flare
#define B_ANIM_GULP_MISSILE 29
#define B_ANIM_STRONG_WINDS 30
// special animations table (gBattleAnims_Special)
#define B_ANIM_LVL_UP 0

View File

@ -123,6 +123,7 @@
#define B_CRASH_IF_TARGET_IMMUNE GEN_7 // In Gen4+, The user of Jump Kick or High Jump Kick will "keep going and crash" if it attacks a target that is immune to the move.
#define B_TAILWIND_TIMER GEN_7 // In Gen5+, Tailwind lasts 4 turns instead of 3.
#define B_MEMENTO_FAIL GEN_7 // In Gen4+, Memento fails if there is no target or if the target is protected or behind substitute. But not if Atk/Sp. Atk are at -6.
#define B_HIDDEN_POWER_DMG GEN_7 // In Gen6+, Hidden Power's base power was set to always be 60. Before, it was determined by the mon's IVs.
// Ability settings
#define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability.
@ -166,6 +167,10 @@
// Item Theft Settings
#define B_TRAINERS_KNOCK_OFF_ITEMS TRUE // If TRUE, trainers can steal/swap your items (non-berries are restored after battle). In vanilla games trainers cannot steal items.
// Last Used Ball
#define B_LAST_USED_BALL TRUE // If TRUE, the "last used ball" feature from Gen 7 will be implemented
#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball.
// Other
#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter.
#define B_SLEEP_TURNS GEN_7 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns.

View File

@ -185,7 +185,8 @@
#define VARIOUS_TRY_HEAL_QUARTER_HP 112
#define VARIOUS_REMOVE_TERRAIN 113
#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 114
#define VARIOUS_CONSUME_BERRY 115
#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 115
#define VARIOUS_CONSUME_BERRY 116
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

File diff suppressed because it is too large Load Diff

View File

@ -130,7 +130,7 @@
// Gen6 hold effects
#define HOLD_EFFECT_FAIRY_POWER 139
#define HOLD_EFFECT_MEGA_STONE 140
#define HOLD_EFFECT_SAFETY_GOOGLES 141
#define HOLD_EFFECT_SAFETY_GOGGLES 141
#define HOLD_EFFECT_LUMINOUS_MOSS 142
#define HOLD_EFFECT_SNOWBALL 143
#define HOLD_EFFECT_WEAKNESS_POLICY 144

View File

@ -4697,6 +4697,7 @@ extern const u32 gBattleAnimSpritePal_MagnifyingGlass[];
extern const u32 gBattleAnimSpritePal_BrownOrb[];
extern const u32 gBattleAnimSpritePal_MetalSoundWaves[];
extern const u32 gBattleAnimSpritePal_FlyingDirt[];
extern const u32 gBattleAnimSpritePal_Windstorm[];
extern const u32 gBattleAnimSpritePal_IcicleSpear[];
extern const u32 gBattleAnimSpritePal_Hail[];
extern const u32 gBattleAnimSpritePal_GlowyRedOrb[];
@ -5199,6 +5200,9 @@ extern const u16 gSlotMachineReelTimePikachu_Pal[];
extern const u32 gBattleAnimBgTilemap_Sandstorm[];
extern const u32 gBattleAnimBgImage_Sandstorm[];
extern const u32 gBattleAnimBgTilemap_Windstorm[];
extern const u32 gBattleAnimBgImage_Windstorm[];
// Pokedex Area Screen
extern const u32 gPokedexAreaScreenAreaUnknown_Gfx[];
extern const u16 gPokedexAreaScreenAreaUnknown_Pal[];

View File

@ -33,5 +33,6 @@ void ItemUseInBattle_EnigmaBerry(u8);
void Task_UseDigEscapeRopeOnField(u8 taskId);
u8 CanUseDigOrEscapeRopeOnCurMap(void);
u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId);
u32 CanThrowBall(void);
#endif // GUARD_ITEM_USE_H

View File

@ -512,7 +512,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// move data
u8 atkPriority = GetMovePriority(battlerAtk, move);
u16 moveEffect = gBattleMoves[move].effect;
u8 moveType = gBattleMoves[move].type;
s32 moveType;
u8 moveTarget = gBattleMoves[move].target;
u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move);
u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef);
@ -525,6 +525,8 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (IsTargetingPartner(battlerAtk, battlerDef))
return score;
GET_MOVE_TYPE(move, moveType);
// check non-user target
if (!(gBattleMoves[move].target & MOVE_TARGET_USER))
@ -751,7 +753,34 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move))
return 0; // Can't even select heal blocked move
// primal weather check
//TODO
if (WEATHER_HAS_EFFECT)
{
if (gBattleWeather & WEATHER_PRIMAL_ANY)
{
switch (move)
{
case MOVE_SUNNY_DAY:
case MOVE_RAIN_DANCE:
case MOVE_HAIL:
case MOVE_SANDSTORM:
RETURN_SCORE_MINUS(30);
}
}
if (!IS_MOVE_STATUS(move))
{
if (gBattleWeather & WEATHER_SUN_PRIMAL)
{
if (moveType == TYPE_WATER)
RETURN_SCORE_MINUS(30);
}
else if (gBattleWeather & WEATHER_RAIN_PRIMAL)
{
if (moveType == TYPE_FIRE)
RETURN_SCORE_MINUS(30);
}
}
}
// check move effects
switch (moveEffect)
@ -2433,13 +2462,32 @@ static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
switch (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef))
{
case AI_EFFECTIVENESS_x4:
score += 4;
if (WEATHER_HAS_EFFECT
&& gBattleWeather & WEATHER_STRONG_WINDS
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING))
{
if (AI_RandLessThan(176)) //Consider it supereffective instead of hypereffective.
score += 2;
else
score++;
}
else
score += 4;
break;
case AI_EFFECTIVENESS_x2:
if (AI_RandLessThan(176))
score += 2;
if (WEATHER_HAS_EFFECT
&& gBattleWeather & WEATHER_STRONG_WINDS
&& IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING))
{
break; // Don't increase score, consider it neutral.
}
else
score++;
{
if (AI_RandLessThan(176))
score += 2;
else
score++;
}
break;
}
}

View File

@ -643,7 +643,7 @@ bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect)
{
if ((B_POWDER_GRASS >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GRASS))
|| ability == ABILITY_OVERCOAT
|| holdEffect == HOLD_EFFECT_SAFETY_GOOGLES)
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES)
return FALSE;
return TRUE;
}
@ -1448,7 +1448,7 @@ bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect)
|| ability == ABILITY_SAND_FORCE
|| ability == ABILITY_OVERCOAT
|| ability == ABILITY_MAGIC_GUARD
|| holdEffect == HOLD_EFFECT_SAFETY_GOOGLES
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES
|| IS_BATTLER_OF_TYPE(battler, TYPE_ROCK)
|| IS_BATTLER_OF_TYPE(battler, TYPE_STEEL)
|| IS_BATTLER_OF_TYPE(battler, TYPE_GROUND)
@ -1473,7 +1473,7 @@ bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect)
|| ability == ABILITY_SLUSH_RUSH
|| ability == ABILITY_MAGIC_GUARD
|| ability == ABILITY_OVERCOAT
|| holdEffect == HOLD_EFFECT_SAFETY_GOOGLES
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES
|| IS_BATTLER_OF_TYPE(battler, TYPE_ICE)
|| HasMove(battler, MOVE_BLIZZARD)
|| HasMoveEffect(battler, EFFECT_AURORA_VEIL)
@ -2273,7 +2273,7 @@ static u32 GetWeatherDamage(u8 battlerId)
{
if (BattlerAffectedBySandstorm(battlerId, ability)
&& !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
&& holdEffect != HOLD_EFFECT_SAFETY_GOOGLES)
&& holdEffect != HOLD_EFFECT_SAFETY_GOGGLES)
{
damage = gBattleMons[battlerId].maxHP / 16;
if (damage == 0)
@ -2284,7 +2284,7 @@ static u32 GetWeatherDamage(u8 battlerId)
{
if (BattlerAffectedByHail(battlerId, ability)
&& !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
&& holdEffect != HOLD_EFFECT_SAFETY_GOOGLES)
&& holdEffect != HOLD_EFFECT_SAFETY_GOGGLES)
{
damage = gBattleMons[battlerId].maxHP / 16;
if (damage == 0)

View File

@ -5,6 +5,8 @@
#include "constants/battle_anim.h"
#include "constants/rgb.h"
#include "random.h"
#include "gpu_regs.h"
#include "graphics.h"
extern const struct SpriteTemplate gFlashingHitSplatSpriteTemplate;
@ -30,7 +32,7 @@ static void AnimUnusedFlashingLight_Step(struct Sprite *);
static void AnimSkyAttackBird(struct Sprite *);
static void AnimSkyAttackBird_Step(struct Sprite *);
static void AnimTask_AnimateGustTornadoPalette_Step(u8);
static void AnimTask_LoadWindstormBackground_Step(u8 taskId);
const struct SpriteTemplate gEllipticalGustSpriteTemplate =
{
@ -1231,3 +1233,99 @@ static void AnimTask_SetAttackerVisibility(u8 taskId)
}
DestroyAnimVisualTask(taskId);
}
void AnimTask_LoadWindstormBackground(u8 taskId)
{
int var0;
struct BattleAnimBgData animBg;
var0 = 0;
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
GetBattleAnimBg1Data(&animBg);
AnimLoadCompressedBgGfx(animBg.bgId, gBattleAnimBgImage_Windstorm, animBg.tilesOffset);
AnimLoadCompressedBgTilemapHandleContest(&animBg, gBattleAnimBgTilemap_Windstorm, 0);
LoadCompressedPalette(gBattleAnimSpritePal_Windstorm, animBg.paletteId * 16, 32);
if (gBattleAnimArgs[0] && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
var0 = 1;
gTasks[taskId].data[0] = var0;
gTasks[taskId].func = AnimTask_LoadWindstormBackground_Step;
}
static void AnimTask_LoadWindstormBackground_Step(u8 taskId)
{
struct BattleAnimBgData animBg;
if (gTasks[taskId].data[0] == 0)
gBattle_BG1_X += -6;
else
gBattle_BG1_X += 6;
gBattle_BG1_Y += -1;
switch (gTasks[taskId].data[12])
{
case 0:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 7)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 1:
if (++gTasks[taskId].data[11] == 101)
{
gTasks[taskId].data[11] = 7;
gTasks[taskId].data[12]++;
}
break;
case 2:
if (++gTasks[taskId].data[10] == 4)
{
gTasks[taskId].data[10] = 0;
gTasks[taskId].data[11]--;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
if (gTasks[taskId].data[11] == 0)
{
gTasks[taskId].data[12]++;
gTasks[taskId].data[11] = 0;
}
}
break;
case 3:
GetBattleAnimBg1Data(&animBg);
ClearBattleAnimBg(animBg.bgId);
gTasks[taskId].data[12]++;
break;
case 4:
if (!IsContest())
SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
DestroyAnimVisualTask(taskId);
break;
}
}

View File

@ -249,7 +249,8 @@ static void HandleInputChooseAction(void)
if (JOY_NEW(A_BUTTON))
{
PlaySE(SE_SELECT);
TryHideLastUsedBall();
switch (gActionSelectionCursor[gActiveBattler])
{
case 0:
@ -336,6 +337,15 @@ static void HandleInputChooseAction(void)
BtlController_EmitTwoReturnValues(1, B_ACTION_DEBUG, 0);
PlayerBufferExecCompleted();
}
#if B_LAST_USED_BALL == TRUE
else if (JOY_NEW(B_LAST_USED_BALL_BUTTON) && CanThrowLastUsedBall())
{
PlaySE(SE_SELECT);
TryHideLastUsedBall();
BtlController_EmitTwoReturnValues(1, B_ACTION_THROW_BALL, 0);
PlayerBufferExecCompleted();
}
#endif
}
static void UnusedEndBounceEffect(void)
@ -372,6 +382,7 @@ static void HandleInputChooseTarget(void)
else
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX);
TryHideLastUsedBall();
HideMegaTriggerSprite();
PlayerBufferExecCompleted();
}
@ -514,6 +525,7 @@ static void HandleInputShowTargets(void)
else
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
HideMegaTriggerSprite();
TryHideLastUsedBall();
PlayerBufferExecCompleted();
}
else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59)
@ -606,6 +618,7 @@ static void HandleInputChooseMove(void)
else
BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8));
HideMegaTriggerSprite();
TryHideLastUsedBall();
PlayerBufferExecCompleted();
}
else if (canSelectTarget == 1)
@ -2696,6 +2709,7 @@ static void PlayerHandleChooseAction(void)
for (i = 0; i < 4; i++)
ActionSelectionDestroyCursorAt(i);
TryRestoreLastUsedBall();
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo);
BattlePutTextOnWindow(gDisplayedStringBattle, 1);

View File

@ -1951,7 +1951,7 @@ static const u8 sText_HoldEffectAbsorbBulb[] = _("Absorb Bulb");
static const u8 sText_HoldEffectCellBattery[] = _("Cell Battery");
static const u8 sText_HoldEffectFairyPower[] = _("Fairy Power");
static const u8 sText_HoldEffectMegaStone[] = _("Mega Stone");
static const u8 sText_HoldEffectSafetyGoogles[] = _("Safety Googles");
static const u8 sText_HoldEffectSafetyGoggles[] = _("Safety Goggles");
static const u8 sText_HoldEffectLuminousMoss[] = _("Luminous Moss");
static const u8 sText_HoldEffectSnowball[] = _("Snowball");
static const u8 sText_HoldEffectWeaknessPolicy[] = _("Weakness Policy");
@ -2091,7 +2091,7 @@ static const u8 *const sHoldEffectNames[] =
[HOLD_EFFECT_CELL_BATTERY] = sText_HoldEffectCellBattery,
[HOLD_EFFECT_FAIRY_POWER] = sText_HoldEffectFairyPower,
[HOLD_EFFECT_MEGA_STONE] = sText_HoldEffectMegaStone,
[HOLD_EFFECT_SAFETY_GOOGLES] = sText_HoldEffectSafetyGoogles,
[HOLD_EFFECT_SAFETY_GOGGLES] = sText_HoldEffectSafetyGoggles,
[HOLD_EFFECT_LUMINOUS_MOSS] = sText_HoldEffectLuminousMoss,
[HOLD_EFFECT_SNOWBALL] = sText_HoldEffectSnowball,
[HOLD_EFFECT_WEAKNESS_POLICY] = sText_HoldEffectWeaknessPolicy,

View File

@ -27,6 +27,10 @@
#include "constants/battle_config.h"
#include "data.h"
#include "pokemon_summary_screen.h"
#include "item_icon.h"
#include "item_use.h"
#include "item.h"
#include "constants/items.h"
enum
{ // Corresponds to gHealthboxElementsGfxTable (and the tables after it) in graphics.c
@ -196,6 +200,9 @@ static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32
static void SpriteCb_AbilityPopUp(struct Sprite *sprite);
static void Task_FreeAbilityPopUpGfx(u8 taskId);
static void SpriteCB_LastUsedBall(struct Sprite *sprite);
static void SpriteCB_LastUsedBallWin(struct Sprite *sprite);
// const rom data
static const struct OamData sUnknown_0832C138 =
{
@ -723,6 +730,12 @@ u8 GetMegaIndicatorSpriteId(u32 healthboxSpriteId)
return gSprites[spriteId].hOther_IndicatorSpriteId;
}
static void InitLastUsedBallAssets(void)
{
gBattleStruct->ballSpriteIds[0] = MAX_SPRITES;
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
}
u8 CreateBattlerHealthboxSprites(u8 battlerId)
{
s16 data6 = 0;
@ -812,6 +825,9 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId)
gSprites[megaIndicatorSpriteId].invisible = TRUE;
}
gBattleStruct->ballSpriteIds[0] = MAX_SPRITES;
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
return healthboxLeftSpriteId;
}
@ -3123,3 +3139,200 @@ static void Task_FreeAbilityPopUpGfx(u8 taskId)
DestroyTask(taskId);
}
}
// last used ball
#define LAST_BALL_WINDOW_TAG 0xD721
static const struct OamData sOamData_LastUsedBall =
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = SPRITE_SHAPE(32x32),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x32),
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0,
};
static const struct SpriteTemplate sSpriteTemplate_LastUsedBallWindow =
{
.tileTag = LAST_BALL_WINDOW_TAG,
.paletteTag = ABILITY_POP_UP_TAG,
.oam = &sOamData_LastUsedBall,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_LastUsedBallWin
};
#if B_LAST_USED_BALL_BUTTON == R_BUTTON
static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_r.4bpp");
#else
static const u8 sLastUsedBallWindowGfx[] = INCBIN_U8("graphics/battle_interface/last_used_ball_l.4bpp");
#endif
static const struct SpriteSheet sSpriteSheet_LastUsedBallWindow =
{
sLastUsedBallWindowGfx, sizeof(sLastUsedBallWindowGfx), LAST_BALL_WINDOW_TAG
};
#define LAST_USED_BALL_X_F 15
#define LAST_USED_BALL_X_0 -15
#define LAST_USED_BALL_Y ((IsDoubleBattle()) ? 78 : 68)
#define LAST_BALL_WIN_X_F (LAST_USED_BALL_X_F - 1)
#define LAST_BALL_WIN_X_0 (LAST_USED_BALL_X_0 - 0)
#define LAST_USED_WIN_Y (LAST_USED_BALL_Y - 8)
#define sHide data[0]
bool32 CanThrowLastUsedBall(void)
{
#if B_LAST_USED_BALL == FALSE
return FALSE;
#else
return (!(CanThrowBall() != 0
|| (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|| !CheckBagHasItem(gLastThrownBall, 1)));
#endif
}
void TryAddLastUsedBallItemSprites(void)
{
#if B_LAST_USED_BALL == TRUE
if (gLastThrownBall == 0
|| (gLastThrownBall != 0 && !CheckBagHasItem(gLastThrownBall, 1)))
{
// we're out of the last used ball, so just set it to the first ball in the bag
// we have to compact the bag first bc it is typically only compacted when you open it
CompactItemsInBagPocket(&gBagPockets[BALLS_POCKET]);
gLastThrownBall = gBagPockets[BALLS_POCKET].itemSlots[0].itemId;
}
if (CanThrowBall() != 0
|| (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|| !CheckBagHasItem(gLastThrownBall, 1))
return;
// ball
if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES)
{
gBattleStruct->ballSpriteIds[0] = AddItemIconSprite(102, 102, gLastThrownBall);
gSprites[gBattleStruct->ballSpriteIds[0]].x = LAST_USED_BALL_X_0;
gSprites[gBattleStruct->ballSpriteIds[0]].y = LAST_USED_BALL_Y;
gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore
gSprites[gBattleStruct->ballSpriteIds[0]].callback = SpriteCB_LastUsedBall;
}
// window
LoadSpritePalette(&sSpritePalette_AbilityPopUp);
if (GetSpriteTileStartByTag(LAST_BALL_WINDOW_TAG) == 0xFFFF)
LoadSpriteSheet(&sSpriteSheet_LastUsedBallWindow);
if (gBattleStruct->ballSpriteIds[1] == MAX_SPRITES)
{
gBattleStruct->ballSpriteIds[1] = CreateSprite(&sSpriteTemplate_LastUsedBallWindow,
LAST_BALL_WIN_X_0,
LAST_USED_WIN_Y, 5);
gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore
}
#endif
}
static void DestroyLastUsedBallWinGfx(struct Sprite *sprite)
{
FreeSpriteTilesByTag(LAST_BALL_WINDOW_TAG);
FreeSpritePaletteByTag(ABILITY_POP_UP_TAG);
DestroySprite(sprite);
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
}
static void DestroyLastUsedBallGfx(struct Sprite *sprite)
{
FreeSpriteTilesByTag(102);
FreeSpritePaletteByTag(102);
DestroySprite(sprite);
gBattleStruct->ballSpriteIds[0] = MAX_SPRITES;
}
static void SpriteCB_LastUsedBallWin(struct Sprite *sprite)
{
if (sprite->sHide)
{
if (sprite->x != LAST_BALL_WIN_X_0)
sprite->x--;
if (sprite->x == LAST_BALL_WIN_X_0)
DestroyLastUsedBallWinGfx(sprite);
}
else
{
if (sprite->x != LAST_BALL_WIN_X_F)
sprite->x++;
}
}
static void SpriteCB_LastUsedBall(struct Sprite *sprite)
{
if (sprite->sHide)
{
if (sprite->x != LAST_USED_BALL_X_0)
sprite->x--;
if (sprite->x == LAST_USED_BALL_X_0)
DestroyLastUsedBallGfx(sprite);
}
else
{
if (sprite->x != LAST_USED_BALL_X_F)
sprite->x++;
}
}
static void TryHideOrRestoreLastUsedBall(u8 caseId)
{
#if B_LAST_USED_BALL == TRUE
if (gBattleStruct->ballSpriteIds[0] == MAX_SPRITES)
return;
switch (caseId)
{
case 0: // hide
if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES)
gSprites[gBattleStruct->ballSpriteIds[0]].sHide = TRUE; // hide
if (gBattleStruct->ballSpriteIds[1] != MAX_SPRITES)
gSprites[gBattleStruct->ballSpriteIds[1]].sHide = TRUE; // hide
break;
case 1: // restore
if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES)
gSprites[gBattleStruct->ballSpriteIds[0]].sHide = FALSE; // restore
if (gBattleStruct->ballSpriteIds[1] != MAX_SPRITES)
gSprites[gBattleStruct->ballSpriteIds[1]].sHide = FALSE; // restore
break;
}
#endif
}
void TryHideLastUsedBall(void)
{
#if B_LAST_USED_BALL == TRUE
TryHideOrRestoreLastUsedBall(0);
#endif
}
void TryRestoreLastUsedBall(void)
{
#if B_LAST_USED_BALL == TRUE
if (gBattleStruct->ballSpriteIds[0] != MAX_SPRITES)
TryHideOrRestoreLastUsedBall(1);
else
TryAddLastUsedBallItemSprites();
#endif
}

View File

@ -230,6 +230,7 @@ EWRAM_DATA u16 gPartnerSpriteId = 0;
EWRAM_DATA struct TotemBoost gTotemBoosts[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA bool8 gHasFetchedBall = FALSE;
EWRAM_DATA u8 gLastUsedBall = 0;
EWRAM_DATA u16 gLastThrownBall = 0;
// IWRAM common vars
void (*gPreBattleCallback1)(void);
@ -401,6 +402,7 @@ static void (* const sTurnActionsFuncsTable[])(void) =
[B_ACTION_TRY_FINISH] = HandleAction_TryFinish,
[B_ACTION_FINISHED] = HandleAction_ActionFinished,
[B_ACTION_NOTHING_FAINTED] = HandleAction_NothingIsFainted,
[B_ACTION_THROW_BALL] = HandleAction_ThrowBall,
};
static void (* const sEndTurnFuncsTable[])(void) =
@ -4073,6 +4075,10 @@ static void HandleTurnActionSelectionState(void)
case B_ACTION_SAFARI_BALL:
gBattleCommunication[gActiveBattler]++;
break;
case B_ACTION_THROW_BALL:
gBattleStruct->throwingPokeBall = TRUE;
gBattleCommunication[gActiveBattler]++;
break;
case B_ACTION_SAFARI_POKEBLOCK:
if ((gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8)) != 0)
{
@ -4186,6 +4192,13 @@ static void HandleTurnActionSelectionState(void)
if (gBattleCommunication[ACTIONS_CONFIRMED_COUNT] == gBattlersCount)
{
sub_818603C(1);
if (WILD_DOUBLE_BATTLE && gBattleStruct->throwingPokeBall) {
// if we choose to throw a ball with our second mon, skip the action of the first
// (if we have chosen throw ball with first, second's is already skipped)
gChosenActionByBattler[B_POSITION_PLAYER_LEFT] = B_ACTION_NOTHING_FAINTED;
}
gBattleMainFunc = SetActionsAndBattlersTurnOrder;
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
@ -4507,7 +4520,9 @@ static void SetActionsAndBattlersTurnOrder(void)
{
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
{
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM || gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH)
if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM
|| gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH
|| gChosenActionByBattler[gActiveBattler] == B_ACTION_THROW_BALL)
{
gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
@ -4516,7 +4531,9 @@ static void SetActionsAndBattlersTurnOrder(void)
}
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
{
if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM && gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH)
if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM
&& gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH
&& gChosenActionByBattler[gActiveBattler] != B_ACTION_THROW_BALL)
{
gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
@ -4532,7 +4549,9 @@ static void SetActionsAndBattlersTurnOrder(void)
if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM
&& gActionsByTurnOrder[j] != B_ACTION_USE_ITEM
&& gActionsByTurnOrder[i] != B_ACTION_SWITCH
&& gActionsByTurnOrder[j] != B_ACTION_SWITCH)
&& gActionsByTurnOrder[j] != B_ACTION_SWITCH
&& gActionsByTurnOrder[i] != B_ACTION_THROW_BALL
&& gActionsByTurnOrder[j] != B_ACTION_THROW_BALL)
{
if (GetWhoStrikesFirst(battler1, battler2, FALSE))
SwapTurnOrder(i, j);

View File

@ -653,7 +653,7 @@ static const u8 sText_MistyTerrainPreventsStatus[] = _("{B_DEF_NAME_WITH_PREFIX}
static const u8 sText_GrassyTerrainHeals[] = _("{B_ATK_NAME_WITH_PREFIX} is healed\nby the grassy terrain!");
static const u8 sText_ElectricTerrainPreventsSleep[] = _("{B_DEF_NAME_WITH_PREFIX} surrounds itself\nwith electrified terrain!");
static const u8 sText_PsychicTerrainPreventsPriority[] = _("{B_DEF_NAME_WITH_PREFIX} surrounds itself\nwith psychic terrain!");
static const u8 sText_SafetyGooglesProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is not affected\nthanks to its {B_LAST_ITEM}!");
static const u8 sText_SafetyGogglesProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is not affected\nthanks to its {B_LAST_ITEM}!");
static const u8 sText_FlowerVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} surrounded itself\nwith a veil of petals!");
static const u8 sText_SweetVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} surrounded itself\nwith a veil of sweetness!");
static const u8 sText_AromaVeilProtected[] = _("{B_DEF_NAME_WITH_PREFIX} is protected\nby an aromatic veil!");
@ -706,11 +706,35 @@ static const u8 sText_TormentedNoMore[] = _("{B_ATK_NAME_WITH_PREFIX} is\ntormen
static const u8 sText_HealBlockedNoMore[] = _("{B_ATK_NAME_WITH_PREFIX} is cured of\nits heal block!");
static const u8 sText_AttackerBecameFullyCharged[] = _("{B_ATK_NAME_WITH_PREFIX} became fully charged\ndue to its bond with its trainer!\p");
static const u8 sText_AttackerBecameAshSpecies[] = _("{B_ATK_NAME_WITH_PREFIX} became Ash-{B_BUFF1}!\p");
static const u8 sText_ExtremelyHarshSunlight[] = _("The sunlight turned\nextremely harsh!");
static const u8 sText_ExtremeSunlightFaded[] = _("The extreme sunlight faded.{PAUSE 64}");
static const u8 sText_MoveEvaporatedInTheHarshSunlight[] = _("The Water-type attack evaporated\nin the harsh sunlight!");
static const u8 sText_ExtremelyHarshSunlightWasNotLessened[] = _("The extremely harsh sunlight\nwas not lessened at all!");
static const u8 sText_HeavyRain[] = _("A heavy rain began to fall!");
static const u8 sText_HeavyRainLifted[] = _("The heavy rain has lifted!{PAUSE 64}");
static const u8 sText_MoveFizzledOutInTheHeavyRain[] = _("The Fire-type attack fizzled out\nin the heavy rain!");
static const u8 sText_NoReliefFromHeavyRain[] = _("There is no relief from\nthis heavy rain!");
static const u8 sText_MysteriousAirCurrent[] = _("A mysterious air current is\nprotecting Flying-type Pokémon!");
static const u8 sText_StrongWindsDissipated[] = _("The mysterious strong winds\nhave dissipated!{PAUSE 64}");
static const u8 sText_MysteriousAirCurrentBlowsOn[] = _("The mysterious air current\nblows on regardless!");
static const u8 sText_AttackWeakenedByStrongWinds[] = _("The mysterious strong winds\nweakened the attack!");
static const u8 sText_StuffCheeksCantSelect[] = _("Stuff Cheeks cannot be\nselected without a Berry!\p");
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
[STRINGID_STUFFCHEEKSCANTSELECT - 12] = sText_StuffCheeksCantSelect,
[STRINGID_ATTACKWEAKENEDBSTRONGWINDS - 12] = sText_AttackWeakenedByStrongWinds,
[STRINGID_MYSTERIOUSAIRCURRENTBLOWSON - 12] = sText_MysteriousAirCurrentBlowsOn,
[STRINGID_STRONGWINDSDISSIPATED - 12] = sText_StrongWindsDissipated,
[STRINGID_MYSTERIOUSAIRCURRENT - 12] = sText_MysteriousAirCurrent,
[STRINGID_NORELIEFROMHEAVYRAIN - 12] = sText_NoReliefFromHeavyRain,
[STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN - 12] = sText_MoveFizzledOutInTheHeavyRain,
[STRINGID_HEAVYRAINLIFTED - 12] = sText_HeavyRainLifted,
[STRINGID_HEAVYRAIN - 12] = sText_HeavyRain,
[STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED - 12] = sText_ExtremelyHarshSunlightWasNotLessened,
[STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT - 12] = sText_MoveEvaporatedInTheHarshSunlight,
[STRINGID_EXTREMESUNLIGHTFADED - 12] = sText_ExtremeSunlightFaded,
[STRINGID_EXTREMELYHARSHSUNLIGHT - 12] = sText_ExtremelyHarshSunlight,
[STRINGID_ATTACKERBECAMEASHSPECIES - 12] = sText_AttackerBecameAshSpecies,
[STRINGID_ATTACKERBECAMEFULLYCHARGED - 12] = sText_AttackerBecameFullyCharged,
[STRINGID_HEALBLOCKEDNOMORE - 12] = sText_HealBlockedNoMore,
@ -758,7 +782,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_AROMAVEILPROTECTED - 12] = sText_AromaVeilProtected,
[STRINGID_SWEETVEILPROTECTED - 12] = sText_SweetVeilProtected,
[STRINGID_FLOWERVEILPROTECTED - 12] = sText_FlowerVeilProtected,
[STRINGID_SAFETYGOOGLESPROTECTED - 12] = sText_SafetyGooglesProtected,
[STRINGID_SAFETYGOGGLESPROTECTED - 12] = sText_SafetyGogglesProtected,
[STRINGID_SPECTRALTHIEFSTEAL - 12] = sText_SpectralThiefSteal,
[STRINGID_BELCHCANTSELECT - 12] = sText_BelchCantUse,
[STRINGID_TRAINER1LOSETEXT - 12] = sText_Trainer1LoseText,

View File

@ -1334,6 +1334,28 @@ static void Cmd_attackcanceler(void)
{
s32 i, moveType;
GET_MOVE_TYPE(gCurrentMove, moveType);
if (moveType == TYPE_FIRE
&& (gBattleWeather & WEATHER_RAIN_PRIMAL)
&& WEATHER_HAS_EFFECT
&& gBattleMoves[gCurrentMove].power)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_PrimordialSeaFizzlesOutFireTypeMoves;
return;
}
if (moveType == TYPE_WATER
&& (gBattleWeather & WEATHER_SUN_PRIMAL)
&& WEATHER_HAS_EFFECT
&& gBattleMoves[gCurrentMove].power)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_DesolateLandEvaporatesWaterTypeMoves;
return;
}
if (gBattleOutcome != 0)
{
gCurrentActionFuncId = B_ACTION_FINISHED;
@ -1353,7 +1375,6 @@ static void Cmd_attackcanceler(void)
return;
// Check Protean activation.
GET_MOVE_TYPE(gCurrentMove, moveType);
if ((GetBattlerAbility(gBattlerAttacker) == ABILITY_PROTEAN || GetBattlerAbility(gBattlerAttacker) == ABILITY_LIBERO)
&& (gBattleMons[gBattlerAttacker].type1 != moveType || gBattleMons[gBattlerAttacker].type2 != moveType ||
(gBattleMons[gBattlerAttacker].type3 != moveType && gBattleMons[gBattlerAttacker].type3 != TYPE_MYSTERY))
@ -1893,6 +1914,9 @@ static void Cmd_typecalc(void)
static void Cmd_adjustdamage(void)
{
u8 holdEffect, param;
u32 moveType;
GET_MOVE_TYPE(gCurrentMove, moveType);
if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
goto END;
@ -1970,6 +1994,23 @@ END:
gBattlescriptCurrInstr = BattleScript_GemActivates;
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
}
// WEATHER_STRONG_WINDS prints a string when it's about to reduce the power
// of a move that is Super Effective against a Flying-type Pokémon.
if (gBattleWeather & WEATHER_STRONG_WINDS)
{
if ((gBattleMons[gBattlerTarget].type1 == TYPE_FLYING
&& GetTypeModifier(moveType, gBattleMons[gBattlerTarget].type1) >= UQ_4_12(2.0))
|| (gBattleMons[gBattlerTarget].type2 == TYPE_FLYING
&& GetTypeModifier(moveType, gBattleMons[gBattlerTarget].type2) >= UQ_4_12(2.0))
|| (gBattleMons[gBattlerTarget].type3 == TYPE_FLYING
&& GetTypeModifier(moveType, gBattleMons[gBattlerTarget].type3) >= UQ_4_12(2.0)))
{
gBattlerAbility = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AttackWeakenedByStrongWinds;
}
}
}
static void Cmd_multihitresultmessage(void)
@ -5145,7 +5186,7 @@ static void Cmd_moveend(void)
// Attacker is the damage-dealer, battler is mon to be switched out
if (IsBattlerAlive(battler)
&& GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_EJECT_BUTTON
&& !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battler)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
&& (gSpecialStatuses[battler].physicalDmg != 0 || gSpecialStatuses[battler].specialDmg != 0)
&& CountUsablePartyMons(battler) > 0) // Has mon to switch into
{
@ -5179,7 +5220,7 @@ static void Cmd_moveend(void)
// Attacker is the one to be switched out, battler is one with red card
if (battler != gBattlerAttacker
&& IsBattlerAlive(battler)
&& !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battler)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
&& GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_RED_CARD
&& (gSpecialStatuses[battler].physicalDmg != 0 || gSpecialStatuses[battler].specialDmg != 0)
&& CanBattlerSwitch(gBattlerAttacker))
@ -5246,7 +5287,7 @@ static void Cmd_moveend(void)
if (battler != gBattlerAttacker // Cannot pickpocket yourself
&& GetBattlerAbility(battler) == ABILITY_PICKPOCKET // Target must have pickpocket ability
&& BATTLER_DAMAGED(battler) // Target needs to have been damaged
&& !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battler) // Subsitute unaffected
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) // Subsitute unaffected
&& IsBattlerAlive(battler) // Battler must be alive to pickpocket
&& gBattleMons[battler].item == ITEM_NONE // Pickpocketer can't have an item already
&& CanStealItem(battler, gBattlerAttacker, gBattleMons[gBattlerAttacker].item)) // Cannot steal plates, mega stones, etc
@ -8748,12 +8789,45 @@ static void Cmd_various(void)
}
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain
break;
case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED:
case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED:
if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
case VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER:
{
bool8 shouldNotClear = FALSE;
for (i = 0; i < gBattlersCount; i++)
{
if (((GetBattlerAbility(i) == ABILITY_DESOLATE_LAND && gBattleWeather & WEATHER_SUN_PRIMAL)
|| (GetBattlerAbility(i) == ABILITY_PRIMORDIAL_SEA && gBattleWeather & WEATHER_RAIN_PRIMAL)
|| (GetBattlerAbility(i) == ABILITY_DELTA_STREAM && gBattleWeather & WEATHER_STRONG_WINDS))
&& IsBattlerAlive(i)
&& !(gStatuses3[i] & STATUS3_GASTRO_ACID))
shouldNotClear = TRUE;
}
if (gBattleWeather & WEATHER_SUN_PRIMAL && !shouldNotClear)
{
gBattleWeather &= ~WEATHER_SUN_PRIMAL;
PrepareStringBattle(STRINGID_EXTREMESUNLIGHTFADED, gActiveBattler);
gBattleCommunication[MSG_DISPLAY] = 1;
}
else if (gBattleWeather & WEATHER_RAIN_PRIMAL && !shouldNotClear)
{
gBattleWeather &= ~WEATHER_RAIN_PRIMAL;
PrepareStringBattle(STRINGID_HEAVYRAINLIFTED, gActiveBattler);
gBattleCommunication[MSG_DISPLAY] = 1;
}
else if (gBattleWeather & WEATHER_STRONG_WINDS && !shouldNotClear)
{
gBattleWeather &= ~WEATHER_STRONG_WINDS;
PrepareStringBattle(STRINGID_STRONGWINDSDISSIPATED, gActiveBattler);
gBattleCommunication[MSG_DISPLAY] = 1;
}
break;
}
case VARIOUS_CONSUME_BERRY:
if (ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item) == HOLD_EFFECT_NONE)
{
@ -10082,7 +10156,7 @@ static void Cmd_weatherdamage(void)
&& ability != ABILITY_SAND_RUSH
&& ability != ABILITY_OVERCOAT
&& !(gStatuses3[gBattlerAttacker] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOOGLES)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES)
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16;
if (gBattleMoveDamage == 0)
@ -10107,7 +10181,7 @@ static void Cmd_weatherdamage(void)
&& ability != ABILITY_OVERCOAT
&& ability != ABILITY_ICE_BODY
&& !(gStatuses3[gBattlerAttacker] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOOGLES)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES)
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16;
if (gBattleMoveDamage == 0)
@ -12465,7 +12539,8 @@ static void Cmd_handleballthrow(void)
{
u32 odds;
u8 catchRate;
gLastThrownBall = gLastUsedItem;
if (gLastUsedItem == ITEM_SAFARI_BALL)
catchRate = gBattleStruct->safariCatchFactor * 1275 / 100;
else

View File

@ -756,6 +756,17 @@ void HandleAction_SafariZoneBallThrow(void)
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
}
void HandleAction_ThrowBall(void)
{
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
gBattle_BG0_X = 0;
gBattle_BG0_Y = 0;
gLastUsedItem = gLastThrownBall;
RemoveBagItem(gLastUsedItem, 1);
gBattlescriptCurrInstr = BattleScript_BallThrow;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
}
void HandleAction_ThrowPokeblock(void)
{
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
@ -2123,7 +2134,8 @@ u8 DoFieldEndTurnEffects(void)
case ENDTURN_RAIN:
if (gBattleWeather & WEATHER_RAIN_ANY)
{
if (!(gBattleWeather & WEATHER_RAIN_PERMANENT))
if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)
&& !(gBattleWeather & WEATHER_RAIN_PRIMAL))
{
if (--gWishFutureKnock.weatherDuration == 0)
{
@ -2173,7 +2185,9 @@ u8 DoFieldEndTurnEffects(void)
case ENDTURN_SUN:
if (gBattleWeather & WEATHER_SUN_ANY)
{
if (!(gBattleWeather & WEATHER_SUN_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
if (!(gBattleWeather & WEATHER_SUN_PERMANENT)
&& !(gBattleWeather & WEATHER_SUN_PRIMAL)
&& --gWishFutureKnock.weatherDuration == 0)
{
gBattleWeather &= ~WEATHER_SUN_TEMPORARY;
gBattlescriptCurrInstr = BattleScript_SunlightFaded;
@ -3400,9 +3414,10 @@ u8 AtkCanceller_UnableToUseMove(void)
gBattlerAbility = gBattlerTarget;
effect = 1;
}
else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOOGLES)
else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES)
{
RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOOGLES);
RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOGGLES);
gLastUsedItem = gBattleMons[gBattlerTarget].item;
effect = 1;
}
@ -3692,9 +3707,12 @@ u8 TryWeatherFormChange(u8 battler)
static const u16 sWeatherFlagsInfo[][3] =
{
[ENUM_WEATHER_RAIN] = {WEATHER_RAIN_TEMPORARY, WEATHER_RAIN_PERMANENT, HOLD_EFFECT_DAMP_ROCK},
[ENUM_WEATHER_RAIN_PRIMAL] = {WEATHER_RAIN_PRIMAL, WEATHER_RAIN_PRIMAL, HOLD_EFFECT_DAMP_ROCK},
[ENUM_WEATHER_SUN] = {WEATHER_SUN_TEMPORARY, WEATHER_SUN_PERMANENT, HOLD_EFFECT_HEAT_ROCK},
[ENUM_WEATHER_SUN_PRIMAL] = {WEATHER_SUN_PRIMAL, WEATHER_SUN_PRIMAL, HOLD_EFFECT_HEAT_ROCK},
[ENUM_WEATHER_SANDSTORM] = {WEATHER_SANDSTORM_TEMPORARY, WEATHER_SANDSTORM_PERMANENT, HOLD_EFFECT_SMOOTH_ROCK},
[ENUM_WEATHER_HAIL] = {WEATHER_HAIL_TEMPORARY, WEATHER_HAIL_PERMANENT, HOLD_EFFECT_ICY_ROCK},
[ENUM_WEATHER_STRONG_WINDS] = {WEATHER_STRONG_WINDS, WEATHER_STRONG_WINDS, HOLD_EFFECT_NONE},
};
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
@ -3705,6 +3723,13 @@ bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility)
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]);
return TRUE;
}
else if (gBattleWeather & WEATHER_PRIMAL_ANY
&& GetBattlerAbility(battler) != ABILITY_DESOLATE_LAND
&& GetBattlerAbility(battler) != ABILITY_PRIMORDIAL_SEA
&& GetBattlerAbility(battler) != ABILITY_DELTA_STREAM)
{
return FALSE;
}
else if (!(gBattleWeather & (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1])))
{
gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0]);
@ -4175,6 +4200,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates);
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = 1;
BattleScriptPushCursorAndCallback(BattleScript_BlockedByPrimalWeatherEnd3);
effect++;
}
break;
case ABILITY_SAND_STREAM:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE))
@ -4182,6 +4213,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates);
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = 1;
BattleScriptPushCursorAndCallback(BattleScript_BlockedByPrimalWeatherEnd3);
effect++;
}
break;
case ABILITY_DROUGHT:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SUN, TRUE))
@ -4189,6 +4226,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates);
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = 1;
BattleScriptPushCursorAndCallback(BattleScript_BlockedByPrimalWeatherEnd3);
effect++;
}
break;
case ABILITY_SNOW_WARNING:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_HAIL, TRUE))
@ -4196,6 +4239,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
BattleScriptPushCursorAndCallback(BattleScript_SnowWarningActivates);
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY && !gSpecialStatuses[battler].switchInAbilityDone)
{
gSpecialStatuses[battler].switchInAbilityDone = 1;
BattleScriptPushCursorAndCallback(BattleScript_BlockedByPrimalWeatherEnd3);
effect++;
}
break;
case ABILITY_ELECTRIC_SURGE:
if (TryChangeBattleTerrain(battler, STATUS_FIELD_ELECTRIC_TERRAIN, &gFieldTimers.electricTerrainTimer))
@ -4285,6 +4334,27 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
effect++;
}
break;
case ABILITY_DESOLATE_LAND:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_SUN_PRIMAL, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_DesolateLandActivates);
effect++;
}
break;
case ABILITY_PRIMORDIAL_SEA:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_RAIN_PRIMAL, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_PrimordialSeaActivates);
effect++;
}
break;
case ABILITY_DELTA_STREAM:
if (TryChangeBattleWeather(battler, ENUM_WEATHER_STRONG_WINDS, TRUE))
{
BattleScriptPushCursorAndCallback(BattleScript_DeltaStreamActivates);
effect++;
}
break;
}
break;
case ABILITYEFFECT_ENDTURN: // 1
@ -4475,7 +4545,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
}
break;
case ABILITYEFFECT_MOVES_BLOCK: // 2
if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND)
if ((gLastUsedAbility == ABILITY_SOUNDPROOF && gBattleMoves[move].flags & FLAG_SOUND && !(gBattleMoves[move].target & MOVE_TARGET_USER))
|| (gLastUsedAbility == ABILITY_BULLETPROOF && gBattleMoves[move].flags & FLAG_BALLISTIC))
{
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)
@ -4841,7 +4911,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITY_EFFECT_SPORE:
if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GRASS)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_OVERCOAT
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOOGLES)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES)
{
i = Random() % 3;
if (i == 0)
@ -4976,13 +5046,20 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SANDSTORM_ANY)
&& TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE))
&& TryChangeBattleWeather(battler, ENUM_WEATHER_SANDSTORM, TRUE)
&& !(WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY))
{
gBattleScripting.battler = gActiveBattler = battler;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SandSpitActivates;
effect++;
}
else if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_PRIMAL_ANY)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BlockedByPrimalWeatherRet;
effect++;
}
break;
case ABILITY_PERISH_BODY:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
@ -5614,7 +5691,7 @@ static u8 HealConfuseBerry(u32 battlerId, u32 itemId, u8 flavorId, bool32 end2)
gBattleMoveDamage *= 2;
gBattlerAbility = battlerId;
}
gBattleScripting.battler = battlerId;
if (end2)
{
if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, flavorId) < 0)
@ -6832,7 +6909,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
if (TARGET_TURN_DAMAGED
&& (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
&& IsMoveMakingContact(gCurrentMove, gBattlerAttacker)
&& !DoesSubstituteBlockMove(gCurrentMove, gBattlerAttacker, battlerId)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battlerId, gCurrentMove)
&& IsBattlerAlive(gBattlerAttacker)
&& CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item)
&& gBattleMons[gBattlerAttacker].item == ITEM_NONE)
@ -7603,6 +7680,22 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
basePower *= 2;
#endif
break;
case EFFECT_HIDDEN_POWER:
{
#if B_HIDDEN_POWER_DMG < GEN_6
u8 powerBits;
powerBits = ((gBattleMons[gBattlerAttacker].hpIV & 2) >> 1)
| ((gBattleMons[gBattlerAttacker].attackIV & 2) << 0)
| ((gBattleMons[gBattlerAttacker].defenseIV & 2) << 1)
| ((gBattleMons[gBattlerAttacker].speedIV & 2) << 2)
| ((gBattleMons[gBattlerAttacker].spAttackIV & 2) << 3)
| ((gBattleMons[gBattlerAttacker].spDefenseIV & 2) << 4);
basePower = (40 * powerBits) / 63 + 30;
#endif
break;
}
}
// move-specific base power changes
@ -8475,6 +8568,13 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt
if (gProtectStructs[battlerDef].kingsShielded && gBattleMoves[move].effect != EFFECT_FEINT)
mod = UQ_4_12(1.0);
// WEATHER_STRONG_WINDS weakens Super Effective moves against Flying-type Pokémon
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_STRONG_WINDS)
{
if (defType == TYPE_FLYING && mod >= UQ_4_12(2.0))
mod = UQ_4_12(1.0);
}
MulModifier(modifier, mod);
}

View File

@ -3753,7 +3753,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] =
[MOVE_HIDDEN_POWER] =
{
#if B_UPDATED_MOVE_DATA >= GEN_6
#if B_HIDDEN_POWER_DMG >= GEN_6
.power = 60,
#else
.power = 1,

View File

@ -1312,11 +1312,14 @@ const u32 gUnknown_08D85A1C[] = INCBIN_U32("graphics/battle_frontier/battle_tile
#include "data/graphics/intro_scene.h"
const u32 gBattleAnimSpriteGfx_FlyingDirt[] = INCBIN_U32("graphics/battle_anims/sprites/flying_dirt.4bpp.lz");
const u32 gBattleAnimSpritePal_FlyingDirt[] = INCBIN_U32("graphics/battle_anims/sprites/flying_dirt.gbapal.lz");
const u32 gBattleAnimBgTilemap_Sandstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/sandstorm_brew.bin.lz");
const u32 gBattleAnimBgImage_Sandstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/sandstorm_brew.4bpp.lz");
const u32 gBattleAnimSpritePal_FlyingDirt[] = INCBIN_U32("graphics/battle_anims/sprites/flying_dirt.gbapal.lz");
const u32 gBattleAnimBgTilemap_Windstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/sandstorm_brew.bin.lz");
const u32 gBattleAnimBgImage_Windstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/windstorm_brew.4bpp.lz");
const u32 gBattleAnimSpritePal_Windstorm[] = INCBIN_U32("graphics/battle_anims/backgrounds/windstorm_brew.gbapal.lz");
const u32 gBattleAnimSpriteGfx_MetalSoundWaves[] = INCBIN_U32("graphics/battle_anims/sprites/metal_sound_waves.4bpp.lz");
const u32 gBattleAnimSpritePal_MetalSoundWaves[] = INCBIN_U32("graphics/battle_anims/sprites/metal_sound_waves.gbapal.lz");

View File

@ -936,42 +936,46 @@ void ItemUseOutOfBattle_EvolutionStone(u8 taskId)
SetUpItemUseCallback(taskId);
}
void ItemUseInBattle_PokeBall(u8 taskId)
u32 CanThrowBall(void)
{
if (IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))
&& IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))) // There are two present pokemon.
&& IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)))
{
static const u8 textCantThrowPokeBall[] = _("Cannot throw a ball!\nThere are two pokemon out there!\p");
if (!InBattlePyramid())
DisplayItemMessage(taskId, 1, textCantThrowPokeBall, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, textCantThrowPokeBall, Task_CloseBattlePyramidBagMessage);
return 1; // There are two present pokemon.
}
else if (gBattlerInMenuId == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)
&& IsBattlerAlive(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) // Attempting to throw a ball with the second pokemon while both are alive.
else if (IsPlayerPartyAndPokemonStorageFull() == TRUE)
{
static const u8 textCantThrowPokeBall[] = _("Cannot throw a ball!\p");
if (!InBattlePyramid())
DisplayItemMessage(taskId, 1, textCantThrowPokeBall, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, textCantThrowPokeBall, Task_CloseBattlePyramidBagMessage);
return 2; // No room for mon
}
else if (IsPlayerPartyAndPokemonStorageFull() == FALSE) // have room for mon?
return 0; // usable
}
static const u8 sText_CantThrowPokeBall_TwoMons[] = _("Cannot throw a ball!\nThere are two pokemon out there!\p");
void ItemUseInBattle_PokeBall(u8 taskId)
{
switch (CanThrowBall())
{
case 0: // usable
default:
RemoveBagItem(gSpecialVar_ItemId, 1);
if (!InBattlePyramid())
Task_FadeAndCloseBagMenu(taskId);
else
CloseBattlePyramidBag(taskId);
}
else
{
break;
case 1: // There are two present pokemon.
if (!InBattlePyramid())
DisplayItemMessage(taskId, 1, sText_CantThrowPokeBall_TwoMons, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, sText_CantThrowPokeBall_TwoMons, Task_CloseBattlePyramidBagMessage);
break;
case 2: // No room for mon
if (!InBattlePyramid())
DisplayItemMessage(taskId, 1, gText_BoxFull, CloseItemMessage);
else
DisplayItemMessageInBattlePyramid(taskId, gText_BoxFull, Task_CloseBattlePyramidBagMessage);
break;
}
}

View File

@ -45,6 +45,7 @@
#include "berry_powder.h"
#include "mevent.h"
#include "union_room_chat.h"
#include "constants/items.h"
extern const u8 EventScript_ResetAllMapFlags[];