Add functionality to Poké Flute and Town Map (#5405)
* Add functionality to Poké Flute and Town Map * Poke flute in-battle * Address reviews * Update item_use.c * Update battle_message.c * Update battle_script_commands.c * Update battle_script_commands.c * Update battle_script_commands.c * Update battle_script_commands.c * Update battle_script_commands.c * Update battle_script_commands.c
This commit is contained in:
parent
f082fe7e42
commit
44bf14e6fd
12 changed files with 190 additions and 9 deletions
|
@ -1731,6 +1731,14 @@
|
|||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro checkpokeflute
|
||||
callnative BS_CheckPokeFlute
|
||||
.endm
|
||||
|
||||
.macro waitfanfare
|
||||
callnative BS_WaitFanfare
|
||||
.endm
|
||||
|
||||
@ various command changed to more readable macros
|
||||
.macro cancelmultiturnmoves battler:req
|
||||
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
|
||||
|
|
|
@ -25,6 +25,7 @@ gBattlescriptsForUsingItem::
|
|||
.4byte BattleScript_ItemRestoreHP @ EFFECT_ITEM_REVIVE
|
||||
.4byte BattleScript_ItemRestorePP @ EFFECT_ITEM_RESTORE_PP
|
||||
.4byte BattleScript_ItemIncreaseAllStats @ EFFECT_ITEM_INCREASE_ALL_STATS
|
||||
.4byte BattleScript_UsePokeFlute @ EFFECT_ITEM_USE_POKE_FLUTE
|
||||
|
||||
.align 2
|
||||
gBattlescriptsForSafariActions::
|
||||
|
@ -110,6 +111,25 @@ BattleScript_ItemIncreaseStat::
|
|||
waitmessage B_WAIT_TIME_LONG
|
||||
end
|
||||
|
||||
BattleScript_UsePokeFlute::
|
||||
checkpokeflute
|
||||
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 1, BattleScript_PokeFluteWakeUp
|
||||
printstring STRINGID_POKEFLUTECATCHY
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_PokeFluteEnd
|
||||
|
||||
BattleScript_PokeFluteWakeUp::
|
||||
printstring STRINGID_POKEFLUTE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
fanfare MUS_RG_POKE_FLUTE
|
||||
waitfanfare
|
||||
printstring STRINGID_MONHEARINGFLUTEAWOKE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
updatestatusicon BS_PLAYER2
|
||||
waitstate
|
||||
BattleScript_PokeFluteEnd::
|
||||
finishaction
|
||||
|
||||
BattleScript_ItemSetMist::
|
||||
call BattleScript_UseItemMessage
|
||||
setmist
|
||||
|
|
|
@ -713,8 +713,11 @@
|
|||
#define STRINGID_PKMNMADESHELLGLEAM 711
|
||||
#define STRINGID_FICKLEBEAMDOUBLED 712
|
||||
#define STRINGID_COMMANDERACTIVATES 713
|
||||
#define STRINGID_POKEFLUTECATCHY 714
|
||||
#define STRINGID_POKEFLUTE 715
|
||||
#define STRINGID_MONHEARINGFLUTEAWOKE 716
|
||||
|
||||
#define BATTLESTRINGS_COUNT 714
|
||||
#define BATTLESTRINGS_COUNT 717
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
|
|
@ -1077,6 +1077,7 @@
|
|||
#define EFFECT_ITEM_REVIVE 9
|
||||
#define EFFECT_ITEM_RESTORE_PP 10
|
||||
#define EFFECT_ITEM_INCREASE_ALL_STATS 11
|
||||
#define EFFECT_ITEM_USE_POKE_FLUTE 12
|
||||
|
||||
// Enigma Berry dummy constant
|
||||
#define EFFECT_ITEM_ENIGMA_BERRY_EREADER 1
|
||||
|
|
|
@ -47,6 +47,8 @@ u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId);
|
|||
void FieldUseFunc_VsSeeker(u8 taskId);
|
||||
void Task_ItemUse_CloseMessageBoxAndReturnToField_VsSeeker(u8 taskId);
|
||||
void DisplayDadsAdviceCannotUseItemMessage(u8 taskId, bool8 isUsingRegisteredKeyItemOnField);
|
||||
void ItemUseOutOfBattle_PokeFlute(u8 taskId);
|
||||
void ItemUseOutOfBattle_TownMap(u8 taskId);
|
||||
|
||||
enum {
|
||||
BALL_THROW_UNABLE_TWO_MONS,
|
||||
|
|
|
@ -833,6 +833,9 @@ extern const u8 gText_UsedVar2WildRepelled[];
|
|||
extern const u8 gText_BoxFull[];
|
||||
extern const u8 gText_WontHaveEffect[];
|
||||
extern const u8 gText_NextFusionMon[];
|
||||
extern const u8 gText_PlayedPokeFluteCatchy[];
|
||||
extern const u8 gText_PlayedPokeFlute[];
|
||||
extern const u8 gText_PokeFluteAwakenedMon[];
|
||||
|
||||
extern const u8 gText_LevelSymbol[];
|
||||
extern const u8 gText_PkmnInfo[];
|
||||
|
|
|
@ -2244,6 +2244,10 @@ static bool32 ShouldUseItem(u32 battler)
|
|||
if (gBattleStruct->itemPartyIndex[battler] != PARTY_SIZE) // Revive if possible.
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
case EFFECT_ITEM_USE_POKE_FLUTE:
|
||||
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
|
||||
shouldUse = TRUE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -517,6 +517,9 @@ static const u8 sText_PkmnsItemRestoredHPALittle[] = _("{B_SCR_ACTIVE_NAME_WITH_
|
|||
static const u8 sText_ItemAllowsOnlyYMove[] = _("{B_LAST_ITEM} allows the\nuse of only {B_CURRENT_MOVE}!\p");
|
||||
static const u8 sText_PkmnHungOnWithX[] = _("{B_DEF_NAME_WITH_PREFIX} hung on\nusing its {B_LAST_ITEM}!");
|
||||
const u8 gText_EmptyString3[] = _("");
|
||||
static const u8 sText_PlayedFluteCatchyTune[] = _("{B_PLAYER_NAME} played the {B_LAST_ITEM}.\pNow, that's a catchy tune!");
|
||||
static const u8 sText_PlayedThe[] = _("{B_PLAYER_NAME} played the\n{B_LAST_ITEM}.");
|
||||
static const u8 sText_PkmnHearingFluteAwoke[] = _("The POKéMON hearing the FLUTE\nawoke!");
|
||||
static const u8 sText_YouThrowABallNowRight[] = _("You throw a BALL now, right?\nI… I'll do my best!");
|
||||
|
||||
// early declaration of strings
|
||||
|
@ -1555,6 +1558,9 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
|||
[STRINGID_ITEMWASUSEDUP - BATTLESTRINGS_TABLE_START] = sText_ItemWasUsedUp,
|
||||
[STRINGID_ATTACKERLOSTITSTYPE - BATTLESTRINGS_TABLE_START] = sText_AttackerLostItsType,
|
||||
[STRINGID_CLOAKEDINAHARSHLIGHT - BATTLESTRINGS_TABLE_START] = sText_PkmnIsCloakedInAHarshLight,
|
||||
[STRINGID_POKEFLUTECATCHY - BATTLESTRINGS_TABLE_START] = sText_PlayedFluteCatchyTune,
|
||||
[STRINGID_POKEFLUTE - BATTLESTRINGS_TABLE_START] = sText_PlayedThe,
|
||||
[STRINGID_MONHEARINGFLUTEAWOKE - BATTLESTRINGS_TABLE_START] = sText_PkmnHearingFluteAwoke,
|
||||
};
|
||||
|
||||
const u16 gTrainerUsedItemStringIds[] =
|
||||
|
|
|
@ -12556,14 +12556,19 @@ static void Cmd_updatestatusicon(void)
|
|||
if (gBattleControllerExecFlags)
|
||||
return;
|
||||
|
||||
if (cmd->battler != BS_ATTACKER_WITH_PARTNER)
|
||||
if (cmd->battler == BS_PLAYER2)
|
||||
{
|
||||
battler = GetBattlerForBattleScript(cmd->battler);
|
||||
BtlController_EmitStatusIconUpdate(battler, BUFFER_A, gBattleMons[battler].status1, gBattleMons[battler].status2);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
for (battler = gBattleControllerExecFlags; battler < gBattlersCount; battler++)
|
||||
{
|
||||
if (!(gAbsentBattlerFlags & (1u << battler)))
|
||||
{
|
||||
BtlController_EmitStatusIconUpdate(battler, BUFFER_A, gBattleMons[battler].status1, gBattleMons[battler].status2);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
}
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
else if (cmd->battler == BS_ATTACKER_WITH_PARTNER)
|
||||
{
|
||||
battler = gBattlerAttacker;
|
||||
if (!(gAbsentBattlerFlags & (1u << battler)))
|
||||
|
@ -12582,6 +12587,13 @@ static void Cmd_updatestatusicon(void)
|
|||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
battler = GetBattlerForBattleScript(cmd->battler);
|
||||
BtlController_EmitStatusIconUpdate(battler, BUFFER_A, gBattleMons[battler].status1, gBattleMons[battler].status2);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_setmist(void)
|
||||
|
@ -17425,3 +17437,62 @@ void BS_JumpIfCommanderActive(void)
|
|||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
static void UpdatePokeFlutePartyStatus(struct Pokemon* party, u8 position)
|
||||
{
|
||||
s32 i;
|
||||
u8 battler;
|
||||
u32 monToCheck, status;
|
||||
u16 species, abilityNum;
|
||||
monToCheck = 0;
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
{
|
||||
species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG);
|
||||
abilityNum = GetMonData(&party[i], MON_DATA_ABILITY_NUM);
|
||||
status = GetMonData(&party[i], MON_DATA_STATUS);
|
||||
if (species != SPECIES_NONE
|
||||
&& species != SPECIES_EGG
|
||||
&& status & AILMENT_FNT
|
||||
&& GetAbilityBySpecies(species, abilityNum) != ABILITY_SOUNDPROOF)
|
||||
monToCheck |= (1 << i);
|
||||
}
|
||||
if (monToCheck)
|
||||
{
|
||||
battler = GetBattlerAtPosition(position);
|
||||
status = 0;
|
||||
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, monToCheck, 4, &status);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void BS_CheckPokeFlute(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
|
||||
s32 i;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (GetBattlerAbility(i) != ABILITY_SOUNDPROOF)
|
||||
{
|
||||
gBattleMons[i].status1 &= ~STATUS1_SLEEP;
|
||||
gBattleMons[i].status2 &= ~STATUS2_NIGHTMARE;
|
||||
}
|
||||
}
|
||||
|
||||
UpdatePokeFlutePartyStatus(gPlayerParty, B_POSITION_PLAYER_LEFT);
|
||||
UpdatePokeFlutePartyStatus(gEnemyParty, B_POSITION_OPPONENT_LEFT);
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_WaitFanfare(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
|
||||
if (!IsFanfareTaskInactive())
|
||||
return;
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
|
|
@ -12262,7 +12262,7 @@ const struct Item gItemsInfo[] =
|
|||
.importance = 1,
|
||||
.pocket = POCKET_KEY_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_TownMap,
|
||||
.iconPic = gItemIcon_TownMap,
|
||||
.iconPalette = gItemIconPalette_TownMap,
|
||||
},
|
||||
|
@ -12442,7 +12442,8 @@ const struct Item gItemsInfo[] =
|
|||
.importance = 1,
|
||||
.pocket = POCKET_KEY_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
|
||||
.fieldUseFunc = ItemUseOutOfBattle_PokeFlute,
|
||||
.battleUsage = EFFECT_ITEM_USE_POKE_FLUTE,
|
||||
.iconPic = gItemIcon_PokeFlute,
|
||||
.iconPalette = gItemIconPalette_PokeFlute,
|
||||
},
|
||||
|
|
|
@ -1284,7 +1284,7 @@ void ItemUseInBattle_BagMenu(u8 taskId)
|
|||
else
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
if (!(B_TRY_CATCH_TRAINER_BALL >= GEN_4 && (ItemId_GetBattleUsage(gSpecialVar_ItemId) == EFFECT_ITEM_THROW_BALL) && (gBattleTypeFlags & BATTLE_TYPE_TRAINER)))
|
||||
if (!ItemId_GetImportance(gSpecialVar_ItemId) && !(B_TRY_CATCH_TRAINER_BALL >= GEN_4 && (ItemId_GetBattleUsage(gSpecialVar_ItemId) == EFFECT_ITEM_THROW_BALL) && (gBattleTypeFlags & BATTLE_TYPE_TRAINER)))
|
||||
RemoveUsedItem();
|
||||
ScheduleBgCopyTilemapToVram(2);
|
||||
if (!InBattlePyramid())
|
||||
|
@ -1499,4 +1499,63 @@ void Task_ItemUse_CloseMessageBoxAndReturnToField_VsSeeker(u8 taskId)
|
|||
Task_CloseCantUseKeyItemMessage(taskId);
|
||||
}
|
||||
|
||||
static void Task_DisplayPokeFluteMessage(u8 taskId)
|
||||
{
|
||||
if (WaitFanfare(FALSE))
|
||||
{
|
||||
if (gTasks[taskId].data[3] == 0)
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gText_PokeFluteAwakenedMon, CloseItemMessage);
|
||||
else
|
||||
DisplayItemMessageOnField(taskId, gText_PokeFluteAwakenedMon, Task_CloseCantUseKeyItemMessage);
|
||||
}
|
||||
}
|
||||
|
||||
static void Task_PlayPokeFlute(u8 taskId)
|
||||
{
|
||||
PlayFanfareByFanfareNum(FANFARE_RG_POKE_FLUTE);
|
||||
gTasks[taskId].func = Task_DisplayPokeFluteMessage;
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_PokeFlute(u8 taskId)
|
||||
{
|
||||
bool32 wokeSomeoneUp = FALSE;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < CalculatePlayerPartyCount(); i++)
|
||||
{
|
||||
if (!ExecuteTableBasedItemEffect(&gPlayerParty[i], ITEM_AWAKENING, i, 0))
|
||||
wokeSomeoneUp = TRUE;
|
||||
}
|
||||
|
||||
if (wokeSomeoneUp)
|
||||
{
|
||||
if (gTasks[taskId].data[3] == 0)
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gText_PlayedPokeFlute, Task_PlayPokeFlute);
|
||||
else
|
||||
DisplayItemMessageOnField(taskId, gText_PlayedPokeFlute, Task_PlayPokeFlute);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gTasks[taskId].data[3] == 0)
|
||||
DisplayItemMessage(taskId, FONT_NORMAL, gText_PlayedPokeFluteCatchy, CloseItemMessage);
|
||||
else
|
||||
DisplayItemMessageOnField(taskId, gText_PlayedPokeFluteCatchy, Task_CloseCantUseKeyItemMessage);
|
||||
}
|
||||
}
|
||||
|
||||
static void ItemUseOnFieldCB_TownMap(u8 taskId)
|
||||
{
|
||||
LockPlayerFieldControls();
|
||||
ScriptContext_SetupScript(EventScript_RegionMap);
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
|
||||
void ItemUseOutOfBattle_TownMap(u8 taskId)
|
||||
{
|
||||
sItemUseOnFieldCB = ItemUseOnFieldCB_TownMap;
|
||||
gFieldCallback = FieldCB_UseItemOnField;
|
||||
gBagMenu->newScreenCallback = CB2_ReturnToField;
|
||||
Task_FadeAndCloseBagMenu(taskId);
|
||||
}
|
||||
|
||||
#undef tUsingRegisteredKeyItem
|
||||
|
|
|
@ -196,6 +196,9 @@ const u8 gText_TheBattle[] = _("the battle");
|
|||
const u8 gText_ThePokemonList[] = _("the POKéMON LIST");
|
||||
const u8 gText_TheShop[] = _("the shop");
|
||||
const u8 gText_ThePC[] = _("the PC");
|
||||
const u8 gText_PlayedPokeFluteCatchy[] = _("Played the POKé FLUTE.\pNow, that's a catchy tune!{PAUSE_UNTIL_PRESS}");
|
||||
const u8 gText_PlayedPokeFlute[] = _("Played the POKé FLUTE.");
|
||||
const u8 gText_PokeFluteAwakenedMon[] = _("The POKé FLUTE awakened sleeping\nPOKéMON.{PAUSE_UNTIL_PRESS}");
|
||||
|
||||
const u8 *const gBagMenu_ReturnToStrings[] =
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue