mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-18 06:12:20 -05:00
VBify pots progress
This commit is contained in:
parent
ba447276df
commit
d5ba83a814
@ -242,6 +242,9 @@ typedef enum {
|
||||
```
|
||||
*/
|
||||
VB_DRAW_AMMO_COUNT,
|
||||
// Opt: *ObjTsubo
|
||||
VB_POT_DRAW,
|
||||
VB_POT_DROP_ITEM,
|
||||
|
||||
/*** Play Cutscenes ***/
|
||||
|
||||
|
@ -64,6 +64,9 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void));
|
||||
//Mark: - Pause Menu
|
||||
void GameInteractor_ExecuteOnKaleidoUpdate();
|
||||
|
||||
//Mark - Randomizer options spawning EnItem00 actors
|
||||
void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "soh/Enhancements/TimeSavers/TimeSavers.h"
|
||||
#include "soh/Enhancements/cheat_hook_handlers.h"
|
||||
#include "soh/Enhancements/randomizer/hook_handlers.h"
|
||||
#include "soh/Enhancements/randomizer/ShufflePots.h"
|
||||
#include "objects/object_gi_compass/object_gi_compass.h"
|
||||
|
||||
#include "src/overlays/actors/ovl_En_Bb/z_en_bb.h"
|
||||
@ -1822,4 +1823,5 @@ void InitMods() {
|
||||
RegisterHurtContainerModeHandler();
|
||||
RegisterPauseMenuHooks();
|
||||
RegisterSkeletonKey();
|
||||
RegisterShufflePots();
|
||||
}
|
||||
|
126
soh/soh/Enhancements/randomizer/ShufflePots.cpp
Normal file
126
soh/soh/Enhancements/randomizer/ShufflePots.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "ShufflePots.h"
|
||||
#include "soh_assets.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h"
|
||||
#include "variables.h"
|
||||
|
||||
u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
|
||||
GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
|
||||
PotIdentity Randomizer_IdentifyPot(s32 sceneNum, s32 posX, s32 posZ);
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ObjTsubo_RandomizerDraw(Actor* thisx, PlayState* play) {
|
||||
float potSize = 1.0f;
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
Matrix_Scale(potSize, potSize, potSize, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gRandoPotDL);
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) {
|
||||
uint8_t isDungeon =
|
||||
play->sceneNum < SCENE_GANONS_TOWER_COLLAPSE_INTERIOR ||
|
||||
(play->sceneNum > SCENE_TREASURE_BOX_SHOP && play->sceneNum < SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR);
|
||||
uint8_t potSetting = Randomizer_GetSettingValue(RSK_SHUFFLE_POTS);
|
||||
|
||||
// Don't pull randomized item if pot isn't randomized or is already checked
|
||||
if (!IS_RANDO || (potSetting == RO_SHUFFLE_POTS_OVERWORLD && isDungeon) ||
|
||||
(potSetting == RO_SHUFFLE_POTS_DUNGEONS && !isDungeon) ||
|
||||
Flags_GetRandomizerInf(potActor->potIdentity.randomizerInf) ||
|
||||
potActor->potIdentity.randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ObjTsubo_RandomizerSkipItemCutscene(ObjTsubo* potActor) {
|
||||
/*return
|
||||
potActor->actor.params == ITEM00_SMALL_KEY && giEntry.modIndex == MOD_NONE &&
|
||||
((giEntry.itemId >= ITEM_RUPEE_GREEN && giEntry.itemId <= ITEM_RUPEE_RED) || giEntry.itemId == ITEM_HEART ||
|
||||
(giEntry.itemId >= ITEM_NUTS_5 && giEntry.itemId <= ITEM_SEEDS_30) || giEntry.itemId == ITEM_MAGIC_SMALL ||
|
||||
giEntry.itemId == ITEM_MAGIC_LARGE);*/
|
||||
}
|
||||
|
||||
void ObjTsubo_RandomizerSpawnCollectible(ObjTsubo* potActor) {
|
||||
EnItem00* item00 =
|
||||
(EnItem00*)Item_DropCollectible2(gPlayState, &potActor->actor.world.pos, ITEM00_SOH_GIVE_ITEM_ENTRY);
|
||||
item00->randoInf = potActor->potIdentity.randomizerInf;
|
||||
item00->itemEntry =
|
||||
OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(potActor->potIdentity.randomizerCheck, GI_NONE);
|
||||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
item00->actor.gravity = -0.9f;
|
||||
item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f);
|
||||
}
|
||||
|
||||
void ObjTsubo_RandomizerInit(void* actorRef) {
|
||||
Actor* actor = static_cast<Actor*>(actorRef);
|
||||
|
||||
if (actor->id != ACTOR_OBJ_TSUBO) return;
|
||||
|
||||
ObjTsubo* potActor = static_cast<ObjTsubo*>(actorRef);
|
||||
|
||||
potActor->potIdentity =
|
||||
Randomizer_IdentifyPot(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z);
|
||||
|
||||
if (ObjTsubo_RandomizerHoldsItem(potActor, gPlayState)) {
|
||||
potActor->potIdentity.isShuffled = true;
|
||||
} else {
|
||||
potActor->potIdentity.isShuffled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void PotOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* optionalArg) {
|
||||
ObjTsubo* potActor = static_cast<ObjTsubo*>(optionalArg);
|
||||
|
||||
switch (id) {
|
||||
case VB_POT_DRAW: {
|
||||
if (potActor->potIdentity.isShuffled) {
|
||||
*should = false;
|
||||
potActor->actor.draw = (ActorFunc)ObjTsubo_RandomizerDraw;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VB_POT_DROP_ITEM: {
|
||||
if (potActor->potIdentity.isShuffled) {
|
||||
*should = false;
|
||||
ObjTsubo_RandomizerSpawnCollectible(potActor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterShufflePots() {
|
||||
static uint32_t onActorInitHook = 0;
|
||||
static uint32_t onVanillaBehaviorHook = 0;
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) {
|
||||
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(onActorInitHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(onVanillaBehaviorHook);
|
||||
|
||||
onActorInitHook = 0;
|
||||
onVanillaBehaviorHook = 0;
|
||||
|
||||
if (!IS_RANDO) return;
|
||||
if (!Randomizer_GetSettingValue(RSK_SHUFFLE_POTS)) return;
|
||||
|
||||
onActorInitHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>(ObjTsubo_RandomizerInit);
|
||||
onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(PotOnVanillaBehaviorHandler);
|
||||
|
||||
});
|
||||
}
|
15
soh/soh/Enhancements/randomizer/ShufflePots.h
Normal file
15
soh/soh/Enhancements/randomizer/ShufflePots.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef SHUFFLEPOTS_H
|
||||
#define SHUFFLEPOTS_H
|
||||
|
||||
#include "z64.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void ObjTsubo_RandomizerDraw(Actor* potActor, PlayState* play);
|
||||
void RegisterShufflePots();
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif //SHUFFLEPOTS_H
|
@ -4899,6 +4899,7 @@ typedef struct CowIdentity {
|
||||
typedef struct PotIdentity {
|
||||
RandomizerInf randomizerInf;
|
||||
RandomizerCheck randomizerCheck;
|
||||
uint8_t isShuffled;
|
||||
} PotIdentity;
|
||||
|
||||
typedef struct FishIdentity {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
|
||||
#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
|
||||
#include "objects/object_tsubo/object_tsubo.h"
|
||||
#include "soh_assets.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_ALWAYS_THROWN)
|
||||
|
||||
@ -84,43 +84,11 @@ static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
s8 ObjTsubo_HoldsRandomizedItem(ObjTsubo* this, PlayState* play) {
|
||||
uint8_t isDungeon = play->sceneNum < SCENE_GANONS_TOWER_COLLAPSE_INTERIOR ||
|
||||
(play->sceneNum > SCENE_TREASURE_BOX_SHOP && play->sceneNum < SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR);
|
||||
uint8_t potSetting = Randomizer_GetSettingValue(RSK_SHUFFLE_POTS);
|
||||
|
||||
// Don't pull randomized item if pot isn't randomized or is already checked
|
||||
if (!IS_RANDO || !potSetting ||
|
||||
(potSetting == RO_SHUFFLE_POTS_OVERWORLD && isDungeon) ||
|
||||
(potSetting == RO_SHUFFLE_POTS_DUNGEONS && !isDungeon) ||
|
||||
Flags_GetRandomizerInf(this->potIdentity.randomizerInf) ||
|
||||
this->potIdentity.randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjTsubo_SpawnCollectible(ObjTsubo* this, PlayState* play) {
|
||||
|
||||
if (IS_RANDO && ObjTsubo_HoldsRandomizedItem(this, play)) {
|
||||
GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(this->potIdentity.randomizerCheck, GI_NONE);
|
||||
|
||||
EnItem00* actor = (EnItem00*)Item_DropCollectible2(play, &this->actor.world.pos, ITEM00_SMALL_KEY);
|
||||
actor->randoCheck = this->potIdentity.randomizerCheck;
|
||||
actor->randoGiEntry = getItemEntry;
|
||||
actor->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING;
|
||||
actor->randoInf = this->potIdentity.randomizerInf;
|
||||
actor->actor.velocity.y = 8.0f;
|
||||
actor->actor.speedXZ = 2.0f;
|
||||
actor->actor.gravity = -0.9f;
|
||||
actor->actor.world.rot.y = Rand_CenteredFloat(65536.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
s16 dropParams = this->actor.params & 0x1F;
|
||||
|
||||
if ((dropParams >= ITEM00_RUPEE_GREEN) && (dropParams <= ITEM00_BOMBS_SPECIAL)) {
|
||||
if ((dropParams >= ITEM00_RUPEE_GREEN) && (dropParams <= ITEM00_BOMBS_SPECIAL) &&
|
||||
GameInteractor_Should(VB_POT_DROP_ITEM, true, this)) {
|
||||
Item_DropCollectible(play, &this->actor.world.pos,
|
||||
(dropParams | (((this->actor.params >> 9) & 0x3F) << 8)));
|
||||
}
|
||||
@ -179,9 +147,6 @@ void ObjTsubo_Init(Actor* thisx, PlayState* play) {
|
||||
ObjTsubo_SetupWaitForObject(this);
|
||||
osSyncPrintf("(dungeon keep 壷)(arg_data 0x%04x)\n", this->actor.params);
|
||||
}
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_POTS)) {
|
||||
this->potIdentity = Randomizer_IdentifyPot(play->sceneNum, (s16)this->actor.world.pos.x, (s16)this->actor.world.pos.z);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjTsubo_Destroy(Actor* thisx, PlayState* play2) {
|
||||
@ -268,7 +233,9 @@ void ObjTsubo_SetupWaitForObject(ObjTsubo* this) {
|
||||
|
||||
void ObjTsubo_WaitForObject(ObjTsubo* this, PlayState* play) {
|
||||
if (Object_IsLoaded(&play->objectCtx, this->objTsuboBankIndex)) {
|
||||
if (GameInteractor_Should(VB_POT_DRAW, true, this)) {
|
||||
this->actor.draw = ObjTsubo_Draw;
|
||||
}
|
||||
this->actor.objBankIndex = this->objTsuboBankIndex;
|
||||
ObjTsubo_SetupIdle(this);
|
||||
this->actor.flags &= ~ACTOR_FLAG_UPDATE_WHILE_CULLED;
|
||||
@ -381,18 +348,5 @@ void ObjTsubo_Update(Actor* thisx, PlayState* play) {
|
||||
void ObjTsubo_Draw(Actor* thisx, PlayState* play) {
|
||||
ObjTsubo* this = (ObjTsubo*)thisx;
|
||||
|
||||
if (IS_RANDO && ObjTsubo_HoldsRandomizedItem(this, play)) {
|
||||
float potSize = 1.0f;
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
Matrix_Scale(potSize, potSize, potSize, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gRandoPotDL);
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
} else {
|
||||
Gfx_DrawDListOpa(play, D_80BA1B84[(thisx->params >> 8) & 1]);
|
||||
}
|
||||
}
|
||||
|
@ -6821,16 +6821,8 @@ s32 Player_ActionChange_2(Player* this, PlayState* play) {
|
||||
// this specifically for items coming from bushes/rocks/enemies when the player has already picked that item up.
|
||||
uint8_t skipItemCutsceneRando = IS_RANDO && Item_CheckObtainability(giEntry.itemId) != ITEM_NONE && isDropToSkip;
|
||||
|
||||
// Automatically skip the pickup messages for very frequent items coming from pots with "Shuffle Pots" on.
|
||||
uint8_t isPotItemToSkip = interactedActor->id == ACTOR_EN_ITEM00 &&
|
||||
interactedActor->params == ITEM00_SMALL_KEY && giEntry.modIndex == MOD_NONE &&
|
||||
((giEntry.itemId >= ITEM_RUPEE_GREEN && giEntry.itemId <= ITEM_RUPEE_RED) ||
|
||||
giEntry.itemId == ITEM_HEART ||
|
||||
(giEntry.itemId >= ITEM_NUTS_5 && giEntry.itemId <= ITEM_SEEDS_30) ||
|
||||
giEntry.itemId == ITEM_MAGIC_SMALL || giEntry.itemId == ITEM_MAGIC_LARGE);
|
||||
|
||||
// Show cutscene when picking up a item.
|
||||
if (showItemCutscene && !skipItemCutscene && !skipItemCutsceneRando && !isPotItemToSkip) {
|
||||
if (showItemCutscene && !skipItemCutscene && !skipItemCutsceneRando) {
|
||||
|
||||
Player_DetachHeldActor(play, this);
|
||||
func_8083AE40(this, giEntry.objectId);
|
||||
|
Loading…
Reference in New Issue
Block a user