Merge branch 'RHH/master' into RHH/upcoming
# Conflicts: # src/battle_main.c
This commit is contained in:
commit
fbbee39886
8 changed files with 88 additions and 34 deletions
4
.github/pull_request_template.md
vendored
4
.github/pull_request_template.md
vendored
|
@ -11,9 +11,9 @@
|
||||||
<!-- Format: "Fixes #2345, fixes #4523, fixes #2222." -->
|
<!-- Format: "Fixes #2345, fixes #4523, fixes #2222." -->
|
||||||
<!-- If it doesn't apply, feel free to remove this section. -->
|
<!-- If it doesn't apply, feel free to remove this section. -->
|
||||||
|
|
||||||
## Issue(s) that this PR introduces
|
## Feature(s) this PR does NOT handle:
|
||||||
<!-- If your PR contains any unfinished features that are not considered merge-blocking, please list them here for clarity so no one can forget. -->
|
<!-- If your PR contains any unfinished features that are not considered merge-blocking, please list them here for clarity so no one can forget. -->
|
||||||
|
|
||||||
## **Discord contact info**
|
## **Discord contact info**
|
||||||
<!--- formatted as name#numbers, e.g. Lunos#4026 -->
|
<!--- formatted as name#numbers, e.g. Lunos#4026 -->
|
||||||
<!--- Contributors must join https://discord.gg/6CzjAG6GZk -->
|
<!--- Contributors must join https://discord.gg/6CzjAG6GZk -->
|
||||||
|
|
|
@ -1034,7 +1034,6 @@ extern u32 gStatuses4[MAX_BATTLERS_COUNT];
|
||||||
extern struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT];
|
extern struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT];
|
||||||
extern u16 gPauseCounterBattle;
|
extern u16 gPauseCounterBattle;
|
||||||
extern u16 gPaydayMoney;
|
extern u16 gPaydayMoney;
|
||||||
extern u16 gRandomTurnNumber;
|
|
||||||
extern u8 gBattleCommunication[BATTLE_COMMUNICATION_ENTRIES_COUNT];
|
extern u8 gBattleCommunication[BATTLE_COMMUNICATION_ENTRIES_COUNT];
|
||||||
extern u8 gBattleOutcome;
|
extern u8 gBattleOutcome;
|
||||||
extern struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT];
|
extern struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT];
|
||||||
|
|
|
@ -97,6 +97,7 @@ enum RandomTag
|
||||||
RNG_TRIPLE_ARROWS_DEFENSE_DOWN,
|
RNG_TRIPLE_ARROWS_DEFENSE_DOWN,
|
||||||
RNG_TRIPLE_ARROWS_FLINCH,
|
RNG_TRIPLE_ARROWS_FLINCH,
|
||||||
RNG_QUICK_DRAW,
|
RNG_QUICK_DRAW,
|
||||||
|
RNG_QUICK_CLAW,
|
||||||
RNG_TRACE,
|
RNG_TRACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,8 @@ static void SetActionsAndBattlersTurnOrder(void);
|
||||||
static void UpdateBattlerPartyOrdersOnSwitch(u32 battler);
|
static void UpdateBattlerPartyOrdersOnSwitch(u32 battler);
|
||||||
static bool8 AllAtActionConfirmed(void);
|
static bool8 AllAtActionConfirmed(void);
|
||||||
static void TryChangeTurnOrder(void);
|
static void TryChangeTurnOrder(void);
|
||||||
static void CheckQuickClaw_CustapBerryActivation(void);
|
static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2);
|
||||||
|
static void CheckChangingTurnOrderEffects(void);
|
||||||
static void FreeResetData_ReturnToOvOrDoEvolutions(void);
|
static void FreeResetData_ReturnToOvOrDoEvolutions(void);
|
||||||
static void ReturnFromBattleToOverworld(void);
|
static void ReturnFromBattleToOverworld(void);
|
||||||
static void TryEvolvePokemon(void);
|
static void TryEvolvePokemon(void);
|
||||||
|
@ -192,7 +193,6 @@ EWRAM_DATA u32 gStatuses4[MAX_BATTLERS_COUNT] = {0};
|
||||||
EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0};
|
EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0};
|
||||||
EWRAM_DATA u16 gPauseCounterBattle = 0;
|
EWRAM_DATA u16 gPauseCounterBattle = 0;
|
||||||
EWRAM_DATA u16 gPaydayMoney = 0;
|
EWRAM_DATA u16 gPaydayMoney = 0;
|
||||||
EWRAM_DATA u16 gRandomTurnNumber = 0;
|
|
||||||
EWRAM_DATA u8 gBattleCommunication[BATTLE_COMMUNICATION_ENTRIES_COUNT] = {0};
|
EWRAM_DATA u8 gBattleCommunication[BATTLE_COMMUNICATION_ENTRIES_COUNT] = {0};
|
||||||
EWRAM_DATA u8 gBattleOutcome = 0;
|
EWRAM_DATA u8 gBattleOutcome = 0;
|
||||||
EWRAM_DATA struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT] = {0};
|
EWRAM_DATA struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT] = {0};
|
||||||
|
@ -3045,8 +3045,6 @@ static void BattleStartClearSetData(void)
|
||||||
gBattleStruct->givenExpMons = 0;
|
gBattleStruct->givenExpMons = 0;
|
||||||
gBattleStruct->palaceFlags = 0;
|
gBattleStruct->palaceFlags = 0;
|
||||||
|
|
||||||
gRandomTurnNumber = Random();
|
|
||||||
|
|
||||||
gBattleResults.shinyWildMon = IsMonShiny(&gEnemyParty[0]);
|
gBattleResults.shinyWildMon = IsMonShiny(&gEnemyParty[0]);
|
||||||
|
|
||||||
gBattleStruct->arenaLostPlayerMons = 0;
|
gBattleStruct->arenaLostPlayerMons = 0;
|
||||||
|
@ -3815,8 +3813,6 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||||
gBattleStruct->turnCountersTracker = 0;
|
gBattleStruct->turnCountersTracker = 0;
|
||||||
gMoveResultFlags = 0;
|
gMoveResultFlags = 0;
|
||||||
|
|
||||||
gRandomTurnNumber = Random();
|
|
||||||
|
|
||||||
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts)); // erase all totem boosts just to be safe
|
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts)); // erase all totem boosts just to be safe
|
||||||
|
|
||||||
SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
|
SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
|
||||||
|
@ -3913,7 +3909,6 @@ void BattleTurnPassed(void)
|
||||||
BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG);
|
BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG);
|
||||||
SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
|
SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers
|
||||||
gBattleMainFunc = HandleTurnActionSelectionState;
|
gBattleMainFunc = HandleTurnActionSelectionState;
|
||||||
gRandomTurnNumber = Random();
|
|
||||||
|
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||||
BattleScriptExecute(BattleScript_PalacePrintFlavorText);
|
BattleScriptExecute(BattleScript_PalacePrintFlavorText);
|
||||||
|
@ -4710,26 +4705,6 @@ u32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMov
|
||||||
{
|
{
|
||||||
u32 strikesFirst = 0;
|
u32 strikesFirst = 0;
|
||||||
|
|
||||||
// Battler 1
|
|
||||||
// Quick Draw
|
|
||||||
if (!ignoreChosenMoves && ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && RandomPercentage(RNG_QUICK_DRAW, 30))
|
|
||||||
gProtectStructs[battler1].quickDraw = TRUE;
|
|
||||||
// Quick Claw and Custap Berry
|
|
||||||
if (!gProtectStructs[battler1].quickDraw
|
|
||||||
&& ((holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler1)) / 100)
|
|
||||||
|| (holdEffectBattler1 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler1, 4, gBattleMons[battler1].item))))
|
|
||||||
gProtectStructs[battler1].usedCustapBerry = TRUE;
|
|
||||||
|
|
||||||
// Battler 2
|
|
||||||
// Quick Draw
|
|
||||||
if (!ignoreChosenMoves && ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && RandomPercentage(RNG_QUICK_DRAW, 30))
|
|
||||||
gProtectStructs[battler2].quickDraw = TRUE;
|
|
||||||
// Quick Claw and Custap Berry
|
|
||||||
if (!gProtectStructs[battler2].quickDraw
|
|
||||||
&& ((holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * GetBattlerHoldEffectParam(battler2)) / 100)
|
|
||||||
|| (holdEffectBattler2 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler2, 4, gBattleMons[battler2].item))))
|
|
||||||
gProtectStructs[battler2].usedCustapBerry = TRUE;
|
|
||||||
|
|
||||||
if (priority1 == priority2)
|
if (priority1 == priority2)
|
||||||
{
|
{
|
||||||
// QUICK CLAW / CUSTAP - always first
|
// QUICK CLAW / CUSTAP - always first
|
||||||
|
@ -4900,6 +4875,7 @@ static void SetActionsAndBattlersTurnOrder(void)
|
||||||
{
|
{
|
||||||
u8 battler1 = gBattlerByTurnOrder[i];
|
u8 battler1 = gBattlerByTurnOrder[i];
|
||||||
u8 battler2 = gBattlerByTurnOrder[j];
|
u8 battler2 = gBattlerByTurnOrder[j];
|
||||||
|
TryChangingTurnOrderEffects(battler1, battler2);
|
||||||
if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM
|
if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM
|
||||||
&& gActionsByTurnOrder[j] != B_ACTION_USE_ITEM
|
&& gActionsByTurnOrder[j] != B_ACTION_USE_ITEM
|
||||||
&& gActionsByTurnOrder[i] != B_ACTION_SWITCH
|
&& gActionsByTurnOrder[i] != B_ACTION_SWITCH
|
||||||
|
@ -4914,7 +4890,7 @@ static void SetActionsAndBattlersTurnOrder(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gBattleMainFunc = CheckQuickClaw_CustapBerryActivation;
|
gBattleMainFunc = CheckChangingTurnOrderEffects;
|
||||||
gBattleStruct->quickClawBattlerId = 0;
|
gBattleStruct->quickClawBattlerId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4932,6 +4908,7 @@ static void TurnValuesCleanUp(bool8 var0)
|
||||||
gProtectStructs[i].banefulBunkered = FALSE;
|
gProtectStructs[i].banefulBunkered = FALSE;
|
||||||
gProtectStructs[i].quash = FALSE;
|
gProtectStructs[i].quash = FALSE;
|
||||||
gProtectStructs[i].usedCustapBerry = FALSE;
|
gProtectStructs[i].usedCustapBerry = FALSE;
|
||||||
|
gProtectStructs[i].quickDraw = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5083,7 +5060,35 @@ static void TryChangeTurnOrder(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CheckQuickClaw_CustapBerryActivation(void)
|
static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2)
|
||||||
|
{
|
||||||
|
u32 ability1 = GetBattlerAbility(battler1);
|
||||||
|
u32 holdEffectBattler1 = GetBattlerHoldEffect(battler1, TRUE);
|
||||||
|
u32 holdEffectBattler2 = GetBattlerHoldEffect(battler2, TRUE);
|
||||||
|
u32 ability2 = GetBattlerAbility(battler2);
|
||||||
|
|
||||||
|
// Battler 1
|
||||||
|
// Quick Draw
|
||||||
|
if (ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && RandomPercentage(RNG_QUICK_DRAW, 30))
|
||||||
|
gProtectStructs[battler1].quickDraw = TRUE;
|
||||||
|
// Quick Claw and Custap Berry
|
||||||
|
if (!gProtectStructs[battler1].quickDraw
|
||||||
|
&& ((holdEffectBattler1 == HOLD_EFFECT_QUICK_CLAW && RandomPercentage(RNG_QUICK_CLAW, GetBattlerHoldEffectParam(battler1)))
|
||||||
|
|| (holdEffectBattler1 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler1, 4, gBattleMons[battler1].item))))
|
||||||
|
gProtectStructs[battler1].usedCustapBerry = TRUE;
|
||||||
|
|
||||||
|
// Battler 2
|
||||||
|
// Quick Draw
|
||||||
|
if (ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && RandomPercentage(RNG_QUICK_DRAW, 30))
|
||||||
|
gProtectStructs[battler2].quickDraw = TRUE;
|
||||||
|
// Quick Claw and Custap Berry
|
||||||
|
if (!gProtectStructs[battler2].quickDraw
|
||||||
|
&& ((holdEffectBattler2 == HOLD_EFFECT_QUICK_CLAW && RandomPercentage(RNG_QUICK_CLAW, GetBattlerHoldEffectParam(battler2)))
|
||||||
|
|| (holdEffectBattler2 == HOLD_EFFECT_CUSTAP_BERRY && HasEnoughHpToEatBerry(battler2, 4, gBattleMons[battler2].item))))
|
||||||
|
gProtectStructs[battler2].usedCustapBerry = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CheckChangingTurnOrderEffects(void)
|
||||||
{
|
{
|
||||||
u32 i, battler;
|
u32 i, battler;
|
||||||
|
|
||||||
|
@ -5118,7 +5123,6 @@ static void CheckQuickClaw_CustapBerryActivation(void)
|
||||||
else if (gProtectStructs[battler].quickDraw)
|
else if (gProtectStructs[battler].quickDraw)
|
||||||
{
|
{
|
||||||
gBattlerAbility = battler;
|
gBattlerAbility = battler;
|
||||||
gProtectStructs[battler].quickDraw = FALSE;
|
|
||||||
gLastUsedAbility = gBattleMons[battler].ability;
|
gLastUsedAbility = gBattleMons[battler].ability;
|
||||||
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
|
||||||
RecordAbilityBattle(battler, gLastUsedAbility);
|
RecordAbilityBattle(battler, gLastUsedAbility);
|
||||||
|
|
|
@ -15,3 +15,18 @@ SINGLE_BATTLE_TEST("Quick Draw has a 30% chance of going first")
|
||||||
MESSAGE("Foe Wobbuffet used Celebrate!");
|
MESSAGE("Foe Wobbuffet used Celebrate!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Quick Draw does not activate 70% of the time")
|
||||||
|
{
|
||||||
|
PASSES_RANDOMLY(7, 10, RNG_QUICK_DRAW);
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_SLOWBRO_GALARIAN) { Ability(ABILITY_QUICK_DRAW); Speed(1); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_TACKLE); }
|
||||||
|
} SCENE {
|
||||||
|
NOT ABILITY_POPUP(player, ABILITY_QUICK_DRAW);
|
||||||
|
MESSAGE("Foe Wobbuffet used Celebrate!");
|
||||||
|
MESSAGE("Slowbro used Tackle!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ AI_SINGLE_BATTLE_TEST("AI can choose a status move that boosts the attack by two
|
||||||
{
|
{
|
||||||
GIVEN {
|
GIVEN {
|
||||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||||
PLAYER(SPECIES_WOBBUFFET) { HP(278); };
|
PLAYER(SPECIES_WOBBUFFET) { HP(277); };
|
||||||
PLAYER(SPECIES_WOBBUFFET);
|
PLAYER(SPECIES_WOBBUFFET);
|
||||||
OPPONENT(SPECIES_KANGASKHAN) { Moves(MOVE_STRENGTH, MOVE_HORN_ATTACK, MOVE_SWORDS_DANCE); }
|
OPPONENT(SPECIES_KANGASKHAN) { Moves(MOVE_STRENGTH, MOVE_HORN_ATTACK, MOVE_SWORDS_DANCE); }
|
||||||
} WHEN {
|
} WHEN {
|
||||||
|
|
|
@ -35,3 +35,17 @@ SINGLE_BATTLE_TEST("Custap Berry allows the holder to move first in its priority
|
||||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
|
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Custap Berry activates even if the opposing mon switches out")
|
||||||
|
{
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_REGIROCK) { HP(1); Item(ITEM_CUSTAP_BERRY); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET);
|
||||||
|
} WHEN {
|
||||||
|
TURN { SWITCH(opponent, 1); }
|
||||||
|
} SCENE {
|
||||||
|
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||||
|
MESSAGE("Regirock can act faster, thanks to Custap Berry!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
21
test/battle/hold_effect/quick_claw.c
Normal file
21
test/battle/hold_effect/quick_claw.c
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include "global.h"
|
||||||
|
#include "test/battle.h"
|
||||||
|
|
||||||
|
ASSUMPTIONS
|
||||||
|
{
|
||||||
|
ASSUME(gItems[ITEM_QUICK_CLAW].holdEffect == HOLD_EFFECT_QUICK_CLAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
SINGLE_BATTLE_TEST("Quick Claw activates 10% of the time")
|
||||||
|
{
|
||||||
|
PASSES_RANDOMLY(2, 10, RNG_QUICK_CLAW);
|
||||||
|
GIVEN {
|
||||||
|
PLAYER(SPECIES_WOBBUFFET) { Speed(1); Item(ITEM_QUICK_CLAW); }
|
||||||
|
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
|
||||||
|
} WHEN {
|
||||||
|
TURN { MOVE(player, MOVE_TACKLE); }
|
||||||
|
} SCENE {
|
||||||
|
MESSAGE("Wobbuffet used Tackle!");
|
||||||
|
MESSAGE("Foe Wobbuffet used Celebrate!");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue