-
Notifications
You must be signed in to change notification settings - Fork 49
Dev updates #3058
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dev updates #3058
Conversation
Fix DivisionByZeroError
- Fixed a bug where the fake fairy song wouldn't end when going out of range of an ice trap fairy - Fixed a bug where talking to vanilla caged Diddy without pressing B to close the textbox would softlock you. (technically, you're now forced to press B to close the textbox, or it won't close)
- Fixed a bug where music would always be sped up when playing with certain win conditions without requiring K.Rool.
Fairy and diddy fixes
you wouldn't exit a level in arcade
Unshuffled Keys in SLO
Logical Lanky Returns
Fix helm
Some small fixes
| world.options.logic_type.value = 1 # Force to glitchless | ||
|
|
||
| if affected_players: | ||
| import logging |
Check notice
Code scanning / CodeQL
Module is imported more than once Note
on line 135
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 days ago
To fix the issue, remove the redundant inner import logging and rely on the existing top-level import logging at line 135. In general, modules should be imported once at module scope unless there is a specific need for a local or conditional import.
Concretely, in __init__.py, within the generate_early method around lines 968–974, delete the line import logging that appears just before logging.warning(...). No other changes are necessary: the logging.warning call will use the module imported at line 135. This preserves all existing behavior while cleaning up the redundant import.
| @@ -966,8 +966,6 @@ | ||
| world.options.logic_type.value = 1 # Force to glitchless | ||
|
|
||
| if affected_players: | ||
| import logging | ||
|
|
||
| logging.warning( | ||
| f"DK64: Minimal logic is DISABLED in host.yaml. " | ||
| f"The following player(s) have tried to sneak Minimal Logic in: {', '.join(affected_players)}. As such, they have been forced to use glitchless logic." |
| try: | ||
| ap_location = world.get_location(location_data.name, player) | ||
| forbid_item(ap_location, "Donkey", player) | ||
| except KeyError: |
Check notice
Code scanning / CodeQL
Empty except Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 days ago
In general, to fix an empty except block, either (a) add appropriate handling such as logging, cleanup, or re-raising, or (b) add a clear explanatory comment if intentional and benign. Here we can improve safety and diagnosability without changing functional behavior by logging the issue and then skipping the problematic location, matching the intent of “ignore if missing.” The earlier use site in the same function (lines 68–71) already uses continue to skip nonexistent locations, so we should mirror that explicit behavior.
Concretely, in archipelago/Rules.py, within apply_minimal_logic_rules, replace the except KeyError: pass block at lines 108–112 with a block that documents the intent and continues the loop (or simply returns to the next iteration), and optionally logs a debug message. To avoid new dependencies and minimize external assumptions, we can rely on the standard logging module, which is well-known and widely used. We will add a logging import and a module-level logger. Then, in the except KeyError: block, we log a debug message indicating the location was not found and then continue to the next loc_id in non_dk_location_ids. This preserves the current behavior of “do not crash if the location is missing,” but no longer has a completely empty handler.
-
Copy modified line R11 -
Copy modified line R13 -
Copy modified line R15 -
Copy modified lines R113-R120
| @@ -8,8 +8,11 @@ | ||
| from randomizer.Enums.Maps import Maps | ||
| from randomizer.Enums.Types import Types | ||
| from randomizer.Enums.Settings import ShuffleLoadingZones, LogicType | ||
| import logging | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def set_rules(world: MultiWorld, player: int): | ||
| """Set the rules for the given player's world.""" | ||
| world.completion_condition[player] = lambda state: state.has("Banana Hoard", player) | ||
| @@ -109,4 +110,11 @@ | ||
| ap_location = world.get_location(location_data.name, player) | ||
| forbid_item(ap_location, "Donkey", player) | ||
| except KeyError: | ||
| pass | ||
| # Location does not exist in Archipelago for this player; skip applying this rule. | ||
| logger.debug( | ||
| "Non-DK location '%s' (id %s) not found in world for player %s; skipping DK restriction.", | ||
| location_data.name, | ||
| loc_id, | ||
| player, | ||
| ) | ||
| continue |
| # we still need to add them to item_assignment for patching purposes | ||
| if Types.Key not in spoiler.settings.shuffled_location_types: | ||
| if spoiler.settings.shuffle_loading_zones == ShuffleLoadingZones.levels: | ||
| import randomizer.ItemPool as ItemPool |
Check notice
Code scanning / CodeQL
Cyclic import Note
randomizer.ItemPool
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 8 days ago
In general, to fix this kind of cyclic import you remove the direct import that participates in the cycle and instead depend on something that does not itself depend back on the current module. Typical approaches include: moving the shared functionality to a third, lower‑level module; inlining very small helper logic; or passing required objects as arguments instead of importing them.
Here, ShuffleItems only needs ItemPool.Keys() to obtain the collection of key items. We can break the cycle without changing behavior by locally defining the same Keys() logic in this file (or, equivalently, by inlining the check) instead of importing ItemPool. Since we must not modify other files, the best option within this snippet is to remove the import randomizer.ItemPool as ItemPool in the conditional block and replace its usage with a small helper function that returns the key items. To avoid assumptions about the rest of the code, we can implement Keys() using the already‑imported Items enum, which is the natural place where the key items live.
Concretely:
- Add a new helper function near the top of
ShuffleItems.py, e.g.def _key_items(): ..., returning the same iterable thatItemPool.Keys()would have provided. This usesItemsvalues that correspond to keys (e.g.,Items.Key1–Items.Key8or whatever subset is applicable). - Replace the local import
import randomizer.ItemPool as ItemPoolwith a call to this helper, i.e., call_key_items()instead ofItemPool.Keys(). - Adjust the
ifcondition in the loop overLevelInfoList.values()to check membership in_key_items()instead ofItemPool.Keys(). No other behavior changes are needed.
This eliminates the cycle by removing ShuffleItems’s dependency on ItemPool while preserving the semantics of “is this item a key?” as long as the helper returns the correct set of key Items values.
-
Copy modified lines R17-R35 -
Copy modified line R218
| @@ -14,6 +14,25 @@ | ||
| from randomizer.Patching.Library.ItemRando import LocationSelection | ||
|
|
||
|
|
||
| def _key_items(): | ||
| """Return the collection of key items used for vanilla key placement. | ||
|
|
||
| This mirrors the behavior of ItemPool.Keys() without importing ItemPool, | ||
| in order to avoid an import cycle. | ||
| """ | ||
| # NOTE: Adjust this list if additional key items are introduced in Items. | ||
| return { | ||
| Items.Key1, | ||
| Items.Key2, | ||
| Items.Key3, | ||
| Items.Key4, | ||
| Items.Key5, | ||
| Items.Key6, | ||
| Items.Key7, | ||
| Items.Key8, | ||
| } | ||
|
|
||
|
|
||
| class MoveData: | ||
| """Class which contains information pertaining to a move's attributes.""" | ||
|
|
||
| @@ -191,13 +210,12 @@ | ||
| # we still need to add them to item_assignment for patching purposes | ||
| if Types.Key not in spoiler.settings.shuffled_location_types: | ||
| if spoiler.settings.shuffle_loading_zones == ShuffleLoadingZones.levels: | ||
| import randomizer.ItemPool as ItemPool | ||
|
|
||
| vanilla_keys_assignment = [] | ||
| for level in LevelInfoList.values(): | ||
| key_location = spoiler.LocationList[level.KeyLocation] | ||
|
|
||
| if key_location.item is not None and key_location.item in ItemPool.Keys(): | ||
| if key_location.item is not None and key_location.item in _key_items(): | ||
| placement_info = {} | ||
| if key_location.default_mapid_data: | ||
| for location in key_location.default_mapid_data: |
No description provided.