mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-14 10:37:17 -07:00
Chest size and texture matches contents (#1778)
* Implement most of chest size and texture matches contents, just need an item table * Add GetItemCategory to getItem tables * Revert changes that tie chest size and texture to randomizer * Support chest size & texture as an enhancement that works on outside of rando * Add gChestSizeAndTextureMatchesContents to rando preset * Prevent gChestSizeAndTextureMatchesContents in chest minigame * Fix for forest temple boss key chest * Add options for texture or size only
This commit is contained in:
parent
f756da02e5
commit
e5cc09a96f
15 changed files with 412 additions and 249 deletions
|
@ -140,7 +140,9 @@ void func_808A39FC(BgMoriHineri* this, GlobalContext* globalCtx) {
|
|||
colHeader = NULL;
|
||||
this->dyna.actor.draw = BgMoriHineri_DrawHallAndRoom;
|
||||
if (this->dyna.actor.params == 0) {
|
||||
this->actionFunc = func_808A3C8C;
|
||||
// In vanilla this actionFunc is set to func_808A3C8C, and the boss key chest is rendered from scratch in BgMoriHineri_DrawHallAndRoom
|
||||
// In SOH we instead spawn the en_box actor, which allows the rendering to be handled consistently with the rest of the chests in the game
|
||||
this->actionFunc = BgMoriHineri_SpawnBossKeyChest;
|
||||
CollisionHeader_GetVirtual(&object_mori_hineri1_Col_0054B8, &colHeader);
|
||||
} else if (this->dyna.actor.params == 1) {
|
||||
this->actionFunc = BgMoriHineri_SpawnBossKeyChest;
|
||||
|
@ -161,9 +163,15 @@ void BgMoriHineri_DoNothing(BgMoriHineri* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
void BgMoriHineri_SpawnBossKeyChest(BgMoriHineri* this, GlobalContext* globalCtx) {
|
||||
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOX, this->dyna.actor.world.pos.x + 147.0f,
|
||||
this->dyna.actor.world.pos.y + -245.0f, this->dyna.actor.world.pos.z + -453.0f, 0, 0x4000, 0, 0x27EE);
|
||||
this->actionFunc = BgMoriHineri_DoNothing;
|
||||
if (this->dyna.actor.params == 0) {
|
||||
Object_Spawn(&globalCtx->objectCtx, OBJECT_BOX);
|
||||
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOX, -1515.0f, 1440.0f, -3475.0f, -0x4000, 0x4000, 0, 0x27EE);
|
||||
this->actionFunc = func_808A3C8C;
|
||||
} else {
|
||||
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOX, this->dyna.actor.world.pos.x + 147.0f,
|
||||
this->dyna.actor.world.pos.y + -245.0f, this->dyna.actor.world.pos.z + -453.0f, 0, 0x4000, 0, 0x27EE);
|
||||
this->actionFunc = BgMoriHineri_DoNothing;
|
||||
}
|
||||
}
|
||||
|
||||
void func_808A3C8C(BgMoriHineri* this, GlobalContext* globalCtx) {
|
||||
|
@ -255,29 +263,6 @@ void BgMoriHineri_DrawHallAndRoom(Actor* thisx, GlobalContext* globalCtx) {
|
|||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, gDungeonDoorDL);
|
||||
}
|
||||
if ((this->boxObjIdx > 0) && ((this->boxObjIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_BOX)) > 0) &&
|
||||
Object_IsLoaded(&globalCtx->objectCtx, this->boxObjIdx)) {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->boxObjIdx].segment);
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, &D_80116280[2]);
|
||||
Matrix_Put(&mtx);
|
||||
Matrix_Translate(147.0f, -245.0f, -453.0f, MTXMODE_APPLY);
|
||||
Matrix_RotateY(M_PI / 2, MTXMODE_APPLY);
|
||||
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, gTreasureChestBossKeyChestFrontDL);
|
||||
Matrix_Put(&mtx);
|
||||
Matrix_Translate(167.0f, -218.0f, -453.0f, MTXMODE_APPLY);
|
||||
if (Flags_GetTreasure(globalCtx, 0xE)) {
|
||||
Matrix_RotateZ(0x3500 * (M_PI / 0x8000), MTXMODE_APPLY);
|
||||
} else {
|
||||
Matrix_RotateZ(M_PI, MTXMODE_APPLY);
|
||||
}
|
||||
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, gTreasureChestBossKeyChestSideAndTopDL);
|
||||
}
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ void EnBox_AppearInit(EnBox*, GlobalContext*);
|
|||
void EnBox_AppearAnimation(EnBox*, GlobalContext*);
|
||||
void EnBox_WaitOpen(EnBox*, GlobalContext*);
|
||||
void EnBox_Open(EnBox*, GlobalContext*);
|
||||
void EnBox_CreateExtraChestTextures();
|
||||
void EnBox_UpdateSizeAndTexture(EnBox*, GlobalContext*);
|
||||
|
||||
const ActorInit En_Box_InitVars = {
|
||||
ACTOR_EN_BOX,
|
||||
|
@ -72,6 +74,14 @@ static InitChainEntry sInitChain[] = {
|
|||
static UNK_TYPE sUnused;
|
||||
GetItemEntry sItem;
|
||||
|
||||
Gfx gSkullTreasureChestChestSideAndLidDL[116] = {0};
|
||||
Gfx gGoldTreasureChestChestSideAndLidDL[116] = {0};
|
||||
Gfx gKeyTreasureChestChestSideAndLidDL[116] = {0};
|
||||
Gfx gSkullTreasureChestChestFrontDL[128] = {0};
|
||||
Gfx gGoldTreasureChestChestFrontDL[128] = {0};
|
||||
Gfx gKeyTreasureChestChestFrontDL[128] = {0};
|
||||
u8 hasCreatedRandoChestTextures = 0;
|
||||
|
||||
void EnBox_SetupAction(EnBox* this, EnBoxActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
}
|
||||
|
@ -174,17 +184,11 @@ void EnBox_Init(Actor* thisx, GlobalContext* globalCtx2) {
|
|||
SkelAnime_Init(globalCtx, &this->skelanime, &gTreasureChestSkel, anim, this->jointTable, this->morphTable, 5);
|
||||
Animation_Change(&this->skelanime, anim, 1.5f, animFrameStart, endFrame, ANIMMODE_ONCE, 0.0f);
|
||||
|
||||
switch (this->type) {
|
||||
case ENBOX_TYPE_SMALL:
|
||||
case ENBOX_TYPE_6:
|
||||
case ENBOX_TYPE_ROOM_CLEAR_SMALL:
|
||||
case ENBOX_TYPE_SWITCH_FLAG_FALL_SMALL:
|
||||
Actor_SetScale(&this->dyna.actor, 0.005f);
|
||||
Actor_SetFocus(&this->dyna.actor, 20.0f);
|
||||
break;
|
||||
default:
|
||||
Actor_SetScale(&this->dyna.actor, 0.01f);
|
||||
Actor_SetFocus(&this->dyna.actor, 40.0f);
|
||||
EnBox_UpdateSizeAndTexture(this, globalCtx);
|
||||
// For SOH we spawn a chest actor instead of rendering the object from scratch for forest boss
|
||||
// key chest, and it's up on the wall so disable gravity for it.
|
||||
if (globalCtx->sceneNum == SCENE_BMORI1 && this->dyna.actor.params == 10222) {
|
||||
this->movementFlags = ENBOX_MOVE_IMMOBILE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,6 +579,8 @@ void EnBox_SpawnIceSmoke(EnBox* this, GlobalContext* globalCtx) {
|
|||
void EnBox_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnBox* this = (EnBox*)thisx;
|
||||
|
||||
EnBox_UpdateSizeAndTexture(this, globalCtx);
|
||||
|
||||
if (this->movementFlags & ENBOX_MOVE_STICK_TO_GROUND) {
|
||||
this->movementFlags &= ~ENBOX_MOVE_STICK_TO_GROUND;
|
||||
EnBox_ClipToGround(this, globalCtx);
|
||||
|
@ -604,6 +610,154 @@ void EnBox_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||
this->iceSmokeTimer < 100) EnBox_SpawnIceSmoke(this, globalCtx);
|
||||
}
|
||||
|
||||
void EnBox_UpdateSizeAndTexture(EnBox* this, GlobalContext* globalCtx) {
|
||||
EnBox_CreateExtraChestTextures();
|
||||
int cvar = CVar_GetS32("gChestSizeAndTextureMatchesContents", 0);
|
||||
GetItemCategory getItemCategory;
|
||||
|
||||
if (globalCtx->sceneNum != SCENE_TAKARAYA && cvar > 0) {
|
||||
GetItemEntry getItemEntry = GET_ITEM_NONE;
|
||||
|
||||
if (gSaveContext.n64ddFlag) {
|
||||
getItemEntry = Randomizer_GetItemFromActorWithoutObtainabilityCheck(this->dyna.actor.id, globalCtx->sceneNum, this->dyna.actor.params, this->dyna.actor.params >> 5 & 0x7F);
|
||||
} else {
|
||||
getItemEntry = ItemTable_RetrieveEntry(MOD_NONE, this->dyna.actor.params >> 5 & 0x7F);
|
||||
}
|
||||
|
||||
getItemCategory = getItemEntry.getItemCategory;
|
||||
// If they don't have bombchu's yet consider the bombchu item major
|
||||
if (getItemEntry.gid == GID_BOMBCHU && INV_CONTENT(ITEM_BOMBCHU) != ITEM_BOMBCHU) {
|
||||
getItemCategory = ITEM_CATEGORY_MAJOR;
|
||||
}
|
||||
}
|
||||
|
||||
if (globalCtx->sceneNum != SCENE_TAKARAYA && (cvar == 1 || cvar == 3)) {
|
||||
switch (getItemCategory) {
|
||||
case ITEM_CATEGORY_JUNK:
|
||||
case ITEM_CATEGORY_SMALL_KEY:
|
||||
case ITEM_CATEGORY_SKULLTULA_TOKEN:
|
||||
Actor_SetScale(&this->dyna.actor, 0.005f);
|
||||
Actor_SetFocus(&this->dyna.actor, 20.0f);
|
||||
break;
|
||||
default:
|
||||
Actor_SetScale(&this->dyna.actor, 0.01f);
|
||||
Actor_SetFocus(&this->dyna.actor, 40.0f);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (this->type) {
|
||||
case ENBOX_TYPE_SMALL:
|
||||
case ENBOX_TYPE_6:
|
||||
case ENBOX_TYPE_ROOM_CLEAR_SMALL:
|
||||
case ENBOX_TYPE_SWITCH_FLAG_FALL_SMALL:
|
||||
Actor_SetScale(&this->dyna.actor, 0.005f);
|
||||
Actor_SetFocus(&this->dyna.actor, 20.0f);
|
||||
break;
|
||||
default:
|
||||
Actor_SetScale(&this->dyna.actor, 0.01f);
|
||||
Actor_SetFocus(&this->dyna.actor, 40.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (globalCtx->sceneNum != SCENE_TAKARAYA && (cvar == 1 || cvar == 2)) {
|
||||
switch (getItemCategory) {
|
||||
case ITEM_CATEGORY_MAJOR:
|
||||
this->boxBodyDL = gGoldTreasureChestChestFrontDL;
|
||||
this->boxLidDL = gGoldTreasureChestChestSideAndLidDL;
|
||||
break;
|
||||
case ITEM_CATEGORY_SKULLTULA_TOKEN:
|
||||
this->boxBodyDL = gSkullTreasureChestChestFrontDL;
|
||||
this->boxLidDL = gSkullTreasureChestChestSideAndLidDL;
|
||||
break;
|
||||
case ITEM_CATEGORY_SMALL_KEY:
|
||||
this->boxBodyDL = gKeyTreasureChestChestFrontDL;
|
||||
this->boxLidDL = gKeyTreasureChestChestSideAndLidDL;
|
||||
break;
|
||||
case ITEM_CATEGORY_BOSS_KEY:
|
||||
this->boxBodyDL = gTreasureChestBossKeyChestFrontDL;
|
||||
this->boxLidDL = gTreasureChestBossKeyChestSideAndTopDL;
|
||||
break;
|
||||
case ITEM_CATEGORY_LESSER:
|
||||
case ITEM_CATEGORY_JUNK:
|
||||
default:
|
||||
this->boxBodyDL = gTreasureChestChestFrontDL;
|
||||
this->boxLidDL = gTreasureChestChestSideAndLidDL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (this->type != ENBOX_TYPE_DECORATED_BIG) {
|
||||
this->boxBodyDL = gTreasureChestChestFrontDL;
|
||||
this->boxLidDL = gTreasureChestChestSideAndLidDL;
|
||||
} else {
|
||||
this->boxBodyDL = gTreasureChestBossKeyChestFrontDL;
|
||||
this->boxLidDL = gTreasureChestBossKeyChestSideAndTopDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnBox_CreateExtraChestTextures() {
|
||||
if (hasCreatedRandoChestTextures) return;
|
||||
Gfx gTreasureChestChestTextures[] = {
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gSkullTreasureChestFrontTex")),
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gSkullTreasureChestSideAndTopTex")),
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gGoldTreasureChestFrontTex")),
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gGoldTreasureChestSideAndTopTex")),
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gKeyTreasureChestFrontTex")),
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gKeyTreasureChestSideAndTopTex")),
|
||||
};
|
||||
|
||||
Gfx* frontCmd = ResourceMgr_LoadGfxByName(gTreasureChestChestFrontDL);
|
||||
int frontIndex = 0;
|
||||
while (frontCmd->words.w0 >> 24 != G_ENDDL) {
|
||||
gSkullTreasureChestChestFrontDL[frontIndex] = *frontCmd;
|
||||
gGoldTreasureChestChestFrontDL[frontIndex] = *frontCmd;
|
||||
gKeyTreasureChestChestFrontDL[frontIndex] = *frontCmd;
|
||||
frontIndex++;
|
||||
++frontCmd;
|
||||
}
|
||||
gSkullTreasureChestChestFrontDL[frontIndex] = *frontCmd;
|
||||
gGoldTreasureChestChestFrontDL[frontIndex] = *frontCmd;
|
||||
gKeyTreasureChestChestFrontDL[frontIndex] = *frontCmd;
|
||||
|
||||
gSkullTreasureChestChestFrontDL[5] = gTreasureChestChestTextures[0];
|
||||
gSkullTreasureChestChestFrontDL[23] = gTreasureChestChestTextures[1];
|
||||
gSkullTreasureChestChestFrontDL[37] = gTreasureChestChestTextures[0];
|
||||
gSkullTreasureChestChestFrontDL[50] = gTreasureChestChestTextures[1];
|
||||
gGoldTreasureChestChestFrontDL[5] = gTreasureChestChestTextures[2];
|
||||
gGoldTreasureChestChestFrontDL[23] = gTreasureChestChestTextures[3];
|
||||
gGoldTreasureChestChestFrontDL[37] = gTreasureChestChestTextures[2];
|
||||
gGoldTreasureChestChestFrontDL[50] = gTreasureChestChestTextures[3];
|
||||
gKeyTreasureChestChestFrontDL[5] = gTreasureChestChestTextures[4];
|
||||
gKeyTreasureChestChestFrontDL[23] = gTreasureChestChestTextures[5];
|
||||
gKeyTreasureChestChestFrontDL[37] = gTreasureChestChestTextures[4];
|
||||
gKeyTreasureChestChestFrontDL[50] = gTreasureChestChestTextures[5];
|
||||
|
||||
Gfx* sideCmd = ResourceMgr_LoadGfxByName(gTreasureChestChestSideAndLidDL);
|
||||
int sideIndex = 0;
|
||||
while (sideCmd->words.w0 >> 24 != G_ENDDL) {
|
||||
gSkullTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd;
|
||||
gGoldTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd;
|
||||
gKeyTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd;
|
||||
sideIndex++;
|
||||
++sideCmd;
|
||||
}
|
||||
gSkullTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd;
|
||||
gGoldTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd;
|
||||
gKeyTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd;
|
||||
|
||||
gSkullTreasureChestChestSideAndLidDL[5] = gTreasureChestChestTextures[0];
|
||||
gSkullTreasureChestChestSideAndLidDL[29] = gTreasureChestChestTextures[1];
|
||||
gSkullTreasureChestChestSideAndLidDL[45] = gTreasureChestChestTextures[0];
|
||||
gGoldTreasureChestChestSideAndLidDL[5] = gTreasureChestChestTextures[2];
|
||||
gGoldTreasureChestChestSideAndLidDL[29] = gTreasureChestChestTextures[3];
|
||||
gGoldTreasureChestChestSideAndLidDL[45] = gTreasureChestChestTextures[2];
|
||||
gKeyTreasureChestChestSideAndLidDL[5] = gTreasureChestChestTextures[4];
|
||||
gKeyTreasureChestChestSideAndLidDL[29] = gTreasureChestChestTextures[5];
|
||||
gKeyTreasureChestChestSideAndLidDL[45] = gTreasureChestChestTextures[4];
|
||||
|
||||
hasCreatedRandoChestTextures = 1;
|
||||
}
|
||||
|
||||
void EnBox_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx, Gfx** gfx) {
|
||||
EnBox* this = (EnBox*)thisx;
|
||||
s32 pad;
|
||||
|
@ -611,19 +765,11 @@ void EnBox_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve
|
|||
if (limbIndex == 1) {
|
||||
gSPMatrix((*gfx)++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
if (this->type != ENBOX_TYPE_DECORATED_BIG) {
|
||||
gSPDisplayList((*gfx)++, gTreasureChestChestFrontDL);
|
||||
} else {
|
||||
gSPDisplayList((*gfx)++, gTreasureChestBossKeyChestFrontDL);
|
||||
}
|
||||
gSPDisplayList((*gfx)++, this->boxBodyDL);
|
||||
} else if (limbIndex == 3) {
|
||||
gSPMatrix((*gfx)++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
if (this->type != ENBOX_TYPE_DECORATED_BIG) {
|
||||
gSPDisplayList((*gfx)++, gTreasureChestChestSideAndLidDL);
|
||||
} else {
|
||||
gSPDisplayList((*gfx)++, gTreasureChestBossKeyChestSideAndTopDL);
|
||||
}
|
||||
gSPDisplayList((*gfx)++, this->boxLidDL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ typedef struct EnBox {
|
|||
/* 0x01F9 */ u8 type;
|
||||
/* 0x01FA */ u8 iceSmokeTimer;
|
||||
/* 0x01FB */ u8 unk_1FB;
|
||||
/* */ Gfx* boxLidDL;
|
||||
/* */ Gfx* boxBodyDL;
|
||||
} EnBox; // size = 0x01FC
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue