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
4 changes: 2 additions & 2 deletions CommandLine/Sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"Global5050JarDrop": false,
"ReduceDripperVariance": false,
"GoodBoots": true,
"GPLength": "SHORT",
"GPStyle": "RECONSTRUCTED",
"HardBosses": false,
"PalaceItemRoomCount": "ONE",
Expand Down Expand Up @@ -75,6 +76,7 @@
"MixOverworldAndPalaceItems": true,
"NoDuplicateRoomsByEnemies": false,
"NoDuplicateRoomsByLayout": true,
"NormalPalaceLength": "FULL",
"NormalPalaceStyle": "RECONSTRUCTED",
"PalacesCanSwapContinents": false,
"PalacesContainExtraKeys": true,
Expand All @@ -97,8 +99,6 @@
"ScaleLevelRequirementsToCap": false,
"Seed": "821476660",
"ShieldTunic": "Default",
"ShortenGP": true,
"ShortenNormalPalaces": false,
"ShuffleAttackExperience": false,
"ShuffleDripperEnemy": false,
"ShuffleEncounters": false,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/BeginnerPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ public static class BeginnerPreset
//Palaces
NormalPalaceStyle = PalaceStyle.RANDOM_WALK,
GpStyle = PalaceStyle.RANDOM_WALK,
ShortenNormalPalaces = false,
ShortenGP = true,
NormalPalaceLength = PalaceLengthOption.MEDIUM,
GpLength = PalaceLengthOption.SHORT,
IncludeVanillaRooms = true,
Includev4_0Rooms = true,
Includev5_0Rooms = false,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/FullShufflePreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public static class FullShufflePreset
//Palaces
NormalPalaceStyle = PalaceStyle.RANDOM_WALK,
GpStyle = PalaceStyle.RANDOM_WALK,
ShortenNormalPalaces = false,
ShortenGP = true,
NormalPalaceLength = PalaceLengthOption.FULL,
GpLength = PalaceLengthOption.SHORT,
IncludeVanillaRooms = true,
Includev4_0Rooms = true,
Includev5_0Rooms = true,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/HardmodePreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ public static class HardmodePreset
//Palaces
NormalPalaceStyle = PalaceStyle.RANDOM_WALK,
GpStyle = PalaceStyle.RANDOM_WALK,
ShortenNormalPalaces = false,
ShortenGP = false,
NormalPalaceLength = PalaceLengthOption.FULL,
GpLength = PalaceLengthOption.MEDIUM,
IncludeVanillaRooms = true,
Includev4_0Rooms = true,
Includev5_0Rooms = true,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/MaxRandoPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public static class MaxRandoPreset
//Palaces
NormalPalaceStyle = PalaceStyle.RANDOM_PER_PALACE,
GpStyle = PalaceStyle.RANDOM_NO_VANILLA_OR_SHUFFLE,
ShortenNormalPalaces = false,
ShortenGP = null,
NormalPalaceLength = PalaceLengthOption.RANDOM,
GpLength = PalaceLengthOption.RANDOM,
IncludeVanillaRooms = true,
Includev4_0Rooms = true,
Includev5_0Rooms = true,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/NormalPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public static class NormalPreset
//Palaces
NormalPalaceStyle = PalaceStyle.RANDOM_WALK,
GpStyle = PalaceStyle.RANDOM_WALK,
ShortenNormalPalaces = false,
ShortenGP = true,
NormalPalaceLength = PalaceLengthOption.MEDIUM,
GpLength = PalaceLengthOption.SHORT,
IncludeVanillaRooms = true,
Includev4_0Rooms = true,
Includev5_0Rooms = true,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/RandomPercentPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public static class RandomPercentPreset
//Palaces
NormalPalaceStyle = PalaceStyle.RANDOM_PER_PALACE,
GpStyle = PalaceStyle.RANDOM,
ShortenNormalPalaces = false,
ShortenGP = null,
NormalPalaceLength = PalaceLengthOption.RANDOM,
GpLength = PalaceLengthOption.RANDOM,
IncludeVanillaRooms = null,
Includev4_0Rooms = null,
Includev5_0Rooms = null,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/StandardPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public static class StandardPreset
//Palaces
NormalPalaceStyle = PalaceStyle.RANDOM_WALK,
GpStyle = PalaceStyle.RANDOM_WALK,
ShortenNormalPalaces = false,
ShortenGP = true,
NormalPalaceLength = PalaceLengthOption.FULL,
GpLength = PalaceLengthOption.SHORT,
IncludeVanillaRooms = true,
Includev4_0Rooms = true,
Includev5_0Rooms = true,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/StandardSwissPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public static class StandardSwissPreset
//Palaces
NormalPalaceStyle = PalaceStyle.RANDOM_WALK,
GpStyle = PalaceStyle.RANDOM_WALK,
ShortenNormalPalaces = false,
ShortenGP = true,
NormalPalaceLength = PalaceLengthOption.FULL,
GpLength = PalaceLengthOption.SHORT,
IncludeVanillaRooms = true,
Includev4_0Rooms = true,
Includev5_0Rooms = true,
Expand Down
4 changes: 2 additions & 2 deletions CrossPlatformUI/Presets/UpstartsTournamentPreset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public static class UpstartsTournamentPreset
//Palaces
NormalPalaceStyle = PalaceStyle.RECONSTRUCTED,
GpStyle = PalaceStyle.RECONSTRUCTED,
ShortenNormalPalaces = false,
ShortenGP = true,
NormalPalaceLength = PalaceLengthOption.FULL,
GpLength = PalaceLengthOption.SHORT,
IncludeVanillaRooms = true,
Includev4_0Rooms = true,
Includev5_0Rooms = false,
Expand Down
40 changes: 21 additions & 19 deletions CrossPlatformUI/Views/Tabs/PalacesView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,59 +11,61 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="CrossPlatformUI.Views.Tabs.PalacesView"
x:DataType="vm:MainViewModel">
<Grid ColumnDefinitions="440,*" ColumnSpacing="16">
<Grid ColumnDefinitions="480,*">
<StackPanel Grid.Column="0">
<HyperlinkButton
Margin="178 0 0 0"
HorizontalAlignment="Left"
Margin="16 0 16 0"
HorizontalAlignment="Right"
Content="[Wiki: Palace Styles]"
NavigateUri="https://github.com/Ellendar/Z2Randomizer/wiki/Palace-Styles"
FontSize="12"
Foreground="#4557c4"
Cursor="Hand"
/>
<Grid ColumnDefinitions="300,*">
<Grid ColumnDefinitions="260,*">
<ComboBox Grid.Column="0"
Margin="0, 0" Width="300" Theme="{StaticResource MaterialOutlineComboBox}"
Margin="0, 0" Theme="{StaticResource MaterialOutlineComboBox}"
assists:ComboBoxAssist.Label="Normal Palace Style"
Name="NormalPalaceStyleSelector"
ItemsSource="{Binding Source={x:Static rc:Enums.NormalPalaceStyleList}}"
SelectedItem="{Binding Config.NormalPalaceStyle, Converter={x:Static ui:Util.EnumConvert}}">
<ToolTip.Tip><TextBlock Text="{x:Static lang:Resources.NormalPalaceStyleToolTip}"/></ToolTip.Tip>
</ComboBox>
<CheckBox Grid.Column="1"
IsThreeState="True"
IsChecked="{Binding Config.ShortenNormalPalaces}"
Content="Shorten">
<ComboBox Grid.Column="1"
Margin="0, 0" Theme="{StaticResource MaterialOutlineComboBox}"
assists:ComboBoxAssist.Label="Normal Length"
ItemsSource="{Binding Source={x:Static rc:Enums.PalaceLengthOptionList}}"
SelectedItem="{Binding Config.NormalPalaceLength, Converter={x:Static ui:Util.EnumConvert}}">
<ToolTip.Tip><TextBlock Text="{x:Static lang:Resources.ShortenToolTip}"/></ToolTip.Tip>
</CheckBox>
</ComboBox>
</Grid>
<Grid ColumnDefinitions="300,*">
<Grid ColumnDefinitions="260,*">
<ComboBox Grid.Column="0"
Margin="0, 0" Width="300" Theme="{StaticResource MaterialOutlineComboBox}"
Margin="0, 0" Theme="{StaticResource MaterialOutlineComboBox}"
assists:ComboBoxAssist.Label="GP Palace Style"
Name="GPPalaceStyleSelector"
ItemsSource="{Binding Source={x:Static rc:Enums.GpPalaceStyleList}}"
SelectedItem="{Binding Config.GpStyle, Converter={x:Static ui:Util.EnumConvert}}">
<ToolTip.Tip><TextBlock Text="{x:Static lang:Resources.GPPalaceStyleToolTip}"/></ToolTip.Tip>
</ComboBox>
<CheckBox Grid.Column="1"
IsThreeState="True"
IsChecked="{Binding Config.ShortenGP}"
Content="Shorten">
<ComboBox Grid.Column="1"
Margin="0, 0" Theme="{StaticResource MaterialOutlineComboBox}"
assists:ComboBoxAssist.Label="GP Length"
ItemsSource="{Binding Source={x:Static rc:Enums.PalaceLengthOptionList}}"
SelectedItem="{Binding Config.GpLength, Converter={x:Static ui:Util.EnumConvert}}">
<ToolTip.Tip><TextBlock Text="{x:Static lang:Resources.ShortenToolTip}"/></ToolTip.Tip>
</CheckBox>
</ComboBox>
</Grid>
<ComboBox
HorizontalAlignment="Left" Margin="0, 0" Width="300" Theme="{StaticResource MaterialOutlineComboBox}"
HorizontalAlignment="Left" Margin="0, 0" Width="260" Theme="{StaticResource MaterialOutlineComboBox}"
assists:ComboBoxAssist.Label="Minimum Path To Dark Link"
ItemsSource="{Binding Source={x:Static rc:Enums.BossRoomMinDistanceOptions}}"
SelectedItem="{Binding Config.DarkLinkMinDistance, Converter={x:Static ui:Util.EnumConvert}}"
><ToolTip.Tip><TextBlock Text="{x:Static lang:Resources.MinimumPathToDarkLinkToolTip}"/></ToolTip.Tip>

