diff --git a/soh/soh/Enhancements/Holiday/Fredomato.cpp b/soh/soh/Enhancements/Holiday/Fredomato.cpp index b4fd6d4e0c6..29fc71c3b7e 100644 --- a/soh/soh/Enhancements/Holiday/Fredomato.cpp +++ b/soh/soh/Enhancements/Holiday/Fredomato.cpp @@ -25,9 +25,12 @@ extern "C" { #include "functions.h" #include "variables.h" + + extern PlayState* gPlayState; void DoorAna_SetupAction(DoorAna* doorAna, DoorAnaActionFunc actionFunc); void DoorAna_GrabPlayer(DoorAna* doorAna, PlayState* play); + #include "overlays/actors/ovl_Bg_Mjin/z_bg_mjin.h" s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId); } @@ -419,6 +422,32 @@ float treeMoveSpeed = 6.0f; uint32_t corralledTrees = 0; std::vector> treeSlots; +std::vector> CreatePadGrid38(const Vec3f& center) { + std::vector> positions; + positions.reserve(38); + + const int cols = 6; + const int rows = 7; + const float spacing = 80.0f; // adjust as needed + + // Offset so grid is centered on the pad + const float startX = center.x - ((cols - 1) * spacing * 0.5f); + const float startZ = center.z - ((rows - 1) * spacing * 0.5f); + + for (int r = 0; r < rows && positions.size() < 38; ++r) { + for (int c = 0; c < cols && positions.size() < 38; ++c) { + Vec3f pos; + pos.x = startX + (c * spacing); + pos.y = center.y; + pos.z = startZ + (r * spacing); + + positions.push_back({ NULL, pos }); + } + } + + return positions; +} + void MoveTreeActors(void* treeActor) { Actor* tree = (Actor*)treeActor; CollisionPoly* outPoly; @@ -511,22 +540,42 @@ void MoveTreeActors(void* treeActor) { } static void OnConfigurationChanged() { - + // New Fred Ketchmas COND_ID_HOOK(OnActorUpdate, ACTOR_EN_WOOD02, CVarGetInteger(CVAR("FredTest.Enabled"), 0), [](void* actorRef) { - MoveTreeActors(actorRef); - - Actor* warpActor = Actor_FindNearby(gPlayState, (Actor*)actorRef, ACTOR_BG_MJIN, ACTORCAT_BG, 45.0f); - if (warpActor != NULL) { - Actor_Kill((Actor*)actorRef); - corralledTrees++; - Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Actor* treeActor = (Actor*)actorRef; + bool treeSlotted = false; + for (auto& tree : treeSlots) { + if (tree.first == treeActor) { + treeSlotted = true; + treeActor->world.pos.x = tree.second.x; + treeActor->world.pos.y = tree.second.y; + treeActor->world.pos.z = tree.second.z; + break; + } } - - }); + if (!treeSlotted) { + MoveTreeActors(actorRef); + + Actor* warpActor = Actor_FindNearby(gPlayState, (Actor*)actorRef, ACTOR_BG_MJIN, ACTORCAT_BG, 45.0f); + if (warpActor != NULL) { + corralledTrees++; + + for (auto& slot : treeSlots) { + if (slot.first == NULL) { + slot.first = (Actor*)actorRef; + break; + } + } + + Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + } + }); COND_HOOK(OnSceneSpawnActors, CVarGetInteger(CVAR("FredTest.Enabled"), 0), []() { if (gPlayState->sceneNum == SCENE_HYRULE_FIELD) { + treeSlots = CreatePadGrid38({ 335.571f, -0.0f, 2677.854f }); corralledTrees = 0; Object_Spawn(&gPlayState->objectCtx, OBJECT_MJIN); Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_BG_MJIN, 335.571f, -0.0f, 2677.854f, 0, 0, 0, 1, @@ -534,7 +583,7 @@ static void OnConfigurationChanged() { } }); - COND_HOOK(OnSceneSpawnActors, CVarGetInteger(CVAR("FredsQuest.Enabled"), 0), OnSceneInit); + //COND_HOOK(OnSceneSpawnActors, CVarGetInteger(CVAR("FredsQuest.Enabled"), 0), OnSceneInit); COND_HOOK(OnPlayerUpdate, CVarGetInteger(CVAR("RandomTraps.Enabled"), 0), []() { if (rand() % CVarGetInteger(CVAR("RandomTraps.SpawnChance"), 400) == 0) { @@ -556,8 +605,6 @@ static void OnConfigurationChanged() { *should = false; } }); - - } static void RegisterMenu() { @@ -572,8 +619,7 @@ static void RegisterMenu() { SohGui::mSohMenu->AddWidget(path, "FredTest", WIDGET_CVAR_CHECKBOX) .CVar(CVAR("FredTest.Enabled")) .Callback([](WidgetInfo& info) { OnConfigurationChanged(); }) - .Options(UIWidgets::CheckboxOptions().Tooltip( - "Aaaaaaaaah!")); + .Options(UIWidgets::CheckboxOptions().Tooltip("Aaaaaaaaah!")); SohGui::mSohMenu->AddWidget(path, "Trap Lifetime (Seconds)", WIDGET_CVAR_SLIDER_INT) .CVar(CVAR("RandomTraps.Lifetime")) diff --git a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp index 8754579c6f3..c5cecdc3093 100644 --- a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp +++ b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp @@ -144,6 +144,7 @@ static void TimeDisplayGetTimer(uint32_t timeID) { break; case DISPLAY_TREE_CORRAL: timeDisplayTime = std::to_string(corralledTrees); + textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_STICK"); break; default: break; diff --git a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h index 9b150a21d33..d979bad362f 100644 --- a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h +++ b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h @@ -19,7 +19,7 @@ typedef enum TimerDisplay { DISPLAY_CONDITIONAL_TIMER, DISPLAY_NAVI_TIMER, DISPLAY_FRED_QUEST, - DISPLAY_TREE_CORRAL + DISPLAY_TREE_CORRAL, } TimerDisplay; typedef enum NaviTimerValues {