diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/coins.c | 3 | ||||
-rwxr-xr-x | src/field_special_scene.c | 363 | ||||
-rw-r--r-- | src/money.c | 145 | ||||
-rw-r--r-- | src/roamer.c | 218 |
4 files changed, 727 insertions, 2 deletions
diff --git a/src/coins.c b/src/coins.c index 84a79f5f2..4ee601b22 100644 --- a/src/coins.c +++ b/src/coins.c @@ -4,14 +4,13 @@ #include "window.h" #include "text_window.h" #include "string_util.h" +#include "menu.h" #define MAX_COINS 9999 EWRAM_DATA u8 sCoinsWindowId = 0; extern s32 GetStringRightAlignXOffset(u8 fontId, u8 *str, s32 totalWidth); -extern void SetWindowTemplateFields(struct WindowTemplate* template, u8 priority, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height, u8 palNum, u16 baseBlock); -extern void SetWindowBorderStyle(u8 windowId, bool8 copyToVram, s16 tileStart, s8 palette); extern void sub_819746C(u8 windowId, bool8 copyToVram); extern const u8 gText_Coins[]; diff --git a/src/field_special_scene.c b/src/field_special_scene.c new file mode 100755 index 000000000..9c35a33da --- /dev/null +++ b/src/field_special_scene.c @@ -0,0 +1,363 @@ +#include "global.h" +#include "task.h" +#include "sprite.h" +#include "field_map_obj.h" +#include "songs.h" +#include "sound.h" +#include "palette.h" +#include "script.h" +#include "vars.h" +#include "event_data.h" +#include "main.h" + +#define SECONDS(value) ((signed) (60.0 * value + 0.5)) + +extern u8 GetSSTidalLocation(s8 *, s8 *, s16 *, s16 *); // should be in field_specials.h +extern void warp1_set(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y); +extern bool8 sub_80D3340(u8, u8, u8); +extern bool32 CountSSTidalStep(u16); +extern bool8 exec_movement(u8, u8, u8, u8 *); +extern void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused); +extern void sp13E_warp_to_last_warp(void); +extern void saved_warp2_set(int unused, s8 mapGroup, s8 mapNum, s8 warpId); +extern void sub_80AF8B8(void); + +// porthole states +enum +{ + INIT_PORTHOLE, + IDLE_CHECK, + EXECUTE_MOVEMENT, + EXIT_PORTHOLE, +}; + +extern void SetCameraPanning(s16 x, s16 y); +extern void SetCameraPanningCallback(void ( *callback)()); +extern void InstallCameraPanAheadCallback(); +extern void pal_fill_black(void); +extern void MapGridSetMetatileIdAt(s32 x, s32 y, u16 metatileId); +extern void DrawWholeMapView(); + +extern s8 gTruckCamera_HorizontalTable[]; + +extern u8 gUnknown_0858E8AB[]; +extern u8 gUnknown_0858E8AD[]; + +void Task_Truck3(u8); + +s16 GetTruckCameraBobbingY(int a1) +{ + if (!(a1 % 120)) + return -1; + else if ((a1 % 10) <= 4) + return 1; + + return 0; +} + +s16 GetTruckBoxMovement(int a1) // for the box movement? +{ + if (!((a1 + 120) % 180)) + return -1; + + return 0; +} + +// smh STILL BROKEN IN EMERALD +void Task_Truck1(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + s16 cameraYpan; + s16 box1 = 0; + s16 box2 = 0; + s16 box3 = 0; + u8 mapNum, mapGroup; + register s16 zero asm("r4"); + + box1 = GetTruckBoxMovement(data[0] + 30) * 4; // top box. + sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3, box1 + 3); + box2 = GetTruckBoxMovement(data[0]) * 2; // bottom left box. + sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 0, box2 - 3); + box3 = GetTruckBoxMovement(data[0]) * 4; // bottom right box. + mapNum = gSaveBlock1Ptr->location.mapNum; + mapGroup = gSaveBlock1Ptr->location.mapGroup; + zero = 0; + sub_808E82C(3, mapNum, mapGroup, -3, box3); + + if (++data[0] == SECONDS(500)) // this will never run + data[0] = zero; // reset the timer if it gets stuck. + + cameraYpan = GetTruckCameraBobbingY(data[0]); + SetCameraPanning(0, cameraYpan); +} + +void Task_Truck2(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + s16 cameraYpan; + s16 cameraXpan; + s16 box1; + s16 box2; + s16 box3; + + data[0]++; + data[2]++; + + if (data[0] > 5) + { + data[0] = 0; + data[1]++; + } + if ((u16)data[1] == 19) + { + DestroyTask(taskId); + } + else + { + if (gTruckCamera_HorizontalTable[data[1]] == 2) + gTasks[taskId].func = Task_Truck3; + + cameraXpan = gTruckCamera_HorizontalTable[data[1]]; + cameraYpan = GetTruckCameraBobbingY(data[2]); + SetCameraPanning(cameraXpan, cameraYpan); + box1 = GetTruckBoxMovement(data[2] + 30) * 4; + sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3 - cameraXpan, box1 + 3); + box2 = GetTruckBoxMovement(data[2]) * 2; + sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -cameraXpan, box2 - 3); + box3 = GetTruckBoxMovement(data[2]) * 4; + sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3 - cameraXpan, box3); + } +} + +void Task_Truck3(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + s16 cameraXpan; + s16 cameraYpan; + + data[0]++; + + if (data[0] > 5) + { + data[0] = 0; + data[1]++; + } + + if ((u16)data[1] == 19) + { + DestroyTask(taskId); + } + else + { + cameraXpan = gTruckCamera_HorizontalTable[data[1]]; + cameraYpan = 0; + SetCameraPanning(cameraXpan, 0); + sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3 - cameraXpan, cameraYpan + 3); + sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -cameraXpan, cameraYpan - 3); + sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3 - cameraXpan, cameraYpan); + } +} + +void Task_HandleTruckSequence(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + + switch (data[0]) + { + /* + Each case has a timer which is handled with data[1], incrementing + until it reaches the if function's condition, which sets the next task up. + */ + case 0: + data[1]++; + if (data[1] == SECONDS(1.5)) + { + SetCameraPanningCallback(NULL); + data[1] = 0; // reset the timer. + data[2] = CreateTask(Task_Truck1, 0xA); + data[0] = 1; // run the next case. + PlaySE(SE_TRACK_MOVE); + } + break; + case 1: + data[1]++; + if (data[1] == SECONDS(2.5)) + { + pal_fill_black(); + data[1] = 0; + data[0] = 2; + } + break; + case 2: + data[1]++; + if (!gPaletteFade.active && data[1] > SECONDS(5)) + { + data[1] = 0; + DestroyTask(data[2]); + data[3] = CreateTask(Task_Truck2, 0xA); + data[0] = 3; + PlaySE(SE_TRACK_STOP); + } + break; + case 3: + if (!gTasks[data[3]].isActive) // is Truck2 no longer active (is Truck3 active?) + { + InstallCameraPanAheadCallback(); + data[1] = 0; + data[0] = 4; + } + break; + case 4: + data[1]++; + if (data[1] == 90) + { + PlaySE(SE_TRACK_HAIK); + data[1] = 0; + data[0] = 5; + } + break; + case 5: + data[1]++; + if (data[1] == 120) + { + MapGridSetMetatileIdAt(11, 8, 520); + MapGridSetMetatileIdAt(11, 9, 528); + MapGridSetMetatileIdAt(11, 10, 536); + DrawWholeMapView(); + PlaySE(SE_TRACK_DOOR); + DestroyTask(taskId); + ScriptContext2_Disable(); + } + break; + } +} + +void ExecuteTruckSequence(void) +{ + MapGridSetMetatileIdAt(11, 8, 525); + MapGridSetMetatileIdAt(11, 9, 533); + MapGridSetMetatileIdAt(11, 10, 541); + DrawWholeMapView(); + ScriptContext2_Enable(); + CpuFastFill(0, gPlttBufferFaded, 0x400); + CreateTask(Task_HandleTruckSequence, 0xA); +} + +void EndTruckSequence(u8 taskId) +{ + if (!FuncIsActiveTask(Task_HandleTruckSequence)) + { + sub_808E82C(1, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 3, 3); + sub_808E82C(2, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, 0, -3); + sub_808E82C(3, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, -3, 0); + } +} + +bool8 sub_80FB59C(void) +{ + s8 mapGroup, mapNum; + s16 x, y; + + if (GetSSTidalLocation(&mapGroup, &mapNum, &x, &y)) + { + return FALSE; + } + else + { + warp1_set(mapGroup, mapNum, -1, x, y); + return TRUE; + } +} + +void Task_HandlePorthole(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + u16 *var = GetVarPointer(VAR_PORTHOLE); + struct WarpData *location = &gSaveBlock1Ptr->location; + + switch (data[0]) + { + case INIT_PORTHOLE: // finish fading before making porthole finish. + if (!gPaletteFade.active) + { + data[1] = 0; + data[0] = EXECUTE_MOVEMENT; // execute movement before checking if should be exited. strange? + } + break; + case IDLE_CHECK: // idle and move. + if (gMain.newKeys & A_BUTTON) + data[1] = 1; + if (!sub_80D3340(0xFF, location->mapNum, location->mapGroup)) + return; + if (CountSSTidalStep(1) == TRUE) + { + if (*var == 2) + *var = 9; + else + *var = 10; + data[0] = 3; + return; + } + data[0] = 2; + case EXECUTE_MOVEMENT: // execute movement. + if (data[1]) + { + data[0] = EXIT_PORTHOLE; // exit porthole. + return; + } + // run this once. + if (*var == 2) // which direction? + { + exec_movement(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AB); + data[0] = IDLE_CHECK; // run case 1. + } + else + { + exec_movement(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AD); + data[0] = IDLE_CHECK; // run case 1. + } + break; + case EXIT_PORTHOLE: // exit porthole. + FlagReset(0x4001); + FlagReset(0x4000); + copy_saved_warp2_bank_and_enter_x_to_warp1(0); + sp13E_warp_to_last_warp(); + DestroyTask(taskId); + break; + } +} + +void sub_80FB6EC(void) +{ + u8 spriteId = AddPseudoFieldObject(0x8C, SpriteCallbackDummy, 112, 80, 0); + + gSprites[spriteId].coordOffsetEnabled = FALSE; + + if (VarGet(0x40B4) == 2) + { + StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(4)); + } + else + { + StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(3)); + } +} + +void sub_80FB768(void) +{ + sub_80FB6EC(); + gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = TRUE; + pal_fill_black(); + CreateTask(Task_HandlePorthole, 80); + ScriptContext2_Enable(); +} + +void sub_80FB7A4(void) +{ + FlagSet(SYS_CRUISE_MODE); + FlagSet(0x4001); + FlagSet(0x4000); + saved_warp2_set(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1); + sub_80FB59C(); + sub_80AF8B8(); +} diff --git a/src/money.c b/src/money.c index be64d9633..65a45b158 100644 --- a/src/money.c +++ b/src/money.c @@ -1,8 +1,77 @@ #include "global.h" #include "money.h" +#include "event_data.h" +#include "string_util.h" +#include "text.h" +#include "menu.h" +#include "window.h" +#include "sprite.h" +#include "decompress.h" + +extern const u8 gText_PokedollarVar1[]; + +extern const u8 gMenuMoneyGfx[]; +extern const u8 gMenuMoneyPal[]; #define MAX_MONEY 999999 +EWRAM_DATA static u8 sMoneyBoxWindowId = 0; +EWRAM_DATA static u8 sMoneyLabelSpriteId = 0; + +#define MONEY_LABEL_TAG 0x2722 + +static const struct OamData sOamData_MoneyLabel = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 1, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_MoneyLabel[] = +{ + ANIMCMD_FRAME(0, 0), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_MoneyLabel[] = +{ + sSpriteAnim_MoneyLabel, +}; + +static const struct SpriteTemplate sSpriteTemplate_MoneyLabel = +{ + .tileTag = MONEY_LABEL_TAG, + .paletteTag = MONEY_LABEL_TAG, + .oam = &sOamData_MoneyLabel, + .anims = sSpriteAnimTable_MoneyLabel, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct CompressedSpriteSheet sSpriteSheet_MoneyLabel = +{ + .data = gMenuMoneyGfx, + .size = 256, + .tag = MONEY_LABEL_TAG, +}; + +static const struct CompressedSpritePalette sSpritePalette_MoneyLabel = +{ + .data = gMenuMoneyPal, + .tag = MONEY_LABEL_TAG +}; + u32 GetMoney(u32* moneyPtr) { return *moneyPtr ^ gSaveBlock2Ptr->encryptionKey; @@ -53,3 +122,79 @@ void SubtractMoney(u32* moneyPtr, u32 toSub) SetMoney(moneyPtr, toSet); } + +bool8 IsEnoughForCostInVar0x8005(void) +{ + return IsEnoughMoney(&gSaveBlock1Ptr->money, gSpecialVar_0x8005); +} + +void SubtractMoneyFromVar0x8005(void) +{ + SubtractMoney(&gSaveBlock1Ptr->money, gSpecialVar_0x8005); +} + +void PrintMoneyAmountInMoneyBox(u8 windowId, int amount, u8 speed) +{ + PrintMoneyAmount(windowId, 0x26, 1, amount, speed); +} + +void PrintMoneyAmount(u8 windowId, u8 x, u8 y, int amount, u8 speed) +{ + u8 *txtPtr; + s32 strLength; + + ConvertIntToDecimalStringN(gStringVar1, amount, STR_CONV_MODE_LEFT_ALIGN, 6); + + strLength = 6 - StringLength(gStringVar1); + txtPtr = gStringVar4; + + while (strLength-- > 0) + *(txtPtr++) = 0x77; + + StringExpandPlaceholders(txtPtr, gText_PokedollarVar1); + PrintTextOnWindow(windowId, 1, gStringVar4, x, y, speed, NULL); +} + +void PrintMoneyAmountInMoneyBoxWithBorder(u8 windowId, u16 tileStart, u8 pallete, int amount) +{ + SetWindowBorderStyle(windowId, FALSE, tileStart, pallete); + PrintMoneyAmountInMoneyBox(windowId, amount, 0); +} + +void ChangeAmountInMoneyBox(int amount) +{ + PrintMoneyAmountInMoneyBox(sMoneyBoxWindowId, amount, 0); +} + +void DrawMoneyBox(int amount, u8 x, u8 y) +{ + struct WindowTemplate template; + + SetWindowTemplateFields(&template, 0, x + 1, y + 1, 10, 2, 15, 8); + sMoneyBoxWindowId = AddWindow(&template); + FillWindowPixelBuffer(sMoneyBoxWindowId, 0); + PutWindowTilemap(sMoneyBoxWindowId); + CopyWindowToVram(sMoneyBoxWindowId, 1); + PrintMoneyAmountInMoneyBoxWithBorder(sMoneyBoxWindowId, 0x214, 14, amount); + AddMoneyLabelObject((8 * x) + 19, (8 * y) + 11); +} + +void HideMoneyBox(void) +{ + RemoveMoneyLabelObject(); + sub_8198070(sMoneyBoxWindowId, FALSE); + CopyWindowToVram(sMoneyBoxWindowId, 2); + RemoveWindow(sMoneyBoxWindowId); +} + +void AddMoneyLabelObject(u16 x, u16 y) +{ + LoadCompressedObjectPic(&sSpriteSheet_MoneyLabel); + LoadCompressedObjectPalette(&sSpritePalette_MoneyLabel); + sMoneyLabelSpriteId = CreateSprite(&sSpriteTemplate_MoneyLabel, x, y, 0); +} + +void RemoveMoneyLabelObject(void) +{ + DestroySpriteAndFreeResources(&gSprites[sMoneyLabelSpriteId]); +} diff --git a/src/roamer.c b/src/roamer.c new file mode 100644 index 000000000..cbe1b6312 --- /dev/null +++ b/src/roamer.c @@ -0,0 +1,218 @@ +#include "global.h" +#include "roamer.h" +#include "pokemon.h" +#include "rng.h" +#include "species.h" +#include "event_data.h" + +enum +{ + MAP_GRP = 0, // map group + MAP_NUM = 1, // map number +}; + +EWRAM_DATA static u8 sLocationHistory[3][2] = {0}; +EWRAM_DATA static u8 sRoamerLocation[2] = {0}; + +static const u8 sRoamerLocations[][6] = +{ + { 0x19, 0x1A, 0x20, 0x21, 0x31, 0xFF }, + { 0x1A, 0x19, 0x20, 0x21, 0xFF, 0xFF }, + { 0x20, 0x1A, 0x19, 0x21, 0xFF, 0xFF }, + { 0x21, 0x20, 0x19, 0x1A, 0x22, 0x26 }, + { 0x22, 0x21, 0x23, 0xFF, 0xFF, 0xFF }, + { 0x23, 0x22, 0x24, 0xFF, 0xFF, 0xFF }, + { 0x24, 0x23, 0x25, 0x26, 0xFF, 0xFF }, + { 0x25, 0x24, 0x26, 0xFF, 0xFF, 0xFF }, + { 0x26, 0x25, 0x21, 0xFF, 0xFF, 0xFF }, + { 0x27, 0x24, 0x28, 0x29, 0xFF, 0xFF }, + { 0x28, 0x27, 0x2A, 0xFF, 0xFF, 0xFF }, + { 0x29, 0x27, 0x2A, 0xFF, 0xFF, 0xFF }, + { 0x2A, 0x28, 0x29, 0x2B, 0xFF, 0xFF }, + { 0x2B, 0x2A, 0x2C, 0xFF, 0xFF, 0xFF }, + { 0x2C, 0x2B, 0x2D, 0xFF, 0xFF, 0xFF }, + { 0x2D, 0x2C, 0x2E, 0xFF, 0xFF, 0xFF }, + { 0x2E, 0x2D, 0x2F, 0xFF, 0xFF, 0xFF }, + { 0x2F, 0x2E, 0x30, 0xFF, 0xFF, 0xFF }, + { 0x30, 0x2F, 0x31, 0xFF, 0xFF, 0xFF }, + { 0x31, 0x30, 0x19, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, +}; + +void ClearRoamerData(void) +{ + memset(&gSaveBlock1Ptr->roamer, 0, sizeof(struct Roamer)); + (&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS; +} + +void ClearRoamerLocationData(void) +{ + u8 i; + + for (i = 0; i < 3; i++) + { + sLocationHistory[i][MAP_GRP] = 0; + sLocationHistory[i][MAP_NUM] = 0; + } + + sRoamerLocation[MAP_GRP] = 0; + sRoamerLocation[MAP_NUM] = 0; +} + +static void CreateInitialRoamerMon(bool16 createLatios) +{ + if (!createLatios) + (&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIAS; + else + (&gSaveBlock1Ptr->roamer)->species = SPECIES_LATIOS; + + CreateMon(&gEnemyParty[0], (&gSaveBlock1Ptr->roamer)->species, 40, 0x20, 0, 0, 0, 0); + (&gSaveBlock1Ptr->roamer)->level = 40; + (&gSaveBlock1Ptr->roamer)->status = 0; + (&gSaveBlock1Ptr->roamer)->active = TRUE; + (&gSaveBlock1Ptr->roamer)->ivs = GetMonData(&gEnemyParty[0], MON_DATA_IVS); + (&gSaveBlock1Ptr->roamer)->personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY); + (&gSaveBlock1Ptr->roamer)->hp = GetMonData(&gEnemyParty[0], MON_DATA_MAX_HP); + (&gSaveBlock1Ptr->roamer)->cool = GetMonData(&gEnemyParty[0], MON_DATA_COOL); + (&gSaveBlock1Ptr->roamer)->beauty = GetMonData(&gEnemyParty[0], MON_DATA_BEAUTY); + (&gSaveBlock1Ptr->roamer)->cute = GetMonData(&gEnemyParty[0], MON_DATA_CUTE); + (&gSaveBlock1Ptr->roamer)->smart = GetMonData(&gEnemyParty[0], MON_DATA_SMART); + (&gSaveBlock1Ptr->roamer)->tough = GetMonData(&gEnemyParty[0], MON_DATA_TOUGH); + sRoamerLocation[MAP_GRP] = 0; + sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % 20][0]; +} + +void InitRoamer(void) +{ + ClearRoamerData(); + ClearRoamerLocationData(); + CreateInitialRoamerMon(gSpecialVar_0x8004); +} + +void UpdateLocationHistoryForRoamer(void) +{ + sLocationHistory[2][MAP_GRP] = sLocationHistory[1][MAP_GRP]; + sLocationHistory[2][MAP_NUM] = sLocationHistory[1][MAP_NUM]; + + sLocationHistory[1][MAP_GRP] = sLocationHistory[0][MAP_GRP]; + sLocationHistory[1][MAP_NUM] = sLocationHistory[0][MAP_NUM]; + + sLocationHistory[0][MAP_GRP] = gSaveBlock1Ptr->location.mapGroup; + sLocationHistory[0][MAP_NUM] = gSaveBlock1Ptr->location.mapNum; +} + +void RoamerMoveToOtherLocationSet(void) +{ + u8 val = 0; + struct Roamer *roamer = &gSaveBlock1Ptr->roamer; + + if (!roamer->active) + return; + + sRoamerLocation[MAP_GRP] = val; + + while (1) + { + val = sRoamerLocations[Random() % 20][0]; + if (sRoamerLocation[MAP_NUM] != val) + { + sRoamerLocation[MAP_NUM] = val; + return; + } + } +} + +void RoamerMove(void) +{ + u8 locSet = 0; + + if ((Random() % 16) == 0) + { + RoamerMoveToOtherLocationSet(); + } + else + { + struct Roamer *roamer = &gSaveBlock1Ptr->roamer; + + if (!roamer->active) + return; + + while (locSet < 20) + { + if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0]) + { + u8 mapNum; + while (1) + { + mapNum = sRoamerLocations[locSet][(Random() % 5) + 1]; + if (!(sLocationHistory[2][MAP_GRP] == 0 && sLocationHistory[2][MAP_NUM] == mapNum) && mapNum != 0xFF) + break; + } + sRoamerLocation[MAP_NUM] = mapNum; + return; + } + locSet++; + } + } +} + +bool8 IsRoamerAt(u8 mapGroup, u8 mapNum) +{ + struct Roamer *roamer = &gSaveBlock1Ptr->roamer; + + if (roamer->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM]) + return TRUE; + else + return FALSE; +} + +void CreateRoamerMonInstance(void) +{ + struct Pokemon *mon; + struct Roamer *roamer; + + mon = &gEnemyParty[0]; + ZeroEnemyPartyMons(); + roamer = &gSaveBlock1Ptr->roamer; + CreateMonWithIVsPersonality(mon, roamer->species, roamer->level, roamer->ivs, roamer->personality); + SetMonData(mon, MON_DATA_STATUS, &gSaveBlock1Ptr->roamer.status); + SetMonData(mon, MON_DATA_HP, &gSaveBlock1Ptr->roamer.hp); + SetMonData(mon, MON_DATA_COOL, &gSaveBlock1Ptr->roamer.cool); + SetMonData(mon, MON_DATA_BEAUTY, &gSaveBlock1Ptr->roamer.beauty); + SetMonData(mon, MON_DATA_CUTE, &gSaveBlock1Ptr->roamer.cute); + SetMonData(mon, MON_DATA_SMART, &gSaveBlock1Ptr->roamer.smart); + SetMonData(mon, MON_DATA_TOUGH, &gSaveBlock1Ptr->roamer.tough); +} + +bool8 TryStartRoamerEncounter(void) +{ + if (IsRoamerAt(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum) == TRUE && (Random() % 4) == 0) + { + CreateRoamerMonInstance(); + return TRUE; + } + else + { + return FALSE; + } +} + +void UpdateRoamerHPStatus(struct Pokemon *mon) +{ + (&gSaveBlock1Ptr->roamer)->hp = GetMonData(mon, MON_DATA_HP); + (&gSaveBlock1Ptr->roamer)->status = GetMonData(mon, MON_DATA_STATUS); + + RoamerMoveToOtherLocationSet(); +} + +void SetRoamerInactive(void) +{ + struct Roamer *roamer = &gSaveBlock1Ptr->roamer; + roamer->active = FALSE; +} + +void GetRoamerLocation(u8 *mapGroup, u8 *mapNum) +{ + *mapGroup = sRoamerLocation[MAP_GRP]; + *mapNum = sRoamerLocation[MAP_NUM]; +} |