2017-09-30 16:12:35 +02:00
|
|
|
#include "global.h"
|
2017-12-05 18:55:48 +01:00
|
|
|
#include "overworld.h"
|
2017-11-19 22:48:46 +01:00
|
|
|
#include "berry_blender.h"
|
2017-11-04 22:40:36 +01:00
|
|
|
#include "bg.h"
|
|
|
|
#include "window.h"
|
|
|
|
#include "task.h"
|
|
|
|
#include "sprite.h"
|
2017-11-18 16:11:34 +01:00
|
|
|
#include "sound.h"
|
|
|
|
#include "m4a.h"
|
|
|
|
#include "bg.h"
|
|
|
|
#include "palette.h"
|
|
|
|
#include "decompress.h"
|
2019-09-09 03:07:54 +02:00
|
|
|
#include "malloc.h"
|
2017-11-18 16:11:34 +01:00
|
|
|
#include "gpu_regs.h"
|
|
|
|
#include "text.h"
|
2018-07-16 20:23:05 +02:00
|
|
|
#include "text_window.h"
|
2017-11-18 16:11:34 +01:00
|
|
|
#include "event_data.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "link.h"
|
2020-08-24 20:52:33 +02:00
|
|
|
#include "link_rfu.h"
|
2017-11-18 16:11:34 +01:00
|
|
|
#include "item_menu_icons.h"
|
|
|
|
#include "berry.h"
|
2017-11-19 22:48:46 +01:00
|
|
|
#include "item.h"
|
2017-11-18 16:11:34 +01:00
|
|
|
#include "string_util.h"
|
2017-11-18 21:38:57 +01:00
|
|
|
#include "international_string_util.h"
|
2017-12-05 19:27:33 +01:00
|
|
|
#include "random.h"
|
2017-11-19 22:48:46 +01:00
|
|
|
#include "menu.h"
|
|
|
|
#include "pokeblock.h"
|
|
|
|
#include "trig.h"
|
|
|
|
#include "tv.h"
|
2018-03-02 10:21:12 +01:00
|
|
|
#include "item_menu.h"
|
2018-05-01 15:33:13 +02:00
|
|
|
#include "battle_records.h"
|
2018-11-07 19:35:31 +01:00
|
|
|
#include "graphics.h"
|
2018-11-19 01:03:14 +01:00
|
|
|
#include "new_game.h"
|
2019-02-27 04:04:44 +01:00
|
|
|
#include "save.h"
|
2020-08-24 20:52:33 +02:00
|
|
|
#include "strings.h"
|
|
|
|
#include "constants/game_stat.h"
|
|
|
|
#include "constants/items.h"
|
2019-04-04 23:05:46 +02:00
|
|
|
#include "constants/rgb.h"
|
2020-08-24 20:52:33 +02:00
|
|
|
#include "constants/songs.h"
|
2017-09-30 16:12:35 +02:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
enum {
|
|
|
|
SCORE_BEST,
|
|
|
|
SCORE_GOOD,
|
|
|
|
SCORE_MISS,
|
|
|
|
NUM_SCORE_TYPES,
|
|
|
|
};
|
|
|
|
|
|
|
|
// Redundant with the above. Reversed
|
|
|
|
enum {
|
|
|
|
PROXIMITY_MISS,
|
|
|
|
PROXIMITY_GOOD,
|
|
|
|
PROXIMITY_BEST,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
SCOREANIM_GOOD,
|
|
|
|
SCOREANIM_MISS,
|
|
|
|
SCOREANIM_BEST_FLASH,
|
|
|
|
SCOREANIM_BEST_STATIC,
|
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
enum {
|
|
|
|
PLAY_AGAIN_YES,
|
|
|
|
PLAY_AGAIN_NO,
|
|
|
|
CANT_PLAY_NO_BERRIES,
|
|
|
|
CANT_PLAY_NO_PKBLCK_SPACE
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
BLENDER_MISTER,
|
|
|
|
BLENDER_LADDIE,
|
|
|
|
BLENDER_LASSIE,
|
|
|
|
BLENDER_MASTER,
|
|
|
|
BLENDER_DUDE,
|
|
|
|
BLENDER_MISS
|
|
|
|
};
|
|
|
|
|
|
|
|
#define BLENDER_MAX_PLAYERS MAX_LINK_PLAYERS
|
|
|
|
|
|
|
|
#define NO_PLAYER 0xFF
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
#define MAX_PROGRESS_BAR 1000
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
#define MAX_ARROW_POS 0x10000 // By virtue of being u16
|
|
|
|
#define MIN_ARROW_SPEED 0x80
|
|
|
|
#define ARROW_FALL_ROTATION 0x5800 // The amount the arrow spins as it falls in at the start
|
|
|
|
|
|
|
|
// Tile offsets
|
|
|
|
#define PROGRESS_BAR_FILLED_TOP 0x80E9
|
|
|
|
#define PROGRESS_BAR_FILLED_BOTTOM 0x80F9
|
|
|
|
#define PROGRESS_BAR_EMPTY_TOP 0x80E1
|
|
|
|
#define PROGRESS_BAR_EMPTY_BOTTOM 0x80F1
|
|
|
|
#define RPM_DIGIT 0x8072
|
|
|
|
|
|
|
|
// Tile and palette tags
|
2020-08-23 00:20:22 +02:00
|
|
|
#define GFXTAG_COUNTDOWN_NUMBERS 12345
|
|
|
|
#define GFXTAG_START 12346
|
|
|
|
#define GFXTAG_PARTICLES 23456
|
|
|
|
#define GFXTAG_PLAYER_ARROW 46545
|
|
|
|
#define GFXTAG_SCORE_SYMBOLS 48888
|
|
|
|
|
|
|
|
#define PALTAG_PLAYER_ARROW 12312
|
|
|
|
#define PALTAG_MISC 46546
|
2017-09-30 16:12:35 +02:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Last berry that an NPC can put in
|
|
|
|
#define NUM_NPC_BERRIES ITEM_TO_BERRY(ITEM_ASPEAR_BERRY)
|
2017-09-30 16:12:35 +02:00
|
|
|
|
2017-11-18 16:11:34 +01:00
|
|
|
struct BlenderBerry
|
|
|
|
{
|
|
|
|
u16 itemId;
|
2018-09-01 22:03:21 +02:00
|
|
|
u8 name[BERRY_NAME_LENGTH + 1];
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 flavors[FLAVOR_COUNT + 1]; // 5 flavors, + 1 for feel
|
2017-11-18 16:11:34 +01:00
|
|
|
};
|
2017-09-30 16:12:35 +02:00
|
|
|
|
2017-11-19 22:48:46 +01:00
|
|
|
struct TimeAndRPM
|
|
|
|
{
|
|
|
|
u32 time;
|
2020-08-23 00:20:22 +02:00
|
|
|
u16 maxRPM;
|
2017-11-19 22:48:46 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct BlenderGameBlock
|
|
|
|
{
|
|
|
|
struct TimeAndRPM timeRPM;
|
2020-08-23 00:20:22 +02:00
|
|
|
u16 scores[BLENDER_MAX_PLAYERS][NUM_SCORE_TYPES];
|
2017-11-19 22:48:46 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct TvBlenderStruct
|
|
|
|
{
|
|
|
|
u8 name[11];
|
2017-11-27 20:03:41 +01:00
|
|
|
u8 pokeblockFlavor;
|
2017-11-19 22:48:46 +01:00
|
|
|
u8 pokeblockColor;
|
|
|
|
u8 pokeblockSheen;
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
struct BerryBlender
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
u8 mainState;
|
|
|
|
u8 loadGfxState;
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 unused0[66];
|
|
|
|
u16 unk0; // never read
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 scoreIconIds[NUM_SCORE_TYPES];
|
2017-11-18 16:11:34 +01:00
|
|
|
u16 arrowPos;
|
2020-08-23 00:20:22 +02:00
|
|
|
s16 speed;
|
|
|
|
u16 maxRPM;
|
|
|
|
u8 playerArrowSpriteIds[BLENDER_MAX_PLAYERS];
|
|
|
|
u8 playerArrowSpriteIds2[BLENDER_MAX_PLAYERS];
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 unused1[11];
|
2017-11-19 22:48:46 +01:00
|
|
|
u8 gameEndState;
|
2020-08-24 20:52:33 +02:00
|
|
|
u16 playerContinueResponses[BLENDER_MAX_PLAYERS];
|
|
|
|
u16 canceledPlayerCmd;
|
|
|
|
u16 canceledPlayerId;
|
2017-11-19 22:48:46 +01:00
|
|
|
u16 playAgainState;
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 slowdownTimer;
|
2017-11-18 16:11:34 +01:00
|
|
|
u16 chosenItemId[BLENDER_MAX_PLAYERS];
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 numPlayers;
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 unused2[16];
|
|
|
|
u16 arrowIdToPlayerId[BLENDER_MAX_PLAYERS];
|
|
|
|
u16 playerIdToArrowId[BLENDER_MAX_PLAYERS];
|
2017-11-19 22:48:46 +01:00
|
|
|
u8 yesNoAnswer;
|
|
|
|
u8 stringVar[100];
|
2017-11-18 16:11:34 +01:00
|
|
|
u32 gameFrameTime;
|
|
|
|
s32 framesToWait;
|
2020-08-24 20:52:33 +02:00
|
|
|
u32 unk1; // never read
|
|
|
|
u8 unused3[4];
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 playerToThrowBerry;
|
|
|
|
u16 progressBarValue;
|
|
|
|
u16 maxProgressBarValue;
|
2020-08-24 20:52:33 +02:00
|
|
|
u16 centerScale;
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
u16 bg_X;
|
|
|
|
u16 bg_Y;
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 opponentTaskIds[BLENDER_MAX_PLAYERS - 1];
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 perfectOpponents; // for debugging, NPCs will always hit Best
|
2020-08-23 00:20:22 +02:00
|
|
|
u16 scores[BLENDER_MAX_PLAYERS][NUM_SCORE_TYPES];
|
2017-11-19 22:48:46 +01:00
|
|
|
u8 playerPlaces[BLENDER_MAX_PLAYERS];
|
2017-11-18 16:11:34 +01:00
|
|
|
struct BgAffineSrcData bgAffineSrc;
|
2020-08-23 00:20:22 +02:00
|
|
|
u16 savedMusic;
|
2017-11-18 16:11:34 +01:00
|
|
|
struct BlenderBerry blendedBerries[BLENDER_MAX_PLAYERS];
|
2017-11-19 22:48:46 +01:00
|
|
|
struct TimeAndRPM smallBlock;
|
2020-08-24 20:52:33 +02:00
|
|
|
u32 linkPlayAgainState;
|
|
|
|
u8 ownRanking;
|
2017-11-19 22:48:46 +01:00
|
|
|
struct TvBlenderStruct tvBlender;
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 tilemapBuffers[2][BG_SCREEN_SIZE];
|
2017-11-18 16:11:34 +01:00
|
|
|
s16 textState;
|
|
|
|
void *tilesBuffer;
|
2017-11-19 22:48:46 +01:00
|
|
|
struct BlenderGameBlock gameBlock;
|
2017-11-18 16:11:34 +01:00
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void SetBgPos(void);
|
2020-08-23 00:20:22 +02:00
|
|
|
static void Task_HandleOpponent1(u8);
|
|
|
|
static void Task_HandleOpponent2(u8);
|
|
|
|
static void Task_HandleOpponent3(u8);
|
|
|
|
static void Task_HandleBerryMaster(u8);
|
2020-08-24 20:52:33 +02:00
|
|
|
static void Task_PlayPokeblockFanfare(u8);
|
2020-08-23 00:20:22 +02:00
|
|
|
static void SpriteCB_PlayerArrow(struct Sprite *);
|
|
|
|
static void SpriteCB_ScoreSymbol(struct Sprite *);
|
|
|
|
static void SpriteCB_CountdownNumber(struct Sprite *);
|
|
|
|
static void SpriteCB_Start(struct Sprite *);
|
|
|
|
static void SpriteCB_ScoreSymbolBest(struct Sprite *);
|
2020-08-24 20:52:33 +02:00
|
|
|
static void InitLocalPlayers(u8);
|
|
|
|
static void CB2_LoadBerryBlender(void);
|
|
|
|
static void UpdateBlenderCenter(void);
|
2020-08-23 00:20:22 +02:00
|
|
|
static bool32 Blender_PrintText(s16 *, const u8 *, s32 );
|
|
|
|
static void StartBlender(void);
|
|
|
|
static void CB2_StartBlenderLink(void);
|
|
|
|
static void CB2_StartBlenderLocal(void);
|
|
|
|
static void Blender_DummiedOutFunc(s16, s16);
|
|
|
|
static void CB2_PlayBlender(void);
|
|
|
|
static void DrawBlenderCenter(struct BgAffineSrcData *);
|
2020-08-24 20:52:33 +02:00
|
|
|
static bool8 UpdateBlenderLandScreenShake(void);
|
|
|
|
static void SetPlayerIdMaps(void);
|
|
|
|
static void PrintPlayerNames(void);
|
2020-08-23 00:20:22 +02:00
|
|
|
static void InitBlenderBgs(void);
|
2020-08-24 20:52:33 +02:00
|
|
|
static void SetPlayerBerryData(u8, u16);
|
2020-08-23 00:20:22 +02:00
|
|
|
static void Blender_AddTextPrinter(u8, const u8 *, u8, u8, s32, s32);
|
2020-08-24 20:52:33 +02:00
|
|
|
static void ResetLinkCmds(void);
|
2020-08-23 00:20:22 +02:00
|
|
|
static void CreateParticleSprites(void);
|
2020-08-24 20:52:33 +02:00
|
|
|
static void ShakeBgCoordForHit(s16*, u16);
|
2020-08-23 00:20:22 +02:00
|
|
|
static void TryUpdateProgressBar(u16, u16);
|
|
|
|
static void UpdateRPM(u16);
|
2020-08-24 20:52:33 +02:00
|
|
|
static void RestoreBgCoords(void);
|
|
|
|
static void ProcessLinkPlayerCmds(void);
|
|
|
|
static void CB2_EndBlenderGame(void);
|
2020-08-23 00:20:22 +02:00
|
|
|
static bool8 PrintBlendingRanking(void);
|
|
|
|
static bool8 PrintBlendingResults(void);
|
2020-08-24 20:52:33 +02:00
|
|
|
static void CB2_CheckPlayAgainLocal(void);
|
|
|
|
static void CB2_CheckPlayAgainLink(void);
|
2020-08-23 00:20:22 +02:00
|
|
|
static void UpdateProgressBar(u16, u16);
|
2020-08-24 20:52:33 +02:00
|
|
|
static void PrintMadePokeblockString(struct Pokeblock *, u8 *);
|
2020-08-23 00:20:22 +02:00
|
|
|
static bool32 TryAddContestLinkTvShow(struct Pokeblock *, struct TvBlenderStruct *);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
EWRAM_DATA static struct BerryBlender *sBerryBlender = NULL;
|
2020-08-24 20:52:33 +02:00
|
|
|
EWRAM_DATA static s32 sDebug_PokeblockFactorFlavors[FLAVOR_COUNT] = {0};
|
|
|
|
EWRAM_DATA static s32 sDebug_PokeblockFactorFlavorsAfterRPM[FLAVOR_COUNT] = {0};
|
|
|
|
EWRAM_DATA static u32 sDebug_PokeblockFactorRPM = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static s16 sPokeblockFlavors[FLAVOR_COUNT + 1]; // + 1 for feel
|
|
|
|
static s16 sPokeblockPresentFlavors[FLAVOR_COUNT + 1];
|
|
|
|
static s16 sDebug_MaxRPMStage;
|
|
|
|
static s16 sDebug_GameTimeStage;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2018-11-19 01:03:14 +01:00
|
|
|
u8 gInGameOpponentsNo;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const u16 sBlenderCenter_Pal[] = INCBIN_U16("graphics/berry_blender/center.gbapal");
|
|
|
|
static const u8 sBlenderCenter_Tilemap[] = INCBIN_U8("graphics/berry_blender/center_map.bin");
|
|
|
|
static const u16 sBlenderOuter_Pal[] = INCBIN_U16("graphics/berry_blender/outer.gbapal");
|
2017-11-04 22:40:36 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static const u16 sUnused_Pal[] = INCBIN_U16("graphics/berry_blender/unused.gbapal");
|
|
|
|
static const u16 sEmpty_Pal[16 * 14] = {0};
|
2017-11-04 22:40:36 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// unused text
|
2017-11-04 22:40:36 +01:00
|
|
|
static const u8 sUnusedText_YesNo[] = _("YES\nNO");
|
|
|
|
static const u8 sUnusedText_2[] = _("▶");
|
|
|
|
static const u8 sUnusedText_Space[] = _(" ");
|
|
|
|
static const u8 sUnusedText_Terminating[] = _("Terminating.");
|
|
|
|
static const u8 sUnusedText_LinkPartnerNotFound[] = _("Link partner(s) not found.\nPlease try again.\p");
|
|
|
|
|
2017-11-19 22:48:46 +01:00
|
|
|
static const u8 sText_BerryBlenderStart[] = _("Starting up the BERRY BLENDER.\pPlease select a BERRY from your BAG\nto put in the BERRY BLENDER.\p");
|
|
|
|
static const u8 sText_NewParagraph[] = _("\p");
|
|
|
|
static const u8 sText_WasMade[] = _(" was made!");
|
2017-11-04 22:40:36 +01:00
|
|
|
static const u8 sText_Mister[] = _("MISTER");
|
|
|
|
static const u8 sText_Laddie[] = _("LADDIE");
|
|
|
|
static const u8 sText_Lassie[] = _("LASSIE");
|
|
|
|
static const u8 sText_Master[] = _("MASTER");
|
|
|
|
static const u8 sText_Dude[] = _("DUDE");
|
|
|
|
static const u8 sText_Miss[] = _("MISS");
|
|
|
|
|
2017-11-19 22:48:46 +01:00
|
|
|
static const u8* const sBlenderOpponentsNames[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
[BLENDER_MISTER] = sText_Mister,
|
|
|
|
[BLENDER_LADDIE] = sText_Laddie,
|
|
|
|
[BLENDER_LASSIE] = sText_Lassie,
|
|
|
|
[BLENDER_MASTER] = sText_Master,
|
|
|
|
[BLENDER_DUDE] = sText_Dude,
|
|
|
|
[BLENDER_MISS] = sText_Miss
|
2017-11-18 16:11:34 +01:00
|
|
|
};
|
|
|
|
|
2017-11-12 18:41:04 +01:00
|
|
|
static const u8 sText_PressAToStart[] = _("Press the A Button to start.");
|
2017-11-04 22:40:36 +01:00
|
|
|
static const u8 sText_PleaseWaitAWhile[] = _("Please wait a while.");
|
2017-11-19 22:48:46 +01:00
|
|
|
static const u8 sText_CommunicationStandby[] = _("Communication standby…");
|
|
|
|
static const u8 sText_WouldLikeToBlendAnotherBerry[] = _("Would you like to blend another BERRY?");
|
2018-12-07 16:41:08 +01:00
|
|
|
static const u8 sText_RunOutOfBerriesForBlending[] = _("You've run out of BERRIES for\nblending in the BERRY BLENDER.\p");
|
2017-11-19 22:48:46 +01:00
|
|
|
static const u8 sText_YourPokeblockCaseIsFull[] = _("Your {POKEBLOCK} CASE is full.\p");
|
|
|
|
static const u8 sText_HasNoBerriesToPut[] = _(" has no BERRIES to put in\nthe BERRY BLENDER.");
|
2018-12-07 16:41:08 +01:00
|
|
|
static const u8 sText_ApostropheSPokeblockCaseIsFull[] = _("'s {POKEBLOCK} CASE is full.\p");
|
2017-11-19 22:48:46 +01:00
|
|
|
static const u8 sText_BlendingResults[] = _("RESULTS OF BLENDING");
|
2017-11-04 22:40:36 +01:00
|
|
|
static const u8 sText_BerryUsed[] = _("BERRY USED");
|
2017-11-19 22:48:46 +01:00
|
|
|
static const u8 sText_SpaceBerry[] = _(" BERRY");
|
|
|
|
static const u8 sText_Time[] = _("Time:");
|
|
|
|
static const u8 sText_Min[] = _(" min. ");
|
|
|
|
static const u8 sText_Sec[] = _(" sec.");
|
|
|
|
static const u8 sText_MaximumSpeed[] = _("MAXIMUM SPEED");
|
|
|
|
static const u8 sText_RPM[] = _(" RPM");
|
|
|
|
static const u8 sText_Dot[] = _(".");
|
|
|
|
static const u8 sText_NewLine[] = _("\n");
|
2017-11-04 22:40:36 +01:00
|
|
|
static const u8 sText_Space[] = _(" ");
|
2017-11-19 22:48:46 +01:00
|
|
|
static const u8 sText_Ranking[] = _("RANKING");
|
|
|
|
static const u8 sText_TheLevelIs[] = _("The level is ");
|
|
|
|
static const u8 sText_TheFeelIs[] = _(", and the feel is ");
|
|
|
|
static const u8 sText_Dot2[] = _(".");
|
2017-11-04 22:40:36 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct BgTemplate sBgTemplates[3] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
{
|
|
|
|
.bg = 0,
|
|
|
|
.charBaseIndex = 3,
|
|
|
|
.mapBaseIndex = 31,
|
|
|
|
.screenSize = 0,
|
|
|
|
.paletteMode = 0,
|
|
|
|
.priority = 0,
|
|
|
|
.baseTile = 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.bg = 1,
|
|
|
|
.charBaseIndex = 2,
|
|
|
|
.mapBaseIndex = 12,
|
|
|
|
.screenSize = 0,
|
|
|
|
.paletteMode = 0,
|
|
|
|
.priority = 1,
|
|
|
|
.baseTile = 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.bg = 2,
|
|
|
|
.charBaseIndex = 0,
|
|
|
|
.mapBaseIndex = 8,
|
|
|
|
.screenSize = 1,
|
|
|
|
.paletteMode = 1,
|
|
|
|
.priority = 0,
|
|
|
|
.baseTile = 0,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct WindowTemplate sWindowTemplates[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2018-09-02 16:14:23 +02:00
|
|
|
{
|
2018-10-27 00:53:07 +02:00
|
|
|
.bg = 0,
|
2018-09-02 16:14:23 +02:00
|
|
|
.tilemapLeft = 1,
|
|
|
|
.tilemapTop = 6,
|
|
|
|
.width = 7,
|
|
|
|
.height = 2,
|
|
|
|
.paletteNum = 14,
|
|
|
|
.baseBlock = 0x28,
|
|
|
|
},
|
|
|
|
{
|
2018-10-27 00:53:07 +02:00
|
|
|
.bg = 0,
|
2018-09-02 16:14:23 +02:00
|
|
|
.tilemapLeft = 22,
|
|
|
|
.tilemapTop = 6,
|
|
|
|
.width = 7,
|
|
|
|
.height = 2,
|
|
|
|
.paletteNum = 14,
|
|
|
|
.baseBlock = 0x36,
|
|
|
|
},
|
|
|
|
{
|
2018-10-27 00:53:07 +02:00
|
|
|
.bg = 0,
|
2018-09-02 16:14:23 +02:00
|
|
|
.tilemapLeft = 1,
|
|
|
|
.tilemapTop = 12,
|
|
|
|
.width = 7,
|
|
|
|
.height = 2,
|
|
|
|
.paletteNum = 14,
|
|
|
|
.baseBlock = 0x44,
|
|
|
|
},
|
|
|
|
{
|
2018-10-27 00:53:07 +02:00
|
|
|
.bg = 0,
|
2018-09-02 16:14:23 +02:00
|
|
|
.tilemapLeft = 22,
|
|
|
|
.tilemapTop = 12,
|
|
|
|
.width = 7,
|
|
|
|
.height = 2,
|
|
|
|
.paletteNum = 14,
|
|
|
|
.baseBlock = 0x52,
|
|
|
|
},
|
|
|
|
{
|
2018-10-27 00:53:07 +02:00
|
|
|
.bg = 0,
|
2018-09-02 16:14:23 +02:00
|
|
|
.tilemapLeft = 2,
|
|
|
|
.tilemapTop = 15,
|
|
|
|
.width = 27,
|
|
|
|
.height = 4,
|
|
|
|
.paletteNum = 14,
|
|
|
|
.baseBlock = 0x60,
|
|
|
|
},
|
|
|
|
{
|
2018-10-27 00:53:07 +02:00
|
|
|
.bg = 0,
|
2018-09-02 16:14:23 +02:00
|
|
|
.tilemapLeft = 5,
|
|
|
|
.tilemapTop = 3,
|
|
|
|
.width = 21,
|
|
|
|
.height = 14,
|
|
|
|
.paletteNum = 14,
|
|
|
|
.baseBlock = 0x60,
|
|
|
|
},
|
2017-11-04 22:40:36 +01:00
|
|
|
DUMMY_WIN_TEMPLATE
|
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static const struct WindowTemplate sYesNoWindowTemplate_ContinuePlaying =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2018-10-27 00:53:07 +02:00
|
|
|
.bg = 0,
|
2018-09-02 16:14:23 +02:00
|
|
|
.tilemapLeft = 21,
|
|
|
|
.tilemapTop = 9,
|
|
|
|
.width = 5,
|
|
|
|
.height = 4,
|
|
|
|
.paletteNum = 14,
|
|
|
|
.baseBlock = 0xCC
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const s8 sPlayerArrowQuadrant[BLENDER_MAX_PLAYERS][2] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
{-1, -1},
|
|
|
|
{ 1, -1},
|
|
|
|
{-1, 1},
|
|
|
|
{ 1, 1}
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const u8 sPlayerArrowPos[BLENDER_MAX_PLAYERS][2] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
{ 72, 32},
|
|
|
|
{168, 32},
|
|
|
|
{ 72, 128},
|
|
|
|
{168, 128}
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const u8 sPlayerIdMap[BLENDER_MAX_PLAYERS - 1][BLENDER_MAX_PLAYERS] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
{NO_PLAYER, 0, 1, NO_PLAYER}, // 2 Players
|
2020-08-25 18:27:12 +02:00
|
|
|
{NO_PLAYER, 0, 1, 2}, // 3 Players
|
|
|
|
{ 0, 1, 2, 3} // 4 Players
|
2020-08-24 20:52:33 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Blender arrow positions:
|
|
|
|
//
|
|
|
|
// 0x0000 (limit 0x10000)
|
|
|
|
// . .
|
|
|
|
// . .
|
|
|
|
// 0x4000 . . 0xC000
|
|
|
|
// . .
|
|
|
|
// . .
|
|
|
|
// . .
|
|
|
|
// 0x8000
|
|
|
|
//
|
|
|
|
static const u16 sArrowStartPos[] = {
|
|
|
|
0,
|
|
|
|
MAX_ARROW_POS / 4 * 3, // 0xC000
|
|
|
|
MAX_ARROW_POS / 4, // 0x4000
|
|
|
|
MAX_ARROW_POS / 4 * 2 // 0x8000
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
2020-08-23 00:20:22 +02:00
|
|
|
static const u8 sArrowStartPosIds[BLENDER_MAX_PLAYERS - 1] = {1, 1, 0};
|
2020-08-24 20:52:33 +02:00
|
|
|
static const u8 sArrowHitRangeStart[BLENDER_MAX_PLAYERS] = {32, 224, 96, 160};
|
2017-11-04 22:40:36 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const TaskFunc sLocalOpponentTasks[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
Task_HandleOpponent1,
|
|
|
|
Task_HandleOpponent2,
|
|
|
|
Task_HandleOpponent3
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct OamData sOam_PlayerArrow =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
.y = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
2017-11-04 22:40:36 +01:00
|
|
|
.mosaic = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(32x32),
|
2017-11-04 22:40:36 +01:00
|
|
|
.x = 0,
|
|
|
|
.matrixNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
.size = SPRITE_SIZE(32x32),
|
2017-11-04 22:40:36 +01:00
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 1,
|
|
|
|
.paletteNum = 0,
|
|
|
|
.affineParam = 0,
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_TopLeft[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
ANIMCMD_FRAME(16, 5, .vFlip = TRUE, .hFlip = TRUE),
|
2017-11-04 22:40:36 +01:00
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_TopRight[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(16, 5, .vFlip = TRUE),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_BottomLeft[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_BottomRight[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(16, 5, 0, 0),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_TopLeft_Flash[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
ANIMCMD_FRAME(48, 2, .vFlip = TRUE, .hFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(32, 5, .vFlip = TRUE, .hFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(48, 3, .vFlip = TRUE, .hFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(16, 5, .vFlip = TRUE, .hFlip = TRUE),
|
2017-11-04 22:40:36 +01:00
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_TopRight_Flash[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(48, 2, .vFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(32, 5, .vFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(48, 3, .vFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(16, 5, .vFlip = TRUE),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_BottomLeft_Flash[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(48, 2, .hFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(32, 5, .hFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(48, 3, .hFlip = TRUE),
|
|
|
|
ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_BottomRight_Flash[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(48, 2, 0, 0),
|
|
|
|
ANIMCMD_FRAME(32, 5, 0, 0),
|
|
|
|
ANIMCMD_FRAME(48, 3, 0, 0),
|
|
|
|
ANIMCMD_FRAME(16, 5, 0, 0),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_TopLeft_Off[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
ANIMCMD_FRAME(0, 5, .vFlip = TRUE, .hFlip = TRUE),
|
2017-11-04 22:40:36 +01:00
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_TopRight_Off[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 5, .vFlip = TRUE),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_BottomLeft_Off[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_PlayerArrow_BottomRight_Off[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 5, 0, 0),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd *const sAnims_PlayerArrow[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sAnim_PlayerArrow_TopLeft,
|
|
|
|
sAnim_PlayerArrow_TopRight,
|
|
|
|
sAnim_PlayerArrow_BottomLeft,
|
|
|
|
sAnim_PlayerArrow_BottomRight,
|
|
|
|
sAnim_PlayerArrow_TopLeft_Flash,
|
|
|
|
sAnim_PlayerArrow_TopRight_Flash,
|
|
|
|
sAnim_PlayerArrow_BottomLeft_Flash,
|
|
|
|
sAnim_PlayerArrow_BottomRight_Flash,
|
|
|
|
sAnim_PlayerArrow_TopLeft_Off,
|
|
|
|
sAnim_PlayerArrow_TopRight_Off,
|
|
|
|
sAnim_PlayerArrow_BottomLeft_Off,
|
|
|
|
sAnim_PlayerArrow_BottomRight_Off
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteSheet sSpriteSheet_PlayerArrow =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
gBerryBlenderPlayerArrow_Gfx, 0x800, GFXTAG_PLAYER_ARROW
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2017-11-19 22:48:46 +01:00
|
|
|
static const struct SpritePalette sSpritePal_BlenderMisc =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
gBerryBlenderMiscPalette, PALTAG_MISC
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpritePalette sSpritePal_PlayerArrow =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
gBerryBlenderArrowPalette, PALTAG_PLAYER_ARROW
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_PlayerArrow =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
.tileTag = GFXTAG_PLAYER_ARROW,
|
|
|
|
.paletteTag = PALTAG_PLAYER_ARROW,
|
|
|
|
.oam = &sOam_PlayerArrow,
|
|
|
|
.anims = sAnims_PlayerArrow,
|
2017-11-04 22:40:36 +01:00
|
|
|
.images = NULL,
|
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
2020-08-23 00:20:22 +02:00
|
|
|
.callback = SpriteCB_PlayerArrow
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct OamData sOam_ScoreSymbols =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
.y = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
2017-11-04 22:40:36 +01:00
|
|
|
.mosaic = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(16x16),
|
2017-11-04 22:40:36 +01:00
|
|
|
.x = 0,
|
|
|
|
.matrixNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
.size = SPRITE_SIZE(16x16),
|
2017-11-04 22:40:36 +01:00
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 0,
|
|
|
|
.paletteNum = 0,
|
|
|
|
.affineParam = 0,
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_ScoreSymbols_Good[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 20),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_ScoreSymbols_Miss[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(4, 20, 1, 0),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_ScoreSymbols_BestFlash[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(8, 4),
|
|
|
|
ANIMCMD_FRAME(12, 4),
|
|
|
|
ANIMCMD_FRAME(8, 4),
|
|
|
|
ANIMCMD_FRAME(12, 4),
|
|
|
|
ANIMCMD_FRAME(8, 4),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_ScoreSymbols_BestStatic[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(8, 4),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd *const sAnims_ScoreSymbols[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
[SCOREANIM_GOOD] = sAnim_ScoreSymbols_Good,
|
|
|
|
[SCOREANIM_MISS] = sAnim_ScoreSymbols_Miss,
|
|
|
|
[SCOREANIM_BEST_FLASH] = sAnim_ScoreSymbols_BestFlash,
|
|
|
|
[SCOREANIM_BEST_STATIC] = sAnim_ScoreSymbols_BestStatic,
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteSheet sSpriteSheet_ScoreSymbols =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
gBerryBlenderScoreSymbols_Gfx, 0x200, GFXTAG_SCORE_SYMBOLS
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_ScoreSymbols =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
.tileTag = GFXTAG_SCORE_SYMBOLS,
|
|
|
|
.paletteTag = PALTAG_MISC,
|
|
|
|
.oam = &sOam_ScoreSymbols,
|
|
|
|
.anims = sAnims_ScoreSymbols,
|
2017-11-04 22:40:36 +01:00
|
|
|
.images = NULL,
|
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
2020-08-23 00:20:22 +02:00
|
|
|
.callback = SpriteCB_ScoreSymbol
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct OamData sOam_Particles =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
.y = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
2017-11-04 22:40:36 +01:00
|
|
|
.mosaic = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(8x8),
|
2017-11-04 22:40:36 +01:00
|
|
|
.x = 0,
|
|
|
|
.matrixNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
.size = SPRITE_SIZE(8x8),
|
2017-11-04 22:40:36 +01:00
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 1,
|
|
|
|
.paletteNum = 0,
|
|
|
|
.affineParam = 0,
|
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static const union AnimCmd sAnim_SparkleCrossToX[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 3),
|
|
|
|
ANIMCMD_FRAME(1, 4),
|
|
|
|
ANIMCMD_FRAME(3, 5),
|
|
|
|
ANIMCMD_FRAME(1, 4),
|
|
|
|
ANIMCMD_FRAME(0, 3),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static const union AnimCmd sAnim_SparkleXToCross[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 3),
|
|
|
|
ANIMCMD_FRAME(2, 4),
|
|
|
|
ANIMCMD_FRAME(4, 5),
|
|
|
|
ANIMCMD_FRAME(2, 4),
|
|
|
|
ANIMCMD_FRAME(0, 3),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static const union AnimCmd sAnim_SparkleFull[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 2),
|
|
|
|
ANIMCMD_FRAME(1, 2),
|
|
|
|
ANIMCMD_FRAME(2, 2),
|
|
|
|
ANIMCMD_FRAME(4, 4),
|
|
|
|
ANIMCMD_FRAME(3, 3),
|
|
|
|
ANIMCMD_FRAME(2, 2),
|
|
|
|
ANIMCMD_FRAME(1, 2),
|
|
|
|
ANIMCMD_FRAME(0, 2),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static const union AnimCmd sAnim_GreenArrow[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(5, 5, 1, 1),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static const union AnimCmd sAnim_GreenDot[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(6, 5, 1, 1),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd *const sAnims_Particles[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sAnim_SparkleCrossToX, // Only this effect is ever used, rest go unused
|
|
|
|
sAnim_SparkleXToCross,
|
|
|
|
sAnim_SparkleFull,
|
|
|
|
sAnim_GreenArrow,
|
|
|
|
sAnim_GreenDot,
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteSheet sSpriteSheet_Particles =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
gBerryBlenderParticles_Gfx, 0xE0, GFXTAG_PARTICLES
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_Particles =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
.tileTag = GFXTAG_PARTICLES,
|
|
|
|
.paletteTag = PALTAG_MISC,
|
|
|
|
.oam = &sOam_Particles,
|
|
|
|
.anims = sAnims_Particles,
|
2017-11-04 22:40:36 +01:00
|
|
|
.images = NULL,
|
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
|
|
.callback = SpriteCallbackDummy
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct OamData sOam_CountdownNumbers =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
.y = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
2017-11-04 22:40:36 +01:00
|
|
|
.mosaic = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(32x32),
|
2017-11-04 22:40:36 +01:00
|
|
|
.x = 0,
|
|
|
|
.matrixNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
.size = SPRITE_SIZE(32x32),
|
2017-11-04 22:40:36 +01:00
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 1,
|
|
|
|
.paletteNum = 0,
|
|
|
|
.affineParam = 0,
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_CountdownNumbers_3[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(32, 30),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_CountdownNumbers_2[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(16, 30),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_CountdownNumbers_1[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 30),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd *const sAnims_CountdownNumbers[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sAnim_CountdownNumbers_3,
|
|
|
|
sAnim_CountdownNumbers_2,
|
|
|
|
sAnim_CountdownNumbers_1,
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteSheet sSpriteSheet_CountdownNumbers =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
gBerryBlenderCountdownNumbers_Gfx, 0x600, GFXTAG_COUNTDOWN_NUMBERS
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_CountdownNumbers =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
.tileTag = GFXTAG_COUNTDOWN_NUMBERS,
|
|
|
|
.paletteTag = PALTAG_MISC,
|
|
|
|
.oam = &sOam_CountdownNumbers,
|
|
|
|
.anims = sAnims_CountdownNumbers,
|
2017-11-04 22:40:36 +01:00
|
|
|
.images = NULL,
|
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
2020-08-23 00:20:22 +02:00
|
|
|
.callback = SpriteCB_CountdownNumber
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct OamData sOam_Start =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
.y = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
2017-11-04 22:40:36 +01:00
|
|
|
.mosaic = 0,
|
2019-12-04 21:25:13 +01:00
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(64x32),
|
2017-11-04 22:40:36 +01:00
|
|
|
.x = 0,
|
|
|
|
.matrixNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
.size = SPRITE_SIZE(64x32),
|
2017-11-04 22:40:36 +01:00
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 1,
|
|
|
|
.paletteNum = 0,
|
|
|
|
.affineParam = 0,
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd sAnim_Start[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
ANIMCMD_FRAME(0, 30),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const union AnimCmd *const sAnims_Start[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sAnim_Start,
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteSheet sSpriteSheet_Start =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
gBerryBlenderStart_Gfx, 0x400, GFXTAG_START
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_Start =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
.tileTag = GFXTAG_START,
|
|
|
|
.paletteTag = PALTAG_MISC,
|
|
|
|
.oam = &sOam_Start,
|
|
|
|
.anims = sAnims_Start,
|
2017-11-04 22:40:36 +01:00
|
|
|
.images = NULL,
|
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
2020-08-23 00:20:22 +02:00
|
|
|
.callback = SpriteCB_Start
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
// Data for throwing the berries in at the start
|
|
|
|
// x, y, bounce speed, x speed, y speed
|
|
|
|
static const s16 sBerrySpriteData[][5] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
{-10, 20, 10, 2, 1},
|
|
|
|
{250, 20, 10, -2, 1},
|
|
|
|
{-10, 140, 10, 2, -1},
|
|
|
|
{250, 140, 10, -2, -1},
|
|
|
|
};
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// There are only 5 different berries the NPCs will ever use
|
|
|
|
// Each of these sets represents 3 berries chosen to be used by the NPCs
|
|
|
|
// If the player's berry is one of the 5 possible berries, a set is chosen that excludes it
|
|
|
|
static const u8 sOpponentBerrySets[NUM_NPC_BERRIES * 2][3] =
|
|
|
|
{
|
|
|
|
// These sets are used if the player chose one of the 5 NPC berries
|
|
|
|
{ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1, ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1, ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1}, // player chose Cheri Berry
|
|
|
|
{ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1, ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1, ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1}, // player chose Chesto Berry
|
2020-08-25 18:27:12 +02:00
|
|
|
{ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1, ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1}, // player chose Pecha Berry
|
2020-08-24 20:52:33 +02:00
|
|
|
{ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1}, // player chose Rawst Berry
|
|
|
|
{ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1, ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1}, // player chose Aspear Berry
|
|
|
|
|
|
|
|
// These sets are used if the player chose a different berry (set is selected by player's berry % 5)
|
|
|
|
{ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1, ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1, ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1}, // player chose Leppa, Figy, ...
|
|
|
|
{ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1, ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1, ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1}, // player chose Oran, Wiki, ...
|
|
|
|
{ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1, ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1}, // player chose Persim, Mago, ...
|
|
|
|
{ITEM_TO_BERRY(ITEM_RAWST_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHERI_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1}, // player chose Lum, Aguav, ...
|
|
|
|
{ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) - 1, ITEM_TO_BERRY(ITEM_CHESTO_BERRY) - 1, ITEM_TO_BERRY(ITEM_PECHA_BERRY) - 1}, // player chose Sitrus, Iapapa, ...
|
|
|
|
};
|
|
|
|
|
|
|
|
// Berry master's berries follow the same rules as above, but instead of explicitly listing
|
|
|
|
// the alternate sets if the player chooses one of these berries, it implicitly uses these berries - 5, i.e. Tamato - Nomel
|
|
|
|
static const u8 sBerryMasterBerries[] = {
|
|
|
|
ITEM_TO_BERRY(ITEM_SPELON_BERRY) - 1,
|
|
|
|
ITEM_TO_BERRY(ITEM_PAMTRE_BERRY) - 1,
|
|
|
|
ITEM_TO_BERRY(ITEM_WATMEL_BERRY) - 1,
|
|
|
|
ITEM_TO_BERRY(ITEM_DURIN_BERRY) - 1,
|
|
|
|
ITEM_TO_BERRY(ITEM_BELUE_BERRY) - 1
|
2017-11-04 22:40:36 +01:00
|
|
|
};
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
// "0 players" is link
|
|
|
|
static const u8 sNumPlayersToSpeedDivisor[] = {1, 1, 2, 3, 4};
|
2017-11-04 22:40:36 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Black pokeblocks will use one of these random combinations of flavors
|
|
|
|
static const u8 sBlackPokeblockFlavorFlags[] = {
|
|
|
|
(1 << FLAVOR_SOUR) | (1 << FLAVOR_BITTER) | (1 << FLAVOR_SWEET),
|
|
|
|
(1 << FLAVOR_SOUR) | (1 << FLAVOR_SWEET) | (1 << FLAVOR_DRY),
|
|
|
|
(1 << FLAVOR_SOUR) | (1 << FLAVOR_DRY) | (1 << FLAVOR_SPICY),
|
|
|
|
(1 << FLAVOR_SOUR) | (1 << FLAVOR_BITTER) | (1 << FLAVOR_DRY),
|
|
|
|
(1 << FLAVOR_SOUR) | (1 << FLAVOR_BITTER) | (1 << FLAVOR_SPICY),
|
|
|
|
(1 << FLAVOR_BITTER) | (1 << FLAVOR_SWEET) | (1 << FLAVOR_DRY),
|
|
|
|
(1 << FLAVOR_BITTER) | (1 << FLAVOR_SWEET) | (1 << FLAVOR_SPICY),
|
|
|
|
(1 << FLAVOR_BITTER) | (1 << FLAVOR_DRY) | (1 << FLAVOR_SPICY),
|
|
|
|
(1 << FLAVOR_SWEET) | (1 << FLAVOR_DRY) | (1 << FLAVOR_SPICY),
|
|
|
|
(1 << FLAVOR_SOUR) | (1 << FLAVOR_SWEET) | (1 << FLAVOR_SPICY),
|
|
|
|
};
|
2017-11-04 22:40:36 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static const u8 sUnused[] =
|
2017-11-04 22:40:36 +01:00
|
|
|
{
|
|
|
|
0xfe, 0x02, 0x02, 0xce, 0xd0, 0x37, 0x44, 0x07, 0x1f, 0x0c, 0x10,
|
|
|
|
0x00, 0xff, 0xfe, 0x91, 0x72, 0xce, 0xd0, 0x37, 0x44, 0x07, 0x1f,
|
|
|
|
0x0c, 0x10, 0x00, 0xff, 0x06, 0x27, 0x02, 0xff, 0x00, 0x0c, 0x48,
|
|
|
|
0x02, 0xff, 0x00, 0x01, 0x1f, 0x02, 0xff, 0x00, 0x16, 0x37, 0x02,
|
|
|
|
0xff, 0x00, 0x0d, 0x50, 0x4b, 0x02, 0xff, 0x06, 0x06, 0x06, 0x06,
|
|
|
|
0x05, 0x03, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x02
|
|
|
|
};
|
|
|
|
|
2018-09-02 17:10:06 +02:00
|
|
|
static const struct WindowTemplate sBlenderRecordWindowTemplate =
|
|
|
|
{
|
2018-10-27 00:53:07 +02:00
|
|
|
.bg = 0,
|
2018-09-02 17:10:06 +02:00
|
|
|
.tilemapLeft = 6,
|
|
|
|
.tilemapTop = 4,
|
|
|
|
.width = 18,
|
|
|
|
.height = 11,
|
|
|
|
.paletteNum = 15,
|
|
|
|
.baseBlock = 8
|
|
|
|
};
|
2017-09-30 16:12:35 +02:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void UpdateHitPitch(void)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
m4aMPlayPitchControl(&gMPlayInfo_SE2, 0xFFFF, 2 * (sBerryBlender->speed - MIN_ARROW_SPEED));
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void VBlankCB_BerryBlender(void)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
SetBgPos();
|
2020-08-23 00:20:22 +02:00
|
|
|
SetBgAffine(2, sBerryBlender->bgAffineSrc.texX, sBerryBlender->bgAffineSrc.texY,
|
|
|
|
sBerryBlender->bgAffineSrc.scrX, sBerryBlender->bgAffineSrc.scrY,
|
|
|
|
sBerryBlender->bgAffineSrc.sx, sBerryBlender->bgAffineSrc.sy,
|
|
|
|
sBerryBlender->bgAffineSrc.alpha);
|
2017-11-18 16:11:34 +01:00
|
|
|
LoadOam();
|
|
|
|
ProcessSpriteCopyRequests();
|
|
|
|
TransferPlttBuffer();
|
|
|
|
}
|
|
|
|
|
2017-11-19 22:48:46 +01:00
|
|
|
static bool8 LoadBerryBlenderGfx(void)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->loadGfxState)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->tilesBuffer = AllocZeroed(GetDecompressedDataSize(gBerryBlenderCenter_Gfx) + 100);
|
|
|
|
LZDecompressWram(gBerryBlenderCenter_Gfx, sBerryBlender->tilesBuffer);
|
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2020-08-23 00:20:22 +02:00
|
|
|
CopyToBgTilemapBuffer(2, sBlenderCenter_Tilemap, 0x400, 0);
|
2017-11-18 16:11:34 +01:00
|
|
|
CopyBgTilemapBufferToVram(2);
|
2020-08-23 00:20:22 +02:00
|
|
|
LoadPalette(sBlenderCenter_Pal, 0, 0x100);
|
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2020-08-23 00:20:22 +02:00
|
|
|
LoadBgTiles(2, sBerryBlender->tilesBuffer, GetDecompressedDataSize(gBerryBlenderCenter_Gfx), 0);
|
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 3:
|
2020-08-23 00:20:22 +02:00
|
|
|
LZDecompressWram(gBerryBlenderOuter_Gfx, sBerryBlender->tilesBuffer);
|
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 4:
|
2020-08-23 00:20:22 +02:00
|
|
|
LoadBgTiles(1, sBerryBlender->tilesBuffer, GetDecompressedDataSize(gBerryBlenderOuter_Gfx), 0);
|
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 5:
|
2020-08-23 00:20:22 +02:00
|
|
|
LZDecompressWram(gBerryBlenderOuter_Tilemap, sBerryBlender->tilesBuffer);
|
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 6:
|
2020-08-23 00:20:22 +02:00
|
|
|
CopyToBgTilemapBuffer(1, sBerryBlender->tilesBuffer, GetDecompressedDataSize(gBerryBlenderOuter_Tilemap), 0);
|
2017-11-18 16:11:34 +01:00
|
|
|
CopyBgTilemapBufferToVram(1);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 7:
|
2020-08-23 00:20:22 +02:00
|
|
|
LoadPalette(sBlenderOuter_Pal, 0x80, 0x20);
|
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 8:
|
2020-08-23 00:20:22 +02:00
|
|
|
LoadSpriteSheet(&sSpriteSheet_PlayerArrow);
|
|
|
|
LoadSpriteSheet(&sSpriteSheet_Particles);
|
|
|
|
LoadSpriteSheet(&sSpriteSheet_ScoreSymbols);
|
|
|
|
sBerryBlender->loadGfxState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 9:
|
2020-08-23 00:20:22 +02:00
|
|
|
LoadSpriteSheet(&sSpriteSheet_CountdownNumbers);
|
|
|
|
LoadSpriteSheet(&sSpriteSheet_Start);
|
|
|
|
LoadSpritePalette(&sSpritePal_PlayerArrow);
|
2017-11-18 16:11:34 +01:00
|
|
|
LoadSpritePalette(&sSpritePal_BlenderMisc);
|
2020-08-23 00:20:22 +02:00
|
|
|
Free(sBerryBlender->tilesBuffer);
|
|
|
|
sBerryBlender->loadGfxState = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void DrawBlenderBg(void)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x1E, 0x14);
|
|
|
|
CopyBgTilemapBufferToVram(0);
|
|
|
|
ShowBg(0);
|
|
|
|
ShowBg(1);
|
|
|
|
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
|
|
|
|
ChangeBgX(0, 0, 0);
|
|
|
|
ChangeBgY(0, 0, 0);
|
|
|
|
ChangeBgX(1, 0, 0);
|
|
|
|
ChangeBgY(1, 0, 0);
|
|
|
|
}
|
|
|
|
|
2017-11-19 22:48:46 +01:00
|
|
|
static void InitBerryBlenderWindows(void)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (InitWindows(sWindowTemplates))
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
DeactivateAllTextPrinters();
|
|
|
|
for (i = 0; i < 5; i++)
|
2019-03-02 23:25:39 +01:00
|
|
|
FillWindowPixelBuffer(i, PIXEL_FILL(0));
|
2017-11-18 16:11:34 +01:00
|
|
|
|
|
|
|
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x1E, 0x14);
|
2019-04-01 00:59:52 +02:00
|
|
|
Menu_LoadStdPalAt(0xE0);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// gSpecialVar_0x8004 is the number of NPC opponents
|
|
|
|
// Set to 0 indicates it's a link blender
|
2017-11-18 16:11:34 +01:00
|
|
|
void DoBerryBlending(void)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender == NULL)
|
|
|
|
sBerryBlender = AllocZeroed(sizeof(*sBerryBlender));
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 0;
|
|
|
|
sBerryBlender->mainState = 0;
|
|
|
|
sBerryBlender->gameEndState = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
InitLocalPlayers(gSpecialVar_0x8004);
|
|
|
|
SetMainCallback2(CB2_LoadBerryBlender);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Show the blender screen initially and prompt to choose a berry
|
|
|
|
static void CB2_LoadBerryBlender(void)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->mainState)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
SetGpuReg(REG_OFFSET_DISPCNT, 0);
|
|
|
|
ResetSpriteData();
|
|
|
|
FreeAllSpritePalettes();
|
|
|
|
SetVBlankCallback(NULL);
|
|
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
2020-08-23 00:20:22 +02:00
|
|
|
InitBgsFromTemplates(1, sBgTemplates, ARRAY_COUNT(sBgTemplates));
|
|
|
|
SetBgTilemapBuffer(1, sBerryBlender->tilemapBuffers[0]);
|
|
|
|
SetBgTilemapBuffer(2, sBerryBlender->tilemapBuffers[1]);
|
2018-07-15 13:23:38 +02:00
|
|
|
LoadUserWindowBorderGfx(0, 1, 0xD0);
|
2018-06-17 16:48:58 +02:00
|
|
|
LoadMessageBoxGfx(0, 0x14, 0xF0);
|
2017-11-18 16:11:34 +01:00
|
|
|
InitBerryBlenderWindows();
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
|
|
|
sBerryBlender->maxProgressBarValue = 0;
|
|
|
|
sBerryBlender->progressBarValue = 0;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->centerScale = 80;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->bg_X = 0;
|
|
|
|
sBerryBlender->bg_Y = 0;
|
|
|
|
sBerryBlender->loadGfxState = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateBlenderCenter();
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (LoadBerryBlenderGfx())
|
|
|
|
{
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->playerArrowSpriteIds[i] = CreateSprite(&sSpriteTemplate_PlayerArrow, sPlayerArrowPos[i][0], sPlayerArrowPos[i][1], 1);
|
|
|
|
StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds[i]], i + 8);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers && gWirelessCommType)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2019-04-04 23:05:46 +02:00
|
|
|
LoadWirelessStatusIndicatorSpriteGfx();
|
2017-12-04 04:01:06 +01:00
|
|
|
CreateWirelessStatusIndicatorSprite(0, 0);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
SetVBlankCallback(VBlankCB_BerryBlender);
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
2021-02-24 17:01:02 +01:00
|
|
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_BLACK);
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateBlenderCenter();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 3:
|
2020-08-24 20:52:33 +02:00
|
|
|
DrawBlenderBg();
|
2017-11-18 16:11:34 +01:00
|
|
|
if (!gPaletteFade.active)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 4:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (Blender_PrintText(&sBerryBlender->textState, sText_BerryBlenderStart, GetPlayerTextSpeedDelay()))
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 5:
|
2021-02-24 17:01:02 +01:00
|
|
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Go to bag menu to choose berry, set callback to StartBlender
|
2017-11-18 16:11:34 +01:00
|
|
|
FreeAllWindowBuffers();
|
|
|
|
UnsetBgTilemapBuffer(2);
|
|
|
|
UnsetBgTilemapBuffer(1);
|
|
|
|
SetVBlankCallback(NULL);
|
2020-08-23 00:20:22 +02:00
|
|
|
ChooseBerryForMachine(StartBlender);
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
#define sTargetY data[0]
|
|
|
|
#define sX data[1]
|
|
|
|
#define sY data[2]
|
|
|
|
#define sBounceSpeed data[3]
|
|
|
|
#define sYUpSpeed data[4]
|
|
|
|
#define sBounces data[5]
|
|
|
|
#define sXSpeed data[6]
|
|
|
|
#define sYDownSpeed data[7]
|
|
|
|
|
|
|
|
// For throwing berries into the machine
|
|
|
|
static void SpriteCB_Berry(struct Sprite* sprite)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sprite->sX += sprite->sXSpeed;
|
|
|
|
sprite->sY -= sprite->sYUpSpeed;
|
|
|
|
sprite->sY += sprite->sYDownSpeed;
|
|
|
|
sprite->sTargetY += sprite->sYDownSpeed;
|
|
|
|
sprite->sYUpSpeed--;
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sprite->sTargetY < sprite->sY)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sprite->sBounceSpeed = sprite->sYUpSpeed = sprite->sBounceSpeed - 1;
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sprite->sBounces > 3)
|
2017-11-18 16:11:34 +01:00
|
|
|
DestroySprite(sprite);
|
|
|
|
else
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_BALL_TRAY_EXIT);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x = sprite->sX;
|
|
|
|
sprite->y = sprite->sY;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void SetBerrySpriteData(struct Sprite* sprite, s16 x, s16 y, s16 bounceSpeed, s16 xSpeed, s16 ySpeed)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sprite->sTargetY = y;
|
|
|
|
sprite->sX = x;
|
|
|
|
sprite->sY = y;
|
|
|
|
sprite->sBounceSpeed = bounceSpeed;
|
|
|
|
sprite->sYUpSpeed = 10;
|
|
|
|
sprite->sBounces = 0;
|
|
|
|
sprite->sXSpeed = xSpeed;
|
|
|
|
sprite->sYDownSpeed = ySpeed;
|
|
|
|
sprite->callback = SpriteCB_Berry;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
#undef sTargetY
|
|
|
|
#undef sX
|
|
|
|
#undef sY
|
|
|
|
#undef sBounceSpeed
|
|
|
|
#undef sYUpSpeed
|
|
|
|
#undef sBounces
|
|
|
|
#undef sXSpeed
|
|
|
|
#undef sYDownSpeed
|
|
|
|
|
|
|
|
static void CreateBerrySprite(u16 a0, u8 playerId)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 spriteId = CreateSpinningBerrySprite(a0 + FIRST_BERRY_INDEX - 10, 0, 80, playerId & 1);
|
|
|
|
SetBerrySpriteData(&gSprites[spriteId],
|
|
|
|
sBerrySpriteData[playerId][0],
|
|
|
|
sBerrySpriteData[playerId][1],
|
|
|
|
sBerrySpriteData[playerId][2],
|
|
|
|
sBerrySpriteData[playerId][3],
|
|
|
|
sBerrySpriteData[playerId][4]);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void ConvertItemToBlenderBerry(struct BlenderBerry* berry, u16 itemId)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
const struct Berry *berryInfo = GetBerryInfo(ITEM_TO_BERRY(itemId));
|
|
|
|
|
|
|
|
berry->itemId = itemId;
|
|
|
|
StringCopy(berry->name, berryInfo->name);
|
2017-11-27 20:03:41 +01:00
|
|
|
berry->flavors[FLAVOR_SPICY] = berryInfo->spicy;
|
|
|
|
berry->flavors[FLAVOR_DRY] = berryInfo->dry;
|
|
|
|
berry->flavors[FLAVOR_SWEET] = berryInfo->sweet;
|
|
|
|
berry->flavors[FLAVOR_BITTER] = berryInfo->bitter;
|
|
|
|
berry->flavors[FLAVOR_SOUR] = berryInfo->sour;
|
2020-08-24 20:52:33 +02:00
|
|
|
berry->flavors[FLAVOR_COUNT] = berryInfo->smoothness;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void InitLocalPlayers(u8 opponentsNum)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
switch (opponentsNum)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
case 0: // Link games have 0 in-game opponents
|
2017-11-18 16:11:34 +01:00
|
|
|
gInGameOpponentsNo = 0;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
gInGameOpponentsNo = 1;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->numPlayers = 2;
|
2017-11-18 16:11:34 +01:00
|
|
|
StringCopy(gLinkPlayers[0].name, gSaveBlock2Ptr->playerName);
|
|
|
|
|
2019-11-10 16:59:15 +01:00
|
|
|
if (!FlagGet(FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER))
|
2017-11-18 16:11:34 +01:00
|
|
|
StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[BLENDER_MASTER]);
|
|
|
|
else
|
|
|
|
StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[BLENDER_MISTER]);
|
|
|
|
|
|
|
|
gLinkPlayers[0].language = GAME_LANGUAGE;
|
|
|
|
gLinkPlayers[1].language = GAME_LANGUAGE;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
gInGameOpponentsNo = 2;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->numPlayers = 3;
|
2017-11-18 16:11:34 +01:00
|
|
|
StringCopy(gLinkPlayers[0].name, gSaveBlock2Ptr->playerName);
|
|
|
|
StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[BLENDER_DUDE]);
|
|
|
|
StringCopy(gLinkPlayers[2].name, sBlenderOpponentsNames[BLENDER_LASSIE]);
|
|
|
|
|
|
|
|
gLinkPlayers[0].language = GAME_LANGUAGE;
|
|
|
|
gLinkPlayers[1].language = GAME_LANGUAGE;
|
|
|
|
gLinkPlayers[2].language = GAME_LANGUAGE;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
gInGameOpponentsNo = 3;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->numPlayers = 4;
|
2017-11-18 16:11:34 +01:00
|
|
|
StringCopy(gLinkPlayers[0].name, gSaveBlock2Ptr->playerName);
|
|
|
|
StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[BLENDER_MISS]);
|
|
|
|
StringCopy(gLinkPlayers[2].name, sBlenderOpponentsNames[BLENDER_LADDIE]);
|
|
|
|
StringCopy(gLinkPlayers[3].name, sBlenderOpponentsNames[BLENDER_LASSIE]);
|
|
|
|
|
|
|
|
gLinkPlayers[0].language = GAME_LANGUAGE;
|
|
|
|
gLinkPlayers[1].language = GAME_LANGUAGE;
|
|
|
|
gLinkPlayers[2].language = GAME_LANGUAGE;
|
|
|
|
gLinkPlayers[3].language = GAME_LANGUAGE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void StartBlender(void)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
SetGpuReg(REG_OFFSET_DISPCNT, 0);
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender == NULL)
|
|
|
|
sBerryBlender = AllocZeroed(sizeof(*sBerryBlender));
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState = 0;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->unk1 = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->chosenItemId[i] = ITEM_NONE;
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
InitLocalPlayers(gSpecialVar_0x8004);
|
2017-11-18 16:11:34 +01:00
|
|
|
|
|
|
|
if (gSpecialVar_0x8004 == 0)
|
2020-08-23 00:20:22 +02:00
|
|
|
SetMainCallback2(CB2_StartBlenderLink);
|
2017-11-18 16:11:34 +01:00
|
|
|
else
|
2020-08-23 00:20:22 +02:00
|
|
|
SetMainCallback2(CB2_StartBlenderLocal);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void CB2_StartBlenderLink(void)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
s32 i, j;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->mainState)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-08-23 00:20:22 +02:00
|
|
|
InitBlenderBgs();
|
2019-10-11 10:14:09 +02:00
|
|
|
gLinkType = LINKTYPE_BERRY_BLENDER;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->slowdownTimer = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->playerContinueResponses[i] = 0;
|
2020-08-23 00:20:22 +02:00
|
|
|
for (j = 0; j < NUM_SCORE_TYPES; j++)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->scores[i][j] = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->playAgainState = 0;
|
|
|
|
sBerryBlender->maxRPM = 0;
|
|
|
|
sBerryBlender->loadGfxState = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (LoadBerryBlenderGfx())
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateBlenderCenter();
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->playerArrowSpriteIds2[i] = CreateSprite(&sSpriteTemplate_PlayerArrow, sPlayerArrowPos[i][0], sPlayerArrowPos[i][1], 1);
|
|
|
|
StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds2[i]], i + 8);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers && gWirelessCommType)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2019-04-04 23:05:46 +02:00
|
|
|
LoadWirelessStatusIndicatorSpriteGfx();
|
2017-12-04 04:01:06 +01:00
|
|
|
CreateWirelessStatusIndicatorSprite(0, 0);
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 3:
|
2021-02-24 17:01:02 +01:00
|
|
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_BLACK);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 4:
|
2020-08-24 20:52:33 +02:00
|
|
|
DrawBlenderBg();
|
2017-11-18 16:11:34 +01:00
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
2020-08-23 00:20:22 +02:00
|
|
|
Blender_PrintText(&sBerryBlender->textState, sText_CommunicationStandby, 0);
|
|
|
|
sBerryBlender->mainState = 8;
|
|
|
|
sBerryBlender->framesToWait = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 8:
|
2020-08-24 20:52:33 +02:00
|
|
|
// Send berry choice to link partners
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
|
|
|
sBerryBlender->playerToThrowBerry = 0;
|
|
|
|
ConvertItemToBlenderBerry(&sBerryBlender->blendedBerries[0], gSpecialVar_ItemId);
|
|
|
|
memcpy(gBlockSendBuffer, &sBerryBlender->blendedBerries[0], sizeof(struct BlenderBerry));
|
2020-08-13 09:09:47 +02:00
|
|
|
SetLinkStandbyCallback();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 9:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
|
|
|
if (GetMultiplayerId() == 0)
|
2020-08-13 09:09:47 +02:00
|
|
|
SendBlockRequest(4);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 20)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Wait for partners' berries
|
2019-02-22 07:40:11 +01:00
|
|
|
ClearDialogWindowAndFrameToTransparent(4, TRUE);
|
2020-06-08 06:45:06 +02:00
|
|
|
if (GetBlockReceivedStatus() == GetLinkPlayerCountAsBitFlags())
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
|
|
|
for (i = 0; i < GetLinkPlayerCount(); i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
memcpy(&sBerryBlender->blendedBerries[i], &gBlockRecvBuffer[i][0], sizeof(struct BlenderBerry));
|
|
|
|
sBerryBlender->chosenItemId[i] = sBerryBlender->blendedBerries[i].itemId;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ResetBlockReceivedFlags();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->numPlayers = GetLinkPlayerCount();
|
2017-11-18 16:11:34 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Throw 1 player's berry in
|
2017-11-18 16:11:34 +01:00
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->playerToThrowBerry == sPlayerIdMap[sBerryBlender->numPlayers - 2][i])
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateBerrySprite(sBerryBlender->chosenItemId[sBerryBlender->playerToThrowBerry], i);
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
|
|
|
sBerryBlender->playerToThrowBerry++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 12:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 60)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->playerToThrowBerry >= sBerryBlender->numPlayers)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
// Finished throwing berries in
|
|
|
|
sBerryBlender->mainState++;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->arrowPos = sArrowStartPos[sArrowStartPosIds[sBerryBlender->numPlayers - 2]] - ARROW_FALL_ROTATION;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
// Haven't finished throwing berries in, go back to prev step
|
|
|
|
sBerryBlender->mainState--;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 13:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_FALL);
|
2017-11-18 16:11:34 +01:00
|
|
|
ShowBg(2);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 14:
|
|
|
|
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->arrowPos += 0x200;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->centerScale += 4;
|
|
|
|
if (sBerryBlender->centerScale > 255)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2021-04-15 09:00:01 +02:00
|
|
|
SetGpuRegBits(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2));
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->centerScale = 256;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->arrowPos = sArrowStartPos[sArrowStartPosIds[sBerryBlender->numPlayers - 2]];
|
|
|
|
sBerryBlender->framesToWait = 0;
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_TRUCK_DOOR);
|
2020-08-24 20:52:33 +02:00
|
|
|
SetPlayerIdMaps();
|
|
|
|
PrintPlayerNames();
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 15:
|
2020-08-24 20:52:33 +02:00
|
|
|
if (UpdateBlenderLandScreenShake())
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 16:
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateSprite(&sSpriteTemplate_CountdownNumbers, 120, -16, 3);
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
2020-08-24 20:52:33 +02:00
|
|
|
case 17:
|
|
|
|
// Wait here for the countdown
|
|
|
|
// State is progressed in SpriteCB_Start
|
|
|
|
break;
|
2017-11-18 16:11:34 +01:00
|
|
|
case 18:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 19:
|
2020-08-13 09:09:47 +02:00
|
|
|
SetLinkStandbyCallback();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
case 20:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
SetBerryBlenderLinkCallback();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 21:
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->speed = MIN_ARROW_SPEED;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameFrameTime = 0;
|
|
|
|
SetMainCallback2(CB2_PlayBlender);
|
2017-12-22 08:46:19 +01:00
|
|
|
if (GetCurrentMapMusic() != MUS_CYCLING)
|
2017-11-18 16:11:34 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->savedMusic = GetCurrentMapMusic();
|
2017-11-18 16:11:34 +01:00
|
|
|
}
|
2017-12-22 08:46:19 +01:00
|
|
|
PlayBGM(MUS_CYCLING);
|
2017-11-18 16:11:34 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y);
|
2017-11-18 16:11:34 +01:00
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
}
|
2017-11-18 21:38:57 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void InitBlenderBgs(void)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
SetGpuReg(REG_OFFSET_DISPCNT, 0);
|
|
|
|
|
|
|
|
ResetSpriteData();
|
|
|
|
FreeAllSpritePalettes();
|
|
|
|
ResetTasks();
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
SetVBlankCallback(VBlankCB_BerryBlender);
|
2017-11-18 21:38:57 +01:00
|
|
|
|
|
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
2020-08-23 00:20:22 +02:00
|
|
|
InitBgsFromTemplates(1, sBgTemplates, ARRAY_COUNT(sBgTemplates));
|
2017-11-18 21:38:57 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
SetBgTilemapBuffer(1, sBerryBlender->tilemapBuffers[0]);
|
|
|
|
SetBgTilemapBuffer(2, sBerryBlender->tilemapBuffers[1]);
|
2018-07-15 13:23:38 +02:00
|
|
|
LoadUserWindowBorderGfx(0, 1, 0xD0);
|
2018-06-17 16:48:58 +02:00
|
|
|
LoadMessageBoxGfx(0, 0x14, 0xF0);
|
2017-11-18 21:38:57 +01:00
|
|
|
InitBerryBlenderWindows();
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->unk0 = 0;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->speed = 0;
|
|
|
|
sBerryBlender->arrowPos = 0;
|
|
|
|
sBerryBlender->maxRPM = 0;
|
|
|
|
sBerryBlender->bg_X = 0;
|
|
|
|
sBerryBlender->bg_Y = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static u8 GetArrowProximity(u16 arrowPos, u8 playerId)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u32 pos = (arrowPos / 256) + 24;
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 arrowId = sBerryBlender->playerIdToArrowId[playerId];
|
|
|
|
u32 hitRangeStart = sArrowHitRangeStart[arrowId];
|
2017-11-18 21:38:57 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (pos >= hitRangeStart && pos < hitRangeStart + 48)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (pos >= hitRangeStart + 20 && pos < hitRangeStart + 28)
|
2020-08-23 00:20:22 +02:00
|
|
|
return PROXIMITY_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
else
|
2020-08-23 00:20:22 +02:00
|
|
|
return PROXIMITY_GOOD;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
return PROXIMITY_MISS;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void SetOpponentsBerryData(u16 playerBerryItemId, u8 playersNum, struct BlenderBerry* playerBerry)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
u16 opponentSetId = 0;
|
|
|
|
u16 opponentBerryId;
|
2020-08-24 20:52:33 +02:00
|
|
|
u16 berryMasterDiff;
|
2017-11-18 21:38:57 +01:00
|
|
|
u16 i;
|
|
|
|
|
|
|
|
if (playerBerryItemId == ITEM_ENIGMA_BERRY)
|
|
|
|
{
|
2017-11-27 20:03:41 +01:00
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2017-11-27 20:03:41 +01:00
|
|
|
if (playerBerry->flavors[opponentSetId] > playerBerry->flavors[i])
|
2017-11-18 21:38:57 +01:00
|
|
|
opponentSetId = i;
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
opponentSetId += NUM_NPC_BERRIES;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
opponentSetId = ITEM_TO_BERRY(playerBerryItemId) - 1;
|
2020-08-24 20:52:33 +02:00
|
|
|
if (opponentSetId >= NUM_NPC_BERRIES)
|
|
|
|
opponentSetId = (opponentSetId % NUM_NPC_BERRIES) + NUM_NPC_BERRIES;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
for (i = 0; i < playersNum - 1; i++)
|
|
|
|
{
|
|
|
|
opponentBerryId = sOpponentBerrySets[opponentSetId][i];
|
2020-08-24 20:52:33 +02:00
|
|
|
berryMasterDiff = ITEM_TO_BERRY(playerBerryItemId) - ITEM_TO_BERRY(ITEM_SPELON_BERRY);
|
2019-11-10 16:59:15 +01:00
|
|
|
if (!FlagGet(FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER) && gSpecialVar_0x8004 == 1)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
opponentSetId %= ARRAY_COUNT(sBerryMasterBerries);
|
|
|
|
opponentBerryId = sBerryMasterBerries[opponentSetId];
|
|
|
|
|
|
|
|
// If the player's berry is any of the Berry Master's berries,
|
|
|
|
// then use the next lower set of berries
|
|
|
|
if (berryMasterDiff < ARRAY_COUNT(sBerryMasterBerries))
|
|
|
|
opponentBerryId -= ARRAY_COUNT(sBerryMasterBerries);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
SetPlayerBerryData(i + 1, opponentBerryId + FIRST_BERRY_INDEX);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void SetPlayerIdMaps(void)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
s32 i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->playerIdToArrowId[i] = NO_PLAYER;
|
|
|
|
sBerryBlender->arrowIdToPlayerId[i] = sPlayerIdMap[sBerryBlender->numPlayers - 2][i];
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
for (j = 0; j < BLENDER_MAX_PLAYERS; j++)
|
|
|
|
{
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->arrowIdToPlayerId[i] == j)
|
|
|
|
sBerryBlender->playerIdToArrowId[j] = i;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void PrintPlayerNames(void)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2017-11-19 22:48:46 +01:00
|
|
|
s32 i, xPos;
|
2020-08-24 20:52:33 +02:00
|
|
|
u32 playerId = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
u8 text[20];
|
|
|
|
|
|
|
|
if (gReceivedRemoteLinkPlayers)
|
2020-08-24 20:52:33 +02:00
|
|
|
playerId = GetMultiplayerId();
|
2017-11-18 21:38:57 +01:00
|
|
|
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->arrowIdToPlayerId[i] != NO_PLAYER)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->playerArrowSpriteIds[sBerryBlender->arrowIdToPlayerId[i]] = sBerryBlender->playerArrowSpriteIds2[i];
|
|
|
|
StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds[sBerryBlender->arrowIdToPlayerId[i]]], i);
|
2017-11-18 21:38:57 +01:00
|
|
|
|
|
|
|
text[0] = EOS;
|
2020-08-24 20:52:33 +02:00
|
|
|
StringCopy(text, gLinkPlayers[sBerryBlender->arrowIdToPlayerId[i]].name);
|
2017-11-19 22:48:46 +01:00
|
|
|
xPos = GetStringCenterAlignXOffset(1, text, 0x38);
|
2017-11-18 21:38:57 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (playerId == sBerryBlender->arrowIdToPlayerId[i])
|
|
|
|
Blender_AddTextPrinter(i, text, xPos, 1, 0, 2); // Highlight player's name in red
|
2017-11-18 21:38:57 +01:00
|
|
|
else
|
2017-11-19 22:48:46 +01:00
|
|
|
Blender_AddTextPrinter(i, text, xPos, 1, 0, 1);
|
2017-11-18 21:38:57 +01:00
|
|
|
|
|
|
|
PutWindowTilemap(i);
|
|
|
|
CopyWindowToVram(i, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void CB2_StartBlenderLocal(void)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
s32 i, j;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->mainState)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-06-06 22:46:19 +02:00
|
|
|
SetWirelessCommType0();
|
2020-08-23 00:20:22 +02:00
|
|
|
InitBlenderBgs();
|
2020-08-24 20:52:33 +02:00
|
|
|
SetPlayerBerryData(0, gSpecialVar_ItemId);
|
2020-08-23 00:20:22 +02:00
|
|
|
ConvertItemToBlenderBerry(&sBerryBlender->blendedBerries[0], gSpecialVar_ItemId);
|
|
|
|
SetOpponentsBerryData(gSpecialVar_ItemId, sBerryBlender->numPlayers, &sBerryBlender->blendedBerries[0]);
|
2017-11-18 21:38:57 +01:00
|
|
|
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->playerContinueResponses[i] = 0;
|
2020-08-23 00:20:22 +02:00
|
|
|
for (j = 0; j < NUM_SCORE_TYPES; j++)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->scores[i][j] = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->playAgainState = 0;
|
|
|
|
sBerryBlender->loadGfxState = 0;
|
2019-10-11 10:14:09 +02:00
|
|
|
gLinkType = LINKTYPE_BERRY_BLENDER;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (LoadBerryBlenderGfx())
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateBlenderCenter();
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->playerArrowSpriteIds2[i] = CreateSprite(&sSpriteTemplate_PlayerArrow, sPlayerArrowPos[i][0], sPlayerArrowPos[i][1], 1);
|
|
|
|
StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds2[i]], i + 8);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 3:
|
2021-02-24 17:01:02 +01:00
|
|
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_BLACK);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
|
|
|
sBerryBlender->framesToWait = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 4:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait == 2)
|
2020-08-24 20:52:33 +02:00
|
|
|
DrawBlenderBg();
|
2017-11-18 21:38:57 +01:00
|
|
|
if (!gPaletteFade.active)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState = 8;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 8:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState = 11;
|
|
|
|
sBerryBlender->playerToThrowBerry = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Throw 1 player's berry in
|
|
|
|
u32 playerId = sPlayerIdMap[sBerryBlender->numPlayers - 2][i];
|
|
|
|
if (sBerryBlender->playerToThrowBerry == playerId)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateBerrySprite(sBerryBlender->chosenItemId[sBerryBlender->playerToThrowBerry], i);
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
|
|
|
sBerryBlender->playerToThrowBerry++;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 12:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 60)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->playerToThrowBerry >= sBerryBlender->numPlayers)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Finished throwing berries in
|
|
|
|
sBerryBlender->arrowPos = sArrowStartPos[sArrowStartPosIds[sBerryBlender->numPlayers - 2]] - ARROW_FALL_ROTATION;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Haven't finished throwing berries in, go back to prev step
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState--;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 13:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2020-08-24 20:52:33 +02:00
|
|
|
SetPlayerIdMaps();
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_FALL);
|
2020-08-23 00:20:22 +02:00
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2017-11-18 21:38:57 +01:00
|
|
|
ShowBg(2);
|
|
|
|
break;
|
|
|
|
case 14:
|
|
|
|
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->arrowPos += 0x200;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->centerScale += 4;
|
|
|
|
if (sBerryBlender->centerScale > 255)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->centerScale = 256;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->arrowPos = sArrowStartPos[sArrowStartPosIds[sBerryBlender->numPlayers - 2]];
|
2021-04-15 09:00:01 +02:00
|
|
|
SetGpuRegBits(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2));
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_TRUCK_DOOR);
|
2020-08-24 20:52:33 +02:00
|
|
|
PrintPlayerNames();
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 15:
|
2020-08-24 20:52:33 +02:00
|
|
|
if (UpdateBlenderLandScreenShake())
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 16:
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateSprite(&sSpriteTemplate_CountdownNumbers, 120, -16, 3);
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
2020-08-24 20:52:33 +02:00
|
|
|
case 17:
|
|
|
|
// Wait here for the countdown
|
|
|
|
// State is progressed in SpriteCB_Start
|
|
|
|
break;
|
2017-11-18 21:38:57 +01:00
|
|
|
case 18:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 19:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 20:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
case 21:
|
2020-08-24 20:52:33 +02:00
|
|
|
ResetLinkCmds();
|
|
|
|
sBerryBlender->speed = MIN_ARROW_SPEED;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameFrameTime = 0;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->perfectOpponents = FALSE;
|
|
|
|
sBerryBlender->slowdownTimer = 0;
|
2020-08-23 00:20:22 +02:00
|
|
|
SetMainCallback2(CB2_PlayBlender);
|
2017-11-18 21:38:57 +01:00
|
|
|
|
|
|
|
if (gSpecialVar_0x8004 == 1)
|
|
|
|
{
|
2019-11-10 16:59:15 +01:00
|
|
|
if (!FlagGet(FLAG_HIDE_LILYCOVE_CONTEST_HALL_BLEND_MASTER))
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->opponentTaskIds[0] = CreateTask(Task_HandleBerryMaster, 10);
|
2017-11-18 21:38:57 +01:00
|
|
|
else
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->opponentTaskIds[0] = CreateTask(sLocalOpponentTasks[0], 10);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gSpecialVar_0x8004 > 1)
|
|
|
|
{
|
|
|
|
for (i = 0; i < gSpecialVar_0x8004; i++)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->opponentTaskIds[i] = CreateTask(sLocalOpponentTasks[i], 10 + i);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
2017-12-22 08:46:19 +01:00
|
|
|
if (GetCurrentMapMusic() != MUS_CYCLING)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->savedMusic = GetCurrentMapMusic();
|
2017-11-18 21:38:57 +01:00
|
|
|
|
2017-12-22 08:46:19 +01:00
|
|
|
PlayBGM(MUS_CYCLING);
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_BERRY_BLENDER);
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateHitPitch();
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y);
|
2017-11-18 21:38:57 +01:00
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void ResetLinkCmds(void)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
s32 i;
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gSendCmd[BLENDER_COMM_INPUT_STATE] = 0;
|
|
|
|
gSendCmd[BLENDER_COMM_SCORE] = 0;
|
|
|
|
gRecvCmds[i][BLENDER_COMM_INPUT_STATE] = 0;
|
|
|
|
gRecvCmds[i][BLENDER_COMM_SCORE] = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
#define tTimer data[0]
|
|
|
|
#define tDelay data[1]
|
|
|
|
#define tPlayerId data[2]
|
|
|
|
|
|
|
|
static void Task_OpponentMiss(u8 taskId)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if(++gTasks[taskId].tTimer > gTasks[taskId].tDelay)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[gTasks[taskId].tPlayerId][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_MISS;
|
2017-11-18 21:38:57 +01:00
|
|
|
DestroyTask(taskId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void CreateOpponentMissTask(u8 playerId, u8 delay)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 taskId = CreateTask(Task_OpponentMiss, 80);
|
|
|
|
gTasks[taskId].tDelay = delay;
|
|
|
|
gTasks[taskId].tPlayerId = playerId;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
#undef tTimer
|
|
|
|
#undef tDelay
|
|
|
|
#undef tPlayerId
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
#define tDidInput data[0]
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void Task_HandleOpponent1(u8 taskId)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (GetArrowProximity(sBerryBlender->arrowPos, 1) == PROXIMITY_BEST)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (!gTasks[taskId].tDidInput)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (!sBerryBlender->perfectOpponents)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
u8 rand = Random() / 655;
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->speed < 500)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
if (rand > 75)
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2017-11-18 21:38:57 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// BUG: Overrwrote above assignment. Opponent 1 can't get Best at low speed
|
2020-12-13 05:28:01 +01:00
|
|
|
#ifndef BUGFIX
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2020-12-13 05:28:01 +01:00
|
|
|
#endif
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (sBerryBlender->speed < 1500)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
if (rand > 80)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
u8 value = rand - 21;
|
|
|
|
if (value < 60)
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2017-11-18 21:38:57 +01:00
|
|
|
else if (rand < 10)
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateOpponentMissTask(1, 5);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (rand <= 90)
|
|
|
|
{
|
|
|
|
u8 value = rand - 71;
|
|
|
|
if (value < 20)
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2017-11-18 21:38:57 +01:00
|
|
|
else if (rand < 30)
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateOpponentMissTask(1, 5);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
gTasks[taskId].tDidInput = TRUE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gTasks[taskId].tDidInput = FALSE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void Task_HandleOpponent2(u8 taskId)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u32 var1 = (sBerryBlender->arrowPos + 0x1800) & 0xFFFF;
|
2020-08-24 20:52:33 +02:00
|
|
|
u32 arrowId = sBerryBlender->playerIdToArrowId[2] & 0xFF;
|
|
|
|
if ((var1 >> 8) > sArrowHitRangeStart[arrowId] + 20 && (var1 >> 8) < sArrowHitRangeStart[arrowId] + 40)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (!gTasks[taskId].tDidInput)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (!sBerryBlender->perfectOpponents)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
u8 rand = Random() / 655;
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->speed < 500)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
if (rand > 66)
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
u8 value;
|
|
|
|
if (rand > 65)
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
value = rand - 41;
|
|
|
|
if (value < 25)
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2017-11-18 21:38:57 +01:00
|
|
|
if (rand < 10)
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateOpponentMissTask(2, 5);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
gTasks[taskId].tDidInput = TRUE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[2][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
|
|
|
gTasks[taskId].tDidInput = TRUE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gTasks[taskId].tDidInput = FALSE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void Task_HandleOpponent3(u8 taskId)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
u32 var1 = (sBerryBlender->arrowPos + 0x1800) & 0xFFFF;
|
|
|
|
u32 arrowId = sBerryBlender->playerIdToArrowId[3] & 0xFF;
|
|
|
|
if ((var1 >> 8) > sArrowHitRangeStart[arrowId] + 20 && (var1 >> 8) < sArrowHitRangeStart[arrowId] + 40)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
if (gTasks[taskId].data[0] == 0)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (!sBerryBlender->perfectOpponents)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
u8 rand = (Random() / 655);
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->speed < 500)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
if (rand > 88)
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (rand > 60)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
s8 value = rand - 56; // makes me wonder what the original code was
|
|
|
|
u8 value2 = value;
|
|
|
|
if (value2 < 5)
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
if (rand < 5)
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateOpponentMissTask(3, 5);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
gTasks[taskId].tDidInput = TRUE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[3][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
|
|
|
gTasks[taskId].tDidInput = TRUE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gTasks[taskId].tDidInput = FALSE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void Task_HandleBerryMaster(u8 taskId)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (GetArrowProximity(sBerryBlender->arrowPos, 1) == PROXIMITY_BEST)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (!gTasks[taskId].tDidInput)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[1][BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
|
|
|
gTasks[taskId].tDidInput = TRUE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gTasks[taskId].tDidInput = FALSE;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
#undef tDidInput
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void CreateScoreSymbolSprite(u16 cmd, u8 arrowId)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
spriteId = CreateSprite(&sSpriteTemplate_ScoreSymbols,
|
|
|
|
sPlayerArrowPos[arrowId][0] - (10 * sPlayerArrowQuadrant[arrowId][0]),
|
|
|
|
sPlayerArrowPos[arrowId][1] - (10 * sPlayerArrowQuadrant[arrowId][1]),
|
2017-11-18 21:38:57 +01:00
|
|
|
1);
|
2020-08-23 00:20:22 +02:00
|
|
|
if (cmd == LINKCMD_BLENDER_SCORE_BEST)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
StartSpriteAnim(&gSprites[spriteId], SCOREANIM_BEST_FLASH);
|
|
|
|
gSprites[spriteId].callback = SpriteCB_ScoreSymbolBest;
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_ICE_STAIRS);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (cmd == LINKCMD_BLENDER_SCORE_GOOD)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
StartSpriteAnim(&gSprites[spriteId], SCOREANIM_GOOD);
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_SUCCESS);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (cmd == LINKCMD_BLENDER_SCORE_MISS)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
StartSpriteAnim(&gSprites[spriteId], SCOREANIM_MISS);
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_FAILURE);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateParticleSprites();
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void UpdateSpeedFromHit(u16 cmd)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateHitPitch();
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (cmd)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
case LINKCMD_BLENDER_SCORE_BEST:
|
|
|
|
if (sBerryBlender->speed < 1500) {
|
|
|
|
sBerryBlender->speed += (384 / sNumPlayersToSpeedDivisor[sBerryBlender->numPlayers]);
|
|
|
|
}
|
2017-11-18 21:38:57 +01:00
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->speed += (128 / sNumPlayersToSpeedDivisor[sBerryBlender->numPlayers]);
|
2020-08-24 20:52:33 +02:00
|
|
|
ShakeBgCoordForHit(&sBerryBlender->bg_X, (sBerryBlender->speed / 100) - 10);
|
|
|
|
ShakeBgCoordForHit(&sBerryBlender->bg_Y, (sBerryBlender->speed / 100) - 10);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
break;
|
2020-08-23 00:20:22 +02:00
|
|
|
case LINKCMD_BLENDER_SCORE_GOOD:
|
|
|
|
if (sBerryBlender->speed < 1500)
|
|
|
|
sBerryBlender->speed += (256 / sNumPlayersToSpeedDivisor[sBerryBlender->numPlayers]);
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
2020-08-23 00:20:22 +02:00
|
|
|
case LINKCMD_BLENDER_SCORE_MISS:
|
|
|
|
sBerryBlender->speed -= (256 / sNumPlayersToSpeedDivisor[sBerryBlender->numPlayers]);
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->speed < MIN_ARROW_SPEED)
|
|
|
|
sBerryBlender->speed = MIN_ARROW_SPEED;
|
2017-11-18 21:38:57 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Return TRUE if the received command matches the corresponding Link or RFU command
|
|
|
|
static bool32 CheckRecvCmdMatches(u16 recvCmd, u16 linkCmd, u16 rfuCmd)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers && gWirelessCommType)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if ((recvCmd & 0xFF00) == rfuCmd)
|
2017-11-18 21:38:57 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (recvCmd == linkCmd)
|
2017-11-18 21:38:57 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void UpdateOpponentScores(void)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
if (gSpecialVar_0x8004 != 0)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Local game, "send" players score to itself
|
|
|
|
if (gSendCmd[BLENDER_COMM_SCORE] != 0)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[0][BLENDER_COMM_SCORE] = gSendCmd[BLENDER_COMM_SCORE];
|
|
|
|
gRecvCmds[0][BLENDER_COMM_INPUT_STATE] = LINKCMD_BLENDER_SEND_KEYS;
|
|
|
|
gSendCmd[BLENDER_COMM_SCORE] = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// Local game, simulate NPCs sending keys
|
|
|
|
// Their actual inputs are handled by Task_HandleOpponent
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 1; i < BLENDER_MAX_PLAYERS; i++)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gRecvCmds[i][BLENDER_COMM_SCORE] != 0)
|
|
|
|
gRecvCmds[i][BLENDER_COMM_INPUT_STATE] = LINKCMD_BLENDER_SEND_KEYS;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < sBerryBlender->numPlayers; i++)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (CheckRecvCmdMatches(gRecvCmds[i][BLENDER_COMM_INPUT_STATE], LINKCMD_BLENDER_SEND_KEYS, RFUCMD_BLENDER_SEND_KEYS))
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
u32 arrowId = sBerryBlender->playerIdToArrowId[i];
|
|
|
|
if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_BEST)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateSpeedFromHit(LINKCMD_BLENDER_SCORE_BEST);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->progressBarValue += (sBerryBlender->speed / 55);
|
|
|
|
if (sBerryBlender->progressBarValue >= MAX_PROGRESS_BAR)
|
|
|
|
sBerryBlender->progressBarValue = MAX_PROGRESS_BAR;
|
|
|
|
CreateScoreSymbolSprite(LINKCMD_BLENDER_SCORE_BEST, arrowId);
|
|
|
|
sBerryBlender->scores[i][SCORE_BEST]++;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
else if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_GOOD)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateSpeedFromHit(LINKCMD_BLENDER_SCORE_GOOD);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->progressBarValue += (sBerryBlender->speed / 70);
|
|
|
|
CreateScoreSymbolSprite(LINKCMD_BLENDER_SCORE_GOOD, arrowId);
|
|
|
|
sBerryBlender->scores[i][SCORE_GOOD]++;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
else if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_MISS)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateScoreSymbolSprite(LINKCMD_BLENDER_SCORE_MISS, arrowId);
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateSpeedFromHit(LINKCMD_BLENDER_SCORE_MISS);
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->scores[i][SCORE_MISS] < 999)
|
|
|
|
sBerryBlender->scores[i][SCORE_MISS]++;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
2020-12-13 05:28:01 +01:00
|
|
|
// BUG: Should be [i][BLENDER_COMM_SCORE] below, not [BLENDER_COMM_SCORE][i]
|
2020-08-24 20:52:33 +02:00
|
|
|
// As a result the music tempo updates if any player misses, but only if 1 specific player hits
|
2020-12-13 05:28:01 +01:00
|
|
|
#ifdef BUGFIX
|
|
|
|
if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_MISS
|
|
|
|
|| gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_BEST
|
|
|
|
|| gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_GOOD)
|
|
|
|
#else
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gRecvCmds[i][BLENDER_COMM_SCORE] == LINKCMD_BLENDER_SCORE_MISS
|
|
|
|
|| gRecvCmds[BLENDER_COMM_SCORE][i] == LINKCMD_BLENDER_SCORE_BEST
|
|
|
|
|| gRecvCmds[BLENDER_COMM_SCORE][i] == LINKCMD_BLENDER_SCORE_GOOD)
|
2020-12-13 05:28:01 +01:00
|
|
|
#endif
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->speed > 1500)
|
|
|
|
m4aMPlayTempoControl(&gMPlayInfo_BGM, ((sBerryBlender->speed - 750) / 20) + 256);
|
2017-11-18 21:38:57 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
m4aMPlayTempoControl(&gMPlayInfo_BGM, 256);
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (gSpecialVar_0x8004 != 0)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < sBerryBlender->numPlayers; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
gRecvCmds[i][BLENDER_COMM_INPUT_STATE] = 0;
|
|
|
|
gRecvCmds[i][BLENDER_COMM_SCORE] = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void HandlePlayerInput(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 arrowId;
|
|
|
|
bool8 pressedA = FALSE;
|
2017-11-19 22:48:46 +01:00
|
|
|
u8 playerId = 0;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers)
|
2017-11-19 22:48:46 +01:00
|
|
|
playerId = GetMultiplayerId();
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
arrowId = sBerryBlender->playerIdToArrowId[playerId];
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->gameEndState == 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A && JOY_NEW(A_BUTTON))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (JOY_HELD_RAW(A_BUTTON | L_BUTTON) != (A_BUTTON | L_BUTTON))
|
2020-08-23 00:20:22 +02:00
|
|
|
pressedA = TRUE;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
else if (JOY_NEW(A_BUTTON))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
pressedA = TRUE;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (pressedA)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 proximity;
|
2020-08-24 20:52:33 +02:00
|
|
|
StartSpriteAnim(&gSprites[sBerryBlender->playerArrowSpriteIds[sBerryBlender->arrowIdToPlayerId[arrowId]]], arrowId + 4);
|
2020-08-23 00:20:22 +02:00
|
|
|
proximity = GetArrowProximity(sBerryBlender->arrowPos, playerId);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (proximity == PROXIMITY_BEST)
|
2020-08-24 20:52:33 +02:00
|
|
|
gSendCmd[BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_BEST;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (proximity == PROXIMITY_GOOD)
|
2020-08-24 20:52:33 +02:00
|
|
|
gSendCmd[BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_GOOD;
|
2017-11-19 22:48:46 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
gSendCmd[BLENDER_COMM_SCORE] = LINKCMD_BLENDER_SCORE_MISS;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
if (++sBerryBlender->slowdownTimer > 5)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->speed > MIN_ARROW_SPEED)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->speed--;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->slowdownTimer = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
if (gEnableContestDebugging && JOY_NEW(L_BUTTON))
|
|
|
|
sBerryBlender->perfectOpponents ^= 1;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void CB2_PlayBlender(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateBlenderCenter();
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->gameFrameTime < (99 * 60 * 60) + (59 * 60)) // game time can't be longer than 99 minutes and 59 seconds, can't print 3 digits
|
|
|
|
sBerryBlender->gameFrameTime++;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
HandlePlayerInput();
|
|
|
|
SetLinkDebugValues((u16)(sBerryBlender->speed), sBerryBlender->progressBarValue);
|
|
|
|
UpdateOpponentScores();
|
|
|
|
TryUpdateProgressBar(sBerryBlender->progressBarValue, MAX_PROGRESS_BAR);
|
|
|
|
UpdateRPM(sBerryBlender->speed);
|
2020-08-24 20:52:33 +02:00
|
|
|
RestoreBgCoords();
|
|
|
|
ProcessLinkPlayerCmds();
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->gameEndState == 0 && sBerryBlender->maxProgressBarValue >= MAX_PROGRESS_BAR)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->progressBarValue = MAX_PROGRESS_BAR;
|
|
|
|
sBerryBlender->gameEndState = 1;
|
2020-08-24 20:52:33 +02:00
|
|
|
SetMainCallback2(CB2_EndBlenderGame);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y);
|
2017-11-19 22:48:46 +01:00
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Blender_DummiedOutFunc(s16 a0, s16 a1)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static bool8 AreBlenderBerriesSame(struct BlenderBerry* berries, u8 a, u8 b)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// First check to itemId is pointless (and wrong anyway?), always false when this is called
|
|
|
|
// Only used to determine if two enigma berries are equivalent
|
|
|
|
if (berries[a].itemId != berries[b].itemId
|
|
|
|
|| (StringCompare(berries[a].name, berries[b].name) == 0
|
|
|
|
&& (berries[a].flavors[FLAVOR_SPICY] == berries[b].flavors[FLAVOR_SPICY]
|
|
|
|
&& berries[a].flavors[FLAVOR_DRY] == berries[b].flavors[FLAVOR_DRY]
|
|
|
|
&& berries[a].flavors[FLAVOR_SWEET] == berries[b].flavors[FLAVOR_SWEET]
|
|
|
|
&& berries[a].flavors[FLAVOR_BITTER] == berries[b].flavors[FLAVOR_BITTER]
|
|
|
|
&& berries[a].flavors[FLAVOR_SOUR] == berries[b].flavors[FLAVOR_SOUR]
|
|
|
|
&& berries[a].flavors[FLAVOR_COUNT] == berries[b].flavors[FLAVOR_COUNT])))
|
2017-11-19 22:48:46 +01:00
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static u32 CalculatePokeblockColor(struct BlenderBerry* berries, s16* _flavors, u8 numPlayers, u8 negativeFlavors)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
s16 flavors[FLAVOR_COUNT + 1];
|
|
|
|
s32 i, j;
|
|
|
|
u8 numFlavors;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0; i < FLAVOR_COUNT + 1; i++)
|
|
|
|
flavors[i] = _flavors[i];
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
j = 0;
|
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (flavors[i] == 0)
|
|
|
|
j++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// If all flavors are 0, or at least 3 were negative/0
|
|
|
|
// or if players used the same berry, color is black
|
|
|
|
if (j == 5 || negativeFlavors > 3)
|
|
|
|
return PBLOCK_CLR_BLACK;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < numPlayers; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
for (j = 0; j < numPlayers; j++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (berries[i].itemId == berries[j].itemId && i != j
|
|
|
|
&& (berries[i].itemId != ITEM_ENIGMA_BERRY || AreBlenderBerriesSame(berries, i, j)))
|
|
|
|
return PBLOCK_CLR_BLACK;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
numFlavors = 0;
|
|
|
|
for (numFlavors = 0, i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (flavors[i] > 0)
|
|
|
|
numFlavors++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// Check for special colors (White/Gray/Gold)
|
|
|
|
if (numFlavors > 3)
|
|
|
|
return PBLOCK_CLR_WHITE;
|
|
|
|
|
|
|
|
if (numFlavors == 3)
|
|
|
|
return PBLOCK_CLR_GRAY;
|
|
|
|
|
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (flavors[i] > 50)
|
|
|
|
return PBLOCK_CLR_GOLD;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only 1 flavor present, return corresponding color
|
|
|
|
if (numFlavors == 1 && flavors[FLAVOR_SPICY] > 0)
|
|
|
|
return PBLOCK_CLR_RED;
|
|
|
|
if (numFlavors == 1 && flavors[FLAVOR_DRY] > 0)
|
|
|
|
return PBLOCK_CLR_BLUE;
|
|
|
|
if (numFlavors == 1 && flavors[FLAVOR_SWEET] > 0)
|
|
|
|
return PBLOCK_CLR_PINK;
|
|
|
|
if (numFlavors == 1 && flavors[FLAVOR_BITTER] > 0)
|
|
|
|
return PBLOCK_CLR_GREEN;
|
|
|
|
if (numFlavors == 1 && flavors[FLAVOR_SOUR] > 0)
|
|
|
|
return PBLOCK_CLR_YELLOW;
|
|
|
|
|
|
|
|
if (numFlavors == 2)
|
|
|
|
{
|
|
|
|
// Determine which 2 flavors are present
|
|
|
|
s32 idx = 0;
|
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (flavors[i] > 0)
|
|
|
|
sPokeblockPresentFlavors[idx++] = i;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
// Use the stronger flavor to determine color
|
|
|
|
// The weaker flavor is returned in the upper 16 bits, but this is ignored in the color assignment
|
|
|
|
if (flavors[sPokeblockPresentFlavors[0]] >= flavors[sPokeblockPresentFlavors[1]])
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sPokeblockPresentFlavors[0] == FLAVOR_SPICY)
|
|
|
|
return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_PURPLE;
|
|
|
|
if (sPokeblockPresentFlavors[0] == FLAVOR_DRY)
|
|
|
|
return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_INDIGO;
|
|
|
|
if (sPokeblockPresentFlavors[0] == FLAVOR_SWEET)
|
|
|
|
return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_BROWN;
|
|
|
|
if (sPokeblockPresentFlavors[0] == FLAVOR_BITTER)
|
|
|
|
return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_LITE_BLUE;
|
|
|
|
if (sPokeblockPresentFlavors[0] == FLAVOR_SOUR)
|
|
|
|
return (sPokeblockPresentFlavors[1] << 16) | PBLOCK_CLR_OLIVE;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sPokeblockPresentFlavors[1] == FLAVOR_SPICY)
|
|
|
|
return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_PURPLE;
|
|
|
|
if (sPokeblockPresentFlavors[1] == FLAVOR_DRY)
|
|
|
|
return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_INDIGO;
|
|
|
|
if (sPokeblockPresentFlavors[1] == FLAVOR_SWEET)
|
|
|
|
return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_BROWN;
|
|
|
|
if (sPokeblockPresentFlavors[1] == FLAVOR_BITTER)
|
|
|
|
return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_LITE_BLUE;
|
|
|
|
if (sPokeblockPresentFlavors[1] == FLAVOR_SOUR)
|
|
|
|
return (sPokeblockPresentFlavors[0] << 16) | PBLOCK_CLR_OLIVE;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
return PBLOCK_CLR_NONE;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void Debug_SetMaxRPMStage(s16 value)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sDebug_MaxRPMStage = value;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Unused
|
|
|
|
static s16 Debug_GetMaxRPMStage(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
return sDebug_MaxRPMStage;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void Debug_SetGameTimeStage(s16 value)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sDebug_GameTimeStage = value;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Unued
|
|
|
|
static s16 Debug_GetGameTimeStage(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
return sDebug_GameTimeStage;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void CalculatePokeblock(struct BlenderBerry *berries, struct Pokeblock *pokeblock, u8 numPlayers, u8 *flavors, u16 maxRPM)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
s32 i, j;
|
2021-01-19 23:50:52 +01:00
|
|
|
s32 multiuseVar;
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 numNegatives;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0; i < FLAVOR_COUNT + 1; i++)
|
|
|
|
sPokeblockFlavors[i] = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Add up the flavor + feel of each players berry
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < numPlayers; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
for (j = 0; j < FLAVOR_COUNT + 1; j++)
|
|
|
|
sPokeblockFlavors[j] += berries[i].flavors[j];
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Subtract each flavor total from the prev one
|
|
|
|
// The idea is to focus on only the flavors with the highest totals
|
|
|
|
// Bad way to do it though (order matters here)
|
|
|
|
multiuseVar = sPokeblockFlavors[0];
|
|
|
|
sPokeblockFlavors[FLAVOR_SPICY] -= sPokeblockFlavors[FLAVOR_DRY];
|
|
|
|
sPokeblockFlavors[FLAVOR_DRY] -= sPokeblockFlavors[FLAVOR_SWEET];
|
|
|
|
sPokeblockFlavors[FLAVOR_SWEET] -= sPokeblockFlavors[FLAVOR_BITTER];
|
|
|
|
sPokeblockFlavors[FLAVOR_BITTER] -= sPokeblockFlavors[FLAVOR_SOUR];
|
|
|
|
sPokeblockFlavors[FLAVOR_SOUR] -= multiuseVar;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Count (and reset) the resulting negative flavors
|
2017-11-19 22:48:46 +01:00
|
|
|
multiuseVar = 0;
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sPokeblockFlavors[i] < 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sPokeblockFlavors[i] = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
multiuseVar++;
|
|
|
|
}
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
numNegatives = multiuseVar;
|
|
|
|
|
|
|
|
// Subtract the number of negative flavor totals from each positive total (without going below 0)
|
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sPokeblockFlavors[i] > 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sPokeblockFlavors[i] < multiuseVar)
|
|
|
|
sPokeblockFlavors[i] = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
sPokeblockFlavors[i] -= multiuseVar;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
|
|
|
sDebug_PokeblockFactorFlavors[i] = sPokeblockFlavors[i];
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Factor in max RPM and round
|
|
|
|
sDebug_PokeblockFactorRPM = multiuseVar = maxRPM / 333 + 100;
|
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
s32 remainder;
|
|
|
|
s32 flavor = sPokeblockFlavors[i];
|
|
|
|
flavor = (flavor * multiuseVar) / 10;
|
|
|
|
remainder = flavor % 10;
|
|
|
|
flavor /= 10;
|
|
|
|
if (remainder > 4)
|
|
|
|
flavor++;
|
|
|
|
sPokeblockFlavors[i] = flavor;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
|
|
|
sDebug_PokeblockFactorFlavorsAfterRPM[i] = sPokeblockFlavors[i];
|
|
|
|
|
|
|
|
// Calculate color and feel of pokeblock
|
|
|
|
pokeblock->color = CalculatePokeblockColor(berries, &sPokeblockFlavors[0], numPlayers, numNegatives);
|
|
|
|
sPokeblockFlavors[FLAVOR_COUNT] = (sPokeblockFlavors[FLAVOR_COUNT] / numPlayers) - numPlayers;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sPokeblockFlavors[FLAVOR_COUNT] < 0)
|
|
|
|
sPokeblockFlavors[FLAVOR_COUNT] = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (pokeblock->color == PBLOCK_CLR_BLACK)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Black pokeblocks get their flavors randomly reassigned
|
|
|
|
multiuseVar = Random() % ARRAY_COUNT(sBlackPokeblockFlavorFlags);
|
|
|
|
for (i = 0; i < FLAVOR_COUNT; i++)
|
2017-11-18 21:38:57 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if ((sBlackPokeblockFlavorFlags[multiuseVar] >> i) & 1)
|
|
|
|
sPokeblockFlavors[i] = 2;
|
2017-11-19 22:48:46 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
sPokeblockFlavors[i] = 0;
|
2017-11-18 21:38:57 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0; i < FLAVOR_COUNT + 1; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sPokeblockFlavors[i] > 255)
|
|
|
|
sPokeblockFlavors[i] = 255;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
pokeblock->spicy = sPokeblockFlavors[FLAVOR_SPICY];
|
|
|
|
pokeblock->dry = sPokeblockFlavors[FLAVOR_DRY];
|
|
|
|
pokeblock->sweet = sPokeblockFlavors[FLAVOR_SWEET];
|
|
|
|
pokeblock->bitter = sPokeblockFlavors[FLAVOR_BITTER];
|
|
|
|
pokeblock->sour = sPokeblockFlavors[FLAVOR_SOUR];
|
|
|
|
pokeblock->feel = sPokeblockFlavors[FLAVOR_COUNT];
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0; i < FLAVOR_COUNT + 1; i++)
|
|
|
|
flavors[i] = sPokeblockFlavors[i];
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Unused
|
|
|
|
static void Debug_CalculatePokeblock(struct BlenderBerry* berries, struct Pokeblock* pokeblock, u8 numPlayers, u8* flavors, u16 maxRPM)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
CalculatePokeblock(berries, pokeblock, numPlayers, flavors, maxRPM);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void Debug_SetStageVars(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u32 frames = (u16)(sBerryBlender->gameFrameTime);
|
|
|
|
u16 maxRPM = sBerryBlender->maxRPM;
|
2020-08-24 20:52:33 +02:00
|
|
|
s16 stage = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
if (frames < 900)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = 5;
|
2017-11-19 22:48:46 +01:00
|
|
|
else if ((u16)(frames - 900) < 600)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = 4;
|
2017-11-19 22:48:46 +01:00
|
|
|
else if ((u16)(frames - 1500) < 600)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = 3;
|
2017-11-19 22:48:46 +01:00
|
|
|
else if ((u16)(frames - 2100) < 900)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = 2;
|
2017-11-19 22:48:46 +01:00
|
|
|
else if ((u16)(frames - 3300) < 300)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = 1;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
Debug_SetGameTimeStage(stage);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = 0;
|
2020-08-23 00:20:22 +02:00
|
|
|
if (maxRPM <= 64)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (maxRPM >= 50 && maxRPM < 100)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -1;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 100 && maxRPM < 150)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -2;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 150 && maxRPM < 200)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -3;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 200 && maxRPM < 250)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -4;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 250 && maxRPM < 300)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -5;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 350 && maxRPM < 400)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -6;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 400 && maxRPM < 450)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -7;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 500 && maxRPM < 550)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -8;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 550 && maxRPM < 600)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -9;
|
2020-08-23 00:20:22 +02:00
|
|
|
else if (maxRPM >= 600)
|
2020-08-24 20:52:33 +02:00
|
|
|
stage = -10;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
Debug_SetMaxRPMStage(stage);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void SendContinuePromptResponse(u16 *cmd)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers && gWirelessCommType)
|
|
|
|
*cmd = RFUCMD_SEND_PACKET;
|
2017-11-19 22:48:46 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
*cmd = LINKCMD_SEND_PACKET;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void CB2_EndBlenderGame(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u8 i, j;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->gameEndState < 3)
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateBlenderCenter();
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
GetMultiplayerId(); // unused return value
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->gameEndState)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 1:
|
2018-01-10 04:30:54 +01:00
|
|
|
m4aMPlayTempoControl(&gMPlayInfo_BGM, 256);
|
2017-11-19 22:48:46 +01:00
|
|
|
for (i = 0; i < gSpecialVar_0x8004; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
DestroyTask(sBerryBlender->opponentTaskIds[i]);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->speed -= 32;
|
|
|
|
if (sBerryBlender->speed <= 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2017-11-28 02:05:51 +01:00
|
|
|
ClearLinkCallback();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->speed = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
else
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 5;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState = 0;
|
2018-01-10 04:30:54 +01:00
|
|
|
m4aMPlayStop(&gMPlayInfo_SE2);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
UpdateHitPitch();
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (GetMultiplayerId() != 0)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2018-12-31 09:22:21 +01:00
|
|
|
else if (IsLinkTaskFinished())
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers && gWirelessCommType)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameBlock.timeRPM.time = sBerryBlender->gameFrameTime;
|
|
|
|
sBerryBlender->gameBlock.timeRPM.maxRPM = sBerryBlender->maxRPM;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
for (j = 0; j < NUM_SCORE_TYPES; j++)
|
|
|
|
sBerryBlender->gameBlock.scores[i][j] = sBerryBlender->scores[i][j];
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (SendBlock(0, &sBerryBlender->gameBlock, sizeof(sBerryBlender->gameBlock)))
|
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->smallBlock.time = sBerryBlender->gameFrameTime;
|
|
|
|
sBerryBlender->smallBlock.maxRPM = sBerryBlender->maxRPM;
|
|
|
|
if (SendBlock(0, &sBerryBlender->smallBlock, sizeof(sBerryBlender->smallBlock) + 32))
|
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (GetBlockReceivedStatus())
|
|
|
|
{
|
|
|
|
ResetBlockReceivedFlags();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers && gWirelessCommType)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
struct BlenderGameBlock *receivedBlock = (struct BlenderGameBlock*)(&gBlockRecvBuffer);
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->maxRPM = receivedBlock->timeRPM.maxRPM;
|
|
|
|
sBerryBlender->gameFrameTime = receivedBlock->timeRPM.time;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
for (j = 0; j < NUM_SCORE_TYPES; j++)
|
|
|
|
sBerryBlender->scores[i][j] = receivedBlock->scores[i][j];
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
struct TimeAndRPM *receivedBlock = (struct TimeAndRPM*)(&gBlockRecvBuffer);
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->maxRPM = receivedBlock->maxRPM;
|
|
|
|
sBerryBlender->gameFrameTime = receivedBlock->time;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (PrintBlendingRanking())
|
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 6:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (PrintBlendingResults())
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
if (gInGameOpponentsNo == 0)
|
|
|
|
IncrementGameStat(GAME_STAT_POKEBLOCKS_WITH_FRIENDS);
|
|
|
|
else
|
|
|
|
IncrementGameStat(GAME_STAT_POKEBLOCKS);
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (Blender_PrintText(&sBerryBlender->textState, sText_WouldLikeToBlendAnotherBerry, GetPlayerTextSpeedDelay()))
|
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 9:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->yesNoAnswer = 0;
|
2020-08-24 20:52:33 +02:00
|
|
|
CreateYesNoMenu(&sYesNoWindowTemplate_ContinuePlaying, 1, 0xD, 0);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 10:
|
2018-11-05 21:45:54 +01:00
|
|
|
switch (Menu_ProcessInputNoWrapClearOnChoose())
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
case -1:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->yesNoAnswer = 1;
|
|
|
|
sBerryBlender->gameEndState++;
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->arrowIdToPlayerId[i] != NO_PLAYER)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
PutWindowTilemap(i);
|
|
|
|
CopyWindowToVram(i, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->yesNoAnswer = 0;
|
|
|
|
sBerryBlender->gameEndState++;
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->arrowIdToPlayerId[i] != NO_PLAYER)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
PutWindowTilemap(i);
|
|
|
|
CopyWindowToVram(i, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
2020-08-24 20:52:33 +02:00
|
|
|
SendContinuePromptResponse(&gSendCmd[BLENDER_COMM_INPUT_STATE]);
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->yesNoAnswer == 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (IsBagPocketNonEmpty(POCKET_BERRIES) == FALSE)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// No berries
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->playAgainState = CANT_PLAY_NO_BERRIES;
|
2020-08-24 20:52:33 +02:00
|
|
|
gSendCmd[BLENDER_COMM_RESP] = LINKCMD_BLENDER_NO_BERRIES;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
else if (GetFirstFreePokeblockSlot() == -1)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// No space for pokeblocks
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->playAgainState = CANT_PLAY_NO_PKBLCK_SPACE;
|
2020-08-24 20:52:33 +02:00
|
|
|
gSendCmd[BLENDER_COMM_RESP] = LINKCMD_BLENDER_NO_PBLOCK_SPACE;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->playAgainState = PLAY_AGAIN_YES;
|
|
|
|
gSendCmd[BLENDER_COMM_RESP] = LINKCMD_BLENDER_PLAY_AGAIN;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->playAgainState = PLAY_AGAIN_NO;
|
|
|
|
gSendCmd[BLENDER_COMM_RESP] = LINKCMD_CONT_BLOCK;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
if (gInGameOpponentsNo)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
SetMainCallback2(CB2_CheckPlayAgainLocal);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 0;
|
|
|
|
sBerryBlender->mainState = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 13:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (Blender_PrintText(&sBerryBlender->textState, sText_CommunicationStandby, GetPlayerTextSpeedDelay()))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
SetMainCallback2(CB2_CheckPlayAgainLink);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 0;
|
|
|
|
sBerryBlender->mainState = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
RestoreBgCoords();
|
2020-08-23 00:20:22 +02:00
|
|
|
UpdateRPM(sBerryBlender->speed);
|
2020-08-24 20:52:33 +02:00
|
|
|
ProcessLinkPlayerCmds();
|
2020-08-23 00:20:22 +02:00
|
|
|
Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y);
|
2017-11-19 22:48:46 +01:00
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool8 LinkPlayAgainHandleSaving(void)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
switch (sBerryBlender->linkPlayAgainState)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-08-13 09:09:47 +02:00
|
|
|
SetLinkStandbyCallback();
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->linkPlayAgainState = 1;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->linkPlayAgainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
gSoftResetDisabled = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
2019-02-11 02:42:50 +01:00
|
|
|
FullSaveGame();
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->linkPlayAgainState++;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 3:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait == 10)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-13 09:09:47 +02:00
|
|
|
SetLinkStandbyCallback();
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->linkPlayAgainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2019-02-11 02:42:50 +01:00
|
|
|
if (CheckSaveFile())
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->linkPlayAgainState = 5;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->linkPlayAgainState = 3;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5:
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->linkPlayAgainState++;
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 6:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 5)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
gSoftResetDisabled = FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void CB2_CheckPlayAgainLink(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->gameEndState)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->playerContinueResponses[0] == LINKCMD_SEND_LINK_TYPE)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Link leader says game will continue
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 5;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
else if (sBerryBlender->playerContinueResponses[0] == LINKCMD_BLENDER_STOP)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Link leader says game will stop, if necessary print why
|
|
|
|
if (sBerryBlender->canceledPlayerCmd == LINKCMD_BLENDER_NO_BERRIES)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 2;
|
2020-08-24 20:52:33 +02:00
|
|
|
else if (sBerryBlender->canceledPlayerCmd == LINKCMD_BLENDER_NO_PBLOCK_SPACE)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 1;
|
2017-11-19 22:48:46 +01:00
|
|
|
else
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 5;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 3;
|
2020-08-24 20:52:33 +02:00
|
|
|
StringCopy(gStringVar4, gLinkPlayers[sBerryBlender->canceledPlayerId].name);
|
2017-11-19 22:48:46 +01:00
|
|
|
StringAppend(gStringVar4, sText_ApostropheSPokeblockCaseIsFull);
|
|
|
|
break;
|
|
|
|
case 2:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2020-08-24 20:52:33 +02:00
|
|
|
StringCopy(gStringVar4, gLinkPlayers[sBerryBlender->canceledPlayerId].name);
|
2017-11-19 22:48:46 +01:00
|
|
|
StringAppend(gStringVar4, sText_HasNoBerriesToPut);
|
|
|
|
break;
|
|
|
|
case 3:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (Blender_PrintText(&sBerryBlender->textState, gStringVar4, GetPlayerTextSpeedDelay()))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 60)
|
|
|
|
sBerryBlender->gameEndState = 5;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 5:
|
2020-08-23 00:20:22 +02:00
|
|
|
Blender_PrintText(&sBerryBlender->textState, gText_SavingDontTurnOff2, 0);
|
2020-08-13 09:09:47 +02:00
|
|
|
SetLinkStandbyCallback();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 6:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->gameEndState++;
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->linkPlayAgainState = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
if (LinkPlayAgainHandleSaving())
|
|
|
|
{
|
|
|
|
PlaySE(SE_SAVE);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2020-08-13 09:09:47 +02:00
|
|
|
SetLinkStandbyCallback();
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 9:
|
2018-12-31 09:22:21 +01:00
|
|
|
if (IsLinkTaskFinished())
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2021-02-24 17:01:02 +01:00
|
|
|
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->playerContinueResponses[0] == LINKCMD_SEND_LINK_TYPE)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
FreeAllWindowBuffers();
|
|
|
|
UnsetBgTilemapBuffer(2);
|
|
|
|
UnsetBgTilemapBuffer(1);
|
2020-08-23 00:20:22 +02:00
|
|
|
FREE_AND_SET_NULL(sBerryBlender);
|
2017-11-19 22:48:46 +01:00
|
|
|
SetMainCallback2(DoBerryBlending);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 11:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 30)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-13 09:09:47 +02:00
|
|
|
SetCloseLinkCallback();
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 12:
|
2020-08-24 20:52:33 +02:00
|
|
|
if (!gReceivedRemoteLinkPlayers)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
FREE_AND_SET_NULL(sBerryBlender);
|
2018-07-25 06:18:23 +02:00
|
|
|
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
ProcessLinkPlayerCmds();
|
2020-08-23 00:20:22 +02:00
|
|
|
Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y);
|
2017-11-19 22:48:46 +01:00
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void CB2_CheckPlayAgainLocal(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->gameEndState)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->playAgainState == PLAY_AGAIN_YES || sBerryBlender->playAgainState == PLAY_AGAIN_NO)
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 9;
|
|
|
|
if (sBerryBlender->playAgainState == CANT_PLAY_NO_BERRIES)
|
|
|
|
sBerryBlender->gameEndState = 2;
|
|
|
|
if (sBerryBlender->playAgainState == CANT_PLAY_NO_PKBLCK_SPACE)
|
|
|
|
sBerryBlender->gameEndState = 1;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState = 3;
|
|
|
|
sBerryBlender->textState = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
StringCopy(gStringVar4, sText_YourPokeblockCaseIsFull);
|
|
|
|
break;
|
|
|
|
case 2:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
|
|
|
sBerryBlender->textState = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
StringCopy(gStringVar4, sText_RunOutOfBerriesForBlending);
|
|
|
|
break;
|
|
|
|
case 3:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (Blender_PrintText(&sBerryBlender->textState, gStringVar4, GetPlayerTextSpeedDelay()))
|
|
|
|
sBerryBlender->gameEndState = 9;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
BeginFastPaletteFade(3);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->gameEndState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->playAgainState == PLAY_AGAIN_YES)
|
2017-11-19 22:48:46 +01:00
|
|
|
SetMainCallback2(DoBerryBlending);
|
|
|
|
else
|
2018-07-25 06:18:23 +02:00
|
|
|
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
FreeAllWindowBuffers();
|
|
|
|
UnsetBgTilemapBuffer(2);
|
|
|
|
UnsetBgTilemapBuffer(1);
|
2020-08-23 00:20:22 +02:00
|
|
|
FREE_AND_SET_NULL(sBerryBlender);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
ProcessLinkPlayerCmds();
|
2020-08-23 00:20:22 +02:00
|
|
|
Blender_DummiedOutFunc(sBerryBlender->bg_X, sBerryBlender->bg_Y);
|
2017-11-19 22:48:46 +01:00
|
|
|
RunTasks();
|
|
|
|
AnimateSprites();
|
|
|
|
BuildOamBuffer();
|
|
|
|
RunTextPrinters();
|
|
|
|
UpdatePaletteFade();
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void ProcessLinkPlayerCmds(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
if (gReceivedRemoteLinkPlayers)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (CheckRecvCmdMatches(gRecvCmds[0][BLENDER_COMM_INPUT_STATE], LINKCMD_SEND_PACKET, RFUCMD_SEND_PACKET))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gRecvCmds[0][BLENDER_COMM_RESP] == LINKCMD_BLENDER_STOP)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Link leader has indicated play is stopping, read signal to determine why
|
|
|
|
switch (gRecvCmds[0][BLENDER_COMM_STOP_TYPE])
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
case LINKCMD_CONT_BLOCK: // Someone selected "No" to continue playing
|
|
|
|
sBerryBlender->canceledPlayerCmd = LINKCMD_CONT_BLOCK;
|
|
|
|
sBerryBlender->canceledPlayerId = gRecvCmds[0][BLENDER_COMM_PLAYER_ID];
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
2020-08-24 20:52:33 +02:00
|
|
|
case LINKCMD_BLENDER_NO_BERRIES:
|
|
|
|
sBerryBlender->canceledPlayerCmd = LINKCMD_BLENDER_NO_BERRIES;
|
|
|
|
sBerryBlender->canceledPlayerId = gRecvCmds[0][BLENDER_COMM_PLAYER_ID];
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
2020-08-24 20:52:33 +02:00
|
|
|
case LINKCMD_BLENDER_NO_PBLOCK_SPACE:
|
|
|
|
sBerryBlender->canceledPlayerCmd = LINKCMD_BLENDER_NO_PBLOCK_SPACE;
|
|
|
|
sBerryBlender->canceledPlayerId = gRecvCmds[0][BLENDER_COMM_PLAYER_ID];
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->playerContinueResponses[0] = LINKCMD_BLENDER_STOP;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
else if (gRecvCmds[0][BLENDER_COMM_RESP] == LINKCMD_SEND_LINK_TYPE)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Link leader has indicated play will continue
|
|
|
|
sBerryBlender->playerContinueResponses[0] = LINKCMD_SEND_LINK_TYPE;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// If player is link leader, check for responses to the "Continue playing" prompt (even if it's not up yet)
|
|
|
|
if (GetMultiplayerId() == 0
|
|
|
|
&& sBerryBlender->playerContinueResponses[0] != LINKCMD_BLENDER_STOP
|
|
|
|
&& sBerryBlender->playerContinueResponses[0] != LINKCMD_SEND_LINK_TYPE)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u8 i;
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// Try to gather responses
|
2017-11-19 22:48:46 +01:00
|
|
|
for (i = 0; i < GetLinkPlayerCount(); i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (CheckRecvCmdMatches(gRecvCmds[i][BLENDER_COMM_INPUT_STATE], LINKCMD_SEND_PACKET, RFUCMD_SEND_PACKET))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
switch (gRecvCmds[i][BLENDER_COMM_RESP])
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
case LINKCMD_CONT_BLOCK: // Selected "No"
|
|
|
|
sBerryBlender->playerContinueResponses[i] = LINKCMD_CONT_BLOCK;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
2020-08-24 20:52:33 +02:00
|
|
|
case LINKCMD_BLENDER_PLAY_AGAIN: // Selected "Yes"
|
|
|
|
sBerryBlender->playerContinueResponses[i] = LINKCMD_BLENDER_PLAY_AGAIN;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
2020-08-24 20:52:33 +02:00
|
|
|
case LINKCMD_BLENDER_NO_BERRIES:
|
|
|
|
sBerryBlender->playerContinueResponses[i] = LINKCMD_BLENDER_NO_BERRIES;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
2020-08-24 20:52:33 +02:00
|
|
|
case LINKCMD_BLENDER_NO_PBLOCK_SPACE:
|
|
|
|
sBerryBlender->playerContinueResponses[i] = LINKCMD_BLENDER_NO_PBLOCK_SPACE;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// Count players that have responded, stopping at first non-response
|
2017-11-19 22:48:46 +01:00
|
|
|
for (i = 0; i < GetLinkPlayerCount(); i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->playerContinueResponses[i] == 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// If all players responded, handle response
|
2017-11-19 22:48:46 +01:00
|
|
|
if (i == GetLinkPlayerCount())
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Count players that decided to play again, stopping at first negative response
|
2017-11-19 22:48:46 +01:00
|
|
|
for (i = 0; i < GetLinkPlayerCount(); i++)
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->playerContinueResponses[i] != LINKCMD_BLENDER_PLAY_AGAIN)
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// Schedule signal to other players about whether or not play will continue
|
|
|
|
SendContinuePromptResponse(&gSendCmd[BLENDER_COMM_INPUT_STATE]);
|
2017-11-19 22:48:46 +01:00
|
|
|
if (i == GetLinkPlayerCount())
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// All players chose to continue playing
|
|
|
|
gSendCmd[BLENDER_COMM_RESP] = LINKCMD_SEND_LINK_TYPE;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// At least 1 player decided to stop playing, or can't continue playing
|
|
|
|
gSendCmd[BLENDER_COMM_RESP] = LINKCMD_BLENDER_STOP;
|
|
|
|
gSendCmd[BLENDER_COMM_STOP_TYPE] = sBerryBlender->playerContinueResponses[i];
|
|
|
|
gSendCmd[BLENDER_COMM_PLAYER_ID] = i;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void DrawBlenderCenter(struct BgAffineSrcData *dest)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
struct BgAffineSrcData affineSrc;
|
|
|
|
|
2017-11-27 20:03:41 +01:00
|
|
|
affineSrc.texX = 0x7800;
|
|
|
|
affineSrc.texY = 0x5000;
|
2020-08-23 00:20:22 +02:00
|
|
|
affineSrc.scrX = 0x78 - sBerryBlender->bg_X;
|
|
|
|
affineSrc.scrY = 0x50 - sBerryBlender->bg_Y;
|
2020-08-24 20:52:33 +02:00
|
|
|
affineSrc.sx = sBerryBlender->centerScale;
|
|
|
|
affineSrc.sy = sBerryBlender->centerScale;
|
2020-08-23 00:20:22 +02:00
|
|
|
affineSrc.alpha = sBerryBlender->arrowPos;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
*dest = affineSrc;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 GetBlenderArrowPosition(void)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
return sBerryBlender->arrowPos;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void UpdateBlenderCenter(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u8 playerId = 0;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers)
|
2017-11-19 22:48:46 +01:00
|
|
|
playerId = GetMultiplayerId();
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gWirelessCommType && gReceivedRemoteLinkPlayers)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
if (playerId == 0)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->arrowPos += sBerryBlender->speed;
|
2020-08-24 20:52:33 +02:00
|
|
|
gSendCmd[BLENDER_COMM_PROGRESS_BAR] = sBerryBlender->progressBarValue;
|
|
|
|
gSendCmd[BLENDER_COMM_ARROW_POS] = sBerryBlender->arrowPos;
|
2020-08-23 00:20:22 +02:00
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if ((gRecvCmds[0][BLENDER_COMM_INPUT_STATE] & 0xFF00) == RFUCMD_BLENDER_SEND_KEYS)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->progressBarValue = gRecvCmds[0][BLENDER_COMM_PROGRESS_BAR];
|
|
|
|
sBerryBlender->arrowPos = gRecvCmds[0][BLENDER_COMM_ARROW_POS];
|
2020-08-23 00:20:22 +02:00
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->arrowPos += sBerryBlender->speed;
|
|
|
|
DrawBlenderCenter(&sBerryBlender->bgAffineSrc);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void SetBgPos(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
SetGpuReg(REG_OFFSET_BG1HOFS, sBerryBlender->bg_X);
|
|
|
|
SetGpuReg(REG_OFFSET_BG1VOFS, sBerryBlender->bg_Y);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
SetGpuReg(REG_OFFSET_BG0HOFS, sBerryBlender->bg_X);
|
|
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, sBerryBlender->bg_Y);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void SpriteCB_Particle(struct Sprite* sprite)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[2] += sprite->data[0];
|
|
|
|
sprite->data[3] += sprite->data[1];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = sprite->data[2] / 8;
|
|
|
|
sprite->y2 = sprite->data[3] / 8;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
if (sprite->animEnded)
|
|
|
|
DestroySprite(sprite);
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void CreateParticleSprites(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
s32 limit = (Random() % 2) + 1;
|
|
|
|
s32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < limit; i++)
|
|
|
|
{
|
|
|
|
u16 rand;
|
|
|
|
s32 x, y;
|
|
|
|
u8 spriteId;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
rand = sBerryBlender->arrowPos + (Random() % 20);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
x = gSineTable[(rand & 0xFF) + 64] / 4;
|
|
|
|
y = gSineTable[(rand & 0xFF)] / 4;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
spriteId = CreateSprite(&sSpriteTemplate_Particles, x + 120, y + 80, 1);
|
2017-12-02 21:44:50 +01:00
|
|
|
gSprites[spriteId].data[0] = 16 - (Random() % 32);
|
|
|
|
gSprites[spriteId].data[1] = 16 - (Random() % 32);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
gSprites[spriteId].callback = SpriteCB_Particle;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void SpriteCB_ScoreSymbol(struct Sprite* sprite)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[0]++;
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = -(sprite->data[0] / 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
if (sprite->animEnded)
|
|
|
|
DestroySprite(sprite);
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void SpriteCB_ScoreSymbolBest(struct Sprite* sprite)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[0]++;
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = -(sprite->data[0] * 2);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2021-07-07 15:11:52 +02:00
|
|
|
if (sprite->y2 < -12)
|
|
|
|
sprite->y2 = -12;
|
2017-11-19 22:48:46 +01:00
|
|
|
if (sprite->animEnded)
|
|
|
|
DestroySprite(sprite);
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void SetPlayerBerryData(u8 playerId, u16 itemId)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->chosenItemId[playerId] = itemId;
|
|
|
|
ConvertItemToBlenderBerry(&sBerryBlender->blendedBerries[playerId], itemId);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
#define sState data[0]
|
|
|
|
#define sYPos data[1]
|
|
|
|
#define sDelay data[2]
|
|
|
|
#define sAnimId data[3]
|
|
|
|
|
|
|
|
static void SpriteCB_CountdownNumber(struct Sprite* sprite)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sprite->sState)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-08-23 00:20:22 +02:00
|
|
|
sprite->sYPos += 8;
|
|
|
|
if (sprite->sYPos > DISPLAY_HEIGHT / 2 + 8)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sprite->sYPos = DISPLAY_HEIGHT / 2 + 8;
|
|
|
|
sprite->sState++;
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_BALL_BOUNCE_1);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sprite->sDelay > 20)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sprite->sState++;
|
|
|
|
sprite->sDelay = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
2020-08-23 00:20:22 +02:00
|
|
|
sprite->sYPos += 4;
|
|
|
|
if (sprite->sYPos > DISPLAY_HEIGHT + 16)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sprite->sAnimId == 3)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
DestroySprite(sprite);
|
2020-08-23 00:20:22 +02:00
|
|
|
CreateSprite(&sSpriteTemplate_Start, 120, -20, 2);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sprite->sState = 0;
|
|
|
|
sprite->sYPos = -16;
|
|
|
|
StartSpriteAnim(sprite, sprite->sAnimId);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = sprite->sYPos;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
#undef sState
|
|
|
|
#undef sYPos
|
|
|
|
#undef sDelay
|
|
|
|
#undef sAnimId
|
|
|
|
|
|
|
|
static void SpriteCB_Start(struct Sprite* sprite)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
switch (sprite->data[0])
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[1] += 8;
|
|
|
|
if (sprite->data[1] > 92)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[1] = 92;
|
|
|
|
sprite->data[0]++;
|
2017-11-19 22:48:46 +01:00
|
|
|
PlaySE(SE_PIN);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[2] += 1;
|
|
|
|
if (sprite->data[2] > 20)
|
|
|
|
sprite->data[0]++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2017-12-02 21:44:50 +01:00
|
|
|
sprite->data[1] += 4;
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sprite->data[1] > DISPLAY_HEIGHT + 16)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
DestroySprite(sprite);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = sprite->data[1];
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void TryUpdateProgressBar(u16 current, u16 limit)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
// Progress bar doesn't move unless it's going up
|
|
|
|
if (sBerryBlender->maxProgressBarValue < current)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->maxProgressBarValue += 2;
|
|
|
|
UpdateProgressBar(sBerryBlender->maxProgressBarValue, limit);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void UpdateProgressBar(u16 value, u16 limit)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
s32 amountFilled, maxFilledSegment, subSegmentsFilled, i;
|
2017-11-19 22:48:46 +01:00
|
|
|
u16 *vram;
|
|
|
|
|
2019-02-17 06:25:48 +01:00
|
|
|
vram = (u16*)(BG_SCREEN_ADDR(12));
|
2020-08-24 20:52:33 +02:00
|
|
|
amountFilled = (value * 64) / limit;
|
|
|
|
maxFilledSegment = amountFilled / 8;
|
|
|
|
|
|
|
|
// Set filled progress bar tiles in full segments
|
|
|
|
for (i = 0; i < maxFilledSegment; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
vram[11 + i] = PROGRESS_BAR_FILLED_TOP;
|
|
|
|
vram[43 + i] = PROGRESS_BAR_FILLED_BOTTOM;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// If progress bar between segments, fill with the corresponding partial segment tiles
|
|
|
|
subSegmentsFilled = amountFilled % 8;
|
|
|
|
if (subSegmentsFilled != 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
vram[11 + i] = subSegmentsFilled + PROGRESS_BAR_EMPTY_TOP;
|
|
|
|
vram[43 + i] = subSegmentsFilled + PROGRESS_BAR_EMPTY_BOTTOM;
|
2020-08-23 00:20:22 +02:00
|
|
|
i++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
|
|
|
|
// Fill the remaining full segments with empty progress tiles
|
|
|
|
// Essentially unnecessary, given that it starts empty and progress only goes up
|
2020-08-23 00:20:22 +02:00
|
|
|
for (; i < 8; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
vram[11 + i] = PROGRESS_BAR_EMPTY_TOP;
|
|
|
|
vram[43 + i] = PROGRESS_BAR_EMPTY_BOTTOM;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static u32 ArrowSpeedToRPM(u16 speed)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
return 60 * 60 * 100 * speed / MAX_ARROW_POS;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void UpdateRPM(u16 speed)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u8 i;
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 digits[5];
|
|
|
|
|
|
|
|
// Check if new max RPM has been reached
|
|
|
|
u32 currentRPM = ArrowSpeedToRPM(speed);
|
|
|
|
if (sBerryBlender->maxRPM < currentRPM)
|
|
|
|
sBerryBlender->maxRPM = currentRPM;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
// Draw the current RPM number at the bottom of the screen
|
2017-11-19 22:48:46 +01:00
|
|
|
for (i = 0; i < 5; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
digits[i] = currentRPM % 10;
|
|
|
|
currentRPM /= 10;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
*((u16*)(BG_SCREEN_ADDR(12) + 0x458)) = digits[4] + RPM_DIGIT;
|
|
|
|
*((u16*)(BG_SCREEN_ADDR(12) + 0x45A)) = digits[3] + RPM_DIGIT;
|
|
|
|
*((u16*)(BG_SCREEN_ADDR(12) + 0x45C)) = digits[2] + RPM_DIGIT;
|
|
|
|
*((u16*)(BG_SCREEN_ADDR(12) + 0x460)) = digits[1] + RPM_DIGIT;
|
|
|
|
*((u16*)(BG_SCREEN_ADDR(12) + 0x462)) = digits[0] + RPM_DIGIT;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// Passed a pointer to the bg x/y
|
|
|
|
// Used when hitting a Best at high RPM
|
|
|
|
static void ShakeBgCoordForHit(s16* coord, u16 speed)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (*coord == 0)
|
|
|
|
*coord = (Random() % speed) - (speed / 2);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void RestoreBgCoord(s16* coord)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (*coord < 0)
|
|
|
|
(*coord)++;
|
|
|
|
if (*coord > 0)
|
|
|
|
(*coord)--;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// For "unshaking" the screen after ShakeBgCoordForHit is called
|
|
|
|
static void RestoreBgCoords(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
RestoreBgCoord(&sBerryBlender->bg_X);
|
|
|
|
RestoreBgCoord(&sBerryBlender->bg_Y);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void BlenderLandShakeBgCoord(s16* coord, u16 timer)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
s32 strength;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (timer < 10)
|
|
|
|
strength = 16;
|
2017-11-19 22:48:46 +01:00
|
|
|
else
|
2020-08-24 20:52:33 +02:00
|
|
|
strength = 8;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (*coord == 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
*coord = (Random() % strength) - (strength / 2);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (*coord < 0)
|
|
|
|
(*coord)++;
|
|
|
|
if (*coord > 0)
|
|
|
|
(*coord)--;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
// For shaking the screen when the blender lands after falling in at the start
|
|
|
|
static bool8 UpdateBlenderLandScreenShake(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->framesToWait == 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->bg_X = 0;
|
|
|
|
sBerryBlender->bg_Y = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait++;
|
2020-08-24 20:52:33 +02:00
|
|
|
BlenderLandShakeBgCoord(&sBerryBlender->bg_X, sBerryBlender->framesToWait);
|
|
|
|
BlenderLandShakeBgCoord(&sBerryBlender->bg_Y, sBerryBlender->framesToWait);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->framesToWait == 20)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->bg_X = 0;
|
|
|
|
sBerryBlender->bg_Y = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static void SpriteCB_PlayerArrow(struct Sprite* sprite)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = -(sBerryBlender->bg_X);
|
|
|
|
sprite->y2 = -(sBerryBlender->bg_Y);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void TryUpdateBerryBlenderRecord(void)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (gSaveBlock1Ptr->berryBlenderRecords[sBerryBlender->numPlayers - 2] < sBerryBlender->maxRPM)
|
|
|
|
gSaveBlock1Ptr->berryBlenderRecords[sBerryBlender->numPlayers - 2] = sBerryBlender->maxRPM;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static bool8 PrintBlendingResults(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
s32 xPos, yPos;
|
|
|
|
|
|
|
|
struct Pokeblock pokeblock;
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 flavors[FLAVOR_COUNT + 1];
|
2017-11-19 22:48:46 +01:00
|
|
|
u8 text[40];
|
|
|
|
u16 berryIds[4]; // unused
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->mainState)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
|
|
|
sBerryBlender->framesToWait = 17;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait -= 10;
|
|
|
|
if (sBerryBlender->framesToWait < 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 20)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < NUM_SCORE_TYPES; i++)
|
|
|
|
DestroySprite(&gSprites[sBerryBlender->scoreIconIds[i]]);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
{
|
|
|
|
u16 minutes, seconds;
|
|
|
|
u8 *txtPtr;
|
|
|
|
|
|
|
|
xPos = GetStringCenterAlignXOffset(1, sText_BlendingResults, 0xA8);
|
|
|
|
Blender_AddTextPrinter(5, sText_BlendingResults, xPos, 1, TEXT_SPEED_FF, 0);
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->numPlayers == BLENDER_MAX_PLAYERS)
|
2017-11-19 22:48:46 +01:00
|
|
|
yPos = 17;
|
|
|
|
else
|
|
|
|
yPos = 21;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < sBerryBlender->numPlayers; yPos += 16, i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 place = sBerryBlender->playerPlaces[i];
|
|
|
|
|
|
|
|
ConvertIntToDecimalStringN(sBerryBlender->stringVar, i + 1, STR_CONV_MODE_LEFT_ALIGN, 1);
|
|
|
|
StringAppend(sBerryBlender->stringVar, sText_Dot);
|
|
|
|
StringAppend(sBerryBlender->stringVar, gText_Space);
|
|
|
|
StringAppend(sBerryBlender->stringVar, gLinkPlayers[place].name);
|
|
|
|
Blender_AddTextPrinter(5, sBerryBlender->stringVar, 8, yPos, TEXT_SPEED_FF, 3);
|
|
|
|
|
|
|
|
StringCopy(sBerryBlender->stringVar, sBerryBlender->blendedBerries[place].name);
|
|
|
|
ConvertInternationalString(sBerryBlender->stringVar, gLinkPlayers[place].language);
|
|
|
|
StringAppend(sBerryBlender->stringVar, sText_SpaceBerry);
|
|
|
|
Blender_AddTextPrinter(5, sBerryBlender->stringVar, 0x54, yPos, TEXT_SPEED_FF, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Blender_AddTextPrinter(5, sText_MaximumSpeed, 0, 0x51, TEXT_SPEED_FF, 3);
|
2020-08-23 00:20:22 +02:00
|
|
|
ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->maxRPM / 100, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
|
|
|
StringAppend(sBerryBlender->stringVar, sText_Dot);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
ConvertIntToDecimalStringN(text, sBerryBlender->maxRPM % 100, STR_CONV_MODE_LEADING_ZEROS, 2);
|
|
|
|
StringAppend(sBerryBlender->stringVar, text);
|
|
|
|
StringAppend(sBerryBlender->stringVar, sText_RPM);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
xPos = GetStringRightAlignXOffset(1, sBerryBlender->stringVar, 0xA8);
|
|
|
|
Blender_AddTextPrinter(5, sBerryBlender->stringVar, xPos, 0x51, TEXT_SPEED_FF, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
Blender_AddTextPrinter(5, sText_Time, 0, 0x61, TEXT_SPEED_FF, 3);
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
seconds = (sBerryBlender->gameFrameTime / 60) % 60;
|
|
|
|
minutes = (sBerryBlender->gameFrameTime / (60 * 60));
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
ConvertIntToDecimalStringN(sBerryBlender->stringVar, minutes, STR_CONV_MODE_LEADING_ZEROS, 2);
|
|
|
|
txtPtr = StringAppend(sBerryBlender->stringVar, sText_Min);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
ConvertIntToDecimalStringN(txtPtr, seconds, STR_CONV_MODE_LEADING_ZEROS, 2);
|
2020-08-23 00:20:22 +02:00
|
|
|
StringAppend(sBerryBlender->stringVar, sText_Sec);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
xPos = GetStringRightAlignXOffset(1, sBerryBlender->stringVar, 0xA8);
|
|
|
|
Blender_AddTextPrinter(5, sBerryBlender->stringVar, xPos, 0x61, TEXT_SPEED_FF, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
CopyWindowToVram(5, 2);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
2020-08-24 20:52:33 +02:00
|
|
|
if (JOY_NEW(A_BUTTON))
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 5:
|
2019-02-22 07:40:11 +01:00
|
|
|
ClearStdWindowAndFrameToTransparent(5, 1);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
for (i = 0; i < BLENDER_MAX_PLAYERS; i++)
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->chosenItemId[i] != 0)
|
|
|
|
berryIds[i] = sBerryBlender->chosenItemId[i] - FIRST_BERRY_INDEX;
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->arrowIdToPlayerId[i] != NO_PLAYER)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
PutWindowTilemap(i);
|
|
|
|
CopyWindowToVram(i, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
Debug_SetStageVars();
|
|
|
|
CalculatePokeblock(sBerryBlender->blendedBerries, &pokeblock, sBerryBlender->numPlayers, flavors, sBerryBlender->maxRPM);
|
|
|
|
PrintMadePokeblockString(&pokeblock, sBerryBlender->stringVar);
|
2020-08-23 00:20:22 +02:00
|
|
|
TryAddContestLinkTvShow(&pokeblock, &sBerryBlender->tvBlender);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
CreateTask(Task_PlayPokeblockFanfare, 6);
|
2019-10-20 08:31:51 +02:00
|
|
|
IncrementDailyBerryBlender();
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
RemoveBagItem(gSpecialVar_ItemId, 1);
|
|
|
|
AddPokeblock(&pokeblock);
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->textState = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 6:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (Blender_PrintText(&sBerryBlender->textState, sBerryBlender->stringVar, GetPlayerTextSpeedDelay()))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
TryUpdateBerryBlenderRecord();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void PrintMadePokeblockString(struct Pokeblock *pokeblock, u8 *dst)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u8 text[12];
|
2017-11-27 20:03:41 +01:00
|
|
|
u8 flavorLvl, feel;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
dst[0] = EOS;
|
|
|
|
StringCopy(dst, gPokeblockNames[pokeblock->color]);
|
|
|
|
StringAppend(dst, sText_WasMade);
|
|
|
|
StringAppend(dst, sText_NewLine);
|
|
|
|
|
2017-11-27 20:03:41 +01:00
|
|
|
flavorLvl = GetHighestPokeblocksFlavorLevel(pokeblock);
|
2017-11-19 22:48:46 +01:00
|
|
|
feel = GetPokeblocksFeel(pokeblock);
|
|
|
|
|
|
|
|
StringAppend(dst, sText_TheLevelIs);
|
2017-11-27 20:03:41 +01:00
|
|
|
ConvertIntToDecimalStringN(text, flavorLvl, STR_CONV_MODE_LEFT_ALIGN, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
StringAppend(dst, text);
|
|
|
|
|
|
|
|
StringAppend(dst, sText_TheFeelIs);
|
|
|
|
ConvertIntToDecimalStringN(text, feel, STR_CONV_MODE_LEFT_ALIGN, 3);
|
|
|
|
StringAppend(dst, text);
|
|
|
|
|
|
|
|
StringAppend(dst, sText_Dot2);
|
|
|
|
StringAppend(dst, sText_NewParagraph);
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void SortBasedOnPoints(u8 *places, u8 playersNum, u32 *scores)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
s32 i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < playersNum; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < playersNum; j++)
|
|
|
|
{
|
|
|
|
if (scores[places[i]] > scores[places[j]])
|
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
u8 temp;
|
|
|
|
SWAP(places[i], places[j], temp);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void SortScores(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u8 playerId;
|
|
|
|
u8 i;
|
|
|
|
u8 places[BLENDER_MAX_PLAYERS];
|
|
|
|
u32 points[BLENDER_MAX_PLAYERS];
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < sBerryBlender->numPlayers; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
places[i] = i;
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < sBerryBlender->numPlayers; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
points[i] = 1000000 * sBerryBlender->scores[i][SCORE_BEST];
|
|
|
|
points[i] += 1000 * sBerryBlender->scores[i][SCORE_GOOD];
|
|
|
|
points[i] += 1000 - sBerryBlender->scores[i][SCORE_MISS];
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
SortBasedOnPoints(places, sBerryBlender->numPlayers, points);
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < sBerryBlender->numPlayers; i++)
|
|
|
|
sBerryBlender->playerPlaces[i] = places[i];
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (!gReceivedRemoteLinkPlayers)
|
2017-11-19 22:48:46 +01:00
|
|
|
playerId = 0;
|
|
|
|
else
|
|
|
|
playerId = GetMultiplayerId();
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
for (i = 0; i < sBerryBlender->numPlayers; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
if (sBerryBlender->playerPlaces[i] == playerId)
|
2020-08-24 20:52:33 +02:00
|
|
|
sBerryBlender->ownRanking = i;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
static bool8 PrintBlendingRanking(void)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
s32 xPos, yPos;
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
switch (sBerryBlender->mainState)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
|
|
|
sBerryBlender->framesToWait = 255;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait -= 10;
|
|
|
|
if (sBerryBlender->framesToWait < 0)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 20)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
2019-02-22 07:40:11 +01:00
|
|
|
DrawStdFrameWithCustomTileAndPalette(5, 0, 1, 0xD);
|
2020-08-24 20:52:33 +02:00
|
|
|
xPos = GetStringCenterAlignXOffset(1, sText_Ranking, 168);
|
2017-11-19 22:48:46 +01:00
|
|
|
Blender_AddTextPrinter(5, sText_Ranking, xPos, 1, TEXT_SPEED_FF, 0);
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->scoreIconIds[SCORE_BEST] = CreateSprite(&sSpriteTemplate_ScoreSymbols, 128, 52, 0);
|
|
|
|
StartSpriteAnim(&gSprites[sBerryBlender->scoreIconIds[SCORE_BEST]], SCOREANIM_BEST_STATIC);
|
|
|
|
gSprites[sBerryBlender->scoreIconIds[SCORE_BEST]].callback = SpriteCallbackDummy;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->scoreIconIds[SCORE_GOOD] = CreateSprite(&sSpriteTemplate_ScoreSymbols, 160, 52, 0);
|
|
|
|
// implicitly uses SCOREANIM_GOOD, no need to assign
|
|
|
|
gSprites[sBerryBlender->scoreIconIds[SCORE_GOOD]].callback = SpriteCallbackDummy;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->scoreIconIds[SCORE_MISS] = CreateSprite(&sSpriteTemplate_ScoreSymbols, 192, 52, 0);
|
|
|
|
StartSpriteAnim(&gSprites[sBerryBlender->scoreIconIds[SCORE_MISS]], SCOREANIM_MISS);
|
|
|
|
gSprites[sBerryBlender->scoreIconIds[SCORE_MISS]].callback = SpriteCallbackDummy;
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
SortScores();
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
for (yPos = 41, i = 0; i < sBerryBlender->numPlayers; yPos += 16, i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
u8 place = sBerryBlender->playerPlaces[i];
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
ConvertIntToDecimalStringN(sBerryBlender->stringVar, i + 1, STR_CONV_MODE_LEFT_ALIGN, 1);
|
|
|
|
StringAppend(sBerryBlender->stringVar, sText_Dot);
|
|
|
|
StringAppend(sBerryBlender->stringVar, gText_Space);
|
|
|
|
StringAppend(sBerryBlender->stringVar, gLinkPlayers[place].name);
|
|
|
|
Blender_AddTextPrinter(5, sBerryBlender->stringVar, 0, yPos, TEXT_SPEED_FF, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_BEST], STR_CONV_MODE_RIGHT_ALIGN, 3);
|
2020-08-24 20:52:33 +02:00
|
|
|
Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78, yPos, TEXT_SPEED_FF, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_GOOD], STR_CONV_MODE_RIGHT_ALIGN, 3);
|
2020-08-24 20:52:33 +02:00
|
|
|
Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78 + 32, yPos, TEXT_SPEED_FF, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_MISS], STR_CONV_MODE_RIGHT_ALIGN, 3);
|
2020-08-24 20:52:33 +02:00
|
|
|
Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78 + 64, yPos, TEXT_SPEED_FF, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
PutWindowTilemap(5);
|
|
|
|
CopyWindowToVram(5, 3);
|
|
|
|
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->framesToWait = 0;
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 4:
|
2020-08-23 00:20:22 +02:00
|
|
|
if (++sBerryBlender->framesToWait > 20)
|
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 5:
|
2020-08-24 20:52:33 +02:00
|
|
|
if (JOY_NEW(A_BUTTON))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
PlaySE(SE_SELECT);
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState++;
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 6:
|
2020-08-23 00:20:22 +02:00
|
|
|
sBerryBlender->mainState = 0;
|
2017-11-19 22:48:46 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ShowBerryBlenderRecordWindow(void)
|
|
|
|
{
|
|
|
|
s32 i;
|
|
|
|
s32 xPos, yPos;
|
|
|
|
struct WindowTemplate winTemplate;
|
|
|
|
u8 text[32];
|
|
|
|
|
|
|
|
winTemplate = sBlenderRecordWindowTemplate;
|
2018-05-01 15:33:13 +02:00
|
|
|
gRecordsWindowId = AddWindow(&winTemplate);
|
2019-02-22 07:40:11 +01:00
|
|
|
DrawStdWindowFrame(gRecordsWindowId, 0);
|
2019-03-02 23:25:39 +01:00
|
|
|
FillWindowPixelBuffer(gRecordsWindowId, PIXEL_FILL(1));
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
xPos = GetStringCenterAlignXOffset(1, gText_BlenderMaxSpeedRecord, 144);
|
2018-09-08 23:38:30 +02:00
|
|
|
AddTextPrinterParameterized(gRecordsWindowId, 1, gText_BlenderMaxSpeedRecord, xPos, 1, 0, NULL);
|
2020-08-24 20:52:33 +02:00
|
|
|
AddTextPrinterParameterized(gRecordsWindowId, 1, gText_234Players, 4, 41, 0, NULL);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
for (i = 0, yPos = 41; i < NUM_SCORE_TYPES; i++)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
u8 *txtPtr;
|
|
|
|
u32 record;
|
|
|
|
|
|
|
|
record = gSaveBlock1Ptr->berryBlenderRecords[i];
|
|
|
|
|
|
|
|
txtPtr = ConvertIntToDecimalStringN(text, record / 100, STR_CONV_MODE_RIGHT_ALIGN, 3);
|
|
|
|
txtPtr = StringAppend(txtPtr, sText_Dot);
|
|
|
|
txtPtr = ConvertIntToDecimalStringN(txtPtr, record % 100, STR_CONV_MODE_LEADING_ZEROS, 2);
|
|
|
|
txtPtr = StringAppend(txtPtr, sText_RPM);
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
xPos = GetStringRightAlignXOffset(1, text, 140);
|
2018-09-08 23:38:30 +02:00
|
|
|
AddTextPrinterParameterized(gRecordsWindowId, 1, text, xPos, yPos + (i * 16), 0, NULL);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2018-05-01 15:33:13 +02:00
|
|
|
PutWindowTilemap(gRecordsWindowId);
|
|
|
|
CopyWindowToVram(gRecordsWindowId, 3);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
static void Task_PlayPokeblockFanfare(u8 taskId)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
if (gTasks[taskId].data[0] == 0)
|
|
|
|
{
|
2020-08-21 00:02:00 +02:00
|
|
|
PlayFanfare(MUS_LEVEL_UP);
|
2017-11-19 22:48:46 +01:00
|
|
|
gTasks[taskId].data[0]++;
|
|
|
|
}
|
|
|
|
if (IsFanfareTaskInactive())
|
|
|
|
{
|
2020-08-23 00:20:22 +02:00
|
|
|
PlayBGM(sBerryBlender->savedMusic);
|
2017-11-19 22:48:46 +01:00
|
|
|
DestroyTask(taskId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool32 TryAddContestLinkTvShow(struct Pokeblock *pokeblock, struct TvBlenderStruct *tvBlender)
|
|
|
|
{
|
2017-11-27 20:03:41 +01:00
|
|
|
u8 flavorLevel = GetHighestPokeblocksFlavorLevel(pokeblock);
|
|
|
|
u16 sheen = (flavorLevel * 10) / GetPokeblocksFeel(pokeblock);
|
2017-11-19 22:48:46 +01:00
|
|
|
|
|
|
|
tvBlender->pokeblockSheen = sheen;
|
|
|
|
tvBlender->pokeblockColor = pokeblock->color;
|
|
|
|
tvBlender->name[0] = EOS;
|
|
|
|
|
2020-08-24 20:52:33 +02:00
|
|
|
if (gReceivedRemoteLinkPlayers)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
if (sBerryBlender->ownRanking == 0 && sheen > 20)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Player came first, try to put on air
|
2020-08-23 00:20:22 +02:00
|
|
|
StringCopy(tvBlender->name, gLinkPlayers[sBerryBlender->playerPlaces[sBerryBlender->numPlayers - 1]].name);
|
2017-11-27 20:03:41 +01:00
|
|
|
tvBlender->pokeblockFlavor = GetPokeblocksFlavor(pokeblock);
|
|
|
|
if (Put3CheersForPokeblocksOnTheAir(tvBlender->name, tvBlender->pokeblockFlavor,
|
2017-11-19 22:48:46 +01:00
|
|
|
tvBlender->pokeblockColor, tvBlender->pokeblockSheen,
|
2020-08-23 00:20:22 +02:00
|
|
|
gLinkPlayers[sBerryBlender->playerPlaces[sBerryBlender->numPlayers - 1]].language))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
2020-08-24 20:52:33 +02:00
|
|
|
else if (sBerryBlender->ownRanking == sBerryBlender->numPlayers - 1 && sheen <= 20)
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
2020-08-24 20:52:33 +02:00
|
|
|
// Player came last, try to put on air
|
2020-08-23 00:20:22 +02:00
|
|
|
StringCopy(tvBlender->name, gLinkPlayers[sBerryBlender->playerPlaces[0]].name);
|
2017-11-27 20:03:41 +01:00
|
|
|
tvBlender->pokeblockFlavor = GetPokeblocksFlavor(pokeblock);
|
|
|
|
if (Put3CheersForPokeblocksOnTheAir(tvBlender->name, tvBlender->pokeblockFlavor,
|
2017-11-19 22:48:46 +01:00
|
|
|
tvBlender->pokeblockColor, tvBlender->pokeblockSheen,
|
2020-08-23 00:20:22 +02:00
|
|
|
gLinkPlayers[sBerryBlender->playerPlaces[0]].language))
|
2017-11-19 22:48:46 +01:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Blender_AddTextPrinter(u8 windowId, const u8 *string, u8 x, u8 y, s32 speed, s32 caseId)
|
|
|
|
{
|
2018-02-07 03:37:54 +01:00
|
|
|
u8 txtColor[3];
|
2017-11-19 22:48:46 +01:00
|
|
|
u32 letterSpacing = 0;
|
|
|
|
|
|
|
|
switch (caseId)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 3:
|
2020-08-24 20:52:33 +02:00
|
|
|
txtColor[0] = TEXT_COLOR_WHITE;
|
2021-04-10 04:39:34 +02:00
|
|
|
txtColor[1] = TEXT_COLOR_DARK_GRAY;
|
|
|
|
txtColor[2] = TEXT_COLOR_LIGHT_GRAY;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2020-08-24 20:52:33 +02:00
|
|
|
txtColor[0] = TEXT_COLOR_TRANSPARENT;
|
2021-04-10 04:39:34 +02:00
|
|
|
txtColor[1] = TEXT_COLOR_DARK_GRAY;
|
|
|
|
txtColor[2] = TEXT_COLOR_LIGHT_GRAY;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2020-08-24 20:52:33 +02:00
|
|
|
txtColor[0] = TEXT_COLOR_TRANSPARENT;
|
|
|
|
txtColor[1] = TEXT_COLOR_RED;
|
|
|
|
txtColor[2] = TEXT_COLOR_LIGHT_RED;
|
2017-11-19 22:48:46 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (caseId != 3)
|
|
|
|
{
|
2019-03-02 23:25:39 +01:00
|
|
|
FillWindowPixelBuffer(windowId, PIXEL_FILL(txtColor[0]));
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
2018-09-08 23:38:30 +02:00
|
|
|
AddTextPrinterParameterized4(windowId, 1, x, y, letterSpacing, 1, txtColor, speed, string);
|
2017-11-19 22:48:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool32 Blender_PrintText(s16 *textState, const u8 *string, s32 textSpeed)
|
|
|
|
{
|
|
|
|
switch (*textState)
|
|
|
|
{
|
|
|
|
case 0:
|
2019-02-22 07:40:11 +01:00
|
|
|
DrawDialogFrameWithCustomTileAndPalette(4, FALSE, 0x14, 0xF);
|
2017-11-19 22:48:46 +01:00
|
|
|
Blender_AddTextPrinter(4, string, 0, 1, textSpeed, 0);
|
|
|
|
PutWindowTilemap(4);
|
|
|
|
CopyWindowToVram(4, 3);
|
|
|
|
(*textState)++;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (!IsTextPrinterActive(4))
|
|
|
|
{
|
|
|
|
*textState = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2017-09-30 16:12:35 +02:00
|
|
|
|
2017-11-19 22:48:46 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|