* 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>
		
			
				
	
	
		
			230 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
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)): {
 | 
						|
            And(str, Use(str.title), lambda s: s in weapons_to_id): And(int, lambda i: i in range(-1, 14))
 | 
						|
        }
 | 
						|
    })
 | 
						|
    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
 |