mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-08-13 17:03:47 -04:00
39cc86c260
subrepo: subdir: "soh" merged: "ba904bbd0" upstream: origin: "https://github.com/HarbourMasters/soh.git" branch: "master" commit: "ba904bbd0" git-subrepo: version: "0.4.1" origin: "???" commit: "???"
416 lines
13 KiB
C
416 lines
13 KiB
C
/*
|
|
* File: z_en_tory.c
|
|
* Overlay: ovl_En_Toryo
|
|
* Description: Boss Carpenter
|
|
*/
|
|
|
|
#include "z_en_toryo.h"
|
|
#include "objects/object_toryo/object_toryo.h"
|
|
|
|
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
|
|
|
|
void EnToryo_Init(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnToryo_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnToryo_Update(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnToryo_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
void func_80B20914(EnToryo* this, GlobalContext* globalCtx);
|
|
s32 EnToryo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx);
|
|
void EnToryo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx);
|
|
|
|
const ActorInit En_Toryo_InitVars = {
|
|
ACTOR_EN_TORYO,
|
|
ACTORCAT_NPC,
|
|
FLAGS,
|
|
OBJECT_TORYO,
|
|
sizeof(EnToryo),
|
|
(ActorFunc)EnToryo_Init,
|
|
(ActorFunc)EnToryo_Destroy,
|
|
(ActorFunc)EnToryo_Update,
|
|
(ActorFunc)EnToryo_Draw,
|
|
NULL,
|
|
};
|
|
|
|
static ColliderCylinderInit sCylinderInit = {
|
|
{
|
|
COLTYPE_NONE,
|
|
AT_NONE,
|
|
AC_NONE,
|
|
OC1_ON | OC1_TYPE_ALL,
|
|
OC2_TYPE_2,
|
|
COLSHAPE_CYLINDER,
|
|
},
|
|
{
|
|
ELEMTYPE_UNK0,
|
|
{ 0x00000000, 0x00, 0x00 },
|
|
{ 0x00000000, 0x00, 0x00 },
|
|
TOUCH_NONE,
|
|
BUMP_NONE,
|
|
OCELEM_ON,
|
|
},
|
|
{ 18, 63, 0, { 0, 0, 0 } },
|
|
};
|
|
|
|
static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE };
|
|
|
|
static DamageTable sDamageTable = {
|
|
/* Deku nut */ DMG_ENTRY(0, 0x0),
|
|
/* Deku stick */ DMG_ENTRY(0, 0x0),
|
|
/* Slingshot */ DMG_ENTRY(0, 0x0),
|
|
/* Explosive */ DMG_ENTRY(0, 0x0),
|
|
/* Boomerang */ DMG_ENTRY(0, 0x0),
|
|
/* Normal arrow */ DMG_ENTRY(0, 0x0),
|
|
/* Hammer swing */ DMG_ENTRY(0, 0x0),
|
|
/* Hookshot */ DMG_ENTRY(0, 0x0),
|
|
/* Kokiri sword */ DMG_ENTRY(0, 0x0),
|
|
/* Master sword */ DMG_ENTRY(0, 0x0),
|
|
/* Giant's Knife */ DMG_ENTRY(0, 0x0),
|
|
/* Fire arrow */ DMG_ENTRY(0, 0x0),
|
|
/* Ice arrow */ DMG_ENTRY(0, 0x0),
|
|
/* Light arrow */ DMG_ENTRY(0, 0x0),
|
|
/* Unk arrow 1 */ DMG_ENTRY(0, 0x0),
|
|
/* Unk arrow 2 */ DMG_ENTRY(0, 0x0),
|
|
/* Unk arrow 3 */ DMG_ENTRY(0, 0x0),
|
|
/* Fire magic */ DMG_ENTRY(0, 0x0),
|
|
/* Ice magic */ DMG_ENTRY(0, 0x0),
|
|
/* Light magic */ DMG_ENTRY(0, 0x0),
|
|
/* Shield */ DMG_ENTRY(0, 0x0),
|
|
/* Mirror Ray */ DMG_ENTRY(0, 0x0),
|
|
/* Kokiri spin */ DMG_ENTRY(0, 0x0),
|
|
/* Giant spin */ DMG_ENTRY(0, 0x0),
|
|
/* Master spin */ DMG_ENTRY(0, 0x0),
|
|
/* Kokiri jump */ DMG_ENTRY(0, 0x0),
|
|
/* Giant jump */ DMG_ENTRY(0, 0x0),
|
|
/* Master jump */ DMG_ENTRY(0, 0x0),
|
|
/* Unknown 1 */ DMG_ENTRY(0, 0x0),
|
|
/* Unblockable */ DMG_ENTRY(0, 0x0),
|
|
/* Hammer jump */ DMG_ENTRY(0, 0x0),
|
|
/* Unknown 2 */ DMG_ENTRY(0, 0x0),
|
|
};
|
|
|
|
static AnimationSpeedInfo sEnToryoAnimation = { &object_toryo_Anim_000E50, 1.0f, 0, 0 };
|
|
|
|
static Vec3f sMultVec = { 800.0f, 1000.0f, 0.0f };
|
|
|
|
void EnToryo_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnToryo* this = (EnToryo*)thisx;
|
|
s32 pad;
|
|
|
|
switch (globalCtx->sceneNum) {
|
|
case SCENE_SPOT09:
|
|
if (LINK_AGE_IN_YEARS == YEARS_ADULT) {
|
|
this->stateFlags |= 1;
|
|
}
|
|
break;
|
|
case SCENE_SPOT01:
|
|
if ((LINK_AGE_IN_YEARS == YEARS_CHILD) && IS_DAY) {
|
|
this->stateFlags |= 2;
|
|
}
|
|
break;
|
|
case SCENE_KAKARIKO:
|
|
if ((LINK_AGE_IN_YEARS == YEARS_CHILD) && IS_NIGHT) {
|
|
this->stateFlags |= 4;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if ((this->stateFlags & 7) == 0) {
|
|
Actor_Kill(&this->actor);
|
|
}
|
|
|
|
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 42.0f);
|
|
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_toryo_Skel_007150, NULL, this->jointTable, this->morphTable,
|
|
17);
|
|
Collider_InitCylinder(globalCtx, &this->collider);
|
|
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
|
|
CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit);
|
|
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4);
|
|
Animation_Change(&this->skelAnime, sEnToryoAnimation.animation, 1.0f, 0.0f,
|
|
Animation_GetLastFrame(sEnToryoAnimation.animation), sEnToryoAnimation.mode,
|
|
sEnToryoAnimation.morphFrames);
|
|
this->stateFlags |= 8;
|
|
this->actor.targetMode = 6;
|
|
this->actionFunc = func_80B20914;
|
|
}
|
|
|
|
void EnToryo_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnToryo* this = (EnToryo*)thisx;
|
|
|
|
Collider_DestroyCylinder(globalCtx, &this->collider);
|
|
}
|
|
|
|
s32 func_80B203D8(EnToryo* this, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
s32 ret = 1;
|
|
|
|
switch (Message_GetState(&globalCtx->msgCtx)) {
|
|
case TEXT_STATE_NONE:
|
|
case TEXT_STATE_DONE_HAS_NEXT:
|
|
case TEXT_STATE_CLOSING:
|
|
case TEXT_STATE_DONE_FADING:
|
|
case TEXT_STATE_EVENT:
|
|
ret = 1;
|
|
break;
|
|
case TEXT_STATE_CHOICE:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
if (globalCtx->msgCtx.choiceIndex == 0) {
|
|
Message_CloseTextbox(globalCtx);
|
|
this->actor.parent = NULL;
|
|
player->exchangeItemId = EXCH_ITEM_NONE;
|
|
globalCtx->msgCtx.msgMode = MSGMODE_PAUSED;
|
|
this->actor.textId = 0x601B;
|
|
ret = 3;
|
|
} else {
|
|
this->actor.textId = 0x606F;
|
|
ret = 2;
|
|
}
|
|
}
|
|
break;
|
|
case TEXT_STATE_DONE:
|
|
switch (this->actor.textId) {
|
|
case 0x5028:
|
|
ret = 1;
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
gSaveContext.infTable[23] |= 4;
|
|
ret = 0;
|
|
}
|
|
break;
|
|
case 0x601B:
|
|
ret = 1;
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
ret = 4;
|
|
}
|
|
break;
|
|
case 0x606F:
|
|
ret = 1;
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
gSaveContext.infTable[23] |= 2;
|
|
ret = 0;
|
|
}
|
|
break;
|
|
case 0x606A:
|
|
ret = 1;
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
gSaveContext.infTable[23] |= 1;
|
|
ret = 0;
|
|
}
|
|
break;
|
|
case 0x606B:
|
|
case 0x606C:
|
|
case 0x606D:
|
|
case 0x606E:
|
|
default:
|
|
ret = 1;
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
ret = 0;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
s32 func_80B205CC(EnToryo* this, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
s32 ret = 5;
|
|
|
|
switch (Message_GetState(&globalCtx->msgCtx)) {
|
|
case TEXT_STATE_NONE:
|
|
case TEXT_STATE_DONE_HAS_NEXT:
|
|
case TEXT_STATE_CLOSING:
|
|
case TEXT_STATE_DONE_FADING:
|
|
case TEXT_STATE_CHOICE:
|
|
case TEXT_STATE_EVENT:
|
|
ret = 5;
|
|
break;
|
|
case TEXT_STATE_DONE:
|
|
if (Message_ShouldAdvance(globalCtx)) {
|
|
ret = 0;
|
|
}
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
u32 func_80B20634(EnToryo* this, GlobalContext* globalCtx) {
|
|
u32 ret;
|
|
|
|
if (this->unk_1E0 != 0) {
|
|
if (this->unk_1E0 == 10) {
|
|
func_80078884(NA_SE_SY_TRE_BOX_APPEAR);
|
|
if (gSaveContext.infTable[23] & 2) {
|
|
ret = 0x606E;
|
|
} else {
|
|
ret = 0x606D;
|
|
}
|
|
} else {
|
|
ret = 0x200F;
|
|
}
|
|
}
|
|
//! @bug return value may be unitialized
|
|
return ret;
|
|
}
|
|
|
|
s32 func_80B206A0(EnToryo* this, GlobalContext* globalCtx) {
|
|
s32 textId = Text_GetFaceReaction(globalCtx, 0);
|
|
s32 ret = textId;
|
|
|
|
if (textId == 0) {
|
|
if ((this->stateFlags & 1)) {
|
|
if ((gSaveContext.eventChkInf[9] & 0xF) == 0xF) {
|
|
ret = 0x606C;
|
|
} else if ((gSaveContext.infTable[23] & 1)) {
|
|
ret = 0x606B;
|
|
} else {
|
|
ret = 0x606A;
|
|
}
|
|
} else if ((this->stateFlags & 2)) {
|
|
if ((gSaveContext.infTable[23] & 4)) {
|
|
ret = 0x5029;
|
|
} else {
|
|
ret = 0x5028;
|
|
}
|
|
} else {
|
|
ret = textId;
|
|
if ((this->stateFlags & 4)) {
|
|
ret = 0x506C;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void func_80B20768(EnToryo* this, GlobalContext* globalCtx) {
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
s16 sp32;
|
|
s16 sp30;
|
|
|
|
if (this->unk_1E4 == 3) {
|
|
Actor_ProcessTalkRequest(&this->actor, globalCtx);
|
|
Message_ContinueTextbox(globalCtx, this->actor.textId);
|
|
this->unk_1E4 = 1;
|
|
}
|
|
|
|
if (this->unk_1E4 == 1) {
|
|
this->unk_1E4 = func_80B203D8(this, globalCtx);
|
|
}
|
|
|
|
if (this->unk_1E4 == 5) {
|
|
this->unk_1E4 = func_80B205CC(this, globalCtx);
|
|
return;
|
|
}
|
|
|
|
if (this->unk_1E4 == 2) {
|
|
Message_ContinueTextbox(globalCtx, this->actor.textId);
|
|
this->unk_1E4 = 1;
|
|
}
|
|
|
|
if (this->unk_1E4 == 4) {
|
|
if (Actor_HasParent(&this->actor, globalCtx)) {
|
|
this->actor.parent = NULL;
|
|
this->unk_1E4 = 5;
|
|
} else {
|
|
func_8002F434(&this->actor, globalCtx, GI_SWORD_BROKEN, 100.0f, 10.0f);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (this->unk_1E4 == 0) {
|
|
if (Actor_ProcessTalkRequest(&this->actor, globalCtx)) {
|
|
this->unk_1E0 = func_8002F368(globalCtx);
|
|
if (this->unk_1E0 != 0) {
|
|
player->actor.textId = func_80B20634(this, globalCtx);
|
|
this->actor.textId = player->actor.textId;
|
|
}
|
|
this->unk_1E4 = 1;
|
|
return;
|
|
}
|
|
|
|
Actor_GetScreenPos(globalCtx, &this->actor, &sp32, &sp30);
|
|
if ((sp32 >= 0) && (sp32 < 0x141) && (sp30 >= 0) && (sp30 < 0xF1)) {
|
|
this->actor.textId = func_80B206A0(this, globalCtx);
|
|
func_8002F298(&this->actor, globalCtx, 100.0f, 10);
|
|
}
|
|
}
|
|
}
|
|
|
|
void func_80B20914(EnToryo* this, GlobalContext* globalCtx) {
|
|
SkelAnime_Update(&this->skelAnime);
|
|
func_80B20768(this, globalCtx);
|
|
if (this->unk_1E4 != 0) {
|
|
this->stateFlags |= 0x10;
|
|
} else {
|
|
this->stateFlags &= ~0x10;
|
|
}
|
|
}
|
|
|
|
void EnToryo_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnToryo* this = (EnToryo*)thisx;
|
|
ColliderCylinder* collider = &this->collider;
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
f32 rot;
|
|
|
|
Collider_UpdateCylinder(thisx, collider);
|
|
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, (Collider*)collider);
|
|
|
|
this->actionFunc(this, globalCtx);
|
|
|
|
if ((this->stateFlags & 8)) {
|
|
this->unk_1EC.unk_18.x = player->actor.focus.pos.x;
|
|
this->unk_1EC.unk_18.y = player->actor.focus.pos.y;
|
|
this->unk_1EC.unk_18.z = player->actor.focus.pos.z;
|
|
|
|
if ((this->stateFlags & 0x10)) {
|
|
func_80034A14(thisx, &this->unk_1EC, 0, 4);
|
|
return;
|
|
}
|
|
|
|
rot = thisx->yawTowardsPlayer - thisx->shape.rot.y;
|
|
if ((rot < 14563.0f) && (rot > -14563.0f)) {
|
|
func_80034A14(thisx, &this->unk_1EC, 0, 2);
|
|
} else {
|
|
func_80034A14(thisx, &this->unk_1EC, 0, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnToryo_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|
EnToryo* this = (EnToryo*)thisx;
|
|
|
|
func_80093D18(globalCtx->state.gfxCtx);
|
|
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
|
|
EnToryo_OverrideLimbDraw, EnToryo_PostLimbDraw, this);
|
|
}
|
|
|
|
s32 EnToryo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
|
void* thisx) {
|
|
EnToryo* this = (EnToryo*)thisx;
|
|
|
|
if ((this->stateFlags & 8)) {
|
|
switch (limbIndex) {
|
|
case 8:
|
|
rot->x += this->unk_1EC.unk_0E.y;
|
|
rot->y -= this->unk_1EC.unk_0E.x;
|
|
break;
|
|
case 15:
|
|
rot->x += this->unk_1EC.unk_08.y;
|
|
rot->z += this->unk_1EC.unk_08.x;
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void EnToryo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
|
|
EnToryo* this = (EnToryo*)thisx;
|
|
|
|
switch (limbIndex) {
|
|
case 15:
|
|
Matrix_MultVec3f(&sMultVec, &this->actor.focus.pos);
|
|
break;
|
|
}
|
|
}
|