diff --git a/assets/xml/overlays/ovl_Obj_Jgame_Light.xml b/assets/xml/overlays/ovl_Obj_Jgame_Light.xml new file mode 100644 index 0000000000..e6b740aca3 --- /dev/null +++ b/assets/xml/overlays/ovl_Obj_Jgame_Light.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/spec b/spec index 714369ef04..cb8ddd6c00 100644 --- a/spec +++ b/spec @@ -5018,8 +5018,7 @@ beginseg name "ovl_Obj_Jgame_Light" compress include "build/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.o" - include "build/data/ovl_Obj_Jgame_Light/ovl_Obj_Jgame_Light.data.o" - include "build/data/ovl_Obj_Jgame_Light/ovl_Obj_Jgame_Light.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Jgame_Light/ovl_Obj_Jgame_Light_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c b/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c index 27027c87f4..14ad0136e6 100644 --- a/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c +++ b/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c @@ -303,7 +303,7 @@ void func_80C1418C(EnJgameTsn* this, PlayState* play) { void func_80C141DC(EnJgameTsn* this) { this->unk_218 = Rand_Next() & 3; this->unk_2FC = 0; - *this->unk_208[this->unk_218] |= 1; + *this->unk_208[this->unk_218] |= OBJLUPYGAMELIFT_IGNITE_FIRE; this->actionFunc = func_80C14230; } @@ -324,10 +324,10 @@ void func_80C14230(EnJgameTsn* this, PlayState* play) { for (i = 0; i < ARRAY_COUNT(this->unk_208); i++) { if (i == this->unk_218) { - *this->unk_208[i] |= 1; - *this->unk_208[i] &= ~8; + *this->unk_208[i] |= OBJLUPYGAMELIFT_IGNITE_FIRE; + *this->unk_208[i] &= ~OBJLUPYGAMELIFT_SNUFF_FIRE; } else { - *this->unk_208[i] |= 8; + *this->unk_208[i] |= OBJLUPYGAMELIFT_SNUFF_FIRE; } } } @@ -339,7 +339,7 @@ void func_80C14230(EnJgameTsn* this, PlayState* play) { Message_StartTextbox(play, 0x109F, &this->actor); this->unk_300 = 0x109F; player->stateFlags1 |= 0x20; - *this->unk_208[this->unk_218] &= ~1; + *this->unk_208[this->unk_218] &= ~OBJLUPYGAMELIFT_IGNITE_FIRE; func_801A2C20(); func_80C14030(this); } else if ((player->actor.bgCheckFlags & 0x40) || (player->actor.bgCheckFlags & 0x20)) { @@ -347,7 +347,7 @@ void func_80C14230(EnJgameTsn* this, PlayState* play) { Message_StartTextbox(play, 0x10A0, &this->actor); this->unk_300 = 0x10A0; player->stateFlags1 |= 0x20; - *this->unk_208[this->unk_218] &= ~1; + *this->unk_208[this->unk_218] &= ~OBJLUPYGAMELIFT_IGNITE_FIRE; func_801A2C20(); func_80C14030(this); } @@ -356,7 +356,7 @@ void func_80C14230(EnJgameTsn* this, PlayState* play) { Message_StartTextbox(play, 0x10A1, &this->actor); this->unk_300 = 0x10A1; player->stateFlags1 |= 0x20; - *this->unk_208[this->unk_218] &= ~1; + *this->unk_208[this->unk_218] &= ~OBJLUPYGAMELIFT_IGNITE_FIRE; func_801A2C20(); func_80C14030(this); } @@ -562,17 +562,17 @@ s32 func_80C14BCC(EnJgameTsn* this, PlayState* play) { if (phi_s3 == this->unk_218) { Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); - *this->unk_208[phi_s3] |= 2; + *this->unk_208[phi_s3] |= OBJLUPYGAMELIFT_DISPLAY_CORRECT; play->interfaceCtx.unk_25C = 1; return true; } - if (*this->unk_208[phi_s3] & 1) { + if (*this->unk_208[phi_s3] & OBJLUPYGAMELIFT_IGNITE_FIRE) { Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); - *this->unk_208[phi_s3] |= 2; + *this->unk_208[phi_s3] |= OBJLUPYGAMELIFT_DISPLAY_CORRECT; play->interfaceCtx.unk_25C = 1; } else { - *this->unk_208[phi_s3] |= 4; + *this->unk_208[phi_s3] |= OBJLUPYGAMELIFT_DISPLAY_INCORRECT; Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_ERROR); } } diff --git a/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.c b/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.c index 1d34515c91..dfea61857e 100644 --- a/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.c +++ b/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.c @@ -5,17 +5,28 @@ */ #include "z_obj_jgame_light.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_syokudai/object_syokudai.h" #define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjJgameLight*)thisx) +typedef enum { + /* 0x0 */ OBJJGAMELIGHT_NONE, + /* 0x1 */ OBJJGAMELIGHT_CORRECT, + /* 0x2 */ OBJJGAMELIGHT_INCORRECT, +} ObjJgameLightSignal; + void ObjJgameLight_Init(Actor* thisx, PlayState* play); void ObjJgameLight_Destroy(Actor* thisx, PlayState* play); void ObjJgameLight_Update(Actor* thisx, PlayState* play); void ObjJgameLight_Draw(Actor* thisx, PlayState* play); -#if 0 +void func_80C15474(ObjJgameLight* this, PlayState* play); +void ObjJgameLight_UpdateCollision(ObjJgameLight* this, PlayState* play); +void func_80C15718(ObjJgameLight* this, PlayState* play); + const ActorInit Obj_Jgame_Light_InitVars = { ACTOR_OBJ_JGAME_LIGHT, ACTORCAT_PROP, @@ -28,29 +39,173 @@ const ActorInit Obj_Jgame_Light_InitVars = { (ActorFunc)ObjJgameLight_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C15BC0 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00100000, 0x00, 0x00 }, { 0xF6CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00100000, 0x00, 0x00 }, + { 0xF6CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 12, 45, 0, { 0, 0, 0 } }, }; -#endif +#include "assets/overlays/ovl_Obj_Jgame_Light/ovl_Obj_Jgame_Light.c" -extern ColliderCylinderInit D_80C15BC0; +void ObjJgameLight_Init(Actor* thisx, PlayState* play) { + ObjJgameLight* this = THIS; + LightInfo* lights = &this->lightInfo; -extern UNK_TYPE D_060003A0; + Actor_SetScale(&this->actor, 1.0f); + func_800B4AEC(play, &this->actor, 50.0f); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B4B50, 1.0f); + Collider_InitCylinder(play, &this->collider); + Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit); + Lights_PointGlowSetInfo(lights, this->actor.world.pos.x, (this->actor.world.pos.y + 70.0f), this->actor.world.pos.z, + 255, 255, 180, -1); + this->lightNode = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo); + Actor_SetFocus(&this->actor, 60.0f); + this->actor.colChkInfo.health = 0; + this->prevHealth = 0; + this->isOn = false; + this->lightRadius = 0; + this->alpha = 0; + this->signal = OBJJGAMELIGHT_NONE; + this->flameScaleProportion = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jgame_Light/ObjJgameLight_Init.s") +void ObjJgameLight_Destroy(Actor* thisx, PlayState* play) { + ObjJgameLight* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jgame_Light/ObjJgameLight_Destroy.s") + Collider_DestroyCylinder(play, &this->collider); + LightContext_RemoveLight(play, &play->lightCtx, this->lightNode); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jgame_Light/func_80C15474.s") +void func_80C15474(ObjJgameLight* this, PlayState* play) { + u8 temp_a1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jgame_Light/func_80C156C4.s") + if ((this->actor.colChkInfo.health & OBJLUPYGAMELIFT_IGNITE_FIRE) && (this->isOn == false)) { + if (this->lightRadius < 160) { + this->lightRadius += 40; + } else { + this->lightRadius = 200; + this->isOn = true; + } + if (this->flameScaleProportion < 0.7f) { + this->flameScaleProportion += 0.3f; + } else { + this->flameScaleProportion = 1.0f; + } + } else if (this->actor.colChkInfo.health & OBJLUPYGAMELIFT_SNUFF_FIRE) { + if (this->lightRadius > 40) { + this->lightRadius -= 40; + } else { + this->lightRadius = -1; + if (this->flameScaleProportion == 0.0f) { + this->isOn = false; + this->actor.colChkInfo.health &= ~OBJLUPYGAMELIFT_IGNITE_FIRE; + this->actor.colChkInfo.health &= ~OBJLUPYGAMELIFT_SNUFF_FIRE; + } + } + if (this->flameScaleProportion > 0.3f) { + this->flameScaleProportion -= 0.3f; + } else { + this->flameScaleProportion = 0.0f; + } + } + if (this->flameScaleProportion > 0.1f) { + func_800B9010(&this->actor, NA_SE_EV_TORCH - SFX_FLAG); + } + temp_a1 = (s32)(Rand_ZeroOne() * 127.0f) + 128; + Lights_PointSetColorAndRadius(&this->lightInfo, temp_a1, temp_a1 * 0.7f, 0, this->lightRadius); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jgame_Light/func_80C15718.s") +void ObjJgameLight_UpdateCollision(ObjJgameLight* this, PlayState* play) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jgame_Light/ObjJgameLight_Update.s") +void func_80C15718(ObjJgameLight* this, PlayState* play) { + if ((this->actor.colChkInfo.health & OBJLUPYGAMELIFT_IGNITE_FIRE) && + !(this->prevHealth & OBJLUPYGAMELIFT_IGNITE_FIRE)) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_FLAME_IGNITION); + this->prevHealth = this->actor.colChkInfo.health; + } + if (this->actor.colChkInfo.health & OBJLUPYGAMELIFT_DISPLAY_CORRECT) { + this->actor.colChkInfo.health &= ~OBJLUPYGAMELIFT_DISPLAY_CORRECT; + this->alpha = 300; + this->signal = OBJJGAMELIGHT_CORRECT; + } else if (this->actor.colChkInfo.health & OBJLUPYGAMELIFT_DISPLAY_INCORRECT) { + this->actor.colChkInfo.health &= ~OBJLUPYGAMELIFT_DISPLAY_INCORRECT; + this->alpha = 300; + this->signal = OBJJGAMELIGHT_INCORRECT; + } + if (this->alpha > 15) { + this->alpha -= 15; + } else { + this->alpha = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jgame_Light/ObjJgameLight_Draw.s") +void ObjJgameLight_Update(Actor* thisx, PlayState* play) { + ObjJgameLight* this = THIS; + + func_80C15718(this, play); + func_80C15474(this, play); + ObjJgameLight_UpdateCollision(this, play); + this->flameScroll++; +} + +void ObjJgameLight_Draw(Actor* thisx, PlayState* play) { + s32 pad; + ObjJgameLight* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C28C(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, &gObjectSyokudaiTypeSwitchCausesFlameDL); + if (this->alpha > 0) { + func_8012C2DC(play->state.gfxCtx); + if (this->alpha > 255) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 210, 64, 32, 255); + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 210, 64, 32, this->alpha); + } + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + if (this->signal == OBJJGAMELIGHT_CORRECT) { + gSPDisplayList(POLY_XLU_DISP++, gObjJgameLightCorrectDL); + } else if (this->signal == OBJJGAMELIGHT_INCORRECT) { + gSPDisplayList(POLY_XLU_DISP++, gObjJgameLightIncorrectDL); + } + } + if (this->flameScaleProportion != 0.0f) { + f32 scale; + + func_8012C2DC(play->state.gfxCtx); + scale = (this->flameScaleProportion * 27.0f) / 10000.0f; + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (this->flameScroll * -20) & 0x1FF, + 0x20, 0x80)); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + Matrix_Translate(0.0f, 52.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateYS( + ((Camera_GetCamDirYaw(play->cameraPtrs[play->activeCamera]) - this->actor.shape.rot.y) + 0x8000), + MTXMODE_APPLY); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); + } + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h b/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h index 50023c252d..a81bbf3cc0 100644 --- a/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h +++ b/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h @@ -6,10 +6,25 @@ struct ObjJgameLight; #define OBJJGAMELIGHT_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJLUPYGAMELIFT_IGNITE_FIRE (1 << 0) +#define OBJLUPYGAMELIFT_DISPLAY_CORRECT (1 << 1) +#define OBJLUPYGAMELIFT_DISPLAY_INCORRECT (1 << 2) +#define OBJLUPYGAMELIFT_SNUFF_FIRE (1 << 3) typedef struct ObjJgameLight { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x78]; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ UNK_TYPE1 pad_190[4]; + /* 0x194 */ LightNode* lightNode; + /* 0x198 */ LightInfo lightInfo; + /* 0x1A8 */ f32 flameScaleProportion; + /* 0x1AC */ s16 lightRadius; + /* 0x1AE */ s16 flameScroll; + /* 0x1B0 */ UNK_TYPE1 pad_1B0[2]; + /* 0x1B2 */ s16 alpha; + /* 0x1B4 */ s16 signal; + /* 0x1B6 */ s16 isOn; + /* 0x1B8 */ u8 prevHealth; } ObjJgameLight; // size = 0x1BC extern const ActorInit Obj_Jgame_Light_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 4d6a750a24..4b8274441c 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -16817,7 +16817,7 @@ 0x80C152F0:("ObjJgameLight_Init",), 0x80C1542C:("ObjJgameLight_Destroy",), 0x80C15474:("func_80C15474",), - 0x80C156C4:("func_80C156C4",), + 0x80C156C4:("ObjJgameLight_UpdateCollision",), 0x80C15718:("func_80C15718",), 0x80C157D4:("ObjJgameLight_Update",), 0x80C15828:("ObjJgameLight_Draw",), diff --git a/undefined_syms.txt b/undefined_syms.txt index b3ba1cdd9d..fbdce5265e 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -1515,10 +1515,6 @@ D_06000F00 = 0x06000F00; D_06000180 = 0x06000180; D_06000BA0 = 0x06000BA0; -// ovl_Obj_Jgame_Light - -D_060003A0 = 0x060003A0; - // ovl_Obj_Lift D_06000D10 = 0x06000D10;