summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaide <34639600+Kelebek1@users.noreply.github.com>2022-01-12 15:37:26 +0000
committerGitHub <noreply@github.com>2022-01-12 15:37:26 +0000
commit816971d98cc6d1fcdffce3db6e16a1ef805567f6 (patch)
treea1a8c3ef28d043f3f3060dbc8a3667cc5b6525f8 /src
parentc44e26a14356be233402fc98a44681c37ae45761 (diff)
En_Kanban (1 non-matching) (#419)
* En_Kanban * PR * PR * Object * undef * PR * Merge * Merge * Merge
Diffstat (limited to 'src')
-rw-r--r--src/overlays/actors/ovl_En_Kanban/z_en_kanban.c1016
-rw-r--r--src/overlays/actors/ovl_En_Kanban/z_en_kanban.h95
-rw-r--r--src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c68
3 files changed, 1165 insertions, 14 deletions
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 63c5854ea..fdf1c3e48 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 } },
};
-#endif
+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;
+ }
-extern ColliderCylinderInit D_80957300;
+ 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;
+ }
+ }
-extern UNK_TYPE D_06000C30;
+ if (Rand_ZeroOne() < 0.5f) {
+ this->spinXFlag = 1;
+ } else {
+ this->spinXFlag = 0;
+ }
+ }
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/func_80954960.s")
+ 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;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Init.s")
+ if (Rand_ZeroOne() < 0.5f) {
+ this->spinZFlag = 1;
+ } else {
+ this->spinZFlag = 0;
+ }
+ }
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Destroy.s")
+ 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;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/func_80954BE8.s")
+ 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
+
+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,
+};
+
+#include "z_en_kanban_gfx.c"
+
+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,
+};
+
+#include "overlays/ovl_En_Kanban/ovl_En_Kanban.c"
+
+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));
+
+ OPEN_DISPS(globalCtx->state.gfxCtx);
+
+ func_8012C28C(globalCtx->state.gfxCtx);
+ func_8012C2DC(globalCtx->state.gfxCtx);
+
+ 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);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Draw.s")
+ 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 40eeb1060..b667bd9e8 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 000000000..c38e9df94
--- /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,
+};