diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5a93491 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,273 @@ +# SPDX-License-Identifier: MIT +# Copyright 2023 Beslogic Inc. + +# The source skeleton for this configuration can be found at +# https://github.com/BesLogic/shared-configs/blob/main/.editorconfig +# Modifications to this file that are not project-specific should also be done upstream. + +# Editor configuration, see https://editorconfig.org +root = true + +[*] +#### Widely Supported by Editors #### +#### https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#widely-supported-by-editors + +indent_style = space +indent_size = 2 +# tab_width defaults indent_size when indent_size is a number, but VS will add it back +tab_width = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +#### Supported By A Limited Number of Editors #### +#### https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#supported-by-a-limited-number-of-editors + +max_line_length = 100 + +#### Ideas for Domain-Specific Properties #### +#### https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#ideas-for-domain-specific-properties + +quote_type = auto + +#### EditorGuidelines #### +#### https://marketplace.visualstudio.com/items?itemName=PaulHarrington.EditorGuidelinesPreview#editorconfig-support-vs-2017-and-above +guidelines = 80, 100 + +#### Language-specific overrides #### + +[*.{js,jsx,ts,tsx}] +quote_type = single + +[*.{py,pyi}] +quote_type = double +indent_size = 4 + +[*.md] +max_line_length = off +trim_trailing_whitespace = false + +[*.csproj] +indent_size = 4 + +#### .NET source code analysis #### +#### https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/categories +# Note that Visual Studio automatically adds back *:severity. So we left them there to avoid unwanted changes. + +[*] +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# Avoid simple if block w/o brace that could lead to inserting a new statement and breaking code +# csharp_prefer_braces = true:silent +# csharp_preserve_single_line_statements = false +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent +# TODO: Reconsider later. For now, allow single-line if-guards +csharp_prefer_braces = when_multiline:silent +csharp_preserve_single_line_statements = true + +# Extra loop safety. TODO: consider "always" +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed + +# Allow { get; set; } on a single line +csharp_preserve_single_line_blocks = true + +# Don't hide the operator at the end of the line +dotnet_style_operator_placement_when_wrapping = beginning_of_line + +# Modifier preferences +csharp_prefer_static_local_function = true:suggestion +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async +csharp_style_prefer_readonly_struct = true:suggestion +csharp_style_prefer_readonly_struct_member = true:suggestion +dotnet_style_readonly_field = true:suggestion +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +# Organize usings and namespace +csharp_style_namespace_declarations = file_scoped:silent +csharp_using_directive_placement = outside_namespace:suggestion +csharp_prefer_simple_using_statement = true:suggestion +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = true +dotnet_style_namespace_match_folder = true:suggestion + +# Destructuring and ranges +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_switch_expression = true:suggestion + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# New lines and Blank lines +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:silent +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false:silent +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false:silent +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false:silent +dotnet_style_allow_multiple_blank_lines_experimental = false:silent +dotnet_style_allow_statement_immediately_after_block_experimental = false:silent + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +#### Code simplifications #### + +# Simplified initializers and calls +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion + +# Unused variables, declarations and assignements +csharp_style_prefer_top_level_statements = true:silent +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = false +dotnet_code_quality_unused_parameters = all:suggestion + +# Ternaries, coalescence and null-checking +csharp_style_conditional_delegate_call = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +# ... but don't treat throw as an expression and ensure it stays obvious +csharp_style_throw_expression = false:suggestion +dotnet_style_prefer_conditional_expression_over_return = false:silent + +# Prefer arrow functions! +csharp_style_expression_bodied_methods = true:silent +# TODO: Take a decision on this, false vs when_on_single_line +# csharp_style_expression_bodied_constructors = when_on_single_line:silent +# For now just disable +dotnet_diagnostic.IDE0021.severity = none +csharp_style_expression_bodied_operators = when_on_single_line:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = true:silent + +# Prefer more succint variable declarations +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_var_elsewhere = true:silent +csharp_style_var_for_built_in_types = true:silent +csharp_style_var_when_type_is_apparent = true:silent +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Avoid redundant this. and Me. +dotnet_style_qualification_for_event = false:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_property = false:silent + +#### Naming styles, rules and Symbol specifications ### + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style._fieldname.required_prefix = _ +dotnet_naming_style._fieldname.required_suffix = +dotnet_naming_style._fieldname.word_separator = +dotnet_naming_style._fieldname.capitalization = camel_case + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.private_or_internal_field_should_be__fieldname.severity = suggestion +dotnet_naming_rule.private_or_internal_field_should_be__fieldname.symbols = private_or_internal_field +dotnet_naming_rule.private_or_internal_field_should_be__fieldname.style = _fieldname + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field +dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected +dotnet_naming_symbols.private_or_internal_field.required_modifiers = diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index af4e34b..43e6bad 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,25 +17,25 @@ repos: # # args: [--autofix] # # I don't like it, it really messes up a lot a stuff # # - id: pretty-format-yaml - # # args: [--autofix, --indent, "2", --offset, "0", --preserve-quotes, --line-width, "120"], + # # args: [--autofix, --indent, "2", --offset, "0", --preserve-quotes, --line-width, "100"], # - id: pretty-format-ini # args: [--autofix] - - repo: local + - repo: local # https://github.com/dprint/dprint hooks: - id: dprint name: dprint entry: dprint fmt language: node types: [text] - additional_dependencies: ["dprint@~0.38.0"] + additional_dependencies: ["dprint@~0.45.1"] pass_filenames: false # https://github.com/adamchainz/pre-commit-dprint/issues/3#issuecomment-1483410008 - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.2.0" # Must match requirements-dev.txt + rev: "v0.4.2" # Must match requirements-dev.txt hooks: - id: ruff args: [--fix] - repo: https://github.com/hhatto/autopep8 - rev: "v2.0.4" # Must match requirements-dev.txt + rev: "v2.1.0" # Must match requirements-dev.txt hooks: - id: autopep8 - repo: https://github.com/asottile/add-trailing-comma @@ -43,7 +43,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/RobertCraigie/pyright-python - rev: "v1.1.350" + rev: "v1.1.360" hooks: - id: pyright diff --git a/.vscode/settings.json b/.vscode/settings.json index eb10216..2be908b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,9 +5,7 @@ }, "files.associations": { "*.dmw": "json", - "pyrightconfig*.json": "jsonc", - "dprint*.json": "jsonc", - ".flake8": "properties" + "*.json": "jsonc" }, "files.exclude": { "**/.mypy_cache": true, @@ -23,7 +21,7 @@ "editor.tabSize": 2, "editor.rulers": [ 80, - 120 + 100 ], "[git-commit]": { "editor.rulers": [ @@ -48,7 +46,7 @@ // 79, // PEP8-17 default max // 88, // Black default // 99, // PEP8-17 acceptable max - 120 // Our hard rule + 100 // Our hard rule ], "editor.codeActionsOnSave": { // TODO: Ruff is supposed to be able to take care of this @@ -64,20 +62,9 @@ // Specifically ignoring unusedImports because it's annoying to loose imports when commenting code for testing // "source.unusedImports" ], - "python.linting.enabled": true, "ruff.importStrategy": "fromEnvironment", // Use the Ruff extension instead "isort.check": false, - "python.linting.banditEnabled": false, - "python.linting.flake8Enabled": false, - "python.linting.prospectorEnabled": false, - "python.linting.pycodestyleEnabled": false, - "python.linting.pylamaEnabled": false, - "python.linting.pylintEnabled": false, - // Use the autopep8 extension instead - "python.formatting.provider": "none", - // Use Pyright/Pylance instead - "python.linting.mypyEnabled": false, "emeraldwalk.runonsave": { "commands": [ { @@ -95,7 +82,7 @@ "evenBetterToml.formatter.arrayAutoCollapse": true, "evenBetterToml.formatter.arrayAutoExpand": true, "evenBetterToml.formatter.arrayTrailingComma": true, - "evenBetterToml.formatter.columnWidth": 120, + "evenBetterToml.formatter.columnWidth": 100, "evenBetterToml.formatter.compactArrays": true, "evenBetterToml.formatter.compactEntries": false, "evenBetterToml.formatter.compactInlineTables": false, diff --git a/Dolphin Memory Watches (DMW)/README.md b/Dolphin Memory Watches (DMW)/README.md index 13c7ea7..a195a5f 100644 --- a/Dolphin Memory Watches (DMW)/README.md +++ b/Dolphin Memory Watches (DMW)/README.md @@ -13,7 +13,7 @@ It even explains how to deal with dynamic pointers, which is my current issue wi All codes below are for NTSC Gamecube only -Start in specific Level (by Avasam): +Start in specific Level (by Avasam):\ Replace `XXXX XXXX` by the `asset_crc32` found in [world_infos.json](/Various%20technical%20notes/world_infos.json) ```txt diff --git a/Dolphin scripts/Entrance Randomizer/CONFIGS.py b/Dolphin scripts/Entrance Randomizer/CONFIGS.py index 286fd65..152d35c 100644 --- a/Dolphin scripts/Entrance Randomizer/CONFIGS.py +++ b/Dolphin scripts/Entrance Randomizer/CONFIGS.py @@ -25,7 +25,9 @@ DISABLE_MAPS_IN_SHOP: bool = True """ Whether you can buy maps in the Shaman Shop. -When maps are disabled, and using original shop prices, the 4 lowest prices (0, 1, 2, 2) are also removed form the pool. + +When maps are disabled, and using original shop prices, +the 4 lowest prices (0, 1, 2, 2) are also removed form the pool. """ SHOP_PRICES_RANGE: PriceRange = False # (0, 32) diff --git a/Dolphin scripts/Entrance Randomizer/__main__.py b/Dolphin scripts/Entrance Randomizer/__main__.py index 7e7fc36..ffbb812 100644 --- a/Dolphin scripts/Entrance Randomizer/__main__.py +++ b/Dolphin scripts/Entrance Randomizer/__main__.py @@ -62,7 +62,10 @@ async def main_loop(): f"Starting area: {hex(starting_area)}" + " (Random)" if CONFIGS.STARTING_AREA is None else f"{starting_area_name}", ) - draw_text(f"Current area: {hex(state.current_area_new).upper()} {f'({current_area.name})' if current_area else ''}") + draw_text( + f"Current area: {hex(state.current_area_new).upper()}" + + f"({current_area.name})" if current_area else "", + ) # Always re-enable Item Swap. if memory.read_u32(ADDRESSES.item_swap) == 1: @@ -74,7 +77,8 @@ async def main_loop(): # Standardize the Altar of Ages exit if highjack_transition(ALTAR_OF_AGES, None, MYSTERIOUS_TEMPLE): - # Even if the cutscene isn't actually watched. Just leaving the Altar is good enough for the rando. + # Even if the cutscene isn't actually watched. + # Just leaving the Altar is good enough for the rando. state.visited_altar_of_ages = True state.current_area_new = MYSTERIOUS_TEMPLE diff --git a/Dolphin scripts/Entrance Randomizer/lib/constants.py b/Dolphin scripts/Entrance Randomizer/lib/constants.py index 19fb02d..ceefefc 100644 --- a/Dolphin scripts/Entrance Randomizer/lib/constants.py +++ b/Dolphin scripts/Entrance Randomizer/lib/constants.py @@ -21,7 +21,7 @@ print(f"Rando version: {__version__}") # Sets the seed -seed = CONFIGS.SEED if CONFIGS.SEED else random.randrange(sys.maxsize) +seed = CONFIGS.SEED or random.randrange(sys.maxsize) random.seed(seed) seed_string = hex(seed).upper() if isinstance(seed, int) else seed print("Seed set to:", seed_string) @@ -61,7 +61,8 @@ class Addresses: TODO = 0x0 -# Including the version number seems overkill, I don't think there was ever a non v0. Can add later if needed. +# Including the version number seems overkill, +# I don't think there was ever a non v0. Can add later if needed. if GAME_VERSION != 0: raise Exception(f"Unknown game version {GAME_VERSION}!") _addresses_map = { diff --git a/Dolphin scripts/Entrance Randomizer/lib/entrance_rando.py b/Dolphin scripts/Entrance Randomizer/lib/entrance_rando.py index 1fa3bc3..3439f88 100644 --- a/Dolphin scripts/Entrance Randomizer/lib/entrance_rando.py +++ b/Dolphin scripts/Entrance Randomizer/lib/entrance_rando.py @@ -13,11 +13,7 @@ # Add back areas removed from transitions because of issues ] + [CRASH_SITE, TELEPORTERS] -starting_area = ( - CONFIGS.STARTING_AREA - if CONFIGS.STARTING_AREA - else random.choice(_possible_starting_areas) -) +starting_area = CONFIGS.STARTING_AREA or random.choice(_possible_starting_areas) @dataclass @@ -43,7 +39,8 @@ def get_prev_area_addr(): return addr -def highjack_transition_rando() -> int: # pyright doesn't narrow `int | False` to just `int` after truthy check +# -> int: pyright doesn't narrow `int | False` to just `int` after truthy check +def highjack_transition_rando() -> int: # Early return, faster check if state.current_area_old == state.current_area_new: return False @@ -128,7 +125,8 @@ def _transition_map_set(from_: int, to: int, redirect: int): for to_og in (exit_.area_id for exit_ in area.exits): redirect = get_random_redirection(from_, to_og, _possible_exits_bucket) if redirect is None or transitions_map.get(from_, {}).get(to_og): - # Don't override something set in a previous iteration, like from linked two-way entrances + # Don't override something set in a previous iteration, + # like from linked two-way entrances. continue _transition_map_set(from_, to_og, redirect) diff --git a/Dolphin scripts/Entrance Randomizer/lib/shaman_shop.py b/Dolphin scripts/Entrance Randomizer/lib/shaman_shop.py index eda0f07..222bc58 100644 --- a/Dolphin scripts/Entrance Randomizer/lib/shaman_shop.py +++ b/Dolphin scripts/Entrance Randomizer/lib/shaman_shop.py @@ -52,7 +52,12 @@ class ShopCountOffset(IntEnum): _shaman_shop_prices_string = "" -def randint_with_bias(a: int, b: int, bias: int = 1, direction: Literal["start", "middle"] = "middle"): +def randint_with_bias( + a: int, + b: int, + bias: int = 1, + direction: Literal["start", "middle"] = "middle", +): """ Run randint multiple times then averaged and rounded to create a bell-curve bias. @@ -91,7 +96,9 @@ def randomize_shaman_shop(): if ADDRESSES.shaman_shop_struct == TODO: return - _shaman_shop_prices = MAPLESS_SHOP_PRICES[:] if CONFIGS.DISABLE_MAPS_IN_SHOP else DEFAULT_SHOP_PRICES[:] + _shaman_shop_prices = MAPLESS_SHOP_PRICES[:] \ + if CONFIGS.DISABLE_MAPS_IN_SHOP \ + else DEFAULT_SHOP_PRICES[:] if CONFIGS.SHOP_PRICES_RANGE: shop_size = len(_shaman_shop_prices) @@ -100,7 +107,7 @@ def randomize_shaman_shop(): minimum_max_price = equal_price_per_item + 1 max_price = max(minimum_max_price, CONFIGS.SHOP_PRICES_RANGE[1]) min_price = min(max_price, equal_price_per_item, CONFIGS.SHOP_PRICES_RANGE[0]) - _shaman_shop_prices = [] + _shaman_shop_prices: list[int] = [] for items_left in range(shop_size, 0, -1): # Ensure we don't bust the total of idols max_price = min(idols_left, max_price) @@ -111,8 +118,8 @@ def randomize_shaman_shop(): # Ensure a full fill when possible if max_price * (items_left - 1) <= idols_left: - # Last few items in the shop, and it's currently possible for low rolls to not total 138, - # use as many idols as as needed + # Last few items in the shop, and it's currently possible for + # low rolls to not total 138, use as many idols as as needed min_price = maximum_min_price # Ramp up min_price to avoid having to deal with a bunch of forced 0 price near the end # note we already know that `max_price <= idols_left` so no need to check @@ -121,13 +128,11 @@ def randomize_shaman_shop(): # Strongly bias the distribution towards the middle price = randint_with_bias(min_price, max_price, 3, "start") - print(f"\n{idols_left=}, {price=}, {min_price=}, {max_price=}, {maximum_min_price=}, {items_left=}\n") + print(f"\n{idols_left=}, {price=}, {min_price=}, {max_price=}, {maximum_min_price=}, {items_left=}\n") # noqa: E501 idols_left -= price if idols_left < 0: - raise RuntimeError( - f"Oops, somehow we used too many idols! {idols_left=}, {price=}, {min_price=}, {max_price=}", - ) + raise RuntimeError(f"Oops, somehow we used too many idols! {idols_left=}, {price=}, {min_price=}, {max_price=}") # noqa: E501 _shaman_shop_prices.append(price) # Try to avoid repeated low prices @@ -139,9 +144,7 @@ def randomize_shaman_shop(): max_price -= 1 if sum(_shaman_shop_prices) != MAX_IDOLS: - raise RuntimeError( - f"{_shaman_shop_prices=} totals {sum(_shaman_shop_prices)}, which isn't {MAX_IDOLS}.", - ) + raise RuntimeError(f"{_shaman_shop_prices=} totals {sum(_shaman_shop_prices)}, which isn't {MAX_IDOLS}.") # noqa: E501 random.shuffle(_shaman_shop_prices) if CONFIGS.DISABLE_MAPS_IN_SHOP: diff --git a/Dolphin scripts/Entrance Randomizer/lib/utils.py b/Dolphin scripts/Entrance Randomizer/lib/utils.py index 139e1eb..42edf01 100644 --- a/Dolphin scripts/Entrance Randomizer/lib/utils.py +++ b/Dolphin scripts/Entrance Randomizer/lib/utils.py @@ -28,7 +28,11 @@ def draw_text(text: str): _draw_text_index += 1 -def dump_spoiler_logs(starting_area_name: str, transitions_map: dict[int, dict[int, int]], seed_string: SeedType): +def dump_spoiler_logs( + starting_area_name: str, + transitions_map: dict[int, dict[int, int]], + seed_string: SeedType, +): spoiler_logs = f"Starting area: {starting_area_name}\n" for from_, to_old_and_new in transitions_map.items(): for to_old, to_new in to_old_and_new.items(): @@ -36,10 +40,15 @@ def dump_spoiler_logs(starting_area_name: str, transitions_map: dict[int, dict[i f"To: {TRANSITION_INFOS_DICT[to_old].name}. " + \ f"Redirecting to: {TRANSITION_INFOS_DICT[to_new].name}\n" - # TODO: Get actual user folder based whether Dolphin Emulator is in AppData/Roaming + # TODO (Avasam): Get actual user folder based whether Dolphin Emulator is in AppData/Roaming # and if the current installation is portable. dolphin_path = Path().absolute() - spoiler_logs_file = dolphin_path / "User" / "Logs" / f"SPOILER_LOGS_v{__version__}_{seed_string}.txt" + spoiler_logs_file = ( + dolphin_path + / "User" + / "Logs" + / f"SPOILER_LOGS_v{__version__}_{seed_string}.txt" + ) Path.mkdir(spoiler_logs_file.parent, parents=True, exist_ok=True) Path.write_text(spoiler_logs_file, spoiler_logs) print("Spoiler logs written to", spoiler_logs_file) diff --git a/Dolphin scripts/requirements-dev.txt b/Dolphin scripts/requirements-dev.txt index 7b9f161..4fef1a0 100644 --- a/Dolphin scripts/requirements-dev.txt +++ b/Dolphin scripts/requirements-dev.txt @@ -1,4 +1,4 @@ -add-trailing-comma>=2.4.0 # Added support for with statement -autopep8>=2.0.2 # New checks # Must match .pre-commit-config.yaml +add-trailing-comma>=3.1.0 # Must match .pre-commit-config.yaml +autopep8>=2.1.0 # Must match .pre-commit-config.yaml pre-commit -ruff>=0.0.277 # New Bandit checks and fixed issue # Must match .pre-commit-config.yaml +ruff>=0.4.2 # Must match .pre-commit-config.yaml diff --git a/Dolphin scripts/typings/dolphin.pyi b/Dolphin scripts/typings/dolphin.pyi index 0eb264d..140dfe0 100644 --- a/Dolphin scripts/typings/dolphin.pyi +++ b/Dolphin scripts/typings/dolphin.pyi @@ -23,9 +23,9 @@ import dolphin_memory as memory import dolphin_savestate as savestate __all__ = [ + "controller", "event", - "memory", "gui", + "memory", "savestate", - "controller", ] diff --git a/README.md b/README.md index 0eebff1..04fa8a0 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,9 @@ Various graphical modifications and post-processing effects using [Dolphin's Gra Read more about [Dolphin Custom Texure Projects](https://forums.dolphin-emu.org/Thread-how-to-install-texture-packs-custom-textures-info). - [PC to Dolphin Texture Pack generator](/Texture%20packs/Dolphin%20PC%20texture%20pack%20generator) (higher resolution textures from the PC version) -- [Dynamic Input Pack](https://github.com/Venomalia/UniversalDynamicInput#how-to-install-the-pack) (display non-GameCube/Wii controller buttons) - Download: +- [Dynamic Input Pack](https://github.com/Venomalia/UniversalDynamicInput#how-to-install-the-pack) (display non-GameCube/Wii controller buttons) + \ + Download: \ |![Controls Remap](https://user-images.githubusercontent.com/1350584/233196583-abc829b4-59cd-4f86-bb2c-26b3e6fb7d7f.png)|![Looking Around](https://user-images.githubusercontent.com/1350584/233196608-ce722296-8a88-4634-a08c-ce6dca7712c2.png)|![Switches](https://user-images.githubusercontent.com/1350584/233196610-30e426d7-6a2d-4426-96d5-4151567d2981.png)|![Vine Climbing](https://user-images.githubusercontent.com/1350584/233196611-861ceda7-8670-45dc-a52b-72e3cd40aca3.png) |-|-|-|-| |![Vine Steering](https://user-images.githubusercontent.com/1350584/233196612-fe30350b-ed69-43de-bedc-f8d842240714.png)|![Camera](https://user-images.githubusercontent.com/1350584/233196615-7aae3a68-9daf-45ae-a17f-a42ad4082411.png)|![Items](https://user-images.githubusercontent.com/1350584/233196617-4bc996d4-06f3-4301-a813-e6ceac37167b.png)|![Super Sling](https://user-images.githubusercontent.com/1350584/233208007-9eb4379a-8e35-4cd4-bbbd-2660965decb5.png) diff --git a/Texture packs/Dolphin PC texture pack generator/.EditorConfig b/Texture packs/Dolphin PC texture pack generator/.EditorConfig deleted file mode 100644 index 8dd334e..0000000 --- a/Texture packs/Dolphin PC texture pack generator/.EditorConfig +++ /dev/null @@ -1,138 +0,0 @@ -# EditorConfig is awesome: https://EditorConfig.org -# top-most EditorConfig file -root = true - -# Default configs for all files -[*] -indent_style = space -indent_size = 2 -tab_width = 2 -end_of_line = lf -charset = utf-8-bom -trim_trailing_whitespace = true -insert_final_newline = true -max_line_length = 120 - -[*.md] -trim_trailing_whitespace = false - -# Python and type stubs -[*.py?(i)] -indent_size = 4 -tab_width = 4 - -# Started from dotnet defaults: https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options#example-editorconfig-file - -############################### -# .NET Coding Conventions # -############################### -[*.{cs,vb}] -# Organize usings -dotnet_sort_system_directives_first = true -# this. preferences -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_property = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_event = false:silent -# Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent -# Parentheses preferences -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent -# Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent -dotnet_style_readonly_field = true:suggestion -# Expression-level preferences -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent -############################### -# Naming Conventions # -############################### -# Style Definitions -dotnet_naming_style.pascal_case_style.capitalization = pascal_case -# Use PascalCase for constant fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style -dotnet_naming_symbols.constant_fields.applicable_kinds = field -dotnet_naming_symbols.constant_fields.applicable_accessibilities = * -dotnet_naming_symbols.constant_fields.required_modifiers = const -############################### -# C# Coding Conventions # -############################### -[*.cs] -# var preferences -csharp_style_var_for_built_in_types = true:silent -csharp_style_var_when_type_is_apparent = true:silent -csharp_style_var_elsewhere = true:silent -# Expression-bodied members -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_accessors = true:silent -# Pattern matching preferences -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -# Null-checking preferences -csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion -# Modifier preferences -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion -# Expression-level preferences -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_prefer_local_over_anonymous_function = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -############################### -# C# Formatting Rules # -############################### -# New line preferences -csharp_new_line_before_open_brace = all -csharp_new_line_before_else = true -csharp_new_line_before_catch = true -csharp_new_line_before_finally = true -csharp_new_line_before_members_in_object_initializers = true -csharp_new_line_before_members_in_anonymous_types = true -csharp_new_line_between_query_expression_clauses = true -# Indentation preferences -csharp_indent_case_contents = true -csharp_indent_switch_labels = true -csharp_indent_labels = flush_left -# Space preferences -csharp_space_after_cast = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_parentheses = false -csharp_space_before_colon_in_inheritance_clause = true -csharp_space_after_colon_in_inheritance_clause = true -csharp_space_around_binary_operators = before_and_after -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -# Wrapping preferences -csharp_preserve_single_line_statements = true -csharp_preserve_single_line_blocks = true - -############################### -# Differs from defaults # -############################### - -# Allows if-guards -csharp_prefer_braces = when_multiline:silent -# Don't force using discard variables -dotnet_diagnostic.IDE0058.severity = none diff --git a/Texture packs/Dolphin PC texture pack generator/Console Generator/ImageUtils.cs b/Texture packs/Dolphin PC texture pack generator/Console Generator/ImageUtils.cs index 4c7f0f1..bc44e5e 100644 --- a/Texture packs/Dolphin PC texture pack generator/Console Generator/ImageUtils.cs +++ b/Texture packs/Dolphin PC texture pack generator/Console Generator/ImageUtils.cs @@ -1,42 +1,43 @@ using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; -namespace PCTexturePackGeneratorConsole +namespace PCTexturePackGeneratorConsole; + +internal class ImageUtils { - internal class ImageUtils + // Copied from TexConvert.cs + public static (Image, Image) SplitAlphaTexture(Image image) { - // Copied from TexConvert.cs - public static (Image, Image) SplitAlphaTexture(Image image) + var colorPixels = new Rgba32[image.Width * image.Height]; + var alphaPixels = new Rgba32[image.Width * image.Height]; + image.CopyPixelDataTo(colorPixels); + image.CopyPixelDataTo(alphaPixels); + for (var i = 0; i < colorPixels.Length; i++) { - var colorPixels = new Rgba32[image.Width * image.Height]; - var alphaPixels = new Rgba32[image.Width * image.Height]; - image.CopyPixelDataTo(colorPixels); - image.CopyPixelDataTo(alphaPixels); - for (var i = 0; i < colorPixels.Length; i++) - { - colorPixels[i].A = 255; - alphaPixels[i] = new Rgba32(0, alphaPixels[i].A, 0, 255); - } - return ( - Image.LoadPixelData(colorPixels, image.Width, image.Height), - Image.LoadPixelData(alphaPixels, image.Width, image.Height)); + colorPixels[i].A = 255; + alphaPixels[i] = new Rgba32(0, alphaPixels[i].A, 0, 255); } - // Copied from TexConvert.cs - public static (Image, Image) SplitBATexture(Image image) + return ( + Image.LoadPixelData(colorPixels, image.Width, image.Height), + Image.LoadPixelData(alphaPixels, image.Width, image.Height)); + } + + // Copied from TexConvert.cs + public static (Image, Image) SplitBATexture(Image image) + { + var rgPixels = new Rgba32[image.Width * image.Height]; + var baPixels = new Rgba32[image.Width * image.Height]; + image.CopyPixelDataTo(rgPixels); + image.CopyPixelDataTo(baPixels); + for (var i = 0; i < rgPixels.Length; i++) { - var rgPixels = new Rgba32[image.Width * image.Height]; - var baPixels = new Rgba32[image.Width * image.Height]; - image.CopyPixelDataTo(rgPixels); - image.CopyPixelDataTo(baPixels); - for (var i = 0; i < rgPixels.Length; i++) - { - rgPixels[i] = new Rgba32(rgPixels[i].R, rgPixels[i].R, rgPixels[i].R, rgPixels[i].G); - baPixels[i] = new Rgba32(baPixels[i].B, baPixels[i].B, baPixels[i].B, baPixels[i].A); - } - return ( - Image.LoadPixelData(rgPixels, image.Width, image.Height), - Image.LoadPixelData(baPixels, image.Width, image.Height)); + rgPixels[i] = new Rgba32(rgPixels[i].R, rgPixels[i].R, rgPixels[i].R, rgPixels[i].G); + baPixels[i] = new Rgba32(baPixels[i].B, baPixels[i].B, baPixels[i].B, baPixels[i].A); } + + return ( + Image.LoadPixelData(rgPixels, image.Width, image.Height), + Image.LoadPixelData(baPixels, image.Width, image.Height)); } } diff --git a/Texture packs/Dolphin PC texture pack generator/Console Generator/Program.cs b/Texture packs/Dolphin PC texture pack generator/Console Generator/Program.cs index 4ad589c..3829090 100644 --- a/Texture packs/Dolphin PC texture pack generator/Console Generator/Program.cs +++ b/Texture packs/Dolphin PC texture pack generator/Console Generator/Program.cs @@ -1,4 +1,4 @@ -using System.IO.Compression; +using System.IO.Compression; using System.Reflection; using System.Text.Json; using PCTexturePackGeneratorConsole; @@ -32,7 +32,6 @@ Console.WriteLine(""); if (exitCode != 0) return exitCode; - Directory.CreateDirectory(workingPackFolder); Directory.CreateDirectory(gcGameTexturesFolder); Directory.CreateDirectory(wiiGameTexturesFolder); @@ -42,6 +41,7 @@ { copy.Save(Path.Join(workingPackFolder, "logo.png")); } + Console.WriteLine("Creating manifest.json"); File.WriteAllText( Path.Join(workingPackFolder, "manifest.json"), @@ -58,7 +58,6 @@ ); Console.WriteLine(""); - // First loop to remove unused textures and rename LODs foreach (var textureFileInfo in convertedTexturesDirectoryInfo.GetFiles()) { @@ -94,7 +93,6 @@ } } - Console.WriteLine("\nConverting textures to Dolphin format..."); // Second loop to do the Dolphin name and format conversion foreach (var textureFileInfo in convertedTexturesDirectoryInfo.GetFiles()) @@ -124,6 +122,7 @@ a.Dispose(); b.Dispose(); } + File.Delete(textureFileInfo.FullName); } else @@ -139,6 +138,7 @@ { File.Delete(resorucePackFilePath); } + ZipFile.CreateFromDirectory(workingPackFolder, resorucePackFilePath, CompressionLevel.SmallestSize, false); Console.WriteLine("Done!"); diff --git a/Texture packs/Dolphin PC texture pack generator/Dolphin PC texture pack generator.sln b/Texture packs/Dolphin PC texture pack generator/Dolphin PC texture pack generator.sln index 31823a4..0c307c1 100644 --- a/Texture packs/Dolphin PC texture pack generator/Dolphin PC texture pack generator.sln +++ b/Texture packs/Dolphin PC texture pack generator/Dolphin PC texture pack generator.sln @@ -13,10 +13,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PitfallARCTool", "..\..\Pit EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{022964B5-C052-491F-80BC-02959384313C}" ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig + ..\..\.editorconfig = ..\..\.editorconfig EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TexturePackCleanup", "TexturePackCleanup\TexturePackCleanup.csproj", "{9C85E81A-9E2F-4C5D-918C-E0A489B13F60}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TexturePackCleanup", "TexturePackCleanup\TexturePackCleanup.csproj", "{9C85E81A-9E2F-4C5D-918C-E0A489B13F60}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Texture packs/Dolphin PC texture pack generator/GUI/Form1.cs b/Texture packs/Dolphin PC texture pack generator/GUI/Form1.cs index 277e926..473b578 100644 --- a/Texture packs/Dolphin PC texture pack generator/GUI/Form1.cs +++ b/Texture packs/Dolphin PC texture pack generator/GUI/Form1.cs @@ -1,9 +1,9 @@ -namespace PCTexturePackGeneratorGUI +namespace PCTexturePackGeneratorGUI; + +public partial class Form1 : Form { - public partial class Form1 : Form - { - public Form1() { - InitializeComponent(); - } - } + public Form1() + { + InitializeComponent(); + } } diff --git a/Texture packs/Dolphin PC texture pack generator/TexturePackCleanup/Utils.cs b/Texture packs/Dolphin PC texture pack generator/TexturePackCleanup/Utils.cs index 06129e4..0592b75 100644 --- a/Texture packs/Dolphin PC texture pack generator/TexturePackCleanup/Utils.cs +++ b/Texture packs/Dolphin PC texture pack generator/TexturePackCleanup/Utils.cs @@ -1,226 +1,225 @@ using System.Text.Json; -namespace TexturePackCleanup +namespace TexturePackCleanup; + +public static class Utils { - public static class Utils + private static Dictionary _GetDteTextureMap() { - private static Dictionary _GetDteTextureMap() - { - var dteTextureMapJson = File.ReadAllText(".\\DTETextureMap.jsonc"); - var dteTextureMap = JsonSerializer.Deserialize>( - dteTextureMapJson, - new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip } - ); - return dteTextureMap ?? throw new NullReferenceException(nameof(dteTextureMap) + " is null."); - } + var dteTextureMapJson = File.ReadAllText(".\\DTETextureMap.jsonc"); + var dteTextureMap = JsonSerializer.Deserialize>( + dteTextureMapJson, + new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip } + ); + return dteTextureMap ?? throw new NullReferenceException(nameof(dteTextureMap) + " is null."); + } - private static Dictionary? _dteTextureMap = null; + private static Dictionary? _dteTextureMap = null; - public static Dictionary DteTextureMap => _dteTextureMap ??= _GetDteTextureMap(); + public static Dictionary DteTextureMap => _dteTextureMap ??= _GetDteTextureMap(); - // Checks whether a texture is used on GameCube/Wii - public static bool IsUsedOnDolphin(string textureName, bool isDolphinHashedName, out string unusedReason) + // Checks whether a texture is used on GameCube/Wii + public static bool IsUsedOnDolphin(string textureName, bool isDolphinHashedName, out string unusedReason) + { + if (isDolphinHashedName) { - if (isDolphinHashedName) + if (!DteTextureMap.Values.SelectMany(x => x).Contains(textureName)) { - if (!DteTextureMap.Values.SelectMany(x => x).Contains(textureName)) - { - unusedReason = "it does not exist in the GameCube version's textures archive"; - return false; - }; - if (UnusedTexturesDolphin - .SelectMany(unusedTexture => DteTextureMap[unusedTexture]) - .Contains(textureName)) - { - unusedReason = "it's known to be unused on GameCube & Wii"; - return false; - }; - } - else + unusedReason = "it does not exist in the GameCube version's textures archive"; + return false; + }; + if (UnusedTexturesDolphin + .SelectMany(unusedTexture => DteTextureMap[unusedTexture]) + .Contains(textureName)) { - if (UnusedTexturesDolphin.Contains(textureName)) - { - unusedReason = "it does not exist in the GameCube version's textures archive"; - return false; - } - - if (!DteTextureMap.ContainsKey(textureName)) - { - unusedReason = "it's known to be unused on GameCube & Wii"; - return false; - } + unusedReason = "it's known to be unused on GameCube & Wii"; + return false; + }; + } + else + { + if (UnusedTexturesDolphin.Contains(textureName)) + { + unusedReason = "it does not exist in the GameCube version's textures archive"; + return false; } - unusedReason = ""; - return true; + if (!DteTextureMap.ContainsKey(textureName)) + { + unusedReason = "it's known to be unused on GameCube & Wii"; + return false; + } } - // Map the Level of Details textures to their higher resolution equivalents. - public static Dictionary LodMapping = new() - { - // ["LOD"] = "higher_res", - ["tucotuco_rotisserie"] = "tucotuco", - ["kh_steelwire"] = "jm_steelwire03p", - ["harry_whiphat"] = "icon_sling", - ["torch-01"] = "icon_torch", - ["supai_eye_glow"] = "jungle_rt_light_beam_spot_01", - ["c00_ws_rockwall"] = "small_c00_ws_rockwall", // Not a mistake, "small" is bigger - ["harry_ice_pick_128"] = "icon_pickaxe", - ["a_kg_vistaa"] = "a_kg_vistaa_256", - ["a_kg_vistab"] = "a_kg_vistab_256", - ["a_figleaf3_lod"] = "a_figleaf3", - ["a_kg_palm_leaf03_lod"] = "a_kg_palm_leaf03", - ["bernard_legs_lod"] = "bernard_legs", - ["bernard_head_lod"] = "bernard_head", - ["explorerlegs_type2_lod"] = "explorerlegs_type2", - ["explorerhead_lod"] = "explorerhead", - ["explorerhead_type2_lod"] = "explorerhead_type2", - ["croc3_body_lod"] = "croc3_body", - ["eel_lod"] = "eel", - ["croc3_tail_lod"] = "croc3_tail", - ["explorerlegs_lod"] = "explorerlegs", - ["henchman_body_lod"] = "henchman_body", - ["henchman_head_lod"] = "henchman_head", - ["howler_lod"] = "howler", - ["gen_native_legs_lod"] = "gen_native_legs", - ["gen_native_pouch_lod"] = "gen_native_pouch", - ["gen_native_torso_lod"] = "gen_native_torso", - ["jungle_jj_planta_lod"] = "jungle_jj_planta", - ["leech_body_lod"] = "leech_body", - ["leech_head_lod"] = "leech_head", - ["monkey2_lod"] = "monkey2", - ["native_mask_lod"] = "native_mask", - ["monkeybaby_texturecloth_lod"] = "monkeybaby_texturecloth", - ["monkeymom_texture_lod"] = "monkeymom_texture", - ["renegade_native_torso_lod"] = "renegade_native_torso", - ["shaman_native_torso_lod"] = "shaman_native_torso", - ["penguin_map_lod"] = "penguin_map", - ["porcu_texture_lod"] = "porcu_texture", - ["micay_legs_lod"] = "micay_legs", - ["snblowler_legs_lod"] = "snblowler_legs", - ["micay_torso_lod"] = "micay_torso", - ["snbowler_ball_lod"] = "snbowler_ball", - ["noxious_lod"] = "noxious", - ["snbowler_mask_lod"] = "snbowler_mask", - ["snbowler_torso_lod"] = "snbowler_torso", - ["renegade_native_legs_lod"] = "renegade_native_legs", - ["scarab_lod"] = "scarab", - ["renegade_native_mask_lod"] = "renegade_native_mask", - ["spinja_legs_lod"] = "spinja_legs", - ["spinja_mask_lod"] = "spinja_mask", - ["spinja_torso_lod"] = "spinja_torso", - ["shaman_native_legs_lod"] = "shaman_native_legs", - ["shaman_native_mask_lod"] = "shaman_native_mask", - ["tucotuco_body_lod"] = "tucotuco_body", - }; + unusedReason = ""; + return true; + } - // Textures that we know for certain are unused on GameCube/Wii - public static HashSet UnusedTexturesDolphin = new() + // Map the Level of Details textures to their higher resolution equivalents. + public static Dictionary LodMapping = new() { - // Unused icons - "icon_emptyslot", - "icon_inv_pogostilt", - "heroic", - // TODO: Validate! - //"icon_emptyhand", - //"icon_pickaxe", - //"icon_torch", - //"icon_save_shaman", - //"icon_save_idol", - //"icon_sling", - //"harry_whiphat", - // Xbox - "legal_screen_xbox_english", - "book_page_options_controls_remap_xbox", - "button_xbx_a", - "button_xbx_analog_left_down", - "button_xbx_analog_left_left", - "button_xbx_analog_left_leftright", - "button_xbx_analog_left_none", - "button_xbx_analog_left_right", - "button_xbx_analog_left_up", - "button_xbx_analog_left_updown", - "button_xbx_analog_right_down", - "button_xbx_analog_right_left", - "button_xbx_analog_right_leftright", - "button_xbx_analog_right_none", - "button_xbx_analog_right_right", - "button_xbx_analog_right_up", - "button_xbx_b", - "button_xbx_black", - "button_xbx_dpad_down", - "button_xbx_dpad_left", - "button_xbx_dpad_right", - "button_xbx_dpad_up", - "button_xbx_l", - "button_xbx_r", - "button_xbx_start", - "button_xbx_white", - "button_xbx_x", - "button_xbx_y", - // PS2 - "insert_controller", - "legal_screen_ps2_english", - "book_page_options_controls_remap_ps2", - "button_ps2_analog_left_down", - "button_ps2_analog_left_left", - "button_ps2_analog_left_leftright", - "button_ps2_analog_left_none", - "button_ps2_analog_left_right", - "button_ps2_analog_left_up", - "button_ps2_analog_left_updown", - "button_ps2_analog_right_down", - "button_ps2_analog_right_left", - "button_ps2_analog_right_leftright", - "button_ps2_analog_right_none", - "button_ps2_analog_right_right", - "button_ps2_analog_right_up", - "button_ps2_analog_right_updown", - "button_ps2_circle", - "button_ps2_dpad_down", - "button_ps2_dpad_left", - "button_ps2_dpad_right", - "button_ps2_dpad_up", - "button_ps2_l1", - "button_ps2_l2", - "button_ps2_r1", - "button_ps2_r2", - "button_ps2_square", - "button_ps2_start", - "button_ps2_triangle", - "button_ps2_x", - // Demo - "a05", - "a50", - "b15", - "c02", - "s14", - "book_page_opm_controls", - "opmcontrolscreen", - "opmexitscreenall", - "opmexitscreennotall", - "opmlegalscreen", - "opmtitlescreen", - // Early dev - "font_systemfont_s12_p0", - "legal_screen_bad", - "lifepiplevel1", - "lifepiplevel2", - "lifepiplevel3", - "lifepiplevel4", - "lifepipoff", - "lifepipon", - "screendeveloper", - "screenpublisher", - "a28", - "a29", - "a30", - "a31", - "a32", - "c07", - "b09", - // TODO: Book overlays and inserts! - // TODO: Supai + // ["LOD"] = "higher_res", + ["tucotuco_rotisserie"] = "tucotuco", + ["kh_steelwire"] = "jm_steelwire03p", + ["harry_whiphat"] = "icon_sling", + ["torch-01"] = "icon_torch", + ["supai_eye_glow"] = "jungle_rt_light_beam_spot_01", + ["c00_ws_rockwall"] = "small_c00_ws_rockwall", // Not a mistake, "small" is bigger + ["harry_ice_pick_128"] = "icon_pickaxe", + ["a_kg_vistaa"] = "a_kg_vistaa_256", + ["a_kg_vistab"] = "a_kg_vistab_256", + ["a_figleaf3_lod"] = "a_figleaf3", + ["a_kg_palm_leaf03_lod"] = "a_kg_palm_leaf03", + ["bernard_legs_lod"] = "bernard_legs", + ["bernard_head_lod"] = "bernard_head", + ["explorerlegs_type2_lod"] = "explorerlegs_type2", + ["explorerhead_lod"] = "explorerhead", + ["explorerhead_type2_lod"] = "explorerhead_type2", + ["croc3_body_lod"] = "croc3_body", + ["eel_lod"] = "eel", + ["croc3_tail_lod"] = "croc3_tail", + ["explorerlegs_lod"] = "explorerlegs", + ["henchman_body_lod"] = "henchman_body", + ["henchman_head_lod"] = "henchman_head", + ["howler_lod"] = "howler", + ["gen_native_legs_lod"] = "gen_native_legs", + ["gen_native_pouch_lod"] = "gen_native_pouch", + ["gen_native_torso_lod"] = "gen_native_torso", + ["jungle_jj_planta_lod"] = "jungle_jj_planta", + ["leech_body_lod"] = "leech_body", + ["leech_head_lod"] = "leech_head", + ["monkey2_lod"] = "monkey2", + ["native_mask_lod"] = "native_mask", + ["monkeybaby_texturecloth_lod"] = "monkeybaby_texturecloth", + ["monkeymom_texture_lod"] = "monkeymom_texture", + ["renegade_native_torso_lod"] = "renegade_native_torso", + ["shaman_native_torso_lod"] = "shaman_native_torso", + ["penguin_map_lod"] = "penguin_map", + ["porcu_texture_lod"] = "porcu_texture", + ["micay_legs_lod"] = "micay_legs", + ["snblowler_legs_lod"] = "snblowler_legs", + ["micay_torso_lod"] = "micay_torso", + ["snbowler_ball_lod"] = "snbowler_ball", + ["noxious_lod"] = "noxious", + ["snbowler_mask_lod"] = "snbowler_mask", + ["snbowler_torso_lod"] = "snbowler_torso", + ["renegade_native_legs_lod"] = "renegade_native_legs", + ["scarab_lod"] = "scarab", + ["renegade_native_mask_lod"] = "renegade_native_mask", + ["spinja_legs_lod"] = "spinja_legs", + ["spinja_mask_lod"] = "spinja_mask", + ["spinja_torso_lod"] = "spinja_torso", + ["shaman_native_legs_lod"] = "shaman_native_legs", + ["shaman_native_mask_lod"] = "shaman_native_mask", + ["tucotuco_body_lod"] = "tucotuco_body", }; - } + + // Textures that we know for certain are unused on GameCube/Wii + public static HashSet UnusedTexturesDolphin = new() +{ + // Unused icons + "icon_emptyslot", + "icon_inv_pogostilt", + "heroic", + // TODO: Validate! + //"icon_emptyhand", + //"icon_pickaxe", + //"icon_torch", + //"icon_save_shaman", + //"icon_save_idol", + //"icon_sling", + //"harry_whiphat", + // Xbox + "legal_screen_xbox_english", + "book_page_options_controls_remap_xbox", + "button_xbx_a", + "button_xbx_analog_left_down", + "button_xbx_analog_left_left", + "button_xbx_analog_left_leftright", + "button_xbx_analog_left_none", + "button_xbx_analog_left_right", + "button_xbx_analog_left_up", + "button_xbx_analog_left_updown", + "button_xbx_analog_right_down", + "button_xbx_analog_right_left", + "button_xbx_analog_right_leftright", + "button_xbx_analog_right_none", + "button_xbx_analog_right_right", + "button_xbx_analog_right_up", + "button_xbx_b", + "button_xbx_black", + "button_xbx_dpad_down", + "button_xbx_dpad_left", + "button_xbx_dpad_right", + "button_xbx_dpad_up", + "button_xbx_l", + "button_xbx_r", + "button_xbx_start", + "button_xbx_white", + "button_xbx_x", + "button_xbx_y", + // PS2 + "insert_controller", + "legal_screen_ps2_english", + "book_page_options_controls_remap_ps2", + "button_ps2_analog_left_down", + "button_ps2_analog_left_left", + "button_ps2_analog_left_leftright", + "button_ps2_analog_left_none", + "button_ps2_analog_left_right", + "button_ps2_analog_left_up", + "button_ps2_analog_left_updown", + "button_ps2_analog_right_down", + "button_ps2_analog_right_left", + "button_ps2_analog_right_leftright", + "button_ps2_analog_right_none", + "button_ps2_analog_right_right", + "button_ps2_analog_right_up", + "button_ps2_analog_right_updown", + "button_ps2_circle", + "button_ps2_dpad_down", + "button_ps2_dpad_left", + "button_ps2_dpad_right", + "button_ps2_dpad_up", + "button_ps2_l1", + "button_ps2_l2", + "button_ps2_r1", + "button_ps2_r2", + "button_ps2_square", + "button_ps2_start", + "button_ps2_triangle", + "button_ps2_x", + // Demo + "a05", + "a50", + "b15", + "c02", + "s14", + "book_page_opm_controls", + "opmcontrolscreen", + "opmexitscreenall", + "opmexitscreennotall", + "opmlegalscreen", + "opmtitlescreen", + // Early dev + "font_systemfont_s12_p0", + "legal_screen_bad", + "lifepiplevel1", + "lifepiplevel2", + "lifepiplevel3", + "lifepiplevel4", + "lifepipoff", + "lifepipon", + "screendeveloper", + "screenpublisher", + "a28", + "a29", + "a30", + "a31", + "a32", + "c07", + "b09", + // TODO: Book overlays and inserts! + // TODO: Supai +}; } diff --git a/dprint.json b/dprint.json index 65cf427..34805f5 100644 --- a/dprint.json +++ b/dprint.json @@ -1,6 +1,6 @@ { - "extends": "https://raw.githubusercontent.com/Samuel-Therrien-Beslogic/beslogic-dprint-configuration/main/dprint.json", - "includes": ["**/*"], + // https://dprint.dev/config/#extending-a-different-configuration-file + "extends": "https://raw.githubusercontent.com/BesLogic/shared-configs/main/dprint.json", "excludes": [ "**/node_modules", "**/*-lock.json", diff --git a/pyproject.toml b/pyproject.toml index 574be70..d963930 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,40 @@ -# https://beta.ruff.rs/docs/configuration +# The source skeleton for this configuration can be found at +# https://github.com/BesLogic/shared-configs/blob/main/ruff.toml +# Modifications to this file that are not project-specific should also be done upstream. +# These configs were last updated for ruff==0.3.7 +# https://docs.astral.sh/ruff/configuration/ [tool.ruff] -line-length = 120 +line-length = 100 +preview = true +target-version = "py38" # Change this to the oldest supported version by your application +# Exclude auto-generated files +# exclude = [""] + +# https://docs.astral.sh/ruff/settings/#flake8-implicit-str-concat +[tool.ruff.lint.flake8-implicit-str-concat] +allow-multiline = false + +# https://docs.astral.sh/ruff/settings/#isort +[tool.ruff.lint.isort] +combine-as-imports = true +split-on-trailing-comma = false + +# https://docs.astral.sh/ruff/settings/#mccabe +[tool.ruff.lint.mccabe] +# Hard limit, arbitrary to 4 bytes +# max-complexity = 31 +# Arbitrary to 2 bytes, same as SonarLint +max-complexity = 15 + +[tool.ruff.lint.pylint] +# Arbitrary to 1 byte, same as SonarLint +max-args = 7 +# At least same as max-complexity +max-branches = 15 + +[tool.ruff.lint] select = ["ALL"] -target-version = "py38" -# https://beta.ruff.rs/docs/rules +# https://docs.astral.sh/ruff/rules/ ignore = [ ### # Not needed or wanted @@ -11,7 +42,10 @@ ignore = [ "D1", # pydocstyle Missing doctring "D401", # pydocstyle: non-imperative-mood "EM", # flake8-errmsg - "FBT", # flake8-boolean-trap + "EXE", # flake8-executable + # This is often something we can't control: https://github.com/astral-sh/ruff/issues/9497 + # Also false-positive with positional-only arguments: https://github.com/astral-sh/ruff/issues/3247 + "FBT003", # flake8-boolean-trap: boolean-positional-value-in-call "INP", # flake8-no-pep420 "ISC003", # flake8-implicit-str-concat: explicit-string-concatenation # Short messages are still considered "long" messages @@ -20,7 +54,9 @@ ignore = [ "ERA001", # eradicate: commented-out-code # contextlib.suppress is roughly 3x slower than try/except "SIM105", # flake8-simplify: use-contextlib-suppress - # Checked by type-checker (pyright) + # Negative performance impact and more verbose https://github.com/astral-sh/ruff/issues/7871 + "UP038", # non-pep604-isinstance + # Checked by type-checker (pyright/mypy) "ANN", # flake-annotations "PGH003", # blanket-type-ignore "TCH", # flake8-type-checking @@ -33,7 +69,7 @@ ignore = [ "TD001", # flake8-todos: invalid-todo-tag ### - # These should be warnings (https://github.com/charliermarsh/ruff/issues/1256) + # These should be warnings (https://github.com/astral-sh/ruff/issues/1256 & https://github.com/astral-sh/ruff/issues/1774) ### "FIX", # flake8-fixme # Not all TODOs are worth an issue, this would be better as a warning @@ -41,16 +77,41 @@ ignore = [ # False-positives "TCH004", # https://github.com/astral-sh/ruff/issues/3821 + + ### + # Specific to this project + ### + "CPY001", # missing-copyright-notice: Assume license from root + + ### FIXME/TODO: I'd normally set them as temporarily warnings, but no warnings in Ruff yet: + ### https://github.com/astral-sh/ruff/issues/1256 & https://github.com/astral-sh/ruff/issues/1774): + # "", +] + +[tool.ruff.lint.per-file-ignores] +"**/typings/**/*.pyi" = [ + "F811", # Re-exports false positives + # The following can't be controlled for external libraries: + "A", # Shadowing builtin names + "E741", # ambiguous variable name + "F403", # `from . import *` used; unable to detect undefined names + "FBT", # flake8-boolean-trap + "ICN001", # unconventional-import-alias + "N8", # Naming conventions + "PLC2701", # Private name import + "PLR0904", # Too many public methods + "PLR0913", # Argument count + "PLR0917", # Too many positional arguments + "PLW3201", # misspelled dunder method name + "PYI042", # CamelCase TypeAlias + # Stubs can sometimes re-export entire modules. + # Issues with using a star-imported name will be caught by type-checkers. + "F405", # may be undefined, or defined from star imports ] ### -# Project(s)-specifics +# Specific to this project ### -[tool.ruff.per-file-ignores] -"*.pyi" = [ - "I002", # Stubs don't need from __future__ import annotations - "PLC0414", # https://github.com/charliermarsh/ruff/issues/3734 -] "Dolphin scripts/Entrance Randomizer/**.py" = [ "F405", # Allow * import from constants since we use a lot, but not all "PLW0603", # Using globals due to the nature of this script @@ -70,52 +131,11 @@ ignore = [ "PYI021", # No source, keep docstrings ] -# https://beta.ruff.rs/docs/settings/#flake8-implicit-str-concat -[tool.ruff.flake8-implicit-str-concat] -allow-multiline = false - -# https://beta.ruff.rs/docs/settings/#isort -[tool.ruff.isort] -combine-as-imports = true -required-imports = ["from __future__ import annotations"] # Safer with Python 3.8 and 3.9 -split-on-trailing-comma = false - -# https://beta.ruff.rs/docs/settings/#mccabe -[tool.ruff.mccabe] -# Hard limit, arbitrary to 4 bytes -max-complexity = 31 -# Arbitrary to 2 bytes, same as SonarLint -# max-complexity = 15 - -[tool.ruff.pylint] -# Arbitrary to 1 byte, same as SonarLint -max-args = 7 -# At least same as max-complexity -max-branches = 15 - ### Possible future ruff.pylint configurations # https://github.com/charliermarsh/ruff/issues/970 -# # Dynamic/Generated members from SQLAlchemy -# ignored-classes = ["scoped_session"] # # Arbitrary to 2 bytes # max-attributes = 15 # max-locals = 15 -# disable = [ -# # No need to mention the fixmes -# "fixme", -# "missing-docstring", -# # Already taken care of and grayed out. Also conflicts with Pylance reportIncompatibleMethodOverride -# "unused-argument", -# # Only reports a single instance. Pyright does a better job anyway -# "cyclic-import", -# # Strings are ok. Pylance also doesn't seem to see our overriden Exception classes (TODO: Make it better?) -# "invalid-sequence-index", -# # Happens too often with Flask, child classes should not be affected by this rule -# # See: https://github.com/PyCQA/pylint/issues/4352 -# "too-few-public-methods", -# # Similar lines in 2 files, doesn't really work -# "R0801", -# ] # https://github.com/hhatto/autopep8#usage # https://github.com/hhatto/autopep8#more-advanced-usage @@ -127,16 +147,31 @@ ignore = [ "E124", # Closing bracket may not match multi-line method invocation style (enforced by add-trailing-comma) "E402", # Allow imports at the bottom of file "E70", # Allow ... on same line as def + "E721", # Breaks when needing an exact type "W503", # Linebreak before binary operator + # Autofixed by Ruff + # Check for the "Fix" flag https://docs.astral.sh/ruff/rules/#pycodestyle-e-w + "E2", # Whitespace + "E3", # Blank lines + "E502", # Remove extraneous escape of newline + "E703", # useless-semicolon + "E71", # Statement (comparisons) + "E731", # lambda-assignment + "W29", # Whitespace warning + "W391", # Remove trailing blank lines + "W605", # invalid-escape-sequence + # Autofixed by other Ruff rules + "E401", # I001: unsorted-imports + "W690", # UP: pyupgrade ] -max_line_length = 120 +max_line_length = 100 per_file_ignores = ["*.pyi: E302"] # https://github.com/microsoft/pyright/blob/main/docs/configuration.md#sample-pyprojecttoml-file [tool.pyright] # Minimal python version supported extraPaths = ["Dolphin scripts/typings"] -pythonVersion = "3.8.5" +pythonVersion = "3.8" typeCheckingMode = "strict" # Extra strict reportCallInDefaultInitializer = "error"