pokeemerald/src/contest_util.c

2757 lines
82 KiB
C
Raw Normal View History

#include "global.h"
#include "malloc.h"
#include "battle.h"
2019-02-21 01:05:33 +01:00
#include "battle_gfx_sfx_util.h"
#include "bg.h"
#include "contest.h"
#include "contest_util.h"
#include "contest_link.h"
#include "contest_painting.h"
2019-04-04 23:53:06 +02:00
#include "data.h"
#include "decompress.h"
#include "dma3.h"
#include "event_data.h"
#include "event_object_movement.h"
#include "field_specials.h"
#include "gpu_regs.h"
#include "graphics.h"
#include "international_string_util.h"
#include "link.h"
#include "link_rfu.h"
#include "load_save.h"
#include "main.h"
#include "overworld.h"
#include "palette.h"
#include "pokedex.h"
#include "pokemon.h"
#include "pokemon_icon.h"
#include "random.h"
#include "save.h"
#include "scanline_effect.h"
2019-02-21 01:05:33 +01:00
#include "script.h"
#include "script_menu.h"
#include "sound.h"
#include "string_util.h"
#include "strings.h"
#include "task.h"
#include "text.h"
2019-02-21 01:05:33 +01:00
#include "trig.h"
#include "tv.h"
#include "util.h"
#include "window.h"
#include "constants/event_objects.h"
2020-06-17 23:48:20 +02:00
#include "constants/field_specials.h"
#include "constants/game_stat.h"
#include "constants/rgb.h"
#include "constants/songs.h"
2019-03-02 04:32:50 +01:00
#include "contest.h"
2020-06-17 23:48:20 +02:00
enum {
SLIDING_TEXT_OFFSCREEN,
SLIDING_TEXT_ENTERING,
SLIDING_TEXT_ARRIVED,
SLIDING_TEXT_EXITING,
};
enum {
SLIDING_MON_ENTERED = 1,
SLIDING_MON_EXITED,
};
#define GET_CONTEST_WINNER_ID(i) { for ((i) = 0; (i) < CONTESTANT_COUNT && gContestFinalStandings[(i)] != 0; (i)++); }
2021-04-21 03:16:47 +02:00
// Gfx/pal tags for the text window sprites on the contest results screen.
// Both types of text windows are made up of 4 individual sprites
// These tags are used by the spritesheets, and implicitly in the loop in CreateResultsTextWindowSprites
#define TAG_TEXT_WINDOW_BASE 3009
enum {
TAG_RESULTS_TEXT_WINDOW_LEFT = TAG_TEXT_WINDOW_BASE,
TAG_RESULTS_TEXT_WINDOW_MIDLEFT,
TAG_RESULTS_TEXT_WINDOW_MIDRIGHT,
TAG_RESULTS_TEXT_WINDOW_RIGHT,
TAG_LINK_TEXT_WINDOW_LEFT,
TAG_LINK_TEXT_WINDOW_MIDLEFT,
TAG_LINK_TEXT_WINDOW_MIDRIGHT,
TAG_LINK_TEXT_WINDOW_RIGHT, // 3016
};
2020-06-17 09:39:03 +02:00
#define TAG_CONFETTI 3017
2021-04-21 03:16:47 +02:00
#define TAG_WIRELESS_INDICATOR_WINDOW 22222
2020-06-17 09:39:03 +02:00
2022-05-16 20:55:20 +02:00
// Length of the score bar on the results screen
#define NUM_BAR_SEGMENTS 11
#define BAR_SEGMENT_LENGTH 8 // Each segment of the results bar is a single tile, so 8 pixels long
#define MAX_BAR_LENGTH (NUM_BAR_SEGMENTS * BAR_SEGMENT_LENGTH)
2020-06-17 23:48:20 +02:00
2021-04-21 03:16:47 +02:00
// Starting x/y for the sliding results screen text box
#define TEXT_BOX_X (DISPLAY_WIDTH + 32)
#define TEXT_BOX_Y (DISPLAY_HEIGHT - 16)
2020-06-17 23:48:20 +02:00
struct ContestResultsInternal
{
u8 slidingTextBoxSpriteId;
u8 linkTextBoxSpriteId;
u8 showResultsTaskId;
u8 highlightWinnerTaskId;
u8 slidingTextBoxState;
u8 numStandingsPrinted;
u8 winnerMonSlidingState;
u8 confettiCount;
u8 winnerMonSpriteId;
bool8 destroyConfetti;
bool8 pointsFlashing;
2022-05-16 20:55:20 +02:00
s16 barLength[CONTESTANT_COUNT];
2020-06-17 23:48:20 +02:00
u8 numBarsUpdating;
};
2020-06-17 23:48:20 +02:00
struct ContestMonResults
2019-02-21 01:05:33 +01:00
{
2020-06-17 23:48:20 +02:00
int relativePreliminaryPoints;
int relativeRound2Points;
u32 barLengthPreliminary;
u32 barLengthRound2;
bool8 lostPoints;
u8 numStars;
u8 numHearts;
2019-02-21 01:05:33 +01:00
};
2020-06-17 23:48:20 +02:00
struct ContestResults
{
2020-06-17 23:48:20 +02:00
struct ContestResultsInternal *data;
struct ContestMonResults (*monResults)[CONTESTANT_COUNT];
u8 *unusedBg; // Allocated/freed, never used
u8 *tilemapBuffers[4];
u8 *unused; // Allocated/freed, never used
};
2020-06-17 23:48:20 +02:00
static EWRAM_DATA struct ContestResults *sContestResults = NULL;
2020-06-17 23:48:20 +02:00
static void LoadAllContestMonIconPalettes(void);
2021-04-21 03:16:47 +02:00
static void LoadContestResultsTitleBarTilemaps(void);
2020-06-17 23:48:20 +02:00
static u8 GetNumPreliminaryPoints(u8, bool8);
static s8 GetNumRound2Points(u8, bool8);
static void AddContestTextPrinter(int, u8 *, int);
static void AllocContestResults(void);
static void FreeContestResults(void);
2019-02-21 01:05:33 +01:00
static void LoadAllContestMonIcons(u8, u8);
2021-04-21 03:16:47 +02:00
static void CreateResultsTextWindowSprites(void);
2020-06-17 23:48:20 +02:00
static void TryCreateWirelessSprites(void);
static void Task_StartShowContestResults(u8 taskId);
static void CB2_StartShowContestResults(void);
static void Task_ShowContestResults(u8);
static void CB2_ShowContestResults(void);
static void VBlankCB_ShowContestResults(void);
static void Task_SlideContestResultsBg(u8);
static void Task_WaitForLinkPartnersBeforeResults(u8);
2020-08-14 01:10:23 +02:00
static void Task_CommunicateMonIdxsForResults(u8);
static void Task_WaitForLinkPartnerMonIdxs(u8);
2020-06-17 23:48:20 +02:00
static void Task_AnnouncePreliminaryResults(u8);
static void Task_FlashStarsAndHearts(u8);
static void Task_ShowPreliminaryResults(u8);
static void Task_AnnounceRound2Results(u8);
static void Task_ShowRound2Results(u8);
static void Task_AnnounceWinner(u8);
static void Task_DrawFinalStandingNumber(u8);
static void Task_StartHighlightWinnersBox(u8);
static void Task_HighlightWinnersBox(u8);
static void Task_ShowWinnerMonBanner(u8);
static void Task_SetSeenWinnerMon(u8);
static void Task_TryDisconnectLinkPartners(u8);
static void Task_WaitForLinkPartnersDisconnect(u8);
static void Task_TrySetContestInterviewData(u8);
static void Task_EndShowContestResults(u8);
static void CalculateContestantsResultData(void);
static void ShowLinkResultsTextBox(const u8 *);
static void HideLinkResultsTextBox(void);
static s32 DrawResultsTextWindow(const u8 *, u8);
static void StartTextBoxSlideIn(s16, u16, u16, u16);
static void UpdateContestResultBars(bool8, u8);
static void Task_UpdateContestResultBar(u8);
static void StartTextBoxSlideOut(u16);
static void BounceMonIconInBox(u8, u8);
static void Task_BounceMonIconInBox(u8);
static void SpriteCB_WinnerMonSlideIn(struct Sprite *);
static void SpriteCB_WinnerMonSlideOut(struct Sprite *);
static void Task_CreateConfetti(u8);
static void SpriteCB_TextBoxSlideIn(struct Sprite *);
static void SpriteCB_TextBoxSlideOut(struct Sprite *);
static void SpriteCB_EndTextBoxSlideIn(struct Sprite *);
2020-08-13 09:09:47 +02:00
static void Task_StartCommunication(u8);
static void Task_StartCommunicateRngRS(u8);
static void Task_StartCommunicateLeaderIdsRS(u8);
static void Task_StartCommunicateCategoryRS(u8);
static void Task_LinkContest_SetUpContestRS(u8);
static void Task_LinkContest_CalculateTurnOrderRS(u8);
static void Task_LinkContest_Disconnect(u8);
static void Task_LinkContest_WaitDisconnect(u8);
2020-06-17 09:39:03 +02:00
static void SpriteCB_Confetti(struct Sprite *sprite);
static void Task_ShowContestEntryMonPic(u8 taskId);
static void Task_LinkContestWaitForConnection(u8 taskId);
2021-04-21 03:16:47 +02:00
static const u16 sResultsTextWindow_Pal[] = INCBIN_U16("graphics/contest/results_screen/text_window.gbapal");
static const u8 sResultsTextWindow_Gfx[] = INCBIN_U8("graphics/contest/results_screen/text_window.4bpp");
2020-02-08 18:20:05 +01:00
static const u16 sMiscBlank_Pal[] = INCBIN_U16("graphics/interface/blank.gbapal");
2021-04-21 03:16:47 +02:00
static const struct OamData sOamData_ResultsTextWindow =
2020-02-08 18:20:05 +01:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2022-07-30 03:27:39 +02:00
.mosaic = FALSE,
2020-02-08 18:20:05 +01:00
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(64x32),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(64x32),
.tileNum = 0,
.priority = 3,
.paletteNum = 2,
.affineParam = 0,
};
2021-04-21 03:16:47 +02:00
static const struct SpriteTemplate sSpriteTemplate_ResultsTextWindow =
2020-09-02 15:49:04 +02:00
{
2021-04-21 03:16:47 +02:00
.tileTag = TAG_TEXT_WINDOW_BASE,
.paletteTag = TAG_TEXT_WINDOW_BASE,
.oam = &sOamData_ResultsTextWindow,
2020-09-02 15:49:04 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-02-08 18:20:05 +01:00
.callback = SpriteCallbackDummy
};
2021-04-21 03:16:47 +02:00
static const struct SpriteSheet sSpriteSheets_ResultsTextWindow[] =
2020-02-08 18:20:05 +01:00
{
2021-04-21 03:16:47 +02:00
{ .data = gMiscBlank_Gfx, .size = 0x400, .tag = TAG_RESULTS_TEXT_WINDOW_LEFT },
{ .data = gMiscBlank_Gfx, .size = 0x400, .tag = TAG_RESULTS_TEXT_WINDOW_MIDLEFT },
{ .data = gMiscBlank_Gfx, .size = 0x400, .tag = TAG_RESULTS_TEXT_WINDOW_MIDRIGHT },
{ .data = gMiscBlank_Gfx, .size = 0x400, .tag = TAG_RESULTS_TEXT_WINDOW_RIGHT },
{ .data = gMiscBlank_Gfx, .size = 0x400, .tag = TAG_LINK_TEXT_WINDOW_LEFT },
{ .data = gMiscBlank_Gfx, .size = 0x400, .tag = TAG_LINK_TEXT_WINDOW_MIDLEFT },
{ .data = gMiscBlank_Gfx, .size = 0x400, .tag = TAG_LINK_TEXT_WINDOW_MIDRIGHT },
{ .data = gMiscBlank_Gfx, .size = 0x400, .tag = TAG_LINK_TEXT_WINDOW_RIGHT },
2020-02-08 18:20:05 +01:00
};
2021-04-21 03:16:47 +02:00
static const struct SpritePalette sSpritePalette_ResultsTextWindow =
2020-02-08 18:20:05 +01:00
{
.data = sMiscBlank_Pal,
2021-04-21 03:16:47 +02:00
.tag = TAG_TEXT_WINDOW_BASE,
2020-02-08 18:20:05 +01:00
};
2020-06-17 09:39:03 +02:00
static const struct OamData sOamData_Confetti =
2020-02-08 18:20:05 +01:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2022-07-30 03:27:39 +02:00
.mosaic = FALSE,
2020-02-08 18:20:05 +01:00
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(8x8),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(8x8),
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
.affineParam = 0,
};
2020-06-17 09:39:03 +02:00
static const struct SpriteTemplate sSpriteTemplate_Confetti =
2020-02-08 18:20:05 +01:00
{
2020-09-02 15:49:04 +02:00
.tileTag = TAG_CONFETTI,
.paletteTag = TAG_CONFETTI,
.oam = &sOamData_Confetti,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-06-17 09:39:03 +02:00
.callback = SpriteCB_Confetti
2020-02-08 18:20:05 +01:00
};
2020-06-17 09:39:03 +02:00
static const struct CompressedSpriteSheet sSpriteSheet_Confetti =
2020-02-08 18:20:05 +01:00
{
2020-09-02 15:49:04 +02:00
.data = gConfetti_Gfx,
.size = 0x220,
2020-06-17 09:39:03 +02:00
.tag = TAG_CONFETTI
2020-02-08 18:20:05 +01:00
};
2020-06-17 09:39:03 +02:00
static const struct CompressedSpritePalette sSpritePalette_Confetti =
2020-02-08 18:20:05 +01:00
{
2020-09-02 15:49:04 +02:00
.data = gConfetti_Pal,
2020-06-17 09:39:03 +02:00
.tag = TAG_CONFETTI
2020-02-08 18:20:05 +01:00
};
2020-06-17 23:48:20 +02:00
static const struct BgTemplate sBgTemplates[] =
2020-02-08 18:20:05 +01:00
{
{
.bg = 0,
.charBaseIndex = 0,
.mapBaseIndex = 30,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0,
},
{
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 24,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0,
2020-09-02 15:49:04 +02:00
},
2020-02-08 18:20:05 +01:00
{
.bg = 2,
.charBaseIndex = 0,
.mapBaseIndex = 28,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0,
2020-09-02 15:49:04 +02:00
},
2020-02-08 18:20:05 +01:00
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 26,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0,
}
};
2020-06-17 23:48:20 +02:00
static const struct WindowTemplate sWindowTemplates[] =
2020-02-08 18:20:05 +01:00
{
{
2020-09-02 15:49:04 +02:00
.bg = 1,
.tilemapLeft = 7,
.tilemapTop = 4,
.width = 12,
.height = 2,
.paletteNum = 15,
2020-02-08 18:20:05 +01:00
.baseBlock = 770
},
{
2020-09-02 15:49:04 +02:00
.bg = 1,
.tilemapLeft = 7,
.tilemapTop = 7,
.width = 12,
.height = 2,
.paletteNum = 15,
2020-02-08 18:20:05 +01:00
.baseBlock = 794
},
{
2020-09-02 15:49:04 +02:00
.bg = 1,
.tilemapLeft = 7,
.tilemapTop = 10,
.width = 12,
.height = 2,
.paletteNum = 15,
2020-02-08 18:20:05 +01:00
.baseBlock = 818
},
{
2020-09-02 15:49:04 +02:00
.bg = 1,
.tilemapLeft = 7,
.tilemapTop = 13,
.width = 12,
.height = 2,
.paletteNum = 15,
2020-02-08 18:20:05 +01:00
.baseBlock = 842
},
DUMMY_WIN_TEMPLATE,
};
2021-04-21 03:16:47 +02:00
static const struct OamData sOamData_WirelessIndicatorWindow =
2020-02-08 18:20:05 +01:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2022-07-30 03:27:39 +02:00
.mosaic = FALSE,
2020-02-08 18:20:05 +01:00
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(16x16),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(16x16),
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
.affineParam = 0,
};
2021-04-21 03:16:47 +02:00
static const struct SpriteTemplate sSpriteTemplate_WirelessIndicatorWindow =
2020-02-08 18:20:05 +01:00
{
2021-04-21 03:16:47 +02:00
.tileTag = TAG_WIRELESS_INDICATOR_WINDOW,
2020-09-02 15:49:04 +02:00
.paletteTag = 0,
2021-04-21 03:16:47 +02:00
.oam = &sOamData_WirelessIndicatorWindow,
2020-09-02 15:49:04 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-02-08 18:20:05 +01:00
.callback = SpriteCallbackDummy
};
2021-04-21 03:16:47 +02:00
static const struct SpriteSheet sSpriteSheet_WirelessIndicatorWindow =
2020-02-08 18:20:05 +01:00
{
2020-09-02 15:49:04 +02:00
.data = gMiscBlank_Gfx,
.size = 0x200,
2021-04-21 03:16:47 +02:00
.tag = TAG_WIRELESS_INDICATOR_WINDOW
2020-02-08 18:20:05 +01:00
};
static const u8 sContestLinkTextColors[4] = {TEXT_COLOR_WHITE, TEXT_DYNAMIC_COLOR_6, TEXT_DYNAMIC_COLOR_5};
2020-06-17 23:48:20 +02:00
static void InitContestResultsDisplay(void)
{
int i;
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP);
ResetBgsAndClearDma3BusyFlags(0);
2020-06-17 23:48:20 +02:00
InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates));
for (i = 0; i < (int)ARRAY_COUNT(sContestResults->tilemapBuffers); i++)
SetBgTilemapBuffer(i, sContestResults->tilemapBuffers[i]);
2019-02-02 12:44:00 +01:00
2020-06-17 23:48:20 +02:00
InitWindows(sWindowTemplates);
DeactivateAllTextPrinters();
SetGpuReg(REG_OFFSET_MOSAIC, 0);
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
SetGpuReg(REG_OFFSET_WIN0H, 0);
SetGpuReg(REG_OFFSET_WIN0V, 0);
SetGpuReg(REG_OFFSET_WIN1H, 0);
SetGpuReg(REG_OFFSET_WIN1V, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
SetGpuReg(REG_OFFSET_BG1HOFS, 0);
SetGpuReg(REG_OFFSET_BG1VOFS, 0);
SetGpuReg(REG_OFFSET_BG2HOFS, 0);
SetGpuReg(REG_OFFSET_BG2VOFS, 0);
SetGpuReg(REG_OFFSET_BG3HOFS, 0);
SetGpuReg(REG_OFFSET_BG3VOFS, 0);
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJWIN_ON);
gBattle_BG0_X = 0;
gBattle_BG0_Y = 0;
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
gBattle_BG3_X = 0;
gBattle_BG3_Y = 0;
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
gBattle_WIN1H = 0;
gBattle_WIN1V = 0;
}
2020-06-17 23:48:20 +02:00
static void LoadContestResultsBgGfx(void)
{
int i, j;
2020-06-17 23:48:20 +02:00
s8 numStars, round2Points;
u16 tile1, tile2;
2020-06-17 23:48:20 +02:00
LZDecompressVram(gContestResults_Gfx, (void *)BG_CHAR_ADDR(0));
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBuffer(3, gContestResults_Bg_Tilemap, 0, 0);
CopyToBgTilemapBuffer(2, gContestResults_Interface_Tilemap, 0, 0);
CopyToBgTilemapBuffer(0, gContestResults_WinnerBanner_Tilemap, 0, 0);
LoadContestResultsTitleBarTilemaps();
2020-06-17 23:48:20 +02:00
LoadCompressedPalette(gContestResults_Pal, 0, 0x200);
2021-04-21 03:16:47 +02:00
LoadPalette(sResultsTextWindow_Pal, 0xF0, sizeof(sResultsTextWindow_Pal));
2020-06-17 23:48:20 +02:00
for (i = 0; i < CONTESTANT_COUNT; i++)
{
2020-06-17 23:48:20 +02:00
numStars = GetNumPreliminaryPoints(i, TRUE);
round2Points = GetNumRound2Points(i, TRUE);
for (j = 0; j < 10; j++)
{
tile1 = 0x60B2;
2020-06-17 23:48:20 +02:00
if (j < numStars)
tile1 += 2;
2020-06-17 23:48:20 +02:00
// Abs of round2Points is number of hearts
if (j < abs(round2Points))
{
tile2 = 0x60A4;
2020-06-17 23:48:20 +02:00
if (round2Points < 0)
tile2 += 2;
}
else
{
tile2 = 0x60A2;
}
FillBgTilemapBufferRect_Palette0(1, tile1, j + 19, i * 3 + 5, 1, 1);
FillBgTilemapBufferRect_Palette0(1, tile2, j + 19, i * 3 + 6, 1, 1);
}
}
CopyBgTilemapBufferToVram(0);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
ShowBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
}
2020-06-17 23:48:20 +02:00
static void LoadContestMonName(u8 monIndex)
{
struct ContestPokemon *mon = &gContestMons[monIndex];
u8 *str = gDisplayedStringBattle;
if (monIndex == gContestPlayerMonIndex)
str = StringCopy(gDisplayedStringBattle, gText_ColorDarkGray);
StringCopy(str, mon->nickname);
2020-06-17 23:48:20 +02:00
AddContestTextPrinter(monIndex, gDisplayedStringBattle, 0);
StringCopy(str, gText_Slash);
StringAppend(str, mon->trainerName);
2020-06-17 23:48:20 +02:00
AddContestTextPrinter(monIndex, gDisplayedStringBattle, 50);
}
2020-06-17 23:48:20 +02:00
static void LoadAllContestMonNames(void)
{
int i;
2019-11-11 03:54:00 +01:00
for (i = 0; i < CONTESTANT_COUNT; i++)
2020-06-17 23:48:20 +02:00
LoadContestMonName(i);
CopyBgTilemapBufferToVram(1);
}
2020-06-17 23:48:20 +02:00
static void CB2_StartShowContestResults(void)
{
2020-06-17 23:48:20 +02:00
gPaletteFade.bufferTransferDisabled = TRUE;
SetVBlankCallback(NULL);
2020-06-17 23:48:20 +02:00
AllocContestResults();
InitContestResultsDisplay();
ScanlineEffect_Clear();
ResetPaletteFade();
ResetSpriteData();
ResetTasks();
FreeAllSpritePalettes();
2020-06-17 23:48:20 +02:00
LoadContestResultsBgGfx();
LoadAllContestMonIconPalettes();
LoadAllContestMonIcons(0, TRUE);
LoadAllContestMonNames();
memset(sContestResults->data, 0, sizeof(*sContestResults->data));
memset(sContestResults->monResults, 0, sizeof(*sContestResults->monResults));
2021-04-21 03:16:47 +02:00
CreateResultsTextWindowSprites();
2020-06-17 23:48:20 +02:00
TryCreateWirelessSprites();
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
2020-06-17 23:48:20 +02:00
gPaletteFade.bufferTransferDisabled = FALSE;
sContestResults->data->showResultsTaskId = CreateTask(Task_ShowContestResults, 5);
SetMainCallback2(CB2_ShowContestResults);
2021-04-15 08:04:01 +02:00
gBattle_WIN1H = WIN_RANGE(0, DISPLAY_WIDTH);
2021-04-21 03:16:47 +02:00
gBattle_WIN1V = WIN_RANGE(DISPLAY_HEIGHT - 32, DISPLAY_HEIGHT);
2020-06-17 23:48:20 +02:00
CreateTask(Task_SlideContestResultsBg, 20);
CalculateContestantsResultData();
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)
2020-06-17 23:48:20 +02:00
gPaletteFade.bufferTransferDisabled = TRUE;
else
2020-08-21 00:02:00 +02:00
PlayBGM(MUS_CONTEST_RESULTS);
2020-06-17 23:48:20 +02:00
SetVBlankCallback(VBlankCB_ShowContestResults);
}
2020-06-17 23:48:20 +02:00
static void CB2_ShowContestResults(void)
{
AnimateSprites();
BuildOamBuffer();
RunTasks();
UpdatePaletteFade();
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
}
2020-06-17 23:48:20 +02:00
static void VBlankCB_ShowContestResults(void)
{
SetGpuReg(REG_OFFSET_BG0HOFS, gBattle_BG0_X);
SetGpuReg(REG_OFFSET_BG0VOFS, gBattle_BG0_Y);
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
SetGpuReg(REG_OFFSET_BG2HOFS, gBattle_BG2_X);
SetGpuReg(REG_OFFSET_BG2VOFS, gBattle_BG2_Y);
SetGpuReg(REG_OFFSET_BG3HOFS, gBattle_BG3_X);
SetGpuReg(REG_OFFSET_BG3VOFS, gBattle_BG3_Y);
SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H);
SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V);
SetGpuReg(REG_OFFSET_WIN1H, gBattle_WIN1H);
SetGpuReg(REG_OFFSET_WIN1V, gBattle_WIN1V);
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
ScanlineEffect_InitHBlankDmaTransfer();
}
2020-06-17 23:48:20 +02:00
#define tState data[0]
#define tTimer data[1]
#define tCounter data[2]
static void Task_ShowContestResults(u8 taskId)
{
u16 var;
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
{
2020-06-17 23:48:20 +02:00
switch (gTasks[taskId].tState)
{
case 0:
SaveLinkContestResults();
if (gContestFinalStandings[gContestPlayerMonIndex] == 0)
{
IncrementGameStat(GAME_STAT_WON_LINK_CONTEST);
2020-06-17 23:48:20 +02:00
gSpecialVar_0x8005 = TVSHOW_CONTEST_LIVE_UPDATES;
InterviewBefore();
2020-06-17 23:48:20 +02:00
if (gSpecialVar_Result != TRUE)
InterviewAfter();
}
2020-06-17 23:48:20 +02:00
TryGainNewFanFromCounter(FANCOUNTER_FINISHED_CONTEST);
2021-04-22 02:04:12 +02:00
SaveContestWinner(gSpecialVar_ContestRank); // Save for lobby painting
SaveContestWinner(CONTEST_SAVE_FOR_ARTIST);
gCurContestWinnerIsForArtist = TRUE;
gCurContestWinnerSaveIdx = GetContestWinnerSaveIdx(CONTEST_SAVE_FOR_ARTIST, FALSE);
2019-11-11 03:54:00 +01:00
var = VarGet(VAR_CONTEST_HALL_STATE);
VarSet(VAR_CONTEST_HALL_STATE, 0);
SetContinueGameWarpStatusToDynamicWarp();
TrySavingData(SAVE_LINK);
ClearContinueGameWarpStatus2();
2019-11-11 03:54:00 +01:00
VarSet(VAR_CONTEST_HALL_STATE, var);
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
break;
case 1:
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS))
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState = 100;
break;
case 2:
if (IsLinkTaskFinished())
{
2020-08-13 09:09:47 +02:00
SetLinkStandbyCallback();
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
}
return;
case 3:
if (IsLinkTaskFinished() == TRUE)
{
2020-08-21 00:02:00 +02:00
PlayBGM(MUS_CONTEST_RESULTS);
2020-06-17 23:48:20 +02:00
gPaletteFade.bufferTransferDisabled = FALSE;
gTasks[taskId].tState++;
break;
}
return;
}
}
if (!gPaletteFade.active)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState = 0;
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
{
2020-06-17 23:48:20 +02:00
ShowLinkResultsTextBox(gText_CommunicationStandby);
gTasks[taskId].func = Task_WaitForLinkPartnersBeforeResults;
}
else
{
IncrementGameStat(GAME_STAT_ENTERED_CONTEST);
if (gContestFinalStandings[gContestPlayerMonIndex] == 0)
IncrementGameStat(GAME_STAT_WON_CONTEST);
2021-04-22 02:04:12 +02:00
SaveContestWinner(gSpecialVar_ContestRank); // Save for lobby painting
SaveContestWinner(CONTEST_SAVE_FOR_ARTIST);
gCurContestWinnerIsForArtist = TRUE;
gCurContestWinnerSaveIdx = GetContestWinnerSaveIdx(CONTEST_SAVE_FOR_ARTIST, FALSE);
2020-06-17 23:48:20 +02:00
TryGainNewFanFromCounter(FANCOUNTER_FINISHED_CONTEST);
gTasks[taskId].func = Task_AnnouncePreliminaryResults;
}
}
}
2020-06-17 23:48:20 +02:00
static void Task_WaitForLinkPartnersBeforeResults(u8 taskId)
{
if (gReceivedRemoteLinkPlayers)
{
2020-08-14 01:10:23 +02:00
CreateTask(Task_CommunicateMonIdxsForResults, 0);
gTasks[taskId].func = TaskDummy;
}
}
2020-08-14 01:10:23 +02:00
static void Task_CommunicateMonIdxsForResults(u8 taskId)
{
2020-08-14 01:10:23 +02:00
SetTaskFuncWithFollowupFunc(taskId, Task_LinkContest_CommunicateMonIdxs, Task_WaitForLinkPartnerMonIdxs);
}
2020-08-14 01:10:23 +02:00
static void Task_WaitForLinkPartnerMonIdxs(u8 taskId)
{
if (IsLinkTaskFinished())
{
DestroyTask(taskId);
2020-06-17 23:48:20 +02:00
gTasks[sContestResults->data->showResultsTaskId].func = Task_AnnouncePreliminaryResults;
HideLinkResultsTextBox();
}
}
2020-06-17 23:48:20 +02:00
static void Task_AnnouncePreliminaryResults(u8 taskId)
{
2020-06-17 23:48:20 +02:00
s16 x;
2020-06-17 23:48:20 +02:00
if (gTasks[taskId].tState == 0)
{
2020-06-17 23:48:20 +02:00
CreateTask(Task_FlashStarsAndHearts, 20);
x = DrawResultsTextWindow(gText_AnnouncingResults, sContestResults->data->slidingTextBoxSpriteId);
2021-04-21 03:16:47 +02:00
StartTextBoxSlideIn(x, TEXT_BOX_Y, 120, 1088);
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
}
2020-06-17 23:48:20 +02:00
else if (gTasks[taskId].tState == 1)
{
2020-06-17 23:48:20 +02:00
// Wait for "Announcing Results" text to leave
if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer = 0;
gTasks[taskId].tState++;
}
}
2020-06-17 23:48:20 +02:00
else if (gTasks[taskId].tState == 2)
{
2020-06-17 23:48:20 +02:00
if (++gTasks[taskId].tTimer == 21)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer = 0;
gTasks[taskId].tState++;
}
}
2020-06-17 23:48:20 +02:00
else if (gTasks[taskId].tState == 3)
{
2020-06-17 23:48:20 +02:00
x = DrawResultsTextWindow(gText_PreliminaryResults, sContestResults->data->slidingTextBoxSpriteId);
2021-04-21 03:16:47 +02:00
StartTextBoxSlideIn(x, TEXT_BOX_Y, -1, 1088);
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
}
2020-06-17 23:48:20 +02:00
else if (gTasks[taskId].tState == 4)
{
2020-06-17 23:48:20 +02:00
if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_ARRIVED)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState = 0;
gTasks[taskId].func = Task_ShowPreliminaryResults;
}
}
}
2020-06-17 23:48:20 +02:00
static void Task_ShowPreliminaryResults(u8 taskId)
{
2020-06-17 23:48:20 +02:00
switch (gTasks[taskId].tState)
{
case 0:
2020-06-17 23:48:20 +02:00
if (!sContestResults->data->pointsFlashing)
{
2020-06-17 23:48:20 +02:00
UpdateContestResultBars(FALSE, gTasks[taskId].tCounter++);
if (sContestResults->data->numBarsUpdating == 0)
gTasks[taskId].tState = 2;
else
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
}
break;
case 1:
2020-06-17 23:48:20 +02:00
if (sContestResults->data->numBarsUpdating == 0)
gTasks[taskId].tState = 0;
break;
case 2:
2020-06-17 23:48:20 +02:00
StartTextBoxSlideOut(1088);
gTasks[taskId].tState = 0;
gTasks[taskId].tCounter = 0;
gTasks[taskId].func = Task_AnnounceRound2Results;
break;
}
}
2020-06-17 23:48:20 +02:00
static void Task_AnnounceRound2Results(u8 taskId)
{
2020-06-17 23:48:20 +02:00
s16 x;
2020-06-17 23:48:20 +02:00
if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN)
{
2020-06-17 23:48:20 +02:00
if (++gTasks[taskId].tTimer == 21)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer = 0;
x = DrawResultsTextWindow(gText_Round2Results, sContestResults->data->slidingTextBoxSpriteId);
2021-04-21 03:16:47 +02:00
StartTextBoxSlideIn(x, TEXT_BOX_Y, -1, 1088);
}
}
2020-06-17 23:48:20 +02:00
else if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_ARRIVED)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].func = Task_ShowRound2Results;
}
}
2020-06-17 23:48:20 +02:00
static void Task_ShowRound2Results(u8 taskId)
{
2020-06-17 23:48:20 +02:00
switch (gTasks[taskId].tState)
{
case 0:
2020-06-17 23:48:20 +02:00
if (!sContestResults->data->pointsFlashing)
{
2020-06-17 23:48:20 +02:00
UpdateContestResultBars(TRUE, gTasks[taskId].tCounter++);
if (sContestResults->data->numBarsUpdating == 0)
gTasks[taskId].tState = 2;
else
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
}
break;
case 1:
2020-06-17 23:48:20 +02:00
if (sContestResults->data->numBarsUpdating == 0)
gTasks[taskId].tState = 0;
break;
case 2:
2020-06-17 23:48:20 +02:00
StartTextBoxSlideOut(1088);
gTasks[taskId].tState = 0;
gTasks[taskId].func = Task_AnnounceWinner;
break;
}
}
2020-06-17 23:48:20 +02:00
// Task data for Task_DrawFinalStandingNumber
#define tFinalStanding data[0]
#define tMonIndex data[1]
static void Task_AnnounceWinner(u8 taskId)
{
int i;
2020-06-17 23:48:20 +02:00
switch (gTasks[taskId].tState)
{
case 0:
2020-06-17 23:48:20 +02:00
if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN)
gTasks[taskId].tState++;
break;
case 1:
2020-06-17 23:48:20 +02:00
if (++gTasks[taskId].tTimer == 31)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer = 0;
gTasks[taskId].tState++;
}
break;
case 2:
2019-11-11 03:54:00 +01:00
for (i = 0; i < CONTESTANT_COUNT; i++)
{
2020-06-17 23:48:20 +02:00
u8 newTaskId = CreateTask(Task_DrawFinalStandingNumber, 10);
gTasks[newTaskId].tFinalStanding = gContestFinalStandings[i];
gTasks[newTaskId].tMonIndex = i;
}
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
break;
case 3:
2020-06-17 23:48:20 +02:00
if (sContestResults->data->numStandingsPrinted == CONTESTANT_COUNT)
{
2020-06-17 23:48:20 +02:00
if (++gTasks[taskId].tTimer == 31)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer = 0;
CreateTask(Task_StartHighlightWinnersBox, 10);
gTasks[taskId].tState++;
GET_CONTEST_WINNER_ID(i);
BounceMonIconInBox(i, 14);
}
}
break;
case 4:
2020-06-17 23:48:20 +02:00
if (++gTasks[taskId].tTimer == 21)
{
2020-06-17 23:48:20 +02:00
u8 winnerTextBuffer[100];
s16 x;
gTasks[taskId].tTimer = 0;
GET_CONTEST_WINNER_ID(i);
StringCopy(gStringVar1, gContestMons[i].trainerName);
2021-04-22 20:30:45 +02:00
ConvertInternationalContestantName(gStringVar1);
StringCopy(gStringVar2, gContestMons[i].nickname);
2020-06-17 23:48:20 +02:00
StringExpandPlaceholders(winnerTextBuffer, gText_ContestantsMonWon);
x = DrawResultsTextWindow(winnerTextBuffer, sContestResults->data->slidingTextBoxSpriteId);
2021-04-21 03:16:47 +02:00
StartTextBoxSlideIn(x, TEXT_BOX_Y, -1, 1088);
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
}
break;
case 5:
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState = 0;
gTasks[taskId].func = Task_ShowWinnerMonBanner;
break;
}
}
2020-06-17 23:48:20 +02:00
static void Task_ShowWinnerMonBanner(u8 taskId)
{
int i;
u8 spriteId;
u16 species;
u32 otId;
u32 personality;
const struct CompressedSpritePalette *pokePal;
2020-06-17 23:48:20 +02:00
switch (gTasks[taskId].tState)
{
case 0:
2021-04-15 08:04:01 +02:00
gBattle_WIN0H = WIN_RANGE(0, DISPLAY_WIDTH);
gBattle_WIN0V = WIN_RANGE(DISPLAY_HEIGHT / 2, DISPLAY_HEIGHT / 2);
2020-06-17 23:48:20 +02:00
GET_CONTEST_WINNER_ID(i);
species = gContestMons[i].species;
personality = gContestMons[i].personality;
otId = gContestMons[i].otId;
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT],
species,
personality);
pokePal = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
LoadCompressedSpritePalette(pokePal);
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT);
gMultiuseSpriteTemplate.paletteTag = pokePal->tag;
2021-04-21 03:16:47 +02:00
spriteId = CreateSprite(&gMultiuseSpriteTemplate, DISPLAY_WIDTH + 32, DISPLAY_HEIGHT / 2, 10);
gSprites[spriteId].data[1] = species;
gSprites[spriteId].oam.priority = 0;
2020-06-17 23:48:20 +02:00
gSprites[spriteId].callback = SpriteCB_WinnerMonSlideIn;
sContestResults->data->winnerMonSpriteId = spriteId;
2020-06-17 09:39:03 +02:00
LoadCompressedSpriteSheet(&sSpriteSheet_Confetti);
LoadCompressedSpritePalette(&sSpritePalette_Confetti);
2020-06-17 23:48:20 +02:00
CreateTask(Task_CreateConfetti, 10);
gTasks[taskId].tState++;
break;
case 1:
if (++gTasks[taskId].data[3] == 1)
{
u8 counter;
gTasks[taskId].data[3] = 0;
2020-06-17 23:48:20 +02:00
gTasks[taskId].tCounter += 2;
if (gTasks[taskId].tCounter > 32)
gTasks[taskId].tCounter = 32;
2020-06-17 23:48:20 +02:00
counter = gTasks[taskId].tCounter;
2021-04-15 08:04:01 +02:00
gBattle_WIN0V = WIN_RANGE(DISPLAY_HEIGHT / 2 - counter, DISPLAY_HEIGHT / 2 + counter);
if (counter == 32)
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
}
break;
case 2:
2020-06-17 23:48:20 +02:00
if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_ENTERED)
gTasks[taskId].tState++;
break;
case 3:
2020-06-17 23:48:20 +02:00
if (++gTasks[taskId].tTimer == 121)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer = 0;
gSprites[sContestResults->data->winnerMonSpriteId].callback = SpriteCB_WinnerMonSlideOut;
gTasks[taskId].tState++;
}
break;
case 4:
2020-06-17 23:48:20 +02:00
if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_EXITED)
{
u8 top = (gBattle_WIN0V >> 8);
top += 2;
2021-04-15 08:04:01 +02:00
if (top > DISPLAY_HEIGHT / 2)
top = DISPLAY_HEIGHT / 2;
2021-04-15 08:04:01 +02:00
gBattle_WIN0V = WIN_RANGE(top, DISPLAY_HEIGHT - top);
if (top == DISPLAY_HEIGHT / 2)
2020-06-17 23:48:20 +02:00
gTasks[taskId].tState++;
}
break;
case 5:
2020-06-17 23:48:20 +02:00
if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_EXITED)
{
2020-06-17 23:48:20 +02:00
sContestResults->data->destroyConfetti = TRUE;
gTasks[taskId].tState = 0;
gTasks[taskId].func = Task_SetSeenWinnerMon;
}
break;
}
}
2020-06-17 23:48:20 +02:00
static void Task_SetSeenWinnerMon(u8 taskId)
{
2019-07-30 13:48:12 +02:00
int i, nationalDexNum;
2020-06-17 23:48:20 +02:00
if (JOY_NEW(A_BUTTON))
{
if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK))
{
2019-11-11 03:54:00 +01:00
for (i = 0; i < CONTESTANT_COUNT; i++)
{
nationalDexNum = SpeciesToNationalPokedexNum(gContestMons[i].species);
GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN);
2019-02-02 12:44:00 +01:00
}
}
gTasks[taskId].data[10] = 0;
2020-06-17 23:48:20 +02:00
gTasks[taskId].func = Task_TryDisconnectLinkPartners;
}
}
2020-06-17 23:48:20 +02:00
static void Task_TryDisconnectLinkPartners(u8 taskId)
{
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
{
if (!gTasks[taskId].data[10])
{
2020-06-17 23:48:20 +02:00
ShowLinkResultsTextBox(gText_CommunicationStandby);
2020-08-13 09:09:47 +02:00
SetCloseLinkCallback();
2020-06-17 23:48:20 +02:00
gTasks[taskId].func = Task_WaitForLinkPartnersDisconnect;
}
}
else
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].func = Task_TrySetContestInterviewData;
}
}
2020-06-17 23:48:20 +02:00
static void Task_WaitForLinkPartnersDisconnect(u8 taskId)
{
if (!gReceivedRemoteLinkPlayers)
{
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)
2019-04-01 00:59:52 +02:00
DestroyWirelessStatusIndicatorSprite();
2020-06-17 23:48:20 +02:00
HideLinkResultsTextBox();
gTasks[taskId].func = Task_TrySetContestInterviewData;
}
}
2020-06-17 23:48:20 +02:00
static void Task_TrySetContestInterviewData(u8 taskId)
{
if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK))
BravoTrainerPokemonProfile_BeforeInterview2(gContestFinalStandings[gContestPlayerMonIndex]);
2019-02-02 12:44:00 +01:00
BeginHardwarePaletteFade(0xFF, 0, 0, 16, 0);
2020-06-17 23:48:20 +02:00
gTasks[taskId].func = Task_EndShowContestResults;
}
2020-06-17 23:48:20 +02:00
static void Task_EndShowContestResults(u8 taskId)
{
if (!gPaletteFade.active)
{
2020-06-17 23:48:20 +02:00
if (gTasks[taskId].tTimer == 0)
{
2020-06-17 23:48:20 +02:00
DestroyTask(sContestResults->data->highlightWinnerTaskId);
2021-02-24 17:01:02 +01:00
BlendPalettes(PALETTES_BG, 16, RGB_BLACK);
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer++;
}
2020-06-17 23:48:20 +02:00
else if (gTasks[taskId].tTimer == 1)
{
2021-02-24 17:01:02 +01:00
BlendPalettes(PALETTES_OBJECTS, 16, RGB_BLACK);
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer++;
}
else
{
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
DestroyTask(taskId);
FreeAllWindowBuffers();
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
2020-06-17 23:48:20 +02:00
FreeContestResults();
}
}
}
2020-06-17 23:48:20 +02:00
#undef tState
#undef tTimer
#undef tCounter
static void Task_SlideContestResultsBg(u8 taskId)
{
gBattle_BG3_X += 2;
gBattle_BG3_Y += 1;
if (gBattle_BG3_X > 255)
gBattle_BG3_X -= 255;
if (gBattle_BG3_Y > 255)
gBattle_BG3_Y -= 255;
}
2020-06-17 23:48:20 +02:00
#define tDelay data[0]
#define tCoeff data[1]
#define tDecreasing data[2]
static void Task_FlashStarsAndHearts(u8 taskId)
{
2020-06-17 23:48:20 +02:00
if (++gTasks[taskId].tDelay == 2)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tDelay = 0;
if (!gTasks[taskId].tDecreasing)
gTasks[taskId].tCoeff++;
else
2020-06-17 23:48:20 +02:00
gTasks[taskId].tCoeff--;
2020-06-17 23:48:20 +02:00
if (gTasks[taskId].tCoeff == 16)
gTasks[taskId].tDecreasing = TRUE;
else if (gTasks[taskId].tCoeff == 0)
gTasks[taskId].tDecreasing = FALSE;
2020-06-17 23:48:20 +02:00
BlendPalette(0x6B, 1, gTasks[taskId].tCoeff, RGB(30, 22, 11));
BlendPalette(0x68, 1, gTasks[taskId].tCoeff, RGB_WHITE);
BlendPalette(0x6E, 1, gTasks[taskId].tCoeff, RGB(30, 29, 29));
}
2020-06-17 23:48:20 +02:00
if (gTasks[taskId].tCoeff == 0)
sContestResults->data->pointsFlashing = FALSE;
else
2020-06-17 23:48:20 +02:00
sContestResults->data->pointsFlashing = TRUE;
}
2020-06-17 23:48:20 +02:00
static void LoadContestMonIcon(u16 species, u8 monIndex, u8 srcOffset, u8 useDmaNow, u32 personality)
{
const u8 *iconPtr;
2020-12-22 07:39:19 +01:00
u16 var0, var1;
2020-12-22 07:39:19 +01:00
iconPtr = GetMonIconPtr(species, personality);
2019-02-21 01:05:33 +01:00
iconPtr += srcOffset * 0x200 + 0x80;
if (useDmaNow)
{
RequestDma3Copy(iconPtr, (void *)BG_CHAR_ADDR(1) + monIndex * 0x200, 0x180, 1);
var0 = ((monIndex + 10) << 12);
var1 = (monIndex * 0x10 + 0x200);
WriteSequenceToBgTilemapBuffer(1, var1 | var0, 3, monIndex * 3 + 4, 4, 3, 17, 1);
}
else
{
RequestDma3Copy(iconPtr, (void *)BG_CHAR_ADDR(1) + monIndex * 0x200, 0x180, 1);
}
}
2020-06-17 23:48:20 +02:00
static void LoadAllContestMonIcons(u8 srcOffset, bool8 useDmaNow)
{
int i;
2019-11-11 03:54:00 +01:00
for (i = 0; i < CONTESTANT_COUNT; i++)
2020-06-17 23:48:20 +02:00
LoadContestMonIcon(gContestMons[i].species, i, srcOffset, useDmaNow, gContestMons[i].personality);
}
2020-06-17 23:48:20 +02:00
static void LoadAllContestMonIconPalettes(void)
{
2019-07-30 13:48:12 +02:00
int i, species;
2019-11-11 03:54:00 +01:00
for (i = 0; i < CONTESTANT_COUNT; i++)
{
2019-07-30 13:48:12 +02:00
species = gContestMons[i].species;
LoadPalette(gMonIconPalettes[gMonIconPaletteIndices[GetIconSpecies(species, 0)]], i * 0x10 + 0xA0, 0x20);
}
}
2020-06-17 23:48:20 +02:00
static void TryCreateWirelessSprites(void)
{
u16 sheet;
u8 spriteId;
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)
{
2019-04-04 23:05:46 +02:00
LoadWirelessStatusIndicatorSpriteGfx();
CreateWirelessStatusIndicatorSprite(8, 8);
gSprites[gWirelessStatusIndicatorSpriteId].subpriority = 1;
2021-04-21 03:16:47 +02:00
sheet = LoadSpriteSheet(&sSpriteSheet_WirelessIndicatorWindow);
RequestDma3Fill(0xFFFFFFFF, (void *)BG_CHAR_ADDR(4) + sheet * 0x20, 0x80, 1);
2021-04-21 03:16:47 +02:00
spriteId = CreateSprite(&sSpriteTemplate_WirelessIndicatorWindow, 8, 8, 0);
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_WINDOW;
}
}
2020-06-17 23:48:20 +02:00
static s32 DrawResultsTextWindow(const u8 *text, u8 spriteId)
2019-04-10 20:49:10 +02:00
{
u16 windowId;
2022-09-26 18:22:27 +02:00
int tileWidth;
int strWidth;
2019-04-10 20:49:10 +02:00
u8 *spriteTilePtrs[4];
u8 *dst;
2021-04-21 03:16:47 +02:00
struct WindowTemplate windowTemplate;
memset(&windowTemplate, 0, sizeof(windowTemplate));
2022-09-26 18:22:27 +02:00
windowTemplate.width = DISPLAY_TILE_WIDTH;
2021-04-21 03:16:47 +02:00
windowTemplate.height = 2;
windowId = AddWindow(&windowTemplate);
FillWindowPixelBuffer(windowId, PIXEL_FILL(1));
2019-04-10 20:49:10 +02:00
2022-09-26 18:22:27 +02:00
strWidth = GetStringWidth(FONT_NORMAL, text, 0);
tileWidth = (strWidth + 9) / 8;
if (tileWidth > DISPLAY_TILE_WIDTH)
tileWidth = DISPLAY_TILE_WIDTH;
2019-04-10 20:49:10 +02:00
2022-09-26 18:22:27 +02:00
AddTextPrinterParameterized3(windowId, FONT_NORMAL, (tileWidth * 8 - strWidth) / 2, 1, sContestLinkTextColors, TEXT_SKIP_DRAW, text);
{
s32 i;
struct Sprite *sprite;
const u8 *src, *windowTilesPtr;
2021-04-21 03:16:47 +02:00
windowTilesPtr = (u8 *)GetWindowAttribute(windowId, WINDOW_TILE_DATA);
src = (u8 *)sResultsTextWindow_Gfx;
sprite = &gSprites[spriteId];
2020-11-03 00:43:11 +01:00
spriteTilePtrs[0] = (u8 *)(sprite->oam.tileNum * 32 + OBJ_VRAM0);
2021-04-21 03:16:47 +02:00
for (i = 1; i < (int)ARRAY_COUNT(spriteTilePtrs); i++)
2022-07-29 16:52:35 +02:00
spriteTilePtrs[i] = (void *)(gSprites[sprite->data[i - 1]].oam.tileNum * 32 + OBJ_VRAM0);
2021-04-21 03:16:47 +02:00
for (i = 0; i < (int)ARRAY_COUNT(spriteTilePtrs); i++)
CpuFill32(0, spriteTilePtrs[i], 0x400);
dst = spriteTilePtrs[0];
CpuCopy32(src, dst, 0x20);
CpuCopy32(src + 128, dst + 0x100, 0x20);
CpuCopy32(src + 128, dst + 0x200, 0x20);
CpuCopy32(src + 64, dst + 0x300, 0x20);
2022-09-26 18:22:27 +02:00
for (i = 0; i < tileWidth; i++)
{
dst = &spriteTilePtrs[(i + 1) / 8][((i + 1) % 8) * 32];
CpuCopy32(src + 192, dst, 0x20);
CpuCopy32(windowTilesPtr, dst + 0x100, 0x20);
CpuCopy32(windowTilesPtr + 960, dst + 0x200, 0x20);
CpuCopy32(src + 224, dst + 0x300, 0x20);
windowTilesPtr += 0x20;
}
2019-04-10 20:49:10 +02:00
dst = &spriteTilePtrs[(i + 1) / 8][((i + 1) % 8) * 32];
CpuCopy32(src + 32, dst, 0x20);
CpuCopy32(src + 160, dst + 0x100, 0x20);
CpuCopy32(src + 160, dst + 0x200, 0x20);
CpuCopy32(src + 96, dst + 0x300, 0x20);
}
2019-04-10 20:49:10 +02:00
RemoveWindow(windowId);
2022-09-26 18:22:27 +02:00
return (DISPLAY_WIDTH - (tileWidth + 2) * 8) / 2;
2019-04-10 20:49:10 +02:00
}
2021-04-21 03:16:47 +02:00
static void CreateResultsTextWindowSprites(void)
{
int i;
struct SpriteTemplate template;
2021-04-21 03:16:47 +02:00
u8 spriteIds[ARRAY_COUNT(sSpriteSheets_ResultsTextWindow)];
2021-04-21 03:16:47 +02:00
template = sSpriteTemplate_ResultsTextWindow;
for (i = 0; i < (int)ARRAY_COUNT(sSpriteSheets_ResultsTextWindow); i++)
LoadSpriteSheet(&sSpriteSheets_ResultsTextWindow[i]);
2021-04-21 03:16:47 +02:00
LoadSpritePalette(&sSpritePalette_ResultsTextWindow);
2021-04-21 03:16:47 +02:00
// Create sprites for the two window types, each made up of 4 sprites
for (i = 0; i < (int)ARRAY_COUNT(sSpriteSheets_ResultsTextWindow); i++)
{
2021-04-21 03:16:47 +02:00
spriteIds[i] = CreateSprite(&template, TEXT_BOX_X, TEXT_BOX_Y, 10);
template.tileTag++;
}
2021-04-21 03:16:47 +02:00
// Save sprite ids of the sliding text box onto its leftmost sprite
gSprites[spriteIds[0]].data[0] = spriteIds[1];
gSprites[spriteIds[0]].data[1] = spriteIds[2];
gSprites[spriteIds[0]].data[2] = spriteIds[3];
2021-04-21 03:16:47 +02:00
// Save sprite ids of the link text box onto its leftmost sprite
gSprites[spriteIds[4]].data[0] = spriteIds[5];
gSprites[spriteIds[4]].data[1] = spriteIds[6];
gSprites[spriteIds[4]].data[2] = spriteIds[7];
2020-06-17 23:48:20 +02:00
sContestResults->data->slidingTextBoxSpriteId = spriteIds[0];
sContestResults->data->slidingTextBoxState = SLIDING_TEXT_OFFSCREEN;
sContestResults->data->linkTextBoxSpriteId = spriteIds[4];
HideLinkResultsTextBox();
}
2020-06-17 23:48:20 +02:00
#define sTargetX data[4]
#define sSlideOutTimer data[5]
#define sSlideIncrement data[6]
#define sDistance data[7]
// If slideOutTimer is -1, it will not automatically slide out
static void StartTextBoxSlideIn(s16 x, u16 y, u16 slideOutTimer, u16 slideIncrement)
{
2020-06-17 23:48:20 +02:00
struct Sprite *sprite = &gSprites[sContestResults->data->slidingTextBoxSpriteId];
2021-07-07 15:11:52 +02:00
sprite->x = TEXT_BOX_X;
sprite->y = y;
sprite->x2 = 0;
sprite->y2 = 0;
2020-06-17 23:48:20 +02:00
sprite->sTargetX = x + 32;
sprite->sSlideOutTimer = slideOutTimer;
sprite->sSlideIncrement = slideIncrement;
sprite->sDistance = 0;
sprite->callback = SpriteCB_TextBoxSlideIn;
sContestResults->data->slidingTextBoxState = SLIDING_TEXT_ENTERING;
}
2020-06-17 23:48:20 +02:00
static void StartTextBoxSlideOut(u16 slideIncrement)
{
2020-06-17 23:48:20 +02:00
struct Sprite *sprite = &gSprites[sContestResults->data->slidingTextBoxSpriteId];
2021-07-07 15:11:52 +02:00
sprite->x += sprite->x2;
sprite->y += sprite->y2;
sprite->y2 = 0;
sprite->x2 = 0;
2020-06-17 23:48:20 +02:00
sprite->sSlideIncrement = slideIncrement;
sprite->sDistance = 0;
sprite->callback = SpriteCB_TextBoxSlideOut;
sContestResults->data->slidingTextBoxState = SLIDING_TEXT_EXITING;
}
2020-06-17 23:48:20 +02:00
static void EndTextBoxSlideOut(struct Sprite *sprite)
{
2021-07-07 15:11:52 +02:00
sprite->x = TEXT_BOX_X;
sprite->y = TEXT_BOX_Y;
sprite->y2 = 0;
sprite->x2 = 0;
sprite->callback = SpriteCallbackDummy;
2020-06-17 23:48:20 +02:00
sContestResults->data->slidingTextBoxState = SLIDING_TEXT_OFFSCREEN;
}
2020-06-17 23:48:20 +02:00
static void SpriteCB_TextBoxSlideIn(struct Sprite *sprite)
{
int i;
2020-06-17 23:48:20 +02:00
s16 delta = sprite->sDistance + sprite->sSlideIncrement;
2021-07-07 15:11:52 +02:00
sprite->x -= delta >> 8;
2020-06-17 23:48:20 +02:00
sprite->sDistance += sprite->sSlideIncrement;
sprite->sDistance &= 0xFF;
// Prevent overshooting target
2021-07-07 15:11:52 +02:00
if (sprite->x < sprite->sTargetX)
sprite->x = sprite->sTargetX;
for (i = 0; i < 3; i++)
{
struct Sprite *sprite2 = &gSprites[sprite->data[i]];
2021-07-07 15:11:52 +02:00
sprite2->x = sprite->x + sprite->x2 + (i + 1) * 64;
}
2019-02-02 12:44:00 +01:00
2021-07-07 15:11:52 +02:00
if (sprite->x == sprite->sTargetX)
2020-06-17 23:48:20 +02:00
sprite->callback = SpriteCB_EndTextBoxSlideIn;
}
2020-06-17 23:48:20 +02:00
static void SpriteCB_EndTextBoxSlideIn(struct Sprite *sprite)
{
2020-06-17 23:48:20 +02:00
sContestResults->data->slidingTextBoxState = SLIDING_TEXT_ARRIVED;
if ((u16)sprite->sSlideOutTimer != 0xFFFF)
{
2020-06-17 23:48:20 +02:00
if (--sprite->sSlideOutTimer == -1)
StartTextBoxSlideOut(sprite->sSlideIncrement);
}
}
2020-06-17 23:48:20 +02:00
static void SpriteCB_TextBoxSlideOut(struct Sprite *sprite)
{
int i;
2019-07-30 13:48:12 +02:00
s16 delta;
2020-06-17 23:48:20 +02:00
delta = sprite->sDistance + sprite->sSlideIncrement;
2021-07-07 15:11:52 +02:00
sprite->x -= delta >> 8;
2020-06-17 23:48:20 +02:00
sprite->sDistance += sprite->sSlideIncrement;
sprite->sDistance &= 0xFF;
for (i = 0; i < 3; i++)
{
struct Sprite *sprite2 = &gSprites[sprite->data[i]];
2021-07-07 15:11:52 +02:00
sprite2->x = sprite->x + sprite->x2 + (i + 1) * 64;
}
2021-07-07 15:11:52 +02:00
if (sprite->x + sprite->x2 < -224)
2020-06-17 23:48:20 +02:00
EndTextBoxSlideOut(sprite);
}
2020-06-17 23:48:20 +02:00
static void ShowLinkResultsTextBox(const u8 *text)
{
int i;
u16 x;
struct Sprite *sprite;
2020-06-17 23:48:20 +02:00
x = DrawResultsTextWindow(text, sContestResults->data->linkTextBoxSpriteId);
sprite = &gSprites[sContestResults->data->linkTextBoxSpriteId];
2021-07-07 15:11:52 +02:00
sprite->x = x + 32;
sprite->y = 80;
2020-06-17 23:48:20 +02:00
sprite->invisible = FALSE;
for (i = 0; i < 3; i++)
{
2021-07-07 15:11:52 +02:00
gSprites[sprite->data[i]].x = sprite->x + sprite->x2 + (i + 1) * 64;
gSprites[sprite->data[i]].y = sprite->y;
2020-06-17 23:48:20 +02:00
gSprites[sprite->data[i]].invisible = FALSE;
}
2021-04-15 08:04:01 +02:00
gBattle_WIN0H = WIN_RANGE(0, DISPLAY_WIDTH);
2021-07-07 15:11:52 +02:00
gBattle_WIN0V = WIN_RANGE(sprite->y - 16, sprite->y + 16);
SetGpuReg(REG_OFFSET_WININ, WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR
| WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3 | WININ_WIN0_OBJ | WININ_WIN0_CLR);
}
2020-06-17 23:48:20 +02:00
static void HideLinkResultsTextBox(void)
{
int i;
struct Sprite *sprite;
2020-06-17 23:48:20 +02:00
sprite = &gSprites[sContestResults->data->linkTextBoxSpriteId];
sprite->invisible = TRUE;
for (i = 0; i < 3; i++)
2020-06-17 23:48:20 +02:00
gSprites[sprite->data[i]].invisible = TRUE;
2019-02-02 12:44:00 +01:00
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H);
SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V);
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR
| WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
}
2021-04-21 03:16:47 +02:00
static void LoadContestResultsTitleBarTilemaps(void)
{
u8 palette;
int x, y;
x = 5;
y = 1;
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
{
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Link_Tilemap, 5, 1, 5, 2);
x = 10;
}
2019-11-11 03:54:00 +01:00
else if (gSpecialVar_ContestRank == CONTEST_RANK_NORMAL)
{
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Normal_Tilemap, 5, 1, 10, 2);
x = 15;
}
2019-11-11 03:54:00 +01:00
else if (gSpecialVar_ContestRank == CONTEST_RANK_SUPER)
{
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Super_Tilemap, 5, 1, 10, 2);
x = 15;
}
2019-11-11 03:54:00 +01:00
else if (gSpecialVar_ContestRank == CONTEST_RANK_HYPER)
{
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Hyper_Tilemap, 5, 1, 10, 2);
x = 15;
}
2019-11-11 03:54:00 +01:00
else // CONTEST_RANK_MASTER
{
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Master_Tilemap, 5, 1, 10, 2);
x = 15;
}
2019-11-11 03:54:00 +01:00
if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_COOL)
{
palette = 0;
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Cool_Tilemap, x, y, 5, 2);
}
2019-11-11 03:54:00 +01:00
else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_BEAUTY)
{
palette = 1;
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Beauty_Tilemap, x, y, 5, 2);
}
2019-11-11 03:54:00 +01:00
else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_CUTE)
{
palette = 2;
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Cute_Tilemap, x, y, 5, 2);
}
2019-11-11 03:54:00 +01:00
else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_SMART)
{
palette = 3;
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Smart_Tilemap, x, y, 5, 2);
}
2019-11-11 03:54:00 +01:00
else // CONTEST_CATEGORY_TOUGH
{
palette = 4;
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Tough_Tilemap, x, y, 5, 2);
}
x += 5;
2021-04-21 03:16:47 +02:00
CopyToBgTilemapBufferRect(2, gContestResultsTitle_Tilemap, x, y, 6, 2);
2020-06-17 23:48:20 +02:00
CopyToBgTilemapBufferRect_ChangePalette(2, sContestResults->tilemapBuffers[2], 0, 0, 32, 4, palette);
}
2020-06-17 23:48:20 +02:00
// Represented on results board as stars
static u8 GetNumPreliminaryPoints(u8 monIndex, bool8 capPoints)
{
2020-07-24 06:14:53 +02:00
u32 condition = gContestMonRound1Points[monIndex] << 16;
2020-06-17 23:48:20 +02:00
u32 numStars = condition / 0x3F;
2020-06-17 23:48:20 +02:00
if (numStars & 0xFFFF)
numStars += 0x10000;
2020-06-17 23:48:20 +02:00
numStars >>= 16;
if (numStars == 0 && condition)
numStars = 1;
2020-06-17 23:48:20 +02:00
if (capPoints && numStars > 10)
numStars = 10;
2020-06-17 23:48:20 +02:00
return numStars;
}
2020-06-17 23:48:20 +02:00
// Represented on results board as hearts
static s8 GetNumRound2Points(u8 monIndex, bool8 capPoints)
{
2020-06-17 23:48:20 +02:00
u32 r4, numHearts;
s16 results;
s8 points;
2020-06-17 23:48:20 +02:00
results = gContestMonRound2Points[monIndex];
if (results < 0)
r4 = -results << 16;
else
2020-06-17 23:48:20 +02:00
r4 = results << 16;
2020-06-17 23:48:20 +02:00
numHearts = r4 / 80;
if (numHearts & 0xFFFF)
numHearts += 0x10000;
2020-06-17 23:48:20 +02:00
numHearts >>= 16;
if (numHearts == 0 && r4 != 0)
numHearts = 1;
2020-06-17 23:48:20 +02:00
if (capPoints && numHearts > 10)
numHearts = 10;
2020-06-17 23:48:20 +02:00
if (gContestMonRound2Points[monIndex] < 0)
points = -numHearts;
else
2020-06-17 23:48:20 +02:00
points = numHearts;
2020-06-17 23:48:20 +02:00
return points;
}
2020-06-17 23:48:20 +02:00
#define tState data[10]
static void Task_DrawFinalStandingNumber(u8 taskId)
{
u16 firstTileNum;
2020-06-17 23:48:20 +02:00
if (gTasks[taskId].tState == 0)
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].data[11] = (3 - gTasks[taskId].tFinalStanding) * 40;
gTasks[taskId].tState++;
}
2020-06-17 23:48:20 +02:00
else if (gTasks[taskId].tState == 1)
{
if (--gTasks[taskId].data[11] == -1)
{
2020-06-17 23:48:20 +02:00
firstTileNum = gTasks[taskId].tFinalStanding * 2 + 0x5043;
WriteSequenceToBgTilemapBuffer(2, firstTileNum, 1, gTasks[taskId].tMonIndex * 3 + 5, 2, 1, 17, 1);
WriteSequenceToBgTilemapBuffer(2, firstTileNum + 0x10, 1, gTasks[taskId].tMonIndex * 3 + 6, 2, 1, 17, 1);
sContestResults->data->numStandingsPrinted++;
DestroyTask(taskId);
2020-08-21 00:02:00 +02:00
PlaySE(SE_CONTEST_PLACE);
}
}
}
2020-06-17 23:48:20 +02:00
#undef tFinalStanding
#undef tMonIndex
#undef tState
static void Task_StartHighlightWinnersBox(u8 taskId)
{
int i;
2020-06-17 23:48:20 +02:00
GET_CONTEST_WINNER_ID(i);
CopyToBgTilemapBufferRect_ChangePalette(2, i * 0xC0 + 0x100 + sContestResults->tilemapBuffers[2], 0, i * 3 + 4, 32, 3, 9);
gTasks[taskId].data[10] = i;
gTasks[taskId].data[12] = 1;
2020-06-17 23:48:20 +02:00
gTasks[taskId].func = Task_HighlightWinnersBox;
sContestResults->data->highlightWinnerTaskId = taskId;
}
2020-06-17 23:48:20 +02:00
static void Task_HighlightWinnersBox(u8 taskId)
{
if (++gTasks[taskId].data[11] == 1)
{
gTasks[taskId].data[11] = 0;
BlendPalette(0x91, 1, gTasks[taskId].data[12], RGB(13, 28, 27));
if (gTasks[taskId].data[13] == 0)
{
if (++gTasks[taskId].data[12] == 16)
gTasks[taskId].data[13] = 1;
}
else
{
if (--gTasks[taskId].data[12] == 0)
gTasks[taskId].data[13] = 0;
}
}
}
2020-06-17 23:48:20 +02:00
static void SpriteCB_WinnerMonSlideIn(struct Sprite *sprite)
{
if (sprite->data[0] < 10)
{
if (++sprite->data[0] == 10)
{
2021-11-07 19:54:44 +01:00
PlayCry_Normal(sprite->data[1], 0);
sprite->data[1] = 0;
}
}
else
{
2019-07-30 13:48:12 +02:00
s16 delta = sprite->data[1] + 0x600;
2021-07-07 15:11:52 +02:00
sprite->x -= delta >> 8;
2019-07-30 13:48:12 +02:00
sprite->data[1] += 0x600;
sprite->data[1] &= 0xFF;
2021-07-07 15:11:52 +02:00
if (sprite->x < DISPLAY_WIDTH / 2)
sprite->x = DISPLAY_WIDTH / 2;
2021-07-07 15:11:52 +02:00
if (sprite->x == DISPLAY_WIDTH / 2)
{
sprite->callback = SpriteCallbackDummy;
sprite->data[1] = 0;
2020-06-17 23:48:20 +02:00
sContestResults->data->winnerMonSlidingState = SLIDING_MON_ENTERED;
}
}
}
2020-06-17 23:48:20 +02:00
static void SpriteCB_WinnerMonSlideOut(struct Sprite *sprite)
{
2019-07-30 13:48:12 +02:00
s16 delta = sprite->data[1] + 0x600;
2021-07-07 15:11:52 +02:00
sprite->x -= delta >> 8;
2019-07-30 13:48:12 +02:00
sprite->data[1] += + 0x600;
sprite->data[1] &= 0xFF;
2021-07-07 15:11:52 +02:00
if (sprite->x < -32)
{
sprite->callback = SpriteCallbackDummy;
2020-06-17 23:48:20 +02:00
sprite->invisible = TRUE;
sContestResults->data->winnerMonSlidingState = SLIDING_MON_EXITED;
}
}
2019-02-21 01:05:33 +01:00
2020-06-17 23:48:20 +02:00
static void Task_CreateConfetti(u8 taskId)
2019-02-21 01:05:33 +01:00
{
if (++gTasks[taskId].data[0] == 5)
{
gTasks[taskId].data[0] = 0;
2020-06-17 23:48:20 +02:00
if (sContestResults->data->confettiCount < 40)
2019-02-21 01:05:33 +01:00
{
2021-04-15 08:04:01 +02:00
u8 spriteId = CreateSprite(&sSpriteTemplate_Confetti, (Random() % DISPLAY_WIDTH) - 20, 44, 5);
2019-02-21 01:05:33 +01:00
gSprites[spriteId].data[0] = Random() % 512;
gSprites[spriteId].data[1] = (Random() % 24) + 16;
gSprites[spriteId].data[2] = (Random() % 256) + 48;
gSprites[spriteId].oam.tileNum += Random() % 17;
2020-06-17 23:48:20 +02:00
sContestResults->data->confettiCount++;
2019-02-21 01:05:33 +01:00
}
}
2020-06-17 23:48:20 +02:00
if (sContestResults->data->destroyConfetti)
2019-02-21 01:05:33 +01:00
DestroyTask(taskId);
}
2020-06-17 09:39:03 +02:00
static void SpriteCB_Confetti(struct Sprite *sprite)
2019-02-21 01:05:33 +01:00
{
2019-07-30 13:48:12 +02:00
s16 delta;
2019-02-21 01:05:33 +01:00
sprite->data[3] += sprite->data[0];
2021-07-07 15:11:52 +02:00
sprite->x2 = Sin(sprite->data[3] >> 8, sprite->data[1]);
2019-07-30 13:48:12 +02:00
delta = sprite->data[4] + sprite->data[2];
2021-07-07 15:11:52 +02:00
sprite->x += delta >> 8;
2019-07-30 13:48:12 +02:00
sprite->data[4] += sprite->data[2];
sprite->data[4] &= 0xff;
2021-07-07 15:11:52 +02:00
sprite->y++;
2020-06-17 23:48:20 +02:00
if (sContestResults->data->destroyConfetti)
sprite->invisible = TRUE;
2019-04-10 20:49:10 +02:00
2021-07-07 15:11:52 +02:00
if (sprite->x > DISPLAY_WIDTH + 8 || sprite->y > 116)
2019-02-21 01:05:33 +01:00
{
DestroySprite(sprite);
2020-06-17 23:48:20 +02:00
sContestResults->data->confettiCount--;
2019-02-21 01:05:33 +01:00
}
}
2020-06-17 23:48:20 +02:00
#define tMonIndex data[0]
#define tNumFrames data[1]
#define tSpecies data[2]
#define tTimer data[10]
#define tBounced data[11]
static void BounceMonIconInBox(u8 monIndex, u8 numFrames)
2019-02-21 01:05:33 +01:00
{
2020-06-17 23:48:20 +02:00
u8 taskId = CreateTask(Task_BounceMonIconInBox, 8);
gTasks[taskId].tMonIndex = monIndex;
gTasks[taskId].tNumFrames = numFrames;
gTasks[taskId].tSpecies = gContestMons[monIndex].species;
2019-02-21 01:05:33 +01:00
}
2020-06-17 23:48:20 +02:00
static void Task_BounceMonIconInBox(u8 taskId)
2019-02-21 01:05:33 +01:00
{
2020-06-17 23:48:20 +02:00
u8 monIndex = gTasks[taskId].tMonIndex;
if (gTasks[taskId].tTimer++ == gTasks[taskId].tNumFrames)
2019-02-21 01:05:33 +01:00
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTimer = 0;
LoadContestMonIcon(gTasks[taskId].tSpecies, monIndex, gTasks[taskId].tBounced, FALSE, gContestMons[monIndex].personality);
gTasks[taskId].tBounced ^= 1;
2019-02-21 01:05:33 +01:00
}
}
2020-06-17 23:48:20 +02:00
#undef tMonIndex
#undef tNumFrames
#undef tSpecies
#undef tTimer
#undef tBounced
static void CalculateContestantsResultData(void)
2019-02-21 01:05:33 +01:00
{
2020-06-17 23:48:20 +02:00
int i, relativePoints;
u32 barLength;
s16 highestPoints;
s8 round2Points;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
highestPoints = gContestMonTotalPoints[0];
for (i = 1; i < CONTESTANT_COUNT; i++)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
if (highestPoints < gContestMonTotalPoints[i])
highestPoints = gContestMonTotalPoints[i];
2019-07-30 13:48:12 +02:00
}
2020-06-17 23:48:20 +02:00
if (highestPoints < 0)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
highestPoints = gContestMonTotalPoints[0];
for (i = 1; i < CONTESTANT_COUNT; i++)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
if (highestPoints > gContestMonTotalPoints[i])
highestPoints = gContestMonTotalPoints[i];
2019-07-30 13:48:12 +02:00
}
}
2019-11-11 03:54:00 +01:00
for (i = 0; i < CONTESTANT_COUNT; i++)
2019-07-30 13:48:12 +02:00
{
2020-07-24 06:14:53 +02:00
relativePoints = (gContestMonRound1Points[i] * 1000) / abs(highestPoints);
2020-06-17 23:48:20 +02:00
if (relativePoints % 10 > 4)
relativePoints += 10;
(*sContestResults->monResults)[i].relativePreliminaryPoints = relativePoints / 10;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
relativePoints = (abs(gContestMonRound2Points[i]) * 1000) / abs(highestPoints);
if (relativePoints % 10 > 4)
relativePoints += 10;
(*sContestResults->monResults)[i].relativeRound2Points = relativePoints / 10;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
if (gContestMonRound2Points[i] < 0)
(*sContestResults->monResults)[i].lostPoints = TRUE;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
barLength = ((*sContestResults->monResults)[i].relativePreliminaryPoints * 0x5800) / 100;
if ((barLength & 0xFF) > 0x7F)
barLength += 0x100;
(*sContestResults->monResults)[i].barLengthPreliminary = barLength >> 8;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
barLength = ((*sContestResults->monResults)[i].relativeRound2Points * 0x5800) / 100;
if ((barLength & 0xFF) > 0x7F)
barLength += 0x100;
(*sContestResults->monResults)[i].barLengthRound2 = barLength >> 8;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
(*sContestResults->monResults)[i].numStars = GetNumPreliminaryPoints(i, TRUE);
round2Points = GetNumRound2Points(i, TRUE);
(*sContestResults->monResults)[i].numHearts = abs(round2Points);
2019-07-30 13:48:12 +02:00
if (gContestFinalStandings[i])
{
2020-06-17 23:48:20 +02:00
s16 barLengthPreliminary = (*sContestResults->monResults)[i].barLengthPreliminary;
s16 barLengthRound2 = (*sContestResults->monResults)[i].barLengthRound2;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
if ((*sContestResults->monResults)[i].lostPoints)
barLengthRound2 *= -1;
2019-07-30 13:48:12 +02:00
2022-05-16 20:55:20 +02:00
if (barLengthPreliminary + barLengthRound2 == MAX_BAR_LENGTH)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
if (barLengthRound2 > 0)
(*sContestResults->monResults)[i].barLengthRound2--;
else if (barLengthPreliminary > 0)
(*sContestResults->monResults)[i].barLengthPreliminary--;
2019-07-30 13:48:12 +02:00
}
}
}
}
2019-02-21 01:05:33 +01:00
2020-06-17 23:48:20 +02:00
#define tMonId data[0]
#define tTarget data[1]
#define tDecreasing data[2]
static void UpdateContestResultBars(bool8 isRound2, u8 numUpdates)
2019-02-21 01:05:33 +01:00
{
2019-07-30 13:48:12 +02:00
int i, taskId;
2020-06-17 23:48:20 +02:00
u32 target;
u8 numIncreasing = 0, numDecreasing = 0;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
if (!isRound2)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
for (i = 0; i < CONTESTANT_COUNT; i++)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
u8 numStars = (*sContestResults->monResults)[i].numStars;
if (numUpdates < numStars)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
FillBgTilemapBufferRect_Palette0(1, 0x60B3, ((19 + numStars) - numUpdates) - 1, i * 3 + 5, 1, 1);
taskId = CreateTask(Task_UpdateContestResultBar, 10);
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
target = (((*sContestResults->monResults)[i].barLengthPreliminary << 16) / (*sContestResults->monResults)[i].numStars) * (numUpdates + 1);
if ((target & 0xFFFF) > 0x7FFF)
target += 0x10000;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
gTasks[taskId].tMonId = i;
gTasks[taskId].tTarget = target >> 16;
sContestResults->data->numBarsUpdating++;
numIncreasing++;
2019-07-30 13:48:12 +02:00
}
}
}
else
{
2020-06-17 23:48:20 +02:00
for (i = 0; i < CONTESTANT_COUNT; i++)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
s8 numHearts = (*sContestResults->monResults)[i].numHearts;
u32 tile = (*sContestResults->monResults)[i].lostPoints ? 0x60A5 : 0x60A3;
if (numUpdates < numHearts)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
FillBgTilemapBufferRect_Palette0(1, tile, ((19 + numHearts) - numUpdates) - 1, i * 3 + 6, 1, 1);
taskId = CreateTask(Task_UpdateContestResultBar, 10);
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
target = (((*sContestResults->monResults)[i].barLengthRound2 << 16) / (*sContestResults->monResults)[i].numHearts) * (numUpdates + 1);
if ((target & 0xFFFF) > 0x7FFF)
target += 0x10000;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
gTasks[taskId].tMonId = i;
if ((*sContestResults->monResults)[i].lostPoints)
2019-07-30 13:48:12 +02:00
{
2020-06-17 23:48:20 +02:00
gTasks[taskId].tDecreasing = TRUE;
numDecreasing++;
2019-07-30 13:48:12 +02:00
}
else
{
2020-06-17 23:48:20 +02:00
numIncreasing++;
2019-07-30 13:48:12 +02:00
}
2020-06-17 23:48:20 +02:00
if ((*sContestResults->monResults)[i].lostPoints)
gTasks[taskId].tTarget = -(target >> 16) + (*sContestResults->monResults)[i].barLengthPreliminary;
2019-07-30 13:48:12 +02:00
else
2020-06-17 23:48:20 +02:00
gTasks[taskId].tTarget = (target >> 16) + (*sContestResults->monResults)[i].barLengthPreliminary;
2019-07-30 13:48:12 +02:00
2020-06-17 23:48:20 +02:00
sContestResults->data->numBarsUpdating++;
2019-07-30 13:48:12 +02:00
}
}
}
2020-06-17 23:48:20 +02:00
if (numDecreasing)
2019-07-30 13:48:12 +02:00
PlaySE(SE_BOO);
2020-06-17 23:48:20 +02:00
if (numIncreasing)
2019-07-30 13:48:12 +02:00
PlaySE(SE_PIN);
2019-02-21 01:05:33 +01:00
}
2020-06-17 23:48:20 +02:00
static void Task_UpdateContestResultBar(u8 taskId)
2019-02-21 01:05:33 +01:00
{
int i;
2020-06-17 23:48:20 +02:00
bool32 minMaxReached = FALSE;
bool32 targetReached = FALSE;
u8 monId = gTasks[taskId].tMonId;
s16 target = gTasks[taskId].tTarget;
s16 decreasing = gTasks[taskId].tDecreasing;
2019-02-21 01:05:33 +01:00
2022-05-16 20:55:20 +02:00
// Has the results bar reached the limit?
2020-06-17 23:48:20 +02:00
if (decreasing)
2019-02-21 01:05:33 +01:00
{
2022-05-16 20:55:20 +02:00
if (sContestResults->data->barLength[monId] <= 0)
2020-06-17 23:48:20 +02:00
minMaxReached = TRUE;
2019-02-21 01:05:33 +01:00
}
else
{
2022-05-16 20:55:20 +02:00
if (sContestResults->data->barLength[monId] >= MAX_BAR_LENGTH)
2020-06-17 23:48:20 +02:00
minMaxReached = TRUE;
2019-02-21 01:05:33 +01:00
}
2022-05-16 20:55:20 +02:00
if (sContestResults->data->barLength[monId] == target)
2020-06-17 23:48:20 +02:00
targetReached = TRUE;
2019-02-21 01:05:33 +01:00
2020-06-17 23:48:20 +02:00
if (!targetReached)
2019-02-21 01:05:33 +01:00
{
2022-05-16 20:55:20 +02:00
// Target length has not been reached, update bar length
2020-06-17 23:48:20 +02:00
if (minMaxReached)
2022-05-16 20:55:20 +02:00
sContestResults->data->barLength[monId] = target;
2020-06-17 23:48:20 +02:00
else if (decreasing)
2022-05-16 20:55:20 +02:00
sContestResults->data->barLength[monId]--;
2019-02-21 01:05:33 +01:00
else
2022-05-16 20:55:20 +02:00
sContestResults->data->barLength[monId]++;
2019-02-21 01:05:33 +01:00
}
2022-05-16 20:55:20 +02:00
// Update the tiles of the results bar if it's still changing
2020-06-17 23:48:20 +02:00
if (!minMaxReached && !targetReached)
2019-02-21 01:05:33 +01:00
{
2022-05-16 20:55:20 +02:00
u8 tileOffset;
2020-06-17 23:48:20 +02:00
u16 tileNum;
2022-05-16 20:55:20 +02:00
for (i = 0; i < NUM_BAR_SEGMENTS; i++)
2019-02-21 01:05:33 +01:00
{
2022-05-16 20:55:20 +02:00
if (sContestResults->data->barLength[monId] >= (i + 1) * BAR_SEGMENT_LENGTH)
tileOffset = 8; // Bar segment is full
else if (sContestResults->data->barLength[monId] >= i * BAR_SEGMENT_LENGTH)
tileOffset = sContestResults->data->barLength[monId] % 8; // Bar segment is between full and empty
2019-02-21 01:05:33 +01:00
else
2022-05-16 20:55:20 +02:00
tileOffset = 0; // Bar segment is empty
2019-02-21 01:05:33 +01:00
2022-05-16 20:55:20 +02:00
// The first 4 bar segment tiles are not adjacent in the tileset to the
// remaining bar segment tiles; choose the base tile number accordingly.
if (tileOffset < 4)
tileNum = 0x504C + tileOffset;
2019-02-21 01:05:33 +01:00
else
2022-05-16 20:55:20 +02:00
tileNum = 0x5057 + tileOffset;
2019-02-21 01:05:33 +01:00
2020-06-17 23:48:20 +02:00
FillBgTilemapBufferRect_Palette0(2, tileNum, i + 7, monId * 3 + 6, 1, 1);
2019-02-21 01:05:33 +01:00
}
}
2019-04-10 20:49:10 +02:00
2020-06-17 23:48:20 +02:00
if (targetReached)
2019-02-21 01:05:33 +01:00
{
2020-06-17 23:48:20 +02:00
sContestResults->data->numBarsUpdating--;
2019-02-21 01:05:33 +01:00
DestroyTask(taskId);
}
}
2020-06-17 23:48:20 +02:00
#undef tMonId
#undef tTarget
#undef tDecreasing
static void AllocContestResults(void)
2019-02-21 01:05:33 +01:00
{
2020-06-17 23:48:20 +02:00
sContestResults = AllocZeroed(sizeof(*sContestResults));
sContestResults->data = AllocZeroed(sizeof(*sContestResults->data));
sContestResults->monResults = AllocZeroed(sizeof(*sContestResults->monResults));
sContestResults->unusedBg = AllocZeroed(BG_SCREEN_SIZE);
sContestResults->tilemapBuffers[0] = AllocZeroed(BG_SCREEN_SIZE);
sContestResults->tilemapBuffers[1] = AllocZeroed(BG_SCREEN_SIZE);
sContestResults->tilemapBuffers[2] = AllocZeroed(BG_SCREEN_SIZE);
sContestResults->tilemapBuffers[3] = AllocZeroed(BG_SCREEN_SIZE);
sContestResults->unused = AllocZeroed(0x1000);
2019-02-21 01:05:33 +01:00
AllocateMonSpritesGfx();
}
2020-06-17 23:48:20 +02:00
static void FreeContestResults(void)
2019-02-21 01:05:33 +01:00
{
2020-06-17 23:48:20 +02:00
FREE_AND_SET_NULL(sContestResults->data);
FREE_AND_SET_NULL(sContestResults->monResults);
FREE_AND_SET_NULL(sContestResults->unusedBg);
FREE_AND_SET_NULL(sContestResults->tilemapBuffers[0]);
FREE_AND_SET_NULL(sContestResults->tilemapBuffers[1]);
FREE_AND_SET_NULL(sContestResults->tilemapBuffers[2]);
FREE_AND_SET_NULL(sContestResults->tilemapBuffers[3]);
FREE_AND_SET_NULL(sContestResults->unused);
FREE_AND_SET_NULL(sContestResults);
2019-02-21 01:05:33 +01:00
FreeMonSpritesGfx();
}
2020-06-17 23:48:20 +02:00
static void AddContestTextPrinter(int windowId, u8 *str, int x)
2019-02-21 01:05:33 +01:00
{
struct TextPrinterTemplate textPrinter;
textPrinter.currentChar = str;
textPrinter.windowId = windowId;
2021-10-30 22:47:37 +02:00
textPrinter.fontId = FONT_NARROW;
2020-06-17 23:48:20 +02:00
textPrinter.x = x;
2019-02-21 01:05:33 +01:00
textPrinter.y = 2;
2020-06-17 23:48:20 +02:00
textPrinter.currentX = x;
2019-02-21 01:05:33 +01:00
textPrinter.currentY = 2;
textPrinter.letterSpacing = 0;
textPrinter.lineSpacing = 0;
textPrinter.unk = 0;
2019-02-21 01:05:33 +01:00
textPrinter.fgColor = 1;
textPrinter.bgColor = 0;
textPrinter.shadowColor = 8;
AddTextPrinter(&textPrinter, 0, NULL);
PutWindowTilemap(windowId);
}
2019-11-11 03:54:00 +01:00
void TryEnterContestMon(void)
2019-02-21 01:05:33 +01:00
{
2019-10-18 01:22:03 +02:00
u8 eligibility = GetContestEntryEligibility(&gPlayerParty[gContestMonPartyIndex]);
// Nonzero eligibility can still be non-eligibile, if mon is fainted or egg
if (eligibility)
2019-02-21 01:05:33 +01:00
{
2020-07-24 06:14:53 +02:00
SetContestants(gSpecialVar_ContestCategory, gSpecialVar_ContestRank);
2020-08-13 09:09:47 +02:00
CalculateRound1Points(gSpecialVar_ContestCategory);
2019-02-21 01:05:33 +01:00
}
2019-10-18 01:22:03 +02:00
gSpecialVar_Result = eligibility;
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
u16 HasMonWonThisContestBefore(void)
2019-02-21 01:05:33 +01:00
{
2019-11-11 03:54:00 +01:00
u16 hasRankRibbon = FALSE;
2019-02-21 01:05:33 +01:00
struct Pokemon *mon = &gPlayerParty[gContestMonPartyIndex];
switch (gSpecialVar_ContestCategory)
{
case CONTEST_CATEGORY_COOL:
if (GetMonData(mon, MON_DATA_COOL_RIBBON) > gSpecialVar_ContestRank)
2019-11-11 03:54:00 +01:00
hasRankRibbon = TRUE;
2019-02-21 01:05:33 +01:00
break;
case CONTEST_CATEGORY_BEAUTY:
if (GetMonData(mon, MON_DATA_BEAUTY_RIBBON) > gSpecialVar_ContestRank)
2019-11-11 03:54:00 +01:00
hasRankRibbon = TRUE;
2019-02-21 01:05:33 +01:00
break;
case CONTEST_CATEGORY_CUTE:
if (GetMonData(mon, MON_DATA_CUTE_RIBBON) > gSpecialVar_ContestRank)
2019-11-11 03:54:00 +01:00
hasRankRibbon = TRUE;
2019-02-21 01:05:33 +01:00
break;
case CONTEST_CATEGORY_SMART:
if (GetMonData(mon, MON_DATA_SMART_RIBBON) > gSpecialVar_ContestRank)
2019-11-11 03:54:00 +01:00
hasRankRibbon = TRUE;
2019-02-21 01:05:33 +01:00
break;
case CONTEST_CATEGORY_TOUGH:
if (GetMonData(mon, MON_DATA_TOUGH_RIBBON) > gSpecialVar_ContestRank)
2019-11-11 03:54:00 +01:00
hasRankRibbon = TRUE;
2019-02-21 01:05:33 +01:00
break;
}
2019-11-11 03:54:00 +01:00
return hasRankRibbon;
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
void GiveMonContestRibbon(void)
2019-02-21 01:05:33 +01:00
{
u8 ribbonData;
if (gContestFinalStandings[gContestPlayerMonIndex] != 0)
return;
switch (gSpecialVar_ContestCategory)
{
case CONTEST_CATEGORY_COOL:
ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON);
if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4)
{
ribbonData++;
SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON, &ribbonData);
2019-11-11 03:54:00 +01:00
if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS)
TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON);
2019-02-21 01:05:33 +01:00
}
break;
case CONTEST_CATEGORY_BEAUTY:
ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON);
if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4)
{
ribbonData++;
SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON, &ribbonData);
2019-11-11 03:54:00 +01:00
if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS)
TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON);
2019-02-21 01:05:33 +01:00
}
break;
case CONTEST_CATEGORY_CUTE:
ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON);
if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4)
{
ribbonData++;
SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON, &ribbonData);
2019-11-11 03:54:00 +01:00
if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS)
TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON);
2019-02-21 01:05:33 +01:00
}
break;
case CONTEST_CATEGORY_SMART:
ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON);
if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4)
{
ribbonData++;
SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON, &ribbonData);
2019-11-11 03:54:00 +01:00
if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS)
TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON);
2019-02-21 01:05:33 +01:00
}
break;
case CONTEST_CATEGORY_TOUGH:
ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON);
if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4)
{
ribbonData++;
SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON, &ribbonData);
2019-11-11 03:54:00 +01:00
if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS)
TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON);
2019-02-21 01:05:33 +01:00
}
break;
}
}
2019-11-11 03:54:00 +01:00
void BufferContestantTrainerName(void)
2019-02-21 01:05:33 +01:00
{
StringCopy(gStringVar1, gContestMons[gSpecialVar_0x8006].trainerName);
2021-04-22 20:30:45 +02:00
ConvertInternationalContestantName(gStringVar1);
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
void BufferContestantMonNickname(void)
2019-02-21 01:05:33 +01:00
{
StringCopy(gStringVar3, gContestMons[gSpecialVar_0x8006].nickname);
}
2019-11-11 03:54:00 +01:00
// Unused script special
void GetContestMonConditionRanking(void)
2019-02-21 01:05:33 +01:00
{
2019-11-11 03:54:00 +01:00
u8 i, rank;
2019-02-21 01:05:33 +01:00
2019-11-11 03:54:00 +01:00
for (i = 0, rank = 0; i < CONTESTANT_COUNT; i++)
2019-02-21 01:05:33 +01:00
{
2020-07-24 06:14:53 +02:00
if (gContestMonRound1Points[gSpecialVar_0x8006] < gContestMonRound1Points[i])
2019-11-11 03:54:00 +01:00
rank++;
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
gSpecialVar_0x8004 = rank;
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
void GetContestMonCondition(void)
2019-02-21 01:05:33 +01:00
{
2020-07-24 06:14:53 +02:00
gSpecialVar_0x8004 = gContestMonRound1Points[gSpecialVar_0x8006];
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
void GetContestWinnerId(void)
2019-02-21 01:05:33 +01:00
{
u8 i;
2020-06-17 23:48:20 +02:00
GET_CONTEST_WINNER_ID(i);
2019-02-21 01:05:33 +01:00
gSpecialVar_0x8005 = i;
}
2019-11-11 03:54:00 +01:00
void BufferContestWinnerTrainerName(void)
2019-02-21 01:05:33 +01:00
{
u8 i;
2020-06-17 23:48:20 +02:00
GET_CONTEST_WINNER_ID(i);
2019-02-21 01:05:33 +01:00
StringCopy(gStringVar3, gContestMons[i].trainerName);
2021-04-22 20:30:45 +02:00
ConvertInternationalContestantName(gStringVar3);
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
void BufferContestWinnerMonName(void)
2019-02-21 01:05:33 +01:00
{
u8 i;
2020-06-17 23:48:20 +02:00
GET_CONTEST_WINNER_ID(i);
2019-02-21 01:05:33 +01:00
StringCopy(gStringVar1, gContestMons[i].nickname);
}
2019-11-11 03:54:00 +01:00
void CB2_SetStartContestCallback(void)
2019-02-21 01:05:33 +01:00
{
SetMainCallback2(CB2_StartContest);
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
static void Task_StartContest(u8 taskId)
2019-02-21 01:05:33 +01:00
{
if (!gPaletteFade.active)
{
DestroyTask(taskId);
2019-11-11 03:54:00 +01:00
SetMainCallback2(CB2_SetStartContestCallback);
2019-02-21 01:05:33 +01:00
}
}
2019-11-11 03:54:00 +01:00
void StartContest(void)
2019-02-21 01:05:33 +01:00
{
LockPlayerFieldControls();
2019-11-11 03:54:00 +01:00
CreateTask(Task_StartContest, 10);
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
void BufferContestantMonSpecies(void)
2019-02-21 01:05:33 +01:00
{
gSpecialVar_0x8004 = gContestMons[gSpecialVar_0x8006].species;
}
2020-06-17 23:48:20 +02:00
static void Task_StartShowContestResults(u8 taskId)
2019-02-21 01:05:33 +01:00
{
if (!gPaletteFade.active)
{
DestroyTask(taskId);
2020-06-17 23:48:20 +02:00
SetMainCallback2(CB2_StartShowContestResults);
2019-02-21 01:05:33 +01:00
}
}
2020-06-17 23:48:20 +02:00
void ShowContestResults(void)
2019-02-21 01:05:33 +01:00
{
LockPlayerFieldControls();
2020-06-17 23:48:20 +02:00
CreateTask(Task_StartShowContestResults, 10);
2021-02-24 17:01:02 +01:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
2019-02-21 01:05:33 +01:00
}
2019-11-11 03:54:00 +01:00
void GetContestPlayerId(void)
2019-02-21 01:05:33 +01:00
{
gSpecialVar_0x8004 = gContestPlayerMonIndex;
}
2020-07-12 02:25:56 +02:00
void ContestLinkTransfer(u8 category)
2019-02-21 01:05:33 +01:00
{
u8 newTaskId;
LockPlayerFieldControls();
2020-08-13 09:09:47 +02:00
newTaskId = CreateTask(Task_LinkContest_Init, 0);
SetTaskFuncWithFollowupFunc(newTaskId, Task_LinkContest_Init, Task_StartCommunication);
2020-07-12 02:25:56 +02:00
gTasks[newTaskId].data[9] = category;
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
static void Task_StartCommunication(u8 taskId)
2019-02-21 01:05:33 +01:00
{
if (gLinkContestFlags & LINK_CONTEST_FLAG_HAS_RS_PLAYER)
2019-02-21 01:05:33 +01:00
{
2020-07-12 02:25:56 +02:00
CreateContestMonFromParty(gContestMonPartyIndex);
2020-08-13 09:09:47 +02:00
SetTaskFuncWithFollowupFunc(taskId, Task_LinkContest_CommunicateMonsRS, Task_StartCommunicateRngRS);
2019-02-21 01:05:33 +01:00
}
else
{
2020-07-12 02:25:56 +02:00
CreateContestMonFromParty(gContestMonPartyIndex);
2020-08-13 09:09:47 +02:00
gTasks[taskId].func = Task_LinkContest_StartCommunicationEm;
2019-02-21 01:05:33 +01:00
}
}
2020-08-13 09:09:47 +02:00
static void Task_StartCommunicateRngRS(u8 taskId)
2019-02-21 01:05:33 +01:00
{
2020-08-13 09:09:47 +02:00
SetTaskFuncWithFollowupFunc(taskId, Task_LinkContest_CommunicateRngRS, Task_StartCommunicateLeaderIdsRS);
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
static void Task_StartCommunicateLeaderIdsRS(u8 taskId)
2019-02-21 01:05:33 +01:00
{
2020-08-13 09:09:47 +02:00
SetTaskFuncWithFollowupFunc(taskId, Task_LinkContest_CommunicateLeaderIdsRS, Task_StartCommunicateCategoryRS);
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
static void Task_StartCommunicateCategoryRS(u8 taskId)
2019-02-21 01:05:33 +01:00
{
2020-08-13 09:09:47 +02:00
SetTaskFuncWithFollowupFunc(taskId, Task_LinkContest_CommunicateCategoryRS, Task_LinkContest_SetUpContestRS);
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
static void Task_LinkContest_SetUpContestRS(u8 taskId)
2019-02-21 01:05:33 +01:00
{
2019-04-10 20:49:10 +02:00
u8 i;
2020-08-13 09:09:47 +02:00
u8 categories[CONTESTANT_COUNT];
u8 leaderIds[CONTESTANT_COUNT];
2019-02-21 01:05:33 +01:00
2020-08-13 09:09:47 +02:00
memset(categories, 0, sizeof(categories));
memset(leaderIds, 0, sizeof(leaderIds));
2019-02-21 01:05:33 +01:00
for (i = 0; i < gNumLinkContestPlayers; i++)
2020-08-13 09:09:47 +02:00
categories[i] = gTasks[taskId].data[i + 1];
2019-02-21 01:05:33 +01:00
2020-08-13 09:09:47 +02:00
// Ensure all players are doing the same category
for (i = 0; i < gNumLinkContestPlayers && categories[0] == categories[i]; i++)
;
2019-02-21 01:05:33 +01:00
if (i == gNumLinkContestPlayers)
2020-08-13 09:09:47 +02:00
gSpecialVar_0x8004 = FALSE; // Category choices the same
2019-02-21 01:05:33 +01:00
else
2020-08-13 09:09:47 +02:00
gSpecialVar_0x8004 = TRUE; // Category choices differ
2019-02-21 01:05:33 +01:00
for (i = 0; i < gNumLinkContestPlayers; i++)
2020-08-13 09:09:47 +02:00
leaderIds[i] = gTasks[taskId].data[i + 5];
2019-04-10 20:49:10 +02:00
2020-08-13 09:09:47 +02:00
gContestLinkLeaderIndex = LinkContest_GetLeaderIndex(leaderIds);
CalculateRound1Points(gSpecialVar_ContestCategory);
SetTaskFuncWithFollowupFunc(taskId, Task_LinkContest_CommunicateRound1Points, Task_LinkContest_CalculateTurnOrderRS);
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
static void Task_LinkContest_CalculateTurnOrderRS(u8 taskId)
2019-02-21 01:05:33 +01:00
{
SortContestants(FALSE);
2020-08-13 09:09:47 +02:00
SetTaskFuncWithFollowupFunc(taskId, Task_LinkContest_CommunicateTurnOrder, Task_LinkContest_FinalizeConnection);
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
u8 LinkContest_GetLeaderIndex(u8 *ids)
2019-02-21 01:05:33 +01:00
{
int i;
2020-08-13 09:09:47 +02:00
u8 leaderIdx = 0;
2019-02-21 01:05:33 +01:00
for (i = 1; i < gNumLinkContestPlayers; i++)
{
2020-08-13 09:09:47 +02:00
if (ids[leaderIdx] < ids[i])
leaderIdx = i;
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
return leaderIdx;
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
void Task_LinkContest_FinalizeConnection(u8 taskId)
2019-02-21 01:05:33 +01:00
{
int i;
2020-08-13 09:09:47 +02:00
if (gSpecialVar_0x8004 == TRUE)
2019-02-21 01:05:33 +01:00
{
2020-08-13 09:09:47 +02:00
// Link partner data doesn't agree, disconnect
2019-02-21 01:05:33 +01:00
if (IsLinkTaskFinished())
2020-08-13 09:09:47 +02:00
gTasks[taskId].func = Task_LinkContest_Disconnect;
2019-02-21 01:05:33 +01:00
}
else
{
2020-08-13 09:09:47 +02:00
// Succesfully connected
2019-11-11 03:54:00 +01:00
for (i = 0; i < CONTESTANT_COUNT; i++)
StringGet_Nickname(gContestMons[i].nickname);
2019-02-21 01:05:33 +01:00
DestroyTask(taskId);
SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, WARP_ID_NONE);
UnlockPlayerFieldControls();
ScriptContext_Enable();
2019-02-21 01:05:33 +01:00
}
}
2020-08-13 09:09:47 +02:00
static void Task_LinkContest_Disconnect(u8 taskId)
2019-02-21 01:05:33 +01:00
{
2020-08-13 09:09:47 +02:00
SetCloseLinkCallback();
gTasks[taskId].func = Task_LinkContest_WaitDisconnect;
2019-02-21 01:05:33 +01:00
}
2020-08-13 09:09:47 +02:00
static void Task_LinkContest_WaitDisconnect(u8 taskId)
2019-02-21 01:05:33 +01:00
{
if (!gReceivedRemoteLinkPlayers)
{
DestroyTask(taskId);
UnlockPlayerFieldControls();
ScriptContext_Enable();
2019-02-21 01:05:33 +01:00
}
}
2021-04-22 20:30:45 +02:00
/*
A section of contest script functions starts here
*/
void SetContestTrainerGfxIds(void)
{
gSaveBlock1Ptr->vars[VAR_OBJ_GFX_ID_0 - VARS_START] = gContestMons[0].trainerGfxId;
gSaveBlock1Ptr->vars[VAR_OBJ_GFX_ID_1 - VARS_START] = gContestMons[1].trainerGfxId;
gSaveBlock1Ptr->vars[VAR_OBJ_GFX_ID_2 - VARS_START] = gContestMons[2].trainerGfxId;
}
// Unused
2021-04-22 20:30:45 +02:00
void GetNpcContestantLocalId(void)
{
2021-04-22 20:30:45 +02:00
u16 localId;
u8 contestant = gSpecialVar_0x8005;
switch (contestant)
{
case 0:
2021-04-22 20:30:45 +02:00
localId = 3;
break;
case 1:
2021-04-22 20:30:45 +02:00
localId = 4;
break;
case 2:
2021-04-22 20:30:45 +02:00
localId = 5;
break;
2021-04-22 20:30:45 +02:00
default: // Invalid
localId = 100;
break;
}
2021-04-22 20:30:45 +02:00
gSpecialVar_0x8004 = localId;
}
void BufferContestTrainerAndMonNames(void)
{
BufferContestantTrainerName();
BufferContestantMonNickname();
BufferContestantMonSpecies();
}
// Unused
2021-04-22 20:30:45 +02:00
void DoesContestCategoryHaveMuseumPainting(void)
{
int contestWinner;
switch (gSpecialVar_ContestCategory)
{
case CONTEST_CATEGORY_COOL:
2021-04-22 20:30:45 +02:00
contestWinner = CONTEST_WINNER_MUSEUM_COOL - 1;
break;
case CONTEST_CATEGORY_BEAUTY:
2021-04-22 20:30:45 +02:00
contestWinner = CONTEST_WINNER_MUSEUM_BEAUTY - 1;
break;
case CONTEST_CATEGORY_CUTE:
2021-04-22 20:30:45 +02:00
contestWinner = CONTEST_WINNER_MUSEUM_CUTE - 1;
break;
case CONTEST_CATEGORY_SMART:
2021-04-22 20:30:45 +02:00
contestWinner = CONTEST_WINNER_MUSEUM_SMART - 1;
break;
case CONTEST_CATEGORY_TOUGH:
default:
2021-04-22 20:30:45 +02:00
contestWinner = CONTEST_WINNER_MUSEUM_TOUGH - 1;
break;
}
if (gSaveBlock1Ptr->contestWinners[contestWinner].species == SPECIES_NONE)
gSpecialVar_0x8004 = FALSE;
else
gSpecialVar_0x8004 = TRUE;
}
void SaveMuseumContestPainting(void)
{
2021-04-22 02:04:12 +02:00
SaveContestWinner(CONTEST_SAVE_FOR_MUSEUM);
}
void ShouldReadyContestArtist(void)
{
if (gContestFinalStandings[gContestPlayerMonIndex] == 0
&& gSpecialVar_ContestRank == CONTEST_RANK_MASTER
&& gContestMonTotalPoints[gContestPlayerMonIndex] >= 800)
{
gSpecialVar_0x8004 = TRUE;
}
else
{
gSpecialVar_0x8004 = FALSE;
}
}
2021-04-22 20:30:45 +02:00
u8 CountPlayerMuseumPaintings(void)
{
int i;
u8 count = 0;
2021-04-22 20:30:45 +02:00
for (i = 0; i < NUM_CONTEST_WINNERS - MUSEUM_CONTEST_WINNERS_START; i++)
{
2021-04-22 20:30:45 +02:00
if (gSaveBlock1Ptr->contestWinners[MUSEUM_CONTEST_WINNERS_START + i].species)
count++;
}
return count;
}
// Unused
2021-04-22 20:30:45 +02:00
void GetContestantNamesAtRank(void)
{
s16 conditions[CONTESTANT_COUNT];
int i, j;
s16 condition;
2021-04-22 20:30:45 +02:00
s8 numAtCondition;
u8 contestantOffset;
u8 tieRank;
u8 rank;
2021-04-22 20:30:45 +02:00
// Get round 1 points
for (i = 0; i < CONTESTANT_COUNT; i++)
conditions[i] = gContestMonRound1Points[i];
2021-04-22 20:30:45 +02:00
// Sort round 1 points
for (i = 0; i < CONTESTANT_COUNT - 1; i++)
{
for (j = CONTESTANT_COUNT - 1; j > i; j--)
{
if (conditions[j - 1] < conditions[j])
{
int temp;
SWAP(conditions[j], conditions[j - 1], temp)
}
}
}
2021-04-22 20:30:45 +02:00
// Get round 1 points at specified rank
condition = conditions[gSpecialVar_0x8006];
2021-04-22 20:30:45 +02:00
// Count number of contestants with the same number of points
numAtCondition = 0;
tieRank = 0;
for (i = 0; i < CONTESTANT_COUNT; i++)
{
if (conditions[i] == condition)
{
2021-04-22 20:30:45 +02:00
numAtCondition++;
if (i == gSpecialVar_0x8006)
2021-04-22 20:30:45 +02:00
tieRank = numAtCondition;
}
}
2021-04-22 20:30:45 +02:00
// Get rank of first contestant with the same number of points
for (i = 0; i < CONTESTANT_COUNT; i++)
{
if (conditions[i] == condition)
break;
}
2021-04-22 20:30:45 +02:00
rank = i;
2021-04-22 20:30:45 +02:00
// Get contestant id of player at rank (taking ties into account)
contestantOffset = tieRank;
for (i = 0; i < CONTESTANT_COUNT; i++)
{
if (condition == gContestMonRound1Points[i])
{
2021-04-22 20:30:45 +02:00
if (contestantOffset == 1)
break;
2021-04-22 20:30:45 +02:00
contestantOffset--;
}
}
2021-04-22 20:30:45 +02:00
// Use contestant id to get names
StringCopy(gStringVar1, gContestMons[i].nickname);
StringCopy(gStringVar2, gContestMons[i].trainerName);
2021-04-22 20:30:45 +02:00
ConvertInternationalContestantName(gStringVar2);
2021-04-22 20:30:45 +02:00
// Return adjusted rank
if (numAtCondition == 1)
gSpecialVar_0x8006 = rank;
else if (tieRank == numAtCondition)
gSpecialVar_0x8006 = rank;
else
2021-04-22 20:30:45 +02:00
gSpecialVar_0x8006 = rank + CONTESTANT_COUNT;
}
2021-04-22 02:04:12 +02:00
static void ExitContestPainting(void)
{
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
2021-04-22 02:04:12 +02:00
void ShowContestPainting(void)
{
SetMainCallback2(CB2_ContestPainting);
2021-04-22 02:04:12 +02:00
gMain.savedCallback = ExitContestPainting;
}
void SetLinkContestPlayerGfx(void)
{
int i;
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
{
for (i = 0; i < gNumLinkContestPlayers; i++)
{
int version = (u8)gLinkPlayers[i].version;
if (version == VERSION_RUBY || version == VERSION_SAPPHIRE)
{
if (gLinkPlayers[i].gender == MALE)
gContestMons[i].trainerGfxId = OBJ_EVENT_GFX_LINK_RS_BRENDAN;
else
gContestMons[i].trainerGfxId = OBJ_EVENT_GFX_LINK_RS_MAY;
}
}
VarSet(VAR_OBJ_GFX_ID_0, gContestMons[0].trainerGfxId);
VarSet(VAR_OBJ_GFX_ID_1, gContestMons[1].trainerGfxId);
VarSet(VAR_OBJ_GFX_ID_2, gContestMons[2].trainerGfxId);
VarSet(VAR_OBJ_GFX_ID_3, gContestMons[3].trainerGfxId);
}
}
void LoadLinkContestPlayerPalettes(void)
{
int i;
u8 objectEventId;
int version;
struct Sprite *sprite;
static const u8 sContestantLocalIds[CONTESTANT_COUNT] = { 3, 4, 5, 14 };
gReservedSpritePaletteCount = 12;
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
{
for (i = 0; i < gNumLinkContestPlayers; i++)
{
objectEventId = GetObjectEventIdByLocalIdAndMap(sContestantLocalIds[i], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
sprite = &gSprites[gObjectEvents[objectEventId].spriteId];
sprite->oam.paletteNum = 6 + i;
version = (u8)gLinkPlayers[i].version;
if (version == VERSION_RUBY || version == VERSION_SAPPHIRE)
{
if (gLinkPlayers[i].gender == MALE)
2020-11-23 20:12:07 +01:00
LoadPalette(gObjectEventPal_RubySapphireBrendan, 0x160 + i * 0x10, 0x20);
else
2020-11-23 20:12:07 +01:00
LoadPalette(gObjectEventPal_RubySapphireMay, 0x160 + i * 0x10, 0x20);
}
else
{
if (gLinkPlayers[i].gender == MALE)
2020-11-23 20:12:07 +01:00
LoadPalette(gObjectEventPal_Brendan, 0x160 + i * 0x10, 0x20);
else
2020-11-23 20:12:07 +01:00
LoadPalette(gObjectEventPal_May, 0x160 + i * 0x10, 0x20);
}
}
}
}
bool8 GiveMonArtistRibbon(void)
{
u8 hasArtistRibbon;
hasArtistRibbon = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_ARTIST_RIBBON);
2020-09-02 15:49:04 +02:00
if (!hasArtistRibbon
&& gContestFinalStandings[gContestPlayerMonIndex] == 0
&& gSpecialVar_ContestRank == CONTEST_RANK_MASTER
&& gContestMonTotalPoints[gContestPlayerMonIndex] >= 800)
{
hasArtistRibbon = 1;
SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_ARTIST_RIBBON, &hasArtistRibbon);
if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS)
TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_ARTIST_RIBBON);
return TRUE;
}
else
{
return FALSE;
}
}
bool8 IsContestDebugActive(void)
{
return FALSE; // gUnknown_0203856C in pokeruby
}
void ShowContestEntryMonPic(void)
{
const struct CompressedSpritePalette *palette;
u32 personality, otId;
u16 species;
u8 spriteId;
u8 taskId;
u8 left, top;
2021-02-20 05:22:26 +01:00
if (FindTaskIdByFunc(Task_ShowContestEntryMonPic) == TASK_NONE)
{
AllocateMonSpritesGfx();
left = 10;
top = 3;
species = gContestMons[gSpecialVar_0x8006].species;
personality = gContestMons[gSpecialVar_0x8006].personality;
otId = gContestMons[gSpecialVar_0x8006].otId;
taskId = CreateTask(Task_ShowContestEntryMonPic, 0x50);
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = species;
HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_LEFT], species, personality);
palette = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
LoadCompressedSpritePalette(palette);
2021-10-03 05:47:59 +02:00
SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT);
gMultiuseSpriteTemplate.paletteTag = palette->tag;
spriteId = CreateSprite(&gMultiuseSpriteTemplate, (left + 1) * 8 + 32, (top * 8) + 40, 0);
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
{
if (!(gLinkContestFlags & LINK_CONTEST_FLAG_HAS_RS_PLAYER))
DoMonFrontSpriteAnimation(&gSprites[spriteId], species, FALSE, 0);
}
else
{
DoMonFrontSpriteAnimation(&gSprites[spriteId], species, FALSE, 0);
}
gTasks[taskId].data[2] = spriteId;
gTasks[taskId].data[3] = left;
gTasks[taskId].data[4] = top;
gSprites[spriteId].callback = SpriteCallbackDummy;
gSprites[spriteId].oam.priority = 0;
}
}
void HideContestEntryMonPic(void)
{
u8 taskId = FindTaskIdByFunc(Task_ShowContestEntryMonPic);
2021-02-20 05:22:26 +01:00
if (taskId != TASK_NONE)
{
gTasks[taskId].data[0]++;
FreeMonSpritesGfx();
}
}
static void Task_ShowContestEntryMonPic(u8 taskId)
{
struct Task *task = &gTasks[taskId];
struct Sprite *sprite;
switch(task->data[0])
{
case 0:
task->data[0]++;
break;
case 1:
task->data[5] = CreateWindowFromRect(10, 3, 8, 8);
2022-07-25 20:59:14 +02:00
SetStandardWindowBorderStyle(task->data[5], TRUE);
task->data[0]++;
break;
case 2:
break;
case 3:
sprite = &gSprites[task->data[2]];
FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum));
if(sprite->oam.affineMode)
FreeOamMatrix(sprite->oam.matrixNum);
DestroySprite(sprite);
task->data[0]++;
break;
case 4:
ClearToTransparentAndRemoveWindow(gTasks[taskId].data[5]);
DestroyTask(taskId);
break;
}
}
void GetContestMultiplayerId(void)
{
2020-09-02 15:49:04 +02:00
if ((gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
&& gNumLinkContestPlayers == CONTESTANT_COUNT
&& !(gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS))
gSpecialVar_Result = GetMultiplayerId();
else
gSpecialVar_Result = MAX_LINK_PLAYERS;
}
void GenerateContestRand(void)
{
u16 random;
u16 *result;
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)
{
gContestRngValue = ISO_RANDOMIZE1(gContestRngValue);
random = gContestRngValue >> 16;
result = &gSpecialVar_Result;
}
else
{
result = &gSpecialVar_Result;
random = Random();
}
*result = random % *result;
}
u16 GetContestRand(void)
{
gContestRngValue = ISO_RANDOMIZE1(gContestRngValue);
return gContestRngValue >> 16;
}
bool8 LinkContestWaitForConnection(void)
{
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)
{
CreateTask(Task_LinkContestWaitForConnection, 5);
return TRUE;
}
else
{
return FALSE;
}
}
static void Task_LinkContestWaitForConnection(u8 taskId)
{
switch (gTasks[taskId].data[0])
{
case 0:
if (IsLinkTaskFinished())
{
SetLinkStandbyCallback();
gTasks[taskId].data[0]++;
}
break;
case 1:
gTasks[taskId].data[0]++;
break;
default:
if (IsLinkTaskFinished() == 1)
{
ScriptContext_Enable();
DestroyTask(taskId);
}
break;
}
}
void LinkContestTryShowWirelessIndicator(void)
{
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)
{
if (gReceivedRemoteLinkPlayers)
{
LoadWirelessStatusIndicatorSpriteGfx();
CreateWirelessStatusIndicatorSprite(8, 8);
}
}
}
void LinkContestTryHideWirelessIndicator(void)
{
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)
{
if (gReceivedRemoteLinkPlayers)
DestroyWirelessStatusIndicatorSprite();
}
}
bool8 IsContestWithRSPlayer(void)
{
if (gLinkContestFlags & LINK_CONTEST_FLAG_HAS_RS_PLAYER)
return TRUE;
else
return FALSE;
}
void ClearLinkContestFlags(void)
{
gLinkContestFlags = 0;
}
bool8 IsWirelessContest(void)
{
if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)
return TRUE;
else
return FALSE;
}