mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
Merge pull request #255 from DizzyEggg/decomp_record_mixing
Fix pika's Record Mixing PR Also closes #107.
This commit is contained in:
commit
dd28854a22
2
Makefile
2
Makefile
@ -115,6 +115,8 @@ $(C_BUILDDIR)/agb_flash_mx.o: CFLAGS := -O -mthumb-interwork
|
||||
$(C_BUILDDIR)/m4a_2.o: CC1 := tools/agbcc/bin/old_agbcc
|
||||
$(C_BUILDDIR)/m4a_4.o: CC1 := tools/agbcc/bin/old_agbcc
|
||||
|
||||
$(C_BUILDDIR)/record_mixing.o: CFLAGS += -ffreestanding
|
||||
|
||||
ifeq ($(NODEP),)
|
||||
$(C_BUILDDIR)/%.o: c_dep = $(shell $(SCANINC) -I include $(C_SUBDIR)/$*.c)
|
||||
else
|
||||
|
@ -3746,7 +3746,7 @@ _08163FF4:
|
||||
ldr r0, [r6]
|
||||
ldr r1, =0x0000064c
|
||||
adds r0, r1
|
||||
bl sub_8164F70
|
||||
bl CalcEmeraldBattleTowerChecksum
|
||||
bl sub_8163E90
|
||||
pop {r3,r4}
|
||||
mov r8, r3
|
||||
@ -5484,8 +5484,8 @@ _08164F52:
|
||||
.pool
|
||||
thumb_func_end sub_8164ED8
|
||||
|
||||
thumb_func_start sub_8164F70
|
||||
sub_8164F70: @ 8164F70
|
||||
thumb_func_start CalcEmeraldBattleTowerChecksum
|
||||
CalcEmeraldBattleTowerChecksum: @ 8164F70
|
||||
push {r4,lr}
|
||||
adds r2, r0, 0
|
||||
adds r2, 0xE8
|
||||
@ -5504,7 +5504,7 @@ _08164F7E:
|
||||
pop {r4}
|
||||
pop {r0}
|
||||
bx r0
|
||||
thumb_func_end sub_8164F70
|
||||
thumb_func_end CalcEmeraldBattleTowerChecksum
|
||||
|
||||
thumb_func_start sub_8164F94
|
||||
sub_8164F94: @ 8164F94
|
||||
@ -6750,7 +6750,7 @@ _08165988:
|
||||
ldr r1, [sp, 0x10]
|
||||
bl CpuSet
|
||||
adds r0, r5, 0
|
||||
bl sub_8164F70
|
||||
bl CalcEmeraldBattleTowerChecksum
|
||||
movs r0, 0x1
|
||||
_081659BE:
|
||||
add sp, 0x14
|
||||
|
@ -795,7 +795,7 @@ sub_80B2A08: @ 80B2A08
|
||||
ldrh r0, [r0]
|
||||
cmp r0, 0x4
|
||||
bne _080B2A38
|
||||
bl sub_800A064
|
||||
bl Link_AnyPartnersPlayingRubyOrSapphire
|
||||
cmp r0, 0
|
||||
bne _080B2A4A
|
||||
bl sub_800AC34
|
||||
|
@ -2431,8 +2431,8 @@ sub_80FAFF8: @ 80FAFF8
|
||||
.pool
|
||||
thumb_func_end sub_80FAFF8
|
||||
|
||||
thumb_func_start sub_80FB00C
|
||||
sub_80FB00C: @ 80FB00C
|
||||
thumb_func_start CreateRecordMixingSprite
|
||||
CreateRecordMixingSprite: @ 80FB00C
|
||||
push {r4,r5,lr}
|
||||
ldr r0, =gUnknown_0858E864
|
||||
bl LoadSpritePalette
|
||||
@ -2478,10 +2478,10 @@ _080FB06E:
|
||||
pop {r4,r5}
|
||||
pop {r1}
|
||||
bx r1
|
||||
thumb_func_end sub_80FB00C
|
||||
thumb_func_end CreateRecordMixingSprite
|
||||
|
||||
thumb_func_start sub_80FB074
|
||||
sub_80FB074: @ 80FB074
|
||||
thumb_func_start DestroyRecordMixingSprite
|
||||
DestroyRecordMixingSprite: @ 80FB074
|
||||
push {r4-r7,lr}
|
||||
ldr r4, =gSprites
|
||||
adds r7, r4, 0
|
||||
@ -2509,6 +2509,6 @@ _080FB098:
|
||||
pop {r0}
|
||||
bx r0
|
||||
.pool
|
||||
thumb_func_end sub_80FB074
|
||||
thumb_func_end DestroyRecordMixingSprite
|
||||
|
||||
.align 2, 0 @ Don't pad with nop.
|
||||
|
3711
asm/record_mixing.s
3711
asm/record_mixing.s
File diff suppressed because it is too large
Load Diff
@ -1,37 +0,0 @@
|
||||
.include "asm/macros.inc"
|
||||
.include "constants/constants.inc"
|
||||
|
||||
.section .rodata
|
||||
.align 2, 0
|
||||
|
||||
gUnknown_0858CF8C:: @ 858CF8C
|
||||
.byte 1, 0
|
||||
|
||||
gUnknown_0858CF8E:: @ 858CF8E
|
||||
.byte 1, 2, 0
|
||||
.byte 2, 0, 1
|
||||
|
||||
gUnknown_0858CF94:: @ 858CF94
|
||||
.byte 1, 0, 3
|
||||
.byte 2, 3, 0
|
||||
.byte 1, 2, 2
|
||||
.byte 0, 3, 1
|
||||
.byte 1, 3, 0
|
||||
.byte 2, 2, 3
|
||||
.byte 0, 1, 3
|
||||
.byte 2, 0, 1
|
||||
.byte 1, 2, 3
|
||||
.byte 0, 2, 3
|
||||
.byte 1, 0, 3
|
||||
.byte 2, 1, 0
|
||||
|
||||
gUnknown_0858CFB8:: @ 858CFB8
|
||||
.byte 0, 1
|
||||
.byte 1, 2
|
||||
.byte 2, 0
|
||||
|
||||
gUnknown_0858CFBE:: @ 858CFBE
|
||||
.byte 0, 1, 2, 3
|
||||
.byte 0, 2, 1, 3
|
||||
.byte 0, 3, 2, 1
|
||||
.byte 0, 0
|
@ -1,6 +1,31 @@
|
||||
#ifndef GUARD_BATTLE_TOWER_H
|
||||
#define GUARD_BATTLE_TOWER_H
|
||||
|
||||
struct RSBattleTowerRecord
|
||||
{
|
||||
/*0x00*/ u8 battleTowerLevelType; // 0 = level 50, 1 = level 100
|
||||
/*0x01*/ u8 trainerClass;
|
||||
/*0x02*/ u16 winStreak;
|
||||
/*0x04*/ u8 name[8];
|
||||
/*0x0C*/ u8 trainerId[4];
|
||||
/*0x10*/ struct {
|
||||
u16 easyChat[6];
|
||||
} greeting;
|
||||
/*0x1C*/ struct UnknownPokemonStruct party[3];
|
||||
/*0xA0*/ u32 checksum;
|
||||
/*0xA4*/ u16 unk_11c8;
|
||||
};
|
||||
|
||||
union BattleTowerRecord
|
||||
{
|
||||
struct RSBattleTowerRecord ruby_sapphire;
|
||||
struct EmeraldBattleTowerRecord emerald;
|
||||
};
|
||||
|
||||
u16 sub_8164FCC(u8, u8);
|
||||
void sub_81659DC(struct RSBattleTowerRecord *a0, struct RSBattleTowerRecord *a1);
|
||||
bool32 sub_816587C(union BattleTowerRecord *, union BattleTowerRecord *);
|
||||
void CalcEmeraldBattleTowerChecksum(struct EmeraldBattleTowerRecord *);
|
||||
void sub_81628A0(union BattleTowerRecord *);
|
||||
|
||||
#endif //GUARD_BATTLE_TOWER_H
|
||||
|
13
include/cable_club.h
Normal file
13
include/cable_club.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef GUARD_CABLE_CLUB_H
|
||||
#define GUARD_CABLE_CLUB_H
|
||||
|
||||
// Exported type declarations
|
||||
|
||||
// Exported RAM declarations
|
||||
|
||||
// Exported ROM declarations
|
||||
|
||||
void sub_80B37D4(TaskFunc taskFunc);
|
||||
u8 sub_80B3050(void);
|
||||
|
||||
#endif //GUARD_CABLE_CLUB_H
|
@ -9,6 +9,7 @@
|
||||
void pal_fill_black(void);
|
||||
bool8 IsWeatherNotFadingIn(void);
|
||||
void sub_80AF168(void);
|
||||
void sub_80AF2B4(u8 taskId);
|
||||
void UpdateWeatherPerDay(u16 days);
|
||||
void sub_80AC3D0(void);
|
||||
void sub_80AC3E4(void);
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
void sub_80FA5E4(s16 id, s16 x, s16 y);
|
||||
void sub_80FA794(s16 x, s16 y);
|
||||
void CreateRecordMixingSprite(void);
|
||||
void DestroyRecordMixingSprite(void);
|
||||
void overworld_poison_effect(void);
|
||||
bool8 sub_80FADE4(u16, u8);
|
||||
|
||||
|
137
include/global.h
137
include/global.h
@ -103,6 +103,8 @@ enum LanguageId
|
||||
#define VARS_COUNT 256
|
||||
#define MAIL_COUNT 16
|
||||
#define SECRET_BASES_COUNT 20
|
||||
#define TV_SHOWS_COUNT 25
|
||||
#define POKE_NEWS_COUNT 16
|
||||
#define PC_ITEMS_COUNT 50
|
||||
#define BAG_ITEMS_COUNT 30
|
||||
#define BAG_KEYITEMS_COUNT 30
|
||||
@ -256,6 +258,56 @@ struct UnknownSaveBlock2Struct
|
||||
u8 field_EB;
|
||||
}; // sizeof = 0xEC
|
||||
|
||||
struct UnkRecordMixingStruct
|
||||
{
|
||||
u8 field_0[0x34];
|
||||
u8 playerId[4];
|
||||
u8 field_38[10];
|
||||
};
|
||||
|
||||
struct UnknownPokemonStruct
|
||||
{
|
||||
u16 species;
|
||||
u16 heldItem;
|
||||
u16 moves[4];
|
||||
u8 level;
|
||||
u8 ppBonuses;
|
||||
u8 hpEV;
|
||||
u8 attackEV;
|
||||
u8 defenseEV;
|
||||
u8 speedEV;
|
||||
u8 spAttackEV;
|
||||
u8 spDefenseEV;
|
||||
u32 otId;
|
||||
u32 hpIV:5;
|
||||
u32 attackIV:5;
|
||||
u32 defenseIV:5;
|
||||
u32 speedIV:5;
|
||||
u32 spAttackIV:5;
|
||||
u32 spDefenseIV:5;
|
||||
u32 gap:1;
|
||||
u32 altAbility:1;
|
||||
u32 personality;
|
||||
u8 nickname[POKEMON_NAME_LENGTH + 1];
|
||||
u8 friendship;
|
||||
};
|
||||
|
||||
struct EmeraldBattleTowerRecord
|
||||
{
|
||||
/*0x00*/ u8 battleTowerLevelType; // 0 = level 50, 1 = level 100
|
||||
/*0x01*/ u8 trainerClass;
|
||||
/*0x02*/ u16 winStreak;
|
||||
/*0x04*/ u8 name[8];
|
||||
/*0x0C*/ u8 trainerId[4];
|
||||
/*0x10*/ struct {
|
||||
u16 easyChat[6];
|
||||
} greeting;
|
||||
/*0x1C*/ u8 filler_1c[0x18];
|
||||
/*0x34*/ struct UnknownPokemonStruct party[4];
|
||||
/*0xE4*/ u8 language;
|
||||
/*0xE8*/ u32 checksum;
|
||||
};
|
||||
|
||||
struct SaveBlock2
|
||||
{
|
||||
/*0x00*/ u8 playerName[PLAYER_NAME_LENGTH];
|
||||
@ -281,7 +333,12 @@ struct SaveBlock2
|
||||
/*0xAC*/ u32 encryptionKey;
|
||||
|
||||
// TODO: fix and verify labels
|
||||
/*0xB0*/ u8 field_B0[316];
|
||||
/*0xB0*/ u8 field_B0;
|
||||
/*0xB1*/ u8 field_B1;
|
||||
/*0xB2*/ u8 field_B2_0:3;
|
||||
/*0xB2*/ u8 field_B2_1:2;
|
||||
/*0xB3*/ u8 field_B3[0x29];
|
||||
/*0xDC*/ struct UnkRecordMixingStruct field_DC[4];
|
||||
/*0x1EC*/ struct BerryCrush berryCrush;
|
||||
/*0x1FC*/ struct PokemonJumpResults pokeJump;
|
||||
/*0x20C*/ struct BerryPickingResults berryPick;
|
||||
@ -290,7 +347,7 @@ struct SaveBlock2
|
||||
|
||||
// All below could be a one giant struct
|
||||
|
||||
/*0x64C*/ u8 field_64C[236];
|
||||
/*0x64C*/ struct EmeraldBattleTowerRecord battleTower;
|
||||
/*0x738*/ struct UnknownSaveBlock2Struct field_738[5]; // No idea here, it's probably wrong, no clue.
|
||||
/*0xBD4*/ u16 field_BD4;
|
||||
/*0xBD6*/ u16 field_BD6;
|
||||
@ -307,22 +364,64 @@ struct SaveBlock2
|
||||
/*0xCA9*/ u8 field_CA9_f : 1; // 0x80
|
||||
/*0xCAA*/ u16 field_CAA[4];
|
||||
/*0xCB2*/ u16 battlePyramidWildHeaderId;
|
||||
/*0xCB4*/ u16 field_CB4[41];
|
||||
/*0xCB4*/ u16 field_CB4[30];
|
||||
/*0xCF0*/ u16 field_CF0[2];
|
||||
/*0xCF4*/ u16 field_CF4[2];
|
||||
/*0xCF8*/ u16 field_CF8[2];
|
||||
/*0xCFC*/ u16 field_CFC[5];
|
||||
/*0xD06*/ u8 field_D06;
|
||||
/*0xD07*/ u8 field_D07;
|
||||
/*0xD08*/ u8 filler_D08[0x112];
|
||||
/*0xD08*/ u8 filler_D08;
|
||||
/*0xD09*/ u8 filler_D09;
|
||||
/*0xD0A*/ u8 filler_D0A;
|
||||
/*0xD0B*/ u8 filler_D0B;
|
||||
/*0xD0C*/ u8 filler_D0C;
|
||||
/*0xD0D*/ u8 filler_D0D;
|
||||
/*0xD0E*/ u8 filler_D0E;
|
||||
/*0xD0F*/ u8 filler_D0F;
|
||||
/*0xD10*/ u8 filler_D10;
|
||||
/*0xD11*/ u8 filler_D11;
|
||||
/*0xD12*/ u8 filler_D12;
|
||||
/*0xD13*/ u8 filler_D13;
|
||||
/*0xD14*/ u16 field_D14[2];
|
||||
/*0xD18*/ u8 field_D18[0xB8];
|
||||
/*0xDD0*/ u16 field_DD0[2];
|
||||
/*0xDD4*/ u16 field_DD4[2];
|
||||
/*0xDD8*/ u16 field_DD8;
|
||||
/*0xDDA*/ u16 field_DDA;
|
||||
/*0xDDC*/ u16 field_DDC;
|
||||
/*0xDDE*/ u16 field_DDE[2];
|
||||
/*0xDE2*/ u16 field_DE2;
|
||||
/*0xDE4*/ u16 field_DE4;
|
||||
/*0xDE6*/ u16 field_DE6;
|
||||
/*0xDE8*/ u16 field_DE8;
|
||||
/*0xDEA*/ u16 field_DEA[2];
|
||||
/*0xDEE*/ u16 field_DEE;
|
||||
/*0xDF0*/ u16 field_DF0;
|
||||
/*0xDF2*/ u16 field_DF2;
|
||||
/*0xDF4*/ u16 field_DF4;
|
||||
/*0xDF6*/ u16 field_DF6;
|
||||
/*0xDF8*/ u16 field_DF8;
|
||||
/*0xDFA*/ u16 field_DFA;
|
||||
/*0xDFC*/ u16 field_DFC;
|
||||
/*0xDFE*/ u16 field_DFE;
|
||||
/*0xE00*/ u16 field_E00;
|
||||
/*0xE02*/ u16 field_E02;
|
||||
/*0xE04*/ u16 field_E04;
|
||||
/*0xE06*/ u16 field_E06;
|
||||
/*0xE08*/ u16 field_E08[9];
|
||||
/*0xE1A*/ u16 battlePyramidFloor; // possibly?
|
||||
/*0xE1C*/ u8 field_E1C[16];
|
||||
/*0xE1C*/ u16 field_E1C;
|
||||
/*0xE1E*/ u16 field_E1E[7];
|
||||
/*0xE2C*/ struct PyramidBag pyramidBag;
|
||||
/*0x???*/ u8 field_unkown[6];
|
||||
/*0xE6E*/ u16 battleTentWinStreak;
|
||||
/*0xE70*/ u8 field_E70[72];
|
||||
/*0xEB8*/ u16 frontierBattlePoints;
|
||||
/*0xEBA*/ u8 field_EBA[39];
|
||||
/*0xEE1*/ u8 field_EE1;
|
||||
/*0xEE2*/ u8 field_EE2[7];
|
||||
/*0xEE9*/ u8 field_EE9;
|
||||
/*0xEEA*/ u8 field_EEA[66];
|
||||
/*0xEE1*/ u8 field_EE1[2][PLAYER_NAME_LENGTH];
|
||||
/*0xEF1*/ u8 field_EF1[2][4];
|
||||
/*0xEF9*/ u8 field_EF9[51];
|
||||
// sizeof=0xF2C
|
||||
};
|
||||
|
||||
@ -558,9 +657,9 @@ struct ContestWinner
|
||||
u8 contestRank;
|
||||
};
|
||||
|
||||
struct DaycareMiscMon
|
||||
struct DayCareMail
|
||||
{
|
||||
struct MailStruct mail;
|
||||
struct MailStruct message;
|
||||
u8 OT_name[OT_NAME_LENGTH + 1];
|
||||
u8 monName[POKEMON_NAME_LENGTH + 1];
|
||||
u8 gameLanguage:4;
|
||||
@ -570,7 +669,7 @@ struct DaycareMiscMon
|
||||
struct DaycareMon
|
||||
{
|
||||
struct BoxPokemon mon;
|
||||
struct DaycareMiscMon misc;
|
||||
struct DayCareMail mail;
|
||||
u32 steps;
|
||||
};
|
||||
|
||||
@ -581,12 +680,6 @@ struct DayCare
|
||||
u8 stepCounter;
|
||||
};
|
||||
|
||||
struct DayCareMail
|
||||
{
|
||||
/*0x00*/ struct MailStruct message;
|
||||
/*0x24*/ u8 names[19];
|
||||
};
|
||||
|
||||
struct RecordMixingDayCareMail
|
||||
{
|
||||
struct DayCareMail mail[DAYCARE_MON_COUNT];
|
||||
@ -642,12 +735,13 @@ struct LilycoveLadyContest
|
||||
/*0x00e*/ u8 language;
|
||||
};
|
||||
|
||||
typedef union // TODO
|
||||
typedef union
|
||||
{
|
||||
struct LilycoveLadyQuiz quiz;
|
||||
struct LilycoveLadyFavour favour;
|
||||
struct LilycoveLadyContest contest;
|
||||
u8 id;
|
||||
u8 pad[0x40];
|
||||
} LilycoveLady;
|
||||
|
||||
struct WaldaPhrase
|
||||
@ -714,8 +808,8 @@ struct SaveBlock1
|
||||
/*0x????*/ u8 decorDoll[40];
|
||||
/*0x????*/ u8 decorCushion[10];
|
||||
/*0x27CA*/ u8 padding_27CA[2];
|
||||
/*0x27CC*/ TVShow tvShows[25];
|
||||
/*0x2B50*/ PokeNews pokeNews[16];
|
||||
/*0x27CC*/ TVShow tvShows[TV_SHOWS_COUNT];
|
||||
/*0x2B50*/ PokeNews pokeNews[POKE_NEWS_COUNT];
|
||||
/*0x2B90*/ u16 outbreakPokemonSpecies;
|
||||
/*0x2B92*/ u8 outbreakLocationMapNum;
|
||||
/*0x2B93*/ u8 outbreakLocationMapGroup;
|
||||
@ -747,7 +841,6 @@ struct SaveBlock1
|
||||
/*0x3B14*/ struct RecordMixingGift recordMixingGift;
|
||||
/*0x3B24*/ u8 seen2[52];
|
||||
/*0x3B58*/ LilycoveLady lilycoveLady;
|
||||
/*0x3B88*/ u8 filler_3B88[0x10];
|
||||
/*0x3B98*/ struct UnkSaveSubstruct_3b98 unk_3B98[20];
|
||||
/*0x3C88*/ u8 filler_3C88[0xE8];
|
||||
/*0x3D70*/ struct WaldaPhrase waldaPhrase;
|
||||
|
@ -6,7 +6,7 @@ void SetLilycoveLady(void);
|
||||
void sub_818DA78(void);
|
||||
void sub_818DEF4(void);
|
||||
void sub_818E564(void);
|
||||
void sub_818E570(const struct LilycoveLadyQuiz *quiz);
|
||||
void sub_818E570(const LilycoveLady *lilycoveLady);
|
||||
bool8 GivePokeblockToContestLady(struct Pokeblock *pokeblock);
|
||||
void sub_818E7E0(u8 *dest1, u8 *dest2);
|
||||
void sub_818E81C(u8 *dest);
|
||||
|
@ -293,4 +293,13 @@ extern u32 gFiller_03004138;
|
||||
extern u32 gFiller_0300413C;
|
||||
extern u32 gFiller_03003080;
|
||||
|
||||
bool32 Link_AnyPartnersPlayingRubyOrSapphire(void);
|
||||
bool32 sub_800A03C(void);
|
||||
void sub_8009628(u8);
|
||||
u8 sub_800AA48(void);
|
||||
void sub_8009FAC(void);
|
||||
bool8 sub_800A4D8(u8 a0);
|
||||
u8 sub_800A9D8(void);
|
||||
u8 sub_800A0C8(s32, s32);
|
||||
|
||||
#endif // GUARD_LINK_H
|
||||
|
@ -231,5 +231,6 @@ struct UnkLinkRfuStruct_02022B14 *sub_800F7DC(void);
|
||||
void sub_8011068(u8 a0);
|
||||
void sub_8011170(u32 a0);
|
||||
void sub_8011A64(u8 a0, u16 a1);
|
||||
u8 sub_801048C(bool32 a0);
|
||||
|
||||
#endif //GUARD_LINK_RFU_H
|
||||
|
@ -11,9 +11,16 @@ enum MauvilleOldManType
|
||||
MAUVILLE_MAN_GIDDY
|
||||
};
|
||||
|
||||
extern struct BardSong gBardSong;
|
||||
|
||||
void SetMauvilleOldMan(void);
|
||||
u8 GetCurrentMauvilleOldMan(void);
|
||||
extern struct BardSong gBardSong;
|
||||
void ScrSpecial_SetMauvilleOldManMapObjGfx(void);
|
||||
u8 sub_81201C8(void);
|
||||
void sub_8120B70(OldMan *dest);
|
||||
void sub_8120670(void);
|
||||
void SanitizeReceivedRubyOldMan(union OldMan * oldMan, u32 r1, u32 r6);
|
||||
void SanitizeReceivedEmeraldOldMan(union OldMan * oldMan, u32 unused, u32 a2);
|
||||
void ResetMauvilleOldManFlag(void);
|
||||
|
||||
#endif // GUARD_MAUVILLE_OLD_MAN_H
|
||||
|
@ -240,33 +240,6 @@ struct PokemonStorage
|
||||
/*0x83C2*/ u8 boxWallpapers[14];
|
||||
};
|
||||
|
||||
struct UnknownPokemonStruct
|
||||
{
|
||||
u16 species;
|
||||
u16 heldItem;
|
||||
u16 moves[4];
|
||||
u8 level;
|
||||
u8 ppBonuses;
|
||||
u8 hpEV;
|
||||
u8 attackEV;
|
||||
u8 defenseEV;
|
||||
u8 speedEV;
|
||||
u8 spAttackEV;
|
||||
u8 spDefenseEV;
|
||||
u32 otId;
|
||||
u32 hpIV:5;
|
||||
u32 attackIV:5;
|
||||
u32 defenseIV:5;
|
||||
u32 speedIV:5;
|
||||
u32 spAttackIV:5;
|
||||
u32 spDefenseIV:5;
|
||||
u32 gap:1;
|
||||
u32 altAbility:1;
|
||||
u32 personality;
|
||||
u8 nickname[POKEMON_NAME_LENGTH + 1];
|
||||
u8 friendship;
|
||||
};
|
||||
|
||||
struct UnknownPokemonSubStruct2
|
||||
{
|
||||
u16 species;
|
||||
|
35
include/record_mixing.h
Normal file
35
include/record_mixing.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef GUARD_RECORD_MIXING_H
|
||||
#define GUARD_RECORD_MIXING_H
|
||||
|
||||
// Exported type declarations
|
||||
struct UnkRecordMixingStruct2a
|
||||
{
|
||||
u8 playerId[4];
|
||||
u16 field_4;
|
||||
u8 playerName[PLAYER_NAME_LENGTH];
|
||||
u8 language;
|
||||
};
|
||||
|
||||
struct UnkRecordMixingStruct2b
|
||||
{
|
||||
u8 playerId1[4];
|
||||
u8 playerId2[4];
|
||||
u16 field_8;
|
||||
u8 playerName1[PLAYER_NAME_LENGTH];
|
||||
u8 playerName2[PLAYER_NAME_LENGTH];
|
||||
u8 language;
|
||||
};
|
||||
|
||||
struct UnkRecordMixingStruct2
|
||||
{
|
||||
struct UnkRecordMixingStruct2a field_0[9][2];
|
||||
struct UnkRecordMixingStruct2b field_120[2];
|
||||
};
|
||||
|
||||
// Exported RAM declarations
|
||||
|
||||
// Exported ROM declarations
|
||||
void sub_80E6BE8(void);
|
||||
void sub_80E8260(struct UnkRecordMixingStruct2 *arg0);
|
||||
|
||||
#endif //GUARD_RECORD_MIXING_H
|
@ -90,6 +90,9 @@ u8 sub_8153430(void);
|
||||
bool8 sub_8153474(void);
|
||||
u8 Save_LoadGameData(u8 a1);
|
||||
u16 sub_815355C(void);
|
||||
u8 sub_81534D0(u8);
|
||||
u8 sub_8153430(void);
|
||||
bool8 sub_8153474(void);
|
||||
u32 TryCopySpecialSaveSection(u8 sector, u8* dst);
|
||||
u32 sub_8153634(u8 sector, u8* src);
|
||||
void sub_8153688(u8 taskId);
|
||||
|
@ -8,6 +8,8 @@
|
||||
// Exported ROM declarations
|
||||
void sub_80E9578(void);
|
||||
void sub_80E980C(void);
|
||||
void sub_80EB18C(struct SecretBaseRecord *dest);
|
||||
void sub_80E9914(void);
|
||||
u8 *GetSecretBaseMapName(u8 *dest);
|
||||
const u8 *GetSecretBaseTrainerLoseText(void);
|
||||
void sub_80E8EE0(struct MapEvents const *events);
|
||||
|
@ -110,6 +110,8 @@ extern const u8 gText_MoveCloserToLinkPartner[];
|
||||
extern const u8 gText_CommErrorCheckConnections[];
|
||||
extern const u8 gText_ABtnTitleScreen[];
|
||||
extern const u8 gText_ABtnRegistrationCounter[];
|
||||
extern const u8 gText_MixingRecords[];
|
||||
extern const u8 gText_RecordMixingComplete[];
|
||||
extern const u8 gText_EmptyString2[];
|
||||
extern const u8 gText_Confirm3[];
|
||||
extern const u8 gText_Cancel4[];
|
||||
|
@ -16,7 +16,7 @@ void sub_80EED10(void);
|
||||
void sub_80EED34(void);
|
||||
void sub_80EED60(u16 delta);
|
||||
void sub_80F01B8(void);
|
||||
void sub_80F01E8(void *src, u32 size, u8 masterIdx);
|
||||
void ReceiveTvShowsData(void *src, u32 size, u8 masterIdx);
|
||||
void sub_80EE4DC(struct Pokemon *pokemon, u8 ribbonMonDataIdx);
|
||||
u32 GetPlayerIDAsU32(void);
|
||||
bool8 GetPriceReduction(u8 newsKind);
|
||||
@ -30,7 +30,7 @@ void sub_80EEA70(void);
|
||||
void sub_80EDB44(void);
|
||||
void sub_80EDC60(const u16 *words);
|
||||
void sub_80EDA80(void);
|
||||
void sub_80F0C7C(void *src, u32 size, u8 masterIdx);
|
||||
void ReceivePokeNewsData(void *src, u32 size, u8 masterIdx);
|
||||
void sub_80F0BB8(void);
|
||||
void sub_80ED950(bool8 flag);
|
||||
void sub_80EEC80(void);
|
||||
@ -39,11 +39,13 @@ void sub_80EECC8(void);
|
||||
void sub_80EECEC(void);
|
||||
void sub_80F1208(TVShow *shows);
|
||||
void sub_80EE44C(u8 nMonsCaught, u8 nPkblkUsed);
|
||||
void sub_80F14F8(TVShow *shows);
|
||||
size_t sub_80EF370(int value);
|
||||
bool8 Put3CheersForPokeblocksOnTheAir(const u8 *partnersName, u8 flavor, u8 unused, u8 sheen, u8 language);
|
||||
void SetPokemonAnglerSpecies(u16 species);
|
||||
void UpdateTVShowsPerDay(u16 days);
|
||||
void PutPokemonTodayCaughtOnAir(void);
|
||||
void TV_PutSecretBaseVisitOnTheAir(void);
|
||||
bool8 Put3CheersForPokeblocksOnTheAir(const u8 *partnersName, u8 flavor, u8 unused, u8 sheen, u8 language);
|
||||
void PutBattleUpdateOnTheAir(u8 opponentLinkPlayerId, u16 move, u16 speciesPlayer, u16 speciesOpponent);
|
||||
void UpdateTVScreensOnMap(int, int);
|
||||
|
||||
|
@ -144,7 +144,7 @@ SECTIONS {
|
||||
src/naming_screen.o(.text);
|
||||
src/money.o(.text);
|
||||
asm/contest_effect.o(.text);
|
||||
asm/record_mixing.o(.text);
|
||||
src/record_mixing.o(.text);
|
||||
src/secret_base.o(.text);
|
||||
src/tv.o(.text);
|
||||
asm/contest_link_80F57C4.o(.text);
|
||||
@ -439,7 +439,7 @@ SECTIONS {
|
||||
src/naming_screen.o(.rodata);
|
||||
src/money.o(.rodata);
|
||||
data/contest_effect.o(.rodata);
|
||||
data/record_mixing.o(.rodata);
|
||||
src/record_mixing.o(.rodata);
|
||||
src/secret_base.o(.rodata);
|
||||
src/tv.o(.rodata);
|
||||
data/contest_link_80F57C4.o(.rodata);
|
||||
|
@ -151,15 +151,14 @@ extern const u8 gText_Space[];
|
||||
extern const u8 gText_BlenderMaxSpeedRecord[];
|
||||
extern const u8 gText_234Players[];
|
||||
|
||||
extern void sub_81978B0(u16);
|
||||
extern void sub_800A418(void);
|
||||
extern u8 sub_800A9D8(void);
|
||||
extern bool8 sub_800A4D8(u8);
|
||||
extern void sub_809882C(u8, u16, u8);
|
||||
extern void copy_textbox_border_tile_patterns_to_vram(u8, u16, u8);
|
||||
extern void sub_81AABF0(void (*callback)(void));
|
||||
extern void sub_800B4C0(void);
|
||||
extern void ClearLinkCallback(void);
|
||||
extern void sub_8009F8C(void);
|
||||
extern void sub_8153430(void);
|
||||
extern bool8 sub_8153474(void);
|
||||
extern void sub_80EECEC(void);
|
||||
|
@ -47,7 +47,7 @@ extern void sub_81B9328(void);
|
||||
extern void CB2_ReturnToField(void);
|
||||
|
||||
// this file's functions
|
||||
static void ClearDaycareMonMisc(struct DaycareMiscMon *misc);
|
||||
static void ClearDaycareMonMail(struct DayCareMail *mail);
|
||||
static void SetInitialEggData(struct Pokemon *mon, u16 species, struct DayCare *daycare);
|
||||
static u8 GetDaycareCompatibilityScore(struct DayCare *daycare);
|
||||
static void DaycarePrintMonInfo(u8 windowId, s32 daycareSlotId, u8 y);
|
||||
@ -179,13 +179,13 @@ static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycar
|
||||
{
|
||||
u8 mailId;
|
||||
|
||||
StringCopy(daycareMon->misc.OT_name, gSaveBlock2Ptr->playerName);
|
||||
GetMonNick(mon, daycareMon->misc.monName);
|
||||
StripExtCtrlCodes(daycareMon->misc.monName);
|
||||
daycareMon->misc.gameLanguage = LANGUAGE_ENGLISH;
|
||||
daycareMon->misc.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE);
|
||||
StringCopy(daycareMon->mail.OT_name, gSaveBlock2Ptr->playerName);
|
||||
GetMonNick(mon, daycareMon->mail.monName);
|
||||
StripExtCtrlCodes(daycareMon->mail.monName);
|
||||
daycareMon->mail.gameLanguage = LANGUAGE_ENGLISH;
|
||||
daycareMon->mail.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE);
|
||||
mailId = GetMonData(mon, MON_DATA_MAIL);
|
||||
daycareMon->misc.mail = gSaveBlock1Ptr->mail[mailId];
|
||||
daycareMon->mail.message = gSaveBlock1Ptr->mail[mailId];
|
||||
TakeMailFromMon(mon);
|
||||
}
|
||||
|
||||
@ -219,10 +219,10 @@ static void ShiftDaycareSlots(struct DayCare *daycare)
|
||||
daycare->mons[0].mon = daycare->mons[1].mon;
|
||||
ZeroBoxMonData(&daycare->mons[1].mon);
|
||||
|
||||
daycare->mons[0].misc = daycare->mons[1].misc;
|
||||
daycare->mons[0].mail = daycare->mons[1].mail;
|
||||
daycare->mons[0].steps = daycare->mons[1].steps;
|
||||
daycare->mons[1].steps = 0;
|
||||
ClearDaycareMonMisc(&daycare->mons[1].misc);
|
||||
ClearDaycareMonMail(&daycare->mons[1].mail);
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,10 +277,10 @@ static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon)
|
||||
}
|
||||
|
||||
gPlayerParty[PARTY_SIZE - 1] = pokemon;
|
||||
if (daycareMon->misc.mail.itemId)
|
||||
if (daycareMon->mail.message.itemId)
|
||||
{
|
||||
GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &daycareMon->misc.mail);
|
||||
ClearDaycareMonMisc(&daycareMon->misc);
|
||||
GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &daycareMon->mail.message);
|
||||
ClearDaycareMonMail(&daycareMon->mail);
|
||||
}
|
||||
|
||||
ZeroBoxMonData(&daycareMon->mon);
|
||||
@ -364,23 +364,23 @@ u8 GetNumLevelsGainedFromDaycare(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ClearDaycareMonMisc(struct DaycareMiscMon *misc)
|
||||
static void ClearDaycareMonMail(struct DayCareMail *mail)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < OT_NAME_LENGTH + 1; i++)
|
||||
misc->OT_name[i] = 0;
|
||||
mail->OT_name[i] = 0;
|
||||
for (i = 0; i < POKEMON_NAME_LENGTH + 1; i++)
|
||||
misc->monName[i] = 0;
|
||||
mail->monName[i] = 0;
|
||||
|
||||
ClearMailStruct(&misc->mail);
|
||||
ClearMailStruct(&mail->message);
|
||||
}
|
||||
|
||||
static void ClearDaycareMon(struct DaycareMon *daycareMon)
|
||||
{
|
||||
ZeroBoxMonData(&daycareMon->mon);
|
||||
daycareMon->steps = 0;
|
||||
ClearDaycareMonMisc(&daycareMon->misc);
|
||||
ClearDaycareMonMail(&daycareMon->mail);
|
||||
}
|
||||
|
||||
static void ClearAllDaycareData(struct DayCare *daycare)
|
||||
|
@ -158,7 +158,7 @@ static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c)
|
||||
}
|
||||
}
|
||||
|
||||
void sub_812287C(void *a, u32 b, u8 unused)
|
||||
void ReceiveEasyChatPairsData(void *a, u32 b, u8 unused)
|
||||
{
|
||||
u16 i, j, r3, players;
|
||||
struct EasyChatPair *buffer1, *buffer2, *src, *dst, *foo_of_buffer2;
|
||||
|
@ -390,13 +390,13 @@ static bool8 sub_807158C(struct DayCare *daycare, u8 daycareId)
|
||||
struct DaycareMon *daycareMon = &daycare->mons[daycareId];
|
||||
|
||||
GetBoxMonNick(&daycareMon->mon, nick);
|
||||
if (daycareMon->misc.mail.itemId != 0
|
||||
&& (StringCompareWithoutExtCtrlCodes(nick, daycareMon->misc.monName) != 0
|
||||
|| StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->misc.OT_name) != 0))
|
||||
if (daycareMon->mail.message.itemId != 0
|
||||
&& (StringCompareWithoutExtCtrlCodes(nick, daycareMon->mail.monName) != 0
|
||||
|| StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->mail.OT_name) != 0))
|
||||
{
|
||||
StringCopy(gStringVar1, nick);
|
||||
TVShowConvertInternationalString(gStringVar2, daycareMon->misc.OT_name, daycareMon->misc.gameLanguage);
|
||||
TVShowConvertInternationalString(gStringVar3, daycareMon->misc.monName, daycareMon->misc.monLanguage);
|
||||
TVShowConvertInternationalString(gStringVar2, daycareMon->mail.OT_name, daycareMon->mail.gameLanguage);
|
||||
TVShowConvertInternationalString(gStringVar3, daycareMon->mail.monName, daycareMon->mail.monLanguage);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -801,26 +801,26 @@ void sub_818E564(void)
|
||||
EnableBothScriptContexts();
|
||||
}
|
||||
|
||||
void sub_818E570(const struct LilycoveLadyQuiz *quiz)
|
||||
void sub_818E570(const LilycoveLady *lilycoveLady)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz;
|
||||
if (quiz->unk_02c < 16 && gUnknown_0203CD68->id == LILYCOVE_LADY_QUIZ)
|
||||
if (lilycoveLady->quiz.unk_02c < 16 && gUnknown_0203CD68->id == LILYCOVE_LADY_QUIZ)
|
||||
{
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
if (quiz->unk_02c != gUnknown_0203CD68->unk_02b)
|
||||
if (lilycoveLady->quiz.unk_02c != gUnknown_0203CD68->unk_02b)
|
||||
{
|
||||
break;
|
||||
}
|
||||
gUnknown_0203CD68->unk_02b = Random() % 16;
|
||||
}
|
||||
if (quiz->unk_02c == gUnknown_0203CD68->unk_02b)
|
||||
if (lilycoveLady->quiz.unk_02c == gUnknown_0203CD68->unk_02b)
|
||||
{
|
||||
gUnknown_0203CD68->unk_02b = (gUnknown_0203CD68->unk_02b + 1) % 16;
|
||||
}
|
||||
gUnknown_0203CD68->unk_02c = quiz->unk_02c;
|
||||
gUnknown_0203CD68->unk_02c = lilycoveLady->quiz.unk_02c;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -798,7 +798,7 @@ bool32 sub_800A040(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 sub_800A064(void)
|
||||
bool32 Link_AnyPartnersPlayingRubyOrSapphire(void)
|
||||
{
|
||||
if (sub_8009FF8(VERSION_RUBY, VERSION_SAPPHIRE) >= 0)
|
||||
{
|
||||
|
@ -387,7 +387,7 @@ static void ResetStorytellerFlag(void)
|
||||
Storyteller_ResetFlag();
|
||||
}
|
||||
|
||||
void ResetMauvilleOldManFlag(void) // ResetMauvilleOldManFlag
|
||||
void ResetMauvilleOldManFlag(void)
|
||||
{
|
||||
switch (GetCurrentMauvilleOldMan())
|
||||
{
|
||||
@ -793,11 +793,11 @@ void sub_8120C0C(union OldMan * oldMan, u32 r8, u32 r7, u32 r3)
|
||||
}
|
||||
}
|
||||
|
||||
void sub_8120CD0(union OldMan * oldMan, u32 unused, u32 a2)
|
||||
void SanitizeReceivedEmeraldOldMan(union OldMan * oldMan, u32 version, u32 language)
|
||||
{
|
||||
u8 sp00[8];
|
||||
s32 i;
|
||||
if (oldMan->common.id == MAUVILLE_MAN_STORYTELLER && a2 == LANGUAGE_JAPANESE)
|
||||
if (oldMan->common.id == MAUVILLE_MAN_STORYTELLER && language == LANGUAGE_JAPANESE)
|
||||
{
|
||||
struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
|
||||
|
||||
@ -816,9 +816,10 @@ void sub_8120CD0(union OldMan * oldMan, u32 unused, u32 a2)
|
||||
}
|
||||
}
|
||||
|
||||
void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
|
||||
void SanitizeReceivedRubyOldMan(union OldMan * oldMan, u32 version, u32 language)
|
||||
{
|
||||
u32 r2 = (r1 == LANGUAGE_JAPANESE || r1 == LANGUAGE_ENGLISH) ? 1 : 0;
|
||||
bool32 isRuby = (version == VERSION_SAPPHIRE || version == VERSION_RUBY);
|
||||
|
||||
switch (oldMan->common.id)
|
||||
{
|
||||
case MAUVILLE_MAN_TRADER:
|
||||
@ -826,7 +827,7 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
|
||||
struct MauvilleOldManTrader * trader = &oldMan->trader;
|
||||
s32 i;
|
||||
|
||||
if (r2)
|
||||
if (isRuby)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
@ -837,7 +838,7 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
|
||||
trader->language[i] = LANGUAGE_JAPANESE;
|
||||
}
|
||||
else
|
||||
trader->language[i] = r6;
|
||||
trader->language[i] = language;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -858,12 +859,12 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
|
||||
struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
|
||||
s32 i;
|
||||
|
||||
if (r2)
|
||||
if (isRuby)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (storyteller->gameStatIDs[i] != 0)
|
||||
storyteller->language[i] = r6;
|
||||
storyteller->language[i] = language;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -872,9 +873,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
|
||||
{
|
||||
struct MauvilleManBard * bard = &oldMan->bard;
|
||||
|
||||
if (r2)
|
||||
if (isRuby)
|
||||
{
|
||||
bard->language = r6;
|
||||
bard->language = language;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -882,9 +883,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
|
||||
{
|
||||
struct MauvilleManHipster * hipster = &oldMan->hipster;
|
||||
|
||||
if (r2)
|
||||
if (isRuby)
|
||||
{
|
||||
hipster->language = r6;
|
||||
hipster->language = language;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -892,9 +893,9 @@ void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
|
||||
{
|
||||
struct MauvilleManGiddy * giddy = &oldMan->giddy;
|
||||
|
||||
if (r2)
|
||||
if (isRuby)
|
||||
{
|
||||
giddy->language = r6;
|
||||
giddy->language = language;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -119,11 +119,10 @@ void ClearAllContestWinnerPics(void)
|
||||
void sub_8084400(void)
|
||||
{
|
||||
// probably clearing one struct for battle frontier
|
||||
CpuFill32(0, gSaveBlock2Ptr->field_64C, 2272);
|
||||
CpuFill32(0, &gSaveBlock2Ptr->battleTower, 2272);
|
||||
|
||||
// those look like strings
|
||||
gSaveBlock2Ptr->field_EE1 = 0xFF;
|
||||
gSaveBlock2Ptr->field_EE9 = 0xFF;
|
||||
gSaveBlock2Ptr->field_EE1[0][0] = EOS;
|
||||
gSaveBlock2Ptr->field_EE1[1][0] = EOS;
|
||||
}
|
||||
|
||||
void WarpToTruck(void)
|
||||
|
2286
src/record_mixing.c
2286
src/record_mixing.c
File diff suppressed because it is too large
Load Diff
@ -1673,7 +1673,7 @@ void sub_80EAEF4(struct SecretBaseRecordMixer *mixers)
|
||||
sub_80EABA4(&mixers[2], 0);
|
||||
}
|
||||
|
||||
void sub_80EAF80(void *records, size_t recordSize, u8 linkIdx)
|
||||
void ReceiveSecretBasesData(void *records, size_t recordSize, u8 linkIdx)
|
||||
{
|
||||
struct SecretBaseRecordMixer mixers[3];
|
||||
u16 i;
|
||||
|
4
src/tv.c
4
src/tv.c
@ -3606,7 +3606,7 @@ void sub_80F01B8(void)
|
||||
FlagSet(0x396);
|
||||
}
|
||||
|
||||
void sub_80F01E8(void *src, u32 size, u8 masterIdx)
|
||||
void ReceiveTvShowsData(void *src, u32 size, u8 masterIdx)
|
||||
{
|
||||
u8 i;
|
||||
u16 version;
|
||||
@ -4434,7 +4434,7 @@ static void sub_80F0C04(void)
|
||||
}
|
||||
}
|
||||
|
||||
void sub_80F0C7C(void *src, u32 size, u8 masterIdx)
|
||||
void ReceivePokeNewsData(void *src, u32 size, u8 masterIdx)
|
||||
{
|
||||
u8 i;
|
||||
PokeNews (*rmBuffer2)[4][16];
|
||||
|
@ -487,17 +487,7 @@ gUnknown_02039F90: @ 2039F90
|
||||
|
||||
.include "src/naming_screen.o"
|
||||
.include "src/money.o"
|
||||
|
||||
.align 2
|
||||
gUnknown_02039F9C: @ 2039F9C
|
||||
.space 0x78
|
||||
|
||||
gUnknown_0203A014: @ 203A014
|
||||
.space 0x4
|
||||
|
||||
gUnknown_0203A018: @ 203A018
|
||||
.space 0x4
|
||||
|
||||
.include "src/record_mixing.o"
|
||||
.include "src/secret_base.o"
|
||||
.include "src/tv.o"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user