[Slay the Spire] Enable support for modded characters, and add downfall support (#1368)
* add ability to choose custom characters in STS * bump required protocol (client?) version. * fix slot data fill. * add downfall mode, as well as characters. * small change in documentation for character choice as it now uses internal ID's instead of visible titles... because other languages are a thing.
This commit is contained in:
		| @@ -1,15 +1,34 @@ | ||||
| import typing | ||||
| from Options import Choice, Option, Range, Toggle | ||||
| from Options import TextChoice, Option, Range, Toggle | ||||
|  | ||||
|  | ||||
| class Character(Choice): | ||||
|     """Pick What Character you wish to play with.""" | ||||
| class Character(TextChoice): | ||||
|     """Enter the internal ID of the character to use. | ||||
|  | ||||
|       if you don't know the exact ID to enter with the mod installed go to | ||||
|      `Mods -> Archipelago Multi-world -> config` to view a list of installed modded character IDs. | ||||
|  | ||||
|      the downfall characters will only work if you have downfall installed. | ||||
|  | ||||
|      Spire Take the Wheel will have your client pick a random character from the list of all your installed characters | ||||
|      including custom ones. | ||||
|  | ||||
|      if the chosen character mod is not installed it will default back to 'The Ironclad' | ||||
|      """ | ||||
|     display_name = "Character" | ||||
|     option_ironclad = 0 | ||||
|     option_silent = 1 | ||||
|     option_defect = 2 | ||||
|     option_watcher = 3 | ||||
|     default = 0 | ||||
|     option_The_Ironclad = 0 | ||||
|     option_The_Silent = 1 | ||||
|     option_The_Defect = 2 | ||||
|     option_The_Watcher = 3 | ||||
|     option_The_Hermit = 4 | ||||
|     option_The_Slime_Boss = 5 | ||||
|     option_The_Guardian = 6 | ||||
|     option_The_Hexaghost = 7 | ||||
|     option_The_Champ = 8 | ||||
|     option_The_Gremlins = 9 | ||||
|     option_The_Automaton = 10 | ||||
|     option_The_Snecko = 11 | ||||
|     option_spire_take_the_wheel = 12 | ||||
|  | ||||
|  | ||||
| class Ascension(Range): | ||||
| @@ -20,10 +39,17 @@ class Ascension(Range): | ||||
|     default = 0 | ||||
|  | ||||
|  | ||||
| class HeartRun(Toggle): | ||||
|     """Whether or not you will need to collect the 3 keys and enter the final act to | ||||
|     complete the game. The Heart does not need to be defeated.""" | ||||
|     display_name = "Heart Run" | ||||
| class FinalAct(Toggle): | ||||
|     """Whether you will need to collect the 3 keys and beat the final act to complete the game.""" | ||||
|     display_name = "Final Act" | ||||
|     option_true = 1 | ||||
|     option_false = 0 | ||||
|     default = 0 | ||||
|  | ||||
|  | ||||
| class Downfall(Toggle): | ||||
|     """When Downfall is Installed this will switch the played mode to Downfall""" | ||||
|     display_name = "Downfall" | ||||
|     option_true = 1 | ||||
|     option_false = 0 | ||||
|     default = 0 | ||||
| @@ -32,5 +58,6 @@ class HeartRun(Toggle): | ||||
| spire_options: typing.Dict[str, type(Option)] = { | ||||
|     "character": Character, | ||||
|     "ascension": Ascension, | ||||
|     "heart_run": HeartRun | ||||
|     "final_act": FinalAct, | ||||
|     "downfall": Downfall, | ||||
| } | ||||
|   | ||||
| @@ -32,18 +32,11 @@ class SpireWorld(World): | ||||
|     topology_present = False | ||||
|     data_version = 1 | ||||
|     web = SpireWeb() | ||||
|     required_client_version = (0, 3, 7) | ||||
|  | ||||
|     item_name_to_id = {name: data.code for name, data in item_table.items()} | ||||
|     location_name_to_id = location_table | ||||
|  | ||||
|     def _get_slot_data(self): | ||||
|         return { | ||||
|             'seed': "".join(self.multiworld.per_slot_randoms[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] | ||||
|         } | ||||
|  | ||||
|     def generate_basic(self): | ||||
|         # Fill out our pool with our items from item_pool, assuming 1 item if not present in item_pool | ||||
|         pool = [] | ||||
| @@ -63,7 +56,6 @@ class SpireWorld(World): | ||||
|         if self.multiworld.logic[self.player] != 'no logic': | ||||
|             self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) | ||||
|  | ||||
|  | ||||
|     def set_rules(self): | ||||
|         set_rules(self.multiworld, self.player) | ||||
|  | ||||
| @@ -74,10 +66,12 @@ class SpireWorld(World): | ||||
|         create_regions(self.multiworld, self.player) | ||||
|  | ||||
|     def fill_slot_data(self) -> dict: | ||||
|         slot_data = self._get_slot_data() | ||||
|         slot_data = { | ||||
|             'seed': "".join(self.multiworld.slot_seeds[self.player].choice(string.ascii_letters) for i in range(16)) | ||||
|         } | ||||
|         for option_name in spire_options: | ||||
|             option = getattr(self.multiworld, option_name)[self.player] | ||||
|             slot_data[option_name] = int(option.value) | ||||
|             slot_data[option_name] = option.value | ||||
|         return slot_data | ||||
|  | ||||
|     def get_filler_item_name(self) -> str: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 KonoTyran
					KonoTyran