|
22 | 22 | display_region_levels_dictionary |
23 | 23 | from .options import CrystalProjectOptions, create_option_groups |
24 | 24 | from .rules import CrystalProjectLogic |
25 | | -from .mod_helper import ModLocationData, get_modded_items, get_modded_locations, \ |
| 25 | +from .mod_helper import ModLocationData, get_modded_items, get_modded_locations, get_modded_home_points, \ |
26 | 26 | get_modded_shopsanity_locations, get_modded_bosses, build_condition_rule, update_item_classification, get_mod_info, get_removed_locations |
27 | 27 | from typing import List, Set, Dict, Any |
28 | 28 | from worlds.AutoWorld import World, WebWorld |
@@ -94,6 +94,15 @@ class CrystalProjectWorld(World): |
94 | 94 | for modded_boss in modded_bosses: |
95 | 95 | location_name_to_id[modded_boss.name] = modded_boss.code |
96 | 96 |
|
| 97 | + modded_home_points = get_modded_home_points(mod_info) |
| 98 | + |
| 99 | + for modded_home_point in modded_home_points: |
| 100 | + location_name_to_id[modded_home_point.name] = modded_home_point.code + home_point_location_index_offset |
| 101 | + if modded_home_point.name in item_name_to_id and item_name_to_id[modded_home_point.name] != modded_home_point.code: |
| 102 | + raise Exception(f"A modded item({modded_home_point.name}) with id {modded_home_point.code} tried to change the code of item_name_to_id and it can never change!") |
| 103 | + item_name_to_id[modded_home_point.name] = modded_home_point.code + home_point_item_index_offset |
| 104 | + item_name_groups.setdefault(MOD, set()).add(modded_home_point.name) |
| 105 | + |
97 | 106 | removed_locations = get_removed_locations(mod_info) |
98 | 107 |
|
99 | 108 | web = CrystalProjectWeb() |
@@ -221,10 +230,20 @@ def create_regions(self) -> None: |
221 | 230 | if self.options.home_point_hustle.value != self.options.home_point_hustle.option_disabled: |
222 | 231 | home_points = get_home_points() |
223 | 232 |
|
| 233 | + # todo removed home points |
224 | 234 | for home_point in home_points: |
225 | 235 | home_point_location = LocationData(home_point.ap_region, home_point.name, (home_point.code + home_point_location_index_offset), home_point.rule) |
226 | 236 | locations.append(home_point_location) |
227 | 237 |
|
| 238 | + if self.options.use_mods.value == self.options.use_mods.option_true: |
| 239 | + for modded_home_point in self.modded_home_points: |
| 240 | + location = LocationData(display_region_subregions_dictionary[modded_home_point.display_region][0], |
| 241 | + modded_home_point.name, |
| 242 | + modded_home_point.code + home_point_location_index_offset, |
| 243 | + build_condition_rule(modded_home_point.display_region, |
| 244 | + modded_home_point.rule_condition, self)) |
| 245 | + locations.append(location) |
| 246 | + |
228 | 247 | #Regionsanity completion locations need to be added after all other locations so they can be removed if the region is empty (e.g. Neptune Shrine w/o Shopsanity) |
229 | 248 | if self.options.regionsanity.value != self.options.regionsanity.option_disabled: |
230 | 249 | region_completions = get_region_completion_locations() |
@@ -381,8 +400,14 @@ def create_item(self, name: str) -> Item: |
381 | 400 | return Item(name, data.classification, data.code, self.player) |
382 | 401 | else: |
383 | 402 | matches_mod = [item for (index, item) in enumerate(self.modded_items) if item.name == name] |
| 403 | + matches_mod_home_point = [item for (index, item) in enumerate(self.modded_home_points) if item.name == name] |
384 | 404 |
|
385 | | - return Item(matches_mod[0].name, matches_mod[0].classification, matches_mod[0].code, self.player) |
| 405 | + if len(matches_mod) > 0: |
| 406 | + return Item(matches_mod[0].name, matches_mod[0].classification, matches_mod[0].code, self.player) |
| 407 | + elif len(matches_mod_home_point) > 0: |
| 408 | + return Item(matches_mod_home_point[0].name, ItemClassification.progression, matches_mod_home_point[0].code + home_point_item_index_offset, self.player) |
| 409 | + else: |
| 410 | + raise Exception(f"No matches found for name {name}") |
386 | 411 |
|
387 | 412 | def create_items(self) -> None: |
388 | 413 | pool = self.get_item_pool(self.get_excluded_items()) |
@@ -656,6 +681,12 @@ def get_item_pool(self, excluded_items: Set[str]) -> List[Item]: |
656 | 681 | item = self.create_item(modded_item.name) |
657 | 682 | pool.append(item) |
658 | 683 |
|
| 684 | + if self.options.home_point_hustle != self.options.home_point_hustle.option_disabled: |
| 685 | + for modded_home_point in self.modded_home_points: |
| 686 | + item = self.create_item(modded_home_point.name) |
| 687 | + update_item_classification(item, [location.rule_condition for location in combined_locations], self) |
| 688 | + pool.append(item) |
| 689 | + |
659 | 690 | if not self.options.level_gating.value == self.options.level_gating.option_none: |
660 | 691 | #guarantee space for 2 clamshells |
661 | 692 | min_clamshells = 2 |
@@ -710,7 +741,10 @@ def get_job_id_list(self) -> List[int]: |
710 | 741 | def fill_slot_data(self) -> Dict[str, Any]: |
711 | 742 | mod_info = [] |
712 | 743 | slot_data_locations = [] |
| 744 | + slot_data_home_points = [] |
713 | 745 | slot_data_removed_locations = [] |
| 746 | + slot_data_removed_home_points = [] |
| 747 | + |
714 | 748 | if self.options.use_mods: |
715 | 749 | for mod in self.mod_info: |
716 | 750 | mod_info.append({ "Id": mod.mod_id, "Name": mod.mod_name, "LoadOrder": mod.load_order }) |
@@ -740,10 +774,21 @@ def fill_slot_data(self) -> Dict[str, Any]: |
740 | 774 | "BiomeId": boss.biomeId, |
741 | 775 | "Rule": None }) |
742 | 776 |
|
| 777 | + if self.options.home_point_hustle != self.options.home_point_hustle.option_disabled: |
| 778 | + for home_point in self.modded_home_points: |
| 779 | + slot_data_home_points.append({ "Id": home_point.offsetless_code, |
| 780 | + "APRegion": display_region_subregions_dictionary[home_point.display_region][0], |
| 781 | + "Name": home_point.name, |
| 782 | + "Coordinates": home_point.coordinates, |
| 783 | + "BiomeId": home_point.biomeId, |
| 784 | + "Rule": None }) |
| 785 | + |
743 | 786 | for location in self.removed_locations: |
744 | 787 | slot_data_removed_locations.append({"Id": location.code, |
745 | 788 | "APRegion": location.ap_region}) |
746 | 789 |
|
| 790 | + #TODO removed home points |
| 791 | + |
747 | 792 | # look into replacing this big chonky return block with self.options.as_dict() and then just adding the extras to the dict after |
748 | 793 | return { |
749 | 794 | "apworldVersion": self.world_version.as_simple_string(), |
@@ -782,6 +827,7 @@ def fill_slot_data(self) -> Dict[str, Any]: |
782 | 827 | "useMods": self.options.use_mods.value, |
783 | 828 | "modInfo": mod_info, |
784 | 829 | "moddedLocations": slot_data_locations, |
| 830 | + "moddedHomePoints": slot_data_home_points, |
785 | 831 | "removedLocations": slot_data_removed_locations, |
786 | 832 | # "moddedLocationsForUT": self.modded_locations, |
787 | 833 | # "moddedShopsForUT": self.modded_shops, |
|
0 commit comments