From c048540dc99d8a84ca9d0ecf8b6a76fe51c117b3 Mon Sep 17 00:00:00 2001 From: Richard Snider Date: Thu, 30 Apr 2026 20:46:00 -0600 Subject: [PATCH 1/2] add *actual* support for botanics completion amount --- worlds/crosscode/locations.py | 10 +++++----- worlds/crosscode/types/condition.py | 7 +++++-- worlds/crosscode/world.py | 2 ++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/worlds/crosscode/locations.py b/worlds/crosscode/locations.py index 33be5168877c..b4531df940cc 100644 --- a/worlds/crosscode/locations.py +++ b/worlds/crosscode/locations.py @@ -420,9 +420,9 @@ LocationData(code=3235824367, name="Krys'kajo SP Upgrade", area='tree-dng', access=AccessInfo(region={'linear': '30', 'open': 'open15.3'})), LocationData(code=3235824790, name='Apollo Duel East Pass', area='jungle', access=AccessInfo(region={'linear': '30', 'open': 'open10'})), LocationData(code=3235824791, name='Apollo Duel West Pass', area='jungle', access=AccessInfo(region={'linear': '30', 'open': 'open10'})), - LocationData(code=3235824374, name='Talatu Bergen 25%', area='bergen', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'}, cond=[LocationCondition(location_name='Talatu Introductions'), ItemCondition(item_name='Disc of Flora', amount=1), BotanicsCompletionCondition(amount=20)])), - LocationData(code=3235824375, name="Talatu Ba'kii 50%", area='heat-village', metadata={'quest': True}, access=AccessInfo(region={'linear': '11', 'open': 'open5'}, cond=[LocationCondition(location_name='Talatu Bergen 25%'), BotanicsCompletionCondition(amount=39)])), - LocationData(code=3235824376, name='Talatu Basin 75%', area='jungle-city', metadata={'quest': True}, access=AccessInfo(region={'linear': '23', 'open': 'open10'}, cond=[LocationCondition(location_name="Talatu Ba'kii 50%"), BotanicsCompletionCondition(amount=58)])), + LocationData(code=3235824374, name='Talatu Bergen 25%', area='bergen', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'}, cond=[LocationCondition(location_name='Talatu Introductions'), ItemCondition(item_name='Disc of Flora', amount=1), BotanicsCompletionCondition(amount=0.25)])), + LocationData(code=3235824375, name="Talatu Ba'kii 50%", area='heat-village', metadata={'quest': True}, access=AccessInfo(region={'linear': '11', 'open': 'open5'}, cond=[LocationCondition(location_name='Talatu Bergen 25%'), BotanicsCompletionCondition(amount=0.5)])), + LocationData(code=3235824376, name='Talatu Basin 75%', area='jungle-city', metadata={'quest': True}, access=AccessInfo(region={'linear': '23', 'open': 'open10'}, cond=[LocationCondition(location_name="Talatu Ba'kii 50%"), BotanicsCompletionCondition(amount=0.75)])), LocationData(code=3235824834, name='Full Rhombus Pass cutscene', area='evo-village', metadata={'dlc': True}, access=AccessInfo(region={'open': 'openDLC1'})), LocationData(code=3235824835, name='Ancient Shade SP Upgrade', area='beach', metadata={'dlc': True}, access=AccessInfo(region={'open': 'openDLC_Beach'}, cond=[ItemCondition(item_name='Heat', amount=1), ItemCondition(item_name='Cold', amount=1)])), LocationData(code=3235824836, name='Ancient Shade Pickup', area='beach', metadata={'dlc': True}, access=AccessInfo(region={'open': 'openDLC_Beach'}, cond=[ItemCondition(item_name='Heat', amount=1), ItemCondition(item_name='Cold', amount=1)])), @@ -456,7 +456,7 @@ LocationData(code=3235824386, name='Round and Round - Reward 1', area='autumn-area', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'})), LocationData(code=3235824387, name='Round and Round - Reward 2', area='autumn-area', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'})), LocationData(code=3235824388, name='Round and Round - Reward 3', area='autumn-area', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'})), - LocationData(code=3235824389, name='Crocus Pocus', area='autumn-area', metadata={'quest': True}, access=AccessInfo(region={'linear': '31', 'open': 'open3'}, cond=[ItemCondition(item_name='Disc of Flora', amount=1), LocationCondition(location_name='Talatu Basin 75%'), BotanicsCompletionCondition(amount=77)])), + LocationData(code=3235824389, name='Crocus Pocus', area='autumn-area', metadata={'quest': True}, access=AccessInfo(region={'linear': '31', 'open': 'open3'}, cond=[ItemCondition(item_name='Disc of Flora', amount=1), LocationCondition(location_name='Talatu Basin 75%'), BotanicsCompletionCondition(amount=1.0)])), LocationData(code=3235824390, name='The Observatory', area='autumn-area', metadata={'quest': True}, access=AccessInfo(region={'linear': '31', 'open': 'open18'}, cond=[QuestCondition(quest_name='A Promise is a Promise 5'), ItemCondition(item_name='Mine Pass', amount=1)])), LocationData(code=3235824391, name='Bergen Trailblazing', area='bergen-trails', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'}, cond=[QuestCondition(quest_name='Bergen Trailblazing Collect'), QuestCondition(quest_name='Bergen Trailblazing Defeat'), QuestCondition(quest_name='Bergen Trailblazing Landmarks'), QuestCondition(quest_name='Bergen Trailblazing Data Probe')])), LocationData(code=3235824392, name='Bergen Trailblazing Collect', area='bergen-trails', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'})), @@ -1031,7 +1031,7 @@ LocationData(code=None, name="Autumn's Rise Landmarks (Event)", metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'})), LocationData(code=None, name="Autumn's Rise Data Probe (Event)", metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'})), LocationData(code=None, name='Round and Round (Event)', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'})), - LocationData(code=None, name='Crocus Pocus (Event)', metadata={'quest': True}, access=AccessInfo(region={'linear': '31', 'open': 'open3'}, cond=[ItemCondition(item_name='Disc of Flora', amount=1), LocationCondition(location_name='Talatu Basin 75%'), BotanicsCompletionCondition(amount=77)])), + LocationData(code=None, name='Crocus Pocus (Event)', metadata={'quest': True}, access=AccessInfo(region={'linear': '31', 'open': 'open3'}, cond=[ItemCondition(item_name='Disc of Flora', amount=1), LocationCondition(location_name='Talatu Basin 75%'), BotanicsCompletionCondition(amount=1.0)])), LocationData(code=None, name='The Observatory (Event)', metadata={'quest': True}, access=AccessInfo(region={'linear': '31', 'open': 'open18'}, cond=[QuestCondition(quest_name='A Promise is a Promise 5'), ItemCondition(item_name='Mine Pass', amount=1)])), LocationData(code=None, name='Bergen Trailblazing (Event)', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'}, cond=[QuestCondition(quest_name='Bergen Trailblazing Collect'), QuestCondition(quest_name='Bergen Trailblazing Defeat'), QuestCondition(quest_name='Bergen Trailblazing Landmarks'), QuestCondition(quest_name='Bergen Trailblazing Data Probe')])), LocationData(code=None, name='Bergen Trailblazing Collect (Event)', metadata={'quest': True}, access=AccessInfo(region={'linear': '3', 'open': 'open3'})), diff --git a/worlds/crosscode/types/condition.py b/worlds/crosscode/types/condition.py index 0b0e6f58a014..e9ee4cf8d51f 100644 --- a/worlds/crosscode/types/condition.py +++ b/worlds/crosscode/types/condition.py @@ -19,6 +19,7 @@ class LogicDict(typing.TypedDict): shop_unlock_by_shop: dict[str, ItemPoolEntry] shop_unlock_by_shop_and_id: dict[tuple[str, int], ItemPoolEntry] region_botanics_amounts: dict[str, int] + botanics_completion_amount: int class Condition(abc.ABC): @abc.abstractmethod @@ -168,7 +169,7 @@ def satisfied(self, state: CollectionState, player: int, location: int | None, a @dataclass class BotanicsCompletionCondition(Condition): - amount: int + amount: float def satisfied(self, state: CollectionState, player: int, location: int | None, args: LogicDict) -> bool: collected = sum([ @@ -177,7 +178,9 @@ def satisfied(self, state: CollectionState, player: int, location: int | None, a if state.can_reach_region(region, player) ]) - return collected >= self.amount + print(collected, args["botanics_completion_amount"], self.amount, collected / args["botanics_completion_amount"]) + + return collected / args["botanics_completion_amount"] >= self.amount class NeverCondition(Condition): def satisfied(self, state: CollectionState, player: int, location: int | None, args: LogicDict) -> bool: diff --git a/worlds/crosscode/world.py b/worlds/crosscode/world.py index c65c5e543a89..a5519beed596 100644 --- a/worlds/crosscode/world.py +++ b/worlds/crosscode/world.py @@ -1,4 +1,5 @@ """ + This module contains the world class for CrossCode. """ @@ -424,6 +425,7 @@ def generate_early(self): "shop_unlock_by_shop": self.world_data.shop_unlock_by_shop, "shop_unlock_by_shop_and_id": self.world_data.shop_unlock_by_shop_and_id, "region_botanics_amounts": self.world_data.region_botanics_amounts[self.logic_mode], + "botanics_completion_amount": self.options.botanics_completion_amount.value, } # Universal Tracker support From 6b015ff0c7a611e87c0fe170883ee36702e18a29 Mon Sep 17 00:00:00 2001 From: Richard Snider Date: Fri, 1 May 2026 01:21:51 -0600 Subject: [PATCH 2/2] throw OptionError on incompatible option sets in particular, it fails if DLC is not enabled and more chests are given than exist in vanilla also, remove a debug print statement log haha lol --- worlds/crosscode/types/condition.py | 2 -- worlds/crosscode/world.py | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/worlds/crosscode/types/condition.py b/worlds/crosscode/types/condition.py index e9ee4cf8d51f..dc383b4396fa 100644 --- a/worlds/crosscode/types/condition.py +++ b/worlds/crosscode/types/condition.py @@ -178,8 +178,6 @@ def satisfied(self, state: CollectionState, player: int, location: int | None, a if state.can_reach_region(region, player) ]) - print(collected, args["botanics_completion_amount"], self.amount, collected / args["botanics_completion_amount"]) - return collected / args["botanics_completion_amount"] >= self.amount class NeverCondition(Condition): diff --git a/worlds/crosscode/world.py b/worlds/crosscode/world.py index a5519beed596..e5dba7865fbe 100644 --- a/worlds/crosscode/world.py +++ b/worlds/crosscode/world.py @@ -301,6 +301,14 @@ def generate_early(self): "Di'orbis goal requires DLC to be enabled" ) + if ( + not self.options.enable_dlc.value and + self.options.botanics_completion_amount.value > (vanilla_amt := self.options.botanics_completion_amount.special_range_names["vanilla"]) + ): + raise OptionError( + f"Cannot have more than {vanilla_amt} botanics chests required without DLC" + ) + self.fill_pools() self.variables = defaultdict(list)