mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-08-13 17:03:47 -04:00
39cc86c260
subrepo: subdir: "soh" merged: "ba904bbd0" upstream: origin: "https://github.com/HarbourMasters/soh.git" branch: "master" commit: "ba904bbd0" git-subrepo: version: "0.4.1" origin: "???" commit: "???"
176 lines
5.5 KiB
C
176 lines
5.5 KiB
C
/*
|
|
* File: z_en_blkobj.c
|
|
* Overlay: ovl_En_Blkobj
|
|
* Description: Dark Link's Illusion Room
|
|
*/
|
|
|
|
#include "z_en_blkobj.h"
|
|
#include "objects/object_blkobj/object_blkobj.h"
|
|
|
|
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
|
|
|
void EnBlkobj_Init(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnBlkobj_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnBlkobj_Update(Actor* thisx, GlobalContext* globalCtx);
|
|
void EnBlkobj_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
void EnBlkobj_Wait(EnBlkobj* this, GlobalContext* globalCtx);
|
|
void EnBlkobj_SpawnDarkLink(EnBlkobj* this, GlobalContext* globalCtx);
|
|
void EnBlkobj_DarkLinkFight(EnBlkobj* this, GlobalContext* globalCtx);
|
|
void EnBlkobj_DoNothing(EnBlkobj* this, GlobalContext* globalCtx);
|
|
|
|
const ActorInit En_Blkobj_InitVars = {
|
|
ACTOR_EN_BLKOBJ,
|
|
ACTORCAT_PROP,
|
|
FLAGS,
|
|
OBJECT_BLKOBJ,
|
|
sizeof(EnBlkobj),
|
|
(ActorFunc)EnBlkobj_Init,
|
|
(ActorFunc)EnBlkobj_Destroy,
|
|
(ActorFunc)EnBlkobj_Update,
|
|
(ActorFunc)EnBlkobj_Draw,
|
|
NULL,
|
|
};
|
|
|
|
static InitChainEntry sInitChain[] = {
|
|
ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE),
|
|
ICHAIN_F32(uncullZoneForward, 800, ICHAIN_CONTINUE),
|
|
ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE),
|
|
ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_STOP),
|
|
};
|
|
|
|
static Gfx sSetupOpaDL[] = {
|
|
gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2),
|
|
gsSPEndDisplayList(),
|
|
};
|
|
|
|
static Gfx sSetupXluDL[] = {
|
|
gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2),
|
|
gsSPEndDisplayList(),
|
|
};
|
|
|
|
void EnBlkobj_SetupAction(EnBlkobj* this, EnBlkobjActionFunc actionFunc) {
|
|
this->actionFunc = actionFunc;
|
|
this->timer = 0;
|
|
}
|
|
|
|
void EnBlkobj_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
EnBlkobj* this = (EnBlkobj*)thisx;
|
|
CollisionHeader* colHeader = NULL;
|
|
|
|
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
|
|
DynaPolyActor_Init(&this->dyna, DPM_UNK);
|
|
if (Flags_GetClear(globalCtx, this->dyna.actor.room)) {
|
|
this->alpha = 255;
|
|
EnBlkobj_SetupAction(this, EnBlkobj_DoNothing);
|
|
} else {
|
|
CollisionHeader_GetVirtual(&gIllusionRoomCol, &colHeader);
|
|
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
|
|
EnBlkobj_SetupAction(this, EnBlkobj_Wait);
|
|
}
|
|
}
|
|
|
|
void EnBlkobj_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
EnBlkobj* this = (EnBlkobj*)thisx;
|
|
|
|
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
|
}
|
|
|
|
void EnBlkobj_Wait(EnBlkobj* this, GlobalContext* globalCtx) {
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
|
|
if (this->dyna.actor.xzDistToPlayer < 120.0f) {
|
|
EnBlkobj_SetupAction(this, EnBlkobj_SpawnDarkLink);
|
|
}
|
|
player->stateFlags2 |= 0x04000000;
|
|
}
|
|
|
|
void EnBlkobj_SpawnDarkLink(EnBlkobj* this, GlobalContext* globalCtx) {
|
|
if (!(this->dyna.actor.flags & ACTOR_FLAG_6)) {
|
|
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_TORCH2, this->dyna.actor.world.pos.x,
|
|
this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, this->dyna.actor.yawTowardsPlayer, 0,
|
|
0);
|
|
EnBlkobj_SetupAction(this, EnBlkobj_DarkLinkFight);
|
|
}
|
|
}
|
|
|
|
void EnBlkobj_DarkLinkFight(EnBlkobj* this, GlobalContext* globalCtx) {
|
|
s32 alphaMod;
|
|
|
|
if (this->timer == 0) {
|
|
if (Actor_Find(&globalCtx->actorCtx, ACTOR_EN_TORCH2, ACTORCAT_BOSS) == NULL) {
|
|
Flags_SetClear(globalCtx, this->dyna.actor.room);
|
|
this->timer++;
|
|
}
|
|
} else if (this->timer++ > 100) {
|
|
alphaMod = (this->timer - 100) >> 2;
|
|
if (alphaMod > 5) {
|
|
alphaMod = 5;
|
|
}
|
|
this->alpha += alphaMod;
|
|
if (this->alpha > 255) {
|
|
this->alpha = 255;
|
|
EnBlkobj_SetupAction(this, EnBlkobj_DoNothing);
|
|
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EnBlkobj_DoNothing(EnBlkobj* this, GlobalContext* globalCtx) {
|
|
}
|
|
|
|
void EnBlkobj_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
EnBlkobj* this = (EnBlkobj*)thisx;
|
|
|
|
this->actionFunc(this, globalCtx);
|
|
}
|
|
|
|
void EnBlkobj_DrawAlpha(GlobalContext* globalCtx, Gfx* dList, s32 alpha) {
|
|
Gfx* segment;
|
|
|
|
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_blkobj.c", 322);
|
|
|
|
if (alpha == 255) {
|
|
segment = sSetupOpaDL;
|
|
} else {
|
|
segment = sSetupXluDL;
|
|
}
|
|
|
|
gSPSegment(POLY_XLU_DISP++, 0x08, segment);
|
|
gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, alpha);
|
|
gSPDisplayList(POLY_XLU_DISP++, dList);
|
|
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_blkobj.c", 330);
|
|
}
|
|
|
|
void EnBlkobj_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|
s32 pad;
|
|
EnBlkobj* this = (EnBlkobj*)thisx;
|
|
s32 illusionAlpha;
|
|
u32 gameplayFrames;
|
|
|
|
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_blkobj.c", 349);
|
|
|
|
func_80093D84(globalCtx->state.gfxCtx);
|
|
|
|
gameplayFrames = globalCtx->gameplayFrames % 128;
|
|
|
|
gSPSegment(POLY_XLU_DISP++, 0x0D,
|
|
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, gameplayFrames, 0, 32, 32, 1, gameplayFrames, 0, 32, 32));
|
|
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_blkobj.c", 363),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
|
|
if (this->alpha != 0) {
|
|
EnBlkobj_DrawAlpha(globalCtx, gIllusionRoomNormalDL, this->alpha);
|
|
}
|
|
illusionAlpha = 255 - this->alpha;
|
|
if (illusionAlpha != 0) {
|
|
EnBlkobj_DrawAlpha(globalCtx, gIllusionRoomIllusionDL, illusionAlpha);
|
|
}
|
|
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_blkobj.c", 375);
|
|
}
|