| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | import string | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-17 03:23:27 +02:00
										 |  |  | from BaseClasses import Item, MultiWorld, Region, Location, Entrance, Tutorial, ItemClassification, RegionType | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | from .Items import item_table, item_pool, event_item_pairs | 
					
						
							|  |  |  | from .Locations import location_table | 
					
						
							|  |  |  | from .Regions import create_regions | 
					
						
							|  |  |  | from .Rules import set_rules | 
					
						
							| 
									
										
										
										
											2022-05-11 13:05:53 -05:00
										 |  |  | from ..AutoWorld import World, WebWorld | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | from .Options import spire_options | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-11 13:05:53 -05:00
										 |  |  | class SpireWeb(WebWorld): | 
					
						
							|  |  |  |     tutorials = [Tutorial( | 
					
						
							|  |  |  |         "Multiworld Setup Guide", | 
					
						
							| 
									
										
										
										
											2022-06-17 03:23:27 +02:00
										 |  |  |         "A guide to setting up Slay the Spire for Archipelago. " | 
					
						
							|  |  |  |         "This guide covers single-player, multiworld, and related software.", | 
					
						
							| 
									
										
										
										
											2022-05-11 13:05:53 -05:00
										 |  |  |         "English", | 
					
						
							|  |  |  |         "slay-the-spire_en.md", | 
					
						
							|  |  |  |         "slay-the-spire/en", | 
					
						
							|  |  |  |         ["Phar"] | 
					
						
							|  |  |  |     )] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | class SpireWorld(World): | 
					
						
							| 
									
										
										
										
											2022-08-06 21:36:32 -05:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     A deck-building roguelike where you must craft a unique deck, encounter bizarre creatures, discover relics of | 
					
						
							|  |  |  |     immense power, and Slay the Spire! | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-15 16:46:59 -05:00
										 |  |  |     option_definitions = spire_options | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  |     game = "Slay the Spire" | 
					
						
							|  |  |  |     topology_present = False | 
					
						
							|  |  |  |     data_version = 1 | 
					
						
							| 
									
										
										
										
											2022-05-11 13:05:53 -05:00
										 |  |  |     web = SpireWeb() | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     item_name_to_id = {name: data.code for name, data in item_table.items()} | 
					
						
							|  |  |  |     location_name_to_id = location_table | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 16:04:37 +02:00
										 |  |  |     forced_auto_forfeit = True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  |     def _get_slot_data(self): | 
					
						
							|  |  |  |         return { | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             'seed': "".join(self.multiworld.slot_seeds[self.player].choice(string.ascii_letters) for i in range(16)), | 
					
						
							|  |  |  |             'character': self.multiworld.character[self.player], | 
					
						
							|  |  |  |             'ascension': self.multiworld.ascension[self.player], | 
					
						
							|  |  |  |             'heart_run': self.multiworld.heart_run[self.player] | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def generate_basic(self): | 
					
						
							|  |  |  |         # Fill out our pool with our items from item_pool, assuming 1 item if not present in item_pool | 
					
						
							|  |  |  |         pool = [] | 
					
						
							|  |  |  |         for name, data in item_table.items(): | 
					
						
							|  |  |  |             if not data.event: | 
					
						
							| 
									
										
										
										
											2022-06-17 03:23:27 +02:00
										 |  |  |                 for amount in range(item_pool.get(name, 1)): | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  |                     item = SpireItem(name, self.player) | 
					
						
							|  |  |  |                     pool.append(item) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |         self.multiworld.itempool += pool | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Pair up our event locations with our event items | 
					
						
							|  |  |  |         for event, item in event_item_pairs.items(): | 
					
						
							|  |  |  |             event_item = SpireItem(item, self.player) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             self.multiworld.get_location(event, self.player).place_locked_item(event_item) | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |         if self.multiworld.logic[self.player] != 'no logic': | 
					
						
							|  |  |  |             self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_rules(self): | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |         set_rules(self.multiworld, self.player) | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def create_item(self, name: str) -> Item: | 
					
						
							| 
									
										
										
										
											2022-06-17 03:23:27 +02:00
										 |  |  |         return SpireItem(name, self.player) | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def create_regions(self): | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |         create_regions(self.multiworld, self.player) | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def fill_slot_data(self) -> dict: | 
					
						
							|  |  |  |         slot_data = self._get_slot_data() | 
					
						
							|  |  |  |         for option_name in spire_options: | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |             option = getattr(self.multiworld, option_name)[self.player] | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  |             slot_data[option_name] = int(option.value) | 
					
						
							|  |  |  |         return slot_data | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-19 09:37:26 -04:00
										 |  |  |     def get_filler_item_name(self) -> str: | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |         return self.multiworld.random.choice(["Card Draw", "Card Draw", "Card Draw", "Relic", "Relic"]) | 
					
						
							| 
									
										
										
										
											2022-05-19 09:37:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None): | 
					
						
							| 
									
										
										
										
											2022-06-17 03:23:27 +02:00
										 |  |  |     ret = Region(name, RegionType.Generic, name, player) | 
					
						
							| 
									
										
										
										
											2022-10-31 21:41:21 -05:00
										 |  |  |     ret.multiworld = world | 
					
						
							| 
									
										
										
										
											2021-08-29 08:30:44 -07:00
										 |  |  |     if locations: | 
					
						
							|  |  |  |         for location in locations: | 
					
						
							|  |  |  |             loc_id = location_table.get(location, 0) | 
					
						
							|  |  |  |             location = SpireLocation(player, location, loc_id, ret) | 
					
						
							|  |  |  |             ret.locations.append(location) | 
					
						
							|  |  |  |     if exits: | 
					
						
							|  |  |  |         for exit in exits: | 
					
						
							|  |  |  |             ret.exits.append(Entrance(player, exit, ret)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ret | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SpireLocation(Location): | 
					
						
							|  |  |  |     game: str = "Slay the Spire" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, player: int, name: str, address=None, parent=None): | 
					
						
							|  |  |  |         super(SpireLocation, self).__init__(player, name, address, parent) | 
					
						
							|  |  |  |         if address is None: | 
					
						
							|  |  |  |             self.event = True | 
					
						
							|  |  |  |             self.locked = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SpireItem(Item): | 
					
						
							|  |  |  |     game = "Slay the Spire" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, name, player: int = None): | 
					
						
							|  |  |  |         item_data = item_table[name] | 
					
						
							| 
									
										
										
										
											2022-06-17 03:23:27 +02:00
										 |  |  |         super(SpireItem, self).__init__( | 
					
						
							|  |  |  |             name, | 
					
						
							|  |  |  |             ItemClassification.progression if item_data.progression else ItemClassification.filler, | 
					
						
							|  |  |  |             item_data.code, player | 
					
						
							|  |  |  |         ) |