Skip to content

Commit 6f93fa4

Browse files
committed
Merge changes from 0.6 dev
2 parents 0281509 + 5cdaed2 commit 6f93fa4

File tree

9 files changed

+1704
-390
lines changed

9 files changed

+1704
-390
lines changed

worlds/crosscode/codegen/context.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class Context:
3838
"""
3939
The number of items in the item database.
4040
"""
41+
area_names: dict[str, str]
42+
"""
43+
Dict associating internal area names with their English fancy names.
44+
"""
4145

4246
def __post_init__(self):
4347
self.num_items = len(self.item_data)
@@ -63,10 +67,17 @@ def make_context_from_package(package: str) -> Context:
6367
except FileNotFoundError:
6468
pass
6569

70+
database = get_json_object(package, "data/assets/data/database.json")
71+
72+
area_names = {
73+
name: data["name"]["en_US"] for name, data in database["areas"].items()
74+
}
75+
6676
return Context(
6777
master,
6878
get_json_object(package, "data/assets/data/item-database.json")["items"],
69-
get_json_object(package, "data/assets/data/database.json"),
79+
database,
7080
cached_location_ids,
71-
cached_item_ids
81+
cached_item_ids,
82+
area_names
7283
)

worlds/crosscode/codegen/lists.py

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44

55
from collections import defaultdict
6+
from enum import StrEnum
67
import typing
78

89
from BaseClasses import ItemClassification
@@ -14,9 +15,18 @@
1415

1516
from ..types.items import ItemData, ProgressiveItemChainSingle, SingleItemData, ItemPoolEntry, ProgressiveItemChain
1617
from ..types.locations import AccessInfo, LocationData
17-
from ..types.condition import Condition, RegionCondition, OrCondition, ShopSlotCondition
18+
from ..types.condition import Condition, NeverCondition, RegionCondition, OrCondition, ShopSlotCondition
1819
from ..types.shops import ShopData
1920

21+
class LocationCategory(StrEnum):
22+
"""
23+
Enum of check types, used for location categorization and markers.
24+
"""
25+
CHEST = "Chest"
26+
CUTSCENE = "Cutscene"
27+
ELEMENT = "Element"
28+
QUEST = "Quest"
29+
2030

2131
class ListInfo:
2232
"""
@@ -120,13 +130,13 @@ def build(self):
120130
file = self.ctx.rando_data
121131

122132
if "chests" in file:
123-
self.__add_location_list(file["chests"])
133+
self.__add_location_list(file["chests"], LocationCategory.CHEST)
124134
if "cutscenes" in file:
125-
self.__add_location_list(file["cutscenes"])
135+
self.__add_location_list(file["cutscenes"], LocationCategory.CUTSCENE)
126136
if "elements" in file:
127-
self.__add_location_list(file["elements"])
137+
self.__add_location_list(file["elements"], LocationCategory.ELEMENT)
128138
if "quests" in file:
129-
self.__add_location_list(file["quests"], True)
139+
self.__add_location_list(file["quests"], LocationCategory.QUEST, True)
130140

131141
self.__add_shop_list(self.ctx.rando_data["shops"])
132142

@@ -182,7 +192,7 @@ def __get_or_allocate_item_id(self, name: str) -> int:
182192

183193
return item_id
184194

185-
def __add_location(self, name: str, raw_loc: dict[str, typing.Any], create_event: bool = False):
195+
def __add_location(self, name: str, raw_loc: dict[str, typing.Any], category: LocationCategory, create_event: bool = False):
186196
"""
187197
Add a location to the lists.
188198
"""
@@ -191,6 +201,8 @@ def __add_location(self, name: str, raw_loc: dict[str, typing.Any], create_event
191201
item_rewards = rewards.get("items", [])
192202
num_rewards = max(1, len(item_rewards))
193203

204+
properties = raw_loc.get("properties", {})
205+
194206
found = False
195207

196208
if name in self.reward_amounts:
@@ -202,7 +214,11 @@ def __add_location(self, name: str, raw_loc: dict[str, typing.Any], create_event
202214
"Cannot add or overwrite with {num_rewards}."
203215
)
204216

205-
area = raw_loc.get("location", {}).get("area", None)
217+
if category == LocationCategory.QUEST:
218+
area = dbentry["area"]
219+
else:
220+
area = raw_loc.get("location", {}).get("area", None)
221+
area_name = self.ctx.area_names[area]
206222

207223
location_names: list[str] = []
208224

@@ -233,10 +249,14 @@ def __add_location(self, name: str, raw_loc: dict[str, typing.Any], create_event
233249
self.pool_locations.append(loc)
234250
if area != None:
235251
try:
236-
self.location_groups[self.ctx.database["areas"][area]["name"]["en_US"]].append(loc)
252+
self.location_groups[area_name].append(loc)
253+
self.location_groups[f"{area_name} {category}s"].append(loc)
237254
except KeyError:
238255
print(f"Cannot add location '{name}' in area '{area}'")
239256

257+
if properties.get("alwaysQuest", False):
258+
self.location_groups["Always Quests"].append(loc)
259+
240260
if locked:
241261
self.locked_locations.append(locid)
242262

@@ -256,12 +276,12 @@ def __add_location(self, name: str, raw_loc: dict[str, typing.Any], create_event
256276
)
257277
self.events_data[event_name] = event
258278

259-
def __add_location_list(self, loc_list: dict[str, dict[str, typing.Any]], create_events: bool = False):
279+
def __add_location_list(self, loc_list: dict[str, dict[str, typing.Any]], category: LocationCategory, create_events: bool = False):
260280
"""
261281
Add a list of locations to the list.
262282
"""
263283
for name, raw_loc in loc_list.items():
264-
self.__add_location(name, raw_loc, create_events)
284+
self.__add_location(name, raw_loc, category, create_events)
265285

266286
def __add_item_data(self, name: str, raw_item: dict[str, typing.Any]) -> tuple[SingleItemData, ItemData]:
267287
"""
@@ -303,6 +323,8 @@ def __add_shop_unlock_item(self, name: str) -> ItemData:
303323

