Merge branch 'battle_engine' of https://github.com/rh-hideout/pokeemerald-expansion into last_ball

This commit is contained in:
ghoulslash 2021-07-18 11:11:03 -06:00
commit 45d4cee243
14 changed files with 59 additions and 21 deletions

View File

@ -863,6 +863,7 @@ Move_ROOST:
Move_GRAVITY:
fadetobg BG_COSMIC
waitbgfadein
createvisualtask AnimTask_SetAnimTargetToAttackerOpposite, 1
playsewithpan SE_M_TAKE_DOWN, SOUND_PAN_ATTACKER
createvisualtask AnimTask_ShakeAndSinkMon, 5, ANIM_ATTACKER, 2, 0, 96, 30
createvisualtask AnimTask_ShakeAndSinkMon, 5, ANIM_DEF_PARTNER, 2, 0, 96, 30

View File

@ -6258,6 +6258,8 @@ BattleScript_CottonDownActivates::
savetarget
setbyte gBattlerTarget, 0
BattleScript_CottonDownLoop:
getbattlerfainted BS_TARGET
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_CottonDownLoopIncrement
setstatchanger STAT_SPEED, 1, TRUE
jumpifbyteequal gBattlerTarget, gEffectBattler, BattleScript_CottonDownLoopIncrement
statbuffchange STAT_BUFF_NOT_PROTECT_AFFECTED, BattleScript_CottonDownTargetSpeedCantGoLower

View File

@ -36,6 +36,7 @@ u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbil
bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move);
bool32 AI_WeatherHasEffect(void);
bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits);
bool32 AI_IsTerrainAffected(u8 battlerId, u32 flags);
bool32 AI_IsBattlerGrounded(u8 battlerId);
bool32 HasDamagingMove(u8 battlerId);
bool32 HasDamagingMoveOfType(u8 battlerId, u8 type);

View File

@ -124,7 +124,7 @@ u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId);
u16 GetWishMegaEvolutionSpecies(u16 preEvoSpecies, u16 moveId1, u16 moveId2, u16 moveId3, u16 moveId4);
bool32 CanMegaEvolve(u8 battlerId);
void UndoMegaEvolution(u32 monId);
void UndoFormChange(u32 monId, u32 side);
void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut);
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
bool32 CanBattlerGetOrLoseItem(u8 battlerId, u16 itemId);
struct Pokemon *GetIllusionMonPtr(u32 battlerId);

View File

@ -1,6 +1,8 @@
#ifndef GUARD_CONSTANTS_BATTLE_CONFIG_H
#define GUARD_CONSTANTS_BATTLE_CONFIG_H
#include "constants/expansion_branches.h"
// Species with peculiar battle effects.
#ifndef POKEMON_EXPANSION
#define SPECIES_DIALGA 0

View File

@ -0,0 +1,10 @@
#ifndef GUARD_CONSTANTS_EXPANSION_BRANCHES_H
#define GUARD_CONSTANTS_EXPANSION_BRANCHES_H
// Branch defines: Used by other branches to detect each other.
// Each define must be here for each of RHH's branch you have pulled.
// e.g. If you have both the battle_engine and pokemon_expansion branch,
// then both BATTLE_ENGINE and POKEMON_EXPANSION must be defined here.
#define BATTLE_ENGINE
#endif

View File

@ -10,6 +10,7 @@
#include "constants/vars.h"
#include "constants/species.h"
#include "constants/berry.h"
#include "constants/expansion_branches.h"
// Prevent cross-jump optimization.
#define BLOCK_CROSS_JUMP asm("");
@ -127,12 +128,6 @@
f; \
})
// Branch defines: Used by other branches to detect each other.
// Each define must be here for each of RHH's branch you have pulled.
// e.g. If you have both the battle_engine and pokemon_expansion branch,
// then both BATTLE_ENGINE and POKEMON_EXPANSION must be defined here.
#define BATTLE_ENGINE
#define ROUND_BITS_TO_BYTES(numBits)(((numBits) / 8) + (((numBits) % 8) ? 1 : 0))
#define DEX_FLAGS_NO (ROUND_BITS_TO_BYTES(NUM_SPECIES))

View File

