diff --git a/asm/non_matching/playerUtils/sub_080784E4.inc b/asm/non_matching/playerUtils/sub_080784E4.inc index 40c47409..14b6afbb 100644 --- a/asm/non_matching/playerUtils/sub_080784E4.inc +++ b/asm/non_matching/playerUtils/sub_080784E4.inc @@ -4,7 +4,7 @@ mov r6, sb mov r5, r8 push {r5, r6, r7} - ldr r0, _080784FC @ =gUnk_03003DF0 + ldr r0, _080784FC @ =gPossibleInteraction ldrb r1, [r0] mov r8, r0 cmp r1, #0 @@ -12,7 +12,7 @@ ldr r0, [r0, #4] b _0807876A .align 2, 0 -_080784FC: .4byte gUnk_03003DF0 +_080784FC: .4byte gPossibleInteraction _08078500: ldr r2, _08078528 @ =gPlayerState adds r0, r2, #0 @@ -74,14 +74,14 @@ _08078598: movs r0, #0xff mov r1, r8 strb r0, [r1, #3] - ldr r0, _080785AC @ =gUnk_0811C000 + ldr r0, _080785AC @ =gNoInteraction str r0, [r1, #4] movs r1, #1 mov r2, r8 strb r1, [r2] b _0807876A .align 2, 0 -_080785AC: .4byte gUnk_0811C000 +_080785AC: .4byte gNoInteraction _080785B0: ldr r0, [r2, #0x30] movs r1, #0x80 @@ -104,21 +104,21 @@ _080785D2: ldrb r0, [r3, #0x14] movs r1, #6 ands r1, r0 - ldr r0, _080785E8 @ =gUnk_0811C00C + ldr r0, _080785E8 @ =gPlayerInteractHitboxOffsetNormal adds r2, r1, r0 - ldr r5, _080785EC @ =gUnk_03003DF0 + ldr r5, _080785EC @ =gPossibleInteraction mov r8, r5 b _080785FE .align 2, 0 _080785E4: .4byte gPlayerEntity -_080785E8: .4byte gUnk_0811C00C -_080785EC: .4byte gUnk_03003DF0 +_080785E8: .4byte gPlayerInteractHitboxOffsetNormal +_080785EC: .4byte gPossibleInteraction _080785F0: ldr r3, _08078624 @ =gPlayerEntity ldrb r0, [r3, #0x14] movs r1, #6 ands r1, r0 - ldr r0, _08078628 @ =gUnk_0811C014 + ldr r0, _08078628 @ =gPlayerInteractHitboxOffsetMinish adds r2, r1, r0 movs r7, #0 _080785FE: @@ -138,12 +138,12 @@ _080785FE: adds r1, r1, r0 mov sb, r1 movs r6, #0 - ldr r5, _0807862C @ =gUnk_03003DF8 + ldr r5, _0807862C @ =gInteractableObjects b _08078724 .align 2, 0 _08078624: .4byte gPlayerEntity -_08078628: .4byte gUnk_0811C014 -_0807862C: .4byte gUnk_03003DF8 +_08078628: .4byte gPlayerInteractHitboxOffsetMinish +_0807862C: .4byte gInteractableObjects _08078630: ldrb r1, [r5] movs r3, #1 @@ -264,7 +264,7 @@ _08078714: lsls r0, r6, #1 adds r0, r0, r6 lsls r0, r0, #2 - ldr r3, _08078754 @ =gUnk_03003DF8 + ldr r3, _08078754 @ =gInteractableObjects adds r5, r0, r3 _08078724: ldr r2, [r5, #8] @@ -292,12 +292,12 @@ _0807873A: str r0, [r5, #4] b _08078762 .align 2, 0 -_08078754: .4byte gUnk_03003DF8 +_08078754: .4byte gInteractableObjects _08078758: movs r0, #0xff mov r1, r8 strb r0, [r1, #3] - ldr r0, _08078774 @ =gUnk_0811C000 + ldr r0, _08078774 @ =gNoInteraction str r0, [r1, #4] _08078762: movs r0, #1 @@ -311,5 +311,5 @@ _0807876A: mov sl, r5 pop {r4, r5, r6, r7, pc} .align 2, 0 -_08078774: .4byte gUnk_0811C000 +_08078774: .4byte gNoInteraction .syntax divided diff --git a/include/structures.h b/include/structures.h index 49282475..9a50b897 100644 --- a/include/structures.h +++ b/include/structures.h @@ -259,26 +259,26 @@ typedef struct { } struct_020227E8; typedef struct { - /*0x00*/ u8 unk_0; - /*0x01*/ u8 unk_1; - /*0x02*/ u8 unk_2; - /*0x03*/ u8 unk_3; - /*0x04*/ const u8* unk_4; + /*0x00*/ u8 ignoreLayer; /* if bit 0 set, skip layer check for collision */ + /*0x01*/ u8 interactCondition; + /*0x02*/ u8 interactDirections; /* lower 4 bits determine Link's allowed facing directions to interact, 0 to allow (0000WSEN) */ + /*0x03*/ u8 kinstoneId; + /*0x04*/ const u8* customHitbox; /* if set, array contains x, y, width and height */ /*0x08*/ Entity* entity; -} struct_03003DF8; +} InteractableObject; typedef struct { - /*0x00*/ u8 unk_0; - /*0x01*/ u8 unk_1; - /*0x02*/ u8 unk_2; // TODO kinstoneId, sub_0801DFB4 - /*0x03*/ u8 unk_3; - /*0x04*/ struct_03003DF8* unk_4; - /*0x08*/ struct_03003DF8 array[0x20]; -} struct_03003DF0; + /*0x00*/ u8 isUpdated; + /*0x01*/ u8 unused; + /*0x02*/ u8 kinstoneId; + /*0x03*/ u8 currentIndex; /* index of currentObject in canditate list, or 0xFF */ + /*0x04*/ InteractableObject* currentObject; + /*0x08*/ InteractableObject candidates[0x20]; /* contains the loaded NPCs, key doors, windcrests and other objects */ +} PossibleInteraction; -static_assert(sizeof(struct_03003DF0) == 0x188); +static_assert(sizeof(PossibleInteraction) == 0x188); -extern struct_03003DF0 gUnk_03003DF0; +extern PossibleInteraction gPossibleInteraction; typedef struct { u8 numTiles; diff --git a/linker.ld b/linker.ld index 17221aa0..479e7328 100644 --- a/linker.ld +++ b/linker.ld @@ -143,8 +143,8 @@ SECTIONS { . = 0x00003DD0; gUpdateContext = .; . = 0x00003DE0; gUnk_03003DE0 = .; . = 0x00003DE4; gUnk_03003DE4 = .; - . = 0x00003DF0; gUnk_03003DF0 = .; - . = 0x00003DF8; gUnk_03003DF8 = .; + . = 0x00003DF0; gPossibleInteraction = .; + . = 0x00003DF8; gInteractableObjects = .; . = 0x00003F80; gPlayerState = .; . = 0x00004030; gDiggingCaveEntranceTransition = .; . = 0x00004040; gPlayerClones = .; diff --git a/src/common.c b/src/common.c index d55dbf54..24dba48d 100644 --- a/src/common.c +++ b/src/common.c @@ -624,7 +624,7 @@ void sub_0801DFB4(Entity* entity, u32 textIndex, u32 a3, u32 a4) { gFuseInfo._8 = a3; gFuseInfo._a = a4; gFuseInfo.ent = entity; - gFuseInfo.kinstoneId = gUnk_03003DF0.unk_2; + gFuseInfo.kinstoneId = gPossibleInteraction.kinstoneId; if (entity != NULL) { gFuseInfo.prevUpdatePriority = entity->updatePriority; entity->updatePriority = 2; @@ -845,8 +845,8 @@ void NotifyFusersOnFusionDone(u32 kinstoneId) { gSave.fuserOffers[tmp] = 0xf2; } for (index = 0; index < 0x20; index++) { - if (kinstoneId == gUnk_03003DF0.array[index].unk_3) { - gUnk_03003DF0.array[index].unk_3 = 0xf1; + if (kinstoneId == gPossibleInteraction.candidates[index].kinstoneId) { + gPossibleInteraction.candidates[index].kinstoneId = 0xf1; } } } diff --git a/src/interrupts.c b/src/interrupts.c index 33a7d5e7..63abe0ea 100644 --- a/src/interrupts.c +++ b/src/interrupts.c @@ -240,7 +240,7 @@ static void HandlePlayerLife(Entity* this) { if (sub_08079B24() == 0) sub_08079708(this); - gUnk_03003DF0.unk_0 = 0; + gPossibleInteraction.isUpdated = 0; if (gPlayerState.field_0x27[0] != 0) gPlayerState.field_0x27[0]--; diff --git a/src/menu/kinstoneMenu.c b/src/menu/kinstoneMenu.c index 8fa799bb..97d49044 100644 --- a/src/menu/kinstoneMenu.c +++ b/src/menu/kinstoneMenu.c @@ -606,8 +606,8 @@ u32 sub_080A4418(u32 param_1, u32 param_2) { } void KinstoneMenu_080A4468(void) { - gUnk_03003DF0.unk_2 = 0; - gUnk_03003DF0.unk_4->unk_3 = 0; + gPossibleInteraction.kinstoneId = 0; + gPossibleInteraction.currentObject->kinstoneId = 0; NotifyFusersOnFusionDone(gFuseInfo.kinstoneId); RemoveKinstoneFromBag(gKinstoneMenu.unk2a); } diff --git a/src/object/bossDoor.c b/src/object/bossDoor.c index 4f9a5220..62ce4aeb 100644 --- a/src/object/bossDoor.c +++ b/src/object/bossDoor.c @@ -27,7 +27,7 @@ typedef struct { } BossDoorEntity; extern bool32 gUnk_02036BB8; -extern const u8 gUnk_0811F740[]; +extern const u8 gLockedDoorInteractDirections[]; void sub_0808C500(BossDoorEntity*); void sub_0808C4BC(BossDoorEntity*); @@ -70,7 +70,7 @@ void BossDoor_Init(BossDoorEntity* this) { super->spriteSettings.draw = 1; sub_0808C500(this); sub_08078800(super); - sub_08078850(super, 0, gUnk_0811F740[this->unk_76], 0); + sub_08078850(super, 0, gLockedDoorInteractDirections[this->unk_76], 0); break; case 1: super->action = 4; diff --git a/src/object/cameraTarget.c b/src/object/cameraTarget.c index c86735ac..88831f94 100644 --- a/src/object/cameraTarget.c +++ b/src/object/cameraTarget.c @@ -57,7 +57,7 @@ void CameraTarget(Entity* this) { break; } default: - if (gUnk_03003DF0.unk_4->unk_3 == KINSTONE_32) { + if (gPossibleInteraction.currentObject->kinstoneId == KINSTONE_32) { if (CheckKinstoneFused(KINSTONE_32) == 0) { uVar2 = 0; break; @@ -103,9 +103,9 @@ void CameraTarget_Action1(Entity* this) { if (this->timer) { this->timer--; } else { - if ((gUnk_03003DF0.unk_4->entity != NULL) && ((u8)(gUnk_03003DF0.unk_4->unk_3 - 1) < 100)) { - this->child = gUnk_03003DF0.unk_4->entity; - this->interactType = gUnk_03003DF0.unk_3; + if ((gPossibleInteraction.currentObject->entity != NULL) && ((u8)(gPossibleInteraction.currentObject->kinstoneId - 1) < 100)) { + this->child = gPossibleInteraction.currentObject->entity; + this->interactType = gPossibleInteraction.currentIndex; sub_08083A40(this); } } @@ -120,7 +120,7 @@ void CameraTarget_Action2(Entity* this) { const KinstoneWorldEvent* ptr; if ((this->type != 1) && - (((u8)(gUnk_03003DF0.unk_4->unk_3 - 1) >= 100 || (this->child != gUnk_03003DF0.unk_4->entity)))) { + (((u8)(gPossibleInteraction.currentObject->kinstoneId - 1) >= 100 || (this->child != gPossibleInteraction.currentObject->entity)))) { sub_080838DC(this); } else { this->x = this->child->x; @@ -129,7 +129,7 @@ void CameraTarget_Action2(Entity* this) { if (this->frame == 1) { this->frame = 0; if (this->type == 0) { - bVar2 = gUnk_03003DF0.unk_4->unk_3; + bVar2 = gPossibleInteraction.currentObject->kinstoneId; } else { bVar2 = this->type2; } diff --git a/src/object/itemForSale.c b/src/object/itemForSale.c index e4629fa1..342ba851 100644 --- a/src/object/itemForSale.c +++ b/src/object/itemForSale.c @@ -160,7 +160,7 @@ void sub_080819B4(ItemForSaleEntity* this) { void sub_08081A5C(ItemForSaleEntity* this) { u32 tmp = sub_080787D8(super); if (super->timer == 1) { - gUnk_03003DF0.array[tmp].unk_2 = 0; + gPossibleInteraction.candidates[tmp].interactDirections = 0; } } diff --git a/src/object/lockedDoor.c b/src/object/lockedDoor.c index 1b704f50..91cc9ea7 100644 --- a/src/object/lockedDoor.c +++ b/src/object/lockedDoor.c @@ -81,7 +81,7 @@ const struct_0811F730 gUnk_0811F730[] = { { { 8, 8 }, { 8, -8 } }, }; -const u8 gUnk_0811F740[] = { +const u8 gLockedDoorInteractDirections[] = { 0xBE, 0x7D, 0xEB, @@ -134,7 +134,7 @@ void LockedDoor_Init(Entity* this) { } else { this->action = 8; sub_080787CC(this); - sub_08078850(this, 0, gUnk_0811F740[this->field_0x7c.BYTES.byte2], 0); + sub_08078850(this, 0, gLockedDoorInteractDirections[this->field_0x7c.BYTES.byte2], 0); } } else { DeleteThisEntity(); diff --git a/src/playerUtils.c b/src/playerUtils.c index c8ed16b7..f6745116 100644 --- a/src/playerUtils.c +++ b/src/playerUtils.c @@ -73,7 +73,7 @@ bool32 sub_0807BF88(u32, u32, RoomResInfo*); void sub_0807BFD0(void); void ForceSetPlayerState(u32 framestate); -struct_03003DF8* sub_080784E4(void); +InteractableObject* sub_080784E4(void); u32 sub_08079778(void); u32 GetPlayerTilePos(void); @@ -658,14 +658,17 @@ bool32 (*const gPlayerChargeActions[])(ChargeState*) = { sub_08078008, sub_08078124, sub_08078140, sub_08078070, sub_080780E0, sub_08078108, }; -const struct_03003DF8 gUnk_0811C000 = { - 0, 255, 0, 0, 0, 0, +const InteractableObject gNoInteraction = { + 0, 0xFF, 0, 0, 0, 0, }; -const u8 gUnk_0811C00C[] = { - 0, 238, 14, 255, 0, 10, 241, 255, + +// for shifting the hitbox in which entities can be interacted with in Link's facing direction +// from left to right: north, east, south and west in x, y pairs +const s8 gPlayerInteractHitboxOffsetNormal[] = { + 0, -18, 14, -1, 0, 10, -15, -1, }; -const u8 gUnk_0811C014[] = { - 0, 242, 10, 255, 0, 6, 245, 255, +const s8 gPlayerInteractHitboxOffsetMinish[] = { + 0, -14, 10, -1, 0, 6, -11, -1, }; const u8 gUnk_0811C01C[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 3, 4, 3, 0, 1, 2, 0, 3, 3, 4, 3, 10, 15, 0, 0, 0, @@ -971,7 +974,7 @@ void ForceSetPlayerState(u32 framestate) { void sub_08078180(void) { u8 uVar1; u8 uVar3; - struct_03003DF8* ptr; + InteractableObject* ptr; if (gUnk_0200AF00.unk_2f != 0) return; @@ -992,7 +995,7 @@ void sub_08078180(void) { ptr = sub_080784E4(); if (ptr->entity->interactType == 0) { - switch (ptr->unk_1) { + switch (ptr->interactCondition) { case 1: case 7: uVar1 = 7; @@ -1088,11 +1091,11 @@ bool32 sub_080782C0(void) { return FALSE; } } - if (((gPlayerState.playerInput.newInput & PLAYER_INPUT_1000) != 0) && ((u8)(gUnk_03003DF0.unk_4->unk_3 - 1) < 100)) { + if (((gPlayerState.playerInput.newInput & PLAYER_INPUT_1000) != 0) && ((u8)(gPossibleInteraction.currentObject->kinstoneId - 1) < 100)) { AddKinstoneToBag(0); if (gSave.kinstoneAmounts[0] != 0) { - gUnk_03003DF0.unk_2 = gUnk_03003DF0.unk_4->unk_3; - gUnk_03003DF0.unk_4->entity->interactType = 2; + gPossibleInteraction.kinstoneId = gPossibleInteraction.currentObject->kinstoneId; + gPossibleInteraction.currentObject->entity->interactType = 2; gPlayerState.queued_action = PLAYER_08070E9C; } else { CreateEzloHint(TEXT_INDEX(TEXT_EZLO, 0x65), 0); @@ -1103,7 +1106,7 @@ bool32 sub_080782C0(void) { if ((gPlayerState.playerInput.newInput & (PLAYER_INPUT_80 | PLAYER_INPUT_8)) == 0) { return FALSE; } - switch (gUnk_03003DF0.unk_4->unk_1) { + switch (gPossibleInteraction.currentObject->interactCondition) { default: case 0: return TRUE; @@ -1117,7 +1120,7 @@ bool32 sub_080782C0(void) { case 5: case 7: entity->interactType = 1; - gUnk_03003DF0.unk_2 = 0; + gPossibleInteraction.kinstoneId = 0; return TRUE; case 8: if (gRoomVars.shopItemType == 0) { @@ -1132,11 +1135,11 @@ bool32 sub_080782C0(void) { } void sub_080784C8(void) { - MemClear(&gUnk_03003DF0, sizeof(gUnk_03003DF0)); - gUnk_03003DF0.unk_4 = (struct_03003DF8*)&gUnk_0811C000; + MemClear(&gPossibleInteraction, sizeof(gPossibleInteraction)); + gPossibleInteraction.currentObject = (InteractableObject*)&gNoInteraction; } -ASM_FUNC("asm/non_matching/playerUtils/sub_080784E4.inc", struct_03003DF8* sub_080784E4(void)) +ASM_FUNC("asm/non_matching/playerUtils/sub_080784E4.inc", InteractableObject* sub_080784E4(void)) void sub_08078778(Entity* ent) { sub_0807887C(ent, 1, 0); @@ -1175,7 +1178,7 @@ s32 sub_080787D8(Entity* ent) { iVar1 = sub_0807887C(ent, 8, 0); if (iVar1 >= 0) { - gUnk_03003DF0.array[iVar1].unk_2 = 0xbe; + gPossibleInteraction.candidates[iVar1].interactDirections = 0xbe; } return iVar1; } @@ -1185,7 +1188,7 @@ s32 sub_08078800(Entity* ent) { iVar1 = sub_0807887C(ent, 6, 0); if (iVar1 >= 0) { - gUnk_03003DF0.array[iVar1].unk_2 = 0xbe; + gPossibleInteraction.candidates[iVar1].interactDirections = 0xbe; } return iVar1; } @@ -1195,7 +1198,7 @@ s32 sub_08078828(Entity* ent) { iVar1 = sub_0807887C(ent, 3, 0); if (iVar1 >= 0) { - gUnk_03003DF0.array[iVar1].unk_2 = 0xbe; + gPossibleInteraction.candidates[iVar1].interactDirections = 0xbe; } return iVar1; } @@ -1205,9 +1208,9 @@ void sub_08078850(Entity* arg0, u32 arg1, u32 arg2, const void* arg3) { iVar1 = sub_08078904(arg0); if (iVar1 >= 0) { - gUnk_03003DF0.array[iVar1].unk_0 = arg1; - gUnk_03003DF0.array[iVar1].unk_2 = arg2; - gUnk_03003DF0.array[iVar1].unk_4 = arg3; + gPossibleInteraction.candidates[iVar1].ignoreLayer = arg1; + gPossibleInteraction.candidates[iVar1].interactDirections = arg2; + gPossibleInteraction.candidates[iVar1].customHitbox = arg3; } } @@ -1219,9 +1222,9 @@ s32 sub_0807887C(Entity* entity, u32 param_2, u32 param_3) { index = sub_08078904(0); } if (index >= 0) { - gUnk_03003DF0.array[index].entity = entity; - gUnk_03003DF0.array[index].unk_1 = param_2; - gUnk_03003DF0.array[index].unk_3 = param_3; + gPossibleInteraction.candidates[index].entity = entity; + gPossibleInteraction.candidates[index].interactCondition = param_2; + gPossibleInteraction.candidates[index].kinstoneId = param_3; } if (param_3 != 0) { Entity* entity = FindEntityByID(OBJECT, CAMERA_TARGET, 6); @@ -1236,7 +1239,7 @@ s32 sub_0807887C(Entity* entity, u32 param_2, u32 param_3) { void sub_080788E0(Entity* entity) { s32 index = sub_08078904(entity); if (index > -1) { - MemClear(&gUnk_03003DF0.array[index], 0xc); + MemClear(&gPossibleInteraction.candidates[index], sizeof(InteractableObject)); } } @@ -1244,7 +1247,7 @@ void sub_080788E0(Entity* entity) { s32 sub_08078904(Entity* entity) { u32 index; for (index = 0; index < 0x20; index++) { - if (entity == gUnk_03003DF0.array[index].entity) { + if (entity == gPossibleInteraction.candidates[index].entity) { return index; } } @@ -1376,7 +1379,7 @@ void ClearPlayerState(void) { gPlayerState.spriteOffsetY = 0; gPlayerState.field_0x3c = 0; MemFill32(0xffffffff, gPlayerState.path_memory, 0x40); - MemClear(&gUnk_03003DF0, sizeof(gUnk_03003DF0)); + MemClear(&gPossibleInteraction, sizeof(gPossibleInteraction)); } void UpdateCarriedObject(void) {