#include "global.h" #include "main.h" #include "battle.h" #include "battle_tower.h" #include "data2.h" #include "diploma.h" #include "event_data.h" #include "event_object_movement.h" #include "fieldmap.h" #include "field_camera.h" #include "field_message_box.h" #include "field_player_avatar.h" #include "field_region_map.h" #include "field_specials.h" #include "field_weather.h" #include "link.h" #include "overworld.h" #include "party_menu.h" #include "pokeblock.h" #include "pokemon.h" #include "pokemon_storage_system.h" #include "region_map.h" #include "rom_8011DC0.h" #include "rtc.h" #include "script.h" #include "sound.h" #include "starter_choose.h" #include "string_util.h" #include "strings.h" #include "task.h" #include "text.h" #include "tv.h" #include "wallclock.h" #include "constants/event_objects.h" #include "constants/items.h" #include "constants/maps.h" #include "constants/songs.h" #include "constants/species.h" #include "constants/moves.h" #include "constants/vars.h" EWRAM_DATA bool8 gBikeCyclingChallenge = FALSE; EWRAM_DATA u8 gBikeCollisions = 0; EWRAM_DATA u32 gBikeCyclingTimer = 0; EWRAM_DATA u8 gUnknown_0203AB5C = 0; EWRAM_DATA u8 gUnknown_0203AB5D = 0; extern const u16 gEventObjectPalette8[]; extern const u16 gEventObjectPalette17[]; extern const u16 gEventObjectPalette33[]; extern const u16 gEventObjectPalette34[]; extern void LoadPalette(const void *src, u32 offset, u16 size); // incorrect signature, needed to match static void RecordCyclingRoadResults(u32, u8); static void LoadLinkPartnerEventObjectSpritePalette(u8 graphicsId, u8 localEventId, u8 paletteNum); void Special_ShowDiploma(void) { SetMainCallback2(CB2_ShowDiploma); ScriptContext2_Enable(); } void Special_ViewWallClock(void) { gMain.savedCallback = CB2_ReturnToField; SetMainCallback2(CB2_ViewWallClock); ScriptContext2_Enable(); } void ResetCyclingRoadChallengeData(void) { gBikeCyclingChallenge = FALSE; gBikeCollisions = 0; gBikeCyclingTimer = 0; } void Special_BeginCyclingRoadChallenge(void) { gBikeCyclingChallenge = TRUE; gBikeCollisions = 0; gBikeCyclingTimer = gMain.vblankCounter1; } u16 GetPlayerAvatarBike(void) { if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE)) return 1; if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE)) return 2; return 0; } static void DetermineCyclingRoadResults(u32 numFrames, u8 numBikeCollisions) { u8 result; if (numBikeCollisions < 100) { ConvertIntToDecimalStringN(gStringVar1, numBikeCollisions, STR_CONV_MODE_LEFT_ALIGN, 2); StringAppend(gStringVar1, gText_SpaceTimes); } else { StringCopy(gStringVar1, gText_99TimesPlus); } if (numFrames < 3600) { ConvertIntToDecimalStringN(gStringVar2, numFrames / 60, STR_CONV_MODE_RIGHT_ALIGN, 2); gStringVar2[2] = CHAR_PERIOD; ConvertIntToDecimalStringN(&gStringVar2[3], ((numFrames % 60) * 100) / 60, STR_CONV_MODE_LEADING_ZEROS, 2); StringAppend(gStringVar2, gText_SpaceSeconds); } else { StringCopy(gStringVar2, gText_1MinutePlus); } result = 0; if (numBikeCollisions == 0) { result = 5; } else if (numBikeCollisions < 4) { result = 4; } else if (numBikeCollisions < 10) { result = 3; } else if (numBikeCollisions < 20) { result = 2; } else if (numBikeCollisions < 100) { result = 1; } if (numFrames / 60 <= 10) { result += 5; } else if (numFrames / 60 <= 15) { result += 4; } else if (numFrames / 60 <= 20) { result += 3; } else if (numFrames / 60 <= 40) { result += 2; } else if (numFrames / 60 < 60) { result += 1; } gSpecialVar_Result = result; } void FinishCyclingRoadChallenge(void) { const u32 numFrames = gMain.vblankCounter1 - gBikeCyclingTimer; DetermineCyclingRoadResults(numFrames, gBikeCollisions); RecordCyclingRoadResults(numFrames, gBikeCollisions); } static void RecordCyclingRoadResults(u32 numFrames, u8 numBikeCollisions) { u16 low = VarGet(VAR_CYCLING_ROAD_RECORD_TIME_L); u16 high = VarGet(VAR_CYCLING_ROAD_RECORD_TIME_H); u32 framesRecord = low + (high << 16); if (framesRecord > numFrames || framesRecord == 0) { VarSet(VAR_CYCLING_ROAD_RECORD_TIME_L, numFrames); VarSet(VAR_CYCLING_ROAD_RECORD_TIME_H, numFrames >> 16); VarSet(VAR_CYCLING_ROAD_RECORD_COLLISIONS, numBikeCollisions); } } u16 GetRecordedCyclingRoadResults(void) { u16 low = VarGet(VAR_CYCLING_ROAD_RECORD_TIME_L); u16 high = VarGet(VAR_CYCLING_ROAD_RECORD_TIME_H); u32 framesRecord = low + (high << 16); if (framesRecord == 0) { return FALSE; } DetermineCyclingRoadResults(framesRecord, VarGet(VAR_CYCLING_ROAD_RECORD_COLLISIONS)); return TRUE; } void UpdateCyclingRoadState(void) { if (gUnknown_020322DC.mapNum == MAP_NUM(ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE) && gUnknown_020322DC.mapGroup == MAP_GROUP(ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE)) { return; } if (VarGet(VAR_CYCLING_CHALLENGE_STATE) == 2 || VarGet(VAR_CYCLING_CHALLENGE_STATE) == 3) { VarSet(VAR_CYCLING_CHALLENGE_STATE, 0); Overworld_SetSavedMusic(MUS_DUMMY); } } void SetSSTidalFlag(void) { FlagSet(FLAG_SYS_CRUISE_MODE); *GetVarPointer(VAR_CRUISE_STEP_COUNT) = 0; } void ResetSSTidalFlag(void) { FlagClear(FLAG_SYS_CRUISE_MODE); } bool32 CountSSTidalStep(u16 delta) { if (!FlagGet(FLAG_SYS_CRUISE_MODE) || (*GetVarPointer(VAR_CRUISE_STEP_COUNT) += delta) <= 0xcc) { return FALSE; } return TRUE; } u8 GetSSTidalLocation(s8 *mapGroup, s8 *mapNum, s16 *x, s16 *y) { u16 *varCruiseStepCount = GetVarPointer(VAR_CRUISE_STEP_COUNT); switch (*GetVarPointer(VAR_PORTHOLE_STATE)) { case 1: case 8: return 1; case 3: case 9: return 4; case 4: case 5: return 2; case 6: case 10: return 3; case 2: if (*varCruiseStepCount < 60) { *mapNum = MAP_NUM(ROUTE134); *x = *varCruiseStepCount + 19; } else if (*varCruiseStepCount < 140) { *mapNum = MAP_NUM(ROUTE133); *x = *varCruiseStepCount - 60; } else { *mapNum = MAP_NUM(ROUTE132); *x = *varCruiseStepCount - 140; } break; case 7: if (*varCruiseStepCount < 66) { *mapNum = MAP_NUM(ROUTE132); *x = 65 - *varCruiseStepCount; } else if (*varCruiseStepCount < 146) { *mapNum = MAP_NUM(ROUTE133); *x = 145 - *varCruiseStepCount; } else { *mapNum = MAP_NUM(ROUTE134); *x = 224 - *varCruiseStepCount; } break; } *mapGroup = MAP_GROUP(ROUTE132); *y = 20; return 0; } bool32 is_tile_that_overrides_player_control(void) { if (FlagGet(FLAG_0x088)) { switch (gMapHeader.mapType) { case 1: case 2: case 3: case 6: if (++(*GetVarPointer(VAR_0x40F2)) < 0xFA) { return FALSE; } break; default: return FALSE; } } else { return FALSE; } return TRUE; } bool32 sub_8138120(void) { if (FlagGet(FLAG_0x08A)) { switch (gMapHeader.mapType) { case 1: case 2: case 3: case 6: if (++(*GetVarPointer(VAR_0x40F3)) < 0xA) { return FALSE; } break; default: return FALSE; } } else { return FALSE; } return TRUE; } bool32 sub_8138168(void) { if (FlagGet(FLAG_0x072)) { switch (gMapHeader.mapType) { case 1: case 2: case 3: case 6: if (++(*GetVarPointer(VAR_0x40F5)) < 0xA) { return FALSE; } break; default: return FALSE; } } else { return FALSE; } return TRUE; } bool32 sub_81381B0(void) { if (FlagGet(FLAG_0x080)) { switch (gMapHeader.mapType) { case 1: case 2: case 3: case 6: if (++(*GetVarPointer(VAR_0x40F4)) < 0xFA) { return FALSE; } break; default: return FALSE; } } else { return FALSE; } return TRUE; } bool32 sub_81381F8(void) { if (FlagGet(FLAG_0x075)) { switch (gMapHeader.mapType) { case 1: case 2: case 3: case 6: if (++(*GetVarPointer(VAR_0x40F6)) < 0xFA) { return FALSE; } break; default: return FALSE; } } else { return FALSE; } return TRUE; } u8 GetLinkPartnerNames(void) { u8 i; u8 j = 0; u8 myLinkPlayerNumber = GetMultiplayerId(); u8 nLinkPlayers = GetLinkPlayerCount(); for (i = 0; i < nLinkPlayers; i++) { if (myLinkPlayerNumber != i) { StringCopy(gTVStringVarPtrs[j], gLinkPlayers[i].name); j++; } } return nLinkPlayers; } void SpawnLinkPartnerEventObject(void) { u8 j = 0; s16 x = 0; s16 y = 0; u8 gUnknown_085B2B5C[] = {7, 9, 8, 10}; s8 gUnknown_085B2B60[][2] = { { 0, 1}, { 1, 0}, { 0, -1}, {-1, 0} }; u8 myLinkPlayerNumber; u8 playerFacingDirection; u8 linkSpriteId; u8 i; myLinkPlayerNumber = GetMultiplayerId(); playerFacingDirection = GetPlayerFacingDirection(); switch (playerFacingDirection) { case DIR_WEST: j = 2; x = gSaveBlock1Ptr->pos.x - 1; y = gSaveBlock1Ptr->pos.y; break; case DIR_NORTH: j = 1; x = gSaveBlock1Ptr->pos.x; y = gSaveBlock1Ptr->pos.y - 1; break; case DIR_EAST: x = gSaveBlock1Ptr->pos.x + 1; y = gSaveBlock1Ptr->pos.y; break; case DIR_SOUTH: j = 3; x = gSaveBlock1Ptr->pos.x; y = gSaveBlock1Ptr->pos.y + 1; } for (i = 0; i < gSpecialVar_0x8004; i++) { if (myLinkPlayerNumber != i) { switch ((u8)gLinkPlayers[i].version) { case VERSION_RUBY: case VERSION_SAPPHIRE: if (gLinkPlayers[i].gender == 0) linkSpriteId = EVENT_OBJ_GFX_LINK_RS_BRENDAN; else linkSpriteId = EVENT_OBJ_GFX_LINK_RS_MAY; break; case VERSION_EMERALD: if (gLinkPlayers[i].gender == 0) linkSpriteId = EVENT_OBJ_GFX_RIVAL_BRENDAN_NORMAL; else linkSpriteId = EVENT_OBJ_GFX_RIVAL_MAY_NORMAL; break; default: if (gLinkPlayers[i].gender == 0) linkSpriteId = EVENT_OBJ_GFX_RIVAL_BRENDAN_NORMAL; else linkSpriteId = EVENT_OBJ_GFX_RIVAL_MAY_NORMAL; break; } SpawnSpecialEventObjectParameterized(linkSpriteId, gUnknown_085B2B5C[j], 0xf0 - i, gUnknown_085B2B60[j][0] + x + 7, gUnknown_085B2B60[j][1] + y + 7, 0); LoadLinkPartnerEventObjectSpritePalette(linkSpriteId, 0xf0 - i, i); j++; if (j == 4) { j = 0; } } } } static void LoadLinkPartnerEventObjectSpritePalette(u8 graphicsId, u8 localEventId, u8 paletteNum) { paletteNum += 6; if (graphicsId == EVENT_OBJ_GFX_LINK_RS_BRENDAN || graphicsId == EVENT_OBJ_GFX_LINK_RS_MAY || graphicsId == EVENT_OBJ_GFX_RIVAL_BRENDAN_NORMAL || graphicsId == EVENT_OBJ_GFX_RIVAL_MAY_NORMAL) { u8 obj = GetEventObjectIdByLocalIdAndMap(localEventId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); if (obj != NUM_EVENT_OBJECTS) { u8 spriteId = gEventObjects[obj].spriteId; struct Sprite *sprite = &gSprites[spriteId]; sprite->oam.paletteNum = paletteNum; switch (graphicsId) { case EVENT_OBJ_GFX_LINK_RS_BRENDAN: LoadPalette(gEventObjectPalette33, 0x100 + paletteNum * 16, 0x20); break; case EVENT_OBJ_GFX_LINK_RS_MAY: LoadPalette(gEventObjectPalette34, 0x100 + paletteNum * 16, 0x20); break; case EVENT_OBJ_GFX_RIVAL_BRENDAN_NORMAL: LoadPalette(gEventObjectPalette8, 0x100 + paletteNum * 16, 0x20); break; case EVENT_OBJ_GFX_RIVAL_MAY_NORMAL: LoadPalette(gEventObjectPalette17, 0x100 + paletteNum * 16, 0x20); break; } } } } struct Coords8 { u8 x; u8 y; }; const struct Coords8 gUnknown_085B2B68[] = { { 7, 22}, {11, 19}, {10, 16}, {15, 16} }; void MauvilleGymSpecial1(void) { u8 i; for (i = 0; i < ARRAY_COUNT(gUnknown_085B2B68); i++) { if (i == gSpecialVar_0x8004) { MapGridSetMetatileIdAt(gUnknown_085B2B68[i].x, gUnknown_085B2B68[i].y, 0x206); } else { MapGridSetMetatileIdAt(gUnknown_085B2B68[i].x, gUnknown_085B2B68[i].y, 0x205); } } } void MauvilleGymSpecial2(void) { int x, y; for (y = 12; y < 24; y++) { for (x = 7; x < 16; x++) { switch (MapGridGetMetatileIdAt(x, y)) { case 0x220: MapGridSetMetatileIdAt(x, y, 0x230); break; case 0x221: MapGridSetMetatileIdAt(x, y, 0x231); break; case 0x228: MapGridSetMetatileIdAt(x, y, 0x238); break; case 0x229: MapGridSetMetatileIdAt(x, y, 0x239); break; case 0x230: MapGridSetMetatileIdAt(x, y, 0x220); break; case 0x231: MapGridSetMetatileIdAt(x, y, 0x221); break; case 0x238: MapGridSetMetatileIdAt(x, y, 0xe28); break; case 0x239: MapGridSetMetatileIdAt(x, y, 0xe29); break; case 0x222: MapGridSetMetatileIdAt(x, y, 0x232); break; case 0x223: MapGridSetMetatileIdAt(x, y, 0x233); break; case 0x22a: MapGridSetMetatileIdAt(x, y, 0x23a); break; case 0x22b: MapGridSetMetatileIdAt(x, y, 0x23b); break; case 0x232: MapGridSetMetatileIdAt(x, y, 0x222); break; case 0x233: MapGridSetMetatileIdAt(x, y, 0x223); break; case 0x23a: MapGridSetMetatileIdAt(x, y, 0xe2a); break; case 0x23b: MapGridSetMetatileIdAt(x, y, 0xe2b); break; case 0x240: MapGridSetMetatileIdAt(x, y, 0xe42); break; case 0x248: MapGridSetMetatileIdAt(x, y, 0x21a); break; case 0x241: MapGridSetMetatileIdAt(x, y, 0xe43); break; case 0x249: MapGridSetMetatileIdAt(x, y, 0x21a); break; case 0x242: MapGridSetMetatileIdAt(x, y, 0xe40); break; case 0x21a: if (MapGridGetMetatileIdAt(x, y - 1) == 0x240) { MapGridSetMetatileIdAt(x, y, 0xe48); } else { MapGridSetMetatileIdAt(x, y, 0xe49); } break; case 0x243: MapGridSetMetatileIdAt(x, y, 0xe41); break; case 0x251: MapGridSetMetatileIdAt(x, y, 0xe50); break; case 0x250: MapGridSetMetatileIdAt(x, y, 0x251); break; } } } } void MauvilleGymSpecial3(void) { int i, x, y; const struct Coords8 *switchCoords = gUnknown_085B2B68; for (i = ARRAY_COUNT(gUnknown_085B2B68) - 1; i >= 0; i--) { MapGridSetMetatileIdAt(switchCoords->x, switchCoords->y, 0x206); switchCoords++; } for (y = 12; y < 24; y++) { for (x = 7; x < 16; x++) { switch (MapGridGetMetatileIdAt(x, y)) { case 0x220: MapGridSetMetatileIdAt(x, y, 0x230); break; case 0x221: MapGridSetMetatileIdAt(x, y, 0x231); break; case 0x228: MapGridSetMetatileIdAt(x, y, 0x238); break; case 0x229: MapGridSetMetatileIdAt(x, y, 0x239); break; case 0x222: MapGridSetMetatileIdAt(x, y, 0x232); break; case 0x223: MapGridSetMetatileIdAt(x, y, 0x233); break; case 0x22a: MapGridSetMetatileIdAt(x, y, 0x23a); break; case 0x22b: MapGridSetMetatileIdAt(x, y, 0x23b); break; case 0x240: MapGridSetMetatileIdAt(x, y, 0xe42); break; case 0x241: MapGridSetMetatileIdAt(x, y, 0xe43); break; case 0x248: case 0x249: MapGridSetMetatileIdAt(x, y, 0x21a); break; case 0x250: MapGridSetMetatileIdAt(x, y, 0x251); break; } } } } static void Task_PetalburgGym(u8); static void PetalburgGymFunc(u8, u16); const u8 gUnknown_085B2B78[] = {0, 1, 1, 1, 1}; const u16 gUnknown_085B2B7E[] = {0x218, 0x219, 0x21a, 0x21b, 0x21c}; void PetalburgGymSpecial1(void) { gUnknown_0203AB5C = 0; gUnknown_0203AB5D = 0; PlaySE(SE_KI_GASYAN); CreateTask(Task_PetalburgGym, 8); } static void Task_PetalburgGym(u8 taskId) { if (gUnknown_085B2B78[gUnknown_0203AB5D] == gUnknown_0203AB5C) { PetalburgGymFunc(gSpecialVar_0x8004, gUnknown_085B2B7E[gUnknown_0203AB5D]); gUnknown_0203AB5C = 0; if ((++gUnknown_0203AB5D) == 5) { DestroyTask(taskId); EnableBothScriptContexts(); } } else { gUnknown_0203AB5C++; } } static void PetalburgGymFunc(u8 a0, u16 a1) { u16 x[4]; u16 y[4]; u8 i; u8 nDoors = 0; switch (a0) { case 1: nDoors = 2; x[0] = 1; x[1] = 7; y[0] = 0x68; y[1] = 0x68; break; case 2: nDoors = 2; x[0] = 1; x[1] = 7; y[0] = 0x4e; y[1] = 0x4e; break; case 3: nDoors = 2; x[0] = 1; x[1] = 7; y[0] = 0x5b; y[1] = 0x5b; break; case 4: nDoors = 1; x[0] = 7; y[0] = 0x27; break; case 5: nDoors = 2; x[0] = 1; x[1] = 7; y[0] = 0x34; y[1] = 0x34; break; case 6: nDoors = 1; x[0] = 1; y[0] = 0x41; break; case 7: nDoors = 1; x[0] = 7; y[0] = 0xd; break; case 8: nDoors = 1; x[0] = 1; y[0] = 0x1a; break; } for (i = 0; i < nDoors; i++) { MapGridSetMetatileIdAt(x[i] + 7, y[i] + 7, a1 | 0xc00); MapGridSetMetatileIdAt(x[i] + 7, y[i] + 8, (a1 + 8) | 0xc00); } DrawWholeMapView(); } void PetalburgGymSpecial2(void) { PetalburgGymFunc(gSpecialVar_0x8004, gUnknown_085B2B7E[4]); } void ShowFieldMessageStringVar4(void) { ShowFieldMessage(gStringVar4); } void StorePlayerCoordsInVars(void) { gSpecialVar_0x8004 = gSaveBlock1Ptr->pos.x; gSpecialVar_0x8005 = gSaveBlock1Ptr->pos.y; } u8 GetPlayerTrainerIdOnesDigit(void) { return (u16)((gSaveBlock2Ptr->playerTrainerId[1] << 8) | gSaveBlock2Ptr->playerTrainerId[0]) % 10; } void GetPlayerBigGuyGirlString(void) { if (gSaveBlock2Ptr->playerGender == MALE) { StringCopy(gStringVar1, gText_BigGuy); } else { StringCopy(gStringVar1, gText_BigGirl); } } void GetRivalSonDaughterString(void) { if (gSaveBlock2Ptr->playerGender == MALE) { StringCopy(gStringVar1, gText_Daughter); } else { StringCopy(gStringVar1, gText_Son); } } u8 GetBattleOutcome(void) { return gBattleOutcome; } void CableCarWarp(void) { if (gSpecialVar_0x8004 != 0) { Overworld_SetWarpDestination(MAP_GROUP(ROUTE112_CABLE_CAR_STATION), MAP_NUM(ROUTE112_CABLE_CAR_STATION), -1, 6, 4); } else { Overworld_SetWarpDestination(MAP_GROUP(MT_CHIMNEY_CABLE_CAR_STATION), MAP_NUM(MT_CHIMNEY_CABLE_CAR_STATION), -1, 6, 4); } } void SetFlagInVar(void) { FlagSet(gSpecialVar_0x8004); } u16 GetWeekCount(void) { u16 weekCount = gLocalTime.days / 7; if (weekCount > 9999) { weekCount = 9999; } return weekCount; } u8 GetLeadMonFriendshipScore(void) { struct Pokemon *pokemon = &gPlayerParty[GetLeadMonIndex()]; if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) == 255) { return 6; } if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 200) { return 5; } if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 150) { return 4; } if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 100) { return 3; } if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 50) { return 2; } if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 1) { return 1; } return 0; } void CB2_FieldShowRegionMap(void) { FieldInitRegionMap(CB2_ReturnToFieldContinueScriptPlayMapMusic); } void FieldShowRegionMap(void) { SetMainCallback2(CB2_FieldShowRegionMap); } static void Task_PCTurnOnEffect(u8); static void PCTurnOnEffect_0(struct Task *); static void PCTurnOnEffect_1(s16, s8, s8); void DoPCTurnOnEffect(void) { if (FuncIsActiveTask(Task_PCTurnOnEffect) != TRUE) { u8 taskId = CreateTask(Task_PCTurnOnEffect, 8); gTasks[taskId].data[0] = 0; gTasks[taskId].data[1] = taskId; gTasks[taskId].data[2] = 0; gTasks[taskId].data[3] = 0; gTasks[taskId].data[4] = 0; } } static void Task_PCTurnOnEffect(u8 taskId) { struct Task *task = &gTasks[taskId]; if (task->data[0] == 0) { PCTurnOnEffect_0(task); } } static void PCTurnOnEffect_0(struct Task *task) { u8 playerDirection; s8 dx = 0; s8 dy = 0; if (task->data[3] == 6) { task->data[3] = 0; playerDirection = GetPlayerFacingDirection(); switch (playerDirection) { case DIR_NORTH: dx = 0; dy = -1; break; case DIR_WEST: dx = -1; dy = -1; break; case DIR_EAST: dx = 1; dy = -1; break; } PCTurnOnEffect_1(task->data[4], dx, dy); DrawWholeMapView(); task->data[4] ^= 1; if ((++task->data[2]) == 5) { DestroyTask(task->data[1]); } } task->data[3]++; } static void PCTurnOnEffect_1(s16 flag, s8 dx, s8 dy) { u16 tileId = 0; if (flag != 0) { if (gSpecialVar_0x8004 == 0) { tileId = 0x4; } else if (gSpecialVar_0x8004 == 1) { tileId = 0x25a; } else if (gSpecialVar_0x8004 == 2) { tileId = 0x259; } } else { if (gSpecialVar_0x8004 == 0) { tileId = 0x5; } else if (gSpecialVar_0x8004 == 1) { tileId = 0x27f; } else if (gSpecialVar_0x8004 == 2) { tileId = 0x27e; } } MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + 7, gSaveBlock1Ptr->pos.y + dy + 7, tileId | 0xc00); } static void PCTurnOffEffect(void); void DoPCTurnOffEffect(void) { PCTurnOffEffect(); } static void PCTurnOffEffect(void) { s8 dx = 0; s8 dy = 0; u16 tileId = 0; u8 playerDirection = GetPlayerFacingDirection(); switch (playerDirection) { case DIR_NORTH: dx = 0; dy = -1; break; case DIR_WEST: dx = -1; dy = -1; break; case DIR_EAST: dx = 1; dy = -1; break; } if (gSpecialVar_0x8004 == 0) { tileId = 0x4; } else if (gSpecialVar_0x8004 == 1) { tileId = 0x25a; } else if (gSpecialVar_0x8004 == 2) { tileId = 0x259; } MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + 7, gSaveBlock1Ptr->pos.y + dy + 7, tileId | 0xc00); DrawWholeMapView(); } static void Task_LotteryCornerComputerEffect(u8); static void LotteryCornerComputerEffect(struct Task *); void DoLotteryCornerComputerEffect(void) { if (FuncIsActiveTask(Task_LotteryCornerComputerEffect) != TRUE) { u8 taskId = CreateTask(Task_LotteryCornerComputerEffect, 8); gTasks[taskId].data[0] = 0; gTasks[taskId].data[1] = taskId; gTasks[taskId].data[2] = 0; gTasks[taskId].data[3] = 0; gTasks[taskId].data[4] = 0; } } static void Task_LotteryCornerComputerEffect(u8 taskId) { struct Task *task = &gTasks[taskId]; if (task->data[0] == 0) { LotteryCornerComputerEffect(task); } } static void LotteryCornerComputerEffect(struct Task *task) { if (task->data[3] == 6) { task->data[3] = 0; if (task->data[4] != 0) { MapGridSetMetatileIdAt(18, 8, 0xe9d); MapGridSetMetatileIdAt(18, 9, 0xea5); } else { MapGridSetMetatileIdAt(18, 8, 0xe58); MapGridSetMetatileIdAt(18, 9, 0xe60); } DrawWholeMapView(); task->data[4] ^= 1; if ((++task->data[2]) == 5) { DestroyTask(task->data[1]); } } task->data[3]++; } void EndLotteryCornerComputerEffect(void) { MapGridSetMetatileIdAt(18, 8, 0xe9d); MapGridSetMetatileIdAt(18, 9, 0xea5); DrawWholeMapView(); } void SetTrickHouseEndRoomFlag(void) { u16 *specVar = &gSpecialVar_0x8004; u16 flag = FLAG_0x1F5; *specVar = flag; FlagSet(flag); } void ResetTrickHouseEndRoomFlag(void) { u16 *specVar = &gSpecialVar_0x8004; u16 flag = FLAG_0x1F5; *specVar = flag; FlagClear(flag); } bool8 CheckLeadMonCool(void) { if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_COOL) < 200) { return FALSE; } return TRUE; } bool8 CheckLeadMonBeauty(void) { if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_BEAUTY) < 200) { return FALSE; } return TRUE; } bool8 CheckLeadMonCute(void) { if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_CUTE) < 200) { return FALSE; } return TRUE; } bool8 CheckLeadMonSmart(void) { if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SMART) < 200) { return FALSE; } return TRUE; } bool8 CheckLeadMonTough(void) { if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_TOUGH) < 200) { return FALSE; } return TRUE; } void IsGrassTypeInParty(void) { u8 i; u16 species; struct Pokemon *pokemon; for (i = 0; i < PARTY_SIZE; i++) { pokemon = &gPlayerParty[i]; if (GetMonData(pokemon, MON_DATA_SANITY_BIT2) && !GetMonData(pokemon, MON_DATA_IS_EGG)) { species = GetMonData(pokemon, MON_DATA_SPECIES); if (gBaseStats[species].type1 == TYPE_GRASS || gBaseStats[species].type2 == TYPE_GRASS) { gSpecialVar_Result = TRUE; return; } } } gSpecialVar_Result = FALSE; } void SpawnScriptEventObject(void) { u8 obj = SpawnSpecialEventObjectParameterized(EVENT_OBJ_GFX_BOY_1, 8, 0x7F, gSaveBlock1Ptr->pos.x + 7, gSaveBlock1Ptr->pos.y + 7, 3); gEventObjects[obj].invisible = TRUE; CameraObjectSetFollowedObjectId(gEventObjects[obj].spriteId); } void RemoveScriptEventObject(void) { CameraObjectSetFollowedObjectId(GetPlayerAvatarObjectId()); RemoveEventObjectByLocalIdAndMap(0x7F, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); } u8 GetPokeblockNameByMonNature(void) { return CopyMonFavoritePokeblockName(GetNature(&gPlayerParty[GetLeadMonIndex()]), gStringVar1); } void GetSecretBaseNearbyMapName(void) { GetMapName(gStringVar1, VarGet(VAR_SECRET_BASE_MAP), 0); } u16 GetBestBattleTowerStreak(void) { return GetGameStat(GAME_STAT_BATTLE_TOWER_BEST_STREAK); } void BufferEReaderTrainerName(void) { GetEreaderTrainerName(gStringVar1); } const u8 gUnknown_085B2B88[] = {12, 2, 4, 5, 1, 8, 7, 11, 3, 10, 9, 6}; const u8 gUnknown_085B2B94[] = {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5}; const u8 gUnknown_085B2BA0[] = {3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5}; u16 GetSlotMachineId(void) { u32 v0 = gSaveBlock1Ptr->easyChatPairs[0].unk0_0 + gSaveBlock1Ptr->easyChatPairs[0].unk2 + gUnknown_085B2B88[gSpecialVar_0x8004]; if (GetPriceReduction(2)) { return gUnknown_085B2BA0[v0 % 12]; } return gUnknown_085B2B94[v0 % 12]; } bool8 FoundAbandonedShipRoom1Key(void) { u16 *specVar = &gSpecialVar_0x8004; u16 flag = FLAG_HIDDEN_ITEM_1F; *specVar = flag; if (!FlagGet(flag)) { return FALSE; } return TRUE; } bool8 FoundAbandonedShipRoom2Key(void) { u16 *specVar = &gSpecialVar_0x8004; u16 flag = FLAG_HIDDEN_ITEM_20; *specVar = flag; if (!FlagGet(flag)) { return FALSE; } return TRUE; } bool8 FoundAbandonedShipRoom4Key(void) { u16 *specVar = &gSpecialVar_0x8004; u16 flag = FLAG_HIDDEN_ITEM_21; *specVar = flag; if (!FlagGet(flag)) { return FALSE; } return TRUE; } bool8 FoundAbandonedShipRoom6Key(void) { u16 *specVar = &gSpecialVar_0x8004; u16 flag = FLAG_HIDDEN_ITEM_22; *specVar = flag; if (!FlagGet(flag)) { return FALSE; } return TRUE; } bool8 LeadMonHasEffortRibbon(void) { return GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_EFFORT_RIBBON, NULL); } void GiveLeadMonEffortRibbon(void) { bool8 ribbonSet; struct Pokemon *leadMon; IncrementGameStat(GAME_STAT_RECEIVED_RIBBONS); FlagSet(FLAG_SYS_RIBBON_GET); ribbonSet = TRUE; leadMon = &gPlayerParty[GetLeadMonIndex()]; SetMonData(leadMon, MON_DATA_EFFORT_RIBBON, &ribbonSet); if (GetRibbonCount(leadMon) > 4) { sub_80EE4DC(leadMon, 0x47); } } bool8 Special_AreLeadMonEVsMaxedOut(void) { if (GetMonEVCount(&gPlayerParty[GetLeadMonIndex()]) >= 510) { return TRUE; } return FALSE; } u8 TryUpdateRusturfTunnelState(void) { if (!FlagGet(FLAG_RUSTURF_TUNNEL_OPENED) && gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(RUSTURF_TUNNEL) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(RUSTURF_TUNNEL)) { if (FlagGet(FLAG_HIDE_RUSTURF_TUNNEL_ROCK_1)) { VarSet(VAR_RUSTURF_TUNNEL_STATE, 4); return TRUE; } else if (FlagGet(FLAG_HIDE_RUSTURF_TUNNEL_ROCK_2)) { VarSet(VAR_RUSTURF_TUNNEL_STATE, 5); return TRUE; } } return FALSE; } void SetShoalItemFlag(u16 v0) { FlagSet(FLAG_SYS_SHOAL_ITEM); } void PutZigzagoonInPlayerParty(void) { u16 monData; CreateMon(&gPlayerParty[0], SPECIES_ZIGZAGOON, 7, 0x20, FALSE, 0, FALSE, 0); monData = TRUE; SetMonData(&gPlayerParty[0], MON_DATA_ALT_ABILITY, &monData); monData = MOVE_TACKLE; SetMonData(&gPlayerParty[0], MON_DATA_MOVE1, &monData); monData = MOVE_NONE; SetMonData(&gPlayerParty[0], MON_DATA_MOVE2, &monData); SetMonData(&gPlayerParty[0], MON_DATA_MOVE3, &monData); SetMonData(&gPlayerParty[0], MON_DATA_MOVE4, &monData); } bool8 IsStarterInParty(void) { u8 i; u16 starter = GetStarterPokemon(VarGet(VAR_STARTER_MON)); u8 partyCount = CalculatePlayerPartyCount(); for (i = 0; i < partyCount; i++) { if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) == starter) { return TRUE; } } return FALSE; } bool8 ScriptCheckFreePokemonStorageSpace(void) { return CheckFreePokemonStorageSpace(); } bool8 IsPokerusInParty(void) { if (!CheckPartyPokerus(gPlayerParty, 0x3f)) { return FALSE; } return TRUE; } static void sub_81395BC(u8 taskId); static void sub_8139620(u8 taskId); void sub_8139560(void) { u8 taskId = CreateTask(sub_81395BC, 9); gTasks[taskId].data[0] = gSpecialVar_0x8005; gTasks[taskId].data[1] = 0; gTasks[taskId].data[2] = gSpecialVar_0x8006; gTasks[taskId].data[3] = gSpecialVar_0x8007; gTasks[taskId].data[4] = gSpecialVar_0x8004; SetCameraPanningCallback(NULL); PlaySE(SE_W070); } static void sub_81395BC(u8 taskId) { s16 *data = gTasks[taskId].data; data[1]++; if (data[1] % data[3] == 0) { data[1] = 0; data[2]--; data[0] = -data[0]; data[4] = -data[4]; SetCameraPanning(data[0], data[4]); if (data[2] == 0) { sub_8139620(taskId); InstallCameraPanAheadCallback(); } } } static void sub_8139620(u8 taskId) { DestroyTask(taskId); EnableBothScriptContexts(); } bool8 FoundBlackGlasses(void) { return FlagGet(FLAG_HIDDEN_ITEM_BLACK_GLASSES); } void SetRoute119Weather(void) { if (is_map_type_1_2_3_5_or_6(get_map_light_from_warp0()) != TRUE) { SetSav1Weather(0x14); } } void SetRoute123Weather(void) { if (is_map_type_1_2_3_5_or_6(get_map_light_from_warp0()) != TRUE) { SetSav1Weather(0x15); } } u8 GetLeadMonIndex(void) { u8 i; u8 partyCount = CalculatePlayerPartyCount(); for (i = 0; i < partyCount; i++) { if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != 0) { return i; } } return 0; } u16 ScriptGetPartyMonSpecies(void) { return GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES2, NULL); } void nullsub_54(void) { } u16 GetDaysUntilPacifidlogTMAvailable(void) { u16 tmReceivedDay = VarGet(VAR_PACIFIDLOG_TM_RECEIVED_DAY); if (gLocalTime.days - tmReceivedDay >= 7) { return 0; } else if (gLocalTime.days < 0) { return 8; } return 7 - (gLocalTime.days - tmReceivedDay); } u16 SetPacifidlogTMReceivedDay(void) { VarSet(VAR_PACIFIDLOG_TM_RECEIVED_DAY, gLocalTime.days); return gLocalTime.days; } bool8 MonOTNameMatchesPlayer(void) { if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_LANGUAGE) != GAME_LANGUAGE) return TRUE; // huh? GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_OT_NAME, gStringVar1); if (!StringCompare(gSaveBlock2Ptr->playerName, gStringVar1)) { return FALSE; } return TRUE; } void BufferLottoTicketNumber(void) { if (gSpecialVar_Result >= 10000) { TV_PrintIntToStringVar(0, gSpecialVar_Result); } else if (gSpecialVar_Result >= 1000) { gStringVar1[0] = CHAR_0; ConvertIntToDecimalStringN(gStringVar1 + 1, gSpecialVar_Result, 0, CountDigits(gSpecialVar_Result)); } else if (gSpecialVar_Result >= 100) { gStringVar1[0] = CHAR_0; gStringVar1[1] = CHAR_0; ConvertIntToDecimalStringN(gStringVar1 + 2, gSpecialVar_Result, 0, CountDigits(gSpecialVar_Result)); } else if (gSpecialVar_Result >= 10) { gStringVar1[0] = CHAR_0; gStringVar1[1] = CHAR_0; gStringVar1[2] = CHAR_0; ConvertIntToDecimalStringN(gStringVar1 + 3, gSpecialVar_Result, 0, CountDigits(gSpecialVar_Result)); } else { gStringVar1[0] = CHAR_0; gStringVar1[1] = CHAR_0; gStringVar1[2] = CHAR_0; gStringVar1[3] = CHAR_0; ConvertIntToDecimalStringN(gStringVar1 + 4, gSpecialVar_Result, 0, CountDigits(gSpecialVar_Result)); } } u16 sub_813986C(void) { switch (gSpecialVar_Result) { case 0: return mevent_081445C0(3); case 1: return mevent_081445C0(4); case 2: return mevent_081445C0(0); case 3: return mevent_081445C0(1); case 4: return mevent_081445C0(2); default: return 0; } } bool8 sub_81398C0(void) { if (gSpecialVar_0x8004 >= ITEM_TM01 && gSpecialVar_0x8004 <= ITEM_HM08) { StringCopy(gStringVar2, gMoveNames[ItemIdToBattleMoveId(gSpecialVar_0x8004)]); return TRUE; } return FALSE; } bool8 sub_813990C(void) { u8 partyCount = CalculatePlayerPartyCount(); u8 i; for (i = 0; i < partyCount; i++) { if (GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT1) == 1) return TRUE; } return FALSE; } bool8 InMultiBattleRoom(void) { if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM) && VarGet(VAR_0x40CE) == 2) return TRUE; return FALSE; } void sub_8139980(void) { SetCameraPanningCallback(NULL); SetCameraPanning(8, 0); } void SetDepartmentStoreFloorVar(void) { u8 deptStoreFloor; switch (gSaveBlock1Ptr->warp2.mapNum) { case MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_1F): deptStoreFloor = 4; break; case MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_2F): deptStoreFloor = 5; break; case MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_3F): deptStoreFloor = 6; break; case MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_4F): deptStoreFloor = 7; break; case MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_5F): deptStoreFloor = 8; break; case MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP): deptStoreFloor = 15; break; default: deptStoreFloor = 4; break; } VarSet(VAR_DEPT_STORE_FLOOR, deptStoreFloor); }