mirror of
https://github.com/zeldaret/oot.git
synced 2025-08-07 14:50:15 +00:00
En_Heishi1 and Eff_Ss_Solder_Srch_Ball OK (#234)
* progress * init ok and merge master * enheishi1 and srchball OK * cleanup * cleanup * cleanup * more cleanup * done * more comments * add file headers * some review comments * move vectors * more review comments * angle in decimal * add prototype * semicolon would be good * fix * make unset actor ids 0 * reword comment * no &
This commit is contained in:
parent
b4a7ac9d71
commit
8b6e86649d
54 changed files with 636 additions and 1880 deletions
|
@ -17,7 +17,7 @@ void EnBdfire_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|||
|
||||
/*
|
||||
const ActorInit En_Bdfire_InitVars = {
|
||||
ACTOR_PLAYER,
|
||||
0,
|
||||
ACTORTYPE_ENEMY,
|
||||
FLAGS,
|
||||
OBJECT_KINGDODONGO,
|
||||
|
|
|
@ -11,7 +11,7 @@ void EnFhgFire_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|||
|
||||
/*
|
||||
const ActorInit En_Fhg_Fire_InitVars = {
|
||||
ACTOR_PLAYER,
|
||||
0,
|
||||
ACTORTYPE_BOSS,
|
||||
FLAGS,
|
||||
OBJECT_FHG,
|
||||
|
|
|
@ -1053,7 +1053,7 @@ void EnFloormas_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||
}
|
||||
if (this->actionFunc != EnFloormas_GrabLink) {
|
||||
if (this->actionFunc != EnFloormas_Split && this->actionFunc != EnFloormas_TakeDamage &&
|
||||
this->actor.freeze == 0) {
|
||||
this->actor.freezeTimer == 0) {
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider);
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ void EnFu_WaitAdult(EnFu* this, GlobalContext* globalCtx) {
|
|||
func_80A1D94C(this, globalCtx, 0x508E, func_80A1DBA0);
|
||||
} else if (player->stateFlags2 & 0x1000000) {
|
||||
this->actor.textId = 0x5035;
|
||||
func_8010B680(globalCtx, this->actor.textId, 0);
|
||||
func_8010B680(globalCtx, this->actor.textId, NULL);
|
||||
this->actionFunc = EnFu_TeachSong;
|
||||
this->behaviorFlags |= FU_WAIT;
|
||||
} else if (func_8002F194(&this->actor, globalCtx) != 0) {
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
/*
|
||||
* File: z_en_heishi1.c
|
||||
* Overlay: ovl_En_Heishi1
|
||||
* Description: Courtyard Guards
|
||||
*/
|
||||
|
||||
#include "z_en_heishi1.h"
|
||||
#include <vt.h>
|
||||
|
||||
#define FLAGS 0x00000010
|
||||
|
||||
|
@ -9,9 +16,24 @@ void EnHeishi1_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void EnHeishi1_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnHeishi1_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
/*
|
||||
void EnHeishi1_SetupWait(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_SetupWalk(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_SetupMoveToLink(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_SetupTurnTowardLink(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_SetupKick(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_SetupWaitNight(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
|
||||
void EnHeishi1_Wait(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_Walk(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_MoveToLink(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_TurnTowardLink(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_Kick(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_WaitNight(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
|
||||
s32 sPlayerIsCaught = false;
|
||||
|
||||
const ActorInit En_Heishi1_InitVars = {
|
||||
ACTOR_PLAYER,
|
||||
0,
|
||||
ACTORTYPE_NPC,
|
||||
FLAGS,
|
||||
OBJECT_SD,
|
||||
|
@ -21,37 +43,467 @@ const ActorInit En_Heishi1_InitVars = {
|
|||
(ActorFunc)EnHeishi1_Update,
|
||||
(ActorFunc)EnHeishi1_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/EnHeishi1_Init.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/EnHeishi1_Destroy.s")
|
||||
f32 sAnimParamsInit[][8] = {
|
||||
{ 1.0f, -10.0f, 3.0f, 0.5f, 1000.0f, 200.0f, 0.3f, 1000.0f },
|
||||
{ 3.0f, -3.0f, 6.0f, 0.8f, 2000.0f, 400.0f, 0.5f, 2000.0f },
|
||||
{ 1.0f, -10.0f, 3.0f, 0.5f, 1000.0f, 200.0f, 0.3f, 1000.0f },
|
||||
{ 3.0f, -3.0f, 6.0f, 0.8f, 2000.0f, 400.0f, 0.5f, 2000.0f },
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A5162C.s")
|
||||
s16 sBaseHeadTimers[] = { 20, 10, 20, 10, 13, 0 };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A516E4.s")
|
||||
Vec3f sRupeePositions[] = {
|
||||
{ 0.0f, 0.0f, 90.0f }, { -55.0f, 0.0f, 90.0f }, { -55.0f, 0.0f, 30.0f }, { -55.0f, 0.0f, -30.0f },
|
||||
{ 0.0f, 0.0f, -30.0f }, { 55.0f, 0.0f, -30.0f }, { 55.0f, 0.0f, 30.0f }, { 55.0f, 0.0f, 90.0f },
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A51A98.s")
|
||||
s32 sCamDataIdxs[] = {
|
||||
7, 7, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 4, 4, 5, 6,
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A51B54.s")
|
||||
s16 sWaypoints[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A51C4C.s")
|
||||
extern AnimationHeader D_06005880;
|
||||
extern AnimationHeader D_06005C30;
|
||||
extern SkeletonHeader D_0600BAC8;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A51D18.s")
|
||||
void EnHeishi1_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
EnHeishi1* this = THIS;
|
||||
Vec3f rupeePos;
|
||||
s32 i;
|
||||
u16 time;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A51F50.s")
|
||||
Actor_SetScale(&this->actor, 0.01f);
|
||||
SkelAnime_Init(globalCtx, &this->skelAnime, &D_0600BAC8, &D_06005C30, this->limbDrawTable,
|
||||
this->transitionDrawTable, 17);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A51FEC.s")
|
||||
this->type = (this->actor.params >> 8) & 0xFF;
|
||||
this->path = this->actor.params & 0xFF;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A52098.s")
|
||||
for (i = 0; i < ARRAY_COUNT(sAnimParamsInit[0]); i++) {
|
||||
this->animParams[i] = sAnimParamsInit[this->type][i];
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A5212C.s")
|
||||
// "type"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) " 種類☆☆☆☆☆☆☆☆☆☆☆☆☆ %d\n" VT_RST, this->type);
|
||||
// "path data"
|
||||
osSyncPrintf(VT_FGCOL(YELLOW) " れえるでぇたぁ☆☆☆☆☆☆☆☆ %d\n" VT_RST, this->path);
|
||||
osSyncPrintf(VT_FGCOL(PURPLE) " anime_frame_speed ☆☆☆☆☆☆ %f\n" VT_RST, this->animSpeed);
|
||||
// "interpolation frame"
|
||||
osSyncPrintf(VT_FGCOL(PURPLE) " 補間フレーム☆☆☆☆☆☆☆☆☆ %f\n" VT_RST, this->transitionRate);
|
||||
// "targeted movement speed value between points"
|
||||
osSyncPrintf(VT_FGCOL(PURPLE) " point間の移動スピード目標値 ☆ %f\n" VT_RST, this->moveSpeedTarget);
|
||||
// "maximum movement speed value between points"
|
||||
osSyncPrintf(VT_FGCOL(PURPLE) " point間の移動スピード最大 ☆☆ %f\n" VT_RST, this->moveSpeedMax);
|
||||
// "(body) targeted turning angle speed value"
|
||||
osSyncPrintf(VT_FGCOL(PURPLE) " (体)反転アングルスピード目標値 %f\n" VT_RST, this->bodyTurnSpeedTarget);
|
||||
// "(body) maximum turning angle speed"
|
||||
osSyncPrintf(VT_FGCOL(PURPLE) " (体)反転アングルスピード最大☆ %f\n" VT_RST, this->bodyTurnSpeedMax);
|
||||
// "(head) targeted turning angle speed value"
|
||||
osSyncPrintf(VT_FGCOL(PURPLE) " (頭)反転アングルスピード加算値 %f\n" VT_RST, this->headTurnSpeedScale);
|
||||
// "(head) maximum turning angle speed"
|
||||
osSyncPrintf(VT_FGCOL(PURPLE) " (頭)反転アングルスピード最大☆ %f\n" VT_RST, this->headTurnSpeedMax);
|
||||
// "current time"
|
||||
// clang-format off
|
||||
time = gSaveContext.dayTime; osSyncPrintf(VT_FGCOL(GREEN) " 今時間 %d\n" VT_RST, time);
|
||||
// clang-format on
|
||||
// "check time"
|
||||
osSyncPrintf(VT_FGCOL(YELLOW) " チェック時間 %d\n" VT_RST, 0xBAAA);
|
||||
osSyncPrintf("\n\n");
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A521FC.s")
|
||||
if (this->path == 3) {
|
||||
for (i = 0; i < ARRAY_COUNT(sRupeePositions); i++) {
|
||||
rupeePos = sRupeePositions[i];
|
||||
Actor_SpawnAttached(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_EX_RUPPY, rupeePos.x,
|
||||
rupeePos.y, rupeePos.z, 0, 0, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A52290.s")
|
||||
if (this->type != 5) {
|
||||
if (((gSaveContext.dayTime < 0xB888) || (!gSaveContext.nightFlag)) && !(gSaveContext.eventChkInf[8] & 1)) {
|
||||
this->actionFunc = EnHeishi1_SetupWalk;
|
||||
} else {
|
||||
Actor_Kill(&this->actor);
|
||||
}
|
||||
} else {
|
||||
if ((gSaveContext.dayTime >= 0xB889) || (gSaveContext.nightFlag) || (gSaveContext.eventChkInf[8] & 1)) {
|
||||
this->actionFunc = EnHeishi1_SetupWaitNight;
|
||||
} else {
|
||||
Actor_Kill(&this->actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/EnHeishi1_Update.s")
|
||||
void EnHeishi1_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/func_80A5263C.s")
|
||||
void EnHeishi1_SetupWalk(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
s16 frameCount = (f32)SkelAnime_GetFrameCount(&D_06005880.genericHeader);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Heishi1/EnHeishi1_Draw.s")
|
||||
SkelAnime_ChangeAnim(&this->skelAnime, &D_06005880, this->animSpeed, 0.0f, frameCount, 0, this->transitionRate);
|
||||
this->bodyTurnSpeed = 0.0f;
|
||||
this->moveSpeed = 0.0f;
|
||||
this->headDirection = Math_Rand_ZeroFloat(1.99f);
|
||||
this->actionFunc = EnHeishi1_Walk;
|
||||
}
|
||||
|
||||
void EnHeishi1_Walk(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
Path* path;
|
||||
Vec3s* pointPos;
|
||||
f32 pathDiffX;
|
||||
f32 pathDiffZ;
|
||||
s16 randOffset;
|
||||
|
||||
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||
|
||||
if (func_800A56C8(&this->skelAnime, 1.0f) || func_800A56C8(&this->skelAnime, 17.0f)) {
|
||||
Audio_PlayActorSound2(&this->actor, NA_SE_EV_KNIGHT_WALK);
|
||||
}
|
||||
|
||||
if (!sPlayerIsCaught) {
|
||||
path = &globalCtx->setupPathList[this->path];
|
||||
pointPos = SEGMENTED_TO_VIRTUAL(path->points);
|
||||
pointPos += this->waypoint;
|
||||
|
||||
Math_SmoothScaleMaxF(&this->actor.posRot.pos.x, pointPos->x, 1.0f, this->moveSpeed);
|
||||
Math_SmoothScaleMaxF(&this->actor.posRot.pos.z, pointPos->z, 1.0f, this->moveSpeed);
|
||||
|
||||
Math_SmoothScaleMaxF(&this->moveSpeed, this->moveSpeedTarget, 1.0f, this->moveSpeedMax);
|
||||
|
||||
pathDiffX = pointPos->x - this->actor.posRot.pos.x;
|
||||
pathDiffZ = pointPos->z - this->actor.posRot.pos.z;
|
||||
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.y, (Math_atan2f(pathDiffX, pathDiffZ) * 10430.378f), 3,
|
||||
this->bodyTurnSpeed, 0);
|
||||
|
||||
Math_SmoothScaleMaxF(&this->bodyTurnSpeed, this->bodyTurnSpeedTarget, 1.0f, this->bodyTurnSpeedMax);
|
||||
|
||||
if (this->headTimer == 0) {
|
||||
this->headDirection++;
|
||||
this->headAngleTarget = 0x2000;
|
||||
// if headDirection is odd, face 45 degrees left
|
||||
if ((this->headDirection & 1) != 0) {
|
||||
this->headAngleTarget *= -1;
|
||||
}
|
||||
randOffset = Math_Rand_ZeroFloat(30.0f);
|
||||
this->headTimer = sBaseHeadTimers[this->type] + randOffset;
|
||||
}
|
||||
|
||||
Math_SmoothScaleMaxF(&this->headAngle, this->headAngleTarget, this->headTurnSpeedScale, this->headTurnSpeedMax);
|
||||
|
||||
if ((this->path == BREG(1)) && (BREG(0) != 0)) {
|
||||
osSyncPrintf(VT_FGCOL(RED) " 種類 %d\n" VT_RST, this->path);
|
||||
osSyncPrintf(VT_FGCOL(RED) " ぱす %d\n" VT_RST, this->waypoint);
|
||||
osSyncPrintf(VT_FGCOL(RED) " 反転 %d\n" VT_RST, this->bodyTurnSpeed);
|
||||
osSyncPrintf(VT_FGCOL(RED) " 時間 %d\n" VT_RST, this->waypointTimer);
|
||||
osSyncPrintf(VT_FGCOL(RED) " 点座 %d\n" VT_RST, path->count);
|
||||
osSyncPrintf("\n\n");
|
||||
}
|
||||
|
||||
// when 20 units away from a middle waypoint, decide whether or not to skip it
|
||||
if ((fabsf(pathDiffX) < 20.0f) && (fabsf(pathDiffZ) < 20.0f)) {
|
||||
if (this->waypointTimer == 0) {
|
||||
if (this->type >= 2) {
|
||||
if ((this->waypoint >= 4) && (Math_Rand_ZeroFloat(1.99f) > 1.0f)) {
|
||||
if (this->waypoint == 7) {
|
||||
this->waypoint = 0;
|
||||
}
|
||||
if (this->waypoint >= 4) {
|
||||
this->waypoint -= 3;
|
||||
}
|
||||
this->waypointTimer = 5;
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->actionFunc = EnHeishi1_SetupWait;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnHeishi1_SetupMoveToLink(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
s16 frameCount = (f32)SkelAnime_GetFrameCount(&D_06005880.genericHeader);
|
||||
|
||||
SkelAnime_ChangeAnim(&this->skelAnime, &D_06005880, 3.0f, 0.0f, frameCount, 0, -3.0f);
|
||||
this->bodyTurnSpeed = 0.0f;
|
||||
this->moveSpeed = 0.0f;
|
||||
func_8010B680(globalCtx, 0x702D, &this->actor);
|
||||
Interface_SetDoAction(globalCtx, 0x12);
|
||||
this->actionFunc = EnHeishi1_MoveToLink;
|
||||
}
|
||||
|
||||
void EnHeishi1_MoveToLink(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
|
||||
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||
Math_SmoothScaleMaxF(&this->actor.posRot.pos.x, player->actor.posRot.pos.x, 1.0f, this->moveSpeed);
|
||||
Math_SmoothScaleMaxF(&this->actor.posRot.pos.z, player->actor.posRot.pos.z, 1.0f, this->moveSpeed);
|
||||
Math_SmoothScaleMaxF(&this->moveSpeed, 6.0f, 1.0f, 0.4f);
|
||||
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.y, this->actor.yawTowardsLink, 3, this->bodyTurnSpeed, 0);
|
||||
Math_SmoothScaleMaxF(&this->bodyTurnSpeed, 3000.0f, 1.0f, 300.0f);
|
||||
Math_SmoothDownscaleMaxF(&this->headAngle, 0.5f, 2000.0f);
|
||||
|
||||
if (this->actor.xzDistFromLink < 70.0f) {
|
||||
this->actionFunc = EnHeishi1_SetupTurnTowardLink;
|
||||
}
|
||||
}
|
||||
|
||||
void EnHeishi1_SetupWait(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
s16 rand;
|
||||
s16 frameCount = (f32)SkelAnime_GetFrameCount(&D_06005C30.genericHeader);
|
||||
|
||||
SkelAnime_ChangeAnim(&this->skelAnime, &D_06005C30, this->animSpeed, 0.0f, frameCount, 0, this->transitionRate);
|
||||
this->headBehaviorDecided = false;
|
||||
this->headDirection = Math_Rand_ZeroFloat(1.99f);
|
||||
rand = Math_Rand_ZeroFloat(50.0f);
|
||||
this->waitTimer = rand + 50;
|
||||
this->actionFunc = EnHeishi1_Wait;
|
||||
}
|
||||
|
||||
void EnHeishi1_Wait(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
s16 randOffset;
|
||||
s32 i;
|
||||
|
||||
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||
if (!sPlayerIsCaught) {
|
||||
switch (this->headBehaviorDecided) {
|
||||
case false:
|
||||
this->headDirection++;
|
||||
// if headDirection is odd, face 52 degrees left
|
||||
this->headAngleTarget = (this->headDirection & 1) ? 0x2500 : -0x2500;
|
||||
randOffset = Math_Rand_ZeroFloat(30.0f);
|
||||
this->headTimer = sBaseHeadTimers[this->type] + randOffset;
|
||||
this->headBehaviorDecided = true;
|
||||
break;
|
||||
case true:
|
||||
if (this->headTimer == 0) {
|
||||
if (this->waitTimer == 0) {
|
||||
if ((this->type == 0) || (this->type == 1)) {
|
||||
this->waypoint++;
|
||||
if (this->waypoint >= 4) {
|
||||
this->waypoint = 0;
|
||||
}
|
||||
} else {
|
||||
// waypoints are defined with corners as 0-3 and middle points as 4-7
|
||||
// to choose the next waypoint, the order "04152637" is hardcoded in an array
|
||||
for (i = 0; i < ARRAY_COUNT(sWaypoints); i++) {
|
||||
if (this->waypoint == sWaypoints[i]) {
|
||||
i++;
|
||||
if (i >= ARRAY_COUNT(sWaypoints)) {
|
||||
i = 0;
|
||||
}
|
||||
this->waypoint = sWaypoints[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->waypointTimer = 5;
|
||||
}
|
||||
this->actionFunc = EnHeishi1_SetupWalk;
|
||||
} else {
|
||||
this->headBehaviorDecided = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
Math_SmoothScaleMaxF(&this->headAngle, this->headAngleTarget, this->headTurnSpeedScale,
|
||||
this->headTurnSpeedMax + this->headTurnSpeedMax);
|
||||
|
||||
if ((this->path == BREG(1)) && (BREG(0) != 0)) {
|
||||
osSyncPrintf(VT_FGCOL(GREEN) " 種類 %d\n" VT_RST, this->path);
|
||||
osSyncPrintf(VT_FGCOL(GREEN) " ぱす %d\n" VT_RST, this->waypoint);
|
||||
osSyncPrintf(VT_FGCOL(GREEN) " 反転 %d\n" VT_RST, this->bodyTurnSpeed);
|
||||
osSyncPrintf(VT_FGCOL(GREEN) " 時間 %d\n" VT_RST, this->waypointTimer);
|
||||
osSyncPrintf("\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnHeishi1_SetupTurnTowardLink(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
s16 frameCount = (f32)SkelAnime_GetFrameCount(&D_06005C30.genericHeader);
|
||||
|
||||
SkelAnime_ChangeAnim(&this->skelAnime, &D_06005C30, 1.0f, 0.0f, frameCount, 0, -10.0f);
|
||||
this->kickTimer = 30;
|
||||
this->actionFunc = EnHeishi1_TurnTowardLink;
|
||||
}
|
||||
|
||||
void EnHeishi1_TurnTowardLink(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||
|
||||
if (this->type != 5) {
|
||||
Math_SmoothScaleMaxMinS(&this->actor.shape.rot.y, this->actor.yawTowardsLink, 3, this->bodyTurnSpeed, 0);
|
||||
Math_SmoothScaleMaxF(&this->bodyTurnSpeed, 3000.0f, 1.0f, 300.0f);
|
||||
Math_SmoothDownscaleMaxF(&this->headAngle, 0.5f, 2000.0f);
|
||||
}
|
||||
|
||||
if (this->kickTimer == 0) {
|
||||
this->actionFunc = EnHeishi1_SetupKick;
|
||||
}
|
||||
}
|
||||
|
||||
void EnHeishi1_SetupKick(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
s16 frameCount = (f32)SkelAnime_GetFrameCount(&D_06005C30.genericHeader);
|
||||
|
||||
SkelAnime_ChangeAnim(&this->skelAnime, &D_06005C30, 1.0f, 0.0f, frameCount, 0, -10.0f);
|
||||
this->actionFunc = EnHeishi1_Kick;
|
||||
}
|
||||
|
||||
void EnHeishi1_Kick(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||
if (!this->loadStarted) {
|
||||
// if dialog state is 5 and textbox has been advanced, kick player out
|
||||
if ((func_8010BDBC(&globalCtx->msgCtx) == 5) && (func_80106BC8(globalCtx))) {
|
||||
func_80106CCC(globalCtx);
|
||||
if (!this->loadStarted) {
|
||||
gSaveContext.eventChkInf[4] |= 0x4000;
|
||||
globalCtx->nextEntranceIndex = 0x4FA;
|
||||
globalCtx->sceneLoadFlag = 0x14;
|
||||
this->loadStarted = true;
|
||||
sPlayerIsCaught = false;
|
||||
globalCtx->fadeTransition = 0x2E;
|
||||
gSaveContext.nextTransition = 0x2E;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnHeishi1_SetupWaitNight(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
s16 frameCount = (f32)SkelAnime_GetFrameCount(&D_06005C30.genericHeader);
|
||||
|
||||
SkelAnime_ChangeAnim(&this->skelAnime, &D_06005C30, 1.0f, 0.0f, frameCount, 0, -10.0f);
|
||||
this->actionFunc = EnHeishi1_WaitNight;
|
||||
}
|
||||
|
||||
void EnHeishi1_WaitNight(EnHeishi1* this, GlobalContext* globalCtx) {
|
||||
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||
|
||||
if (this->actor.xzDistFromLink < 100.0f) {
|
||||
func_8010B680(globalCtx, 0x702D, &this->actor);
|
||||
func_80078884(NA_SE_SY_FOUND);
|
||||
// "Discovered!"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST);
|
||||
func_8002DF54(globalCtx, &this->actor, 1);
|
||||
this->actionFunc = EnHeishi1_SetupKick;
|
||||
}
|
||||
}
|
||||
|
||||
void EnHeishi1_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnHeishi1* this = THIS;
|
||||
s16 path;
|
||||
u8 i;
|
||||
s32 pad;
|
||||
Player* player = PLAYER;
|
||||
s32 pad2;
|
||||
Camera* activeCam;
|
||||
|
||||
this->activeTimer++;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(this->timers); i++) {
|
||||
if (this->timers[i] != 0) {
|
||||
this->timers[i]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->waypointTimer != 0) {
|
||||
this->waypointTimer--;
|
||||
}
|
||||
|
||||
activeCam = ACTIVE_CAM;
|
||||
|
||||
if (player->actor.freezeTimer == 0) {
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
|
||||
this->actor.uncullZoneForward = 550.0f;
|
||||
this->actor.uncullZoneScale = 350.0f;
|
||||
this->actor.uncullZoneDownward = 700.0f;
|
||||
|
||||
if (this->type != 5) {
|
||||
path = this->path * 2;
|
||||
if ((sCamDataIdxs[path] == activeCam->unk_148) || (sCamDataIdxs[path + 1] == activeCam->unk_148)) {
|
||||
if (!sPlayerIsCaught) {
|
||||
if ((this->actionFunc == EnHeishi1_Walk) || (this->actionFunc == EnHeishi1_Wait)) {
|
||||
Vec3f searchBallVel;
|
||||
Vec3f searchBallAccel = { 0.0f, 0.0f, 0.0f };
|
||||
Vec3f searchBallMult = { 0.0f, 0.0f, 20.0f };
|
||||
Vec3f searchBallPos;
|
||||
|
||||
searchBallPos.x = this->actor.posRot.pos.x;
|
||||
searchBallPos.y = this->actor.posRot.pos.y + 60.0f;
|
||||
searchBallPos.z = this->actor.posRot.pos.z;
|
||||
|
||||
Matrix_Push();
|
||||
Matrix_RotateY(((this->actor.shape.rot.y + this->headAngle) / 32768.0f) * M_PI, 0);
|
||||
searchBallMult.z = 30.0f;
|
||||
Matrix_MultVec3f(&searchBallMult, &searchBallVel);
|
||||
Matrix_Pull();
|
||||
|
||||
EffectSsSolderSrchBall_Spawn(globalCtx, &searchBallPos, &searchBallVel, &searchBallAccel, 2,
|
||||
&this->linkDetected);
|
||||
|
||||
if (this->actor.xzDistFromLink < 60.0f) {
|
||||
this->linkDetected = true;
|
||||
} else if (this->actor.xzDistFromLink < 70.0f) {
|
||||
// this case probably exists to detect link making a jump sound
|
||||
// from slightly further away than the previous 60 unit check
|
||||
if (player->actor.velocity.y > -4.0f) {
|
||||
this->linkDetected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->linkDetected) {
|
||||
// ! @bug This appears to be a check to make sure that link is standing on the ground
|
||||
// before getting caught. However this is an issue for two reasons:
|
||||
// 1: When doing a backflip or falling from the upper path, links y velocity will reach
|
||||
// less than -4.0 before even touching the ground.
|
||||
// 2: There is one frame when landing from a sidehop where you can sidehop again without
|
||||
// letting y velocity reach -4.0 or less. This enables the player to do frame perfect
|
||||
// sidehops onto the next screen and prevent getting caught.
|
||||
if (!(player->actor.velocity.y > -3.9f)) {
|
||||
this->linkDetected = false;
|
||||
// this 60 unit height check is so the player doesnt get caught when on the upper path
|
||||
if (fabsf(player->actor.posRot.pos.y - this->actor.posRot.pos.y) < 60.0f) {
|
||||
func_80078884(NA_SE_SY_FOUND);
|
||||
// "Discovered!"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST);
|
||||
func_8002DF54(globalCtx, &this->actor, 1);
|
||||
sPlayerIsCaught = true;
|
||||
this->actionFunc = EnHeishi1_SetupMoveToLink;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 EnHeishi1_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
Actor* thisx) {
|
||||
EnHeishi1* this = THIS;
|
||||
|
||||
// turn the guards head to match the direction he is looking
|
||||
if (limbIndex == 16) {
|
||||
rot->x += (s16)this->headAngle;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EnHeishi1_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
EnHeishi1* this = THIS;
|
||||
Vec3f matrixScale = { 0.3f, 0.3f, 0.3f };
|
||||
|
||||
func_80093D18(globalCtx->state.gfxCtx);
|
||||
SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, EnHeishi1_OverrideLimbDraw, NULL,
|
||||
&this->actor);
|
||||
func_80033C30(&this->actor.posRot.pos, &matrixScale, 0xFF, globalCtx);
|
||||
|
||||
if ((this->path == BREG(1)) && (BREG(0) != 0)) {
|
||||
DebugDisplay_AddObject(this->actor.posRot.pos.x, this->actor.posRot.pos.y + 100.0f, this->actor.posRot.pos.z,
|
||||
17000, this->actor.posRot.rot.y, this->actor.posRot.rot.z, 1.0f, 1.0f, 1.0f, 255, 0, 0,
|
||||
255, 4, globalCtx->state.gfxCtx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,50 @@
|
|||
|
||||
struct EnHeishi1;
|
||||
|
||||
typedef void (*EnHeishi1ActionFunc)(struct EnHeishi1*, GlobalContext*);
|
||||
|
||||
typedef struct EnHeishi1 {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x160];
|
||||
/* 0x014C */ SkelAnime skelAnime;
|
||||
/* 0x0190 */ Vec3s limbDrawTable[17];
|
||||
/* 0x01F6 */ Vec3s transitionDrawTable[17];
|
||||
/* 0x025C */ EnHeishi1ActionFunc actionFunc;
|
||||
/* 0x0260 */ s16 activeTimer;
|
||||
/* 0x0262 */ s16 headDirection;
|
||||
/* 0x0264 */ s16 headBehaviorDecided;
|
||||
/* 0x0266 */ s16 linkDetected;
|
||||
/* 0x0268 */ s16 loadStarted;
|
||||
/* 0x026A */ s16 type;
|
||||
/* 0x026C */ s16 path;
|
||||
/* 0x026E */ s16 unused1;
|
||||
/* 0x0270 */ s16 waypointTimer;
|
||||
/* 0x0272 */ s16 unused2;
|
||||
/* 0x0274 */ f32 moveSpeed;
|
||||
/* 0x0278 */ f32 bodyTurnSpeed;
|
||||
/* 0x027C */ f32 headAngle;
|
||||
/* 0x0280 */ f32 headAngleTarget;
|
||||
union {
|
||||
struct {
|
||||
/* 0x0284 */ f32 animSpeed;
|
||||
/* 0x0288 */ f32 transitionRate;
|
||||
/* 0x028C */ f32 moveSpeedTarget;
|
||||
/* 0x0290 */ f32 moveSpeedMax;
|
||||
/* 0x0294 */ f32 bodyTurnSpeedTarget;
|
||||
/* 0x0298 */ f32 bodyTurnSpeedMax;
|
||||
/* 0x029C */ f32 headTurnSpeedScale;
|
||||
/* 0x02A0 */ f32 headTurnSpeedMax;
|
||||
};
|
||||
f32 animParams[8];
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
/* 0x02A4 */ s16 headTimer;
|
||||
/* 0x02A6 */ s16 waitTimer;
|
||||
/* 0x02A8 */ s16 kickTimer;
|
||||
};
|
||||
s16 timers[3];
|
||||
};
|
||||
/* 0x02AA */ s16 waypoint;
|
||||
} EnHeishi1; // size = 0x02AC
|
||||
|
||||
extern const ActorInit En_Heishi1_InitVars;
|
||||
|
|
|
@ -631,7 +631,7 @@ void func_80A544AC(EnHeishi2* this, GlobalContext* globalCtx) {
|
|||
Math_SmoothScaleMaxF(&this->unk_2E4, 3000.0f, 1.0f, 500.0f);
|
||||
this->actor.posRot.rot.z = this->actor.shape.rot.z;
|
||||
if (this->actor.shape.rot.z < -6000) {
|
||||
func_8010B680(globalCtx, 0x708F, 0);
|
||||
func_8010B680(globalCtx, 0x708F, NULL);
|
||||
this->actor.flags |= 0x10000;
|
||||
this->actionFunc = func_80A5455C;
|
||||
this->unk_2E4 = 0.0f;
|
||||
|
|
|
@ -338,7 +338,7 @@ void func_80AA0F44(EnMa1* this, GlobalContext* globalCtx) {
|
|||
player->stateFlags2 |= 0x2000000;
|
||||
player->unk_6A8 = &this->actor;
|
||||
this->actor.textId = 0x2061;
|
||||
func_8010B680(globalCtx, this->actor.textId, 0);
|
||||
func_8010B680(globalCtx, this->actor.textId, NULL);
|
||||
this->unk_1E8.unk_00 = 1;
|
||||
this->actor.flags |= 0x10000;
|
||||
this->actionFunc = func_80AA106C;
|
||||
|
|
|
@ -656,7 +656,7 @@ void func_80AF390C(EnRu2* this, GlobalContext* globalCtx) {
|
|||
func_80AF37AC();
|
||||
} else if (*unk_2C4 > kREG(4) + 50.0f) {
|
||||
this->actor.textId = 0x403E;
|
||||
func_8010B680(globalCtx, this->actor.textId, 0);
|
||||
func_8010B680(globalCtx, this->actor.textId, NULL);
|
||||
this->action = 17;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ void func_80AFB768(EnSi* this, GlobalContext* globalCtx) {
|
|||
if (this->collider.base.maskB & 0x1) {
|
||||
this->collider.base.maskB &= ~0x1;
|
||||
Item_Give(globalCtx, ITEM_SKULL_TOKEN);
|
||||
player->actor.freeze = 10;
|
||||
player->actor.freezeTimer = 10;
|
||||
func_8010B680(globalCtx, 0xB4, 0);
|
||||
func_800F5C64(0x39);
|
||||
this->actionFunc = func_80AFB950;
|
||||
|
@ -105,7 +105,7 @@ void func_80AFB89C(EnSi* this, GlobalContext* globalCtx) {
|
|||
|
||||
if ((this->actor.flags & 0x2000) != 0x2000) {
|
||||
Item_Give(globalCtx, ITEM_SKULL_TOKEN);
|
||||
player->actor.freeze = 10;
|
||||
player->actor.freezeTimer = 10;
|
||||
func_8010B680(globalCtx, 0xB4, 0);
|
||||
func_800F5C64(0x39);
|
||||
this->actionFunc = func_80AFB950;
|
||||
|
@ -118,7 +118,7 @@ void func_80AFB950(EnSi* this, GlobalContext* globalCtx) {
|
|||
s16 params;
|
||||
|
||||
if (func_8010BDBC(&globalCtx->msgCtx) != 2) {
|
||||
player->actor.freeze = 10;
|
||||
player->actor.freezeTimer = 10;
|
||||
} else {
|
||||
params = this->actor.params;
|
||||
temp = (params & 0x1F00) >> 8;
|
||||
|
|
|
@ -661,7 +661,7 @@ void EnTk_Dig(EnTk* this, GlobalContext* globalCtx) {
|
|||
if (func_800A56C8(&this->skelAnim, this->skelAnim.animFrameCount) != 0) {
|
||||
if (this->currentReward < 0) {
|
||||
/* "Nope, nothing here!" */
|
||||
func_8010B680(globalCtx, 0x501A, 0);
|
||||
func_8010B680(globalCtx, 0x501A, NULL);
|
||||
} else {
|
||||
func_80106CCC(globalCtx);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ void EnVbBall_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|||
|
||||
/*
|
||||
const ActorInit En_Vb_Ball_InitVars = {
|
||||
ACTOR_PLAYER,
|
||||
0,
|
||||
ACTORTYPE_BOSS,
|
||||
FLAGS,
|
||||
OBJECT_FD,
|
||||
|
|
|
@ -539,7 +539,7 @@ void EnWallmas_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider);
|
||||
|
||||
if ((this->actionFunc != EnWallmas_TakeDamage) && (this->actor.bgCheckFlags & 1) != 0 &&
|
||||
(this->actor.freeze == 0)) {
|
||||
(this->actor.freezeTimer == 0)) {
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ void func_80B4B240(EnZl1* this, GlobalContext* globalCtx) {
|
|||
animationHeader = &D_06011348;
|
||||
sp3C = 1;
|
||||
this->actor.textId = 0x702E;
|
||||
func_8010B680(globalCtx, this->actor.textId, 0);
|
||||
func_8010B680(globalCtx, this->actor.textId, NULL);
|
||||
this->unk_1E2 += 1;
|
||||
break;
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ void func_80B4BBC4(EnZl1* this, GlobalContext* globalCtx) {
|
|||
func_8002DF54(globalCtx, &this->actor, 1);
|
||||
func_8002F7DC(&player->actor, NA_SE_VO_LI_SURPRISE_KID);
|
||||
this->actor.textId = 0x7039;
|
||||
func_8010B680(globalCtx, this->actor.textId, 0);
|
||||
func_8010B680(globalCtx, this->actor.textId, NULL);
|
||||
this->unk_1E2 = 0;
|
||||
this->actionFunc = func_80B4BF2C;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,53 @@
|
|||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
/*
|
||||
* File: z_eff_ss_solder_srch_ball.c
|
||||
* Overlay: ovl_Effect_Ss_Solder_Srch_Ball
|
||||
* Description: Vision sphere for courtyard guards
|
||||
*/
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/func_809AC130.s")
|
||||
#include "z_eff_ss_solder_srch_ball.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/effects/ovl_Effect_Ss_Solder_Srch_Ball/func_809AC1AC.s")
|
||||
u32 EffectSsSolderSrchBall_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx);
|
||||
void EffectSsSolderSrchBall_Update(GlobalContext* globalCtx, u32 index, EffectSs* this);
|
||||
|
||||
EffectSsInit Effect_Ss_Solder_Srch_Ball_InitVars = {
|
||||
EFFECT_SS_SOLDER_SRCH_BALL,
|
||||
EffectSsSolderSrchBall_Init,
|
||||
};
|
||||
|
||||
u32 EffectSsSolderSrchBall_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) {
|
||||
EffectSsSolderSrchBallInitParams* initParams = (EffectSsSolderSrchBallInitParams*)initParamsx;
|
||||
|
||||
this->pos = initParams->pos;
|
||||
this->velocity = initParams->velocity;
|
||||
this->accel = initParams->accel;
|
||||
this->update = EffectSsSolderSrchBall_Update;
|
||||
this->life = 100;
|
||||
this->regs[1] = initParams->unk_24;
|
||||
this->unk_3C = initParams->linkDetected;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EffectSsSolderSrchBall_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) {
|
||||
s32 pad;
|
||||
f32 playerPosDiffX;
|
||||
f32 playerPosDiffY;
|
||||
f32 playerPosDiffZ;
|
||||
s16* linkDetected;
|
||||
Player* player = PLAYER;
|
||||
|
||||
linkDetected = this->unk_3C;
|
||||
|
||||
playerPosDiffX = player->actor.posRot.pos.x - this->pos.x;
|
||||
playerPosDiffY = player->actor.posRot.pos.y - this->pos.y;
|
||||
playerPosDiffZ = player->actor.posRot.pos.z - this->pos.z;
|
||||
|
||||
if (!func_8003E30C(&globalCtx->colCtx, &this->pos, 30.0f)) {
|
||||
if (sqrtf(SQ(playerPosDiffX) + SQ(playerPosDiffY) + SQ(playerPosDiffZ)) < 70.0f) {
|
||||
*linkDetected = true;
|
||||
}
|
||||
} else {
|
||||
if (this->life > 1) {
|
||||
this->life = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef _Z_EFF_SS_SOLDERSRCHBALL_H_
|
||||
#define _Z_EFF_SS_SOLDERSRCHBALL_H_
|
||||
|
||||
#include <ultra64.h>
|
||||
#include <global.h>
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ Vec3f pos;
|
||||
/* 0x0C */ Vec3f velocity;
|
||||
/* 0x18 */ Vec3f accel;
|
||||
/* 0x24 */ s16 unk_24;
|
||||
/* 0x28 */ s16* linkDetected;
|
||||
} EffectSsSolderSrchBallInitParams;
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue