mirror of
https://github.com/pret/pokeheartgold.git
synced 2024-11-30 08:30:54 +00:00
Data dump + file splitting
This commit is contained in:
parent
91fd721530
commit
32b2b012a4
@ -7,68 +7,4 @@
|
||||
.include "asm/macros.inc"
|
||||
.include "overlay_02.inc"
|
||||
.include "global.inc"
|
||||
|
||||
.text
|
||||
.public CelebiCutscene_SwirlEffect
|
||||
.public ov02_02252E80
|
||||
.public ov02_02252EA8
|
||||
|
||||
.rodata
|
||||
|
||||
.public ov02_02253C84
|
||||
ov02_02253C84: ; 0x02253C84
|
||||
.byte 0x01, 0x00
|
||||
|
||||
.public ov02_02253C86
|
||||
ov02_02253C86: ; 0x02253C86
|
||||
.byte 0x0D, 0x00
|
||||
|
||||
.public ov02_02253C88
|
||||
ov02_02253C88: ; 0x02253C88
|
||||
.byte 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00
|
||||
.byte 0x0F, 0x00, 0x55, 0x00, 0x01, 0x00, 0x09, 0x00, 0x5D, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00
|
||||
.byte 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00
|
||||
.byte 0x8E, 0x00, 0x01, 0x00, 0x18, 0x00, 0x8F, 0x00, 0x01, 0x00, 0x18, 0x00, 0x90, 0x00, 0x01, 0x00
|
||||
.byte 0x18, 0x00, 0x91, 0x00, 0x01, 0x00, 0x18, 0x00, 0x92, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1B, 0x00
|
||||
.byte 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
.public ov02_02253CD4
|
||||
ov02_02253CD4: ; 0x02253CD4
|
||||
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
.public ov02_02253CE0
|
||||
ov02_02253CE0: ; 0x02253CE0
|
||||
.byte 0x00, 0x00, 0xFF, 0xFF, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00
|
||||
|
||||
.public sCelebiCutsceneAnimationFiles
|
||||
sCelebiCutsceneAnimationFiles: ; 0x02253CEC
|
||||
.byte 0x4C, 0x00, 0x00, 0x00
|
||||
.byte 0x4E, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00
|
||||
|
||||
.public ov02_02253CF8
|
||||
ov02_02253CF8: ; 0x02253CF8
|
||||
.byte 0x56, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00
|
||||
.byte 0x4F, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00
|
||||
|
||||
.public ov02_02253D08
|
||||
ov02_02253D08: ; 0x02253D08
|
||||
.byte 0x58, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00
|
||||
.byte 0x60, 0x00, 0x00, 0x00
|
||||
|
||||
.public ov02_02253D14
|
||||
ov02_02253D14: ; 0x02253D14
|
||||
.byte 0x50, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00
|
||||
.byte 0x54, 0x00, 0x00, 0x00
|
||||
|
||||
.public ov02_02253D24
|
||||
ov02_02253D24: ; 0x02253D24
|
||||
.byte 0x64, 0x00, 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00
|
||||
.byte 0x59, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00
|
||||
.byte 0x5D, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00
|
||||
.byte 0x61, 0x00, 0x00, 0x00
|
||||
|
||||
.public ov02_02253D54
|
||||
ov02_02253D54: ; 0x02253D54
|
||||
.byte 0x2F, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42
|
||||
.byte 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52
|
||||
.byte 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5F, 0x60, 0x00
|
||||
|
@ -2,5 +2,6 @@
|
||||
#define POKEHEARTGOLD_OVERLAY_01_021F467C_H
|
||||
|
||||
u32 ov01_021F467C(u32 a0, u32 a1);
|
||||
void ov01_021F46DC(u32 *a0);
|
||||
|
||||
#endif // POKEHEARTGOLD_OVERLAY_01_021F467C_H
|
||||
|
12
include/overlay_2/event_cutscene.h
Normal file
12
include/overlay_2/event_cutscene.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef POKEHEARTGOLD_OVERLAY_02_EVENT_CUTSCENE_H
|
||||
#define POKEHEARTGOLD_OVERLAY_02_EVENT_CUTSCENE_H
|
||||
|
||||
#include "field_system.h"
|
||||
|
||||
BOOL ov02_02252334(FieldSystem *fieldSystem);
|
||||
void ov02_022523B4(TaskManager *taskMan);
|
||||
void FieldSystem_BeginCelebiTimeTravelCutsceneTask(FieldSystem *fieldSystem);
|
||||
void FieldSystem_BeginSinjohCutsceneTask(FieldSystem *fieldSystem);
|
||||
void FieldSystem_BeginSinjohGetEggCutsceneTask(FieldSystem *fieldSystem, u8 a1);
|
||||
|
||||
#endif
|
@ -1,114 +1,11 @@
|
||||
#ifndef POKEHEARTGOLD_OVERLAY_02_02251E74_H
|
||||
#define POKEHEARTGOLD_OVERLAY_02_02251E74_H
|
||||
|
||||
#include "field/overlay_01_021FB878.h"
|
||||
|
||||
#include "field_system.h"
|
||||
#include "gear_phone.h"
|
||||
|
||||
String *GetPhoneBookEntryName(GearPhoneRingManager *gearPhone, HeapID heapId);
|
||||
void ov02_02251EB8(GearPhoneRingManager *phoneRingManager, u8 a1, u8 a2, u8 a3, u8 a4, u8 a5);
|
||||
u8 ov02_02251EE8(GearPhoneRingManager *gearPhone, u8 *a1);
|
||||
BOOL ov02_02251F20(GearPhoneRingManager *gearPhone);
|
||||
u32 ov02_02251FDC(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId);
|
||||
u32 ov02_022521C0(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId);
|
||||
u8 ov02_02252218(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId);
|
||||
void ov02_022522AC(GearPhoneRingManager *gearPhone, BOOL a1);
|
||||
int GetRadioMusicPlayingSeq(void);
|
||||
BOOL ov02_02252334(FieldSystem *fieldSystem);
|
||||
void ov02_022523B4(TaskManager *taskMan);
|
||||
BOOL ov02_022523D0(TaskManager *taskMan);
|
||||
void FieldSystem_BeginCelebiTimeTravelCutsceneTask(FieldSystem *fieldSystem);
|
||||
void FieldSystem_BeginSinjohCutsceneTask(FieldSystem *fieldSystem);
|
||||
void FieldSystem_BeginSinjohGetEggCutsceneTask(FieldSystem *fieldSystem, u8 a1);
|
||||
BOOL ov02_02253134(SaveData *saveData);
|
||||
|
||||
// the following is as of yet not decompiled
|
||||
BOOL Task_CelebiTimeTravelCutscene(TaskManager *taskMan);
|
||||
|
||||
// the following functions are static
|
||||
typedef struct CelebiTimeTravelCutsceneTaskData {
|
||||
u16 unk0;
|
||||
u8 unk2;
|
||||
u8 isSwirlFinished;
|
||||
u32 unk4;
|
||||
FieldSystem *fieldSystem; // 0x8
|
||||
NNSFndAllocator alloc; // 0xC
|
||||
Field3dModel model; // 0x1C
|
||||
Field3DModelAnimation animations[3];
|
||||
Field3dObject object3d;
|
||||
s32 unkE0;
|
||||
u16 unkE4;
|
||||
u16 unkE6;
|
||||
u16 unkE8;
|
||||
u16 perspective;
|
||||
u16 unkEC;
|
||||
u16 unkEE;
|
||||
u8 unkF0;
|
||||
u8 unkF1;
|
||||
u8 unkF2;
|
||||
u8 unkF3;
|
||||
} CelebiTimeTravelCutsceneTaskData;
|
||||
|
||||
typedef struct UnkStruct_02253CE0 {
|
||||
u32 unk0;
|
||||
u32 unk4;
|
||||
u16 unk8;
|
||||
u16 unkA;
|
||||
} UnkStruct_02253CE0;
|
||||
|
||||
typedef struct SinjohCutsceneData {
|
||||
FieldSystem *fieldSystem;
|
||||
struct NNSFndAllocator alloc;
|
||||
Field3dModel model[2];
|
||||
Field3DModelAnimation animations[2][2];
|
||||
Field3dObject object84[2];
|
||||
Field3dModel model174;
|
||||
Field3DModelAnimation animation184[2];
|
||||
Field3dObject object1AC;
|
||||
u8 unk224;
|
||||
u8 unk225;
|
||||
u8 unk226;
|
||||
u8 unk227;
|
||||
} SinjohCutsceneData;
|
||||
|
||||
typedef struct SinjohGetEggCutsceneData {
|
||||
FieldSystem *fieldSystem;
|
||||
NNSFndAllocator alloc;
|
||||
Field3dModel model;
|
||||
Field3DModelAnimation animations[4];
|
||||
Field3dObject object;
|
||||
u8 unkEC;
|
||||
u8 unkED;
|
||||
u8 unkEE;
|
||||
u8 unkEF;
|
||||
} SinjohGetEggCutsceneData;
|
||||
|
||||
void CelebiCutscene_StartSwirlTask(CelebiTimeTravelCutsceneTaskData *data);
|
||||
BOOL ov02_022526EC(CelebiTimeTravelCutsceneTaskData *data);
|
||||
void Task_CelebiCutsceneSwirl(SysTask *task, void *data);
|
||||
void CelebiCutscene_InitSwirlData(CelebiTimeTravelCutsceneTaskData *a0, UnkStruct_02253CE0 *a1);
|
||||
BOOL CelebiCutscene_SwirlEffect(CelebiTimeTravelCutsceneTaskData *data);
|
||||
void Task_CelebiCutsceneSwirlEffect(SysTask *task, void *data);
|
||||
BOOL CelebiCutscene_IsSwirlFinished(CelebiTimeTravelCutsceneTaskData *data);
|
||||
void CelebiCutscene_LoadResources(CelebiTimeTravelCutsceneTaskData *data);
|
||||
void CelebiCutscene_UnloadResources(CelebiTimeTravelCutsceneTaskData *data);
|
||||
void CelebiCutsceneAnimations_FrameSet(Field3DModelAnimation *animations, u32 frame);
|
||||
BOOL CelebiCutsceneAnimations_FrameAdvanceAndCheck(Field3DModelAnimation *animations);
|
||||
BOOL Task_SinjohCutscene(TaskManager *taskMan);
|
||||
void SinjohCutscene_LoadResources(SinjohCutsceneData *data);
|
||||
void SinjohCutscene_FreeResources(SinjohCutsceneData *data);
|
||||
void ov02_02252E80(Field3DModelAnimation *animation, u32 a1, u32 a2);
|
||||
BOOL ov02_02252EA8(Field3DModelAnimation *animation, u32 a1);
|
||||
BOOL Task_SinjohGetEggCutscene(TaskManager *taskMan);
|
||||
u8 ov02_0225316C();
|
||||
BOOL ov02_02253188(SaveData *saveData);
|
||||
u8 ov02_022531B4(SaveData *saveData);
|
||||
BOOL ov02_02253188(SaveData *saveData);
|
||||
// the following functions are static and not decompiled
|
||||
void ov01_021F46DC(u32 *a0);
|
||||
BOOL Task_SinjohCutscene(TaskManager *taskMan);
|
||||
void SinjohGetEggCutscene_LoadResources(SinjohGetEggCutsceneData *data);
|
||||
void SinjohGetEggCutscene_FreeResources(SinjohGetEggCutsceneData *data);
|
||||
|
||||
#endif // POKEHEARTGOLD_OVERLAY_02_02251E74_H
|
||||
|
12
include/overlay_2/overlay_02_gear_phone.h
Normal file
12
include/overlay_2/overlay_02_gear_phone.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef POKEHEARTGOLD_OVERLAY_02_GEAR_PHONE_H
|
||||
#define POKEHEARTGOLD_OVERLAY_02_GEAR_PHONE_H
|
||||
|
||||
#include "field_system.h"
|
||||
|
||||
String *GetPhoneBookEntryName(GearPhoneRingManager *gearPhone, HeapID heapId);
|
||||
void ov02_02251EB8(GearPhoneRingManager *phoneRingManager, u8 a1, u8 a2, u8 a3, u8 a4, u8 a5);
|
||||
u8 ov02_02251EE8(GearPhoneRingManager *gearPhone, u8 *a1);
|
||||
BOOL ov02_02251F20(GearPhoneRingManager *gearPhone);
|
||||
int GetRadioMusicPlayingSeq(void);
|
||||
|
||||
#endif
|
4
main.lsf
4
main.lsf
@ -523,6 +523,10 @@ Overlay OVY_2
|
||||
After field
|
||||
Object asm/overlay_02_02245B80.o
|
||||
Object src/field/legend_cutscene_camera.o
|
||||
Object src/field/overlay_2_gear_phone.o
|
||||
Object src/field/event_cutscene_shaymin.o
|
||||
Object src/field/event_cutscene_celebi.o
|
||||
Object src/field/event_cutscene_sinjoh.o
|
||||
Object src/overlay_02_02251E74.o
|
||||
Object asm/overlay_02_02251E74_s.o
|
||||
}
|
||||
|
0
src/data/overlay_02.h
Normal file
0
src/data/overlay_02.h
Normal file
238
src/field/event_cutscene_celebi.c
Normal file
238
src/field/event_cutscene_celebi.c
Normal file
@ -0,0 +1,238 @@
|
||||
#include "field/overlay_01_021FB878.h"
|
||||
#include "overlay_2/event_cutscene.h"
|
||||
|
||||
#include "fieldmap.h"
|
||||
#include "follow_mon.h"
|
||||
#include "math_util.h"
|
||||
#include "overlay_01_021F467C.h"
|
||||
#include "overlay_01_021F944C.h"
|
||||
#include "overlay_01_022053EC.h"
|
||||
#include "script_pokemon_util.h"
|
||||
#include "task.h"
|
||||
#include "unk_0200FA24.h"
|
||||
#include "unk_02062108.h"
|
||||
#include "unk_020689C8.h"
|
||||
|
||||
typedef struct CelebiTimeTravelCutsceneTaskData {
|
||||
u16 unk0;
|
||||
u8 unk2;
|
||||
u8 isSwirlFinished;
|
||||
u32 unk4;
|
||||
FieldSystem *fieldSystem; // 0x8
|
||||
NNSFndAllocator alloc; // 0xC
|
||||
Field3dModel model; // 0x1C
|
||||
Field3DModelAnimation animations[3];
|
||||
Field3dObject object3d;
|
||||
s32 unkE0;
|
||||
u16 unkE4;
|
||||
u16 unkE6;
|
||||
u16 unkE8;
|
||||
u16 perspective;
|
||||
u16 unkEC;
|
||||
u16 unkEE;
|
||||
u8 unkF0;
|
||||
u8 unkF1;
|
||||
u8 unkF2;
|
||||
u8 unkF3;
|
||||
} CelebiTimeTravelCutsceneTaskData;
|
||||
|
||||
typedef struct UnkStruct_02253CE0 {
|
||||
u32 unk0;
|
||||
u32 unk4;
|
||||
u16 unk8;
|
||||
} UnkStruct_02253CE0;
|
||||
// static const u32 sCelebiCutsceneFiles[] = {76, 78, 77};
|
||||
// static const VecFx32 sUnkVec = {0, 16, 0};
|
||||
// static const UnkStruct_02253CE0 sUnkStructDatas = {0xFFFF0000, 0xB4, 0x500};
|
||||
|
||||
static BOOL Task_CelebiTimeTravelCutscene(TaskManager *taskMan);
|
||||
static void CelebiCutscene_StartSwirlTask(CelebiTimeTravelCutsceneTaskData *data);
|
||||
static BOOL ov02_022526EC(CelebiTimeTravelCutsceneTaskData *data);
|
||||
static void Task_CelebiCutsceneSwirl(SysTask *task, void *data);
|
||||
static void CelebiCutscene_InitSwirlData(CelebiTimeTravelCutsceneTaskData *a0, UnkStruct_02253CE0 *a1);
|
||||
static BOOL CelebiCutscene_SwirlEffect(CelebiTimeTravelCutsceneTaskData *data);
|
||||
static void Task_CelebiCutsceneSwirlEffect(SysTask *task, void *data);
|
||||
static BOOL CelebiCutscene_IsSwirlFinished(CelebiTimeTravelCutsceneTaskData *data);
|
||||
static void CelebiCutscene_LoadResources(CelebiTimeTravelCutsceneTaskData *data);
|
||||
static void CelebiCutscene_UnloadResources(CelebiTimeTravelCutsceneTaskData *data);
|
||||
static void CelebiCutsceneAnimations_FrameSet(Field3DModelAnimation *animations, u32 frame);
|
||||
static BOOL CelebiCutsceneAnimations_FrameAdvanceAndCheck(Field3DModelAnimation *animations);
|
||||
|
||||
void FieldSystem_BeginCelebiTimeTravelCutsceneTask(FieldSystem *fieldSystem) {
|
||||
CelebiTimeTravelCutsceneTaskData *ptr = AllocFromHeapAtEnd(HEAP_ID_FIELD, sizeof(CelebiTimeTravelCutsceneTaskData));
|
||||
MI_CpuFill8(ptr, 0, sizeof(CelebiTimeTravelCutsceneTaskData));
|
||||
ptr->fieldSystem = fieldSystem;
|
||||
TaskManager_Call(fieldSystem->taskman, Task_CelebiTimeTravelCutscene, ptr);
|
||||
}
|
||||
|
||||
static BOOL Task_CelebiTimeTravelCutscene(TaskManager *taskMan) {
|
||||
int *state = TaskManager_GetStatePtr(taskMan);
|
||||
FieldSystem *fieldSystem = TaskManager_GetFieldSystem(taskMan);
|
||||
CelebiTimeTravelCutsceneTaskData *data = TaskManager_GetEnvironment(taskMan);
|
||||
switch (*state) {
|
||||
case 0:
|
||||
BeginNormalPaletteFade(3, 0, 0, RGB_WHITE, 4, 1, HEAP_ID_4);
|
||||
(*state)++;
|
||||
break;
|
||||
case 1:
|
||||
if (IsPaletteFadeFinished()) {
|
||||
CelebiCutscene_LoadResources(data);
|
||||
sub_02069DC8(FollowMon_GetMapObject(data->fieldSystem), 1);
|
||||
BeginNormalPaletteFade(3, 1, 0, RGB_WHITE, 4, 1, HEAP_ID_4);
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (IsPaletteFadeFinished()) {
|
||||
sub_0205F484(FollowMon_GetMapObject(data->fieldSystem));
|
||||
data->unkF0 = 1;
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (++data->unkF2 >= 30) {
|
||||
CelebiCutscene_StartSwirlTask(data);
|
||||
data->unkF2 = 0;
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (++data->unkF2 >= 80) {
|
||||
BeginNormalPaletteFade(0, 0, 0, RGB_WHITE, 30, 1, HEAP_ID_4);
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (IsPaletteFadeFinished() && ov02_022526EC(data)) {
|
||||
CelebiCutscene_UnloadResources(data);
|
||||
ov01_021F46DC(&data->unk4);
|
||||
FreeToHeap(data);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (data->unkF0) {
|
||||
CelebiCutsceneAnimations_FrameAdvanceAndCheck(&data->animations[0]);
|
||||
}
|
||||
if (data->unkF1) {
|
||||
Field3dObject_Draw(&data->object3d);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void CelebiCutscene_StartSwirlTask(CelebiTimeTravelCutsceneTaskData *data) {
|
||||
data->unk4 = ov01_021F467C(3, 13);
|
||||
SysTask_CreateOnMainQueue(Task_CelebiCutsceneSwirl, data, 0);
|
||||
data->unk2 = 0;
|
||||
}
|
||||
|
||||
static BOOL ov02_022526EC(CelebiTimeTravelCutsceneTaskData *data) {
|
||||
return data->unk2 != 0;
|
||||
}
|
||||
|
||||
static void Task_CelebiCutsceneSwirl(SysTask *task, void *_data) {
|
||||
CelebiTimeTravelCutsceneTaskData *data = _data;
|
||||
switch (data->unkEE) {
|
||||
case 0:
|
||||
UnkStruct_02253CE0 unk = { 0xFFFF0000, 0xB4, 0x500 };
|
||||
unk.unk8 = Camera_GetPerspectiveAngle(data->fieldSystem->camera);
|
||||
CelebiCutscene_InitSwirlData(data, &unk);
|
||||
data->unkEE++;
|
||||
break;
|
||||
case 1:
|
||||
if (CelebiCutscene_IsSwirlFinished(data)) {
|
||||
data->unk2 = 1;
|
||||
SysTask_Destroy(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CelebiCutscene_InitSwirlData(CelebiTimeTravelCutsceneTaskData *data, UnkStruct_02253CE0 *a1) {
|
||||
data->isSwirlFinished = FALSE;
|
||||
data->unkE6 = 0;
|
||||
data->unkE0 = a1->unk0;
|
||||
data->unkE4 = data->unk0;
|
||||
data->perspective = Camera_GetPerspectiveAngle(data->fieldSystem->camera);
|
||||
data->unkEC = a1->unk8;
|
||||
data->unkE8 = a1->unk4;
|
||||
SysTask_CreateOnMainQueue(Task_CelebiCutsceneSwirlEffect, data, 1);
|
||||
}
|
||||
|
||||
static BOOL CelebiCutscene_SwirlEffect(CelebiTimeTravelCutsceneTaskData *data) {
|
||||
VecFx32 vec;
|
||||
MtxFx33 rotMatrix;
|
||||
const VecFx32 vec2 = { 0, 0x1000, 0 };
|
||||
Camera *camera = data->fieldSystem->camera;
|
||||
|
||||
data->unkE6++;
|
||||
int e6 = data->unkE6;
|
||||
int e8 = data->unkE8;
|
||||
|
||||
int angle = data->unkEC - data->perspective;
|
||||
angle *= e6;
|
||||
angle /= e8;
|
||||
angle += data->perspective;
|
||||
u16 index = ((data->unkE0 * e6) / e8) + data->unkE4;
|
||||
MTX_RotZ33(&rotMatrix, FX_SinIdx(index), FX_CosIdx(index));
|
||||
MTX_MultVec33(&vec2, &rotMatrix, &vec);
|
||||
Camera_SetLookAtCamUp(&vec, camera);
|
||||
Camera_SetPerspectiveAngle(angle, camera);
|
||||
return data->unkE6 >= data->unkE8;
|
||||
}
|
||||
|
||||
static void Task_CelebiCutsceneSwirlEffect(SysTask *task, void *_data) {
|
||||
CelebiTimeTravelCutsceneTaskData *data = _data;
|
||||
if (CelebiCutscene_SwirlEffect(data)) {
|
||||
data->isSwirlFinished = TRUE;
|
||||
SysTask_Destroy(task);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL CelebiCutscene_IsSwirlFinished(CelebiTimeTravelCutsceneTaskData *data) {
|
||||
return data->isSwirlFinished != FALSE;
|
||||
}
|
||||
|
||||
static void CelebiCutscene_LoadResources(CelebiTimeTravelCutsceneTaskData *data) {
|
||||
const u32 files[3] = { 76, 78, 77 };
|
||||
GF_ExpHeap_FndInitAllocator(&data->alloc, HEAP_ID_4, 32);
|
||||
Field3dModel_LoadFromFilesystem(&data->model, NARC_demo_legend, 75, HEAP_ID_4);
|
||||
for (u8 i = 0; i < 3; i++) {
|
||||
Field3dModelAnimation_LoadFromFilesystem(&data->animations[i], &data->model, NARC_demo_legend, files[i], HEAP_ID_4, &data->alloc);
|
||||
}
|
||||
Field3dObject_InitFromModel(&data->object3d, &data->model);
|
||||
for (u8 i = 0; i < 3; i++) {
|
||||
Field3dObject_AddAnimation(&data->object3d, &data->animations[i]);
|
||||
}
|
||||
Field3dObject_SetActiveFlag(&data->object3d, 1);
|
||||
CelebiCutsceneAnimations_FrameSet(&data->animations[0], 0);
|
||||
LocalMapObject *followMonObj = FollowMon_GetMapObject(data->fieldSystem);
|
||||
VecFx32 pos;
|
||||
MapObject_GetPositionVec(followMonObj, &pos);
|
||||
Field3dObject_SetPosEx(&data->object3d, pos.x, pos.y, pos.z);
|
||||
data->unkF1 = 1;
|
||||
}
|
||||
|
||||
static void CelebiCutscene_UnloadResources(CelebiTimeTravelCutsceneTaskData *data) {
|
||||
for (u8 i = 0; i < 3; i++) {
|
||||
Field3dModelAnimation_Unload(&data->animations[i], &data->alloc);
|
||||
}
|
||||
Field3dModel_Unload(&data->model);
|
||||
}
|
||||
|
||||
static void CelebiCutsceneAnimations_FrameSet(Field3DModelAnimation *animations, u32 frame) {
|
||||
for (u8 i = 0; i < 3; i++) {
|
||||
Field3dModelAnimation_FrameSet(&animations[i], frame);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL CelebiCutsceneAnimations_FrameAdvanceAndCheck(Field3DModelAnimation *animations) {
|
||||
u8 i;
|
||||
u8 cnt = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (Field3dModelAnimation_FrameAdvanceAndCheck(&animations[i], 0x1000) != 0) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt == 3;
|
||||
}
|
110
src/field/event_cutscene_shaymin.c
Normal file
110
src/field/event_cutscene_shaymin.c
Normal file
@ -0,0 +1,110 @@
|
||||
#include "overlay_2/event_cutscene.h"
|
||||
|
||||
#include "fieldmap.h"
|
||||
#include "follow_mon.h"
|
||||
#include "math_util.h"
|
||||
#include "overlay_01_021F467C.h"
|
||||
#include "overlay_01_021F944C.h"
|
||||
#include "overlay_01_022053EC.h"
|
||||
#include "script_pokemon_util.h"
|
||||
#include "task.h"
|
||||
#include "unk_0200FA24.h"
|
||||
#include "unk_02062108.h"
|
||||
#include "unk_020689C8.h"
|
||||
static BOOL ov02_022523D0(TaskManager *taskMan);
|
||||
|
||||
BOOL ov02_02252334(FieldSystem *fieldSystem) {
|
||||
if (!MapObject_AreBitsSetForMovementScriptInit(PlayerAvatar_GetMapObject(fieldSystem->playerAvatar))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (FollowMon_IsActive(fieldSystem) && fieldSystem->followMon.species == SPECIES_SHAYMIN) {
|
||||
Pokemon *mon = GetFirstAliveMonInParty_CrashIfNone(SaveArray_Party_Get(fieldSystem->saveData));
|
||||
u32 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
|
||||
u32 form = GetMonData(mon, MON_DATA_FORM, NULL);
|
||||
GF_ASSERT(species == fieldSystem->followMon.species);
|
||||
// yes, this is explicitly checked twice
|
||||
if (species != fieldSystem->followMon.species) {
|
||||
return FALSE;
|
||||
}
|
||||
if (fieldSystem->followMon.form == SHAYMIN_SKY && form == SHAYMIN_LAND) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void ov02_022523B4(TaskManager *taskMan) {
|
||||
void *data = AllocFromHeapAtEnd(HEAP_ID_FIELD, 12);
|
||||
TaskManager_Call(taskMan, ov02_022523D0, data);
|
||||
}
|
||||
|
||||
typedef struct UnkStruct_022523D0 {
|
||||
int unk0;
|
||||
u32 unk4;
|
||||
u32 unk8;
|
||||
} UnkStruct_022523D0;
|
||||
|
||||
static BOOL ov02_022523D0(TaskManager *taskMan) {
|
||||
int *state = TaskManager_GetStatePtr(taskMan);
|
||||
VecFx32 pos;
|
||||
FieldSystem *fieldSystem = TaskManager_GetFieldSystem(taskMan);
|
||||
UnkStruct_022523D0 *env = TaskManager_GetEnvironment(taskMan);
|
||||
switch (*state) {
|
||||
case 0:
|
||||
MapObject_UnpauseMovement(FollowMon_GetMapObject(fieldSystem));
|
||||
TaskManager_Call(fieldSystem->taskman, ov01_02205A60, NULL);
|
||||
(*state)++;
|
||||
break;
|
||||
case 1:
|
||||
MapObject_GetPositionVec(FollowMon_GetMapObject(fieldSystem), &pos);
|
||||
u32 res;
|
||||
if (FollowMon_IsVisible(fieldSystem)) {
|
||||
env->unk4 = ov01_022052C4(fieldSystem->unk_44, &pos);
|
||||
res = 1;
|
||||
} else {
|
||||
env->unk4 = 0;
|
||||
res = 0;
|
||||
}
|
||||
env->unk8 = res;
|
||||
env->unk0 = 0;
|
||||
FollowMon_SetObjectParams(fieldSystem->followMon.mapObject, SPECIES_SHAYMIN, 0, fieldSystem->followMon.shiny);
|
||||
(*state)++;
|
||||
break;
|
||||
case 2:
|
||||
if (env->unk8 != 0) {
|
||||
if (++env->unk0 >= 4) {
|
||||
ov01_021FA930(fieldSystem->followMon.mapObject, 974);
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
MapObjectManager *mapObjectMan = MapObject_GetManager(fieldSystem->followMon.mapObject);
|
||||
u32 spriteId = MapObject_GetSpriteID(fieldSystem->followMon.mapObject);
|
||||
sub_0205E420(fieldSystem->followMon.mapObject);
|
||||
ov01_021FA108(mapObjectMan, spriteId, fieldSystem->followMon.mapObject);
|
||||
sub_0205E38C(fieldSystem->followMon.mapObject, 974);
|
||||
(*state)++;
|
||||
break;
|
||||
case 3:
|
||||
if (ov01_021FA2D4(fieldSystem->followMon.mapObject) == 0) {
|
||||
fieldSystem->followMon.form = 0;
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
u32 var = 0;
|
||||
if (env->unk4 == 0) {
|
||||
var = 1;
|
||||
} else if (ov01_022052F4()) {
|
||||
sub_02068B48(env->unk4);
|
||||
var = 1;
|
||||
}
|
||||
if (var != 0) {
|
||||
FreeToHeap(env);
|
||||
MapObject_PauseMovement(FollowMon_GetMapObject(fieldSystem));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
321
src/field/event_cutscene_sinjoh.c
Normal file
321
src/field/event_cutscene_sinjoh.c
Normal file
@ -0,0 +1,321 @@
|
||||
#include "field/overlay_01_021FB878.h"
|
||||
#include "overlay_2/event_cutscene.h"
|
||||
|
||||
#include "fieldmap.h"
|
||||
#include "follow_mon.h"
|
||||
#include "math_util.h"
|
||||
#include "overlay_01_021F467C.h"
|
||||
#include "overlay_01_021F944C.h"
|
||||
#include "overlay_01_022053EC.h"
|
||||
#include "script_pokemon_util.h"
|
||||
#include "task.h"
|
||||
#include "unk_0200FA24.h"
|
||||
#include "unk_02062108.h"
|
||||
#include "unk_020689C8.h"
|
||||
|
||||
typedef struct SinjohCutsceneData {
|
||||
FieldSystem *fieldSystem;
|
||||
struct NNSFndAllocator alloc;
|
||||
Field3dModel model[2];
|
||||
Field3DModelAnimation animations[2][2];
|
||||
Field3dObject object84[2];
|
||||
Field3dModel model174;
|
||||
Field3DModelAnimation animation184[2];
|
||||
Field3dObject object1AC;
|
||||
u8 unk224;
|
||||
u8 unk225;
|
||||
u8 unk226;
|
||||
u8 unk227;
|
||||
} SinjohCutsceneData;
|
||||
|
||||
typedef struct SinjohGetEggCutsceneData {
|
||||
FieldSystem *fieldSystem;
|
||||
NNSFndAllocator alloc;
|
||||
Field3dModel model;
|
||||
Field3DModelAnimation animations[4];
|
||||
Field3dObject object;
|
||||
u8 unkEC;
|
||||
u8 unkED;
|
||||
u8 unkEE;
|
||||
u8 unkEF;
|
||||
} SinjohGetEggCutsceneData;
|
||||
|
||||
static BOOL Task_SinjohCutscene(TaskManager *taskMan);
|
||||
static void SinjohCutscene_LoadResources(SinjohCutsceneData *data);
|
||||
static void SinjohCutscene_FreeResources(SinjohCutsceneData *data);
|
||||
static void ov02_02252E80(Field3DModelAnimation *animation, u32 a1, u32 a2);
|
||||
static BOOL ov02_02252EA8(Field3DModelAnimation *animation, u32 a1);
|
||||
static BOOL Task_SinjohGetEggCutscene(TaskManager *taskMan);
|
||||
static void SinjohGetEggCutscene_LoadResources(SinjohGetEggCutsceneData *data);
|
||||
static void SinjohGetEggCutscene_FreeResources(SinjohGetEggCutsceneData *data);
|
||||
|
||||
void FieldSystem_BeginSinjohCutsceneTask(FieldSystem *fieldSystem) {
|
||||
SinjohCutsceneData *data = AllocFromHeapAtEnd(HEAP_ID_FIELD, sizeof(SinjohCutsceneData));
|
||||
MI_CpuFill8(data, 0, sizeof(SinjohCutsceneData));
|
||||
data->fieldSystem = fieldSystem;
|
||||
TaskManager_Call(fieldSystem->taskman, Task_SinjohCutscene, data);
|
||||
}
|
||||
|
||||
static BOOL Task_SinjohCutscene(TaskManager *taskMan) {
|
||||
int *state = TaskManager_GetStatePtr(taskMan);
|
||||
FieldSystem *fieldSystem = TaskManager_GetFieldSystem(taskMan);
|
||||
SinjohCutsceneData *data = TaskManager_GetEnvironment(taskMan);
|
||||
switch (*state) {
|
||||
case 0:
|
||||
BeginNormalPaletteFade(3, 0, 0, RGB_WHITE, 2, 1, HEAP_ID_4);
|
||||
(*state)++;
|
||||
break;
|
||||
case 1:
|
||||
if (IsPaletteFadeFinished()) {
|
||||
SinjohCutscene_LoadResources(data);
|
||||
BeginNormalPaletteFade(3, 1, 0, RGB_WHITE, 2, 1, HEAP_ID_4);
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (IsPaletteFadeFinished()) {
|
||||
data->unk224 = 1;
|
||||
data->unk227 = 0;
|
||||
Field3dObject_SetActiveFlag(&data->object1AC, 1);
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (++data->unk227 >= 100) {
|
||||
data->unk225 = 1;
|
||||
data->unk227 = 0;
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (++data->unk227 >= 150) {
|
||||
BeginNormalPaletteFade(3, 0, 0, RGB_WHITE, 2, 1, HEAP_ID_4);
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (IsPaletteFadeFinished()) {
|
||||
SinjohCutscene_FreeResources(data);
|
||||
FreeToHeap(data);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (data->unk224) {
|
||||
ov02_02252EA8(&data->animations[0][0], 2);
|
||||
ov02_02252EA8(&data->animations[1][0], 2);
|
||||
}
|
||||
if (data->unk225) {
|
||||
ov02_02252EA8(&data->animation184[0], 2);
|
||||
}
|
||||
if (data->unk226) {
|
||||
Field3dObject_Draw(&data->object84[0]);
|
||||
Field3dObject_Draw(&data->object84[1]);
|
||||
Field3dObject_Draw(&data->object1AC);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const u32 ov02_02253D14[2][2] = {
|
||||
{ 80, 81 },
|
||||
{ 83, 84 },
|
||||
};
|
||||
|
||||
static const u32 sSinjohEggModelFiles[3] = { 88, 92, 96 };
|
||||
|
||||
static const u32 ov02_02253CF8_1[2] = { 79, 82 };
|
||||
static const u32 ov02_02253CF8_0[2] = { 86, 87 };
|
||||
|
||||
static void SinjohCutscene_LoadResources(SinjohCutsceneData *data) {
|
||||
u8 i, j;
|
||||
|
||||
u32 unkData[2][2];
|
||||
unkData = ov02_02253D14;
|
||||
VecFx32 arceusPos;
|
||||
u32 unkData2[2];
|
||||
u32 unkData3[2];
|
||||
unkData2 = ov02_02253CF8_0;
|
||||
unkData3 = ov02_02253CF8_1;
|
||||
|
||||
GF_ExpHeap_FndInitAllocator(&data->alloc, HEAP_ID_4, 32);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Field3dModel_LoadFromFilesystem(&data->model[i], NARC_demo_legend, unkData3[i], HEAP_ID_4);
|
||||
}
|
||||
|
||||
Field3dModel_LoadFromFilesystem(&data->model174, NARC_demo_legend, 85, HEAP_ID_4);
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
Field3dModelAnimation_LoadFromFilesystem(&data->animations[j][i], &data->model[j], NARC_demo_legend, unkData[j][i], HEAP_ID_4, &data->alloc);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Field3dModelAnimation_LoadFromFilesystem(&data->animation184[i], &data->model174, NARC_demo_legend, unkData2[i], HEAP_ID_4, &data->alloc);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Field3dObject_InitFromModel(&data->object84[i], &data->model[i]);
|
||||
}
|
||||
|
||||
Field3dObject_InitFromModel(&data->object1AC, &data->model174);
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
Field3dObject_AddAnimation(&data->object84[j], &data->animations[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Field3dObject_AddAnimation(&data->object1AC, &data->animation184[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Field3dObject_SetActiveFlag(&data->object84[i], 1);
|
||||
ov02_02252E80(&data->animations[i][0], 2, 0);
|
||||
}
|
||||
|
||||
Field3dObject_SetActiveFlag(&data->object1AC, 0);
|
||||
ov02_02252E80(&data->animation184[0], 2, 0);
|
||||
|
||||
MapObject_GetPositionVec(FollowMon_GetMapObject(data->fieldSystem), &arceusPos);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
Field3dObject_SetPosEx(&data->object84[i], arceusPos.x, arceusPos.y, arceusPos.z);
|
||||
}
|
||||
|
||||
Field3dObject_SetPosEx(&data->object1AC, arceusPos.x, arceusPos.y, arceusPos.z);
|
||||
|
||||
data->unk226 = 1;
|
||||
}
|
||||
|
||||
static void SinjohCutscene_FreeResources(SinjohCutsceneData *data) {
|
||||
for (u8 i = 0; i < 2; i++) {
|
||||
for (u8 j = 0; j < 2; j++) {
|
||||
Field3dModelAnimation_Unload(&data->animations[i][j], &data->alloc);
|
||||
}
|
||||
Field3dModel_Unload(&data->model[i]);
|
||||
}
|
||||
|
||||
for (u8 i = 0; i < 2; i++) {
|
||||
Field3dModelAnimation_Unload(&data->animation184[i], &data->alloc);
|
||||
}
|
||||
|
||||
Field3dModel_Unload(&data->model174);
|
||||
}
|
||||
|
||||
static void ov02_02252E80(Field3DModelAnimation *animation, u32 a1, u32 a2) {
|
||||
for (u8 i = 0; i < a1; i++) {
|
||||
Field3dModelAnimation_FrameSet(&animation[i], a2);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL ov02_02252EA8(Field3DModelAnimation *animation, u32 a1) {
|
||||
u8 i;
|
||||
u8 cnt = 0;
|
||||
for (i = 0; i < a1; i++) {
|
||||
if (Field3dModelAnimation_FrameAdvanceAndCheck(&animation[i], (1 << 12))) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
return cnt == a1;
|
||||
}
|
||||
|
||||
void FieldSystem_BeginSinjohGetEggCutsceneTask(FieldSystem *fieldSystem, u8 a1) {
|
||||
SinjohGetEggCutsceneData *data = AllocFromHeapAtEnd(HEAP_ID_FIELD, sizeof(SinjohGetEggCutsceneData));
|
||||
MI_CpuFill8(data, 0, sizeof(SinjohGetEggCutsceneData));
|
||||
data->fieldSystem = fieldSystem;
|
||||
data->unkEF = a1;
|
||||
TaskManager_Call(fieldSystem->taskman, Task_SinjohGetEggCutscene, data);
|
||||
}
|
||||
|
||||
static BOOL Task_SinjohGetEggCutscene(TaskManager *taskMan) {
|
||||
int *state = TaskManager_GetStatePtr(taskMan);
|
||||
FieldSystem *fieldSystem = TaskManager_GetFieldSystem(taskMan);
|
||||
SinjohGetEggCutsceneData *data = TaskManager_GetEnvironment(taskMan);
|
||||
|
||||
switch (*state) {
|
||||
case 0:
|
||||
BeginNormalPaletteFade(3, 0, 0, RGB_WHITE, 2, 1, HEAP_ID_4);
|
||||
(*state)++;
|
||||
break;
|
||||
case 1:
|
||||
if (IsPaletteFadeFinished()) {
|
||||
SinjohGetEggCutscene_LoadResources(data);
|
||||
BeginNormalPaletteFade(3, 1, 0, RGB_WHITE, 2, 1, HEAP_ID_4);
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (IsPaletteFadeFinished()) {
|
||||
data->unkEC = 1;
|
||||
data->unkED = 0;
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (data->unkED) {
|
||||
(*state)++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
SinjohGetEggCutscene_FreeResources(data);
|
||||
FreeToHeap(data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (data->unkEC) {
|
||||
data->unkED = ov02_02252EA8(&data->animations[0], 4);
|
||||
}
|
||||
|
||||
if (data->unkEE) {
|
||||
Field3dObject_Draw(&data->object);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const u32 ov02_02253D24[3][4] = {
|
||||
{ 100, 90, 91, 89 },
|
||||
{ 100, 94, 95, 93 },
|
||||
{ 100, 98, 99, 97 },
|
||||
};
|
||||
|
||||
static void SinjohGetEggCutscene_LoadResources(SinjohGetEggCutsceneData *data) {
|
||||
u32 animFiles[3][4];
|
||||
animFiles = ov02_02253D24;
|
||||
|
||||
u32 modelFiles[3];
|
||||
modelFiles = sSinjohEggModelFiles;
|
||||
|
||||
VecFx32 arceusPos;
|
||||
|
||||
GF_ExpHeap_FndInitAllocator(&data->alloc, HEAP_ID_4, 32);
|
||||
Field3dModel_LoadFromFilesystem(&data->model, NARC_demo_legend, modelFiles[data->unkEF], HEAP_ID_4);
|
||||
|
||||
for (u8 i = 0; i < 4; i++) {
|
||||
Field3dModelAnimation_LoadFromFilesystem(&data->animations[i], &data->model, NARC_demo_legend, animFiles[data->unkEF][i], HEAP_ID_4, &data->alloc);
|
||||
}
|
||||
|
||||
Field3dObject_InitFromModel(&data->object, &data->model);
|
||||
|
||||
for (u8 i = 0; i < 4; i++) {
|
||||
Field3dObject_AddAnimation(&data->object, &data->animations[i]);
|
||||
}
|
||||
|
||||
Field3dObject_SetActiveFlag(&data->object, 1);
|
||||
ov02_02252E80(&data->animations[0], 4, 0);
|
||||
|
||||
MapObject_GetPositionVec(FollowMon_GetMapObject(data->fieldSystem), &arceusPos);
|
||||
|
||||
Field3dObject_SetPosEx(&data->object, arceusPos.x, arceusPos.y, arceusPos.z);
|
||||
|
||||
data->unkEE = 1;
|
||||
}
|
||||
|
||||
static void SinjohGetEggCutscene_FreeResources(SinjohGetEggCutsceneData *data) {
|
||||
for (u8 i = 0; i < 4; i++) {
|
||||
Field3dModelAnimation_Unload(&data->animations[i], &data->alloc);
|
||||
}
|
||||
Field3dModel_Unload(&data->model);
|
||||
}
|
513
src/field/overlay_2_gear_phone.c
Normal file
513
src/field/overlay_2_gear_phone.c
Normal file
@ -0,0 +1,513 @@
|
||||
#include "constants/sndseq.h"
|
||||
|
||||
#include "overlay_2/overlay_02_gear_phone.h"
|
||||
|
||||
#include "fieldmap.h"
|
||||
#include "map_header.h"
|
||||
#include "math_util.h"
|
||||
#include "msgdata.h"
|
||||
#include "phonebook_dat.h"
|
||||
#include "sav_system_info.h"
|
||||
#include "save_local_field_data.h"
|
||||
#include "save_vars_flags.h"
|
||||
#include "sound_radio.h"
|
||||
#include "sys_flags.h"
|
||||
#include "sys_vars.h"
|
||||
#include "unk_02092BE8.h"
|
||||
|
||||
typedef struct UnkStruct_02253C86 {
|
||||
u8 unk0;
|
||||
u8 unk1;
|
||||
u16 unk2;
|
||||
u8 unk4;
|
||||
u8 unk5;
|
||||
} UnkStruct_02253C86;
|
||||
|
||||
static const UnkStruct_02253C86 ov02_02253C84[] = {
|
||||
{ 1, 0, 13, 0, 0 },
|
||||
{ 1, 0, 7, 0, 0 },
|
||||
{ 15, 0, 85, 1, 0 },
|
||||
{ 9, 0, 93, 1, 0 },
|
||||
{ 2, 0, 0, 0, 0 },
|
||||
{ 6, 0, 0, 0, 0 },
|
||||
{ 24, 0, 0, 0, 0 },
|
||||
{ 24, 0, 142, 1, 0 },
|
||||
{ 24, 0, 143, 1, 0 },
|
||||
{ 24, 0, 144, 1, 0 },
|
||||
{ 24, 0, 145, 1, 0 },
|
||||
{ 24, 0, 146, 1, 0 },
|
||||
{ 0, 0, 27, 0, 0 }
|
||||
};
|
||||
|
||||
static u32 ov02_02251FDC(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId);
|
||||
static u32 ov02_022521C0(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId);
|
||||
static u8 ov02_02252218(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId);
|
||||
static void ov02_022522AC(GearPhoneRingManager *gearPhone, BOOL a1);
|
||||
|
||||
String *GetPhoneBookEntryName(GearPhoneRingManager *gearPhone, HeapID heapId) {
|
||||
String *str;
|
||||
if (!gearPhone->unk_var0_0 || gearPhone->unk_var2 >= 75) {
|
||||
str = String_New(8, heapId);
|
||||
} else {
|
||||
int phoneMsg = GetPhoneMessageGmm(gearPhone->unk_var2);
|
||||
MsgData *msgData = NewMsgDataFromNarc(MSGDATA_LOAD_LAZY, NARC_msgdata_msg, phoneMsg, heapId);
|
||||
str = NewString_ReadMsgData(msgData, 0);
|
||||
DestroyMsgData(msgData);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void ov02_02251EB8(GearPhoneRingManager *gearPhone, u8 a1, u8 a2, u8 a3, u8 a4, u8 a5) {
|
||||
if (a1 >= 75) {
|
||||
gearPhone->unk_var2 = 0xFF;
|
||||
gearPhone->unk_arr5[0] = 0xFF;
|
||||
gearPhone->unk_arr5[1] = 0;
|
||||
GF_ASSERT(FALSE);
|
||||
} else {
|
||||
gearPhone->unk_var2 = a1;
|
||||
gearPhone->unk_arr5[0] = a2;
|
||||
gearPhone->unk_arr5[1] = a3;
|
||||
}
|
||||
|
||||
gearPhone->unk_var3 = a4;
|
||||
gearPhone->unk_var4 = a5;
|
||||
}
|
||||
|
||||
u8 ov02_02251EE8(GearPhoneRingManager *gearPhone, u8 *a1) {
|
||||
MI_CpuFill8(a1, 0, 5);
|
||||
if (gearPhone->unk_var2 >= 75) {
|
||||
GF_ASSERT(FALSE);
|
||||
a1[0] = 0xFF;
|
||||
return 0xFF;
|
||||
}
|
||||
a1[0] = gearPhone->unk_arr5[0];
|
||||
a1[1] = gearPhone->unk_arr5[1];
|
||||
a1[3] = gearPhone->unk_var3;
|
||||
a1[4] = gearPhone->unk_var4;
|
||||
a1[2] = gearPhone->unk_var7;
|
||||
return gearPhone->unk_var2;
|
||||
}
|
||||
|
||||
BOOL ov02_02251F20(GearPhoneRingManager *gearPhone) {
|
||||
Location *position = LocalFieldData_GetCurrentPosition(Save_LocalFieldData_Get(gearPhone->saveData));
|
||||
|
||||
if (MapHeader_GetField14_1E(position->mapId) == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gearPhone->unk_var0_0 || gearPhone->unk_var8 < gearPhone->unk_varC) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PhoneBook *phoneBook = AllocAndReadPhoneBook(HEAP_ID_4);
|
||||
u32 var = ov02_022521C0(gearPhone, phoneBook, position->mapId);
|
||||
if (var) {
|
||||
FreePhoneBook(phoneBook);
|
||||
if (var == 2) {
|
||||
gearPhone->sys->unkD2_7 = 1;
|
||||
StartMapSceneScript(gearPhone->sys, 0x7FF, 0);
|
||||
return TRUE;
|
||||
}
|
||||
ov02_022522AC(gearPhone, 1);
|
||||
return FALSE;
|
||||
}
|
||||
u32 rand = MTRandom() % 0x64;
|
||||
|
||||
if (rand > gearPhone->unk_var12) {
|
||||
FreePhoneBook(phoneBook);
|
||||
gearPhone->unk_var8 = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
var = ov02_02251FDC(gearPhone, phoneBook, position->mapId);
|
||||
FreePhoneBook(phoneBook);
|
||||
|
||||
if (var == 0) {
|
||||
gearPhone->unk_var8 = 0;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef NONMATCHING
|
||||
// FIXME: https://decomp.me/scratch/KW1m7 down to stack swaps between bugContestFlag and var -adrienn
|
||||
static u32 ov02_02251FDC(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId) {
|
||||
u8 ret;
|
||||
u8 var;
|
||||
u8 bugContestFlag;
|
||||
PhoneContact *contact;
|
||||
|
||||
SaveVarsFlags *varsFlags = Save_VarsFlags_Get(gearPhone->saveData);
|
||||
Save_PlayerData_GetProfileAddr(gearPhone->saveData);
|
||||
SAVE_MISC_DATA *miscData = Save_Misc_Get(gearPhone->saveData);
|
||||
u32 slot = GSPlayerMisc_FindEmptyGearPhonebookSlot(gearPhone->pokegearData);
|
||||
contact = GSPlayerMisc_AllocAndCopyPhonebook(gearPhone->pokegearData, HEAP_ID_4);
|
||||
u8 *ptr = AllocFromHeapAtEnd(HEAP_ID_4, slot);
|
||||
MI_CpuFill8(ptr, 0xFF, slot);
|
||||
u16 rand = LCRandom() % 1000;
|
||||
|
||||
if (rand < 500) {
|
||||
var = 0;
|
||||
} else if (rand < 800) {
|
||||
var = 1;
|
||||
} else {
|
||||
var = 2;
|
||||
}
|
||||
|
||||
u8 index = 0;
|
||||
for (u8 i = 0; i < slot; i++) {
|
||||
u8 id = contact[i].id;
|
||||
if (phoneBook->entries[id].unkF == var) {
|
||||
// doesn't match with a switch statement
|
||||
if (phoneBook->entries[id].unk1 == 0 || phoneBook->entries[id].unk1 == 12 || phoneBook->entries[id].unk1 == 11 || phoneBook->entries[id].unk1 == 10 || phoneBook->entries[id].unk1 == 14) {
|
||||
ptr[index++] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index == 0) {
|
||||
FreeToHeap(contact);
|
||||
FreeToHeap(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MI_CpuFill8(contact, 0xFF, slot);
|
||||
SysInfo_RTC *rtc = Save_SysInfo_RTC_Get(gearPhone->saveData);
|
||||
u8 hour = rtc->time.hour;
|
||||
bugContestFlag = Save_VarsFlags_CheckBugContestFlag(varsFlags);
|
||||
ret = 0;
|
||||
|
||||
if (sub_0202AAD4(miscData, var) == index) {
|
||||
sub_0202AA9C(miscData, var);
|
||||
}
|
||||
|
||||
for (u8 j = 0; j < index; j++) {
|
||||
if (mapId == phoneBook->entries[ptr[j]].mapId || sub_0202AA44(miscData, var, ptr[j]) || ptr[j] == 8 && (sub_02095FF8(hour) || Save_VarsFlags_IsInRocketTakeover(varsFlags))) {
|
||||
continue;
|
||||
}
|
||||
if (phoneBook->entries[ptr[j]].mapId != 0x60 || !bugContestFlag) {
|
||||
contact[ret++].id = ptr[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
slot = (MTRandom() % (ret * 100));
|
||||
rand = slot / 100;
|
||||
ov02_02251EB8(gearPhone, contact[(u8)rand].id, var, index, 0, 0);
|
||||
sub_02092DF4(gearPhone);
|
||||
ov02_022522AC(gearPhone, 1);
|
||||
}
|
||||
|
||||
FreeToHeap(contact);
|
||||
FreeToHeap(ptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
// clang-format off
|
||||
extern u32 _u32_div_f(u32 a1, u32 a2);
|
||||
extern s32 _s32_div_f(s32 a1, s32 a2);
|
||||
asm static u32 ov02_02251FDC(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId) {
|
||||
push {r3, r4, r5, r6, r7, lr}
|
||||
sub sp, #0x30
|
||||
str r0, [sp, #8]
|
||||
ldr r0, [r0, #0x38]
|
||||
add r6, r1, #0
|
||||
str r2, [sp, #0xc]
|
||||
bl Save_VarsFlags_Get
|
||||
str r0, [sp, #0x1c]
|
||||
ldr r0, [sp, #8]
|
||||
ldr r0, [r0, #0x38]
|
||||
bl Save_PlayerData_GetProfileAddr
|
||||
ldr r0, [sp, #8]
|
||||
ldr r0, [r0, #0x38]
|
||||
bl Save_Misc_Get
|
||||
str r0, [sp, #0x18]
|
||||
ldr r0, [sp, #8]
|
||||
ldr r0, [r0, #0x30]
|
||||
bl GSPlayerMisc_FindEmptyGearPhonebookSlot
|
||||
str r0, [sp, #0x2c]
|
||||
ldr r0, [sp, #8]
|
||||
mov r1, #4
|
||||
ldr r0, [r0, #0x30]
|
||||
bl GSPlayerMisc_AllocAndCopyPhonebook
|
||||
str r0, [sp, #0x20]
|
||||
ldr r1, [sp, #0x2c]
|
||||
mov r0, #4
|
||||
bl AllocFromHeapAtEnd
|
||||
ldr r2, [sp, #0x2c]
|
||||
mov r1, #0xff
|
||||
add r4, r0, #0
|
||||
bl MI_CpuFill8
|
||||
bl LCRandom
|
||||
mov r1, #0xfa
|
||||
lsl r1, r1, #2
|
||||
bl _s32_div_f
|
||||
lsl r0, r1, #0x10
|
||||
lsr r1, r0, #0x10
|
||||
mov r0, #0x7d
|
||||
lsl r0, r0, #2
|
||||
cmp r1, r0
|
||||
bhs _02252046
|
||||
mov r0, #0
|
||||
str r0, [sp, #0x24]
|
||||
b _02252058
|
||||
_02252046:
|
||||
mov r0, #0x32
|
||||
lsl r0, r0, #4
|
||||
cmp r1, r0
|
||||
bhs _02252054
|
||||
mov r0, #1
|
||||
str r0, [sp, #0x24]
|
||||
b _02252058
|
||||
_02252054:
|
||||
mov r0, #2
|
||||
str r0, [sp, #0x24]
|
||||
_02252058:
|
||||
ldr r0, [sp, #0x2c]
|
||||
mov r7, #0
|
||||
add r2, r7, #0
|
||||
cmp r0, #0
|
||||
bls _022520A2
|
||||
_02252062:
|
||||
ldr r0, [sp, #0x20]
|
||||
mov r1, #0x14
|
||||
ldrb r3, [r0, r2]
|
||||
ldr r0, [r6, #4]
|
||||
mul r1, r3
|
||||
add r5, r0, r1
|
||||
ldrb r1, [r5, #0xf]
|
||||
ldr r0, [sp, #0x24]
|
||||
cmp r0, r1
|
||||
bne _02252096
|
||||
ldrb r0, [r5, #1]
|
||||
cmp r0, #0
|
||||
beq _0225208C
|
||||
cmp r0, #0xc
|
||||
beq _0225208C
|
||||
cmp r0, #0xb
|
||||
beq _0225208C
|
||||
cmp r0, #0xa
|
||||
beq _0225208C
|
||||
cmp r0, #0xe
|
||||
bne _02252096
|
||||
_0225208C:
|
||||
add r1, r7, #1
|
||||
add r0, r7, #0
|
||||
lsl r1, r1, #0x18
|
||||
lsr r7, r1, #0x18
|
||||
strb r3, [r4, r0]
|
||||
_02252096:
|
||||
add r0, r2, #1
|
||||
lsl r0, r0, #0x18
|
||||
lsr r2, r0, #0x18
|
||||
ldr r0, [sp, #0x2c]
|
||||
cmp r2, r0
|
||||
blo _02252062
|
||||
_022520A2:
|
||||
cmp r7, #0
|
||||
bne _022520B8
|
||||
ldr r0, [sp, #0x20]
|
||||
bl FreeToHeap
|
||||
add r0, r4, #0
|
||||
bl FreeToHeap
|
||||
add sp, #0x30
|
||||
mov r0, #0
|
||||
pop {r3, r4, r5, r6, r7, pc}
|
||||
_022520B8:
|
||||
ldr r0, [sp, #0x20]
|
||||
ldr r2, [sp, #0x2c]
|
||||
mov r1, #0xff
|
||||
bl MI_CpuFill8
|
||||
ldr r0, [sp, #8]
|
||||
ldr r0, [r0, #0x38]
|
||||
bl Save_SysInfo_RTC_Get
|
||||
ldr r0, [r0, #0x14]
|
||||
lsl r0, r0, #0x18
|
||||
lsr r0, r0, #0x18
|
||||
str r0, [sp, #0x14]
|
||||
ldr r0, [sp, #0x1c]
|
||||
bl Save_VarsFlags_CheckBugContestFlag
|
||||
lsl r0, r0, #0x18
|
||||
lsr r0, r0, #0x18
|
||||
str r0, [sp, #0x10]
|
||||
mov r0, #0
|
||||
str r0, [sp, #0x28]
|
||||
ldr r0, [sp, #0x18]
|
||||
ldr r1, [sp, #0x24]
|
||||
bl sub_0202AAD4
|
||||
cmp r0, r7
|
||||
bne _022520F6
|
||||
ldr r0, [sp, #0x18]
|
||||
ldr r1, [sp, #0x24]
|
||||
bl sub_0202AA9C
|
||||
_022520F6:
|
||||
mov r5, #0
|
||||
cmp r7, #0
|
||||
bls _02252164
|
||||
_022520FC:
|
||||
ldrb r2, [r4, r5]
|
||||
mov r1, #0x14
|
||||
ldr r0, [r6, #4]
|
||||
mul r1, r2
|
||||
add r0, r0, r1
|
||||
ldrh r1, [r0, #6]
|
||||
ldr r0, [sp, #0xc]
|
||||
cmp r0, r1
|
||||
beq _0225215A
|
||||
ldr r0, [sp, #0x18]
|
||||
ldr r1, [sp, #0x24]
|
||||
bl sub_0202AA44
|
||||
cmp r0, #0
|
||||
bne _0225215A
|
||||
ldrb r0, [r4, r5]
|
||||
cmp r0, #8
|
||||
bne _02252134
|
||||
ldr r0, [sp, #0x14]
|
||||
bl sub_02095FF8
|
||||
cmp r0, #0
|
||||
bne _0225215A
|
||||
ldr r0, [sp, #0x1c]
|
||||
bl Save_VarsFlags_IsInRocketTakeover
|
||||
cmp r0, #0
|
||||
bne _0225215A
|
||||
_02252134:
|
||||
ldrb r1, [r4, r5]
|
||||
mov r2, #0x14
|
||||
ldr r0, [r6, #4]
|
||||
mul r2, r1
|
||||
add r0, r0, r2
|
||||
ldrh r0, [r0, #6]
|
||||
cmp r0, #0x60
|
||||
bne _0225214A
|
||||
ldr r0, [sp, #0x10]
|
||||
cmp r0, #0
|
||||
bne _0225215A
|
||||
_0225214A:
|
||||
ldr r0, [sp, #0x28]
|
||||
add r2, r0, #0
|
||||
add r2, r2, #1
|
||||
lsl r2, r2, #0x18
|
||||
lsr r2, r2, #0x18
|
||||
str r2, [sp, #0x28]
|
||||
ldr r2, [sp, #0x20]
|
||||
strb r1, [r2, r0]
|
||||
_0225215A:
|
||||
add r0, r5, #1
|
||||
lsl r0, r0, #0x18
|
||||
lsr r5, r0, #0x18
|
||||
cmp r5, r7
|
||||
blo _022520FC
|
||||
_02252164:
|
||||
ldr r0, [sp, #0x28]
|
||||
cmp r0, #0
|
||||
beq _022521AC
|
||||
bl MTRandom
|
||||
ldr r2, [sp, #0x28]
|
||||
mov r1, #0x64
|
||||
mul r1, r2
|
||||
bl _u32_div_f
|
||||
add r0, r1, #0
|
||||
mov r1, #0x64
|
||||
bl _u32_div_f
|
||||
add r1, r0, #0
|
||||
lsl r1, r1, #0x10
|
||||
lsr r1, r1, #0x10
|
||||
mov r0, #0
|
||||
lsl r1, r1, #0x18
|
||||
str r0, [sp]
|
||||
lsr r2, r1, #0x18
|
||||
str r0, [sp, #4]
|
||||
ldr r1, [sp, #0x20]
|
||||
ldr r0, [sp, #8]
|
||||
ldrb r1, [r1, r2]
|
||||
ldr r2, [sp, #0x24]
|
||||
add r3, r7, #0
|
||||
bl ov02_02251EB8
|
||||
ldr r0, [sp, #8]
|
||||
bl sub_02092DF4
|
||||
ldr r0, [sp, #8]
|
||||
mov r1, #1
|
||||
bl ov02_022522AC
|
||||
_022521AC:
|
||||
ldr r0, [sp, #0x20]
|
||||
bl FreeToHeap
|
||||
add r0, r4, #0
|
||||
bl FreeToHeap
|
||||
ldr r0, [sp, #0x28]
|
||||
add sp, #0x30
|
||||
pop {r3, r4, r5, r6, r7, pc}
|
||||
}
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
static u32 ov02_022521C0(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId) {
|
||||
u8 r6 = ov02_02252218(gearPhone, phoneBook, mapId);
|
||||
if (r6 == 0xFF) {
|
||||
return FALSE;
|
||||
}
|
||||
ov02_02251EB8(gearPhone, ov02_02253C84[r6].unk0, 0xFF, 0, 3, ov02_02253C84[r6].unk2);
|
||||
sub_02092DF4(gearPhone);
|
||||
gearPhone->unk_var7 = r6;
|
||||
return ov02_02253C84[r6].unk4 + 1;
|
||||
}
|
||||
|
||||
// FIXME: This is a fakematch from decomp.me, it doesn't match locally without the label https://decomp.me/scratch/YdDak
|
||||
static u8 ov02_02252218(GearPhoneRingManager *gearPhone, PhoneBook *phoneBook, u32 mapId) {
|
||||
u8 *ptr = AllocFromHeapAtEnd(HEAP_ID_4, 13);
|
||||
MI_CpuFill8(ptr, 0, 13);
|
||||
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < 13; i++) {
|
||||
if (sub_0202F08C(gearPhone->savingsData, i) == 0) {
|
||||
continue;
|
||||
}
|
||||
PhoneBookEntry *entry = &phoneBook->entries[ov02_02253C84[i].unk0];
|
||||
if (entry->unk0 == 6) {
|
||||
if (GSPlayerMisc_IsGearNumberRegistered(gearPhone->pokegearData, 6) != 0xFF) {
|
||||
// had to do this to match
|
||||
goto LABEL;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else if (entry->mapId == mapId) {
|
||||
continue;
|
||||
}
|
||||
LABEL:
|
||||
ptr[cnt++] = i;
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
FreeToHeap(ptr);
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
u8 ret = ptr[LCRandom() % cnt];
|
||||
FreeToHeap(ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ov02_022522AC(GearPhoneRingManager *gearPhone, BOOL a1) {
|
||||
GearPhone_ToggleRinging(gearPhone, a1);
|
||||
}
|
||||
|
||||
int GetRadioMusicPlayingSeq(void) {
|
||||
u16 seq = SndRadio_GetSeqNo();
|
||||
switch (seq) {
|
||||
case SEQ_GS_RADIO_MARCH:
|
||||
case SEQ_GS_P_RADIO_MARCH:
|
||||
return 1;
|
||||
case SEQ_GS_RADIO_KOMORIUTA:
|
||||
case SEQ_GS_P_RADIO_KOMORIUTA:
|
||||
return 2;
|
||||
case SEQ_GS_RADIO_R_101:
|
||||
return 3;
|
||||
case SEQ_GS_RADIO_R_201:
|
||||
return 4;
|
||||
case SEQ_GS_RADIO_UNKNOWN:
|
||||
return 6;
|
||||
case SEQ_GS_HUE:
|
||||
case SEQ_GS_P_HUE:
|
||||
return 5;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
#include "msgdata/msg/msg_0066_D23R0102.h"
|
||||
#include "msgdata/msg/msg_0096_D31R0201.h"
|
||||
#include "overlay_2/overlay_02_02251E74.h"
|
||||
#include "overlay_2/overlay_02_gear_phone.h"
|
||||
|
||||
#include "bag.h"
|
||||
#include "bug_contest.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,9 @@
|
||||
#include "frontier/frontier.h"
|
||||
#include "msgdata/msg.naix"
|
||||
#include "msgdata/msg/msg_0202.h"
|
||||
#include "overlay_2/event_cutscene.h"
|
||||
#include "overlay_2/overlay_02_02251E74.h"
|
||||
#include "overlay_2/overlay_02_gear_phone.h"
|
||||
|
||||
#include "alph_puzzle.h"
|
||||
#include "bg_window.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "constants/sndseq.h"
|
||||
|
||||
#include "overlay_2/overlay_02_02251E74.h"
|
||||
#include "overlay_2/overlay_02_gear_phone.h"
|
||||
|
||||
#include "field_system.h"
|
||||
#include "map_header.h"
|
||||
|
Loading…
Reference in New Issue
Block a user