sm64ex: Various Features (#790)
* sm64ex: Course and Secret Randomizer * sm64ex: Allow higher star door costs, raise minimum amount of stars, deprecate ExtraStars * sm64ex: Support setting MIPS costs * sm64ex: Safeguard MIPS Costs
This commit is contained in:
parent
e6635cdd77
commit
c3ff201b90
|
@ -272,7 +272,7 @@ Super Mario 64:
|
|||
StrictCapRequirements: true
|
||||
StrictCannonRequirements: true
|
||||
StarsToFinish: 70
|
||||
ExtraStars: 30
|
||||
AmountOfStars: 70
|
||||
DeathLink: true
|
||||
BuddyChecks: true
|
||||
AreaRandomizer: true
|
||||
|
|
|
@ -182,26 +182,50 @@ loc100Coin_table = {
|
|||
"RR: 100 Coins": 3626104
|
||||
}
|
||||
|
||||
locPSS_table = {
|
||||
"The Princess's Secret Slide Block": 3626126,
|
||||
"The Princess's Secret Slide Fast": 3626127,
|
||||
}
|
||||
|
||||
locSA_table = {
|
||||
"The Secret Aquarium": 3626161
|
||||
}
|
||||
|
||||
locBitDW_table = {
|
||||
"Bowser in the Dark World Red Coins": 3626105,
|
||||
"Bowser in the Dark World Key": 3626178
|
||||
}
|
||||
|
||||
locTotWC_table = {
|
||||
"Tower of the Wing Cap Switch": 3626181,
|
||||
"Tower of the Wing Cap Red Coins": 3626140
|
||||
}
|
||||
|
||||
locCotMC_table = {
|
||||
"Cavern of the Metal Cap Switch": 3626182,
|
||||
"Cavern of the Metal Cap Red Coins": 3626133
|
||||
}
|
||||
|
||||
locVCutM_table = {
|
||||
"Vanish Cap Under the Moat Switch": 3626183,
|
||||
"Vanish Cap Under the Moat Red Coins": 3626147
|
||||
}
|
||||
|
||||
locBitFS_table = {
|
||||
"Bowser in the Fire Sea Red Coins": 3626112,
|
||||
"Bowser in the Fire Sea Key": 3626179
|
||||
}
|
||||
|
||||
#Secret Stars and Stages
|
||||
locWMotR_table = {
|
||||
"Wing Mario Over the Rainbow": 3626154
|
||||
}
|
||||
|
||||
locBitS_table = {
|
||||
"Bowser in the Sky Red Coins": 3626119
|
||||
}
|
||||
|
||||
#Secret Stars found inside the Castle
|
||||
locSS_table = {
|
||||
"Bowser in the Sky Red Coins": 3626119,
|
||||
"The Princess's Secret Slide Block": 3626126,
|
||||
"The Princess's Secret Slide Fast": 3626127,
|
||||
"Cavern of the Metal Cap Red Coins": 3626133,
|
||||
"Tower of the Wing Cap Red Coins": 3626140,
|
||||
"Vanish Cap Under the Moat Red Coins": 3626147,
|
||||
"Wing Mario Over the Rainbow": 3626154,
|
||||
"The Secret Aquarium": 3626161,
|
||||
"Toad (Basement)": 3626168,
|
||||
"Toad (Second Floor)": 3626169,
|
||||
"Toad (Third Floor)": 3626170,
|
||||
|
@ -209,15 +233,10 @@ locSS_table = {
|
|||
"MIPS 2": 3626172
|
||||
}
|
||||
|
||||
#Caps
|
||||
locCap_table = {
|
||||
"Tower of the Wing Cap Switch": 3626181,
|
||||
"Cavern of the Metal Cap Switch": 3626182,
|
||||
"Vanish Cap Under the Moat Switch": 3626183
|
||||
}
|
||||
|
||||
# Correspond to 3626000 + course index * 7 + star index, then secret stars, then keys, then 100 Coin Stars
|
||||
location_table = {**locBoB_table,**locWhomp_table,**locJRB_table,**locCCM_table,**locBBH_table, \
|
||||
**locHMC_table,**locLLL_table,**locSSL_table,**locDDD_table,**locSL_table, \
|
||||
**locWDW_table,**locTTM_table,**locTHI_table,**locTTC_table,**locRR_table, \
|
||||
**loc100Coin_table,**locBitDW_table,**locBitFS_table,**locSS_table,**locCap_table}
|
||||
**loc100Coin_table,**locPSS_table,**locSA_table,**locBitDW_table,**locTotWC_table, \
|
||||
**locCotMC_table, **locVCutM_table, **locBitFS_table, **locWMotR_table, **locBitS_table, \
|
||||
**locSS_table}
|
|
@ -1,5 +1,5 @@
|
|||
import typing
|
||||
from Options import Option, DefaultOnToggle, Range, Toggle, DeathLink
|
||||
from Options import Option, DefaultOnToggle, Range, Toggle, DeathLink, Choice
|
||||
|
||||
class EnableCoinStars(DefaultOnToggle):
|
||||
"""Disable to Ignore 100 Coin Stars. You can still collect them, but they don't do anything"""
|
||||
|
@ -16,19 +16,31 @@ class StrictCannonRequirements(DefaultOnToggle):
|
|||
class FirstBowserStarDoorCost(Range):
|
||||
"""How many stars are required at the Star Door to Bowser in the Dark World"""
|
||||
range_start = 0
|
||||
range_end = 20
|
||||
range_end = 50
|
||||
default = 8
|
||||
|
||||
class BasementStarDoorCost(Range):
|
||||
"""How many stars are required at the Star Door in the Basement"""
|
||||
range_start = 0
|
||||
range_end = 50
|
||||
range_end = 70
|
||||
default = 30
|
||||
|
||||
class SecondFloorStarDoorCost(Range):
|
||||
"""How many stars are required to access the third floor"""
|
||||
range_start = 0
|
||||
range_end = 50
|
||||
range_end = 90
|
||||
default = 50
|
||||
|
||||
class MIPS1Cost(Range):
|
||||
"""How many stars are required to spawn MIPS the first time"""
|
||||
range_start = 0
|
||||
range_end = 40
|
||||
default = 15
|
||||
|
||||
class MIPS2Cost(Range):
|
||||
"""How many stars are required to spawn MIPS the secound time. Must be bigger or equal MIPS1Cost"""
|
||||
range_start = 0
|
||||
range_end = 80
|
||||
default = 50
|
||||
|
||||
class StarsToFinish(Range):
|
||||
|
@ -38,15 +50,19 @@ class StarsToFinish(Range):
|
|||
range_end = 100
|
||||
default = 70
|
||||
|
||||
class ExtraStars(Range):
|
||||
"""How many stars exist beyond those set for StarsToFinish"""
|
||||
range_start = 0
|
||||
range_end = 50
|
||||
default = 50
|
||||
class AmountOfStars(Range):
|
||||
"""How many stars exist. Disabling 100 Coin Stars removes 15 from the Pool. At least max of any Cost set"""
|
||||
range_start = 35
|
||||
range_end = 120
|
||||
default = 120
|
||||
|
||||
class AreaRandomizer(Toggle):
|
||||
"""Randomize Entrances to Courses"""
|
||||
display_name = "Course Randomizer"
|
||||
class AreaRandomizer(Choice):
|
||||
"""Randomize Entrances"""
|
||||
display_name = "Entrance Randomizer"
|
||||
alias_false = 0
|
||||
option_Off = 0
|
||||
option_Courses_Only = 1
|
||||
option_Courses_and_Secrets = 2
|
||||
|
||||
class BuddyChecks(Toggle):
|
||||
"""Bob-omb Buddies are checks, Cannon Unlocks are items"""
|
||||
|
@ -60,13 +76,15 @@ sm64_options: typing.Dict[str,type(Option)] = {
|
|||
"AreaRandomizer": AreaRandomizer,
|
||||
"ProgressiveKeys": ProgressiveKeys,
|
||||
"EnableCoinStars": EnableCoinStars,
|
||||
"AmountOfStars": AmountOfStars,
|
||||
"StrictCapRequirements": StrictCapRequirements,
|
||||
"StrictCannonRequirements": StrictCannonRequirements,
|
||||
"FirstBowserStarDoorCost": FirstBowserStarDoorCost,
|
||||
"BasementStarDoorCost": BasementStarDoorCost,
|
||||
"SecondFloorStarDoorCost": SecondFloorStarDoorCost,
|
||||
"MIPS1Cost": MIPS1Cost,
|
||||
"MIPS2Cost": MIPS2Cost,
|
||||
"StarsToFinish": StarsToFinish,
|
||||
"ExtraStars": ExtraStars,
|
||||
"death_link": DeathLink,
|
||||
"BuddyChecks": BuddyChecks,
|
||||
}
|
|
@ -4,150 +4,168 @@ from .Locations import SM64Location, location_table, locBoB_table, locWhomp_tabl
|
|||
locBBH_table, \
|
||||
locHMC_table, locLLL_table, locSSL_table, locDDD_table, locSL_table, \
|
||||
locWDW_table, locTTM_table, locTHI_table, locTTC_table, locRR_table, \
|
||||
locBitDW_table, locBitFS_table, locSS_table, locCap_table
|
||||
locPSS_table, locSA_table, locBitDW_table, locTotWC_table, locCotMC_table, \
|
||||
locVCutM_table, locBitFS_table, locWMotR_table, locBitS_table, locSS_table
|
||||
|
||||
# List of all courses, including secrets, without BitS as that one is static
|
||||
sm64courses = ["Bob-omb Battlefield", "Whomp's Fortress", "Jolly Roger Bay", "Cool, Cool Mountain", "Big Boo's Haunt",
|
||||
"Hazy Maze Cave", "Lethal Lava Land", "Shifting Sand Land", "Dire, Dire Docks", "Snowman's Land",
|
||||
"Wet-Dry World",
|
||||
"Tall, Tall Mountain", "Tiny-Huge Island", "Tick Tock Clock", "Rainbow Ride"]
|
||||
"Wet-Dry World", "Tall, Tall Mountain", "Tiny-Huge Island", "Tick Tock Clock", "Rainbow Ride",
|
||||
"The Princess's Secret Slide", "The Secret Aquarium", "Bowser in the Dark World", "Tower of the Wing Cap",
|
||||
"Cavern of the Metal Cap", "Vanish Cap under the Moat", "Bowser in the Fire Sea", "Wing Mario over the Rainbow"]
|
||||
|
||||
# sm64paintings is list of strings for quick reference for Painting IDs (NOT warp node IDs!)
|
||||
sm64paintings = ["BOB", "WF", "JRB", "CCM", "BBH", "HMC", "LLL", "SSL", "DDD", "SL", "WDW", "TTM", "THI Tiny", "THI Huge", "TTC", "RR"]
|
||||
# sm64paintings is list of entrances, format LEVEL | AREA. String Reference below
|
||||
sm64paintings = [91,241,121,51,41,71,221,81,231,101,111,361,132,131,141,151]
|
||||
sm64paintings_s = ["BOB", "WF", "JRB", "CCM", "BBH", "HMC", "LLL", "SSL", "DDD", "SL", "WDW", "TTM", "THI Tiny", "THI Huge", "TTC", "RR"]
|
||||
# sm64secrets is list of secret areas
|
||||
sm64secrets = [271, 201, 171, 291, 281, 181, 191, 311]
|
||||
sm64secrets_s = ["PSS", "SA", "BitDW", "TOTWC", "COTMC", "VCUTM", "BitFS", "WMOTR"]
|
||||
|
||||
sm64entrances = sm64paintings + sm64secrets
|
||||
sm64entrances_s = sm64paintings_s + sm64secrets_s
|
||||
sm64_internalloc_to_string = dict(zip(sm64paintings+sm64secrets, sm64entrances_s))
|
||||
sm64_internalloc_to_regionid = dict(zip(sm64paintings+sm64secrets, list(range(13)) + [12,13,14] + list(range(15,15+len(sm64secrets)))))
|
||||
|
||||
def create_regions(world: MultiWorld, player: int):
|
||||
regSS = Region("Menu", RegionType.Generic, "Castle Area", player, world)
|
||||
locSS_names = [name for name, id in locSS_table.items()]
|
||||
locSS_names += [name for name, id in locCap_table.items()]
|
||||
regSS.locations += [SM64Location(player, loc_name, location_table[loc_name], regSS) for loc_name in locSS_names]
|
||||
create_default_locs(regSS, locSS_table, player)
|
||||
world.regions.append(regSS)
|
||||
|
||||
regBoB = Region("Bob-omb Battlefield", RegionType.Generic, "Bob-omb Battlefield", player, world)
|
||||
locBoB_names = [name for name, id in locBoB_table.items()]
|
||||
regBoB.locations += [SM64Location(player, loc_name, location_table[loc_name], regBoB) for loc_name in locBoB_names]
|
||||
regBoB = create_region("Bob-omb Battlefield", player, world)
|
||||
create_default_locs(regBoB, locBoB_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regBoB.locations.append(SM64Location(player, "BoB: 100 Coins", location_table["BoB: 100 Coins"], regBoB))
|
||||
world.regions.append(regBoB)
|
||||
|
||||
regWhomp = Region("Whomp's Fortress", RegionType.Generic, "Whomp's Fortress", player, world)
|
||||
locWhomp_names = [name for name, id in locWhomp_table.items()]
|
||||
regWhomp.locations += [SM64Location(player, loc_name, location_table[loc_name], regWhomp) for loc_name in
|
||||
locWhomp_names]
|
||||
regWhomp = create_region("Whomp's Fortress", player, world)
|
||||
create_default_locs(regWhomp, locWhomp_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regWhomp.locations.append(SM64Location(player, "WF: 100 Coins", location_table["WF: 100 Coins"], regWhomp))
|
||||
world.regions.append(regWhomp)
|
||||
|
||||
regJRB = Region("Jolly Roger Bay", RegionType.Generic, "Jolly Roger Bay", player, world)
|
||||
locJRB_names = [name for name, id in locJRB_table.items()]
|
||||
regJRB.locations += [SM64Location(player, loc_name, location_table[loc_name], regJRB) for loc_name in locJRB_names]
|
||||
regJRB = create_region("Jolly Roger Bay", player, world)
|
||||
create_default_locs(regJRB, locJRB_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regJRB.locations.append(SM64Location(player, "JRB: 100 Coins", location_table["JRB: 100 Coins"], regJRB))
|
||||
world.regions.append(regJRB)
|
||||
|
||||
regCCM = Region("Cool, Cool Mountain", RegionType.Generic, "Cool, Cool Mountain", player, world)
|
||||
locCCM_names = [name for name, id in locCCM_table.items()]
|
||||
regCCM.locations += [SM64Location(player, loc_name, location_table[loc_name], regCCM) for loc_name in locCCM_names]
|
||||
regCCM = create_region("Cool, Cool Mountain", player, world)
|
||||
create_default_locs(regCCM, locCCM_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regCCM.locations.append(SM64Location(player, "CCM: 100 Coins", location_table["CCM: 100 Coins"], regCCM))
|
||||
world.regions.append(regCCM)
|
||||
|
||||
regBBH = Region("Big Boo's Haunt", RegionType.Generic, "Big Boo's Haunt", player, world)
|
||||
locBBH_names = [name for name, id in locBBH_table.items()]
|
||||
regBBH.locations += [SM64Location(player, loc_name, location_table[loc_name], regBBH) for loc_name in locBBH_names]
|
||||
regBBH = create_region("Big Boo's Haunt", player, world)
|
||||
create_default_locs(regBBH, locBBH_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regBBH.locations.append(SM64Location(player, "BBH: 100 Coins", location_table["BBH: 100 Coins"], regBBH))
|
||||
world.regions.append(regBBH)
|
||||
|
||||
regBitDW = Region("Bowser in the Dark World", RegionType.Generic, "Bowser in the Dark World", player, world)
|
||||
locBitDW_names = [name for name, id in locBitDW_table.items()]
|
||||
regBitDW.locations += [SM64Location(player, loc_name, location_table[loc_name], regBitDW) for loc_name in
|
||||
locBitDW_names]
|
||||
regPSS = create_region("The Princess's Secret Slide", player, world)
|
||||
create_default_locs(regPSS, locPSS_table, player)
|
||||
world.regions.append(regPSS)
|
||||
|
||||
regSA = create_region("The Secret Aquarium", player, world)
|
||||
create_default_locs(regSA, locSA_table, player)
|
||||
world.regions.append(regSA)
|
||||
|
||||
regTotWC = create_region("Tower of the Wing Cap", player, world)
|
||||
create_default_locs(regTotWC, locTotWC_table, player)
|
||||
world.regions.append(regTotWC)
|
||||
|
||||
regBitDW = create_region("Bowser in the Dark World", player, world)
|
||||
create_default_locs(regBitDW, locBitDW_table, player)
|
||||
world.regions.append(regBitDW)
|
||||
|
||||
regBasement = Region("Basement", RegionType.Generic, "Basement", player, world)
|
||||
regBasement = create_region("Basement", player, world)
|
||||
world.regions.append(regBasement)
|
||||
|
||||
regHMC = Region("Hazy Maze Cave", RegionType.Generic, "Hazy Maze Cave", player, world)
|
||||
locHMC_names = [name for name, id in locHMC_table.items()]
|
||||
regHMC.locations += [SM64Location(player, loc_name, location_table[loc_name], regHMC) for loc_name in locHMC_names]
|
||||
regHMC = create_region("Hazy Maze Cave", player, world)
|
||||
create_default_locs(regHMC, locHMC_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regHMC.locations.append(SM64Location(player, "HMC: 100 Coins", location_table["HMC: 100 Coins"], regHMC))
|
||||
world.regions.append(regHMC)
|
||||
|
||||
regLLL = Region("Lethal Lava Land", RegionType.Generic, "Lethal Lava Land", player, world)
|
||||
locLLL_names = [name for name, id in locLLL_table.items()]
|
||||
regLLL.locations += [SM64Location(player, loc_name, location_table[loc_name], regLLL) for loc_name in locLLL_names]
|
||||
regLLL = create_region("Lethal Lava Land", player, world)
|
||||
create_default_locs(regLLL, locLLL_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regLLL.locations.append(SM64Location(player, "LLL: 100 Coins", location_table["LLL: 100 Coins"], regLLL))
|
||||
world.regions.append(regLLL)
|
||||
|
||||
regSSL = Region("Shifting Sand Land", RegionType.Generic, "Shifting Sand Land", player, world)
|
||||
locSSL_names = [name for name, id in locSSL_table.items()]
|
||||
regSSL.locations += [SM64Location(player, loc_name, location_table[loc_name], regSSL) for loc_name in locSSL_names]
|
||||
regSSL = create_region("Shifting Sand Land", player, world)
|
||||
create_default_locs(regSSL, locSSL_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regSSL.locations.append(SM64Location(player, "SSL: 100 Coins", location_table["SSL: 100 Coins"], regSSL))
|
||||
world.regions.append(regSSL)
|
||||
|
||||
regDDD = Region("Dire, Dire Docks", RegionType.Generic, "Dire, Dire Docks", player, world)
|
||||
locDDD_names = [name for name, id in locDDD_table.items()]
|
||||
regDDD.locations += [SM64Location(player, loc_name, location_table[loc_name], regDDD) for loc_name in locDDD_names]
|
||||
regDDD = create_region("Dire, Dire Docks", player, world)
|
||||
create_default_locs(regDDD, locDDD_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regDDD.locations.append(SM64Location(player, "DDD: 100 Coins", location_table["DDD: 100 Coins"], regDDD))
|
||||
world.regions.append(regDDD)
|
||||
|
||||
regBitFS = Region("Bowser in the Fire Sea", RegionType.Generic, "Bowser in the Fire Sea", player, world)
|
||||
locBitFS_names = [name for name, id in locBitFS_table.items()]
|
||||
regBitFS.locations += [SM64Location(player, loc_name, location_table[loc_name], regBitFS) for loc_name in
|
||||
locBitFS_names]
|
||||
regCotMC = create_region("Cavern of the Metal Cap", player, world)
|
||||
create_default_locs(regCotMC, locCotMC_table, player)
|
||||
world.regions.append(regCotMC)
|
||||
|
||||
regVCutM = create_region("Vanish Cap under the Moat", player, world)
|
||||
create_default_locs(regVCutM, locVCutM_table, player)
|
||||
world.regions.append(regVCutM)
|
||||
|
||||
regBitFS = create_region("Bowser in the Fire Sea", player, world)
|
||||
create_default_locs(regBitFS, locBitFS_table, player)
|
||||
world.regions.append(regBitFS)
|
||||
|
||||
regFloor2 = Region("Second Floor", RegionType.Generic, "Second Floor", player, world)
|
||||
regFloor2 = create_region("Second Floor", player, world)
|
||||
world.regions.append(regFloor2)
|
||||
|
||||
regSL = Region("Snowman's Land", RegionType.Generic, "Snowman's Land", player, world)
|
||||
locSL_names = [name for name, id in locSL_table.items()]
|
||||
regSL.locations += [SM64Location(player, loc_name, location_table[loc_name], regSL) for loc_name in locSL_names]
|
||||
regSL = create_region("Snowman's Land", player, world)
|
||||
create_default_locs(regSL, locSL_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regSL.locations.append(SM64Location(player, "SL: 100 Coins", location_table["SL: 100 Coins"], regSL))
|
||||
world.regions.append(regSL)
|
||||
|
||||
regWDW = Region("Wet-Dry World", RegionType.Generic, "Wet-Dry World", player, world)
|
||||
locWDW_names = [name for name, id in locWDW_table.items()]
|
||||
regWDW.locations += [SM64Location(player, loc_name, location_table[loc_name], regWDW) for loc_name in locWDW_names]
|
||||
regWDW = create_region("Wet-Dry World", player, world)
|
||||
create_default_locs(regWDW, locWDW_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regWDW.locations.append(SM64Location(player, "WDW: 100 Coins", location_table["WDW: 100 Coins"], regWDW))
|
||||
world.regions.append(regWDW)
|
||||
|
||||
regTTM = Region("Tall, Tall Mountain", RegionType.Generic, "Tall, Tall Mountain", player, world)
|
||||
locTTM_names = [name for name, id in locTTM_table.items()]
|
||||
regTTM.locations += [SM64Location(player, loc_name, location_table[loc_name], regTTM) for loc_name in locTTM_names]
|
||||
regTTM = create_region("Tall, Tall Mountain", player, world)
|
||||
create_default_locs(regTTM, locTTM_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regTTM.locations.append(SM64Location(player, "TTM: 100 Coins", location_table["TTM: 100 Coins"], regTTM))
|
||||
world.regions.append(regTTM)
|
||||
|
||||
regTHI = Region("Tiny-Huge Island", RegionType.Generic, "Tiny-Huge Island", player, world)
|
||||
locTHI_names = [name for name, id in locTHI_table.items()]
|
||||
regTHI.locations += [SM64Location(player, loc_name, location_table[loc_name], regTHI) for loc_name in locTHI_names]
|
||||
regTHI = create_region("Tiny-Huge Island", player, world)
|
||||
create_default_locs(regTHI, locTHI_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regTHI.locations.append(SM64Location(player, "THI: 100 Coins", location_table["THI: 100 Coins"], regTHI))
|
||||
world.regions.append(regTHI)
|
||||
|
||||
regFloor3 = Region("Third Floor", RegionType.Generic, "Third Floor", player, world)
|
||||
regFloor3 = create_region("Third Floor", player, world)
|
||||
world.regions.append(regFloor3)
|
||||
|
||||
regTTC = Region("Tick Tock Clock", RegionType.Generic, "Tick Tock Clock", player, world)
|
||||
locTTC_names = [name for name, id in locTTC_table.items()]
|
||||
regTTC.locations += [SM64Location(player, loc_name, location_table[loc_name], regTTC) for loc_name in locTTC_names]
|
||||
regTTC = create_region("Tick Tock Clock", player, world)
|
||||
create_default_locs(regTTC, locTTC_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regTTC.locations.append(SM64Location(player, "TTC: 100 Coins", location_table["TTC: 100 Coins"], regTTC))
|
||||
world.regions.append(regTTC)
|
||||
|
||||
regRR = Region("Rainbow Ride", RegionType.Generic, "Rainbow Ride", player, world)
|
||||
locRR_names = [name for name, id in locRR_table.items()]
|
||||
regRR.locations += [SM64Location(player, loc_name, location_table[loc_name], regRR) for loc_name in locRR_names]
|
||||
regRR = create_region("Rainbow Ride", player, world)
|
||||
create_default_locs(regRR, locRR_table, player)
|
||||
if (world.EnableCoinStars[player].value):
|
||||
regRR.locations.append(SM64Location(player, "RR: 100 Coins", location_table["RR: 100 Coins"], regRR))
|
||||
world.regions.append(regRR)
|
||||
|
||||
regWMotR = create_region("Wing Mario over the Rainbow", player, world)
|
||||
create_default_locs(regWMotR, locWMotR_table, player)
|
||||
world.regions.append(regWMotR)
|
||||
|
||||
regBitS = create_region("Bowser in the Sky", player, world)
|
||||
create_default_locs(regBitS, locBitS_table, player)
|
||||
world.regions.append(regBitS)
|
||||
|
||||
|
||||
def connect_regions(world: MultiWorld, player: int, source: str, target: str, rule=None):
|
||||
sourceRegion = world.get_region(source, player)
|
||||
|
@ -159,3 +177,10 @@ def connect_regions(world: MultiWorld, player: int, source: str, target: str, ru
|
|||
|
||||
sourceRegion.exits.append(connection)
|
||||
connection.connect(targetRegion)
|
||||
|
||||
def create_region(name: str, player: int, world: MultiWorld) -> Region:
|
||||
return Region(name, RegionType.Generic, name, player, world)
|
||||
|
||||
def create_default_locs(reg: Region, locs, player):
|
||||
reg_names = [name for name, id in locs.items()]
|
||||
reg.locations += [SM64Location(player, loc_name, location_table[loc_name], reg) for loc_name in locs]
|
||||
|
|
|
@ -1,56 +1,76 @@
|
|||
from ..generic.Rules import add_rule
|
||||
from .Regions import connect_regions, sm64courses, sm64paintings
|
||||
from .Regions import connect_regions, sm64courses, sm64paintings, sm64secrets, sm64entrances
|
||||
|
||||
def fix_reg(entrance_ids, reg, invalidspot, swaplist, world):
|
||||
if entrance_ids.index(reg) == invalidspot: # Unlucky :C
|
||||
swaplist.remove(invalidspot)
|
||||
rand = world.random.choice(swaplist)
|
||||
entrance_ids[invalidspot], entrance_ids[rand] = entrance_ids[rand], entrance_ids[invalidspot]
|
||||
swaplist.append(invalidspot)
|
||||
swaplist.remove(rand)
|
||||
|
||||
def set_rules(world, player: int, area_connections):
|
||||
entrance_ids = list(range(len(sm64paintings)))
|
||||
destination_courses = list(range(13)) + [12,13,14] # Two instances of Destination Course THI
|
||||
if world.AreaRandomizer[player]:
|
||||
destination_regions = list(range(13)) + [12,13,14] + list(range(15,15+len(sm64secrets))) # Two instances of Destination Course THI. Past normal course idx are secret regions
|
||||
if world.AreaRandomizer[player].value == 0:
|
||||
entrance_ids = list(range(len(sm64paintings + sm64secrets)))
|
||||
if world.AreaRandomizer[player].value >= 1: # Some randomization is happening, randomize Courses
|
||||
entrance_ids = list(range(len(sm64paintings)))
|
||||
world.random.shuffle(entrance_ids)
|
||||
temp_assign = dict(zip(entrance_ids,destination_courses)) # Used for Rules only
|
||||
entrance_ids = entrance_ids + list(range(len(sm64paintings), len(sm64paintings) + len(sm64secrets)))
|
||||
if world.AreaRandomizer[player].value == 2: # Secret Regions as well
|
||||
world.random.shuffle(entrance_ids)
|
||||
# Guarantee first entrance is a course
|
||||
swaplist = list(range(len(entrance_ids)))
|
||||
if entrance_ids.index(0) > 15: # Unlucky :C
|
||||
rand = world.random.randint(0,15)
|
||||
entrance_ids[entrance_ids.index(0)], entrance_ids[rand] = entrance_ids[rand], entrance_ids[entrance_ids.index(0)]
|
||||
swaplist.remove(entrance_ids.index(0))
|
||||
# Guarantee COTMC is not mapped to HMC, cuz thats impossible
|
||||
fix_reg(entrance_ids, 20, 5, swaplist, world)
|
||||
# Guarantee BITFS is not mapped to DDD
|
||||
fix_reg(entrance_ids, 22, 8, swaplist, world)
|
||||
temp_assign = dict(zip(entrance_ids,destination_regions)) # Used for Rules only
|
||||
|
||||
# Destination Format: LVL | AREA with LVL = Course ID, 0-indexed, AREA = Area as used in sm64 code
|
||||
area_connections.update({entrance: (destination_course*10 + 1) for entrance, destination_course in temp_assign.items()})
|
||||
for i in range(len(area_connections)):
|
||||
if (int(area_connections[i]/10) == 12):
|
||||
# Change first occurence of course 12 (THI) to Area 2 (THI Tiny)
|
||||
area_connections[i] = 12*10 + 2
|
||||
break
|
||||
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[0]])
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[1]], lambda state: state.has("Power Star", player, 1))
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[2]], lambda state: state.has("Power Star", player, 3))
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[3]], lambda state: state.has("Power Star", player, 3))
|
||||
connect_regions(world, player, "Menu", "Bowser in the Dark World", lambda state: state.has("Power Star", player, world.FirstBowserStarDoorCost[player].value))
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[4]], lambda state: state.has("Power Star", player, 12))
|
||||
# Destination Format: LVL | AREA with LVL = LEVEL_x, AREA = Area as used in sm64 code
|
||||
area_connections.update({sm64entrances[entrance]: destination for entrance, destination in zip(entrance_ids,sm64entrances)})
|
||||
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[0]]) # BOB
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[1]], lambda state: state.has("Power Star", player, 1)) # WF
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[2]], lambda state: state.has("Power Star", player, 3)) # JRB
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[3]], lambda state: state.has("Power Star", player, 3)) # CCM
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[4]], lambda state: state.has("Power Star", player, 12)) # BBH
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[16]], lambda state: state.has("Power Star", player, 1)) # PSS
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[17]], lambda state: state.has("Power Star", player, 3)) # SA
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[19]], lambda state: state.has("Power Star", player, 10)) # TOTWC
|
||||
connect_regions(world, player, "Menu", sm64courses[temp_assign[18]], lambda state: state.has("Power Star", player, world.FirstBowserStarDoorCost[player].value)) # BITDW
|
||||
|
||||
connect_regions(world, player, "Menu", "Basement", lambda state: state.has("Basement Key", player) or state.has("Progressive Key", player, 1))
|
||||
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[5]])
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[6]])
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[7]])
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[8]], lambda state: state.has("Power Star", player, world.BasementStarDoorCost[player].value))
|
||||
connect_regions(world, player, "Basement", "Bowser in the Fire Sea", lambda state: state.has("Power Star", player, world.BasementStarDoorCost[player].value) and
|
||||
state.can_reach("DDD: Board Bowser's Sub", 'Location', player))
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[5]]) # HMC
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[6]]) # LLL
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[7]]) # SSL
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[8]], lambda state: state.has("Power Star", player, world.BasementStarDoorCost[player].value)) # DDD
|
||||
connect_regions(world, player, "Hazy Maze Cave", sm64courses[temp_assign[20]]) # COTMC
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[21]]) # VCUTM
|
||||
connect_regions(world, player, "Basement", sm64courses[temp_assign[22]], lambda state: state.has("Power Star", player, world.BasementStarDoorCost[player].value) and
|
||||
state.can_reach("DDD: Board Bowser's Sub", 'Location', player)) # BITFS
|
||||
|
||||
connect_regions(world, player, "Menu", "Second Floor", lambda state: state.has("Second Floor Key", player) or state.has("Progressive Key", player, 2))
|
||||
|
||||
connect_regions(world, player, "Second Floor", sm64courses[temp_assign[9]])
|
||||
connect_regions(world, player, "Second Floor", sm64courses[temp_assign[10]])
|
||||
connect_regions(world, player, "Second Floor", sm64courses[temp_assign[11]])
|
||||
connect_regions(world, player, "Second Floor", sm64courses[temp_assign[9]]) # SL
|
||||
connect_regions(world, player, "Second Floor", sm64courses[temp_assign[10]]) # WDW
|
||||
connect_regions(world, player, "Second Floor", sm64courses[temp_assign[11]]) # TTM
|
||||
connect_regions(world, player, "Second Floor", sm64courses[temp_assign[12]]) # THI Tiny
|
||||
connect_regions(world, player, "Second Floor", sm64courses[temp_assign[13]]) # THI Huge
|
||||
|
||||
connect_regions(world, player, "Second Floor", "Third Floor", lambda state: state.has("Power Star", player, world.SecondFloorStarDoorCost[player].value))
|
||||
|
||||
connect_regions(world, player, "Third Floor", sm64courses[temp_assign[14]])
|
||||
connect_regions(world, player, "Third Floor", sm64courses[temp_assign[15]])
|
||||
connect_regions(world, player, "Third Floor", sm64courses[temp_assign[14]]) # TTC
|
||||
connect_regions(world, player, "Third Floor", sm64courses[temp_assign[15]]) # RR
|
||||
connect_regions(world, player, "Third Floor", sm64courses[temp_assign[23]]) # WMOTR
|
||||
connect_regions(world, player, "Third Floor", "Bowser in the Sky", lambda state: state.has("Power Star", player, world.StarsToFinish[player].value)) # BITS
|
||||
|
||||
#Special Rules for some Locations
|
||||
add_rule(world.get_location("Tower of the Wing Cap Switch", player), lambda state: state.has("Power Star", player, 10))
|
||||
add_rule(world.get_location("Cavern of the Metal Cap Switch", player), lambda state: state.can_reach("Hazy Maze Cave", 'Region', player))
|
||||
add_rule(world.get_location("Vanish Cap Under the Moat Switch", player), lambda state: state.can_reach("Basement", 'Region', player))
|
||||
|
||||
add_rule(world.get_location("BoB: Mario Wings to the Sky", player), lambda state: state.has("Cannon Unlock BoB", player))
|
||||
add_rule(world.get_location("BBH: Eye to Eye in the Secret Room", player), lambda state: state.has("Vanish Cap", player))
|
||||
add_rule(world.get_location("DDD: Collect the Caps...", player), lambda state: state.has("Vanish Cap", player))
|
||||
|
@ -89,18 +109,14 @@ def set_rules(world, player: int, area_connections):
|
|||
add_rule(world.get_location("BoB: 100 Coins", player), lambda state: state.has("Cannon Unlock BoB", player) or state.has("Wing Cap", player))
|
||||
|
||||
#Rules for Secret Stars
|
||||
add_rule(world.get_location("Bowser in the Sky Red Coins", player), lambda state: state.can_reach("Third Floor", 'Region',player) and state.has("Power Star", player, world.StarsToFinish[player].value))
|
||||
add_rule(world.get_location("The Princess's Secret Slide Block", player), lambda state: state.has("Power Star", player, 1))
|
||||
add_rule(world.get_location("The Princess's Secret Slide Fast", player), lambda state: state.has("Power Star", player, 1))
|
||||
add_rule(world.get_location("Cavern of the Metal Cap Red Coins", player), lambda state: state.can_reach("Cavern of the Metal Cap Switch", 'Location', player))
|
||||
add_rule(world.get_location("Tower of the Wing Cap Red Coins", player), lambda state: state.can_reach("Tower of the Wing Cap Switch", 'Location', player))
|
||||
add_rule(world.get_location("Vanish Cap Under the Moat Red Coins", player), lambda state: state.can_reach("Vanish Cap Under the Moat Switch", 'Location', player))
|
||||
add_rule(world.get_location("Wing Mario Over the Rainbow", player), lambda state: state.can_reach("Third Floor", 'Region', player) and state.has("Wing Cap", player))
|
||||
add_rule(world.get_location("The Secret Aquarium", player), lambda state: state.has("Power Star", player, 3))
|
||||
add_rule(world.get_location("Wing Mario Over the Rainbow", player), lambda state: state.has("Wing Cap", player))
|
||||
add_rule(world.get_location("Toad (Basement)", player), lambda state: state.can_reach("Basement", 'Region', player) and state.has("Power Star", player, 12))
|
||||
add_rule(world.get_location("Toad (Second Floor)", player), lambda state: state.can_reach("Second Floor", 'Region', player) and state.has("Power Star", player, 25))
|
||||
add_rule(world.get_location("Toad (Third Floor)", player), lambda state: state.can_reach("Third Floor", 'Region', player) and state.has("Power Star", player, 35))
|
||||
add_rule(world.get_location("MIPS 1", player), lambda state: state.can_reach("Basement", 'Region', player) and state.has("Power Star", player, 15))
|
||||
add_rule(world.get_location("MIPS 2", player), lambda state: state.can_reach("Basement", 'Region', player) and state.has("Power Star", player, 50))
|
||||
|
||||
world.completion_condition[player] = lambda state: state.can_reach("Third Floor", 'Region', player) and state.has("Power Star", player, world.StarsToFinish[player].value)
|
||||
if world.MIPS1Cost[player].value > world.MIPS2Cost[player].value:
|
||||
world.MIPS2Cost[player].value = world.MIPS1Cost[player].value
|
||||
add_rule(world.get_location("MIPS 1", player), lambda state: state.can_reach("Basement", 'Region', player) and state.has("Power Star", player, world.MIPS1Cost[player].value))
|
||||
add_rule(world.get_location("MIPS 2", player), lambda state: state.can_reach("Basement", 'Region', player) and state.has("Power Star", player, world.MIPS2Cost[player].value))
|
||||
|
||||
world.completion_condition[player] = lambda state: state.can_reach("Bowser in the Sky", 'Region', player)
|
||||
|
|
|
@ -5,7 +5,7 @@ from .Items import item_table, cannon_item_table, SM64Item
|
|||
from .Locations import location_table, SM64Location
|
||||
from .Options import sm64_options
|
||||
from .Rules import set_rules
|
||||
from .Regions import create_regions, sm64courses, sm64paintings
|
||||
from .Regions import create_regions, sm64courses, sm64entrances_s, sm64_internalloc_to_string, sm64_internalloc_to_regionid
|
||||
from BaseClasses import Item, Tutorial, ItemClassification
|
||||
from ..AutoWorld import World, WebWorld
|
||||
|
||||
|
@ -54,10 +54,10 @@ class SM64World(World):
|
|||
set_rules(self.world, self.player, self.area_connections)
|
||||
if self.topology_present:
|
||||
# Write area_connections to spoiler log
|
||||
for painting_id, destination in self.area_connections.items():
|
||||
for entrance, destination in self.area_connections.items():
|
||||
self.world.spoiler.set_entrance(
|
||||
sm64paintings[painting_id] + " Painting",
|
||||
sm64courses[destination // 10],
|
||||
sm64_internalloc_to_string[entrance] + " Entrance",
|
||||
sm64_internalloc_to_string[destination],
|
||||
'entrance', self.player)
|
||||
|
||||
def create_item(self, name: str) -> Item:
|
||||
|
@ -74,9 +74,13 @@ class SM64World(World):
|
|||
|
||||
def generate_basic(self):
|
||||
staritem = self.create_item("Power Star")
|
||||
starcount = min(self.world.StarsToFinish[self.player].value + self.world.ExtraStars[self.player].value,120)
|
||||
starcount = self.world.AmountOfStars[self.player].value
|
||||
if (not self.world.EnableCoinStars[self.player].value):
|
||||
starcount = max(starcount - 15,self.world.StarsToFinish[self.player].value)
|
||||
starcount = max(35,self.world.AmountOfStars[self.player].value-15)
|
||||
starcount = max(starcount, self.world.FirstBowserStarDoorCost[self.player].value,
|
||||
self.world.BasementStarDoorCost[self.player].value, self.world.SecondFloorStarDoorCost[self.player].value,
|
||||
self.world.MIPS1Cost[self.player].value, self.world.MIPS2Cost[self.player].value,
|
||||
self.world.StarsToFinish[self.player].value)
|
||||
self.world.itempool += [staritem for i in range(0,starcount)]
|
||||
mushroomitem = self.create_item("1Up Mushroom")
|
||||
self.world.itempool += [mushroomitem for i in range(starcount,120 - (15 if not self.world.EnableCoinStars[self.player].value else 0))]
|
||||
|
@ -117,6 +121,8 @@ class SM64World(World):
|
|||
"FirstBowserDoorCost": self.world.FirstBowserStarDoorCost[self.player].value,
|
||||
"BasementDoorCost": self.world.BasementStarDoorCost[self.player].value,
|
||||
"SecondFloorCost": self.world.SecondFloorStarDoorCost[self.player].value,
|
||||
"MIPS1Cost": self.world.MIPS1Cost[self.player].value,
|
||||
"MIPS2Cost": self.world.MIPS2Cost[self.player].value,
|
||||
"StarsToFinish": self.world.StarsToFinish[self.player].value,
|
||||
"DeathLink": self.world.death_link[self.player].value,
|
||||
}
|
||||
|
@ -145,8 +151,9 @@ class SM64World(World):
|
|||
def modify_multidata(self, multidata):
|
||||
if self.topology_present:
|
||||
er_hint_data = {}
|
||||
for painting_id, destination in self.area_connections.items():
|
||||
region = self.world.get_region(sm64courses[destination // 10], self.player)
|
||||
for entrance, destination in self.area_connections.items():
|
||||
regionid = sm64_internalloc_to_regionid[destination]
|
||||
region = self.world.get_region(sm64courses[regionid], self.player)
|
||||
for location in region.locations:
|
||||
er_hint_data[location.address] = sm64paintings[painting_id]
|
||||
er_hint_data[location.address] = sm64_internalloc_to_string[entrance]
|
||||
multidata['er_hint_data'][self.player] = er_hint_data
|
||||
|
|
Loading…
Reference in New Issue