Files
Grinch-AP/worlds/mm2/options.py
Silvris 0e6e359747 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-20 04:59:29 +02:00

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