mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-05-27 15:50:02 -07:00
Shops my beloved
This commit is contained in:
@@ -71,6 +71,7 @@ class TunicWorld(World):
|
|||||||
tunic_portal_pairs: Dict[str, str]
|
tunic_portal_pairs: Dict[str, str]
|
||||||
er_portal_hints: Dict[int, str]
|
er_portal_hints: Dict[int, str]
|
||||||
seed_groups: Dict[str, SeedGroup] = {}
|
seed_groups: Dict[str, SeedGroup] = {}
|
||||||
|
shop_num: int = 1 # need to make it so that you can walk out of shops, but also that they aren't all connected
|
||||||
|
|
||||||
def generate_early(self) -> None:
|
def generate_early(self) -> None:
|
||||||
if self.options.plando_connections:
|
if self.options.plando_connections:
|
||||||
@@ -362,6 +363,13 @@ class TunicWorld(World):
|
|||||||
hint_data[self.player][location.address] = hint_text
|
hint_data[self.player][location.address] = hint_text
|
||||||
|
|
||||||
def fill_slot_data(self) -> Dict[str, Any]:
|
def fill_slot_data(self) -> Dict[str, Any]:
|
||||||
|
# todo: remove this
|
||||||
|
# if self.player_name == "Player22":
|
||||||
|
# import Utils
|
||||||
|
# state = self.multiworld.get_all_state(False)
|
||||||
|
# state.update_reachable_regions(self.player)
|
||||||
|
# Utils.visualize_regions(self.multiworld.get_region("Menu", self.player), "tunctest.puml",
|
||||||
|
# show_entrance_names=True, highlight_regions=state.reachable_regions[self.player])
|
||||||
slot_data: Dict[str, Any] = {
|
slot_data: Dict[str, Any] = {
|
||||||
"seed": self.random.randint(0, 2147483647),
|
"seed": self.random.randint(0, 2147483647),
|
||||||
"start_with_sword": self.options.start_with_sword.value,
|
"start_with_sword": self.options.start_with_sword.value,
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ class Portal(NamedTuple):
|
|||||||
elevation: Optional[int] = None # elevation of the entrance, for ladder storage rule generation
|
elevation: Optional[int] = None # elevation of the entrance, for ladder storage rule generation
|
||||||
|
|
||||||
def scene(self) -> str: # the actual scene name in Tunic
|
def scene(self) -> str: # the actual scene name in Tunic
|
||||||
|
if self.region.startswith("Shop"):
|
||||||
|
return tunic_er_regions["Shop"].game_scene
|
||||||
return tunic_er_regions[self.region].game_scene
|
return tunic_er_regions[self.region].game_scene
|
||||||
|
|
||||||
def scene_destination(self) -> str: # full, nonchanging name to interpret by the mod
|
def scene_destination(self) -> str: # full, nonchanging name to interpret by the mod
|
||||||
|
|||||||
+30
-15
@@ -22,17 +22,17 @@ class TunicERLocation(Location):
|
|||||||
|
|
||||||
def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]:
|
def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]:
|
||||||
regions: Dict[str, Region] = {}
|
regions: Dict[str, Region] = {}
|
||||||
|
for region_name, region_data in tunic_er_regions.items():
|
||||||
|
regions[region_name] = Region(region_name, world.player, world.multiworld)
|
||||||
|
|
||||||
if world.options.entrance_rando:
|
if world.options.entrance_rando:
|
||||||
portal_pairs = pair_portals(world)
|
portal_pairs = pair_portals(world, regions)
|
||||||
|
|
||||||
# output the entrances to the spoiler log here for convenience
|
# output the entrances to the spoiler log here for convenience
|
||||||
for portal1, portal2 in portal_pairs.items():
|
for portal1, portal2 in portal_pairs.items():
|
||||||
world.multiworld.spoiler.set_entrance(portal1.name, portal2.name, "both", world.player)
|
world.multiworld.spoiler.set_entrance(portal1.name, portal2.name, "both", world.player)
|
||||||
else:
|
else:
|
||||||
portal_pairs = vanilla_portals()
|
portal_pairs = vanilla_portals(world, regions)
|
||||||
|
|
||||||
for region_name, region_data in tunic_er_regions.items():
|
|
||||||
regions[region_name] = Region(region_name, world.player, world.multiworld)
|
|
||||||
|
|
||||||
set_er_region_rules(world, regions, portal_pairs)
|
set_er_region_rules(world, regions, portal_pairs)
|
||||||
|
|
||||||
@@ -51,6 +51,7 @@ def create_er_regions(world: "TunicWorld") -> Dict[Portal, Portal]:
|
|||||||
victory_region = regions["Spirit Arena Victory"]
|
victory_region = regions["Spirit Arena Victory"]
|
||||||
victory_location = TunicERLocation(world.player, "The Heir", None, victory_region)
|
victory_location = TunicERLocation(world.player, "The Heir", None, victory_region)
|
||||||
victory_location.place_locked_item(TunicERItem("Victory", ItemClassification.progression, None, world.player))
|
victory_location.place_locked_item(TunicERItem("Victory", ItemClassification.progression, None, world.player))
|
||||||
|
# todo: set the victory condition back
|
||||||
world.multiworld.completion_condition[world.player] = lambda state: True # state.has("Victory", world.player)
|
world.multiworld.completion_condition[world.player] = lambda state: True # state.has("Victory", world.player)
|
||||||
victory_region.locations.append(victory_location)
|
victory_region.locations.append(victory_location)
|
||||||
|
|
||||||
@@ -93,7 +94,17 @@ def place_event_items(world: "TunicWorld", regions: Dict[str, Region]) -> None:
|
|||||||
region.locations.append(location)
|
region.locations.append(location)
|
||||||
|
|
||||||
|
|
||||||
def vanilla_portals() -> Dict[Portal, Portal]:
|
# all shops are the same shop. however, you cannot get to all shops from the same shop entrance.
|
||||||
|
# so, we need a bunch of shop regions that connect to the actual shop, but the actual shop cannot connect back
|
||||||
|
def create_shop_region(world: "TunicWorld", regions: Dict[str, Region]) -> None:
|
||||||
|
new_shop_name = f"Shop {world.shop_num}"
|
||||||
|
new_shop_region = Region(new_shop_name, world.player, world.multiworld)
|
||||||
|
new_shop_region.connect(regions["Shop"])
|
||||||
|
regions[new_shop_name] = new_shop_region
|
||||||
|
world.shop_num += 1
|
||||||
|
|
||||||
|
|
||||||
|
def vanilla_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal, Portal]:
|
||||||
portal_pairs: Dict[Portal, Portal] = {}
|
portal_pairs: Dict[Portal, Portal] = {}
|
||||||
# we don't want the zig skip exit for vanilla portals, since it shouldn't be considered for logic here
|
# we don't want the zig skip exit for vanilla portals, since it shouldn't be considered for logic here
|
||||||
portal_map = [portal for portal in portal_mapping if portal.name != "Ziggurat Lower Falling Entrance"]
|
portal_map = [portal for portal in portal_mapping if portal.name != "Ziggurat Lower Falling Entrance"]
|
||||||
@@ -105,8 +116,9 @@ def vanilla_portals() -> Dict[Portal, Portal]:
|
|||||||
portal2_sdt = portal1.destination_scene()
|
portal2_sdt = portal1.destination_scene()
|
||||||
|
|
||||||
if portal2_sdt.startswith("Shop,"):
|
if portal2_sdt.startswith("Shop,"):
|
||||||
portal2 = Portal(name="Shop", region="Shop",
|
portal2 = Portal(name=f"Shop Portal {world.shop_num}", region=f"Shop {world.shop_num}",
|
||||||
destination="Previous Region", tag="_")
|
destination="Previous Region", tag="_")
|
||||||
|
create_shop_region(world, regions)
|
||||||
|
|
||||||
elif portal2_sdt == "Purgatory, Purgatory_bottom":
|
elif portal2_sdt == "Purgatory, Purgatory_bottom":
|
||||||
portal2_sdt = "Purgatory, Purgatory_top"
|
portal2_sdt = "Purgatory, Purgatory_top"
|
||||||
@@ -125,8 +137,7 @@ def vanilla_portals() -> Dict[Portal, Portal]:
|
|||||||
|
|
||||||
|
|
||||||
# pairing off portals, starting with dead ends
|
# pairing off portals, starting with dead ends
|
||||||
def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal, Portal]:
|
||||||
# separate the portals into dead ends and non-dead ends
|
|
||||||
portal_pairs: Dict[Portal, Portal] = {}
|
portal_pairs: Dict[Portal, Portal] = {}
|
||||||
dead_ends: List[Portal] = []
|
dead_ends: List[Portal] = []
|
||||||
two_plus: List[Portal] = []
|
two_plus: List[Portal] = []
|
||||||
@@ -156,6 +167,7 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
|||||||
if laurels_location == "10_fairies" and not hasattr(world.multiworld, "re_gen_passthrough"):
|
if laurels_location == "10_fairies" and not hasattr(world.multiworld, "re_gen_passthrough"):
|
||||||
has_laurels = False
|
has_laurels = False
|
||||||
|
|
||||||
|
# need to keep track of which scenes have shops, since you shouldn't have multiple shops connected to the same scene
|
||||||
shop_scenes: Set[str] = set()
|
shop_scenes: Set[str] = set()
|
||||||
shop_count = 6
|
shop_count = 6
|
||||||
if fixed_shop:
|
if fixed_shop:
|
||||||
@@ -293,8 +305,9 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
|||||||
break
|
break
|
||||||
# if it's not a dead end, it might be a shop
|
# if it's not a dead end, it might be a shop
|
||||||
if p_exit == "Shop Portal":
|
if p_exit == "Shop Portal":
|
||||||
portal2 = Portal(name="Shop Portal", region="Shop",
|
portal2 = Portal(name=f"Shop Portal {world.shop_num}", region=f"Shop {world.shop_num}",
|
||||||
destination="Previous Region", tag="_")
|
destination="Previous Region", tag="_")
|
||||||
|
create_shop_region(world, regions)
|
||||||
shop_count -= 1
|
shop_count -= 1
|
||||||
# need to maintain an even number of portals total
|
# need to maintain an even number of portals total
|
||||||
if shop_count < 0:
|
if shop_count < 0:
|
||||||
@@ -351,7 +364,9 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
|||||||
raise Exception(f"Failed to do Fixed Shop option. "
|
raise Exception(f"Failed to do Fixed Shop option. "
|
||||||
f"Did {player_name} plando connection the Windmill Shop entrance?")
|
f"Did {player_name} plando connection the Windmill Shop entrance?")
|
||||||
|
|
||||||
portal2 = Portal(name="Shop Portal", region="Shop", destination="Previous Region", tag="_")
|
portal2 = Portal(name=f"Shop Portal {world.shop_num}", region=f"Shop {world.shop_num}",
|
||||||
|
destination="Previous Region", tag="_")
|
||||||
|
create_shop_region(world, regions)
|
||||||
|
|
||||||
portal_pairs[portal1] = portal2
|
portal_pairs[portal1] = portal2
|
||||||
two_plus.remove(portal1)
|
two_plus.remove(portal1)
|
||||||
@@ -435,7 +450,9 @@ def pair_portals(world: "TunicWorld") -> Dict[Portal, Portal]:
|
|||||||
break
|
break
|
||||||
if portal1 is None:
|
if portal1 is None:
|
||||||
raise Exception("Too many shops in the pool, or something else went wrong.")
|
raise Exception("Too many shops in the pool, or something else went wrong.")
|
||||||
portal2 = Portal(name="Shop Portal", region="Shop", destination="Previous Region", tag="_")
|
portal2 = Portal(name=f"Shop Portal {world.shop_num}", region=f"Shop {world.shop_num}",
|
||||||
|
destination="Previous Region", tag="_")
|
||||||
|
create_shop_region(world, regions)
|
||||||
|
|
||||||
portal_pairs[portal1] = portal2
|
portal_pairs[portal1] = portal2
|
||||||
|
|
||||||
@@ -468,9 +485,7 @@ def create_randomized_entrances(portal_pairs: Dict[Portal, Portal], regions: Dic
|
|||||||
region1 = regions[portal1.region]
|
region1 = regions[portal1.region]
|
||||||
region2 = regions[portal2.region]
|
region2 = regions[portal2.region]
|
||||||
region1.connect(connecting_region=region2, name=portal1.name)
|
region1.connect(connecting_region=region2, name=portal1.name)
|
||||||
# prevent the logic from thinking you can get to any shop-connected region from the shop
|
region2.connect(connecting_region=region1, name=portal2.name)
|
||||||
if portal2.name not in {"Shop", "Shop Portal"}:
|
|
||||||
region2.connect(connecting_region=region1, name=portal2.name)
|
|
||||||
|
|
||||||
|
|
||||||
def update_reachable_regions(connected_regions: Set[str], traversal_reqs: Dict[str, Dict[str, List[List[str]]]],
|
def update_reachable_regions(connected_regions: Set[str], traversal_reqs: Dict[str, Dict[str, List[List[str]]]],
|
||||||
|
|||||||
Reference in New Issue
Block a user