From 532d510ae5f83f24e714aa6d247760caadac049a Mon Sep 17 00:00:00 2001 From: atravita-mods <94934860+atravita-mods@users.noreply.github.com> Date: Fri, 11 Mar 2022 20:56:48 -0500 Subject: [PATCH] Good question --- .editorconfig | 34 ++++----- .editorconfig.inferred | 113 ---------------------------- FarmCaveSpawn/GlobalSuppressions.cs | 1 + FarmCaveSpawn/ModEntry.cs | 62 ++++++++++++--- 4 files changed, 67 insertions(+), 143 deletions(-) delete mode 100644 .editorconfig.inferred diff --git a/.editorconfig b/.editorconfig index c8bbea9..7690644 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,25 +1,21 @@ [*.{cs,vb}] +dotnet_style_prefer_is_null_check_over_reference_equality_method=true:warning +dotnet_style_null_propagation=true:warning +dotnet_style_qualification_for_field=true:error +dotnet_style_qualification_for_property=true:error +dotnet_style_qualification_for_method=true:error +dotnet_style_qualification_for_event=true:error -#constants -dotnet_naming_symbols.all_constants.applicable_kinds = field -dotnet_naming_symbols.all_constants.applicable_accessibilities = * -dotnet_naming_symbols.all_constants.required_modifiers = const, readonly +# IDE0047: Remove unnecessary parentheses +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity -dotnet_naming_style.all_upper_underscore.capitalization = all_upper -dotnet_naming_style.all_upper_underscore.word_separator = _ +# IDE0047: Remove unnecessary parentheses +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity -dotnet_naming_rule.constants_must_be_all_uppercase.symbols = all_constants -dotnet_naming_rule.constants_must_be_all_uppercase.style = all_upper_underscore -dotnet_naming_rule.constants_must_be_all_uppercase.severity = suggestion - -# IDE0003: Remove qualification -dotnet_style_qualification_for_event =true:suggestion -dotnet_style_qualification_for_field=true:suggestion -dotnet_style_qualification_for_property=true:suggestion -dotnet_style_qualification_for_method=true:suggestion -dotnet_diagnostic.CA1304.severity=suggestion +# IDE0048: Add parentheses for clarity +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity [*.cs] -csharp_style_pattern_matching_over_is_with_cast_check=true:warning -csharp_style_pattern_matching_over_as_with_null_check=true:warning -insert_final_newline=true \ No newline at end of file +csharp_style_var_for_built_in_types=false:suggestion +csharp_style_var_when_type_is_apparent=false:suggestion +csharp_style_var_elsewhere=false:suggestion \ No newline at end of file diff --git a/.editorconfig.inferred b/.editorconfig.inferred deleted file mode 100644 index 884b764..0000000 --- a/.editorconfig.inferred +++ /dev/null @@ -1,113 +0,0 @@ -# Rules in this file were initially inferred by Visual Studio IntelliCode from the C:\Users\night\source\repos\FarmCaveSpawn codebase based on best match to current usage at 1/9/2022 -# There already existed an .editorconfig file in this directory. Copy rules from this .editorconfig.inferred file to the existing .editorconfig file as desired to have them take effect at this location. -# You can modify the rules from these initially generated values to suit your own policies -# You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference -[*.cs] - - -#Core editorconfig formatting - indentation - -#use soft tabs (spaces) for indentation -indent_style = space - -#Formatting - new line options - -#place catch statements on a new line -csharp_new_line_before_catch = true -#place else statements on a new line -csharp_new_line_before_else = true -#require members of object intializers to be on separate lines -csharp_new_line_before_members_in_object_initializers = true -#require braces to be on a new line for methods, control_blocks, types, and object_collection_array_initializers (also known as "Allman" style) -csharp_new_line_before_open_brace = methods, control_blocks, types, object_collection_array_initializers - -#Formatting - organize using options - -#do not place System.* using directives before other using directives -dotnet_sort_system_directives_first = false - -#Formatting - spacing options - -#require NO space between a cast and the value -csharp_space_after_cast = false -#require a space before the colon for bases or interfaces in a type declaration -csharp_space_after_colon_in_inheritance_clause = true -#require a space after a keyword in a control flow statement such as a for loop -csharp_space_after_keywords_in_control_flow_statements = true -#ignore spaces around binary operators -csharp_space_around_binary_operators = ignore -#require a space before the colon for bases or interfaces in a type declaration -csharp_space_before_colon_in_inheritance_clause = true -#remove space within empty argument list parentheses -csharp_space_between_method_call_empty_parameter_list_parentheses = false -#remove space between method call name and opening parenthesis -csharp_space_between_method_call_name_and_opening_parenthesis = false -#do not place space characters after the opening parenthesis and before the closing parenthesis of a method call -csharp_space_between_method_call_parameter_list_parentheses = false -#remove space within empty parameter list parentheses for a method declaration -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -#place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list. -csharp_space_between_method_declaration_parameter_list_parentheses = false - -#Formatting - wrapping options - -#leave code block on single line -csharp_preserve_single_line_blocks = true -#leave statements and member declarations on the same line -csharp_preserve_single_line_statements = true - -#Style - Code block preferences - -#prefer curly braces even for one line of code -csharp_prefer_braces = true:suggestion - -#Style - expression bodied member options - -#prefer block bodies for methods -csharp_style_expression_bodied_methods = false:suggestion - -#Style - expression level options - -#prefer out variables to be declared inline in the argument list of a method call when possible -csharp_style_inlined_variable_declaration = true:suggestion -#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them -dotnet_style_predefined_type_for_member_access = true:suggestion - -#Style - Expression-level preferences - -#prefer objects to be initialized using object initializers when possible -dotnet_style_object_initializer = true:suggestion - -#Style - implicit and explicit types - -#prefer explicit type over var in all cases, unless overridden by another code style rule -csharp_style_var_elsewhere = false:suggestion -#prefer explicit type over var to declare variables with built-in system types such as int -csharp_style_var_for_built_in_types = false:suggestion - -#Style - language keyword and framework type options - -#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them -dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion - -#Style - modifier options - -#prefer accessibility modifiers to be declared except for public interface members. This will currently not differ from always and will act as future proofing for if C# adds default interface methods. -dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion - -#Style - Modifier preferences - -#when this rule is set to a list of modifiers, prefer the specified ordering. -csharp_preferred_modifier_order = public,private,internal,readonly,override:suggestion - -#Style - Pattern matching - -#prefer pattern matching instead of is expression with type casts -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion - -#Style - qualification options - -#prefer fields not to be prefaced with this. or Me. in Visual Basic -dotnet_style_qualification_for_field = false:suggestion -#prefer methods not to be prefaced with this. or Me. in Visual Basic -dotnet_style_qualification_for_method = false:suggestion diff --git a/FarmCaveSpawn/GlobalSuppressions.cs b/FarmCaveSpawn/GlobalSuppressions.cs index bf0860a..835fc29 100644 --- a/FarmCaveSpawn/GlobalSuppressions.cs +++ b/FarmCaveSpawn/GlobalSuppressions.cs @@ -10,3 +10,4 @@ [assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "Preference")] [assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Preference")] [assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:Field names should begin with lower-case letter", Justification = "Preference")] +[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1011:Closing square brackets should be spaced correctly", Justification = "Stylecop doesn't understand nullable apparently")] diff --git a/FarmCaveSpawn/ModEntry.cs b/FarmCaveSpawn/ModEntry.cs index b32f592..ca69d18 100644 --- a/FarmCaveSpawn/ModEntry.cs +++ b/FarmCaveSpawn/ModEntry.cs @@ -2,6 +2,7 @@ using System.Text.RegularExpressions; using AtraBase.Toolkit.Extensions; using AtraShared.Integrations; +using AtraShared.MigrationManager; using AtraShared.Utils.Extensions; using Microsoft.Xna.Framework; using StardewModdingAPI.Events; @@ -37,6 +38,8 @@ public class ModEntry : Mod /// private List TreeFruit = new(); + private MigrationManager? migrator; + // The config is set by the Entry method, so it should never realistically be null #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. private ModConfig config; @@ -67,6 +70,13 @@ internal Random Random /// internal bool SpawnedFruitToday { get; private set; } + /// + /// Formats a float as a percent value. + /// + /// Value to format. + /// Formatted string. + public static string FormatPercentValue(float val) => $"{val:f0}%"; + /// public override void Entry(IModHelper helper) { @@ -87,6 +97,8 @@ public override void Entry(IModHelper helper) helper.Events.GameLoop.DayStarted += this.SpawnFruit; helper.Events.GameLoop.GameLaunched += this.SetUpConfig; helper.Events.GameLoop.OneSecondUpdateTicking += this.BellsAndWhistles; + helper.Events.GameLoop.SaveLoaded += this.SaveLoaded; + helper.ConsoleCommands.Add( name: "av.fcs.list_fruits", documentation: I18n.ListFruits_Description(), @@ -144,7 +156,8 @@ private void SetUpConfig(object? sender, GameLaunchedEventArgs e) property: property, getConfig: () => this.config, min: 0f, - max: 100f); + max: 100f, + formatValue: FormatPercentValue); } else if (property.PropertyType.Equals(typeof(SeasonalBehavior))) { @@ -309,7 +322,7 @@ private void SpawnFruit(object? sender, DayStartedEventArgs e) /// Tile to place fruit on. private void PlaceFruit(GameLocation location, Vector2 tile) { - int fruitToPlace = Utility.GetRandom(this.Random.NextDouble() < (this.config.TreeFruitChance / 100f) && this.TreeFruit.Count > 0 ? this.TreeFruit : this.BASE_FRUIT, this.Random); + int fruitToPlace = Utility.GetRandom(this.TreeFruit.Count > 0 && this.Random.NextDouble() < (this.config.TreeFruitChance / 100f) ? this.TreeFruit : this.BASE_FRUIT, this.Random); location.setObject(tile, new SObject(fruitToPlace, 1) { IsSpawnedObject = true, @@ -347,7 +360,6 @@ private IEnumerable IterateTiles(GameLocation location, int xstart = 1, /// /// Name of command. /// Arguments for command. - [SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "Console command format.")] private void ListFruits(string command, string[] args) { if (!Context.IsWorldReady) @@ -422,17 +434,12 @@ private List GetTreeFruits() if ((!this.config.AllowAnyTreeProduct && fruit.Category != SObject.FruitsCategory) || (this.config.EdiblesOnly && fruit.Edibility < 0) || fruit.Price > this.config.PriceCap - || denylist.Contains(fruit.Name)) + || denylist.Contains(fruit.Name) + || (this.config.NoBananasBeforeShrine && fruit.Name.Equals("Banana", StringComparison.OrdinalIgnoreCase) + && !Context.IsWorldReady && Game1.getLocationFromName("IslandEast") is IslandEast islandeast && !islandeast.bananaShrineComplete.Value)) { continue; } - if (this.config.NoBananasBeforeShrine && fruit.Name.Equals("Banana")) - { - if (!Context.IsWorldReady && Game1.getLocationFromName("IslandEast") is IslandEast islandeast && !islandeast.bananaShrineComplete.Value) - { - continue; - } - } treeFruits.Add(objectIndex); } catch (Exception ex) @@ -494,4 +501,37 @@ private void BellsAndWhistles(object? sender, OneSecondUpdateTickingEventArgs e) } } } + + /// + /// Raised when save is loaded. + /// + /// Unknown, used by SMAPI. + /// Parameters. + /// Used to load in this mod's data models. + private void SaveLoaded(object? sender, SaveLoadedEventArgs e) + { + if (Context.IsSplitScreen && Context.ScreenId != 0) + { + return; + } + this.migrator = new(this.ModManifest, this.Helper, this.Monitor); + this.migrator.ReadVersionInfo(); + + this.Helper.Events.GameLoop.Saved += this.WriteMigrationData; + } + + /// + /// Writes migration data then detaches the migrator. + /// + /// Smapi thing. + /// Arguments for just-before-saving. + private void WriteMigrationData(object? sender, SavedEventArgs e) + { + if (this.migrator is not null) + { + this.migrator.SaveVersionInfo(); + this.migrator = null; + } + this.Helper.Events.GameLoop.Saved -= this.WriteMigrationData; + } }