mirror of
https://github.com/zeldaret/mm.git
synced 2026-07-31 23:58:56 -04:00
DoorAna: OK (#90)
* DoorAna: OK * DoorAna: changed z_lib functionname to match new master * DoorAna: requested changes * DoorAna: requested changes * DoorAna: Renamed nextEntranceIndex * DoorAna: some changes requested Co-authored-by: isghj8 <isghj8@gmail.com>
This commit is contained in:
+1
-1
@@ -525,7 +525,7 @@ void Scene_HeaderCommand1A(GlobalContext* ctxt, SceneCmd* entry) {
|
||||
}
|
||||
|
||||
void func_801306A4(GlobalContext *ctxt) {
|
||||
ctxt->unk1887F = func_801323A0(ctxt->unk1887A) & 0x7F;
|
||||
ctxt->unk1887F = func_801323A0(ctxt->nextEntranceIndex) & 0x7F;
|
||||
}
|
||||
|
||||
s32 Scene_ProcessHeader(GlobalContext* ctxt, SceneCmd* header) {
|
||||
|
||||
@@ -9,7 +9,10 @@ void DoorAna_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void DoorAna_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void DoorAna_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
/*
|
||||
void DoorAna_WaitClosed(DoorAna* this, GlobalContext* globalCtx);
|
||||
void DoorAna_WaitOpen(DoorAna* this, GlobalContext* globalCtx);
|
||||
void DoorAna_GrabLink(DoorAna* this, GlobalContext* globalCtx);
|
||||
|
||||
const ActorInit Door_Ana_InitVars = {
|
||||
ACTOR_DOOR_ANA,
|
||||
ACTORCAT_ITEMACTION,
|
||||
@@ -21,20 +24,168 @@ const ActorInit Door_Ana_InitVars = {
|
||||
(ActorFunc)DoorAna_Update,
|
||||
(ActorFunc)DoorAna_Draw
|
||||
};
|
||||
*/
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Ana_0x808E01A0/func_808E01A0.asm")
|
||||
static ColliderCylinderInit sCylinderInit = {
|
||||
{ COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, },
|
||||
{ ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0x00000008, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
|
||||
{ 50, 10, 0, { 0, 0, 0 } },
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Ana_0x808E01A0/DoorAna_Init.asm")
|
||||
// entrances grottos can link to statically, type DOORANA_TYPE_ADJACENT uses scene exit addresses instead
|
||||
static u16 entrances[] = {
|
||||
0x1A00, 0x1400, 0x1410, 0x1420, 0x1430, 0x1440, 0x1450, 0x1460,
|
||||
0x1470, 0x1480, 0x1490, 0x14A0, 0x14B0, 0x14C0, 0x14D0,
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Ana_0x808E01A0/DoorAna_Destroy.asm")
|
||||
void DoorAna_SetupAction(DoorAna* this, DoorAnaActionFunc actionFunction) {
|
||||
this->actionFunc = actionFunction;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Ana_0x808E01A0/func_808E02A4.asm")
|
||||
void DoorAna_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
DoorAna* this = THIS;
|
||||
s32 grottoType = GET_DOORANA_TYPE(this);
|
||||
this->actor.shape.rot.y = this->actor.shape.rot.z = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Ana_0x808E01A0/func_808E03B8.asm")
|
||||
if ((grottoType == DOORANA_TYPE_UNK) || (grottoType == DOORANA_TYPE_HIDDEN)) {
|
||||
if (grottoType == DOORANA_TYPE_HIDDEN) {
|
||||
Collider_InitAndSetCylinder(globalCtx, &this->bombCollider, &this->actor, &sCylinderInit);
|
||||
} else {
|
||||
this->actor.flags |= 0x10; // always update
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Ana_0x808E01A0/func_808E05C4.asm")
|
||||
Actor_SetScale(&this->actor, 0);
|
||||
DoorAna_SetupAction(this, DoorAna_WaitClosed);
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Ana_0x808E01A0/DoorAna_Update.asm")
|
||||
} else {
|
||||
DoorAna_SetupAction(this, DoorAna_WaitOpen);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Door_Ana_0x808E01A0/DoorAna_Draw.asm")
|
||||
this->actor.targetMode = 0;
|
||||
}
|
||||
|
||||
void DoorAna_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
DoorAna* this = THIS;
|
||||
s32 grottoType = GET_DOORANA_TYPE(this);
|
||||
|
||||
if (grottoType == DOORANA_TYPE_HIDDEN) {
|
||||
Collider_DestroyCylinder(globalCtx, &this->bombCollider);
|
||||
}
|
||||
}
|
||||
|
||||
void DoorAna_WaitClosed(DoorAna* this, GlobalContext* globalCtx) {
|
||||
s32 grottoIsOpen = 0;
|
||||
u32 grottoType = GET_DOORANA_TYPE(this);
|
||||
|
||||
if (grottoType == DOORANA_TYPE_UNK) {
|
||||
// in OOT decomp its marked as open with storms, but does not seem to open with storms in MM
|
||||
if ((this->actor.xyzDistToPlayerSq < 40000.0f) && (func_800F13E8(globalCtx, 5))) {
|
||||
grottoIsOpen = 1;
|
||||
this->actor.flags &= ~0x10; // always update OFF
|
||||
}
|
||||
|
||||
} else {
|
||||
if (this->bombCollider.base.acFlags & AC_HIT) { // bomb collision
|
||||
grottoIsOpen = 1;
|
||||
Collider_DestroyCylinder(globalCtx, &this->bombCollider);
|
||||
|
||||
} else {
|
||||
Collider_UpdateCylinder(&this->actor, &this->bombCollider);
|
||||
CollisionCheck_SetAC(globalCtx, &globalCtx->colCheckCtx, &this->bombCollider.base);
|
||||
}
|
||||
}
|
||||
|
||||
if (grottoIsOpen) {
|
||||
this->actor.params &= ~DOORANA_TYPE_BITRANGE;
|
||||
DoorAna_SetupAction(this, DoorAna_WaitOpen);
|
||||
play_sound(0x4802); // CORRECT_CHIME sfx
|
||||
}
|
||||
|
||||
func_800B8C50(&this->actor, globalCtx);
|
||||
}
|
||||
|
||||
void DoorAna_WaitOpen(DoorAna* this, GlobalContext* globalCtx) {
|
||||
ActorPlayer* player = PLAYER;
|
||||
s32 dooranaType = GET_DOORANA_TYPE(this);
|
||||
s8 pad[4];
|
||||
s32 entranceIndex;
|
||||
f32 yDist;
|
||||
|
||||
if (Math_StepToF( &this->actor.scale, 0.01f, 0.001f) != 0) {
|
||||
if ((this->actor.targetMode != 0) && (globalCtx->unk18875 == 0) && (globalCtx->unk18B4A == 0) &&
|
||||
(player->stateFlags1 & 0x80000000) && (player->unkAE7 == 0)) {
|
||||
|
||||
if (dooranaType == DOORANA_TYPE_ADJACENT) {
|
||||
// 300 uses scene exit addresses, not static DoorAna entrance addresses,
|
||||
// eg. deku playground gets address in the NCT scene exit table
|
||||
|
||||
entranceIndex = GET_DOORANA_ADJACENT_ENTRANCE(this);
|
||||
globalCtx->nextEntranceIndex = globalCtx->setupExitList[entranceIndex];
|
||||
lblUnk_808E03B8: ; // required to convince compiler to not use delay slot
|
||||
|
||||
} else {
|
||||
// unused in vanilla, the highest params bits can directly index an address
|
||||
entranceIndex = GET_DOORANA_DIRECT_ENTRANCE(this);
|
||||
|
||||
func_80169E6C(globalCtx, 3, 0x4FF);
|
||||
|
||||
gSaveContext.extra.unk78 = this->actor.world.pos.y;
|
||||
gSaveContext.extra.unk80 = this->actor.home.rot.y;
|
||||
|
||||
// save the params lower byte for En_Torch to decide what item to use in the grotto chest
|
||||
gSaveContext.extra.unk87 = GET_DOORANA_ITEMFLAGS(this);
|
||||
|
||||
// most grottos in the game use their zrotation as their entrance index, not params
|
||||
if (DOORANA_TYPE_ROTATION_ENTRANCE(entranceIndex)) {
|
||||
entranceIndex = GET_DOORANA_ROTATION_ENTRANCE(this);
|
||||
}
|
||||
|
||||
globalCtx->nextEntranceIndex = entrances[entranceIndex];
|
||||
}
|
||||
|
||||
DoorAna_SetupAction(this, DoorAna_GrabLink);
|
||||
|
||||
} else {
|
||||
if ((func_801690CC(globalCtx) == 0) && ((player->stateFlags1 & 0x08800000) == 0)
|
||||
&& (this->actor.xzDistToPlayer <= 20.0f)
|
||||
&& (yDist = this->actor.yDistToPlayer, (yDist >= -50.0f)) && (yDist <= 15.0f)) {
|
||||
player->stateFlags1 |= 0x80000000;
|
||||
this->actor.targetMode = 1;
|
||||
|
||||
} else {
|
||||
this->actor.targetMode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Actor_SetScale( &this->actor, this->actor.scale.x);
|
||||
}
|
||||
|
||||
void DoorAna_GrabLink(DoorAna* this, GlobalContext* globalCtx) {
|
||||
Actor* player;
|
||||
s8 pad[2];
|
||||
|
||||
if (ActorCutscene_GetCurrentIndex() != this->actor.cutscene) {
|
||||
if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
|
||||
ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor);
|
||||
} else {
|
||||
ActorCutscene_SetIntentToPlay(this->actor.cutscene);
|
||||
}
|
||||
}
|
||||
|
||||
if ((this->actor.yDistToPlayer <= 0.0f) && (this->actor.xzDistToPlayer > 20.0f)) {
|
||||
player = PLAYER;
|
||||
player->world.pos.x = (Math_SinS(this->actor.yawTowardsPlayer) * 20.0f) + this->actor.world.pos.x;
|
||||
player->world.pos.z = (Math_CosS(this->actor.yawTowardsPlayer) * 20.0f) + this->actor.world.pos.z;
|
||||
}
|
||||
}
|
||||
|
||||
void DoorAna_Update(Actor *thisx, GlobalContext *globalCtx) {
|
||||
DoorAna* this = THIS;
|
||||
this->actionFunc(this, globalCtx);
|
||||
this->actor.shape.rot.y = func_800DFCDC(globalCtx->cameraPtrs[globalCtx->activeCamera]) + 0x8000;
|
||||
}
|
||||
|
||||
void DoorAna_Draw(Actor *thisx, GlobalContext *globalCtx) {
|
||||
Gfx* doorAnaDL = D_05000C40;
|
||||
func_800BE03C(globalCtx, doorAnaDL);
|
||||
}
|
||||
|
||||
@@ -5,11 +5,28 @@
|
||||
|
||||
struct DoorAna;
|
||||
|
||||
typedef void (*DoorAnaActionFunc)(struct DoorAna*, GlobalContext*);
|
||||
|
||||
typedef struct DoorAna {
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ char unk_144[0x50];
|
||||
/* 0x144 */ ColliderCylinder bombCollider;
|
||||
/* 0x190 */ DoorAnaActionFunc actionFunc;
|
||||
} DoorAna; // size = 0x194
|
||||
|
||||
extern const ActorInit Door_Ana_InitVars;
|
||||
|
||||
#define DOORANA_TYPE_REGULAR 0x000
|
||||
#define DOORANA_TYPE_UNK 0x100
|
||||
#define DOORANA_TYPE_HIDDEN 0x200
|
||||
#define DOORANA_TYPE_ADJACENT 0x300
|
||||
#define DOORANA_TYPE_BITRANGE 0x300
|
||||
|
||||
#define GET_DOORANA_TYPE(this)(this->actor.params & 0x300)
|
||||
|
||||
#define DOORANA_TYPE_ROTATION_ENTRANCE(directEntrance)(directEntrance < 0)
|
||||
#define GET_DOORANA_DIRECT_ENTRANCE(this) ((((this)->actor.params >> 0xC) & 0x7) - 1)
|
||||
#define GET_DOORANA_ADJACENT_ENTRANCE(this) ((this)->actor.params & 0x1F)
|
||||
#define GET_DOORANA_ROTATION_ENTRANCE(this) (this->actor.home.rot.z + 1)
|
||||
#define GET_DOORANA_ITEMFLAGS(this) ((this)->actor.params & 0xFF)
|
||||
|
||||
#endif // Z_DOOR_ANA_H
|
||||
|
||||
Reference in New Issue
Block a user