diff --git a/assets/xml/objects/object_tsn.xml b/assets/xml/objects/object_tsn.xml index bd83a3be50..761a6e0d74 100644 --- a/assets/xml/objects/object_tsn.xml +++ b/assets/xml/objects/object_tsn.xml @@ -26,11 +26,11 @@ - + - + diff --git a/include/z64item.h b/include/z64item.h index 0eea19008f..00eb0a5a8d 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -332,7 +332,8 @@ typedef enum { /* 0x8E */ GI_MASK_SCENTS, /* 0x8F */ GI_MASK_GIANT, /* 0x92 */ GI_MILK = 0x92, - /* 0x96 */ GI_MOON_TEAR = 0x96, + /* 0x95 */ GI_95 = 0x95, + /* 0x96 */ GI_MOON_TEAR, /* 0x97 */ GI_DEED_LAND, /* 0x98 */ GI_DEED_SWAMP, /* 0x99 */ GI_DEED_MOUNTAIN, diff --git a/spec b/spec index d8fdc7387d..9c92116ddf 100644 --- a/spec +++ b/spec @@ -3620,8 +3620,7 @@ beginseg name "ovl_En_Tsn" compress include "build/src/overlays/actors/ovl_En_Tsn/z_en_tsn.o" - include "build/data/ovl_En_Tsn/ovl_En_Tsn.data.o" - include "build/data/ovl_En_Tsn/ovl_En_Tsn.reloc.o" + include "build/src/overlays/actors/ovl_En_Tsn/ovl_En_Tsn_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Tsn/z_en_tsn.c b/src/overlays/actors/ovl_En_Tsn/z_en_tsn.c index 022aa44bcb..5f0309fbbf 100644 --- a/src/overlays/actors/ovl_En_Tsn/z_en_tsn.c +++ b/src/overlays/actors/ovl_En_Tsn/z_en_tsn.c @@ -5,6 +5,7 @@ */ #include "z_en_tsn.h" +#include "objects/object_tsn/object_tsn.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) @@ -15,7 +16,18 @@ void EnTsn_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTsn_Update(Actor* thisx, GlobalContext* globalCtx); void EnTsn_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80AE0010(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0304(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0418(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0460(EnTsn* this, GlobalContext* globalCtx); +void func_80AE04C4(EnTsn* this, GlobalContext* globalCtx); +void func_80AE04FC(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0704(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0C88(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0D10(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0D78(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0F84(Actor* thisx, GlobalContext* globalCtx); + const ActorInit En_Tsn_InitVars = { ACTOR_EN_TSN, ACTORCAT_NPC, @@ -28,58 +40,597 @@ const ActorInit En_Tsn_InitVars = { (ActorFunc)EnTsn_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AE1190 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_ENEMY, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_ENEMY, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 30, 40, 0, { 0, 0, 0 } }, }; -#endif +Vec3f D_80AE11BC = { 0.0f, 0.0f, 0.0f }; -extern ColliderCylinderInit D_80AE1190; +TexturePtr D_80AE11C8[] = { object_tsn_Tex_0073B8, object_tsn_Tex_0085B8 }; -extern UNK_TYPE D_06001198; -extern UNK_TYPE D_060092FC; +EnTsn* func_80ADFCA0(GlobalContext* globalCtx) { + Actor* npc = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80ADFCA0.s") + while (npc != NULL) { + if ((npc->id == ACTOR_EN_TSN) && !ENTSN_GET_100(npc)) { + return (EnTsn*)npc; + } + npc = npc->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80ADFCEC.s") + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/EnTsn_Init.s") +void func_80ADFCEC(EnTsn* this, GlobalContext* globalCtx) { + this->actionFunc = func_80AE0C88; + this->actor.update = func_80AE0F84; + this->actor.destroy = NULL; + this->actor.draw = NULL; + this->actor.targetMode = 7; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/EnTsn_Destroy.s") + switch (ENTSN_GET_F(&this->actor)) { + case ENTSN_F_0: + if (gSaveContext.weekEventReg[26] & 8) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actor.textId = 0x106E; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80ADFF84.s") + case ENTSN_F_1: + if (gSaveContext.weekEventReg[26] & 4) { + this->actor.textId = 0x1091; + } else { + this->actor.textId = 0x108A; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0010.s") + if (gSaveContext.weekEventReg[55] & 0x80) { + if ((ENTSN_GET_F(&this->actor)) == ENTSN_F_0) { + this->actionFunc = func_80AE0D78; + } else { + Actor_MarkForDeath(&this->actor); + } + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0304.s") + this->unk_1D8 = func_80ADFCA0(globalCtx); + this->unk_220 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0418.s") + if (this->unk_1D8 == NULL) { + Actor_MarkForDeath(&this->actor); + } else if ((ENTSN_GET_F(&this->actor)) == ENTSN_F_1) { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 6); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0460.s") +void EnTsn_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTsn* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE04C4.s") + if (ENTSN_GET_100(&this->actor)) { + func_80ADFCEC(this, globalCtx); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE04FC.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tsn_Skel_008AB8, &object_tsn_Anim_0092FC, NULL, NULL, 0); + Animation_PlayLoop(&this->skelAnime, &object_tsn_Anim_0092FC); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0698.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->unk_220 = 0; + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = -9.0f; + this->actor.gravity = -1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0704.s") + if (gSaveContext.weekEventReg[55] & 0x80) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0C88.s") +void EnTsn_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTsn* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0D10.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0D78.s") +void func_80ADFF84(EnTsn* this, GlobalContext* globalCtx) { + u16 textId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/EnTsn_Update.s") + if (gSaveContext.weekEventReg[26] & 8) { + textId = 0x107E; + } else if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.weekEventReg[25] & 0x80) { + textId = 0x1083; + } else { + textId = 0x107F; + } + } else if (gSaveContext.weekEventReg[26] & 1) { + textId = 0x1089; + } else { + textId = 0x1084; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0F84.s") + Message_StartTextbox(globalCtx, textId, &this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0FA8.s") +void func_80AE0010(EnTsn* this, GlobalContext* globalCtx) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x107F: + case 0x1080: + case 0x1081: + case 0x1082: + case 0x1083: + case 0x1084: + case 0x1085: + case 0x1086: + case 0x1087: + case 0x1088: + case 0x1089: + case 0x1093: + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 6, 0x1838, 0x64); + this->actor.shape.rot.y = this->actor.world.rot.y; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE1024.s") + if ((Message_GetState(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x107F: + case 0x1081: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/EnTsn_Draw.s") + case 0x1080: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_001198, -10.0f); + break; + + case 0x1082: + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + gSaveContext.weekEventReg[25] |= 0x80; + func_801477B4(globalCtx); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + break; + + case 0x1083: + gSaveContext.weekEventReg[25] |= 0x80; + func_801477B4(globalCtx); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + break; + + case 0x1084: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_000964, -10.0f); + break; + + case 0x1085: + case 0x1086: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1089: + case 0x1093: + gSaveContext.weekEventReg[26] |= 1; + func_801477B4(globalCtx); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + break; + + case 0x1087: + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_001198, -10.0f); + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1088: + gSaveContext.weekEventReg[26] |= 1; + if (INV_CONTENT(ITEM_MASK_ZORA) == ITEM_MASK_ZORA) { + func_801477B4(globalCtx); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + } else { + func_80151938(globalCtx, 0x1093); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + } + break; + + case 0x107E: + func_801477B4(globalCtx); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + break; + } + } +} + +void func_80AE0304(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80AE0010; + this->unk_220 |= 1; + if (this->actor.textId == 0) { + func_80ADFF84(this, globalCtx); + } + } else if ((this->actor.xzDistToPlayer < 150.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 160.0f); + this->unk_220 |= 1; + } else { + this->unk_220 &= ~1; + } + if (ENTSN_GET_Z(&this->actor)) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 6, 0x1838, 0x64); + } else { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.home.rot.y, 6, 0x1838, 0x64); + } + this->actor.shape.rot.y = this->actor.world.rot.y; +} + +void func_80AE0418(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + Message_StartTextbox(globalCtx, 0x107D, NULL); + Actor_MarkForDeath(&this->actor); + } +} + +void func_80AE0460(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + ENTSN_SET_Z(&this->unk_1D8->actor, false); + this->actionFunc = func_80AE0418; + } else { + Actor_PickUp(&this->actor, globalCtx, GI_95, 2000.0f, 1000.0f); + } +} + +void func_80AE04C4(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->actionFunc = func_80AE0C88; + } +} + +void func_80AE04FC(EnTsn* this, GlobalContext* globalCtx) { + s32 sp24; + Player* player = GET_PLAYER(globalCtx); + + if (Message_GetState(&globalCtx->msgCtx) == 0x10) { + sp24 = func_80123810(globalCtx); + if (sp24 != 0) { + gSaveContext.weekEventReg[26] |= 2; + } + + if (sp24 > 0) { + func_801477B4(globalCtx); + this->actionFunc = func_80AE0704; + if (sp24 == 19) { + if (CHECK_QUEST_ITEM(QUEST_UNK_19)) { + if (func_8013A4C4(1 | 8)) { + player->actor.textId = 0x107B; + return; + } + + if (func_8013A4C4(1 | 2 | 8)) { + player->actor.textId = 0x10A9; + return; + } + + player->actor.textId = 0x1078; + this->unk_220 |= 8; + return; + } + + player->actor.textId = 0x1078; + this->unk_220 |= 8; + return; + } + + if (sp24 == 13) { + player->actor.textId = 0x1075; + return; + } + + player->actor.textId = 0x1078; + this->unk_220 |= 8; + return; + } + + if (sp24 < 0) { + func_80151938(globalCtx, 0x1078); + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_001198, -10.0f); + this->actionFunc = func_80AE0704; + } + } +} + +void func_80AE0698(EnTsn* this, GlobalContext* globalCtx) { + func_801477B4(globalCtx); + this->actionFunc = func_80AE0C88; + this->unk_220 &= ~2; + this->actor.focus.pos = this->actor.world.pos; + ActorCutscene_Stop(this->actor.cutscene); + ENTSN_SET_Z(&this->unk_1D8->actor, false); +} + +void func_80AE0704(EnTsn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad[2]; + + if ((this->unk_220 & 8) && (globalCtx->msgCtx.unk11F04 == 0x1078)) { + this->unk_220 &= ~8; + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_001198, -10.0f); + } + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 2: + break; + + case 5: + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x106E: + if (gSaveContext.weekEventReg[25] & 0x40) { + func_80151938(globalCtx, 0x1074); + } else { + func_80151938(globalCtx, 0x106F); + } + this->unk_220 |= 2; + gSaveContext.weekEventReg[25] |= 0x40; + ENTSN_SET_Z(&this->unk_1D8->actor, true); + this->unk_220 |= 4; + break; + + case 0x106F: + case 0x1070: + case 0x1071: + case 0x1072: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1076: + case 0x1079: + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_000964, -10.0f); + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x107A: + func_80151938(globalCtx, 0x10A6); + break; + + case 0x1075: + case 0x1078: + player->exchangeItemId = 0; + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + break; + + case 0x107C: + if (Interface_HasEmptyBottle()) { + gSaveContext.weekEventReg[26] |= 8; + func_801477B4(globalCtx); + this->actionFunc = func_80AE0460; + func_80AE0460(this, globalCtx); + this->unk_220 &= ~2; + this->actor.focus.pos = this->actor.world.pos; + ActorCutscene_Stop(this->actor.cutscene); + this->actor.flags &= ~ACTOR_FLAG_100; + REMOVE_QUEST_ITEM(QUEST_UNK_19); + } else { + func_80151938(globalCtx, 0x10A8); + } + break; + + case 0x1073: + case 0x1074: + func_80151938(globalCtx, 0xFF); + this->actionFunc = func_80AE04FC; + break; + + case 0x107B: + player->exchangeItemId = 0; + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + break; + + case 0x1077: + case 0x10A6: + case 0x10A8: + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + func_80AE0698(this, globalCtx); + this->actor.flags &= ~ACTOR_FLAG_100; + this->actionFunc = func_80AE04C4; + break; + + case 0x108A: + case 0x1091: + gSaveContext.weekEventReg[26] |= 4; + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + this->unk_220 |= 2; + this->actor.textId = 0x1091; + break; + + case 0x108B: + case 0x108C: + case 0x108D: + case 0x108E: + case 0x108F: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1092: + if (gSaveContext.weekEventReg[26] & 8) { + func_80AE0698(this, globalCtx); + } else { + func_80151938(globalCtx, 0x10A7); + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_000964, -10.0f); + } + break; + + case 0x10A7: + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + func_80AE0698(this, globalCtx); + break; + + case 0x1090: + func_80AE0698(this, globalCtx); + break; + + case 0x10A9: + func_80AE0698(this, globalCtx); + this->actor.flags &= ~ACTOR_FLAG_100; + this->actionFunc = func_80AE04C4; + break; + } + } + } + + if (this->unk_220 & 2) { + if (this->unk_1D8 != NULL) { + Math_SmoothStepToF(&this->actor.focus.pos.x, this->unk_1D8->actor.focus.pos.x, 0.8f, 100.0f, 5.0f); + Math_SmoothStepToF(&this->actor.focus.pos.y, this->unk_1D8->actor.focus.pos.y, 0.8f, 100.0f, 5.0f); + Math_SmoothStepToF(&this->actor.focus.pos.z, this->unk_1D8->actor.focus.pos.z, 0.8f, 100.0f, 5.0f); + } + } + + if (this->unk_220 & 4) { + if (this->actor.cutscene == -1) { + this->unk_220 &= ~4; + } else if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->unk_220 &= ~4; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } +} + +void func_80AE0C88(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80AE0704; + if ((this->actor.textId == 0x108A) || (this->actor.textId == 0x1091)) { + this->unk_220 |= 4; + ENTSN_SET_Z(&this->unk_1D8->actor, true); + } + } else if (this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 1000.0f); + } +} + +void func_80AE0D10(EnTsn* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + this->actionFunc = func_80AE0D78; + ActorCutscene_Stop(this->actor.cutscene); + } +} + +void func_80AE0D78(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80AE0D10; + this->unk_220 |= 4; + } else if (this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 1000.0f); + } +} + +void EnTsn_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTsn* this = THIS; + + this->actionFunc(this, globalCtx); + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 25.0f, 0.0f, 4); + SkelAnime_Update(&this->skelAnime); + + if (this->unk_220 & 1) { + func_800E9250(globalCtx, &this->actor, &this->unk_222, &this->unk_228, this->actor.focus.pos); + } else { + Math_SmoothStepToS(&this->unk_222.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_222.y, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_228.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_228.y, 0, 6, 0x1838, 0x64); + } + + if (DECR(this->unk_230) == 0) { + this->unk_230 = Rand_S16Offset(60, 60); + } + + if ((this->unk_230 == 1) || (this->unk_230 == 3)) { + this->unk_22E = 1; + } else { + this->unk_22E = 0; + } +} + +void func_80AE0F84(Actor* thisx, GlobalContext* globalCtx) { + EnTsn* this = THIS; + + this->actionFunc(this, globalCtx); +} + +s32 EnTsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnTsn* this = THIS; + s16 shifted = this->unk_222.x >> 1; + + if (limbIndex == 15) { + rot->x += this->unk_222.y; + rot->z += shifted; + } + + if (limbIndex == 8) { + rot->x += this->unk_228.y; + rot->z += shifted; + } + return false; +} + +void EnTsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnTsn* this = THIS; + Vec3f sp18 = D_80AE11BC; + + if (limbIndex == 15) { + Matrix_MultiplyVector3fByState(&sp18, &this->actor.focus.pos); + } +} + +void EnTsn_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTsn* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C5B0(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AE11C8[this->unk_22E])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80AE11C8[this->unk_22E])); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnTsn_OverrideLimbDraw, EnTsn_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tsn/z_en_tsn.h b/src/overlays/actors/ovl_En_Tsn/z_en_tsn.h index 6b7810cf6b..64df6ac423 100644 --- a/src/overlays/actors/ovl_En_Tsn/z_en_tsn.h +++ b/src/overlays/actors/ovl_En_Tsn/z_en_tsn.h @@ -7,11 +7,26 @@ struct EnTsn; typedef void (*EnTsnActionFunc)(struct EnTsn*, GlobalContext*); +#define ENTSN_GET_F(thisx) ((thisx)->params & 0xF) +#define ENTSN_GET_100(thisx) ((thisx)->params & 0x100) +#define ENTSN_GET_Z(thisx) ((thisx)->home.rot.z) +#define ENTSN_SET_Z(thisx, state) ((thisx)->home.rot.z = state) + +#define ENTSN_F_0 0 +#define ENTSN_F_1 1 + typedef struct EnTsn { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnTsnActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x5C]; + /* 0x01D8 */ struct EnTsn* unk_1D8; + /* 0x01DC */ UNK_TYPE1 unk1DC[0x44]; + /* 0x0220 */ u16 unk_220; + /* 0x0222 */ Vec3s unk_222; + /* 0x0228 */ Vec3s unk_228; + /* 0x022E */ s16 unk_22E; + /* 0x0230 */ s16 unk_230; } EnTsn; // size = 0x234 extern const ActorInit En_Tsn_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 88487c9168..538521a083 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -12384,8 +12384,8 @@ 0x80AE0D78:("func_80AE0D78",), 0x80AE0DDC:("EnTsn_Update",), 0x80AE0F84:("func_80AE0F84",), - 0x80AE0FA8:("func_80AE0FA8",), - 0x80AE1024:("func_80AE1024",), + 0x80AE0FA8:("EnTsn_OverrideLimbDraw",), + 0x80AE1024:("EnTsn_PostLimbDraw",), 0x80AE1080:("EnTsn_Draw",), 0x80AE1650:("func_80AE1650",), 0x80AE16A0:("func_80AE16A0",), diff --git a/undefined_syms.txt b/undefined_syms.txt index 836f195728..ed19028777 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -1802,13 +1802,6 @@ D_0601A830 = 0x0601A830; D_060004C8 = 0x060004C8; D_0601AA60 = 0x0601AA60; -// ovl_En_Tsn - -D_06000964 = 0x06000964; -D_06001198 = 0x06001198; -D_06008AB8 = 0x06008AB8; -D_060092FC = 0x060092FC; - // ovl_En_Twig D_060014C8 = 0x060014C8;