diff --git a/.github/workflows/build-debug.yaml b/.github/workflows/build-debug.yaml index b4ded7d4e..35eb3f934 100644 --- a/.github/workflows/build-debug.yaml +++ b/.github/workflows/build-debug.yaml @@ -5,7 +5,9 @@ on: branches-ignore: - main - testing - - '5.1' + - extras + - sgl + - '5.2' pull_request: env: diff --git a/.github/workflows/build-latest.yaml b/.github/workflows/build-latest.yaml index 06f3f7c8d..54c37e8ae 100644 --- a/.github/workflows/build-latest.yaml +++ b/.github/workflows/build-latest.yaml @@ -5,7 +5,9 @@ on: branches: - main - testing - - '5.1' + - extras + - sgl + - '5.2' env: # I'm not a fan of the telemetry as-is, but this also suppresses some lines in the build log. diff --git a/CoreSourceGenerator/CoreSourceGenerator.csproj b/CoreSourceGenerator/CoreSourceGenerator.csproj index bed7384f5..b20c92c0b 100644 --- a/CoreSourceGenerator/CoreSourceGenerator.csproj +++ b/CoreSourceGenerator/CoreSourceGenerator.csproj @@ -11,10 +11,7 @@ Debug;Release;Unsafe Debug AnyCPU - - true - true - + true false diff --git a/CoreSourceGenerator/FlagsSerializeGenerator.cs b/CoreSourceGenerator/FlagsSerializeGenerator.cs index 55882e30d..683f04bca 100644 --- a/CoreSourceGenerator/FlagsSerializeGenerator.cs +++ b/CoreSourceGenerator/FlagsSerializeGenerator.cs @@ -58,7 +58,7 @@ private static bool IsPartialClass(SyntaxNode node) .Select(f => { // Look up the source code for the declaration to find if it has a default value - var equalsSyntax = f.DeclaringSyntaxReferences[0].GetSyntax() switch + var equalsSyntax = f.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() switch { PropertyDeclarationSyntax property => property.Initializer, VariableDeclaratorSyntax variable => variable.Initializer, @@ -81,18 +81,32 @@ private static bool IsPartialClass(SyntaxNode node) var serializeFields = classSymbol.GetMembers() .OfType() .Where(f => !HasIgnoreInFlagsAttribute(f)) - .Select(f => new SerializedFieldInfo() + .Select(f => { - FieldName = f.Name, - FieldType = f.Type.ToDisplayString(), - IsDifficultyOnly = HasDifficultyOnlyAttribute(f), - IsConditionallyIncluded = HasConditionallyIncludedInFlagsAttribute(f), - DefaultValue = GetDefaultValue(f), - IsEnum = f.Type.TypeKind == TypeKind.Enum, - EnumSymbol = f.Type.TypeKind == TypeKind.Enum ? f.Type as INamedTypeSymbol : null, - Minimum = GetCustomMinimum(f), - Maximum = GetCustomMaximum(f), - CustomSerializerName = GetCustomFlagSerializer(f), + var dictionaryInterface = f.Type.AllInterfaces + .FirstOrDefault(i => i.OriginalDefinition.ToDisplayString().StartsWith("System.Collections.Generic.IDictionary")); + var innerType = dictionaryInterface != null ? dictionaryInterface.TypeArguments[0] : f.Type; + + var equalsSyntax = f.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() switch + { + PropertyDeclarationSyntax property => property.Initializer, + VariableDeclaratorSyntax variable => variable.Initializer, + _ => null + }; + + return new SerializedFieldInfo() + { + FieldName = f.Name, + FieldType = f.Type.ToDisplayString(), + IsDifficultyOnly = HasDifficultyOnlyAttribute(f), + IsConditionallyIncluded = HasConditionallyIncludedInFlagsAttribute(f), + DefaultValue = equalsSyntax?.Value.ToString(), + IsEnum = f.Type.TypeKind == TypeKind.Enum, + EnumSymbol = f.Type.TypeKind == TypeKind.Enum ? f.Type as INamedTypeSymbol : null, + Minimum = GetCustomMinimum(f), + Maximum = GetCustomMaximum(f), + CustomSerializerName = GetCustomFlagSerializer(f), + }; }).ToList(); classInfo.SerializedFields.AddRange(serializeFields); @@ -140,14 +154,6 @@ private static bool HasDifficultyOnlyAttribute(IFieldSymbol field) .Any(attr => attr.AttributeClass?.Name.StartsWith("DifficultyOnly") ?? false); } - private static string GetDefaultValue(IFieldSymbol f) - { - var defaultAttr = f.GetAttributes() - .FirstOrDefault(a => a.AttributeClass?.ToDisplayString() == "System.ComponentModel.DefaultValueAttribute"); - var arg = defaultAttr?.ConstructorArguments[0]; - return arg != null ? FormatArgument(arg.Value) : "default"; - } - private static bool HasIgnoreInFlagsAttribute(IFieldSymbol field) { return field.GetAttributes() @@ -317,7 +323,10 @@ private static void GenerateReactiveProperty(StringBuilder sb, ReactiveFieldInfo sb.AppendLine($"{indent} {{"); sb.AppendLine($"{indent} {field.FieldName} = value;"); sb.AppendLine($"{indent} OnPropertyChanged(nameof({field.PropertyName}));"); - sb.AppendLine($"{indent} OnPropertyChanged(\"Flags\");"); + sb.AppendLine($"{indent} if (!_inDeserializeFlags)"); + sb.AppendLine($"{indent} {{"); + sb.AppendLine($"{indent} OnPropertyChanged(\"Flags\");"); + sb.AppendLine($"{indent} }}"); sb.AppendLine($"{indent} }}"); sb.AppendLine($"{indent} }}"); sb.AppendLine($"{indent} }}{defaultValue}"); diff --git a/CrossPlatformUI.Browser/CrossPlatformUI.Browser.csproj b/CrossPlatformUI.Browser/CrossPlatformUI.Browser.csproj index 3bbe79176..a63b7f6d5 100644 --- a/CrossPlatformUI.Browser/CrossPlatformUI.Browser.csproj +++ b/CrossPlatformUI.Browser/CrossPlatformUI.Browser.csproj @@ -22,8 +22,14 @@ false false + true + true + + + + true diff --git a/CrossPlatformUI/Assets/palace-blockers.png b/CrossPlatformUI/Assets/palace-blockers.png deleted file mode 100644 index 7493ce1b0..000000000 Binary files a/CrossPlatformUI/Assets/palace-blockers.png and /dev/null differ diff --git a/CrossPlatformUI/CrossPlatformUI.csproj b/CrossPlatformUI/CrossPlatformUI.csproj index 36406d1c1..fa91327a7 100644 --- a/CrossPlatformUI/CrossPlatformUI.csproj +++ b/CrossPlatformUI/CrossPlatformUI.csproj @@ -13,11 +13,6 @@ true - - - $(NoWarn);IL2026 - - true false @@ -35,6 +30,7 @@ + @@ -46,6 +42,11 @@ + + + + + diff --git a/CrossPlatformUI/Lang/Resources.resx b/CrossPlatformUI/Lang/Resources.resx index 1a2dbc393..0d6dbec3b 100644 --- a/CrossPlatformUI/Lang/Resources.resx +++ b/CrossPlatformUI/Lang/Resources.resx @@ -231,9 +231,20 @@ group is the same as the number in that group that steal EXP in vanilla. If selected, the amount of EXP each stealer steals is between 50% and 150% of the vanilla amount. - -Randomly reassigns which enemies are immune to stabs. The number of enemies that are -immune in each group is the same as the number in that group that are immune in vanilla. + +Vanilla: +Uses the game's original sword immunities. (Tektites and Zoras) + +Shuffle: +Randomly reassigns which enemies are immune to sword attacks and require the Fire spell +to damage. On average, the same number of enemies are immune as in the vanilla game. + +Shuffle/None if Fire unusable: +Uses Shuffle if the Fire spell is usable (not replaced by Dash nor linked with Fairy). +Otherwise, removes all sword immunities. + +None: +Removes all sword immunities. Randomizes the color palettes of enemies and NPCs. Health bar color is also randomized. @@ -692,9 +703,9 @@ linear. make room. Random Item Rooms Per Palace: + • Each palace gets 0–3 item rooms (varies by palace length/style). • Clouds in the entrance screen and Ironknuckle statues by the entrance elevator indicate how many items there are in the palace. - • Each palace gets 0–3 item rooms (varies by palace length/style). If selected, the normal zelda 2 rooms will be available for palace generation. Note that @@ -766,8 +777,10 @@ considered duplicates of each other. Has no effect on vanilla palaces. Does not prevent duplicates for Random Walk generated palaces. -Allows rooms that require an item or spell to traverse to appear in any palace. Otherwise, -palaces can only contain blocks according to the following table. +Allows rooms that cannot be passed without a specific item or spell to appear in any palace. +Otherwise, the allowed requirements for rooms in palaces are based on the items and spells +needed to pass through every room in that palace in vanilla (from either direction). +See the Wiki for the full table. Removes dead-end rooms from the room pool. This helps newer players who are not yet diff --git a/CrossPlatformUI/Presets/BeginnerPreset.cs b/CrossPlatformUI/Presets/BeginnerPreset.cs index 644b69e3d..c077f3ebe 100644 --- a/CrossPlatformUI/Presets/BeginnerPreset.cs +++ b/CrossPlatformUI/Presets/BeginnerPreset.cs @@ -31,8 +31,8 @@ public static class BeginnerPreset EastBiome = Biome.VANILLALIKE, DmBiome = Biome.VANILLALIKE, MazeBiome = Biome.VANILLALIKE, - WestClimate = ClimateEnum.VANILLA_WEIGHTED_WEST, - EastClimate = ClimateEnum.VANILLA_WEIGHTED_EAST, + WestClimate = ClimateEnum.VANILLA_WEIGHTED, + EastClimate = ClimateEnum.VANILLA_WEIGHTED, //Palaces NormalPalaceStyle = PalaceStyle.VANILLA_WEIGHTED, diff --git a/CrossPlatformUI/Presets/FullShufflePreset.cs b/CrossPlatformUI/Presets/FullShufflePreset.cs index 51cc1e5be..4e7e47541 100644 --- a/CrossPlatformUI/Presets/FullShufflePreset.cs +++ b/CrossPlatformUI/Presets/FullShufflePreset.cs @@ -29,8 +29,8 @@ public static class FullShufflePreset EastBiome = Biome.RANDOM_NO_VANILLA_OR_SHUFFLE, DmBiome = Biome.RANDOM_NO_VANILLA_OR_SHUFFLE, MazeBiome = Biome.VANILLALIKE, - WestClimate = ClimateEnum.VANILLA_WEIGHTED_WEST, - EastClimate = ClimateEnum.VANILLA_WEIGHTED_EAST, + WestClimate = ClimateEnum.VANILLA_WEIGHTED, + EastClimate = ClimateEnum.VANILLA_WEIGHTED, ContinentConnectionType = ContinentConnectionType.ANYTHING_GOES, //Palaces @@ -77,7 +77,7 @@ public static class FullShufflePreset ShuffleBossHP = EnemyLifeOption.MEDIUM, ShuffleXPStealers = true, ShuffleXPStolenAmount = true, - ShuffleSwordImmunity = true, + SwordImmunityOption = SwordImmunityOption.SHUFFLE, EnemyXPDrops = XPEffectiveness.RANDOM, //Items diff --git a/CrossPlatformUI/Presets/MaxRando2025Preset.cs b/CrossPlatformUI/Presets/MaxRando2025Preset.cs index 0eb0834dc..9668fee8e 100644 --- a/CrossPlatformUI/Presets/MaxRando2025Preset.cs +++ b/CrossPlatformUI/Presets/MaxRando2025Preset.cs @@ -79,7 +79,7 @@ public static class MaxRando2025Preset ShuffleBossHP = EnemyLifeOption.MEDIUM, ShuffleXPStealers = true, ShuffleXPStolenAmount = true, - ShuffleSwordImmunity = true, + SwordImmunityOption = SwordImmunityOption.SHUFFLE, EnemyXPDrops = XPEffectiveness.RANDOM, //Items diff --git a/CrossPlatformUI/Presets/MaxRandoPreset.cs b/CrossPlatformUI/Presets/MaxRandoPreset.cs index c7898e406..1296f963b 100644 --- a/CrossPlatformUI/Presets/MaxRandoPreset.cs +++ b/CrossPlatformUI/Presets/MaxRandoPreset.cs @@ -90,7 +90,7 @@ public static class MaxRandoPreset ShuffleBossHP = EnemyLifeOption.MEDIUM, ShuffleXPStealers = true, ShuffleXPStolenAmount = true, - ShuffleSwordImmunity = true, + SwordImmunityOption = SwordImmunityOption.SHUFFLE, EnemyXPDrops = XPEffectiveness.WIDE, //Items diff --git a/CrossPlatformUI/Presets/NormalPreset.cs b/CrossPlatformUI/Presets/NormalPreset.cs index d2c6b421d..5f723b002 100644 --- a/CrossPlatformUI/Presets/NormalPreset.cs +++ b/CrossPlatformUI/Presets/NormalPreset.cs @@ -27,8 +27,8 @@ public static class NormalPreset EastBiome = Biome.RANDOM_NO_VANILLA_OR_SHUFFLE, MazeBiome = Biome.VANILLALIKE, DmBiome = Biome.RANDOM_NO_VANILLA_OR_SHUFFLE, - WestClimate = ClimateEnum.VANILLA_WEIGHTED_WEST, - EastClimate = ClimateEnum.VANILLA_WEIGHTED_EAST, + WestClimate = ClimateEnum.VANILLA_WEIGHTED, + EastClimate = ClimateEnum.VANILLA_WEIGHTED, ContinentConnectionType = ContinentConnectionType.TRANSPORTATION_SHUFFLE, //Palaces @@ -70,7 +70,7 @@ public static class NormalPreset ShuffleBossHP = EnemyLifeOption.MEDIUM, ShuffleXPStealers = true, ShuffleXPStolenAmount = true, - ShuffleSwordImmunity = true, + SwordImmunityOption = SwordImmunityOption.SHUFFLE, EnemyXPDrops = XPEffectiveness.RANDOM, //Items diff --git a/CrossPlatformUI/Presets/RandomPercentPreset.cs b/CrossPlatformUI/Presets/RandomPercentPreset.cs index 8825f8310..e1389ac38 100644 --- a/CrossPlatformUI/Presets/RandomPercentPreset.cs +++ b/CrossPlatformUI/Presets/RandomPercentPreset.cs @@ -88,7 +88,7 @@ public static class RandomPercentPreset ShuffleBossHP = EnemyLifeOption.MEDIUM, ShuffleXPStealers = true, ShuffleXPStolenAmount = true, - ShuffleSwordImmunity = true, + SwordImmunityOption = SwordImmunityOption.SHUFFLE, EnemyXPDrops = XPEffectiveness.RANDOM, //Items diff --git a/CrossPlatformUI/Presets/StandardPreset.cs b/CrossPlatformUI/Presets/StandardPreset.cs index 10de722b9..d3b6e1b38 100644 --- a/CrossPlatformUI/Presets/StandardPreset.cs +++ b/CrossPlatformUI/Presets/StandardPreset.cs @@ -74,7 +74,7 @@ public static class StandardPreset ShuffleBossHP = EnemyLifeOption.MEDIUM, ShuffleXPStealers = true, ShuffleXPStolenAmount = true, - ShuffleSwordImmunity = true, + SwordImmunityOption = SwordImmunityOption.SHUFFLE, EnemyXPDrops = XPEffectiveness.RANDOM, //Items diff --git a/CrossPlatformUI/Presets/StandardSwissPreset.cs b/CrossPlatformUI/Presets/StandardSwissPreset.cs index bd611d5eb..e008f96a0 100644 --- a/CrossPlatformUI/Presets/StandardSwissPreset.cs +++ b/CrossPlatformUI/Presets/StandardSwissPreset.cs @@ -73,7 +73,7 @@ public static class StandardSwissPreset ShuffleBossHP = EnemyLifeOption.MEDIUM, ShuffleXPStealers = true, ShuffleXPStolenAmount = true, - ShuffleSwordImmunity = true, + SwordImmunityOption = SwordImmunityOption.SHUFFLE, EnemyXPDrops = XPEffectiveness.RANDOM, //Items diff --git a/CrossPlatformUI/Presets/UpstartsTournamentPreset.cs b/CrossPlatformUI/Presets/UpstartsTournamentPreset.cs index d2e536bd3..fa975a522 100644 --- a/CrossPlatformUI/Presets/UpstartsTournamentPreset.cs +++ b/CrossPlatformUI/Presets/UpstartsTournamentPreset.cs @@ -65,7 +65,7 @@ public static class UpstartsTournamentPreset ShuffleBossHP = EnemyLifeOption.MEDIUM, ShuffleXPStealers = true, ShuffleXPStolenAmount = true, - ShuffleSwordImmunity = true, + SwordImmunityOption = SwordImmunityOption.SHUFFLE, EnemyXPDrops = XPEffectiveness.RANDOM, //Items diff --git a/CrossPlatformUI/ViewModels/RandomizerViewModel.cs b/CrossPlatformUI/ViewModels/RandomizerViewModel.cs index 8cf82394a..e33ddadf5 100644 --- a/CrossPlatformUI/ViewModels/RandomizerViewModel.cs +++ b/CrossPlatformUI/ViewModels/RandomizerViewModel.cs @@ -31,25 +31,8 @@ public class RandomizerViewModel : ReactiveValidationObject, IRoutableViewModel, private static bool IsFlagStringValid(string flags) => FlagPasteParser.IsValidFlagString(flags); - private string flagInput = ""; - [JsonIgnore] - public string FlagInput - { - get => flagInput; - set - { - var trimmedValue = value?.Trim() ?? ""; - var (extractedFlags, extractedSeed) = FlagPasteParser.Parse(trimmedValue); - - if (Main is not null && !string.IsNullOrEmpty(extractedSeed)) - { - Main.Config.Seed = extractedSeed; - } - - this.RaiseAndSetIfChanged(ref flagInput, extractedFlags ?? trimmedValue); - } - } + public string FlagInput { get; set { field = value.Trim(); this.RaisePropertyChanged(); } } = ""; [JsonIgnore] public string Seed @@ -95,6 +78,7 @@ public RandomizerViewModel(MainViewModel main) HostScreen = Main; BiomesViewModel = new(Main); PalacesViewModel = new(Main); + SpellsViewModel = new(Main); ItemsViewModel = new(Main); HintsViewModel = new(Main, this); CustomizeViewModel = new(Main); @@ -226,16 +210,28 @@ private void OnActivate(CompositeDisposable disposables) // flag updates from RandomizerConfiguration always overwrites our flag input Main.FlagsObservable - .Do(x => FlagsValidSubject.OnNext(true)) - .Subscribe(flags => FlagInput = flags) + .Subscribe(flags => + { + FlagsValidSubject.OnNext(true); + FlagInput = flags; + }) .DisposeWith(disposables); - this.WhenAnyValue(x => x.FlagInput) - .WithLatestFrom(Main.FlagsObservable, - (Input, Current) => (Input, Current, IsValid: Input == Current || IsFlagStringValid(Input))) - .Do(x => FlagsValidSubject.OnNext(x.IsValid)) - .Where(x => x.IsValid && x.Input != x.Current) - .Subscribe(x => Main.Config.DeserializeFlags(x.Input)) + this.WhenAnyValue(viewModel => viewModel.FlagInput) + .WithLatestFrom(Main.FlagsObservable, (Input, Current) => (Input, Current)) + .Subscribe(tuple => + { + var isNew = tuple.Input != tuple.Current; + if (isNew) + { + bool isValid = IsFlagStringValid(tuple.Input); + FlagsValidSubject.OnNext(isValid); + if (isValid) + { + Main.Config.DeserializeFlags(tuple.Input); + } + } + }) .DisposeWith(disposables); Main.Config.PropertyChanged += (sender, args) => @@ -248,7 +244,7 @@ private void OnActivate(CompositeDisposable disposables) } }; - this.ValidationRule(x => x.FlagInput, FlagsValidSubject, "Invalid Flags"); + this.ValidationRule(viewModel => viewModel.FlagInput, FlagsValidSubject, "Invalid Flags"); AddValidationRules(); } @@ -330,6 +326,7 @@ private void AddValidationRules() [JsonIgnore] public BiomesViewModel BiomesViewModel { get; } public PalacesViewModel PalacesViewModel { get; } + public SpellsViewModel SpellsViewModel { get; } public ItemsViewModel ItemsViewModel { get; } public HintsViewModel HintsViewModel { get; } public CustomizeViewModel CustomizeViewModel { get; } diff --git a/CrossPlatformUI/ViewModels/Tabs/PalacesViewModel.cs b/CrossPlatformUI/ViewModels/Tabs/PalacesViewModel.cs index 37748c7da..6892599b2 100644 --- a/CrossPlatformUI/ViewModels/Tabs/PalacesViewModel.cs +++ b/CrossPlatformUI/ViewModels/Tabs/PalacesViewModel.cs @@ -12,15 +12,36 @@ public class PalacesViewModel : ReactiveObject, IActivatableViewModel public ViewModelActivator Activator { get; } public MainViewModel Main { get; } + public IObservable BossRoomsExitTypeIncludedObservable { get; } + public IObservable NoDuplicateRoomsByLayoutIncludedObservable { get; } + public IObservable NoDuplicateRoomsByEnemiesIncludedObservable { get; } public IObservable RandomStylesAllowVanillaIncludedObservable { get; } public IObservable RemoveLongDeadEndsIncludedObservable { get; } + public IObservable IncludeVanillaRoomsIncludedObservable { get; } + public IObservable Includev4_0RoomsIncludedObservable { get; } + public IObservable Includev5_0RoomsIncludedObservable { get; } public IObservable IncludeExpertRoomsIncludedObservable { get; } + public IObservable BlockingRoomsInAnyPalaceIncludedObservable { get; } + public IObservable RemoveTBirdIncludedObservable { get; } + public IObservable TBirdRequiredIncludedObservable { get; } public PalacesViewModel(MainViewModel main) { Main = main; Activator = new(); + BossRoomsExitTypeIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.bossRoomsExitTypeIncluded()) + .DistinctUntilChanged(); + + NoDuplicateRoomsByLayoutIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.noDuplicateRoomsByLayoutIncluded()) + .DistinctUntilChanged(); + + NoDuplicateRoomsByEnemiesIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.noDuplicateRoomsByEnemiesIncluded()) + .DistinctUntilChanged(); + RandomStylesAllowVanillaIncludedObservable = Main.FlagsChanged .Select(_ => Main.Config.randomStylesAllowVanillaIncluded()) .DistinctUntilChanged(); @@ -29,10 +50,34 @@ public PalacesViewModel(MainViewModel main) .Select(_ => Main.Config.removeLongDeadEndsIncluded()) .DistinctUntilChanged(); + IncludeVanillaRoomsIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.includeVanillaRoomsIncluded()) + .DistinctUntilChanged(); + + Includev4_0RoomsIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.includev4_0RoomsIncluded()) + .DistinctUntilChanged(); + + Includev5_0RoomsIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.includev5_0RoomsIncluded()) + .DistinctUntilChanged(); + IncludeExpertRoomsIncludedObservable = Main.FlagsChanged .Select(_ => Main.Config.includeExpertRoomsIncluded()) .DistinctUntilChanged(); + BlockingRoomsInAnyPalaceIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.blockingRoomsInAnyPalaceIncluded()) + .DistinctUntilChanged(); + + RemoveTBirdIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.removeTBirdIncluded()) + .DistinctUntilChanged(); + + TBirdRequiredIncludedObservable = Main.FlagsChanged + .Select(_ => Main.Config.tBirdRequiredIncluded()) + .DistinctUntilChanged(); + this.WhenActivated(OnActivate); } diff --git a/CrossPlatformUI/ViewModels/Tabs/SpellsViewModel.cs b/CrossPlatformUI/ViewModels/Tabs/SpellsViewModel.cs new file mode 100644 index 000000000..4993e8c74 --- /dev/null +++ b/CrossPlatformUI/ViewModels/Tabs/SpellsViewModel.cs @@ -0,0 +1,26 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reactive.Disposables; +using System.Reactive.Linq; +using ReactiveUI; + +namespace CrossPlatformUI.ViewModels.Tabs; + +[RequiresUnreferencedCode("ReactiveUI uses reflection")] +public class SpellsViewModel : ReactiveObject, IActivatableViewModel +{ + public ViewModelActivator Activator { get; } + public MainViewModel Main { get; } + + public SpellsViewModel(MainViewModel main) + { + Main = main; + Activator = new(); + + this.WhenActivated(OnActivate); + } + + internal void OnActivate(CompositeDisposable disposables) + { + } +} diff --git a/CrossPlatformUI/Views/NesColorDropdown.axaml b/CrossPlatformUI/Views/NesColorDropdown.axaml index ac0761779..de79d87a1 100644 --- a/CrossPlatformUI/Views/NesColorDropdown.axaml +++ b/CrossPlatformUI/Views/NesColorDropdown.axaml @@ -3,10 +3,10 @@ xmlns:assists="clr-namespace:Material.Styles.Assists;assembly=Material.Styles" x:Class="CrossPlatformUI.Views.NesColorDropdown" Width="340" Height="40"> - - + + - diff --git a/CrossPlatformUI/Views/RandomizerView.axaml b/CrossPlatformUI/Views/RandomizerView.axaml index e92492c3b..5bc93f8af 100644 --- a/CrossPlatformUI/Views/RandomizerView.axaml +++ b/CrossPlatformUI/Views/RandomizerView.axaml @@ -124,7 +124,7 @@ - +