Files
Pokemon-Firered/src/field_specials.c
T
2019-11-23 08:09:22 +08:00

2507 lines
75 KiB
C

#include "global.h"
#include "malloc.h"
#include "palette.h"
#include "quest_log.h"
#include "list_menu.h"
#include "diploma.h"
#include "script.h"
#include "field_player_avatar.h"
#include "overworld.h"
#include "field_message_box.h"
#include "event_data.h"
#include "string_util.h"
#include "strings.h"
#include "battle.h"
#include "fieldmap.h"
#include "field_specials.h"
#include "region_map.h"
#include "task.h"
#include "battle_tower.h"
#include "field_camera.h"
#include "field_effect.h"
#include "field_map_obj.h"
#include "menu_indicators.h"
#include "random.h"
#include "mail_data.h"
#include "help_system.h"
#include "sound.h"
#include "text.h"
#include "pokemon_storage_system.h"
#include "script_menu.h"
#include "data.h"
#include "pokedex.h"
#include "window.h"
#include "text_window.h"
#include "menu.h"
#include "mevent.h"
#include "naming_screen.h"
#include "party_menu.h"
#include "dynamic_placeholder_text_util.h"
#include "new_menu_helpers.h"
#include "constants/songs.h"
#include "constants/species.h"
#include "constants/items.h"
#include "constants/map_objects.h"
#include "constants/maps.h"
#include "constants/region_map.h"
#include "constants/moves.h"
static EWRAM_DATA u8 sElevatorCurrentFloorWindowId = 0;
static EWRAM_DATA u16 sElevatorScroll = 0;
static EWRAM_DATA u16 sElevatorCursorPos = 0;
static EWRAM_DATA struct ListMenuItem * sListMenuItems = NULL;
static EWRAM_DATA u16 sListMenuLastScrollPosition = 0;
static EWRAM_DATA u8 sUnknownBoxId = 0;
static EWRAM_DATA u8 sBrailleTextCursorSpriteID = 0;
struct ListMenuTemplate sFieldSpecialsListMenuTemplate;
u16 sFieldSpecialsListMenuScrollBuffer;
static void Task_AnimatePcTurnOn(u8 taskId);
static void PcTurnOnUpdateMetatileId(bool16 flag);
static void Task_ShakeScreen(u8 taskId);
static void Task_EndScreenShake(u8 taskId);
static u16 SampleResortGorgeousMon(void);
static u16 SampleResortGorgeousReward(void);
static void Task_ElevatorShake(u8 taskId);
static void AnimateElevatorWindowView(u16 nfloors, bool8 direction);
static void Task_AnimateElevatorWindowView(u8 taskId);
static void Task_CreateScriptListMenu(u8 taskId);
static void CreateScriptListMenu(void);
static void ScriptListMenuMoveCursorFunction(s32 nothing, bool8 is, struct ListMenu * used);
static void Task_ListMenuHandleInput(u8 taskId);
static void Task_DestroyListMenu(u8 taskId);
static void Task_SuspendListMenu(u8 taskId);
static void Task_RedrawScrollArrowsAndWaitInput(u8 taskId);
static void Task_CreateMenuRemoveScrollIndicatorArrowPair(u8 taskId);
static void Task_ListMenuRemoveScrollIndicatorArrowPair(u8 taskId);
static u16 GetStarterPokemon(u16 starterIdx);
static void ChangeBoxPokemonNickname_CB(void);
static void ChangePokemonNickname_CB(void);
static void Task_RunPokemonLeagueLightingEffect(u8 taskId);
static void Task_CancelPokemonLeagueLightingEffect(u8 taskId);
static void task_deoxys_sound(u8 taskId);
static void MoveDeoxysObject(u8 num);
static void Task_WaitDeoxysFieldEffect(u8 taskId);
static void Task_WingFlapSound(u8 taskId);
static u8 *const sStringVarPtrs[] = {
gStringVar1,
gStringVar2,
gStringVar3
};
void Special_ShowDiploma(void)
{
sub_8112364();
SetMainCallback2(CB2_ShowDiploma);
ScriptContext2_Enable();
}
void Special_ForcePlayerOntoBike(void)
{
if (gPlayerAvatar.flags & 1)
SetPlayerAvatarTransitionFlags(2);
Overworld_SetSavedMusic(MUS_CYCLING);
Overworld_ChangeMusicTo(MUS_CYCLING);
}
void nullsub_74(void)
{
}
u8 Special_GetPlayerAvatarBike(void)
{
if (TestPlayerAvatarFlags(4))
return 1;
else if (TestPlayerAvatarFlags(2))
return 2;
else
return 0;
}
void Special_ShowStringVar4AsFieldMessage(void)
{
ShowFieldMessage(gStringVar4);
}
void Special_GetPlayerXY(void)
{
gSpecialVar_0x8004 = gSaveBlock1Ptr->pos.x;
gSpecialVar_0x8005 = gSaveBlock1Ptr->pos.y;
}
u8 Special_GetPlayerTrainerIdOnesDigit(void)
{
u16 playerId = (gSaveBlock2Ptr->playerTrainerId[1] << 8) | gSaveBlock2Ptr->playerTrainerId[0];
return playerId % 10;
}
void Special_BufferBigGuyOrBigGirlString(void)
{
if (gSaveBlock2Ptr->playerGender == MALE)
StringCopy(gStringVar1, gText_BigGuy);
else
StringCopy(gStringVar1, gText_BigGirl);
}
void Special_BufferSonOrDaughterString(void)
{
if (gSaveBlock2Ptr->playerGender == MALE)
StringCopy(gStringVar1, gText_Son);
else
StringCopy(gStringVar1, gText_Daughter);
}
u8 Special_GetBattleOutcome(void)
{
return gBattleOutcome;
}
void Special_SetHiddenItemFlag(void)
{
FlagSet(gSpecialVar_0x8004);
}
u8 Special_GetLeadMonFriendship(void)
{
struct Pokemon * pokemon = &gPlayerParty[GetLeadMonIndex()];
if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) == 255)
return 6;
else if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 200)
return 5;
else if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 150)
return 4;
else if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 100)
return 3;
else if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 50)
return 2;
else if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) > 0)
return 1;
else
return 0;
}
void Special_TownMap(void)
{
sub_8112364();
sub_80BFF50(1, CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
bool8 Special_PlayerHasGrassPokemonInParty(void)
{
u8 i;
struct Pokemon * pokemon;
u16 species;
for (i = 0; i < PARTY_SIZE; i++)
{
pokemon = &gPlayerParty[i];
if (GetMonData(pokemon, MON_DATA_SANITY_HAS_SPECIES)
&& !GetMonData(pokemon, MON_DATA_IS_EGG)
)
{
species = GetMonData(pokemon, MON_DATA_SPECIES);
if (gBaseStats[species].type1 == TYPE_GRASS || gBaseStats[species].type2 == TYPE_GRASS)
return TRUE;
}
}
return FALSE;
}
void Special_AnimatePcTurnOn(void)
{
u8 taskId;
if (FuncIsActiveTask(Task_AnimatePcTurnOn) != TRUE)
{
taskId = CreateTask(Task_AnimatePcTurnOn, 8);
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = 0;
}
}
static void Task_AnimatePcTurnOn(u8 taskId)
{
s16 *data = gTasks[taskId].data;
if (data[1] == 6)
{
PcTurnOnUpdateMetatileId(data[0] & 1);
DrawWholeMapView();
data[1] = 0;
data[0]++;
if (data[0] == 5)
DestroyTask(taskId);
}
data[1]++;
}
static void PcTurnOnUpdateMetatileId(bool16 a0)
{
u16 metatileId = 0;
s8 deltaX = 0;
s8 deltaY = 0;
u8 direction = GetPlayerFacingDirection();
switch (direction)
{
case DIR_NORTH:
deltaX = 0;
deltaY = -1;
break;
case DIR_WEST:
deltaX = -1;
deltaY = -1;
break;
case DIR_EAST:
deltaX = 1;
deltaY = -1;
break;
}
if (a0)
{
if (gSpecialVar_0x8004 == 0)
metatileId = 0x62;
else if (gSpecialVar_0x8004 == 1)
metatileId = 0x28F;
else if (gSpecialVar_0x8004 == 2)
metatileId = 0x28F;
}
else
{
if (gSpecialVar_0x8004 == 0)
metatileId = 0x63;
else if (gSpecialVar_0x8004 == 1)
metatileId = 0x28A;
else if (gSpecialVar_0x8004 == 2)
metatileId = 0x28A;
}
MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + deltaX + 7, gSaveBlock1Ptr->pos.y + deltaY + 7, metatileId | 0xC00);
}
void Special_AnimatePcTurnOff()
{
u16 metatileId = 0;
s8 deltaX = 0;
s8 deltaY = 0;
u8 direction = GetPlayerFacingDirection();
switch (direction)
{
case DIR_NORTH:
deltaX = 0;
deltaY = -1;
break;
case DIR_WEST:
deltaX = -1;
deltaY = -1;
break;
case DIR_EAST:
deltaX = 1;
deltaY = -1;
break;
}
if (gSpecialVar_0x8004 == 0)
metatileId = 0x62;
else if (gSpecialVar_0x8004 == 1)
metatileId = 0x28F;
else if (gSpecialVar_0x8004 == 2)
metatileId = 0x28F;
MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + deltaX + 7, gSaveBlock1Ptr->pos.y + deltaY + 7, metatileId | 0xC00);
DrawWholeMapView();
}
void SpawnCameraObject(void)
{
u8 mapObjectId = SpawnSpecialFieldObjectParameterized(MAP_OBJ_GFX_YOUNGSTER, 8, 127, gSaveBlock1Ptr->pos.x + 7, gSaveBlock1Ptr->pos.y + 7, 3);
gMapObjects[mapObjectId].mapobj_bit_13 = TRUE;
CameraObjectSetFollowedObjectId(gMapObjects[mapObjectId].spriteId);
}
void RemoveCameraObject(void)
{
CameraObjectSetFollowedObjectId(GetPlayerAvatarObjectId());
RemoveFieldObjectByLocalIdAndMap(127, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
}
void Special_BufferEReaderTrainerName5(void)
{
CopyEReaderTrainerName5(gStringVar1);
}
static const u8 sUnused_83F5B04[] = {
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
12,
2,
4,
5,
1,
8,
7,
11,
3,
10,
9,
6
};
static const u8 sSlotMachineIndices[] = {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
2,
2,
2,
3,
3,
3,
4,
4,
5
};
u8 Special_GetRandomSlotMachine(void)
{
u16 rval = Random() % NELEMS(sSlotMachineIndices);
return sSlotMachineIndices[rval];
}
bool8 LeadMonHasEffortRibbon(void)
{
u8 leadMonIdx = GetLeadMonIndex();
return GetMonData(&gPlayerParty[leadMonIdx], MON_DATA_EFFORT_RIBBON, NULL);
}
void GiveLeadMonEffortRibbon(void)
{
u8 leadMonIdx;
bool8 param;
IncrementGameStat(GAME_STAT_RECEIVED_RIBBONS);
FlagSet(FLAG_SYS_RIBBON_GET);
param = TRUE;
leadMonIdx = GetLeadMonIndex();
SetMonData(&gPlayerParty[leadMonIdx], MON_DATA_EFFORT_RIBBON, &param);
}
bool8 ScrSpecial_AreLeadMonEVsMaxedOut(void)
{
u8 leadMonIndex = GetLeadMonIndex();
if (GetMonEVCount(&gPlayerParty[leadMonIndex]) >= 510)
return TRUE;
else
return FALSE;
}
bool8 Special_IsStarterFirstStageInParty(void)
{
u16 species = GetStarterPokemon(VarGet(VAR_STARTER_MON));
u8 partyCount = CalculatePlayerPartyCount();
u8 i;
for (i = 0; i < partyCount; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) == species)
return TRUE;
}
return FALSE;
}
bool8 Special_IsThereRoomInAnyBoxForMorePokemon(void)
{
u16 i;
u16 j;
for (i = 0; i < TOTAL_BOXES_COUNT; i++)
{
for (j = 0; j < IN_BOX_COUNT; j++)
{
if (GetBoxMonDataFromAnyBox(i, j, MON_DATA_SPECIES) == SPECIES_NONE)
return TRUE;
}
}
return FALSE;
}
bool8 Special_CheckPartyPokerus(void)
{
if (!CheckPartyPokerus(gPlayerParty, 0x3F))
return FALSE;
else
return TRUE;
}
#define tXtrans data[0]
#define tTimer data[1]
#define tNremain data[2]
#define tDuration data[3]
#define tYtrans data[4]
void Special_ShakeScreen(void)
{
/*
* 0x8004 = x translation
* 0x8005 = y translation
* 0x8006 = num interations
* 0x8007 = duration of an iteration
*/
u8 taskId = CreateTask(Task_ShakeScreen, 9);
gTasks[taskId].tXtrans = gSpecialVar_0x8005;
gTasks[taskId].tTimer = 0;
gTasks[taskId].tNremain = gSpecialVar_0x8006;
gTasks[taskId].tDuration = gSpecialVar_0x8007;
gTasks[taskId].tYtrans = gSpecialVar_0x8004;
SetCameraPanningCallback(NULL);
PlaySE(SE_W070);
}
static void Task_ShakeScreen(u8 taskId)
{
s16 *data = gTasks[taskId].data;
tTimer++;
if (tTimer % tDuration == 0)
{
tTimer = 0;
tNremain--;
tXtrans = -tXtrans;
tYtrans = -tYtrans;
SetCameraPanning(tXtrans, tYtrans);
if (tNremain == 0)
{
Task_EndScreenShake(taskId);
InstallCameraPanAheadCallback();
}
}
}
static void Task_EndScreenShake(u8 taskId)
{
DestroyTask(taskId);
EnableBothScriptContexts();
}
#undef tYtrans
#undef tDuration
#undef tNremain
#undef tTimer
#undef tXtrans
u8 GetLeadMonIndex(void)
{
u8 partyCount = CalculatePlayerPartyCount();
u8 i;
struct Pokemon * pokemon;
for (i = 0; i < partyCount; i++)
{
pokemon = &gPlayerParty[i];
if (GetMonData(pokemon, MON_DATA_SPECIES2, NULL) != SPECIES_EGG && GetMonData(pokemon, MON_DATA_SPECIES2, NULL) != SPECIES_NONE)
return i;
}
return 0;
}
u16 Special_GetSpeciesOfPartySlot_x8004(void)
{
return GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES2, NULL);
}
bool8 Special_BufferMonOTNameAndCompareToPlayerName(void)
{
GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_OT_NAME, gStringVar1);
if (!StringCompare(gSaveBlock2Ptr->playerName, gStringVar1))
return FALSE;
else
return TRUE;
}
void nullsub_75(void)
{
}
void sub_80CADC4(void)
{
u8 t = EOS;
AddTextPrinterParameterized(0, 2, &t, 0, 1, 0, NULL);
sub_809D424();
}
void Special_SetVermilionTrashCans(void)
{
u16 idx = (Random() % 15) + 1;
gSpecialVar_0x8004 = idx;
gSpecialVar_0x8005 = idx;
switch (gSpecialVar_0x8004)
{
case 1:
idx = Random() % 2;
if (idx == 0)
gSpecialVar_0x8005 += 1;
else
gSpecialVar_0x8005 += 5;
break;
case 2:
case 3:
case 4:
idx = Random() % 3;
if (idx == 0)
gSpecialVar_0x8005 += 1;
else if (idx == 1)
gSpecialVar_0x8005 += 5;
else
gSpecialVar_0x8005 -= 1;
break;
case 5:
idx = Random() % 2;
if (idx == 0)
gSpecialVar_0x8005 += 5;
else
gSpecialVar_0x8005 -= 1;
break;
case 6:
idx = Random() % 3;
if (idx == 0)
gSpecialVar_0x8005 -= 5;
else if (idx == 1)
gSpecialVar_0x8005 += 1;
else
gSpecialVar_0x8005 += 5;
break;
case 7:
case 8:
case 9:
idx = Random() % 4;
if (idx == 0)
gSpecialVar_0x8005 -= 5;
else if (idx == 1)
gSpecialVar_0x8005 += 1;
else if (idx == 2)
gSpecialVar_0x8005 += 5;
else
gSpecialVar_0x8005 -= 1;
break;
case 10:
idx = Random() % 3;
if (idx == 0)
gSpecialVar_0x8005 -= 5;
else if (idx == 1)
gSpecialVar_0x8005 += 5;
else
gSpecialVar_0x8005 -= 1;
break;
case 11:
idx = Random() % 2;
if (idx == 0)
gSpecialVar_0x8005 -= 5;
else
gSpecialVar_0x8005 += 1;
break;
case 12:
case 13:
case 14:
idx = Random() % 3;
if (idx == 0)
gSpecialVar_0x8005 -= 5;
else if (idx == 1)
gSpecialVar_0x8005 += 1;
else
gSpecialVar_0x8005 -= 1;
break;
case 15:
idx = Random() % 2;
if (idx == 0)
gSpecialVar_0x8005 -= 5;
else
gSpecialVar_0x8005 -= 1;
break;
}
if (gSpecialVar_0x8005 > 15)
{
if (gSpecialVar_0x8004 % 5 == 1)
gSpecialVar_0x8005 = gSpecialVar_0x8004 + 1;
else if (gSpecialVar_0x8004 % 5 == 0)
gSpecialVar_0x8005 = gSpecialVar_0x8004 - 1;
else
gSpecialVar_0x8005 = gSpecialVar_0x8004 + 1;
}
}
static const u16 sResortGorgeousDeluxeRewards[] = {
ITEM_BIG_PEARL,
ITEM_PEARL,
ITEM_STARDUST,
ITEM_STAR_PIECE,
ITEM_NUGGET,
ITEM_RARE_CANDY
};
void IncrementResortGorgeousStepCounter(void)
{
u16 var4035 = VarGet(VAR_RESORT_GOREGEOUS_STEP_COUNTER);
if (VarGet(VAR_RESORT_GORGEOUS_REQUESTED_MON) != SPECIES_NONE)
{
var4035++;
if (var4035 >= 250)
{
VarSet(VAR_RESORT_GORGEOUS_REQUESTED_MON, 0xFFFF);
VarSet(VAR_RESORT_GOREGEOUS_STEP_COUNTER, 0);
}
else
{
VarSet(VAR_RESORT_GOREGEOUS_STEP_COUNTER, var4035);
}
}
}
void Special_SampleResortGorgeousMonAndReward(void)
{
u16 var4036 = VarGet(VAR_RESORT_GORGEOUS_REQUESTED_MON);
if (var4036 == SPECIES_NONE || var4036 == 0xFFFF)
{
VarSet(VAR_RESORT_GORGEOUS_REQUESTED_MON, SampleResortGorgeousMon());
VarSet(VAR_RESORT_GORGEOUS_REWARD, SampleResortGorgeousReward());
VarSet(VAR_RESORT_GOREGEOUS_STEP_COUNTER, 0);
}
StringCopy(gStringVar1, gSpeciesNames[VarGet(VAR_RESORT_GORGEOUS_REQUESTED_MON)]);
}
static u16 SampleResortGorgeousMon(void)
{
u16 i;
u16 species;
for (i = 0; i < 100; i++)
{
species = (Random() % (NUM_SPECIES - 1)) + 1;
if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), 0) == TRUE)
return species;
}
while (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), 0) != TRUE)
{
if (species == SPECIES_BULBASAUR)
species = NUM_SPECIES - 1;
else
species--;
}
return species;
}
static u16 SampleResortGorgeousReward(void)
{
if ((Random() % 100) >= 30)
return ITEM_LUXURY_BALL;
else
return sResortGorgeousDeluxeRewards[Random() % NELEMS(sResortGorgeousDeluxeRewards)];
}
bool8 Special_CheckAddCoins(void)
{
if (gSpecialVar_Result + gSpecialVar_0x8006 > 9999)
return FALSE;
else
return TRUE;
}
static const struct WindowTemplate sElevatorCurrentFloorWindowTemplate = {
.bg = 0,
.tilemapLeft = 22,
.tilemapTop = 1,
.width = 7,
.height = 4,
.paletteNum = 0xF,
.baseBlock = 0x008
};
static const u8 *const sFloorNamePointers[] = {
gText_B4F,
gText_B3F,
gText_B2F,
gText_B1F,
gText_1F,
gText_2F,
gText_3F,
gText_4F,
gText_5F,
gText_6F,
gText_7F,
gText_8F,
gText_9F,
gText_10F,
gText_11F,
gText_Rooftop
};
static const u8 sUnused_83F5B84[] = {
26,
26,
26,
26,
30,
30,
30,
30,
30,
30,
30,
30,
30,
26,
26,
18
};
static const u16 sElevatorWindowMetatilesGoingUp[][3] = {
{0x2e8, 0x2e9, 0x2ea},
{0x2f0, 0x2f1, 0x2f2},
{0x2f8, 0x2f9, 0x2fa}
};
static const u16 sElevatorWindowMetatilesGoingDown[][3] = {
{0x2e8, 0x2ea, 0x2e9},
{0x2f0, 0x2f2, 0x2f1},
{0x2f8, 0x2fa, 0x2f9}
};
static const u8 sElevatorAnimationDuration[] = {
8,
16,
24,
32,
38,
46,
53,
56,
57
};
static const u8 sElevatorWindowAnimDuration[] = {
3,
6,
9,
12,
15,
18,
21,
24,
27
};
void Special_GetElevatorFloor(void)
{
u16 floor = 4;
if (gSaveBlock1Ptr->warp2.mapGroup == MAP_GROUP(ROCKET_HIDEOUT_B1F))
{
switch (gSaveBlock1Ptr->warp2.mapNum)
{
case MAP_NUM(SILPH_CO_1F):
floor = 4;
break;
case MAP_NUM(SILPH_CO_2F):
floor = 5;
break;
case MAP_NUM(SILPH_CO_3F):
floor = 6;
break;
case MAP_NUM(SILPH_CO_4F):
floor = 7;
break;
case MAP_NUM(SILPH_CO_5F):
floor = 8;
break;
case MAP_NUM(SILPH_CO_6F):
floor = 9;
break;
case MAP_NUM(SILPH_CO_7F):
floor = 10;
break;
case MAP_NUM(SILPH_CO_8F):
floor = 11;
break;
case MAP_NUM(SILPH_CO_9F):
floor = 12;
break;
case MAP_NUM(SILPH_CO_10F):
floor = 13;
break;
case MAP_NUM(SILPH_CO_11F):
floor = 14;
break;
case MAP_NUM(ROCKET_HIDEOUT_B1F):
floor = 3;
break;
case MAP_NUM(ROCKET_HIDEOUT_B2F):
floor = 2;
break;
case MAP_NUM(ROCKET_HIDEOUT_B4F):
floor = 0;
break;
}
}
if (gSaveBlock1Ptr->warp2.mapGroup == MAP_GROUP(CELADON_CITY_DEPARTMENT_STORE_1F))
{
switch (gSaveBlock1Ptr->warp2.mapNum)
{
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_1F):
floor = 4;
break;
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_2F):
floor = 5;
break;
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_3F):
floor = 6;
break;
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_4F):
floor = 7;
break;
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_5F):
floor = 8;
break;
}
}
if (gSaveBlock1Ptr->warp2.mapGroup == MAP_GROUP(SEVEN_ISLAND_TRAINER_TOWER_1F))
{
switch (gSaveBlock1Ptr->warp2.mapNum)
{
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_1F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_2F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_3F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_4F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_5F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_6F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_7F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_8F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_ROOF):
floor = 15;
break;
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_LOBBY):
floor = 3;
break;
}
}
VarSet(VAR_ELEVATOR_FLOOR, floor);
}
u16 Special_InitElevatorFloorSelectMenuPos(void)
{
sElevatorScroll = 0;
sElevatorCursorPos = 0;
if (gSaveBlock1Ptr->warp2.mapGroup == MAP_GROUP(ROCKET_HIDEOUT_B1F))
{
switch (gSaveBlock1Ptr->warp2.mapNum)
{
case MAP_NUM(SILPH_CO_11F):
sElevatorScroll = 0;
sElevatorCursorPos = 0;
break;
case MAP_NUM(SILPH_CO_10F):
sElevatorScroll = 0;
sElevatorCursorPos = 1;
break;
case MAP_NUM(SILPH_CO_9F):
sElevatorScroll = 0;
sElevatorCursorPos = 2;
break;
case MAP_NUM(SILPH_CO_8F):
sElevatorScroll = 0;
sElevatorCursorPos = 3;
break;
case MAP_NUM(SILPH_CO_7F):
sElevatorScroll = 0;
sElevatorCursorPos = 4;
break;
case MAP_NUM(SILPH_CO_6F):
sElevatorScroll = 1;
sElevatorCursorPos = 4;
break;
case MAP_NUM(SILPH_CO_5F):
sElevatorScroll = 2;
sElevatorCursorPos = 4;
break;
case MAP_NUM(SILPH_CO_4F):
sElevatorScroll = 3;
sElevatorCursorPos = 4;
break;
case MAP_NUM(SILPH_CO_3F):
sElevatorScroll = 4;
sElevatorCursorPos = 4;
break;
case MAP_NUM(SILPH_CO_2F):
sElevatorScroll = 5;
sElevatorCursorPos = 4;
break;
case MAP_NUM(SILPH_CO_1F):
sElevatorScroll = 5;
sElevatorCursorPos = 5;
break;
case MAP_NUM(ROCKET_HIDEOUT_B1F):
sElevatorScroll = 0;
sElevatorCursorPos = 0;
break;
case MAP_NUM(ROCKET_HIDEOUT_B2F):
sElevatorScroll = 0;
sElevatorCursorPos = 1;
break;
case MAP_NUM(ROCKET_HIDEOUT_B4F):
sElevatorScroll = 0;
sElevatorCursorPos = 2;
break;
}
}
if (gSaveBlock1Ptr->warp2.mapGroup == MAP_GROUP(CELADON_CITY_DEPARTMENT_STORE_1F))
{
switch (gSaveBlock1Ptr->warp2.mapNum)
{
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_5F):
sElevatorScroll = 0;
sElevatorCursorPos = 0;
break;
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_4F):
sElevatorScroll = 0;
sElevatorCursorPos = 1;
break;
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_3F):
sElevatorScroll = 0;
sElevatorCursorPos = 2;
break;
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_2F):
sElevatorScroll = 0;
sElevatorCursorPos = 3;
break;
case MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_1F):
sElevatorScroll = 0;
sElevatorCursorPos = 4;
break;
}
}
if (gSaveBlock1Ptr->warp2.mapGroup == MAP_GROUP(SEVEN_ISLAND_TRAINER_TOWER_1F))
{
switch (gSaveBlock1Ptr->warp2.mapNum)
{
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_1F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_2F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_3F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_4F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_5F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_6F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_7F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_8F):
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_ROOF):
sElevatorScroll = 0;
sElevatorCursorPos = 0;
break;
case MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_LOBBY):
sElevatorScroll = 0;
sElevatorCursorPos = 1;
break;
}
}
return sElevatorCursorPos;
}
void Special_AnimateElevator(void)
{
u16 nfloors;
s16 *data = gTasks[CreateTask(Task_ElevatorShake, 9)].data;
data[1] = 0;
data[2] = 0;
data[4] = 1;
if (gSpecialVar_0x8005 > gSpecialVar_0x8006)
{
nfloors = gSpecialVar_0x8005 - gSpecialVar_0x8006;
data[6] = 1;
}
else
{
nfloors = gSpecialVar_0x8006 - gSpecialVar_0x8005;
data[6] = 0;
}
if (nfloors > 8)
nfloors = 8;
data[5] = sElevatorAnimationDuration[nfloors];
SetCameraPanningCallback(NULL);
AnimateElevatorWindowView(nfloors, data[6]);
PlaySE(SE_ELEBETA);
}
static void Task_ElevatorShake(u8 taskId)
{
s16 *data = gTasks[taskId].data;
data[1]++;
if ((data[1] % 3) == 0)
{
data[1] = 0;
data[2]++;
data[4] = -data[4];
SetCameraPanning(0, data[4]);
if (data[2] == data[5])
{
PlaySE(SE_PINPON);
DestroyTask(taskId);
EnableBothScriptContexts();
InstallCameraPanAheadCallback();
}
}
}
void Special_DrawElevatorCurrentFloorWindow(void)
{
const u8 *floorname;
u32 strwidth;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE)
{
sElevatorCurrentFloorWindowId = AddWindow(&sElevatorCurrentFloorWindowTemplate);
TextWindow_SetStdFrame0_WithPal(sElevatorCurrentFloorWindowId, 0x21D, 0xD0);
DrawStdFrameWithCustomTileAndPalette(sElevatorCurrentFloorWindowId, FALSE, 0x21D, 0xD);
AddTextPrinterParameterized(sElevatorCurrentFloorWindowId, 2, gText_NowOn, 0, 2, 0xFF, NULL);
floorname = sFloorNamePointers[gSpecialVar_0x8005];
strwidth = GetStringWidth(2, floorname, 0);
AddTextPrinterParameterized(sElevatorCurrentFloorWindowId, 2, floorname, 56 - strwidth, 16, 0xFF, NULL);
PutWindowTilemap(sElevatorCurrentFloorWindowId);
CopyWindowToVram(sElevatorCurrentFloorWindowId, 3);
}
}
void Special_CloseElevatorCurrentFloorWindow(void)
{
ClearStdWindowAndFrameToTransparent(sElevatorCurrentFloorWindowId, TRUE);
RemoveWindow(sElevatorCurrentFloorWindowId);
}
static void AnimateElevatorWindowView(u16 nfloors, u8 direction)
{
u8 taskId;
if (FuncIsActiveTask(Task_AnimateElevatorWindowView) != TRUE)
{
taskId = CreateTask(Task_AnimateElevatorWindowView, 8);
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = direction;
gTasks[taskId].data[3] = sElevatorWindowAnimDuration[nfloors];
}
}
static void Task_AnimateElevatorWindowView(u8 taskId)
{
u8 i;
u8 j;
s16 *data = gTasks[taskId].data;
if (data[1] == 6)
{
data[0]++;
if (data[2] == 0)
{
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
MapGridSetMetatileIdAt(j + 8, i + 7, sElevatorWindowMetatilesGoingUp[i][data[0] % 3] | 0xC00);
}
}
}
else
{
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
MapGridSetMetatileIdAt(j + 8, i + 7, sElevatorWindowMetatilesGoingDown[i][data[0] % 3] | 0xC00);
}
}
}
DrawWholeMapView();
data[1] = 0;
if (data[0] == data[3])
DestroyTask(taskId);
}
data[1]++;
}
void Special_ListMenu(void)
{
u8 taskId;
struct Task * task;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE)
{
taskId = CreateTask(Task_CreateScriptListMenu, 8);
task = &gTasks[taskId];
switch (gSpecialVar_0x8004)
{
case 0:
task->data[0] = 4;
task->data[1] = 9;
task->data[2] = 1;
task->data[3] = 1;
task->data[4] = 12;
task->data[5] = 7;
task->data[6] = 1;
task->data[15] = taskId;
break;
case 1:
task->data[0] = 7;
task->data[1] = 12;
task->data[2] = 1;
task->data[3] = 1;
task->data[4] = 8;
task->data[5] = 12;
task->data[6] = 0;
task->data[15] = taskId;
task->data[7] = sElevatorScroll;
task->data[8] = sElevatorCursorPos;
break;
case 2:
task->data[0] = 4;
task->data[1] = 4;
task->data[2] = 1;
task->data[3] = 1;
task->data[4] = 8;
task->data[5] = 8;
task->data[6] = 0;
task->data[15] = taskId;
break;
case 3:
task->data[0] = 4;
task->data[1] = 6;
task->data[2] = 1;
task->data[3] = 1;
task->data[4] = 8;
task->data[5] = 8;
task->data[6] = 0;
task->data[15] = taskId;
break;
case 4:
task->data[0] = 4;
task->data[1] = 4;
task->data[2] = 1;
task->data[3] = 1;
task->data[4] = 17;
task->data[5] = 8;
task->data[6] = 1;
task->data[15] = taskId;
break;
case 5:
task->data[0] = 7;
task->data[1] = 12;
task->data[2] = 16;
task->data[3] = 1;
task->data[4] = 17;
task->data[5] = 12;
task->data[6] = 0;
task->data[15] = taskId;
break;
case 6:
task->data[0] = 3;
task->data[1] = 3;
task->data[2] = 1;
task->data[3] = 1;
task->data[4] = 8;
task->data[5] = 6;
task->data[6] = 0;
task->data[15] = taskId;
break;
case 99:
break;
default:
gSpecialVar_Result = 0x7F;
DestroyTask(taskId);
break;
}
}
}
static const u8 *const sListMenuLabels[][12] = {
{
gText_BoulderBadge,
gText_CascadeBadge,
gText_ThunderBadge,
gText_RainbowBadge,
gText_SoulBadge,
gText_MarshBadge,
gText_VolcanoBadge,
gText_EarthBadge,
gOtherText_Exit,
}, {
gText_11F,
gText_10F,
gText_9F,
gText_8F,
gText_7F,
gText_6F,
gText_5F,
gText_4F,
gText_3F,
gText_2F,
gText_1F,
gOtherText_Exit,
}, {
gText_B1F,
gText_B2F,
gText_B4F,
gOtherText_Exit,
}, {
gText_5F,
gText_4F,
gText_3F,
gText_2F,
gText_1F,
gOtherText_Exit,
}, {
gText_LinkedGamePlay,
gText_DirectCorner,
gText_UnionRoom,
gOtherText_Quit,
}, {
gText_Energypowder_50,
gText_EnergyRoot_80,
gText_HealPowder_50,
gText_RevivalHerb_300,
gText_Protein_1000,
gText_Iron_1000,
gText_Carbos_1000,
gText_Calcium_1000,
gText_Zinc_1000,
gText_HpUp_1000,
gText_PpUp_3000,
gOtherText_Exit,
}, {
gText_Rooftop,
gText_B1F,
gOtherText_Exit,
}
};
static void Task_CreateScriptListMenu(u8 taskId)
{
struct WindowTemplate template;
u8 i;
s32 width;
s32 mwidth;
struct Task * task = &gTasks[taskId];
u8 windowId;
ScriptContext2_Enable();
if (gSpecialVar_0x8004 == 1)
sListMenuLastScrollPosition = sElevatorScroll;
else
sListMenuLastScrollPosition = 0;
sListMenuItems = AllocZeroed(task->data[1] * sizeof(struct ListMenuItem));
CreateScriptListMenu();
mwidth = 0;
for (i = 0; i < task->data[1]; i++)
{
sListMenuItems[i].label = sListMenuLabels[gSpecialVar_0x8004][i];
sListMenuItems[i].index = i;
width = GetStringWidth(2, sListMenuItems[i].label, 0);
if (width > mwidth)
mwidth = width;
}
task->data[4] = (mwidth + 9) / 8 + 1;
if (task->data[2] + task->data[4] > 29)
task->data[2] = 29 - task->data[4];
template = SetWindowTemplateFields(0, task->data[2], task->data[3], task->data[4], task->data[5], 15, 0x038);
task->data[13] = windowId = AddWindow(&template);
SetStdWindowBorderStyle(task->data[13], 0);
sFieldSpecialsListMenuTemplate.totalItems = task->data[1];
sFieldSpecialsListMenuTemplate.maxShowed = task->data[0];
sFieldSpecialsListMenuTemplate.windowId = task->data[13];
Task_CreateMenuRemoveScrollIndicatorArrowPair(taskId);
task->data[14] = ListMenuInit(&sFieldSpecialsListMenuTemplate, task->data[7], task->data[8]);
PutWindowTilemap(task->data[13]);
CopyWindowToVram(task->data[13], 3);
gTasks[taskId].func = Task_ListMenuHandleInput;
}
static void CreateScriptListMenu(void)
{
sFieldSpecialsListMenuTemplate.items = sListMenuItems;
sFieldSpecialsListMenuTemplate.moveCursorFunc = ScriptListMenuMoveCursorFunction;
sFieldSpecialsListMenuTemplate.itemPrintFunc = NULL;
sFieldSpecialsListMenuTemplate.totalItems = 1;
sFieldSpecialsListMenuTemplate.maxShowed = 1;
sFieldSpecialsListMenuTemplate.windowId = 0;
sFieldSpecialsListMenuTemplate.header_X = 0;
sFieldSpecialsListMenuTemplate.item_X = 8;
sFieldSpecialsListMenuTemplate.cursor_X = 0;
sFieldSpecialsListMenuTemplate.upText_Y = 0;
sFieldSpecialsListMenuTemplate.cursorPal = 2;
sFieldSpecialsListMenuTemplate.fillValue = 1;
sFieldSpecialsListMenuTemplate.cursorShadowPal = 3;
sFieldSpecialsListMenuTemplate.lettersSpacing = 1;
sFieldSpecialsListMenuTemplate.itemVerticalPadding = 0;
sFieldSpecialsListMenuTemplate.scrollMultiple = 0;
sFieldSpecialsListMenuTemplate.fontId = 2;
sFieldSpecialsListMenuTemplate.cursorKind = 0;
}
static void ScriptListMenuMoveCursorFunction(s32 nothing, bool8 is, struct ListMenu * used)
{
u8 taskId;
struct Task * task;
PlaySE(SE_SELECT);
taskId = FindTaskIdByFunc(Task_ListMenuHandleInput);
if (taskId != 0xFF)
{
task = &gTasks[taskId];
ListMenuGetScrollAndRow(task->data[14], &sFieldSpecialsListMenuScrollBuffer, NULL);
sListMenuLastScrollPosition = sFieldSpecialsListMenuScrollBuffer;
}
}
static void Task_ListMenuHandleInput(u8 taskId)
{
s32 input;
struct Task * task;
task = &gTasks[taskId];
task++;task--;
input = ListMenu_ProcessInput(task->data[14]);
switch (input)
{
case -1:
break;
case -2:
gSpecialVar_Result = 0x7F;
PlaySE(SE_SELECT);
Task_DestroyListMenu(taskId);
break;
default:
gSpecialVar_Result = input;
PlaySE(SE_SELECT);
if (task->data[6] == 0 || input == task->data[1] - 1)
{
Task_DestroyListMenu(taskId);
}
else
{
Task_ListMenuRemoveScrollIndicatorArrowPair(taskId);
task->func = Task_SuspendListMenu;
EnableBothScriptContexts();
}
break;
}
}
static void Task_DestroyListMenu(u8 taskId)
{
struct Task * task = &gTasks[taskId];
Task_ListMenuRemoveScrollIndicatorArrowPair(taskId);
DestroyListMenuTask(task->data[14], NULL, NULL);
Free(sListMenuItems);
ClearStdWindowAndFrameToTransparent(task->data[13], TRUE);
FillWindowPixelBuffer(task->data[13], PIXEL_FILL(0));
ClearWindowTilemap(task->data[13]);
CopyWindowToVram(task->data[13], 2);
RemoveWindow(task->data[13]);
DestroyTask(taskId);
EnableBothScriptContexts();
}
static void Task_SuspendListMenu(u8 taskId)
{
switch (gTasks[taskId].data[6])
{
case 1:
break;
case 2:
gTasks[taskId].data[6] = 1;
gTasks[taskId].func = Task_RedrawScrollArrowsAndWaitInput;
break;
}
}
void Special_ReturnToListMenu(void)
{
u8 taskId = FindTaskIdByFunc(Task_SuspendListMenu);
if (taskId == 0xFF)
EnableBothScriptContexts();
else
gTasks[taskId].data[6]++;
}
static void Task_RedrawScrollArrowsAndWaitInput(u8 taskId)
{
ScriptContext2_Enable();
Task_CreateMenuRemoveScrollIndicatorArrowPair(taskId);
gTasks[taskId].func = Task_ListMenuHandleInput;
}
static void Task_CreateMenuRemoveScrollIndicatorArrowPair(u8 taskId)
{
struct Task * task = &gTasks[taskId];
struct ScrollArrowsTemplate template = {
.firstArrowType = 2,
.secondArrowType = 3,
.tileTag = 2000,
.palTag = 100
};
if (task->data[0] != task->data[1])
{
template.firstX = 4 * task->data[4] + 8 * task->data[2];
template.firstY = 8;
template.secondX = 4 * task->data[4] + 8 * task->data[2];
template.secondY = 8 * task->data[5] + 10;
template.fullyUpThreshold = 0;
template.fullyDownThreshold = task->data[1] - task->data[0];
task->data[12] = AddScrollIndicatorArrowPair(&template, &sListMenuLastScrollPosition);
}
}
static void Task_ListMenuRemoveScrollIndicatorArrowPair(u8 taskId)
{
struct Task * task = &gTasks[taskId];
if (task->data[0] != task->data[1])
RemoveScrollIndicatorArrowPair(task->data[12]);
}
void Special_ForcePlayerToStartSurfing(void)
{
HelpSystem_SetSomeVariable2(22);
SetPlayerAvatarTransitionFlags(8);
}
static const u16 sStarterMon[] = {
SPECIES_BULBASAUR,
SPECIES_SQUIRTLE,
SPECIES_CHARMANDER
};
static u16 GetStarterPokemon(u16 idx)
{
if (idx >= NELEMS(sStarterMon))
idx = 0;
return sStarterMon[idx];
}
u16 ScrSpecial_GetStarter(void)
{
return GetStarterPokemon(VarGet(VAR_STARTER_MON));
}
void Special_SetSeenMon(void)
{
GetSetPokedexFlag(SpeciesToNationalPokedexNum(gSpecialVar_0x8004), 2);
}
void sub_80CBDE8(void)
{
gSelectedEventObject = 0;
gSpecialVar_TextColor = 0xFF;
}
u8 ContextNpcGetTextColor(void)
{
u8 gfxId;
if (gSpecialVar_TextColor != 0xFF)
return gSpecialVar_TextColor;
else if (gSelectedEventObject == 0)
return 3;
else
{
gfxId = gMapObjects[gSelectedEventObject].graphicsId;
if (gfxId >= MAP_OBJ_GFX_VAR_0)
gfxId = VarGetFieldObjectGraphicsId(gfxId - MAP_OBJ_GFX_VAR_0);
return GetColorFromTextColorTable(gfxId);
}
}
static bool8 HasMonBeenRenamed(u8 idx)
{
struct Pokemon * pokemon = &gPlayerParty[idx];
u8 language;
GetMonData(pokemon, MON_DATA_NICKNAME, gStringVar1);
language = GetMonData(pokemon, MON_DATA_LANGUAGE, &language);
if (language != LANGUAGE_ENGLISH)
return TRUE;
else if (StringCompare(gSpeciesNames[GetMonData(pokemon, MON_DATA_SPECIES, NULL)], gStringVar1) != 0)
return TRUE;
else
return FALSE;
}
bool8 Special_HasLeadMonBeenRenamed(void)
{
return HasMonBeenRenamed(GetLeadMonIndex());
}
void TV_PrintIntToStringVar(u8 varidx, s32 number)
{
s32 n = CountDigits(number);
ConvertIntToDecimalStringN(sStringVarPtrs[varidx], number, STR_CONV_MODE_LEFT_ALIGN, n);
}
s32 CountDigits(s32 number)
{
if (number / 10 == 0)
return 1;
else if (number / 100 == 0)
return 2;
else if (number / 1000 == 0)
return 3;
else if (number / 10000 == 0)
return 4;
else if (number / 100000 == 0)
return 5;
else if (number / 1000000 == 0)
return 6;
else if (number / 10000000 == 0)
return 7;
else if (number / 100000000 == 0)
return 8;
else
return 1;
}
bool8 NameRaterWasNicknameChanged(void)
{
struct Pokemon * pokemon = &gPlayerParty[gSpecialVar_0x8004];
GetMonData(pokemon, MON_DATA_NICKNAME, gStringVar1);
if (StringCompare(gStringVar3, gStringVar1) == 0)
return FALSE;
else
return TRUE;
}
void ChangeBoxPokemonNickname(void)
{
struct BoxPokemon * pokemon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos);
u16 species;
u8 gender;
u32 personality;
GetBoxMonData(pokemon, MON_DATA_NICKNAME, gStringVar3);
GetBoxMonData(pokemon, MON_DATA_NICKNAME, gStringVar2);
species = GetBoxMonData(pokemon, MON_DATA_SPECIES, NULL);
gender = GetBoxMonGender(pokemon);
personality = GetBoxMonData(pokemon, MON_DATA_PERSONALITY, NULL);
DoNamingScreen(3, gStringVar2, species, gender, personality, ChangeBoxPokemonNickname_CB);
}
static void ChangeBoxPokemonNickname_CB(void)
{
SetBoxMonNickFromAnyBox(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar2);
CB2_ReturnToFieldContinueScriptPlayMapMusic();
}
void ChangePokemonNickname(void)
{
u16 species;
u8 gender;
u32 personality;
GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3);
GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2);
species = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES, NULL);
gender = GetMonGender(&gPlayerParty[gSpecialVar_0x8004]);
personality = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_PERSONALITY, NULL);
DoNamingScreen(3, gStringVar2, species, gender, personality, ChangePokemonNickname_CB);
}
static void ChangePokemonNickname_CB(void)
{
SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2);
CB2_ReturnToFieldContinueScriptPlayMapMusic();
}
void TV_CopyNicknameToStringVar1AndEnsureTerminated(void)
{
GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar1);
StringGetEnd10(gStringVar1);
}
void TV_CheckMonOTIDEqualsPlayerID(void)
{
if (GetPlayerTrainerId() == GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_OT_ID, NULL))
gSpecialVar_Result = FALSE;
else
gSpecialVar_Result = TRUE;
}
u32 GetPlayerTrainerId(void)
{
return (gSaveBlock2Ptr->playerTrainerId[3] << 24) | (gSaveBlock2Ptr->playerTrainerId[2] << 16) | (gSaveBlock2Ptr->playerTrainerId[1] << 8) | gSaveBlock2Ptr->playerTrainerId[0];
}
u8 GetUnlockedSeviiAreas(void)
{
u8 result = 0;
if (FlagGet(FLAG_WORLD_MAP_ONE_ISLAND) == TRUE)
result |= 1 << 0;
if (FlagGet(FLAG_WORLD_MAP_TWO_ISLAND) == TRUE)
result |= 1 << 1;
if (FlagGet(FLAG_WORLD_MAP_THREE_ISLAND) == TRUE)
result |= 1 << 2;
if (FlagGet(FLAG_WORLD_MAP_FOUR_ISLAND) == TRUE)
result |= 1 << 3;
if (FlagGet(FLAG_WORLD_MAP_FIVE_ISLAND) == TRUE)
result |= 1 << 4;
if (FlagGet(FLAG_WORLD_MAP_SIX_ISLAND) == TRUE)
result |= 1 << 5;
if (FlagGet(FLAG_WORLD_MAP_SEVEN_ISLAND) == TRUE)
result |= 1 << 6;
return result;
}
void Special_UpdateTrainerCardPhotoIcons(void)
{
u16 species[PARTY_SIZE];
u32 personality[PARTY_SIZE];
u8 i;
u8 partyCount;
for (i = 0; i < PARTY_SIZE; i++)
species[i] = SPECIES_NONE;
partyCount = CalculatePlayerPartyCount();
for (i = 0; i < partyCount; i++)
{
species[i] = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL);
personality[i] = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY, NULL);
}
VarSet(VAR_TRAINER_CARD_MON_ICON_1, SpeciesToMailSpecies(species[0], personality[0]));
VarSet(VAR_TRAINER_CARD_MON_ICON_2, SpeciesToMailSpecies(species[1], personality[1]));
VarSet(VAR_TRAINER_CARD_MON_ICON_3, SpeciesToMailSpecies(species[2], personality[2]));
VarSet(VAR_TRAINER_CARD_MON_ICON_4, SpeciesToMailSpecies(species[3], personality[3]));
VarSet(VAR_TRAINER_CARD_MON_ICON_5, SpeciesToMailSpecies(species[4], personality[4]));
VarSet(VAR_TRAINER_CARD_MON_ICON_6, SpeciesToMailSpecies(species[5], personality[5]));
VarSet(VAR_TRAINER_CARD_MON_ICON_TINT_IDX, gSpecialVar_0x8004);
}
u16 Special_StickerLadyGetBragFlags(void)
{
u16 result = 0;
u32 numEggs;
gSpecialVar_0x8004 = GetGameStat(GAME_STAT_ENTERED_HOF);
numEggs = GetGameStat(GAME_STAT_HATCHED_EGGS);
gSpecialVar_0x8006 = GetGameStat(GAME_STAT_LINK_BATTLE_WINS);
if (numEggs > 0xFFFF)
gSpecialVar_0x8005 = 0xFFFF;
else
gSpecialVar_0x8005 = numEggs;
if (gSpecialVar_0x8004 != 0)
result |= 1 << 0;
if (gSpecialVar_0x8005 != 0)
result |= 1 << 1;
if (gSpecialVar_0x8006 != 0)
result |= 1 << 2;
return result;
}
u16 GetHiddenItemAttr(u32 hiddenItem, u8 attr)
{
if (attr == 0)
return hiddenItem & 0xFFFF;
else if (attr == 1)
return ((hiddenItem >> 16) & 0xFF) + 1000;
else if (attr == 2)
return (hiddenItem >> 24) & 0x7F;
else if (attr == 3)
return (hiddenItem >> 31) & 0x01;
else
return 1;
}
bool8 Special_PlayerPartyContainsSpecies(void)
{
u8 partyCount = CalculatePlayerPartyCount();
u8 i;
for (i = 0; i < partyCount; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) == gSpecialVar_0x8004)
return TRUE;
}
return FALSE;
}
static const u8 sMartMaps[][3] = {
{MAP_GROUP(VIRIDIAN_CITY_MART), MAP_NUM(VIRIDIAN_CITY_MART), 1},
{MAP_GROUP(PEWTER_CITY_MART), MAP_NUM(PEWTER_CITY_MART), 3},
{MAP_GROUP(CERULEAN_CITY_MART), MAP_NUM(CERULEAN_CITY_MART), 1},
{MAP_GROUP(LAVENDER_TOWN_MART), MAP_NUM(LAVENDER_TOWN_MART), 1},
{MAP_GROUP(VERMILION_CITY_MART), MAP_NUM(VERMILION_CITY_MART), 1},
{MAP_GROUP(FUCHSIA_CITY_MART), MAP_NUM(FUCHSIA_CITY_MART), 1},
{MAP_GROUP(CINNABAR_ISLAND_MART), MAP_NUM(CINNABAR_ISLAND_MART), 1},
{MAP_GROUP(SAFFRON_CITY_MART), MAP_NUM(SAFFRON_CITY_MART), 1},
{MAP_GROUP(THREE_ISLAND_MART), MAP_NUM(THREE_ISLAND_MART), 1},
{MAP_GROUP(FOUR_ISLAND_MART), MAP_NUM(FOUR_ISLAND_MART), 1},
{MAP_GROUP(SEVEN_ISLAND_MART), MAP_NUM(SEVEN_ISLAND_MART), 1},
{MAP_GROUP(SIX_ISLAND_MART), MAP_NUM(SIX_ISLAND_MART), 1}
};
u8 Special_GetMartClerkObjectId(void)
{
u8 i;
for (i = 0; i < NELEMS(sMartMaps); i++)
{
if (gSaveBlock1Ptr->location.mapGroup == sMartMaps[i][0] && gSaveBlock1Ptr->location.mapNum == sMartMaps[i][1])
return sMartMaps[i][2];
}
return 1;
}
void sub_80CC524(void)
{
sub_8113550(11, NULL);
}
static const struct {
u16 grp;
u16 num;
u16 grp2;
u16 num2;
} sInsideOutsidePairs[51] = {
{MAP_GROUP(PALLET_TOWN_PLAYERS_HOUSE_1F), MAP_NUM(PALLET_TOWN_PLAYERS_HOUSE_1F), MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN)},
{MAP_GROUP(PALLET_TOWN_PROFESSOR_OAKS_LAB), MAP_NUM(PALLET_TOWN_PROFESSOR_OAKS_LAB), MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN)},
{MAP_GROUP(VIRIDIAN_CITY_GYM), MAP_NUM(VIRIDIAN_CITY_GYM), MAP_GROUP(VIRIDIAN_CITY), MAP_NUM(VIRIDIAN_CITY)},
{MAP_GROUP(ROUTE22_NORTH_ENTRANCE), MAP_NUM(ROUTE22_NORTH_ENTRANCE), MAP_GROUP(ROUTE22), MAP_NUM(ROUTE22)},
{MAP_GROUP(ROUTE22_NORTH_ENTRANCE), MAP_NUM(ROUTE22_NORTH_ENTRANCE), MAP_GROUP(ROUTE23), MAP_NUM(ROUTE23)},
{MAP_GROUP(VIRIDIAN_FOREST), MAP_NUM(VIRIDIAN_FOREST), MAP_GROUP(ROUTE2_VIRIDIAN_FOREST_SOUTH_ENTRANCE), MAP_NUM(ROUTE2_VIRIDIAN_FOREST_SOUTH_ENTRANCE)},
{MAP_GROUP(VIRIDIAN_FOREST), MAP_NUM(VIRIDIAN_FOREST), MAP_GROUP(ROUTE2_VIRIDIAN_FOREST_NORTH_ENTRANCE), MAP_NUM(ROUTE2_VIRIDIAN_FOREST_NORTH_ENTRANCE)},
{MAP_GROUP(PEWTER_CITY_MUSEUM_1F), MAP_NUM(PEWTER_CITY_MUSEUM_1F), MAP_GROUP(PEWTER_CITY), MAP_NUM(PEWTER_CITY)},
{MAP_GROUP(PEWTER_CITY_GYM), MAP_NUM(PEWTER_CITY_GYM), MAP_GROUP(PEWTER_CITY), MAP_NUM(PEWTER_CITY)},
{MAP_GROUP(MT_MOON_1F), MAP_NUM(MT_MOON_1F), MAP_GROUP(ROUTE4), MAP_NUM(ROUTE4)},
{MAP_GROUP(MT_MOON_B1F), MAP_NUM(MT_MOON_B1F), MAP_GROUP(ROUTE4), MAP_NUM(ROUTE4)},
{MAP_GROUP(CERULEAN_CITY_GYM), MAP_NUM(CERULEAN_CITY_GYM), MAP_GROUP(CERULEAN_CITY), MAP_NUM(CERULEAN_CITY)},
{MAP_GROUP(CERULEAN_CITY_BIKE_SHOP), MAP_NUM(CERULEAN_CITY_BIKE_SHOP), MAP_GROUP(CERULEAN_CITY), MAP_NUM(CERULEAN_CITY)},
{MAP_GROUP(ROUTE25_SEA_COTTAGE), MAP_NUM(ROUTE25_SEA_COTTAGE), MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25)},
{MAP_GROUP(ROUTE5_POKEMON_DAY_CARE), MAP_NUM(ROUTE5_POKEMON_DAY_CARE), MAP_GROUP(ROUTE5), MAP_NUM(ROUTE5)},
{MAP_GROUP(UNDERGROUND_PATH_NORTH_ENTRANCE), MAP_NUM(UNDERGROUND_PATH_NORTH_ENTRANCE), MAP_GROUP(ROUTE5), MAP_NUM(ROUTE5)},
{MAP_GROUP(UNDERGROUND_PATH_SOUTH_ENTRANCE), MAP_NUM(UNDERGROUND_PATH_SOUTH_ENTRANCE), MAP_GROUP(ROUTE6), MAP_NUM(ROUTE6)},
{MAP_GROUP(VERMILION_CITY_POKEMON_FAN_CLUB), MAP_NUM(VERMILION_CITY_POKEMON_FAN_CLUB), MAP_GROUP(VERMILION_CITY), MAP_NUM(VERMILION_CITY)},
{MAP_GROUP(VERMILION_CITY_GYM), MAP_NUM(VERMILION_CITY_GYM), MAP_GROUP(VERMILION_CITY), MAP_NUM(VERMILION_CITY)},
{MAP_GROUP(SSANNE_1F_CORRIDOR), MAP_NUM(SSANNE_1F_CORRIDOR), MAP_GROUP(VERMILION_CITY), MAP_NUM(VERMILION_CITY)},
{MAP_GROUP(DIGLETTS_CAVE_NORTH_ENTRANCE), MAP_NUM(DIGLETTS_CAVE_NORTH_ENTRANCE), MAP_GROUP(ROUTE2), MAP_NUM(ROUTE2)},
{MAP_GROUP(DIGLETTS_CAVE_SOUTH_ENTRANCE), MAP_NUM(DIGLETTS_CAVE_SOUTH_ENTRANCE), MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11)},
{MAP_GROUP(ROCK_TUNNEL_1F), MAP_NUM(ROCK_TUNNEL_1F), MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10)},
{MAP_GROUP(ROCK_TUNNEL_1F), MAP_NUM(ROCK_TUNNEL_1F), MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10)},
{MAP_GROUP(POWER_PLANT), MAP_NUM(POWER_PLANT), MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10)},
{MAP_GROUP(POKEMON_TOWER_1F), MAP_NUM(POKEMON_TOWER_1F), MAP_GROUP(LAVENDER_TOWN), MAP_NUM(LAVENDER_TOWN)},
{MAP_GROUP(LAVENDER_TOWN_VOLUNTEER_POKEMON_HOUSE), MAP_NUM(LAVENDER_TOWN_VOLUNTEER_POKEMON_HOUSE), MAP_GROUP(LAVENDER_TOWN), MAP_NUM(LAVENDER_TOWN)},
{MAP_GROUP(LAVENDER_TOWN_HOUSE2), MAP_NUM(LAVENDER_TOWN_HOUSE2), MAP_GROUP(LAVENDER_TOWN), MAP_NUM(LAVENDER_TOWN)},
{MAP_GROUP(UNDERGROUND_PATH_EAST_ENTRANCE), MAP_NUM(UNDERGROUND_PATH_EAST_ENTRANCE), MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8)},
{MAP_GROUP(UNDERGROUND_PATH_WEST_ENTRANCE), MAP_NUM(UNDERGROUND_PATH_WEST_ENTRANCE), MAP_GROUP(ROUTE7), MAP_NUM(ROUTE7)},
{MAP_GROUP(CELADON_CITY_DEPARTMENT_STORE_1F), MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_1F), MAP_GROUP(CELADON_CITY), MAP_NUM(CELADON_CITY)},
{MAP_GROUP(CELADON_CITY_CONDOMINIUMS_1F), MAP_NUM(CELADON_CITY_CONDOMINIUMS_1F), MAP_GROUP(CELADON_CITY), MAP_NUM(CELADON_CITY)},
{MAP_GROUP(CELADON_CITY_GAME_CORNER), MAP_NUM(CELADON_CITY_GAME_CORNER), MAP_GROUP(CELADON_CITY), MAP_NUM(CELADON_CITY)},
{MAP_GROUP(CELADON_CITY_GYM), MAP_NUM(CELADON_CITY_GYM), MAP_GROUP(CELADON_CITY), MAP_NUM(CELADON_CITY)},
{MAP_GROUP(CELADON_CITY_RESTAURANT), MAP_NUM(CELADON_CITY_RESTAURANT), MAP_GROUP(CELADON_CITY), MAP_NUM(CELADON_CITY)},
{MAP_GROUP(ROCKET_HIDEOUT_B1F), MAP_NUM(ROCKET_HIDEOUT_B1F), MAP_GROUP(CELADON_CITY_GAME_CORNER), MAP_NUM(CELADON_CITY_GAME_CORNER)},
{MAP_GROUP(SAFARI_ZONE_CENTER), MAP_NUM(SAFARI_ZONE_CENTER), MAP_GROUP(FUCHSIA_CITY_SAFARI_ZONE_ENTRANCE), MAP_NUM(FUCHSIA_CITY_SAFARI_ZONE_ENTRANCE)},
{MAP_GROUP(FUCHSIA_CITY_GYM), MAP_NUM(FUCHSIA_CITY_GYM), MAP_GROUP(FUCHSIA_CITY), MAP_NUM(FUCHSIA_CITY)},
{MAP_GROUP(FUCHSIA_CITY_BUILDING1), MAP_NUM(FUCHSIA_CITY_BUILDING1), MAP_GROUP(FUCHSIA_CITY), MAP_NUM(FUCHSIA_CITY)},
{MAP_GROUP(SAFFRON_CITY_DOJO), MAP_NUM(SAFFRON_CITY_DOJO), MAP_GROUP(SAFFRON_CITY), MAP_NUM(SAFFRON_CITY)},
{MAP_GROUP(SAFFRON_CITY_GYM), MAP_NUM(SAFFRON_CITY_GYM), MAP_GROUP(SAFFRON_CITY), MAP_NUM(SAFFRON_CITY)},
{MAP_GROUP(SILPH_CO_1F), MAP_NUM(SILPH_CO_1F), MAP_GROUP(SAFFRON_CITY), MAP_NUM(SAFFRON_CITY)},
{MAP_GROUP(SEAFOAM_ISLANDS_1F), MAP_NUM(SEAFOAM_ISLANDS_1F), MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20)},
{MAP_GROUP(SEAFOAM_ISLANDS_1F), MAP_NUM(SEAFOAM_ISLANDS_1F), MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20)},
{MAP_GROUP(POKEMON_MANSION_1F), MAP_NUM(POKEMON_MANSION_1F), MAP_GROUP(CINNABAR_ISLAND), MAP_NUM(CINNABAR_ISLAND)},
{MAP_GROUP(CINNABAR_ISLAND_GYM), MAP_NUM(CINNABAR_ISLAND_GYM), MAP_GROUP(CINNABAR_ISLAND), MAP_NUM(CINNABAR_ISLAND)},
{MAP_GROUP(CINNABAR_ISLAND_POKEMON_LAB_ENTRANCE), MAP_NUM(CINNABAR_ISLAND_POKEMON_LAB_ENTRANCE), MAP_GROUP(CINNABAR_ISLAND), MAP_NUM(CINNABAR_ISLAND)},
{MAP_GROUP(VICTORY_ROAD_1F), MAP_NUM(VICTORY_ROAD_1F), MAP_GROUP(ROUTE23), MAP_NUM(ROUTE23)},
{MAP_GROUP(VICTORY_ROAD_2F), MAP_NUM(VICTORY_ROAD_2F), MAP_GROUP(ROUTE23), MAP_NUM(ROUTE23)},
{MAP_GROUP(INDIGO_PLATEAU_POKEMON_CENTER_1F), MAP_NUM(INDIGO_PLATEAU_POKEMON_CENTER_1F), MAP_GROUP(INDIGO_PLATEAU_EXTERIOR), MAP_NUM(INDIGO_PLATEAU_EXTERIOR)},
{MAP_GROUP(CERULEAN_CAVE_1F), MAP_NUM(CERULEAN_CAVE_1F), MAP_GROUP(CERULEAN_CITY), MAP_NUM(CERULEAN_CITY)}
};
void sub_80CC534(void)
{
u8 i;
for (i = 0; i < NELEMS(sInsideOutsidePairs); i++)
{
if (gSaveBlock1Ptr->location.mapGroup == sInsideOutsidePairs[i].grp && gSaveBlock1Ptr->location.mapNum == sInsideOutsidePairs[i].num)
{
if (VarGet(VAR_0x404D) != 35 || i != 32)
{
VarSet(VAR_0x404D, i);
FlagSet(FLAG_0x808);
}
break;
}
}
}
void sub_80CC59C(void)
{
s16 x, y;
struct {
u8 unk0;
u8 unk1;
} sp0;
u16 r5 = VarGet(VAR_0x404D);
sp0.unk0 = 0;
sp0.unk1 = 0;
if (FlagGet(FLAG_0x808))
{
if (r5 == 5)
{
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE2_VIRIDIAN_FOREST_SOUTH_ENTRANCE) && (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE2_VIRIDIAN_FOREST_SOUTH_ENTRANCE) || gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE2_VIRIDIAN_FOREST_NORTH_ENTRANCE)))
{
sp0.unk0 = MAPSEC_ROUTE_2;
if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE2_VIRIDIAN_FOREST_SOUTH_ENTRANCE))
sp0.unk1 = r5;
else
sp0.unk1 = r5 + 1;
sub_8113550(35, (void *)&sp0);
FlagClear(FLAG_0x808);
return;
}
}
else if (r5 == 3)
{
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE22) && (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE22) || gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE23)))
{
sp0.unk0 = Overworld_GetMapHeaderByGroupAndId(sInsideOutsidePairs[r5].grp, sInsideOutsidePairs[r5].num)->regionMapSectionId;
if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE22))
sp0.unk1 = r5;
else
sp0.unk1 = r5 + 1;
sub_8113550(35, (void *)&sp0);
FlagClear(FLAG_0x808);
return;
}
}
if (gSaveBlock1Ptr->location.mapGroup == sInsideOutsidePairs[r5].grp2 && gSaveBlock1Ptr->location.mapNum == sInsideOutsidePairs[r5].num2)
{
sp0.unk0 = Overworld_GetMapHeaderByGroupAndId(sInsideOutsidePairs[r5].grp, sInsideOutsidePairs[r5].num)->regionMapSectionId;
sp0.unk1 = r5;
if (r5 == 22)
{
PlayerGetDestCoords(&x, &y);
if (x != 15 || y != 26)
sp0.unk1++;
}
else if (r5 == 42)
{
PlayerGetDestCoords(&x, &y);
if (x != 67 || y != 15)
sp0.unk1++;
}
sub_8113550(35, (void *)&sp0);
FlagClear(FLAG_0x808);
if (r5 == 35)
{
VarSet(VAR_0x404D, 32);
FlagSet(FLAG_0x808);
}
}
}
}
u16 Special_BattleCardAction(void)
{
switch (gSpecialVar_Result)
{
case 0:
return sub_81445C0(3);
case 1:
return sub_81445C0(4);
case 2:
return sub_81445C0(0);
case 3:
return sub_81445C0(1);
case 4:
return sub_81445C0(2);
default:
AGB_ASSERT_EX(0, "C:/WORK/POKeFRLG/src/pm_lgfr_ose/source/scr_tool.c", 3873);
return 0;
}
}
void set_unknown_box_id(u8 boxId)
{
sUnknownBoxId = boxId;
}
u16 get_unknown_box_id(void)
{
return sUnknownBoxId;
}
bool8 sub_80CC7B4(void)
{
if (FlagGet(FLAG_SYS_CHANGED_BOX_TO_STORE_MON))
return FALSE;
if (StorageGetCurrentBox() == VarGet(VAR_0x4037))
return FALSE;
FlagSet(FLAG_SYS_CHANGED_BOX_TO_STORE_MON);
return TRUE;
}
bool8 sub_80CC7F8(void)
{
s32 i;
s32 j;
set_unknown_box_id(VarGet(VAR_0x4037));
i = StorageGetCurrentBox();
do
{
for (j = 0; j < IN_BOX_COUNT; j++)
{
if (GetBoxMonData(GetBoxedMonPtr(i, j), MON_DATA_SPECIES, NULL) == SPECIES_NONE)
{
if (get_unknown_box_id() != i)
FlagClear(FLAG_SYS_CHANGED_BOX_TO_STORE_MON);
VarSet(VAR_0x4037, i);
return sub_80CC7B4();
}
}
i++;
if (i == TOTAL_BOXES_COUNT)
i = 0;
} while (i != StorageGetCurrentBox());
return FALSE;
}
const u16 sPokeCenter1FMaps[] = {
MAP_VIRIDIAN_CITY_POKEMON_CENTER_1F,
MAP_PEWTER_CITY_POKEMON_CENTER_1F,
MAP_CERULEAN_CITY_POKEMON_CENTER_1F,
MAP_LAVENDER_TOWN_POKEMON_CENTER_1F,
MAP_VERMILION_CITY_POKEMON_CENTER_1F,
MAP_CELADON_CITY_POKEMON_CENTER_1F,
MAP_FUCHSIA_CITY_POKEMON_CENTER_1F,
MAP_CINNABAR_ISLAND_POKEMON_CENTER_1F,
MAP_INDIGO_PLATEAU_POKEMON_CENTER_1F,
MAP_SAFFRON_CITY_POKEMON_CENTER_1F,
MAP_ROUTE4_POKEMON_CENTER_1F,
MAP_ROUTE10_POKEMON_CENTER_1F,
MAP_ONE_ISLAND_POKEMON_CENTER_1F,
MAP_TWO_ISLAND_POKEMON_CENTER_1F,
MAP_THREE_ISLAND_POKEMON_CENTER_1F,
MAP_FOUR_ISLAND_POKEMON_CENTER_1F,
MAP_FIVE_ISLAND_POKEMON_CENTER_1F,
MAP_SEVEN_ISLAND_POKEMON_CENTER_1F,
MAP_SIX_ISLAND_POKEMON_CENTER_1F,
MAP_UNKNOWN_MAP_00_04,
MAP_UNDEFINED
};
bool8 sub_80CC87C(void)
{
s32 i;
u16 mapno = (gUnknown_2031DB4.mapGroup << 8) + gUnknown_2031DB4.mapNum;
for (i = 0; sPokeCenter1FMaps[i] != MAP_UNDEFINED; i++)
{
if (sPokeCenter1FMaps[i] == mapno)
return TRUE;
}
return FALSE;
}
bool8 Special_ItemIsTM_GetMoveName(void)
{
// 8004 = item ID
if (gSpecialVar_0x8004 >= ITEM_TM01 && gSpecialVar_0x8004 <= ITEM_HM08)
{
StringCopy(gStringVar1, gMoveNames[ItemIdToBattleMoveId(gSpecialVar_0x8004)]);
return TRUE;
}
else
return FALSE;
}
void RunMassageCooldownStepCounter(void)
{
u16 count = VarGet(VAR_MASSAGE_COOLDOWN_STEP_COUNTER);
if (count < 500)
VarSet(VAR_MASSAGE_COOLDOWN_STEP_COUNTER, count + 1);
}
void Special_DaisyMassageServices(void)
{
AdjustFriendship(&gPlayerParty[gSpecialVar_0x8004], 6);
VarSet(VAR_MASSAGE_COOLDOWN_STEP_COUNTER, 0);
}
static const u16 sEliteFourLightingPalettes[][16] = {
INCBIN_U16("data/field_specials/unk_83F5F50.gbapal"),
INCBIN_U16("data/field_specials/unk_83F5F70.gbapal"),
INCBIN_U16("data/field_specials/unk_83F5F90.gbapal"),
INCBIN_U16("data/field_specials/unk_83F5FB0.gbapal"),
INCBIN_U16("data/field_specials/unk_83F5FD0.gbapal"),
INCBIN_U16("data/field_specials/unk_83F5FF0.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6010.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6030.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6050.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6070.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6090.gbapal"),
INCBIN_U16("data/field_specials/unk_83F60B0.gbapal")
};
static const u16 sChampionRoomLightingPalettes[][16] = {
INCBIN_U16("data/field_specials/unk_83F60D0.gbapal"),
INCBIN_U16("data/field_specials/unk_83F60F0.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6110.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6130.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6150.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6170.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6190.gbapal"),
INCBIN_U16("data/field_specials/unk_83F61B0.gbapal"),
INCBIN_U16("data/field_specials/unk_83F61D0.gbapal")
};
static const u8 sEliteFourLightingTimers[] = {
40,
12,
12,
12,
12,
12,
12,
12,
12,
12,
12
};
static const u8 sChampionRoomLightingTimers[] = {
20,
8,
8,
8,
8,
8,
8,
8
};
void Special_PokemonLeagueLightingEffect(void)
{
u8 taskId = CreateTask(Task_RunPokemonLeagueLightingEffect, 8);
s16 *data = gTasks[taskId].data;
if (FlagGet(FLAG_TEMP_3) == TRUE)
{
gTasks[taskId].func = Task_CancelPokemonLeagueLightingEffect;
}
else
{
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(POKEMON_LEAGUE_CHAMPIONS_ROOM) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(POKEMON_LEAGUE_CHAMPIONS_ROOM))
{
data[0] = sChampionRoomLightingTimers[0];
data[2] = 8;
LoadPalette(sChampionRoomLightingPalettes[0], 0x70, 0x20);
}
else
{
data[0] = sEliteFourLightingTimers[0];
data[2] = 11;
LoadPalette(sEliteFourLightingPalettes[0], 0x70, 0x20);
}
data[1] = 0;
sub_8059948(7, 1);
}
}
static void Task_RunPokemonLeagueLightingEffect(u8 taskId)
{
s16 *data = gTasks[taskId].data;
if (!gPaletteFade.active
&& FlagGet(FLAG_TEMP_2) != FALSE
&& FlagGet(FLAG_TEMP_5) != TRUE
&& gUnknown_2036E28 != 3
&& --data[0] == 0
)
{
if (++data[1] == data[2])
data[1] = 0;
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(POKEMON_LEAGUE_CHAMPIONS_ROOM) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(POKEMON_LEAGUE_CHAMPIONS_ROOM))
{
data[0] = sChampionRoomLightingTimers[data[1]];
LoadPalette(sChampionRoomLightingPalettes[data[1]], 0x70, 0x20);
}
else
{
data[0] = sEliteFourLightingTimers[data[1]];
LoadPalette(sEliteFourLightingPalettes[data[1]], 0x70, 0x20);
}
sub_8059948(7, 1);
}
}
static void Task_CancelPokemonLeagueLightingEffect(u8 taskId)
{
s16 *data = gTasks[taskId].data;
if (FlagGet(FLAG_TEMP_4) != FALSE)
{
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(POKEMON_LEAGUE_CHAMPIONS_ROOM) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(POKEMON_LEAGUE_CHAMPIONS_ROOM))
{
LoadPalette(sChampionRoomLightingPalettes[8], 0x70, 0x20);
}
else
{
LoadPalette(sEliteFourLightingPalettes[11], 0x70, 0x20);
}
sub_8059948(7, 1);
if (gPaletteFade.active)
{
BlendPalettes(0x00000080, 16, RGB_BLACK);
}
DestroyTask(taskId);
}
}
void StopPokemonLeagueLightingEffectTask(void)
{
if (FuncIsActiveTask(Task_RunPokemonLeagueLightingEffect) == TRUE)
{
DestroyTask(FindTaskIdByFunc(Task_RunPokemonLeagueLightingEffect));
}
}
static const u8 sCapeBrinkCompatibleSpecies[] = {
SPECIES_VENUSAUR,
SPECIES_CHARIZARD,
SPECIES_BLASTOISE
};
bool8 Special_CapeBrinkGetMoveToTeachLeadPokemon(void)
{
// Returns:
// 8005 = Move tutor index
// 8006 = Num moves known by lead mon
// 8007 = Index of lead mon
// to specialvar = whether a move can be taught in the first place
u8 r7 = 0;
u8 r6 = 0;
u8 r8 = GetLeadMonIndex();
u8 r4;
gSpecialVar_0x8007 = r8;
for (r4 = 0; r4 < NELEMS(sCapeBrinkCompatibleSpecies); r4++)
{
if (GetMonData(&gPlayerParty[r8], MON_DATA_SPECIES2, NULL) == sCapeBrinkCompatibleSpecies[r4])
{
r7 = r4;
break;
}
}
if (r4 == NELEMS(sCapeBrinkCompatibleSpecies) || GetMonData(&gPlayerParty[r8], MON_DATA_FRIENDSHIP) != 255)
return FALSE;
if (r7 == 0)
{
StringCopy(gStringVar2, gMoveNames[MOVE_FRENZY_PLANT]);
gSpecialVar_0x8005 = MOVETUTOR_FRENZY_PLANT;
if (FlagGet(FLAG_TUTOR_FRENZY_PLANT) == TRUE)
return FALSE;
}
else if (r7 == 1)
{
StringCopy(gStringVar2, gMoveNames[MOVE_BLAST_BURN]);
gSpecialVar_0x8005 = MOVETUTOR_BLAST_BURN;
if (FlagGet(FLAG_TUTOR_BLAST_BURN) == TRUE)
return FALSE;
}
else
{
StringCopy(gStringVar2, gMoveNames[MOVE_HYDRO_CANNON]);
gSpecialVar_0x8005 = MOVETUTOR_HYDRO_CANNON;
if (FlagGet(FLAG_TUTOR_HYDRO_CANNON) == TRUE)
return FALSE;
}
if (GetMonData(&gPlayerParty[r8], MON_DATA_MOVE1) != MOVE_NONE)
r6++;
if (GetMonData(&gPlayerParty[r8], MON_DATA_MOVE2) != MOVE_NONE)
r6++;
if (GetMonData(&gPlayerParty[r8], MON_DATA_MOVE3) != MOVE_NONE)
r6++;
if (GetMonData(&gPlayerParty[r8], MON_DATA_MOVE4) != MOVE_NONE)
r6++;
gSpecialVar_0x8006 = r6;
return TRUE;
}
bool8 Special_HasLearnedAllMovesFromCapeBrinkTutor(void)
{
// 8005 is set by Special_CapeBrinkGetMoveToTeachLeadPokemon
u8 r4 = 0;
if (gSpecialVar_0x8005 == MOVETUTOR_FRENZY_PLANT)
FlagSet(FLAG_TUTOR_FRENZY_PLANT);
else if (gSpecialVar_0x8005 == MOVETUTOR_BLAST_BURN)
FlagSet(FLAG_TUTOR_BLAST_BURN);
else
FlagSet(FLAG_TUTOR_HYDRO_CANNON);
if (FlagGet(FLAG_TUTOR_FRENZY_PLANT) == TRUE)
r4++;
if (FlagGet(FLAG_TUTOR_BLAST_BURN) == TRUE)
r4++;
if (FlagGet(FLAG_TUTOR_HYDRO_CANNON) == TRUE)
r4++;
if (r4 == 3)
return TRUE;
else
return FALSE;
}
bool8 CutMoveRuinValleyCheck(void)
{
if (FlagGet(FLAG_USED_CUT_ON_RUIN_VALLEY_BRAILLE) != TRUE
&& gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(SIX_ISLAND_RUIN_VALLEY)
&& gSaveBlock1Ptr->location.mapNum == MAP_NUM(SIX_ISLAND_RUIN_VALLEY)
&& gSaveBlock1Ptr->pos.x == 24
&& gSaveBlock1Ptr->pos.y == 25
&& GetPlayerFacingDirection() == DIR_NORTH
)
return TRUE;
else
return FALSE;
}
void CutMoveOpenDottedHoleDoor(void)
{
MapGridSetMetatileIdAt(31, 31, 0x358);
DrawWholeMapView();
PlaySE(SE_BAN);
FlagSet(FLAG_USED_CUT_ON_RUIN_VALLEY_BRAILLE);
ScriptContext2_Disable();
}
static const u16 sDeoxysObjectPals[][16] = {
INCBIN_U16("data/field_specials/unk_83F6206.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6226.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6246.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6266.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6286.gbapal"),
INCBIN_U16("data/field_specials/unk_83F62A6.gbapal"),
INCBIN_U16("data/field_specials/unk_83F62C6.gbapal"),
INCBIN_U16("data/field_specials/unk_83F62E6.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6306.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6326.gbapal"),
INCBIN_U16("data/field_specials/unk_83F6346.gbapal")
};
static const u8 sDeoxysCoords[][2] = {
{15, 12},
{11, 14},
{15, 8},
{19, 14},
{12, 11},
{18, 11},
{15, 14},
{11, 14},
{19, 14},
{15, 15},
{15, 10}
};
static const u8 sDeoxysStepCaps[] = {
4,
8,
8,
8,
4,
4,
4,
6,
3,
3
};
void Special_DeoxysSound(void)
{
CreateTask(task_deoxys_sound, 8);
}
static void task_deoxys_sound(u8 taskId)
{
u16 r5;
u16 r6;
if (FlagGet(FLAG_SYS_DEOXYS_AWAKENED) == TRUE)
{
gSpecialVar_Result = 3;
EnableBothScriptContexts();
DestroyTask(taskId);
}
else
{
r5 = VarGet(VAR_DEOXYS_INTERACTION_NUM);
r6 = VarGet(VAR_DEOXYS_INTERACTION_STEP_COUNTER);
VarSet(VAR_DEOXYS_INTERACTION_STEP_COUNTER, 0);
if (r5 != 0 && sDeoxysStepCaps[r5 - 1] < r6)
{
MoveDeoxysObject(0);
VarSet(VAR_DEOXYS_INTERACTION_NUM, 0);
gSpecialVar_Result = 0;
DestroyTask(taskId);
}
else if (r5 == 10)
{
FlagSet(FLAG_SYS_DEOXYS_AWAKENED);
gSpecialVar_Result = 2;
EnableBothScriptContexts();
DestroyTask(taskId);
}
else
{
r5++;
MoveDeoxysObject(r5);
VarSet(VAR_DEOXYS_INTERACTION_NUM, r5);
gSpecialVar_Result = 1;
DestroyTask(taskId);
}
}
}
static void MoveDeoxysObject(u8 num)
{
u8 mapObjId;
LoadPalette(sDeoxysObjectPals[num], 0x1A0, 0x08);
sub_8083598(10);
TryGetFieldObjectIdByLocalIdAndMap(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &mapObjId);
if (num == 0)
PlaySE(SE_W109);
else
PlaySE(SE_DEOMOV);
CreateTask(Task_WaitDeoxysFieldEffect, 8);
gFieldEffectArguments[0] = 1;
gFieldEffectArguments[1] = 56;
gFieldEffectArguments[2] = 2;
gFieldEffectArguments[3] = sDeoxysCoords[num][0];
gFieldEffectArguments[4] = sDeoxysCoords[num][1];
if (num == 0)
gFieldEffectArguments[5] = 60;
else
gFieldEffectArguments[5] = 5;
FieldEffectStart(FLDEFF_UNK_43);
Overworld_SetMapObjTemplateCoords(1, sDeoxysCoords[num][0], sDeoxysCoords[num][1]);
}
static void Task_WaitDeoxysFieldEffect(u8 taskId)
{
if (!FieldEffectActiveListContains(FLDEFF_UNK_43))
{
EnableBothScriptContexts();
DestroyTask(taskId);
}
}
void BirthIslandDeoxysStepCounter(void)
{
u16 count = VarGet(VAR_DEOXYS_INTERACTION_STEP_COUNTER);
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(BIRTH_ISLAND_EXTERIOR) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(BIRTH_ISLAND_EXTERIOR))
{
count++;
if (count > 99)
VarSet(VAR_DEOXYS_INTERACTION_STEP_COUNTER, 0);
else
VarSet(VAR_DEOXYS_INTERACTION_STEP_COUNTER, count);
}
}
void Special_SetDeoxysTriangleObjectPal(void)
{
u8 num = VarGet(VAR_DEOXYS_INTERACTION_NUM);
LoadPalette(sDeoxysObjectPals[num], 0x1A0, 0x08);
sub_8083598(10);
}
bool8 Special_BadEggInParty(void)
{
u8 partyCount = CalculatePlayerPartyCount();
u8 i;
for (i = 0; i < partyCount; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SANITY_IS_BAD_EGG) == TRUE)
return TRUE;
}
return FALSE;
}
bool8 Special_PlayerIsNotInTrainerTowerLobby(void)
{
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(SEVEN_ISLAND_TRAINER_TOWER_LOBBY) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER_LOBBY))
return FALSE;
else
return TRUE;
}
void Special_BrailleCursorToggle(void)
{
// 8004 = x - 27
// 8005 = y
// 8006 = action (0 = create, 1 = delete)
u16 x;
if (gUnknown_203ADFA != 2)
{
x = gSpecialVar_0x8004 + 27;
if (gSpecialVar_0x8006 == 0)
sBrailleTextCursorSpriteID = CreateTextCursorSpriteForOakSpeech(0, x, gSpecialVar_0x8005, 0, 0);
else
sub_8006398(sBrailleTextCursorSpriteID);
}
}
bool8 Special_PlayerPartyContainsSpeciesWithPlayerID(void)
{
// 8004 = species
u8 playerCount = CalculatePlayerPartyCount();
u8 i;
for (i = 0; i < playerCount; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) == gSpecialVar_0x8004 && GetPlayerTrainerId() == GetMonData(&gPlayerParty[i], MON_DATA_OT_ID, NULL))
return TRUE;
}
return FALSE;
}
/*
* Determines which of Lorelei's doll collection to show
* based on how many times you've entered the Hall of Fame.
*/
void Special_ComputeLoreleiDollCollection(void)
{
u32 numHofClears = GetGameStat(GAME_STAT_ENTERED_HOF);
if (numHofClears >= 25)
{
FlagClear(FLAG_HIDE_LORELEI_HOUSE_MEOWTH_DOLL);
if (numHofClears >= 50)
FlagClear(FLAG_HIDE_LORELEI_HOUSE_CHANSEY_DOLL);
if (numHofClears >= 75)
FlagClear(FLAG_HIDE_LORELEIS_HOUSE_NIDORAN_F_DOLL);
if (numHofClears >= 100)
FlagClear(FLAG_HIDE_LORELEI_HOUSE_JIGGLYPUFF_DOLL);
if (numHofClears >= 125)
FlagClear(FLAG_HIDE_LORELEIS_HOUSE_NIDORAN_M_DOLL);
if (numHofClears >= 150)
FlagClear(FLAG_HIDE_LORELEIS_HOUSE_FEAROW_DOLL);
if (numHofClears >= 175)
FlagClear(FLAG_HIDE_LORELEIS_HOUSE_PIDGEOT_DOLL);
if (numHofClears >= 200)
FlagClear(FLAG_HIDE_LORELEIS_HOUSE_LAPRAS_DOLL);
}
}
void Special_LoopWingFlapSound(void)
{
// 8004 = Num flaps
// 8005 = Frame delay between flaps
CreateTask(Task_WingFlapSound, 8);
PlaySE(SE_W017);
}
static void Task_WingFlapSound(u8 taskId)
{
s16 *data = gTasks[taskId].data;
data[1]++;
if (data[1] == gSpecialVar_0x8005)
{
data[0]++;
data[1] = 0;
PlaySE(SE_W017);
}
if (data[0] == gSpecialVar_0x8004 - 1)
DestroyTask(taskId);
}