Shipwright/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c

264 lines
9.4 KiB
C

/*
* File: z_en_niw_girl.c
* Overlay: ovl_En_Niw_Girl
* Description: Girl that chases a cuckoo around in Hyrule Market and Kakariko Village
*/
#include "z_en_niw_girl.h"
#include "objects/object_gr/object_gr.h"
#include "vt.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3 | ACTOR_FLAG_4)
void EnNiwGirl_Init(Actor* thisx, GlobalContext* globalCtx);
void EnNiwGirl_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnNiwGirl_Update(Actor* thisx, GlobalContext* globalCtx);
void EnNiwGirl_Draw(Actor* thisx, GlobalContext* globalCtx);
void EnNiwGirl_Talk(EnNiwGirl* this, GlobalContext* globalCtx);
void func_80AB94D0(EnNiwGirl* this, GlobalContext* globalCtx);
void func_80AB9210(EnNiwGirl* this, GlobalContext* globalCtx);
const ActorInit En_Niw_Girl_InitVars = {
ACTOR_EN_NIW_GIRL,
ACTORCAT_NPC,
FLAGS,
OBJECT_GR,
sizeof(EnNiwGirl),
(ActorFunc)EnNiwGirl_Init,
(ActorFunc)EnNiwGirl_Destroy,
(ActorFunc)EnNiwGirl_Update,
(ActorFunc)EnNiwGirl_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,
},
{ 10, 30, 0, { 0, 0, 0 } },
};
void EnNiwGirl_Init(Actor* thisx, GlobalContext* globalCtx) {
EnNiwGirl* this = (EnNiwGirl*)thisx;
s32 pad;
Vec3f vec1;
Vec3f vec2;
s32 pad2;
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gNiwGirlSkel, &gNiwGirlRunAnim, this->jointTable, this->morphTable,
17);
Collider_InitCylinder(globalCtx, &this->collider);
Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit);
this->actor.targetMode = 6;
if (this->actor.params < 0) {
this->actor.params = 0;
}
this->path = ((this->actor.params >> 8) & 0xFF);
this->actor.gravity = -3.0f;
Matrix_RotateY((this->actor.shape.rot.y / 32768.0f) * M_PI, MTXMODE_NEW);
vec2.x = vec2.y = vec2.z = 0.0f;
vec1.x = vec1.y = 0.0f;
vec1.z = 50.0;
Matrix_MultVec3f(&vec1, &vec2);
this->chasedEnNiw = (EnNiw*)Actor_SpawnAsChild(
&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_NIW, this->actor.world.pos.x + vec2.x,
this->actor.world.pos.y + vec2.y, this->actor.world.pos.z + vec2.z, 0, this->actor.world.rot.y, 0, 0xA);
if (this->chasedEnNiw != NULL) {
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ シツレイしちゃうわね!プンプン ☆☆☆☆☆ %d\n" VT_RST, this->actor.params);
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ きゃははははは、まてー ☆☆☆☆☆ %d\n" VT_RST, this->path);
osSyncPrintf("\n\n");
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
this->actionFunc = EnNiwGirl_Talk;
} else {
osSyncPrintf("\n\n");
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ なぜか、セットできむぅあせん ☆☆☆☆☆ %d\n" VT_RST, this->actor.params);
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ んんがくく ☆☆☆☆☆ %d\n" VT_RST, this->path);
osSyncPrintf("\n\n");
Actor_Kill(&this->actor);
}
}
void EnNiwGirl_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
void EnNiwGirl_Jump(EnNiwGirl* this, GlobalContext* globalCtx) {
f32 frameCount = Animation_GetLastFrame(&gNiwGirlRunAnim);
Animation_Change(&this->skelAnime, &gNiwGirlRunAnim, 1.0f, 0.0f, frameCount, 0, -10.0f);
this->actor.flags &= ~ACTOR_FLAG_0;
this->actionFunc = func_80AB9210;
}
void func_80AB9210(EnNiwGirl* this, GlobalContext* globalCtx) {
Path* path = &globalCtx->setupPathList[this->path];
f32 xDistBetween;
f32 zDistBetween;
SkelAnime_Update(&this->skelAnime);
Math_ApproachF(&this->actor.speedXZ, 3.0f, 0.2f, 0.4f);
// Find the X and Z distance between the girl and the cuckoo she is chasing
xDistBetween = this->chasedEnNiw->actor.world.pos.x - this->actor.world.pos.x;
zDistBetween = this->chasedEnNiw->actor.world.pos.z - this->actor.world.pos.z;
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_NONE) {
this->chasedEnNiw->path = 0;
}
if (sqrtf(SQ(xDistBetween) + SQ(zDistBetween)) < 70.0f) {
this->chasedEnNiw->path = (this->path + 1);
this->chasedEnNiw->unk_2EC = path->count;
} else if (sqrtf(SQ(xDistBetween) + SQ(zDistBetween)) > 150.0f) {
this->chasedEnNiw->path = 0;
}
// Change her angle so that she is always facing the cuckoo
Math_SmoothStepToS(&this->actor.shape.rot.y, Math_FAtan2F(xDistBetween, zDistBetween) * (0x8000 / M_PI), 3,
this->unk_27C, 0);
Math_ApproachF(&this->unk_27C, 5000.0f, 30.0f, 150.0f);
this->actor.world.rot.y = this->actor.shape.rot.y;
// Only allow Link to talk to her when she is playing the jumping animation
if ((this->jumpTimer == 0) || (Player_GetMask(globalCtx) != PLAYER_MASK_NONE)) {
this->jumpTimer = 60;
this->actionFunc = EnNiwGirl_Talk;
}
}
void EnNiwGirl_Talk(EnNiwGirl* this, GlobalContext* globalCtx) {
Animation_Change(&this->skelAnime, &gNiwGirlJumpAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gNiwGirlJumpAnim), 0,
-10.0f);
this->actor.flags |= ACTOR_FLAG_0;
this->actor.textId = 0x7000;
if ((gSaveContext.eventChkInf[8] & 1) && (this->unk_27A == 0)) {
this->actor.textId = 0x70EA;
}
switch (Player_GetMask(globalCtx)) {
case PLAYER_MASK_KEATON:
this->actor.textId = 0x7118;
break;
case PLAYER_MASK_SPOOKY:
this->actor.textId = 0x7119;
break;
case PLAYER_MASK_BUNNY:
case PLAYER_MASK_ZORA:
case PLAYER_MASK_GERUDO:
this->actor.textId = 0x711A;
break;
case PLAYER_MASK_SKULL:
case PLAYER_MASK_GORON:
case PLAYER_MASK_TRUTH:
this->actor.textId = 0x711B;
break;
}
this->unk_270 = 6;
this->actionFunc = func_80AB94D0;
}
void func_80AB94D0(EnNiwGirl* this, GlobalContext* globalCtx) {
SkelAnime_Update(&this->skelAnime);
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_NONE) {
this->chasedEnNiw->path = 0;
}
Math_ApproachZeroF(&this->actor.speedXZ, 0.8f, 0.2f);
if (Actor_ProcessTalkRequest(&this->actor, globalCtx)) {
if (this->actor.textId == 0x70EA) {
this->unk_27A = 1;
}
} else {
if ((this->jumpTimer == 0) && Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_NONE) {
this->jumpTimer = Rand_ZeroFloat(100.0f) + 250.0f;
this->actionFunc = EnNiwGirl_Jump;
} else {
func_8002F2CC(&this->actor, globalCtx, 100.0f);
}
}
}
void EnNiwGirl_Update(Actor* thisx, GlobalContext* globalCtx) {
EnNiwGirl* this = (EnNiwGirl*)thisx;
EnNiwGirlActionFunc tempActionFunc;
Player* player = GET_PLAYER(globalCtx);
Actor_SetScale(&this->actor, 0.013f);
this->unkUpTimer++;
tempActionFunc = func_80AB94D0;
if (this->blinkTimer == 0) {
this->eyeIndex++;
if (this->eyeIndex >= 3) {
this->eyeIndex = 0;
this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20;
}
}
this->unk_280 = 30.0f;
Actor_SetFocus(&this->actor, 30.0f);
if (tempActionFunc == this->actionFunc) {
this->unk_2D4.unk_18 = player->actor.world.pos;
if (!LINK_IS_ADULT) {
this->unk_2D4.unk_18.y = player->actor.world.pos.y - 10.0f;
}
func_80034A14(&this->actor, &this->unk_2D4, 2, 4);
this->unk_260 = this->unk_2D4.unk_08;
this->unk_266 = this->unk_2D4.unk_0E;
} else {
Math_SmoothStepToS(&this->unk_266.y, 0, 5, 3000, 0);
Math_SmoothStepToS(&this->unk_260.y, 0, 5, 3000, 0);
Math_SmoothStepToS(&this->unk_260.z, 0, 5, 3000, 0);
}
if (this->blinkTimer != 0) {
this->blinkTimer--;
}
if (this->jumpTimer != 0) {
this->jumpTimer--;
}
this->actionFunc(this, globalCtx);
Actor_MoveForward(&this->actor);
Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 100.0f, 100.0f, 200.0f, 0x1C);
Collider_UpdateCylinder(&this->actor, &this->collider);
CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
s32 EnNiwGirlOverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
void* thisx) {
EnNiwGirl* this = (EnNiwGirl*)thisx;
if (limbIndex == 3) {
rot->x += this->unk_266.y;
}
if (limbIndex == 4) {
rot->x += this->unk_260.y;
rot->z += this->unk_260.z;
}
return false;
}
static Vec3f sConstVec3f = { 0.2f, 0.2f, 0.2f };
void EnNiwGirl_Draw(Actor* thisx, GlobalContext* globalCtx) {
static void* eyeTextures[] = { gNiwGirlEyeOpenTex, gNiwGirlEyeHalfTex, gNiwGirlEyeClosedTex };
EnNiwGirl* this = (EnNiwGirl*)thisx;
s32 pad;
Vec3f sp4C = sConstVec3f;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeIndex]));
SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnNiwGirlOverrideLimbDraw, NULL, this);
func_80033C30(&this->actor.world.pos, &sp4C, 255, globalCtx);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}