Merge branch 'master' into master-to-upcoming
Conflicts: data/battle_scripts_1.s include/battle_util.h include/constants/battle.h src/battle_script_commands.c src/battle_util.c
This commit is contained in:
commit
a2ef3284dd
@ -441,6 +441,15 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "MandL27",
|
||||
"name": "MandL27",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/10366615?v=4",
|
||||
"profile": "https://github.com/MandL27",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@ -74,6 +74,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ghostyboyy97"><img src="https://avatars.githubusercontent.com/u/106448956?v=4?s=100" width="100px;" alt="ghostyboyy97"/><br /><sub><b>ghostyboyy97</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=ghostyboyy97" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="http://hashtagmarky.github.io"><img src="https://avatars.githubusercontent.com/u/143505183?v=4?s=100" width="100px;" alt="Marky"/><br /><sub><b>Marky</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=HashtagMarky" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MandL27"><img src="https://avatars.githubusercontent.com/u/10366615?v=4?s=100" width="100px;" alt="MandL27"/><br /><sub><b>MandL27</b></sub></a><br /><a href="https://github.com/rh-hideout/pokeemerald-expansion/commits?author=MandL27" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
|
||||
@ -2536,6 +2536,7 @@ BattleScript_CantMakeAsleep::
|
||||
|
||||
BattleScript_EffectAbsorbLiquidOoze::
|
||||
call BattleScript_AbilityPopUpTarget
|
||||
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_EffectAbsorbRet
|
||||
goto BattleScript_EffectAbsorb
|
||||
|
||||
BattleScript_EffectAbsorb::
|
||||
@ -2544,6 +2545,7 @@ BattleScript_EffectAbsorb::
|
||||
printfromtable gAbsorbDrainStringIds
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
tryfaintmon BS_ATTACKER
|
||||
BattleScript_EffectAbsorbRet:
|
||||
return
|
||||
|
||||
BattleScript_EffectExplosion::
|
||||
@ -4945,10 +4947,12 @@ BattleScript_LeechSeedTurnDrainLiquidOoze::
|
||||
copybyte gBattlerAbility, gBattlerAttacker
|
||||
call BattleScript_AbilityPopUp
|
||||
copybyte gBattlerAttacker, gBattlerTarget @ needed to get liquid ooze message correct
|
||||
jumpifability BS_TARGET, ABILITY_MAGIC_GUARD, BattleScript_LeechSeedTurnDrainHealBlockEnd2
|
||||
goto BattleScript_LeechSeedTurnDrainGainHp
|
||||
|
||||
BattleScript_LeechSeedTurnDrainHealBlock::
|
||||
call BattleScript_LeechSeedTurnDrain
|
||||
BattleScript_LeechSeedTurnDrainHealBlockEnd2:
|
||||
end2
|
||||
|
||||
BattleScript_LeechSeedTurnDrainRecovery::
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 914 B After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 728 B After Width: | Height: | Size: 567 B |
@ -35,6 +35,7 @@ void SetGimmickAsActivated(u32 battler, enum Gimmick gimmick);
|
||||
void ChangeGimmickTriggerSprite(u32 spriteId, u32 animId);
|
||||
void CreateGimmickTriggerSprite(u32 battler);
|
||||
bool32 IsGimmickTriggerSpriteActive(void);
|
||||
bool32 IsGimmickTriggerSpriteMatchingBattler(u32 battler);
|
||||
void HideGimmickTriggerSprite(void);
|
||||
void DestroyGimmickTriggerSprite(void);
|
||||
|
||||
|
||||
@ -423,6 +423,7 @@ bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, enum Ability abil
|
||||
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, enum Ability atkAbility, enum Ability defAbility, enum HoldEffect atkHoldEffect, enum HoldEffect defHoldEffect);
|
||||
bool32 IsSemiInvulnerable(u32 battler, enum SemiInvulnerableExclusion excludeCommander);
|
||||
bool32 BreaksThroughSemiInvulnerablity(u32 battler, u32 move);
|
||||
bool32 HasPartnerTrainer(u32 battler);
|
||||
u32 GetNaturePowerMove(u32 battler);
|
||||
u32 GetNaturePowerMove(u32 battler);
|
||||
void RemoveAbilityFlags(u32 battler);
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#define P_SUMMARY_SCREEN_RENAME TRUE // If TRUE, an option to change Pokémon nicknames replaces the cancel prompt on the summary screen info page.
|
||||
#define P_SUMMARY_SCREEN_IV_EV_INFO FALSE // If TRUE, will allow player to cycle through the Stats, IVs, and EVs in the summary screen skills page.
|
||||
#define P_SUMMARY_SCREEN_IV_EV_BOX_ONLY FALSE // If TRUE, will allow player to cycle through the Stats, IVs, and EVs in the summary screen skills page, but only in the PC storage box.
|
||||
#define P_SUMMARY_SCREEN_IV_HYPERTRAIN TRUE // If TRUE, stats that have been hyper trained will show as 31/S when viewing them in the summary screen
|
||||
#define P_SUMMARY_SCREEN_IV_EV_TILESET FALSE // If TRUE, loads an alternate tileset to allow changing the "STATS" label in the summary screen skills page. Note: if it's still loading the alternate tileset after changing this and recompiling, you may need a `make clean` before compilation.
|
||||
#define P_SUMMARY_SCREEN_IV_EV_VALUES FALSE // If TRUE, will show the actual IV value instead of the letter grade.
|
||||
/*
|
||||
|
||||
@ -103,6 +103,7 @@ enum BattleSide
|
||||
#define BATTLE_TWO_VS_ONE_OPPONENT ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && TRAINER_BATTLE_PARAM.opponentB == 0xFFFF))
|
||||
#define BATTLE_TYPE_HAS_AI (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER | BATTLE_TYPE_INGAME_PARTNER)
|
||||
#define BATTLE_TYPE_MORE_THAN_TWO_BATTLERS (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_TWO_OPPONENTS)
|
||||
#define BATTLE_TYPE_PLAYER_HAS_PARTNER (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_TOWER_LINK_MULTI)
|
||||
|
||||
// Multibattle test composite flags
|
||||
#define BATTLE_MULTI_TEST (BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS)
|
||||
|
||||
@ -1119,7 +1119,7 @@ bool32 ShouldSwitch(u32 battler)
|
||||
|
||||
if (IsDoubleBattle())
|
||||
{
|
||||
u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerAtPosition(battler)));
|
||||
u32 partner = BATTLE_PARTNER(battler);
|
||||
battlerIn1 = battler;
|
||||
if (gAbsentBattlerFlags & (1u << partner))
|
||||
battlerIn2 = battler;
|
||||
@ -1270,7 +1270,7 @@ void ModifySwitchAfterMoveScoring(u32 battler)
|
||||
|
||||
if (IsDoubleBattle())
|
||||
{
|
||||
u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerAtPosition(battler)));
|
||||
u32 partner = BATTLE_PARTNER(battler);
|
||||
battlerIn1 = battler;
|
||||
if (gAbsentBattlerFlags & (1u << partner))
|
||||
battlerIn2 = battler;
|
||||
@ -1318,7 +1318,7 @@ bool32 IsSwitchinValid(u32 battler)
|
||||
// Edge case: See if partner already chose to switch into the same mon
|
||||
if (IsDoubleBattle())
|
||||
{
|
||||
u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerAtPosition(battler)));
|
||||
u32 partner = BATTLE_PARTNER(battler);
|
||||
if (gBattleStruct->AI_monToSwitchIntoId[battler] == PARTY_SIZE) // Generic switch
|
||||
{
|
||||
if ((gAiLogicData->shouldSwitch & (1u << partner)) && gAiLogicData->monToSwitchInId[partner] == gAiLogicData->mostSuitableMonId[battler])
|
||||
|
||||
@ -891,7 +891,7 @@ static inline bool32 ShouldCalcCritDamage(u32 battlerAtk, u32 battlerDef, u32 mo
|
||||
|
||||
struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef, u32 weather)
|
||||
{
|
||||
struct SimulatedDamage simDamage;
|
||||
struct SimulatedDamage simDamage = {0};
|
||||
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
|
||||
bool32 isDamageMoveUnusable = FALSE;
|
||||
bool32 toggledGimmickAtk = FALSE;
|
||||
@ -924,7 +924,7 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u
|
||||
gBattleStruct->magnitudeBasePower = 70;
|
||||
gBattleStruct->presentBasePower = 80;
|
||||
|
||||
struct DamageContext ctx;
|
||||
struct DamageContext ctx = {0};
|
||||
ctx.battlerAtk = battlerAtk;
|
||||
ctx.battlerDef = battlerDef;
|
||||
ctx.move = move;
|
||||
|
||||
@ -455,6 +455,12 @@ void HandleInputChooseTarget(u32 battler)
|
||||
PlaySE(SE_SELECT);
|
||||
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_HideAsMoveTarget;
|
||||
gBattlerControllerFuncs[battler] = HandleInputChooseMove;
|
||||
if (gBattleStruct->gimmick.playerSelect == 1 && gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_Z_MOVE)
|
||||
{
|
||||
gBattleStruct->gimmick.playerSelect = 0;
|
||||
gBattleStruct->zmove.viewing = TRUE;
|
||||
ReloadMoveNames(battler);
|
||||
}
|
||||
DoBounceEffect(battler, BOUNCE_HEALTHBOX, 7, 1);
|
||||
DoBounceEffect(battler, BOUNCE_MON, 7, 1);
|
||||
EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX);
|
||||
@ -2100,6 +2106,8 @@ void PlayerHandleChooseMove(u32 battler)
|
||||
|
||||
if (!IsGimmickTriggerSpriteActive())
|
||||
gBattleStruct->gimmick.triggerSpriteId = 0xFF;
|
||||
else if (!IsGimmickTriggerSpriteMatchingBattler(battler))
|
||||
DestroyGimmickTriggerSprite();
|
||||
if (!(gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_Z_MOVE && !gBattleStruct->zmove.viable))
|
||||
CreateGimmickTriggerSprite(battler);
|
||||
|
||||
|
||||
@ -298,13 +298,12 @@ static bool32 HandleEndTurnEmergencyExit(u32 battler)
|
||||
&& IsBattlerAlive(battler)
|
||||
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
|
||||
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||||
&& CountUsablePartyMons(battler) > 0
|
||||
&& gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP) // Not currently held by Sky Drop
|
||||
{
|
||||
gBattlerAbility = battler;
|
||||
gLastUsedAbility = ability;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER || IsOnPlayerSide(battler))
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
||||
BattleScriptExecute(BattleScript_EmergencyExitEnd2);
|
||||
else
|
||||
BattleScriptExecute(BattleScript_EmergencyExitWildEnd2);
|
||||
|
||||
@ -178,6 +178,13 @@ bool32 IsGimmickTriggerSpriteActive(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsGimmickTriggerSpriteMatchingBattler(u32 battler)
|
||||
{
|
||||
if (battler == gSprites[gBattleStruct->gimmick.triggerSpriteId].tBattler)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void HideGimmickTriggerSprite(void)
|
||||
{
|
||||
if (gBattleStruct->gimmick.triggerSpriteId != 0xFF)
|
||||
|
||||
@ -3237,6 +3237,9 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy)
|
||||
gBattleStruct->battlerState[battler].stompingTantrumTimer = 0;
|
||||
gBattleStruct->palaceFlags &= ~(1u << battler);
|
||||
gBattleStruct->battlerState[battler].canPickupItem = FALSE;
|
||||
gBattleStruct->hazardsCounter = 0;
|
||||
gDisableStructs[battler].hazardsDone = FALSE;
|
||||
gSpecialStatuses[battler].switchInItemDone = FALSE;
|
||||
|
||||
ClearPursuitValuesIfSet(battler);
|
||||
|
||||
|
||||
@ -1098,7 +1098,6 @@ bool32 EmergencyExitCanBeTriggered(u32 battler)
|
||||
&& HadMoreThanHalfHpNowDoesnt(battler)
|
||||
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
|
||||
&& !(gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||||
&& CountUsablePartyMons(battler) > 0
|
||||
&& gBattleMons[battler].volatiles.semiInvulnerable != STATE_SKY_DROP)
|
||||
return TRUE;
|
||||
|
||||
@ -6696,7 +6695,7 @@ static void Cmd_moveend(void)
|
||||
effect = TRUE;
|
||||
gBattleScripting.battler = battler;
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER || IsOnPlayerSide(battler))
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
||||
BattleScriptCall(BattleScript_EmergencyExit);
|
||||
else
|
||||
BattleScriptCall(BattleScript_EmergencyExitWild);
|
||||
@ -15386,9 +15385,7 @@ void BS_TryAllySwitch(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *failInstr);
|
||||
|
||||
if (!IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))
|
||||
|| (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
||||
|| (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))
|
||||
if (!IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)) || HasPartnerTrainer(gBattlerAttacker))
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
@ -16831,11 +16828,14 @@ void BS_ArenaJudgmentWindow(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
static void SetArenMonLostValues(u32 battler)
|
||||
static void SetArenMonLostValues(u32 battler, u32 side)
|
||||
{
|
||||
gBattleMons[battler].hp = 0;
|
||||
gHitMarker |= HITMARKER_FAINTED(battler);
|
||||
gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[battler];
|
||||
if (side == B_SIDE_PLAYER)
|
||||
gBattleStruct->arenaLostPlayerMons |= 1u << gBattlerPartyIndexes[battler];
|
||||
else
|
||||
gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[battler];
|
||||
gDisableStructs[battler].truantSwitchInHack = TRUE;
|
||||
}
|
||||
|
||||
@ -16844,22 +16844,22 @@ static void SetArenMonLostValues(u32 battler)
|
||||
void BS_ArenaOpponentMonLost(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
SetArenMonLostValues(opponentMon);
|
||||
SetArenMonLostValues(opponentMon, B_SIDE_OPPONENT);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_ArenaPlayerMonLost(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
SetArenMonLostValues(playerMon);
|
||||
SetArenMonLostValues(playerMon, B_SIDE_PLAYER);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_ArenaBothMonsLost(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
SetArenMonLostValues(playerMon);
|
||||
SetArenMonLostValues(opponentMon);
|
||||
SetArenMonLostValues(playerMon, B_SIDE_PLAYER);
|
||||
SetArenMonLostValues(opponentMon, B_SIDE_OPPONENT);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
#undef playerMon
|
||||
|
||||
@ -1990,7 +1990,7 @@ void DoSpecialTrainerBattle(void)
|
||||
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS;
|
||||
break;
|
||||
case FRONTIER_MODE_LINK_MULTIS:
|
||||
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_MULTI | BATTLE_TYPE_TOWER_LINK_MULTI;
|
||||
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_MULTI | BATTLE_TYPE_TOWER_LINK_MULTI | BATTLE_TYPE_TWO_OPPONENTS;
|
||||
FillFrontierTrainersParties(FRONTIER_MULTI_PARTY_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -10771,6 +10771,15 @@ bool32 BreaksThroughSemiInvulnerablity(u32 battler, u32 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 HasPartnerTrainer(u32 battler)
|
||||
{
|
||||
if ((GetBattlerSide(battler) == B_SIDE_PLAYER && gBattleTypeFlags & BATTLE_TYPE_PLAYER_HAS_PARTNER)
|
||||
|| (GetBattlerSide(battler) == B_SIDE_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u32 GetMirrorMoveMove(void)
|
||||
{
|
||||
s32 i, validMovesCount;
|
||||
|
||||
@ -12522,7 +12522,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
||||
SIZE_32x32,
|
||||
SHADOW_SIZE_M,
|
||||
TRACKS_FOOT,
|
||||
sAnimTable_Following,
|
||||
sAnimTable_Following_Asym,
|
||||
gOverworldPalette_Krabby,
|
||||
gShinyOverworldPalette_Krabby
|
||||
)
|
||||
@ -12592,7 +12592,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
|
||||
SIZE_32x32,
|
||||
SHADOW_SIZE_M,
|
||||
TRACKS_FOOT,
|
||||
sAnimTable_Following,
|
||||
sAnimTable_Following_Asym,
|
||||
gOverworldPalette_Kingler,
|
||||
gShinyOverworldPalette_Kingler
|
||||
)
|
||||
|
||||
@ -22,12 +22,13 @@
|
||||
#include "item.h"
|
||||
#include "item_icon.h"
|
||||
#include "link.h"
|
||||
#include "load_save.h"
|
||||
#include "list_menu.h"
|
||||
#include "load_save.h"
|
||||
#include "main.h"
|
||||
#include "mystery_gift.h"
|
||||
#include "match_call.h"
|
||||
#include "menu.h"
|
||||
#include "metatile_behavior.h"
|
||||
#include "mystery_gift.h"
|
||||
#include "overworld.h"
|
||||
#include "party_menu.h"
|
||||
#include "pokeblock.h"
|
||||
@ -985,7 +986,7 @@ void FieldShowRegionMap(void)
|
||||
|
||||
static bool32 IsBuildingPCTile(u32 tileId)
|
||||
{
|
||||
return gMapHeader.mapLayout->primaryTileset == &gTileset_Building && (tileId == METATILE_Building_PC_On || tileId == METATILE_Building_PC_Off);
|
||||
return (MetatileBehavior_IsPC(UNPACK_BEHAVIOR(GetMetatileAttributesById(tileId))));
|
||||
}
|
||||
|
||||
static bool32 IsPlayerHousePCTile(u32 tileId)
|
||||
|
||||
@ -333,6 +333,7 @@ static const u8 *GetLetterGrade(u32 stat);
|
||||
static u8 AddWindowFromTemplateList(const struct WindowTemplate *template, u8 templateId);
|
||||
static u8 IncrementSkillsStatsMode(u8 mode);
|
||||
static void ClearStatLabel(u32 length, u32 statsCoordX, u32 statsCoordY);
|
||||
u32 GetAdjustedIvData(struct Pokemon *mon, u32 stat);
|
||||
|
||||
static const struct BgTemplate sBgTemplates[] =
|
||||
{
|
||||
@ -1172,6 +1173,13 @@ static void DestroyCategoryIcon(void)
|
||||
sMonSummaryScreen->categoryIconSpriteId = 0xFF;
|
||||
}
|
||||
|
||||
u32 GetAdjustedIvData(struct Pokemon *mon, u32 stat)
|
||||
{
|
||||
if (P_SUMMARY_SCREEN_IV_HYPERTRAIN && GetMonData(mon, MON_DATA_HYPER_TRAINED_HP + stat))
|
||||
return MAX_PER_STAT_IVS;
|
||||
return GetMonData(mon, MON_DATA_HP_IV + stat);
|
||||
}
|
||||
|
||||
void ShowPokemonSummaryScreen(u8 mode, void *mons, u8 monIndex, u8 maxMonIndex, void (*callback)(void))
|
||||
{
|
||||
sMonSummaryScreen = AllocZeroed(sizeof(*sMonSummaryScreen));
|
||||
@ -1863,12 +1871,12 @@ void ExtractMonSkillStatsData(struct Pokemon *mon, struct PokeSummary *sum)
|
||||
|
||||
void ExtractMonSkillIvData(struct Pokemon *mon, struct PokeSummary *sum)
|
||||
{
|
||||
sum->currentHP = GetMonData(mon, MON_DATA_HP_IV);
|
||||
sum->atk = GetMonData(mon, MON_DATA_ATK_IV);
|
||||
sum->def = GetMonData(mon, MON_DATA_DEF_IV);
|
||||
sum->spatk = GetMonData(mon, MON_DATA_SPATK_IV);
|
||||
sum->spdef = GetMonData(mon, MON_DATA_SPDEF_IV);
|
||||
sum->speed = GetMonData(mon, MON_DATA_SPEED_IV);
|
||||
sum->currentHP = GetAdjustedIvData(mon, STAT_HP);
|
||||
sum->atk = GetAdjustedIvData(mon, STAT_ATK);
|
||||
sum->def = GetAdjustedIvData(mon, STAT_DEF);
|
||||
sum->spatk = GetAdjustedIvData(mon, STAT_SPATK);
|
||||
sum->spdef = GetAdjustedIvData(mon, STAT_SPDEF);
|
||||
sum->speed = GetAdjustedIvData(mon, STAT_SPEED);
|
||||
}
|
||||
|
||||
void ExtractMonSkillEvData(struct Pokemon *mon, struct PokeSummary *sum)
|
||||
|
||||
@ -108,3 +108,69 @@ SINGLE_BATTLE_TEST("Emergency Exit activates when taking residual damage and fal
|
||||
ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
|
||||
}
|
||||
}
|
||||
|
||||
WILD_BATTLE_TEST("Emergency Exit makes the pokemon flee during wild battle")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(262); };
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUPER_FANG);}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, player);
|
||||
HP_BAR(opponent);
|
||||
ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
|
||||
} THEN {
|
||||
EXPECT_EQ(gBattleOutcome, B_OUTCOME_MON_TELEPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
WILD_BATTLE_TEST("Emergency Exit activates when taking residual damage and falling under 50% max-hp (wild battle)")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(134); Status1(STATUS1_BURN); };
|
||||
} WHEN {
|
||||
TURN { }
|
||||
} SCENE {
|
||||
HP_BAR(opponent);
|
||||
ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
|
||||
} THEN {
|
||||
EXPECT_EQ(gBattleOutcome, B_OUTCOME_MON_TELEPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
WILD_BATTLE_TEST("Emergency Exit makes the player ran during wild battle")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(262); };
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SUPER_FANG);}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, opponent);
|
||||
HP_BAR(player);
|
||||
ABILITY_POPUP(player, ABILITY_EMERGENCY_EXIT);
|
||||
} THEN {
|
||||
EXPECT_EQ(gBattleOutcome, B_OUTCOME_PLAYER_TELEPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
WILD_BATTLE_TEST("Emergency Exit activates when taking residual damage and falling under 50% max-hp (wild battle player side)")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(134); };
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SANDSTORM);}
|
||||
} SCENE {
|
||||
HP_BAR(player);
|
||||
ABILITY_POPUP(player, ABILITY_EMERGENCY_EXIT);
|
||||
} THEN {
|
||||
EXPECT_EQ(gBattleOutcome, B_OUTCOME_PLAYER_TELEPORTED);
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,3 +187,34 @@ SINGLE_BATTLE_TEST("Liquid Ooze does not cause Dream Eater users to lose HP inst
|
||||
EXPECT_LT(damage, 0); // Negative damage = Heal
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Liquid Ooze HP loss from Absorb is blocked by Magic Guard")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CLEFFA) { Ability(ABILITY_MAGIC_GUARD); }
|
||||
OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ABSORB); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player);
|
||||
HP_BAR(opponent);
|
||||
NONE_OF {
|
||||
HP_BAR(player);
|
||||
MESSAGE("Wobbuffet sucked up the liquid ooze!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Liquid Ooze HP loss from Leech Seed is blocked by Magic Guard")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_CLEFFA) { Ability(ABILITY_MAGIC_GUARD); }
|
||||
OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_LEECH_SEED); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player);
|
||||
HP_BAR(opponent);
|
||||
NOT HP_BAR(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,3 +38,26 @@ SINGLE_BATTLE_TEST("Hazards are applied based on order of set up")
|
||||
EXPECT_EQ(gBattleStruct->hazardsQueue[0][5], HAZARDS_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Hazards are applied correctly after a battler faints")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveEffect(MOVE_FINAL_GAMBIT) == EFFECT_FINAL_GAMBIT);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_STEALTH_ROCK);
|
||||
MOVE(player, MOVE_FINAL_GAMBIT);
|
||||
SEND_OUT(player, 1);
|
||||
SEND_OUT(player, 2); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FINAL_GAMBIT, player);
|
||||
MESSAGE("Wynaut fainted!");
|
||||
MESSAGE("Pointed stones dug into Wobbuffet!");
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
MESSAGE("Pointed stones dug into Wynaut!");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user