Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CrossPlatformUI/Lang/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,9 @@ There can only be as many duplicates as there are minor items to replace.
What is duplicated, in order (and if they are in the pool) is:
Glove, Downstab, Fairy, Thunder, Reflect, Magic key, Hammer, Raft, Flute, Jump, Upstab,
Boots</value>
</data>
<data name="PreventSpellItemChainsToolTip" xml:space="preserve">
<value>When checked, a spell item can never be required to obtain another town item.</value>
</data>
<data name="ShuffleAllExperienceToolTip" xml:space="preserve">
<value>Shuffles the experience required to gain each level of the selected attribute. The new EXP
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/BeginnerPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public static class BeginnerPreset
PalacesContainExtraKeys = true,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/FullShufflePreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public static class FullShufflePreset
PalacesContainExtraKeys = false,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/MaxRando2025Preset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public static class MaxRando2025Preset
PalacesContainExtraKeys = false,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/MaxRandoPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ public static class MaxRandoPreset
PalacesContainExtraKeys = false,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/NormalPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ public static class NormalPreset
PalacesContainExtraKeys = false,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/RandomPercentPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public static class RandomPercentPreset
PalacesContainExtraKeys = null,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/Sgl2025Preset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public static class Sgl2025Preset
PalacesContainExtraKeys = false,
RandomizeNewKasutoJarRequirements = false,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = false,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/StandardPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public static class StandardPreset
PalacesContainExtraKeys = false,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/StandardSwissPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public static class StandardSwissPreset
PalacesContainExtraKeys = false,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
1 change: 1 addition & 0 deletions CrossPlatformUI/Presets/UpstartsTournamentPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public static class UpstartsTournamentPreset
PalacesContainExtraKeys = false,
RandomizeNewKasutoJarRequirements = true,
AllowImportantItemDuplicates = false,
PreventSpellItemChains = false,

//Drops
ShuffleItemDropFrequency = true,
Expand Down
6 changes: 6 additions & 0 deletions CrossPlatformUI/Views/Tabs/ItemsView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@
>
<ToolTip.Tip><TextBlock Text="{x:Static lang:Resources.IncludeTownQuestItemsinShuffleToolTip}"/></ToolTip.Tip>
</CheckBox>
<CheckBox
IsChecked="{Binding Main.Config.PreventSpellItemChains}"
Content="Prevent Spell Item Chains"
>
<ToolTip.Tip><TextBlock Text="{x:Static lang:Resources.PreventSpellItemChainsToolTip}"/></ToolTip.Tip>
</CheckBox>
</StackPanel>
<StackPanel Grid.Column="1">
<CheckBox
Expand Down
13 changes: 13 additions & 0 deletions RandomizerCore/Collectable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,19 @@ public static bool IsQuestItem(this Collectable collectable)
};
}

public static bool IsSpellItem(this Collectable collectable)
{
return collectable switch
{
Collectable.TROPHY => true,
Collectable.MIRROR => true,
Collectable.MEDICINE => true,
Collectable.WATER => true,
Collectable.CHILD => true,
_ => false
};
}

public static bool IsSwordTech(this Collectable collectable)
{
return collectable switch
Expand Down
45 changes: 45 additions & 0 deletions RandomizerCore/Hyrule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,51 @@ private void ShuffleItems()
}
}
}

if (props.PreventSpellItemChains)
{
PreventSpellItemChains();
}
}

// Disallow old men from holding other spell items, preventing long
// item chains
private void PreventSpellItemChains()
{
List<Town> chainTowns = [Town.RUTO, Town.SARIA_NORTH, Town.MIDO_WEST,
Town.NABOORU, Town.DARUNIA_WEST];

bool IsChainLocation(Location l) =>
l.ActualTown != null && chainTowns.Contains((Town)l.ActualTown);

List<Location> chainLocations = itemLocs.Where(IsChainLocation).ToList();
foreach (Location chainLocation in chainLocations)
{
for (int i = 0; i < chainLocation.Collectables.Count; i++)
{
if (!chainLocation.Collectables[i].IsSpellItem())
{
continue;
}

// Town wizard locations are always single-collectable overworld
// locations, so restrict swap targets to other non-chain overworld
// locations to avoid desyncing palace item room bookkeeping.
Location? target = itemLocs
.Where(l => l.PalaceNumber == null && !IsChainLocation(l))
.Where(l => l.Collectables.Any(c => !c.IsSpellItem()))
.ToList()
.Sample(r);
if (target == null)
{
continue;
}

int targetIndex = target.Collectables.FindIndex(c => !c.IsSpellItem());
(chainLocation.Collectables[i], target.Collectables[targetIndex]) =
(target.Collectables[targetIndex], chainLocation.Collectables[i]);
}
}
}

private void DoShuffle(List<Collectable> itemsToShuffle, List<Location> itemShuffleLocations)
Expand Down
4 changes: 4 additions & 0 deletions RandomizerCore/RandomizerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,9 @@ private bool palaceStylesAnyMetastyleSelected()
[Reactive]
private bool? includeQuestItemsInShuffle;

[Reactive]
private bool preventSpellItemChains;

//Drops
[Reactive]
private bool shuffleItemDropFrequency;
Expand Down Expand Up @@ -1367,6 +1370,7 @@ public RandomizerProperties Export(Random r, bool includeDifficulty = true)
properties.StartWithSpellItems = removeSpellItems ?? GetIndeterminateFlagValue(r);
properties.ShufflePbagXp = shufflePBagAmounts ?? GetIndeterminateFlagValue(r);
properties.IncludeQuestItemsInShuffle = includeQuestItemsInShuffle ?? GetIndeterminateFlagValue(r);
properties.PreventSpellItemChains = preventSpellItemChains;
properties.IncludeSpellsInShuffle = includeSpellsInShuffle ?? GetIndeterminateFlagValue(r);
properties.IncludeSwordTechsInShuffle = includeSwordTechsInShuffle ?? GetIndeterminateFlagValue(r);

Expand Down
2 changes: 2 additions & 0 deletions RandomizerCore/RandomizerProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ public class RandomizerProperties
public bool IncludeSwordTechsInShuffle { get; set; }
//Bagu's note / fountain water / saria mirror
public bool IncludeQuestItemsInShuffle { get; set; }
//Spell items may not be required to obtain another spell item
public bool PreventSpellItemChains { get; set; }
public bool RandomizeSmallItems { get; set; }
public bool ExtraKeys { get; set; }
public bool AllowImportantItemDuplicates { get; set; }
Expand Down
Loading