diff --git a/assets/xml/overlays/ovl_En_Kanban.xml b/assets/xml/overlays/ovl_En_Kanban.xml new file mode 100644 index 0000000000..386cfc663f --- /dev/null +++ b/assets/xml/overlays/ovl_En_Kanban.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/include/macros.h b/include/macros.h index 21593c13b6..c5fc2c4aeb 100644 --- a/include/macros.h +++ b/include/macros.h @@ -45,7 +45,7 @@ // linkAge still exists in MM, but is always set to 0 (always adult) // There are remnants of these macros from OOT, but they are essentially useless -//#define LINK_IS_CHILD (gSaveContext.linkAge != 0) +#define LINK_IS_CHILD (gSaveContext.linkAge == 1) #define LINK_IS_ADULT (gSaveContext.linkAge == 0) #define CURRENT_DAY (((void)0, gSaveContext.day) % 5) diff --git a/spec b/spec index 10b3e560e5..f86a1d585a 100644 --- a/spec +++ b/spec @@ -1640,8 +1640,11 @@ beginseg name "ovl_En_Kanban" compress include "build/src/overlays/actors/ovl_En_Kanban/z_en_kanban.o" - include "build/data/ovl_En_Kanban/ovl_En_Kanban.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Kanban/ovl_En_Kanban_reloc.o" +#else include "build/data/ovl_En_Kanban/ovl_En_Kanban.reloc.o" +#endif endseg beginseg diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c index 63c5854ea0..fdf1c3e48d 100644 --- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c @@ -5,6 +5,8 @@ */ #include "z_en_kanban.h" +#include "objects/object_kanban/object_kanban.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000019 @@ -15,7 +17,6 @@ void EnKanban_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKanban_Update(Actor* thisx, GlobalContext* globalCtx); void EnKanban_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Kanban_InitVars = { ACTOR_EN_KANBAN, ACTORCAT_PROP, @@ -28,27 +29,1016 @@ const ActorInit En_Kanban_InitVars = { (ActorFunc)EnKanban_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80957300 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF3CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF3CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 20, 50, 5, { 0, 0, 0 } }, }; +static u16 sPartFlags[] = { + PART_UPPER_LEFT, PART_LEFT_UPPER, PART_LEFT_LOWER, PART_RIGHT_UPPER, PART_RIGHT_LOWER, PART_LOWER_LEFT, + PART_UPPER_RIGHT, PART_LOWER_RIGHT, PART_POST_UPPER, PART_POST_LOWER, PART_POST_STAND, +}; + +static Vec3f sPieceOffsets[] = { + /* WHOLE_SIGN */ { 0.0f, 44.0f, 0.0f }, + /* UPPER_HALF */ { 0.0f, 50.0f, 0.0f }, + /* LOWER_HALF */ { 0.0f, 38.0f, 0.0f }, + /* RIGHT_HALF */ { 10.0f, 44.0f, 0.0f }, + /* LEFT_HALF */ { -10.0f, 44.0f, 0.0f }, + /* 2ND_QUAD */ { -10.0f, 50.0f, 0.0f }, + /* 1ST_QUAD */ { 10.0f, 50.0f, 0.0f }, + /* 3RD_QUAD */ { -10.0f, 38.0f, 0.0f }, + /* 4TH_QUAD */ { 10.0f, 38.0f, 0.0f }, + /* UPPER_LEFT */ { -7.5f, 51.0f, 0.0f }, + /* LEFT_UPPER */ { -12.5f, 48.0f, 0.0f }, + /* LEFT_LOWER */ { -12.5f, 40.0f, 0.0f }, + /* LOWER_LEFT */ { -7.5f, 37.0f, 0.0f }, + /* UPPER_RIGHT */ { 7.5f, 51.0f, 0.0f }, + /* RIGHT_UPPER */ { 12.5f, 48.0f, 0.0f }, + /* RIGHT_LOWER */ { 12.5f, 40.0f, 0.0f }, + /* LOWER_RIGHT */ { 7.5f, 37.0f, 0.0f }, + /* POST_UPPER */ { 0.0f, 50.0f, 0.0f }, + /* POST_LOWER */ { 0.0f, 38.0f, 0.0f }, +}; + +static Vec3f sPieceSizes[] = { + /* WHOLE_SIGN */ { 1500.0f, 1000.0f, 0.0f }, + /* UPPER_HALF */ { 1500.0f, 500.0f, 0.0f }, + /* LOWER_HALF */ { 1500.0f, 500.0f, 0.0f }, + /* RIGHT_HALF */ { 700.0f, 1000.0f, 0.0f }, + /* LEFT_HALF */ { 700.0f, 1000.0f, 0.0f }, + /* 2ND_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 1ST_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 3RD_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 4TH_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* UPPER_LEFT */ { 700.0f, 500.0f, 0.0f }, + /* LEFT_UPPER */ { 700.0f, 500.0f, 0.0f }, + /* LEFT_LOWER */ { 700.0f, 500.0f, 0.0f }, + /* LOWER_LEFT */ { 700.0f, 500.0f, 0.0f }, + /* UPPER_RIGHT */ { 700.0f, 500.0f, 0.0f }, + /* RIGHT_UPPER */ { 700.0f, 500.0f, 0.0f }, + /* RIGHT_LOWER */ { 700.0f, 500.0f, 0.0f }, + /* LOWER_RIGHT */ { 700.0f, 500.0f, 0.0f }, + /* POST_UPPER */ { 200.0f, 500.0f, 0.0f }, + /* POST_LOWER */ { 200.0f, 500.0f, 0.0f }, +}; + +static u8 sCutTypes[] = { + /* 1H_OVER */ CUT_VERT_L, /* 2H_OVER */ CUT_VERT_L, + /* 1H_COMBO */ CUT_DIAG_R, /* 2H_COMBO */ CUT_DIAG_R, + /* 1H_LEFT */ CUT_HORIZ, /* 2H_LEFT */ CUT_HORIZ, + /* 1H_COMBO */ CUT_HORIZ, /* 2H_COMBO */ CUT_HORIZ, + /* 1H_RIGHT */ CUT_HORIZ, /* 2H_RIGHT */ CUT_HORIZ, + /* 1H_COMBO */ CUT_HORIZ, /* 2H_COMBO */ CUT_HORIZ, + /* 1H_STAB */ CUT_POST, /* 2H_STAB */ CUT_POST, + /* 1H_COMBO */ CUT_POST, /* 2H_COMBO */ CUT_POST, + /* FLIP_START */ CUT_VERT_L, /* JUMP_START */ CUT_VERT_L, + /* FLIP_END */ CUT_VERT_L, /* JUMP_END */ CUT_VERT_L, + /* */ CUT_VERT_L, /* */ CUT_VERT_L, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* BACK_LEFT */ CUT_HORIZ, /* BACK_RIGHT */ CUT_HORIZ, + /* OVER_HAMMER */ CUT_POST, /* SIDE_HAMMER */ CUT_POST, + /* 1H_SPIN_ATK */ CUT_POST, /* 2H_SPIN_ATK */ CUT_POST, + /* 1H_BIG_SPIN */ CUT_POST, /* 2H_BIG_SPIN */ CUT_POST, +}; + +static u16 sCutFlags[] = { + /* CUT_POST */ ALL_PARTS, /* CUT_VERT_L */ LEFT_HALF, + /* CUT_HORIZ */ UPPER_HALF, /* CUT_DIAG_L */ UPPERLEFT_HALF, + /* CUT_DIAG_R */ UPPERRIGHT_HALF, /* CUT_VERT_R */ RIGHT_HALF, +}; + +void func_80954960(EnKanban* this) { + f32 nx; + f32 ny; + f32 nz; + + if (this->actor.floorPoly != NULL) { + nx = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.x); + ny = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y); + nz = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z); + + this->floorRot.x = -func_80086B30(-nz * ny, 1.0f); + this->floorRot.z = func_80086B30(-nx * ny, 1.0f); + } +} + +void EnKanban_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + + Actor_SetScale(&this->actor, 0.01f); + if (this->actor.params != ENKANBAN_PIECE) { + this->actor.targetMode = 0; + this->actor.flags |= 1; + this->unk_19A = Rand_ZeroFloat(1.9f); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + + if (this->actor.params == ENKANBAN_FISHING) { + if (LINK_IS_CHILD) { + this->actor.textId = 0x409D; + } else { + this->actor.textId = 0x4090; + } + } else { + this->actor.textId = this->actor.params | ENKANBAN_FISHING; + } + + this->bounceX = 1; + this->partFlags = 0xFFFF; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 4); + func_80954960(this); + } +} + +void EnKanban_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + + if (this->actionState == ENKANBAN_SIGN) { + Collider_DestroyCylinder(globalCtx, &this->collider); + } +} + +void func_80954BE8(EnKanban* this, GlobalContext* globalCtx) { + s16 yaw; + + if (!this->msgFlag) { + if (this->msgTimer == 0) { + yaw = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + if (ABS_ALT(yaw) < 0x2800) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->msgFlag = true; + } else { + func_800B8614(&this->actor, globalCtx, 68.0f); + } + } + } else { + this->msgTimer--; + } + } else if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->msgFlag = false; + this->msgTimer = 20; + } +} + +#ifdef NON_MATCHING +// Lots of branch likely stuff +void EnKanban_Update(Actor* thisx, GlobalContext* globalCtx) { + // GlobalContext* globalCtx = globalCtx2; + u8 bounced = false; + s32 pad; + EnKanban* this = THIS; + Player* player = GET_PLAYER(globalCtx); + Vec3f offset; + EnKanban* piece; + EnKanban* signpost; + s32 temp_v0_18; + f32 phi_f0; + s32 pad2; + + this->frameCount++; + + switch (this->actionState) { + case ENKANBAN_SIGN: + if (this->invincibilityTimer != 0) { + this->invincibilityTimer--; + } + + if (this->zTargetTimer != 0) { + this->zTargetTimer--; + } + + if (DECR(this->unk_1A0) == 0) { + this->unk_19C = NULL; + } + + if (this->zTargetTimer == 1) { + this->actor.flags &= ~1; + } + + if (this->partFlags == 0xFFFF) { + func_80954BE8(this, globalCtx); + } + + if ((this->invincibilityTimer == 0) && (this->collider.base.acFlags & AC_HIT)) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->unk_19C != this->collider.base.ac) { + this->unk_19C = this->collider.base.ac; + this->unk_1A0 = 3; + this->invincibilityTimer = 6; + + piece = (EnKanban*)Actor_SpawnAsChild( + &globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_KANBAN, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.shape.rot.x, + this->actor.shape.rot.y, this->actor.shape.rot.z, ENKANBAN_PIECE); + if (piece != NULL) { + ColliderInfo* hitItem = this->collider.info.acHitInfo; + s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + u8 i; + + if (hitItem->toucher.dmgFlags & 0x200) { + this->cutType = sCutTypes[player->swordAnimation]; + } else if (hitItem->toucher.dmgFlags & 0x10) { + this->invincibilityTimer = 0; + this->cutType = this->unk_19A + 3; + this->unk_19A = 1 - this->unk_19A; + if (this->unk_199 == 0) { + this->unk_199++; + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.focus.pos, 0x60); + } + } else { + this->cutType = 0; + } + + if ((ABS_ALT(yawDiff) > 0x4000) && !(hitItem->toucher.dmgFlags & 0x10)) { + if (this->cutType == 4) { + this->cutType = 3; + } else if (this->cutType == 1) { + this->cutType = 5; + } + } + + piece->partFlags = sCutFlags[this->cutType] & this->partFlags; + if (piece->partFlags == 0) { + Actor_MarkForDeath(&piece->actor); + return; + } + + piece->partCount = 0; + for (i = 0; i < 11; i++) { + if (sPartFlags[i] & piece->partFlags) { + piece->partCount++; + } + } + + this->partFlags &= ~sCutFlags[this->cutType]; + if ((this->partFlags & 0x3FF) == 0) { + this->zTargetTimer = 10; + } + + if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_WHOLE_SIGN; + } else if ((piece->partFlags & PART_LEFT_UPPER) && (piece->partFlags & PART_RIGHT_UPPER)) { + piece->pieceType = PIECE_UPPER_HALF; + } else if ((piece->partFlags & PART_LEFT_LOWER) && (piece->partFlags & PART_RIGHT_LOWER)) { + piece->pieceType = PIECE_LOWER_HALF; + } else if ((piece->partFlags & PART_UPPER_RIGHT) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_RIGHT_HALF; + } else if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LOWER_LEFT)) { + piece->pieceType = PIECE_LEFT_HALF; + } else if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LEFT_UPPER)) { + piece->pieceType = PIECE_2ND_QUAD; + } else if ((piece->partFlags & PART_UPPER_RIGHT) && (piece->partFlags & PART_RIGHT_UPPER)) { + piece->pieceType = PIECE_1ST_QUAD; + } else if ((piece->partFlags & PART_LEFT_LOWER) && (piece->partFlags & PART_LOWER_LEFT)) { + piece->pieceType = PIECE_3RD_QUAD; + } else if ((piece->partFlags & PART_RIGHT_LOWER) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_4TH_QUAD; + } else if (piece->partFlags & PART_UPPER_LEFT) { + piece->pieceType = PIECE_UPPER_LEFT; + } else if (piece->partFlags & PART_LEFT_UPPER) { + piece->pieceType = PIECE_LEFT_UPPER; + } else if (piece->partFlags & PART_LEFT_LOWER) { + piece->pieceType = PIECE_LEFT_LOWER; + } else if (piece->partFlags & PART_LOWER_LEFT) { + piece->pieceType = PIECE_LOWER_LEFT; + } else if (piece->partFlags & PART_UPPER_RIGHT) { + piece->pieceType = PIECE_UPPER_RIGHT; + } else if (piece->partFlags & PART_RIGHT_UPPER) { + piece->pieceType = PIECE_RIGHT_UPPER; + } else if (piece->partFlags & PART_RIGHT_LOWER) { + piece->pieceType = PIECE_RIGHT_LOWER; + } else if (piece->partFlags & PART_LOWER_RIGHT) { + piece->pieceType = PIECE_LOWER_RIGHT; + } else if (piece->partFlags & PART_POST_UPPER) { + piece->pieceType = PIECE_POST_UPPER; + } else if (piece->partFlags & PART_POST_LOWER) { + piece->pieceType = PIECE_POST_LOWER; + } else { + piece->pieceType = PIECE_OTHER; + } + + if (piece->pieceType == PIECE_OTHER) { + piece->pieceType = PIECE_WHOLE_SIGN; + } + + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sPieceOffsets[piece->pieceType], &offset); + piece->actor.world.pos.x += offset.x; + piece->actor.world.pos.y += offset.y; + piece->actor.world.pos.z += offset.z; + + piece->offset.x = -sPieceOffsets[piece->pieceType].x / this->actor.scale.x; + piece->offset.y = -sPieceOffsets[piece->pieceType].y / this->actor.scale.x; + piece->offset.z = -sPieceOffsets[piece->pieceType].z / this->actor.scale.x; + + piece->pieceWidth = sPieceSizes[piece->pieceType].x; + piece->pieceHeight = sPieceSizes[piece->pieceType].y; + piece->actionState = ENKANBAN_AIR; + piece->actor.gravity = -1.0f; + piece->actor.world.rot.y = + BINANG_ROT180((s32)randPlusMinusPoint5Scaled(0x4000) + this->actor.yawTowardsPlayer); + + if ((hitItem->toucher.dmgFlags & 0x10) || (hitItem->toucher.dmgFlags & 8) || + (hitItem->toucher.dmgFlags & 0x80000000)) { + piece->actor.velocity.y = Rand_ZeroFloat(3.0f) + 6.0f; + piece->actor.speedXZ = Rand_ZeroFloat(4.0f) + 6.0f; + } else { + piece->actor.velocity.y = Rand_ZeroFloat(2.0f) + 3.0f; + piece->actor.speedXZ = Rand_ZeroFloat(2.0f) + 3.0f; + } + + if (piece->partCount >= 4) { + piece->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + piece->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + } else { + piece->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + piece->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + } + + piece->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + piece->direction = 1; + } else { + piece->direction = -1; + } + piece->airTimer = 100; + piece->actor.flags &= ~1; + piece->actor.flags |= 0x2000000; + this->cutMarkTimer = 5; + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SWORD_STRIKE); + } + } + } + + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 44.0f; + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->actor.xzDistToPlayer > 500.0f) { + this->actor.flags |= 1; + this->partFlags = 0xFFFF; + } + + if (this->cutMarkTimer != 0) { + if (this->cutMarkTimer >= 5) { + this->cutMarkAlpha += 255; + if (this->cutMarkAlpha > 255) { + this->cutMarkAlpha = 255; + } + } else { + this->cutMarkAlpha -= 65; + if (this->cutMarkAlpha < 0) { + this->cutMarkAlpha = 0; + } + } + this->cutMarkTimer--; + } + break; + + case ENKANBAN_AIR: + case ENKANBAN_UNUSED: { + f32 tempX; + f32 tempY; + f32 tempZ; + f32 tempWaterDepth; + u16 tempBgFlags; + u8 onGround; + + if (this->unk_198 != 0) { + this->actor.velocity.y = -2.0f; + Actor_UpdatePos(&this->actor); + } else { + Actor_MoveWithGravity(&this->actor); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 10.0f, 50.0f, 5); + + tempX = this->actor.world.pos.x; + tempY = this->actor.world.pos.y; + tempZ = this->actor.world.pos.z; + tempBgFlags = this->actor.bgCheckFlags; + tempWaterDepth = this->actor.depthInWater; + this->actor.world.pos.z += ((this->actor.world.pos.y - this->actor.floorHeight) * -50.0f) / 100.0f; + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 4); + func_80954960(this); + + this->actor.world.pos.x = tempX; + this->actor.world.pos.y = tempY; + this->actor.world.pos.z = tempZ; + this->actor.bgCheckFlags = tempBgFlags; + this->actor.depthInWater = tempWaterDepth; + + if (1) {} + + onGround = (this->actor.bgCheckFlags & 1); + + if (this->spinXFlag != 0) { + this->spinRot.x += this->spinVel.x; + this->spinVel.x -= 0x800; + if ((this->spinRot.x <= 0) && onGround) { + this->spinRot.x = 0; + this->spinVel.x = 0; + } + } else { + this->spinRot.x -= this->spinVel.x; + this->spinVel.x -= 0x800; + if ((this->spinRot.x >= 0) && onGround) { + this->spinRot.x = 0; + this->spinVel.x = 0; + } + } + + if (this->spinVel.x < -0xC00) { + this->spinVel.x = -0xC00; + } + + if (this->spinZFlag != 0) { + this->spinRot.z += this->spinVel.z; + this->spinVel.z -= 0x800; + if ((this->spinRot.z <= 0) && onGround) { + this->spinRot.z = 0; + this->spinVel.z = 0; + } + } else { + this->spinRot.z -= this->spinVel.z; + this->spinVel.z -= 0x800; + if ((this->spinRot.z >= 0) && onGround) { + this->spinRot.z = 0; + this->spinVel.z = 0; + } + } + + if (this->spinVel.z < -0xC00) { + this->spinVel.z = -0xC00; + } + + if (this->actor.bgCheckFlags & 8) { + if (!(this->actor.bgCheckFlags & 1)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WOODPLATE_BOUND); + } + this->actor.speedXZ *= -0.5f; + } + + if (this->actor.bgCheckFlags & 0x40) { + this->actionState = ENKANBAN_WATER; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMB_DROP_WATER); + this->bounceX = this->bounceZ = 0; + this->actor.world.pos.y += this->actor.depthInWater; + EffectSsGSplash_Spawn(globalCtx, &this->actor.world.pos, NULL, NULL, 0, (this->partCount * 20) + 300); + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, 150, 650, 0); + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, 300, 800, 5); + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + break; + } + + if (onGround) { + temp_v0_18 = func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + + if ((temp_v0_18 == 15) || (temp_v0_18 == 14)) { + this->unk_197 = 1; + } else if (temp_v0_18 == 5) { + this->unk_197 = -1; + } + + if (this->bounceCount <= 0) { + this->bounceCount++; + if (this->unk_197 != 0) { + this->actor.velocity.y = 0.0f; + } else { + this->actor.velocity.y *= -0.3f; + this->actor.world.rot.y += (s16)randPlusMinusPoint5Scaled(0x4000); + } + bounced = true; + } else { + this->actor.velocity.y = 0.0f; + } + + if (this->unk_197 != 0) { + if (this->unk_197 > 0) { + this->actor.speedXZ = 0.0f; + } else if ((this->floorRot.x > 0.1f) || (this->floorRot.z > 0.1f)) { + this->airTimer = 10; + if (this->actor.bgCheckFlags & 8) { + this->actionState = ENKANBAN_GROUND; + this->actor.speedXZ = 0.0f; + goto nextCase; + } else { + Vec3f spC8; + + Matrix_SetStateXRotation(this->floorRot.x); + Matrix_InsertZRotation_f(this->floorRot.z, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledY(KREG(20) + 10.0f, &spC8); + Math_ApproachF(&this->actor.velocity.x, spC8.x, 0.5f, (KREG(21) * 0.01f) + 0.1f); + Math_ApproachF(&this->actor.velocity.z, spC8.z, 0.5f, (KREG(21) * 0.01f) + 0.3f); + this->actor.world.rot.y = Math_Atan2S(spC8.x, spC8.z); + this->unk_198 = 1; + this->actor.speedXZ = sqrtf(SQXZ(this->actor.velocity)); + } + } else { + this->unk_198 = 0; + Math_ApproachZeroF(&this->actor.speedXZ, 1, 0.1f); + } + } else { + this->actor.speedXZ *= 0.7f; + } + + if (this->spinRot.x == 0) { + if (this->bounceX != 0) { + bounced = true; + if (this->unk_197 != 0) { + this->spinRot.x = 0; + this->bounceX = 0; + } else { + this->spinVel.x = this->bounceX << 9; + if (this->bounceX != 0) { + this->bounceX -= 5; + if (this->bounceX <= 0) { + this->bounceX = 0; + } + } + + if (Rand_ZeroOne() < 0.5f) { + this->spinXFlag = 1; + } else { + this->spinXFlag = 0; + } + } + } + } + + if (this->spinRot.z == 0) { + if (this->bounceZ != 0) { + bounced = 1; + if (this->unk_197 != 0) { + this->spinRot.z = 0; + this->bounceZ = 0; + } else { + this->spinVel.z = this->bounceZ << 9; + if (this->bounceZ != 0) { + this->bounceZ -= 5; + if (this->bounceZ <= 0) { + this->bounceZ = 0; + } + } + + if (Rand_ZeroOne() < 0.5f) { + this->spinZFlag = 1; + } else { + this->spinZFlag = 0; + } + } + } + } + + Math_ApproachS(&this->actor.shape.rot.x, this->direction << 0xE, 1, 0x2000); + } else { + this->actor.shape.rot.y += this->spinVel.y; + this->actor.shape.rot.x += this->direction * 0x7D0; + } + + if (bounced) { + if (this->unk_197 > 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_WALK_SNOW); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WOODPLATE_BOUND); + } + } + + if (bounced && (this->unk_197 >= 0)) { + s16 dustCount; + s16 j; + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + static Color_RGBA8 D_80957548 = { 185, 140, 70, 255 }; + static Color_RGBA8 D_8095754C = { 255, 255, 255, 255 }; + Vec3f accel; + Vec3f pos; + Color_RGBA8 primColor; + Color_RGBA8 envColor; + + if (this->unk_197 != 0) { + primColor = D_8095754C; + envColor = D_8095754C; + } else { + primColor = D_80957548; + envColor = D_80957548; + } + + accel.x = 0.0f; + accel.y = 0.1f; + accel.z = 0.0f; + + pos.y = this->actor.floorHeight + 3.0f; + dustCount = this->partCount * 0.5f; + + for (j = 0; j < dustCount + 3; j++) { + pos.x = randPlusMinusPoint5Scaled((this->partCount * 0.5f) + 20.0f) + this->actor.world.pos.x; + pos.z = randPlusMinusPoint5Scaled((this->partCount * 0.5f) + 20.0f) + this->actor.world.pos.z; + func_800B0F18(globalCtx, &pos, &velocity, &accel, &primColor, &envColor, 100, 5, + Rand_ZeroFloat(5.0f) + 14.0f); + } + } + + if (DECR(this->airTimer) == 0) { + this->actionState = ENKANBAN_GROUND; + } + } + + case ENKANBAN_GROUND: + case ENKANBAN_WATER: + nextCase: + signpost = (EnKanban*)this->actor.parent; + + if (signpost->partFlags == 0xFFFF) { + Actor_MarkForDeath(&this->actor); + } + + phi_f0 = 0.0f; + if (this->unk_197 > 0) { + phi_f0 = -150.0f; + } + + Math_ApproachF(&this->actor.shape.yOffset, 100.0f + phi_f0, 1.0f, 5.0f); + + if (this->actionState == ENKANBAN_WATER) { + s16 rippleDelay; + s32 rippleScale; + + if ((player->actor.speedXZ > 0.0f) && (player->actor.world.pos.y < this->actor.world.pos.y) && + (this->actor.xyzDistToPlayerSq < SQ(50.0f))) { + Math_ApproachF(&this->actor.speedXZ, player->actor.speedXZ, 1.0f, 0.2f); + if (this->actor.speedXZ > 1.0f) { + this->actor.speedXZ = 1.0f; + } + + if (Math_SmoothStepToS(&this->actor.world.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 1, + 0x1000, 0) > 0) { + this->spinVel.y = this->actor.speedXZ * 1000.0f; + } else { + this->spinVel.y = this->actor.speedXZ * -1000.0f; + } + } + + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = 0.0f; + } + + Actor_MoveWithGravity(&this->actor); + + if (this->actor.speedXZ != 0.0f) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 5); + if (this->actor.bgCheckFlags & 8) { + this->actor.speedXZ *= -0.5f; + if (this->spinVel.y > 0) { + this->spinVel.y = -2000; + } else { + this->spinVel.y = 2000; + } + } + Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.15f); + } + this->actor.shape.rot.y += this->spinVel.y; + Math_ApproachS(&this->spinVel.y, 0, 1, 0x3A); + Math_ApproachS(&this->actor.shape.rot.x, this->direction * 0x4000, 2, 0x1000); + Math_ApproachS(&this->spinRot.x, Math_SinS(this->frameCount * 2500) * 500.0f, 2, 0x1000); + Math_ApproachS(&this->spinRot.z, Math_CosS(this->frameCount * 3000) * 500.0f, 2, 0x1000); + Math_ApproachZeroF(&this->floorRot.x, 0.5f, 0.2f); + Math_ApproachZeroF(&this->floorRot.z, 0.5f, 0.2f); + + if (fabsf(this->actor.speedXZ) > 1.0f) { + rippleDelay = 0; + } else if (fabsf(this->actor.speedXZ) > 0.5f) { + rippleDelay = 3; + } else { + rippleDelay = 7; + } + + if (!(this->frameCount & rippleDelay)) { + if (this->partCount < 3) { + rippleScale = 0; + } else if (this->partCount < 6) { + rippleScale = 100; + } else { + rippleScale = 200; + } + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, rippleScale, rippleScale + 500, 0); + } + } else if ((globalCtx->actorCtx.unk2 != 0) && (this->actor.xyzDistToPlayerSq < SQ(100.0f))) { + f32 hammerStrength = (100.0f - sqrtf(this->actor.xyzDistToPlayerSq)) * 0.05f; + + this->actionState = ENKANBAN_AIR; + this->actor.gravity = -1.0f; + this->actor.world.rot.y = randPlusMinusPoint5Scaled(0x10000); + if (this->partCount >= 4) { + this->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + this->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + this->actor.velocity.y = 2.0f + hammerStrength; + this->actor.speedXZ = Rand_ZeroFloat(1.0f); + } else { + this->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + this->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + this->actor.velocity.y = 3.0f + hammerStrength; + this->actor.speedXZ = Rand_ZeroFloat(1.5f); + } + + this->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + this->direction = 1; + } else { + this->direction = -1; + } + this->airTimer = 70; + } + + if (this->bounceX == 0) { + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; + f32 dx; + f32 dy; + f32 dz; + + while (explosive != NULL) { + if (explosive->params != 1) { + explosive = explosive->next; + continue; + } + + dx = this->actor.world.pos.x - explosive->world.pos.x; + dy = this->actor.world.pos.y - explosive->world.pos.y; + dz = this->actor.world.pos.z - explosive->world.pos.z; + + if (sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) < 100.0f) { + f32 bombStrength = (100.0f - sqrtf(SQ(dx) + SQ(dy) + SQ(dz))) * 0.05f; + + this->actionState = ENKANBAN_AIR; + this->actor.gravity = -1.0f; + this->actor.world.rot.y = Math_Atan2S(dx, dz); + + if (this->partCount >= 4) { + this->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + this->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + this->actor.velocity.y = 2.5f + bombStrength; + this->actor.speedXZ = 3.0f + bombStrength; + } else { + this->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + this->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + this->actor.velocity.y = 5.0f + bombStrength; + this->actor.speedXZ = 4.0f + bombStrength; + } + + this->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + this->direction = 1; + } else { + this->direction = -1; + } + this->airTimer = 70; + } + + explosive = explosive->next; + } + } + + switch (this->ocarinaFlag) { + case 0: + if (globalCtx->msgCtx.unk1202A == 1) { + this->ocarinaFlag = 1; + } + break; + + case 1: + if ((globalCtx->msgCtx.unk1202A == 4) && (globalCtx->msgCtx.unk1202E == 7)) { + this->actionState = ENKANBAN_REPAIR; + this->bounceX = 1; + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + break; + } + break; + + case ENKANBAN_REPAIR: { + f32 distX; + f32 distY; + f32 distZ; + s16 pDiff; + s16 yDiff; + s16 rDiff; + + signpost = (EnKanban*)this->actor.parent; + signpost->invincibilityTimer = 5; + + if (signpost->partFlags == 0xFFFF) { + Actor_MarkForDeath(&this->actor); + } + + Matrix_RotateY(signpost->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sPieceOffsets[this->pieceType], &offset); + distX = + Math_SmoothStepToF(&this->actor.world.pos.x, signpost->actor.world.pos.x + offset.x, 1.0f, 3.0f, 0.0f); + distY = + Math_SmoothStepToF(&this->actor.world.pos.y, signpost->actor.world.pos.y + offset.y, 1.0f, 3.0f, 0.0f); + distZ = + Math_SmoothStepToF(&this->actor.world.pos.z, signpost->actor.world.pos.z + offset.z, 1.0f, 3.0f, 0.0f); + pDiff = Math_SmoothStepToS(&this->actor.shape.rot.x, signpost->actor.shape.rot.x, 1, 0x200, 0); + yDiff = Math_SmoothStepToS(&this->actor.shape.rot.y, signpost->actor.shape.rot.y, 1, 0x200, 0); + rDiff = Math_SmoothStepToS(&this->actor.shape.rot.z, signpost->actor.shape.rot.z, 1, 0x200, 0); + Math_ApproachS(&this->spinRot.x, 0, 1, 0x200); + Math_ApproachS(&this->spinRot.z, 0, 1, 0x200); + Math_ApproachZeroF(&this->floorRot.x, 1.0f, 0.05f); + Math_ApproachZeroF(&this->floorRot.z, 1.0f, 0.05f); + Math_ApproachZeroF(&this->actor.shape.yOffset, 1.0f, 2.0f); + if (((distX + distY + distZ) == 0.0f) && + ((pDiff + yDiff + rDiff + this->spinRot.x + this->spinRot.z) == 0) && (this->floorRot.x == 0.0f) && + (this->floorRot.z == 0.0f)) { + signpost->partFlags |= this->partFlags; + signpost->actor.flags |= 1; + Actor_MarkForDeath(&this->actor); + return; + } + break; + } + } +} +#else +static Vec3f D_8095753C = { 0.0f, 0.0f, 0.0f }; +static Color_RGBA8 D_80957548 = { 185, 140, 70, 255 }; +static Color_RGBA8 D_8095754C = { 255, 255, 255, 255 }; +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Update.s") #endif -extern ColliderCylinderInit D_80957300; +static Gfx* sDisplayLists[] = { + object_kanban_DL_000CB0, object_kanban_DL_000DB8, object_kanban_DL_000E78, object_kanban_DL_000F38, + object_kanban_DL_000FF8, object_kanban_DL_0010B8, object_kanban_DL_0011C0, object_kanban_DL_0012C8, + object_kanban_DL_0013D0, object_kanban_DL_001488, object_kanban_DL_001540, +}; -extern UNK_TYPE D_06000C30; +#include "z_en_kanban_gfx.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/func_80954960.s") +static f32 sCutAngles[] = { + /* CUT_POST */ 0.50f * M_PI, + /* CUT_VERT_L */ 0.00f * M_PI, + /* CUT_HORIZ */ 0.50f * M_PI, + /* CUT_DIAG_L */ 0.66f * M_PI, + /* CUT_DIAG_R */ 0.34f * M_PI, + /* CUT_VERT_R */ 0.00f * M_PI, + /* */ 0.00f * M_PI, + /* */ 0.00f * M_PI, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Init.s") +#include "overlays/ovl_En_Kanban/ovl_En_Kanban.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Destroy.s") +void EnKanban_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + f32 zShift; + f32 zShift2; + s32 i; + Player* player = GET_PLAYER(globalCtx); + u8* shadowTex = GRAPH_ALLOC(globalCtx->state.gfxCtx, ARRAY_COUNT(sShadowTexFlags)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/func_80954BE8.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Update.s") + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Draw.s") + gSPDisplayList(POLY_OPA_DISP++, object_kanban_DL_000C30); + + if (this->actionState != ENKANBAN_SIGN) { + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(this->floorRot.x); + Matrix_InsertZRotation_f(this->floorRot.z, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); + + zShift = fabsf(Math_SinS(this->spinRot.x) * this->pieceHeight); + zShift2 = fabsf(Math_SinS(this->spinRot.z) * this->pieceWidth); + zShift = CLAMP_MIN(zShift, zShift2); + zShift *= -(f32)this->direction; + + Matrix_InsertTranslation(0.0f, 0.0f, zShift, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->spinRot.x, MTXMODE_APPLY); + Matrix_RotateY(this->spinRot.z, MTXMODE_APPLY); + Matrix_InsertTranslation(this->offset.x, this->offset.y, this->offset.z - 100.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + for (i = 0; i < ARRAY_COUNT(sPartFlags); i++) { + if (sPartFlags[i] & this->partFlags) { + gSPDisplayList(POLY_OPA_DISP++, sDisplayLists[i]); + } + } + } else { + f32 phi_f0 = 0.0f; + + if ((player->transformation == PLAYER_FORM_HUMAN) || (player->transformation == PLAYER_FORM_DEKU)) { + phi_f0 = -15.0f; + } + this->actor.world.pos.y = this->actor.home.pos.y + phi_f0; + Matrix_InsertTranslation(0.0f, 0.0f, -100.0f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (this->partFlags == 0xFFFF) { + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05AED0); + } else { + for (i = 0; i < ARRAY_COUNT(sPartFlags); i++) { + if (sPartFlags[i] & this->partFlags) { + gSPDisplayList(POLY_OPA_DISP++, sDisplayLists[i]); + } + } + } + + if (this->cutMarkAlpha != 0) { + f32 cutOffset = (this->cutType == CUT_POST) ? -1200.0f : 0.0f; + + Matrix_InsertTranslation(0.0f, 4400.0f + cutOffset, 200.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_f(sCutAngles[this->cutType], MTXMODE_APPLY); + Matrix_Scale(0.0f, 10.0f, 2.0f, MTXMODE_APPLY); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x00, 255, 255, 255, this->cutMarkAlpha); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 150, 0); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_kanban_DL_001630); + } + } + + if ((this->actor.projectedPos.z <= 400.0f) && (this->actor.projectedPos.z > 0.0f) && + (this->actor.floorHeight > -3000.0f) && ((this->bounceX != 0) || (this->bounceZ != 0))) { + u16 dayTime = gSaveContext.time; + f32 shadowAlpha; + + if (dayTime >= CLOCK_TIME(12, 0)) { + dayTime = (0xFFFF - dayTime) & 0xFFFF; + } + + shadowAlpha = (dayTime * 0.00275f) + 10.0f; + if (this->actor.projectedPos.z > 300.0f) { + shadowAlpha *= (400.0f - this->actor.projectedPos.z) * 0.01f; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x00, 0, 0, 0, (s8)shadowAlpha); + + if ((player->transformation == PLAYER_FORM_HUMAN) || (player->transformation == PLAYER_FORM_DEKU)) { + zShift = 0.0f; + } else { + zShift = ((this->actor.world.pos.y - this->actor.floorHeight) * -50.0f) / 100.0f; + } + + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z + zShift, + MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(this->floorRot.x); + Matrix_InsertZRotation_f(this->floorRot.z, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, 0.0f, this->actor.scale.z, MTXMODE_APPLY); + + if (this->actionState == ENKANBAN_SIGN) { + Matrix_RotateStateAroundXAxis(-M_PI / 5); + } + + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->spinRot.x, MTXMODE_APPLY); + Matrix_RotateY(this->spinRot.z, MTXMODE_APPLY); + Matrix_InsertTranslation(this->offset.x, this->offset.y, this->offset.z, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + for (i = 0; i < ARRAY_COUNT(sShadowTexFlags); i++) { + if (sShadowTexFlags[i] & this->partFlags) { + shadowTex[i] = 0xFF; + } else { + shadowTex[i] = 0; + } + } + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(shadowTex)); + gSPDisplayList(POLY_XLU_DISP++, gEnKanban_D_80957DE0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h index 40eeb10609..b667bd9e8c 100644 --- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h @@ -5,11 +5,104 @@ struct EnKanban; +#define PART_UPPER_LEFT (1 << 0) +#define PART_LEFT_UPPER (1 << 1) +#define PART_LEFT_LOWER (1 << 2) +#define PART_RIGHT_UPPER (1 << 3) +#define PART_RIGHT_LOWER (1 << 4) +#define PART_LOWER_LEFT (1 << 5) +#define PART_UPPER_RIGHT (1 << 6) +#define PART_LOWER_RIGHT (1 << 7) +#define PART_POST_UPPER (1 << 8) +#define PART_POST_LOWER (1 << 9) +#define PART_POST_STAND (1 << 10) +#define LEFT_HALF (PART_UPPER_LEFT | PART_LEFT_UPPER | PART_LEFT_LOWER | PART_LOWER_LEFT) +#define RIGHT_HALF (PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_RIGHT_LOWER | PART_LOWER_RIGHT) +#define UPPER_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_UPPER_LEFT | PART_LEFT_UPPER) +#define UPPERLEFT_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_LEFT_LOWER | PART_UPPER_LEFT | PART_LEFT_UPPER) +#define UPPERRIGHT_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_UPPER_LEFT | PART_RIGHT_LOWER) +#define ALL_PARTS (LEFT_HALF | RIGHT_HALF | PART_POST_UPPER | PART_POST_LOWER) + +typedef enum { + /* 0 */ ENKANBAN_SIGN, + /* 1 */ ENKANBAN_AIR, + /* 2 */ ENKANBAN_UNUSED, + /* 3 */ ENKANBAN_GROUND, + /* 4 */ ENKANBAN_WATER, + /* 5 */ ENKANBAN_REPAIR +} EnKanbanActionState; + +typedef enum { + /* 0 */ PIECE_WHOLE_SIGN, + /* 1 */ PIECE_UPPER_HALF, + /* 2 */ PIECE_LOWER_HALF, + /* 3 */ PIECE_RIGHT_HALF, + /* 4 */ PIECE_LEFT_HALF, + /* 5 */ PIECE_2ND_QUAD, + /* 6 */ PIECE_1ST_QUAD, + /* 7 */ PIECE_3RD_QUAD, + /* 8 */ PIECE_4TH_QUAD, + /* 9 */ PIECE_UPPER_LEFT, + /* 10 */ PIECE_LEFT_UPPER, + /* 11 */ PIECE_LEFT_LOWER, + /* 12 */ PIECE_LOWER_LEFT, + /* 13 */ PIECE_UPPER_RIGHT, + /* 14 */ PIECE_RIGHT_UPPER, + /* 15 */ PIECE_RIGHT_LOWER, + /* 16 */ PIECE_LOWER_RIGHT, + /* 17 */ PIECE_POST_UPPER, + /* 18 */ PIECE_POST_LOWER, + /* 100 */ PIECE_OTHER = 100 +} EnKanbanPiece; + +typedef enum { + /* 0 */ CUT_POST, + /* 1 */ CUT_VERT_L, + /* 2 */ CUT_HORIZ, + /* 3 */ CUT_DIAG_L, // lower left to upper right + /* 4 */ CUT_DIAG_R, // upper left to lower right + /* 5 */ CUT_VERT_R +} EnKanbanCutType; + typedef struct EnKanban { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xAC]; + /* 0x144 */ UNK_TYPE1 unk144[4]; // actionFunc? + /* 0x148 */ u8 frameCount; + /* 0x14A */ s16 airTimer; + /* 0x14C */ u8 actionState; + /* 0x14E */ u16 partFlags; + /* 0x150 */ u8 partCount; + /* 0x152 */ s16 invincibilityTimer; + /* 0x154 */ Vec3f offset; + /* 0x160 */ Vec3s spinRot; + /* 0x166 */ Vec3s spinVel; + /* 0x16C */ s8 spinXFlag; + /* 0x16D */ s8 spinZFlag; + /* 0x16E */ s16 bounceX; + /* 0x170 */ s16 bounceZ; + /* 0x172 */ u8 bounceCount; + /* 0x174 */ f32 pieceWidth; + /* 0x178 */ f32 pieceHeight; + /* 0x17C */ s16 direction; + /* 0x180 */ Vec3f floorRot; + /* 0x18C */ u8 cutType; + /* 0x18D */ u8 pieceType; + /* 0x18E */ s16 cutMarkTimer; + /* 0x190 */ s16 cutMarkAlpha; + /* 0x192 */ s16 zTargetTimer; + /* 0x194 */ u8 msgFlag; + /* 0x195 */ u8 msgTimer; + /* 0x196 */ u8 ocarinaFlag; + /* 0x197 */ s8 unk_197; + /* 0x198 */ s8 unk_198; + /* 0x199 */ u8 unk_199; + /* 0x19A */ u8 unk_19A; + /* 0x19C */ Actor* unk_19C; + /* 0x1A0 */ s16 unk_1A0; + /* 0x1A4 */ ColliderCylinder collider; } EnKanban; // size = 0x1F0 +#define ENKANBAN_PIECE ((s16)0xFFDD) #define ENKANBAN_FISHING 0x300 extern const ActorInit En_Kanban_InitVars; diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c b/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c new file mode 100644 index 0000000000..c38e9df942 --- /dev/null +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c @@ -0,0 +1,68 @@ +#include "z_en_kanban.h" + +static u16 sShadowTexFlags[] = { + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, + 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, + 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x102, 0x301, + 0x340, 0x108, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x204, 0x220, + 0x280, 0x210, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, + 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x620, + 0x680, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, +}; diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 60e39862cc..73afcda755 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -8782,14 +8782,14 @@ 0x809548A0:("Bg_Ingate_InitVars","UNK_TYPE1","",0x1), 0x809572E0:("En_Kanban_InitVars","UNK_TYPE1","",0x1), 0x80957300:("D_80957300","UNK_TYPE1","",0x1), - 0x8095732C:("D_8095732C","UNK_TYPE2","",0x2), + 0x8095732C:("sPartFlags","UNK_TYPE2","",0x2), 0x8095732E:("D_8095732E","UNK_TYPE2","",0x2), 0x80957330:("D_80957330","UNK_TYPE2","",0x2), 0x80957332:("D_80957332","UNK_TYPE2","",0x2), - 0x80957344:("D_80957344","UNK_TYPE4","",0x4), - 0x80957428:("D_80957428","UNK_TYPE4","",0x4), - 0x8095750C:("D_8095750C","UNK_TYPE1","",0x1), - 0x80957530:("D_80957530","UNK_TYPE1","",0x1), + 0x80957344:("sPieceOffsets","UNK_TYPE4","",0x4), + 0x80957428:("sPieceSizes","UNK_TYPE4","",0x4), + 0x8095750C:("sCutTypes","UNK_TYPE1","",0x1), + 0x80957530:("sCutFlags","UNK_TYPE1","",0x1), 0x8095753C:("D_8095753C","UNK_TYPE4","",0x4), 0x80957548:("D_80957548","UNK_TYPE4","",0x4), 0x8095754C:("D_8095754C","UNK_TYPE4","",0x4),