304324
def __add_shop(self, shop_display_name: str, raw_shop: dict[str, typing.Any]):
305325
shop_name = raw_shop["location"]["shop"]
326+
area = raw_shop["location"]["area"]
327+
area_name = self.ctx.area_names[area]
306328
shop_base_name = shop_display_name.split(" +")[0] # this is a hack until there are heirarchical shops
307329

308330
dbentry = self.ctx.database["shops"][shop_name]
@@ -334,14 +356,17 @@ def __add_shop(self, shop_display_name: str, raw_shop: dict[str, typing.Any]):
334356
slot_location = LocationData(
335357
name=slot_location_name,
336358
code=locid,
337-
area=None,
359+
area=area,
338360
metadata=metadata,
339361
access=AccessInfo(
340362
region={ name: shop_display_name for name in access_info.region },
341363
cond=[ShopSlotCondition(shop_name, item_id)],
342364
),
343365
)
344366

367+
self.location_groups[area_name].append(slot_location)
368+
self.location_groups[f"{area_name} Shops"].append(slot_location)
369+
345370
shop_locs[item_id] = slot_location
346371
self.locations_data[slot_location.name] = slot_location
347372

@@ -476,10 +501,19 @@ def __add_progressive_chains(self, raw: dict[str, dict[str, typing.Any]]):
476501
for name, chain in raw.items():
477502
self.__add_progressive_chain(name, chain)
478503

479-
def __add_vars(self, variables: dict[str, dict[str, list[typing.Any]]]):
504+
def __add_vars(self, variables: dict[str, str | dict[str, list[typing.Any]]]):
480505
"""
481506
Add a list of variable conditions to the list..
482507
"""
483508
for name, values in variables.items():
509+
if isinstance(values, str):
510+
if values == "boolean":
511+
self.variable_definitions[name] = {
512+
"off": [NeverCondition()],
513+
"on": []
514+
}
515+
continue
516+
else:
517+
raise RuntimeError(f"{values} is not a valid variable type shorthand.")
484518
for value, conds in values.items():
485519
self.variable_definitions[name][value] = self.json_parser.parse_condition(conds)

worlds/crosscode/codegen/parse.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
from ..types.items import ItemData, ProgressiveChainEntry, ProgressiveItemChain, ProgressiveItemChainSingle, ProgressiveItemChainMulti, ProgressiveItemSubchain, SingleItemData
1414
from ..types.locations import AccessInfo, Condition
1515
from ..types.regions import RegionConnection, RegionsData
16-
from ..types.condition import ChestKeyCondition, ItemCondition, LocationCondition, QuestCondition, RegionCondition, AnyElementCondition, \
17-
OrCondition, VariableCondition
16+
from ..types.condition import ChestKeyCondition, ItemCondition, LocationCondition, NeverCondition, QuestCondition, RegionCondition, AnyElementCondition, \
17+
OrCondition, ShopSlotCondition, VariableCondition
1818

1919
class JsonParserError(Exception):
2020
"""
@@ -120,6 +120,20 @@ def parse_condition(self, raw: list[typing.Any]) -> list[Condition]:
120120
f"expected 1 argument, not {num_args}"
121121
)
122122

123+
elif cond[0] == "shop_slot":
124+
if num_args == 2:
125+
result.append(ShopSlotCondition(cond[1], cond[2]))
126+
else:
127+
raise JsonParserError(
128+
raw,
129+
cond,
130+
"shop slot condition",
131+
f"expected 2 arguments, not {num_args}"
132+
)
133+
134+
elif cond[0] == "never":
135+
result.append(NeverCondition())
136+
123137
else:
124138
raise JsonParserError(raw, cond, "condition", f"unknown type {cond[0]}")
125139

0 commit comments

Comments
 (0)