</ComboBox>
<ComboBox
HorizontalAlignment="Left" Margin="0, 0" Width="300" Theme="{StaticResource MaterialOutlineComboBox}"
HorizontalAlignment="Left" Margin="0, 0" Width="260" Theme="{StaticResource MaterialOutlineComboBox}"
assists:ComboBoxAssist.Label="Item Rooms Per Palace"
ItemsSource="{Binding Source={x:Static rc:Enums.PalaceItemRoomCountOptions}}"
SelectedItem="{Binding Config.PalaceItemRoomCount, Converter={x:Static ui:Util.EnumConvert}}"
Expand Down
13 changes: 13 additions & 0 deletions RandomizerCore/EnumTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,18 @@ public enum BossRoomMinDistance
MAX = 24,
}

public enum PalaceLengthOption
{
[Description("Short [50% to 65%]"), RandomRangeDouble(Low = 0.50, High = 0.65)]
SHORT = 0,
[Description("Medium [60% to 80%]"), RandomRangeDouble(Low = 0.60, High = 0.80)]
MEDIUM = 1,
[Description("Full [85% to 115%]"), RandomRangeDouble(Low = 0.85, High = 1.15)]
FULL = 2, // remains 100% for Vanilla palaces
[Description("Random [50% to 115%]"), RandomRangeDouble(Low = 0.50, High = 1.15)]
RANDOM = 3
}