@ -721,22 +721,21 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
#endif
// terrain & effect checks
if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)
if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_ELECTRIC_TERRAIN))
{
if (moveEffect == EFFECT_SLEEP || moveEffect == EFFECT_YAWN)
RETURN_SCORE_MINUS(20);
}
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)
if (AI_IsTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
{
if (IsNonVolatileStatusMoveEffect(moveEffect) || IsConfusionMoveEffect(moveEffect))
RETURN_SCORE_MINUS(20);
}
if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN)
if (AI_IsTerrainAffected(battlerAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && atkPriority > 0)
{
if (atkPriority > 0)
RETURN_SCORE_MINUS(20);
RETURN_SCORE_MINUS(20);
}
} // end check MOVE_TARGET_USER
@ -1641,11 +1640,11 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_TEETER_DANCE:
if (((gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
|| (!DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move) && AI_DATA->defAbility == ABILITY_OWN_TEMPO)
|| (IsBattlerGrounded(battlerDef) && (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
|| (IsBattlerGrounded(battlerDef) && AI_IsTerrainAffected(battlerDef, STATUS_FIELD_MISTY_TERRAIN))
|| (DoesSubstituteBlockMove(battlerAtk, battlerDef, move)))
&& ((gBattleMons[AI_DATA->battlerDefPartner].status2 & STATUS2_CONFUSION)
|| (!DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move) && AI_DATA->defPartnerAbility == ABILITY_OWN_TEMPO)
|| (IsBattlerGrounded(AI_DATA->battlerDefPartner) && (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
|| (IsBattlerGrounded(AI_DATA->battlerDefPartner) && AI_IsTerrainAffected(AI_DATA->battlerDefPartner, STATUS_FIELD_MISTY_TERRAIN))
|| (DoesSubstituteBlockMove(battlerAtk, AI_DATA->battlerDefPartner, move))))
{
score -= 10;
@ -3836,7 +3835,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score++;
break;
case EFFECT_SAFEGUARD:
if (!(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) || !IsBattlerGrounded(battlerAtk))
if (!AI_IsTerrainAffected(battlerAtk, STATUS_FIELD_MISTY_TERRAIN) || !IsBattlerGrounded(battlerAtk))
score++;
//if (CountUsablePartyMons(battlerDef) != 0)
//score += 8;

View File

@ -1110,6 +1110,15 @@ u16 AI_GetHoldEffect(u32 battlerId)
return holdEffect;
}
bool32 AI_IsTerrainAffected(u8 battlerId, u32 flags)
{
if (gStatuses3[battlerId] & STATUS3_SEMI_INVULNERABLE)
return FALSE;
else if (!(gFieldStatuses & flags))
return FALSE;
return AI_IsBattlerGrounded(battlerId);
}
// different from IsBattlerGrounded in that we don't always know battler's hold effect or ability
bool32 AI_IsBattlerGrounded(u8 battlerId)
{

View File

@ -321,6 +321,12 @@ static void AnimTask_ShakeMonInPlace_Step(u8 taskId)
void AnimTask_ShakeAndSinkMon(u8 taskId)
{
u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
if (spriteId == SPRITE_NONE)
{
DestroyAnimVisualTask(taskId);
return;
}
gSprites[spriteId].pos2.x = gBattleAnimArgs[1];
gTasks[taskId].data[0] = spriteId;
gTasks[taskId].data[1] = gBattleAnimArgs[1];

View File

@ -1084,3 +1084,9 @@ void AnimTask_SetInvisible(u8 taskId)
gSprites[spriteId].invisible = gBattleSpritesDataPtr->battlerData[battlerId].invisible = gBattleAnimArgs[1];
DestroyAnimVisualTask(taskId);
}
void AnimTask_SetAnimTargetToAttackerOpposite(u8 taskId)
{
gBattleAnimTarget = BATTLE_OPPOSITE(gBattleAnimAttacker);
DestroyAnimVisualTask(taskId);
}

View File

@ -3123,7 +3123,7 @@ void FaintClearSetData(void)
ClearBattlerMoveHistory(gActiveBattler);
ClearBattlerAbilityHistory(gActiveBattler);
ClearBattlerItemEffectHistory(gActiveBattler);
UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler));
UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler), FALSE);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]);
}
@ -4888,7 +4888,7 @@ static void HandleEndTurn_FinishBattle(void)
for (i = 0; i < PARTY_SIZE; i++)
{
UndoMegaEvolution(i);
UndoFormChange(i, B_SIDE_PLAYER);
UndoFormChange(i, B_SIDE_PLAYER, FALSE);
}
gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions;
gCB2_AfterEvolution = BattleMainCB2;

View File

@ -12098,6 +12098,7 @@ static void Cmd_handleballthrow(void)
{
BtlController_EmitBallThrowAnim(0, BALL_3_SHAKES_SUCCESS);
MarkBattlerForControllerExec(gActiveBattler);
UndoFormChange(gBattlerPartyIndexes[gBattlerTarget], GET_BATTLER_SIDE(gBattlerTarget));
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
@ -12142,6 +12143,7 @@ static void Cmd_handleballthrow(void)
if (IsCriticalCapture())
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 1;
UndoFormChange(gBattlerPartyIndexes[gBattlerTarget], GET_BATTLER_SIDE(gBattlerTarget));
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
if (CalculatePlayerPartyCount() == PARTY_SIZE)

View File

@ -492,7 +492,7 @@ void HandleAction_Switch(void)
if (gBattleResults.playerSwitchesCounter < 255)
gBattleResults.playerSwitchesCounter++;
UndoFormChange(gBattlerPartyIndexes[gBattlerAttacker], GetBattlerSide(gBattlerAttacker));
UndoFormChange(gBattlerPartyIndexes[gBattlerAttacker], GetBattlerSide(gBattlerAttacker), TRUE);
}
void HandleAction_UseItem(void)
@ -8333,14 +8333,14 @@ void UndoMegaEvolution(u32 monId)
}
}
void UndoFormChange(u32 monId, u32 side)
void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
{
u32 i, currSpecies;
struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
static const u16 species[][2] = // changed form id, default form id
{
{SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH},
{SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU},
{SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH},
{SPECIES_DARMANITAN_ZEN_MODE, SPECIES_DARMANITAN},
{SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED},
{SPECIES_MINIOR_METEOR_BLUE, SPECIES_MINIOR_CORE_BLUE},
@ -8352,8 +8352,13 @@ void UndoFormChange(u32 monId, u32 side)
{SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI},
};
if (isSwitchingOut) // Don't revert Mimikyu Busted when switching out
i = 1;
else
i = 0;
currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);
for (i = 0; i < ARRAY_COUNT(species); i++)
for (; i < ARRAY_COUNT(species); i++)
{
if (currSpecies == species[i][0])
{