Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions worlds/crosscode/codegen/gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def generate_python_file_regions(self):
regions_complete = template.render(
modes_string=", ".join([f'"{x}"' for x in self.ctx.rando_data["modes"]]),
region_packs=self.regions_data,
region_botanics_amounts={key: val.items() for key, val in self.lists.region_botanics_amounts.items()},
**self.common_args
)

Expand Down
11 changes: 11 additions & 0 deletions worlds/crosscode/codegen/lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class ListInfo:
shop_unlock_by_shop_and_id: dict[tuple[str, int], ItemData]
global_slot_region_conditions_list: dict[str, list[Condition]]

region_botanics_amounts: dict[str, dict[str, int]] # { mode => { region => number of plants } }

progressive_chains: dict[str, ProgressiveItemChain]
progressive_items: dict[str, ItemData]

Expand Down Expand Up @@ -107,6 +109,8 @@ def __init__(self, ctx: Context):
self.shop_unlock_by_shop_and_id = {}
self.global_slot_region_conditions_list = {}

self.region_botanics_amounts = defaultdict(lambda: defaultdict(lambda: 0))

self.json_parser = JsonParser(self.ctx)
self.json_parser.single_items_dict = self.single_items_dict
self.json_parser.items_dict = self.items_dict
Expand Down Expand Up @@ -153,6 +157,8 @@ def build(self):

self.__add_progressive_chains(file["progressiveChains"])

self.__add_botanics(file["botanics"])

self.__add_vars(self.ctx.rando_data["vars"])

def __get_cached_location_id(self, name: str) -> typing.Optional[int]:
Expand Down Expand Up @@ -463,6 +469,11 @@ def __add_item_pool_list(self, raw: dict[str, list[dict[str, typing.Any]]]):
for name, pool in raw.items():
self.__add_item_pool(name, pool)

def __add_botanics(self, raw: dict[str, dict[str, typing.Any]]):
for plant in raw.values():
for mode, region in plant["region"].items():
self.region_botanics_amounts[mode][region] += 1

