Merge pull request #580 from GriffinRichards/sync-rfu2
Sync wireless link
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
gHostRFUtgtGnameBuffer
|
||||
Rfu
|
||||
gHostRFUtgtUnameBuffer
|
||||
gHostRfuGameData
|
||||
gRfu
|
||||
gHostRfuUsername
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
.set LOCALID_UNION_ROOM_PLAYER_4, 2
|
||||
.set LOCALID_UNION_ROOM_PLAYER_8, 3
|
||||
.set LOCALID_UNION_ROOM_PLAYER_7, 4
|
||||
.set LOCALID_UNION_ROOM_PLAYER_6, 5
|
||||
.set LOCALID_UNION_ROOM_PLAYER_5, 6
|
||||
.set LOCALID_UNION_ROOM_PLAYER_3, 7
|
||||
.set LOCALID_UNION_ROOM_PLAYER_2, 8
|
||||
.set LOCALID_UNION_ROOM_PLAYER_1, 9
|
||||
|
||||
UnionRoom_MapScripts::
|
||||
map_script MAP_SCRIPT_ON_RESUME, UnionRoom_OnResume
|
||||
map_script MAP_SCRIPT_ON_TRANSITION, UnionRoom_OnTransition
|
||||
@@ -29,7 +20,7 @@ UnionRoom_OnResume::
|
||||
removeobject LOCALID_UNION_ROOM_PLAYER_6
|
||||
removeobject LOCALID_UNION_ROOM_PLAYER_7
|
||||
removeobject LOCALID_UNION_ROOM_PLAYER_8
|
||||
special UnionRoomSpecial
|
||||
special RunUnionRoom
|
||||
end
|
||||
|
||||
UnionRoom_OnTransition::
|
||||
|
||||
@@ -796,7 +796,7 @@ CableClub_EventScript_EnterUnionRoom::
|
||||
special SetCableClubWarp
|
||||
warpspinenter MAP_UNION_ROOM, 7, 11
|
||||
waitstate
|
||||
special UnionRoomSpecial
|
||||
special RunUnionRoom
|
||||
waitstate
|
||||
end
|
||||
|
||||
|
||||
+1
-1
@@ -373,7 +373,7 @@ gSpecials::
|
||||
def_special IsWirelessAdapterConnected
|
||||
def_special TryBecomeLinkLeader
|
||||
def_special TryJoinLinkGroup
|
||||
def_special UnionRoomSpecial
|
||||
def_special RunUnionRoom
|
||||
def_special ShowWirelessCommunicationScreen
|
||||
def_special EnableNationalPokedex
|
||||
def_special SetWalkingIntoSignVars
|
||||
|
||||
|
Before Width: | Height: | Size: 308 B After Width: | Height: | Size: 308 B |
@@ -1,19 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
|
Before Width: | Height: | Size: 490 B After Width: | Height: | Size: 490 B |
@@ -189,10 +189,21 @@
|
||||
#define TRACKS_FOOT 1
|
||||
#define TRACKS_BIKE_TIRE 2
|
||||
|
||||
#define OBJ_EVENT_ID_PLAYER 0xFF
|
||||
#define OBJ_EVENT_ID_CAMERA 0x7F
|
||||
|
||||
#define OBJ_KIND_NORMAL 0
|
||||
#define OBJ_KIND_CLONE 255
|
||||
|
||||
// Special object event local ids
|
||||
#define OBJ_EVENT_ID_PLAYER 0xFF
|
||||
#define OBJ_EVENT_ID_CAMERA 0x7F
|
||||
|
||||
// Object event local ids referenced in C files
|
||||
#define LOCALID_UNION_ROOM_PLAYER_4 2
|
||||
#define LOCALID_UNION_ROOM_PLAYER_8 3
|
||||
#define LOCALID_UNION_ROOM_PLAYER_7 4
|
||||
#define LOCALID_UNION_ROOM_PLAYER_6 5
|
||||
#define LOCALID_UNION_ROOM_PLAYER_5 6
|
||||
#define LOCALID_UNION_ROOM_PLAYER_3 7
|
||||
#define LOCALID_UNION_ROOM_PLAYER_2 8
|
||||
#define LOCALID_UNION_ROOM_PLAYER_1 9
|
||||
|
||||
#endif // GUARD_CONSTANTS_EVENT_OBJECTS_H
|
||||
|
||||
@@ -1,47 +1,51 @@
|
||||
#ifndef GUARD_CONSTANTS_UNION_ROOM_H
|
||||
#define GUARD_CONSTANTS_UNION_ROOM_H
|
||||
|
||||
// The number of possible group leaders visible in the Union Room.
|
||||
// Note that this is different than the number of people actively
|
||||
// connected as children via the Wireless Adapter, which cannot
|
||||
// exceed RFU_CHILD_MAX (4), for a total of 5 including the player.
|
||||
#define MAX_UNION_ROOM_LEADERS 8
|
||||
|
||||
#define UNION_ROOM_SPAWN_NONE 0
|
||||
#define UNION_ROOM_SPAWN_IN 1
|
||||
#define UNION_ROOM_SPAWN_OUT 2
|
||||
|
||||
#define ACTIVITY_NONE 0
|
||||
#define ACTIVITY_BATTLE 1
|
||||
#define ACTIVITY_DBLBATTLE 2
|
||||
#define ACTIVITY_MLTBATTLE 3
|
||||
#define ACTIVITY_TRADE 4
|
||||
#define ACTIVITY_CHAT 5
|
||||
#define ACTIVITY_WCARD 6
|
||||
#define ACTIVITY_WNEWS 7
|
||||
#define ACTIVITY_CARD 8
|
||||
#define ACTIVITY_PJUMP 9
|
||||
#define ACTIVITY_BCRUSH 10
|
||||
#define ACTIVITY_BPICK 11
|
||||
#define ACTIVITY_SEARCH 12
|
||||
#define ACTIVITY_SPINTRADE 13
|
||||
#define ACTIVITY_ITEMTRADE 14
|
||||
#define UNION_ROOM_MAX_LEVEL 30
|
||||
|
||||
// The number of possible trainer classes for a trainer of a given gender in the Union Room.
|
||||
// This value is necessarily a power of 2 because of the way it's treated in GetUnionRoomTrainerPic / GetUnionRoomTrainerClass
|
||||
#define NUM_UNION_ROOM_CLASSES (1 << 3) // 8
|
||||
|
||||
#define ACTIVITY_NONE 0
|
||||
#define ACTIVITY_BATTLE_SINGLE 1
|
||||
#define ACTIVITY_BATTLE_DOUBLE 2
|
||||
#define ACTIVITY_BATTLE_MULTI 3
|
||||
#define ACTIVITY_TRADE 4
|
||||
#define ACTIVITY_CHAT 5
|
||||
#define ACTIVITY_WONDER_CARD_DUP 6 // Duplicates of later WONDER constants
|
||||
#define ACTIVITY_WONDER_NEWS_DUP 7 //
|
||||
#define ACTIVITY_CARD 8
|
||||
#define ACTIVITY_POKEMON_JUMP 9
|
||||
#define ACTIVITY_BERRY_CRUSH 10
|
||||
#define ACTIVITY_BERRY_PICK 11
|
||||
#define ACTIVITY_SEARCH 12
|
||||
#define ACTIVITY_SPIN_TRADE 13
|
||||
#define ACTIVITY_ITEM_TRADE 14 // Replaced with ACTIVITY_BATTLE_TOWER_OPEN in Emerald
|
||||
#define ACTIVITY_RECORD_CORNER 15
|
||||
#define ACTIVITY_BERRY_BLENDER 16
|
||||
|
||||
// Player response
|
||||
#define ACTIVITY_ACCEPT 17
|
||||
#define ACTIVITY_DECLINE 18
|
||||
#define ACTIVITY_ACCEPT 17
|
||||
#define ACTIVITY_DECLINE 18
|
||||
|
||||
#define ACTIVITY_NPCTALK 19
|
||||
#define ACTIVITY_PLYRTALK 20
|
||||
#define ACTIVITY_NPCTALK 19
|
||||
#define ACTIVITY_PLYRTALK 20
|
||||
|
||||
// Duplicate IDs?
|
||||
#define ACTIVITY_WCARD2 21
|
||||
#define ACTIVITY_WNEWS2 22
|
||||
#define ACTIVITY_WONDER_CARD 21
|
||||
#define ACTIVITY_WONDER_NEWS 22
|
||||
|
||||
#define IN_UNION_ROOM 0x40
|
||||
|
||||
// Used in UR_AddTextPrinterParameterized
|
||||
#define UR_COLOR_DKE_WHT_LTE 0
|
||||
#define UR_COLOR_RED_WHT_LTR 1
|
||||
#define UR_COLOR_GRN_WHT_LTG 2
|
||||
#define UR_COLOR_WHT_WHT_LTE 3
|
||||
#define UR_COLOR_WHT_DKE_LTE 4
|
||||
#define UR_COLOR_GRN_DN6_LTB 5
|
||||
#define UR_COLOR_DN5_DN6_LTB 6
|
||||
#define IN_UNION_ROOM (1 << 6)
|
||||
|
||||
#define LINK_GROUP_SINGLE_BATTLE 0
|
||||
#define LINK_GROUP_DOUBLE_BATTLE 1
|
||||
@@ -52,9 +56,30 @@
|
||||
#define LINK_GROUP_BERRY_PICKING 6
|
||||
#define LINK_GROUP_WONDER_CARD 7
|
||||
#define LINK_GROUP_WONDER_NEWS 8
|
||||
#define NUM_LINK_GROUP_TYPES 9
|
||||
|
||||
#define LINK_GROUP_UNION_ROOM_RESUME 9
|
||||
#define LINK_GROUP_UNION_ROOM_INIT 10
|
||||
#define LINK_GROUP_UNK_11 11
|
||||
#define LINK_GROUP_UNK_12 12
|
||||
#define NUM_LINK_GROUP_TYPES 13
|
||||
|
||||
#define UR_TRADE_MATCH 0
|
||||
#define UR_TRADE_NOTYPE 1
|
||||
#define UR_TRADE_NOEGG 2
|
||||
|
||||
#define UR_TRADE_READY 0
|
||||
#define UR_TRADE_PLAYER_NOT_READY 1
|
||||
#define UR_TRADE_PARTNER_NOT_READY 2
|
||||
|
||||
#define UR_INTERACT_PLAYER_1 1
|
||||
#define UR_INTERACT_PLAYER_2 2
|
||||
#define UR_INTERACT_PLAYER_3 3
|
||||
#define UR_INTERACT_PLAYER_4 4
|
||||
#define UR_INTERACT_PLAYER_5 5
|
||||
#define UR_INTERACT_PLAYER_6 6
|
||||
#define UR_INTERACT_PLAYER_7 7
|
||||
#define UR_INTERACT_PLAYER_8 8
|
||||
#define UR_INTERACT_ATTENDANT 9
|
||||
#define UR_INTERACT_UNUSED 10
|
||||
#define UR_INTERACT_START_MENU 11
|
||||
|
||||
#endif //GUARD_CONSTANTS_UNION_ROOM_H
|
||||
|
||||
@@ -27,6 +27,9 @@ typedef double f64;
|
||||
typedef u8 bool8;
|
||||
typedef u16 bool16;
|
||||
typedef u32 bool32;
|
||||
typedef vu8 vbool8;
|
||||
typedef vu16 vbool16;
|
||||
typedef vu32 vbool32;
|
||||
|
||||
struct BgCnt
|
||||
{
|
||||
|
||||
+1
-2
@@ -269,7 +269,7 @@ void SetSuppressLinkErrorMessage(bool8);
|
||||
bool8 HasLinkErrorOccurred(void);
|
||||
void ResetSerial(void);
|
||||
u32 LinkMain1(u8 *, u16 *, u16[MAX_RFU_PLAYERS][CMD_LENGTH]);
|
||||
void RFUVSync(void);
|
||||
void RfuVSync(void);
|
||||
void Timer3Intr(void);
|
||||
void SerialCB(void);
|
||||
u8 GetLinkPlayerCount(void);
|
||||
@@ -277,7 +277,6 @@ bool32 InUnionRoom(void);
|
||||
|
||||
void SetLinkStandbyCallback(void);
|
||||
void SetWirelessCommType1(void);
|
||||
void LinkRfu_DestroyIdleTask(void);
|
||||
void SetCloseLinkCallback(void);
|
||||
void OpenLink(void);
|
||||
bool8 IsLinkMaster(void);
|
||||
|
||||
+162
-140
@@ -6,35 +6,29 @@
|
||||
#include "link.h"
|
||||
#include "AgbRfu_LinkManager.h"
|
||||
|
||||
#define RFUCMD_MASK 0xFF00
|
||||
#define RFUCMD_MASK 0xFF00
|
||||
|
||||
#define RFUCMD_SEND_PACKET 0x2F00
|
||||
#define RFUCMD_READY_CLOSE_LINK 0x5f00
|
||||
#define RFUCMD_READY_EXIT_STANDBY 0x6600
|
||||
#define RFUCMD_PLAYERS_LIST 0x7700
|
||||
#define RFUCMD_PLAYERS_LIST_2 0x7800
|
||||
#define RFUCMD_SEND_BLOCK_INIT 0x8800
|
||||
#define RFUCMD_SEND_BLOCK_STEP 0x8900
|
||||
#define RFUCMD_SEND_BLOCK_REQ 0xa100
|
||||
#define RFUCMD_SEND_HELD_KEYS 0xbe00
|
||||
#define RFUCMD_PARENT_DISCONNECT 0xed00
|
||||
#define RFUCMD_CHILD_DISCONNECT 0xee00
|
||||
#define RFUCMD_SEND_PACKET 0x2F00
|
||||
#define RFUCMD_BLENDER_SEND_KEYS 0x4400
|
||||
#define RFUCMD_READY_CLOSE_LINK 0x5F00
|
||||
#define RFUCMD_READY_EXIT_STANDBY 0x6600
|
||||
#define RFUCMD_SEND_PLAYER_IDS 0x7700
|
||||
#define RFUCMD_SEND_PLAYER_IDS_NEW 0x7800
|
||||
#define RFUCMD_SEND_BLOCK_INIT 0x8800
|
||||
#define RFUCMD_SEND_BLOCK 0x8900
|
||||
#define RFUCMD_SEND_BLOCK_REQ 0xA100
|
||||
#define RFUCMD_SEND_HELD_KEYS 0xBE00
|
||||
#define RFUCMD_DISCONNECT 0xED00
|
||||
#define RFUCMD_DISCONNECT_PARENT 0xEE00
|
||||
|
||||
#define RFU_PACKET_SIZE 6
|
||||
|
||||
#define RFU_SERIAL_7F7D 0x7F7D
|
||||
#define RFU_SERIAL_GAME 0x0002 // Serial number for Pokémon game (FRLG or Emerald)
|
||||
#define RFU_SERIAL_WONDER_DISTRIBUTOR 0x7F7D // Serial number for distributing Wonder Cards / News
|
||||
#define RFU_SERIAL_END 0xFFFF
|
||||
|
||||
#define COMM_SLOT_LENGTH 14
|
||||
#define RECV_QUEUE_NUM_SLOTS 20
|
||||
#define RECV_QUEUE_SLOT_LENGTH (14 * MAX_RFU_PLAYERS)
|
||||
|
||||
#define SEND_QUEUE_NUM_SLOTS 40
|
||||
#define SEND_QUEUE_SLOT_LENGTH 14
|
||||
|
||||
#define BACKUP_QUEUE_NUM_SLOTS 2
|
||||
#define BACKUP_QUEUE_SLOT_LENGTH 14
|
||||
|
||||
#define UNUSED_QUEUE_NUM_SLOTS 2
|
||||
#define UNUSED_QUEUE_SLOT_LENGTH 256
|
||||
|
||||
#define RFU_PACKET_SIZE 6
|
||||
|
||||
@@ -48,50 +42,88 @@
|
||||
#define RFU_STATUS_WAIT_ACK_JOIN_GROUP 7
|
||||
#define RFU_STATUS_LEAVE_GROUP_NOTICE 8
|
||||
#define RFU_STATUS_LEAVE_GROUP 9
|
||||
#define RFU_STATUS_10 10
|
||||
#define RFU_STATUS_11 11
|
||||
#define RFU_STATUS_CHILD_LEAVE_READY 10
|
||||
#define RFU_STATUS_CHILD_LEAVE 11
|
||||
#define RFU_STATUS_ACK_JOIN_GROUP 12
|
||||
|
||||
#define RFU_RECV_IDLE 0
|
||||
#define RFU_RECV_RECEIVING 1
|
||||
#define RFU_RECV_FINISHED 2
|
||||
// Values for disconnectMode
|
||||
enum {
|
||||
RFU_DISCONNECT_NONE,
|
||||
RFU_DISCONNECT_ERROR,
|
||||
RFU_DISCONNECT_NORMAL,
|
||||
};
|
||||
|
||||
// Values for errorState
|
||||
enum {
|
||||
RFU_ERROR_STATE_NONE,
|
||||
RFU_ERROR_STATE_OCCURRED,
|
||||
RFU_ERROR_STATE_PROCESSED,
|
||||
RFU_ERROR_STATE_DISCONNECTING,
|
||||
RFU_ERROR_STATE_IGNORE,
|
||||
};
|
||||
|
||||
// These error flags are set in errorInfo, and given as
|
||||
// the uppermost 16 bits of 'status' for sLinkErrorBuffer.
|
||||
// The first 8 bits are reserved for the link manager msg
|
||||
// when the error occurred, and the last 8 bits are this
|
||||
// sequence of presumably meaningful error flags, but
|
||||
// ultimately sLinkErrorBuffer's status is never read.
|
||||
#define F_RFU_ERROR_1 (1 << 8)
|
||||
#define F_RFU_ERROR_2 (1 << 9) // Never set
|
||||
#define F_RFU_ERROR_3 (1 << 10) // Never set
|
||||
#define F_RFU_ERROR_4 (1 << 11) // Never set
|
||||
#define F_RFU_ERROR_5 (1 << 12)
|
||||
#define F_RFU_ERROR_6 (1 << 13)
|
||||
#define F_RFU_ERROR_7 (1 << 14)
|
||||
#define F_RFU_ERROR_8 (1 << 15)
|
||||
|
||||
// RfuTgtData.gname is read as these structs.
|
||||
struct GFtgtGnameSub
|
||||
struct RfuGameCompatibilityData
|
||||
{
|
||||
u16 language:4;
|
||||
u16 hasNews:1;
|
||||
u16 hasCard:1;
|
||||
u16 unknown:1;
|
||||
u16 unknown:1; // Never read
|
||||
u16 isChampion:1;
|
||||
u16 hasNationalDex:1;
|
||||
u16 gameClear:1;
|
||||
u16 version:4;
|
||||
u16 unk_01_6:2;
|
||||
u16 unused:2;
|
||||
u8 playerTrainerId[2];
|
||||
};
|
||||
|
||||
struct __attribute__((packed, aligned(2))) GFtgtGname
|
||||
// This struct is sent via the Wireless Adapter as the game name or "gname" data.
|
||||
// Gname is only applicable during Wireless Single Game Pak Multiplay, when the
|
||||
// adapter needs this data for connection. Per the RFU manual, during "normal"
|
||||
// wireless play (the kind the Pokémon games use) the gname data can be used for
|
||||
// anything the developers want. This struct is what GF decided to use it for.
|
||||
// It can be up to 13 bytes in size (RFU_GAME_NAME_LENGTH).
|
||||
// The player's name is sent separately as the username ("uname"), and does not
|
||||
// use a struct (gHostRfuUsername).
|
||||
struct __attribute__((packed, aligned(2))) RfuGameData
|
||||
{
|
||||
struct GFtgtGnameSub unk_00;
|
||||
u8 child_sprite_gender[RFU_CHILD_MAX]; // u8 sprite_idx:3;
|
||||
// u8 gender:1;
|
||||
// u8 unk_4:3
|
||||
// u8 active:1
|
||||
u16 species:10;
|
||||
u16 type:6;
|
||||
struct RfuGameCompatibilityData compatibility;
|
||||
u8 partnerInfo[RFU_CHILD_MAX];
|
||||
u16 tradeSpecies:10;
|
||||
u16 tradeType:6;
|
||||
u8 activity:7;
|
||||
u8 started:1;
|
||||
u8 startedActivity:1;
|
||||
u8 playerGender:1;
|
||||
u8 level:7;
|
||||
u8 tradeLevel:7;
|
||||
u8 padding;
|
||||
}; // size: RFU_GNAME_SIZE
|
||||
|
||||
struct Padded_U8
|
||||
{
|
||||
u8 value;
|
||||
};
|
||||
|
||||
// Constants for getting/setting information in 'partnerInfo' of RfuGameData.
|
||||
// This data is used to determine what the link partners look like from
|
||||
// the host's perspective.
|
||||
// Bits 0-2 are a shortened trainerId
|
||||
// Bit 3 is the player's gender
|
||||
// Bits 4-6 are unknown/unused
|
||||
// Bit 7 is an 'active' flag
|
||||
#define PINFO_TID_MASK 0x7
|
||||
#define PINFO_GENDER_SHIFT 3
|
||||
#define PINFO_ACTIVE_FLAG (1 << 7)
|
||||
|
||||
struct RfuBlockSend
|
||||
{
|
||||
/* 0x00 */ u16 next;
|
||||
@@ -106,59 +138,50 @@ struct RfuBlockSend
|
||||
|
||||
struct RfuRecvQueue
|
||||
{
|
||||
/* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][RECV_QUEUE_SLOT_LENGTH];
|
||||
/* 0x578 */ vu8 recv_slot;
|
||||
/* 0x579 */ vu8 send_slot;
|
||||
/* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH * MAX_RFU_PLAYERS];
|
||||
/* 0x578 */ vu8 recvSlot;
|
||||
/* 0x579 */ vu8 sendSlot;
|
||||
/* 0x57a */ vu8 count;
|
||||
/* 0x57b */ vu8 full;
|
||||
};
|
||||
|
||||
struct RfuSendQueue
|
||||
{
|
||||
/* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][SEND_QUEUE_SLOT_LENGTH];
|
||||
/* 0x230 */ vu8 recv_slot;
|
||||
/* 0x231 */ vu8 send_slot;
|
||||
/* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH];
|
||||
/* 0x230 */ vu8 recvSlot;
|
||||
/* 0x231 */ vu8 sendSlot;
|
||||
/* 0x232 */ vu8 count;
|
||||
/* 0x233 */ vu8 full;
|
||||
};
|
||||
|
||||
struct RfuBackupQueue
|
||||
{
|
||||
/* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][BACKUP_QUEUE_SLOT_LENGTH];
|
||||
/* 0x1c */ vu8 recv_slot;
|
||||
/* 0x1d */ vu8 send_slot;
|
||||
/* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH];
|
||||
/* 0x1c */ vu8 recvSlot;
|
||||
/* 0x1d */ vu8 sendSlot;
|
||||
/* 0x1e */ vu8 count;
|
||||
};
|
||||
|
||||
struct RfuUnusedQueue
|
||||
struct RfuManager
|
||||
{
|
||||
/* 0x000 */ u8 slots[UNUSED_QUEUE_NUM_SLOTS][UNUSED_QUEUE_SLOT_LENGTH];
|
||||
/* 0x200 */ vu8 recv_slot;
|
||||
/* 0x201 */ vu8 send_slot;
|
||||
/* 0x202 */ vu8 count;
|
||||
/* 0x203 */ vu8 full;
|
||||
};
|
||||
|
||||
typedef struct UnkRfuStruct_2
|
||||
{
|
||||
/* 0x000 */ void (*RfuFunc)(void);
|
||||
/* 0x000 */ void (*callback)(void);
|
||||
/* 0x004 */ u16 state;
|
||||
/* 0x006 */ u8 filler_06[4];
|
||||
/* 0x00a */ u16 linkman_msg;
|
||||
/* 0x00c */ u8 parent_child;
|
||||
/* 0x006 */ u8 unused1[4];
|
||||
/* 0x00a */ u16 errorInfo;
|
||||
/* 0x00c */ u8 parentChild;
|
||||
/* 0x00d */ u8 playerCount;
|
||||
/* 0x00e */ u8 unk_0e;
|
||||
/* 0x00f */ u8 unk_0f;
|
||||
/* 0x010 */ u16 linkman_param[2];
|
||||
/* 0x014 */ u8 main_UNI_recvBuffer[RFU_CHILD_MAX][14];
|
||||
/* 0x04c */ u8 lastCmdBeforeCommInterrupt[14];
|
||||
/* 0x05a */ u8 cmdA100_blockRequestType;
|
||||
/* 0x00e */ bool8 runParentMain2;
|
||||
/* 0x00f */ u8 unused2;
|
||||
/* 0x010 */ u16 errorParams[2];
|
||||
/* 0x014 */ u8 childRecvBuffer[RFU_CHILD_MAX][COMM_SLOT_LENGTH];
|
||||
/* 0x04c */ u8 childSendBuffer[COMM_SLOT_LENGTH];
|
||||
/* 0x05a */ u8 blockRequestType;
|
||||
/* 0x05b */ u8 sendBlockInitDelay;
|
||||
/* 0x05c */ bool8 blockReceived[MAX_RFU_PLAYERS];
|
||||
/* 0x061 */ u8 numBlocksReceived[MAX_RFU_PLAYERS];
|
||||
/* 0x066 */ u8 idleTaskId;
|
||||
/* 0x067 */ u8 searchTaskId;
|
||||
/* 0x068 */ u8 filler_68[4];
|
||||
/* 0x068 */ u8 unused3[4];
|
||||
/* 0x06c */ struct RfuBlockSend sendBlock;
|
||||
/* 0x080 */ struct RfuBlockSend recvBlock[MAX_RFU_PLAYERS];
|
||||
/* 0x0e4 */ bool8 readyCloseLink[MAX_RFU_PLAYERS];
|
||||
@@ -170,67 +193,66 @@ typedef struct UnkRfuStruct_2
|
||||
/* 0x0f2 */ u16 packet[RFU_PACKET_SIZE];
|
||||
/* 0x0fe */ u16 resendExitStandbyTimer;
|
||||
/* 0x100 */ u16 resendExitStandbyCount;
|
||||
/* 0x102 */ u8 unk_102;
|
||||
/* 0x104 */ struct RfuTgtData tgtData;
|
||||
/* 0x102 */ u8 childSendCmdId;
|
||||
/* 0x104 */ struct RfuTgtData parent;
|
||||
/* 0x124 */ struct RfuRecvQueue recvQueue;
|
||||
/* 0x6a0 */ struct RfuSendQueue sendQueue;
|
||||
/* 0x8d4 */ struct RfuBackupQueue backupQueue;
|
||||
/* 0x8f4 */ vu8 linkRecovered;
|
||||
/* 0x8f5 */ u8 reconnectedParentIdx;
|
||||
/* 0x8f6 */ vu8 child_slot;
|
||||
/* 0x8f7 */ u8 unk_c3f[70];
|
||||
/* 0x8f5 */ u8 reconnectParentId;
|
||||
/* 0x8f6 */ vu8 childSlot;
|
||||
/* 0x8f7 */ u8 childRecvQueue[COMM_SLOT_LENGTH * MAX_RFU_PLAYERS];
|
||||
/* 0x93d */ u8 sendStatus;
|
||||
/* 0x93e */ u8 recvStatus;
|
||||
/* 0x93f */ u8 recvCmds[MAX_RFU_PLAYERS][7][2];
|
||||
/* 0x93f */ u8 recvCmds[MAX_RFU_PLAYERS][CMD_LENGTH - 1][2];
|
||||
/* 0x985 */ u8 parentId;
|
||||
/* 0x986 */ u8 multiplayerId; // childId
|
||||
/* 0x987 */ u8 unk_ccf;
|
||||
/* 0x988 */ vu8 sem_UNI_SendRecv;
|
||||
/* 0x987 */ u8 connectParentFailures;
|
||||
/* 0x988 */ vu8 childSendCount;
|
||||
/* 0x989 */ u8 partnerSendStatuses[RFU_CHILD_MAX];
|
||||
/* 0x98d */ u8 partnerRecvStatuses[RFU_CHILD_MAX];
|
||||
/* 0x991 */ u8 linkClosing;
|
||||
/* 0x992 */ u8 unk_cda;
|
||||
/* 0x993 */ volatile bool8 unk_cdb;
|
||||
/* 0x994 */ volatile bool8 unk_cdc;
|
||||
/* 0x995 */ u8 unk_cdd;
|
||||
/* 0x991 */ bool8 stopNewConnections;
|
||||
/* 0x992 */ u8 parentSendSlot;
|
||||
/* 0x993 */ vbool8 parentFinished;
|
||||
/* 0x994 */ vbool8 parentMain2Failed;
|
||||
/* 0x995 */ u8 unused5;
|
||||
/* 0x996 */ u8 linkPlayerIdx[RFU_CHILD_MAX];
|
||||
/* 0x99a */ u8 bm_PartnerFlags;
|
||||
/* 0x99b */ u8 bm_DisconnectSlot;
|
||||
/* 0x99c */ u8 unk_ce4;
|
||||
/* 0x99d */ u8 bmChatLeaderMaybe;
|
||||
/* 0x99e */ u8 unionRoomChatters;
|
||||
/* 0x99a */ u8 parentSlots;
|
||||
/* 0x99b */ u8 disconnectSlots;
|
||||
/* 0x99c */ u8 disconnectMode;
|
||||
/* 0x99d */ u8 nextChildBits;
|
||||
/* 0x99e */ u8 newChildQueue;
|
||||
/* 0x99f */ u8 acceptSlot_flag;
|
||||
/* 0x9a0 */ bool8 foundNewLeaderMaybe;
|
||||
/* 0x9a1 */ u8 unk_ce9;
|
||||
/* 0x9a2 */ u8 unk_cea[RFU_CHILD_MAX];
|
||||
/* 0x9a6 */ u8 unk_cee[RFU_CHILD_MAX];
|
||||
} GF_RFU_MANAGER; // size: 0x9AC
|
||||
/* 0x9a0 */ bool8 playerExchangeActive;
|
||||
/* 0x9a1 */ u8 incomingChild;
|
||||
/* 0x9a2 */ u8 numChildRecvErrors[RFU_CHILD_MAX];
|
||||
/* 0x9a6 */ u8 childRecvIds[RFU_CHILD_MAX];
|
||||
}; // size: 0x9AC
|
||||
|
||||
extern struct GFtgtGname gHostRFUtgtGnameBuffer;
|
||||
extern u8 gHostRFUtgtUnameBuffer[];
|
||||
extern GF_RFU_MANAGER Rfu;
|
||||
extern struct RfuGameData gHostRfuGameData;
|
||||
extern u8 gHostRfuUsername[];
|
||||
extern struct RfuManager gRfu;
|
||||
|
||||
// GameFreak signatures
|
||||
void AddTextPrinterToWindow1(const u8 *str);
|
||||
bool32 MG_PrintTextOnWindow1AndWaitButton(u8 * cmdPtr, const u8 * src);
|
||||
bool32 PrintMysteryGiftMenuMessage(u8 * cmdPtr, const u8 * src);
|
||||
void LinkRfu_FatalError(void);
|
||||
void MG_DrawCheckerboardPattern(void);
|
||||
void Rfu_SetCloseLinkCallback(void);
|
||||
bool8 IsLinkRfuTaskFinished(void);
|
||||
void DestroyWirelessStatusIndicatorSprite(void);
|
||||
void MEvent_CreateTask_CardOrNewsWithFriend(u32 arg0);
|
||||
void MEvent_CreateTask_CardOrNewsOverWireless(u32 arg0);
|
||||
void MEvent_CreateTask_Leader(u32 arg0);
|
||||
void CreateTask_LinkMysteryGiftWithFriend(u32 activity);
|
||||
void CreateTask_LinkMysteryGiftOverWireless(u32 activity);
|
||||
void CreateTask_SendMysteryGift(u32 activity);
|
||||
void Rfu_SendPacket(void *data);
|
||||
u8 CreateTask_ListenToWireless(void);
|
||||
void LinkRfu_DestroyIdleTask(void);
|
||||
void DestroyTask_RfuIdle(void);
|
||||
void InitRFUAPI(void);
|
||||
void sub_80FB128(bool32 a0);
|
||||
void RfuSetIgnoreError(bool32 enable);
|
||||
bool32 IsSendingKeysToRfu(void);
|
||||
void ClearLinkRfuCallback(void);
|
||||
u8 GetRfuPlayerCount(void);
|
||||
u8 Rfu_GetLinkPlayerCount(void);
|
||||
void StartSendingKeysToRfu(void);
|
||||
u8 LinkRfu_GetMultiplayerId(void);
|
||||
u8 Rfu_GetMultiplayerId(void);
|
||||
bool32 Rfu_InitBlockSend(const u8 * src, size_t size);
|
||||
bool8 Rfu_SendBlockRequest(u8 blockRequestType);
|
||||
u8 Rfu_GetBlockReceivedStatus(void);
|
||||
@@ -238,15 +260,15 @@ void Rfu_SetBlockReceivedFlag(u8 linkPlayerId);
|
||||
void Rfu_ResetBlockReceivedFlag(u8 linkPlayerId);
|
||||
bool8 Rfu_IsMaster(void);
|
||||
void ResetLinkRfuGFLayer(void);
|
||||
bool32 LinkRfuMain1(void);
|
||||
bool32 LinkRfuMain2(void);
|
||||
bool32 RfuMain1(void);
|
||||
bool32 RfuMain2(void);
|
||||
bool32 IsRfuRecvQueueEmpty(void);
|
||||
u32 GetRfuRecvQueueLength(void);
|
||||
void LinkRfu_Shutdown(void);
|
||||
void LinkRfu_CreateIdleTask(void);
|
||||
bool8 ToggleLMANlinkRecovery(bool32 enable);
|
||||
void var_800D_set_xB(void);
|
||||
struct GFtgtGname *GetHostRFUtgtGname(void);
|
||||
void CreateTask_RfuIdle(void);
|
||||
bool8 Rfu_SetLinkRecovery(bool32 enable);
|
||||
void SetUsingUnionRoomStartMenu(void);
|
||||
struct RfuGameData *GetHostRfuGameData(void);
|
||||
void UpdateWirelessStatusIndicatorSprite(void);
|
||||
void InitRFU(void);
|
||||
bool32 RfuHasErrored(void);
|
||||
@@ -262,44 +284,44 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest);
|
||||
void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest);
|
||||
bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue * queue, u8 *dest);
|
||||
void RfuSendQueue_Enqueue(struct RfuSendQueue * queue, u8 *src);
|
||||
void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders);
|
||||
void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 started, s32 partnerInfo);
|
||||
void UpdateGameData_GroupLockedIn(bool8 started);
|
||||
bool32 IsRfuSerialNumberValid(u32 serialNo);
|
||||
bool8 IsRfuRecoveringFromLinkLoss(void);
|
||||
bool8 LmanAcceptSlotFlagIsNotZero(void);
|
||||
void LinkRfu_StopManagerAndFinalizeSlots(void);
|
||||
bool32 sub_80FA5D4(void);
|
||||
bool32 sub_80FC1CC(void);
|
||||
bool32 WaitRfuState(bool32 a0);
|
||||
bool32 CheckTrainerHasLeftByIdAndName(u16 trainerId, const u8 *trainerName);
|
||||
void SendByteToPartnerByIdAndName(u8 a0, u16 a1, const u8 *a2);
|
||||
u32 WaitSendByteToPartnerByIdAndName(u16 a0, const u8 *a1);
|
||||
void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 a2);
|
||||
bool32 RfuTryDisconnectLeavingChildren(void);
|
||||
bool32 IsRfuCommunicatingWithAllChildren(void);
|
||||
bool32 WaitRfuState(bool32 force);
|
||||
bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *trainerName);
|
||||
void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name);
|
||||
u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name);
|
||||
void SetHostRfuGameData(u8 activity, u32 partnerInfo, bool32 startedActivity);
|
||||
void InitializeRfuLinkManager_LinkLeader(u32 availSlots);
|
||||
void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId);
|
||||
void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *gname, u8 *uname);
|
||||
void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username);
|
||||
void InitializeRfuLinkManager_JoinGroup(void);
|
||||
void SendLeaveGroupNotice(void);
|
||||
void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId);
|
||||
void UpdateGameDataWithActivitySpriteGendersFlag(u8 activity, u32 child_sprite_genders, u32 started);
|
||||
void RecordMixTrainerNames(void);
|
||||
void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, u32 startedActivity);
|
||||
void SaveLinkTrainerNames(void);
|
||||
void LinkRfu_CreateConnectionAsParent();
|
||||
void LinkRfu_StopManagerBeforeEnteringChat();
|
||||
void SetGnameBufferWonderFlags(bool32 hasNews, bool32 hasCard);
|
||||
void ClearAndInitHostRFUtgtGname(void);
|
||||
void sub_80F8FA0(void);
|
||||
void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level);
|
||||
void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard);
|
||||
void ResetHostRfuGameData(void);
|
||||
void StopUnionRoomLinkManager(void);
|
||||
void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level);
|
||||
bool32 IsUnionRoomListenTaskActive(void);
|
||||
void InitializeRfuLinkManager_EnterUnionRoom(void);
|
||||
void sub_80FBD6C(u32 a0);
|
||||
void sub_80FC114(const u8 *name, struct GFtgtGname *structPtr, u8 a2);
|
||||
void Rfu_DisconnectPlayerById(u32 playerIdx);
|
||||
void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8 activity);
|
||||
bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name);
|
||||
bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx);
|
||||
bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *gname, u8 *uname, u8 idx);
|
||||
bool32 RfuHasFoundNewLeader(void);
|
||||
void Rfu_UnionRoomChat_StopLinkManager(void);
|
||||
void sub_80FB9D0(void);
|
||||
void sub_80FB030(u32 a0);
|
||||
bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx);
|
||||
bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx);
|
||||
bool32 Rfu_IsPlayerExchangeActive(void);
|
||||
void Rfu_StopPartnerSearch(void);
|
||||
void RfuSetNormalDisconnectMode(void);
|
||||
void SetUnionRoomChatPlayerData(u32 numPlayers);
|
||||
void ClearRecvCommands(void);
|
||||
|
||||
#include "mevent_server.h"
|
||||
|
||||
+2
-2
@@ -101,8 +101,8 @@ void InitMEventData(void);
|
||||
u16 MEvent_GetBattleCardCount(u32 command);
|
||||
void MysteryGift_TryIncrementStat(u32 eventId, u32 trainerId);
|
||||
u16 *GetMEventProfileECWordsMaybe(void);
|
||||
void ResetReceivedWonderCardFlag(void);
|
||||
bool32 MEventHandleReceivedWonderCard(u16 flagId);
|
||||
void MysteryGift_DisableStats(void);
|
||||
bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId);
|
||||
u16 GetWonderCardFlagId(void);
|
||||
|
||||
#endif //GUARD_MEVENT_H
|
||||
|
||||
@@ -6,8 +6,8 @@ extern bool8 gGiftIsFromEReader;
|
||||
void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void);
|
||||
void PrintMysteryGiftOrEReaderTopMenu(bool8, bool32);
|
||||
void c2_mystery_gift(void);
|
||||
void c2_mystery_gift_e_reader_run(void);
|
||||
s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str);
|
||||
void CB2_MysteryGiftEReader(void);
|
||||
s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str);
|
||||
void MG_DrawTextBorder(u8 windowId);
|
||||
u16 GetMysteryGiftBaseBlock(void);
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||
#define GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||
|
||||
#include "union_room.h"
|
||||
|
||||
u8 ZeroUnionObjWork(struct UnionObj * ptr);
|
||||
void DeleteUnionObjWorkAndStopTask(void);
|
||||
void CreateGroupMemberObjectsInvisible(u8 *spriteIds, s32 group);
|
||||
void DestroyGroupMemberObjects(u8 *spriteIds);
|
||||
void MakeGroupAssemblyAreasPassable(void);
|
||||
void ScheduleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p);
|
||||
void HandleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p);
|
||||
bool32 RfuUnionTool_GetGroupAndMemberInFrontOfPlayer(struct UnkStruct_Main0 *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds);
|
||||
void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct UnkStruct_Main0 *main0_p);
|
||||
|
||||
#endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||
+3
-3
@@ -13,10 +13,10 @@ extern const u8 gText_FemaleSymbol4[];
|
||||
extern const u8 gText_GenderlessSymbol[];
|
||||
|
||||
extern const u16 gTradeOrHatchMonShadowTilemap[];
|
||||
void CB2_ReturnFromLinkTrade(void);
|
||||
void CB2_StartCreateTradeMenu(void);
|
||||
s32 Trade_CalcLinkPlayerCompatibilityParam(void);
|
||||
s32 CanRegisterMonForTradingBoard(struct GFtgtGnameSub rfuPlayer, u16 species2, u16 species, u8 isEventLegal);
|
||||
s32 GetUnionRoomTradeMessageId(struct GFtgtGnameSub rfuPlayer, struct GFtgtGnameSub rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal);
|
||||
s32 CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData rfuPlayer, u16 species2, u16 species, u8 isEventLegal);
|
||||
s32 GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData rfuPlayer, struct RfuGameCompatibilityData rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal);
|
||||
void CB2_ReturnToTradeMenuFromSummary(void);
|
||||
|
||||
#endif //GUARD_TRADE_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef GUARD_TRADE_SCENE_H
|
||||
#define GUARD_TRADE_SCENE_H
|
||||
|
||||
void CB2_InitTradeAnim_LinkTrade(void);
|
||||
void CB2_LinkTrade(void);
|
||||
void CreateInGameTradePokemon(void);
|
||||
void DoInGameTradeScene(void);
|
||||
void DrawTextOnTradeWindow(u8 windowId, const u8 *str, s8 speed);
|
||||
|
||||
+85
-97
@@ -3,58 +3,60 @@
|
||||
|
||||
#include "global.h"
|
||||
#include "link_rfu.h"
|
||||
#include "constants/union_room.h"
|
||||
|
||||
// Return value of IsRequestedTypeAndSpeciesInPlayerParty
|
||||
#define UR_TRADE_MATCH 0
|
||||
#define UR_TRADE_NOTYPE 1
|
||||
#define UR_TRADE_NOEGG 2
|
||||
// In the Union Room the player is only ever connected to ≤ 4 other players.
|
||||
// However, there can be up to MAX_UNION_ROOM_LEADERS (8) object events to
|
||||
// represent leaders of recently discovered link groups, and each of those groups
|
||||
// may have up to MAX_RFU_PLAYERS (5) players in it including the leader.
|
||||
// These players are represented on-screen by NPC sprites drawn around the leader.
|
||||
// Thus there can be 40 sprites of other players on-screen, in 8 groups of 5.
|
||||
#define NUM_UNION_ROOM_SPRITES (MAX_UNION_ROOM_LEADERS * MAX_RFU_PLAYERS)
|
||||
|
||||
#define UROOM_MAX_GROUP_COUNT 8
|
||||
#define UROOM_MAX_PARTY_SIZE 5
|
||||
// The maximum number of recently connected players that can be tracked.
|
||||
// Note that this is significantly less than NUM_UNION_ROOM_SPRITES, i.e. not
|
||||
// every player that can be shown in the Union Room can be tracked at once.
|
||||
// Information such as a group member's gender can instead be read from partnerInfo
|
||||
// of the leader's RfuGameData by tracking at least all of the group leaders.
|
||||
#define MAX_RFU_PLAYER_LIST_SIZE 16
|
||||
|
||||
struct UnionGnameUnamePair
|
||||
struct RfuPlayerData
|
||||
{
|
||||
struct GFtgtGname gname;
|
||||
u8 ALIGNED(4) uname[PLAYER_NAME_LENGTH + 1];
|
||||
struct RfuGameData data;
|
||||
u8 ALIGNED(4) name[RFU_USER_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct UnkStruct_x1C
|
||||
struct RfuPlayer
|
||||
{
|
||||
struct UnionGnameUnamePair gname_uname;
|
||||
struct RfuPlayerData rfu;
|
||||
u16 timeoutCounter;
|
||||
u8 groupScheduledAnim:2;
|
||||
bool8 useRedText:1; // Never set
|
||||
u8 newPlayerCountdown;
|
||||
u8 unused;
|
||||
};
|
||||
|
||||
struct RfuPlayerList
|
||||
{
|
||||
struct RfuPlayer players[MAX_RFU_PLAYER_LIST_SIZE];
|
||||
};
|
||||
|
||||
struct RfuIncomingPlayer
|
||||
{
|
||||
struct RfuPlayerData rfu;
|
||||
u8 active:1;
|
||||
};
|
||||
|
||||
struct UnkStruct_x20
|
||||
struct RfuIncomingPlayerList
|
||||
{
|
||||
struct UnionGnameUnamePair gname_uname;
|
||||
u16 field_18;
|
||||
u8 groupScheduledAnim:2;
|
||||
bool8 field_1A_1:1;
|
||||
u8 field_1B;
|
||||
u32 field_1C; // unused
|
||||
struct RfuIncomingPlayer players[MAX_RFU_PLAYERS];
|
||||
};
|
||||
|
||||
// These arrays are dynamically allocated but must be
|
||||
// represented as structs to match.
|
||||
// Don't ask me why.
|
||||
|
||||
// FIXME: Find a way around this.
|
||||
|
||||
struct UnkStruct_Main0
|
||||
struct WirelessLink_Leader
|
||||
{
|
||||
struct UnkStruct_x20 arr[0];
|
||||
};
|
||||
|
||||
struct UnkStruct_Main4
|
||||
{
|
||||
struct UnkStruct_x1C arr[0];
|
||||
};
|
||||
|
||||
struct UnkStruct_Leader
|
||||
{
|
||||
struct UnkStruct_Main0 * field_0;
|
||||
struct UnkStruct_Main4 * field_4;
|
||||
struct UnkStruct_Main0 * field_8;
|
||||
struct RfuPlayerList * playerList;
|
||||
struct RfuIncomingPlayerList * incomingPlayerList;
|
||||
struct RfuPlayerList * playerListBackup;
|
||||
u8 state;
|
||||
u8 textState;
|
||||
u8 delayTimerAfterOk;
|
||||
@@ -63,36 +65,35 @@ struct UnkStruct_Leader
|
||||
u8 nPlayerModeWindowId;
|
||||
u8 listTaskId;
|
||||
u8 playerCount;
|
||||
u8 messageWindowId;
|
||||
u8 field_15;
|
||||
u8 field_16;
|
||||
u16 yesNoWindowId;
|
||||
u8 unused;
|
||||
u8 listenTaskId;
|
||||
u8 activity;
|
||||
u8 field_19;
|
||||
u16 field_1A;
|
||||
u8 joinRequestAnswer;
|
||||
u16 memberConfirmTimeout;
|
||||
};
|
||||
|
||||
struct UnkStruct_Group
|
||||
struct WirelessLink_Group
|
||||
{
|
||||
struct UnkStruct_Main0 * field_0;
|
||||
struct UnkStruct_Main4 * field_4;
|
||||
struct RfuPlayerList * playerList;
|
||||
struct RfuIncomingPlayerList * incomingPlayerList;
|
||||
u8 state;
|
||||
u8 textState;
|
||||
u8 field_A; // unused
|
||||
u8 delayTimerAfterOk; // unused
|
||||
u8 listWindowId;
|
||||
u8 bButtonCancelWindowId;
|
||||
u8 playerNameAndIdWindowId;
|
||||
u8 listTaskId;
|
||||
u8 leaderId;
|
||||
u8 field_10;
|
||||
u8 unused;
|
||||
u8 listenTaskId;
|
||||
u8 cardOrNews;
|
||||
u8 field_13; // referenced but never set
|
||||
bool8 isWonderNews;
|
||||
bool8 showListMenu; // referenced but never set
|
||||
u8 refreshTimer;
|
||||
u8 delayBeforePrint;
|
||||
};
|
||||
|
||||
struct UnionObj
|
||||
struct UnionRoomObject
|
||||
{
|
||||
u8 state;
|
||||
u8 gfxId;
|
||||
@@ -100,69 +101,56 @@ struct UnionObj
|
||||
u8 schedAnim;
|
||||
};
|
||||
|
||||
struct UnkStruct_URoom
|
||||
struct WirelessLink_URoom
|
||||
{
|
||||
/* 0x000 */ struct UnkStruct_Main0 * field_0;
|
||||
/* 0x004 */ struct UnkStruct_Main4 * field_4;
|
||||
/* 0x008 */ struct UnkStruct_Main0 * field_8;
|
||||
/* 0x00C */ struct UnkStruct_Main4 * field_C;
|
||||
/* 0x010 */ u16 field_10;
|
||||
/* 0x012 */ u16 field_12;
|
||||
/* 0x014 */ u8 state;
|
||||
/* 0x015 */ u8 stateAfterPrint;
|
||||
/* 0x016 */ u8 textState;
|
||||
/* 0x017 */ u8 field_17;
|
||||
/* 0x018 */ u8 field_18;
|
||||
/* 0x019 */ u8 field_19;
|
||||
/* 0x01A */ u8 field_1A;
|
||||
/* 0x01B */ u8 topListMenuWindowId;
|
||||
/* 0x01C */ u8 topListMenuListMenuId;
|
||||
/* 0x01D */ u8 tradeBoardSelectWindowId;
|
||||
/* 0x01E */ u8 tradeBoardDetailsWindowId;
|
||||
/* 0x01F */ u8 field_1F;
|
||||
/* 0x020 */ u8 field_20;
|
||||
/* 0x021 */ u8 spriteIds[40];
|
||||
/* 0x049 */ u8 field_49;
|
||||
/* 0x04A */ u8 tradeBoardListMenuId;
|
||||
|
||||
// For communication with potential link partners
|
||||
/* 0x04C */ u16 playerSendBuffer[6];
|
||||
/* 0x058 */ u8 activityRequestStrbufs[4][11];
|
||||
/* 0x084 */ u16 partnerYesNoResponse;
|
||||
/* 0x086 */ u16 recvActivityRequest[3]; // activity[, species, level]
|
||||
/* 0x08C */ struct UnionObj unionObjs[8];
|
||||
/* 0x0AC */ u8 trainerCardStrbufs[12][15];
|
||||
/* 0x160 */ u8 field_174[48];
|
||||
/* 0x190 */ u8 field_1A4[200];
|
||||
};
|
||||
|
||||
union UnkUnion_Main
|
||||
{
|
||||
struct UnkStruct_Leader * leader;
|
||||
struct UnkStruct_Group * group;
|
||||
struct UnkStruct_URoom * uRoom;
|
||||
struct RfuPlayerList * playerList;
|
||||
struct RfuIncomingPlayerList * incomingChildList;
|
||||
struct RfuPlayerList * spawnPlayer;
|
||||
struct RfuIncomingPlayerList * incomingParentList;
|
||||
u16 unknown; // Never read
|
||||
u16 unreadPlayerId;
|
||||
u8 state;
|
||||
u8 stateAfterPrint;
|
||||
u8 textState;
|
||||
u8 filler[4];
|
||||
u8 topListMenuWindowId;
|
||||
u8 topListMenuId;
|
||||
u8 tradeBoardMainWindowId;
|
||||
u8 tradeBoardHeaderWindowId;
|
||||
u8 unused1;
|
||||
u8 searchTaskId;
|
||||
u8 spriteIds[NUM_UNION_ROOM_SPRITES];
|
||||
u8 unused2;
|
||||
u8 tradeBoardListMenuId;
|
||||
// For communication with potential link partners
|
||||
u16 playerSendBuffer[6];
|
||||
u8 activityRequestStrbufs[4][11];
|
||||
u16 partnerYesNoResponse;
|
||||
u16 recvActivityRequest[3]; // activity[, species, level]
|
||||
struct UnionRoomObject objects[MAX_UNION_ROOM_LEADERS];
|
||||
u8 trainerCardStrBuffer[12][15];
|
||||
u8 trainerCardColorStrBuffer[48];
|
||||
u8 trainerCardMsgStrBuffer[200];
|
||||
};
|
||||
|
||||
struct UnionRoomTrade
|
||||
{
|
||||
u16 field_0;
|
||||
u16 state;
|
||||
u16 type;
|
||||
u32 playerPersonality;
|
||||
u8 field_8;
|
||||
u8 field_9;
|
||||
u8 offerPlayerId;
|
||||
u16 playerSpecies;
|
||||
u16 playerLevel;
|
||||
u16 species;
|
||||
u16 level;
|
||||
u16 field_12;
|
||||
u32 personality;
|
||||
};
|
||||
|
||||
extern struct GFtgtGnameSub gPartnerTgtGnameSub;
|
||||
extern struct RfuGameCompatibilityData gRfuPartnerCompatibilityData;
|
||||
extern u16 gUnionRoomOfferedSpecies;
|
||||
extern u8 gUnionRoomRequestedMonType;
|
||||
|
||||
void StartUnionRoomBattle(u16 battleFlags);
|
||||
u8 UnionRoom_CreateTask_CallCB2ReturnFromLinkTrade(void);
|
||||
u8 CreateTask_CreateTradeMenu(void);
|
||||
|
||||
#endif //GUARD_UNION_ROOM_H
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||
#define GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||
|
||||
#include "union_room.h"
|
||||
|
||||
u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players);
|
||||
void DestroyUnionRoomPlayerObjects(void);
|
||||
void CreateUnionRoomPlayerSprites(u8 *spriteIds, s32 leaderId);
|
||||
void DestroyUnionRoomPlayerSprites(u8 *spriteIds);
|
||||
void MakeGroupAssemblyAreasPassable(void);
|
||||
void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom);
|
||||
void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom);
|
||||
bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds);
|
||||
void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list);
|
||||
|
||||
#endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H
|
||||
+2
-2
@@ -249,7 +249,7 @@ SECTIONS {
|
||||
src/trainer_fan_club.o(.text);
|
||||
src/quest_log_events.o(.text);
|
||||
src/union_room.o(.text);
|
||||
src/rfu_union_tool.o(.text);
|
||||
src/union_room_player_avatar.o(.text);
|
||||
src/union_room_battle.o(.text);
|
||||
src/pokemon_special_anim.o(.text);
|
||||
src/pokemon_special_anim_scene.o(.text);
|
||||
@@ -542,7 +542,7 @@ SECTIONS {
|
||||
src/trainer_fan_club.o(.rodata);
|
||||
src/quest_log_events.o(.rodata);
|
||||
src/union_room.o(.rodata);
|
||||
src/rfu_union_tool.o(.rodata);
|
||||
src/union_room_player_avatar.o(.rodata);
|
||||
src/union_room_battle.o(.rodata);
|
||||
src/union_room_message.o(.rodata);
|
||||
src/pokemon_special_anim.o(.rodata);
|
||||
|
||||
@@ -519,7 +519,7 @@ void TryReceiveLinkBattleData(void)
|
||||
|
||||
if (gReceivedRemoteLinkPlayers != 0 && (gBattleTypeFlags & BATTLE_TYPE_LINK_IN_BATTLE) && (gLinkPlayers[0].linkType == 0x2211))
|
||||
{
|
||||
LinkRfu_DestroyIdleTask();
|
||||
DestroyTask_RfuIdle();
|
||||
for (i = 0; i < GetLinkPlayerCount(); i++)
|
||||
{
|
||||
if (GetBlockReceivedStatus() & gBitTable[i])
|
||||
|
||||
+3
-3
@@ -969,9 +969,9 @@ static u32 QuitBerryCrush(MainCallback callback)
|
||||
#define ERROR_EXIT(exitCallback) \
|
||||
{ \
|
||||
SetMainCallback2(exitCallback); \
|
||||
Rfu.linkman_param[0] = 0; \
|
||||
Rfu.linkman_param[1] = 0; \
|
||||
Rfu.errorState = 1; \
|
||||
gRfu.errorParams[0] = 0; \
|
||||
gRfu.errorParams[1] = 0; \
|
||||
gRfu.errorState = 1; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -897,7 +897,7 @@ static void Task_StartWiredTrade(u8 taskId)
|
||||
case 3:
|
||||
if (!gReceivedRemoteLinkPlayers)
|
||||
{
|
||||
SetMainCallback2(CB2_ReturnFromLinkTrade);
|
||||
SetMainCallback2(CB2_StartCreateTradeMenu);
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
break;
|
||||
@@ -929,7 +929,7 @@ static void Task_StartWirelessTrade(u8 taskId)
|
||||
case 3:
|
||||
if (IsLinkTaskFinished())
|
||||
{
|
||||
UnionRoom_CreateTask_CallCB2ReturnFromLinkTrade();
|
||||
CreateTask_CreateTradeMenu();
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,471 @@
|
||||
static const u8 *const sLinkGroupActivityNameTexts[] = {
|
||||
[ACTIVITY_NONE] = gText_UR_EmptyString,
|
||||
[ACTIVITY_BATTLE_SINGLE] = gText_UR_SingleBattle,
|
||||
[ACTIVITY_BATTLE_DOUBLE] = gText_UR_DoubleBattle,
|
||||
[ACTIVITY_BATTLE_MULTI] = gText_UR_MultiBattle,
|
||||
[ACTIVITY_TRADE] = gText_UR_PokemonTrades,
|
||||
[ACTIVITY_CHAT] = gText_UR_Chat,
|
||||
[ACTIVITY_WONDER_CARD_DUP] = gText_UR_WonderCards,
|
||||
[ACTIVITY_WONDER_NEWS_DUP] = gText_UR_WonderNews,
|
||||
[ACTIVITY_CARD] = gText_UR_Cards,
|
||||
[ACTIVITY_POKEMON_JUMP] = gText_UR_PokemonJump,
|
||||
[ACTIVITY_BERRY_CRUSH] = gText_UR_BerryCrush,
|
||||
[ACTIVITY_BERRY_PICK] = gText_UR_BerryPicking,
|
||||
[ACTIVITY_SEARCH] = gText_UR_Search,
|
||||
[ACTIVITY_SPIN_TRADE] = gText_UR_SpinTrade,
|
||||
[ACTIVITY_ITEM_TRADE] = gText_UR_ItemTrade,
|
||||
[ACTIVITY_RECORD_CORNER] = gText_UR_EmptyString,
|
||||
[ACTIVITY_BERRY_BLENDER] = gText_UR_EmptyString,
|
||||
[ACTIVITY_ACCEPT] = gText_UR_EmptyString,
|
||||
[ACTIVITY_DECLINE] = gText_UR_EmptyString,
|
||||
[ACTIVITY_NPCTALK] = gText_UR_EmptyString,
|
||||
[ACTIVITY_PLYRTALK] = gText_UR_EmptyString,
|
||||
[ACTIVITY_WONDER_CARD] = gText_UR_WonderCards,
|
||||
[ACTIVITY_WONDER_NEWS] = gText_UR_WonderNews
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_BButtonCancel = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 0,
|
||||
.tilemapTop = 0,
|
||||
.width = 30,
|
||||
.height = 2,
|
||||
.paletteNum = 0xF,
|
||||
.baseBlock = 0x008
|
||||
};
|
||||
|
||||
// Minimum and maximum number of players for a link group
|
||||
// A minimum of 0 means the min and max are equal
|
||||
#define LINK_GROUP_CAPACITY(min, max)(((min) << 12) | ((max) << 8))
|
||||
#define GROUP_MAX(capacity)(capacity & 0x0F)
|
||||
#define GROUP_MIN(capacity)(capacity >> 4)
|
||||
#define GROUP_MIN2(capacity)(capacity & 0xF0) // Unnecessary to have both, but needed to match
|
||||
|
||||
static const u32 sLinkGroupToActivityAndCapacity[] = {
|
||||
[LINK_GROUP_SINGLE_BATTLE] = ACTIVITY_BATTLE_SINGLE | LINK_GROUP_CAPACITY(0, 2),
|
||||
[LINK_GROUP_DOUBLE_BATTLE] = ACTIVITY_BATTLE_DOUBLE | LINK_GROUP_CAPACITY(0, 2),
|
||||
[LINK_GROUP_MULTI_BATTLE] = ACTIVITY_BATTLE_MULTI | LINK_GROUP_CAPACITY(0, 4),
|
||||
[LINK_GROUP_TRADE] = ACTIVITY_TRADE | LINK_GROUP_CAPACITY(0, 2),
|
||||
[LINK_GROUP_POKEMON_JUMP] = ACTIVITY_POKEMON_JUMP | LINK_GROUP_CAPACITY(2, 5),
|
||||
[LINK_GROUP_BERRY_CRUSH] = ACTIVITY_BERRY_CRUSH | LINK_GROUP_CAPACITY(2, 5),
|
||||
[LINK_GROUP_BERRY_PICKING] = ACTIVITY_BERRY_PICK | LINK_GROUP_CAPACITY(3, 5),
|
||||
[LINK_GROUP_WONDER_CARD] = ACTIVITY_SPIN_TRADE | LINK_GROUP_CAPACITY(3, 5),
|
||||
[LINK_GROUP_WONDER_NEWS] = ACTIVITY_ITEM_TRADE | LINK_GROUP_CAPACITY(3, 5)
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_List_PossibleGroupMembers = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 1,
|
||||
.tilemapTop = 3,
|
||||
.width = 13,
|
||||
.height = 10,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x044
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_NumPlayerMode = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 16,
|
||||
.tilemapTop = 3,
|
||||
.width = 7,
|
||||
.height = 4,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x0C6
|
||||
};
|
||||
|
||||
const struct ListMenuItem sListMenuItems_PossibleGroupMembers[] = {
|
||||
{gText_UR_EmptyString, 0},
|
||||
{gText_UR_EmptyString, 1},
|
||||
{gText_UR_EmptyString, 2},
|
||||
{gText_UR_EmptyString, 3},
|
||||
{gText_UR_EmptyString, 4}
|
||||
};
|
||||
|
||||
static const struct ListMenuTemplate sListMenuTemplate_PossibleGroupMembers = {
|
||||
.items = sListMenuItems_PossibleGroupMembers,
|
||||
.moveCursorFunc = NULL,
|
||||
.itemPrintFunc = ItemPrintFunc_PossibleGroupMembers,
|
||||
.totalItems = ARRAY_COUNT(sListMenuItems_PossibleGroupMembers),
|
||||
.maxShowed = 5,
|
||||
.windowId = 0,
|
||||
.header_X = 0,
|
||||
.item_X = 1,
|
||||
.cursor_X = 0,
|
||||
.upText_Y = 0,
|
||||
.cursorPal = 2,
|
||||
.fillValue = 1,
|
||||
.cursorShadowPal = 3,
|
||||
.lettersSpacing = 0,
|
||||
.itemVerticalPadding = 2,
|
||||
.scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
|
||||
.fontId = FONT_2,
|
||||
.cursorKind = 1
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_GroupList = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 1,
|
||||
.tilemapTop = 3,
|
||||
.width = 17,
|
||||
.height = 10,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x044
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_PlayerNameAndId = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 20,
|
||||
.tilemapTop = 3,
|
||||
.width = 7,
|
||||
.height = 4,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x0EE
|
||||
};
|
||||
|
||||
static const struct ListMenuItem sListMenuItems_UnionRoomGroups[] = {
|
||||
{gText_UR_EmptyString, 0},
|
||||
{gText_UR_EmptyString, 1},
|
||||
{gText_UR_EmptyString, 2},
|
||||
{gText_UR_EmptyString, 3},
|
||||
{gText_UR_EmptyString, 4},
|
||||
{gText_UR_EmptyString, 5},
|
||||
{gText_UR_EmptyString, 6},
|
||||
{gText_UR_EmptyString, 7},
|
||||
{gText_UR_EmptyString, 8},
|
||||
{gText_UR_EmptyString, 9},
|
||||
{gText_UR_EmptyString, 10},
|
||||
{gText_UR_EmptyString, 11},
|
||||
{gText_UR_EmptyString, 12},
|
||||
{gText_UR_EmptyString, 13},
|
||||
{gText_UR_EmptyString, 14},
|
||||
{gText_UR_EmptyString, 15}
|
||||
};
|
||||
|
||||
static const struct ListMenuTemplate sListMenuTemplate_UnionRoomGroups = {
|
||||
.items = sListMenuItems_UnionRoomGroups,
|
||||
.moveCursorFunc = ListMenuDefaultCursorMoveFunc,
|
||||
.itemPrintFunc = ListMenuItemPrintFunc_UnionRoomGroups,
|
||||
.totalItems = ARRAY_COUNT(sListMenuItems_UnionRoomGroups),
|
||||
.maxShowed = 5,
|
||||
.windowId = 0,
|
||||
.header_X = 0,
|
||||
.item_X = 8,
|
||||
.cursor_X = 0,
|
||||
.upText_Y = 0,
|
||||
.cursorPal = 2,
|
||||
.fillValue = 1,
|
||||
.cursorShadowPal = 3,
|
||||
.lettersSpacing = 0,
|
||||
.itemVerticalPadding = 2,
|
||||
.scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD,
|
||||
.fontId = FONT_2,
|
||||
.cursorKind = 0
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_InviteToActivity = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 20,
|
||||
.tilemapTop = 6,
|
||||
.width = 8,
|
||||
.height = 7,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x001
|
||||
};
|
||||
|
||||
static const struct ListMenuItem sListMenuItems_InviteToActivity[] = {
|
||||
{gText_UR_Greetings, ACTIVITY_CARD | LINK_GROUP_CAPACITY(0, 2)},
|
||||
{gText_UR_Battle, ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM | LINK_GROUP_CAPACITY(0, 2)},
|
||||
{gText_UR_Chat2, ACTIVITY_CHAT | IN_UNION_ROOM | LINK_GROUP_CAPACITY(0, 2)},
|
||||
{gText_UR_Exit, ACTIVITY_NONE | IN_UNION_ROOM }
|
||||
};
|
||||
|
||||
static const struct ListMenuTemplate sListMenuTemplate_InviteToActivity = {
|
||||
.items = sListMenuItems_InviteToActivity,
|
||||
.moveCursorFunc = ListMenuDefaultCursorMoveFunc,
|
||||
.itemPrintFunc = NULL,
|
||||
.totalItems = ARRAY_COUNT(sListMenuItems_InviteToActivity),
|
||||
.maxShowed = 4,
|
||||
.windowId = 0,
|
||||
.header_X = 0,
|
||||
.item_X = 8,
|
||||
.cursor_X = 0,
|
||||
.upText_Y = 0,
|
||||
.cursorPal = 2,
|
||||
.fillValue = 1,
|
||||
.cursorShadowPal = 3,
|
||||
.lettersSpacing = 1,
|
||||
.itemVerticalPadding = 0,
|
||||
.scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
|
||||
.fontId = FONT_2,
|
||||
.cursorKind = 0
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_RegisterForTrade = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 18,
|
||||
.tilemapTop = 8,
|
||||
.width = 11,
|
||||
.height = 5,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x001
|
||||
};
|
||||
|
||||
static const struct ListMenuItem sListMenuItems_RegisterForTrade[] = {
|
||||
{gText_Register, 1},
|
||||
{gText_UR_Info, 2},
|
||||
{gText_UR_Exit, 3}
|
||||
};
|
||||
|
||||
static const struct ListMenuTemplate sListMenuTemplate_RegisterForTrade = {
|
||||
.items = sListMenuItems_RegisterForTrade,
|
||||
.moveCursorFunc = ListMenuDefaultCursorMoveFunc,
|
||||
.itemPrintFunc = NULL,
|
||||
.totalItems = ARRAY_COUNT(sListMenuItems_RegisterForTrade),
|
||||
.maxShowed = 3,
|
||||
.windowId = 0,
|
||||
.header_X = 0,
|
||||
.item_X = 8,
|
||||
.cursor_X = 0,
|
||||
.upText_Y = 0,
|
||||
.cursorPal = 2,
|
||||
.fillValue = 1,
|
||||
.cursorShadowPal = 3,
|
||||
.lettersSpacing = 1,
|
||||
.itemVerticalPadding = 0,
|
||||
.scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
|
||||
.fontId = FONT_2,
|
||||
.cursorKind = 0
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_TypeNames = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 20,
|
||||
.tilemapTop = 2,
|
||||
.width = 9,
|
||||
.height = 11,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x001
|
||||
};
|
||||
|
||||
static const struct ListMenuItem sListMenuItems_TypeNames[NUMBER_OF_MON_TYPES] = {
|
||||
{ gTypeNames[TYPE_NORMAL], TYPE_NORMAL },
|
||||
{ gTypeNames[TYPE_FIRE], TYPE_FIRE },
|
||||
{ gTypeNames[TYPE_WATER], TYPE_WATER },
|
||||
{ gTypeNames[TYPE_ELECTRIC], TYPE_ELECTRIC },
|
||||
{ gTypeNames[TYPE_GRASS], TYPE_GRASS },
|
||||
{ gTypeNames[TYPE_ICE], TYPE_ICE },
|
||||
{ gTypeNames[TYPE_GROUND], TYPE_GROUND },
|
||||
{ gTypeNames[TYPE_ROCK], TYPE_ROCK },
|
||||
{ gTypeNames[TYPE_FLYING], TYPE_FLYING },
|
||||
{ gTypeNames[TYPE_PSYCHIC], TYPE_PSYCHIC },
|
||||
{ gTypeNames[TYPE_FIGHTING], TYPE_FIGHTING },
|
||||
{ gTypeNames[TYPE_POISON], TYPE_POISON },
|
||||
{ gTypeNames[TYPE_BUG], TYPE_BUG },
|
||||
{ gTypeNames[TYPE_GHOST], TYPE_GHOST },
|
||||
{ gTypeNames[TYPE_DRAGON], TYPE_DRAGON },
|
||||
{ gTypeNames[TYPE_STEEL], TYPE_STEEL },
|
||||
{ gTypeNames[TYPE_DARK], TYPE_DARK },
|
||||
{ gText_UR_Exit, NUMBER_OF_MON_TYPES }
|
||||
};
|
||||
|
||||
static const struct ListMenuTemplate sListMenuTemplate_TypeNames = {
|
||||
.items = sListMenuItems_TypeNames,
|
||||
.moveCursorFunc = ListMenuDefaultCursorMoveFunc,
|
||||
.itemPrintFunc = NULL,
|
||||
.totalItems = NUMBER_OF_MON_TYPES,
|
||||
.maxShowed = 6,
|
||||
.windowId = 0,
|
||||
.header_X = 0,
|
||||
.item_X = 8,
|
||||
.cursor_X = 0,
|
||||
.upText_Y = 2,
|
||||
.cursorPal = 2,
|
||||
.fillValue = 1,
|
||||
.cursorShadowPal = 3,
|
||||
.lettersSpacing = 1,
|
||||
.itemVerticalPadding = 0,
|
||||
.scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
|
||||
.fontId = FONT_2,
|
||||
.cursorKind = 0
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_TradingBoardHeader = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 1,
|
||||
.tilemapTop = 1,
|
||||
.width = 28,
|
||||
.height = 2,
|
||||
.paletteNum = 13,
|
||||
.baseBlock = 0x001
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_TradingBoardMain = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 1,
|
||||
.tilemapTop = 5,
|
||||
.width = 28,
|
||||
.height = 10,
|
||||
.paletteNum = 13,
|
||||
.baseBlock = 0x039
|
||||
};
|
||||
|
||||
static const struct ListMenuItem sListMenuItems_TradeBoard[] = {
|
||||
{gText_UR_EmptyString, -3},
|
||||
{gText_UR_EmptyString, 0},
|
||||
{gText_UR_EmptyString, 1},
|
||||
{gText_UR_EmptyString, 2},
|
||||
{gText_UR_EmptyString, 3},
|
||||
{gText_UR_EmptyString, 4},
|
||||
{gText_UR_EmptyString, 5},
|
||||
{gText_UR_EmptyString, 6},
|
||||
{gText_UR_EmptyString, 7},
|
||||
{gText_UR_Exit2, 8}
|
||||
};
|
||||
|
||||
static const struct ListMenuTemplate sListMenuTemplate_TradeBoard = {
|
||||
.items = sListMenuItems_TradeBoard,
|
||||
.moveCursorFunc = ListMenuDefaultCursorMoveFunc,
|
||||
.itemPrintFunc = TradeBoardListMenuItemPrintFunc,
|
||||
.totalItems = ARRAY_COUNT(sListMenuItems_TradeBoard),
|
||||
.maxShowed = 5,
|
||||
.windowId = 0,
|
||||
.header_X = 0,
|
||||
.item_X = 12,
|
||||
.cursor_X = 0,
|
||||
.upText_Y = 2,
|
||||
.cursorPal = 14,
|
||||
.fillValue = 15,
|
||||
.cursorShadowPal = 13,
|
||||
.lettersSpacing = 1,
|
||||
.itemVerticalPadding = 1,
|
||||
.scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
|
||||
.fontId = FONT_2,
|
||||
.cursorKind = 0
|
||||
};
|
||||
|
||||
static const struct WindowTemplate sWindowTemplate_Unused = {
|
||||
.bg = 0,
|
||||
.tilemapLeft = 1,
|
||||
.tilemapTop = 5,
|
||||
.width = 28,
|
||||
.height = 10,
|
||||
.paletteNum = 13,
|
||||
.baseBlock = 0x039
|
||||
};
|
||||
|
||||
static const struct ListMenuItem sListMenuItems_Unused[] = {
|
||||
{gText_UR_EmptyString, 0},
|
||||
{gText_UR_EmptyString, 1},
|
||||
{gText_UR_EmptyString, 2},
|
||||
{gText_UR_EmptyString, 3},
|
||||
{gText_UR_EmptyString, 4},
|
||||
{gText_UR_EmptyString, 5},
|
||||
{gText_UR_EmptyString, 6},
|
||||
{gText_UR_EmptyString, 7},
|
||||
{gText_UR_EmptyString, 8},
|
||||
{gText_UR_EmptyString, 9},
|
||||
{gText_UR_EmptyString, 10},
|
||||
{gText_UR_EmptyString, 11},
|
||||
{gText_UR_EmptyString, 12},
|
||||
{gText_UR_EmptyString, 13},
|
||||
{gText_UR_EmptyString, 14},
|
||||
{gText_UR_EmptyString, 15}
|
||||
};
|
||||
|
||||
static const struct ListMenuTemplate sListMenuTemplate_Unused = {
|
||||
.items = sListMenuItems_Unused,
|
||||
.moveCursorFunc = ListMenuDefaultCursorMoveFunc,
|
||||
.itemPrintFunc = ItemPrintFunc_Unused,
|
||||
.totalItems = ARRAY_COUNT(sListMenuItems_Unused),
|
||||
.maxShowed = 4,
|
||||
.windowId = 0,
|
||||
.header_X = 0,
|
||||
.item_X = 8,
|
||||
.cursor_X = 1,
|
||||
.upText_Y = 0,
|
||||
.cursorPal = 2,
|
||||
.fillValue = 1,
|
||||
.cursorShadowPal = 3,
|
||||
.lettersSpacing = 1,
|
||||
.itemVerticalPadding = 0,
|
||||
.scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD,
|
||||
.fontId = FONT_2,
|
||||
.cursorKind = 0
|
||||
};
|
||||
|
||||
static const struct RfuPlayerData sRfuPlayerData_Dummy = {};
|
||||
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_SingleBattle[] = {ACTIVITY_BATTLE_SINGLE, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_DoubleBattle[] = {ACTIVITY_BATTLE_DOUBLE, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_MultiBattle[] = {ACTIVITY_BATTLE_MULTI, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_Trade[] = {ACTIVITY_TRADE, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_PokemonJump[] = {ACTIVITY_POKEMON_JUMP, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_BerryCrush[] = {ACTIVITY_BERRY_CRUSH, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_BerryPicking[] = {ACTIVITY_BERRY_PICK, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_WonderCard[] = {ACTIVITY_WONDER_CARD, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_WonderNews[] = {ACTIVITY_WONDER_NEWS, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_Resume[] = {
|
||||
IN_UNION_ROOM | ACTIVITY_NONE,
|
||||
IN_UNION_ROOM | ACTIVITY_BATTLE_SINGLE,
|
||||
IN_UNION_ROOM | ACTIVITY_TRADE,
|
||||
IN_UNION_ROOM | ACTIVITY_CHAT,
|
||||
IN_UNION_ROOM | ACTIVITY_CARD,
|
||||
IN_UNION_ROOM | ACTIVITY_ACCEPT,
|
||||
IN_UNION_ROOM | ACTIVITY_DECLINE,
|
||||
IN_UNION_ROOM | ACTIVITY_NPCTALK,
|
||||
IN_UNION_ROOM | ACTIVITY_PLYRTALK,
|
||||
0xFF
|
||||
};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_Init[] = {ACTIVITY_SEARCH, 0xFF};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_Unk11[] = {
|
||||
ACTIVITY_BATTLE_SINGLE,
|
||||
ACTIVITY_BATTLE_DOUBLE,
|
||||
ACTIVITY_BATTLE_MULTI,
|
||||
ACTIVITY_TRADE,
|
||||
ACTIVITY_POKEMON_JUMP,
|
||||
ACTIVITY_BERRY_CRUSH,
|
||||
ACTIVITY_BERRY_PICK,
|
||||
ACTIVITY_WONDER_CARD,
|
||||
ACTIVITY_WONDER_NEWS,
|
||||
ACTIVITY_SPIN_TRADE,
|
||||
0xFF
|
||||
};
|
||||
ALIGNED(4) static const u8 sAcceptedActivityIds_Unk12[] = {
|
||||
ACTIVITY_BATTLE_SINGLE,
|
||||
ACTIVITY_BATTLE_DOUBLE,
|
||||
ACTIVITY_BATTLE_MULTI,
|
||||
ACTIVITY_TRADE,
|
||||
ACTIVITY_BERRY_CRUSH,
|
||||
0xFF
|
||||
};
|
||||
|
||||
static const u8 *const sAcceptedActivityIds[NUM_LINK_GROUP_TYPES] = {
|
||||
[LINK_GROUP_SINGLE_BATTLE] = sAcceptedActivityIds_SingleBattle,
|
||||
[LINK_GROUP_DOUBLE_BATTLE] = sAcceptedActivityIds_DoubleBattle,
|
||||
[LINK_GROUP_MULTI_BATTLE] = sAcceptedActivityIds_MultiBattle,
|
||||
[LINK_GROUP_TRADE] = sAcceptedActivityIds_Trade,
|
||||
[LINK_GROUP_POKEMON_JUMP] = sAcceptedActivityIds_PokemonJump,
|
||||
[LINK_GROUP_BERRY_CRUSH] = sAcceptedActivityIds_BerryCrush,
|
||||
[LINK_GROUP_BERRY_PICKING] = sAcceptedActivityIds_BerryPicking,
|
||||
[LINK_GROUP_WONDER_CARD] = sAcceptedActivityIds_WonderCard,
|
||||
[LINK_GROUP_WONDER_NEWS] = sAcceptedActivityIds_WonderNews,
|
||||
[LINK_GROUP_UNION_ROOM_RESUME] = sAcceptedActivityIds_Resume,
|
||||
[LINK_GROUP_UNION_ROOM_INIT] = sAcceptedActivityIds_Init,
|
||||
[LINK_GROUP_UNK_11] = sAcceptedActivityIds_Unk11,
|
||||
[LINK_GROUP_UNK_12] = sAcceptedActivityIds_Unk12,
|
||||
};
|
||||
|
||||
static const u8 sLinkGroupToURoomActivity[] = {
|
||||
[LINK_GROUP_SINGLE_BATTLE] = ACTIVITY_BATTLE_SINGLE,
|
||||
[LINK_GROUP_DOUBLE_BATTLE] = ACTIVITY_BATTLE_DOUBLE,
|
||||
[LINK_GROUP_MULTI_BATTLE] = ACTIVITY_BATTLE_MULTI,
|
||||
[LINK_GROUP_TRADE] = ACTIVITY_TRADE,
|
||||
[LINK_GROUP_POKEMON_JUMP] = ACTIVITY_POKEMON_JUMP,
|
||||
[LINK_GROUP_BERRY_CRUSH] = ACTIVITY_BERRY_CRUSH,
|
||||
[LINK_GROUP_BERRY_PICKING] = ACTIVITY_BERRY_PICK,
|
||||
[LINK_GROUP_WONDER_CARD] = ACTIVITY_WONDER_CARD,
|
||||
[LINK_GROUP_WONDER_NEWS] = ACTIVITY_WONDER_NEWS
|
||||
};
|
||||
|
||||
// Unused
|
||||
static const u8 sDotSeparatedValues[] = _("{DYNAMIC 00}·{DYNAMIC 01}");
|
||||
+5
-5
@@ -222,7 +222,7 @@ bool8 IsWirelessAdapterConnected(void)
|
||||
|
||||
SetWirelessCommType1();
|
||||
InitRFUAPI();
|
||||
sub_80FB128(TRUE);
|
||||
RfuSetIgnoreError(TRUE);
|
||||
if (rfu_LMAN_REQBN_softReset_and_checkID() == RFU_ID)
|
||||
{
|
||||
rfu_REQ_stopMode();
|
||||
@@ -718,7 +718,7 @@ void ClearLinkCallback_2(void)
|
||||
u8 GetLinkPlayerCount(void)
|
||||
{
|
||||
if (gWirelessCommType)
|
||||
return GetRfuPlayerCount();
|
||||
return Rfu_GetLinkPlayerCount();
|
||||
|
||||
return EXTRACT_PLAYER_COUNT(gLinkStatus);
|
||||
}
|
||||
@@ -924,7 +924,7 @@ static void SendBerryBlenderNoSpaceForPokeblocks(void)
|
||||
u8 GetMultiplayerId(void)
|
||||
{
|
||||
if (gWirelessCommType == 1)
|
||||
return LinkRfu_GetMultiplayerId();
|
||||
return Rfu_GetMultiplayerId();
|
||||
|
||||
return SIO_MULTI_CNT->id;
|
||||
}
|
||||
@@ -1576,8 +1576,8 @@ bool8 HandleLinkConnection(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
main1Failed = LinkRfuMain1(); // Always returns FALSE
|
||||
main2Failed = LinkRfuMain2();
|
||||
main1Failed = RfuMain1(); // Always returns FALSE
|
||||
main2Failed = RfuMain2();
|
||||
if (IsSendingKeysOverCable() == TRUE)
|
||||
{
|
||||
// This will never be reached.
|
||||
|
||||
+1149
-1061
File diff suppressed because it is too large
Load Diff
+162
-217
@@ -6,12 +6,35 @@
|
||||
#include "link_rfu.h"
|
||||
#include "random.h"
|
||||
|
||||
static EWRAM_DATA u8 gWirelessStatusIndicatorSpriteId = 0;
|
||||
enum {
|
||||
WIRELESS_STATUS_ANIM_3_BARS,
|
||||
WIRELESS_STATUS_ANIM_2_BARS,
|
||||
WIRELESS_STATUS_ANIM_1_BAR,
|
||||
WIRELESS_STATUS_ANIM_SEARCHING,
|
||||
WIRELESS_STATUS_ANIM_ERROR,
|
||||
};
|
||||
|
||||
static const u16 gWirelessLinkIconPalette[] = INCBIN_U16("graphics/interface/wireless_link_icon.gbapal");
|
||||
#define TAG_GFX_STATUS_INDICATOR 0xD431
|
||||
#define TAG_PAL_STATUS_INDICATOR 0xD432
|
||||
|
||||
static const u32 gWirelessLinkIconPic[] = INCBIN_U32("graphics/interface/wireless_link_icon.4bpp.lz");
|
||||
#define UNUSED_QUEUE_NUM_SLOTS 2
|
||||
#define UNUSED_QUEUE_SLOT_LENGTH 256
|
||||
|
||||
struct RfuUnusedQueue
|
||||
{
|
||||
u8 slots[UNUSED_QUEUE_NUM_SLOTS][UNUSED_QUEUE_SLOT_LENGTH];
|
||||
vu8 recvSlot;
|
||||
vu8 sendSlot;
|
||||
vu8 count;
|
||||
vu8 full;
|
||||
};
|
||||
|
||||
static EWRAM_DATA u8 sWirelessStatusIndicatorSpriteId = 0;
|
||||
|
||||
static const u16 sWirelessLinkIconPalette[] = INCBIN_U16("graphics/link/wireless_icon.gbapal");
|
||||
static const u32 sWirelessLinkIconPic[] = INCBIN_U32("graphics/link/wireless_icon.4bpp.lz");
|
||||
|
||||
// Most of the below two tables won't make sense with ASCII encoding.
|
||||
static const u8 sWireless_ASCIItoRSETable[] = {
|
||||
EOS,
|
||||
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x37,
|
||||
@@ -222,8 +245,7 @@ static const struct OamData sWirelessStatusIndicatorOamData =
|
||||
.paletteNum = 0,
|
||||
};
|
||||
|
||||
static const union AnimCmd sWirelessStatusIndicatorAnim0[] = {
|
||||
// 3 bars
|
||||
static const union AnimCmd sWirelessStatusIndicator_3Bars[] = {
|
||||
ANIMCMD_FRAME( 4, 5),
|
||||
ANIMCMD_FRAME( 8, 5),
|
||||
ANIMCMD_FRAME(12, 5),
|
||||
@@ -233,8 +255,7 @@ static const union AnimCmd sWirelessStatusIndicatorAnim0[] = {
|
||||
ANIMCMD_JUMP(0)
|
||||
};
|
||||
|
||||
static const union AnimCmd sWirelessStatusIndicatorAnim1[] = {
|
||||
// 2 bars
|
||||
static const union AnimCmd sWirelessStatusIndicator_2Bars[] = {
|
||||
ANIMCMD_FRAME( 4, 5),
|
||||
ANIMCMD_FRAME( 8, 5),
|
||||
ANIMCMD_FRAME(12, 10),
|
||||
@@ -242,46 +263,43 @@ static const union AnimCmd sWirelessStatusIndicatorAnim1[] = {
|
||||
ANIMCMD_JUMP(0)
|
||||
};
|
||||
|
||||
static const union AnimCmd sWirelessStatusIndicatorAnim2[] = {
|
||||
// 1 bar
|
||||
static const union AnimCmd sWirelessStatusIndicator_1Bar[] = {
|
||||
ANIMCMD_FRAME(4, 5),
|
||||
ANIMCMD_FRAME(8, 5),
|
||||
ANIMCMD_JUMP(0)
|
||||
};
|
||||
|
||||
static const union AnimCmd sWirelessStatusIndicatorAnim3[] = {
|
||||
// searching
|
||||
static const union AnimCmd sWirelessStatusIndicator_Searching[] = {
|
||||
ANIMCMD_FRAME( 4, 10),
|
||||
ANIMCMD_FRAME(20, 10),
|
||||
ANIMCMD_JUMP(0)
|
||||
};
|
||||
|
||||
static const union AnimCmd sWirelessStatusIndicatorAnim4[] = {
|
||||
// error
|
||||
static const union AnimCmd sWirelessStatusIndicator_Error[] = {
|
||||
ANIMCMD_FRAME(24, 10),
|
||||
ANIMCMD_FRAME( 4, 10),
|
||||
ANIMCMD_JUMP(0)
|
||||
};
|
||||
|
||||
static const union AnimCmd *const sWirelessStatusIndicatorAnims[] = {
|
||||
sWirelessStatusIndicatorAnim0,
|
||||
sWirelessStatusIndicatorAnim1,
|
||||
sWirelessStatusIndicatorAnim2,
|
||||
sWirelessStatusIndicatorAnim3,
|
||||
sWirelessStatusIndicatorAnim4
|
||||
[WIRELESS_STATUS_ANIM_3_BARS] = sWirelessStatusIndicator_3Bars,
|
||||
[WIRELESS_STATUS_ANIM_2_BARS] = sWirelessStatusIndicator_2Bars,
|
||||
[WIRELESS_STATUS_ANIM_1_BAR] = sWirelessStatusIndicator_1Bar,
|
||||
[WIRELESS_STATUS_ANIM_SEARCHING] = sWirelessStatusIndicator_Searching,
|
||||
[WIRELESS_STATUS_ANIM_ERROR] = sWirelessStatusIndicator_Error
|
||||
};
|
||||
|
||||
static const struct CompressedSpriteSheet sWirelessStatusIndicatorSpriteSheet = {
|
||||
gWirelessLinkIconPic, 0x0380, 0xD431
|
||||
sWirelessLinkIconPic, 0x0380, TAG_GFX_STATUS_INDICATOR
|
||||
};
|
||||
|
||||
static const struct SpritePalette sWirelessStatusIndicatorSpritePalette = {
|
||||
gWirelessLinkIconPalette, 0xD432
|
||||
sWirelessLinkIconPalette, TAG_PAL_STATUS_INDICATOR
|
||||
};
|
||||
|
||||
static const struct SpriteTemplate sWirelessStatusIndicatorSpriteTemplate = {
|
||||
.tileTag = 0xD431,
|
||||
.paletteTag = 0xD432,
|
||||
.tileTag = TAG_GFX_STATUS_INDICATOR,
|
||||
.paletteTag = TAG_PAL_STATUS_INDICATOR,
|
||||
.oam = &sWirelessStatusIndicatorOamData,
|
||||
.anims = sWirelessStatusIndicatorAnims,
|
||||
.images = NULL,
|
||||
@@ -298,13 +316,11 @@ void RfuRecvQueue_Reset(struct RfuRecvQueue *queue)
|
||||
|
||||
for (i = 0; i < RECV_QUEUE_NUM_SLOTS; i++)
|
||||
{
|
||||
for (j = 0; j < RECV_QUEUE_SLOT_LENGTH; j++)
|
||||
{
|
||||
for (j = 0; j < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; j++)
|
||||
queue->slots[i][j] = 0;
|
||||
}
|
||||
}
|
||||
queue->send_slot = 0;
|
||||
queue->recv_slot = 0;
|
||||
queue->sendSlot = 0;
|
||||
queue->recvSlot = 0;
|
||||
queue->count = 0;
|
||||
queue->full = FALSE;
|
||||
}
|
||||
@@ -316,13 +332,11 @@ void RfuSendQueue_Reset(struct RfuSendQueue *queue)
|
||||
|
||||
for (i = 0; i < SEND_QUEUE_NUM_SLOTS; i++)
|
||||
{
|
||||
for (j = 0; j < SEND_QUEUE_SLOT_LENGTH; j++)
|
||||
{
|
||||
for (j = 0; j < COMM_SLOT_LENGTH; j++)
|
||||
queue->slots[i][j] = 0;
|
||||
}
|
||||
}
|
||||
queue->send_slot = 0;
|
||||
queue->recv_slot = 0;
|
||||
queue->sendSlot = 0;
|
||||
queue->recvSlot = 0;
|
||||
queue->count = 0;
|
||||
queue->full = FALSE;
|
||||
}
|
||||
@@ -335,12 +349,10 @@ static void RfuUnusedQueue_Reset(struct RfuUnusedQueue *queue)
|
||||
for (i = 0; i < UNUSED_QUEUE_NUM_SLOTS; i++)
|
||||
{
|
||||
for (j = 0; j < UNUSED_QUEUE_SLOT_LENGTH; j++)
|
||||
{
|
||||
queue->slots[i][j] = 0;
|
||||
}
|
||||
}
|
||||
queue->send_slot = 0;
|
||||
queue->recv_slot = 0;
|
||||
queue->sendSlot = 0;
|
||||
queue->recvSlot = 0;
|
||||
queue->count = 0;
|
||||
queue->full = FALSE;
|
||||
}
|
||||
@@ -356,26 +368,20 @@ void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *src)
|
||||
imeBak = REG_IME;
|
||||
REG_IME = 0;
|
||||
count = 0;
|
||||
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i += RECV_QUEUE_SLOT_LENGTH / MAX_RFU_PLAYERS)
|
||||
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i += COMM_SLOT_LENGTH)
|
||||
{
|
||||
if (src[i] == 0 && src[i + 1] == 0)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count != MAX_RFU_PLAYERS)
|
||||
{
|
||||
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
queue->slots[queue->recv_slot][i] = src[i];
|
||||
}
|
||||
queue->recv_slot++;
|
||||
queue->recv_slot %= RECV_QUEUE_NUM_SLOTS;
|
||||
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++)
|
||||
queue->slots[queue->recvSlot][i] = src[i];
|
||||
queue->recvSlot++;
|
||||
queue->recvSlot %= RECV_QUEUE_NUM_SLOTS;
|
||||
queue->count++;
|
||||
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++)
|
||||
src[i] = 0;
|
||||
}
|
||||
}
|
||||
REG_IME = imeBak;
|
||||
}
|
||||
@@ -394,26 +400,20 @@ void RfuSendQueue_Enqueue(struct RfuSendQueue *queue, u8 *src)
|
||||
{
|
||||
imeBak = REG_IME;
|
||||
REG_IME = 0;
|
||||
for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++)
|
||||
for (i = 0; i < COMM_SLOT_LENGTH; i++)
|
||||
{
|
||||
if (src[i] != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != SEND_QUEUE_SLOT_LENGTH)
|
||||
if (i != COMM_SLOT_LENGTH)
|
||||
{
|
||||
for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
queue->slots[queue->recv_slot][i] = src[i];
|
||||
}
|
||||
queue->recv_slot++;
|
||||
queue->recv_slot %= SEND_QUEUE_NUM_SLOTS;
|
||||
for (i = 0; i < COMM_SLOT_LENGTH; i++)
|
||||
queue->slots[queue->recvSlot][i] = src[i];
|
||||
queue->recvSlot++;
|
||||
queue->recvSlot %= SEND_QUEUE_NUM_SLOTS;
|
||||
queue->count++;
|
||||
for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
for (i = 0; i < COMM_SLOT_LENGTH; i++)
|
||||
src[i] = 0;
|
||||
}
|
||||
}
|
||||
REG_IME = imeBak;
|
||||
}
|
||||
@@ -430,21 +430,17 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest)
|
||||
|
||||
imeBak = REG_IME;
|
||||
REG_IME = 0;
|
||||
if (queue->recv_slot == queue->send_slot || queue->full)
|
||||
if (queue->recvSlot == queue->sendSlot || queue->full)
|
||||
{
|
||||
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++)
|
||||
dest[i] = 0;
|
||||
}
|
||||
REG_IME = imeBak;
|
||||
return FALSE;
|
||||
}
|
||||
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
dest[i] = queue->slots[queue->send_slot][i];
|
||||
}
|
||||
queue->send_slot++;
|
||||
queue->send_slot %= RECV_QUEUE_NUM_SLOTS;
|
||||
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++)
|
||||
dest[i] = queue->slots[queue->sendSlot][i];
|
||||
queue->sendSlot++;
|
||||
queue->sendSlot %= RECV_QUEUE_NUM_SLOTS;
|
||||
queue->count--;
|
||||
REG_IME = imeBak;
|
||||
return TRUE;
|
||||
@@ -455,18 +451,14 @@ bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *dest)
|
||||
s32 i;
|
||||
u16 imeBak;
|
||||
|
||||
if (queue->recv_slot == queue->send_slot || queue->full)
|
||||
{
|
||||
if (queue->recvSlot == queue->sendSlot || queue->full)
|
||||
return FALSE;
|
||||
}
|
||||
imeBak = REG_IME;
|
||||
REG_IME = 0;
|
||||
for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
dest[i] = queue->slots[queue->send_slot][i];
|
||||
}
|
||||
queue->send_slot++;
|
||||
queue->send_slot %= SEND_QUEUE_NUM_SLOTS;
|
||||
for (i = 0; i < COMM_SLOT_LENGTH; i++)
|
||||
dest[i] = queue->slots[queue->sendSlot][i];
|
||||
queue->sendSlot++;
|
||||
queue->sendSlot %= SEND_QUEUE_NUM_SLOTS;
|
||||
queue->count--;
|
||||
REG_IME = imeBak;
|
||||
return TRUE;
|
||||
@@ -482,20 +474,14 @@ void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
queue->slots[queue->recv_slot][i] = dest[i];
|
||||
}
|
||||
queue->recv_slot++;
|
||||
queue->recv_slot %= BACKUP_QUEUE_NUM_SLOTS;
|
||||
for (i = 0; i < COMM_SLOT_LENGTH; i++)
|
||||
queue->slots[queue->recvSlot][i] = dest[i];
|
||||
queue->recvSlot++;
|
||||
queue->recvSlot %= BACKUP_QUEUE_NUM_SLOTS;
|
||||
if (queue->count < BACKUP_QUEUE_NUM_SLOTS)
|
||||
{
|
||||
queue->count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
queue->send_slot = queue->recv_slot;
|
||||
}
|
||||
queue->sendSlot = queue->recvSlot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,18 +490,15 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest)
|
||||
s32 i;
|
||||
|
||||
if (queue->count == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dest != NULL)
|
||||
{
|
||||
for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
dest[i] = queue->slots[queue->send_slot][i];
|
||||
}
|
||||
for (i = 0; i < COMM_SLOT_LENGTH; i++)
|
||||
dest[i] = queue->slots[queue->sendSlot][i];
|
||||
}
|
||||
queue->send_slot++;
|
||||
queue->send_slot %= BACKUP_QUEUE_NUM_SLOTS;
|
||||
queue->sendSlot++;
|
||||
queue->sendSlot %= BACKUP_QUEUE_NUM_SLOTS;
|
||||
queue->count--;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -527,11 +510,9 @@ static void RfuUnusedQueue_Dequeue(struct RfuUnusedQueue *queue, u8 *dest)
|
||||
if (queue->count < UNUSED_QUEUE_NUM_SLOTS)
|
||||
{
|
||||
for (i = 0; i < UNUSED_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
queue->slots[queue->recv_slot][i] = dest[i];
|
||||
}
|
||||
queue->recv_slot++;
|
||||
queue->recv_slot %= UNUSED_QUEUE_NUM_SLOTS;
|
||||
queue->slots[queue->recvSlot][i] = dest[i];
|
||||
queue->recvSlot++;
|
||||
queue->recvSlot %= UNUSED_QUEUE_NUM_SLOTS;
|
||||
queue->count++;
|
||||
}
|
||||
else
|
||||
@@ -544,16 +525,14 @@ static bool8 RfuUnusedQueue_Enqueue(struct RfuUnusedQueue *queue, u8 *dest)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
if (queue->recv_slot == queue->send_slot || queue->full)
|
||||
{
|
||||
if (queue->recvSlot == queue->sendSlot || queue->full)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < UNUSED_QUEUE_SLOT_LENGTH; i++)
|
||||
{
|
||||
dest[i] = queue->slots[queue->send_slot][i];
|
||||
}
|
||||
queue->send_slot++;
|
||||
queue->send_slot %= UNUSED_QUEUE_NUM_SLOTS;
|
||||
dest[i] = queue->slots[queue->sendSlot][i];
|
||||
|
||||
queue->sendSlot++;
|
||||
queue->sendSlot %= UNUSED_QUEUE_NUM_SLOTS;
|
||||
queue->count--;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -621,9 +600,7 @@ static void PkmnStrToASCII(u8 *dest, const u8 *src)
|
||||
s32 i;
|
||||
|
||||
for (i = 0; src[i] != EOS; i++)
|
||||
{
|
||||
dest[i] = sWireless_RSEtoASCIITable[src[i]];
|
||||
}
|
||||
dest[i] = 0;
|
||||
}
|
||||
|
||||
@@ -632,9 +609,7 @@ static void ASCIIToPkmnStr(u8 *dest, const u8 *src)
|
||||
s32 i;
|
||||
|
||||
for (i = 0; src[i] != 0; i++)
|
||||
{
|
||||
dest[i] = sWireless_ASCIItoRSETable[src[i]];
|
||||
}
|
||||
dest[i] = EOS;
|
||||
}
|
||||
|
||||
@@ -672,40 +647,39 @@ static u8 GetConnectedChildStrength(u8 maxFlags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders)
|
||||
void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
data->unk_00.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
|
||||
}
|
||||
for (i = 0; i < (s32)ARRAY_COUNT(data->compatibility.playerTrainerId); i++)
|
||||
data->compatibility.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
|
||||
|
||||
for (i = 0; i < RFU_CHILD_MAX; i++)
|
||||
{
|
||||
data->child_sprite_gender[i] = child_sprite_genders;
|
||||
child_sprite_genders >>= 8;
|
||||
data->partnerInfo[i] = partnerInfo;
|
||||
partnerInfo >>= 8; // Each element is 1 byte
|
||||
}
|
||||
data->playerGender = gSaveBlock2Ptr->playerGender;
|
||||
data->activity = activity;
|
||||
data->started = started;
|
||||
data->unk_00.language = GAME_LANGUAGE;
|
||||
data->unk_00.version = GAME_VERSION;
|
||||
data->unk_00.hasNews = FALSE;
|
||||
data->unk_00.hasCard = FALSE;
|
||||
data->unk_00.unknown = FALSE;
|
||||
data->unk_00.isChampion = FlagGet(FLAG_SYS_CAN_LINK_WITH_RS);
|
||||
data->unk_00.hasNationalDex = IsNationalPokedexEnabled();
|
||||
data->unk_00.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR);
|
||||
data->startedActivity = startedActivity;
|
||||
data->compatibility.language = GAME_LANGUAGE;
|
||||
data->compatibility.version = GAME_VERSION;
|
||||
data->compatibility.hasNews = FALSE;
|
||||
data->compatibility.hasCard = FALSE;
|
||||
data->compatibility.unknown = FALSE;
|
||||
data->compatibility.isChampion = FlagGet(FLAG_SYS_CAN_LINK_WITH_RS);
|
||||
data->compatibility.hasNationalDex = IsNationalPokedexEnabled();
|
||||
data->compatibility.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR);
|
||||
}
|
||||
|
||||
/*
|
||||
* ==========================================================
|
||||
* ================================================================
|
||||
* Returns 1 if parent, 0 if child or neutral.
|
||||
* If partner serial number is valid, copies gname and uname.
|
||||
* If partner serial number is valid, copies gameData and username.
|
||||
* Otherwise, blanks these.
|
||||
* ==========================================================
|
||||
* ================================================================
|
||||
*/
|
||||
bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx)
|
||||
bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx)
|
||||
{
|
||||
bool8 retVal;
|
||||
|
||||
@@ -714,13 +688,13 @@ bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx)
|
||||
retVal = TRUE;
|
||||
if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo) && ((gRfuLinkStatus->getNameFlag >> idx) & 1))
|
||||
{
|
||||
memcpy(gname, &gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
|
||||
memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
|
||||
memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
|
||||
memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(gname, 0, RFU_GAME_NAME_LENGTH);
|
||||
memset(uname, 0, RFU_USER_NAME_LENGTH);
|
||||
memset(gameData, 0, RFU_GAME_NAME_LENGTH);
|
||||
memset(username, 0, RFU_USER_NAME_LENGTH);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -728,45 +702,39 @@ bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx)
|
||||
retVal = FALSE;
|
||||
if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo))
|
||||
{
|
||||
memcpy(gname, &gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
|
||||
memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
|
||||
memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
|
||||
memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(gname, 0, RFU_GAME_NAME_LENGTH);
|
||||
memset(uname, 0, RFU_USER_NAME_LENGTH);
|
||||
memset(gameData, 0, RFU_GAME_NAME_LENGTH);
|
||||
memset(username, 0, RFU_USER_NAME_LENGTH);
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==========================================================
|
||||
* Specific check for serial number 0x7F7D,
|
||||
* which comes from ???
|
||||
* ==========================================================
|
||||
*/
|
||||
bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *gname, u8 *uname, u8 idx)
|
||||
bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx)
|
||||
{
|
||||
bool8 retVal = FALSE;
|
||||
if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_7F7D)
|
||||
if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_WONDER_DISTRIBUTOR)
|
||||
{
|
||||
memcpy(gname, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
|
||||
memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
|
||||
memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
|
||||
memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
|
||||
retVal = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(gname, 0, RFU_GAME_NAME_LENGTH);
|
||||
memset(uname, 0, RFU_USER_NAME_LENGTH);
|
||||
memset(gameData, 0, RFU_GAME_NAME_LENGTH);
|
||||
memset(username, 0, RFU_USER_NAME_LENGTH);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *gname, u8 *uname)
|
||||
void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username)
|
||||
{
|
||||
memcpy(gname, &gHostRFUtgtGnameBuffer, RFU_GAME_NAME_LENGTH);
|
||||
memcpy(uname, gHostRFUtgtUnameBuffer, RFU_USER_NAME_LENGTH);
|
||||
memcpy(gameData, &gHostRfuGameData, RFU_GAME_NAME_LENGTH);
|
||||
memcpy(username, gHostRfuUsername, RFU_USER_NAME_LENGTH);
|
||||
}
|
||||
|
||||
#define sNextAnimNum data[0]
|
||||
@@ -793,23 +761,23 @@ void CreateWirelessStatusIndicatorSprite(u8 x, u8 y)
|
||||
gSprites[sprId].sValidator = STATUS_INDICATOR_ACTIVE;
|
||||
gSprites[sprId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag);
|
||||
gSprites[sprId].invisible = TRUE;
|
||||
gWirelessStatusIndicatorSpriteId = sprId;
|
||||
sWirelessStatusIndicatorSpriteId = sprId;
|
||||
}
|
||||
else
|
||||
{
|
||||
gWirelessStatusIndicatorSpriteId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0);
|
||||
gSprites[gWirelessStatusIndicatorSpriteId].sValidator = STATUS_INDICATOR_ACTIVE;
|
||||
gSprites[gWirelessStatusIndicatorSpriteId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag);
|
||||
gSprites[gWirelessStatusIndicatorSpriteId].invisible = TRUE;
|
||||
sWirelessStatusIndicatorSpriteId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0);
|
||||
gSprites[sWirelessStatusIndicatorSpriteId].sValidator = STATUS_INDICATOR_ACTIVE;
|
||||
gSprites[sWirelessStatusIndicatorSpriteId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag);
|
||||
gSprites[sWirelessStatusIndicatorSpriteId].invisible = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyWirelessStatusIndicatorSprite(void)
|
||||
{
|
||||
if (gSprites[gWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE)
|
||||
if (gSprites[sWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE)
|
||||
{
|
||||
gSprites[gWirelessStatusIndicatorSpriteId].sValidator = 0;
|
||||
DestroySprite(&gSprites[gWirelessStatusIndicatorSpriteId]);
|
||||
gSprites[sWirelessStatusIndicatorSpriteId].sValidator = 0;
|
||||
DestroySprite(&gSprites[sWirelessStatusIndicatorSpriteId]);
|
||||
gMain.oamBuffer[125] = gDummyOamData;
|
||||
CpuCopy16(&gDummyOamData, (struct OamData *)OAM + 125, sizeof(struct OamData));
|
||||
}
|
||||
@@ -818,11 +786,9 @@ void DestroyWirelessStatusIndicatorSprite(void)
|
||||
void LoadWirelessStatusIndicatorSpriteGfx(void)
|
||||
{
|
||||
if (GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag) == 0xFFFF)
|
||||
{
|
||||
LoadCompressedSpriteSheet(&sWirelessStatusIndicatorSpriteSheet);
|
||||
}
|
||||
LoadSpritePalette(&sWirelessStatusIndicatorSpritePalette);
|
||||
gWirelessStatusIndicatorSpriteId = 0xFF;
|
||||
sWirelessStatusIndicatorSpriteId = SPRITE_NONE;
|
||||
}
|
||||
|
||||
static u8 GetParentSignalStrength(void)
|
||||
@@ -832,19 +798,17 @@ static u8 GetParentSignalStrength(void)
|
||||
for (i = 0; i < RFU_CHILD_MAX; i++)
|
||||
{
|
||||
if (flags & 1)
|
||||
{
|
||||
return gRfuLinkStatus->strength[i];
|
||||
}
|
||||
flags >>= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32 signalStrengthAnimNum)
|
||||
static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32 animNum)
|
||||
{
|
||||
if (sprite->sCurrAnimNum != signalStrengthAnimNum)
|
||||
if (sprite->sCurrAnimNum != animNum)
|
||||
{
|
||||
sprite->sCurrAnimNum = signalStrengthAnimNum;
|
||||
sprite->sCurrAnimNum = animNum;
|
||||
sprite->sFrameDelay = 0;
|
||||
sprite->sFrameIdx = 0;
|
||||
}
|
||||
@@ -852,45 +816,38 @@ static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32
|
||||
|
||||
void UpdateWirelessStatusIndicatorSprite(void)
|
||||
{
|
||||
if (gWirelessStatusIndicatorSpriteId != 0xFF && gSprites[gWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE)
|
||||
if (sWirelessStatusIndicatorSpriteId != SPRITE_NONE && gSprites[sWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE)
|
||||
{
|
||||
struct Sprite *sprite = &gSprites[gWirelessStatusIndicatorSpriteId];
|
||||
struct Sprite *sprite = &gSprites[sWirelessStatusIndicatorSpriteId];
|
||||
u8 signalStrength = RFU_LINK_ICON_LEVEL4_MAX;
|
||||
u8 i = 0;
|
||||
|
||||
// Get weakest signal strength
|
||||
if (gRfuLinkStatus->parentChild == MODE_PARENT)
|
||||
{
|
||||
for (i = 0; i < GetLinkPlayerCount() - 1; i++)
|
||||
{
|
||||
if (signalStrength >= GetConnectedChildStrength(i + 1))
|
||||
{
|
||||
signalStrength = GetConnectedChildStrength(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
signalStrength = GetParentSignalStrength();
|
||||
}
|
||||
|
||||
// Set signal strength sprite anim number
|
||||
if (IsRfuRecoveringFromLinkLoss() == TRUE)
|
||||
{
|
||||
sprite->sNextAnimNum = 4;
|
||||
}
|
||||
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_ERROR;
|
||||
else if (signalStrength <= RFU_LINK_ICON_LEVEL1_MAX)
|
||||
{
|
||||
sprite->sNextAnimNum = 3;
|
||||
}
|
||||
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_SEARCHING;
|
||||
else if (signalStrength >= RFU_LINK_ICON_LEVEL2_MIN && signalStrength <= RFU_LINK_ICON_LEVEL2_MAX)
|
||||
{
|
||||
sprite->sNextAnimNum = 2;
|
||||
}
|
||||
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_1_BAR;
|
||||
else if (signalStrength >= RFU_LINK_ICON_LEVEL3_MIN && signalStrength <= RFU_LINK_ICON_LEVEL3_MAX)
|
||||
{
|
||||
sprite->sNextAnimNum = 1;
|
||||
}
|
||||
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_2_BARS;
|
||||
else if (signalStrength >= RFU_LINK_ICON_LEVEL4_MIN)
|
||||
{
|
||||
sprite->sNextAnimNum = 0;
|
||||
}
|
||||
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_3_BARS;
|
||||
|
||||
if (sprite->sNextAnimNum != sprite->sSavedAnimNum)
|
||||
{
|
||||
SetAndRestartWirelessStatusIndicatorAnim(sprite, sprite->sNextAnimNum);
|
||||
@@ -901,9 +858,7 @@ void UpdateWirelessStatusIndicatorSprite(void)
|
||||
sprite->sFrameIdx++;
|
||||
sprite->sFrameDelay = 0;
|
||||
if (sprite->anims[sprite->sCurrAnimNum][sprite->sFrameIdx].type == -2) // ANIMCMD_JUMP
|
||||
{
|
||||
sprite->sFrameIdx = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -934,7 +889,7 @@ static void CopyTrainerRecord(struct TrainerNameRecord *dest, u32 trainerId, con
|
||||
{
|
||||
int i;
|
||||
dest->trainerId = trainerId;
|
||||
for (i = 0; i < 7; i++)
|
||||
for (i = 0; i < PLAYER_NAME_LENGTH; i++)
|
||||
{
|
||||
if (name[i] == EOS)
|
||||
break;
|
||||
@@ -948,9 +903,7 @@ static void ZeroName(u8 *name)
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
|
||||
{
|
||||
*name++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool32 NameIsEmpty(const u8 *name)
|
||||
@@ -960,15 +913,13 @@ static bool32 NameIsEmpty(const u8 *name)
|
||||
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
|
||||
{
|
||||
if (*name++ != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Save the currently connected players into the trainer records, shifting all previous records down.
|
||||
void RecordMixTrainerNames(void)
|
||||
void SaveLinkTrainerNames(void)
|
||||
{
|
||||
if (gWirelessCommType != 0)
|
||||
{
|
||||
@@ -976,13 +927,13 @@ void RecordMixTrainerNames(void)
|
||||
s32 j;
|
||||
s32 nextSpace;
|
||||
s32 connectedTrainerRecordIndices[5];
|
||||
struct TrainerNameRecord *newRecords = AllocZeroed(20 * sizeof(struct TrainerNameRecord));
|
||||
struct TrainerNameRecord *newRecords = AllocZeroed(sizeof(gSaveBlock1Ptr->trainerNameRecords));
|
||||
|
||||
// Check if we already have a record saved for connected trainers.
|
||||
for (i = 0; i < GetLinkPlayerCount(); i++)
|
||||
{
|
||||
connectedTrainerRecordIndices[i] = -1;
|
||||
for (j = 0; j < 20; j++)
|
||||
for (j = 0; j < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); j++)
|
||||
{
|
||||
if ((u16)gLinkPlayers[i].trainerId == gSaveBlock1Ptr->trainerNameRecords[j].trainerId && StringCompare(gLinkPlayers[i].name, gSaveBlock1Ptr->trainerNameRecords[j].trainerName) == 0)
|
||||
{
|
||||
@@ -1001,29 +952,25 @@ void RecordMixTrainerNames(void)
|
||||
|
||||
// If we already had a record for this trainer, wipe it so that the next step doesn't duplicate it.
|
||||
if (connectedTrainerRecordIndices[i] >= 0)
|
||||
{
|
||||
ZeroName(gSaveBlock1Ptr->trainerNameRecords[connectedTrainerRecordIndices[i]].trainerName);
|
||||
}
|
||||
nextSpace++;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy all non-empty records to the new list, in the order they appear on the old list. If the list is full,
|
||||
// the last (oldest) records will be dropped.
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); i++)
|
||||
{
|
||||
if (!NameIsEmpty(gSaveBlock1Ptr->trainerNameRecords[i].trainerName))
|
||||
{
|
||||
CopyTrainerRecord(&newRecords[nextSpace], gSaveBlock1Ptr->trainerNameRecords[i].trainerId, gSaveBlock1Ptr->trainerNameRecords[i].trainerName);
|
||||
if (++nextSpace >= 20)
|
||||
{
|
||||
if (++nextSpace >= (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize the new list, and clean up.
|
||||
memcpy(gSaveBlock1Ptr->trainerNameRecords, newRecords, 20 * sizeof(struct TrainerNameRecord));
|
||||
memcpy(gSaveBlock1Ptr->trainerNameRecords, newRecords, sizeof(gSaveBlock1Ptr->trainerNameRecords));
|
||||
Free(newRecords);
|
||||
}
|
||||
}
|
||||
@@ -1032,16 +979,14 @@ bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
for (i = 0; i < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); i++)
|
||||
{
|
||||
if (StringCompareN(gSaveBlock1Ptr->trainerNameRecords[i].trainerName, name, 7) == 0 && gSaveBlock1Ptr->trainerNameRecords[i].trainerId == id)
|
||||
{
|
||||
if (StringCompareN(gSaveBlock1Ptr->trainerNameRecords[i].trainerName, name, PLAYER_NAME_LENGTH) == 0
|
||||
&& gSaveBlock1Ptr->trainerNameRecords[i].trainerId == id)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (NameIsEmpty(gSaveBlock1Ptr->trainerNameRecords[i].trainerName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+1
-1
@@ -358,7 +358,7 @@ extern void ProcessDma3Requests(void);
|
||||
static void VBlankIntr(void)
|
||||
{
|
||||
if (gWirelessCommType)
|
||||
RFUVSync();
|
||||
RfuVSync();
|
||||
else if (!gLinkVSyncDisabled)
|
||||
LinkVSync();
|
||||
|
||||
|
||||
+9
-9
@@ -263,7 +263,7 @@ static void Task_EReaderComm(u8 taskId)
|
||||
switch (data->state)
|
||||
{
|
||||
case 0:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ReceiveMysteryGiftWithEReader))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ReceiveMysteryGiftWithEReader))
|
||||
data->state = 1;
|
||||
break;
|
||||
case 1:
|
||||
@@ -285,7 +285,7 @@ static void Task_EReaderComm(u8 taskId)
|
||||
data->state = 13;
|
||||
break;
|
||||
case 4:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_SelectConnectFromEReaderMenu))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_SelectConnectFromEReaderMenu))
|
||||
{
|
||||
AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA);
|
||||
ResetDelayTimer(&data->stateAdvanceDelay);
|
||||
@@ -334,7 +334,7 @@ static void Task_EReaderComm(u8 taskId)
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_LinkIsIncorrect))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_LinkIsIncorrect))
|
||||
data->state = 4;
|
||||
break;
|
||||
case 8:
|
||||
@@ -451,19 +451,19 @@ static void Task_EReaderComm(u8 taskId)
|
||||
data->state = 26;
|
||||
break;
|
||||
case 23:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_CardReadingHasBeenHalted))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_CardReadingHasBeenHalted))
|
||||
data->state = 26;
|
||||
break;
|
||||
case 20:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ConnectionErrorCheckLink))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ConnectionErrorCheckLink))
|
||||
data->state = 0;
|
||||
break;
|
||||
case 21:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ConnectionErrorTryAgain))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ConnectionErrorTryAgain))
|
||||
data->state = 0;
|
||||
break;
|
||||
case 22:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_WriteErrorUnableToSaveData))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_WriteErrorUnableToSaveData))
|
||||
data->state = 0;
|
||||
break;
|
||||
case 26:
|
||||
@@ -943,12 +943,12 @@ u16 MEvent_GetBattleCardCount(u32 command)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ResetReceivedWonderCardFlag(void)
|
||||
void MysteryGift_DisableStats(void)
|
||||
{
|
||||
sReceivedWonderCardIsValid = FALSE;
|
||||
}
|
||||
|
||||
bool32 MEventHandleReceivedWonderCard(u16 flagId)
|
||||
bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId)
|
||||
{
|
||||
sReceivedWonderCardIsValid = FALSE;
|
||||
if (flagId == 0)
|
||||
|
||||
+27
-48
@@ -354,7 +354,7 @@ void vblankcb_mystery_gift_e_reader_run(void)
|
||||
TransferPlttBuffer();
|
||||
}
|
||||
|
||||
void c2_mystery_gift_e_reader_run(void)
|
||||
void CB2_MysteryGiftEReader(void)
|
||||
{
|
||||
RunTasks();
|
||||
RunTextPrinters();
|
||||
@@ -434,7 +434,7 @@ void c2_mystery_gift(void)
|
||||
{
|
||||
if (HandleMysteryGiftOrEReaderSetup(0))
|
||||
{
|
||||
SetMainCallback2(c2_mystery_gift_e_reader_run);
|
||||
SetMainCallback2(CB2_MysteryGiftEReader);
|
||||
gGiftIsFromEReader = FALSE;
|
||||
task_add_00_mystery_gift();
|
||||
}
|
||||
@@ -444,7 +444,7 @@ void c2_ereader(void)
|
||||
{
|
||||
if (HandleMysteryGiftOrEReaderSetup(1))
|
||||
{
|
||||
SetMainCallback2(c2_mystery_gift_e_reader_run);
|
||||
SetMainCallback2(CB2_MysteryGiftEReader);
|
||||
gGiftIsFromEReader = TRUE;
|
||||
task_add_00_ereader();
|
||||
}
|
||||
@@ -540,7 +540,7 @@ void ClearTextWindow(void)
|
||||
CopyWindowToVram(1, COPYWIN_MAP);
|
||||
}
|
||||
|
||||
bool32 MG_PrintTextOnWindow1AndWaitButton(u8 *textState, const u8 *str)
|
||||
bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str)
|
||||
{
|
||||
switch (*textState)
|
||||
{
|
||||
@@ -650,7 +650,7 @@ u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu)
|
||||
return response;
|
||||
}
|
||||
|
||||
s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str)
|
||||
s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str)
|
||||
{
|
||||
struct WindowTemplate windowTemplate;
|
||||
s8 input;
|
||||
@@ -878,25 +878,17 @@ bool32 TearDownCardOrNews_ReturnToTopMenu(bool32 cardOrNews, bool32 arg1)
|
||||
s32 mevent_message_prompt_discard(u8 * textState, u16 * windowId, bool32 cardOrNews)
|
||||
{
|
||||
if (cardOrNews == 0)
|
||||
{
|
||||
return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen);
|
||||
}
|
||||
return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen);
|
||||
else
|
||||
{
|
||||
return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_OkayToDiscardNews);
|
||||
}
|
||||
return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_OkayToDiscardNews);
|
||||
}
|
||||
|
||||
bool32 mevent_message_was_thrown_away(u8 * textState, bool32 cardOrNews)
|
||||
{
|
||||
if (cardOrNews == 0)
|
||||
{
|
||||
return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderCardThrownAway);
|
||||
}
|
||||
return PrintMysteryGiftMenuMessage(textState, gText_WonderCardThrownAway);
|
||||
else
|
||||
{
|
||||
return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderNewsThrownAway);
|
||||
}
|
||||
return PrintMysteryGiftMenuMessage(textState, gText_WonderNewsThrownAway);
|
||||
}
|
||||
|
||||
bool32 mevent_save_game(u8 * state)
|
||||
@@ -1098,7 +1090,7 @@ static bool32 PrintMGSendStatus(u8 * state, u16 * arg1, u8 arg2, u32 msgId)
|
||||
}
|
||||
else
|
||||
{
|
||||
return MG_PrintTextOnWindow1AndWaitButton(state, str);
|
||||
return PrintMysteryGiftMenuMessage(state, str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1165,7 +1157,7 @@ void task00_mystery_gift(u8 taskId)
|
||||
{
|
||||
if (data->IsCardOrNews == 0)
|
||||
{
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveCardNewOneInput))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveCardNewOneInput))
|
||||
{
|
||||
data->state = 3;
|
||||
PrintMysteryGiftOrEReaderTopMenu(0, 1);
|
||||
@@ -1173,7 +1165,7 @@ void task00_mystery_gift(u8 taskId)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveNewsNewOneInput))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput))
|
||||
{
|
||||
data->state = 3;
|
||||
PrintMysteryGiftOrEReaderTopMenu(0, 1);
|
||||
@@ -1228,23 +1220,15 @@ void task00_mystery_gift(u8 taskId)
|
||||
{
|
||||
case 0:
|
||||
if (data->source == 1)
|
||||
{
|
||||
MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WCARD2);
|
||||
}
|
||||
CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_CARD);
|
||||
else if (data->source == 0)
|
||||
{
|
||||
MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WCARD2);
|
||||
}
|
||||
CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_CARD);
|
||||
break;
|
||||
case 1:
|
||||
if (data->source == 1)
|
||||
{
|
||||
MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WNEWS2);
|
||||
}
|
||||
CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_NEWS);
|
||||
else if (data->source == 0)
|
||||
{
|
||||
MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WNEWS2);
|
||||
}
|
||||
CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_NEWS);
|
||||
break;
|
||||
}
|
||||
data->state = 6;
|
||||
@@ -1291,7 +1275,7 @@ void task00_mystery_gift(u8 taskId)
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer());
|
||||
flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer());
|
||||
switch (flag)
|
||||
{
|
||||
case 0:
|
||||
@@ -1312,14 +1296,14 @@ void task00_mystery_gift(u8 taskId)
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, mevent_client_get_buffer()))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textState, mevent_client_get_buffer()))
|
||||
{
|
||||
mevent_client_inc_flag();
|
||||
data->state = 7;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard);
|
||||
flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard);
|
||||
switch (flag)
|
||||
{
|
||||
case 0:
|
||||
@@ -1347,7 +1331,7 @@ void task00_mystery_gift(u8 taskId)
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift);
|
||||
flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift);
|
||||
switch (flag)
|
||||
{
|
||||
case 0:
|
||||
@@ -1387,17 +1371,12 @@ void task00_mystery_gift(u8 taskId)
|
||||
case 15:
|
||||
r1 = mevent_message(&sp0, data->IsCardOrNews, data->source, data->prevPromptWindowId);
|
||||
if (r1 == NULL)
|
||||
{
|
||||
r1 = data->buffer;
|
||||
}
|
||||
if (sp0)
|
||||
{
|
||||
flag = PrintMGSuccessMessage(&data->textState, r1, &data->curPromptWindowId);
|
||||
}
|
||||
else
|
||||
{
|
||||
flag = MG_PrintTextOnWindow1AndWaitButton(&data->textState, r1);
|
||||
}
|
||||
flag = PrintMysteryGiftMenuMessage(&data->textState, r1);
|
||||
|
||||
if (flag)
|
||||
{
|
||||
if (data->prevPromptWindowId == 3)
|
||||
@@ -1423,7 +1402,7 @@ void task00_mystery_gift(u8 taskId)
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError))
|
||||
{
|
||||
data->state = 0;
|
||||
PrintMysteryGiftOrEReaderTopMenu(0, 0);
|
||||
@@ -1536,7 +1515,7 @@ void task00_mystery_gift(u8 taskId)
|
||||
}
|
||||
break;
|
||||
case 23:
|
||||
switch ((u32)mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard))
|
||||
switch ((u32)DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard))
|
||||
{
|
||||
case 0:
|
||||
data->state = 24;
|
||||
@@ -1587,10 +1566,10 @@ void task00_mystery_gift(u8 taskId)
|
||||
switch (data->IsCardOrNews)
|
||||
{
|
||||
case 0:
|
||||
MEvent_CreateTask_Leader(ACTIVITY_WCARD2);
|
||||
CreateTask_SendMysteryGift(ACTIVITY_WONDER_CARD);
|
||||
break;
|
||||
case 1:
|
||||
MEvent_CreateTask_Leader(ACTIVITY_WNEWS2);
|
||||
CreateTask_SendMysteryGift(ACTIVITY_WONDER_NEWS);
|
||||
break;
|
||||
}
|
||||
data->source = 1;
|
||||
@@ -1660,7 +1639,7 @@ void task00_mystery_gift(u8 taskId)
|
||||
}
|
||||
break;
|
||||
case 36:
|
||||
if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError))
|
||||
if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError))
|
||||
{
|
||||
data->state = 0;
|
||||
PrintMysteryGiftOrEReaderTopMenu(0, 0);
|
||||
|
||||
+1
-1
@@ -3239,7 +3239,7 @@ bool32 IsSendingKeysOverCable(void)
|
||||
static u32 GetLinkSendQueueLength(void)
|
||||
{
|
||||
if (gWirelessCommType != 0)
|
||||
return Rfu.sendQueue.count;
|
||||
return gRfu.sendQueue.count;
|
||||
else
|
||||
return gLink.sendQueue.count;
|
||||
}
|
||||
|
||||
+2
-2
@@ -3851,7 +3851,7 @@ static void CursorCB_Register(u8 taskId)
|
||||
u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES);
|
||||
u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL);
|
||||
|
||||
switch (CanRegisterMonForTradingBoard(*(struct GFtgtGnameSub *)GetHostRFUtgtGname(), species2, species, isEventLegal))
|
||||
switch (CanRegisterMonForTradingBoard(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), species2, species, isEventLegal))
|
||||
{
|
||||
case CANT_REGISTER_MON:
|
||||
StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow);
|
||||
@@ -3877,7 +3877,7 @@ static void CursorCB_Trade1(u8 taskId)
|
||||
u16 species2 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2);
|
||||
u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES);
|
||||
u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL);
|
||||
u32 stringId = GetUnionRoomTradeMessageId(*(struct GFtgtGnameSub *)GetHostRFUtgtGname(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal);
|
||||
u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), gRfuPartnerCompatibilityData, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal);
|
||||
|
||||
if (stringId != UR_TRADE_MSG_NONE)
|
||||
{
|
||||
|
||||
+10
-7
@@ -34,6 +34,7 @@
|
||||
#include "constants/trainers.h"
|
||||
#include "constants/hold_effects.h"
|
||||
#include "constants/battle_move_effects.h"
|
||||
#include "constants/union_room.h"
|
||||
|
||||
#define SPECIES_TO_HOENN(name) [SPECIES_##name - 1] = HOENN_DEX_##name
|
||||
#define SPECIES_TO_NATIONAL(name) [SPECIES_##name - 1] = NATIONAL_DEX_##name
|
||||
@@ -1643,7 +1644,9 @@ static const u16 sDeoxysBaseStats[] =
|
||||
};
|
||||
#endif
|
||||
|
||||
const u16 gLinkPlayerFacilityClasses[] =
|
||||
// The classes used by other players in the Union Room.
|
||||
// These should correspond with the overworld graphics in sUnionRoomObjGfxIds
|
||||
const u16 gUnionRoomFacilityClasses[NUM_UNION_ROOM_CLASSES * GENDER_COUNT] =
|
||||
{
|
||||
// Male
|
||||
FACILITY_CLASS_COOLTRAINER_M,
|
||||
@@ -6031,19 +6034,19 @@ void SetDeoxysStats(void)
|
||||
u16 GetUnionRoomTrainerPic(void)
|
||||
{
|
||||
u8 linkId = GetMultiplayerId() ^ 1;
|
||||
u32 arrId = gLinkPlayers[linkId].trainerId & 7;
|
||||
|
||||
arrId |= gLinkPlayers[linkId].gender << 3;
|
||||
return FacilityClassToPicIndex(gLinkPlayerFacilityClasses[arrId]);
|
||||
u32 arrId = gLinkPlayers[linkId].trainerId % NUM_UNION_ROOM_CLASSES;
|
||||
arrId |= gLinkPlayers[linkId].gender * NUM_UNION_ROOM_CLASSES;
|
||||
return FacilityClassToPicIndex(gUnionRoomFacilityClasses[arrId]);
|
||||
}
|
||||
|
||||
u16 GetUnionRoomTrainerClass(void)
|
||||
{
|
||||
u8 linkId = GetMultiplayerId() ^ 1;
|
||||
u32 arrId = gLinkPlayers[linkId].trainerId & 7;
|
||||
|
||||
arrId |= gLinkPlayers[linkId].gender << 3;
|
||||
return gFacilityClassToTrainerClass[gLinkPlayerFacilityClasses[arrId]];
|
||||
u32 arrId = gLinkPlayers[linkId].trainerId % NUM_UNION_ROOM_CLASSES;
|
||||
arrId |= gLinkPlayers[linkId].gender * NUM_UNION_ROOM_CLASSES;
|
||||
return gFacilityClassToTrainerClass[gUnionRoomFacilityClasses[arrId]];
|
||||
}
|
||||
|
||||
void CreateEventLegalEnemyMon(void)
|
||||
|
||||
+1
-1
@@ -2540,7 +2540,7 @@ static int GetPlayersAtJumpPeak(void)
|
||||
|
||||
static bool32 AreLinkQueuesEmpty(void)
|
||||
{
|
||||
return !Rfu.recvQueue.count && !Rfu.sendQueue.count;
|
||||
return !gRfu.recvQueue.count && !gRfu.sendQueue.count;
|
||||
}
|
||||
|
||||
static int GetNumPlayersForBonus(u8 *arg0)
|
||||
|
||||
@@ -1,663 +0,0 @@
|
||||
#include "global.h"
|
||||
#include "event_data.h"
|
||||
#include "event_object_movement.h"
|
||||
#include "field_player_avatar.h"
|
||||
#include "fieldmap.h"
|
||||
#include "rfu_union_tool.h"
|
||||
#include "script.h"
|
||||
#include "task.h"
|
||||
#include "constants/event_object_movement.h"
|
||||
#include "constants/union_room.h"
|
||||
#include "constants/event_objects.h"
|
||||
|
||||
static EWRAM_DATA struct UnionObj * UnionObjWork = NULL;
|
||||
static EWRAM_DATA u32 sUnionObjRefreshTimer = 0;
|
||||
|
||||
static u8 StartUnionObjAnimTask(void);
|
||||
static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member);
|
||||
static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction);
|
||||
|
||||
static const u8 sUnionObjectEventGfxIds[][10] = {
|
||||
[MALE] = {
|
||||
OBJ_EVENT_GFX_COOLTRAINER_M,
|
||||
OBJ_EVENT_GFX_BLACKBELT,
|
||||
OBJ_EVENT_GFX_CAMPER,
|
||||
OBJ_EVENT_GFX_YOUNGSTER,
|
||||
OBJ_EVENT_GFX_BOY,
|
||||
OBJ_EVENT_GFX_BUG_CATCHER,
|
||||
OBJ_EVENT_GFX_MAN,
|
||||
OBJ_EVENT_GFX_ROCKER
|
||||
},
|
||||
[FEMALE] = {
|
||||
OBJ_EVENT_GFX_COOLTRAINER_F,
|
||||
OBJ_EVENT_GFX_CHANNELER,
|
||||
OBJ_EVENT_GFX_PICNICKER,
|
||||
OBJ_EVENT_GFX_LASS,
|
||||
OBJ_EVENT_GFX_WOMAN_1,
|
||||
OBJ_EVENT_GFX_BATTLE_GIRL,
|
||||
OBJ_EVENT_GFX_WOMAN_2,
|
||||
OBJ_EVENT_GFX_BEAUTY
|
||||
}
|
||||
};
|
||||
|
||||
static const s16 sUnionPartnerCoords[][2] = {
|
||||
{ 4, 6},
|
||||
{13, 8},
|
||||
{10, 6},
|
||||
{ 1, 8},
|
||||
{13, 4},
|
||||
{ 7, 4},
|
||||
{ 1, 4},
|
||||
{ 7, 8}
|
||||
};
|
||||
|
||||
static const s8 sFacingDirectionOffsets[][2] = {
|
||||
[DIR_NONE] = { 0, 0},
|
||||
[DIR_SOUTH] = { 1, 0},
|
||||
[DIR_NORTH] = { 0, -1},
|
||||
[DIR_WEST] = {-1, 0},
|
||||
[DIR_EAST] = { 0, 1}
|
||||
};
|
||||
|
||||
static const u8 sOppositeFacingDirection[] = {
|
||||
[DIR_NONE] = DIR_NONE,
|
||||
[DIR_SOUTH] = DIR_NORTH,
|
||||
[DIR_NORTH] = DIR_SOUTH,
|
||||
[DIR_WEST] = DIR_EAST,
|
||||
[DIR_EAST] = DIR_WEST
|
||||
};
|
||||
|
||||
static const u8 sUnionGroupMemberFacings[] = {
|
||||
DIR_SOUTH,
|
||||
DIR_WEST,
|
||||
DIR_SOUTH,
|
||||
DIR_EAST,
|
||||
DIR_NORTH
|
||||
};
|
||||
|
||||
static const u8 sUnionRoomLocalIds[] = {
|
||||
9,
|
||||
8,
|
||||
7,
|
||||
2,
|
||||
6,
|
||||
5,
|
||||
4,
|
||||
3
|
||||
};
|
||||
|
||||
// Unused
|
||||
static const u16 sHidePlayerFlags[] = {
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_1,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_2,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_3,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_4,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_5,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_6,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_7,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_8
|
||||
};
|
||||
|
||||
static bool32 is_walking_or_running(void)
|
||||
{
|
||||
if (gPlayerAvatar.tileTransitionState == 2 || gPlayerAvatar.tileTransitionState == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id)
|
||||
{
|
||||
return sUnionObjectEventGfxIds[gender][id % 8];
|
||||
}
|
||||
|
||||
static void GetUnionRoomPlayerFacingCoords(u32 group, u32 member, s32 * xp, s32 * yp)
|
||||
{
|
||||
*xp = sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[member][0] + 7;
|
||||
*yp = sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[member][1] + 7;
|
||||
}
|
||||
|
||||
static bool32 IsUnionRoomPlayerFacingTileAt(u32 group, u32 member, s32 x, s32 y)
|
||||
{
|
||||
if (sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[member][0] + 7 != x)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if (sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[member][1] + 7 != y)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool32 IsUnionRoomPlayerHidden(u32 player_idx)
|
||||
{
|
||||
return FlagGet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx);
|
||||
}
|
||||
|
||||
static void HideUnionRoomPlayer(u32 player_idx)
|
||||
{
|
||||
FlagSet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx);
|
||||
}
|
||||
|
||||
static void ShowUnionRoomPlayer(u32 player_idx)
|
||||
{
|
||||
FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx);
|
||||
}
|
||||
|
||||
static void SetUnionRoomPlayerGfx(u32 playerIdx, u32 gfxId)
|
||||
{
|
||||
VarSet(VAR_OBJ_GFX_ID_0 + playerIdx, gfxId);
|
||||
}
|
||||
|
||||
static void CreateUnionRoomPlayerObjectEvent(u32 playerIdx)
|
||||
{
|
||||
TrySpawnObjectEvent(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
|
||||
}
|
||||
|
||||
static void RemoveUnionRoomPlayerObjectEvent(u32 playerIdx)
|
||||
{
|
||||
RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
|
||||
}
|
||||
|
||||
static bool32 SetUnionRoomPlayerEnterExitMovement(u32 playerIdx, const u8 * movement)
|
||||
{
|
||||
u8 objectId;
|
||||
struct ObjectEvent * object;
|
||||
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
object = &gObjectEvents[objectId];
|
||||
if (ObjectEventIsMovementOverridden(object))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (ObjectEventSetHeldMovement(object, *movement))
|
||||
{
|
||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 387);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 playerIdx)
|
||||
{
|
||||
u8 objectId;
|
||||
struct ObjectEvent * object;
|
||||
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
object = &gObjectEvents[objectId];
|
||||
if (!ObjectEventClearHeldMovementIfFinished(object))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!ArePlayerFieldControlsLocked())
|
||||
{
|
||||
UnfreezeObjectEvent(object);
|
||||
}
|
||||
else
|
||||
{
|
||||
FreezeObjectEvent(object);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u8 ZeroUnionObjWork(struct UnionObj * ptr)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
sUnionObjRefreshTimer = 0;
|
||||
UnionObjWork = ptr;
|
||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 442)
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
ptr[i].state = 0;
|
||||
ptr[i].gfxId = 0;
|
||||
ptr[i].animState = 0;
|
||||
ptr[i].schedAnim = 0;
|
||||
}
|
||||
return StartUnionObjAnimTask();
|
||||
}
|
||||
|
||||
static const u8 sMovement_UnionPlayerExit[2] = {
|
||||
MOVEMENT_ACTION_FLY_UP,
|
||||
MOVEMENT_ACTION_STEP_END
|
||||
};
|
||||
|
||||
static bool32 AnimateUnionRoomPlayerDespawn(s8 * a0, u32 playerIdx, struct UnionObj * ptr)
|
||||
{
|
||||
switch (*a0)
|
||||
{
|
||||
case 0:
|
||||
if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerExit) == TRUE)
|
||||
{
|
||||
HideUnionRoomPlayer(playerIdx);
|
||||
(*a0)++;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx))
|
||||
{
|
||||
RemoveUnionRoomPlayerObjectEvent(playerIdx);
|
||||
HideUnionRoomPlayer(playerIdx);
|
||||
*a0 = 0;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const u8 sMovement_UnionPlayerEnter[2] = {
|
||||
MOVEMENT_ACTION_FLY_DOWN,
|
||||
MOVEMENT_ACTION_STEP_END
|
||||
};
|
||||
|
||||
static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct UnionObj * ptr)
|
||||
{
|
||||
s16 x, y;
|
||||
|
||||
switch (*state_p)
|
||||
{
|
||||
case 0:
|
||||
if (!is_walking_or_running())
|
||||
{
|
||||
break;
|
||||
}
|
||||
PlayerGetDestCoords(&x, &y);
|
||||
if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
player_get_pos_including_state_based_drift(&x, &y);
|
||||
if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
SetUnionRoomPlayerGfx(playerIdx, ptr->gfxId);
|
||||
CreateUnionRoomPlayerObjectEvent(playerIdx);
|
||||
ShowUnionRoomPlayer(playerIdx);
|
||||
(*state_p)++;
|
||||
// fallthrough
|
||||
case 3: // incorrect?
|
||||
if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerEnter) == 1)
|
||||
{
|
||||
(*state_p)++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx))
|
||||
{
|
||||
*state_p = 0;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 idMod256)
|
||||
{
|
||||
struct UnionObj * ptr = &UnionObjWork[playerIdx];
|
||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561)
|
||||
ptr->schedAnim = UNION_ROOM_SPAWN_IN;
|
||||
ptr->gfxId = GetUnionRoomPlayerGraphicsId(gender, idMod256);
|
||||
if (ptr->state == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool32 DespawnGroupLeader(u32 playerIdx)
|
||||
{
|
||||
struct UnionObj * ptr = &UnionObjWork[playerIdx];
|
||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577)
|
||||
ptr->schedAnim = UNION_ROOM_SPAWN_OUT;
|
||||
if (ptr->state == 1)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void AnimateUnionObj(u32 playerIdx, struct UnionObj * ptr)
|
||||
{
|
||||
switch (ptr->state)
|
||||
{
|
||||
case 0:
|
||||
if (ptr->schedAnim == UNION_ROOM_SPAWN_IN)
|
||||
{
|
||||
ptr->state = 2;
|
||||
ptr->animState = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case 2:
|
||||
if (!RfuUnionGroupMemberIsInvisible(playerIdx, 0) && ptr->schedAnim == 2)
|
||||
{
|
||||
ptr->state = 0;
|
||||
ptr->animState = 0;
|
||||
RemoveUnionRoomPlayerObjectEvent(playerIdx);
|
||||
HideUnionRoomPlayer(playerIdx);
|
||||
}
|
||||
else if (AnimateUnionRoomPlayerSpawn(&ptr->animState, playerIdx, ptr) == TRUE)
|
||||
{
|
||||
ptr->state = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (ptr->schedAnim == UNION_ROOM_SPAWN_OUT)
|
||||
{
|
||||
ptr->state = 3;
|
||||
ptr->animState = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case 3:
|
||||
if (AnimateUnionRoomPlayerDespawn(&ptr->animState, playerIdx, ptr) == TRUE)
|
||||
{
|
||||
ptr->state = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ptr->schedAnim = UNION_ROOM_SPAWN_NONE;
|
||||
}
|
||||
|
||||
static void Task_AnimateUnionObjs(u8 taskId)
|
||||
{
|
||||
s32 i;
|
||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 643)
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
AnimateUnionObj(i, &UnionObjWork[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static u8 StartUnionObjAnimTask(void)
|
||||
{
|
||||
if (FuncIsActiveTask(Task_AnimateUnionObjs) == TRUE)
|
||||
{
|
||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 655)
|
||||
return NUM_TASKS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CreateTask(Task_AnimateUnionObjs, 5);
|
||||
}
|
||||
}
|
||||
|
||||
static void DestroyAnimateUnionObjsTask(void)
|
||||
{
|
||||
u8 taskId = FindTaskIdByFunc(Task_AnimateUnionObjs);
|
||||
if (taskId < NUM_TASKS)
|
||||
{
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteUnionObjWorkAndStopTask(void)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (!IsUnionRoomPlayerHidden(i))
|
||||
{
|
||||
RemoveUnionRoomPlayerObjectEvent(i);
|
||||
HideUnionRoomPlayer(i);
|
||||
}
|
||||
}
|
||||
UnionObjWork = NULL;
|
||||
DestroyAnimateUnionObjsTask();
|
||||
}
|
||||
|
||||
void CreateGroupMemberObjectsInvisible(u8 * sprite_ids, s32 group)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
s32 obj_id = 5 * group + i;
|
||||
sprite_ids[obj_id] = CreateVirtualObject(OBJ_EVENT_GFX_MAN, obj_id - 0x38, sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[i][0], sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[i][1], 3, 1);
|
||||
SetVirtualObjectInvisibility(obj_id - 0x38, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyGroupMemberObjects(u8 *spriteIds)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < 40; i++)
|
||||
{
|
||||
DestroySprite(&gSprites[spriteIds[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
void MakeGroupAssemblyAreasPassable(void)
|
||||
{
|
||||
s32 i, j, x, y;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
for (j = 0; j < 5; j++)
|
||||
{
|
||||
GetUnionRoomPlayerFacingCoords(i, j, &x, &y);
|
||||
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u8 UnionPartnerObjectGetFacing(u32 member, u32 group, struct GFtgtGname * gname)
|
||||
{
|
||||
if (member != 0)
|
||||
{
|
||||
return sUnionGroupMemberFacings[member];
|
||||
}
|
||||
else if (gname->activity == 0x45)
|
||||
{
|
||||
return DIR_SOUTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DIR_EAST;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member)
|
||||
{
|
||||
return IsVirtualObjectInvisible(5 * group + member - 0x38);
|
||||
}
|
||||
|
||||
static void SpawnGroupMember(u32 groupNo, u32 memberNo, u8 direction, struct GFtgtGname * gname)
|
||||
{
|
||||
s32 x, y;
|
||||
s32 objId = 5 * groupNo + memberNo;
|
||||
if (RfuUnionGroupMemberIsInvisible(groupNo, memberNo) == TRUE)
|
||||
{
|
||||
SetVirtualObjectInvisibility(objId - 0x38, FALSE);
|
||||
SetVirtualObjectSpriteAnim(objId - 0x38, UNION_ROOM_SPAWN_IN);
|
||||
}
|
||||
SetVirtualObjectGraphics(objId - 0x38, direction);
|
||||
UnionPartnerObjectSetFacing(memberNo, groupNo, UnionPartnerObjectGetFacing(memberNo, groupNo, gname));
|
||||
GetUnionRoomPlayerFacingCoords(groupNo, memberNo, &x, &y);
|
||||
MapGridSetMetatileImpassabilityAt(x, y, TRUE);
|
||||
}
|
||||
|
||||
static void DespawnGroupMember(u32 group, u32 member)
|
||||
{
|
||||
s32 x, y;
|
||||
SetVirtualObjectSpriteAnim(5 * group + member - 0x38, UNION_ROOM_SPAWN_OUT);
|
||||
GetUnionRoomPlayerFacingCoords(group, member, &x, &y);
|
||||
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
|
||||
}
|
||||
|
||||
static void AssembleGroup(u32 group, struct GFtgtGname * gname)
|
||||
{
|
||||
s16 x, y, x2, y2;
|
||||
s32 i;
|
||||
|
||||
PlayerGetDestCoords(&x, &y);
|
||||
player_get_pos_including_state_based_drift(&x2, &y2);
|
||||
if (IsVirtualObjectInvisible(5 * group - 0x38) == TRUE)
|
||||
{
|
||||
if (IsUnionRoomPlayerFacingTileAt(group, 0, x, y) == TRUE || IsUnionRoomPlayerFacingTileAt(group, 0, x2, y2) == TRUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SpawnGroupMember(group, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->unk_00.playerTrainerId[0]), gname);
|
||||
}
|
||||
for (i = 1; i < 5; i++)
|
||||
{
|
||||
if (gname->child_sprite_gender[i - 1] == 0)
|
||||
{
|
||||
DespawnGroupMember(group, i);
|
||||
}
|
||||
else if (IsUnionRoomPlayerFacingTileAt(group, i, x, y) == FALSE && IsUnionRoomPlayerFacingTileAt(group, i, x2, y2) == FALSE)
|
||||
{
|
||||
SpawnGroupMember(group, i, GetUnionRoomPlayerGraphicsId((gname->child_sprite_gender[i - 1] >> 3) & 1, gname->child_sprite_gender[i - 1] & 7), gname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SpawnGroupLeaderAndMembers(u32 group, struct GFtgtGname * gname)
|
||||
{
|
||||
u32 i;
|
||||
switch (gname->activity)
|
||||
{
|
||||
case 0x40:
|
||||
case 0x54:
|
||||
SpawnGroupLeader(group, gname->playerGender, gname->unk_00.playerTrainerId[0]);
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
DespawnGroupMember(group, i);
|
||||
}
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x44:
|
||||
case 0x45:
|
||||
case 0x48:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
DespawnGroupLeader(group);
|
||||
AssembleGroup(group, gname);
|
||||
break;
|
||||
default:
|
||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 979)
|
||||
}
|
||||
}
|
||||
|
||||
static void DespawnGroupLeaderAndMembers(u32 group, struct GFtgtGname * gname)
|
||||
{
|
||||
s32 i;
|
||||
DespawnGroupLeader(group);
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
DespawnGroupMember(group, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateUnionRoomPlayerSprites(struct UnkStruct_URoom * groups)
|
||||
{
|
||||
s32 i;
|
||||
struct UnkStruct_x20 * x20_p;
|
||||
sUnionObjRefreshTimer = 0;
|
||||
for (i = 0, x20_p = groups->field_0->arr; i < 8; i++)
|
||||
{
|
||||
if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN)
|
||||
{
|
||||
SpawnGroupLeaderAndMembers(i, &x20_p[i].gname_uname.gname);
|
||||
}
|
||||
else if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT)
|
||||
{
|
||||
DespawnGroupLeaderAndMembers(i, &x20_p[i].gname_uname.gname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p)
|
||||
{
|
||||
sUnionObjRefreshTimer = 300;
|
||||
}
|
||||
|
||||
void HandleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p)
|
||||
{
|
||||
if (++sUnionObjRefreshTimer > 300)
|
||||
{
|
||||
UpdateUnionRoomPlayerSprites(uroom_p);
|
||||
}
|
||||
}
|
||||
|
||||
bool32 RfuUnionTool_GetGroupAndMemberInFrontOfPlayer(struct UnkStruct_Main0 *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds)
|
||||
{
|
||||
s16 x, y;
|
||||
s32 i, j;
|
||||
struct UnkStruct_x20 * x20_p;
|
||||
if (!is_walking_or_running())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
|
||||
for (i = 0, x20_p = main0_p->arr; i < 8; i++)
|
||||
{
|
||||
for (j = 0; j < 5; j++)
|
||||
{
|
||||
s32 objId = 5 * i + j;
|
||||
if (x != sUnionPartnerCoords[i][0] + sFacingDirectionOffsets[j][0] + 7)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (y != sUnionPartnerCoords[i][1] + sFacingDirectionOffsets[j][1] + 7)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (IsVirtualObjectInvisible(objId - 0x38) != FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (IsVirtualObjectAnimating(objId - 0x38) != FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (x20_p[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
UnionPartnerObjectSetFacing(j, i, sOppositeFacingDirection[GetPlayerFacingDirection()]);
|
||||
*member_p = j;
|
||||
*group_p = i;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction)
|
||||
{
|
||||
TurnVirtualObject(5 * group - 0x38 + member, direction);
|
||||
}
|
||||
|
||||
void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct UnkStruct_Main0 *main0_p)
|
||||
{
|
||||
return UnionPartnerObjectSetFacing(member, group, UnionPartnerObjectGetFacing(member, group, &main0_p->arr[group].gname_uname.gname));
|
||||
}
|
||||
+1
-1
@@ -374,7 +374,7 @@ void Task_StartMenuHandleInput(u8 taskId)
|
||||
{
|
||||
case 0:
|
||||
if (InUnionRoom() == TRUE)
|
||||
var_800D_set_xB();
|
||||
SetUsingUnionRoomStartMenu();
|
||||
sStartMenuCallback = StartCB_HandleInput;
|
||||
data[0]++;
|
||||
break;
|
||||
|
||||
+10
-10
@@ -711,7 +711,7 @@ static void InitTradeMenuResources(void)
|
||||
}
|
||||
}
|
||||
|
||||
void CB2_ReturnFromLinkTrade(void)
|
||||
void CB2_StartCreateTradeMenu(void)
|
||||
{
|
||||
SetMainCallback2(CB2_ReturnFromLinkTrade2);
|
||||
}
|
||||
@@ -759,7 +759,7 @@ static void CB2_ReturnFromLinkTrade2(void)
|
||||
{
|
||||
SetWirelessCommType1();
|
||||
OpenLink();
|
||||
LinkRfu_CreateIdleTask();
|
||||
CreateTask_RfuIdle();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -802,13 +802,13 @@ static void CB2_ReturnFromLinkTrade2(void)
|
||||
case 4:
|
||||
if (gReceivedRemoteLinkPlayers == TRUE && IsLinkPlayerDataExchangeComplete() == TRUE)
|
||||
{
|
||||
LinkRfu_DestroyIdleTask();
|
||||
DestroyTask_RfuIdle();
|
||||
CalculatePlayerPartyCount();
|
||||
gMain.state++;
|
||||
sTradeMenuResourcesPtr->loadUISpritesState = 0;
|
||||
if (gWirelessCommType)
|
||||
{
|
||||
ToggleLMANlinkRecovery(TRUE);
|
||||
Rfu_SetLinkRecovery(TRUE);
|
||||
SetLinkStandbyCallback();
|
||||
}
|
||||
}
|
||||
@@ -1208,7 +1208,7 @@ static void TradeMenuCB_10(void)
|
||||
|
||||
static void TradeMenuCB_13(void)
|
||||
{
|
||||
gMain.savedCallback = CB2_ReturnFromLinkTrade;
|
||||
gMain.savedCallback = CB2_StartCreateTradeMenu;
|
||||
if (gWirelessCommType != 0)
|
||||
{
|
||||
if (IsLinkRfuTaskFinished())
|
||||
@@ -1218,7 +1218,7 @@ static void TradeMenuCB_13(void)
|
||||
Free(sTradeMenuResourcesPtr);
|
||||
gMain.callback1 = NULL;
|
||||
DestroyWirelessStatusIndicatorSprite();
|
||||
SetMainCallback2(CB2_InitTradeAnim_LinkTrade);
|
||||
SetMainCallback2(CB2_LinkTrade);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1229,7 +1229,7 @@ static void TradeMenuCB_13(void)
|
||||
FreeAllWindowBuffers();
|
||||
Free(sTradeMenuResourcesPtr);
|
||||
gMain.callback1 = NULL;
|
||||
SetMainCallback2(CB2_InitTradeAnim_LinkTrade);
|
||||
SetMainCallback2(CB2_LinkTrade);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2019,7 +2019,7 @@ static void TradeMenuCB_12(void)
|
||||
|
||||
static void TradeMenuCB_16(void)
|
||||
{
|
||||
if (!ToggleLMANlinkRecovery(FALSE))
|
||||
if (!Rfu_SetLinkRecovery(FALSE))
|
||||
{
|
||||
SetLinkStandbyCallback();
|
||||
sTradeMenuResourcesPtr->tradeMenuCBnum = 13;
|
||||
@@ -2720,7 +2720,7 @@ static bool32 IsDeoxysOrMewUntradable(u16 species, bool8 isEventLegal)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int GetUnionRoomTradeMessageId(struct GFtgtGnameSub playerSub, struct GFtgtGnameSub partnerSub, u16 species1, u16 species2, u8 type, u16 species3, u8 isEventLegal)
|
||||
int GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData playerSub, struct RfuGameCompatibilityData partnerSub, u16 species1, u16 species2, u8 type, u16 species3, u8 isEventLegal)
|
||||
{
|
||||
u8 playerHasNationalDex = playerSub.hasNationalDex;
|
||||
u8 playerIsChampion = playerSub.isChampion;
|
||||
@@ -2800,7 +2800,7 @@ int GetUnionRoomTradeMessageId(struct GFtgtGnameSub playerSub, struct GFtgtGname
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CanRegisterMonForTradingBoard(struct GFtgtGnameSub playerSub, u16 species2, u16 species, u8 isEventLegal)
|
||||
int CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData playerSub, u16 species2, u16 species, u8 isEventLegal)
|
||||
{
|
||||
u8 canTradeEggAndNational = playerSub.hasNationalDex;
|
||||
|
||||
|
||||
+3
-3
@@ -773,7 +773,7 @@ static void LoadTradeMonPic(u8 whichParty, u8 action)
|
||||
}
|
||||
}
|
||||
|
||||
void CB2_InitTradeAnim_LinkTrade(void)
|
||||
void CB2_LinkTrade(void)
|
||||
{
|
||||
switch (gMain.state)
|
||||
{
|
||||
@@ -2668,7 +2668,7 @@ static void CB2_HandleTradeEnded(void)
|
||||
case 8:
|
||||
if (IsBGMStopped() == TRUE)
|
||||
{
|
||||
if (gWirelessCommType && gMain.savedCallback == CB2_ReturnFromLinkTrade)
|
||||
if (gWirelessCommType && gMain.savedCallback == CB2_StartCreateTradeMenu)
|
||||
{
|
||||
SetLinkStandbyCallback();
|
||||
}
|
||||
@@ -2680,7 +2680,7 @@ static void CB2_HandleTradeEnded(void)
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (gWirelessCommType && gMain.savedCallback == CB2_ReturnFromLinkTrade)
|
||||
if (gWirelessCommType && gMain.savedCallback == CB2_StartCreateTradeMenu)
|
||||
{
|
||||
if (IsLinkRfuTaskFinished())
|
||||
{
|
||||
|
||||
+1560
-1970
File diff suppressed because it is too large
Load Diff
+15
-15
@@ -324,7 +324,7 @@ static void ChatEntryRoutine_Join(void)
|
||||
sWork->routineState++;
|
||||
// fall through
|
||||
case 1:
|
||||
if (IsLinkTaskFinished() && !RfuHasFoundNewLeader())
|
||||
if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive())
|
||||
{
|
||||
if (SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer)))
|
||||
sWork->routineState++;
|
||||
@@ -527,14 +527,14 @@ static void ChatEntryRoutine_AskQuitChatting(void)
|
||||
sWork->routineState = 3;
|
||||
break;
|
||||
case 0:
|
||||
Rfu_UnionRoomChat_StopLinkManager();
|
||||
Rfu_StopPartnerSearch();
|
||||
PrepareSendBuffer_Disband(sWork->sendMessageBuffer);
|
||||
sWork->routineState = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (IsLinkTaskFinished() && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer)))
|
||||
if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer)))
|
||||
{
|
||||
if (sWork->multiplayerId == 0)
|
||||
sWork->routineState = 6;
|
||||
@@ -577,15 +577,15 @@ static void ChatEntryRoutine_ExitChat(void)
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (IsLinkTaskFinished() && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer)))
|
||||
if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer)))
|
||||
sWork->routineState++;
|
||||
break;
|
||||
case 4:
|
||||
if ((GetBlockReceivedStatus() & 1) && !RfuHasFoundNewLeader())
|
||||
if ((GetBlockReceivedStatus() & 1) && !Rfu_IsPlayerExchangeActive())
|
||||
sWork->routineState++;
|
||||
break;
|
||||
case 5:
|
||||
if (IsLinkTaskFinished() && !RfuHasFoundNewLeader())
|
||||
if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive())
|
||||
{
|
||||
SetCloseLinkCallback();
|
||||
sWork->exitDelayTimer = 0;
|
||||
@@ -620,7 +620,7 @@ static void ChatEntryRoutine_Drop(void)
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (!RunDisplaySubtask(0) && IsLinkTaskFinished() && !RfuHasFoundNewLeader())
|
||||
if (!RunDisplaySubtask(0) && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive())
|
||||
{
|
||||
SetCloseLinkCallback();
|
||||
sWork->exitDelayTimer = 0;
|
||||
@@ -666,7 +666,7 @@ static void ChatEntryRoutine_Disbanded(void)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (RunDisplaySubtask(0) != TRUE && IsLinkTaskFinished() && !RfuHasFoundNewLeader())
|
||||
if (RunDisplaySubtask(0) != TRUE && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive())
|
||||
{
|
||||
SetCloseLinkCallback();
|
||||
sWork->exitDelayTimer = 0;
|
||||
@@ -704,7 +704,7 @@ static void ChatEntryRoutine_SendMessage(void)
|
||||
sWork->routineState++;
|
||||
// fall through
|
||||
case 1:
|
||||
if (IsLinkTaskFinished() == TRUE && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer)))
|
||||
if (IsLinkTaskFinished() == TRUE && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer)))
|
||||
sWork->routineState++;
|
||||
break;
|
||||
case 2:
|
||||
@@ -1144,7 +1144,7 @@ static void PrepareSendBuffer_Leave(u8 *arg0)
|
||||
arg0[0] = CHAT_MESSAGE_LEAVE;
|
||||
StringCopy(&arg0[1], gSaveBlock2Ptr->playerName);
|
||||
arg0[1 + (PLAYER_NAME_LENGTH + 1)] = sWork->multiplayerId;
|
||||
sub_80FB9D0();
|
||||
RfuSetNormalDisconnectMode();
|
||||
}
|
||||
|
||||
static void PrepareSendBuffer_Drop(u8 *arg0)
|
||||
@@ -1355,7 +1355,7 @@ static void Task_ReceiveChatMessage(u8 taskId)
|
||||
}
|
||||
|
||||
tBlockReceivedStatus = GetBlockReceivedStatus();
|
||||
if (!tBlockReceivedStatus && RfuHasFoundNewLeader())
|
||||
if (!tBlockReceivedStatus && Rfu_IsPlayerExchangeActive())
|
||||
return;
|
||||
|
||||
tI = 0;
|
||||
@@ -1409,13 +1409,13 @@ static void Task_ReceiveChatMessage(u8 taskId)
|
||||
// You're the leader, and the person who left is not you
|
||||
if (GetLinkPlayerCount() == 2)
|
||||
{
|
||||
Rfu_UnionRoomChat_StopLinkManager();
|
||||
Rfu_StopPartnerSearch();
|
||||
sWork->exitType = CHATEXIT_LEADER_LAST;
|
||||
DestroyTask(taskId);
|
||||
return;
|
||||
}
|
||||
|
||||
sub_80FBD6C(tCurrLinkPlayer);
|
||||
Rfu_DisconnectPlayerById(tCurrLinkPlayer);
|
||||
}
|
||||
|
||||
tState = 3;
|
||||
@@ -1433,10 +1433,10 @@ static void Task_ReceiveChatMessage(u8 taskId)
|
||||
DestroyTask(taskId);
|
||||
break;
|
||||
case 2:
|
||||
if (!RfuHasFoundNewLeader())
|
||||
if (!Rfu_IsPlayerExchangeActive())
|
||||
{
|
||||
if (sWork->multiplayerId == 0)
|
||||
sub_80FB030(sWork->linkPlayerCount);
|
||||
SetUnionRoomChatPlayerData(sWork->linkPlayerCount);
|
||||
|
||||
tState = 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,615 @@
|
||||
#include "global.h"
|
||||
#include "event_data.h"
|
||||
#include "event_object_movement.h"
|
||||
#include "field_player_avatar.h"
|
||||
#include "fieldmap.h"
|
||||
#include "union_room_player_avatar.h"
|
||||
#include "script.h"
|
||||
#include "task.h"
|
||||
#include "constants/event_object_movement.h"
|
||||
#include "constants/union_room.h"
|
||||
#include "constants/event_objects.h"
|
||||
|
||||
#define UR_SPRITE_START_ID (MAX_SPRITES - MAX_UNION_ROOM_LEADERS)
|
||||
|
||||
// Each parent player can lead a group of up to MAX_RFU_PLAYERS (including themselves).
|
||||
// Multiply the leader's id by MAX_RFU_PLAYERS and add the member's id (0 if the leader) to
|
||||
// get the sprite index of that player.
|
||||
#define UR_PLAYER_SPRITE_ID(leaderId, memberId)(MAX_RFU_PLAYERS * leaderId + memberId)
|
||||
|
||||
// Original symbol name from ASSERT statements
|
||||
#define UnionObjWork sUnionObjWork
|
||||
|
||||
static EWRAM_DATA struct UnionRoomObject * sUnionObjWork = NULL;
|
||||
static EWRAM_DATA u32 sUnionObjRefreshTimer = 0;
|
||||
|
||||
static u8 CreateTask_AnimateUnionRoomPlayers(void);
|
||||
static u32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 member);
|
||||
static void SetUnionRoomObjectFacingDirection(s32 member, s32 leaderId, u8 direction);
|
||||
|
||||
// + 2 is just to match, those elements are empty and never read
|
||||
// Graphics ids should correspond with the classes in gUnionRoomFacilityClasses
|
||||
static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][NUM_UNION_ROOM_CLASSES + 2] = {
|
||||
[MALE] = {
|
||||
OBJ_EVENT_GFX_COOLTRAINER_M,
|
||||
OBJ_EVENT_GFX_BLACKBELT,
|
||||
OBJ_EVENT_GFX_CAMPER,
|
||||
OBJ_EVENT_GFX_YOUNGSTER,
|
||||
OBJ_EVENT_GFX_BOY,
|
||||
OBJ_EVENT_GFX_BUG_CATCHER,
|
||||
OBJ_EVENT_GFX_MAN,
|
||||
OBJ_EVENT_GFX_ROCKER
|
||||
},
|
||||
[FEMALE] = {
|
||||
OBJ_EVENT_GFX_COOLTRAINER_F,
|
||||
OBJ_EVENT_GFX_CHANNELER,
|
||||
OBJ_EVENT_GFX_PICNICKER,
|
||||
OBJ_EVENT_GFX_LASS,
|
||||
OBJ_EVENT_GFX_WOMAN_1,
|
||||
OBJ_EVENT_GFX_BATTLE_GIRL,
|
||||
OBJ_EVENT_GFX_WOMAN_2,
|
||||
OBJ_EVENT_GFX_BEAUTY
|
||||
}
|
||||
};
|
||||
|
||||
static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_LEADERS][2] = {
|
||||
{ 4, 6},
|
||||
{13, 8},
|
||||
{10, 6},
|
||||
{ 1, 8},
|
||||
{13, 4},
|
||||
{ 7, 4},
|
||||
{ 1, 4},
|
||||
{ 7, 8}
|
||||
};
|
||||
|
||||
// If there's a group of players interacting in the Union Room, the group
|
||||
// leader will be at one of the positions above and each member in the group
|
||||
// will be at one of the offsets from that position below. The leader will
|
||||
// be at the first offset (0,0), as they're at the center.
|
||||
static const s8 sUnionRoomGroupOffsets[][2] = {
|
||||
{ 0, 0}, // Center
|
||||
{ 1, 0}, // Left
|
||||
{ 0, -1}, // Top
|
||||
{-1, 0}, // Right
|
||||
{ 0, 1} // Bottom
|
||||
};
|
||||
|
||||
static const u8 sOppositeFacingDirection[] = {
|
||||
[DIR_NONE] = DIR_NONE,
|
||||
[DIR_SOUTH] = DIR_NORTH,
|
||||
[DIR_NORTH] = DIR_SOUTH,
|
||||
[DIR_WEST] = DIR_EAST,
|
||||
[DIR_EAST] = DIR_WEST
|
||||
};
|
||||
|
||||
// Compare to sUnionRoomGroupOffsets, the direction each group member
|
||||
// needs to be facing in order to face the group leader in the center.
|
||||
static const u8 sMemberFacingDirections[] = {
|
||||
DIR_SOUTH, // Leader, but never read
|
||||
DIR_WEST,
|
||||
DIR_SOUTH,
|
||||
DIR_EAST,
|
||||
DIR_NORTH
|
||||
};
|
||||
|
||||
static const u8 sUnionRoomLocalIds[] = {
|
||||
LOCALID_UNION_ROOM_PLAYER_1,
|
||||
LOCALID_UNION_ROOM_PLAYER_2,
|
||||
LOCALID_UNION_ROOM_PLAYER_3,
|
||||
LOCALID_UNION_ROOM_PLAYER_4,
|
||||
LOCALID_UNION_ROOM_PLAYER_5,
|
||||
LOCALID_UNION_ROOM_PLAYER_6,
|
||||
LOCALID_UNION_ROOM_PLAYER_7,
|
||||
LOCALID_UNION_ROOM_PLAYER_8
|
||||
};
|
||||
|
||||
// Unused
|
||||
static const u16 sHidePlayerFlags[] = {
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_1,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_2,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_3,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_4,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_5,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_6,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_7,
|
||||
FLAG_HIDE_UNION_ROOM_PLAYER_8
|
||||
};
|
||||
|
||||
static bool32 IsPlayerStandingStill(void)
|
||||
{
|
||||
if (gPlayerAvatar.tileTransitionState == T_TILE_CENTER || gPlayerAvatar.tileTransitionState == T_NOT_MOVING)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Gender and trainer id are used to determine which sprite a player appears as
|
||||
static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id)
|
||||
{
|
||||
return sUnionRoomObjGfxIds[gender][id % NUM_UNION_ROOM_CLASSES];
|
||||
}
|
||||
|
||||
static void GetUnionRoomPlayerCoords(u32 leaderId, u32 memberId, s32 * x, s32 * y)
|
||||
{
|
||||
*x = sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7;
|
||||
*y = sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7;
|
||||
}
|
||||
|
||||
static bool32 IsUnionRoomPlayerAt(u32 leaderId, u32 memberId, s32 x, s32 y)
|
||||
{
|
||||
if ((sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + MAP_OFFSET == x)
|
||||
&& (sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + MAP_OFFSET == y))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 IsUnionRoomPlayerHidden(u32 leaderId)
|
||||
{
|
||||
return FlagGet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId);
|
||||
}
|
||||
|
||||
static void HideUnionRoomPlayer(u32 leaderId)
|
||||
{
|
||||
FlagSet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId);
|
||||
}
|
||||
|
||||
static void ShowUnionRoomPlayer(u32 leaderId)
|
||||
{
|
||||
FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId);
|
||||
}
|
||||
|
||||
static void SetUnionRoomPlayerGfx(u32 leaderId, u32 gfxId)
|
||||
{
|
||||
VarSet(VAR_OBJ_GFX_ID_0 + leaderId, gfxId);
|
||||
}
|
||||
|
||||
static void CreateUnionRoomPlayerObjectEvent(u32 leaderId)
|
||||
{
|
||||
TrySpawnObjectEvent(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
|
||||
}
|
||||
|
||||
static void RemoveUnionRoomPlayerObjectEvent(u32 leaderId)
|
||||
{
|
||||
RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
|
||||
}
|
||||
|
||||
static bool32 SetUnionRoomPlayerEnterExitMovement(u32 leaderId, const u8 * movement)
|
||||
{
|
||||
u8 objectId;
|
||||
struct ObjectEvent * object;
|
||||
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
|
||||
return FALSE;
|
||||
object = &gObjectEvents[objectId];
|
||||
if (ObjectEventIsMovementOverridden(object))
|
||||
return FALSE;
|
||||
if (ObjectEventSetHeldMovement(object, *movement))
|
||||
{
|
||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 387);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 leaderId)
|
||||
{
|
||||
u8 objectId;
|
||||
struct ObjectEvent * object;
|
||||
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
|
||||
return TRUE;
|
||||
|
||||
object = &gObjectEvents[objectId];
|
||||
if (!ObjectEventClearHeldMovementIfFinished(object))
|
||||
return FALSE;
|
||||
|
||||
if (!ArePlayerFieldControlsLocked())
|
||||
UnfreezeObjectEvent(object);
|
||||
else
|
||||
FreezeObjectEvent(object);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
sUnionObjRefreshTimer = 0;
|
||||
sUnionObjWork = players;
|
||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 442)
|
||||
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
|
||||
{
|
||||
players[i].state = 0;
|
||||
players[i].gfxId = 0;
|
||||
players[i].animState = 0;
|
||||
players[i].schedAnim = UNION_ROOM_SPAWN_NONE;
|
||||
}
|
||||
return CreateTask_AnimateUnionRoomPlayers();
|
||||
}
|
||||
|
||||
static const u8 sMovement_UnionPlayerExit[2] = {
|
||||
MOVEMENT_ACTION_FLY_UP,
|
||||
MOVEMENT_ACTION_STEP_END
|
||||
};
|
||||
|
||||
static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 leaderId, struct UnionRoomObject * object)
|
||||
{
|
||||
switch (*state)
|
||||
{
|
||||
case 0:
|
||||
if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerExit) == TRUE)
|
||||
{
|
||||
HideUnionRoomPlayer(leaderId);
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (TryReleaseUnionRoomPlayerObjectEvent(leaderId))
|
||||
{
|
||||
RemoveUnionRoomPlayerObjectEvent(leaderId);
|
||||
HideUnionRoomPlayer(leaderId);
|
||||
*state = 0;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const u8 sMovement_UnionPlayerEnter[2] = {
|
||||
MOVEMENT_ACTION_FLY_DOWN,
|
||||
MOVEMENT_ACTION_STEP_END
|
||||
};
|
||||
|
||||
static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 leaderId, struct UnionRoomObject * object)
|
||||
{
|
||||
s16 x, y;
|
||||
|
||||
switch (*state)
|
||||
{
|
||||
case 0:
|
||||
if (!IsPlayerStandingStill())
|
||||
break;
|
||||
PlayerGetDestCoords(&x, &y);
|
||||
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE)
|
||||
break;
|
||||
player_get_pos_including_state_based_drift(&x, &y);
|
||||
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE)
|
||||
break;
|
||||
SetUnionRoomPlayerGfx(leaderId, object->gfxId);
|
||||
CreateUnionRoomPlayerObjectEvent(leaderId);
|
||||
ShowUnionRoomPlayer(leaderId);
|
||||
(*state)++;
|
||||
// fallthrough
|
||||
case 3: // incorrect?
|
||||
if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerEnter) == 1)
|
||||
(*state)++;
|
||||
break;
|
||||
case 2:
|
||||
if (TryReleaseUnionRoomPlayerObjectEvent(leaderId))
|
||||
{
|
||||
*state = 0;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 SpawnGroupLeader(u32 leaderId, u32 gender, u32 id)
|
||||
{
|
||||
struct UnionRoomObject * object = &sUnionObjWork[leaderId];
|
||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561)
|
||||
object->schedAnim = UNION_ROOM_SPAWN_IN;
|
||||
object->gfxId = GetUnionRoomPlayerGraphicsId(gender, id);
|
||||
|
||||
if (object->state == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 DespawnGroupLeader(u32 leaderId)
|
||||
{
|
||||
struct UnionRoomObject * object = &sUnionObjWork[leaderId];
|
||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577)
|
||||
object->schedAnim = UNION_ROOM_SPAWN_OUT;
|
||||
|
||||
if (object->state == 1)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void AnimateUnionRoomPlayer(u32 leaderId, struct UnionRoomObject * object)
|
||||
{
|
||||
switch (object->state)
|
||||
{
|
||||
case 0:
|
||||
if (object->schedAnim == UNION_ROOM_SPAWN_IN)
|
||||
{
|
||||
object->state = 2;
|
||||
object->animState = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case 2:
|
||||
if (!IsUnionRoomPlayerInvisible(leaderId, 0) && object->schedAnim == UNION_ROOM_SPAWN_OUT)
|
||||
{
|
||||
object->state = 0;
|
||||
object->animState = 0;
|
||||
RemoveUnionRoomPlayerObjectEvent(leaderId);
|
||||
HideUnionRoomPlayer(leaderId);
|
||||
}
|
||||
else if (AnimateUnionRoomPlayerSpawn(&object->animState, leaderId, object) == TRUE)
|
||||
{
|
||||
object->state = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (object->schedAnim != UNION_ROOM_SPAWN_OUT)
|
||||
break;
|
||||
object->state = 3;
|
||||
object->animState = 0;
|
||||
// fallthrough
|
||||
case 3:
|
||||
if (AnimateUnionRoomPlayerDespawn(&object->animState, leaderId, object) == TRUE)
|
||||
object->state = 0;
|
||||
break;
|
||||
}
|
||||
object->schedAnim = UNION_ROOM_SPAWN_NONE;
|
||||
}
|
||||
|
||||
static void Task_AnimateUnionRoomPlayers(u8 taskId)
|
||||
{
|
||||
s32 i;
|
||||
AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 643)
|
||||
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
|
||||
AnimateUnionRoomPlayer(i, &sUnionObjWork[i]);
|
||||
}
|
||||
|
||||
static u8 CreateTask_AnimateUnionRoomPlayers(void)
|
||||
{
|
||||
if (FuncIsActiveTask(Task_AnimateUnionRoomPlayers) == TRUE)
|
||||
{
|
||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 655)
|
||||
return NUM_TASKS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CreateTask(Task_AnimateUnionRoomPlayers, 5);
|
||||
}
|
||||
}
|
||||
|
||||
static void DestroyTask_AnimateUnionRoomPlayers(void)
|
||||
{
|
||||
u8 taskId = FindTaskIdByFunc(Task_AnimateUnionRoomPlayers);
|
||||
if (taskId < NUM_TASKS)
|
||||
DestroyTask(taskId);
|
||||
}
|
||||
|
||||
void DestroyUnionRoomPlayerObjects(void)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
|
||||
{
|
||||
if (!IsUnionRoomPlayerHidden(i))
|
||||
{
|
||||
RemoveUnionRoomPlayerObjectEvent(i);
|
||||
HideUnionRoomPlayer(i);
|
||||
}
|
||||
}
|
||||
sUnionObjWork = NULL;
|
||||
DestroyTask_AnimateUnionRoomPlayers();
|
||||
}
|
||||
|
||||
void CreateUnionRoomPlayerSprites(u8 * spriteIds, s32 leaderId)
|
||||
{
|
||||
s32 memberId;
|
||||
|
||||
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
|
||||
{
|
||||
s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId);
|
||||
spriteIds[id] = CreateVirtualObject(OBJ_EVENT_GFX_MAN,
|
||||
id - UR_SPRITE_START_ID,
|
||||
sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0],
|
||||
sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1],
|
||||
3, 1);
|
||||
SetVirtualObjectInvisibility(id - UR_SPRITE_START_ID, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyUnionRoomPlayerSprites(u8 *spriteIds)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < NUM_UNION_ROOM_SPRITES; i++)
|
||||
DestroySprite(&gSprites[spriteIds[i]]);
|
||||
}
|
||||
|
||||
// Clear the impassable metatiles around the group leaders that get set
|
||||
// to prevent the player from walking through the group member sprites.
|
||||
void MakeGroupAssemblyAreasPassable(void)
|
||||
{
|
||||
s32 leaderId, memberId, x, y;
|
||||
for (leaderId = 0; leaderId < MAX_UNION_ROOM_LEADERS; leaderId++)
|
||||
{
|
||||
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
|
||||
{
|
||||
GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y);
|
||||
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static u8 GetNewFacingDirectionForUnionRoomPlayer(u32 memberId, u32 leaderId, struct RfuGameData * gameData)
|
||||
{
|
||||
if (memberId != 0) // If not leader
|
||||
return sMemberFacingDirections[memberId];
|
||||
else if (gameData->activity == (ACTIVITY_CHAT | IN_UNION_ROOM))
|
||||
return DIR_SOUTH;
|
||||
else
|
||||
return DIR_EAST;
|
||||
}
|
||||
|
||||
static u32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 memberId)
|
||||
{
|
||||
return IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID);
|
||||
}
|
||||
|
||||
static void SpawnGroupMember(u32 leaderId, u32 memberId, u8 graphicsId, struct RfuGameData * gameData)
|
||||
{
|
||||
s32 x, y;
|
||||
s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId);
|
||||
if (IsUnionRoomPlayerInvisible(leaderId, memberId) == TRUE)
|
||||
{
|
||||
SetVirtualObjectInvisibility(id - UR_SPRITE_START_ID, FALSE);
|
||||
SetVirtualObjectSpriteAnim(id - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_IN);
|
||||
}
|
||||
SetVirtualObjectGraphics(id - UR_SPRITE_START_ID, graphicsId);
|
||||
SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, gameData));
|
||||
GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y);
|
||||
MapGridSetMetatileImpassabilityAt(x, y, TRUE);
|
||||
}
|
||||
|
||||
static void DespawnGroupMember(u32 leaderId, u32 memberId)
|
||||
{
|
||||
s32 x, y;
|
||||
SetVirtualObjectSpriteAnim(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_OUT);
|
||||
GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y);
|
||||
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
|
||||
}
|
||||
|
||||
static void AssembleGroup(u32 leaderId, struct RfuGameData * gameData)
|
||||
{
|
||||
s16 x, y, x2, y2;
|
||||
s32 i;
|
||||
|
||||
PlayerGetDestCoords(&x, &y);
|
||||
player_get_pos_including_state_based_drift(&x2, &y2);
|
||||
if (IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, 0) - UR_SPRITE_START_ID) == TRUE)
|
||||
{
|
||||
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE || IsUnionRoomPlayerAt(leaderId, 0, x2, y2) == TRUE)
|
||||
return;
|
||||
SpawnGroupMember(leaderId, 0, GetUnionRoomPlayerGraphicsId(gameData->playerGender, gameData->compatibility.playerTrainerId[0]), gameData);
|
||||
}
|
||||
for (i = 1; i < MAX_RFU_PLAYERS; i++)
|
||||
{
|
||||
if (gameData->partnerInfo[i - 1] == 0)
|
||||
DespawnGroupMember(leaderId, i);
|
||||
else if (IsUnionRoomPlayerAt(leaderId, i, x, y) == FALSE && IsUnionRoomPlayerAt(leaderId, i, x2, y2) == FALSE)
|
||||
SpawnGroupMember(leaderId, i, GetUnionRoomPlayerGraphicsId((gameData->partnerInfo[i - 1] >> PINFO_GENDER_SHIFT) & 1,
|
||||
gameData->partnerInfo[i - 1] & PINFO_TID_MASK),
|
||||
gameData);
|
||||
}
|
||||
}
|
||||
|
||||
static void SpawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData)
|
||||
{
|
||||
u32 i;
|
||||
switch (gameData->activity)
|
||||
{
|
||||
case ACTIVITY_NONE | IN_UNION_ROOM:
|
||||
case ACTIVITY_PLYRTALK | IN_UNION_ROOM:
|
||||
SpawnGroupLeader(leaderId, gameData->playerGender, gameData->compatibility.playerTrainerId[0]);
|
||||
for (i = 0; i < MAX_RFU_PLAYERS; i++)
|
||||
DespawnGroupMember(leaderId, i);
|
||||
break;
|
||||
case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM:
|
||||
case ACTIVITY_TRADE | IN_UNION_ROOM:
|
||||
case ACTIVITY_CHAT | IN_UNION_ROOM:
|
||||
case ACTIVITY_CARD | IN_UNION_ROOM:
|
||||
case ACTIVITY_ACCEPT | IN_UNION_ROOM:
|
||||
case ACTIVITY_DECLINE | IN_UNION_ROOM:
|
||||
case ACTIVITY_NPCTALK | IN_UNION_ROOM:
|
||||
DespawnGroupLeader(leaderId);
|
||||
AssembleGroup(leaderId, gameData);
|
||||
break;
|
||||
default:
|
||||
AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 979)
|
||||
}
|
||||
}
|
||||
|
||||
static void DespawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData)
|
||||
{
|
||||
s32 i;
|
||||
DespawnGroupLeader(leaderId);
|
||||
for (i = 0; i < MAX_RFU_PLAYERS; i++)
|
||||
DespawnGroupMember(leaderId, i);
|
||||
}
|
||||
|
||||
static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * uroom)
|
||||
{
|
||||
s32 i;
|
||||
struct RfuPlayer * leaders;
|
||||
sUnionObjRefreshTimer = 0;
|
||||
for (i = 0, leaders = uroom->playerList->players; i < MAX_UNION_ROOM_LEADERS; i++)
|
||||
{
|
||||
if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN)
|
||||
SpawnGroupLeaderAndMembers(i, &leaders[i].rfu.data);
|
||||
else if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT)
|
||||
DespawnGroupLeaderAndMembers(i, &leaders[i].rfu.data);
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom)
|
||||
{
|
||||
sUnionObjRefreshTimer = 300;
|
||||
}
|
||||
|
||||
void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom)
|
||||
{
|
||||
if (++sUnionObjRefreshTimer > 300)
|
||||
UpdateUnionRoomPlayerSprites(uroom);
|
||||
}
|
||||
|
||||
bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds)
|
||||
{
|
||||
s16 x, y;
|
||||
s32 leaderId, memberId;
|
||||
struct RfuPlayer * leaders;
|
||||
if (!IsPlayerStandingStill())
|
||||
return FALSE;
|
||||
|
||||
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
|
||||
for (leaderId = 0, leaders = list->players; leaderId < MAX_UNION_ROOM_LEADERS; leaderId++)
|
||||
{
|
||||
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
|
||||
{
|
||||
s32 objId = UR_PLAYER_SPRITE_ID(leaderId, memberId);
|
||||
|
||||
// Is the player in front of a group member position?
|
||||
if (x != sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7)
|
||||
continue;
|
||||
if (y != sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7)
|
||||
continue;
|
||||
|
||||
// Has a group member spawned at this position?
|
||||
if (IsVirtualObjectInvisible(objId - UR_SPRITE_START_ID) != FALSE)
|
||||
continue;
|
||||
if (IsVirtualObjectAnimating(objId - UR_SPRITE_START_ID) != FALSE)
|
||||
continue;
|
||||
if (leaders[leaderId].groupScheduledAnim != UNION_ROOM_SPAWN_IN)
|
||||
continue;
|
||||
|
||||
// Interaction attempt successful, face player
|
||||
SetUnionRoomObjectFacingDirection(memberId, leaderId, sOppositeFacingDirection[GetPlayerFacingDirection()]);
|
||||
*memberIdPtr = memberId;
|
||||
*leaderIdPtr = leaderId;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void SetUnionRoomObjectFacingDirection(s32 memberId, s32 leaderId, u8 direction)
|
||||
{
|
||||
TurnVirtualObject(MAX_RFU_PLAYERS * leaderId - UR_SPRITE_START_ID + memberId, direction);
|
||||
}
|
||||
|
||||
void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list)
|
||||
{
|
||||
return SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, &list->players[leaderId].rfu.data));
|
||||
}
|
||||
@@ -14,46 +14,60 @@
|
||||
#include "constants/songs.h"
|
||||
#include "constants/union_room.h"
|
||||
|
||||
struct WirelessCommunicationStatusScreenStruct
|
||||
{
|
||||
u32 counts[4];
|
||||
u32 lastCounts[4];
|
||||
u32 activities[16];
|
||||
u8 taskId;
|
||||
u8 rfuTaskId;
|
||||
u8 filler_62[0xA];
|
||||
enum {
|
||||
COLOR_NONE,
|
||||
COLOR_NORMAL,
|
||||
COLOR_TOTAL,
|
||||
COLOR_TITLE,
|
||||
COLOR_UNUSED,
|
||||
};
|
||||
|
||||
static struct WirelessCommunicationStatusScreenStruct * sWCSS;
|
||||
enum {
|
||||
GROUPTYPE_NONE = -1,
|
||||
GROUPTYPE_TRADE,
|
||||
GROUPTYPE_BATTLE,
|
||||
GROUPTYPE_UNION,
|
||||
GROUPTYPE_TOTAL,
|
||||
NUM_GROUPTYPES
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
u32 groupCounts[NUM_GROUPTYPES];
|
||||
u32 prevGroupCounts[NUM_GROUPTYPES];
|
||||
u32 activities[NUM_TASK_DATA];
|
||||
u8 taskId;
|
||||
u8 rfuTaskId;
|
||||
u8 filler[10];
|
||||
} * sStatusScreen;
|
||||
|
||||
static void CB2_InitWirelessCommunicationScreen(void);
|
||||
static void Task_WirelessCommunicationScreen(u8 taskId);
|
||||
static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 palIdx);
|
||||
static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * activities, u8 taskId);
|
||||
|
||||
static const u16 sWCSS_Palettes[][16] = {
|
||||
INCBIN_U16("graphics/misc/unk_846f4d0.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f4f0.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f510.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f530.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f550.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f570.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f590.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f5b0.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f5d0.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f5f0.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f610.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f630.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f650.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f670.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f690.gbapal"),
|
||||
INCBIN_U16("graphics/misc/unk_846f6b0.gbapal")
|
||||
static const u16 sPalettes[][16] = {
|
||||
INCBIN_U16("graphics/wireless_status_screen/default.gbapal"),
|
||||
{}, // All black. Never read
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_00.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_01.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_02.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_03.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_04.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_05.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_06.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_07.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_08.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_09.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_10.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_11.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_12.gbapal"),
|
||||
INCBIN_U16("graphics/wireless_status_screen/anim_13.gbapal")
|
||||
};
|
||||
static const u32 sBgTiles_Gfx[] = INCBIN_U32("graphics/wireless_status_screen/bg.4bpp.lz");
|
||||
static const u16 sBgTiles_Tilemap[] = INCBIN_U16("graphics/wireless_status_screen/bg.bin");
|
||||
|
||||
static const u32 sBgTilesGfx[] = INCBIN_U32("graphics/misc/unk_846f6d0.4bpp.lz");
|
||||
static const u16 sBgTilemap[] = INCBIN_U16("graphics/misc/unk_846f8e0.bin");
|
||||
|
||||
static const struct BgTemplate sBGTemplates[] = {
|
||||
static const struct BgTemplate sBgTemplates[] = {
|
||||
{
|
||||
.bg = 0,
|
||||
.charBaseIndex = 2,
|
||||
@@ -75,29 +89,29 @@ static const struct BgTemplate sBGTemplates[] = {
|
||||
|
||||
static const struct WindowTemplate sWindowTemplates[] = {
|
||||
{
|
||||
.bg = 0x00,
|
||||
.tilemapLeft = 0x03,
|
||||
.tilemapTop = 0x00,
|
||||
.width = 0x18,
|
||||
.height = 0x03,
|
||||
.paletteNum = 0x0f,
|
||||
.baseBlock = 0x0001
|
||||
.bg = 0,
|
||||
.tilemapLeft = 3,
|
||||
.tilemapTop = 0,
|
||||
.width = 24,
|
||||
.height = 3,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x001
|
||||
}, {
|
||||
.bg = 0x00,
|
||||
.tilemapLeft = 0x03,
|
||||
.tilemapTop = 0x04,
|
||||
.width = 0x16,
|
||||
.height = 0x0f,
|
||||
.paletteNum = 0x0f,
|
||||
.baseBlock = 0x0049
|
||||
.bg = 0,
|
||||
.tilemapLeft = 3,
|
||||
.tilemapTop = 4,
|
||||
.width = 22,
|
||||
.height = 15,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x049
|
||||
}, {
|
||||
.bg = 0x00,
|
||||
.tilemapLeft = 0x19,
|
||||
.tilemapTop = 0x04,
|
||||
.width = 0x02,
|
||||
.height = 0x0f,
|
||||
.paletteNum = 0x0f,
|
||||
.baseBlock = 0x0193
|
||||
.bg = 0,
|
||||
.tilemapLeft = 25,
|
||||
.tilemapTop = 4,
|
||||
.width = 2,
|
||||
.height = 15,
|
||||
.paletteNum = 15,
|
||||
.baseBlock = 0x193
|
||||
}, DUMMY_WIN_TEMPLATE
|
||||
};
|
||||
|
||||
@@ -109,41 +123,43 @@ static const u8 *const sPlayersTextPtrs[] = {
|
||||
gText_Dynamic3Players
|
||||
};
|
||||
|
||||
static const u8 *const sHeaderTextPtrs[] = {
|
||||
gText_WirelessCommunicationStatus,
|
||||
gText_PeopleTrading,
|
||||
gText_PeopleBattling,
|
||||
gText_PeopleInUnionRoom,
|
||||
gText_PeopleCommunicating
|
||||
static const u8 *const sHeaderTexts[NUM_GROUPTYPES + 1] = {
|
||||
[0] = gText_WirelessCommunicationStatus,
|
||||
[GROUPTYPE_TRADE + 1] = gText_PeopleTrading,
|
||||
[GROUPTYPE_BATTLE + 1] = gText_PeopleBattling,
|
||||
[GROUPTYPE_UNION + 1] = gText_PeopleInUnionRoom,
|
||||
[GROUPTYPE_TOTAL + 1] = gText_PeopleCommunicating
|
||||
};
|
||||
|
||||
static const u8 sCountParams[][3] = {
|
||||
// activity, count idx, by
|
||||
// by=0 means count all
|
||||
// UB: no check for count idx == -1
|
||||
{ACTIVITY_BATTLE, 1, 2},
|
||||
{ACTIVITY_DBLBATTLE, 1, 2},
|
||||
{ACTIVITY_MLTBATTLE, 1, 4},
|
||||
{ACTIVITY_TRADE, 0, 2},
|
||||
{ACTIVITY_WCARD2, 3, 2},
|
||||
{ACTIVITY_WNEWS2, 3, 2},
|
||||
{ACTIVITY_PJUMP, 4, 0},
|
||||
{ACTIVITY_BCRUSH, 4, 0},
|
||||
{ACTIVITY_BPICK, 4, 0},
|
||||
{ACTIVITY_SEARCH, -1, 0},
|
||||
{ACTIVITY_SPINTRADE, 0, 0},
|
||||
{ACTIVITY_ITEMTRADE, -1, 0},
|
||||
{0x0f, 4, 0},
|
||||
{0x10, -1, 0},
|
||||
{0x40, 2, 1},
|
||||
{ACTIVITY_BATTLE | 0x40, 2, 2},
|
||||
{ACTIVITY_TRADE | 0x40, 2, 2},
|
||||
{ACTIVITY_CHAT | 0x40, 2, 0},
|
||||
{ACTIVITY_CARD | 0x40, 2, 2},
|
||||
{20 | 0x40, 2, 1},
|
||||
{19 | 0x40, 2, 2},
|
||||
{ACTIVITY_ACCEPT | 0x40, 2, 1},
|
||||
{ACTIVITY_DECLINE | 0x40, 2, 1}
|
||||
// Activity, group type, number of players
|
||||
// 0 players means the number of players can change and should be counted dynamically
|
||||
// GROUPTYPE_TOTAL have no unique group and are simply counted in the total of "people communicating".
|
||||
// A handful use NUM_GROUPTYPES, which is invalid, and are changed to GROUPTYPE_TOTAL in Emerald.
|
||||
// UB: GROUPTYPE_NONE (-1) can potentially be used as an index into a u8[4] in CountPlayersInGroupAndGetActivity.
|
||||
static const u8 sActivityGroupInfo[][3] = {
|
||||
{ACTIVITY_BATTLE_SINGLE, GROUPTYPE_BATTLE, 2},
|
||||
{ACTIVITY_BATTLE_DOUBLE, GROUPTYPE_BATTLE, 2},
|
||||
{ACTIVITY_BATTLE_MULTI, GROUPTYPE_BATTLE, 4},
|
||||
{ACTIVITY_TRADE, GROUPTYPE_TRADE, 2},
|
||||
{ACTIVITY_WONDER_CARD, GROUPTYPE_TOTAL, 2},
|
||||
{ACTIVITY_WONDER_NEWS, GROUPTYPE_TOTAL, 2},
|
||||
{ACTIVITY_POKEMON_JUMP, NUM_GROUPTYPES, 0},
|
||||
{ACTIVITY_BERRY_CRUSH, NUM_GROUPTYPES, 0},
|
||||
{ACTIVITY_BERRY_PICK, NUM_GROUPTYPES, 0},
|
||||
{ACTIVITY_SEARCH, GROUPTYPE_NONE, 0},
|
||||
{ACTIVITY_SPIN_TRADE, GROUPTYPE_TRADE, 0},
|
||||
{ACTIVITY_ITEM_TRADE, GROUPTYPE_NONE, 0},
|
||||
{ACTIVITY_RECORD_CORNER, NUM_GROUPTYPES, 0},
|
||||
{ACTIVITY_BERRY_BLENDER, GROUPTYPE_NONE, 0},
|
||||
{ACTIVITY_NONE | IN_UNION_ROOM, GROUPTYPE_UNION, 1},
|
||||
{ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM, GROUPTYPE_UNION, 2},
|
||||
{ACTIVITY_TRADE | IN_UNION_ROOM, GROUPTYPE_UNION, 2},
|
||||
{ACTIVITY_CHAT | IN_UNION_ROOM, GROUPTYPE_UNION, 0},
|
||||
{ACTIVITY_CARD | IN_UNION_ROOM, GROUPTYPE_UNION, 2},
|
||||
{ACTIVITY_PLYRTALK | IN_UNION_ROOM, GROUPTYPE_UNION, 1},
|
||||
{ACTIVITY_NPCTALK | IN_UNION_ROOM, GROUPTYPE_UNION, 2},
|
||||
{ACTIVITY_ACCEPT | IN_UNION_ROOM, GROUPTYPE_UNION, 1},
|
||||
{ACTIVITY_DECLINE | IN_UNION_ROOM, GROUPTYPE_UNION, 1}
|
||||
};
|
||||
|
||||
static void CB2_RunWirelessCommunicationScreen(void)
|
||||
@@ -173,14 +189,14 @@ void ShowWirelessCommunicationScreen(void)
|
||||
static void CB2_InitWirelessCommunicationScreen(void)
|
||||
{
|
||||
SetGpuReg(REG_OFFSET_DISPCNT, 0);
|
||||
sWCSS = AllocZeroed(sizeof(*sWCSS));
|
||||
sStatusScreen = AllocZeroed(sizeof(*sStatusScreen));
|
||||
SetVBlankCallback(NULL);
|
||||
ResetBgsAndClearDma3BusyFlags(FALSE);
|
||||
InitBgsFromTemplates(0, sBGTemplates, NELEMS(sBGTemplates));
|
||||
SetBgTilemapBuffer(1, Alloc(0x800));
|
||||
SetBgTilemapBuffer(0, Alloc(0x800));
|
||||
DecompressAndLoadBgGfxUsingHeap(1, sBgTilesGfx, 0, 0, 0);
|
||||
CopyToBgTilemapBuffer(1, sBgTilemap, 0, 0);
|
||||
InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates));
|
||||
SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE));
|
||||
SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE));
|
||||
DecompressAndLoadBgGfxUsingHeap(1, sBgTiles_Gfx, 0, 0, 0);
|
||||
CopyToBgTilemapBuffer(1, sBgTiles_Tilemap, 0, 0);
|
||||
InitWindows(sWindowTemplates);
|
||||
DeactivateAllTextPrinters();
|
||||
ResetPaletteFade();
|
||||
@@ -189,14 +205,14 @@ static void CB2_InitWirelessCommunicationScreen(void)
|
||||
ScanlineEffect_Stop();
|
||||
m4aSoundVSyncOn();
|
||||
SetVBlankCallback(VBlankCB_WirelessCommunicationScreen);
|
||||
sWCSS->taskId = CreateTask(Task_WirelessCommunicationScreen, 0);
|
||||
sWCSS->rfuTaskId = CreateTask_ListenToWireless();
|
||||
sWCSS->lastCounts[3] = 1;
|
||||
ChangeBgX(0, 0, 0);
|
||||
ChangeBgY(0, 0, 0);
|
||||
ChangeBgX(1, 0, 0);
|
||||
ChangeBgY(1, 0, 0);
|
||||
LoadPalette(sWCSS_Palettes, 0, 0x20);
|
||||
sStatusScreen->taskId = CreateTask(Task_WirelessCommunicationScreen, 0);
|
||||
sStatusScreen->rfuTaskId = CreateTask_ListenToWireless();
|
||||
sStatusScreen->prevGroupCounts[3] = 1;
|
||||
ChangeBgX(0, 0, BG_COORD_SET);
|
||||
ChangeBgY(0, 0, BG_COORD_SET);
|
||||
ChangeBgX(1, 0, BG_COORD_SET);
|
||||
ChangeBgY(1, 0, BG_COORD_SET);
|
||||
LoadPalette(sPalettes, 0, 0x20);
|
||||
Menu_LoadStdPalAt(0xf0);
|
||||
DynamicPlaceholderTextUtil_Reset();
|
||||
FillBgTilemapBufferRect(0, 0x000, 0, 0, 32, 32, 0xF);
|
||||
@@ -214,29 +230,24 @@ static void ExitWirelessCommunicationStatusScreen(void)
|
||||
s32 i;
|
||||
|
||||
FreeAllWindowBuffers();
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
for (i = 0; i < (int)ARRAY_COUNT(sBgTemplates); i++)
|
||||
Free(GetBgTilemapBuffer(i));
|
||||
}
|
||||
Free(sWCSS);
|
||||
Free(sStatusScreen);
|
||||
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
|
||||
}
|
||||
|
||||
static void WCSS_CyclePalette(s16 * frameCtr_p, s16 * palIdx_p)
|
||||
// Cycle through palettes that relocate various shades of blue to create the wave effect at the bottom of the screen.
|
||||
static void CyclePalette(s16 * counter, s16 * palIdx)
|
||||
{
|
||||
s32 idx;
|
||||
(*frameCtr_p)++;
|
||||
if (*frameCtr_p > 5)
|
||||
if (++(*counter) > 5)
|
||||
{
|
||||
(*palIdx_p)++;
|
||||
if (*palIdx_p == 14)
|
||||
{
|
||||
*palIdx_p = 0;
|
||||
}
|
||||
*frameCtr_p = 0;
|
||||
if (++(*palIdx) == (int)ARRAY_COUNT(sPalettes) - 2)
|
||||
*palIdx = 0;
|
||||
*counter = 0;
|
||||
}
|
||||
idx = *palIdx_p + 2;
|
||||
LoadPalette(sWCSS_Palettes[idx], 0, 16);
|
||||
idx = *palIdx + 2; // +2 skips over default.pal and the empty black palette after it
|
||||
LoadPalette(sPalettes[idx], 0, 16);
|
||||
}
|
||||
|
||||
static void PrintHeaderTexts(void)
|
||||
@@ -247,50 +258,57 @@ static void PrintHeaderTexts(void)
|
||||
FillWindowPixelBuffer(0, PIXEL_FILL(0));
|
||||
FillWindowPixelBuffer(1, PIXEL_FILL(0));
|
||||
FillWindowPixelBuffer(2, PIXEL_FILL(0));
|
||||
width = 0xC0 - GetStringWidth(FONT_3, sHeaderTextPtrs[0], 0);
|
||||
WCSS_AddTextPrinterParameterized(0, FONT_3, sHeaderTextPtrs[0], width / 2, 6, 3);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTextPtrs[i + 1], 0, 30 * i + 10, 1);
|
||||
}
|
||||
WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTextPtrs[i + 1], 0, 30 * i + 10, 2);
|
||||
|
||||
// Print title
|
||||
width = 192 - GetStringWidth(FONT_3, sHeaderTexts[0], 0);
|
||||
WCSS_AddTextPrinterParameterized(0, FONT_3, sHeaderTexts[0], width / 2, 6, COLOR_TITLE);
|
||||
|
||||
// Print label for each group (excluding total)
|
||||
for (i = 0; i < NUM_GROUPTYPES - 1; i++)
|
||||
WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTexts[i + 1], 0, 30 * i + 10, COLOR_NORMAL);
|
||||
|
||||
// Print label for total
|
||||
WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTexts[i + 1], 0, 30 * i + 10, COLOR_TOTAL);
|
||||
|
||||
PutWindowTilemap(0);
|
||||
CopyWindowToVram(0, COPYWIN_GFX);
|
||||
PutWindowTilemap(1);
|
||||
CopyWindowToVram(1, COPYWIN_GFX);
|
||||
}
|
||||
|
||||
#define tState data[0]
|
||||
|
||||
static void Task_WirelessCommunicationScreen(u8 taskId)
|
||||
{
|
||||
s32 i;
|
||||
switch (gTasks[taskId].data[0])
|
||||
switch (gTasks[taskId].tState)
|
||||
{
|
||||
case 0:
|
||||
PrintHeaderTexts();
|
||||
gTasks[taskId].data[0]++;
|
||||
gTasks[taskId].tState++;
|
||||
break;
|
||||
case 1:
|
||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
|
||||
ShowBg(1);
|
||||
CopyBgTilemapBufferToVram(0);
|
||||
ShowBg(0);
|
||||
gTasks[taskId].data[0]++;
|
||||
gTasks[taskId].tState++;
|
||||
break;
|
||||
case 2:
|
||||
if (!gPaletteFade.active)
|
||||
gTasks[taskId].data[0]++;
|
||||
gTasks[taskId].tState++;
|
||||
break;
|
||||
case 3:
|
||||
if (UpdateCommunicationCounts(sWCSS->counts, sWCSS->lastCounts, sWCSS->activities, sWCSS->rfuTaskId))
|
||||
if (UpdateCommunicationCounts(sStatusScreen->groupCounts, sStatusScreen->prevGroupCounts, sStatusScreen->activities, sStatusScreen->rfuTaskId))
|
||||
{
|
||||
FillWindowPixelBuffer(2, PIXEL_FILL(0));
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < NUM_GROUPTYPES; i++)
|
||||
{
|
||||
ConvertIntToDecimalStringN(gStringVar4, sWCSS->counts[i], STR_CONV_MODE_RIGHT_ALIGN, 2);
|
||||
if (i != 3)
|
||||
WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 30 * i + 10, 1);
|
||||
ConvertIntToDecimalStringN(gStringVar4, sStatusScreen->groupCounts[i], STR_CONV_MODE_RIGHT_ALIGN, 2);
|
||||
if (i != GROUPTYPE_TOTAL)
|
||||
WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 30 * i + 10, COLOR_NORMAL);
|
||||
else
|
||||
WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 100, 2);
|
||||
WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 100, COLOR_TOTAL);
|
||||
}
|
||||
PutWindowTilemap(2);
|
||||
CopyWindowToVram(2, COPYWIN_FULL);
|
||||
@@ -298,14 +316,14 @@ static void Task_WirelessCommunicationScreen(u8 taskId)
|
||||
if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
gTasks[sWCSS->rfuTaskId].data[15] = 0xFF;
|
||||
gTasks[taskId].data[0]++;
|
||||
gTasks[sStatusScreen->rfuTaskId].data[15] = 0xFF;
|
||||
gTasks[taskId].tState++;
|
||||
}
|
||||
WCSS_CyclePalette(&gTasks[taskId].data[7], &gTasks[taskId].data[8]);
|
||||
CyclePalette(&gTasks[taskId].data[7], &gTasks[taskId].data[8]);
|
||||
break;
|
||||
case 4:
|
||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
|
||||
gTasks[taskId].data[0]++;
|
||||
gTasks[taskId].tState++;
|
||||
break;
|
||||
case 5:
|
||||
if (!gPaletteFade.active)
|
||||
@@ -317,93 +335,99 @@ static void Task_WirelessCommunicationScreen(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 palIdx)
|
||||
static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 mode)
|
||||
{
|
||||
u8 textColor[3];
|
||||
switch (palIdx)
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
case COLOR_NONE: // Unused. Default to usual text colors
|
||||
textColor[0] = TEXT_COLOR_TRANSPARENT;
|
||||
textColor[1] = TEXT_COLOR_DARK_GRAY;
|
||||
textColor[2] = TEXT_COLOR_LIGHT_GRAY;
|
||||
break;
|
||||
case 1:
|
||||
case COLOR_NORMAL:
|
||||
textColor[0] = TEXT_COLOR_TRANSPARENT;
|
||||
textColor[1] = TEXT_COLOR_WHITE;
|
||||
textColor[2] = TEXT_COLOR_LIGHT_GRAY;
|
||||
break;
|
||||
case 2:
|
||||
case COLOR_TOTAL:
|
||||
textColor[0] = TEXT_COLOR_TRANSPARENT;
|
||||
textColor[1] = TEXT_COLOR_RED;
|
||||
textColor[2] = TEXT_COLOR_LIGHT_RED;
|
||||
break;
|
||||
case 3:
|
||||
case COLOR_TITLE:
|
||||
textColor[0] = TEXT_COLOR_TRANSPARENT;
|
||||
textColor[1] = TEXT_COLOR_LIGHT_GREEN;
|
||||
textColor[2] = TEXT_COLOR_GREEN;
|
||||
break;
|
||||
case 4:
|
||||
case COLOR_UNUSED:
|
||||
textColor[0] = TEXT_COLOR_TRANSPARENT;
|
||||
textColor[1] = TEXT_COLOR_WHITE;
|
||||
textColor[2] = TEXT_COLOR_DARK_GRAY;
|
||||
break;
|
||||
// default: UB
|
||||
}
|
||||
AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_0 ? 0 : 1, 0, textColor, -1, str);
|
||||
AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_0 ? 0 : 1, 0, textColor, TEXT_SKIP_DRAW, str);
|
||||
}
|
||||
|
||||
static u32 CountMembersInGroup(struct UnkStruct_x20 * unk20, u32 * counts)
|
||||
static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * groupCounts)
|
||||
{
|
||||
u32 activity = unk20->gname_uname.gname.activity;
|
||||
u32 activity = player->rfu.data.activity;
|
||||
s32 i, j, k;
|
||||
|
||||
for (i = 0; i < NELEMS(sCountParams); i++)
|
||||
#define group_activity(i) (sActivityGroupInfo[(i)][0])
|
||||
#define group_type(i) (sActivityGroupInfo[(i)][1])
|
||||
#define group_players(i) (sActivityGroupInfo[(i)][2])
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sActivityGroupInfo); i++)
|
||||
{
|
||||
if (activity == sCountParams[i][0] && unk20->groupScheduledAnim == UNION_ROOM_SPAWN_IN)
|
||||
if (activity == group_activity(i) && player->groupScheduledAnim == UNION_ROOM_SPAWN_IN)
|
||||
{
|
||||
if (sCountParams[i][2] == 0)
|
||||
if (group_players(i) == 0)
|
||||
{
|
||||
k = 0;
|
||||
for (j = 0; j < RFU_CHILD_MAX; j++)
|
||||
{
|
||||
if (unk20->gname_uname.gname.child_sprite_gender[j] != 0) k++;
|
||||
}
|
||||
if (player->rfu.data.partnerInfo[j] != 0) k++;
|
||||
k++;
|
||||
counts[sCountParams[i][1]] += k;
|
||||
groupCounts[group_type(i)] += k;
|
||||
}
|
||||
else
|
||||
{
|
||||
counts[sCountParams[i][1]] += sCountParams[i][2];
|
||||
groupCounts[group_type(i)] += group_players(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activity;
|
||||
|
||||
#undef group_activity
|
||||
#undef group_type
|
||||
#undef group_players
|
||||
}
|
||||
|
||||
static bool32 HaveCountsChanged(const u32 * newCounts, const u32 * prevCounts)
|
||||
static bool32 HaveCountsChanged(const u32 * curCounts, const u32 * prevCounts)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < NUM_GROUPTYPES; i++)
|
||||
{
|
||||
if (newCounts[i] != prevCounts[i])
|
||||
if (curCounts[i] != prevCounts[i])
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * activities, u8 taskId)
|
||||
static bool32 UpdateCommunicationCounts(u32 * groupCounts, u32 * prevGroupCounts, u32 * activities, u8 taskId)
|
||||
{
|
||||
bool32 activitiesUpdated = FALSE;
|
||||
u32 buffer[4] = {0, 0, 0, 0};
|
||||
struct UnkStruct_Group * group = (void *)gTasks[taskId].data;
|
||||
u32 groupCountBuffer[NUM_GROUPTYPES] = {0, 0, 0, 0};
|
||||
struct WirelessLink_Group * group = (void *)gTasks[taskId].data;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
for (i = 0; i < NUM_TASK_DATA; i++)
|
||||
{
|
||||
u32 activity = CountMembersInGroup(&group->field_0->arr[i], buffer);
|
||||
u32 activity = CountPlayersInGroupAndGetActivity(&group->playerList->players[i], groupCountBuffer);
|
||||
if (activity != activities[i])
|
||||
{
|
||||
activities[i] = activity;
|
||||
@@ -411,7 +435,7 @@ static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * ac
|
||||
}
|
||||
}
|
||||
|
||||
if (HaveCountsChanged(buffer, lastCounts) == FALSE)
|
||||
if (!HaveCountsChanged(groupCountBuffer, prevGroupCounts))
|
||||
{
|
||||
if (activitiesUpdated == TRUE)
|
||||
return TRUE;
|
||||
@@ -419,8 +443,15 @@ static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * ac
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(counts, buffer, sizeof(buffer));
|
||||
memcpy(lastCounts, buffer, sizeof(buffer));
|
||||
counts[3] = counts[0] + counts[1] + counts[2];
|
||||
memcpy(groupCounts, groupCountBuffer, sizeof(groupCountBuffer));
|
||||
memcpy(prevGroupCounts, groupCountBuffer, sizeof(groupCountBuffer));
|
||||
|
||||
groupCounts[GROUPTYPE_TOTAL] = groupCounts[GROUPTYPE_TRADE]
|
||||
+ groupCounts[GROUPTYPE_BATTLE]
|
||||
+ groupCounts[GROUPTYPE_UNION]
|
||||
#ifdef BUGFIX
|
||||
+ groupCounts[GROUPTYPE_TOTAL] // Missing count for activities not in above groups
|
||||
#endif
|
||||
;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@
|
||||
.include "src/help_message.o"
|
||||
.include "src/quest_log_events.o"
|
||||
.include "src/union_room.o"
|
||||
.include "src/rfu_union_tool.o"
|
||||
.include "src/union_room_player_avatar.o"
|
||||
.include "src/union_room_battle.o"
|
||||
.include "src/pokemon_special_anim.o"
|
||||
.include "src/party_menu.o"
|
||||
|
||||
Reference in New Issue
Block a user