diff options
| author | octorock <79596758+octorock@users.noreply.github.com> | 2022-11-06 10:20:34 +0000 |
|---|---|---|
| committer | octorock <79596758+octorock@users.noreply.github.com> | 2022-11-06 10:45:14 +0000 |
| commit | 6531b8828535d6cb347a6d008feb7b1fcfdd4f9a (patch) | |
| tree | 25af23b18664b7e815dbf0c8aa08a60acfc03361 /src | |
| parent | 2ddfdc3e4f1ac9cfb414592b66c9e39931a57e2b (diff) | |
Match UpdatePlayerCollision
Diffstat (limited to 'src')
| -rw-r--r-- | src/beanstalkSubtask.c | 449 | ||||
| -rw-r--r-- | src/common.c | 12 | ||||
| -rw-r--r-- | src/enemy/gleerok.c | 22 |
3 files changed, 467 insertions, 16 deletions
diff --git a/src/beanstalkSubtask.c b/src/beanstalkSubtask.c index ceb5a7c3..d09ea3cd 100644 --- a/src/beanstalkSubtask.c +++ b/src/beanstalkSubtask.c @@ -57,6 +57,25 @@ void sub_0801AB08(u16*, LayerStruct*); u32 sub_0801AC68(u32 position, u32 data); +extern u32 sub_0807BDB8(Entity* this, u32 param_2); +extern void sub_0804B388(u32 a1, u32 a2); +extern u32 sub_080A7CFC(u32 a1, u32 tmp); // TODO does this really have a second param? +extern void OpenSmallChest(u32 pos, u32 layer); +extern bool32 sub_08079778(); +extern Transition* sub_08080734(u32, u32); + +extern const s16 gUnk_080B4490[]; +extern const s16 gUnk_080B4468[]; +extern const s16 gUnk_080B4478[]; + +bool32 sub_0801A2B0(LayerStruct* layer, u32 position, u32 collisionType); +bool32 sub_0801A9F0(u32 param_1, u32 param_2, u32 param_3); +u32 sub_0801A570(Entity*, u32); +bool32 sub_0801A458(LayerStruct* layer, u32 position, u32 collisionType); +bool32 sub_0801A370(LayerStruct* layer, u32 position); +u32 sub_0801A8D0(Entity* this, u32 param_2); +extern void sub_080001D0(u32, u32, u32); + void sub_0801967C(void) { gUnk_080B4458[gMenu.overlayType](); } @@ -140,7 +159,433 @@ void sub_080197D4(struct_08109194* param_1) { } // Has ifdefs for other variants -ASM_FUNC("asm/non_matching/beanstalkSubtask/UpdatePlayerCollision.inc", void UpdatePlayerCollision()) +u32 UpdatePlayerCollision(void) { + u32 direction; + u32 tileType; + LayerStruct* layer; + Transition* transition; + Entity* pushedBlock; + Entity* player; + u32 position; + u32 index; + const s16* ptr1; + const s16* ptr2; + s32 tmp1; + u32 tmp2; + u32 tmp3; + // There are some weird assignment necessary to access gPlayerEntity.animationState correctly. + u32 animationState1; + u32 animationState2; + u32 animationState3; + + if (gPlayerState.framestate == 0) { + tmp1 = gPlayerState.framestate_last; + } else { + tmp1 = gPlayerState.framestate; + } + + switch (tmp1) { + case 3: + return 0; + case 0x12: + return 0; + case 0x16: + return 0; + } + + if (gPlayerState.dash_state != 0 || gPlayerEntity.action == PLAYER_CLIMB) { + direction = gPlayerEntity.direction; + } else { + direction = gPlayerState.direction; + } + if (((direction & 0x83) == 0) && (gPlayerState.field_0xa == 0)) { + index = sub_0807BDB8(&gPlayerEntity, direction >> 2); + if (index != 0xff && (gRoomControls.scroll_flags & 4) == 0) { + ptr1 = &gUnk_080B4490[index * 2]; + if (sub_080B1B44(COORD_TO_TILE_OFFSET(&gPlayerEntity, -ptr1[0], -ptr1[1]), gPlayerEntity.collisionLayer) == + 0xff) { + if ((((gPlayerState.flags & 0x10002) != 0) || ((gPlayerState.sword_state & 0x10) != 0)) || + ((sub_080806BC(gPlayerEntity.x.HALF.HI - gRoomControls.origin_x, + gPlayerEntity.y.HALF.HI - gRoomControls.origin_y, index, 5) == 0 && + (((gPlayerState.heldObject != 0 || ((gPlayerState.field_0x1c & 0xf) != 0)) || + (sub_0807BD14(&gPlayerEntity, index) == 0)))))) { + return 3; + } + gPlayerEntity.direction = (index << 3); + return 0xf; + } + } + } + layer = GetLayerByIndex(gPlayerEntity.collisionLayer); + ptr1 = &gUnk_080B4468[gPlayerEntity.animationState & 6]; + position = COORD_TO_TILE_OFFSET(&gPlayerEntity, -ptr1[0], -ptr1[1]); + tileType = GetTileType(position, gPlayerEntity.collisionLayer); + if (tileType < 0x4000) { + direction = sub_080B1B54(tileType); + } else { + direction = tileType; + } + animationState1 = gPlayerEntity.animationState; + animationState2 = animationState1 & 0xff; + + switch (direction) { + case 0x4000: + if (sub_0801A458(layer, position, 2) == 0) { + return 0; + } + layer->mapData[position] = 0x4001 + (gPlayerEntity.animationState >> 1); + if ((gPlayerState.flags & 0x80) != 0) { + gPlayerState.pushedObject = 0xc0; + } else { + gPlayerState.pushedObject = 0xa0; + } + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x28: + if ((gPlayerState.flags & 0x80) != 0) { + return 0; + } + gPlayerEntity.action = gPlayerEntity.action; + if (gPlayerState.field_0xa != 0) { + return 0; + } + if ((Direction8FromAnimationState(gPlayerEntity.animationState)) - gPlayerState.direction != 0) { + return 0; + } + if ((gPlayerEntity.direction & 0x80) != 0) { + return 0; + } + if (sub_080B1B44(position, gPlayerEntity.collisionLayer) != 0xf) { + return 0; + } + if (sub_08079778() == 0) { + return 0; + } + + ptr1 = &gUnk_080B4478[gPlayerEntity.animationState & 6]; + transition = sub_08080734((gPlayerEntity.x.HALF.HI - gRoomControls.origin_x) + ptr1[0], + (gPlayerEntity.y.HALF.HI - gRoomControls.origin_y) + ptr1[1]); + if (transition == NULL) { + return 0; + } + if ((gPlayerEntity.animationState & 2) != 0) { + gPlayerEntity.y.HALF.HI = gRoomControls.origin_y + transition->startY + 6; + } else { + gPlayerEntity.x.HALF.HI = gRoomControls.origin_x + transition->startX; + } + sub_08078AC0(4, 0, 1); + return 0; + case 0x401b: + if (sub_0801A2B0(layer, position, 0xb) == 0) { + return 0; + } + layer->mapData[position] = 0x401c + (gPlayerEntity.animationState >> 1); + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + gPlayerEntity.type = 1; + return 1; + case 0x70: + if ((gPlayerState.field_0x35 & 0x80) == 0) { + if ((gPlayerEntity.frame & 1) != 0) { + if (sub_0801A9F0(gPlayerState.field_0x35 << 2, tileType, position) != 0) { + return 1; + } + } + } + return 0; + case 0x3a: + case 0x5b: + case 0x4051: + if ((gPlayerState.flags & 0x80) != 0) { + return 0; + } + if (gPlayerEntity.animationState != 0) { + return 0; + } + gUnk_0200AF00.unk_2d = 4; + if ((gPlayerState.playerInput.newInput & (PLAYER_INPUT_80 | PLAYER_INPUT_40)) == 0) { + return 0; + } + gPlayerState.mobility = 1; + sub_080A7CFC(position, gPlayerEntity.collisionLayer); + return 1; + case 0x1a: + if ((animationState1 & 0xff) != 0) { + return 0; + } + if ((gPlayerState.flags & 0x4080) != 0) { + return 0; + } + gUnk_0200AF00.unk_2d = 6; + if ((gPlayerState.playerInput.newInput & (PLAYER_INPUT_80 | PLAYER_INPUT_8)) == 0) { + return 0; + } + gPlayerState.mobility = 1; + OpenSmallChest(position, gPlayerEntity.collisionLayer); + return 2; + case 0x71: + if (HasDungeonMap() == 0) { + return 0; + } + gUnk_0200AF00.unk_2d = 6; + if ((gPlayerState.playerInput.newInput & (PLAYER_INPUT_80 | PLAYER_INPUT_8)) == 0) { + return 0; + } + gPlayerState.mobility = 1; + sub_0804B388(position, gPlayerEntity.collisionLayer); + return 2; + case 0x3d: + case 0x4040 ... 0x4048: + if ((gPlayerState.flags & 0x4000) != 0) { + return 0; + } + if (sub_08079778() == 0) { + return 0; + } +#if !(defined(EU) || defined(JP)) + if (gPlayerState.field_0xa != 0) { + return 0; + } +#endif + if ((Direction8FromAnimationState(gPlayerEntity.animationState)) - gPlayerState.direction != 0) { + return 0; + } + if ((gPlayerEntity.direction & 0x80) != 0) { + return 0; + } + if (gPlayerEntity.subtimer < 6) { + return 0; + } + gPlayerState.jump_status = 0x81; + gPlayerState.flags |= 0x20; + gPlayerState.queued_action = PLAYER_USEPORTAL; + gPlayerEntity.zVelocity = 0x20000; + COLLISION_OFF(&gPlayerEntity); + return 1; + case 0x400b: + if (sub_0801A2B0(layer, position, 8) == 0) { + return 0; + } + if ((gPlayerEntity.collisionLayer == 3) && (gMapTop.mapData[position] == 0x400b)) { + gMapTop.mapData[position] = 0x400c + (gPlayerEntity.animationState >> 1); + } else { + layer->mapData[position] = 0x400c + (gPlayerEntity.animationState >> 1); + } + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x405a: + if (sub_0801A2B0(layer, position, 2) == 0) { + return 0; + } + layer->mapData[position] = 0x405b + (gPlayerEntity.animationState >> 1); + gPlayerState.pushedObject = 0x98; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x4036: + if (sub_0801A2B0(layer, position, 0xb) == 0) { + return 0; + } + layer->mapData[position] = 0x4037 + (gPlayerEntity.animationState >> 1); + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x403e: + if ((animationState1 & 0xff) != 0) { + return 0; + } + if (((gPlayerState.field_0x35 | gPlayerState.direction) & 0x80) != 0) { + return 0; + } + if ((gPlayerEntity.frame & 2) == 0) { + return 0; + } + layer->mapData[position] = 0x403f; + gPlayerState.pushedObject = 0x82; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x72: + if ((gPlayerState.field_0x35 & 0x80) != 0) { + return 0; + } + if ((gPlayerEntity.frame & 1) == 0) { + return 0; + } + position = sub_0801A570(&gPlayerEntity, 1); + if (position == 0xffff) { + return 0; + } + tmp2 = (position >> 0xc) - 1; + position &= 0xfff; + // TODO convert to for loop? + index = 0; + tmp3 = 0; + while (index < 3) { + if ((((*(u32*)(&(gPlayerClones[0])->field_0x6c)) & (1 << index)) != 0) && + (sub_0801A570(gPlayerClones[index], 0) == position)) { + tmp3++; + } + index++; + } + if (tmp3 < tmp2) { + return 0; + } + pushedBlock = CreateObject(PUSHED_BLOCK, tmp2, 0); + if (pushedBlock == NULL) { + return 0; + } + pushedBlock->direction = Direction8FromAnimationState(gPlayerEntity.animationState); + pushedBlock->x.HALF.HI = ((position & 0xfff & 0x3f) << 4) + 8 + gRoomControls.origin_x; + pushedBlock->y.HALF.HI = ((position & 0xfc0) >> 2) + 8 + gRoomControls.origin_y; + pushedBlock->collisionLayer = gPlayerEntity.collisionLayer; + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = pushedBlock->direction; + return 1; + case 0x402b ... 0x402d: + if (sub_0801A370(layer, position) != 0) { + layer->mapData[position] = 0x4030 + ((gPlayerEntity.animationState & 4) >> 2); + if ((gPlayerState.flags & 0x80) != 0) { + gPlayerState.pushedObject = 0xa0; + } else { + gPlayerState.pushedObject = 0x90; + } + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + } else { + return 0; + } + case 0x404a: + if (sub_0801A458(layer, position, 8) == 0) { + return 0; + } + layer->mapData[position] = 0x404b + (gPlayerEntity.animationState >> 1); + if ((gPlayerState.flags & 0x80) != 0) { + gPlayerState.pushedObject = 0xc0; + } else { + gPlayerState.pushedObject = 0xa0; + } + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x4052: + if (gPlayerState.field_0x35 != 0) { + return 0; + } + SetTile(0x4054, position, gPlayerEntity.collisionLayer); + return 4; + case 0x4053: + if (gPlayerState.field_0x35 != 6) { + return 0; + } + SetTile(0x4054, position, gPlayerEntity.collisionLayer); + return 4; + case 0x4055: + position--; + // fallthrough + case 0x4056: + if (gPlayerState.field_0x35 != 0) { + return 0; + } + if ((gPlayerEntity.y.HALF.HI & 0xf) < 10) { + return 0; + } + for (index = 0; index < 3; index++) { + if (sub_0801A8D0(gPlayerClones[index], 0) == position) { + SetTile(0x4059, position, gPlayerEntity.collisionLayer); + return 4; + } + } + return 0; + case 0x4057: + position -= 0x40; + // fallthrough + case 0x4058: + if (gPlayerState.field_0x35 != 6) { + return 0; + } + if ((gPlayerEntity.x.HALF.HI & 0xf) < 10) { + return 0; + } + for (index = 0; index < 3; index++) { + if (sub_0801A8D0(gPlayerClones[index], 6) == position) { + SetTile(0x4059, position, gPlayerEntity.collisionLayer); + return 4; + } + } + return 0; + case 0x405f: + animationState3 = 2; + animationState3 &= animationState1; + if (animationState3 == 0) { + return 0; + } + if (((gPlayerState.field_0x35 | gPlayerState.direction) & 0x80) != 0) { + return 0; + } + if ((gPlayerEntity.frame & 1) == 0) { + return 0; + } + SetTile(0x4074, position, gPlayerEntity.collisionLayer); + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x407d: + animationState3 = gPlayerEntity.animationState; + if ((animationState2) != 4) { + return 0; + } + if (((gPlayerState.field_0x35 | gPlayerState.direction) & 0x80) != 0) { + return 0; + } + if ((gPlayerEntity.frame & 1) == 0) { + return 0; + } + SetTile(0x4074, position, gPlayerEntity.collisionLayer); + sub_080001D0(0xd, position, gPlayerEntity.collisionLayer); + return 1; + default: + return 0; + } +} bool32 sub_0801A2B0(LayerStruct* layer, u32 position, u32 collisionType) { u16 uVar1; @@ -287,7 +732,7 @@ bool32 sub_0801A4F8(void) { return TRUE; } -ASM_FUNC("asm/non_matching/beanstalkSubtask/sub_0801A570.inc", void sub_0801A570()) +ASM_FUNC("asm/non_matching/beanstalkSubtask/sub_0801A570.inc", u32 sub_0801A570(Entity* a, u32 b)) u32 sub_0801A8D0(Entity* this, u32 param_2) { u16* mapData; diff --git a/src/common.c b/src/common.c index e343aa98..0ad58ee5 100644 --- a/src/common.c +++ b/src/common.c @@ -887,9 +887,15 @@ code0_2: goto code0_2; #endif } -return i; -} -return -1; + +s32 sub_0801E8B0(u32 idx) { + u32 i; + + for (i = 0; i < 18; ++i) { + if (idx == gSave.unk118[i]) + return i; + } + return -1; } // Check conditions, something with kinstones diff --git a/src/enemy/gleerok.c b/src/enemy/gleerok.c index f5afc6c3..3921b18f 100644 --- a/src/enemy/gleerok.c +++ b/src/enemy/gleerok.c @@ -78,7 +78,7 @@ extern void sub_0802EA48(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, extern void sub_0802EA68(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, u32 param_4); extern bool32 sub_0802E7CC(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, u32 param_4); extern bool32 sub_0802EA88(Gleerok_HeapStruct* param_1); -extern bool32 sub_0802E768(Gleerok_HeapStruct* param_1); +extern void sub_0802E768(Gleerok_HeapStruct* param_1); void Gleerok_OnTick(GleerokEntity* this); void Gleerok_OnDeath(GleerokEntity* this); @@ -638,7 +638,7 @@ void sub_0802D86C(GleerokEntity* this) { super->child = enemy; if (enemy) { enemy->parent = super->parent; - super->timer = this->unk_84->filler[0].unk1; + super->timer = this->unk_84->filler[0].unk0.HALF.HI; this->unk_84->ent = super->child; ((GleerokEntity*)super->child)->unk_84 = this->unk_84; } @@ -669,8 +669,8 @@ void sub_0802D86C(GleerokEntity* this) { SoundReq(SFX_BUTTON_PRESS); } } else { - if (super->timer != this->unk_84->filler[0].unk1) { - if (((super->timer - this->unk_84->filler[0].unk1) & 0x1f) > 0x10) { + if (super->timer != this->unk_84->filler[0].unk0.HALF.HI) { + if (((super->timer - this->unk_84->filler[0].unk0.HALF.HI) & 0x1f) > 0x10) { if (++super->frameIndex >= 0x31) { super->frameIndex = 0x28; } @@ -680,7 +680,7 @@ void sub_0802D86C(GleerokEntity* this) { } } - super->timer = this->unk_84->filler[0].unk1; + super->timer = this->unk_84->filler[0].unk0.HALF.HI; } } @@ -1326,8 +1326,8 @@ void sub_0802E768(Gleerok_HeapStruct* param_1) { s32 iVar5; for (uVar4 = 0; uVar4 <= 4; uVar4++) { - bVar3 = param_1->filler[uVar4].unk1; - bVar2 = (bVar3 - param_1->filler[uVar4 + 1].unk1) & 0x1f; + bVar3 = param_1->filler[uVar4].unk0.HALF.HI; + bVar2 = (bVar3 - param_1->filler[uVar4 + 1].unk0.HALF.HI) & 0x1f; if (bVar2 > 0x10) { if (bVar2 <= 0x1e) { @@ -1337,9 +1337,9 @@ void sub_0802E768(Gleerok_HeapStruct* param_1) { bVar3 = (bVar3 - 1) & 0x1f; } - param_1->filler[uVar4].unk1 = bVar3; - bVar3 = param_1->filler2[(uVar4)].unk1; - bVar2 = (bVar3 - param_1->filler2[(uVar4 + 1)].unk1) & 0x1f; + param_1->filler[uVar4].unk0.HALF.HI = bVar3; + bVar3 = param_1->filler2[(uVar4)].unk0.HALF.HI; + bVar2 = (bVar3 - param_1->filler2[(uVar4 + 1)].unk0.HALF.HI) & 0x1f; if (bVar2 > 0x10) { if (bVar2 <= 0x1d) { @@ -1349,7 +1349,7 @@ void sub_0802E768(Gleerok_HeapStruct* param_1) { bVar3 = (bVar3 - 1) & 0x1f; } - param_1->filler2[(uVar4)].unk1 = bVar3; + param_1->filler2[(uVar4)].unk0.HALF.HI = bVar3; } } |
