-
Notifications
You must be signed in to change notification settings - Fork 776
Feature/split songs #6627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Feature/split songs #6627
Changes from 17 commits
9397b10
5feddec
2bd2ea4
5417774
3d0a0f6
0386051
6d49e4d
042e035
6a10537
bc2027e
72c849f
bd13ce5
11a4287
f8464be
10f462d
2340e5a
3e1aff7
2998034
600b8d3
39427cc
b78aac9
79b6882
1198703
7d146a6
2edee8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| #include "random.hpp" | ||
| #include "spoiler_log.hpp" | ||
| #include "soh/Enhancements/randomizer/Traps.h" | ||
| #include "soh/Enhancements/randomizer/split_songs.h" | ||
| #include "z64item.h" | ||
| #include <spdlog/spdlog.h> | ||
|
|
||
|
|
@@ -156,6 +157,15 @@ void GenerateItemPool() { | |
| lesserPool.clear(); | ||
| int reservedSlots = 0; | ||
|
|
||
| if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE)) { | ||
| const bool split = static_cast<bool>(ctx->GetOption(RSK_SPLIT_OCARINA_SONGS)); | ||
| std::vector<RandomizerGet> songTrapModels; | ||
| Rando::SplitSongs::AppendSongIceTrapModels(songTrapModels, split); | ||
| for (RandomizerGet rg : songTrapModels) { | ||
| ctx->possibleIceTrapModels.insert(rg); | ||
| } | ||
| } | ||
|
|
||
| // clang-format off | ||
| AddItemToPool(RG_BOOMERANG, 2, 1, 1, 1); | ||
| AddItemToPool(RG_LENS_OF_TRUTH, 2, 1, 1, 1); | ||
|
|
@@ -252,42 +262,38 @@ void GenerateItemPool() { | |
| // add extra songs only if song shuffle is anywhere | ||
| if (ctx->GetOption(RSK_SHUFFLE_SONGS).IsNot(RO_SONG_SHUFFLE_OFF)) { | ||
| bool songAnywhere = ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE); | ||
| if (!ctx->GetOption(RSK_STARTING_ZELDAS_LULLABY).Get()) { | ||
| AddItemToPool(RG_ZELDAS_LULLABY, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_EPONAS_SONG).Get()) { | ||
| AddItemToPool(RG_EPONAS_SONG, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_SARIAS_SONG).Get()) { | ||
| AddItemToPool(RG_SARIAS_SONG, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_SUNS_SONG).Get()) { | ||
| AddItemToPool(RG_SUNS_SONG, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_SONG_OF_TIME).Get()) { | ||
| AddItemToPool(RG_SONG_OF_TIME, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_SONG_OF_STORMS).Get()) { | ||
| AddItemToPool(RG_SONG_OF_STORMS, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_MINUET_OF_FOREST).Get()) { | ||
| AddItemToPool(RG_MINUET_OF_FOREST, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_BOLERO_OF_FIRE).Get()) { | ||
| AddItemToPool(RG_BOLERO_OF_FIRE, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_SERENADE_OF_WATER).Get()) { | ||
| AddItemToPool(RG_SERENADE_OF_WATER, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_REQUIEM_OF_SPIRIT).Get()) { | ||
| AddItemToPool(RG_REQUIEM_OF_SPIRIT, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_NOCTURNE_OF_SHADOW).Get()) { | ||
| AddItemToPool(RG_NOCTURNE_OF_SHADOW, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| if (!ctx->GetOption(RSK_STARTING_PRELUDE_OF_LIGHT).Get()) { | ||
| AddItemToPool(RG_PRELUDE_OF_LIGHT, songAnywhere ? 2 : 1, 1, 1, 1, songAnywhere); | ||
| } | ||
| const bool split = ctx->GetOption(RSK_SPLIT_OCARINA_SONGS) && songAnywhere; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having songs anywhere silently disable split songs here is not good practice for handling settings incompatibilities, instead check for and set 1 setting or the other in Context::FinalizeSettings and then trust it has been handled properly here. This makes the setting easier to edit later. |
||
| const int defaultPlentiful = songAnywhere ? 2 : 1; | ||
| auto addShuffledSong = [&](RandomizerGet fullSong, RandomizerGet progressive, bool hasStarting) { | ||
| if (hasStarting) { | ||
| return; | ||
| } | ||
| if (!split) { | ||
| AddItemToPool(fullSong, defaultPlentiful, 1, 1, 1, songAnywhere); | ||
| } else { | ||
| AddItemToPool(progressive, 3, 2, 2, 2, songAnywhere); | ||
| } | ||
| }; | ||
| addShuffledSong(RG_ZELDAS_LULLABY, RG_PROGRESSIVE_ZELDAS_LULLABY, | ||
| ctx->GetOption(RSK_STARTING_ZELDAS_LULLABY).Get()); | ||
| addShuffledSong(RG_EPONAS_SONG, RG_PROGRESSIVE_EPONAS_SONG, ctx->GetOption(RSK_STARTING_EPONAS_SONG).Get()); | ||
| addShuffledSong(RG_SARIAS_SONG, RG_PROGRESSIVE_SARIAS_SONG, ctx->GetOption(RSK_STARTING_SARIAS_SONG).Get()); | ||
| addShuffledSong(RG_SUNS_SONG, RG_PROGRESSIVE_SUNS_SONG, ctx->GetOption(RSK_STARTING_SUNS_SONG).Get()); | ||
| addShuffledSong(RG_SONG_OF_TIME, RG_PROGRESSIVE_SONG_OF_TIME, ctx->GetOption(RSK_STARTING_SONG_OF_TIME).Get()); | ||
| addShuffledSong(RG_SONG_OF_STORMS, RG_PROGRESSIVE_SONG_OF_STORMS, | ||
| ctx->GetOption(RSK_STARTING_SONG_OF_STORMS).Get()); | ||
| addShuffledSong(RG_MINUET_OF_FOREST, RG_PROGRESSIVE_MINUET_OF_FOREST, | ||
| ctx->GetOption(RSK_STARTING_MINUET_OF_FOREST).Get()); | ||
| addShuffledSong(RG_BOLERO_OF_FIRE, RG_PROGRESSIVE_BOLERO_OF_FIRE, | ||
| ctx->GetOption(RSK_STARTING_BOLERO_OF_FIRE).Get()); | ||
| addShuffledSong(RG_SERENADE_OF_WATER, RG_PROGRESSIVE_SERENADE_OF_WATER, | ||
| ctx->GetOption(RSK_STARTING_SERENADE_OF_WATER).Get()); | ||
| addShuffledSong(RG_REQUIEM_OF_SPIRIT, RG_PROGRESSIVE_REQUIEM_OF_SPIRIT, | ||
| ctx->GetOption(RSK_STARTING_REQUIEM_OF_SPIRIT).Get()); | ||
| addShuffledSong(RG_NOCTURNE_OF_SHADOW, RG_PROGRESSIVE_NOCTURNE_OF_SHADOW, | ||
| ctx->GetOption(RSK_STARTING_NOCTURNE_OF_SHADOW).Get()); | ||
| addShuffledSong(RG_PRELUDE_OF_LIGHT, RG_PROGRESSIVE_PRELUDE_OF_LIGHT, | ||
| ctx->GetOption(RSK_STARTING_PRELUDE_OF_LIGHT).Get()); | ||
| } else { | ||
| ctx->PlaceItemInLocation(RC_SHEIK_IN_FOREST, RG_MINUET_OF_FOREST, false, true); | ||
| ctx->PlaceItemInLocation(RC_SHEIK_IN_CRATER, RG_BOLERO_OF_FIRE, false, true); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations, | |
| Random_Init(seed); | ||
|
|
||
| auto ctx = Rando::Context::GetInstance(); | ||
| ctx->SetSeedGenerated(false); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain why you added these?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you again for your help and patience with me (first timer — I kept messaging Cal). Every time I ran a new seed or generated one, SoH was crashing because other things (item tracker, spoiler lookups) could read placement data while Fill() was still mid-reset — like a “seed ready” race. I SetSeedGenerated(false) at the top of Playthrough_Init and only flip to true after SpoilerLog_Write() finishes, so nothing treats the seed as valid until the spoiler JSON is fully written. Before that, things were trying to use spoiler data that wasn’t ready yet and it’d just crash on generate. If there’s a better way I’ll relook and sort. This showed up most with split songs because the tracker hits song progress during seed generation, but the flag lifecycle fix is general — it just enforces generate → write → consume order.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rebuilt and tested split songs still works (first pickup = part / 1/2 on tracker, second = full song). |
||
| ctx->overrides.clear(); | ||
| ctx->ItemReset(); | ||
| ctx->HintReset(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AddItemToPool already adds items to possibleIceTrapModels if they are in the item pool, you should not need to add them manually.
You will however need to add trick names for the Progressive Songs in shop.cpp