mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 11:37:40 +01:00
parent
e4656f3ab8
commit
86242c1c70
@ -2263,3 +2263,8 @@
|
||||
.macro hitswitchtargetfailed
|
||||
various 0, VARIOUS_HIT_SWITCH_TARGET_FAILED
|
||||
.endm
|
||||
|
||||
.macro tryrevivalblessing, jumpInstr:req
|
||||
various 0, VARIOUS_TRY_REVIVAL_BLESSING
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
@ -423,6 +423,25 @@ gBattleScriptsForMoveEffects::
|
||||
.4byte BattleScript_EffectHitSetEntryHazard @ EFFECT_HIT_SET_ENTRY_HAZARD
|
||||
.4byte BattleScript_EffectDireClaw @ EFFECT_DIRE_CLAW
|
||||
.4byte BattleScript_EffectBarbBarrage @ EFFECT_BARB_BARRAGE
|
||||
.4byte BattleScript_EffectRevivalBlessing @ EFFECT_REVIVAL_BLESSING
|
||||
|
||||
BattleScript_EffectRevivalBlessing::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
attackanimation
|
||||
waitanimation
|
||||
tryrevivalblessing BattleScript_ButItFailed
|
||||
printstring STRINGID_PKMNREVIVEDREADYTOFIGHT
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_EffectRevivalBlessingSendOut
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_EffectRevivalBlessingSendOut:
|
||||
switchinanim BS_SCRIPTING, FALSE
|
||||
waitstate
|
||||
switchineffects BS_SCRIPTING
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_StealthRockActivates::
|
||||
setstealthrock BattleScript_MoveEnd
|
||||
|
@ -46,6 +46,7 @@ u8 GetCatchingBattler(void);
|
||||
u32 GetHighestStatId(u32 battlerId);
|
||||
bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType);
|
||||
bool32 DoSwitchInAbilitiesItems(u32 battlerId);
|
||||
u8 GetFirstFaintedPartyIndex(u8 battlerId);
|
||||
|
||||
extern void (* const gBattleScriptingCommandsTable[])(void);
|
||||
extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4];
|
||||
|
@ -404,7 +404,8 @@
|
||||
#define EFFECT_HIT_SET_ENTRY_HAZARD 398
|
||||
#define EFFECT_DIRE_CLAW 399
|
||||
#define EFFECT_BARB_BARRAGE 400
|
||||
#define EFFECT_REVIVAL_BLESSING 401
|
||||
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 401
|
||||
#define NUM_BATTLE_MOVE_EFFECTS 402
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H
|
||||
|
@ -259,6 +259,7 @@
|
||||
#define VARIOUS_STORE_HEALING_WISH 167
|
||||
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 168
|
||||
#define VARIOUS_JUMP_IF_SHELL_TRAP 169
|
||||
#define VARIOUS_TRY_REVIVAL_BLESSING 170
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
@ -647,8 +647,9 @@
|
||||
#define STRINGID_STEALTHROCKDISAPPEAREDFROMTEAM 645
|
||||
#define STRINGID_COULDNTFULLYPROTECT 646
|
||||
#define STRINGID_STOCKPILEDEFFECTWOREOFF 647
|
||||
#define STRINGID_PKMNREVIVEDREADYTOFIGHT 648
|
||||
|
||||
#define BATTLESTRINGS_COUNT 648
|
||||
#define BATTLESTRINGS_COUNT 649
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
@ -48,6 +48,7 @@
|
||||
#define PARTY_ACTION_MOVE_TUTOR 12
|
||||
#define PARTY_ACTION_MINIGAME 13
|
||||
#define PARTY_ACTION_REUSABLE_ITEM 14 // Unused. The only reusable items are handled separately
|
||||
#define PARTY_ACTION_CHOOSE_FAINTED_MON 15
|
||||
|
||||
// IDs for DisplayPartyMenuStdMessage, to display the message at the bottom of the party menu
|
||||
#define PARTY_MSG_CHOOSE_MON 0
|
||||
|
@ -2623,6 +2623,15 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
if (gBattleMons[battlerAtk].hp <= gBattleMons[battlerAtk].maxHP / 3)
|
||||
score -= 10;
|
||||
break;*/
|
||||
case EFFECT_REVIVAL_BLESSING:
|
||||
if (GetFirstFaintedPartyIndex(battlerAtk) == PARTY_SIZE)
|
||||
score -= 10;
|
||||
else if (CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
score -= 10;
|
||||
else if (CanTargetFaintAi(battlerDef, battlerAtk)
|
||||
&& AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER)
|
||||
score -= 10;
|
||||
break;
|
||||
case EFFECT_PLACEHOLDER:
|
||||
return 0; // cannot even select
|
||||
} // move effect checks
|
||||
@ -4808,6 +4817,10 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
score++;
|
||||
}
|
||||
break;
|
||||
case EFFECT_REVIVAL_BLESSING:
|
||||
if (GetFirstFaintedPartyIndex(battlerAtk) != PARTY_SIZE)
|
||||
score += 2;
|
||||
break;
|
||||
//case EFFECT_EXTREME_EVOBOOST: // TODO
|
||||
//break;
|
||||
//case EFFECT_CLANGOROUS_SOUL: // TODO
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "palette.h"
|
||||
#include "party_menu.h"
|
||||
#include "pokeball.h"
|
||||
#include "pokemon.h"
|
||||
#include "random.h"
|
||||
@ -33,6 +34,7 @@
|
||||
#include "constants/battle_anim.h"
|
||||
#include "constants/items.h"
|
||||
#include "constants/moves.h"
|
||||
#include "constants/party_menu.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/trainers.h"
|
||||
#include "trainer_hill.h"
|
||||
@ -1674,7 +1676,13 @@ static void OpponentHandleChoosePokemon(void)
|
||||
s32 chosenMonId;
|
||||
s32 pokemonInBattle = 1;
|
||||
|
||||
if (*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) == PARTY_SIZE)
|
||||
// Choosing Revival Blessing target
|
||||
if ((gBattleResources->bufferA[gActiveBattler][1] & 0xF) == PARTY_ACTION_CHOOSE_FAINTED_MON)
|
||||
{
|
||||
chosenMonId = gSelectedMonPartyId = GetFirstFaintedPartyIndex(gActiveBattler);
|
||||
}
|
||||
// Switching out
|
||||
else if (*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) == PARTY_SIZE)
|
||||
{
|
||||
chosenMonId = GetMostSuitableMonToSwitchInto();
|
||||
|
||||
@ -1709,17 +1717,17 @@ static void OpponentHandleChoosePokemon(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId;
|
||||
}
|
||||
else
|
||||
{
|
||||
chosenMonId = *(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler);
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
|
||||
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId;
|
||||
}
|
||||
|
||||
|
||||
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId;
|
||||
BtlController_EmitChosenMonReturnValue(BUFFER_B, chosenMonId, NULL);
|
||||
OpponentBufferExecCompleted();
|
||||
|
||||
}
|
||||
|
||||
static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore)
|
||||
|
@ -2907,7 +2907,8 @@ static void PlayerHandleChoosePokemon(void)
|
||||
for (i = 0; i < ARRAY_COUNT(gBattlePartyCurrentOrder); i++)
|
||||
gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[gActiveBattler][4 + i];
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_ARENA && (gBattleResources->bufferA[gActiveBattler][1] & 0xF) != PARTY_ACTION_CANT_SWITCH)
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_ARENA && (gBattleResources->bufferA[gActiveBattler][1] & 0xF) != PARTY_ACTION_CANT_SWITCH
|
||||
&& (gBattleResources->bufferA[gActiveBattler][1] & 0xF) != PARTY_ACTION_CHOOSE_FAINTED_MON)
|
||||
{
|
||||
BtlController_EmitChosenMonReturnValue(BUFFER_B, gBattlerPartyIndexes[gActiveBattler] + 1, gBattlePartyCurrentOrder);
|
||||
PlayerBufferExecCompleted();
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "palette.h"
|
||||
#include "party_menu.h"
|
||||
#include "pokeball.h"
|
||||
#include "pokemon.h"
|
||||
#include "reshow_battle_screen.h"
|
||||
@ -27,6 +28,7 @@
|
||||
#include "window.h"
|
||||
#include "constants/battle_anim.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/party_menu.h"
|
||||
#include "constants/trainers.h"
|
||||
|
||||
static void PlayerPartnerHandleGetMonData(void);
|
||||
@ -1549,25 +1551,33 @@ static void PlayerPartnerHandleChooseItem(void)
|
||||
|
||||
static void PlayerPartnerHandleChoosePokemon(void)
|
||||
{
|
||||
s32 chosenMonId = GetMostSuitableMonToSwitchInto();
|
||||
|
||||
if (chosenMonId == PARTY_SIZE) // just switch to the next mon
|
||||
s32 chosenMonId;
|
||||
// Choosing Revival Blessing target
|
||||
if ((gBattleResources->bufferA[gActiveBattler][1] & 0xF) == PARTY_ACTION_CHOOSE_FAINTED_MON)
|
||||
{
|
||||
u8 playerMonIdentity = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
||||
u8 selfIdentity = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
||||
|
||||
for (chosenMonId = PARTY_SIZE / 2; chosenMonId < PARTY_SIZE; chosenMonId++)
|
||||
chosenMonId = gSelectedMonPartyId = GetFirstFaintedPartyIndex(gActiveBattler);
|
||||
}
|
||||
// Switching out
|
||||
else
|
||||
{
|
||||
chosenMonId = GetMostSuitableMonToSwitchInto();
|
||||
if (chosenMonId == PARTY_SIZE) // just switch to the next mon
|
||||
{
|
||||
if (GetMonData(&gPlayerParty[chosenMonId], MON_DATA_HP) != 0
|
||||
&& chosenMonId != gBattlerPartyIndexes[playerMonIdentity]
|
||||
&& chosenMonId != gBattlerPartyIndexes[selfIdentity])
|
||||
u8 playerMonIdentity = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
|
||||
u8 selfIdentity = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
||||
|
||||
for (chosenMonId = PARTY_SIZE / 2; chosenMonId < PARTY_SIZE; chosenMonId++)
|
||||
{
|
||||
break;
|
||||
if (GetMonData(&gPlayerParty[chosenMonId], MON_DATA_HP) != 0
|
||||
&& chosenMonId != gBattlerPartyIndexes[playerMonIdentity]
|
||||
&& chosenMonId != gBattlerPartyIndexes[selfIdentity])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId;
|
||||
}
|
||||
|
||||
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId;
|
||||
BtlController_EmitChosenMonReturnValue(BUFFER_B, chosenMonId, NULL);
|
||||
PlayerPartnerBufferExecCompleted();
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "palette.h"
|
||||
#include "party_menu.h"
|
||||
#include "pokeball.h"
|
||||
#include "pokemon.h"
|
||||
#include "recorded_battle.h"
|
||||
@ -1442,6 +1443,7 @@ static void RecordedOpponentHandleChooseItem(void)
|
||||
static void RecordedOpponentHandleChoosePokemon(void)
|
||||
{
|
||||
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, gActiveBattler);
|
||||
gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[gActiveBattler]; // Revival Blessing
|
||||
BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + gActiveBattler), NULL);
|
||||
RecordedOpponentBufferExecCompleted();
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "main.h"
|
||||
#include "m4a.h"
|
||||
#include "palette.h"
|
||||
#include "party_menu.h"
|
||||
#include "pokeball.h"
|
||||
#include "pokemon.h"
|
||||
#include "recorded_battle.h"
|
||||
@ -1466,6 +1467,7 @@ static void RecordedPlayerHandleChooseItem(void)
|
||||
static void RecordedPlayerHandleChoosePokemon(void)
|
||||
{
|
||||
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, gActiveBattler);
|
||||
gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[gActiveBattler]; // Revival Blessing
|
||||
BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + gActiveBattler), NULL);
|
||||
RecordedPlayerBufferExecCompleted();
|
||||
}
|
||||
|
@ -3196,6 +3196,7 @@ static void BattleStartClearSetData(void)
|
||||
}
|
||||
|
||||
gBattleStruct->swapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
|
||||
gSelectedMonPartyId = PARTY_SIZE; // Revival Blessing
|
||||
}
|
||||
|
||||
void SwitchInClearSetData(void)
|
||||
@ -3308,6 +3309,9 @@ void SwitchInClearSetData(void)
|
||||
|
||||
gBattleStruct->overwrittenAbilities[gActiveBattler] = ABILITY_NONE;
|
||||
|
||||
// Clear selected party ID so Revival Blessing doesn't get confused.
|
||||
gSelectedMonPartyId = PARTY_SIZE;
|
||||
|
||||
Ai_UpdateSwitchInData(gActiveBattler);
|
||||
}
|
||||
|
||||
|
@ -782,9 +782,11 @@ static const u8 sText_PrepareShellTrap[] = _("{B_ATK_NAME_WITH_PREFIX} set a she
|
||||
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!");
|
||||
static const u8 sText_StockpiledEffectWoreOff[] = _("{B_ATK_NAME_WITH_PREFIX}'s stockpiled\neffect wore off!");
|
||||
static const u8 sText_PkmnRevivedReadyToFight[] = _("{B_BUFF1} was revived and\nis ready to fight again!");
|
||||
|
||||
const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
{
|
||||
[STRINGID_PKMNREVIVEDREADYTOFIGHT - BATTLESTRINGS_TABLE_START] = sText_PkmnRevivedReadyToFight,
|
||||
[STRINGID_STOCKPILEDEFFECTWOREOFF - BATTLESTRINGS_TABLE_START] = sText_StockpiledEffectWoreOff,
|
||||
[STRINGID_COULDNTFULLYPROTECT - BATTLESTRINGS_TABLE_START] = sText_CouldntFullyProtect,
|
||||
[STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN - BATTLESTRINGS_TABLE_START] = sText_AttackerGainedStrengthFromTheFallen,
|
||||
|
@ -11225,6 +11225,50 @@ static void Cmd_various(void)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
}
|
||||
case VARIOUS_TRY_REVIVAL_BLESSING:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *failInstr);
|
||||
u32 side = GetBattlerSide(gBattlerAttacker);
|
||||
u8 index = GetFirstFaintedPartyIndex(gBattlerAttacker);
|
||||
|
||||
// Move fails if there are no battlers to revive.
|
||||
if (index == PARTY_SIZE)
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
return;
|
||||
}
|
||||
|
||||
// Battler selected! Revive and go to next instruction.
|
||||
if (gSelectedMonPartyId != PARTY_SIZE)
|
||||
{
|
||||
struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
|
||||
|
||||
u16 hp = GetMonData(&party[gSelectedMonPartyId], MON_DATA_MAX_HP) / 2;
|
||||
BtlController_EmitSetMonData(BUFFER_A, REQUEST_HP_BATTLE, gBitTable[gSelectedMonPartyId], sizeof(hp), &hp);
|
||||
MarkBattlerForControllerExec(gBattlerAttacker);
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gSelectedMonPartyId], MON_DATA_SPECIES));
|
||||
|
||||
// If an on-field battler is revived, it needs to be sent out again.
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE &&
|
||||
gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)] == gSelectedMonPartyId)
|
||||
{
|
||||
gBattleScripting.battler = BATTLE_PARTNER(gBattlerAttacker);
|
||||
gBattleCommunication[MULTIUSE_STATE] = TRUE;
|
||||
}
|
||||
|
||||
gSelectedMonPartyId = PARTY_SIZE;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
return;
|
||||
}
|
||||
|
||||
// Open party menu, wait to go to next instruction.
|
||||
else
|
||||
{
|
||||
BtlController_EmitChoosePokemon(BUFFER_A, PARTY_ACTION_CHOOSE_FAINTED_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gActiveBattler]);
|
||||
MarkBattlerForControllerExec(gBattlerAttacker);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} // End of switch (cmd->id)
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
@ -16346,3 +16390,40 @@ static void TryUpdateRoundTurnOrder(void)
|
||||
}
|
||||
}
|
||||
|
||||
u8 GetFirstFaintedPartyIndex(u8 battlerId)
|
||||
{
|
||||
u32 i;
|
||||
u32 start = 0;
|
||||
u32 end = PARTY_SIZE;
|
||||
struct Pokemon *party = (GetBattlerSide(battlerId) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
|
||||
|
||||
// Check whether partner is separate trainer.
|
||||
if ((GetBattlerSide(battlerId) == B_SIDE_PLAYER && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
||||
|| (GetBattlerSide(battlerId) == B_SIDE_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))
|
||||
{
|
||||
if (GetBattlerPosition(battlerId) == B_POSITION_OPPONENT_LEFT
|
||||
|| GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT)
|
||||
{
|
||||
end = PARTY_SIZE / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = PARTY_SIZE / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through to find fainted battler.
|
||||
for (i = start; i < end; ++i)
|
||||
{
|
||||
u32 species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG);
|
||||
if (species != SPECIES_NONE
|
||||
&& species != SPECIES_EGG
|
||||
&& GetMonData(&party[i], MON_DATA_HP) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns PARTY_SIZE if none found.
|
||||
return PARTY_SIZE;
|
||||
}
|
||||
|
@ -13048,7 +13048,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
|
||||
|
||||
[MOVE_REVIVAL_BLESSING] =
|
||||
{
|
||||
.effect = EFFECT_PLACEHOLDER, // EFFECT_REVIVAL_BLESSING
|
||||
.effect = EFFECT_REVIVAL_BLESSING,
|
||||
.power = 0,
|
||||
.type = TYPE_NORMAL,
|
||||
.accuracy = 0,
|
||||
|
@ -1354,6 +1354,24 @@ static void HandleChooseMonSelection(u8 taskId, s8 *slotPtr)
|
||||
TryEnterMonForMinigame(taskId, (u8)*slotPtr);
|
||||
}
|
||||
break;
|
||||
case PARTY_ACTION_CHOOSE_FAINTED_MON:
|
||||
{
|
||||
u8 partyId = GetPartyIdFromBattleSlot((u8)*slotPtr);
|
||||
if (GetMonData(&gPlayerParty[*slotPtr], MON_DATA_HP) > 0
|
||||
|| GetMonData(&gPlayerParty[*slotPtr], MON_DATA_SPECIES_OR_EGG) == SPECIES_EGG
|
||||
|| ((gBattleTypeFlags & BATTLE_TYPE_MULTI) && partyId >= (PARTY_SIZE / 2)))
|
||||
{
|
||||
// Can't select if egg, alive, or doesn't belong to you
|
||||
PlaySE(SE_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
gSelectedMonPartyId = partyId;
|
||||
Task_ClosePartyMenu(taskId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case PARTY_ACTION_ABILITY_PREVENTS:
|
||||
case PARTY_ACTION_SWITCHING:
|
||||
@ -1379,6 +1397,7 @@ static void HandleChooseMonCancel(u8 taskId, s8 *slotPtr)
|
||||
switch (gPartyMenu.action)
|
||||
{
|
||||
case PARTY_ACTION_SEND_OUT:
|
||||
case PARTY_ACTION_CHOOSE_FAINTED_MON:
|
||||
PlaySE(SE_FAILURE);
|
||||
break;
|
||||
case PARTY_ACTION_SWITCH:
|
||||
|
117
test/move_effect_revival_blessing.c
Normal file
117
test/move_effect_revival_blessing.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
// Note: Since these tests are recorded battle, they don't test the right battle controller
|
||||
// behaviors. These have been tested in-game, in double, in multi, and in link battles. AI will always
|
||||
// revive their first fainted party member in order.
|
||||
|
||||
#define MOVE_MESSAGE(name) \
|
||||
do { \
|
||||
if (B_EXPANDED_MOVE_NAMES == FALSE) \
|
||||
MESSAGE(name" used RevivlBlesng!"); \
|
||||
else \
|
||||
MESSAGE(name" used Revival Blessing!"); \
|
||||
} while (0); \
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_REVIVAL_BLESSING].effect == EFFECT_REVIVAL_BLESSING);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Revival Blessing revives a chosen fainted party member for the player")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(0); }
|
||||
PLAYER(SPECIES_WYNAUT) { HP(0); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_REVIVAL_BLESSING); SEND_OUT(player, 2); }
|
||||
} SCENE {
|
||||
MOVE_MESSAGE("Wobbuffet")
|
||||
MESSAGE("Wynaut was revived and is ready to fight again!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Revival Blessing revives a fainted party member for an opponent")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_RAICHU);
|
||||
OPPONENT(SPECIES_PICHU) { HP(0); }
|
||||
OPPONENT(SPECIES_PIKACHU) { HP(0); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_REVIVAL_BLESSING); SEND_OUT(opponent, 1); }
|
||||
} SCENE {
|
||||
MOVE_MESSAGE("Foe Raichu")
|
||||
MESSAGE("Pichu was revived and is ready to fight again!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Revival Blessing fails if no party members are fainted")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_REVIVAL_BLESSING); }
|
||||
} SCENE {
|
||||
MOVE_MESSAGE("Wobbuffet")
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
// Note: There isn't a good way to test multi battles at the moment, but
|
||||
// this PASSES in game!
|
||||
TO_DO_BATTLE_TEST("Revival Blessing cannot revive a partner's party member");
|
||||
// DOUBLE_BATTLE_TEST("Revival Blessing cannot revive a partner's party member")
|
||||
// {
|
||||
// struct BattlePokemon *user;
|
||||
// gBattleTypeFlags |= BATTLE_TYPE_TWO_OPPONENTS;
|
||||
// PARAMETRIZE { user = opponentLeft; }
|
||||
// PARAMETRIZE { user = opponentRight; }
|
||||
// GIVEN {
|
||||
// ASSUME((gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) != FALSE);
|
||||
// PLAYER(SPECIES_WOBBUFFET);
|
||||
// PLAYER(SPECIES_WOBBUFFET);
|
||||
// OPPONENT(SPECIES_WOBBUFFET);
|
||||
// OPPONENT(SPECIES_WOBBUFFET);
|
||||
// OPPONENT(SPECIES_WOBBUFFET);
|
||||
// OPPONENT(SPECIES_WYNAUT);
|
||||
// OPPONENT(SPECIES_WYNAUT) { HP(0); }
|
||||
// OPPONENT(SPECIES_WYNAUT);
|
||||
// } WHEN {
|
||||
// TURN { MOVE(user, MOVE_REVIVAL_BLESSING); }
|
||||
// } SCENE {
|
||||
// if (user == opponentLeft) {
|
||||
// MOVE_MESSAGE(Foe Wobbuffet)
|
||||
// MESSAGE("But it failed!");
|
||||
// } else {
|
||||
// MOVE_MESSAGE(Foe Wynaut)
|
||||
// MESSAGE("Wynaut was revived and is ready to fight again!");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Note: The test runner gets upset about "sending out" a battler on the field,
|
||||
// but this PASSES in game!
|
||||
TO_DO_BATTLE_TEST("Revived battlers still lose their turn");
|
||||
// DOUBLE_BATTLE_TEST("Revived battlers still lose their turn")
|
||||
// {
|
||||
// GIVEN {
|
||||
// PLAYER(SPECIES_WOBBUFFET);
|
||||
// PLAYER(SPECIES_WYNAUT);
|
||||
// OPPONENT(SPECIES_WOBBUFFET);
|
||||
// OPPONENT(SPECIES_WYNAUT) { HP(1); }
|
||||
// } WHEN {
|
||||
// TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentRight);
|
||||
// MOVE(opponentLeft, MOVE_REVIVAL_BLESSING);
|
||||
// SEND_OUT(opponentLeft, 1); }
|
||||
// } SCENE {
|
||||
// MESSAGE("Wobbuffet used Tackle!");
|
||||
// MESSAGE("Foe Wynaut fainted!");
|
||||
// MOVE_MESSAGE("Foe Wobbuffet")
|
||||
// MESSAGE("Wynaut was revived and is ready to fight again!");
|
||||
// NOT { MESSAGE("Wynaut used Celebrate!"); }
|
||||
// }
|
||||
// }
|
Loading…
Reference in New Issue
Block a user