| 
									
										
											  
											
												Mega Man 2: Implement New Game (#3256)
* initial (broken) commit
* small work on init
* Update Items.py
* beginning work, some rom patches
* commit progress from bh branch
* deathlink, fix soft-reset kill, e-tank loss
* begin work on targeting new bhclient
* write font
* definitely didn't forget to add the other two hashes no
* update to modern options, begin colors
* fix 6th letter bug
* palette shuffle + logic rewrite
* fix a bunch of pointers
* fix color changes, deathlink, and add wily 5 req
* adjust weapon weakness generation
* Update Rules.py
* attempt wily 5 softlock fix
* add explicit test for rbm weaknesses
* fix difficulty and hard reset
* fix connect deathlink and off by one item color
* fix atomic fire again
* de-jank deathlink
* rewrite wily5 rule
* fix rare solo-gen fill issue, hopefully
* Update Client.py
* fix wily 5 requirements
* undo fill hook
* fix picopico-kun rules
* for real this time
* update minimum damage requirement
* begin move to procedure patch
* finish move to APPP, allow rando boobeam, color updates
* fix color bug, UT support?
* what do you mean I forgot the procedure
* fix UT?
* plando weakness and fixes
* sfx when item received, more time stopper edge cases
* Update test_weakness.py
* fix rules and color bug
* fix color bug, support reduced flashing
* major world overhaul
* Update Locations.py
* fix first found bugs
* mypy cleanup
* headerless roms
* Update Rom.py
* further cleanup
* work on energylink
* el fixes
* update to energylink 2.0 packet
* energylink balancing
* potentially break other clients, more balancing
* Update Items.py
* remove startup change from basepatch
we write that in patch, since we also need to clean the area before applying
* el balancing and feedback
* hopefully less test failures?
* implement world version check
* add weapon/health option
* Update Rom.py
* x/x2
* specials
* Update Color.py
* Update Options.py
* finally apply location groups
* bump minor version number instead
* fix duplicate stage sends
* validate wily 5, tests
* see if renaming fixes
* add shuffled weakness
* remove passwords
* refresh rbm select, fix wily 5 validation
* forgot we can't check 0
* oops I broke the basepatch (remove failing test later)
* fix solo gen fill error?
* fix webhost patch recognition
* fix imports, basepatch
* move to flexibility metric for boss validation
* special case boobeam trap
* block strobe on stage select init
* more energylink balancing
* bump world version
* wily HP inaccurate in validation
* fix validation edge case
* save last completed wily to data storage
* mypy and pep8 cleanup
* fix file browse validation
* fix test failure, add enemy weakness
* remove test seed
* update enemy damage
* inno setup
* Update en_Mega Man 2.md
* setup guide
* Update en_Mega Man 2.md
* finish plando weakness section
* starting rbm edge case
* remove * imports
* properly wrap later weakness additions in regen playthrough
* fix import
* forgot readme
* remove time stopper special casing
since we moved to proper wily 5 validation, this special casing is no longer important
* properly type added locations
* Update CODEOWNERS
* add animation reduction
* deprioritize Time Stopper in rush checks
* special case wily phase 1
* fix key error
* forgot the test
* music and general cleanup
* the great rename
* fix import
* thanks pycharm
* reorder palette shuffle
* account for alien on shuffled weakness
* apply suggestions
* fix seedbleed
* fix invalid buster passthrough
* fix weakness landing beneath required amount
* fix failsafe
* finish music
* fix Time Stopper on Flash/Alien
* asar pls
* Apply suggestions from code review
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* world helpers
* init cleanup
* apostrophes
* clearer wording
* mypy and cleanup
* options doc cleanup
* Update rom.py
* rules cleanup
* Update __init__.py
* Update __init__.py
* move to defaultdict
* cleanup world helpers
* Update __init__.py
* remove unnecessary line from fill hook
* forgot the other one
* apply code review
* remove collect
* Update rules.py
* forgot another
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
											2024-08-19 21:59:29 -05:00
										 |  |  | from dataclasses import dataclass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from Options import Choice, Toggle, DeathLink, DefaultOnToggle, TextChoice, Range, OptionDict, PerGameCommonOptions | 
					
						
							|  |  |  | from schema import Schema, And, Use, Optional | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bosses = { | 
					
						
							|  |  |  |     "Heat Man": 0, | 
					
						
							|  |  |  |     "Air Man": 1, | 
					
						
							|  |  |  |     "Wood Man": 2, | 
					
						
							|  |  |  |     "Bubble Man": 3, | 
					
						
							|  |  |  |     "Quick Man": 4, | 
					
						
							|  |  |  |     "Flash Man": 5, | 
					
						
							|  |  |  |     "Metal Man": 6, | 
					
						
							|  |  |  |     "Crash Man": 7, | 
					
						
							|  |  |  |     "Mecha Dragon": 8, | 
					
						
							|  |  |  |     "Picopico-kun": 9, | 
					
						
							|  |  |  |     "Guts Tank": 10, | 
					
						
							|  |  |  |     "Boobeam Trap": 11, | 
					
						
							|  |  |  |     "Wily Machine 2": 12, | 
					
						
							|  |  |  |     "Alien": 13 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | weapons_to_id = { | 
					
						
							|  |  |  |     "Mega Buster": 0, | 
					
						
							|  |  |  |     "Atomic Fire": 1, | 
					
						
							|  |  |  |     "Air Shooter": 2, | 
					
						
							|  |  |  |     "Leaf Shield": 3, | 
					
						
							|  |  |  |     "Bubble Lead": 4, | 
					
						
							|  |  |  |     "Quick Boomerang": 5, | 
					
						
							|  |  |  |     "Metal Blade": 7, | 
					
						
							|  |  |  |     "Crash Bomber": 6, | 
					
						
							|  |  |  |     "Time Stopper": 8, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class EnergyLink(Toggle): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Enables EnergyLink support. | 
					
						
							|  |  |  |     When enabled, pickups dropped from enemies are sent to the EnergyLink pool, and healing/weapon energy/1-Ups can | 
					
						
							|  |  |  |     be requested from the EnergyLink pool. | 
					
						
							|  |  |  |     Some of the energy sent to the pool will be lost on transfer. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "EnergyLink" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class StartingRobotMaster(Choice): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     The initial stage unlocked at the start. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Starting Robot Master" | 
					
						
							|  |  |  |     option_heat_man = 0 | 
					
						
							|  |  |  |     option_air_man = 1 | 
					
						
							|  |  |  |     option_wood_man = 2 | 
					
						
							|  |  |  |     option_bubble_man = 3 | 
					
						
							|  |  |  |     option_quick_man = 4 | 
					
						
							|  |  |  |     option_flash_man = 5 | 
					
						
							|  |  |  |     option_metal_man = 6 | 
					
						
							|  |  |  |     option_crash_man = 7 | 
					
						
							|  |  |  |     default = "random" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class YokuJumps(Toggle): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     When enabled, the player is expected to be able to perform the yoku block sequence in Heat Man's | 
					
						
							|  |  |  |     stage without Item 2. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Yoku Block Jumps" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class EnableLasers(Toggle): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     When enabled, the player is expected to complete (and acquire items within) the laser sections of Quick Man's | 
					
						
							|  |  |  |     stage without the Time Stopper. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Enable Lasers" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Consumables(Choice): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     When enabled, e-tanks/1-ups/health/weapon energy will be added to the pool of items and included as checks. | 
					
						
							|  |  |  |     E-Tanks and 1-Ups add 20 checks to the pool. | 
					
						
							|  |  |  |     Weapon/Health Energy add 27 checks to the pool. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Consumables" | 
					
						
							|  |  |  |     option_none = 0 | 
					
						
							|  |  |  |     option_1up_etank = 1 | 
					
						
							|  |  |  |     option_weapon_health = 2 | 
					
						
							|  |  |  |     option_all = 3 | 
					
						
							|  |  |  |     default = 1 | 
					
						
							|  |  |  |     alias_true = 3 | 
					
						
							|  |  |  |     alias_false = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_option_name(cls, value: int) -> str: | 
					
						
							|  |  |  |         if value == 1: | 
					
						
							|  |  |  |             return "1-Ups/E-Tanks" | 
					
						
							|  |  |  |         if value == 2: | 
					
						
							|  |  |  |             return "Weapon/Health Energy" | 
					
						
							|  |  |  |         return super().get_option_name(value) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Quickswap(DefaultOnToggle): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     When enabled, the player can quickswap through all received weapons by pressing Select. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Quickswap" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PaletteShuffle(TextChoice): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Change the color of Mega Man and the Robot Masters. | 
					
						
							|  |  |  |     None: The palettes are unchanged. | 
					
						
							|  |  |  |     Shuffled: Palette colors are shuffled amongst the robot masters. | 
					
						
							|  |  |  |     Randomized: Random (usually good) palettes are generated for each robot master. | 
					
						
							|  |  |  |     Singularity: one palette is generated and used for all robot masters. | 
					
						
							|  |  |  |     Supports custom palettes using HTML named colors in the | 
					
						
							|  |  |  |     following format: Mega Buster-Lavender|Violet;randomized | 
					
						
							|  |  |  |     The first value is the character whose palette you'd like to define, then separated by - is a set of 2 colors for | 
					
						
							|  |  |  |     that character. separate every color with a pipe, and separate every character as well as the remaining shuffle with | 
					
						
							|  |  |  |     a semicolon. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Palette Shuffle" | 
					
						
							|  |  |  |     option_none = 0 | 
					
						
							|  |  |  |     option_shuffled = 1 | 
					
						
							|  |  |  |     option_randomized = 2 | 
					
						
							|  |  |  |     option_singularity = 3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class EnemyWeaknesses(Toggle): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Randomizes the damage dealt to enemies by weapons. Friender will always take damage from the buster. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Random Enemy Weaknesses" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class StrictWeaknesses(Toggle): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Only your starting Robot Master will take damage from the Mega Buster, the rest must be defeated with weapons. | 
					
						
							|  |  |  |     Weapons that only do 1-3 damage to bosses no longer deal damage (aside from Alien). | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Strict Boss Weaknesses" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class RandomWeaknesses(Choice): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     None: Bosses will have their regular weaknesses. | 
					
						
							|  |  |  |     Shuffled: Weapon damage will be shuffled amongst the weapons, so Metal Blade may do Bubble Lead damage. | 
					
						
							|  |  |  |     Time Stopper will deplete half of a random Robot Master's HP. | 
					
						
							|  |  |  |     Randomized: Weapon damage will be fully randomized. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Random Boss Weaknesses" | 
					
						
							|  |  |  |     option_none = 0 | 
					
						
							|  |  |  |     option_shuffled = 1 | 
					
						
							|  |  |  |     option_randomized = 2 | 
					
						
							|  |  |  |     alias_false = 0 | 
					
						
							|  |  |  |     alias_true = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Wily5Requirement(Range): | 
					
						
							|  |  |  |     """Change the number of Robot Masters that are required to be defeated for
 | 
					
						
							|  |  |  |     the teleporter to the Wily Machine to appear."""
 | 
					
						
							|  |  |  |     display_name = "Wily 5 Requirement" | 
					
						
							|  |  |  |     default = 8 | 
					
						
							|  |  |  |     range_start = 1 | 
					
						
							|  |  |  |     range_end = 8 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class WeaknessPlando(OptionDict): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Specify specific damage numbers for boss damage. Can be used even without strict/random weaknesses. | 
					
						
							|  |  |  |     plando_weakness: | 
					
						
							|  |  |  |         Robot Master: | 
					
						
							|  |  |  |             Weapon: Damage | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Plando Weaknesses" | 
					
						
							|  |  |  |     schema = Schema({ | 
					
						
							|  |  |  |         Optional(And(str, Use(str.title), lambda s: s in bosses)): { | 
					
						
							| 
									
										
										
										
											2025-01-28 14:45:28 -06:00
										 |  |  |             And(str, Use(str.title), lambda s: s in weapons_to_id): And(int, lambda i: i in range(-1, 15)) | 
					
						
							| 
									
										
											  
											
												Mega Man 2: Implement New Game (#3256)
* initial (broken) commit
* small work on init
* Update Items.py
* beginning work, some rom patches
* commit progress from bh branch
* deathlink, fix soft-reset kill, e-tank loss
* begin work on targeting new bhclient
* write font
* definitely didn't forget to add the other two hashes no
* update to modern options, begin colors
* fix 6th letter bug
* palette shuffle + logic rewrite
* fix a bunch of pointers
* fix color changes, deathlink, and add wily 5 req
* adjust weapon weakness generation
* Update Rules.py
* attempt wily 5 softlock fix
* add explicit test for rbm weaknesses
* fix difficulty and hard reset
* fix connect deathlink and off by one item color
* fix atomic fire again
* de-jank deathlink
* rewrite wily5 rule
* fix rare solo-gen fill issue, hopefully
* Update Client.py
* fix wily 5 requirements
* undo fill hook
* fix picopico-kun rules
* for real this time
* update minimum damage requirement
* begin move to procedure patch
* finish move to APPP, allow rando boobeam, color updates
* fix color bug, UT support?
* what do you mean I forgot the procedure
* fix UT?
* plando weakness and fixes
* sfx when item received, more time stopper edge cases
* Update test_weakness.py
* fix rules and color bug
* fix color bug, support reduced flashing
* major world overhaul
* Update Locations.py
* fix first found bugs
* mypy cleanup
* headerless roms
* Update Rom.py
* further cleanup
* work on energylink
* el fixes
* update to energylink 2.0 packet
* energylink balancing
* potentially break other clients, more balancing
* Update Items.py
* remove startup change from basepatch
we write that in patch, since we also need to clean the area before applying
* el balancing and feedback
* hopefully less test failures?
* implement world version check
* add weapon/health option
* Update Rom.py
* x/x2
* specials
* Update Color.py
* Update Options.py
* finally apply location groups
* bump minor version number instead
* fix duplicate stage sends
* validate wily 5, tests
* see if renaming fixes
* add shuffled weakness
* remove passwords
* refresh rbm select, fix wily 5 validation
* forgot we can't check 0
* oops I broke the basepatch (remove failing test later)
* fix solo gen fill error?
* fix webhost patch recognition
* fix imports, basepatch
* move to flexibility metric for boss validation
* special case boobeam trap
* block strobe on stage select init
* more energylink balancing
* bump world version
* wily HP inaccurate in validation
* fix validation edge case
* save last completed wily to data storage
* mypy and pep8 cleanup
* fix file browse validation
* fix test failure, add enemy weakness
* remove test seed
* update enemy damage
* inno setup
* Update en_Mega Man 2.md
* setup guide
* Update en_Mega Man 2.md
* finish plando weakness section
* starting rbm edge case
* remove * imports
* properly wrap later weakness additions in regen playthrough
* fix import
* forgot readme
* remove time stopper special casing
since we moved to proper wily 5 validation, this special casing is no longer important
* properly type added locations
* Update CODEOWNERS
* add animation reduction
* deprioritize Time Stopper in rush checks
* special case wily phase 1
* fix key error
* forgot the test
* music and general cleanup
* the great rename
* fix import
* thanks pycharm
* reorder palette shuffle
* account for alien on shuffled weakness
* apply suggestions
* fix seedbleed
* fix invalid buster passthrough
* fix weakness landing beneath required amount
* fix failsafe
* finish music
* fix Time Stopper on Flash/Alien
* asar pls
* Apply suggestions from code review
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
* world helpers
* init cleanup
* apostrophes
* clearer wording
* mypy and cleanup
* options doc cleanup
* Update rom.py
* rules cleanup
* Update __init__.py
* Update __init__.py
* move to defaultdict
* cleanup world helpers
* Update __init__.py
* remove unnecessary line from fill hook
* forgot the other one
* apply code review
* remove collect
* Update rules.py
* forgot another
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
											2024-08-19 21:59:29 -05:00
										 |  |  |         } | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     default = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ReduceFlashing(Choice): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Reduce flashing seen in gameplay, such as the stage select and when defeating a Wily boss. | 
					
						
							|  |  |  |     Virtual Console: increases length of most flashes, changes some flashes from white to a dark gray. | 
					
						
							|  |  |  |     Minor: VC changes + decreasing the speed of Bubble/Metal Man stage animations. | 
					
						
							|  |  |  |     Full: VC changes + further decreasing the brightness of most flashes and | 
					
						
							|  |  |  |     disables stage animations for Metal/Bubble Man stages. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Reduce Flashing" | 
					
						
							|  |  |  |     option_none = 0 | 
					
						
							|  |  |  |     option_virtual_console = 1 | 
					
						
							|  |  |  |     option_minor = 2 | 
					
						
							|  |  |  |     option_full = 3 | 
					
						
							|  |  |  |     default = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class RandomMusic(Choice): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Vanilla: music is unchanged | 
					
						
							|  |  |  |     Shuffled: stage and certain menu music is shuffled. | 
					
						
							|  |  |  |     Randomized: stage and certain menu music is randomly selected | 
					
						
							|  |  |  |     None: no music will play | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     display_name = "Random Music" | 
					
						
							|  |  |  |     option_vanilla = 0 | 
					
						
							|  |  |  |     option_shuffled = 1 | 
					
						
							|  |  |  |     option_randomized = 2 | 
					
						
							|  |  |  |     option_none = 3 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @dataclass | 
					
						
							|  |  |  | class MM2Options(PerGameCommonOptions): | 
					
						
							|  |  |  |     death_link: DeathLink | 
					
						
							|  |  |  |     energy_link: EnergyLink | 
					
						
							|  |  |  |     starting_robot_master: StartingRobotMaster | 
					
						
							|  |  |  |     consumables: Consumables | 
					
						
							|  |  |  |     yoku_jumps: YokuJumps | 
					
						
							|  |  |  |     enable_lasers: EnableLasers | 
					
						
							|  |  |  |     enemy_weakness: EnemyWeaknesses | 
					
						
							|  |  |  |     strict_weakness: StrictWeaknesses | 
					
						
							|  |  |  |     random_weakness: RandomWeaknesses | 
					
						
							|  |  |  |     wily_5_requirement: Wily5Requirement | 
					
						
							|  |  |  |     plando_weakness: WeaknessPlando | 
					
						
							|  |  |  |     palette_shuffle: PaletteShuffle | 
					
						
							|  |  |  |     quickswap: Quickswap | 
					
						
							|  |  |  |     reduce_flashing: ReduceFlashing | 
					
						
							|  |  |  |     random_music: RandomMusic |