public enum PalaceItemRoomCount
{
[Description("Zero")]
Expand Down Expand Up @@ -809,6 +821,7 @@ public static class Enums
public static IEnumerable<EnumDescription> BossLifeOptionList { get; } = ToDescriptions<EnemyLifeOption>(i => i != EnemyLifeOption.WIDE);
public static IEnumerable<EnumDescription> FireOptionList { get; } = ToDescriptions<FireOption>();
public static IEnumerable<EnumDescription> BossRoomMinDistanceOptions { get; } = ToDescriptions<BossRoomMinDistance>();
public static IEnumerable<EnumDescription> PalaceLengthOptionList { get; } = ToDescriptions<PalaceLengthOption>();
public static IEnumerable<EnumDescription> PalaceItemRoomCountOptions { get; } = ToDescriptions<PalaceItemRoomCount>();
public static IEnumerable<EnumDescription> NormalPalaceStyleList { get; }
= ToDescriptions<PalaceStyle>(i => i != PalaceStyle.RANDOM && i != PalaceStyle.RANDOM_NO_VANILLA_OR_SHUFFLE);
Expand Down
71 changes: 38 additions & 33 deletions RandomizerCore/RandomizerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -588,10 +588,10 @@ public sealed partial class RandomizerConfiguration : INotifyPropertyChanged
private bool randomizeKnockback;

[Reactive]
private bool? shortenGP;
private PalaceLengthOption gpLength;

[Reactive]
private bool? shortenNormalPalaces;
private PalaceLengthOption normalPalaceLength;


[Reactive]
Expand Down Expand Up @@ -839,8 +839,8 @@ public RandomizerProperties Export(Random r)
}
}

