mirror of
https://github.com/zeldaret/mm.git
synced 2024-11-23 12:59:44 +00:00
Mayor Dotour (ovl_en_dt) OK and documented (#1607)
* EnDt deecomp first pass, two nonmatching * Some cleanup, got the big boy matching * Some light cleanup, documenting blinking behaviour * Fixed last non-matching with some permuter silliness * Decompilation complete * Mayor documentation, first pass * Updating some unknown vars in baisen * Added an enum for mayor's cutscene state * Formatting pass for mayor * Cleaning up unk var in mayor meeting method * Some cleanup and changes based on PR feedback * Another cleanup and fix pass based on PR feedback * Updated mayor event flags according to their usage * All the parentheses * Another round of PR feedback cleanup * Having another crack at naming/cleanup based on PR feedback * Renaming animation symbols * Fixing broken references in other actors from anim rename --------- Co-authored-by: GinNoOokami <noreply>
This commit is contained in:
parent
0a65e85856
commit
47d43f2fa1
@ -1,10 +1,10 @@
|
|||||||
<Root>
|
<Root>
|
||||||
<File Name="object_dt" Segment="6">
|
<File Name="object_dt" Segment="6">
|
||||||
<Animation Name="object_dt_Anim_0005A4" Offset="0x5A4" /> <!-- Original name is "dt_aiya" -->
|
<Animation Name="gDotourDistressAnim" Offset="0x5A4" /> <!-- Original name is "dt_aiya" -->
|
||||||
<Animation Name="object_dt_Anim_000854" Offset="0x854" /> <!-- Original name is "dt_aiya2yomesan" -->
|
<Animation Name="gDotourShockAnim" Offset="0x854" /> <!-- Original name is "dt_aiya2yomesan" -->
|
||||||
<Animation Name="object_dt_Anim_000BE0" Offset="0xBE0" /> <!-- Original name is "dt_arigato" -->
|
<Animation Name="gDotourUprightAnim" Offset="0xBE0" /> <!-- Original name is "dt_arigato" -->
|
||||||
<Animation Name="object_dt_Anim_000DA8" Offset="0xDA8" /> <!-- Original name is "dt_mojimoji" -->
|
<Animation Name="gDotourTapDeskAnim" Offset="0xDA8" /> <!-- Original name is "dt_mojimoji" -->
|
||||||
<Animation Name="object_dt_Anim_00112C" Offset="0x112C" /> <!-- Original name is "dt_wait" -->
|
<Animation Name="gDotourWaitAnim" Offset="0x112C" /> <!-- Original name is "dt_wait" -->
|
||||||
<DList Name="object_dt_DL_004DB0" Offset="0x4DB0" />
|
<DList Name="object_dt_DL_004DB0" Offset="0x4DB0" />
|
||||||
<DList Name="object_dt_DL_005130" Offset="0x5130" />
|
<DList Name="object_dt_DL_005130" Offset="0x5130" />
|
||||||
<DList Name="object_dt_DL_0054C8" Offset="0x54C8" />
|
<DList Name="object_dt_DL_0054C8" Offset="0x54C8" />
|
||||||
@ -62,6 +62,6 @@
|
|||||||
<Limb Name="object_dt_Standardlimb_00B07C" Type="Standard" EnumName="OBJECT_DT_LIMB_0D" Offset="0xB07C" />
|
<Limb Name="object_dt_Standardlimb_00B07C" Type="Standard" EnumName="OBJECT_DT_LIMB_0D" Offset="0xB07C" />
|
||||||
<Limb Name="object_dt_Standardlimb_00B088" Type="Standard" EnumName="OBJECT_DT_LIMB_0E" Offset="0xB088" />
|
<Limb Name="object_dt_Standardlimb_00B088" Type="Standard" EnumName="OBJECT_DT_LIMB_0E" Offset="0xB088" />
|
||||||
<Skeleton Name="object_dt_Skel_00B0CC" Type="Flex" LimbType="Standard" LimbNone="OBJECT_DT_LIMB_NONE" LimbMax="OBJECT_DT_LIMB_MAX" EnumName="ObjectDtLimb" Offset="0xB0CC" />
|
<Skeleton Name="object_dt_Skel_00B0CC" Type="Flex" LimbType="Standard" LimbNone="OBJECT_DT_LIMB_NONE" LimbMax="OBJECT_DT_LIMB_MAX" EnumName="ObjectDtLimb" Offset="0xB0CC" />
|
||||||
<Animation Name="object_dt_Anim_00B500" Offset="0xB500" /> <!-- Original name is "dt_yome2arigato" -->
|
<Animation Name="gDotourSitUpAnim" Offset="0xB500" /> <!-- Original name is "dt_yome2arigato" -->
|
||||||
</File>
|
</File>
|
||||||
</Root>
|
</Root>
|
||||||
|
@ -1108,10 +1108,10 @@ typedef enum {
|
|||||||
#define WEEKEVENTREG_60_01 PACK_WEEKEVENTREG_FLAG(60, 0x01)
|
#define WEEKEVENTREG_60_01 PACK_WEEKEVENTREG_FLAG(60, 0x01)
|
||||||
#define WEEKEVENTREG_60_02 PACK_WEEKEVENTREG_FLAG(60, 0x02)
|
#define WEEKEVENTREG_60_02 PACK_WEEKEVENTREG_FLAG(60, 0x02)
|
||||||
#define WEEKEVENTREG_60_04 PACK_WEEKEVENTREG_FLAG(60, 0x04)
|
#define WEEKEVENTREG_60_04 PACK_WEEKEVENTREG_FLAG(60, 0x04)
|
||||||
#define WEEKEVENTREG_60_08 PACK_WEEKEVENTREG_FLAG(60, 0x08)
|
#define WEEKEVENTREG_ATTENDED_MAYOR_MEETING PACK_WEEKEVENTREG_FLAG(60, 0x08)
|
||||||
#define WEEKEVENTREG_60_10 PACK_WEEKEVENTREG_FLAG(60, 0x10)
|
#define WEEKEVENTREG_RECEIVED_MAYOR_REWARD PACK_WEEKEVENTREG_FLAG(60, 0x10)
|
||||||
#define WEEKEVENTREG_60_20 PACK_WEEKEVENTREG_FLAG(60, 0x20)
|
#define WEEKEVENTREG_60_20 PACK_WEEKEVENTREG_FLAG(60, 0x20)
|
||||||
#define WEEKEVENTREG_60_40 PACK_WEEKEVENTREG_FLAG(60, 0x40)
|
#define WEEKEVENTREG_TALKED_MAYOR_NIGHT_3 PACK_WEEKEVENTREG_FLAG(60, 0x40)
|
||||||
#define WEEKEVENTREG_60_80 PACK_WEEKEVENTREG_FLAG(60, 0x80)
|
#define WEEKEVENTREG_60_80 PACK_WEEKEVENTREG_FLAG(60, 0x80)
|
||||||
#define WEEKEVENTREG_61_01 PACK_WEEKEVENTREG_FLAG(61, 0x01)
|
#define WEEKEVENTREG_61_01 PACK_WEEKEVENTREG_FLAG(61, 0x01)
|
||||||
#define WEEKEVENTREG_61_02 PACK_WEEKEVENTREG_FLAG(61, 0x02)
|
#define WEEKEVENTREG_61_02 PACK_WEEKEVENTREG_FLAG(61, 0x02)
|
||||||
@ -1141,8 +1141,8 @@ typedef enum {
|
|||||||
#define WEEKEVENTREG_63_20 PACK_WEEKEVENTREG_FLAG(63, 0x20)
|
#define WEEKEVENTREG_63_20 PACK_WEEKEVENTREG_FLAG(63, 0x20)
|
||||||
#define WEEKEVENTREG_63_40 PACK_WEEKEVENTREG_FLAG(63, 0x40)
|
#define WEEKEVENTREG_63_40 PACK_WEEKEVENTREG_FLAG(63, 0x40)
|
||||||
|
|
||||||
// showed Couple's Mask to meeting
|
// Showed Couple's Mask at meeting
|
||||||
#define WEEKEVENTREG_63_80 PACK_WEEKEVENTREG_FLAG(63, 0x80)
|
#define WEEKEVENTREG_RESOLVED_MAYOR_MEETING PACK_WEEKEVENTREG_FLAG(63, 0x80)
|
||||||
|
|
||||||
#define WEEKEVENTREG_64_01 PACK_WEEKEVENTREG_FLAG(64, 0x01)
|
#define WEEKEVENTREG_64_01 PACK_WEEKEVENTREG_FLAG(64, 0x01)
|
||||||
#define WEEKEVENTREG_64_02 PACK_WEEKEVENTREG_FLAG(64, 0x02)
|
#define WEEKEVENTREG_64_02 PACK_WEEKEVENTREG_FLAG(64, 0x02)
|
||||||
|
3
spec
3
spec
@ -4529,8 +4529,7 @@ beginseg
|
|||||||
name "ovl_En_Dt"
|
name "ovl_En_Dt"
|
||||||
compress
|
compress
|
||||||
include "build/src/overlays/actors/ovl_En_Dt/z_en_dt.o"
|
include "build/src/overlays/actors/ovl_En_Dt/z_en_dt.o"
|
||||||
include "build/data/ovl_En_Dt/ovl_En_Dt.data.o"
|
include "build/src/overlays/actors/ovl_En_Dt/ovl_En_Dt_reloc.o"
|
||||||
include "build/data/ovl_En_Dt/ovl_En_Dt.reloc.o"
|
|
||||||
endseg
|
endseg
|
||||||
|
|
||||||
beginseg
|
beginseg
|
||||||
|
@ -152,7 +152,7 @@ u16 sPersistentCycleWeekEventRegs[ARRAY_COUNT(gSaveContext.save.saveInfo.weekEve
|
|||||||
PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_59_04) | PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_59_08) |
|
PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_59_04) | PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_59_08) |
|
||||||
PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_SWAMP_SHOOTING_GALLERY_QUIVER_UPGRADE) |
|
PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_SWAMP_SHOOTING_GALLERY_QUIVER_UPGRADE) |
|
||||||
PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_TOWN_SHOOTING_GALLERY_QUIVER_UPGRADE),
|
PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_TOWN_SHOOTING_GALLERY_QUIVER_UPGRADE),
|
||||||
/* 60 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_60_10),
|
/* 60 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_MAYOR_REWARD),
|
||||||
/* 61 */ 0,
|
/* 61 */ 0,
|
||||||
/* 62 */ 0,
|
/* 62 */ 0,
|
||||||
/* 63 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_63_20),
|
/* 63 */ PERSISTENT_WEEKEVENTREG(WEEKEVENTREG_63_20),
|
||||||
|
@ -86,14 +86,16 @@ void EnBaisen_Init(Actor* thisx, PlayState* play) {
|
|||||||
this->paramCopy = this->actor.params;
|
this->paramCopy = this->actor.params;
|
||||||
if (this->actor.params == 0) {
|
if (this->actor.params == 0) {
|
||||||
this->unk290 = true;
|
this->unk290 = true;
|
||||||
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_63_80) && ((gSaveContext.save.day != 3) || !gSaveContext.save.isNight)) {
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) &&
|
||||||
|
((gSaveContext.save.day != 3) || !gSaveContext.save.isNight)) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->collider.dim.radius = 30;
|
this->collider.dim.radius = 30;
|
||||||
this->collider.dim.height = 60;
|
this->collider.dim.height = 60;
|
||||||
this->collider.dim.yShift = 0;
|
this->collider.dim.yShift = 0;
|
||||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_63_80) || ((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) ||
|
||||||
|
((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,13 +170,13 @@ void func_80BE887C(EnBaisen* this, PlayState* play) {
|
|||||||
} else {
|
} else {
|
||||||
if (this->paramCopy != 0) {
|
if (this->paramCopy != 0) {
|
||||||
this->textIdIndex = 0;
|
this->textIdIndex = 0;
|
||||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_60_08)) {
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_ATTENDED_MAYOR_MEETING)) {
|
||||||
this->textIdIndex = 1;
|
this->textIdIndex = 1;
|
||||||
}
|
}
|
||||||
if (Player_GetMask(play) == PLAYER_MASK_COUPLE) {
|
if (Player_GetMask(play) == PLAYER_MASK_COUPLE) {
|
||||||
this->textIdIndex = 6;
|
this->textIdIndex = 6;
|
||||||
}
|
}
|
||||||
if (this->unk2AC == 1) {
|
if (this->cutsceneState == 1) {
|
||||||
func_80BE895C(this, play);
|
func_80BE895C(this, play);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -185,14 +187,14 @@ void func_80BE887C(EnBaisen* this, PlayState* play) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void func_80BE895C(EnBaisen* this, PlayState* play) {
|
void func_80BE895C(EnBaisen* this, PlayState* play) {
|
||||||
if (this->unk2A4 != NULL) {
|
if (this->targetActor != NULL) {
|
||||||
this->unk290 = true;
|
this->unk290 = true;
|
||||||
this->unk2AC = 1;
|
this->cutsceneState = 1;
|
||||||
Actor_ChangeFocus(this->unk2A4, play, this->unk2A4);
|
Actor_ChangeFocus(this->targetActor, play, this->targetActor);
|
||||||
}
|
}
|
||||||
this->unk29C = 1;
|
this->unk29C = 1;
|
||||||
if (this->paramCopy == 0) {
|
if (this->paramCopy == 0) {
|
||||||
this->unk2A4 = this->heishiPointer;
|
this->targetActor = this->heishiPointer;
|
||||||
this->actionFunc = func_80BE8AAC;
|
this->actionFunc = func_80BE8AAC;
|
||||||
} else {
|
} else {
|
||||||
this->actionFunc = func_80BE89D8;
|
this->actionFunc = func_80BE89D8;
|
||||||
@ -200,13 +202,13 @@ void func_80BE895C(EnBaisen* this, PlayState* play) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void func_80BE89D8(EnBaisen* this, PlayState* play) {
|
void func_80BE89D8(EnBaisen* this, PlayState* play) {
|
||||||
if (&this->actor == this->unk2A4) {
|
if (&this->actor == this->targetActor) {
|
||||||
this->unk29E = this->actor.world.rot.y;
|
this->unk29E = this->actor.world.rot.y;
|
||||||
if (this->animIndex == ENBAISEN_ANIM_0) {
|
if (this->animIndex == ENBAISEN_ANIM_0) {
|
||||||
EnBaisen_ChangeAnim(this, ENBAISEN_ANIM_1);
|
EnBaisen_ChangeAnim(this, ENBAISEN_ANIM_1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->unk29E = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk2A4->world.pos);
|
this->unk29E = Math_Vec3f_Yaw(&this->actor.world.pos, &this->targetActor->world.pos);
|
||||||
if (this->animIndex != ENBAISEN_ANIM_0) {
|
if (this->animIndex != ENBAISEN_ANIM_0) {
|
||||||
EnBaisen_ChangeAnim(this, ENBAISEN_ANIM_0);
|
EnBaisen_ChangeAnim(this, ENBAISEN_ANIM_0);
|
||||||
}
|
}
|
||||||
@ -216,7 +218,7 @@ void func_80BE89D8(EnBaisen* this, PlayState* play) {
|
|||||||
this->skelAnime.playSpeed = 0.0f;
|
this->skelAnime.playSpeed = 0.0f;
|
||||||
this->unk29E = this->actor.yawTowardsPlayer;
|
this->unk29E = this->actor.yawTowardsPlayer;
|
||||||
}
|
}
|
||||||
if (this->unk2AC == 2) { // Note: This variable is only ever set to 1.
|
if (this->cutsceneState == 2) { // Note: This variable is also set by EnDt.
|
||||||
func_80BE87FC(this);
|
func_80BE87FC(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,8 +230,8 @@ void func_80BE8AAC(EnBaisen* this, PlayState* play) {
|
|||||||
EnBaisen_ChangeAnim(this, ENBAISEN_ANIM_1);
|
EnBaisen_ChangeAnim(this, ENBAISEN_ANIM_1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this->unk2A4 != NULL) {
|
if (this->targetActor != NULL) {
|
||||||
this->unk29E = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk2A4->world.pos);
|
this->unk29E = Math_Vec3f_Yaw(&this->actor.world.pos, &this->targetActor->world.pos);
|
||||||
}
|
}
|
||||||
if (this->animIndex != ENBAISEN_ANIM_0) {
|
if (this->animIndex != ENBAISEN_ANIM_0) {
|
||||||
EnBaisen_ChangeAnim(this, ENBAISEN_ANIM_0);
|
EnBaisen_ChangeAnim(this, ENBAISEN_ANIM_0);
|
||||||
@ -241,11 +243,11 @@ void func_80BE8AAC(EnBaisen* this, PlayState* play) {
|
|||||||
if (this->textIdIndex < 6) {
|
if (this->textIdIndex < 6) {
|
||||||
Message_ContinueTextbox(play, sTextIds[this->textIdIndex]);
|
Message_ContinueTextbox(play, sTextIds[this->textIdIndex]);
|
||||||
if ((this->textIdIndex % 2) == 0) {
|
if ((this->textIdIndex % 2) == 0) {
|
||||||
this->unk2A4 = this->heishiPointer;
|
this->targetActor = this->heishiPointer;
|
||||||
} else {
|
} else {
|
||||||
this->unk2A4 = &this->actor;
|
this->targetActor = &this->actor;
|
||||||
}
|
}
|
||||||
Actor_ChangeFocus(this->unk2A4, play, this->unk2A4);
|
Actor_ChangeFocus(this->targetActor, play, this->targetActor);
|
||||||
} else {
|
} else {
|
||||||
func_80BE87FC(this);
|
func_80BE87FC(this);
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,9 @@ typedef struct EnBaisen {
|
|||||||
/* 0x29C */ s16 unk29C;
|
/* 0x29C */ s16 unk29C;
|
||||||
/* 0x29E */ s16 unk29E;
|
/* 0x29E */ s16 unk29E;
|
||||||
/* 0x2A0 */ s16 textIdIndex;
|
/* 0x2A0 */ s16 textIdIndex;
|
||||||
/* 0x2A4 */ Actor* unk2A4;
|
/* 0x2A4 */ Actor* targetActor;
|
||||||
/* 0x2A8 */ Actor* heishiPointer;
|
/* 0x2A8 */ Actor* heishiPointer;
|
||||||
/* 0x2AC */ s32 unk2AC;
|
/* 0x2AC */ s32 cutsceneState;
|
||||||
/* 0x2B0 */ ColliderCylinder collider;
|
/* 0x2B0 */ ColliderCylinder collider;
|
||||||
} EnBaisen; // size = 0x2FC
|
} EnBaisen; // size = 0x2FC
|
||||||
|
|
||||||
|
@ -114,7 +114,8 @@ void EnDaiku_Init(Actor* thisx, PlayState* play) {
|
|||||||
this->collider.dim.height = 60;
|
this->collider.dim.height = 60;
|
||||||
this->collider.dim.yShift = 0;
|
this->collider.dim.yShift = 0;
|
||||||
this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
|
this->actor.flags |= ACTOR_FLAG_CANT_LOCK_ON;
|
||||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_63_80) || ((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) ||
|
||||||
|
((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
}
|
}
|
||||||
} else if ((gSaveContext.save.day == 3) && gSaveContext.save.isNight) {
|
} else if ((gSaveContext.save.day == 3) && gSaveContext.save.isNight) {
|
||||||
|
@ -2,10 +2,17 @@
|
|||||||
* File: z_en_dt.c
|
* File: z_en_dt.c
|
||||||
* Overlay: ovl_En_Dt
|
* Overlay: ovl_En_Dt
|
||||||
* Description: Mayor Dotour
|
* Description: Mayor Dotour
|
||||||
|
*
|
||||||
|
* This actor handles the logic for the meeting event between the mayor, Mutoh, and Baisen.
|
||||||
|
* It is also the source of a heart piece and two bomber notebook events.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "z_en_dt.h"
|
#include "z_en_dt.h"
|
||||||
|
|
||||||
|
#include "objects/object_dt/object_dt.h"
|
||||||
|
#include "overlays/actors/ovl_En_Baisen/z_en_baisen.h"
|
||||||
|
#include "overlays/actors/ovl_En_Muto/z_en_muto.h"
|
||||||
|
|
||||||
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
|
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
|
||||||
|
|
||||||
#define THIS ((EnDt*)thisx)
|
#define THIS ((EnDt*)thisx)
|
||||||
@ -15,7 +22,80 @@ void EnDt_Destroy(Actor* thisx, PlayState* play);
|
|||||||
void EnDt_Update(Actor* thisx, PlayState* play);
|
void EnDt_Update(Actor* thisx, PlayState* play);
|
||||||
void EnDt_Draw(Actor* thisx, PlayState* play);
|
void EnDt_Draw(Actor* thisx, PlayState* play);
|
||||||
|
|
||||||
#if 0
|
void EnDt_ChangeAnim(EnDt* this, s32 animIndex);
|
||||||
|
void EnDt_SetupRegularState(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_SetupCutsceneNpcs(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_OfferRegularTalk(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_SetupMeetingCutscene(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_UpdateMeetingCutscene(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_FinishMeetingCutscene(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_OfferMeetingReward(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_OfferFinalNightTalk(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_TriggerFinalNightTalkEvent(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_TriggerMeetingRewardEvent(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_TriggerMeetingNotebookEvent(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_SetupFinalNightState(EnDt* this, PlayState* play);
|
||||||
|
void EnDt_UpdateAppearance(EnDt* this);
|
||||||
|
void EnDt_StartFinalNightTalk(EnDt* this);
|
||||||
|
void EnDt_UpdateCutsceneFocusTarget(EnDt* this);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ EN_DT_NPC_STATE_DEFAULT,
|
||||||
|
/* 1 */ EN_DT_NPC_STATE_IDLE,
|
||||||
|
/* 2 */ EN_DT_NPC_STATE_VIEWING_MEETING,
|
||||||
|
/* 3 */ EN_DT_NPC_STATE_OFFERED_MEETING_REWARD,
|
||||||
|
/* 4 */ EN_DT_NPC_STATE_WAIT_FINAL_NIGHT_TALK,
|
||||||
|
/* 5 */ EN_DT_NPC_STATE_DONE_FINAL_NIGHT_TALK
|
||||||
|
} EnDtNpcState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ EN_DT_CS_STATE_NONE,
|
||||||
|
/* 1 */ EN_DT_CS_STATE_WAITING,
|
||||||
|
/* 2 */ EN_DT_CS_STATE_PLAYING
|
||||||
|
} EnDtCutsceneState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ EN_DT_CS_FOCUS_TARGET_MUTO,
|
||||||
|
/* 1 */ EN_DT_CS_FOCUS_TARGET_BAISEN,
|
||||||
|
/* 2 */ EN_DT_CS_FOCUS_TARGET_MAYOR
|
||||||
|
} EnDtCutsceneFocusTarget;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ EN_DT_APPEARANCE_DEFAULT,
|
||||||
|
/* 1 */ EN_DT_APPEARANCE_PRE_MEETING,
|
||||||
|
/* 2 */ EN_DT_APPEARANCE_POST_MEETING,
|
||||||
|
/* 3 */ EN_DT_APPEARANCE_UNUSED,
|
||||||
|
/* 4 */ EN_DT_APPEARANCE_RESOLUTION_TALK,
|
||||||
|
/* 5 */ EN_DT_APPEARANCE_RESOLVED_MEETING,
|
||||||
|
/* 6 */ EN_DT_APPEARANCE_MAX
|
||||||
|
} EnDtAppearance;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ EN_DT_ANIMATION_WAIT,
|
||||||
|
/* 1 */ EN_DT_ANIMATION_DISTRESS,
|
||||||
|
/* 2 */ EN_DT_ANIMATION_SHOCK,
|
||||||
|
/* 3 */ EN_DT_ANIMATION_TAP_DESK,
|
||||||
|
/* 4 */ EN_DT_ANIMATION_UPRIGHT,
|
||||||
|
/* 5 */ EN_DT_ANIMATION_SIT_UP,
|
||||||
|
/* 6 */ EN_DT_ANIMATION_MAX
|
||||||
|
} EnDtAnimation;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ EN_DT_EYE_TEXTURE_SHOCK,
|
||||||
|
/* 1 */ EN_DT_EYE_TEXTURE_OPEN,
|
||||||
|
/* 2 */ EN_DT_EYE_TEXTURE_CLOSED,
|
||||||
|
/* 3 */ EN_DT_EYE_TEXTURE_LOOK_DOWN,
|
||||||
|
/* 4 */ EN_DT_EYE_TEXTURE_SQUINT,
|
||||||
|
/* 5 */ EN_DT_EYE_TEXTURE_MAX
|
||||||
|
} EnDtEyeTextures;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ EN_DT_BROW_TEXTURE_HIGH,
|
||||||
|
/* 1 */ EN_DT_BROW_TEXTURE_MID,
|
||||||
|
/* 2 */ EN_DT_BROW_TEXTURE_LOW,
|
||||||
|
/* 3 */ EN_DT_BROW_TEXTURE_MAX
|
||||||
|
} EnDtBrowTextures;
|
||||||
|
|
||||||
ActorInit En_Dt_InitVars = {
|
ActorInit En_Dt_InitVars = {
|
||||||
/**/ ACTOR_EN_DT,
|
/**/ ACTOR_EN_DT,
|
||||||
/**/ ACTORCAT_NPC,
|
/**/ ACTORCAT_NPC,
|
||||||
@ -28,59 +108,743 @@ ActorInit En_Dt_InitVars = {
|
|||||||
/**/ EnDt_Draw,
|
/**/ EnDt_Draw,
|
||||||
};
|
};
|
||||||
|
|
||||||
// static ColliderCylinderInit sCylinderInit = {
|
static u16 sTextIds[] = {
|
||||||
static ColliderCylinderInit D_80BEB29C = {
|
0x2ABD, 0x2ABE, 0x2ABF, 0x2AC0, 0x2ABE, 0x2AC1, 0x2AC2, 0x2AC3, 0x2AC4, 0x2ABB, 0x2ABC, 0x2AC6, 0x2AC7, 0x2AC8,
|
||||||
{ COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, },
|
0x2AC9, 0x2ACA, 0x2ACB, 0x2ACC, 0x2ACD, 0x2ACE, 0x2ACF, 0x2AD0, 0x2AD1, 0x2AC5, 0x2AD3, 0x2AD4, 0x2AD2,
|
||||||
{ ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, },
|
};
|
||||||
|
|
||||||
|
// The code uses EnDt::textIdIndex as an index into this lookup table
|
||||||
|
static s32 sCutsceneFocusTargetTable[] = {
|
||||||
|
// Start of initial mayor meeting cutscene
|
||||||
|
/* 0 */ EN_DT_CS_FOCUS_TARGET_BAISEN,
|
||||||
|
/* 1 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
/* 2 */ EN_DT_CS_FOCUS_TARGET_MUTO,
|
||||||
|
/* 3 */ EN_DT_CS_FOCUS_TARGET_MUTO,
|
||||||
|
/* 4 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
/* 5 */ EN_DT_CS_FOCUS_TARGET_BAISEN,
|
||||||
|
/* 6 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
/* 7 */ EN_DT_CS_FOCUS_TARGET_MUTO,
|
||||||
|
/* 8 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
// End of intitial mayor meeting cutscene
|
||||||
|
|
||||||
|
// Start of repeat mayor meeting cutscene
|
||||||
|
/* 9 */ EN_DT_CS_FOCUS_TARGET_BAISEN,
|
||||||
|
/* 10 */ EN_DT_CS_FOCUS_TARGET_MUTO,
|
||||||
|
// End of repeat mayor meeting cutscene
|
||||||
|
|
||||||
|
// Start of meeting resolution cutscene
|
||||||
|
/* 11 */ EN_DT_CS_FOCUS_TARGET_BAISEN,
|
||||||
|
/* 12 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
/* 13 */ EN_DT_CS_FOCUS_TARGET_MUTO,
|
||||||
|
/* 14 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
/* 15 */ EN_DT_CS_FOCUS_TARGET_MUTO,
|
||||||
|
/* 16 */ EN_DT_CS_FOCUS_TARGET_BAISEN,
|
||||||
|
/* 17 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
/* 18 */ EN_DT_CS_FOCUS_TARGET_BAISEN,
|
||||||
|
/* 19 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
/* 20 */ EN_DT_CS_FOCUS_TARGET_MUTO,
|
||||||
|
/* 21 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
/* 22 */ EN_DT_CS_FOCUS_TARGET_MAYOR,
|
||||||
|
// End of meeting resolution cutscene
|
||||||
|
|
||||||
|
// Final night cutscene with mayor
|
||||||
|
/* 23 */ EN_DT_CS_FOCUS_TARGET_MAYOR
|
||||||
|
};
|
||||||
|
|
||||||
|
static s16 sStringIdCsIndexTable[] = {
|
||||||
|
0x2ABB, 0, //
|
||||||
|
0x2ABD, 0, //
|
||||||
|
0x2AC0, 1, //
|
||||||
|
0x2AC1, 2, //
|
||||||
|
0x2AC4, 3, //
|
||||||
|
0x2AC6, 4, //
|
||||||
|
0x2AC7, 5, //
|
||||||
|
0x2AC8, 6, //
|
||||||
|
0x2AC9, 7, //
|
||||||
|
0x2ACC, 8, //
|
||||||
|
0x2ACF, 9, //
|
||||||
|
0x2AD0, 10, //
|
||||||
|
};
|
||||||
|
|
||||||
|
static s16 sUnused[] = { 777, 777 };
|
||||||
|
|
||||||
|
static ColliderCylinderInit sCylinderInit = {
|
||||||
|
{
|
||||||
|
COLTYPE_NONE,
|
||||||
|
AT_NONE,
|
||||||
|
AC_NONE,
|
||||||
|
OC1_ON | OC1_TYPE_ALL,
|
||||||
|
OC2_TYPE_2,
|
||||||
|
COLSHAPE_CYLINDER,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ELEMTYPE_UNK0,
|
||||||
|
{ 0x00000000, 0x00, 0x00 },
|
||||||
|
{ 0xF7CFFFFF, 0x00, 0x00 },
|
||||||
|
TOUCH_NONE | TOUCH_SFX_NORMAL,
|
||||||
|
BUMP_NONE,
|
||||||
|
OCELEM_ON,
|
||||||
|
},
|
||||||
{ 25, 70, 0, { 0, 0, 0 } },
|
{ 25, 70, 0, { 0, 0, 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
static AnimationHeader* sAnimations[EN_DT_ANIMATION_MAX] = {
|
||||||
|
&gDotourWaitAnim, // EN_DT_ANIMATION_WAIT
|
||||||
|
&gDotourDistressAnim, // EN_DT_ANIMATION_DISTRESS
|
||||||
|
&gDotourShockAnim, // EN_DT_ANIMATION_SHOCK
|
||||||
|
&gDotourTapDeskAnim, // EN_DT_ANIMATION_TAP_DESK
|
||||||
|
&gDotourUprightAnim, // EN_DT_ANIMATION_UPRIGHT
|
||||||
|
&gDotourSitUpAnim, // EN_DT_ANIMATION_SIT_UP
|
||||||
|
};
|
||||||
|
|
||||||
extern ColliderCylinderInit D_80BEB29C;
|
static u8 sAnimationModes[EN_DT_ANIMATION_MAX] = {
|
||||||
|
ANIMMODE_LOOP, // EN_DT_ANIMATION_WAIT
|
||||||
|
ANIMMODE_LOOP, // EN_DT_ANIMATION_DISTRESS
|
||||||
|
ANIMMODE_ONCE, // EN_DT_ANIMATION_SHOCK
|
||||||
|
ANIMMODE_LOOP, // EN_DT_ANIMATION_TAP_DESK
|
||||||
|
ANIMMODE_LOOP, // EN_DT_ANIMATION_UPRIGHT
|
||||||
|
ANIMMODE_ONCE, // EN_DT_ANIMATION_SIT_UP
|
||||||
|
};
|
||||||
|
|
||||||
extern UNK_TYPE D_0600112C;
|
// Based on the usage in its accompanying method, this must be an array where each row
|
||||||
|
// is 4 values wide. The first value is never used and always 0, while indexes 1, 2,
|
||||||
|
// and 3 are the animation index, the eye texture index, and a flag determining if
|
||||||
|
// the actor should have a dead-panned expression (not blinking).
|
||||||
|
static s32 sAppearancePropertiesTable[] = {
|
||||||
|
0, EN_DT_ANIMATION_DISTRESS, EN_DT_EYE_TEXTURE_LOOK_DOWN, true, // EN_DT_APPEARANCE_DEFAULT
|
||||||
|
0, EN_DT_ANIMATION_SHOCK, EN_DT_EYE_TEXTURE_LOOK_DOWN, true, // EN_DT_APPEARANCE_PRE_MEETING
|
||||||
|
0, EN_DT_ANIMATION_TAP_DESK, EN_DT_EYE_TEXTURE_LOOK_DOWN, true, // EN_DT_APPEARANCE_POST_MEETING
|
||||||
|
0, EN_DT_ANIMATION_TAP_DESK, EN_DT_EYE_TEXTURE_SHOCK, false, // EN_DT_APPEARANCE_UNUSED
|
||||||
|
0, EN_DT_ANIMATION_SIT_UP, EN_DT_EYE_TEXTURE_SHOCK, false, // EN_DT_APPEARANCE_RESOLUTION_TALK
|
||||||
|
0, EN_DT_ANIMATION_UPRIGHT, EN_DT_EYE_TEXTURE_SHOCK, false // EN_DT_APPEARANCE_RESOLVED_MEETING
|
||||||
|
};
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/EnDt_Init.s")
|
static TexturePtr sEyeTextures[] = {
|
||||||
|
gDotourEyeShockTex, // EN_DT_EYE_TEXTURE_SHOCK
|
||||||
|
gDotourEyeOpenTex, // EN_DT_EYE_TEXTURE_OPEN
|
||||||
|
gDotourEyeClosedTex, // EN_DT_EYE_TEXTURE_CLOSED
|
||||||
|
gDotourEyeLookDownTex, // EN_DT_EYE_TEXTURE_LOOK_DOWN
|
||||||
|
gDotourEyeSquintTex, // EN_DT_EYE_TEXTURE_SQUINT
|
||||||
|
};
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/EnDt_Destroy.s")
|
static TexturePtr sEyebrowTextures[] = {
|
||||||
|
gDotourEyebrowHighTex, // EN_DT_BROW_TEXTURE_HIGH
|
||||||
|
gDotourEyebrowMidTex, // EN_DT_BROW_TEXTURE_MID
|
||||||
|
gDotourEyebrowLowTex, // EN_DT_BROW_TEXTURE_LOW
|
||||||
|
};
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BE9C74.s")
|
void EnDt_Init(Actor* thisx, PlayState* play) {
|
||||||
|
EnDt* this = THIS;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BE9CE8.s")
|
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
|
||||||
|
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f);
|
||||||
|
SkelAnime_InitFlex(play, &this->skelAnime, &object_dt_Skel_00B0CC, &gDotourWaitAnim, this->jointTable,
|
||||||
|
this->morphTable, OBJECT_DT_LIMB_MAX);
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BE9D9C.s")
|
this->actor.targetMode = TARGET_MODE_6;
|
||||||
|
this->npcEnMuto = NULL;
|
||||||
|
this->npcEnBaisen = NULL;
|
||||||
|
Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BE9DF8.s")
|
if ((gSaveContext.save.day == 3) && gSaveContext.save.isNight) {
|
||||||
|
EnDt_SetupFinalNightState(this, play);
|
||||||
|
} else {
|
||||||
|
s32 csId = this->actor.csId;
|
||||||
|
s32 i = 0;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BE9E94.s")
|
// clang-format off
|
||||||
|
while (csId != CS_ID_NONE) { this->csIds[i] = csId; csId = CutsceneManager_GetAdditionalCsId(csId); i++; }
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
this->actionFunc = EnDt_SetupCutsceneNpcs;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BE9EF8.s")
|
void EnDt_Destroy(Actor* thisx, PlayState* play) {
|
||||||
|
EnDt* this = THIS;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEA088.s")
|
Collider_DestroyCylinder(play, &this->collider);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEA254.s")
|
void EnDt_UpdateHeadRotate(EnDt* this) {
|
||||||
|
s32 yaw = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.world.rot.y));
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEA394.s")
|
this->headRotTarget.y = 0;
|
||||||
|
if (yaw < 0x4E20) {
|
||||||
|
this->headRotTarget.y = BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.world.rot.y);
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEA8F0.s")
|
if (this->headRotTarget.y > 0x2710) {
|
||||||
|
this->headRotTarget.y = 0x2710;
|
||||||
|
} else if (this->headRotTarget.y < -0x2710) {
|
||||||
|
this->headRotTarget.y = -0x2710;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEAAF8.s")
|
void EnDt_ChangeAnim(EnDt* this, s32 animIndex) {
|
||||||
|
f32 morphFrames;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEAB44.s")
|
this->animIndex = animIndex;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEABF8.s")
|
morphFrames = -4.0f;
|
||||||
|
if ((this->animIndex == EN_DT_ANIMATION_SHOCK) || (this->animIndex == EN_DT_ANIMATION_SIT_UP)) {
|
||||||
|
morphFrames = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEAC84.s")
|
this->animEndFrame = Animation_GetLastFrame(sAnimations[this->animIndex]);
|
||||||
|
Animation_Change(&this->skelAnime, sAnimations[this->animIndex], 1.0f, 0.0f, this->animEndFrame,
|
||||||
|
sAnimationModes[this->animIndex], morphFrames);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEAD2C.s")
|
void EnDt_UpdateAppearance(EnDt* this) {
|
||||||
|
s32 index = this->appearancePhase * 4;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEADB8.s")
|
index++;
|
||||||
|
EnDt_ChangeAnim(this, sAppearancePropertiesTable[index]);
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEADD4.s")
|
index++;
|
||||||
|
this->eyeTexIndex = sAppearancePropertiesTable[index];
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/EnDt_Update.s")
|
index++;
|
||||||
|
this->disableBlinking = sAppearancePropertiesTable[index];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/func_80BEB06C.s")
|
void EnDt_UpdateCutsceneFocusTarget(EnDt* this) {
|
||||||
|
if ((this->npcEnMuto != NULL) && (this->npcEnBaisen != NULL)) {
|
||||||
|
EnMuto* npcEnMuto = (EnMuto*)this->npcEnMuto;
|
||||||
|
EnBaisen* npcEnBaisen = (EnBaisen*)this->npcEnBaisen;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dt/EnDt_Draw.s")
|
switch (sCutsceneFocusTargetTable[this->textIdIndex]) {
|
||||||
|
case EN_DT_CS_FOCUS_TARGET_MUTO:
|
||||||
|
npcEnMuto->targetActor = this->npcEnMuto;
|
||||||
|
npcEnBaisen->targetActor = this->npcEnMuto;
|
||||||
|
this->targetActor = this->npcEnMuto;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EN_DT_CS_FOCUS_TARGET_BAISEN:
|
||||||
|
npcEnMuto->targetActor = this->npcEnBaisen;
|
||||||
|
npcEnBaisen->targetActor = this->npcEnBaisen;
|
||||||
|
this->targetActor = this->npcEnBaisen;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EN_DT_CS_FOCUS_TARGET_MAYOR:
|
||||||
|
npcEnMuto->targetActor = &this->actor;
|
||||||
|
npcEnBaisen->targetActor = &this->actor;
|
||||||
|
this->targetActor = &this->actor;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_SetupCutsceneNpcs(EnDt* this, PlayState* play) {
|
||||||
|
Actor* npc = play->actorCtx.actorLists[ACTORCAT_NPC].first;
|
||||||
|
|
||||||
|
while (npc != NULL) {
|
||||||
|
if (npc->id == ACTOR_EN_MUTO) {
|
||||||
|
this->npcEnMuto = npc;
|
||||||
|
} else if (npc->id == ACTOR_EN_BAISEN) {
|
||||||
|
this->npcEnBaisen = npc;
|
||||||
|
}
|
||||||
|
npc = npc->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnDt_SetupRegularState(this, play);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_SetupRegularState(EnDt* this, PlayState* play) {
|
||||||
|
this->textIdIndex = 0;
|
||||||
|
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_MAYOR_REWARD)) {
|
||||||
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING)) {
|
||||||
|
this->textIdIndex = 21;
|
||||||
|
this->appearancePhase = EN_DT_APPEARANCE_RESOLVED_MEETING;
|
||||||
|
EnDt_UpdateAppearance(this);
|
||||||
|
|
||||||
|
this->actor.textId = sTextIds[this->textIdIndex];
|
||||||
|
Message_StartTextbox(play, this->actor.textId, &this->actor);
|
||||||
|
Player_SetCsActionWithHaltedActors(play, &this->actor, PLAYER_CSACTION_WAIT);
|
||||||
|
|
||||||
|
this->state = EN_DT_NPC_STATE_IDLE;
|
||||||
|
this->actionFunc = EnDt_UpdateMeetingCutscene;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING)) {
|
||||||
|
this->textIdIndex = 23;
|
||||||
|
this->appearancePhase = EN_DT_APPEARANCE_RESOLVED_MEETING;
|
||||||
|
this->meetingFinished = true;
|
||||||
|
EnDt_UpdateAppearance(this);
|
||||||
|
Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_PERSON_MAYOR_DOTOUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->appearancePhase == EN_DT_APPEARANCE_DEFAULT) {
|
||||||
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_ATTENDED_MAYOR_MEETING)) {
|
||||||
|
this->textIdIndex = 9;
|
||||||
|
this->appearancePhase = EN_DT_APPEARANCE_POST_MEETING;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnDt_UpdateAppearance(this);
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_ATTENDED_MAYOR_MEETING)) {
|
||||||
|
this->appearancePhase = EN_DT_APPEARANCE_PRE_MEETING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->actor.textId = sTextIds[this->textIdIndex];
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING)) {
|
||||||
|
EnDt_UpdateCutsceneFocusTarget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->state = EN_DT_NPC_STATE_IDLE;
|
||||||
|
this->actionFunc = EnDt_OfferRegularTalk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_OfferRegularTalk(EnDt* this, PlayState* play) {
|
||||||
|
EnMuto* npcMuto = NULL;
|
||||||
|
EnBaisen* npcBaisen = NULL;
|
||||||
|
|
||||||
|
if (Actor_TalkOfferAccepted(&this->actor, &play->state)) {
|
||||||
|
EnDt_SetupMeetingCutscene(this, play);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING)) {
|
||||||
|
if ((this->npcEnMuto != NULL) && (this->npcEnBaisen)) {
|
||||||
|
npcMuto = (EnMuto*)this->npcEnMuto;
|
||||||
|
npcBaisen = (EnBaisen*)this->npcEnBaisen;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->showedCouplesMask = false;
|
||||||
|
this->textIdIndex = 0;
|
||||||
|
|
||||||
|
if (Player_GetMask(play) == PLAYER_MASK_COUPLE) {
|
||||||
|
this->textIdIndex = 11;
|
||||||
|
this->showedCouplesMask = true;
|
||||||
|
|
||||||
|
if (this->npcEnMuto && this->npcEnBaisen) {
|
||||||
|
npcMuto->textIdIndex = 4;
|
||||||
|
npcBaisen->textIdIndex = 6;
|
||||||
|
}
|
||||||
|
} else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_ATTENDED_MAYOR_MEETING)) {
|
||||||
|
this->textIdIndex = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->actor.textId = sTextIds[this->textIdIndex];
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) && (this->npcEnMuto != NULL) &&
|
||||||
|
(this->npcEnBaisen != NULL) && (npcMuto->cutsceneState == 1 || npcBaisen->cutsceneState == 1)) {
|
||||||
|
EnDt_SetupMeetingCutscene(this, play);
|
||||||
|
}
|
||||||
|
|
||||||
|
// After completing Couple's Mask event and wearing Kafeis Mask
|
||||||
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) && (Player_GetMask(play) == PLAYER_MASK_KAFEIS_MASK)) {
|
||||||
|
this->actor.textId = 0x2368; // "My wife hired you? Go ask the Curiosity Shop"
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor_OfferTalk(&this->actor, play, 150.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_SetupMeetingCutscene(EnDt* this, PlayState* play) {
|
||||||
|
EnMuto* npcMuto;
|
||||||
|
EnBaisen* npcBaisen;
|
||||||
|
s32 index;
|
||||||
|
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING)) {
|
||||||
|
if ((this->npcEnMuto != NULL) && (this->npcEnBaisen != NULL)) {
|
||||||
|
npcMuto = (EnMuto*)this->npcEnMuto;
|
||||||
|
npcBaisen = (EnBaisen*)this->npcEnBaisen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this->npcEnMuto != NULL) && (this->npcEnBaisen != NULL)) {
|
||||||
|
npcMuto->cutsceneState = 1;
|
||||||
|
npcBaisen->cutsceneState = 1;
|
||||||
|
|
||||||
|
if (Player_GetMask(play) == PLAYER_MASK_COUPLE) {
|
||||||
|
npcMuto->textIdIndex = 4;
|
||||||
|
npcBaisen->textIdIndex = 6;
|
||||||
|
this->appearancePhase = EN_DT_APPEARANCE_RESOLVED_MEETING;
|
||||||
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_ATTENDED_MAYOR_MEETING)) {
|
||||||
|
this->appearancePhase = EN_DT_APPEARANCE_RESOLUTION_TALK;
|
||||||
|
}
|
||||||
|
EnDt_UpdateAppearance(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->cutsceneState = EN_DT_CS_STATE_NONE;
|
||||||
|
for (index = 0; index < ARRAY_COUNT(sStringIdCsIndexTable); index += 2) {
|
||||||
|
if ((play->msgCtx.currentTextId == sStringIdCsIndexTable[index]) ||
|
||||||
|
(this->actor.textId == sStringIdCsIndexTable[index])) {
|
||||||
|
this->cutsceneState = EN_DT_CS_STATE_WAITING;
|
||||||
|
this->csIdIndex = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->state = EN_DT_NPC_STATE_VIEWING_MEETING;
|
||||||
|
this->actionFunc = EnDt_UpdateMeetingCutscene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_UpdateMeetingCutscene(EnDt* this, PlayState* play) {
|
||||||
|
EnMuto* muto = NULL;
|
||||||
|
EnBaisen* baisen = NULL;
|
||||||
|
s32 index = sStringIdCsIndexTable[this->csIdIndex + 1];
|
||||||
|
s32 csIdIndex = sStringIdCsIndexTable[this->csIdIndex + 1];
|
||||||
|
|
||||||
|
if (this->cutsceneState == EN_DT_CS_STATE_WAITING) {
|
||||||
|
if (CutsceneManager_GetCurrentCsId() == CS_ID_GLOBAL_TALK) {
|
||||||
|
CutsceneManager_Stop(CS_ID_GLOBAL_TALK);
|
||||||
|
CutsceneManager_Queue(this->csIds[index]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CutsceneManager_IsNext(this->csIds[index])) {
|
||||||
|
CutsceneManager_Queue(this->csIds[index]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CutsceneManager_StartWithPlayerCs(this->csIds[index], this->targetActor);
|
||||||
|
Actor_ChangeFocus(&this->actor, play, this->targetActor);
|
||||||
|
this->cutsceneState = EN_DT_CS_STATE_PLAYING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) &&
|
||||||
|
((this->npcEnMuto != NULL) || (this->npcEnBaisen != NULL))) {
|
||||||
|
muto = (EnMuto*)this->npcEnMuto;
|
||||||
|
baisen = (EnBaisen*)this->npcEnBaisen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this->timer == 0) && (Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) {
|
||||||
|
if (this->textIdIndex == 21) {
|
||||||
|
Player_SetCsActionWithHaltedActors(play, &this->actor, PLAYER_CSACTION_END);
|
||||||
|
if (this->cutsceneState == EN_DT_CS_STATE_PLAYING) {
|
||||||
|
CutsceneManager_Stop(this->csIds[index]);
|
||||||
|
this->cutsceneState = EN_DT_CS_STATE_NONE;
|
||||||
|
}
|
||||||
|
EnDt_OfferMeetingReward(this, play);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After Muto and Baisen react to the Couple's Mask,
|
||||||
|
// they leave the office and trigger a transition.
|
||||||
|
if (this->textIdIndex == 20) { // Muto reacts to Mayor's final comments
|
||||||
|
Message_CloseTextbox(play);
|
||||||
|
play->nextEntrance = ENTRANCE(MAYORS_RESIDENCE, 1);
|
||||||
|
Scene_SetExitFade(play);
|
||||||
|
play->transitionTrigger = TRANS_TRIGGER_START;
|
||||||
|
|
||||||
|
SET_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING);
|
||||||
|
this->meetingFinished = true;
|
||||||
|
|
||||||
|
if (this->cutsceneState == EN_DT_CS_STATE_PLAYING) {
|
||||||
|
CutsceneManager_Stop(this->csIds[index]);
|
||||||
|
this->cutsceneState = EN_DT_CS_STATE_NONE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// At the end of each cutscene dialog, trigger an event flag
|
||||||
|
if ((this->textIdIndex == 8) || (this->textIdIndex == 10) || (this->textIdIndex == 22) ||
|
||||||
|
(this->textIdIndex == 23)) {
|
||||||
|
SET_WEEKEVENTREG(WEEKEVENTREG_ATTENDED_MAYOR_MEETING);
|
||||||
|
Message_CloseTextbox(play);
|
||||||
|
|
||||||
|
// If the meeting is ongoing, reset all of the npc targets
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING)) {
|
||||||
|
if ((this->npcEnMuto != NULL) && (this->npcEnBaisen != NULL)) {
|
||||||
|
muto->cutsceneState = 2;
|
||||||
|
baisen->cutsceneState = 2;
|
||||||
|
muto->targetActor = this->npcEnMuto;
|
||||||
|
baisen->targetActor = this->npcEnBaisen;
|
||||||
|
}
|
||||||
|
this->targetActor = &this->actor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->cutsceneState == EN_DT_CS_STATE_PLAYING) {
|
||||||
|
CutsceneManager_Stop(this->csIds[index]);
|
||||||
|
this->cutsceneState = EN_DT_CS_STATE_NONE;
|
||||||
|
}
|
||||||
|
EnDt_SetupRegularState(this, play);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->textIdIndex++;
|
||||||
|
|
||||||
|
// End of initial meeting cutscene
|
||||||
|
if (this->textIdIndex == 8) {
|
||||||
|
play->msgCtx.msgLength = 0;
|
||||||
|
EnDt_UpdateCutsceneFocusTarget(this);
|
||||||
|
Actor_ChangeFocus(&this->actor, play, this->targetActor);
|
||||||
|
Camera_SetTargetActor(Play_GetCamera(play, CutsceneManager_GetCurrentSubCamId(this->csIds[index])),
|
||||||
|
this->targetActor);
|
||||||
|
|
||||||
|
this->timer = 2;
|
||||||
|
this->actionFunc = EnDt_FinishMeetingCutscene;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->textIdIndex == 12) { // Mayor reacts to Couple's mask
|
||||||
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_ATTENDED_MAYOR_MEETING)) {
|
||||||
|
EnDt_UpdateAppearance(this);
|
||||||
|
this->timer = 25;
|
||||||
|
} else {
|
||||||
|
EnDt_ChangeAnim(this, EN_DT_ANIMATION_UPRIGHT);
|
||||||
|
SkelAnime_Update(&this->skelAnime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->textIdIndex == 13) { // Muto reacts to Couple's mask
|
||||||
|
EnDt_ChangeAnim(this, EN_DT_ANIMATION_UPRIGHT);
|
||||||
|
SkelAnime_Update(&this->skelAnime);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnDt_UpdateCutsceneFocusTarget(this);
|
||||||
|
Actor_ChangeFocus(&this->actor, play, this->targetActor);
|
||||||
|
Camera_SetTargetActor(Play_GetCamera(play, CutsceneManager_GetCurrentSubCamId(this->csIds[index])),
|
||||||
|
this->targetActor);
|
||||||
|
|
||||||
|
this->actor.textId = sTextIds[this->textIdIndex];
|
||||||
|
Message_CloseTextbox(play);
|
||||||
|
Message_StartTextbox(play, this->actor.textId, &this->actor);
|
||||||
|
|
||||||
|
// Sets the cutscene ID index based off the current textId
|
||||||
|
for (index = 0; index < ARRAY_COUNT(sStringIdCsIndexTable); index += 2) {
|
||||||
|
if (play->msgCtx.currentTextId == sStringIdCsIndexTable[index] ||
|
||||||
|
this->actor.textId == sStringIdCsIndexTable[index]) {
|
||||||
|
this->csIdIndex = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index = sStringIdCsIndexTable[this->csIdIndex + 1];
|
||||||
|
if (this->cutsceneState == EN_DT_CS_STATE_PLAYING && (index != csIdIndex)) {
|
||||||
|
this->cutsceneState = EN_DT_CS_STATE_WAITING;
|
||||||
|
CutsceneManager_Stop(this->csIds[csIdIndex]);
|
||||||
|
CutsceneManager_Queue(this->csIds[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutoh turns his head to focus on the Mayor after saying "Isn't that right Mayor?"
|
||||||
|
if ((this->textIdIndex == 3) && (this->npcEnMuto != NULL) && (this->npcEnBaisen != NULL)) {
|
||||||
|
muto->targetActor = &this->actor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_FinishMeetingCutscene(EnDt* this, PlayState* play) {
|
||||||
|
f32 currFrame = this->skelAnime.curFrame;
|
||||||
|
|
||||||
|
if (this->timer != 0) {
|
||||||
|
if (this->timer == 1) {
|
||||||
|
if ((this->textIdIndex == 8) || (this->appearancePhase == EN_DT_APPEARANCE_RESOLUTION_TALK)) {
|
||||||
|
EnDt_UpdateAppearance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->appearancePhase++;
|
||||||
|
if (this->appearancePhase >= EN_DT_APPEARANCE_MAX) {
|
||||||
|
this->appearancePhase = EN_DT_APPEARANCE_RESOLVED_MEETING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this->animEndFrame <= currFrame) {
|
||||||
|
Camera* subCam;
|
||||||
|
s32 index;
|
||||||
|
s32 csIdIndex = sStringIdCsIndexTable[this->csIdIndex + 1];
|
||||||
|
|
||||||
|
EnDt_UpdateAppearance(this);
|
||||||
|
|
||||||
|
Message_CloseTextbox(play);
|
||||||
|
this->actor.textId = sTextIds[this->textIdIndex];
|
||||||
|
Message_StartTextbox(play, this->actor.textId, &this->actor);
|
||||||
|
|
||||||
|
if (this->textIdIndex == 8) { // End of initial meeting cutscene
|
||||||
|
Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_PERSON_MAYOR_DOTOUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the cutscene ID index based off the current textId
|
||||||
|
//! @bug Bug Relatively harmless, but the index should actually be incremented by 2 like similar loops
|
||||||
|
for (index = 0; index < ARRAY_COUNT(sStringIdCsIndexTable); index++) {
|
||||||
|
if ((play->msgCtx.currentTextId == sStringIdCsIndexTable[index]) ||
|
||||||
|
(this->actor.textId == sStringIdCsIndexTable[index])) {
|
||||||
|
this->csIdIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index = sStringIdCsIndexTable[this->csIdIndex + 1];
|
||||||
|
if ((this->cutsceneState == EN_DT_CS_STATE_PLAYING) && (index != csIdIndex)) {
|
||||||
|
this->cutsceneState = EN_DT_CS_STATE_WAITING;
|
||||||
|
CutsceneManager_Stop(this->csIds[csIdIndex]);
|
||||||
|
CutsceneManager_Queue(this->csIds[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnDt_UpdateCutsceneFocusTarget(this);
|
||||||
|
Actor_ChangeFocus(&this->actor, play, this->targetActor);
|
||||||
|
|
||||||
|
subCam = Play_GetCamera(play, CutsceneManager_GetCurrentSubCamId(this->csIds[index]));
|
||||||
|
Camera_SetTargetActor(subCam, this->targetActor);
|
||||||
|
|
||||||
|
this->actionFunc = EnDt_UpdateMeetingCutscene;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_OfferMeetingReward(EnDt* this, PlayState* play) {
|
||||||
|
Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 300.0f, 300.0f);
|
||||||
|
this->state = EN_DT_NPC_STATE_OFFERED_MEETING_REWARD;
|
||||||
|
this->actionFunc = EnDt_TriggerMeetingRewardEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_TriggerMeetingRewardEvent(EnDt* this, PlayState* play) {
|
||||||
|
if (Actor_HasParent(&this->actor, play)) {
|
||||||
|
this->textIdIndex = 22;
|
||||||
|
this->actor.parent = NULL;
|
||||||
|
this->actor.textId = sTextIds[this->textIdIndex];
|
||||||
|
|
||||||
|
Actor_OfferTalkExchange(&this->actor, play, 400.0f, 400.0f, PLAYER_IA_MINUS1);
|
||||||
|
|
||||||
|
SET_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_MAYOR_REWARD);
|
||||||
|
this->actionFunc = EnDt_TriggerMeetingNotebookEvent;
|
||||||
|
} else {
|
||||||
|
Actor_OfferGetItem(&this->actor, play, GI_HEART_PIECE, 300.0f, 300.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_TriggerMeetingNotebookEvent(EnDt* this, PlayState* play) {
|
||||||
|
SkelAnime_Update(&this->skelAnime);
|
||||||
|
|
||||||
|
if (Actor_TalkOfferAccepted(&this->actor, &play->state)) {
|
||||||
|
Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_EVENT_RECEIVED_MAYOR_HP);
|
||||||
|
Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_PERSON_MAYOR_DOTOUR);
|
||||||
|
this->actionFunc = EnDt_UpdateMeetingCutscene;
|
||||||
|
} else {
|
||||||
|
Actor_OfferTalkExchange(&this->actor, play, 400.0f, 400.0f, PLAYER_IA_MINUS1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_SetupFinalNightState(EnDt* this, PlayState* play) {
|
||||||
|
EnDt_ChangeAnim(this, EN_DT_ANIMATION_TAP_DESK);
|
||||||
|
|
||||||
|
this->disableBlinking = true;
|
||||||
|
this->textIdIndex = 24;
|
||||||
|
Message_BombersNotebookQueueEvent(play, BOMBERS_NOTEBOOK_PERSON_MAYOR_DOTOUR);
|
||||||
|
|
||||||
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_MAYOR_NIGHT_3)) {
|
||||||
|
this->textIdIndex = 26;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->actor.textId = sTextIds[this->textIdIndex];
|
||||||
|
this->eyeTexIndex = EN_DT_EYE_TEXTURE_LOOK_DOWN;
|
||||||
|
this->disableBlinking = true;
|
||||||
|
this->state = EN_DT_NPC_STATE_WAIT_FINAL_NIGHT_TALK;
|
||||||
|
this->actionFunc = EnDt_OfferFinalNightTalk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_OfferFinalNightTalk(EnDt* this, PlayState* play) {
|
||||||
|
EnDt_UpdateHeadRotate(this);
|
||||||
|
|
||||||
|
if (Actor_TalkOfferAccepted(&this->actor, &play->state)) {
|
||||||
|
EnDt_StartFinalNightTalk(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After completing Couple's Mask event and wearing Kafeis Mask
|
||||||
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) && (Player_GetMask(play) == PLAYER_MASK_KAFEIS_MASK)) {
|
||||||
|
this->actor.textId = 0x2368; // "My wife hired you? Go ask the Curiosity Shop"
|
||||||
|
}
|
||||||
|
|
||||||
|
Actor_OfferTalk(&this->actor, play, 150.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_StartFinalNightTalk(EnDt* this) {
|
||||||
|
this->state = EN_DT_NPC_STATE_DONE_FINAL_NIGHT_TALK;
|
||||||
|
this->actionFunc = EnDt_TriggerFinalNightTalkEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_TriggerFinalNightTalkEvent(EnDt* this, PlayState* play) {
|
||||||
|
EnDt_UpdateHeadRotate(this);
|
||||||
|
|
||||||
|
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) {
|
||||||
|
Message_CloseTextbox(play);
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_TALKED_MAYOR_NIGHT_3)) {
|
||||||
|
this->textIdIndex = 25;
|
||||||
|
Message_ContinueTextbox(play, sTextIds[this->textIdIndex]);
|
||||||
|
SET_WEEKEVENTREG(WEEKEVENTREG_TALKED_MAYOR_NIGHT_3);
|
||||||
|
} else {
|
||||||
|
EnDt_SetupFinalNightState(this, play);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_Update(Actor* thisx, PlayState* play) {
|
||||||
|
s32 pad;
|
||||||
|
EnDt* this = THIS;
|
||||||
|
|
||||||
|
SkelAnime_Update(&this->skelAnime);
|
||||||
|
Actor_SetScale(&this->actor, 0.01f);
|
||||||
|
|
||||||
|
if ((this->state != 4) && (this->state != 5) && (gSaveContext.save.day == 3) && gSaveContext.save.isNight) {
|
||||||
|
EnDt_SetupFinalNightState(this, play);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) &&
|
||||||
|
((gSaveContext.save.day != 3) || ((gSaveContext.save.day == 3) && !gSaveContext.save.isNight))) {
|
||||||
|
Audio_PlaySequenceAtPos(SEQ_PLAYER_BGM_SUB, &gSfxDefaultPos, NA_BGM_MAYORS_OFFICE, 1000.0f);
|
||||||
|
Actor_PlaySfx(&this->actor, NA_SE_EV_CROWD - SFX_FLAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
DECR(this->blinkTimer);
|
||||||
|
DECR(this->timer);
|
||||||
|
|
||||||
|
if (this->meetingFinished) {
|
||||||
|
EnDt_UpdateHeadRotate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blinking update
|
||||||
|
if (!this->disableBlinking && (this->blinkTimer == 0)) {
|
||||||
|
this->eyeTexIndex++;
|
||||||
|
if (this->eyeTexIndex >= EN_DT_EYE_TEXTURE_LOOK_DOWN) {
|
||||||
|
this->eyeTexIndex = EN_DT_EYE_TEXTURE_SHOCK;
|
||||||
|
this->blinkTimer = (s32)Rand_ZeroFloat(60.0f) + 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->actionFunc(this, play);
|
||||||
|
|
||||||
|
this->actor.shape.rot.y = this->actor.world.rot.y;
|
||||||
|
Math_SmoothStepToS(&this->headRotValue.y, this->headRotTarget.y, 1, 3000, 0);
|
||||||
|
|
||||||
|
Actor_SetFocus(&this->actor, 60.0f);
|
||||||
|
Actor_MoveWithGravity(&this->actor);
|
||||||
|
|
||||||
|
Collider_UpdateCylinder(&this->actor, &this->collider);
|
||||||
|
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 EnDt_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) {
|
||||||
|
EnDt* this = THIS;
|
||||||
|
|
||||||
|
if (limbIndex == OBJECT_DT_LIMB_0C) {
|
||||||
|
rot->y += -1 * this->headRotValue.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnDt_Draw(Actor* thisx, PlayState* play) {
|
||||||
|
EnDt* this = THIS;
|
||||||
|
s32 eyebrowIndex = 0;
|
||||||
|
|
||||||
|
OPEN_DISPS(play->state.gfxCtx);
|
||||||
|
|
||||||
|
Gfx_SetupDL25_Opa(play->state.gfxCtx);
|
||||||
|
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
|
||||||
|
|
||||||
|
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeTexIndex]));
|
||||||
|
|
||||||
|
if (this->eyeTexIndex < EN_DT_BROW_TEXTURE_MAX) {
|
||||||
|
eyebrowIndex = this->eyeTexIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(sEyebrowTextures[eyebrowIndex]));
|
||||||
|
|
||||||
|
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
|
||||||
|
EnDt_OverrideLimbDraw, NULL, &this->actor);
|
||||||
|
|
||||||
|
CLOSE_DISPS(play->state.gfxCtx);
|
||||||
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
#define Z_EN_DT_H
|
#define Z_EN_DT_H
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "objects/object_dt/object_dt.h"
|
||||||
|
|
||||||
|
#define EN_DT_CUTSCENE_COUNT 11
|
||||||
|
|
||||||
struct EnDt;
|
struct EnDt;
|
||||||
|
|
||||||
@ -9,9 +12,30 @@ typedef void (*EnDtActionFunc)(struct EnDt*, PlayState*);
|
|||||||
|
|
||||||
typedef struct EnDt {
|
typedef struct EnDt {
|
||||||
/* 0x000 */ Actor actor;
|
/* 0x000 */ Actor actor;
|
||||||
/* 0x144 */ char unk_144[0xF8];
|
/* 0x144 */ SkelAnime skelAnime;
|
||||||
|
/* 0x188 */ Vec3s jointTable[OBJECT_DT_LIMB_MAX];
|
||||||
|
/* 0x1E2 */ Vec3s morphTable[OBJECT_DT_LIMB_MAX];
|
||||||
/* 0x23C */ EnDtActionFunc actionFunc;
|
/* 0x23C */ EnDtActionFunc actionFunc;
|
||||||
/* 0x240 */ char unk_240[0xA0];
|
/* 0x240 */ s32 showedCouplesMask; // Is set, but never read from
|
||||||
|
/* 0x244 */ s16 timer;
|
||||||
|
/* 0x246 */ s16 animIndex;
|
||||||
|
/* 0x248 */ s16 disableBlinking;
|
||||||
|
/* 0x24A */ s16 blinkTimer;
|
||||||
|
/* 0x24C */ s16 eyeTexIndex;
|
||||||
|
/* 0x250 */ f32 animEndFrame;
|
||||||
|
/* 0x254 */ s16 state;
|
||||||
|
/* 0x256 */ s16 textIdIndex;
|
||||||
|
/* 0x258 */ s16 csIds[EN_DT_CUTSCENE_COUNT];
|
||||||
|
/* 0x26E */ s16 csIdIndex;
|
||||||
|
/* 0x270 */ s16 cutsceneState;
|
||||||
|
/* 0x274 */ Actor* npcEnMuto;
|
||||||
|
/* 0x278 */ Actor* npcEnBaisen;
|
||||||
|
/* 0x27C */ Actor* targetActor;
|
||||||
|
/* 0x280 */ s32 appearancePhase;
|
||||||
|
/* 0x284 */ Vec3s headRotValue;
|
||||||
|
/* 0x28A */ Vec3s headRotTarget;
|
||||||
|
/* 0x290 */ s32 meetingFinished;
|
||||||
|
/* 0x294 */ ColliderCylinder collider;
|
||||||
} EnDt; // size = 0x2E0
|
} EnDt; // size = 0x2E0
|
||||||
|
|
||||||
#endif // Z_EN_DT_H
|
#endif // Z_EN_DT_H
|
||||||
|
@ -37,7 +37,7 @@ void EnEndingHero_Init(Actor* thisx, PlayState* play) {
|
|||||||
Actor_SetScale(&this->actor, 0.01f);
|
Actor_SetScale(&this->actor, 0.01f);
|
||||||
this->actor.targetMode = TARGET_MODE_6;
|
this->actor.targetMode = TARGET_MODE_6;
|
||||||
this->actor.gravity = -3.0f;
|
this->actor.gravity = -3.0f;
|
||||||
SkelAnime_InitFlex(play, &this->skelAnime, &object_dt_Skel_00B0CC, &object_dt_Anim_000BE0, this->jointTable,
|
SkelAnime_InitFlex(play, &this->skelAnime, &object_dt_Skel_00B0CC, &gDotourUprightAnim, this->jointTable,
|
||||||
this->morphTable, OBJECT_DT_LIMB_MAX);
|
this->morphTable, OBJECT_DT_LIMB_MAX);
|
||||||
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f);
|
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f);
|
||||||
EnEndingHero1_SetupIdle(this);
|
EnEndingHero1_SetupIdle(this);
|
||||||
|
@ -56,7 +56,7 @@ static FlexSkeletonHeader* sSkeletons[ENDING_HERO6_TYPE_MAX] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static AnimationHeader* sAnimations[ENDING_HERO6_TYPE_MAX] = {
|
static AnimationHeader* sAnimations[ENDING_HERO6_TYPE_MAX] = {
|
||||||
&object_dt_Anim_000BE0, // ENDING_HERO6_TYPE_DT
|
&gDotourUprightAnim, // ENDING_HERO6_TYPE_DT
|
||||||
&object_bai_Anim_0011C0, // ENDING_HERO6_TYPE_BAI
|
&object_bai_Anim_0011C0, // ENDING_HERO6_TYPE_BAI
|
||||||
&object_toryo_Anim_000E50, // ENDING_HERO6_TYPE_TORYO
|
&object_toryo_Anim_000E50, // ENDING_HERO6_TYPE_TORYO
|
||||||
&gSoldierCheerWithSpearAnim, // ENDING_HERO6_TYPE_SOLDIER
|
&gSoldierCheerWithSpearAnim, // ENDING_HERO6_TYPE_SOLDIER
|
||||||
|
@ -64,14 +64,16 @@ void EnHeishi_Init(Actor* thisx, PlayState* play) {
|
|||||||
|
|
||||||
if (this->paramsCopy == 0) {
|
if (this->paramsCopy == 0) {
|
||||||
this->shouldSetHeadRotation = 1;
|
this->shouldSetHeadRotation = 1;
|
||||||
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_63_80) && !((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) &&
|
||||||
|
!((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->colliderCylinder.dim.radius = 30;
|
this->colliderCylinder.dim.radius = 30;
|
||||||
this->colliderCylinder.dim.height = 60;
|
this->colliderCylinder.dim.height = 60;
|
||||||
this->colliderCylinder.dim.yShift = 0;
|
this->colliderCylinder.dim.yShift = 0;
|
||||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_63_80) || ((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) ||
|
||||||
|
((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,8 @@ void EnMuto_Init(Actor* thisx, PlayState* play) {
|
|||||||
this->collider.dim.height = 60;
|
this->collider.dim.height = 60;
|
||||||
this->collider.dim.yShift = 0;
|
this->collider.dim.yShift = 0;
|
||||||
|
|
||||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_63_80) || ((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING) ||
|
||||||
|
((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +174,7 @@ void EnMuto_Idle(EnMuto* this, PlayState* play) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->textIdIndex = 0;
|
this->textIdIndex = 0;
|
||||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_60_08)) {
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_ATTENDED_MAYOR_MEETING)) {
|
||||||
this->textIdIndex = 1;
|
this->textIdIndex = 1;
|
||||||
}
|
}
|
||||||
if (Player_GetMask(play) == PLAYER_MASK_COUPLE) {
|
if (Player_GetMask(play) == PLAYER_MASK_COUPLE) {
|
||||||
|
@ -152,7 +152,7 @@ void EnRecepgirl_Talk(EnRecepgirl* this, PlayState* play) {
|
|||||||
Flags_SetSwitch(play, ENRECEPGIRL_GET_SWITCH_FLAG(&this->actor));
|
Flags_SetSwitch(play, ENRECEPGIRL_GET_SWITCH_FLAG(&this->actor));
|
||||||
Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 10.0f);
|
Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 10.0f);
|
||||||
|
|
||||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_63_80)) {
|
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RESOLVED_MAYOR_MEETING)) {
|
||||||
this->actor.textId = 0x2ADF; // Mayor's office is on the left (meeting ended)
|
this->actor.textId = 0x2ADF; // Mayor's office is on the left (meeting ended)
|
||||||
} else {
|
} else {
|
||||||
this->actor.textId = 0x2ADA; // Mayor's office is on the left (meeting ongoing)
|
this->actor.textId = 0x2ADA; // Mayor's office is on the left (meeting ongoing)
|
||||||
|
@ -16181,25 +16181,25 @@
|
|||||||
0x80BE99CC:("EnDemoheishi_Draw",),
|
0x80BE99CC:("EnDemoheishi_Draw",),
|
||||||
0x80BE9B20:("EnDt_Init",),
|
0x80BE9B20:("EnDt_Init",),
|
||||||
0x80BE9C48:("EnDt_Destroy",),
|
0x80BE9C48:("EnDt_Destroy",),
|
||||||
0x80BE9C74:("func_80BE9C74",),
|
0x80BE9C74:("EnDt_UpdateHeadRotate",),
|
||||||
0x80BE9CE8:("func_80BE9CE8",),
|
0x80BE9CE8:("EnDt_ChangeAnim",),
|
||||||
0x80BE9D9C:("func_80BE9D9C",),
|
0x80BE9D9C:("EnDt_UpdateAppearance",),
|
||||||
0x80BE9DF8:("func_80BE9DF8",),
|
0x80BE9DF8:("EnDt_UpdateCutsceneFocusTarget",),
|
||||||
0x80BE9E94:("func_80BE9E94",),
|
0x80BE9E94:("EnDt_SetupCutsceneNpcs",),
|
||||||
0x80BE9EF8:("func_80BE9EF8",),
|
0x80BE9EF8:("EnDt_SetupRegularState",),
|
||||||
0x80BEA088:("func_80BEA088",),
|
0x80BEA088:("EnDt_OfferRegularTalk",),
|
||||||
0x80BEA254:("func_80BEA254",),
|
0x80BEA254:("EnDt_SetupMeetingCutscene",),
|
||||||
0x80BEA394:("func_80BEA394",),
|
0x80BEA394:("EnDt_UpdateMeetingCutscene",),
|
||||||
0x80BEA8F0:("func_80BEA8F0",),
|
0x80BEA8F0:("EnDt_FinishMeetingCutscene",),
|
||||||
0x80BEAAF8:("func_80BEAAF8",),
|
0x80BEAAF8:("EnDt_OfferMeetingReward",),
|
||||||
0x80BEAB44:("func_80BEAB44",),
|
0x80BEAB44:("EnDt_TriggerMeetingRewardEvent",),
|
||||||
0x80BEABF8:("func_80BEABF8",),
|
0x80BEABF8:("EnDt_TriggerMeetingNotebookEvent",),
|
||||||
0x80BEAC84:("func_80BEAC84",),
|
0x80BEAC84:("EnDt_SetupFinalNightState",),
|
||||||
0x80BEAD2C:("func_80BEAD2C",),
|
0x80BEAD2C:("EnDt_OfferFinalNightTalk",),
|
||||||
0x80BEADB8:("func_80BEADB8",),
|
0x80BEADB8:("EnDt_StartFinalNightTalk",),
|
||||||
0x80BEADD4:("func_80BEADD4",),
|
0x80BEADD4:("EnDt_TriggerFinalNightTalkEvent",),
|
||||||
0x80BEAE94:("EnDt_Update",),
|
0x80BEAE94:("EnDt_Update",),
|
||||||
0x80BEB06C:("func_80BEB06C",),
|
0x80BEB06C:("EnDt_OverrideLimbDraw",),
|
||||||
0x80BEB0A8:("EnDt_Draw",),
|
0x80BEB0A8:("EnDt_Draw",),
|
||||||
0x80BEB520:("EnCha_Init",),
|
0x80BEB520:("EnCha_Init",),
|
||||||
0x80BEB5B0:("EnCha_Destroy",),
|
0x80BEB5B0:("EnCha_Destroy",),
|
||||||
|
@ -15862,16 +15862,16 @@
|
|||||||
0x80BE9A80:("sAnimations","UNK_TYPE1","",0x1),
|
0x80BE9A80:("sAnimations","UNK_TYPE1","",0x1),
|
||||||
0x80BE9A94:("sAnimationModes","UNK_TYPE1","",0x1),
|
0x80BE9A94:("sAnimationModes","UNK_TYPE1","",0x1),
|
||||||
0x80BEB1B0:("En_Dt_InitVars","UNK_TYPE1","",0x1),
|
0x80BEB1B0:("En_Dt_InitVars","UNK_TYPE1","",0x1),
|
||||||
0x80BEB1D0:("D_80BEB1D0","UNK_TYPE1","",0x1),
|
0x80BEB1D0:("sTextIds","UNK_TYPE1","",0x1),
|
||||||
0x80BEB208:("D_80BEB208","UNK_TYPE1","",0x1),
|
0x80BEB208:("sCutsceneFocusTargetTable","UNK_TYPE1","",0x1),
|
||||||
0x80BEB268:("D_80BEB268","UNK_TYPE2","",0x2),
|
0x80BEB268:("D_80BEB268","UNK_TYPE2","",0x2),
|
||||||
0x80BEB26A:("D_80BEB26A","UNK_TYPE2","",0x2),
|
0x80BEB26A:("D_80BEB26A","UNK_TYPE2","",0x2),
|
||||||
0x80BEB29C:("D_80BEB29C","UNK_TYPE1","",0x1),
|
0x80BEB29C:("sCylinderInit","UNK_TYPE1","",0x1),
|
||||||
0x80BEB2C8:("D_80BEB2C8","UNK_TYPE1","",0x1),
|
0x80BEB2C8:("sAnimations","UNK_TYPE1","",0x1),
|
||||||
0x80BEB2E0:("D_80BEB2E0","UNK_TYPE1","",0x1),
|
0x80BEB2E0:("sAnimationModes","UNK_TYPE1","",0x1),
|
||||||
0x80BEB2E8:("D_80BEB2E8","UNK_TYPE1","",0x1),
|
0x80BEB2E8:("sAppearancePropertiesTable","UNK_TYPE1","",0x1),
|
||||||
0x80BEB348:("D_80BEB348","UNK_TYPE1","",0x1),
|
0x80BEB348:("sEyeTextures","UNK_TYPE1","",0x1),
|
||||||
0x80BEB35C:("D_80BEB35C","UNK_TYPE1","",0x1),
|
0x80BEB35C:("sBrowTextures","UNK_TYPE1","",0x1),
|
||||||
0x80BEB860:("En_Cha_InitVars","UNK_TYPE1","",0x1),
|
0x80BEB860:("En_Cha_InitVars","UNK_TYPE1","",0x1),
|
||||||
0x80BEB880:("D_80BEB880","UNK_TYPE1","",0x1),
|
0x80BEB880:("D_80BEB880","UNK_TYPE1","",0x1),
|
||||||
0x80BEB8B0:("D_80BEB8B0","f32","",0x4),
|
0x80BEB8B0:("D_80BEB8B0","f32","",0x4),
|
||||||
|
Loading…
Reference in New Issue
Block a user