MM2: Fix invalid weakness failsafe and refactor weakness tests (#4899)

This commit is contained in:
Silvris
2025-04-20 08:08:30 -05:00
committed by GitHub
parent 04aa471526
commit b76f2163a4
2 changed files with 35 additions and 19 deletions

View File

@@ -215,7 +215,7 @@ def set_rules(world: "MM2World") -> None:
continue continue
highest, wp = max(zip(weapon_weight.values(), weapon_weight.keys())) highest, wp = max(zip(weapon_weight.values(), weapon_weight.keys()))
uses = weapon_energy[wp] // weapon_costs[wp] uses = weapon_energy[wp] // weapon_costs[wp]
if int(uses * boss_damage[wp]) > boss_health[boss]: if int(uses * boss_damage[wp]) >= boss_health[boss]:
used = ceil(boss_health[boss] / boss_damage[wp]) used = ceil(boss_health[boss] / boss_damage[wp])
weapon_energy[wp] -= weapon_costs[wp] * used weapon_energy[wp] -= weapon_costs[wp] * used
boss_health[boss] = 0 boss_health[boss] = 0
@@ -226,7 +226,7 @@ def set_rules(world: "MM2World") -> None:
# it should be impossible to be out of energy, simply because even if every boss took 1 from # it should be impossible to be out of energy, simply because even if every boss took 1 from
# Quick Boomerang and no other, it would only be 28 off from defeating all 9, # Quick Boomerang and no other, it would only be 28 off from defeating all 9,
# which Metal Blade should be able to cover # which Metal Blade should be able to cover
wp, max_uses = max((weapon, weapon_energy[weapon] // weapon_costs[weapon]) max_uses, wp = max((weapon_energy[weapon] // weapon_costs[weapon], weapon)
for weapon in weapon_weight for weapon in weapon_weight
if weapon != 0 and (weapon != 8 or boss != 12)) if weapon != 0 and (weapon != 8 or boss != 12))
# Wily Machine cannot under any circumstances take damage from Time Stopper, prevent this # Wily Machine cannot under any circumstances take damage from Time Stopper, prevent this

View File

@@ -2,9 +2,9 @@ from math import ceil
from . import MM2TestBase from . import MM2TestBase
from ..options import bosses from ..options import bosses
from ..rules import minimum_weakness_requirement
# Need to figure out how this test should work
def validate_wily_5(base: MM2TestBase) -> None: def validate_wily_5(base: MM2TestBase) -> None:
world = base.multiworld.worlds[base.player] world = base.multiworld.worlds[base.player]
weapon_damage = world.weapon_damage weapon_damage = world.weapon_damage
@@ -67,38 +67,54 @@ def validate_wily_5(base: MM2TestBase) -> None:
weapon_weight.pop(wp) weapon_weight.pop(wp)
class StrictWeaknessTests(MM2TestBase): class WeaknessTests(MM2TestBase):
options = { options = {
"strict_weakness": True,
"yoku_jumps": True, "yoku_jumps": True,
"enable_lasers": True "enable_lasers": True,
} }
def test_that_every_boss_has_a_weakness(self) -> None: def test_that_every_boss_has_a_weakness(self) -> None:
world = self.multiworld.worlds[self.player] world = self.multiworld.worlds[self.player]
weapon_damage = world.weapon_damage weapon_damage = world.weapon_damage
for boss in range(14): for boss in range(14):
if not any(weapon_damage[weapon][boss] for weapon in range(9)): if not any(weapon_damage[weapon][boss] >= minimum_weakness_requirement[weapon] for weapon in range(9)):
self.fail(f"Boss {boss} generated without weakness! Seed: {self.multiworld.seed}") self.fail(f"Boss {boss} generated without weakness! Seed: {self.multiworld.seed}")
def test_wily_5(self) -> None: def test_wily_5(self) -> None:
validate_wily_5(self) validate_wily_5(self)
class RandomStrictWeaknessTests(MM2TestBase): class StrictWeaknessTests(WeaknessTests):
options = {
"strict_weakness": True,
**WeaknessTests.options
}
class RandomWeaknessTests(WeaknessTests):
options = {
"random_weakness": "randomized",
**WeaknessTests.options
}
class ShuffledWeaknessTests(WeaknessTests):
options = {
"random_weakness": "shuffled",
**WeaknessTests.options
}
class RandomStrictWeaknessTests(WeaknessTests):
options = { options = {
"strict_weakness": True, "strict_weakness": True,
"random_weakness": "randomized", "random_weakness": "randomized",
"yoku_jumps": True, **WeaknessTests.options
"enable_lasers": True
} }
def test_that_every_boss_has_a_weakness(self) -> None:
world = self.multiworld.worlds[self.player]
weapon_damage = world.weapon_damage
for boss in range(14):
if not any(weapon_damage[weapon][boss] for weapon in range(9)):
self.fail(f"Boss {boss} generated without weakness! Seed: {self.multiworld.seed}")
def test_wily_5(self) -> None: class ShuffledStrictWeaknessTests(WeaknessTests):
validate_wily_5(self) options = {
"strict_weakness": True,
"random_weakness": "shuffled",
**WeaknessTests.options
}