mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 19:47:35 +01:00
Merge branch 'upcoming' of https://github.com/rh-hideout/pokeemerald-expansion into trainerSlideMsgUpdate
This commit is contained in:
commit
a54a8d9b2a
@ -10338,3 +10338,8 @@ BattleScript_PokemonCantUseTheMove::
|
||||
printstring STRINGID_BUTPOKEMONCANTUSETHEMOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_CouldntFullyProtect::
|
||||
printstring STRINGID_COULDNTFULLYPROTECT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
return
|
||||
|
@ -192,16 +192,30 @@ BattleScript_ActionWallyThrow:
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
|
||||
BattleScript_TrainerSlideMsgRet::
|
||||
BattleScript_TrainerASlideMsgRet::
|
||||
handletrainerslidemsg BS_SCRIPTING, 0
|
||||
trainerslidein 1
|
||||
trainerslidein B_POSITION_OPPONENT_LEFT
|
||||
handletrainerslidemsg BS_SCRIPTING, 1
|
||||
waitstate
|
||||
trainerslideout 1
|
||||
handletrainerslidemsg BS_SCRIPTING, 2
|
||||
trainerslideout B_POSITION_OPPONENT_LEFT
|
||||
waitstate
|
||||
handletrainerslidemsg BS_SCRIPTING, 2
|
||||
return
|
||||
|
||||
BattleScript_TrainerSlideMsgEnd2::
|
||||
call BattleScript_TrainerSlideMsgRet
|
||||
BattleScript_TrainerASlideMsgEnd2::
|
||||
call BattleScript_TrainerASlideMsgRet
|
||||
end2
|
||||
|
||||
BattleScript_TrainerBSlideMsgRet::
|
||||
handletrainerslidemsg BS_SCRIPTING, 0
|
||||
trainerslidein B_POSITION_OPPONENT_RIGHT
|
||||
handletrainerslidemsg BS_SCRIPTING, 1
|
||||
waitstate
|
||||
trainerslideout B_POSITION_OPPONENT_RIGHT
|
||||
waitstate
|
||||
handletrainerslidemsg BS_SCRIPTING, 2
|
||||
return
|
||||
|
||||
BattleScript_TrainerBSlideMsgEnd2::
|
||||
call BattleScript_TrainerBSlideMsgRet
|
||||
end2
|
||||
|
@ -252,6 +252,7 @@ struct AI_SavedBattleMon
|
||||
u16 moves[MAX_MON_MOVES];
|
||||
u16 heldItem;
|
||||
u16 species;
|
||||
u8 types[3];
|
||||
};
|
||||
|
||||
struct AiPartyMon
|
||||
|
@ -244,7 +244,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst);
|
||||
void BattlePutTextOnWindow(const u8 *text, u8 windowId);
|
||||
void SetPpNumbersPaletteInMoveSelection(void);
|
||||
u8 GetCurrentPpToMaxPpState(u8 currentPp, u8 maxPp);
|
||||
bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which);
|
||||
u32 ShouldDoTrainerSlide(u32 battlerId, u32 which); // return 1 for TrainerA, 2 forTrainerB
|
||||
void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst);
|
||||
|
||||
extern struct BattleMsgData *gBattleMsgDataPtr;
|
||||
|
@ -295,8 +295,10 @@ extern const u8 BattleScript_MoveEffectClearSmog[];
|
||||
extern const u8 BattleScript_SideStatusWoreOffReturn[];
|
||||
extern const u8 BattleScript_MoveEffectSmackDown[];
|
||||
extern const u8 BattleScript_MoveEffectFlameBurst[];
|
||||
extern const u8 BattleScript_TrainerSlideMsgRet[];
|
||||
extern const u8 BattleScript_TrainerSlideMsgEnd2[];
|
||||
extern const u8 BattleScript_TrainerASlideMsgRet[];
|
||||
extern const u8 BattleScript_TrainerASlideMsgEnd2[];
|
||||
extern const u8 BattleScript_TrainerBSlideMsgRet[];
|
||||
extern const u8 BattleScript_TrainerBSlideMsgEnd2[];
|
||||
extern const u8 BattleScript_MoveEffectFeint[];
|
||||
extern const u8 BattleScript_ProteanActivates[];
|
||||
extern const u8 BattleScript_DazzlingProtected[];
|
||||
@ -453,6 +455,7 @@ extern const u8 BattleScript_DampPreventsAftermath[];
|
||||
extern const u8 BattleScript_HealingWishActivates[];
|
||||
extern const u8 BattleScript_LunarDanceActivates[];
|
||||
extern const u8 BattleScript_ShellTrapSetUp[];
|
||||
extern const u8 BattleScript_CouldntFullyProtect[];
|
||||
|
||||
// zmoves
|
||||
extern const u8 BattleScript_ZMoveActivateDamaging[];
|
||||
|
@ -641,8 +641,9 @@
|
||||
#define STRINGID_PKMNSABILITYPREVENTSABILITY 639
|
||||
#define STRINGID_PREPARESHELLTRAP 640
|
||||
#define STRINGID_SHELLTRAPDIDNTWORK 641
|
||||
#define STRINGID_COULDNTFULLYPROTECT 642
|
||||
|
||||
#define BATTLESTRINGS_COUNT 642
|
||||
#define BATTLESTRINGS_COUNT 643
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
@ -538,23 +538,73 @@ void SaveBattlerData(u8 battlerId)
|
||||
AI_THINKING_STRUCT->saved[battlerId].species = gBattleMons[battlerId].species;
|
||||
for (i = 0; i < 4; i++)
|
||||
AI_THINKING_STRUCT->saved[battlerId].moves[i] = gBattleMons[battlerId].moves[i];
|
||||
AI_THINKING_STRUCT->saved[battlerId].types[0] = gBattleMons[battlerId].type1;
|
||||
AI_THINKING_STRUCT->saved[battlerId].types[1] = gBattleMons[battlerId].type2;
|
||||
}
|
||||
}
|
||||
|
||||
static bool32 ShouldFailForIllusion(u16 illusionSpecies, u32 battlerId)
|
||||
{
|
||||
u32 i, j;
|
||||
|
||||
if (BATTLE_HISTORY->abilities[battlerId] == ABILITY_ILLUSION)
|
||||
return FALSE;
|
||||
|
||||
// Don't fall for Illusion if the mon used a move it cannot know.
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
u16 move = BATTLE_HISTORY->usedMoves[battlerId][i];
|
||||
if (move == MOVE_NONE)
|
||||
continue;
|
||||
|
||||
for (j = 0; gLevelUpLearnsets[illusionSpecies][j].move != MOVE_UNAVAILABLE; j++)
|
||||
{
|
||||
if (gLevelUpLearnsets[illusionSpecies][j].move == move)
|
||||
break;
|
||||
}
|
||||
// The used move is in the learnsets of the fake species.
|
||||
if (gLevelUpLearnsets[illusionSpecies][j].move != MOVE_UNAVAILABLE)
|
||||
continue;
|
||||
|
||||
// The used move can be learned from Tm/Hm or Move Tutors.
|
||||
if (CanLearnTeachableMove(illusionSpecies, move))
|
||||
continue;
|
||||
|
||||
// 'Illegal move', AI won't fail for the illusion.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void SetBattlerData(u8 battlerId)
|
||||
{
|
||||
if (!IsBattlerAIControlled(battlerId))
|
||||
{
|
||||
struct Pokemon *illusionMon;
|
||||
u32 i;
|
||||
u32 i, species, illusionSpecies;
|
||||
|
||||
// Simulate Illusion
|
||||
species = gBattleMons[battlerId].species;
|
||||
illusionSpecies = GetIllusionMonSpecies(battlerId);
|
||||
if (illusionSpecies != SPECIES_NONE && ShouldFailForIllusion(illusionSpecies, battlerId))
|
||||
{
|
||||
// If the battler's type has not been changed, AI assumes the types of the illusion mon.
|
||||
if (gBattleMons[battlerId].type1 == gSpeciesInfo[species].types[0]
|
||||
&& gBattleMons[battlerId].type2 == gSpeciesInfo[species].types[1])
|
||||
{
|
||||
gBattleMons[battlerId].type1 = gSpeciesInfo[illusionSpecies].types[0];
|
||||
gBattleMons[battlerId].type2 = gSpeciesInfo[illusionSpecies].types[1];
|
||||
}
|
||||
species = illusionSpecies;
|
||||
}
|
||||
|
||||
// Use the known battler's ability.
|
||||
if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE)
|
||||
gBattleMons[battlerId].ability = BATTLE_HISTORY->abilities[battlerId];
|
||||
// Check if mon can only have one ability.
|
||||
else if (gSpeciesInfo[gBattleMons[battlerId].species].abilities[1] == ABILITY_NONE
|
||||
|| gSpeciesInfo[gBattleMons[battlerId].species].abilities[1] == gSpeciesInfo[gBattleMons[battlerId].species].abilities[0])
|
||||
gBattleMons[battlerId].ability = gSpeciesInfo[gBattleMons[battlerId].species].abilities[0];
|
||||
else if (gSpeciesInfo[species].abilities[1] == ABILITY_NONE
|
||||
|| 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;
|
||||
@ -567,10 +617,6 @@ void SetBattlerData(u8 battlerId)
|
||||
if (BATTLE_HISTORY->usedMoves[battlerId][i] == 0)
|
||||
gBattleMons[battlerId].moves[i] = 0;
|
||||
}
|
||||
|
||||
// Simulate Illusion
|
||||
if ((illusionMon = GetIllusionMonPtr(battlerId)) != NULL)
|
||||
gBattleMons[battlerId].species = GetMonData(illusionMon, MON_DATA_SPECIES2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,6 +631,8 @@ void RestoreBattlerData(u8 battlerId)
|
||||
gBattleMons[battlerId].species = AI_THINKING_STRUCT->saved[battlerId].species;
|
||||
for (i = 0; i < 4; i++)
|
||||
gBattleMons[battlerId].moves[i] = AI_THINKING_STRUCT->saved[battlerId].moves[i];
|
||||
gBattleMons[battlerId].type1 = AI_THINKING_STRUCT->saved[battlerId].types[0];
|
||||
gBattleMons[battlerId].type2 = AI_THINKING_STRUCT->saved[battlerId].types[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3866,18 +3866,18 @@ void BattleTurnPassed(void)
|
||||
BattleScriptExecute(BattleScript_PalacePrintFlavorText);
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaTurnCounter == 0)
|
||||
BattleScriptExecute(BattleScript_ArenaTurnBeginning);
|
||||
else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_LOW_HP))
|
||||
BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2);
|
||||
else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_HALF_HP))
|
||||
BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2);
|
||||
else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_CRITICAL_HIT))
|
||||
BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2);
|
||||
else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_SUPER_EFFECTIVE_HIT))
|
||||
BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2);
|
||||
else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_STAB_MOVE))
|
||||
BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2);
|
||||
else if (ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), gTrainerBattleOpponent_A, TRAINER_SLIDE_PLAYER_MON_UNAFFECTED))
|
||||
BattleScriptExecute(BattleScript_TrainerSlideMsgEnd2);
|
||||
else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_LAST_LOW_HP)))
|
||||
BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2);
|
||||
else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_LAST_HALF_HP))
|
||||
BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2);
|
||||
else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_CRITICAL_HIT))
|
||||
BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2);
|
||||
else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_SUPER_EFFECTIVE_HIT))
|
||||
BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2);
|
||||
else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_FIRST_STAB_MOVE))
|
||||
BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2);
|
||||
else if ((i = ShouldDoTrainerSlide(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), TRAINER_SLIDE_PLAYER_MON_UNAFFECTED))
|
||||
BattleScriptExecute(i == 1 ? BattleScript_TrainerASlideMsgEnd2 : BattleScript_TrainerBSlideMsgEnd2);
|
||||
}
|
||||
|
||||
u8 IsRunningFromBattleImpossible(void)
|
||||
|
@ -776,9 +776,11 @@ static const u8 sText_AbilityWeakenedSurroundingMonsStat[] = _("{B_ATK_NAME_WITH
|
||||
static const u8 sText_AttackerGainedStrengthFromTheFallen[] = _("{B_ATK_NAME_WITH_PREFIX} gained strength\nfrom the fallen!");
|
||||
static const u8 sText_PrepareShellTrap[] = _("{B_ATK_NAME_WITH_PREFIX} set a shell trap!");
|
||||
static const u8 sText_ShellTrapDidntWork[] = _("{B_ATK_NAME_WITH_PREFIX}'s shell trap didn't work!");
|
||||
static const u8 sText_CouldntFullyProtect[] = _("{B_DEF_NAME_WITH_PREFIX} couldn't fully protect\nitself and got hurt!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_COULDNTFULLYPROTECT - BATTLESTRINGS_TABLE_START] = sText_CouldntFullyProtect,
|
||||
[STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN - BATTLESTRINGS_TABLE_START] = sText_AttackerGainedStrengthFromTheFallen,
|
||||
[STRINGID_ABILITYWEAKENEDFSURROUNDINGMONSSTAT - BATTLESTRINGS_TABLE_START] = sText_AbilityWeakenedSurroundingMonsStat,
|
||||
[STRINGID_ELECTRICTERRAINACTIVATEDABILITY - BATTLESTRINGS_TABLE_START] = sText_ElectricTerrainActivatedAbility,
|
||||
@ -3901,40 +3903,49 @@ static const struct TrainerSlide sTrainerSlides[] =
|
||||
*/
|
||||
};
|
||||
|
||||
static u32 GetAliveEnemyMonCount(void)
|
||||
static u32 GetEnemyMonCount(u32 firstId, u32 lastId, bool32 onlyAlive)
|
||||
{
|
||||
u32 i, count = 0;
|
||||
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
for (i = firstId; i < lastId; i++)
|
||||
{
|
||||
u32 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2, NULL);
|
||||
if (species != SPECIES_NONE && species != SPECIES_EGG && GetMonData(&gEnemyParty[i], MON_DATA_HP, NULL))
|
||||
if (species != SPECIES_NONE
|
||||
&& species != SPECIES_EGG
|
||||
&& (!onlyAlive || GetMonData(&gEnemyParty[i], MON_DATA_HP, NULL)))
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static u32 GetTotalEnemyMonCount(void)
|
||||
u32 ShouldDoTrainerSlide(u32 battlerId, u32 which)
|
||||
{
|
||||
u32 i, count = 0;
|
||||
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
{
|
||||
u32 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2, NULL);
|
||||
if (species != SPECIES_NONE && species != SPECIES_EGG)
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which)
|
||||
{
|
||||
s32 i;
|
||||
u32 i, firstId, lastId, trainerId, retValue = 1;
|
||||
|
||||
if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) || GetBattlerSide(battlerId) != B_SIDE_OPPONENT)
|
||||
return FALSE;
|
||||
return 0;
|
||||
|
||||
// Two opponents support.
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
|
||||
{
|
||||
if (gBattlerPartyIndexes[battlerId] >= 3)
|
||||
{
|
||||
firstId = 3, lastId = PARTY_SIZE;
|
||||
trainerId = gTrainerBattleOpponent_B;
|
||||
retValue = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstId = 0, lastId = 3;
|
||||
trainerId = gTrainerBattleOpponent_A;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
firstId = 0, lastId = PARTY_SIZE;
|
||||
trainerId = gTrainerBattleOpponent_A;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sTrainerSlides); i++)
|
||||
{
|
||||
@ -3944,33 +3955,33 @@ bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which)
|
||||
switch (which)
|
||||
{
|
||||
case TRAINER_SLIDE_LAST_SWITCHIN:
|
||||
if (sTrainerSlides[i].msgLastSwitchIn != NULL && GetAliveEnemyMonCount() == 1)
|
||||
if (sTrainerSlides[i].msgLastSwitchIn != NULL && !CanBattlerSwitch(battlerId))
|
||||
{
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastSwitchIn;
|
||||
return TRUE;
|
||||
return retValue;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_LAST_LOW_HP:
|
||||
if (sTrainerSlides[i].msgLastLowHp != NULL
|
||||
&& GetAliveEnemyMonCount() == 1
|
||||
&& gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 4)
|
||||
&& !gBattleStruct->trainerSlideLowHpMsgDone)
|
||||
&& GetEnemyMonCount(firstId, lastId, TRUE) == 1
|
||||
&& IsBattlerHpLow(battlerId)
|
||||
&& !gBattleStruct->trainerSlideLowHpMsgDone)
|
||||
{
|
||||
gBattleStruct->trainerSlideLowHpMsgDone = TRUE;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastLowHp;
|
||||
return TRUE;
|
||||
return retValue;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_FIRST_DOWN:
|
||||
if (sTrainerSlides[i].msgFirstDown != NULL && GetAliveEnemyMonCount() == GetTotalEnemyMonCount() - 1)
|
||||
if (sTrainerSlides[i].msgFirstDown != NULL && GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE) - 1)
|
||||
{
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstDown;
|
||||
return TRUE;
|
||||
return retValue;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_LAST_HALF_HP:
|
||||
if (sTrainerSlides[i].msgLastHalfHp != NULL
|
||||
&& GetAliveEnemyMonCount() == 1
|
||||
&& GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE) - 1
|
||||
&& (gBattleMons[battlerId].hp <= (gBattleMons[battlerId].maxHP / 2) && gBattleMons[battlerId].hp > (gBattleMons[battlerId].maxHP / 4))
|
||||
&& !gBattleStruct->trainerSlideHalfHpMsgDone)
|
||||
{
|
||||
@ -4000,7 +4011,7 @@ bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which)
|
||||
case TRAINER_SLIDE_FIRST_STAB_MOVE:
|
||||
if (sTrainerSlides[i].msgFirstSTABMove != NULL
|
||||
&& gBattleStruct->trainerSlideFirstSTABMoveMsgState == 1
|
||||
&& GetAliveEnemyMonCount() == GetTotalEnemyMonCount())
|
||||
&& GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE))
|
||||
{
|
||||
gBattleStruct->trainerSlideFirstSTABMoveMsgState = 2;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstSTABMove;
|
||||
@ -4010,7 +4021,7 @@ bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which)
|
||||
case TRAINER_SLIDE_PLAYER_MON_UNAFFECTED:
|
||||
if (sTrainerSlides[i].msgPlayerMonUnaffected != NULL
|
||||
&& gBattleStruct->trainerSlidePlayerMonUnaffectedMsgState == 1
|
||||
&& GetAliveEnemyMonCount() == GetTotalEnemyMonCount())
|
||||
&& GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE))
|
||||
{
|
||||
gBattleStruct->trainerSlidePlayerMonUnaffectedMsgState = 2;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgPlayerMonUnaffected;
|
||||
@ -4038,5 +4049,5 @@ bool32 ShouldDoTrainerSlide(u32 battlerId, u32 trainerId, u32 which)
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1591,6 +1591,14 @@ static void Cmd_attackcanceler(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// Z-moves and Max Moves bypass protection, but deal reduced damage (factored in CalcFinalDmg)
|
||||
if (gBattleStruct->zmove.active && IS_BATTLER_PROTECTED(gBattlerTarget))
|
||||
{
|
||||
BattleScriptPush(cmd->nextInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_CouldntFullyProtect;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if ((gProtectStructs[gBattlerByTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & FLAG_SNATCH_AFFECTED)
|
||||
@ -10120,7 +10128,8 @@ static void Cmd_various(void)
|
||||
VARIOUS_ARGS(u8 case_);
|
||||
if (cmd->case_ == 0)
|
||||
{
|
||||
gBattleScripting.savedDmg = gBattlerSpriteIds[gActiveBattler];
|
||||
// Save sprite IDs, because trainer slide in will overwrite gBattlerSpriteIds variable.
|
||||
gBattleScripting.savedDmg = (gBattlerSpriteIds[gActiveBattler] & 0xFF) | (gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)] << 8);
|
||||
HideBattlerShadowSprite(gActiveBattler);
|
||||
}
|
||||
else if (cmd->case_ == 1)
|
||||
@ -10130,12 +10139,19 @@ static void Cmd_various(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlerSpriteIds[gActiveBattler] = gBattleScripting.savedDmg;
|
||||
if (gBattleMons[gActiveBattler].hp != 0)
|
||||
gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)] = gBattleScripting.savedDmg >> 8;
|
||||
gBattlerSpriteIds[gActiveBattler] = gBattleScripting.savedDmg & 0xFF;
|
||||
if (IsBattlerAlive(gActiveBattler))
|
||||
{
|
||||
SetBattlerShadowSpriteCallback(gActiveBattler, gBattleMons[gActiveBattler].species);
|
||||
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
|
||||
}
|
||||
i = BATTLE_PARTNER(gActiveBattler);
|
||||
if (IsBattlerAlive(i))
|
||||
{
|
||||
SetBattlerShadowSpriteCallback(i, gBattleMons[i].species);
|
||||
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[i]], i);
|
||||
}
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
@ -10143,11 +10159,11 @@ static void Cmd_various(void)
|
||||
case VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_DOWN))
|
||||
if ((i = ShouldDoTrainerSlide(gActiveBattler, TRAINER_SLIDE_FIRST_DOWN)))
|
||||
{
|
||||
gBattleScripting.battler = gActiveBattler;
|
||||
BattleScriptPush(cmd->nextInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet;
|
||||
gBattlescriptCurrInstr = (i == 1 ? BattleScript_TrainerASlideMsgRet : BattleScript_TrainerBSlideMsgRet);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -10155,11 +10171,11 @@ static void Cmd_various(void)
|
||||
case VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON:
|
||||
{
|
||||
VARIOUS_ARGS();
|
||||
if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_SWITCHIN))
|
||||
if ((i = ShouldDoTrainerSlide(gActiveBattler, TRAINER_SLIDE_LAST_SWITCHIN)))
|
||||
{
|
||||
gBattleScripting.battler = gActiveBattler;
|
||||
BattleScriptPush(cmd->nextInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet;
|
||||
gBattlescriptCurrInstr = (i == 1 ? BattleScript_TrainerASlideMsgRet : BattleScript_TrainerBSlideMsgRet);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -8249,9 +8249,15 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (move == MOVE_TEATIME)
|
||||
if (move == MOVE_TEATIME)
|
||||
{
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Z-Moves and Max Moves bypass protection
|
||||
if (gBattleStruct->zmove.active)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here.
|
||||
@ -9638,6 +9644,12 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
||||
MulModifier(&finalModifier, UQ_4_12(0.25));
|
||||
}
|
||||
|
||||
// Z-Moves and Max Moves bypass Protect and do 25% of their original damage
|
||||
if (gBattleStruct->zmove.active && IS_BATTLER_PROTECTED(battlerDef))
|
||||
{
|
||||
MulModifier(&finalModifier, UQ_4_12(0.25));
|
||||
}
|
||||
|
||||
// attacker's abilities
|
||||
switch (abilityAtk)
|
||||
{
|
||||
@ -9823,6 +9835,18 @@ static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 batt
|
||||
MulModifier(modifier, mod);
|
||||
}
|
||||
|
||||
static void TryNoticeIllusionInTypeEffectiveness(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, u16 resultingModifier, u32 illusionSpecies)
|
||||
{
|
||||
// Check if the type effectiveness would've been different if the pokemon really had the types as the disguise.
|
||||
u16 presumedModifier = UQ_4_12(1.0);
|
||||
MulByTypeEffectiveness(&presumedModifier, move, moveType, battlerDef, gSpeciesInfo[illusionSpecies].types[0], battlerAtk, FALSE);
|
||||
if (gSpeciesInfo[illusionSpecies].types[1] != gSpeciesInfo[illusionSpecies].types[0])
|
||||
MulByTypeEffectiveness(&presumedModifier, move, moveType, battlerDef, gSpeciesInfo[illusionSpecies].types[1], battlerAtk, FALSE);
|
||||
|
||||
if (presumedModifier != resultingModifier)
|
||||
RecordAbilityBattle(battlerDef, ABILITY_ILLUSION);
|
||||
}
|
||||
|
||||
static void UpdateMoveResultFlags(u16 modifier)
|
||||
{
|
||||
if (modifier == UQ_4_12(0.0))
|
||||
@ -9848,6 +9872,7 @@ static void UpdateMoveResultFlags(u16 modifier)
|
||||
|
||||
static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities, u16 modifier)
|
||||
{
|
||||
u32 illusionSpecies;
|
||||
u16 defAbility = GetBattlerAbility(battlerDef);
|
||||
|
||||
MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type1, battlerAtk, recordAbilities);
|
||||
@ -9857,15 +9882,18 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat
|
||||
&& gBattleMons[battlerDef].type3 != gBattleMons[battlerDef].type1)
|
||||
MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type3, battlerAtk, recordAbilities);
|
||||
|
||||
if (recordAbilities && (illusionSpecies = GetIllusionMonSpecies(battlerDef)))
|
||||
TryNoticeIllusionInTypeEffectiveness(move, moveType, battlerAtk, battlerDef, modifier, illusionSpecies);
|
||||
|
||||
if (gBattleMoves[move].split == SPLIT_STATUS && move != MOVE_THUNDER_WAVE)
|
||||
{
|
||||
modifier = UQ_4_12(1.0);
|
||||
#if B_GLARE_GHOST <= GEN_3
|
||||
if (move == MOVE_GLARE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST))
|
||||
{
|
||||
modifier = UQ_4_12(0.0);
|
||||
}
|
||||
#endif
|
||||
#if B_GLARE_GHOST <= GEN_3
|
||||
if (move == MOVE_GLARE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST))
|
||||
{
|
||||
modifier = UQ_4_12(0.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (moveType == TYPE_GROUND && !IsBattlerGrounded2(battlerDef, TRUE) && !(gBattleMoves[move].flags & FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user