| 
									
										
											  
											
												Castlevania: Circle of the Moon - Implement New Game (#3299)
* Add the cotm package with working seed playthrough generation.
* Add the proper event flag IDs for the Item codes.
* Oooops. Put the world completion condition in!
* Adjust the game name and abbreviations.
* Implement more settings.
* Account for too many start_inventory_from_pool cards with Halve DSS Cards Placed.
* Working (albeit very sloooooooooooow) ROM patching.
* Screw you, bsdiff! AP Procedure Patch for life!
* Nuke stage_assert_generate as the ROM is no longer needed for that.
* Working item writing and position adjusting.
* Fix the magic item graphics in Locations wherein they can be fixed.
* Enable sub-weapon shuffle
* Get the seed display working.
* Get the enemy item drop randomization working. Phew!
* Enemy drop rando and seed display fixes.
* Functional Countdown + Early Double setting
* Working multiworld (yay!)
* Fix item links and demo shenanigans.
* Add Wii U VC hash and a docs section explaining the rereleases.
* Change all client read/writes to EWRAM instead of Combined WRAM.
* Custom text insertion foundations.
* Working text converter and word wrap detector.
* More refinements to the text wrap system.
* Well and truly working sent/received messages.
* Add DeathLink and Battle Arena goal options.
* Add tracker stuff, unittests, all locations countdown, presets.
* Add to README, CODEOWNERS, and inno_setup
* Add to README, CODEOWNERS, and inno_setup
* Address some suggestions/problems.
* Switch the Items and Locations to using dataclasses.
* Add note about the alternate classes to the Game Page.
* Oooops, typo!
* Touch up the Options descriptions.
* Fix Battle Arena flag being detected incorrectly on connection and name the locked location/item pairs better.
* Implement option groups
* Swap the Lizard-man Locations into their correct Regions.
* Local start inventory, better DeathLink message handling, handle receiving over 255 of an item.
* Update the PopTracker pack links to no longer point to the Releases page.
* Add Skip Dialogues option.
* Update the presets for the accessibility rework.
* Swap the choices in the accessibility preset options.
* Uhhhhhhh...just see the apworld v4 changelog for this one.
* Ooops, typo!
* .
* Bunch of small stuff
* Correctly change "Fake" to "Breakable" in this comment.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Make can_touch_water one line.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Make broke_iron_maidens one line.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Fix majors countdown and make can_open_ceremonial_door one line.
* Make the Trap AP Item less obvious.
* Add Progression + Useful stuff, patcher handling for incompatible versions, and fix some mypy stuff.
* Better option groups.
* Change Early Double to Early Escape Item.
* Update DeathLink description and ditch the Menu region.
* Fix the Start Broken choice for Iron Maiden Behavior
* Remove the forced option change with Arena goal + required All Bosses and Arena.
* Update the Game Page with the removal of the forced option combination change.
* Fix client potential to send packets nonstop.
* More review addressing.
* Fix the new select_drop code.
* Fix the new select_drop code for REAL this time.
* Send another LocationScout if we send Location checks without having the Location info.
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
Co-authored-by: Exempt-Medic <ExemptMedic@Gmail.com>
Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
											
										 
											2024-12-12 06:47:47 -07:00
										 |  |  | import os | 
					
						
							|  |  |  | import typing | 
					
						
							|  |  |  | import settings | 
					
						
							|  |  |  | import base64 | 
					
						
							|  |  |  | import logging | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from BaseClasses import Item, Region, Tutorial, ItemClassification | 
					
						
							|  |  |  | from .items import CVCotMItem, FILLER_ITEM_NAMES, ACTION_CARDS, ATTRIBUTE_CARDS, cvcotm_item_info, \ | 
					
						
							|  |  |  |     get_item_names_to_ids, get_item_counts | 
					
						
							|  |  |  | from .locations import CVCotMLocation, get_location_names_to_ids, BASE_ID, get_named_locations_data, \ | 
					
						
							|  |  |  |     get_location_name_groups | 
					
						
							|  |  |  | from .options import cvcotm_option_groups, CVCotMOptions, SubWeaponShuffle, IronMaidenBehavior, RequiredSkirmishes, \ | 
					
						
							|  |  |  |     CompletionGoal, EarlyEscapeItem | 
					
						
							|  |  |  | from .regions import get_region_info, get_all_region_names | 
					
						
							|  |  |  | from .rules import CVCotMRules | 
					
						
							|  |  |  | from .data import iname, lname | 
					
						
							|  |  |  | from .presets import cvcotm_options_presets | 
					
						
							|  |  |  | from worlds.AutoWorld import WebWorld, World | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from .aesthetics import shuffle_sub_weapons, get_location_data, get_countdown_flags, populate_enemy_drops, \ | 
					
						
							|  |  |  |     get_start_inventory_data | 
					
						
							| 
									
										
										
										
											2025-03-12 17:21:09 -06:00
										 |  |  | from .rom import RomData, patch_rom, get_base_rom_path, CVCotMProcedurePatch, CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH | 
					
						
							|  |  |  |     # CVCOTM_VC_US_HASH | 
					
						
							| 
									
										
											  
											
												Castlevania: Circle of the Moon - Implement New Game (#3299)
* Add the cotm package with working seed playthrough generation.
* Add the proper event flag IDs for the Item codes.
* Oooops. Put the world completion condition in!
* Adjust the game name and abbreviations.
* Implement more settings.
* Account for too many start_inventory_from_pool cards with Halve DSS Cards Placed.
* Working (albeit very sloooooooooooow) ROM patching.
* Screw you, bsdiff! AP Procedure Patch for life!
* Nuke stage_assert_generate as the ROM is no longer needed for that.
* Working item writing and position adjusting.
* Fix the magic item graphics in Locations wherein they can be fixed.
* Enable sub-weapon shuffle
* Get the seed display working.
* Get the enemy item drop randomization working. Phew!
* Enemy drop rando and seed display fixes.
* Functional Countdown + Early Double setting
* Working multiworld (yay!)
* Fix item links and demo shenanigans.
* Add Wii U VC hash and a docs section explaining the rereleases.
* Change all client read/writes to EWRAM instead of Combined WRAM.
* Custom text insertion foundations.
* Working text converter and word wrap detector.
* More refinements to the text wrap system.
* Well and truly working sent/received messages.
* Add DeathLink and Battle Arena goal options.
* Add tracker stuff, unittests, all locations countdown, presets.
* Add to README, CODEOWNERS, and inno_setup
* Add to README, CODEOWNERS, and inno_setup
* Address some suggestions/problems.
* Switch the Items and Locations to using dataclasses.
* Add note about the alternate classes to the Game Page.
* Oooops, typo!
* Touch up the Options descriptions.
* Fix Battle Arena flag being detected incorrectly on connection and name the locked location/item pairs better.
* Implement option groups
* Swap the Lizard-man Locations into their correct Regions.
* Local start inventory, better DeathLink message handling, handle receiving over 255 of an item.
* Update the PopTracker pack links to no longer point to the Releases page.
* Add Skip Dialogues option.
* Update the presets for the accessibility rework.
* Swap the choices in the accessibility preset options.
* Uhhhhhhh...just see the apworld v4 changelog for this one.
* Ooops, typo!
* .
* Bunch of small stuff
* Correctly change "Fake" to "Breakable" in this comment.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Make can_touch_water one line.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Make broke_iron_maidens one line.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Fix majors countdown and make can_open_ceremonial_door one line.
* Make the Trap AP Item less obvious.
* Add Progression + Useful stuff, patcher handling for incompatible versions, and fix some mypy stuff.
* Better option groups.
* Change Early Double to Early Escape Item.
* Update DeathLink description and ditch the Menu region.
* Fix the Start Broken choice for Iron Maiden Behavior
* Remove the forced option change with Arena goal + required All Bosses and Arena.
* Update the Game Page with the removal of the forced option combination change.
* Fix client potential to send packets nonstop.
* More review addressing.
* Fix the new select_drop code.
* Fix the new select_drop code for REAL this time.
* Send another LocationScout if we send Location checks without having the Location info.
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
Co-authored-by: Exempt-Medic <ExemptMedic@Gmail.com>
Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
											
										 
											2024-12-12 06:47:47 -07:00
										 |  |  | from .client import CastlevaniaCotMClient | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CVCotMSettings(settings.Group): | 
					
						
							|  |  |  |     class RomFile(settings.UserFilePath): | 
					
						
							|  |  |  |         """File name of the Castlevania CotM US rom""" | 
					
						
							|  |  |  |         copy_to = "Castlevania - Circle of the Moon (USA).gba" | 
					
						
							|  |  |  |         description = "Castlevania CotM (US) ROM File" | 
					
						
							| 
									
										
										
										
											2025-03-12 17:21:09 -06:00
										 |  |  |         # md5s = [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH, CVCOTM_VC_US_HASH] | 
					
						
							|  |  |  |         md5s = [CVCOTM_CT_US_HASH, CVCOTM_AC_US_HASH] | 
					
						
							| 
									
										
											  
											
												Castlevania: Circle of the Moon - Implement New Game (#3299)
* Add the cotm package with working seed playthrough generation.
* Add the proper event flag IDs for the Item codes.
* Oooops. Put the world completion condition in!
* Adjust the game name and abbreviations.
* Implement more settings.
* Account for too many start_inventory_from_pool cards with Halve DSS Cards Placed.
* Working (albeit very sloooooooooooow) ROM patching.
* Screw you, bsdiff! AP Procedure Patch for life!
* Nuke stage_assert_generate as the ROM is no longer needed for that.
* Working item writing and position adjusting.
* Fix the magic item graphics in Locations wherein they can be fixed.
* Enable sub-weapon shuffle
* Get the seed display working.
* Get the enemy item drop randomization working. Phew!
* Enemy drop rando and seed display fixes.
* Functional Countdown + Early Double setting
* Working multiworld (yay!)
* Fix item links and demo shenanigans.
* Add Wii U VC hash and a docs section explaining the rereleases.
* Change all client read/writes to EWRAM instead of Combined WRAM.
* Custom text insertion foundations.
* Working text converter and word wrap detector.
* More refinements to the text wrap system.
* Well and truly working sent/received messages.
* Add DeathLink and Battle Arena goal options.
* Add tracker stuff, unittests, all locations countdown, presets.
* Add to README, CODEOWNERS, and inno_setup
* Add to README, CODEOWNERS, and inno_setup
* Address some suggestions/problems.
* Switch the Items and Locations to using dataclasses.
* Add note about the alternate classes to the Game Page.
* Oooops, typo!
* Touch up the Options descriptions.
* Fix Battle Arena flag being detected incorrectly on connection and name the locked location/item pairs better.
* Implement option groups
* Swap the Lizard-man Locations into their correct Regions.
* Local start inventory, better DeathLink message handling, handle receiving over 255 of an item.
* Update the PopTracker pack links to no longer point to the Releases page.
* Add Skip Dialogues option.
* Update the presets for the accessibility rework.
* Swap the choices in the accessibility preset options.
* Uhhhhhhh...just see the apworld v4 changelog for this one.
* Ooops, typo!
* .
* Bunch of small stuff
* Correctly change "Fake" to "Breakable" in this comment.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Make can_touch_water one line.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Make broke_iron_maidens one line.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Fix majors countdown and make can_open_ceremonial_door one line.
* Make the Trap AP Item less obvious.
* Add Progression + Useful stuff, patcher handling for incompatible versions, and fix some mypy stuff.
* Better option groups.
* Change Early Double to Early Escape Item.
* Update DeathLink description and ditch the Menu region.
* Fix the Start Broken choice for Iron Maiden Behavior
* Remove the forced option change with Arena goal + required All Bosses and Arena.
* Update the Game Page with the removal of the forced option combination change.
* Fix client potential to send packets nonstop.
* More review addressing.
* Fix the new select_drop code.
* Fix the new select_drop code for REAL this time.
* Send another LocationScout if we send Location checks without having the Location info.
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
Co-authored-by: Exempt-Medic <ExemptMedic@Gmail.com>
Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
											
										 
											2024-12-12 06:47:47 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     rom_file: RomFile = RomFile(RomFile.copy_to) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CVCotMWeb(WebWorld): | 
					
						
							|  |  |  |     theme = "stone" | 
					
						
							|  |  |  |     options_presets = cvcotm_options_presets | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tutorials = [Tutorial( | 
					
						
							|  |  |  |         "Multiworld Setup Guide", | 
					
						
							|  |  |  |         "A guide to setting up the Archipleago Castlevania: Circle of the Moon randomizer on your computer and " | 
					
						
							|  |  |  |         "connecting it to a multiworld.", | 
					
						
							|  |  |  |         "English", | 
					
						
							|  |  |  |         "setup_en.md", | 
					
						
							|  |  |  |         "setup/en", | 
					
						
							|  |  |  |         ["Liquid Cat"] | 
					
						
							|  |  |  |     )] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     option_groups = cvcotm_option_groups | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CVCotMWorld(World): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Castlevania: Circle of the Moon is a launch title for the Game Boy Advance and the first of three Castlevania games | 
					
						
							|  |  |  |     released for the handheld in the "Metroidvania" format. As Nathan Graves, wielding the Hunter Whip and utilizing the | 
					
						
							|  |  |  |     Dual Set-Up System for new possibilities, you must battle your way through Camilla's castle and rescue your master | 
					
						
							|  |  |  |     from a demonic ritual to restore the Count's power... | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     game = "Castlevania - Circle of the Moon" | 
					
						
							|  |  |  |     item_name_groups = { | 
					
						
							|  |  |  |         "DSS": ACTION_CARDS.union(ATTRIBUTE_CARDS), | 
					
						
							|  |  |  |         "Card": ACTION_CARDS.union(ATTRIBUTE_CARDS), | 
					
						
							|  |  |  |         "Action": ACTION_CARDS, | 
					
						
							|  |  |  |         "Action Card": ACTION_CARDS, | 
					
						
							|  |  |  |         "Attribute": ATTRIBUTE_CARDS, | 
					
						
							|  |  |  |         "Attribute Card": ATTRIBUTE_CARDS, | 
					
						
							|  |  |  |         "Freeze": {iname.serpent, iname.cockatrice, iname.mercury, iname.mars}, | 
					
						
							|  |  |  |         "Freeze Action": {iname.mercury, iname.mars}, | 
					
						
							|  |  |  |         "Freeze Attribute": {iname.serpent, iname.cockatrice} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     location_name_groups = get_location_name_groups() | 
					
						
							|  |  |  |     options_dataclass = CVCotMOptions | 
					
						
							|  |  |  |     options: CVCotMOptions | 
					
						
							|  |  |  |     settings: typing.ClassVar[CVCotMSettings] | 
					
						
							|  |  |  |     origin_region_name = "Catacomb" | 
					
						
							|  |  |  |     hint_blacklist = frozenset({lname.ba24})  # The Battle Arena reward, if it's put in, will always be a Last Key. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     item_name_to_id = {name: cvcotm_item_info[name].code + BASE_ID for name in cvcotm_item_info | 
					
						
							|  |  |  |                        if cvcotm_item_info[name].code is not None} | 
					
						
							|  |  |  |     location_name_to_id = get_location_names_to_ids() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Default values to possibly be updated in generate_early | 
					
						
							|  |  |  |     total_last_keys: int = 0 | 
					
						
							|  |  |  |     required_last_keys: int = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auth: bytearray | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     web = CVCotMWeb() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def generate_early(self) -> None: | 
					
						
							|  |  |  |         # Generate the player's unique authentication | 
					
						
							|  |  |  |         self.auth = bytearray(self.random.getrandbits(8) for _ in range(16)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # If Required Skirmishes are on, force the Required and Available Last Keys to 8 or 9 depending on which option | 
					
						
							|  |  |  |         # was chosen. | 
					
						
							|  |  |  |         if self.options.required_skirmishes == RequiredSkirmishes.option_all_bosses: | 
					
						
							|  |  |  |             self.options.required_last_keys.value = 8 | 
					
						
							|  |  |  |             self.options.available_last_keys.value = 8 | 
					
						
							|  |  |  |         elif self.options.required_skirmishes == RequiredSkirmishes.option_all_bosses_and_arena: | 
					
						
							|  |  |  |             self.options.required_last_keys.value = 9 | 
					
						
							|  |  |  |             self.options.available_last_keys.value = 9 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.total_last_keys = self.options.available_last_keys.value | 
					
						
							|  |  |  |         self.required_last_keys = self.options.required_last_keys.value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # If there are more Last Keys required than there are Last Keys in total, drop the required Last Keys to | 
					
						
							|  |  |  |         # the total Last Keys. | 
					
						
							|  |  |  |         if self.required_last_keys > self.total_last_keys: | 
					
						
							|  |  |  |             self.required_last_keys = self.total_last_keys | 
					
						
							|  |  |  |             logging.warning(f"[{self.player_name}] The Required Last Keys " | 
					
						
							|  |  |  |                             f"({self.options.required_last_keys.value}) is higher than the Available Last Keys " | 
					
						
							|  |  |  |                             f"({self.options.available_last_keys.value}). Lowering the required number to: " | 
					
						
							|  |  |  |                             f"{self.required_last_keys}") | 
					
						
							|  |  |  |             self.options.required_last_keys.value = self.required_last_keys | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Place the Double or Roc Wing in local_early_items if the Early Escape option is being used. | 
					
						
							|  |  |  |         if self.options.early_escape_item == EarlyEscapeItem.option_double: | 
					
						
							|  |  |  |             self.multiworld.local_early_items[self.player][iname.double] = 1 | 
					
						
							|  |  |  |         elif self.options.early_escape_item == EarlyEscapeItem.option_roc_wing: | 
					
						
							|  |  |  |             self.multiworld.local_early_items[self.player][iname.roc_wing] = 1 | 
					
						
							|  |  |  |         elif self.options.early_escape_item == EarlyEscapeItem.option_double_or_roc_wing: | 
					
						
							|  |  |  |             self.multiworld.local_early_items[self.player][self.random.choice([iname.double, iname.roc_wing])] = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_regions(self) -> None: | 
					
						
							|  |  |  |         # Create every Region object. | 
					
						
							|  |  |  |         created_regions = [Region(name, self.player, self.multiworld) for name in get_all_region_names()] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Attach the Regions to the Multiworld. | 
					
						
							|  |  |  |         self.multiworld.regions.extend(created_regions) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for reg in created_regions: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Add the Entrances to all the Regions. | 
					
						
							|  |  |  |             ent_destinations_and_names = get_region_info(reg.name, "entrances") | 
					
						
							|  |  |  |             if ent_destinations_and_names is not None: | 
					
						
							|  |  |  |                 reg.add_exits(ent_destinations_and_names) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Add the Locations to all the Regions. | 
					
						
							|  |  |  |             loc_names = get_region_info(reg.name, "locations") | 
					
						
							|  |  |  |             if loc_names is None: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             locations_with_ids, locked_pairs = get_named_locations_data(loc_names, self.options) | 
					
						
							|  |  |  |             reg.add_locations(locations_with_ids, CVCotMLocation) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Place locked Items on all of their associated Locations. | 
					
						
							|  |  |  |             for locked_loc, locked_item in locked_pairs.items(): | 
					
						
							|  |  |  |                 self.get_location(locked_loc).place_locked_item(self.create_item(locked_item, | 
					
						
							|  |  |  |                                                                                  ItemClassification.progression)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_item(self, name: str, force_classification: typing.Optional[ItemClassification] = None) -> Item: | 
					
						
							|  |  |  |         if force_classification is not None: | 
					
						
							|  |  |  |             classification = force_classification | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             classification = cvcotm_item_info[name].default_classification | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         code = cvcotm_item_info[name].code | 
					
						
							|  |  |  |         if code is not None: | 
					
						
							|  |  |  |             code += BASE_ID | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         created_item = CVCotMItem(name, classification, code, self.player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return created_item | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def create_items(self) -> None: | 
					
						
							|  |  |  |         item_counts = get_item_counts(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Set up the items correctly | 
					
						
							|  |  |  |         self.multiworld.itempool += [self.create_item(item, classification) for classification in item_counts for item | 
					
						
							|  |  |  |                                      in item_counts[classification] for _ in range(item_counts[classification][item])] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_rules(self) -> None: | 
					
						
							|  |  |  |         # Set all the Entrance and Location rules properly. | 
					
						
							|  |  |  |         CVCotMRules(self).set_cvcotm_rules() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def generate_output(self, output_directory: str) -> None: | 
					
						
							|  |  |  |         # Get out all the Locations that are not Events. Only take the Iron Maiden switch if the Maiden Detonator is in | 
					
						
							|  |  |  |         # the item pool. | 
					
						
							|  |  |  |         active_locations = [loc for loc in self.multiworld.get_locations(self.player) if loc.address is not None and | 
					
						
							|  |  |  |                             (loc.name != lname.ct21 or self.options.iron_maiden_behavior == | 
					
						
							|  |  |  |                              IronMaidenBehavior.option_detonator_in_pool)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Location data | 
					
						
							|  |  |  |         offset_data = get_location_data(self, active_locations) | 
					
						
							|  |  |  |         # Sub-weapons | 
					
						
							|  |  |  |         if self.options.sub_weapon_shuffle: | 
					
						
							|  |  |  |             offset_data.update(shuffle_sub_weapons(self)) | 
					
						
							|  |  |  |         # Item drop randomization | 
					
						
							|  |  |  |         if self.options.item_drop_randomization: | 
					
						
							|  |  |  |             offset_data.update(populate_enemy_drops(self)) | 
					
						
							|  |  |  |         # Countdown | 
					
						
							|  |  |  |         if self.options.countdown: | 
					
						
							|  |  |  |             offset_data.update(get_countdown_flags(self, active_locations)) | 
					
						
							|  |  |  |         # Start Inventory | 
					
						
							|  |  |  |         start_inventory_data = get_start_inventory_data(self) | 
					
						
							|  |  |  |         offset_data.update(start_inventory_data[0]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         patch = CVCotMProcedurePatch(player=self.player, player_name=self.player_name) | 
					
						
							|  |  |  |         patch_rom(self, patch, offset_data, start_inventory_data[1]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         rom_path = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}" | 
					
						
							|  |  |  |                                                   f"{patch.patch_file_ending}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         patch.write(rom_path) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def fill_slot_data(self) -> dict: | 
					
						
							|  |  |  |         return {"death_link": self.options.death_link.value, | 
					
						
							|  |  |  |                 "iron_maiden_behavior": self.options.iron_maiden_behavior.value, | 
					
						
							|  |  |  |                 "ignore_cleansing": self.options.ignore_cleansing.value, | 
					
						
							|  |  |  |                 "skip_tutorials": self.options.skip_tutorials.value, | 
					
						
							|  |  |  |                 "required_last_keys": self.required_last_keys, | 
					
						
							| 
									
										
										
										
											2025-05-28 08:47:24 -06:00
										 |  |  |                 "completion_goal": self.options.completion_goal.value, | 
					
						
							|  |  |  |                 "nerf_roc_wing": self.options.nerf_roc_wing.value} | 
					
						
							| 
									
										
											  
											
												Castlevania: Circle of the Moon - Implement New Game (#3299)
* Add the cotm package with working seed playthrough generation.
* Add the proper event flag IDs for the Item codes.
* Oooops. Put the world completion condition in!
* Adjust the game name and abbreviations.
* Implement more settings.
* Account for too many start_inventory_from_pool cards with Halve DSS Cards Placed.
* Working (albeit very sloooooooooooow) ROM patching.
* Screw you, bsdiff! AP Procedure Patch for life!
* Nuke stage_assert_generate as the ROM is no longer needed for that.
* Working item writing and position adjusting.
* Fix the magic item graphics in Locations wherein they can be fixed.
* Enable sub-weapon shuffle
* Get the seed display working.
* Get the enemy item drop randomization working. Phew!
* Enemy drop rando and seed display fixes.
* Functional Countdown + Early Double setting
* Working multiworld (yay!)
* Fix item links and demo shenanigans.
* Add Wii U VC hash and a docs section explaining the rereleases.
* Change all client read/writes to EWRAM instead of Combined WRAM.
* Custom text insertion foundations.
* Working text converter and word wrap detector.
* More refinements to the text wrap system.
* Well and truly working sent/received messages.
* Add DeathLink and Battle Arena goal options.
* Add tracker stuff, unittests, all locations countdown, presets.
* Add to README, CODEOWNERS, and inno_setup
* Add to README, CODEOWNERS, and inno_setup
* Address some suggestions/problems.
* Switch the Items and Locations to using dataclasses.
* Add note about the alternate classes to the Game Page.
* Oooops, typo!
* Touch up the Options descriptions.
* Fix Battle Arena flag being detected incorrectly on connection and name the locked location/item pairs better.
* Implement option groups
* Swap the Lizard-man Locations into their correct Regions.
* Local start inventory, better DeathLink message handling, handle receiving over 255 of an item.
* Update the PopTracker pack links to no longer point to the Releases page.
* Add Skip Dialogues option.
* Update the presets for the accessibility rework.
* Swap the choices in the accessibility preset options.
* Uhhhhhhh...just see the apworld v4 changelog for this one.
* Ooops, typo!
* .
* Bunch of small stuff
* Correctly change "Fake" to "Breakable" in this comment.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Make can_touch_water one line.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Make broke_iron_maidens one line.
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* Fix majors countdown and make can_open_ceremonial_door one line.
* Make the Trap AP Item less obvious.
* Add Progression + Useful stuff, patcher handling for incompatible versions, and fix some mypy stuff.
* Better option groups.
* Change Early Double to Early Escape Item.
* Update DeathLink description and ditch the Menu region.
* Fix the Start Broken choice for Iron Maiden Behavior
* Remove the forced option change with Arena goal + required All Bosses and Arena.
* Update the Game Page with the removal of the forced option combination change.
* Fix client potential to send packets nonstop.
* More review addressing.
* Fix the new select_drop code.
* Fix the new select_drop code for REAL this time.
* Send another LocationScout if we send Location checks without having the Location info.
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
Co-authored-by: Exempt-Medic <ExemptMedic@Gmail.com>
Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
											
										 
											2024-12-12 06:47:47 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_filler_item_name(self) -> str: | 
					
						
							|  |  |  |         return self.random.choice(FILLER_ITEM_NAMES) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def modify_multidata(self, multidata: typing.Dict[str, typing.Any]): | 
					
						
							|  |  |  |         # Put the player's unique authentication in connect_names. | 
					
						
							|  |  |  |         multidata["connect_names"][base64.b64encode(self.auth).decode("ascii")] = \ | 
					
						
							|  |  |  |             multidata["connect_names"][self.player_name] |