mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-05-20 01:31:45 -07:00
Super Mario 64: Basic testing (#4335)
--------- Co-authored-by: Yussur Mustafa Oraji <N00byKing@hotmail.de> Co-authored-by: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com>
This commit is contained in:
@@ -79,6 +79,14 @@ sm64_secrets_to_level = {secret: level for (level,secret) in sm64_level_to_secre
|
||||
sm64_entrances_to_level = {**sm64_paintings_to_level, **sm64_secrets_to_level }
|
||||
sm64_level_to_entrances = {**sm64_level_to_paintings, **sm64_level_to_secrets }
|
||||
|
||||
# Levels with at least one star without a movement rule
|
||||
# Currently excluding WF, HMC, WDW, TTM, THI, TTC, and RR
|
||||
valid_move_randomizer_start_courses = [
|
||||
"Bob-omb Battlefield", "Jolly Roger Bay", "Cool, Cool Mountain",
|
||||
"Big Boo's Haunt", "Lethal Lava Land", "Shifting Sand Land",
|
||||
"Dire, Dire Docks", "Snowman's Land"
|
||||
]
|
||||
|
||||
def create_regions(multiworld: MultiWorld, options: SM64Options, player: int):
|
||||
regSS = Region("Menu", player, multiworld, "Castle Area")
|
||||
create_default_locs(regSS, locSS_table)
|
||||
|
||||
+26
-32
@@ -5,7 +5,8 @@ from ..generic.Rules import add_rule, set_rule
|
||||
from .Locations import location_table
|
||||
from .Options import SM64Options
|
||||
from .Regions import connect_regions, SM64Levels, sm64_level_to_paintings, sm64_paintings_to_level,\
|
||||
sm64_level_to_secrets, sm64_secrets_to_level, sm64_entrances_to_level, sm64_level_to_entrances
|
||||
sm64_level_to_secrets, sm64_secrets_to_level, sm64_entrances_to_level, sm64_level_to_entrances,\
|
||||
valid_move_randomizer_start_courses
|
||||
from .Items import action_item_data_table
|
||||
|
||||
def shuffle_dict_keys(multiworld: MultiWorld, dictionary: dict) -> dict:
|
||||
@@ -28,40 +29,33 @@ def fix_reg(entrance_map: Dict[SM64Levels, str], entrance: SM64Levels, invalid_r
|
||||
def set_rules(multiworld: MultiWorld, options: SM64Options, player: int, area_connections: dict, star_costs: dict, move_rando_bitvec: int):
|
||||
randomized_level_to_paintings = sm64_level_to_paintings.copy()
|
||||
randomized_level_to_secrets = sm64_level_to_secrets.copy()
|
||||
valid_move_randomizer_start_courses = [
|
||||
"Bob-omb Battlefield", "Jolly Roger Bay", "Cool, Cool Mountain",
|
||||
"Big Boo's Haunt", "Lethal Lava Land", "Shifting Sand Land",
|
||||
"Dire, Dire Docks", "Snowman's Land"
|
||||
] # Excluding WF, HMC, WDW, TTM, THI, TTC, and RR
|
||||
if options.area_rando >= 1: # Some randomization is happening, randomize Courses
|
||||
randomized_level_to_paintings = shuffle_dict_keys(multiworld,sm64_level_to_paintings)
|
||||
# If not shuffling later, ensure a valid start course on move randomizer
|
||||
if options.area_rando < 3 and move_rando_bitvec > 0:
|
||||
swapdict = randomized_level_to_paintings.copy()
|
||||
invalid_start_courses = {course for course in randomized_level_to_paintings.values() if course not in valid_move_randomizer_start_courses}
|
||||
fix_reg(randomized_level_to_paintings, SM64Levels.BOB_OMB_BATTLEFIELD, invalid_start_courses, swapdict, multiworld)
|
||||
fix_reg(randomized_level_to_paintings, SM64Levels.WHOMPS_FORTRESS, invalid_start_courses, swapdict, multiworld)
|
||||
|
||||
if options.area_rando == 2: # Randomize Secrets as well
|
||||
if options.area_rando > options.area_rando.option_Off: # Some randomization is happening, randomize Courses
|
||||
randomized_level_to_paintings = shuffle_dict_keys(multiworld, sm64_level_to_paintings)
|
||||
|
||||
if options.area_rando == options.area_rando.option_Courses_and_Secrets_Separate: # Randomize Secrets as well
|
||||
randomized_level_to_secrets = shuffle_dict_keys(multiworld, sm64_level_to_secrets)
|
||||
randomized_entrances = {**randomized_level_to_paintings, **randomized_level_to_secrets}
|
||||
if options.area_rando == 3: # Randomize Courses and Secrets in one pool
|
||||
|
||||
randomized_entrances = {**randomized_level_to_paintings, **randomized_level_to_secrets} # Concatenate courses and secrets for rest
|
||||
|
||||
if options.area_rando == options.area_rando.option_Courses_and_Secrets: # Randomize Courses and Secrets in one pool
|
||||
randomized_entrances = shuffle_dict_keys(multiworld, randomized_entrances)
|
||||
# Guarantee first entrance is a course
|
||||
swapdict = randomized_entrances.copy()
|
||||
if move_rando_bitvec == 0:
|
||||
fix_reg(randomized_entrances, SM64Levels.BOB_OMB_BATTLEFIELD, sm64_secrets_to_level.keys(), swapdict, multiworld)
|
||||
else:
|
||||
invalid_start_courses = {course for course in randomized_entrances.values() if course not in valid_move_randomizer_start_courses}
|
||||
fix_reg(randomized_entrances, SM64Levels.BOB_OMB_BATTLEFIELD, invalid_start_courses, swapdict, multiworld)
|
||||
fix_reg(randomized_entrances, SM64Levels.WHOMPS_FORTRESS, invalid_start_courses, swapdict, multiworld)
|
||||
# Guarantee BITFS is not mapped to DDD
|
||||
fix_reg(randomized_entrances, SM64Levels.BOWSER_IN_THE_FIRE_SEA, {"Dire, Dire Docks"}, swapdict, multiworld)
|
||||
# Guarantee COTMC is not mapped to HMC, cuz thats impossible. If BitFS -> HMC, also no COTMC -> DDD.
|
||||
if randomized_entrances[SM64Levels.BOWSER_IN_THE_FIRE_SEA] == "Hazy Maze Cave":
|
||||
fix_reg(randomized_entrances, SM64Levels.CAVERN_OF_THE_METAL_CAP, {"Hazy Maze Cave", "Dire, Dire Docks"}, swapdict, multiworld)
|
||||
else:
|
||||
fix_reg(randomized_entrances, SM64Levels.CAVERN_OF_THE_METAL_CAP, {"Hazy Maze Cave"}, swapdict, multiworld)
|
||||
|
||||
# Now, fix assignment if necessary
|
||||
swapdict = randomized_entrances.copy()
|
||||
if move_rando_bitvec == 0:
|
||||
fix_reg(randomized_entrances, SM64Levels.BOB_OMB_BATTLEFIELD, sm64_secrets_to_level.keys(), swapdict, multiworld)
|
||||
else:
|
||||
invalid_start_courses = {course for course in randomized_entrances.values() if course not in valid_move_randomizer_start_courses}
|
||||
fix_reg(randomized_entrances, SM64Levels.BOB_OMB_BATTLEFIELD, invalid_start_courses, swapdict, multiworld)
|
||||
fix_reg(randomized_entrances, SM64Levels.WHOMPS_FORTRESS, invalid_start_courses, swapdict, multiworld)
|
||||
# Guarantee BITFS is not mapped to DDD
|
||||
fix_reg(randomized_entrances, SM64Levels.BOWSER_IN_THE_FIRE_SEA, {"Dire, Dire Docks"}, swapdict, multiworld)
|
||||
# Guarantee COTMC is not mapped to HMC, cuz thats impossible. If BitFS -> HMC, also no COTMC -> DDD.
|
||||
if randomized_entrances[SM64Levels.BOWSER_IN_THE_FIRE_SEA] == "Hazy Maze Cave":
|
||||
fix_reg(randomized_entrances, SM64Levels.CAVERN_OF_THE_METAL_CAP, {"Hazy Maze Cave", "Dire, Dire Docks"}, swapdict, multiworld)
|
||||
else:
|
||||
fix_reg(randomized_entrances, SM64Levels.CAVERN_OF_THE_METAL_CAP, {"Hazy Maze Cave"}, swapdict, multiworld)
|
||||
|
||||
# Destination Format: LVL | AREA with LVL = LEVEL_x, AREA = Area as used in sm64 code
|
||||
# Cast to int to not rely on availability of SM64Levels enum. Will cause crash in MultiServer otherwise
|
||||
|
||||
@@ -139,7 +139,7 @@ class SM64World(World):
|
||||
if self.move_rando_bitvec & (1 << itemdata.code - double_jump_bitvec_offset)]
|
||||
|
||||
def generate_basic(self):
|
||||
if not (self.options.buddy_checks):
|
||||
if not self.options.buddy_checks:
|
||||
self.multiworld.get_location("BoB: Bob-omb Buddy", self.player).place_locked_item(self.create_item("Cannon Unlock BoB"))
|
||||
self.multiworld.get_location("WF: Bob-omb Buddy", self.player).place_locked_item(self.create_item("Cannon Unlock WF"))
|
||||
self.multiworld.get_location("JRB: Bob-omb Buddy", self.player).place_locked_item(self.create_item("Cannon Unlock JRB"))
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from test.bases import WorldTestBase
|
||||
|
||||
from .. import SM64World
|
||||
|
||||
|
||||
class SM64TestBase(WorldTestBase):
|
||||
game = "Super Mario 64"
|
||||
world: SM64World
|
||||
@@ -0,0 +1,81 @@
|
||||
from .bases import SM64TestBase
|
||||
from .. import Options
|
||||
from ..Regions import sm64_entrances_to_level, sm64_level_to_entrances
|
||||
|
||||
# Access to Locations/Areas/Entrances by Power Star count in star_cost
|
||||
class StarCostAccessTestBase(SM64TestBase):
|
||||
run_default_tests = False
|
||||
options = {
|
||||
"progressive_keys": Options.ProgressiveKeys.option_false,
|
||||
"enable_locked_paintings": Options.EnableLockedPaintings.option_false,
|
||||
# Test for access would mean access to entrance/painting,
|
||||
# not level itself for the sake of entrance rando.
|
||||
"area_rando": Options.AreaRandomizer.option_Courses_and_Secrets,
|
||||
}
|
||||
|
||||
def test_BoB_entrance_access(self):
|
||||
# Always accessible, no stars needed.
|
||||
bob_level_id = sm64_entrances_to_level["Bob-omb Battlefield"]
|
||||
bob_entrance_id = self.world.area_connections[bob_level_id]
|
||||
bob_entrance = sm64_level_to_entrances[bob_entrance_id]
|
||||
self.assertTrue(self.can_reach_region(bob_entrance))
|
||||
|
||||
def test_MIPS1_access(self):
|
||||
# Requires Basement Key and Power Stars calculated in star_costs["MIPS1Cost"]
|
||||
self.assertFalse(self.can_reach_location("MIPS 1"))
|
||||
self.collect([self.get_item_by_name("Basement Key")])
|
||||
self.assertFalse(self.can_reach_location("MIPS 1"))
|
||||
mips1_cost = self.world.star_costs["MIPS1Cost"]
|
||||
self.collect([self.get_item_by_name("Power Star")] * mips1_cost)
|
||||
self.assertTrue(self.can_reach_location("MIPS 1"))
|
||||
|
||||
def test_MIPS2_access(self):
|
||||
# Requires Basement Key and Power Stars calculated in star_costs["MIPS2Cost"]
|
||||
self.assertFalse(self.can_reach_location("MIPS 2"))
|
||||
self.collect([self.get_item_by_name("Basement Key")])
|
||||
self.assertFalse(self.can_reach_location("MIPS 2"))
|
||||
mips2_cost = self.world.star_costs["MIPS2Cost"]
|
||||
self.collect([self.get_item_by_name("Power Star")] * mips2_cost)
|
||||
self.assertTrue(self.can_reach_location("MIPS 2"))
|
||||
|
||||
def test_BitDW_entrance_access(self):
|
||||
# Requires Power Stars calculated in star_costs["FirstBowserDoorCost"]
|
||||
bitdw_level_id = sm64_entrances_to_level["Bowser in the Dark World"]
|
||||
bitdw_entrance_id = self.world.area_connections[bitdw_level_id]
|
||||
bitdw_entrance = sm64_level_to_entrances[bitdw_entrance_id]
|
||||
self.assertFalse(self.can_reach_region(bitdw_entrance))
|
||||
bitdw_cost = self.world.star_costs["FirstBowserDoorCost"]
|
||||
self.collect([self.get_item_by_name("Power Star")] * bitdw_cost)
|
||||
self.assertTrue(self.can_reach_region(bitdw_entrance))
|
||||
|
||||
# Since BitFS is locked behind "DDD: Board Bowser's Sub", we just need to test DDD.
|
||||
def test_DDD_entrance_access(self):
|
||||
# Requires Basement Key and Power Stars calculated in star_costs["BasementDoorCost"]
|
||||
ddd_level_id = sm64_entrances_to_level["Dire, Dire Docks"]
|
||||
ddd_entrance_id = self.world.area_connections[ddd_level_id]
|
||||
ddd_entrance = sm64_level_to_entrances[ddd_entrance_id]
|
||||
self.assertFalse(self.can_reach_region(ddd_entrance))
|
||||
self.collect([self.get_item_by_name("Basement Key")])
|
||||
self.assertFalse(self.can_reach_region(ddd_entrance))
|
||||
bitfs_cost = self.world.star_costs["BasementDoorCost"]
|
||||
self.collect([self.get_item_by_name("Power Star")] * bitfs_cost)
|
||||
self.assertTrue(self.can_reach_region(ddd_entrance))
|
||||
|
||||
def test_Floor3_access(self):
|
||||
# Requires Second Floor Key and Power Stars calculated in star_costs["SecondFloorDoorCost"]
|
||||
self.assertFalse(self.can_reach_region("Third Floor"))
|
||||
self.collect([self.get_item_by_name("Second Floor Key")])
|
||||
self.assertFalse(self.can_reach_region("Third Floor"))
|
||||
floor3_cost = self.world.star_costs["StarsToFinish"]
|
||||
self.collect([self.get_item_by_name("Power Star")] * floor3_cost)
|
||||
self.assertTrue(self.can_reach_region("Third Floor"))
|
||||
|
||||
def test_BitS_entrance_access(self):
|
||||
# Requires Second Floor Key and Power Stars calculated in star_costs["StarsToFinish"]
|
||||
self.assertFalse(self.can_reach_region("Bowser in the Sky"))
|
||||
self.collect([self.get_item_by_name("Second Floor Key")])
|
||||
self.assertFalse(self.can_reach_region("Bowser in the Sky"))
|
||||
bits_cost = self.world.star_costs["StarsToFinish"]
|
||||
self.collect([self.get_item_by_name("Power Star")] * bits_cost)
|
||||
self.assertTrue(self.can_reach_region("Third Floor"))
|
||||
self.assertTrue(self.can_reach_region("Bowser in the Sky"))
|
||||
@@ -0,0 +1,278 @@
|
||||
from .bases import SM64TestBase
|
||||
from .. import Options
|
||||
from ..Locations import loc100Coin_table, location_table
|
||||
from ..Regions import sm64_entrances_to_level, sm64_level_to_paintings, sm64_level_to_secrets, \
|
||||
valid_move_randomizer_start_courses
|
||||
|
||||
valid_move_randomizer_start_entrances = {
|
||||
level: entrance
|
||||
for (level, entrance) in sm64_entrances_to_level.items()
|
||||
if level in valid_move_randomizer_start_courses
|
||||
}
|
||||
|
||||
|
||||
# Coin Star Logic
|
||||
class EnableCoinStarsTestBase(SM64TestBase):
|
||||
options = {
|
||||
"enable_coin_stars": Options.EnableCoinStars.option_on
|
||||
}
|
||||
|
||||
# Ensure Coin Star locations are created
|
||||
def test_coin_star_locations(self):
|
||||
possible_locations = self.world.location_names
|
||||
for loc in loc100Coin_table:
|
||||
# Use subtest to force all locations to be tested
|
||||
with self.subTest("Location created", location=loc):
|
||||
self.assertIn(loc, possible_locations)
|
||||
|
||||
|
||||
class DisableCoinStarsTestBase(SM64TestBase):
|
||||
options = {
|
||||
"enable_coin_stars": Options.EnableCoinStars.option_off
|
||||
}
|
||||
|
||||
# Ensure Coin Star locations are not created
|
||||
def test_coin_star_locations(self):
|
||||
possible_locations = self.world.get_locations()
|
||||
for loc in loc100Coin_table:
|
||||
# Use subtest to force all locations to be tested
|
||||
with self.subTest("Location not created", location=loc):
|
||||
self.assertNotIn(loc, possible_locations)
|
||||
|
||||
|
||||
class VanillaCoinStarsTestBase(SM64TestBase):
|
||||
options = {
|
||||
"enable_coin_stars": Options.EnableCoinStars.option_vanilla
|
||||
}
|
||||
|
||||
# Ensure Coin Star locations are created
|
||||
def test_coin_star_locations(self):
|
||||
possible_locations = self.world.location_names
|
||||
for loc in loc100Coin_table:
|
||||
# Use subtest to force all locations to be tested
|
||||
with self.subTest("Location created", location=loc):
|
||||
self.assertIn(loc, possible_locations)
|
||||
|
||||
# Vanilla Coin Stars should give the player their own Power Stars
|
||||
def test_items_in_coin_star_locations(self):
|
||||
for loc in loc100Coin_table:
|
||||
# Use subtest to force all locations to be tested
|
||||
with self.subTest("Location created", location=loc):
|
||||
item_in_loc = self.world.get_location(loc).item
|
||||
self.assertEqual(item_in_loc.name, "Power Star")
|
||||
# By default, these test bases are single player multiworld.
|
||||
# In any other case, we should test that they belong to their respective worlds.
|
||||
|
||||
|
||||
# Exclamation Boxes
|
||||
class ExclamationBoxesOnTestBase(SM64TestBase):
|
||||
options = {
|
||||
"exclamation_boxes": Options.ExclamationBoxes.option_true,
|
||||
}
|
||||
|
||||
|
||||
class ExclamationBoxesOffTestBase(SM64TestBase):
|
||||
options = {
|
||||
"exclamation_boxes": Options.ExclamationBoxes.option_false,
|
||||
}
|
||||
|
||||
# Should populate the boxes with the players own 1Up Mushrooms
|
||||
def test_items_in_exclamation_box_locations(self):
|
||||
# Get 1Up Block locations
|
||||
loc1ups_table = {name for name in location_table.keys() if "1Up Block" in name}
|
||||
for loc in loc1ups_table:
|
||||
# Use subtest to force all locations to be tested
|
||||
with self.subTest("Location has own 1Up Mushroom.", location=loc):
|
||||
item_in_loc = self.world.get_location(loc).item
|
||||
self.assertEqual(item_in_loc.name, "1Up Mushroom")
|
||||
# By default, these test bases are single player multiworld.
|
||||
# In any other case, we should test that they belong to their respective worlds.
|
||||
|
||||
|
||||
# Entrance Randomizer
|
||||
class EntranceRandoOffTestBase(SM64TestBase):
|
||||
options = {
|
||||
"area_rando": Options.AreaRandomizer.option_Off
|
||||
}
|
||||
|
||||
# Ensure entrance rando disabled
|
||||
def test_BoB_entrance(self):
|
||||
bob_level_id = sm64_entrances_to_level["Bob-omb Battlefield"]
|
||||
self.assertEqual(self.world.area_connections[bob_level_id], bob_level_id)
|
||||
|
||||
def test_BitFS_entrance(self):
|
||||
bitfs_level_id = sm64_entrances_to_level["Bowser in the Fire Sea"]
|
||||
self.assertEqual(self.world.area_connections[bitfs_level_id], bitfs_level_id)
|
||||
|
||||
|
||||
class EntranceRandoCourseTestBase(SM64TestBase):
|
||||
options = {
|
||||
"area_rando": Options.AreaRandomizer.option_Courses_Only
|
||||
}
|
||||
|
||||
def test_BoB_entrance(self):
|
||||
bob_level_id = sm64_entrances_to_level["Bob-omb Battlefield"]
|
||||
# BoB goes to a painting, not a secret
|
||||
self.assertNotIn(self.world.area_connections[bob_level_id], sm64_level_to_secrets.keys())
|
||||
self.assertIn(self.world.area_connections[bob_level_id], sm64_level_to_paintings.keys())
|
||||
|
||||
def test_BitFS_entrance(self):
|
||||
bitfs_level_id = sm64_entrances_to_level["Bowser in the Fire Sea"]
|
||||
# BitFS is a secret (aka not a course), unaffected by Course Only entrance rando.
|
||||
self.assertEqual(self.world.area_connections[bitfs_level_id], bitfs_level_id)
|
||||
|
||||
|
||||
class EntranceRandoSeparateTestBase(SM64TestBase):
|
||||
options = {
|
||||
"area_rando": Options.AreaRandomizer.option_Courses_and_Secrets_Separate
|
||||
}
|
||||
|
||||
def test_BoB_entrance(self):
|
||||
bob_level_id = sm64_entrances_to_level["Bob-omb Battlefield"]
|
||||
# BoB goes to a painting, not a secret
|
||||
self.assertNotIn(self.world.area_connections[bob_level_id], sm64_level_to_secrets.keys())
|
||||
self.assertIn(self.world.area_connections[bob_level_id], sm64_level_to_paintings.keys())
|
||||
|
||||
def test_BitFS_entrance(self):
|
||||
bitfs_level_id = sm64_entrances_to_level["Bowser in the Fire Sea"]
|
||||
# BitFS goes to a secret, not a painting
|
||||
self.assertIn(self.world.area_connections[bitfs_level_id], sm64_level_to_secrets.keys())
|
||||
self.assertNotIn(self.world.area_connections[bitfs_level_id], sm64_level_to_paintings.keys())
|
||||
# BitFS does not go to DDD
|
||||
self.assertIsNot(self.world.area_connections[bitfs_level_id], sm64_entrances_to_level["Dire, Dire Docks"])
|
||||
|
||||
|
||||
class EntranceRandoAllTestBase(SM64TestBase):
|
||||
options = {
|
||||
"area_rando": Options.AreaRandomizer.option_Courses_and_Secrets
|
||||
}
|
||||
|
||||
def test_BitFS_entrance(self):
|
||||
bitfs_level_id = sm64_entrances_to_level["Bowser in the Fire Sea"]
|
||||
# BitFS does not go to DDD
|
||||
self.assertIsNot(self.world.area_connections[bitfs_level_id], sm64_entrances_to_level["Dire, Dire Docks"])
|
||||
|
||||
|
||||
# Completion Type
|
||||
class CompletionLastBowserTestBase(SM64TestBase):
|
||||
options = {
|
||||
"completion_type": Options.CompletionType.option_Last_Bowser_Stage
|
||||
}
|
||||
|
||||
|
||||
class CompletionAllBowserTestBase(SM64TestBase):
|
||||
options = {
|
||||
"completion_type": Options.CompletionType.option_All_Bowser_Stages
|
||||
}
|
||||
|
||||
|
||||
# Option Combos
|
||||
|
||||
|
||||
# Smallest Power Star count possible
|
||||
class MinimumStarsPossibleTestBase(SM64TestBase):
|
||||
options = {
|
||||
"amount_of_stars": Options.AmountOfStars.range_start,
|
||||
"enable_move_rando": Options.EnableMoveRandomizer.option_true,
|
||||
"exclamation_boxes": Options.ExclamationBoxes.option_false,
|
||||
"enable_coin_stars": Options.EnableCoinStars.option_off
|
||||
}
|
||||
|
||||
# There will be less Power Stars than filler with this low of a star count
|
||||
def test_stars_vs_filler(self):
|
||||
filler_count = len(self.get_items_by_name("1Up Mushroom"))
|
||||
star_count = len(self.get_items_by_name("Power Star"))
|
||||
self.assertGreater(filler_count, star_count)
|
||||
|
||||
|
||||
# Entrance + Move Randos
|
||||
class CourseEntrancesMoveTestBase(SM64TestBase):
|
||||
options = {
|
||||
"enable_move_rando": Options.EnableMoveRandomizer.option_true,
|
||||
"area_rando": Options.AreaRandomizer.option_Courses_Only
|
||||
}
|
||||
|
||||
def test_BoB_entrance(self):
|
||||
bob_level_id = sm64_entrances_to_level["Bob-omb Battlefield"]
|
||||
# BoB goes to a course, not a secret.
|
||||
self.assertNotIn(self.world.area_connections[bob_level_id], sm64_level_to_secrets.keys())
|
||||
self.assertIn(self.world.area_connections[bob_level_id], sm64_level_to_paintings.keys())
|
||||
# BoB goes to level with at least one star without a movement rule.
|
||||
self.assertIn(self.world.area_connections[bob_level_id], valid_move_randomizer_start_entrances.values())
|
||||
|
||||
def test_BitFS_entrance(self):
|
||||
bitfs_level_id = sm64_entrances_to_level["Bowser in the Fire Sea"]
|
||||
# BitFS is a secret (aka not a course), unaffected by Course Only entrance rando.
|
||||
self.assertEqual(self.world.area_connections[bitfs_level_id], bitfs_level_id)
|
||||
|
||||
def test_WF_entrance(self):
|
||||
wf_level_id = sm64_entrances_to_level["Whomp's Fortress"]
|
||||
# WF goes to level with at least one star without a movement rule.
|
||||
self.assertIn(self.world.area_connections[wf_level_id], valid_move_randomizer_start_entrances.values())
|
||||
|
||||
|
||||
class SeparateEntrancesMoveTestBase(SM64TestBase):
|
||||
options = {
|
||||
"enable_move_rando": Options.EnableMoveRandomizer.option_true,
|
||||
"area_rando": Options.AreaRandomizer.option_Courses_and_Secrets_Separate
|
||||
}
|
||||
|
||||
def test_BoB_entrance(self):
|
||||
bob_level_id = sm64_entrances_to_level["Bob-omb Battlefield"]
|
||||
# BoB goes to a course, not a secret.
|
||||
self.assertNotIn(self.world.area_connections[bob_level_id], sm64_level_to_secrets.keys())
|
||||
self.assertIn(self.world.area_connections[bob_level_id], sm64_level_to_paintings.keys())
|
||||
# BoB goes to level with at least one star without a movement rule.
|
||||
self.assertIn(self.world.area_connections[bob_level_id], valid_move_randomizer_start_entrances.values())
|
||||
|
||||
def test_BitFS_entrance(self):
|
||||
bitfs_level_id = sm64_entrances_to_level["Bowser in the Fire Sea"]
|
||||
# BitFS does not go to DDD.
|
||||
self.assertIsNot(self.world.area_connections[bitfs_level_id], sm64_entrances_to_level["Dire, Dire Docks"])
|
||||
|
||||
def test_WF_entrance(self):
|
||||
wf_level_id = sm64_entrances_to_level["Whomp's Fortress"]
|
||||
# WF goes to level with at least one star without a movement rule.
|
||||
self.assertIn(self.world.area_connections[wf_level_id], valid_move_randomizer_start_entrances.values())
|
||||
|
||||
|
||||
class AllEntrancesMoveTestBase(SM64TestBase):
|
||||
options = {
|
||||
"enable_move_rando": Options.EnableMoveRandomizer.option_true,
|
||||
"area_rando": Options.AreaRandomizer.option_Courses_and_Secrets
|
||||
}
|
||||
|
||||
def test_BoB_entrance(self):
|
||||
bob_level_id = sm64_entrances_to_level["Bob-omb Battlefield"]
|
||||
# BoB goes to level with at least one star without a movement rule.
|
||||
self.assertIn(self.world.area_connections[bob_level_id], valid_move_randomizer_start_entrances.values())
|
||||
|
||||
def test_BitFS_entrance(self):
|
||||
bitfs_level_id = sm64_entrances_to_level["Bowser in the Fire Sea"]
|
||||
# BitFS does not go to DDD.
|
||||
self.assertIsNot(self.world.area_connections[bitfs_level_id], sm64_entrances_to_level["Dire, Dire Docks"])
|
||||
|
||||
def test_WF_entrance(self):
|
||||
wf_level_id = sm64_entrances_to_level["Whomp's Fortress"]
|
||||
# WF goes to level with at least one star without a movement rule.
|
||||
self.assertIn(self.world.area_connections[wf_level_id], valid_move_randomizer_start_entrances.values())
|
||||
|
||||
def test_CotMC_entrance(self):
|
||||
cotmc_level_id = sm64_entrances_to_level["Cavern of the Metal Cap"]
|
||||
# CotMC does not go to HMC.
|
||||
self.assertIsNot(self.world.area_connections[cotmc_level_id], sm64_entrances_to_level["Hazy Maze Cave"])
|
||||
# If BitFS -> HMC, CotMC does not go to DDD.
|
||||
bitfs_level_id = sm64_entrances_to_level["Bowser in the Fire Sea"]
|
||||
if self.world.area_connections[bitfs_level_id] == sm64_entrances_to_level["Hazy Maze Cave"]:
|
||||
self.assertIsNot(self.world.area_connections[cotmc_level_id], sm64_entrances_to_level["Dire, Dire Docks"])
|
||||
|
||||
|
||||
# No Strict Requirements
|
||||
class NoStrictRequirementsTestBase(SM64TestBase):
|
||||
options = {
|
||||
"enable_move_rando": Options.EnableMoveRandomizer.option_true,
|
||||
"buddy_checks": Options.BuddyChecks.option_true,
|
||||
"strict_move_requirements": Options.StrictMoveRequirements.option_false,
|
||||
"strict_cap_requirements": Options.StrictCapRequirements.option_false,
|
||||
"strict_cannon_requirements": Options.StrictCannonRequirements.option_false,
|
||||
}
|
||||
Reference in New Issue
Block a user