properties.ShortenGP = shortenGP ?? GetIndeterminateFlagValue(r);
properties.ShortenNormalPalaces = shortenNormalPalaces ?? GetIndeterminateFlagValue(r);
properties.PalaceLengths = Palaces.RollPalaceLengths(r, properties, this);

properties.DarkLinkMinDistance = GetDarkLinkMinDistance();

//Palace item counts and prerequisites.
Expand Down Expand Up @@ -1450,38 +1450,45 @@ public void AssignPalaceItemCounts(RandomizerProperties properties, Random r)
{
//I'm not sure whether I like the bias introduced in generating random values and then capping them
//vs just determining min/max ranges and fair rolling between them. Keeping it for now.
int[] palaceItemRoomsMax = [1, 1, 1, 1, 1, 1];
int[] palaceItemRoomsMin = palaceItemRoomCount == PalaceItemRoomCount.RANDOM_INCLUDE_ZERO ? [0, 0, 0, 0, 0, 0] : [1, 1, 1, 1, 1, 1];
// To keep weighting consistent between 0-item and 1-item rooms across
// Standard, Max Rando, etc., we roll the room count the same way
// regardless of palace type. This also reduces how much (imperfect)
// information the item count reveals about the palace style.
int[] palaceItemRoomsMax = palaceItemRoomCount switch
{
PalaceItemRoomCount.ZERO => [0, 0, 0, 0, 0, 0],
PalaceItemRoomCount.ONE => [1, 1, 1, 1, 1, 1],
PalaceItemRoomCount.TWO => [2, 2, 2, 2, 2, 2],
PalaceItemRoomCount.RANDOM_NOT_ZERO or
PalaceItemRoomCount.RANDOM_INCLUDE_ZERO =>
properties.PalaceLengths.Select(len => len switch
{
< 14 => 1,
< 24 => 2,
_ => 3,
}).ToArray(),
_ => throw new NotImplementedException(),
};
// We have to cap the number of item rooms for some styles.
// Vanilla, because it doesn't make sense to change any rooms,
// and Vanilla Shuffled, because it crashes with more than two.
int[] palaceItemRoomsLimit = properties.PalaceStyles.Select(style => style switch
{
PalaceStyle.VANILLA => 1,
PalaceStyle.SHUFFLED => 2,
_ => int.MaxValue,
}).ToArray();

switch (palaceItemRoomCount)
{
case PalaceItemRoomCount.RANDOM_INCLUDE_ZERO:
case PalaceItemRoomCount.RANDOM_NOT_ZERO:
palaceItemRoomsMax = properties.ShortenNormalPalaces ? [1, 2, 1, 2, 2, 2] : [2, 2, 2, 2, 3, 3];
for (int i = 0; i < 6; i++)
{
properties.PalaceItemRoomCounts[i] = r.Next(palaceItemRoomsMin[i], palaceItemRoomsMax[i] + 1);
// Limit vanilla palace style to 1 item rooms max
// Rationale:
// The benefit of the vanilla palace style is that you can use vanilla
// knowledge to know exactly where to go. Changing random rooms into
// additonal item rooms ruins this. So, unless the user specifically
// sets two items per, we should not do it.
//
// This way we can combine the fun of having both style and item count
// set to random, for Max Rando players, without the downside of having
// to track down which room was changed in a vanilla palace.
if (properties.PalaceStyles[i] == PalaceStyle.VANILLA)
{
properties.PalaceItemRoomCounts[i] = Math.Min(properties.PalaceItemRoomCounts[i], 1);
}
// Limit shuffled vanilla palace style to 2 item rooms max.
// More than that often caused errors when generating.
// Technically, non-shortened P4 & P5 can have 3 item rooms,
// but lets keep it simple.
else if (properties.PalaceStyles[i] == PalaceStyle.SHUFFLED)
{
properties.PalaceItemRoomCounts[i] = Math.Min(properties.PalaceItemRoomCounts[i], 2);
}
var roll = r.Next(palaceItemRoomsMin[i], palaceItemRoomsMax[i] + 1);
var capped = Math.Min(roll, palaceItemRoomsLimit[i]);
properties.PalaceItemRoomCounts[i] = capped;
}
properties.UsePalaceItemRoomCountIndicator = true;
break;
Expand All @@ -1493,7 +1500,6 @@ public void AssignPalaceItemCounts(RandomizerProperties properties, Random r)

//If shuffle palace items is off, the minimum number of palace rooms for a palace must be 1
//otherwise it is impossible to place the palace items.

if (!properties.ShufflePalaceItems)
{
for (int i = 0; i < 6; i++)
Expand All @@ -1508,7 +1514,7 @@ public void AssignPalaceItemCounts(RandomizerProperties properties, Random r)
while (properties.PalaceItemRoomCounts.Sum() < 6)
{
int i = r.Next(6);
if (properties.PalaceItemRoomCounts[i] < palaceItemRoomsMax[i])
if (properties.PalaceItemRoomCounts[i] < palaceItemRoomsLimit[i])
{
properties.PalaceItemRoomCounts[i]++;
}
Expand Down Expand Up @@ -1727,8 +1733,7 @@ private int GetDarkLinkMinDistance()
{
// limiting here based on how long it takes to generate the seeds
if (gpStyle == PalaceStyle.RECONSTRUCTED) { return 16; }
if (shortenGP != false) { return 20; }
return 24;
return 20;
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions RandomizerCore/RandomizerProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ public class RandomizerProperties
//Palaces
[NotMapped]
public PalaceStyle[] PalaceStyles { get; set; } = new PalaceStyle[7];
public bool ShortenNormalPalaces { get; set; }
public bool ShortenGP { get; set; }
[NotMapped]
public int[] PalaceLengths { get; set; } = new int[7];
public int StartGems { get; set; }
public bool RequireTbird { get; set; }
public int DarkLinkMinDistance { get; set; }
Expand Down
4 changes: 3 additions & 1 deletion RandomizerCore/Sidescroll/ChaosPalaceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ internal override async Task<Palace> GeneratePalace(RandomizerProperties props,
debug++;
bool duplicateProtection = (props.NoDuplicateRooms || props.NoDuplicateRoomsBySideview) && AllowDuplicatePrevention(props, palaceNumber);
RoomPool roomPool = new(rooms);
ILookup<string, Room>? duplicateRoomLookup = CreateRoomVariantsLookupOrNull(props, palaceNumber, roomPool);
DetermineRoomVariants(r, duplicateRoomLookup, roomPool.NormalRooms);
Palace palace = new(palaceNumber);
var palaceGroup = Util.AsPalaceGrouping(palaceNumber);

Expand Down Expand Up @@ -90,7 +92,7 @@ internal override async Task<Palace> GeneratePalace(RandomizerProperties props,
int roomIndex = r.Next(roomPool.NormalRooms.Count);
Room newRoom = new(roomPool.NormalRooms[roomIndex]);
palace.AllRooms.Add(newRoom);
if (duplicateProtection) { RemoveDuplicatesFromPool(props, roomPool.NormalRooms, newRoom); }
if (duplicateProtection) { RemoveDuplicatesFromPool(roomPool.NormalRooms, newRoom); }
}

Dictionary<Room, RoomExitType> roomExits = [];
Expand Down
Loading
Loading