def __add_reward(self, reward: list[dict[str, typing.Any]]) -> ItemData:
"""
Ensure an item reward is in the list of items.
Expand Down
11 changes: 11 additions & 0 deletions worlds/crosscode/codegen/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,17 @@ def parse_condition(self, raw: list[typing.Any]) -> list[Condition]:
f"expected 2 arguments, not {num_args}"
)

elif cond[0] == "botanics":
if num_args == 1:
result.append(BotanicsCompletionCondition(cond[1]))
else:
raise JsonParserError(
raw,
cond,
"botanics completion condition",
f"expected 1 arguments, not {num_args}"
)

elif cond[0] == "never":
result.append(NeverCondition())

Expand Down
10 changes: 5 additions & 5 deletions worlds/crosscode/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,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)])),
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%')])),
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%")])),
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=3235824368, name='Heat Pedestal', area='cold-dng', access=AccessInfo(region={'linear': '8', 'open': 'open4.5'})),
LocationData(code=3235824369, name='Cold Pedestal', area='heat-dng', access=AccessInfo(region={'linear': '16', 'open': 'open7.4'})),
LocationData(code=3235824370, name='Shock Pedestal', area='wave-dng', access=AccessInfo(region={'linear': '27', 'open': 'open14.5'})),
Expand All @@ -401,7 +401,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), ItemCondition(item_name='Heat', amount=1), LocationCondition(location_name='Talatu Bergen 25%'), LocationCondition(location_name="Talatu Ba'kii 50%"), LocationCondition(location_name='Talatu Basin 75%'), RegionCondition(target_mode='open', region_name='open4.1'), RegionCondition(target_mode='open', region_name='open5'), RegionCondition(target_mode='open', region_name='open9'), RegionCondition(target_mode='open', region_name='open10'), RegionCondition(target_mode='open', region_name='open16'), RegionCondition(target_mode='open', region_name='open20')])),
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=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'})),
Expand Down Expand Up @@ -814,7 +814,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), ItemCondition(item_name='Heat', amount=1), LocationCondition(location_name='Talatu Bergen 25%'), LocationCondition(location_name="Talatu Ba'kii 50%"), LocationCondition(location_name='Talatu Basin 75%'), RegionCondition(target_mode='open', region_name='open4.1'), RegionCondition(target_mode='open', region_name='open5'), RegionCondition(target_mode='open', region_name='open9'), RegionCondition(target_mode='open', region_name='open10'), RegionCondition(target_mode='open', region_name='open16'), RegionCondition(target_mode='open', region_name='open20')])),
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='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'})),
Expand Down
24 changes: 21 additions & 3 deletions worlds/crosscode/regions.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@
'open7.8',
'open8',
'open9',
'open10',
'open10.Mid',
'open10.Right',
'open10.Infested',
'open10',
'open10.Grove',
'open10.Left',
'open10.Mid',
'open10.Right',
'open11',
'open13.1',
'open13.2',
Expand Down Expand Up @@ -202,4 +202,22 @@
}
),

}

region_botanics_amounts: dict[str, dict[str, int]] = {
"open": {
'open3': 20,
'open4.4': 6,
'open5': 18,
'open8': 7,
'open10': 5,
'open10.Mid': 1,
'open10.Left': 6,
'open10.Right': 2,
'open10.Infested': 1,
'open16': 9,
'open20': 1,
'open11': 1,
}

}
6 changes: 6 additions & 0 deletions worlds/crosscode/templates/regions.template.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@
),
{% endfor %}
}

region_botanics_amounts: dict[str, dict[str, int]] = {
{% for mode, amounts in region_botanics_amounts.items() -%}
"{{mode}}": {{ amounts | emit_dict("constant", "constant") | indent(4) }}
{% endfor %}
}
15 changes: 15 additions & 0 deletions worlds/crosscode/types/condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class LogicDict(typing.TypedDict):
shop_unlock_by_id: dict[int, ItemData]
shop_unlock_by_shop: dict[str, ItemData]
shop_unlock_by_shop_and_id: dict[tuple[str, int], ItemData]
region_botanics_amounts: dict[str, int]

class Condition(abc.ABC):
@abc.abstractmethod
Expand Down Expand Up @@ -165,6 +166,19 @@ def satisfied(self, state: CollectionState, player: int, location: int | None, a
return state.has(args["shop_unlock_by_shop_and_id"][self.shop_name, self.item_id].name, player)
return True

@dataclass
class BotanicsCompletionCondition(Condition):
amount: int

def satisfied(self, state: CollectionState, player: int, location: int | None, args: LogicDict) -> bool:
collected = sum([
amount
for region, amount in args["region_botanics_amounts"].items()
if state.can_reach_region(region, player)
])

return collected >= self.amount

class NeverCondition(Condition):
def satisfied(self, state: CollectionState, player: int, location: int | None, args: LogicDict) -> bool:
return False
Expand All @@ -182,5 +196,6 @@ def satisfied(self, state: CollectionState, player: int, location: int | None, a
"VariableEntryCondition",
"ChestKeyCondition",
"ShopSlotCondition",
"BotanicsCompletionCondition",
"NeverCondition"
]
1 change: 1 addition & 0 deletions worlds/crosscode/types/world.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class WorldData:
# regions.py
region_packs: dict[str, RegionsData]
modes: list[str] = field(init=False)
region_botanics_amounts: dict[str, dict[str, int]]

# locations.py
locations_dict: dict[str, LocationData]
Expand Down
1 change: 1 addition & 0 deletions worlds/crosscode/world.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ def generate_early(self):
"shop_unlock_by_id": self.world_data.shop_unlock_by_id,
"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],
}

# Universal Tracker support
Expand Down
3 changes: 2 additions & 1 deletion worlds/crosscode/world_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from .common import BASE_ID, DATA_VERSION
from .types.world import WorldData
from .regions import region_packs
from .regions import region_packs, region_botanics_amounts
from .items import single_items_dict, items_dict, items_by_full_name, keyring_items
from .shops import shop_dict, per_shop_locations, global_shop_locations, shop_unlock_by_id, shop_unlock_by_shop, \
shop_unlock_by_shop_and_id
Expand All @@ -17,6 +17,7 @@
data_version=DATA_VERSION,
base_id=BASE_ID,
region_packs=region_packs,
region_botanics_amounts=region_botanics_amounts,
locations_dict=locations_dict,
events_dict=events_dict,
locked_locations=locked_locations,
Expand Down
Loading