pokeemerald/src/field_specials.c
2018-08-08 01:37:12 -07:00

1658 lines
40 KiB
C

#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);
}