diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml index d87ef3f31b..11b6a0861c 100644 --- a/assets/xml/objects/gameplay_keep.xml +++ b/assets/xml/objects/gameplay_keep.xml @@ -972,16 +972,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/src/code/z_en_item00.c b/src/code/z_en_item00.c index 10c33090cb..87f1a18029 100644 --- a/src/code/z_en_item00.c +++ b/src/code/z_en_item00.c @@ -1,6 +1,7 @@ #include "global.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_gi_hearts/object_gi_hearts.h" +#include "overlays/actors/ovl_En_Elforg/z_en_elforg.h" #define FLAGS 0x00000000 @@ -867,8 +868,9 @@ Actor* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, u32 params) { SoundSource_PlaySfxAtFixedWorldPos(play, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); } } else { - spawnedActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, - spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) & 0x7F) << 9) | 7); + spawnedActor = + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, + 0, STRAY_FAIRY_PARAMS(((param7F00 >> 8) & 0x7F), 0, STRAY_FAIRY_TYPE_COLLECTIBLE)); if (param20000 == 0) { if (!Flags_GetCollectible(play, (param7F00 >> 8) & 0x7F)) { SoundSource_PlaySfxAtFixedWorldPos(play, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); @@ -924,8 +926,9 @@ Actor* Item_DropCollectible2(PlayState* play, Vec3f* spawnPos, s32 params) { spawnedActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) << 9) & 0xFE00) | 0x102); } else { - spawnedActor = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, - spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) & 0x7F) << 9) | 7); + spawnedActor = + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, + 0, STRAY_FAIRY_PARAMS(((param7F00 >> 8) & 0x7F), 0, STRAY_FAIRY_TYPE_COLLECTIBLE)); } if (Flags_GetCollectible(play, (param7F00 >> 8) & 0x7F) == 0) { SoundSource_PlaySfxAtFixedWorldPos(play, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); diff --git a/src/overlays/actors/ovl_En_Box/z_en_box.c b/src/overlays/actors/ovl_En_Box/z_en_box.c index 81ddc423ae..b63018b888 100644 --- a/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -538,7 +538,7 @@ void EnBox_Open(EnBox* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_ELFORG, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, this->dyna.actor.world.rot.x, this->dyna.actor.world.rot.y, this->dyna.actor.world.rot.z, - ((ENBOX_GET_CHEST_FLAG(&this->dyna.actor) & 0x7F) << 9) | STRAY_FAIRY_TYPE_CHEST); + STRAY_FAIRY_PARAMS(ENBOX_GET_CHEST_FLAG(&this->dyna.actor), 0, STRAY_FAIRY_TYPE_CHEST)); } else if (this->movementFlags & ENBOX_MOVE_0x40) { this->movementFlags &= ~ENBOX_MOVE_0x40; } diff --git a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c index e02ac11182..d0bc05b8b5 100644 --- a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c +++ b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c @@ -73,10 +73,10 @@ void EnElfbub_Init(Actor* thisx, PlayState* play) { Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); this->actor.colChkInfo.mass = MASS_IMMOVABLE; - childActor = Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_ELFORG, this->actor.world.pos.x, - this->actor.world.pos.y + 12.0f, this->actor.world.pos.z, this->actor.world.rot.x, - this->actor.world.rot.y, this->actor.world.rot.z, - ((ENELFBUB_GET_SWITCHFLAG(&this->actor) & 0x7F) << 9) | STRAY_FAIRY_TYPE_BUBBLE); + childActor = Actor_SpawnAsChild( + &play->actorCtx, &this->actor, play, ACTOR_EN_ELFORG, this->actor.world.pos.x, this->actor.world.pos.y + 12.0f, + this->actor.world.pos.z, this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, + STRAY_FAIRY_PARAMS(ENELFBUB_GET_SWITCHFLAG(&this->actor), 0, STRAY_FAIRY_TYPE_BUBBLE)); if (childActor != NULL) { childActor->parent = &this->actor; } diff --git a/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c b/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c index db131058c1..ba8cb4f019 100644 --- a/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c +++ b/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c @@ -241,7 +241,7 @@ void func_80A39DC8(EnElfgrp* this, PlayState* play, s32 arg2, s32 arg3) { s32 pad; s32 i; Actor* elforg; - s32 temp; + s32 params; Vec3f sp6C; Player* player = GET_PLAYER(play); @@ -252,16 +252,16 @@ void func_80A39DC8(EnElfgrp* this, PlayState* play, s32 arg2, s32 arg3) { if (arg3 == 0) { sp6C = this->actor.world.pos; sp6C.y += 20.0f; - temp = ((this->unk_147 & 7) << 6) | STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN; + params = STRAY_FAIRY_PARAMS(0, this->unk_147, STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN); } else { sp6C = player->actor.world.pos; sp6C.y += 20.0f; - temp = ((this->unk_147 & 7) << 6) | STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN; + params = STRAY_FAIRY_PARAMS(0, this->unk_147, STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN); } for (i = 0; i < arg2; i++) { elforg = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELFORG, randPlusMinusPoint5Scaled(20.0f) + sp6C.x, sp6C.y, - randPlusMinusPoint5Scaled(20.0f) + sp6C.z, 0, 0, 0, temp); + randPlusMinusPoint5Scaled(20.0f) + sp6C.z, 0, 0, 0, params); if (elforg == NULL) { continue; } @@ -284,8 +284,8 @@ s32 func_80A39F50(PlayState* play) { } elfOrg = (EnElforg*)itemAction; - if (!(elfOrg->flags & STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME)) { - elfOrg->flags |= STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME; + if (!(elfOrg->strayFairyFlags & STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME)) { + elfOrg->strayFairyFlags |= STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME; } itemAction = itemAction->next; } @@ -307,8 +307,8 @@ s32 func_80A39FBC(PlayState* play) { } elfOrg = (EnElforg*)itemAction; - if (!(elfOrg->flags & STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN)) { - elfOrg->flags |= STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN; + if (!(elfOrg->strayFairyFlags & STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN)) { + elfOrg->strayFairyFlags |= STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN; if (phi_v1 >= 100) { return phi_v1; } @@ -336,7 +336,7 @@ void func_80A3A044(PlayState* play) { elfOrg = (EnElforg*)itemAction; elfOrg->actor.home.rot.x = 0x14; - elfOrg->flags |= STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS; + elfOrg->strayFairyFlags |= STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS; itemAction = itemAction->next; } diff --git a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c index 915eb1d6c7..04ad98f8fa 100644 --- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c +++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c @@ -5,7 +5,6 @@ */ #include "z_en_elforg.h" -#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS (ACTOR_FLAG_10) @@ -70,34 +69,37 @@ void EnElforg_Init(Actor* thisx, PlayState* play) { s32 pad; EnElforg* this = THIS; - Actor_SetScale(&this->actor, 0.01f); - this->flags = 0; + Actor_SetScale(thisx, 0.01f); + this->strayFairyFlags = 0; this->direction = 0; SkelAnime_InitFlex(play, &this->skelAnime, &gStrayFairySkel, &gStrayFairyFlyingAnim, this->jointTable, this->jointTable, STRAY_FAIRY_LIMB_MAX); this->skelAnime.playSpeed = 1.0f; - ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); - this->actor.shape.shadowAlpha = 255; + ActorShape_Init(&thisx->shape, 0.0f, NULL, 0.0f); + thisx->shape.shadowAlpha = 255; - switch (STRAY_FAIRY_TYPE(&this->actor)) { + switch (STRAY_FAIRY_TYPE(thisx)) { case STRAY_FAIRY_TYPE_CLOCK_TOWN: if (gSaveContext.save.weekEventReg[8] & 0x80) { - Actor_MarkForDeath(&this->actor); + Actor_MarkForDeath(thisx); return; } break; + case STRAY_FAIRY_TYPE_COLLECTIBLE: - if (Flags_GetCollectible(play, STRAY_FAIRY_FLAG(&this->actor))) { - Actor_MarkForDeath(&this->actor); + if (Flags_GetCollectible(play, STRAY_FAIRY_FLAG(thisx))) { + Actor_MarkForDeath(thisx); return; } break; + default: - if (Flags_GetSwitch(play, STRAY_FAIRY_FLAG(&this->actor))) { - Actor_MarkForDeath(&this->actor); + if (Flags_GetSwitch(play, STRAY_FAIRY_FLAG(thisx))) { + Actor_MarkForDeath(thisx); return; } break; + case STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN: case STRAY_FAIRY_TYPE_BUBBLE: case STRAY_FAIRY_TYPE_CHEST: @@ -108,44 +110,48 @@ void EnElforg_Init(Actor* thisx, PlayState* play) { if (Map_IsInDungeonOrBossArea(play)) { this->area = gSaveContext.dungeonIndex + STRAY_FAIRY_AREA_WOODFALL; } else { - // Needs to be thisx in order to match this->area = STRAY_FAIRY_GET_NON_DUNGEON_AREA(thisx); } - switch (STRAY_FAIRY_TYPE(&this->actor)) { + switch (STRAY_FAIRY_TYPE(thisx)) { case STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN: EnElforg_InitializeParams(this); this->actionFunc = EnElforg_FreeFloatingFairyFountain; this->targetSpeedXZ = Rand_ZeroFloat(2.0f) + 1.0f; this->targetDistanceFromHome = Rand_ZeroFloat(100.0f) + 50.0f; break; + case STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN: EnElforg_InitializeParams(this); this->actionFunc = EnElforg_TurnInFairy; this->secondaryTimer = 60; break; + case STRAY_FAIRY_TYPE_BUBBLE: this->timer = 0; this->actionFunc = EnElforg_TrappedByBubble; break; + case STRAY_FAIRY_TYPE_ENEMY: this->actionFunc = EnElforg_SetupTrappedByEnemy; EnElforg_SetupTrappedByEnemy(this, play); - this->actor.draw = NULL; + thisx->draw = NULL; break; + case STRAY_FAIRY_TYPE_COLLIDER: this->actionFunc = EnElforg_HiddenByCollider; - this->actor.draw = NULL; - Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); - Collider_UpdateCylinder(&this->actor, &this->collider); + thisx->draw = NULL; + Collider_InitAndSetCylinder(play, &this->collider, thisx, &sCylinderInit); + Collider_UpdateCylinder(thisx, &this->collider); break; + default: EnElforg_InitializeParams(this); this->actionFunc = EnElforg_FreeFloating; break; } - this->actor.shape.rot.y = 0; + thisx->shape.rot.y = 0; } void EnElforg_Destroy(Actor* thisx, PlayState* play) { @@ -216,6 +222,7 @@ void EnElforg_MoveToTargetFairyFountain(EnElforg* this, Vec3f* homePos) { zDifference = this->actor.world.pos.z - homePos->z; targetAngle = Math_FAtan2F(-zDifference, -xDifference); xzDistance = sqrtf(SQ(xDifference) + SQ(zDifference)); + if ((this->targetDistanceFromHome + 10.0f) < xzDistance) { angleAdjustment = 0x1000; } else if ((this->targetDistanceFromHome - 10.0f) > xzDistance) { @@ -223,6 +230,7 @@ void EnElforg_MoveToTargetFairyFountain(EnElforg* this, Vec3f* homePos) { } else { angleAdjustment = 0x4000; } + targetAngle += angleAdjustment; Math_SmoothStepToS(&this->actor.world.rot.y, targetAngle, 2, 4000, 1000); EnElforg_ApproachTargetSpeedXZ(this); @@ -240,6 +248,7 @@ void EnElforg_MoveToTarget(EnElforg* this, Vec3f* targetPos) { this->actor.shape.yOffset += 100.0f * Math_SinS(this->timer << 9); EnElforg_ApproachTargetYPosition(this, targetPos); targetAngle = Math_FAtan2F(-(this->actor.world.pos.z - targetPos->z), -(this->actor.world.pos.x - targetPos->x)); + if (this->targetSpeedXZ > 2.0f) { Math_SmoothStepToS(&this->actor.world.rot.y, targetAngle, 2, 0x400, 0x100); } else { @@ -248,6 +257,7 @@ void EnElforg_MoveToTarget(EnElforg* this, Vec3f* targetPos) { targetAngle += 0x2000; Math_SmoothStepToS(&this->actor.world.rot.y, targetAngle, 10, 0x200, 0x80); } + EnElforg_ApproachTargetSpeedXZ(this); Actor_MoveWithGravity(&this->actor); } @@ -258,6 +268,7 @@ void func_80ACCBB8(EnElforg* this, PlayState* play) { void EnElforg_TrappedByBubble(EnElforg* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); + if ((this->actor.parent == NULL) || (this->actor.parent->update == NULL)) { EnElforg_InitializeParams(this); this->actionFunc = EnElforg_FreeFloating; @@ -266,6 +277,7 @@ void EnElforg_TrappedByBubble(EnElforg* this, PlayState* play) { this->actor.world.pos = this->actor.parent->world.pos; this->actor.world.pos.y += 12.0f; } + func_80ACCBB8(this, play); } @@ -282,10 +294,12 @@ void EnElforg_TurnInFairy(EnElforg* this, PlayState* play) { this->actor.shape.yOffset *= 0.9f; this->actor.speedXZ = 5.0f; EnElforg_ApproachTargetYPosition(this, &player->bodyPartsPos[0]); + xzDistToPlayer = this->actor.xzDistToPlayer; if (xzDistToPlayer < 0.0f) { xzDistToPlayer = 10.0f; } + newAngle = 0x28000 / xzDistToPlayer; Math_SmoothStepToF(&xzDistToPlayer, 40.0f, 0.2f, 100.0f, 1.0f); rotationTemp = this->actor.yawTowardsPlayer - newAngle; @@ -303,7 +317,7 @@ void EnElforg_TurnInFairy(EnElforg* this, PlayState* play) { this->targetSpeedXZ = 3.0f; this->targetDistanceFromHome = 50.0f; this->actionFunc = EnElforg_FreeFloatingFairyFountain; - this->flags &= ~STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN; + this->strayFairyFlags &= ~STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN; } } @@ -313,19 +327,21 @@ void EnElforg_QuicklyCircleFairyFountain(EnElforg* this, PlayState* play) { if (this->secondaryTimer <= 30) { this->actionFunc = EnElforg_TurnInFairy; } + this->secondaryTimer--; } void EnElforg_FreeFloatingFairyFountain(EnElforg* this, PlayState* play) { s32 pad; - if (this->flags & STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME) { + if (this->strayFairyFlags & STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME) { // This happens when "turning in" the last batch of Stray Fairies to // a Fairy Fountain. The ones being "turned in" will fly very // quickly to the center of the fountain. if (this->targetSpeedXZ < 8.0f) { this->targetSpeedXZ += 0.1f; } + if (this->targetDistanceFromHome > 0.0f) { this->targetDistanceFromHome -= 2.0f; } @@ -335,22 +351,27 @@ void EnElforg_FreeFloatingFairyFountain(EnElforg* this, PlayState* play) { } else { this->targetSpeedXZ = Rand_ZeroFloat(2.0f) + 1.0f; } + this->targetDistanceFromHome = Rand_ZeroFloat(100.0f) + 50.0f; } + SkelAnime_Update(&this->skelAnime); EnElforg_MoveToTargetFairyFountain(this, &this->actor.home.pos); - if (this->flags & STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN) { + + if (this->strayFairyFlags & STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN) { // A small number of fairies will do this when the player walks into // the center of the fountain to be healed. this->actionFunc = EnElforg_QuicklyCircleFairyFountain; } - if (this->flags & STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS) { + + if (this->strayFairyFlags & STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS) { // This happens right before the Great Fairy appears once all // Stray Fairies are saved. if (this->actor.home.rot.x > 0) { EnElforg_SpawnSparkles(this, play, 10); this->actor.home.rot.x--; } + Actor_SetScale(&this->actor, this->actor.scale.x * 0.9f); if (this->actor.scale.x < 0.001f) { Actor_MarkForDeath(&this->actor); @@ -369,6 +390,7 @@ void EnElforg_CirclePlayer(EnElforg* this, PlayState* play) { } else { distanceFromPlayer = 20.0f; } + this->actor.world.pos.x = (Math_SinS(this->timer << 12) * distanceFromPlayer) + playerActor->world.pos.x; this->actor.world.pos.z = (Math_CosS(this->timer << 12) * distanceFromPlayer) + playerActor->world.pos.z; this->actor.world.pos.y = player->bodyPartsPos[0].y; @@ -381,6 +403,7 @@ void EnElforg_FairyCollected(EnElforg* this, PlayState* play) { Actor_MarkForDeath(&this->actor); return; } + func_800B9010(&this->actor, NA_SE_PL_CHIBI_FAIRY_HEAL - SFX_FLAG); } @@ -445,9 +468,11 @@ void EnElforg_FreeFloating(EnElforg* this, PlayState* play) { case STRAY_FAIRY_TYPE_COLLECTIBLE: Flags_SetCollectible(play, STRAY_FAIRY_FLAG(&this->actor)); break; + case STRAY_FAIRY_TYPE_CHEST: Flags_SetTreasure(play, STRAY_FAIRY_FLAG(&this->actor)); break; + default: Flags_SetSwitch(play, STRAY_FAIRY_FLAG(&this->actor)); break; @@ -456,6 +481,7 @@ void EnElforg_FreeFloating(EnElforg* this, PlayState* play) { if (STRAY_FAIRY_TYPE(&this->actor) == STRAY_FAIRY_TYPE_CLOCK_TOWN) { player->actor.freezeTimer = 100; player->stateFlags1 |= 0x20000000; + // Bring me back to North Clock Town! Message_StartTextbox(play, 0x579, NULL); this->actionFunc = EnElforg_ClockTownFairyCollected; ActorCutscene_SetIntentToPlay(0x7C); @@ -464,6 +490,7 @@ void EnElforg_FreeFloating(EnElforg* this, PlayState* play) { if (Map_IsInDungeonOrBossArea(play)) { gSaveContext.save.inventory.strayFairies[gSaveContext.dungeonIndex]++; + // You found a Stray Fairy! Message_StartTextbox(play, 0x11, NULL); if (gSaveContext.save.inventory.strayFairies[(void)0, gSaveContext.dungeonIndex] >= 15) { func_801A3098(NA_BGM_GET_ITEM | 0x900); @@ -474,12 +501,13 @@ void EnElforg_FreeFloating(EnElforg* this, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f, 7); func_80ACCBB8(this, play); if (Player_GetMask(play) == PLAYER_MASK_GREAT_FAIRY) { - if (!(this->flags & STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED)) { + if (!(this->strayFairyFlags & STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED)) { play_sound(NA_SE_SY_FAIRY_MASK_SUCCESS); } - this->flags |= STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED; + + this->strayFairyFlags |= STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED; } else { - this->flags &= ~STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED; + this->strayFairyFlags &= ~STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED; } } } @@ -499,6 +527,7 @@ Actor* EnElforg_GetHoldingEnemy(EnElforg* this, PlayState* play) { return enemy; } } + return NULL; } @@ -523,6 +552,7 @@ void EnElforg_TrappedByEnemy(EnElforg* this, PlayState* play) { this->actor.world.pos.z = posTemp; this->actor.home.pos.z = posTemp; } + func_80ACCBB8(this, play); } @@ -546,6 +576,7 @@ void EnElforg_HiddenByCollider(EnElforg* this, PlayState* play) { } else { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); } + func_80ACCBB8(this, play); } @@ -598,19 +629,24 @@ void EnElforg_Draw(Actor* thisx, PlayState* play) { case STRAY_FAIRY_AREA_WOODFALL: AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gStrayFairyWoodfallTexAnim)); break; + case STRAY_FAIRY_AREA_SNOWHEAD: AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gStrayFairySnowheadTexAnim)); break; + case STRAY_FAIRY_AREA_GREAT_BAY: AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gStrayFairyGreatBayTexAnim)); break; + case STRAY_FAIRY_AREA_STONE_TOWER: AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gStrayFairyStoneTowerTexAnim)); break; + default: AnimatedMat_Draw(play, Lib_SegmentedToVirtual(gStrayFairyClockTownTexAnim)); break; } + Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY); POLY_XLU_DISP = diff --git a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h index 55695240f6..5de48e955a 100644 --- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h +++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h @@ -2,10 +2,12 @@ #define Z_EN_ELFORG_H #include "global.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define STRAY_FAIRY_TYPE(thisx) ((thisx)->params & 0xF) #define STRAY_FAIRY_GET_NON_DUNGEON_AREA(thisx) (((thisx)->params & 0x1C0) >> 6) #define STRAY_FAIRY_FLAG(thisx) (((thisx)->params & 0xFE00) >> 9) +#define STRAY_FAIRY_PARAMS(flag, nonDungeonArea, type) (((flag & 0x7F) << 9) | ((nonDungeonArea & 7) << 6) | (type & 0xF)) #define STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME (1 << 0) #define STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS (1 << 1) @@ -13,40 +15,26 @@ #define STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED (1 << 3) typedef enum { - STRAY_FAIRY_TYPE_FREE_FLOATING, // The ones just floating around - STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN, // The ones already present when you enter a Fairy Fountain - STRAY_FAIRY_TYPE_BUBBLE, // The ones trapped in bubbles - STRAY_FAIRY_TYPE_CLOCK_TOWN, // The free-floating Stray Fairies in Clock Town - STRAY_FAIRY_TYPE_ENEMY, // The ones trapped inside enemies - STRAY_FAIRY_TYPE_COLLIDER, // Unused in retail. The fairy is hidden until the collider is hit - STRAY_FAIRY_TYPE_CHEST, // The ones in treasure chests - STRAY_FAIRY_TYPE_COLLECTIBLE, // The ones in boxes, pots, beehives, etc. - STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN // The ones you "turn in" by walking into a Fairy Fountain + /* 0 */ STRAY_FAIRY_TYPE_FREE_FLOATING, // The ones just floating around + /* 1 */ STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN, // The ones already present when you enter a Fairy Fountain + /* 2 */ STRAY_FAIRY_TYPE_BUBBLE, // The ones trapped in bubbles + /* 3 */ STRAY_FAIRY_TYPE_CLOCK_TOWN, // The free-floating Stray Fairies in Clock Town + /* 4 */ STRAY_FAIRY_TYPE_ENEMY, // The ones trapped inside enemies + /* 5 */ STRAY_FAIRY_TYPE_COLLIDER, // Unused in retail. The fairy is hidden until the collider is hit + /* 6 */ STRAY_FAIRY_TYPE_CHEST, // The ones in treasure chests + /* 7 */ STRAY_FAIRY_TYPE_COLLECTIBLE, // The ones in boxes, pots, beehives, etc. + /* 8 */ STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN // The ones you "turn in" by walking into a Fairy Fountain } StrayFairyType; typedef enum { - STRAY_FAIRY_AREA_CLOCK_TOWN, - STRAY_FAIRY_AREA_WOODFALL, - STRAY_FAIRY_AREA_SNOWHEAD, - STRAY_FAIRY_AREA_GREAT_BAY, - STRAY_FAIRY_AREA_STONE_TOWER, - STRAY_FAIRY_AREA_MAX + /* 0 */ STRAY_FAIRY_AREA_CLOCK_TOWN, + /* 1 */ STRAY_FAIRY_AREA_WOODFALL, + /* 2 */ STRAY_FAIRY_AREA_SNOWHEAD, + /* 3 */ STRAY_FAIRY_AREA_GREAT_BAY, + /* 4 */ STRAY_FAIRY_AREA_STONE_TOWER, + /* 5 */ STRAY_FAIRY_AREA_MAX } StrayFairyArea; -typedef enum { - /* 0 */ STRAY_FAIRY_LIMB_NONE, - /* 1 */ STRAY_FAIRY_LIMB_RIGHT_FACING_HEAD, - /* 2 */ STRAY_FAIRY_LIMB_LEFT_WING, - /* 3 */ STRAY_FAIRY_LIMB_RIGHT_WING, - /* 4 */ STRAY_FAIRY_LIMB_GLOW, - /* 5 */ STRAY_FAIRY_LIMB_TORSO, - /* 6 */ STRAY_FAIRY_LIMB_RIGHT_ARM, - /* 7 */ STRAY_FAIRY_LIMB_PELVIS_AND_LEGS, - /* 8 */ STRAY_FAIRY_LIMB_LEFT_ARM, - /* 9 */ STRAY_FAIRY_LIMB_LEFT_FACING_HEAD, - /* 10 */ STRAY_FAIRY_LIMB_MAX, -} StrayFairyLimbs; - struct EnElforg; typedef void (*EnElforgActionFunc)(struct EnElforg*, PlayState*); @@ -57,7 +45,7 @@ typedef struct EnElforg { /* 0x188 */ Vec3s jointTable[STRAY_FAIRY_LIMB_MAX]; /* 0x1C4 */ ColliderCylinder collider; /* 0x210 */ Actor* enemy; - /* 0x214 */ u16 flags; + /* 0x214 */ u16 strayFairyFlags; /* 0x216 */ s16 direction; // negative when facing right, positive when facing left /* 0x218 */ s16 area; /* 0x21C */ s32 timer;