Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionality to Poké Flute and Town Map #5405

Merged
merged 15 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions asm/macros/battle_script.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,14 @@
.4byte \failInstr
.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
Expand Down
20 changes: 20 additions & 0 deletions data/battle_scripts_2.s
Original file line number Diff line number Diff line change
Expand Up @@ -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::
Expand Down Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion include/constants/battle_string_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,11 @@
#define STRINGID_FOGLIFTED 710
#define STRINGID_PKMNMADESHELLGLEAM 711
#define STRINGID_FICKLEBEAMDOUBLED 712
#define STRINGID_POKEFLUTECATCHY 713
#define STRINGID_POKEFLUTE 714
#define STRINGID_MONHEARINGFLUTEAWOKE 715

#define BATTLESTRINGS_COUNT 713
#define BATTLESTRINGS_COUNT 716

// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
Expand Down
1 change: 1 addition & 0 deletions include/constants/items.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions include/item_use.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions include/strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,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[];
Expand Down
4 changes: 4 additions & 0 deletions src/battle_ai_switch_items.c
Original file line number Diff line number Diff line change
Expand Up @@ -2249,6 +2249,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;
}
Expand Down
7 changes: 7 additions & 0 deletions src/battle_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1553,6 +1556,10 @@ 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[] =
Expand Down
95 changes: 90 additions & 5 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -12378,14 +12378,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)))
Expand All @@ -12404,6 +12409,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)
Expand Down Expand Up @@ -17236,3 +17248,76 @@ void BS_TryRevivalBlessing(void)
MarkBattlerForControllerExec(gBattlerAttacker);
}
}

void BS_CheckPokeFlute(void)
{
NATIVE_ARGS();
u8 battler;
s32 i;
u32 monToCheck, status;
u16 species;
u8 abilityNum;
kittenchilly marked this conversation as resolved.
Show resolved Hide resolved
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
monToCheck = 0;
kittenchilly marked this conversation as resolved.
Show resolved Hide resolved
for (i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].ability != ABILITY_SOUNDPROOF)
{
gBattleMons[i].status1 &= ~STATUS1_SLEEP;
gBattleMons[i].status2 &= ~STATUS2_NIGHTMARE;

}
}
for (i = 0; i < PARTY_SIZE; i++)
{
species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG);
abilityNum = GetMonData(&gPlayerParty[i], MON_DATA_ABILITY_NUM);
status = GetMonData(&gPlayerParty[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(B_POSITION_PLAYER_LEFT);
status = 0;
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, monToCheck, 4, &status);
MarkBattlerForControllerExec(battler);
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
monToCheck = 0;
for (i = 0; i < PARTY_SIZE; i++)
{
species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES_OR_EGG);
abilityNum = GetMonData(&gEnemyParty[i], MON_DATA_ABILITY_NUM);
status = GetMonData(&gEnemyParty[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(B_POSITION_OPPONENT_LEFT);
status = 0;
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, monToCheck, 4, &status);
MarkBattlerForControllerExec(battler);
gBattleCommunication[5] = 1;
}

gBattlescriptCurrInstr = cmd->nextInstr;
}

void BS_WaitFanfare(void)
{
NATIVE_ARGS();

if (!IsFanfareTaskInactive())
return;

gBattlescriptCurrInstr = cmd->nextInstr;
}
5 changes: 3 additions & 2 deletions src/data/items.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down Expand Up @@ -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,
},
Expand Down
61 changes: 60 additions & 1 deletion src/item_use.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 (!(B_TRY_CATCH_TRAINER_BALL >= GEN_4 && (ItemId_GetBattleUsage(gSpecialVar_ItemId) == EFFECT_ITEM_THROW_BALL) && (gBattleTypeFlags & BATTLE_TYPE_TRAINER)) && ItemId_GetBattleUsage(gSpecialVar_ItemId) != EFFECT_ITEM_USE_POKE_FLUTE)
kittenchilly marked this conversation as resolved.
Show resolved Hide resolved
RemoveUsedItem();
ScheduleBgCopyTilemapToVram(2);
if (!InBattlePyramid())
Expand Down Expand Up @@ -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)
{
bool8 wokeSomeoneUp = FALSE;
u8 i;
kittenchilly marked this conversation as resolved.
Show resolved Hide resolved

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
3 changes: 3 additions & 0 deletions src/strings.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,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[] =
{
Expand Down
Loading